Ресурс script
Эта страница сгенерирована из исходного кода Chef Chef source code. Чтобы предложить изменение, отредактируйте файл script.rb и отправьте запрос на включение изменений в репозиторий Chef repository.
Используйте ресурс 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, если свойство password указано.
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 InfraClient.
Уведомления
notifies-
Тип Ruby: Символ, 'Chef::Resource[Строка]'
Ресурс может уведомлять другой ресурс о действии при изменении его состояния. Укажите
'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[Строка]'
Ресурс может слушать другой ресурс и выполнять действия, если состояние прослушиваемого ресурса изменится. Укажите '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/