【问题标题】:How can I get Chef to run apt-get update before running other recipes如何让 Chef 在运行其他食谱之前运行 apt-get update
【发布时间】:2012-03-04 01:03:36
【问题描述】:

现在我的 Vagrantfile 中有以下内容:

config.vm.provision :chef_solo do |chef|
    chef.cookbooks_path = "cookbooks"
    chef.add_recipe "apt"
    chef.add_recipe "build-essential"
    chef.add_recipe "chef-redis::source"
    chef.add_recipe "openssl"
    chef.add_recipe "git"
    chef.add_recipe "postgresql::server"
    chef.add_recipe "postgresql::client"
end

为了安装添加到我的 recipe_list 中的软件,我需要让 VM 在安装其他软件之前发出 apt-get update

我的印象是,这是“apt”配方的功能之一——它会首先运行更新。

当我执行 vagrant provision 时的输出是:

[Sat, 11 Feb 2012 22:20:03 -0800] INFO: *** Chef 0.10.2 ***
[Sat, 11 Feb 2012 22:20:03 -0800] INFO: Setting the run_list to ["recipe[apt]", "recipe[build-essential]", "recipe[chef-redis::source]", "recipe[openssl]", "recipe[git]", "recipe[postgresql::server]", "recipe[postgresql::client]", "recipe[vagrant-main]"] from JSON
[Sat, 11 Feb 2012 22:20:03 -0800] INFO: Run List is [recipe[apt], recipe[build-essential], recipe[chef-redis::source], recipe[openssl], recipe[git], recipe[postgresql::server], recipe[postgresql::client], recipe[vagrant-main]]
[Sat, 11 Feb 2012 22:20:03 -0800] INFO: Run List expands to [apt, build-essential, chef-redis::source, openssl, git, postgresql::server, postgresql::client, vagrant-main]
[Sat, 11 Feb 2012 22:20:03 -0800] INFO: Starting Chef Run for lucid32
[Sat, 11 Feb 2012 22:20:03 -0800] INFO: Processing package[postgresql-client] action install (postgresql::client line 37)
[Sat, 11 Feb 2012 22:20:04 -0800] ERROR: package[postgresql-client] (postgresql::client line 37) has had an error
[Sat, 11 Feb 2012 22:20:04 -0800] ERROR: Running exception handlers
[Sat, 11 Feb 2012 22:20:04 -0800] ERROR: Exception handlers complete
[Sat, 11 Feb 2012 22:20:04 -0800] FATAL: Stacktrace dumped to /tmp/vagrant-chef-1/chef-stacktrace.out
[Sat, 11 Feb 2012 22:20:04 -0800] FATAL: Chef::Exceptions::Exec: package[postgresql-client] (postgresql::client line 37) had an error: apt-get -q -y install postgresql-client=8.4.8-0ubuntu0.10.04 returned 100, expected 0

【问题讨论】:

标签: apt apt-get chef-infra vagrant


【解决方案1】:

您可以在一开始就包含 apt 配方:

include_recipe 'apt'

这将运行更新命令。

【讨论】:

  • 对我来说,我必须:include_recipe 'apt'
【解决方案2】:

apt-get update 应该首先按照您的方式运行。但是,配方只会每 24 小时更新一次:

execute "apt-get-update-periodic" do
  command "apt-get update"
  ignore_failure true
  only_if do
    File.exists?('/var/lib/apt/periodic/update-success-stamp') &&
    File.mtime('/var/lib/apt/periodic/update-success-stamp') < Time.now - 86400
  end
end

【讨论】:

  • 问题是 apt-get 更新最初没有运行。此外,似乎 chef.add_recipe "postgresql::server" 和 chef.add_recipe "postgresql::client" 在 apt 配方之前首先运行。
  • 这真的很奇怪,但应该可以。您可以尝试删除 /var/lib/apt/periodic/update-success-stamp 一次吗?
  • @ashchristopher - 您希望它最初运行 - 请参阅下面的答案。我也想要那个。
  • 当时间戳文件不存在时,它不会运行apt-get update,它最初不会这样做。在我看来,正确的逻辑是!File.exists?(...) || File.mtime ...
