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


83

Fabric无法识别自己所在的主机时遇到了麻烦~/.ssh/config

fabfile.py的如下:

from fabric.api import run, env

env.hosts = ['lulu']

def whoami():
    run('whoami')

运行$ fab whoami给出:

[lulu]跑:whoami

致命错误:lulu的名称查找失败

名称lulu在my中~/.ssh/config,如下所示:

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

我首先想到的解决,这是添加类似lulu.lulu/etc/hosts(我在Mac),但后来我也必须通过在身份文件面料-我宁愿让我的认证(即~/.ssh/config)从我的部署分开(即fabfile.py)。

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

Fabric是否无法识别此lulu名称?

Answers:


145

从1.4.0版开始,Fabric使用ssh配置(部分)。但是,您需要使用以下命令显式启用它

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.4.0之前的行为)。我删除了此序言,因为我的回答被接受了;)谢谢!
rbp 2012年

9

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


5

更新:此答案现在已过时


Fabric目前不支持.ssh / config文件。您可以在一个函数中进行设置,然后调用cli,例如:fab production task; 生产在其中设置用户名,主机名,端口和ssh身份。

对于rsync项目,现在应该具有端口设置功能,如果没有,则可以始终运行local(“ rsync ...”),因为从本质上讲,这就是贡献函数的功能。


1
将env.key_filename设置为私钥的完整路径。另外,如果您遇到麻烦,请参见code.fabfile.org/issues/show/265了解有关此问题的一些信息。
tobych 2011年

1
是的,现在有支持。(尽管我评论时是1.0之前的版本),但请以后的读者注意。
Morgan

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()

1
织物1.2+使用ssh库(paramiko fork):try: \n from ssh.config import SSHConfig \n except ImportError: \n from paramiko.config import SSHConfig
jfs

SSH库已合并回Paramiko,例如 from paramiko.config import SSHConfig
Paramiko
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.