ruby - videos - recetas de los mejores chefs
SECO dentro de una receta de Chef (2)
¿Cuál es la mejor manera de hacer un poco SECO dentro de una receta de chef? Es decir, solo explico pequeños fragmentos del código Ruby, así que no voy a copiarlo y pegarlo una y otra vez.
Lo siguiente falla, por supuesto, con:
NoMethodError: undefined method `connect_root'' for Chef::Resource::RubyBlock
Es posible que tenga varios ruby_blocks en una receta, ya que hacen cosas diferentes y necesitan tener diferentes bloques not_if para ser realmente idempotentes.
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
Como ya descubrió, no puede definir funciones en las recetas. Para eso se proporcionan bibliotecas. Debe crear un archivo (por ejemplo, mysql_helper.rb ) dentro de la carpeta de bibliotecas en su libro de recetas con lo siguiente:
module MysqlHelper
def self.connect_root( root_password )
m = Mysql.new("localhost", "root", root_password)
begin
yield m
ensure
m.close
end
end
end
Debe ser un módulo, no una clase. Note que también lo definimos como estático (usando self.method_name). Entonces podrá usar las funciones definidas en este módulo en sus recetas usando el nombre del módulo con el nombre del método:
MysqlHelper.connect_root node[:mysql][:server_root_password] do |connection|
[...]
end
Para el registro, acabo de crear una biblioteca con lo siguiente. Pero eso parece excesivo para DRY dentro de un archivo. Tampoco pude averiguar cómo obtener otro espacio de nombres para que el módulo lo use, para que funcione.
class Chef
class Resource
def connect_root(root_password)
...