рдореИрдВ рдирдП рдХрдкрдбрд╝реЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рд╕рдорд╛рдирд╛рдВрддрд░ рдирд┐рд╖реНрдкрд╛рджрди рдкрд░ рдХреЛрдИ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдирд╣реАрдВ рдвреВрдВрдв рдкрд╛ рд░рд╣рд╛ рдерд╛ред рдХреНрдпрд╛ рдпрд╣ рдЕрдЬрдЧрд░ 2 рд╕рдВрд╕реНрдХрд░рдг рдЬреИрд╕рд╛ рд╣реА рд╣реИ, рдпрд╛ рдпрд╣ рдкреНрд░рдЧрддрд┐ рдкрд░ рд╣реИ?
рдзрдиреНрдпрд╡рд╛рдж!
рд╣рд╛рдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдереНрд░реЗрдбрд┐рдВрдЧ рд╕рдореВрд╣ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ:
config = Config(overrides={'sudo':{'password': 'changeme'}})
c = ThreadingGroup("[email protected]", "[email protected]", connect_kwargs={"password": "changeme"}, config=config)
c.run("whoami")
c.sudo("whoami") #Throws AttributeError: 'ThreadingGroup' object has no attribute 'sudo'
рдереНрд░реЗрдбрд┐рдВрдЧрдЧреНрд░реБрдк рдиреЗ рдХреЗрд╡рд▓ рд░рди рдХрдорд╛рдВрдб рдХреА рдЕрдиреБрдорддрд┐ рджреА рд╣реИред
https://github.com/fabric/fabric/issues/1899#issue -377714688
рдЖрдк рдХрдорд╛рдВрдб рд╕рдкреЛрд░реНрдЯ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦ рдФрд░ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред
SerialGroup рдФрд░ ThreadingGroup рдореЗрдВ sudo рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреИрдЪ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЖрдк рдХреНрдпрд╛ рд╕реЛрдЪрддреЗ рд╣реИрдВ?
(рдХрдкрдбрд╝реЗ 2.4 рдкрд░ рд▓рд╛рдЧреВ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЧрдпрд╛)
--- fabric-orig/group.py 2018-10-30 14:35:22.000000000 +0100
+++ fabric-patched/group.py 2019-02-18 10:16:29.186000000 +0100
@@ -183,12 +183,28 @@
raise GroupException(results)
return results
+ def sudo(self, *args, **kwargs):
+ results = GroupResult()
+ excepted = False
+ for cxn in self:
+ try:
+ results[cxn] = cxn.sudo(*args, **kwargs)
+ except Exception as e:
+ results[cxn] = e
+ excepted = True
+ if excepted:
+ raise GroupException(results)
+ return results
def thread_worker(cxn, queue, args, kwargs):
result = cxn.run(*args, **kwargs)
# TODO: namedtuple or attrs object?
queue.put((cxn, result))
+def thread_worker_sudo(cxn, queue, args, kwargs):
+ result = cxn.sudo(*args, **kwargs)
+ # TODO: namedtuple or attrs object?
+ queue.put((cxn, result))
class ThreadingGroup(Group):
"""
@@ -208,6 +224,49 @@
)
threads.append(thread)
for thread in threads:
+ thread.start()
+ for thread in threads:
+ # TODO: configurable join timeout
+ # TODO: (in sudo's version) configurability around interactive
+ # prompting resulting in an exception instead, as in v1
+ thread.join()
+ # Get non-exception results from queue
+ while not queue.empty():
+ # TODO: io-sleep? shouldn't matter if all threads are now joined
+ cxn, result = queue.get(block=False)
+ # TODO: outstanding musings about how exactly aggregate results
+ # ought to ideally operate...heterogenous obj like this, multiple
+ # objs, ??
+ results[cxn] = result
+ # Get exceptions from the threads themselves.
+ # TODO: in a non-thread setup, this would differ, e.g.:
+ # - a queue if using multiprocessing
+ # - some other state-passing mechanism if using e.g. coroutines
+ # - ???
+ excepted = False
+ for thread in threads:
+ wrapper = thread.exception()
+ if wrapper is not None:
+ # Outer kwargs is Thread instantiation kwargs, inner is kwargs
+ # passed to thread target/body.
+ cxn = wrapper.kwargs["kwargs"]["cxn"]
+ results[cxn] = wrapper.value
+ excepted = True
+ if excepted:
+ raise GroupException(results)
+ return results
+
+ def sudo(self, *args, **kwargs):
+ results = GroupResult()
+ queue = Queue()
+ threads = []
+ for cxn in self:
+ my_kwargs = dict(cxn=cxn, queue=queue, args=args, kwargs=kwargs)
+ thread = ExceptionHandlingThread(
+ target=thread_worker_sudo, kwargs=my_kwargs
+ )
+ threads.append(thread)
+ for thread in threads:
thread.start()
for thread in threads:
# TODO: configurable join timeout
рдпрд╣ рд╡рд╛рдХрдИ рдХрдорд╛рд▓ рдХрд╛ рд╣реЛрдЧрд╛ @akiuni
рдлреИрдмреНрд░рд┐рдХ2 рдХреЗ рд▓рд┐рдП рдереНрд░реЗрдбрд┐рдВрдЧрдЧреНрд░реБрдк рдореЗрдВ рдПрдХреНрдЬрд╝реАрдХреНрдпреВрдЯ () рдлреАрдЪрд░ рдХреЛ рд╡рд╛рдкрд╕ рд▓рд╛рдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред
@akiuni рдЗрд╕рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдкреАрдЖрд░ рд╣реИ? https://github.com/fabric/fabric/issues/1912#issuecomment -464652728
@akiuni рдЗрд╕рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдкреАрдЖрд░ рд╣реИ? #1912 (рдЯрд┐рдкреНрдкрдгреА)
рдирдорд╕реНрддреЗ, рдореБрдЭреЗ рдРрд╕рд╛ рдирд╣реАрдВ рд▓рдЧрддрд╛.. рд╕рдЪ рдХрд╣реВрдВ, рддреЛ рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХреИрд╕реЗ рдЬрд╛рдВрдЪрдирд╛ рд╣реИ рдФрд░ рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕рдВрд╢реЛрдзрди рдХреЛ рдЬрдорд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреИрд╕реЗ рдЖрдЧреЗ рдмрдврд╝рдирд╛ рд╣реИ...
рд╣рдореЗрдВ рдЗрд╕реЗ рдЬрд▓реНрдж рд╕реЗ рдЬрд▓реНрдж рдлреИрдмреНрд░рд┐рдХ рдореЗрдВ рдорд┐рд▓рд╛рдирд╛ рд╣реЛрдЧрд╛ред
рдорд┐рдореА рд╡рд░реНрддрдорд╛рди рдХреЛрдб рдХреЛ v 2.5.0 . рдореЗрдВ рджреЗрдЦ рд░рд╣рд╛ рд╣реИ
https://github.com/fabric/fabric/blob/2.5.0/fabric/group.py#L127 рдореИрдВ рджреЗрдЦ рд╕рдХрддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рдХреЛрдб рдЕрдм рдЪрд╛рд▓реВ рдирд╣реАрдВ рд╣реИ, рдФрд░ рд▓реЗрдЦрдХ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд╕рд░реНрд╡реЛрддреНрддрдо рддрд░реАрдХреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪ рд░рд╣реЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХреЛрдИ рдкреАрдЖрд░ рдирд╣реАрдВ рд╣реЛрдиреЗ рдХреЗ рдХрд╛рд░рдг рдЙрдирдХреЗ рдкрд╛рд╕ рдХреЛрдб рджреНрд╡рд╛рд░рд╛ рдкреЗрд╢ рдХрд┐рдП рдЧрдП рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдордВрдЪ рдирд╣реАрдВ рд╣реИред рдореИрдВ рдЗрд╕реЗ рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рдкрд╛рдпрдерди рдХреЛрдбрд░ рдирд╣реАрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕реЗ рдкреАрдЖрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╢реЙрдЯ рджреЗрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛
рд╣реИрд▓реЛ, рдореИрдВ git developmentpemen рдХреЗ рд▓рд┐рдП рдЕрднреНрдпрд╕реНрдд рдирд╣реАрдВ рд╣реВрдВ (рдкреАрдЖрд░ рдореЗрд░реЗ рд▓рд┐рдП рдПрдХ рдЕрдЬреАрдм рд╢рдмреНрдж рд╣реИ), рдмреЗрдЭрд┐рдЭрдХ рдореБрдЭреЗ рдмрддрд╛рдПрдВ рдХрд┐ рдХреНрдпрд╛ рдореИрдВ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ
рдЕрд░реЗ @akiuni
рдкреАрдЖрд░ рдкреБрд▓ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рдЦрдбрд╝рд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐, рдпрджрд┐ рдЖрдк рдХреЛрдИ рдмрджрд▓рд╛рд╡ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЙрд╕ рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рдПрдХ рдкреБрд▓ рдЕрдиреБрд░реЛрдз рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реНрд░реЛрдд рдХреЛрдб рдореЗрдВ рд▓рд╛рддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рддрдм рдмрд╛рддрдЪреАрдд рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХреА рд╕рдореАрдХреНрд╖рд╛ рд╣реЛрдиреЗ рддрдХ рд╕рдореАрдХреНрд╖рд╛ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред рдЬрдм рдЗрд╕реЗ рд╕реНрд╡реАрдХреГрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдкреАрдЖрд░ рджреНрд╡рд╛рд░рд╛ рдкреЗрд╢ рдХрд┐рдП рдЧрдП рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рдПрдХ рдкреНрд░рддрд┐рдмрджреНрдзрддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреИрд╕реЗ рдореИрдВрдиреЗ рдпрд╣рд╛рдВ рдХрд┐рдпрд╛ рд╣реИ: # 2052
рдкреБрд▓ рдЕрдиреБрд░реЛрдз (рдкреАрдЖрд░) рдореЗрдВ ".рдкреИрдЪ" рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЪрддреБрд░ рдЪрд╛рд▓ рд╣реИ рдЬреИрд╕реЗ рдпрд╣рд╛рдВ: https://patch-diff.githubusercontent.com/raw/fabric/fabric/pull/2052.patch рдЬреЛ рдЖрдкрдХреЛ рдПрдХ рдЕрдВрддрд░ рджреЗрдЧрд╛ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдореЗрдВ рд╕реЗ (рдЬреИрд╕рд╛ рдХрд┐ рдЖрдкрдиреЗ рдЕрдкрдиреА рдкрд┐рдЫрд▓реА рдЯрд┐рдкреНрдкрдгреА рдореЗрдВ рдЖрдкреВрд░реНрддрд┐ рдХреА рд╣реИ) рд▓реЗрдХрд┐рди рдЕрдм, рд▓рд╛рдн рд╣реИ, рд╡рд╛рд░реНрддрд╛рд▓рд╛рдк / рд╕рдореАрдХреНрд╖рд╛ / рдкрд░рд┐рд╡рд░реНрддрди рдХрд╛ рдПрдХрд▓ рдмрд┐рдВрджреБ рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдКрдкрд░ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рд╣реИ - рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдкреИрдЪ рдХреЗ рд╕рд╛рде рдкрд╣рд▓реЗ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореИрдВ рджреЗрдЦ рд░рд╣рд╛ рдерд╛ рдЙрд╕ рд╕рдордп рдЬрдм рдореИрдВрдиреЗ PR . рдмрдирд╛рдпрд╛
рд╕реВрдбреЛ рдХреЛ рдЕрднреА рд╕рдореВрд╣ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ! рджреЗрдЦреЗрдВ #1999
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
рдирдорд╕реНрддреЗ, рдореБрдЭреЗ рдРрд╕рд╛ рдирд╣реАрдВ рд▓рдЧрддрд╛.. рд╕рдЪ рдХрд╣реВрдВ, рддреЛ рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХреИрд╕реЗ рдЬрд╛рдВрдЪрдирд╛ рд╣реИ рдФрд░ рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕рдВрд╢реЛрдзрди рдХреЛ рдЬрдорд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреИрд╕реЗ рдЖрдЧреЗ рдмрдврд╝рдирд╛ рд╣реИ...