Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a Fabric env.hosts sting as a variable is not work in function

Passing a Fabric env.hosts sting as a variable is not work in function.

demo.py

#!/usr/bin/env python

from fabric.api import env, run

def deploy(hosts, command):
    print hosts
    env.hosts = hosts
    run(command)

main.py

#!/usr/bin/env python

from demo import deploy

hosts = ['localhost']
command = 'hostname'
deploy(hosts, command)

python main.py

['localhost']
No hosts found. Please specify (single) host string for connection:

But env.host_string works!

demo.py

#!/usr/bin/env python

from fabric.api import env, run

def deploy(host, command):
  print host
  env.host_string = host
  run(command)

main.py

#!/usr/bin/env python

from demo import deploy

host = 'localhost'
command = 'hostname'
deploy(host, command)

python main.py

localhost
[localhost] run: hostname
[localhost] out: heydevops-workspace

But the env.host_string is not enough for us, it's a single host. Maybe we can use env.host_string within a loop, but that's not good. Because we also want to set the concurrent tasks number and run them parallelly.

Now in ddep(my deployment engine), I only use MySQLdb to get the parameters then execute the fab command like:

os.system("fab -f service/%s.py -H %s -P -z %s %s" % (project,host,number,task))

This is a simple way but not good. Because if I use the fab command, I can't catch the exceptions and failures of the results in Python, to make my ddep can "retry" the failed hosts. If I use the "from demo import deploy", I can control and get them by some codes in Python.

So now "env.host " is the trouble. Can somebody give me a solution? Thanks a lot.

like image 553
mcsrainbow Avatar asked Apr 25 '13 07:04

mcsrainbow


People also ask

What are the environment variables in service fabric?

Service Fabric has built-in environment variables set for each service instance. The full list of environment variables is below: The IP or FQDN of the node, as specified in the cluster manifest file. The fabric uri name of the service, if service is hosted in ExclusiveProcess mode.

How do I override the environment variables in the application manifest?

To override the environment variables in the application manifest, use the EnvironmentOverrides element. Service Fabric supports the ability to Use Docker Compose for Deployment. Compose files can source environment variables from the shell. This behavior can be used to substitute desired environment values dynamically:

How do I change the environment variable in servicemanifest?

Open the ServiceManifest.xml file. In the CodePackage element, add a new EnvironmentVariables element and an EnvironmentVariable element for each environment variable. Environment variables can be overridden in the application manifest. To override the environment variables in the application manifest, use the EnvironmentOverrides element.


2 Answers

Here's my insight.

According to docs, if you're calling fabric tasks from python scripts - you should use fabric.tasks.execute.

Should be smth like this:

  • demo.py

    from fabric.api import run
    from fabric.tasks import execute
    
    
    def deploy(hosts, command):
        execute(execute_deploy, command=command, hosts=hosts)
    
    
    def execute_deploy(command):
        run(command)
    
  • main.py

    from demo import deploy
    
    hosts = ['localhost']
    command = 'hostname'
    
    deploy(hosts, command)
    

Then, just run python main.py. Hope that helps.

like image 170
alecxe Avatar answered Oct 10 '22 17:10

alecxe


Finally, I fixed this problem by using execute() and exec.

main.py

#!/usr/bin/env python

from demo import FabricSupport

hosts = ['localhost']

myfab = FabricSupport()
myfab.execute("df",hosts)

demo.py

#!/usr/bin/env python

from fabric.api import env, run, execute

class FabricSupport:
    def __init__(self):
        pass

    def hostname(self):
        run("hostname")

    def df(self):
        run("df -h")

    def execute(self,task,hosts):
        get_task = "task = self.%s" % task
        exec get_task
        execute(task,hosts=hosts)

python main.py

[localhost] Executing task 'hostname'
[localhost] run: hostname
[localhost] out: heydevops-workspace
like image 2
mcsrainbow Avatar answered Oct 10 '22 18:10

mcsrainbow