Подключение к узлу, указанному в ~/.ssh/config при использовании 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 - и я предпочел бы сохранить свой аутентификация (т.е. ~/.ssh/config) отдельно от моего развертывания (т.е. fabfile.py).

Кроме того, кстати, если вы попытаетесь подключиться к хосту в файле hosts, fabric.contrib.projects.rsync_project, похоже, не признает "порты" в hosts.env (т.е. если вы используете hosts.env = [lulu:2100] вызов rsync_project похоже, пытается подключиться к lulu:21).

Есть ли причина, по которой Fabric не распознает это имя lulu?

Ответ 1

Начиная с версии 1.4.0, Fabric использует вашу конфигурацию ssh (частично). Однако вам нужно явно включить его, используя

env.use_ssh_config = True

где-то рядом с верхней частью вашего файла. Когда вы это сделаете, 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

Ответ 2

Обратите внимание, что это также происходит, когда имя не находится в /etc/hosts. У меня была такая же проблема, и мне пришлось добавить имя хоста для этого файла и ~/.ssh/config.

Ответ 3

update: этот ответ теперь устарел.


В настоящее время для файла .ssh/config Fabric нет поддержки. Вы можете установить их в функции, чтобы затем вызвать cli, например: производственная задача fab; где продукция устанавливает имя пользователя, имя хоста, порт и идентификатор ssh.

Что касается проекта rsync, теперь у него должна быть возможность настройки порта, а если нет, вы всегда можете запускать локальную ( "rsync..." ), поскольку это по существу то, что делает эта функция.

Ответ 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 = '%[email protected]%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()