Подтвердить что ты не робот

СУХОЙ в рецепте шеф-повара

Какой лучший способ сделать немного СУХОЙ в рецепте шеф-повара? То есть просто вырвайте маленькие кусочки кода Ruby, поэтому я не копирую их снова и снова.

Ниже, конечно, не удается:

NoMethodError: undefined method `connect_root' for Chef::Resource::RubyBlock

У меня может быть несколько ruby_blocks в одном рецепте, так как они делают разные вещи и нуждаются в том, чтобы разные блоки not_if были истинными идемпотентными.

def connect_root(root_password)
  m = Mysql.new("localhost", "root", root_password)
  begin
    yield m
  ensure
    m.close
  end
end

ruby_block "set readonly" do
  block do
    connect_root node[:mysql][:server_root_password] do |connection|
      command = 'SET GLOBAL read_only = ON'
      Chef::Log.info "#{command}"
      connection.query(command)
    end
  end
  not_if do
    ro = nil
    connect_root node[:mysql][:server_root_password] do |connection|
      connection.query("SELECT @@read_only as ro") {|r| r.each_hash {|h| 
        ro = h['ro']
      } }
    end
    ro
  end
end
4b9b3361

Ответ 1

Как вы уже выяснили, вы не можете определять функции в рецептах. Для этого предоставляются библиотеки. Вы должны создать файл (например, mysql_helper.rb) внутри папки libraries в своей кулинарной книге со следующим:

module MysqlHelper
  def self.connect_root( root_password )
    m = Mysql.new("localhost", "root", root_password)
    begin
      yield m
    ensure
      m.close
    end
  end
end

Он должен быть модулем, а не классом. Обратите внимание, что мы также определяем его как static (используя self.method_name). Затем вы сможете использовать функции, определенные в этом модуле, в своих рецептах, используя имя модуля с именем метода:

MysqlHelper.connect_root node[:mysql][:server_root_password] do |connection|
  [...]
end

Ответ 2

Для записи я просто создал библиотеку со следующим. Но это кажется излишним для DRY в одном файле. Я также не мог понять, как получить другое пространство имен для использования модуля, чтобы работать.

class Chef
  class Resource
    def connect_root(root_password)
      ...