Reputation: 16029
I am trying to loop over all my server configurations in fabric and get their hostname like such:
from fabric.api import env, run
def serv_foo():
env.hosts = ['[email protected]']
def serv_bar():
env.hosts = ['[email protected]']
def get_all_servers():
return {(k,v) for k,v in globals().items() if k.startswith("serv_")}
def get_hostnames():
for serv_name, serv_fptr in get_all_servers():
print(env.hosts)
serv_fptr()
print(env.hosts)
hostname = run("hostname")
print(hostname)
This however fails:
>>> fab get_hostnames
>>> []
>>> ['[email protected]']
>>> No hosts found. Please specify (single) host string for connection:
How can I dynamically update the hosts in fabric?
fab serv_foo get_hostnames
. Not interested in that.execute(serv_fptr)
gives the same problem.Upvotes: 1
Views: 149
Reputation: 473813
You should set a host for the run
command by using execute:
from fabric.api import env, run
from fabric.tasks import execute
def serv_foo():
return ['[email protected]']
def serv_bar():
return ['[email protected]']
def get_all_servers():
return {(k, v) for k, v in globals().items() if k.startswith("serv_")}
def get_hostname():
return run("hostname")
def get_hostnames():
for serv_name, serv_fptr in get_all_servers():
print(env.hosts)
hostname = execute(get_hostname, hosts=serv_fptr())
print(hostname)
or settings context manager:
from fabric.api import run
from fabric.context_managers import settings
def serv_foo():
return '[email protected]'
def serv_bar():
return '[email protected]'
def get_all_servers():
return {(k, v) for k, v in globals().items() if k.startswith("serv_")}
def get_hostnames():
for serv_name, serv_fptr in get_all_servers():
with settings(host_string=serv_fptr()):
hostname = run("hostname")
print(hostname)
Hope that helps.
Upvotes: 1