現在、リモートの 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 を間違って使用していますか?