Spec-Zone.ru › Chef 17

Ресурс сценария

Эта страница сгенерирована из исходного кода Chef Infra Client. Чтобы предложить изменение, отредактируйте файл script.rb и отправьте запрос на вытягивание в репозиторий Chef Infra Client.

Все страницы ресурсов Infra


Используйте ресурс script для выполнения скриптов с помощью указанного интерпретатора, такого как Bash, csh, Perl, Python или Ruby. Этот ресурс также может использовать любые действия и свойства, доступные ресурсу execute. Команды, выполняемые с помощью этого ресурса, по своей природе не идемпотентны, поскольку они обычно уникальны для среды, в которой они выполняются. Используйте not_if и only_if для защиты этого ресурса от идемпотентности.

Этот ресурс является базовым ресурсом для нескольких других ресурсов, используемых для скриптинга на конкретных платформах. Дополнительную информацию о конкретных ресурсах для конкретных платформ см. в следующих разделах:

  • bash
  • csh
  • ksh
  • perl
  • python
  • ruby

Изменено в 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/

Spec-Zone.ru

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