2013-04-04 7 views
6

Ich bin sehr neu zu Chef und versuche, Templating herauszufinden (was wirklich cool scheint). In meiner alten Bereitstellungsstruktur hatte ich ein Verzeichnis, das ich einfach kopieren wollte. Es hatte eine Reihe von Konfigurationsparametern über die Dateien im Verzeichnis verstreut. Ich habe weitergegangen und versucht, diese Parameter in eine Attributdatei (viel sauberer) zu abstrahieren, habe aber Probleme, sie mit Chef zu installieren. Ich habe die Erweiterungen aller Dateien mit ERB in ihnen geändert, um mit .erb zu enden (ich komme von einem Rails-Hintergrund, so scheint das für mich natürlich). Zum Beispiel hatte ich eine Datei mit dem Namen run.conf und heißt jetzt run.conf.erb.Chef Vorlagen mit rekursiven Verzeichnissen

Idealerweise hätte ich gerne einen Vorlagenblock im Rezept, der nur alle Dateien im Verzeichnis kopiert und diese .ERB-Dateien mit den von mir bereitgestellten Variablen aktualisiert (die Erweiterung .ERB wird entfernt). Hier ist ein Beispiel, wo ich bin bei so weit:

template "#{node["dcm4chee"]["home"]}" do 
    source "server/" 
    variables(
    "java_mem_opts" => node["dcm4chee"]["java_mem_opts"], 
    "db_username" => node["dcm4chee"]["admin"]["username"], 
    "db_password" => node["dcm4chee"]["admin"]["password"], 
    "db_hostname" => node["mysql"]["hostname"], 
    "db_port" => node["mysql"]["port"] 
) 
end 

ich einen Ordner Server unter templates/default genannt gesetzt haben und dass Ordner enthält die Dateien, die ich als Templat sollen. Die Variable # {node ["dcm4chee"] ["home"]} ist der Ort, an dem ich die Dateien auf dem Zielrechner ablegen möchte. Idealerweise möchte ich dies tun, ohne bestimmte Dateien innerhalb des Rezepts zu benennen, da ich auf diese Weise das Rezept nicht berühren muss, wenn ich den Inhalt des Serververzeichnisses für die Bereitstellung modifiziere.

Ist das möglich? Wenn ja, was mache ich falsch? Wenn nicht, was sind meine Alternativen?

Dank

EDIT

Nach über diese ein wenig zu denken, habe ich versucht, einige benutzerdefinierte Ruby-Code zu verwenden, um dies zu tun. Hier ist mein aktueller Versuch, der mit einem NoMethodError fehlschlägt, der sich auf tempate_dir vom ersten Aufruf innerhalb des ruby_block bezieht.

def template_dir(file) 
    Dir.foreach("server") do |file| 
    if File.file?(file) 
     template "#{node["dcm4chee"]["home"]}/#{file}" do 
     source "server/#{file}" 
      variables(
      "java_mem_opts" => node["dcm4chee"]["java_mem_opts"], 
      "db_username" => node["dcm4chee"]["admin"]["username"], 
      "db_password" => node["dcm4chee"]["admin"]["password"], 
      "db_hostname" => node["mysql"]["hostname"], 
      "db_port" => node["mysql"]["port"] 
     ) 
     end 
    else 
     directory "#{node["dcm4chee"]["home"]}/#{file}" do 
     action :create 
     end 
     template_dir(file) 
    end 
    end 
end 

ruby_block "template the whole server directory" do 
    block do 
    template_dir("server") 
    end 
end 
+0

Müssen all Ihre Dateien Templating mit Parametern oder nur ein paar? – cmur2

+0

Nur ein paar für jetzt, aber im Idealfall möchte ich sie alle zusammen halten (diejenigen, die Templating benötigen, und solche, die das nicht tun), so dass es in Zukunft sehr einfach ist, Dateien hinzuzufügen/zu entfernen. – Jon

+0

Sie könnten wahrscheinlich Ruby verwenden, um alle Dateien im Templates-Verzeichnis relativ zum Rezept zu erhalten. Dann verwenden Sie einfach die 'template' Ressource in einem' files.each' Block. – cassianoleal

Antwort

2

Sie könnten template_dir innerhalb Ihres ruby_block statt an der Spitze Ebene- definieren, die gut funktionieren wird.

find ist ein Teil der Ruby-Standardbibliothek und wird rekursiv durch ein Verzeichnis gehen. Mit ihm Reinigern in etwas leicht führen würde:

ruby_block "recursive templating" do 
    block do 
     require 'find' 
     root = 'server' 
     Find.find(root) do |file| 
      if File.file?(file) 
       template "#{node["dcm4chee"]["home"]}/#{file}" do 
        source file 
        variables(
         "java_mem_opts" => node["dcm4chee"]["java_mem_opts"], 
         "db_username" => node["dcm4chee"]["admin"]["username"], 
         "db_password" => node["dcm4chee"]["admin"]["password"], 
         "db_hostname" => node["mysql"]["hostname"], 
         "db_port" => node["mysql"]["port"] 
        ) 
       end 
      end 
     end 
    end 
end 

Im Allgemeinen, wenn Sie jede Art von leicht komplizierter Logik schreiben, sollten Sie erwägen, einen LWRP schreiben, anstatt sie in Ihr Rezept zu stellen. Die zweiphasige Kompilierungs-/Ausführungs-Sache verursacht eine Menge unintuitives Verhalten (wie die Tatsache, dass der Block nicht nachschlagen kann template_dir), und weil das Schreiben einer LWRP die Eingabe validiert, Tests schreibt und eine bessere Arbeit zur Sicherstellung der Idempotenz leistet .

Auch ich bin ein wenig verwirrt über die 'Server' Zeichenfolge, die Sie haben- Ich bin mir nicht sicher in welcher Umgebung, die zu Ihrem templates Verzeichnis auflösen wird. Wenn Sie Zugriff auf eine Liste aller Vorlagen in Ihrem Kochbuch haben möchten, steht Ihnen hier ein Array zur Verfügung: run_context.cookbook_collection[cookbook_name].template_filenames

Verwandte Themen