2

現在、リモートの Linux マシンに SSH で接続し、そのマシンでコマンドを実行する Python スクリプトが動作しています。paramikoを使用して ssh 接続を処理しています。hostname -sコマンドを実行する実際のコードは次のとおりです。

blade = '192.168.1.15'
username='root'
password=''
# now, connect 
try:
    client = paramiko.SSHClient()
    client.load_system_host_keys()
    client.set_missing_host_key_policy(paramiko.WarningPolicy())
    print '*** Connecting...'
    client.connect(blade, 22, username, password)
# print hostname for verification
    stdin, stdout, stderr  = client.exec_command('hostname --short')
    print stdout.readlines()
except Exception, e:
    print '*** Caught exception: %s: %s' % (e.__class__, e)
    traceback.print_exc()
    try:
        client.close()
    except:
        pass
    sys.exit(1)

これは問題なく動作しますが、実際にやろうとしていることはもっと複雑です。私が実際にやりたいのは、上で行ったように、同じ Linux マシンに SSH で接続することですが、その上に一時的な仮想マシンを作成し、その仮想マシンでコマンドを実行します。これが私の(機能しない)試みです:

blade='192.168.1.15'
username='root'
password=''
# now, connect 
try:
   # client = paramiko.SSHClient()
    client.load_system_host_keys()
    client.set_missing_host_key_policy(paramiko.WarningPolicy())
    print '*** Connecting...'
    client.connect(blade, 22, username, password)
   # create VM, log in, and print hostname for verification
    stdin, stdout, stderr = client.exec_command('sudo kvm -m 1024 -drive file=/var/lib/libvirt/images/oa4-vm$
    time.sleep(60) #delay to allow VM to initialize
    stdin.write(username + '\n') #log into VM
    stdin.write(password + '\n') #log into VM
    stdin, stdout, stderr  = client.exec_command('hostname --short')
    print stdout.readlines()
except Exception, e:
    print '*** Caught exception: %s: %s' % (e.__class__, e)
    traceback.print_exc()
    try:
        client.close()
    except:
        pass
    sys.exit(1)

これを実行すると、次のようになります。

joe@computer:~$ python automata.py
*** Connecting...
/home/joe/.local/lib/python2.7/site-packages/paramiko/client.py:95: UserWarning: Unknown ssh-rsa host key for 192.168.1.15: 25f6a84613a635f6bcb5cceae2c2b435
  (key.get_name(), hostname, hexlify(key.get_fingerprint())))
*** Caught exception: <class 'socket.error'>: Socket is closed
Traceback (most recent call last):
  File "automata.py", line 32, in function1
stdin.write(username + '\n') #log into VM
  File "/home/joe/.local/lib/python2.7/site-packages/paramiko/file.py", line 314, in write
self._write_all(data)
  File "/home/joe/.local/lib/python2.7/site-packages/paramiko/file.py", line 439, in _write_all
    count = self._write(data)
  File "/home/joe/.local/lib/python2.7/site-packages/paramiko/channel.py", line 1263, in _write
    self.channel.sendall(data)
  File "/home/joe/.local/lib/python2.7/site-packages/paramiko/channel.py", line 796, in sendall
    raise socket.error('Socket is closed')
error: Socket is closed

このエラーの解釈方法がわかりません。「ソケットが閉じられています」と表示されると、VM を作成しようとしている接続が SSH 接続で終了していると思われます。誰にも指針がありますか?

アップデート

pexpect ラッパーを使用しようとしていますが、un/pw プロンプトと対話するのに問題があります。リモート マシンに ssh 接続し、test.py スクリプトを実行してプロセスをテストしています。このスクリプトは、ユーザー名の入力を求め、ユーザー名をテキスト ファイルに保存します。ここに私のfabファイルがあります:

env.hosts = ['hostname']
env.user = 'userame'
env.password = 'password'


def vm_create():
        run("python test.py")

リモート マシンの test.py の内容は次のとおりです。

#! /usr/bin/env python

uname = raw_input("Enter Username: ")

f = open('output.txt','w')
f.write(uname + "\n")
f.close

したがって、ローカル マシンで「fab vm_create」を実行すると、SSH 接続が正常に確立され、test.py で定義されているユーザー名の入力を求められます。ただし、pexpect ラッパーを使用してローカル マシンで 3 番目の Python ファイルを実行すると、次のようになります。

import pexpect
child = pexpect.spawn('fab vm_create')
child.expect ('Enter Username: ')
child.sendline ('password')

何も起こらないようです。エラーは発生せず、リモート マシンに output.txt は作成されません。pexpect を間違って使用していますか?

4

2 に答える 2