Ответ 1
Кажется, я смог решить проблему, применив следующий патч:
https://github.com/wil/cookbooks/commit/a470a4f68602ec3bf3374830f4990a7e19e9de81
Сейчас у меня есть следующее в моем 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, мне нужно заставить виртуальную машину выдать обновление apt-get перед установкой другого программного обеспечения.
У меня создалось впечатление, что это была одна из особенностей рецепта "apt" - что он первым запускал обновление.
Вывод, когда я выполняю бродяжничество:
[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
Кажется, я смог решить проблему, применив следующий патч:
https://github.com/wil/cookbooks/commit/a470a4f68602ec3bf3374830f4990a7e19e9de81
Вы можете включить рецепт apt в самом начале:
include_recipe 'apt'
это запустит команду обновления.
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
Есть три ресурса, которые сделают это хорошо в системе ubuntu, в частности, используя 12.04 точных 64 бит.
запустите apt-get-update по желанию, когда другие рецепты требуют
установить update-notifier-общий пакет, который дает нам временные отметки об обновлениях
периодически проверять метки времени и обновлять их. В этом случае ниже через 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
Похоже, что последняя версия куковой книги opscode apt позволяет запускать ее во время компиляции.
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = "cookbooks"
chef.add_recipe "apt"
chef.json = { "apt" => {"compiletime" => true} }
end
До тех пор, пока apt запускается до других кулинарных книг компиляции (например, postgres) в списке запуска, это должно работать.
Многие другие ответы, размещенные здесь, скорее всего, вызовут предупреждения о клонировании ресурсов.
В соответствии с 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)
Очевидно, что вы также захотите включить кучную книгу apt
в файл metadata.rb:
# ./metadata.rb
depends 'apt'
Самый простой и самый прямой способ решить проблему - применить следующий патч (h/t @ashchristopher):
https://github.com/wil/cookbooks/commit/a470a4f68602ec3bf3374830f4990a7e19e9de81
Проблема заключается в том, что в рецепте postgresql::client
выполняется действие установки на ресурсах пакета postgresql/recipes/client.rb: 39 и 44 в время компиляции, а не время выполнения, как обычно (h/t Tim Potter), заставляя их оцениваться шеф-поваром (и, таким образом, установлен), прежде чем что-нибудь еще запустится.
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
, который будет установлен до его компиляции. Применение вышеуказанного патча может сломать кулинарную книгу database
.
Другим альтернативным решением было бы создать рецепт, который запускает apt-get update
также во время компиляции и помещает его в run_list
перед кулинарной книгой postgresql
. В его простейшей форме, вероятно, будет что-то вроде:
execute "apt-get update" do
action :nothing
end.run_action(:install)
Без исправления это общий подход к проблеме, который будет обновляться при каждом запуске:
bash "update-apt-repository" do
user "root"
code <<-EOH
apt-get update
EOH
end
Возможно, стоит подумать, что такой запуск на каждом прогоне связывает справедливый бит системных ресурсов в течение примерно 30 секунд; вам может понадобиться специальный рецепт с именем recipe:: update_apt, который вы выполнили через cron или через какое-то другое событие i.e.
chef-client -o "recipe[yourrecipe::update_apt]"
Чтобы запустить 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
У меня была такая же ситуация, и в моем случае кулинарная книга apt была второй после той, которая называлась установкой пакета. Просто оставив его здесь, поэтому, возможно, кто-то выиграет от этого. Проверьте порядок кулинарных книг в своем списке, роли или где-либо еще.
просто дружественное напоминание о том, что добавление всех этих рецептов внутри брандмауэра может быстро стать неуправляемым.
Лучше всего создать роль шеф-повара 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