Ресурс execute
Эта страница сгенерирована из исходного кода Chef. Чтобы предложить изменение, отредактируйте файл execute.rb и отправьте запрос на внесение изменений в репозиторий Chef.
Страница справочника по ресурсам
Используйте ресурс execute для выполнения одной команды. Команды, выполняемые с помощью этого ресурса, (по своей природе) не являются идемпотентными, поскольку они обычно уникальны для среды, в которой они выполняются. Используйте not_if и only_if для защиты этого ресурса от потери идемпотентности.
Примечание
Используйте ресурс script для выполнения скрипта с использованием определенного интерпретатора (Ruby, Python, Perl, csh или Bash).
Синтаксис
Блок ресурсов execute обычно выполняет одну команду, которая уникальна для среды, в которой будет выполняться рецепт. Некоторые команды ресурса execute выполняются сами по себе, но часто они выполняются в сочетании с другими ресурсами Chef. Например, одна команда, выполняемая сама по себе:
execute 'apache_configtest' do
command '/usr/sbin/apachectl configtest'
end
Полный синтаксис для всех свойств, доступных ресурсу execute:
execute 'name' do
command String, Array # default value: 'name' unless specified
creates String
cwd String
default_env true, false # default value: false
domain String
elevated true, false # default value: false
environment Hash
group String, Integer
input String
live_stream true, false # default value: false
password String
returns Integer, Array # default value: 0
sensitive true, false
timeout Integer, String, Float # default value: 3600
umask String, Integer
user String, Integer
action Symbol # defaults to :run if not specified
endгде:
-
execute— это ресурс. -
name— это имя, данное блоку ресурсов. -
actionопределяет, какие шаги предпримет клиент Chef Infra для приведения узла в желаемое состояние. -
command,creates,cwd,default_env,domain,elevated,environment,group,input,live_stream,password,returns,sensitive,timeout,umask, иuser— это свойства, доступные для этого ресурса.
Действия
Ресурс execute имеет следующие действия:
:nothing- Этот блок ресурсов не выполняет никаких действий, если не получит уведомление от другого ресурса о необходимости принять меры. После получения уведомления этот блок ресурсов либо запускается немедленно, либо помещается в очередь для запуска в конце выполнения клиента Chef Infra.
:run- По умолчанию. Выполнить команду.
Свойства
Ресурс execute имеет следующие свойства:
command-
Тип Ruby: String, Array | Значение по умолчанию:
The resource block's nameИмя команды, которая должна быть выполнена. Значение по умолчанию:
nameблока ресурсов. Для получения дополнительной информации см. раздел «Синтаксис» выше.Примечание
Используйте ресурс execute для выполнения одной команды. Используйте несколько блоков ресурсов execute для выполнения нескольких команд.
creates-
Тип Ruby: String
Запретить команде создавать файл, если этот файл уже существует.
cwd-
Тип Ruby: String
Текущий рабочий каталог, из которого будет выполняться команда.
default_env-
Тип Ruby: true, false | Значение по умолчанию:
falseЕсли значение true, это включает магию ENV для добавления path_sanity в PATH и принудительного использования локали English+UTF-8 для анализа вывода
Новое в Chef Client 14.2
domain-
Тип Ruby: String
Только для Windows: Домен пользователя, указанного свойством user. Если не указано, имя пользователя и пароль, указанные свойствами user и password, будут использоваться для разрешения этого пользователя в домене, к которому подключена система, выполняющая клиент Chef Infra, или, если эта система не подключена к домену, он разрешит пользователя как локальную учетную запись на этой системе. Альтернативный способ указать домен — это оставить это свойство неуказанным и указать домен как часть свойства user.
Новое в Chef Client 12.21
elevated-
Тип Ruby: true, false | Значение по умолчанию:
falseОпределяет, будет ли скрипт выполняться с повышенными правами для обхода интерактивного блокирования процесса Управлением учетными записями пользователей (UAC). Это приведет к тому, что процесс будет выполняться в режиме пакетного входа, а не интерактивного входа. Пользователь, запускающий chef-client, должен иметь разрешения «Замена маркера уровня процесса» и «Корректировка квот памяти для процесса». Пользователь, выполняющий команду, должен иметь разрешение «Вход как пакетная задача». Поскольку это требует входа в систему, необходимы свойства user и password.
Новое в Chef Client 13.3
environment-
Тип Ruby: Hash
Хэш переменных среды в формате
({'ENV_VARIABLE' => 'VALUE'}). Примечание: Эти переменные должны существовать для успешного выполнения команды.
group-
Тип Ruby: String, Integer
Имя группы или идентификатор группы, которые необходимо изменить перед выполнением команды.
input-
Тип Ruby: String
Необязательное свойство для установки входных данных, отправляемых в команду, в качестве STDIN.
Новое в Chef Infra Client 16.2
live_stream-
Тип Ruby: true, false | Значение по умолчанию:
falseОтправить вывод команды, выполняемой этим блоком ресурсов execute, в поток событий клиента Chef Infra.
password-
Тип Ruby: String
Только для Windows: Пароль пользователя, указанного свойством user. Это свойство является обязательным, если указан user в Windows, и может быть указано только в том случае, если указан user. Свойство sensitive для этого ресурса будет автоматически установлено в true, если указан password.
Новое в Chef Client 12.21
returns-
Тип Ruby: Integer, Array | Значение по умолчанию:
0Возвращаемое значение для команды. Это может быть массив допустимых значений. Исключение возникает, когда возвращаемые значения не совпадают.
sensitive-
Тип Ruby: true, false | Значение по умолчанию:
True if the password property is set. False otherwise.Обеспечьте, чтобы конфиденциальные данные ресурса не регистрировались клиентом Chef Infra.
timeout-
Тип Ruby: Integer, String, Float | Значение по умолчанию:
3600Время (в секундах), которое команда должна ждать, прежде чем истечет время ожидания.
umask-
Тип Ruby: String, Integer
Маска создания режима файла или umask.
user-
Тип Ruby: String, Integer
Имя пользователя учетной записи пользователя, под которой должен быть запущен новый процесс. Имя пользователя может быть указано с доменом, например, domainuser или user@my.dns.domain.com в формате универсального имени участника (UPN). Его также можно указать без домена, просто как user, если домен вместо этого указан с помощью свойства domain. Только в Windows, если указано это свойство, должно быть указано свойство password.
Общие функции ресурса
Ресурсы Chef включают общие свойства, уведомления и средства защиты ресурсов.
Общие свойства
Следующие свойства являются общими для каждого ресурса:
compile_time-
Тип Ruby: true, false | Значение по умолчанию:
falseУправляйте фазой, во время которой ресурс запускается на узле. Установите значение true, чтобы запустить во время построения коллекции ресурсов (
compile phase). Установите значение false, чтобы запустить во время настройки узла клиентом Chef Infra (converge phase). ignore_failure-
Тип Ruby: true, false, :quiet | Значение по умолчанию:
falseПродолжайте выполнение рецепта, если ресурс завершится неудачей по какой-либо причине.
:quietне будет отображать полный трассировку стека, и рецепт будет продолжать выполняться, если ресурс завершится неудачей. retries-
Тип Ruby: Integer | Значение по умолчанию:
0Количество попыток перехвата исключений и повтора попытки ресурса.
retry_delay-
Тип Ruby: Integer | Значение по умолчанию:
2Задержка повтора (в секундах).
sensitive-
Тип Ruby: true, false | Значение по умолчанию:
falseОбеспечьте, чтобы конфиденциальные данные ресурса не регистрировались клиентом Chef InfraClient.
Уведомления
notifies-
Тип Ruby: Symbol, 'Chef::Resource[String]'
Ресурс может уведомить другой ресурс о необходимости принять меры при изменении его состояния. Укажите
'resource[name]',:action, которые должен предпринять этот ресурс, а затем:timerдля этого действия. Ресурс может уведомлять более чем один ресурс; используйте операторnotifiesдля каждого ресурса, который должен быть уведомлен.Если указанный ресурс не существует, возникает ошибка. В отличие от этого,
subscribesне завершится ошибкой, если исходный ресурс не найден.
Таймер указывает момент во время выполнения клиента Chef Infra, в который выполняется уведомление. Доступны следующие таймеры:
:beforeУказывает, что действие в уведомленном ресурсе должно быть выполнено до обработки блока ресурсов, в котором находится уведомление.
:delayedПо умолчанию. Указывает, что уведомление должно быть помещено в очередь, а затем выполнено в конце выполнения клиента Chef Infra.
-
:immediate,:immediately Указывает, что уведомление должно быть выполнено немедленно для каждого уведомленного ресурса.
Синтаксис для notifies:
notifies :action, 'resource[name]', :timer
subscribesТип Ruby: Symbol, 'Chef::Resource[String]'
Ресурс может отслеживать другой ресурс и затем принять действие, если состояние отслеживаемого ресурса изменится. Укажите 'resource[name]', действие :action, и затем :timer для этого действия.
Обратите внимание, что subscribes не применяет указанное действие к ресурсу, за которым он следит — например:
file '/etc/nginx/ssl/example.crt' do
mode '0600'
owner 'root'
end
service 'nginx' do
subscribes :reload, 'file[/etc/nginx/ssl/example.crt]', :immediately
end
В этом случае свойство subscribes перезагружает службу nginx всякий раз, когда файл сертификата, расположенный по адресу /etc/nginx/ssl/example.crt, обновляется. subscribes не вносит никаких изменений в сам файл сертификата, а лишь отслеживает изменения в файле и выполняет действие :reload для своего ресурса (в данном примере nginx) при обнаружении изменения.
Если другого ресурса не существует, подписка не выдаст ошибку. Это отличается от более строгой семантики notifies, которая выдаст ошибку, если другого ресурса не существует.
Таймер определяет момент во время выполнения Chef Infra Client, когда выполняется уведомление. Доступны следующие таймеры:
:beforeУказывает, что действие над уведомлённым ресурсом должно выполняться до обработки блока ресурса, в котором находится уведомление.
:delayedПо умолчанию. Указывает, что уведомление должно помещаться в очередь и затем выполняться в конце выполнения Chef Infra Client.
-
:immediate,:immediately Указывает, что уведомление должно выполняться немедленно, для каждого уведомлённого ресурса.
Синтаксис для subscribes:
subscribes :action, 'resource[name]', :timer
Фильтры
Свойство фильтра может использоваться для оценки состояния узла во время фазы выполнения Chef Infra Client. На основе результатов этой оценки свойство фильтра затем сообщает Chef Infra Client, должен ли он продолжить выполнение ресурса. Свойство фильтра принимает либо строковое значение, либо значение блока Ruby:
- Строка выполняется как команда оболочки. Если команда возвращает
0, фильтр применяется. Если команда возвращает любое другое значение, то свойство фильтра не применяется. Строковые фильтры в powershell_script выполняют команды Windows PowerShell и могут возвращатьtrueпомимо0. - Блок выполняется как код Ruby, который должен вернуть либо
true, либоfalse. Если блок возвращаетtrue, свойство фильтра применяется. Если блок возвращаетfalse, свойство фильтра не применяется.
Свойство фильтра полезно для обеспечения идемпотентности ресурса, позволяя этому ресурсу проверять желаемое состояние по мере его выполнения, а затем, если желаемое состояние присутствует, Chef Infra Client ничего не делает.
СвойстваСледующие свойства могут использоваться для определения фильтра, который оценивается во время фазы выполнения Chef Infra Client:
not_ifЗапрещает выполнение ресурса, когда условие возвращает
true.only_ifРазрешает выполнение ресурса только если условие возвращает
true.
Примеры
В следующих примерах демонстрируются различные подходы к использованию ресурса execute в рецептах:
Выполнение команды при уведомлении:
execute 'slapadd' do
command 'slapadd < /tmp/something.ldif'
creates '/var/lib/slapd/uid.bdb'
action :nothing
end
template '/tmp/something.ldif' do
source 'something.ldif'
notifies :run, 'execute[slapadd]', :immediately
end
Выполнение команды touch файла только один раз во время выполнения команды:
execute 'upgrade script' do
command 'php upgrade-application.php && touch /var/application/.upgraded'
creates '/var/application/.upgraded'
action :run
end
Выполнение команды, требующей переменной окружения:
execute 'slapadd' do
command 'slapadd < /tmp/something.ldif'
creates '/var/lib/slapd/uid.bdb'
action :run
environment ({'HOME' => '/home/my_home'})
end
Удаление репозитория с помощью yum для очистки кэша:
# the following code sample thanks to gaffneyc @ https://gist.github.com/918711
execute 'clean-yum-cache' do
command 'yum clean all'
action :nothing
end
file '/etc/yum.repos.d/bad.repo' do
action :delete
notifies :run, 'execute[clean-yum-cache]', :immediately
end
Предотвращение перезапуска и переконфигурации, если конфигурация повреждена:
Используйте действие :nothing (общее для всех ресурсов) для предотвращения автоматического запуска теста, а затем уведомление subscribes для запуска теста конфигурации при обнаружении изменений в шаблоне.
execute 'test-nagios-config' do
command 'nagios3 --verify-config'
action :nothing
subscribes :run, 'template[/etc/nagios3/configures-nagios.conf]', :immediately
end
Уведомление в определённом порядке:
Чтобы уведомить несколько ресурсов и затем выполнить эти ресурсы в определённом порядке, сделайте следующее.
execute 'foo' do
command '...'
notifies :create, 'template[baz]', :immediately
notifies :install, 'package[bar]', :immediately
notifies :run, 'execute[final]', :immediately
end
template 'baz' do
#...
notifies :run, 'execute[restart_baz]', :immediately
end
package 'bar'
execute 'restart_baz'
execute 'final' do
command '...'
end
где последовательность будет в том же порядке, что и ресурсы в рецепте: execute 'foo', template 'baz', execute [restart_baz], package 'bar', и execute 'final'.
Выполнение команды с помощью шаблона:
Следующий пример показывает, как настроить IPv4-маршрутизацию с помощью ресурса execute для выполнения команды с именем forward_ipv4, которая использует шаблон, определённый ресурсом template.
execute 'forward_ipv4' do
command 'echo > /proc/.../ipv4/ip_forward'
action :nothing
end
template '/etc/file_name.conf' do
source 'routing/file_name.conf.erb'
notifies :run, 'execute[forward_ipv4]', :delayed
end
где свойство command для ресурса execute содержит команду для выполнения, а свойство source для ресурса template указывает, какой шаблон использовать. Свойство notifies для template указывает, что execute[forward_ipv4] (которое определено ресурсом execute) должно быть помещено в очередь и выполнено в конце выполнения Chef Infra Client.
Добавление правила в таблицу IP:
Следующий пример показывает, как добавить правило с именем test_rule в таблицу IP с помощью ресурса execute для выполнения команды с помощью шаблона, определённого ресурсом template:
execute 'test_rule' do
command "command_to_run
--option value
--option value
--source #{node[:name_of_node][:ipsec][:local][:subnet]} -j test_rule"
action :nothing
end
template '/etc/file_name.local' do
source 'routing/file_name.local.erb'
notifies :run, 'execute[test_rule]', :delayed
end
где свойство command для ресурса execute содержит команду для выполнения, а свойство source для ресурса template указывает, какой шаблон использовать. Свойство notifies для template указывает, что execute[test_rule] (которое определено ресурсом execute) должно быть помещено в очередь и выполнено в конце выполнения Chef Infra Client.
Остановка службы, выполнение действий и последующий перезапуск:
Следующий пример показывает, как использовать ресурсы execute, service и mount вместе, чтобы убедиться, что узел, работающий на Amazon EC2, запускает MySQL. Этот пример выполняет следующее:
- Проверка наличия MySQL на узле Amazon EC2
- Если узел имеет MySQL, остановка MySQL
- Установка MySQL
- Монтирование узла
- Перезапуск MySQL
# the following code sample comes from the ``server_ec2``
# recipe in the following cookbook:
# https://github.com/chef-cookbooks/mysql
if (node.attribute?('ec2') && !FileTest.directory?(node['mysql']['ec2_path']))
service 'mysql' do
action :stop
end
execute 'install-mysql' do
command "mv #{node['mysql']['data_dir']}#{node['mysql']['ec2_path']}"
not_if { ::File.directory?(node['mysql']['ec2_path']) }
end
[node['mysql']['ec2_path'], node['mysql']['data_dir']].each do |dir|
directory dir do
owner 'mysql'
group 'mysql'
end
end
mount node['mysql']['data_dir'] do
device node['mysql']['ec2_path']
fstype 'none'
options 'bind,rw'
action [:mount, :enable]
end
service 'mysql' do
action :start
end
end
где
- два ресурса service используются для остановки и затем перезапуска службы MySQL
- ресурс execute используется для установки MySQL
- ресурс mount используется для монтирования узла и включения MySQL
Использование метода platform_family?:
Следующий пример демонстрирует использование метода platform_family? в DSL рецепта для создания переменной, которая может использоваться с другими ресурсами в том же рецепте. В этом примере platform_family? используется для обеспечения использования определённой двоичной программы для определённой платформы перед использованием ресурса remote_file для загрузки файла из удалённого расположения и затем использованием ресурса execute для установки этого файла путём выполнения команды.
if platform_family?('rhel')
pip_binary = '/usr/bin/pip'
else
pip_binary = '/usr/local/bin/pip'
end
remote_file "#{Chef::Config[:file_cache_path]}/distribute_setup.py" do
source 'http://python-distribute.org/distribute_setup.py'
mode '0755'
not_if { ::File.exist?(pip_binary) }
end
execute 'install-pip' do
cwd Chef::Config[:file_cache_path]
command <<~EOF
# command for installing Python goes here
EOF
not_if { ::File.exist?(pip_binary) }
end
где команда для установки Python может выглядеть примерно так:
#{node['python']['binary']} distribute_setup.py #{::File.dirname(pip_binary)}/easy_install pip
Управление службой с помощью ресурса execute:
Предупреждение
Сделайте так:
service 'tomcat' do
action :start
end
а не так:
execute 'start-tomcat' do
command '/etc/init.d/tomcat start'
action :run
end
Нет необходимости использовать ресурс execute для управления службой, так как ресурс service напрямую предоставляет свойство start_command, которое даёт рецепту полный контроль над выдаваемой командой более чистым и прямым способом.
Использование метода search Recipe DSL для поиска пользователей:
Следующий пример показывает, как использовать метод search в DSL рецепта для поиска пользователей:
# the following code sample comes from the openvpn cookbook:
search("users", "*:*") do |u|
execute "generate-openvpn-#{u['id']}" do
command "./pkitool #{u['id']}"
cwd '/etc/openvpn/easy-rsa'
end
%w{ conf ovpn }.each do |ext|
template "#{node['openvpn']['key_dir']}/#{u['id']}.#{ext}" do
source 'client.conf.erb'
variables :username => u['id']
end
end
end
где
- данные поиска будут использованы для создания ресурсов execute
- ресурс template сообщает Chef Infra Client, какой шаблон использовать
Включение удалённого входа для macOS:
execute 'enable ssh' do
command '/usr/sbin/systemsetup -setremotelogin on'
not_if '/usr/sbin/systemsetup -getremotelogin | /usr/bin/grep On'
action :run
end
Выполнение кода немедленно, основываясь на ресурсе template:
По умолчанию уведомления :delayed, то есть они помещаются в очередь по мере возникновения, а затем выполняются в самом конце выполнения Chef Infra Client. Чтобы запустить действие кан немедленно, используйте :immediately:
template '/etc/nagios3/configures-nagios.conf' do
# other parameters
notifies :run, 'execute[test-nagios-config]', :immediately
end
и затем Chef Infra Client немедленно выполнит следующее:
execute 'test-nagios-config' do
command 'nagios3 --verify-config'
action :nothing
end
Подключение файла:
Ресурс execute нельзя использовать для подключения файла (например, command 'source filename'). Следующий пример завершится ошибкой, так как source не является исполняемым файлом:
execute 'foo' do
command 'source /tmp/foo.sh'
end
Вместо этого используйте ресурс script или один из ресурсов на основе script (bash, csh, perl, python или ruby). Например:
bash 'foo' do
code 'source /tmp/foo.sh'
end
Выполнение команды Knife:
execute 'create_user' do
command <<~EOM
knife user create #{user}
--admin
--password password
--disable-editing
--file /home/vagrant/.chef/user.pem
--config /tmp/knife-admin.rb
EOM
end
Выполнение команды установки в виртуальную среду:
Следующий пример показывает, как установить лёгкий JavaScript-фреймворк в Vagrant:
execute "install q and zombiejs" do
cwd "/home/vagrant"
user "vagrant"
environment ({'HOME' => '/home/vagrant', 'USER' => 'vagrant'})
command "npm install -g q zombie should mocha coffee-script"
action :run
end
Выполнение команды от имени пользователя:
Следующий пример показывает, как выполнить bundle install из выполнения Chef Infra Client как конкретного пользователя. Это поместит gem в путь пользователя (vagrant) вместо root-пользователя (от имени которого работает Chef Infra Client):
execute '/opt/chefdk/embedded/bin/bundle install' do
cwd node['chef_workstation']['bundler_path']
user node['chef_workstation']['user']
environment ({
'HOME' => "/home/#{node['chef_workstation']['user']}",
'USER' => node['chef_workstation']['user']
})
not_if 'bundle check'
end
Выполнение команды от имени другого пользователя:
Примечание: Когда Chef работает как служба, эта функция требует, чтобы пользователь, от имени которого работает Chef, обладал правом «SeAssignPrimaryTokenPrivilege» (также известным как «SE_ASSIGNPRIMARYTOKEN_NAME»). По умолчанию этим правом обладают только LocalSystem и NetworkService при работе в качестве службы. Это необходимо даже в том случае, если пользователь является администратором.
Это право можно добавить и проверить в рецепте, используя этот пример:
# Add 'SeAssignPrimaryTokenPrivilege' for the user
Chef::ReservedNames::Win32::Security.add_account_right('<user>', 'SeAssignPrimaryTokenPrivilege')
# Check if the user has 'SeAssignPrimaryTokenPrivilege' rights
Chef::ReservedNames::Win32::Security.get_account_right('<user>').include?('SeAssignPrimaryTokenPrivilege')
Следующий пример демонстрирует, как запустить mkdir test_dir из клиента Chef Infra, запущенного от имени другого пользователя.
# Passing only username and password
execute 'mkdir test_dir' do
cwd Chef::Config[:file_cache_path]
user "username"
password "password"
end
# Passing username and domain
execute 'mkdir test_dir' do
cwd Chef::Config[:file_cache_path]
domain "domain-name"
user "user"
password "password"
end
# Passing username = 'domain-name\username'. No domain is passed
execute 'mkdir test_dir' do
cwd Chef::Config[:file_cache_path]
user "domain-name\username"
password "password"
end
# Passing username = 'username@domain-name'. No domain is passed
execute 'mkdir test_dir' do
cwd Chef::Config[:file_cache_path]
user "username@domain-name"
password "password"
end
Запуск команды с внешним файлом ввода:
execute ‘md5sum’ do input File.read(FILE) end
© Chef Software, Inc.
Licensed under the Creative Commons Attribution 3.0 Unported License.
The Chef™ Mark and Chef Logo are either registered trademarks/service marks or trademarks/servicemarks of Chef, in the United States and other countries and are used with Chef Inc's permission.
We are not affiliated with, endorsed or sponsored by Chef Inc.
https://docs.chef.io/resources/execute/