Reputation: 101
I have hundreds of box can be accessed only with different gateway, like below shows:
gateway1:ip1,ip2
gateway2:ip3,ip4 ...
All job need done in one minute, so I use multiprocess below command fab -f ytj_sto.py doitnow
, errors below.
[]
None
None
***Warning*** Host None via ssh is down
Code:
@parallel(pool_size=20)
def coll():
print env.hosts
print env.host
print env.gateway
if _is_ssh_ok(env.host):
d = patt()
def doitnow():
p=Pool(20)
with open('ytj_sto.hn','r') as f:
for line in f.readlines():
line = line.strip()
if not len(line) or line.startswith('#'):
continue
env.gateway = line.split(':')[0]
env.hosts = line.split(':')[1].split(',')
result = p.apply_async(coll, args=())
result.get()
p.close()
p.join()
EDITED: I have used fab -H -g solved the issue,thanks all
def fabfun(Hosts,Gate,des,func1):
with settings(hide('running'), warn_only=True):
local(("fab -H %s -g %s -f %s %s ") % (Hosts,Gate,des,func1))
p=Pool(20)
starttime = time.asctime( time.localtime(time.time()) )
print('Waiting for all job done...%s' % starttime)
with open('ytj_sto.hn','r') as f:
for line in f.readlines():
line = line.strip()
if not len(line) or line.startswith('#'):
continue
Hosts = line.split(':')[1]
Gate = line.split(':')[0]
p.apply_async(fabfun, args=(Hosts,Gate,des,func1))
p.close()
p.join()
Upvotes: 0
Views: 326
Reputation: 15926
If you want to set env variables dynamically like you are, you should use execute
. That way the execute
d task takes on the env
values that you set at runtime. But unfortunately, because fabric
is not fully thread-safe, you can only kick off tasks like this in parallel in your situation once per gateway because env
is a global singleton.
A simple but integral aspect of Fabric is what is known as the “environment”: a Python dictionary subclass, which is used as a combination settings registry and shared inter-task data namespace.
The environment dict is currently implemented as a global singleton, fabric.state.env, and is included in fabric.api for convenience. Keys in env are sometimes referred to as “env variables”.
from fabric.context_managers import env
@parallel(pool_size=20)
def check_and_patt():
if _is_ssh_ok(env.host):
d = patt()
def doitnow():
p=Pool(20)
with open('ytj_sto.hn','r') as f:
for line in f.readlines():
line = line.strip()
if not len(line) or line.startswith('#'):
continue
env.gateway = line.split(':')[0]
env.hosts = line.split(':')[1].split(',')
result = execute(check_and_patt)
Upvotes: 1
Reputation: 2269
I think you can just supply env
to the coll
function as a parameter, like so:
@parallel(pool_size=20)
def coll(env): # <-- updated
print env.hosts
print env.host
print env.gateway
if _is_ssh_ok(env.host):
d = patt()
def doitnow():
p=Pool(20)
with open('ytj_sto.hn','r') as f:
for line in f.readlines():
line = line.strip()
if not len(line) or line.startswith('#'):
continue
env.gateway = line.split(':')[0]
env.hosts = line.split(':')[1].split(',')
result = p.apply_async(coll, args=(env,)) # <-- updated
result.get()
p.close()
p.join()
There's a few quirks to using the multiprocessing library. This info might be especially relevant to you scenario:
Global variables
Bear in mind that if code run in a child process tries to access a global variable, then the value it sees (if any) may not be the same as the value in the parent process at the time that Process.start was called.
However, global variables which are just module level constants cause no problems.
Upvotes: 0