Il sera bon d'inclure un exemple de cela dans les docs aussi. Supposons que j'ai ce code.
from fabric import ThreadingGroup as Group
from fabric.exceptions import GroupException
hosts = ['web1', 'web2', 'web3']
g = Group(*hosts)
try:
results = g.run('date', hide='both')
except GroupException as e:
print e.args # I read from code that arguments are passed to exception but I'm unable to use that. `args` argument in my case is an empty tuple.
Supposons que web1 et web3 ont réussi alors que web2 n'a pas réussi à se connecter ou que la commande a renvoyé un code de sortie différent de zéro.
Toute aide est appréciée.
Salut @shadyabhi ,
Vous ne savez pas si vous essayez d'attraper une exception spécifique ou si vous voulez simplement attraper toutes les exceptions qui se produisent dans des threads séparés. Je pense que l'objet ThreadingGroup passe déjà autour des objets d'exception à l'aide de files d'attente et déclenche le cas échéant lors de l'exécution. J'ai pu voir les traces de la pile en utilisant l'extrait de code suivant :
def run_data(c):
c.run('date', hide='both')
<strong i="8">@task</strong>
def thread_exception_example(c):
hosts = ['localhost', 'fakehost', 'localhost']
# python list comprehension
{c: run_data(c) for c in Group(*hosts)}
Sur la ligne de commande, j'ai exécuté : fab thread-exception-example
Salut @bossjones ,
Merci d'avoir répondu. Cependant, je n'utilise pas la commande fab mais j'exécute plutôt tout cela en utilisant fabric comme bibliothèque. Donc, une réponse est toujours en attente et serait appréciée.
En d'autres termes, fab
gère moi-même ce que je veux gérer dans mon code. Il y a des raisons pour lesquelles je ne veux pas utiliser directement la commande fab
car j'aimerais avoir plus de flexibilité dans la façon dont j'appelle les tâches.
Merci
Salut tout le monde,
Je suis désolé, j'ai oublié les détails. J'ai vérifié le code du tissu et j'ai obtenu des détails.
L'argument avec GroupException est un dictionnaire avec la clé comme objet fabric.connection.Connection
et la valeur comme objet fabric.runners.Result
.
except GroupException as e:
for c, r in e.result.items():
print "Connection: {}, Result: {}".format(c, r)
Bonjour,
En plus du commentaire de shadyabhi, voici une façon que j'utilise pour gérer GroupException.
J'espère que cela aidera !!
import logging, socket, paramiko.ssh_exception
from fabric import Connection, Config, ThreadingGroup, exceptions, runners
...
g = ThreadingGroup.from_connections(c)
try:
result = g.run('hostname' ) # (just a basic command)
except exceptions.GroupException as e:
i = 0
for c, r in e.result.items():
print("Host[{}] = [{}]".format(i,c.host) )
if isinstance(r,runners.Result) :
print("ok, fine")
elif isinstance(r,socket.gaierror) :
print("Network error")
elif isinstance(r,paramiko.ssh_exception.AuthenticationException) :
print("Auth failed")
else:
print("something else")
i+=1
(obtenu si du support ActivCloud )
Merci @akiuni pour votre exemple ! Je suis nouveau sur Python/Fabric et cela m'a aidé à comprendre comment faire des requêtes à l'aide de ThreadedGroup et collecter les résultats en cas d'exception. Voici ma version étendue de votre exemple. Très appréciée! Pour ce que ça vaut, j'ai également posté ceci sur Stackoverflow .
# requires fabric 2.x - run 'pip install fabric' to install it
import logging, socket, paramiko.ssh_exception
from fabric import Connection, Config, SerialGroup, ThreadingGroup, exceptions, runners
from fabric.exceptions import GroupException
# Note: You need to supply your own valid servers here to ssh to of course!
def main():
testHosts("All should succeed", "validServer1,validServer2,validServer3")
testHosts("Some should fail", "validServer1,validServer2,BADSERVER1,validServer3,BADSERVER2")
def testHosts(message, hostsAsString):
print("")
print(message)
# Get list of hosts from somewhere, and convert them to connections
hosts = hostsAsString.split(",")
servers = [Connection(host=host) for host in hosts]
# Create a thread group to run requests in parallel
g = ThreadingGroup.from_connections(servers)
try:
command = "df -h / | tail -n1 | awk '{print $5}'"
results = g.run(command, hide=True)
for r in results:
connection = results[r]
print("{}".format(r.host) )
print(" SUCCESS, " + connection.stdout.strip())
except GroupException as e:
# If an exception occurred, at least one request failed.
# Iterate through results here
for c, r in e.result.items():
print("{}".format(c.host) )
if isinstance(r,runners.Result) :
print(" SUCCESS, " + r.stdout.strip())
elif isinstance(r,socket.gaierror) :
print(" FAILED, Network error")
elif isinstance(r,paramiko.ssh_exception.AuthenticationException) :
print(" FAILED, Auth failed")
else:
print(" FAILED, Something other reason")
main()
Commentaire le plus utile
Bonjour,
En plus du commentaire de shadyabhi, voici une façon que j'utilise pour gérer GroupException.
J'espère que cela aidera !!
(obtenu si du support ActivCloud )