Ресурс execute
Эта страница создана на основе исходного кода Chef Infra Client. Чтобы предложить изменения, отредактируйте файл execute.rb и отправьте запрос на внесение изменений в репозиторий Chef Infra Client.
Страница со всеми ресурсами Infra
Используйте ресурс 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
login true, false # default value: false
password String
returns Integer, Array # default value: 0
timeout Integer, String, Float # default value: 3600
user String, Integer
action Symbol # defaults to :run if not specified
endгде:
-
execute— это ресурс. -
name— это имя, присвоенное блоку ресурсов. -
actionопределяет, какие шаги предпримет Chef Infra Client для приведения узла в желаемое состояние. -
command,creates,cwd,default_env,domain,elevated,environment,group,input,live_stream,login,password,returns,timeout, иuser— это свойства, доступные этому ресурсу.
Действия
Ресурс execute имеет следующие действия:
:nothing- Этот блок ресурсов не выполняет никаких действий, если не получит уведомление от другого ресурса о необходимости действий. После получения уведомления этот блок ресурсов либо выполняется немедленно, либо помещается в очередь для выполнения в конце работы Chef Infra Client.
:run- Выполнить команду. (по умолчанию)
Свойства
Ресурс execute имеет следующие свойства:
-
command - Тип Ruby: String, Array | Значение по умолчанию:
The resource block's 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 Client, или, если эта система не подключена к домену, он разрешит пользователя как локальную учетную запись на этой системе. Альтернативный способ указать домен — не указывать это свойство и указать домен как часть свойства 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 Client.
-
login - Тип Ruby: true, false | Значение по умолчанию:
falseИспользовать интерактивную оболочку для запуска команд вместо наследования существующей среды выполнения.
Новое в Chef Infra Client 17.0
-
password - Тип Ruby: String
Только для Windows: Пароль пользователя, указанный свойством user. Это свойство является обязательным, если свойство user указано в Windows, и может быть указано только в том случае, если указано свойство user. Свойство sensitive для этого ресурса будет автоматически установлено в true, если указан пароль.
Новое в Chef Client 12.21
-
returns - Тип Ruby: Integer, Array | Значение по умолчанию:
0Возвращаемое значение для команды. Это может быть массив допустимых значений. Исключение возникает, когда возвращаемые значения не совпадают.
-
timeout - Тип Ruby: Integer, String, Float | Значение по умолчанию:
3600Время ожидания команды (в секундах) до истечения времени ожидания.
-
user - Тип Ruby: String, Integer
Имя пользователя, от имени которого будет запущен новый процесс. Имя пользователя может быть дополнительно указано с доменом, например
domain\userилиuser@my.dns.domain.comв формате универсального имени участника (UPN). Его также можно указать без домена, просто как user, если домен указан с помощью свойства domain. Только в Windows, если указано это свойство, необходимо указать свойство password.
Общие функции ресурса
Ресурсы Chef включают общие свойства, уведомления и средства защиты ресурсов.
Общие свойства
Следующие свойства являются общими для всех ресурсов:
compile_time-
Тип Ruby: true, false | Значение по умолчанию:
falseУправление фазой, во время которой ресурс запускается на узле. Установите значение true для запуска во время построения коллекции ресурсов (
compile phase). Установите значение false для запуска во время настройки узла Chef Infra Client (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 Infra Client.
Уведомления
-
notifies -
Тип Ruby: Symbol, 'Chef::Resource[String]'
Ресурс может уведомить другой ресурс о необходимости действий при изменении его состояния. Укажите
'resource[name]',:action, которое должен выполнить этот ресурс, а затем:timerдля этого действия. Ресурс может уведомить более одного ресурса; используйте операторnotifiesдля каждого ресурса, который нужно уведомить.Если указанный ресурс не существует, возникает ошибка. В отличие от этого,
subscribesне завершится неудачей, если исходный ресурс не найден.
Таймер указывает момент во время выполнения Chef Infra Client, когда выполняется уведомление. Доступны следующие таймеры:
:before-
Указывает, что действие в уведомленном ресурсе должно быть выполнено до обработки блока ресурсов, в котором находится уведомление.
:delayed-
По умолчанию. Указывает, что уведомление должно быть помещено в очередь, а затем выполнено в конце выполнения Chef Infra Client.
-
: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
Запись файла только один раз во время выполнения команды:
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 вместе для обеспечения работы MySQL на узле, работающем на Amazon EC2. В этом примере выполняется следующее:
- Проверяется наличие 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 напрямую, что дает рецепту полный контроль над выпущенной командой гораздо более чистым и прямым способом.
Использование помощника по поиску языка Infra для поиска пользователей:
Следующий пример демонстрирует, как использовать метод search в языке Chef Infra для поиска пользователей:
# 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
Выполнение кода немедленно, на основе ресурса шаблона:
По умолчанию уведомления :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 Client в качестве альтернативного пользователя.
# 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(Файл) 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/