Spec-Zone.ru › Chef 18

Ресурс 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, если указан password.

Новое в 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

Выполнение команды 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** для управления службой, а не ресурс **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 Infra Language для поиска пользователей:

Следующий пример демонстрирует использование метода search в Chef Infra Language для поиска пользователей:

#  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(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/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API