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

Posted

技术标签:

【中文标题】使用 Fabric 时连接到 ~/.ssh/config 中列出的主机【英文标题】:Connecting to a host listed in ~/.ssh/config when using Fabric 【发布时间】:2011-03-05 20:55:41 【问题描述】:

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

我的fabfile.py如下:

from fabric.api import run, env

env.hosts = ['lulu']

def whoami():
    run('whoami')

运行$ fab whoami 给出:

[lulu] 运行:whoami

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

名字lulu在我的~/.ssh/config里,像这样:

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

解决此问题的第一个想法是将lulu.lulu 添加到/etc/hosts(我在Mac 上),但随后我还必须将身份文件传递给Fabric - 我宁愿保留我的身份验证(即~/.ssh/config)与我的部署(即fabfile.py)分开。

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

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

【问题讨论】:

【参考方案1】:

从 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.4.0 之前的行为]。我已经删除了这个前言,因为我的回答被接受了;)谢谢!【参考方案2】:

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

【讨论】:

【参考方案3】:

更新:这个答案is now outdated。


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

对于 rsync 项目,它现在应该具有端口设置功能,如果没有,您可以随时运行 local("rsync ...") ,因为这本质上是贡献函数所做的。

【讨论】:

设置 env.key_filename 为私钥的完整路径。此外,如果您遇到麻烦,请参阅 code.fabfile.org/issues/show/265 了解与此相关的一些问题。 是的,它现在得到了支持。 (虽然我评论时它是 1.0 之前的版本)为后来的读者注意。【参考方案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()

【讨论】:

fabric 1.2+ 使用ssh 库(paramiko fork):try: \n from ssh.config import SSHConfig \n except ImportError: \n from paramiko.config import SSHConfig SSH 库已合并回 Paramiko,例如from paramiko.config import SSHConfig

以上是关于使用 Fabric 时连接到 ~/.ssh/config 中列出的主机的主要内容,如果未能解决你的问题,请参考以下文章

设置短名称时连接到生产节点

在主机未连接到网络时连接到 vmware 播放器中的服务器

Spring Boot Starter-Web 尝试在启动时连接到 Mongo

异常:503 将数据推送到 Google Pub/Sub 时连接到所有地址失败

android:无法在 targetSdkVersion 更改时连接到相机服务

如何将多个扬声器连接在一起并同时连接到手机?