Skip to content

Commit 9bec074

Browse files
committed
vm: drop paramiko
And replace with ssh/scp binaries. This is probably more robust than paramiko.
1 parent d7c2d65 commit 9bec074

File tree

2 files changed

+38
-44
lines changed

2 files changed

+38
-44
lines changed

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ jobs:
106106
- name: Install test dependencies
107107
run: |
108108
sudo apt update
109-
sudo apt install -y python3-pytest python3-paramiko python3-boto3 flake8 pylint libosinfo-bin squashfs-tools
109+
sudo apt install -y python3-pytest python3-boto3 flake8 pylint libosinfo-bin squashfs-tools sshpass
110110
- name: Diskspace (before)
111111
run: |
112112
df -h

vmtest/vm.py

Lines changed: 37 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,16 @@
1212
from io import StringIO
1313

1414
import boto3
15-
import paramiko
1615
from botocore.exceptions import ClientError
17-
from paramiko.client import AutoAddPolicy, SSHClient
18-
from scp import SCPClient
1916
from vmtest.util import get_free_port, wait_ssh_ready
2017

2118
AWS_REGION = "us-east-1"
2219

23-
# XXX: find better way to control this
24-
if os.environ.get("OSBUILD_TEST_QEMU_VERBOSE"):
25-
logging.getLogger("paramiko").setLevel(logging.DEBUG)
26-
logging.getLogger("paramiko").addHandler(logging.StreamHandler(sys.stderr))
20+
21+
_non_interactive_ssh = [
22+
"-o", "UserKnownHostsFile=/dev/null",
23+
"-o" "StrictHostKeyChecking=no",
24+
]
2725

2826

2927
class VM(abc.ABC):
@@ -54,50 +52,46 @@ def force_stop(self):
5452
Stop the VM and clean up any resources that were created when setting up and starting the machine.
5553
"""
5654

57-
def _get_ssh_transport(self, user, password="", keyfile=None):
58-
if not self.running():
59-
self.start()
60-
client = SSHClient()
61-
client.set_missing_host_key_policy(AutoAddPolicy)
62-
# workaround, see https://github.com/paramiko/paramiko/issues/2048
63-
pkey = None
64-
if keyfile:
65-
for klass in paramiko.key_classes:
66-
try:
67-
pkey = klass.from_private_key_file(keyfile)
68-
break
69-
except paramiko.ssh_exception.SSHException:
70-
continue
71-
if pkey is None:
72-
raise RuntimeError(f"cannot load {keyfile}, tried {paramiko.key_classes}")
73-
client.connect(
74-
self._address, self._ssh_port,
75-
user, password, pkey=pkey,
76-
allow_agent=False, look_for_keys=False)
77-
return client.get_transport()
55+
def _sshpass(self, password):
56+
if not password:
57+
return []
58+
return ["sshpass", "-p", password]
7859

7960
def run(self, cmd, user, password="", keyfile=None):
8061
"""
8162
Run a command on the VM via SSH using the provided credentials.
8263
"""
83-
tr = self._get_ssh_transport(user, password, keyfile)
84-
chan = tr.open_session()
85-
chan.get_pty()
86-
chan.exec_command(cmd)
87-
stdout_f = chan.makefile()
64+
if not self.running():
65+
self.start()
66+
ssh_cmd = self._sshpass(password) + [
67+
"ssh", "-p", str(self._ssh_port),
68+
] + _non_interactive_ssh
69+
if keyfile:
70+
ssh_cmd.extend(["-i", keyfile])
71+
ssh_cmd.append(f"{user}@{self._address}")
72+
ssh_cmd.append(cmd)
8873
output = StringIO()
89-
while True:
90-
out = stdout_f.readline()
91-
if not out:
92-
break
93-
self._log(out)
94-
output.write(out)
95-
exit_status = stdout_f.channel.recv_exit_status()
96-
return exit_status, output.getvalue()
74+
with subprocess.Popen(
75+
ssh_cmd,
76+
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
77+
text=True, bufsize=1,
78+
) as p:
79+
for out in p.stdout:
80+
self._log(out)
81+
output.write(out)
82+
return p.returncode, output
9783

9884
def scp(self, src, dst, user, password="", keyfile=None):
99-
with SCPClient(self._get_ssh_transport(user, password, keyfile)) as scp:
100-
scp.put(src, dst)
85+
if not self.running():
86+
self.start()
87+
scp_cmd = self._sshpass(password) + [
88+
"scp", "-P", str(self._ssh_port),
89+
] + _non_interactive_ssh
90+
if keyfile:
91+
scp_cmd.extend(["-i", keyfile])
92+
scp_cmd.append(src)
93+
scp_cmd.append(f"{user}@{self._address}:{dst}")
94+
subprocess.check_call(scp_cmd)
10195

10296
@abc.abstractmethod
10397
def running(self):

0 commit comments

Comments
 (0)