Ресурс сценария
Эта страница сгенерирована из исходного кода Chef Infra Client. Чтобы предложить изменение, отредактируйте файл script.rb и отправьте запрос на вытягивание в репозиторий Chef Infra Client.
Используйте ресурс script для выполнения скриптов с помощью указанного интерпретатора, такого как Bash, csh, Perl, Python или Ruby. Этот ресурс также может использовать любые действия и свойства, доступные ресурсу execute. Команды, выполняемые с помощью этого ресурса, по своей природе не идемпотентны, поскольку они обычно уникальны для среды, в которой они выполняются. Используйте not_if и only_if для защиты этого ресурса от идемпотентности.
Этот ресурс является базовым ресурсом для нескольких других ресурсов, используемых для скриптинга на конкретных платформах. Дополнительную информацию о конкретных ресурсах для конкретных платформ см. в следующих разделах:
Изменено в 12.19 для поддержки альтернативной учетной записи пользователя Windows в ресурсах execute
Синтаксис
Блок ресурса script обычно выполняет скрипты с помощью указанного интерпретатора, например Bash, csh, Perl, Python или Ruby:
script 'extract_module' do
interpreter "bash"
cwd ::File.dirname(src_filepath)
code <<-EOH
mkdir -p #{extract_path}
tar xzf #{src_filename} -C #{extract_path}
mv #{extract_path}/*/* #{extract_path}/
EOH
not_if { ::File.exist?(extract_path) }
end
где:
-
interpreterуказывает оболочку команд для использования -
cwdуказывает каталог, из которого выполняется команда -
codeуказывает команду для выполненияЧаще всего используется ресурс script, специфичный для оболочки команд. Chef имеет ресурсы, специфичные для оболочек, для Bash, csh, ksh, Perl, Python и Ruby.
Та же команда, но выполняемая с помощью ресурса bash:
bash 'extract_module' do cwd ::File.dirname(src_filepath) code <<-EOH mkdir -p #{extract_path} tar xzf #{src_filename} -C #{extract_path} mv #{extract_path}/*/* #{extract_path}/ EOH not_if { ::File.exist?(extract_path) } end
Полный синтаксис всех свойств, доступных для ресурса script:
script 'name' do
code String
creates String
cwd String
environment Hash
flags String
group String, Integer
interpreter String
path Array
returns Integer, Array
timeout Integer, Float
user String
password String
domain String
umask String, Integer
action Symbol # defaults to :run if not specified
endгде:
-
script- это ресурс -
name- имя блока ресурса -
cwd- местоположение, из которого выполняется команда -
actionопределяет действия, которые Chef Infra Client предпримет для приведения узла в желаемое состояние -
code,creates,cwd,environment,flags,group,interpreter,path,returns,timeout,user,password,domainиumask— свойства этого ресурса со значением типа Ruby. См. раздел «Свойства» ниже для получения дополнительной информации обо всех свойствах, которые могут использоваться с этим ресурсом.
Действия
Ресурс script имеет следующие действия:
:nothing- Запретить выполнение команды. Это действие используется для указания того, что команда выполняется только при уведомлении о выполнении другого ресурса.
:run- По умолчанию. Выполнить скрипт.
Свойства
Ресурс script имеет следующие свойства:
-
code - Тип Ruby: Строка
Строка кода ("“) для выполнения.
-
creates - Тип Ruby: Строка
Предотвратить создание файла командой, если этот файл уже существует.
-
cwd - Тип Ruby: Строка
Текущий рабочий каталог, из которого будет выполняться команда.
-
environment - Тип Ruby: Хэш
Хэш переменных среды в формате
({"ENV_VARIABLE" => "VALUE"}). (Эти переменные должны существовать для успешного выполнения команды.)
-
flags - Тип Ruby: Строка
Один или несколько флагов командной строки, передаваемых интерпретатору при вызове команды.
-
group - Тип Ruby: Строка, целое число
Имя группы или идентификатор группы, который необходимо изменить перед выполнением команды.
-
interpreter - Тип Ruby: Строка
Интерпретатор скриптов для использования во время выполнения кода.
-
returns - Тип Ruby: Целое число, массив | Значение по умолчанию:
0Значение возврата команды. Это может быть массив допустимых значений. При несовпадении возвращаемого значения(й) возникает исключение.
-
timeout - Тип Ruby: Целое число, число с плавающей запятой | Значение по умолчанию:
3600Время (в секундах) ожидания команды перед истечением времени.
-
user - Тип Ruby: Строка
Имя пользователя учетной записи пользователя, с которой запустить новый процесс. Значение по умолчанию: nil. Имя пользователя может быть необязательно указано с доменом, например domainuser или user@my.dns.domain.com в формате Universal Principal Name (UPN). Также его можно указать без домена, просто как user, если вместо этого домен указан с помощью атрибута domain. Только в Windows, если это свойство указано, должно быть указано свойство password.
-
password - Тип Ruby: Строка
Только Windows: Пароль пользователя, указанного свойством user. Значение по умолчанию: nil. Это свойство обязательно, если user указан в Windows и может быть указано только при указании user. Свойство sensitive для этого ресурса автоматически будет установлено в значение true, если указан пароль.
-
domain - Тип Ruby: Строка
Только Windows: Домен пользователя, указанного свойством user. Значение по умолчанию: nil. Если не указано, имя пользователя и пароль, указанные свойствами user и password, будут использованы для поиска этого пользователя в домене, к которому присоединена система, на которой выполняется Chef-клиент, или, если эта система не присоединена к домену, она будет искать пользователя как локальную учетную запись на этой системе. Альтернативный способ указания домена - оставить это свойство неопределенным и указать домен в свойстве user.
-
umask - Тип Ruby: Строка, целое число
Маска создания режима файла или umask.
Общие функциональные возможности ресурсов
Ресурсы 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: Целое число | Значение по умолчанию:
0Количество попыток перехвата исключений и повторной попытки ресурса.
retry_delay-
Тип Ruby: Целое число | Значение по умолчанию:
2Задержка в секундах между попытками повтора.
sensitive-
Тип Ruby: true, false | Значение по умолчанию:
falseУбедитесь, что конфиденциальные данные ресурса не регистрируются Chef Infra Client.
Уведомления
-
notifies -
Тип Ruby: Символ, '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: Символ, '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.
Интерпретатор фильтра
Любой ресурс, который проходит строковую команду, может также указать интерпретатор, который будет использоваться для оценки этой строковой команды. Это делается с помощью свойства guard_interpreter для указания ресурса на основе скрипта.
Свойство guard_interpreter может быть установлено в любое из следующих значений:
:bash-
Вычисляет строковую команду с использованием ресурса bash.
:batch-
Вычисляет строковую команду с использованием ресурса batch. Значение по умолчанию (внутри блока ресурса batch):
:batch. :csh-
Вычисляет строковую команду с использованием ресурса csh.
:default-
По умолчанию. Выполняет интерпретатор по умолчанию, как определено в Chef Infra Client.
:perl-
Вычисляет строковую команду с использованием ресурса perl.
:powershell_script-
Вычисляет строковую команду с использованием ресурса powershell_script. Значение по умолчанию (внутри блока ресурса powershell_script):
:powershell_script. :python-
Вычисляет строковую команду с использованием ресурса python.
:ruby-
Вычисляет строковую команду с использованием ресурса ruby.
Свойство guard_interpreter по умолчанию установлено в :default для ресурсов bash, csh, perl, python и ruby. Когда свойство guard_interpreter установлено в :default, not_if или only_if операторы фильтра не наследуют свойства, определенные ресурсом на основе скрипта.
Предупреждение
Ресурсы batch и powershell_script наследуют свойства по умолчанию. Свойство guard_interpreter автоматически установлено в :batch или :powershell_script при использовании оператора фильтра not_if или only_if соответственно внутри ресурса batch или powershell_script.
Например, оператор фильтра not_if в следующем примере ресурса не наследует свойство environment:
bash 'javatooling' do
environment 'JAVA_HOME' => '/usr/lib/java/jdk1.7/home'
code 'java-based-daemon-ctl.sh -start'
not_if 'java-based-daemon-ctl.sh -test-started'
end
и требует добавления свойства environment к оператору фильтра not_if для использования пути JAVA_HOME в ходе его оценки:
bash 'javatooling' do
environment 'JAVA_HOME' => '/usr/lib/java/jdk1.7/home'
code 'java-based-daemon-ctl.sh -start'
not_if 'java-based-daemon-ctl.sh -test-started', :environment => 'JAVA_HOME' => '/usr/lib/java/jdk1.7/home'
end
Для наследования свойств добавьте свойство guard_interpreter в блок ресурса и установите его в соответствующее значение:
-
:bashдля bash -
:cshдля csh -
:perlдля perl -
:pythonдля python -
:rubyдля ruby
Например, используя тот же пример, что и выше, но на этот раз добавив свойство guard_interpreter и установив его в значение :bash:
bash 'javatooling' do
guard_interpreter :bash
environment 'JAVA_HOME' => '/usr/lib/java/jdk1.7/home'
code 'java-based-daemon-ctl.sh -start'
not_if 'java-based-daemon-ctl.sh -test-started'
end
Оператор not_if теперь наследует свойство environment и будет использовать путь JAVA_HOME в ходе своей оценки.
Например, следующий блок кода гарантирует, что команда будет оцениваться с использованием интерпретатора по умолчанию, как определено в Chef Infra Client:
resource 'name' do
guard_interpreter :default
# code
end
Примеры
Следующие примеры демонстрируют различные подходы к использованию ресурса script в рецептах:
Использование именованного поставщика для запуска скрипта
bash 'install_something' do
user 'root'
cwd '/tmp'
code <<-EOH
wget http://www.example.com/tarball.tar.gz
tar -zxf tarball.tar.gz
cd tarball
./configure
make
make install
EOH
end
Запуск скрипта
script 'install_something' do
interpreter 'bash'
user 'root'
cwd '/tmp'
code <<-EOH
wget http://www.example.com/tarball.tar.gz
tar -zxf tarball.tar.gz
cd tarball
./configure
make
make install
EOH
end
или что-то вроде:
bash 'openvpn-server-key' do
environment('KEY_CN' => 'server')
code <<-EOF
openssl req -batch -days #{node['openvpn']['key']['expire']} \
-nodes -new -newkey rsa:#{key_size} -keyout #{key_dir}/server.key \
-out #{key_dir}/server.csr -extensions server \
-config #{key_dir}/openssl.cnf
EOF
not_if { File.exist?('#{key_dir}/server.crt') }
end
где code содержит команду OpenSSL для запуска. Свойство not_if сообщает Chef Infra Client не запускать команду, если файл уже существует.
Установка файла из удалённого расположения с помощью bash
Следующий пример демонстрирует, как установить модуль foo123 для Nginx. Этот модуль добавляет функциональность в стиле оболочки в файл конфигурации Nginx и выполняет следующие действия:
- Объявляет три переменные
- Получает файл Nginx из удалённого расположения
- Устанавливает файл с помощью Bash по пути, указанному переменной
src_filepath
# the following code sample is similar to the ``upload_progress_module``
# recipe in the ``nginx`` cookbook:
# https://github.com/chef-cookbooks/nginx
src_filename = "foo123-nginx-module-v#{
node['nginx']['foo123']['version']
}.tar.gz"
src_filepath = "#{Chef::Config['file_cache_path']}/#{src_filename}"
extract_path = "#{
Chef::Config['file_cache_path']
}/nginx_foo123_module/#{
node['nginx']['foo123']['checksum']
}"
remote_file 'src_filepath' do
source node['nginx']['foo123']['url']
checksum node['nginx']['foo123']['checksum']
owner 'root'
group 'root'
mode '0755'
end
bash 'extract_module' do
cwd ::File.dirname(src_filepath)
code <<-EOH
mkdir -p #{extract_path}
tar xzf #{src_filename} -C #{extract_path}
mv #{extract_path}/*/* #{extract_path}/
EOH
not_if { ::File.exist?(extract_path) }
end
Установка приложения из git с помощью bash
Следующий пример показывает, как Bash может использоваться для установки плагина для rbenv под названием ruby-build, который находится в системе управления версиями git. Сначала приложение синхронизируется, затем Bash изменяет рабочую директорию на расположение ruby-build и выполняет команду.
git "#{Chef::Config[:file_cache_path]}/ruby-build" do
repository 'git://github.com/sstephenson/ruby-build.git'
revision 'master'
action :sync
end
bash 'install_ruby_build' do
cwd "#{Chef::Config[:file_cache_path]}/ruby-build"
user 'rbenv'
group 'rbenv'
code <<-EOH
./install.sh
EOH
environment 'PREFIX' => '/usr/local'
end
Для получения дополнительной информации о ruby-build, см. здесь: https://github.com/sstephenson/ruby-build.
Хранение определенных настроек
Следующий рецепт показывает, как можно использовать файл атрибутов для хранения определенных настроек. Файл атрибутов расположен в каталоге attributes/ в том же сборнике, что и рецепт, вызывающий файл атрибутов. В данном примере файл атрибутов задаёт определённые настройки для Python, которые затем используются на всех узлах, на которых будет выполняться этот рецепт.
Пакеты Python имеют версии, каталоги установки, URL-адреса и файлы контрольных сумм. Файл атрибутов, предназначенный для поддержки такого рецепта, должен содержать настройки, подобные следующим:
default['python']['version'] = '2.7.1'
if python['install_method'] == 'package'
default['python']['prefix_dir'] = '/usr'
else
default['python']['prefix_dir'] = '/usr/local'
end
default['python']['url'] = 'http://www.python.org/ftp/python'
default['python']['checksum'] = '80e387...85fd61'
а затем методы в рецепте могут ссылаться на эти значения. Рецепту, используемому для установки Python, необходимо выполнить следующие действия:
- Идентифицировать каждый пакет для установки (подразумевается в примере, не показано)
- Определить переменные для пакета
versionиinstall_path - Получить пакет из удалённого расположения, но только если пакет ещё не существует на целевой системе
- Использовать ресурс bash для установки пакета на узел, но только если пакет ещё не установлен
# the following code sample comes from the ``oc-nginx`` cookbook on |github|: https://github.com/cookbooks/oc-nginx
version = node['python']['version']
install_path = "#{node['python']['prefix_dir']}/lib/python#{version.split(/(^\d+\.\d+)/)[1]}"
remote_file "#{Chef::Config[:file_cache_path]}/Python-#{version}.tar.bz2" do
source "#{node['python']['url']}/#{version}/Python-#{version}.tar.bz2"
checksum node['python']['checksum']
mode '0755'
not_if { ::File.exist?(install_path) }
end
bash 'build-and-install-python' do
cwd Chef::Config[:file_cache_path]
code <<-EOF
tar -jxvf Python-#{version}.tar.bz2
(cd Python-#{version} && ./configure #{configure_options})
(cd Python-#{version} && make && make install)
EOF
not_if { ::File.exist?(install_path) }
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
script 'mkdir test_dir' do
interpreter "bash"
code "mkdir test_dir"
cwd Chef::Config[:file_cache_path]
user "username"
password "password"
end
# Passing username and domain
script 'mkdir test_dir' do
interpreter "bash"
code "mkdir test_dir"
cwd Chef::Config[:file_cache_path]
domain "domain-name"
user "username"
password "password"
end
# Passing username = 'domain-name\\username'. No domain is passed
script 'mkdir test_dir' do
interpreter "bash"
code "mkdir test_dir"
cwd Chef::Config[:file_cache_path]
user "domain-name\\username"
password "password"
end
# Passing username = 'username@domain-name'. No domain is passed
script 'mkdir test_dir' do
interpreter "bash"
code "mkdir test_dir"
cwd Chef::Config[:file_cache_path]
user "username@domain-name"
password "password"
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/script/