2010-06-19 40 views
79

Tôi gặp sự cố với Fabric không nhận dạng được máy chủ lưu trữ mà tôi có trong ~/.ssh/config.Kết nối với máy chủ được liệt kê trong ~/.ssh/config khi sử dụng Fabric

My fabfile.py được như sau:

from fabric.api import run, env 

env.hosts = ['lulu'] 

def whoami(): 
    run('whoami') 

Chạy $ fab whoami cho:

[lulu] run: whoami

Fatal error: Name lookup failed for lulu

Tên lulu là trong ~/.ssh/config của tôi, như thế này:

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

Suy nghĩ đầu tiên của tôi để giải quyết điều này là thêm một cái gì đó như lulu.lulu đến /etc/hosts (Tôi đang ở trên máy Mac), nhưng sau đó tôi cũng phải chuyển vào tệp danh tính cho Vải - và tôi muốn giữ nguyên xác thực của mình (tức là ~/.ssh/config) tách biệt khỏi triển khai của tôi (ví dụ: fabfile.py).

Đồng thời, tình cờ, nếu bạn cố gắng kết nối với một máy chủ trong tập tin host, fabric.contrib.projects.rsync_project dường như không thừa nhận 'cổng' trong hosts.env (tức là nếu bạn sử dụng hosts.env = [lulu:2100] một cuộc gọi đến rsync_project dường như cố gắng kết nối với lulu:21).

Có lý do Vải không nhận ra tên lulu này không?

Trả lời

136

Kể từ phiên bản 1.4.0, Fabric uses your ssh config (một phần). Tuy nhiên, bạn cần bật một cách rõ ràng, với

env.use_ssh_config = True 

ở đâu đó gần đầu fabfile của bạn. Một khi bạn làm điều này, Vải nên đọc cấu hình ssh của bạn (từ ~/.ssh/config theo mặc định, hoặc từ env.ssh_config_path).

Một cảnh báo: nếu bạn sử dụng phiên bản cũ hơn 1.5.4, việc hủy bỏ sẽ xảy ra nếu env.use_ssh_config được đặt nhưng không có tệp cấu hình nào. Trong trường hợp đó, bạn có thể sử dụng một cách giải quyết như:

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

Câu trả lời ban đầu được bắt đầu bằng" Câu trả lời được chấp nhận đã lỗi thời "[vì nó đã ghi lại hành vi trước 1.4.0]. Tôi đã xóa lời nói đầu này, vì câu trả lời của tôi đã được chấp nhận thay thế;) Cảm ơn! – rbp

+0

chỉ cần thử nghiệm này trên 1.4.3 - hoạt động tốt. –

5

cập nhật: Câu trả lời này is now outdated.


Vải hiện không có hỗ trợ cho tệp .ssh/config. Bạn có thể thiết lập chúng trong một hàm để sau đó gọi vào cli, ví dụ: tác vụ sản xuất fab; nơi sản xuất đặt tên người dùng, tên máy chủ, cổng và nhận dạng ssh. Đối với dự án rsync, bây giờ sẽ có khả năng thiết lập cổng, nếu không, bạn luôn có thể chạy cục bộ ("rsync ...") vì đó là những gì mà chức năng đã đóng góp thực hiện.

+0

Vải và SSH: http://docs.fabfile.org/en/1.2.0/usage/ssh.html – tobych

+1

Set env.key_filename đến đường dẫn đầy đủ của khóa riêng. Ngoài ra nếu bạn gặp rắc rối, hãy xem http://code.fabfile.org/issues/show/265 để biết một số vấn đề xung quanh vấn đề này. – tobych

+1

Yup, bây giờ nó đã được hỗ trợ. (mặc dù nó đã được 1.0 trước khi tôi nhận xét) Ghi nhận cho người đọc sau này. – Morgan

9

Lưu ý rằng điều này cũng xảy ra khi tên không nằm trong số /etc/hosts. Tôi đã có cùng một vấn đề và phải thêm tên máy chủ lưu trữ cho cả tệp đó và ~/.ssh/config.

+0

Vẫn hữu ích. :) –

4

Người ta có thể sử dụng đoạn mã sau để đọc các cấu hình (mã gốc lấy từ: 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() 
+1

vải 1.2+ sử dụng thư viện 'ssh' (' paramiko' fork): 'try: \ n từ nhập khẩu ssh.config SSHConfig \ n ngoại trừ ImportError: \ n từ thư viện SSH nhập khẩu paramiko.config SSHConfig' – jfs

+0

đã được hợp nhất lại vào Paramiko, vd 'from paramiko.config nhập SSHConfig' – n8henrie

Các vấn đề liên quan