【解决方案3】:

有三种资源可以在 ubuntu 系统上很好地做到这一点,特别是我在 12.04 精确 64 位上使用。

  1. 当其他配方需要时随意运行 apt-get-update

  2. 安装 update-notifier-common 软件包,为我们提供更新时间戳

  3. 检查时间戳并定期更新。在这种情况下,在 86400 秒之后。

这是这三个食谱。

execute "apt-get-update" do
  command "apt-get update"
  ignore_failure true
  action :nothing
end

package "update-notifier-common" do
  notifies :run, resources(:execute => "apt-get-update"), :immediately
end

execute "apt-get-update-periodic" do
  command "apt-get update"
  ignore_failure true
  only_if do
   File.exists?('/var/lib/apt/periodic/update-success-stamp') &&
   File.mtime('/var/lib/apt/periodic/update-success-stamp') < Time.now - 86400
  end
end

【讨论】:

  • 谢谢 - 这对我有一个小的改动 - 第一次执行调用应该使用 'apt-get-update'。
【解决方案4】:

看起来最新版本的 opscode apt cookbook 允许您在编译时运行它。

config.vm.provision :chef_solo do |chef|
  chef.cookbooks_path = "cookbooks"
  chef.add_recipe "apt"
  chef.json = { "apt" => {"compiletime" => true} }
end

只要 apt 在运行列表中的其他编译时说明书(如 postgres)之前运行,这应该可以工作。

