2016-08-08 36 views
0

In einem bestimmten Projekt habe ich eine Menge Marionette exec Ressourcen mit Rohren. Das scheint gut zu funktionieren.Wie stelle ich sicher, dass eine Puppet-Exec-Ressource immer 'set -o pipefail' enthält?

exec { 'foobar': 
    command => 'foo | bar', 
} 

Es gibt jedoch Fälle, in denen foo fehlschlägt. Standardmäßig wird der Beendigungscode nur für den letzten Befehl in der Pipeline gemeldet. Ich kann das manuell beheben.

exec { 'foobar': 
    command => 'set -o pipefail; foo | bar', 
    provider => shell, 
} 

Aber ich möchte sicherstellen, dass dies in all diesen Fällen automatisch geschieht. Ich möchte manuelle Suche vermeiden/ersetzen und alle Verwendungen von exec überprüfen.

  • Fehle ich ein nützliches Attribut?
  • Gibt es eine Verpackung, die ich verwenden kann?
  • Betrachte ich leider eine benutzerdefinierte Ressource?
+0

Wahrscheinlich nicht: selbst einen Makro würde hier nicht helfen. Ich weiß es nicht. Wahrscheinlich ja, wenn Sie mit einer benutzerdefinierten Ressource benutzerdefinierte Parserfunktion und/oder benutzerdefinierten Typ meinen; Eine benutzerdefinierte Definition würde Ihnen hier sehr wahrscheinlich nicht helfen. –

Antwort

1
  • Bin ich einige nützliche Attribut fehlt?

Nein, Exec hat kein Attribut, das automatisch zusätzlichen Code auf den Befehl voranstellen würde.

  • Gibt es ein Wrapper kann ich verwenden?

Ich bin nicht sicher, dass ich verstehe, was Sie von einem „Wrapper“ bedeuten, aber unten.

  • Bin ich leider Blick auf eine benutzerdefinierte Ressource?

Wenn Sie gefragt werden, ob Sie eine native benutzerdefinierten Typ implementieren müssen, dann sicher nicht. Sie können dieses Problem zweifellos mit einem (DSL-Level-) definierten Typ lösen, obwohl Sie alle Ihre Exec Deklarationen als Deklarationen des definierten Typs anpassen müssen. Dies kann sein, was Sie von einem „Wrapper“ bedeuten - ich bin ziemlich sicher, dass keine bestehenden für Ihren bestimmten Zweck gibt es, aber es sollte nicht schwer zu erstellen:

define mymodule::exec (
    command  => $title, 
    creates  => 'NOT SET', 
    cwd   => 'NOT SET', 
    # ... all other regular parameters ... 
) { 
    $real_provider = $provider ? { 'NOT SET' => 'shell', default => $provider } 
    if $real_provider == 'shell' { 
    $real_command = "set -o pipefail; $command" 
    } else { 
    warning('Non-shell command declared via mymodule::exec') 
    $real_command = $command 
    } 

    exec { $title: 
    command => $real_command, 
    provider => $real_provider, 
    creates => $creates ? { 'NOT SET' => undef, default => $creates }, 
    cwd  => $cwd ? { 'NOT SET' => undef, default => $cwd }, 
    # ... all remaining regular parameters ... 
    } 
} 
+0

Warum haben alle diese Ternärknoten die Standardwerte der Klassenparameter direkt verwendet? z.B. 'mymodule :: exec (provider => 'NOT SET')' und '$ real_provider = $ provider? {'NICHT SET' => 'shell', default => $ provider} 'anstelle von' mymodule :: exec (provider => 'shell') ' –

+0

@MattSchuchard, der Punkt ist zweifach: (1) müssen Sie angeben Standardwerte für die Parameter, um zu verhindern, dass der Benutzer explizite Werte angibt, aber (2) wo der Benutzer tatsächlich keinen Wert angibt, möchten Sie dies in der Ressourcendeklaration durch Angabe von 'undef' ausdrücken. Dies ist ein ziemlich klassisches Muster für optionale Parameter. –

+0

Ich sehe immer noch nicht, warum die ternaries nicht entfernt werden können und die Werte direkt als Standardwerte in den Klassenparametern angegeben werden, weil beide für mich funktional isomorph erscheinen, aber ich denke, wir haben nur unterschiedliche Meinungen zum Codestil. –