使用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.