Frage TROCKEN in einem Chefrezept


Was ist der beste Weg, ein wenig TROCKEN in einem Kochrezept zu machen? I.e. machen Sie nur kleine Teile des Ruby-Codes aus, also kopiere ich sie nicht immer wieder.

Folgendes scheitert natürlich mit:

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

Ich kann mehrere ruby_blocks in einem Rezept haben, da sie verschiedene Dinge machen und verschiedene not_if-Blöcke haben müssen, um truley idempotent zu sein.

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

17
2018-03-24 04:25


Ursprung


Antworten:


Wie Sie bereits herausgefunden haben, können Sie Funktionen in Rezepten nicht definieren. Dafür werden Bibliotheken bereitgestellt. Sie sollten eine Datei erstellen (z. mysql_helper.rb ) Innerhalb Bibliotheken Ordner in Ihrem Kochbuch mit den folgenden:

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

Es Muss Sei ein Modul, keine Klasse. Beachten Sie, dass wir es auch als statisch definieren (mit self.method_name). Dann können Sie die in diesem Modul definierten Funktionen in Ihren Rezepten verwenden, indem Sie den Modulnamen mit dem Methodennamen verwenden:

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

23
2018-03-27 20:38



Für das Protokoll habe ich gerade eine Bibliothek mit folgendem erstellt. Aber das scheint für DRY in einer Datei übertrieben zu sein. Ich konnte auch nicht herausfinden, wie man einen anderen Namensraum für das Modul benutzt, um zu arbeiten.

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

1
2018-03-24 05:02