使用Fabric时连接到〜/ .ssh / config中列出的主机

时间:2010-06-19 21:21:24

标签: python ssh fabric

我在Fabric无法识别~/.ssh/config中的主机时遇到问题。

我的fabfile.py如下:

from fabric.api import run, env

env.hosts = ['lulu']

def whoami():
    run('whoami')

正在运行$ fab whoami

  

[lulu] run:whoami

     

致命错误:名称查找失败   路路

名称lulu位于我的~/.ssh/config中,如下所示:

Host lulu
     hostname 192.168.100.100
     port 2100
     IdentityFile ~/.ssh/lulu-key

我首先考虑解决这个问题,就是在lulu.lulu添加/etc/hosts之类的东西(我在Mac上),但是我还必须将身份文件传递给Fabric - 而且我d而是将我的身份验证(即~/.ssh/config)与我的部署分开(即fabfile.py)。

同样,顺便提一下,如果您尝试连接到hosts文件中的主机,fabric.contrib.projects.rsync_project似乎不会确认hosts.env中的“端口”(即如果您使用{{1}调用hosts.env = [lulu:2100]似乎尝试连接到rsync_project)。

Fabric是否有理由不识别此lulu:21名称?

4 个答案:

答案 0 :(得分:142)

从版本1.4.0开始,Fabric uses your ssh config(部分)。但是,您需要使用

显式启用它
env.use_ssh_config = True

靠近fabfile顶部的某个地方。执行此操作后,Fabric应读取您的ssh配置(默认情况下来自~/.ssh/config,或来自env.ssh_config_path)。

一个警告:如果您使用的版本低于1.5.4,如果设置了env.use_ssh_config但是没有配置文件,则会发生中止。在这种情况下,您可以使用以下解决方法:

if env.ssh_config_path and os.path.isfile(os.path.expanduser(env.ssh_config_path)):
    env.use_ssh_config = True

答案 1 :(得分:9)

请注意,当名称不在/etc/hosts时,也会发生这种情况。我遇到了同样的问题,不得不将主机名添加到该文件和~/.ssh/config

答案 2 :(得分:5)

更新:此答案is now outdated


Fabric目前不支持.ssh / config文件。您可以在函数中设置它们然后调用cli,例如:fab生产任务; production设置用户名,主机名,端口和ssh标识。

对于rsync项目,现在应该具有端口设置能力,如果没有,你可以随时运行本地(“rsync ...”),因为这基本上是贡献功能所做的。

答案 3 :(得分:4)

可以使用以下代码来读取配置(原始代码取自:http://markpasc.typepad.com/blog/2010/04/loading-ssh-config-settings-for-fabric.html):

from fabric.api import *
env.hosts = ['servername']

def _annotate_hosts_with_ssh_config_info():
    from os.path import expanduser
    from paramiko.config import SSHConfig

    def hostinfo(host, config):
        hive = config.lookup(host)
        if 'hostname' in hive:
            host = hive['hostname']
        if 'user' in hive:
            host = '%s@%s' % (hive['user'], host)
        if 'port' in hive:
            host = '%s:%s' % (host, hive['port'])
        return host

    try:
        config_file = file(expanduser('~/.ssh/config'))
    except IOError:
        pass
    else:
        config = SSHConfig()
        config.parse(config_file)
        keys = [config.lookup(host).get('identityfile', None)
            for host in env.hosts]
        env.key_filename = [expanduser(key) for key in keys if key is not None]
        env.hosts = [hostinfo(host, config) for host in env.hosts]

        for role, rolehosts in env.roledefs.items():
            env.roledefs[role] = [hostinfo(host, config) for host in rolehosts]

_annotate_hosts_with_ssh_config_info()