Será bom incluir um exemplo disso nos documentos também. Vamos supor que eu tenha esse código.
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.
Vamos supor que web1 e web3 foram bem-sucedidos enquanto web2 falhou ao se conectar ou o comando retornou com código de saída diferente de zero.
Qualquer ajuda é apreciada.
Oi @shadyabhi ,
Não tenho certeza se você está tentando capturar uma exceção específica ou se deseja apenas capturar todas as exceções que ocorrem em threads separados. Eu acho que o objeto ThreadingGroup já passa objetos de exceção usando filas e aumenta se algum for encontrado durante a execução. Consegui ver rastreamentos de pilha usando o seguinte trecho de código:
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)}
Na linha de comando eu corri: fab thread-exception-example
Olá @bossjones ,
Obrigado por responder. No entanto, não estou usando o comando fab, mas sim executando tudo isso usando o fabric como uma biblioteca. Portanto, uma resposta ainda está pendente e seria apreciada.
Em outras palavras, fab
está lidando com o que eu mesmo quero tratar no meu código. Há razões pelas quais eu não quero usar o comando fab
diretamente, pois gostaria de ter mais flexibilidade na forma como invoco as tarefas.
Obrigado
Olá a todos,
Desculpe, esqueci os detalhes. Verifiquei o código do tecido e obtive detalhes.
O argumento com GroupException é um dicionário com a chave como objeto fabric.connection.Connection
e o valor como objeto fabric.runners.Result
.
except GroupException as e:
for c, r in e.result.items():
print "Connection: {}, Result: {}".format(c, r)
Olá,
Além do comentário de shadyabhi, aqui está uma maneira que uso para lidar com GroupException.
Espero que isso ajude !!
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
(obtido do suporte do ActivCloud )
Obrigado @akiuni pelo seu exemplo! Sou novo em Python/Fabric e isso me ajudou a entender como fazer solicitações usando ThreadedGroup e coletar os resultados quando havia uma exceção. Aqui está minha versão expandida do seu exemplo. Muito apreciado! Por que vale a pena, eu postei isso no Stackoverflow também.
# 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()
Comentários muito úteis
Olá,
Além do comentário de shadyabhi, aqui está uma maneira que uso para lidar com GroupException.
Espero que isso ajude !!
(obtido do suporte do ActivCloud )