2017-06-26 4 views
0

Ich habe folgendes CSV:Fabric: verschiedene Argumente an jede Aufgabe übergeben?

ip, arg1, arg2 
1.2.3.4, foo, bar 
1.3.4.5, baz, bub 

ich auszuführen versuche:

  1. Für jede Zeile in der CSV: ssh in die ip specificed,
  2. Befehle ausführen wie apt-get mit arg1
  3. Benutzerdefinierte Befehle ausführen, die arg2 für diese Zeile verwenden

Fabric hat execute(do_work, hosts=host_list), aber ich kann nicht den richtigen Kontext dafür angeben. Bisher habe ich zusammen etwas gehackt:

from fabric.api import env, execute 

arguments = {} 


def _deploy(): 
    print env.host_string, arguments[env.host_string] 


def deploy(): 
    global arguments 
    arguments['1.2.3.4'] = ('foo', 'bar') 
    arguments['2.3.4.5'] = ('baz', 'bub') 
    execute(_deploy, hosts=arguments.keys()) 

Dieses gedruckt wird:

[1.2.3.4] Executing task '_deploy' 
1.2.3.4 ('foo', 'bar') 
[2.3.4.5] Executing task '_deploy' 
2.3.4.5 ('baz', 'bub') 

Derzeit hat das nicht gebrochen nichts. Gibt es einen besseren Weg oder sogar eine bessere Lib für mich, dies zu tun?

Hinweis: Ich bin kein Fan von Paramiko, weil es zu niedrig ist.

Antwort

0

Dies ist ein Rand Fall in Stoff, der von Zeit zu Zeit kommt. Ich kann Ihnen eine Strategie zeigen, die ich in der Vergangenheit verwendet habe, aber ich werde mit einer sichereren Variante Ihrer Strategie beginnen.

Das env-Wörterbuch dient zum Speichern von Umgebungsdaten, die von anderen Aufgaben verwendet werden können. Alle Daten, die zwischen den Aufgaben geteilt werden sollte, aber das kann nicht als Argumente können hier weitergegeben werden gehen, so würde ich den Code ändern Argumente in env zu halten:

from fabric.api import env, execute, task 

def _deploy(): 
    print env.host_string, env.arguments[env.host_string] 

@task 
def deploy(): 
    env.arguments = {} 
    env.arguments['1.2.3.4'] = ('foo', 'bar') 
    env.arguments['2.3.4.5'] = ('baz', 'bub') 
    execute(_deploy, hosts=env.arguments.keys()) 

Die zweite Strategie ist eine, die ich verwendet habe, in der Vergangenheit, um eine solche Arbeit auszuführen, müssen alle Argumente als Teil der Host-Zeichenkette übergeben werden, und die Aufgabe muss dafür verantwortlich sein, diese in brauchbaren Daten zu analysieren. Es hält Sie von einem großen Wörterbuch, das um global und mit Ihrem Anwendungsfall könnte wirksam sein:

hosts.csv

1.2.3.4, foo, bar 
1.3.4.5, baz, bub 
1.4.5.6, complex-args, maybe with spaces 

fabfile.py

from fabric.api import env, execute, run, settings, task 

def _parse_args(argument_string): 
    # you should really use the csv module here to split properly (escapes, etc) 
    args = argument_string.split(', ') 
    if len(args) != 3: 
     raise ValueError("Only the host and 2 arguments are allowed") 
    return args 

def _deploy(): 
    host, arg1, arg2 = _parse_args(env.host_string) 
    with settings(host_string=host): 
     # run("apt-get '{}'".format(arg1)) 
     # run("service '{}' restart".format(arg2) 
     print "[{}] apt-get '{}'".format(env.host_string, arg1) 
     print "[{}] service '{}' restart".format(env.host_string, arg2) 

@task 
def deploy(): 
    with open('hosts.csv') as f: 
     hosts = [ line.strip() for line in f ] 
    execute(_deploy, hosts=hosts) 

Hier ist die Ausgabe, die Sie‘ d sehen mit dieser Strategie:

$ fab deploy 
[1.2.3.4, foo, bar] Executing task '_deploy' 
[1.2.3.4] apt-get 'foo' 
[1.2.3.4] service 'bar' restart 
[1.3.4.5, baz, bub] Executing task '_deploy' 
[1.3.4.5] apt-get 'baz' 
[1.3.4.5] service 'bub' restart 
[1.4.5.6, complex-args, maybe with spaces] Executing task '_deploy' 
[1.4.5.6] apt-get 'complex-args' 
[1.4.5.6] service 'maybe with spaces' restart 

Done. 
+0

env.arguments Ergebnisse in Attribut Fehler. – Sparrowcide

+0

@Sparrowcide das wäre nur der Fall, wenn Sie env überschreiben. Die Standardimplementierung unterstützt den Zugriff auf Attribute: https://github.com/fabric/fabric/blob/master/fabric/state.py # L334 EDIT: Whoops, du hast Recht. Ich habe es nie als Wörterbuch definiert. Ich habe das Beispiel aktualisiert. Das ist mein Fehler. – RedKrieg

0

Nicht elegant per se, aber das ist die Lösung, die ich mit bin Einschwingzeit:

def special_echo(matrix): 
    key = '[email protected]' + env.host 
    name = matrix[key] 
    run('echo %s `hostname --ip-address`' % name) 

A = {} 
A['[email protected]'] = 'first' 
A['[email protected]'] = 'second' 
A['[email protected]'] = 'third' 

execute(special_echo, A, hosts=A.keys()) 

Ergebnisse in:

[[email protected]] Executing task 'special_echo' 
[[email protected]] run: echo first `hostname --ip-address` 
[[email protected]] out: first 172.31.1.234 
[[email protected]] out: 

[[email protected]] Executing task 'special_echo' 
[[email protected]] run: echo third `hostname --ip-address` 
[[email protected]] out: third 172.31.15.36 
[[email protected]] out: 

[[email protected]] Executing task 'special_echo' 
[[email protected]] run: echo second `hostname --ip-address` 
[[email protected]] out: second 172.31.8.138 
[[email protected]] out: 
Verwandte Themen