如何为fabric local()命令设置docker-machine env

我试图对docker机器云提供商运行命令,所以我需要采取命令docker-machine env digitalocean的内容,通常如下所示:

 export DOCKER_TLS_VERIFY="1" export DOCKER_HOST="tcp://1.2.3.4:2376" export DOCKER_CERT_PATH="/Users/danh/.docker/machine/machines/digitalocean" export DOCKER_MACHINE_NAME="digitalocean" # Run this command to configure your shell: # eval "$(docker-machine env digitalocean)" 

并使用上面的shell作为前缀,如:

 print 'outside with:' + local('echo $DOCKER_HOST') with prefix(local('docker-machine env digitalocean', capture=True)): print 'inside with:' + local('echo $DOCKER_HOST') with prefix('DOCKER_HOST="tcp://1.2.3.4:2376"'): print 'inside with (manual):' + local('echo $DOCKER_HOST') 

但是,这反而会返回:

 outside with:tcp://192.168.99.100:2376 inside with: inside with (manual):tcp://1.2.3.4:2376 

我能看到的唯一方法就是通过手动方式撕开local('docker-machine env digitalocean') 。 当然,还有更多的面料风格的方式吗?

那么,到目前为止我已经解决了这个问题,虽然感觉有些不好意思:

 def dm_env(machine): """ Sets the environment to use a given docker machine. """ _env = local('docker-machine env {}'.format(machine), capture=True) # Reorganize into a string that could be used with prefix(). _env = re.sub(r'^#.*$', '', _env, flags=re.MULTILINE) # Remove comments _env = re.sub(r'^export ', '', _env, flags=re.MULTILINE) # Remove `export ` _env = re.sub(r'\n', ' ', _env, flags=re.MULTILINE) # Merge to a single line return _env @task def blah(): print 'outside with: ' + local('echo $DOCKER_HOST') with prefix(dm_env('digitalocean')): print 'inside with: ' + local('echo $DOCKER_HOST') 

输出:

 outside with: tcp://192.168.99.100:2376 inside with: tcp://1.2.3.4:2376 

获取所需信息的另一种方法是使用docker-machine inspect命令的输出的格式化模板,同样也在文档中显示 。

请注意,Pythonstring中的大括号需要加倍,所以最终每次都有四个左右括号。

 machine_name = dev machine_ip = local("docker-machine inspect --format='{{{{.Driver.IPAddress}}}}' {0}".format(machine_name), capture=True) machine_port = local("docker-machine inspect --format='{{{{.Driver.EnginePort}}}}' {0}".format(machine_name), capture=True) machine_cert_path = local("docker-machine inspect --format='{{{{.HostOptions.AuthOptions.StorePath}}}}' {0}".format(machine), capture=True) 

现在,您可以使用shell_env上下文pipe理器 ,通过设置相应的环境variables来临时将Docker守护进程指向远程计算机:

 from fabric.api import shell_env with shell_env(DOCKER_TLS_VERIFY='1', DOCKER_HOST='tcp://{0}:{1}'.format(machine_ip, machine_port), DOCKER_CERT_PATH=machine_cert_path, DOCKER_MACHINE_NAME=machine_name): # will print containers on the remote machine local('docker ps -a') # will print containers on your local machine # since environment switch is only valid within the context manager local('docker ps -a')