Python's Fabric provides the ability to invoke fabric functions outside of the fab
utility using the execute
function. A contextual problem arises when an execute
function is invoked within another function that was called using execute. Fabric loses the context of the outer execute when the inner execute is invoked and never recovers it. For example:
env.roledefs = {
'webservers': ['web1','web2'],
'load_balancer': ['lb1']
}
@roles('webserver')
def deploy_code():
#ship over tar.gz of code to unpack.
...
execute(remove_webserver_from_load_balancer, sHost=env.host_string)
...
#shutdown webserver, unpack files, and restart web server
...
execute(add_webserver_to_load_balancer, sHost=env.host_string)
@roles('load_balancer')
def remove_webserver_from_load_balancer(sHost=None):
ssh("remove_host %s" % sHost)
execute(deploy_code)
After the first call to execute
, Fabric completely loses its context and executes all further commands within the deploy_code
function with host_string='lb1'
instead of 'web1'
. How can I get it to remember it?
I came up with this hack, but I feel like it could break on future releases:
with settings(**env):
execute(remove_webserver_from_load_balancer, sHost=env.host_string)
This effectively saves all state and restores it after the call, but seems like an unintended use of the function. Is there a better way to tell Fabric that it's in a nested execute and to use a settings stack or an equivalent method to remember state?
Thanks!
Your not using fabric right. As you'd just call fab deploy_code
instead of running the fabfile like it's python. I'd suggest going through the tutorial for a better idea on how to structure your fabfile.
Anyhow though, you can look here for how to use execute()
, and here for more of the specifics.
You have a typo in that you've dropped the 's' from the webservers role. Which might account for you not having a good host string when you want it on the second task.
But that aside, you can also set roles and hosts in the execute() command itself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With