Fabric: ๋ถ€๋ถ„ ์‹คํŒจ ์ค‘์— ThreadingGroup์—์„œ ๊ฒฐ๊ณผ๋ฅผ ์ฝ๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์— ๋งŒ๋“  2018๋…„ 05์›” 14์ผ  ยท  5์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: fabric/fabric

๋ฌธ์„œ์—๋„ ๊ทธ ์˜ˆ๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

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. 

web1๊ณผ web3๋Š” ์„ฑ๊ณตํ–ˆ์ง€๋งŒ web2๋Š” ์—ฐ๊ฒฐ์— ์‹คํŒจํ–ˆ๊ฑฐ๋‚˜ ๋ช…๋ น์ด 0์ด ์•„๋‹Œ ์ข…๋ฃŒ ์ฝ”๋“œ์™€ ํ•จ๊ป˜ ๋ฐ˜ํ™˜๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  • ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ ํ›„ ์ด๋Ÿฌํ•œ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ์–ป์œผ๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?
  • ๋ชจ๋“  ์ž‘์—…์ด ์™„๋ฃŒ๋œ ํ›„์—๋งŒ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๊ฒƒ์ด ๋ณด์žฅ๋ฉ๋‹ˆ๊นŒ?

๋„์›€์„ ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์•ˆ๋…•ํ•˜์„ธ์š”,

shadyabhi์˜ ์˜๊ฒฌ ์™ธ์—๋„ GroupException์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.
๋‚˜๋Š” ์ด๊ฒƒ์ด ๋„์›€์ด๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค !!

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



( ActivCloud ์ง€์›์—์„œ ์–ป์€ ๊ฒฝ์šฐ)

๋ชจ๋“  5 ๋Œ“๊ธ€

์•ˆ๋…•ํ•˜์„ธ์š” @shadyabhi ,

ํŠน์ • ์˜ˆ์™ธ๋ฅผ ํฌ์ฐฉํ•˜๋ ค๋Š” ๊ฒƒ์ธ์ง€ ์•„๋‹ˆ๋ฉด ๋ณ„๋„์˜ ์Šค๋ ˆ๋“œ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ชจ๋“  ์˜ˆ์™ธ๋ฅผ ํฌ์ฐฉํ•˜๋ ค๋Š” ๊ฒƒ์ธ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ThreadingGroup ๊ฐœ์ฒด๋Š” ์ด๋ฏธ ํ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์˜ˆ์™ธ ๊ฐœ์ฒด๋ฅผ ์ „๋‹ฌํ•˜๊ณ  ์‹คํ–‰ ์ค‘์— ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ ๋ฐœ์ƒํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฝ”๋“œ ์Šค๋‹ˆํŽซ์„ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํƒ ์ถ”์ ์„ ๋ณผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

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)}

๋ช…๋ น์ค„์—์„œ ๋‹ค์Œ์„ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. fab thread-exception-example

์•ˆ๋…•ํ•˜์„ธ์š” @bossjones ์ž…๋‹ˆ๋‹ค .

๋‹ต์žฅํ•ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” fab ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์˜คํžˆ๋ ค ํŒจ๋ธŒ๋ฆญ์„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๋ชจ๋“  ๊ฒƒ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ต๋ณ€์ด ์•„์ง ๋ณด๋ฅ˜ ์ค‘์ด๋ฉฐ ๊ฐ์‚ฌํžˆ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ฆ‰, fab ๋Š” ๋‚ด ์ฝ”๋“œ์—์„œ ์ง์ ‘ ์ฒ˜๋ฆฌํ•˜๋ ค๋Š” ๊ฒƒ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ž‘์—…์„ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋” ๋งŽ์€ ์œ ์—ฐ์„ฑ์„ ๊ฐ–๊ณ  ์‹ถ๊ธฐ ๋•Œ๋ฌธ์— fab ๋ช…๋ น์„ ์ง์ ‘ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์ง€ ์•Š์€ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ์‚ฌ ํ•ด์š”

์•ˆ๋…•ํ•˜์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„,

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ๊ฐ„๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค. ํŒจ๋ธŒ๋ฆญ ์ฝ”๋“œ๋ฅผ ํ™•์ธํ•˜๊ณ  ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค.

GroupException์˜ ์ธ์ˆ˜๋Š” ํ‚ค๊ฐ€ fabric.connection.Connection ๊ฐ์ฒด์ด๊ณ  ๊ฐ’์ด fabric.runners.Result ๊ฐ์ฒด์ธ ์‚ฌ์ „์ž…๋‹ˆ๋‹ค.

except GroupException as e:
         for c, r in e.result.items():
             print "Connection: {}, Result: {}".format(c, r)

์•ˆ๋…•ํ•˜์„ธ์š”,

shadyabhi์˜ ์˜๊ฒฌ ์™ธ์—๋„ GroupException์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.
๋‚˜๋Š” ์ด๊ฒƒ์ด ๋„์›€์ด๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค !!

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



( ActivCloud ์ง€์›์—์„œ ์–ป์€ ๊ฒฝ์šฐ)

์˜ˆ๋ฅผ ๋“ค์–ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค @akiuni ! ์ €๋Š” Python/Fabric์„ ์ฒ˜์Œ ์ ‘ํ–ˆ๊ณ  ThreadedGroup์„ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญํ•˜๊ณ  ์˜ˆ์™ธ๊ฐ€ ์žˆ์„ ๋•Œ ๊ฒฐ๊ณผ๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ดํ•ดํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๊ท€ํ•˜์˜ ์˜ˆ๋ฅผ ํ™•์žฅํ•œ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค. ๋งค์šฐ ๊ฐ์‚ฌ! ๊ทธ๋งŒํ•œ ๊ฐ€์น˜๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ์ด๊ฒƒ์„ 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()

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