【讨论】:

    【解决方案5】:

    此处发布的许多其他答案可能会导致有关资源克隆的警告。

    根据Apt cookbook documentation,您应该能够通过设置node['apt']['compile_time_update'] = true 来实现这一点,但是我自己从来没有对这种方法感到过运气

    这就是我所做的:

    这将加载原始apt-get update 资源并确保它运行时不会向资源集合添加重复条目。这将导致 apt-get update 在编译阶段的每次 Chef 运行期间执行:

    # First include the apt::default recipe (so that `apt-get update` is added to the collection)
    include_recipe 'apt'
    
    # Then load the `apt-get update` resource from the collection and run it
    resources(execute: 'apt-get update').run_action(:run)
    

    显然,您还需要在 metadata.rb 文件中包含 apt 食谱:

    # ./metadata.rb
    depends 'apt'
    

    【讨论】:

      【解决方案6】:

      我似乎已经能够通过应用以下补丁来解决这个问题:

      https://github.com/wil/cookbooks/commit/a470a4f68602ec3bf3374830f4990a7e19e9de81

      【讨论】:

      • 这是一种非常奇怪的安装包方式(即使用action :nothingrun_action(:install)。这似乎是在chef-client 运行的编译阶段而不是在执行阶段安装包。有关详细信息,请参阅 [wiki.opscode.com/display/chef/Anatomy+of+a+Chef+Run]。将recipe[apt] 添加到节点的运行列表的前面通常应该将apt-get install 作为第一个操作运行。
      • “将 recipe[apt] 添加到节点运行列表的前面通常应该运行 apt-get install 作为第一个操作。”为我工作。
      【解决方案7】:

      解决问题的最简单和最直接的方法是应用以下补丁 (h/t @ashchristopher):

      https://github.com/wil/cookbooks/commit/a470a4f68602ec3bf3374830f4990a7e19e9de81

      问题在于 postgresql::client 配方在 postgresql/recipes/client.rb:39 和 44 在 compile-time 的包资源上运行安装操作,而不是像正常的运行时(h/t Tim Potter),导致它们被评估在其他任何东西运行之前由 Chef(并因此安装)。

      pg_packages.each do |pg_pack|
        package pg_pack do
          action :nothing
        end.run_action(:install)
      end
      
      gem_package "pg" do
        action :nothing
      end.run_action(:install)
      

      我相信这是为 database cookbook 的 postgres 提供程序服务的,它依赖于 postgresql 食谱并依赖于在编译之前安装的 pg gem。应用上述补丁可能会破坏database 食谱。

      另一种替代解决方案是创建一个同样在编译时运行apt-get update 的配方,并将其放在run_list 之前的postgresql 食谱中。最简单的形式可能是这样的:

      execute "apt-get update" do
        action :nothing
      end.run_action(:install)
      

      【讨论】:

        【解决方案8】:

        不打补丁,这是解决问题的通用方法,每次运行都会更新:

        bash "update-apt-repository" do
          user "root"
          code <<-EOH
          apt-get update
          EOH
        end
        

        可能值得考虑的是,每次运行都会占用相当多的系统资源大约 30 秒;您可能想要一个名为 recipe::update_apt 的特殊配方,您可以通过 cron 或其他事件运行,即

        chef-client -o "recipe[yourrecipe::update_apt]"
        

        【讨论】:

          【解决方案9】:

          要在编译时运行 apt-get update,请执行以下操作:

          e = execute "apt-get update" do
            action :nothing
          end
          
          e.run_action(:run)
          

          查看https://wiki.opscode.com/display/chef/Evaluate+and+Run+Resources+at+Compile+Time

          【讨论】:

          【解决方案10】:

          我也遇到了同样的情况,就我而言,apt cookbook 排在第二位,仅次于安装包。把它留在这里,也许有人会从中受益。检查你的运行列表、角色或其他任何地方的食谱顺序。

          【讨论】:

            【解决方案11】:

            只是一个友好的提醒,在 vagrant 规定中添加所有这些食谱很快就会变得难以管理。

            更好的模式是创建厨师角色chef/my-fancy-role.rb

            # Name of the role should match the name of the file
            name "my-fancy-role"
            
            # Run list function we mentioned earlier
            run_list(
                "recipe[apt]",
                "recipe[build-essential]",
                "recipe[chef-redis::source]",
                "recipe[openssl]"
            )
            

            然后将此角色添加到Vagrantfile 配置部分:

            config.vm.provision :chef_solo do |chef|
              chef.roles_path = "chef/roles"
              chef.cookbooks_path = ["chef/site-cookbooks", "chef/cookbooks"]
              chef.add_role "my-fancy-role"
            end
            

            【讨论】:

              【解决方案12】:

              对于最近的 Chef 版本,即版本 14。 你也可以使用https://docs.chef.io/resource_apt_update.html

              apt_update

              以下输出是我在本地模式(零)下为 chef_14.5.33 运行该资源的实验:

              curl -O https://packages.chef.io/files/stable/chef/14.5.33/ubuntu/18.04/chef_14.5.33-1_amd64.de
              sudo dpkg -i chef_14.5.33-1_amd64.deb
              mkdir -p cookbooks/hello/recipes/ && echo "apt_update" > cookbooks/hello/recipes/default.rb
              
              sudo sh -c 'chef-client -z -o hello'
              [2018-10-12T10:25:30+00:00] WARN: No config file found or specified on command line, using command line options.
              Starting Chef Client, version 14.5.33
              [2018-10-12T10:25:32+00:00] WARN: Run List override has been provided.
              [2018-10-12T10:25:32+00:00] WARN: Run List override has been provided.
              [2018-10-12T10:25:32+00:00] WARN: Original Run List: []
              [2018-10-12T10:25:32+00:00] WARN: Original Run List: []
              [2018-10-12T10:25:32+00:00] WARN: Overridden Run List: [recipe[hello]]
              [2018-10-12T10:25:32+00:00] WARN: Overridden Run List: [recipe[hello]]
              resolving cookbooks for run list: ["hello"]
              Synchronizing Cookbooks:
                - hello (0.0.0)
              Installing Cookbook Gems:
              Compiling Cookbooks...
              Converging 1 resources
              Recipe: hello::default
                * apt_update[] action periodic (up to date)
              [2018-10-12T10:25:32+00:00] WARN: Skipping final node save because override_runlist was given
              [2018-10-12T10:25:32+00:00] WARN: Skipping final node save because override_runlist was given
              
              Running handlers:
              Running handlers complete
              Chef Client finished, 0/1 resources updated in 01 seconds
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2012-06-06
                • 2016-05-25
                • 1970-01-01
                • 2012-02-14
                • 1970-01-01
                • 1970-01-01
                • 2017-06-30
                • 1970-01-01
                相关资源
                最近更新 更多