web-dev-qa-db-ja.com

Fabricを使用している場合に〜/ .ssh / configにリストされているホストに接続する

Fabric~/.ssh/configにあるホストを認識できないという問題があります。

私のfabfile.pyは次のとおりです。

from fabric.api import run, env

env.hosts = ['lulu']

def whoami():
    run('whoami')

$ fab whoamiを実行すると、以下が得られます。

[lulu]実行:whoami

致命的なエラー:luluの名前検索に失敗しました

名前luluは、次のように私の~/.ssh/configにあります:

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

これを解決するために私が最初に考えたのは、lulu.luluのようなものを/etc/hostsに追加することです(Macを使用しています)が、IDファイルをFabricにも渡す必要があります。私の認証(つまり~/.ssh/config)は私の配備(つまりfabfile.py)とは別です。

同様に、偶然にも、hostsファイルのHostに接続しようとすると、fabric.contrib.projects.rsync_projecthosts.envの「ポート」を認識しないようです(つまり、hosts.env = [lulu:2100] a rsync_projectへの呼び出しはlulu:21への接続を試みているようです。

Fabricがこのlulu名を認識しない理由はありますか?

83
Brian M. Hunt

バージョン1.4.0以降、 Fabricはssh設定を使用 (部分的に)。ただし、明示的に有効にする必要があります。

env.use_ssh_config = True

fabfileの上部付近。これを行うと、Fabricはssh設定を読み取る必要があります(~/.ssh/configはデフォルトで、またはenv.ssh_config_path)。

1つの警告: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
143
rbp

これは、名前が/etc/hostsにない場合にも発生することに注意してください。同じ問題があり、そのファイルと~/.ssh/configの両方にホスト名を追加する必要がありました。

9
MrD

update:この回答 現在は古くなっています


Fabricは、現在.ssh/configファイルをサポートしていません。関数でこれらを設定して、cliを呼び出すことができます。 productionは、ユーザー名、ホスト名、ポート、およびssh IDを設定します。

Rsyncプロジェクトに関しては、ポート設定機能が必要になりました。そうでない場合は、local( "rsync ...")をいつでも実行できます。これは、本質的にその寄与関数が行うことです。

5
Morgan

次のコードを使用して構成を読み取ることができます(元のコードは: 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()
4
jmu