Herstellen einer Verbindung zu einem in ~ / .ssh / config aufgelisteten Host bei Verwendung von Fabric


83

Ich habe Probleme damit Fabric, Hosts, in denen ich mich befinde, nicht zu erkennen ~/.ssh/config.

Mein fabfile.pyist wie folgt:

from fabric.api import run, env

env.hosts = ['lulu']

def whoami():
    run('whoami')

Laufen $ fab whoamigibt:

[lulu] rennen: whoami

Schwerwiegender Fehler: Namenssuche für Lulu fehlgeschlagen

Der Name luluist in meinem ~/.ssh/config, so:

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

Mein erster Gedanke, um dies zu lösen, ist das Hinzufügen lulu.luluvon /etc/hosts(ich bin auf einem Mac), aber dann muss ich auch die Identitätsdatei an Fabric übergeben - und ich möchte lieber meine Authentifizierung (dh ~/.ssh/config) von meiner Bereitstellung trennen ( dh fabfile.py).

Übrigens, wenn Sie versuchen, eine Verbindung zu einem Host in der Hosts-Datei herzustellen, werden fabric.contrib.projects.rsync_project'Ports' in der Datei übrigens nicht bestätigt hosts.env(dh wenn Sie hosts.env = [lulu:2100]einen Anruf verwenden, um rsync_projectzu versuchen, eine Verbindung herzustellen lulu:21).

Gibt es einen Grund, warum Fabric diesen luluNamen nicht erkennt ?

Antworten:


145

Seit Version 1.4.0 verwendet Fabric (teilweise) Ihre ssh-Konfiguration . Sie müssen es jedoch explizit mit aktivieren

env.use_ssh_config = True

Irgendwo in der Nähe der Spitze Ihres Fabfiles. Sobald Sie dies getan haben, sollte Fabric Ihre SSH-Konfiguration lesen ( ~/.ssh/configstandardmäßig von oder von env.ssh_config_path).

Eine Warnung: Wenn Sie eine Version verwenden, die älter als 1.5.4 ist, tritt ein Abbruch auf, wenn env.use_ssh_configfestgelegt, aber keine Konfigurationsdatei vorhanden ist. In diesem Fall können Sie eine Problemumgehung wie folgt verwenden:

if env.ssh_config_path and os.path.isfile(os.path.expanduser(env.ssh_config_path)):
    env.use_ssh_config = True

Die Antwort begann ursprünglich mit "Die akzeptierte Antwort ist veraltet" [da das Verhalten vor 1.4.0 dokumentiert wurde]. Ich habe dieses Vorwort entfernt, da meine Antwort stattdessen akzeptiert wurde;) Danke!
rbp

9

Beachten Sie, dass dies auch passiert, wenn der Name nicht vorhanden ist /etc/hosts. Ich hatte das gleiche Problem und musste den Hostnamen sowohl zu dieser Datei als auch zu dieser Datei hinzufügen ~/.ssh/config.


5

Update : Diese Antwort ist jetzt veraltet .


Fabric unterstützt die .ssh / config-Datei derzeit nicht. Sie können diese in einer Funktion einrichten, um dann die CLI aufzurufen, z. B.: Fab Production Task; Dabei legt die Produktion den Benutzernamen, den Hostnamen, den Port und die SSH-Identität fest.

Was das rsync-Projekt betrifft, sollte es jetzt über die Fähigkeit zur Porteinstellung verfügen. Wenn nicht, können Sie immer lokal ("rsync ...") ausführen, da dies im Wesentlichen die Funktion dieser beitragenden Funktion ist.


1
Setzen Sie env.key_filename auf den vollständigen Pfad des privaten Schlüssels. Auch wenn Sie auf Probleme stoßen , finden Sie unter code.fabfile.org/issues/show/265 einige Probleme.
Tobych

1
Ja, es hat jetzt Unterstützung. (obwohl es vor 1.0 war, als ich kommentierte) Hinweis für spätere Leser.
Morgan

4

Zum Lesen der Konfiguration kann folgender Code verwendet werden (Originalcode aus: 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
Fabric 1.2+ verwendet sshBibliothek ( paramikoGabel):try: \n from ssh.config import SSHConfig \n except ImportError: \n from paramiko.config import SSHConfig
JFS

Die SSH-Bibliothek wurde wieder in Paramiko zusammengeführt, z. B.from paramiko.config import SSHConfig
n8henrie
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.