Skip to content

Commit 2cf2cbe

Browse files
authored
Merge branch 'master' into step-formatter-issue
2 parents 35a2bdb + 9636068 commit 2cf2cbe

File tree

10 files changed

+231
-67
lines changed

10 files changed

+231
-67
lines changed

dockerfiles/build.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ has_buildx() {
3131
local docker_cmd
3232
docker_cmd="${1}"
3333

34-
"${docker_cmd}" buildx --help >/dev/null 2>&1
34+
"${docker_cmd}" buildx version >/dev/null 2>&1
3535
}
3636

3737
get_docker_cmd() {

labgrid/driver/networkinterfacedriver.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def configure(self, settings):
6060
self.proxy.configure(self.iface.ifname, settings)
6161

6262
@Driver.check_active
63-
@step()
63+
@step(args=["expected"])
6464
def wait_state(self, expected, timeout=60):
6565
"""Wait until the expected state is reached or the timeout expires.
6666

labgrid/driver/sshdriver.py

+26-14
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ class SSHDriver(CommandMixin, Driver, CommandProtocol, FileTransferProtocol):
4141
def __attrs_post_init__(self):
4242
super().__attrs_post_init__()
4343
self._keepalive = None
44+
self._ssh = self._get_tool("ssh")
45+
self._scp = self._get_tool("scp")
46+
self._sshfs = self._get_tool("sshfs")
47+
self._rsync = self._get_tool("rsync")
48+
49+
def _get_tool(self, name):
50+
if self.target.env:
51+
return self.target.env.config.get_tool(name)
52+
return name
4453

4554
def _get_username(self):
4655
"""Get the username from this class or from NetworkService"""
@@ -105,7 +114,7 @@ def _start_own_master_once(self, timeout):
105114
self.tmpdir, f'control-{self.networkservice.address}'
106115
)
107116

108-
args = ["ssh", "-f", *self.ssh_prefix, "-x", "-o", f"ConnectTimeout={timeout}",
117+
args = [self._ssh, "-f", *self.ssh_prefix, "-x", "-o", f"ConnectTimeout={timeout}",
109118
"-o", "ControlPersist=300", "-o",
110119
"UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no",
111120
"-o", "ServerAliveInterval=15", "-MN", "-S", control.replace('%', '%%'), "-p",
@@ -203,7 +212,7 @@ def _run(self, cmd, codec="utf-8", decodeerrors="strict", timeout=None):
203212
if not self._check_keepalive():
204213
raise ExecutionError("Keepalive no longer running")
205214

206-
complete_cmd = ["ssh", "-x", *self.ssh_prefix,
215+
complete_cmd = [self._ssh, "-x", *self.ssh_prefix,
207216
"-p", str(self.networkservice.port), "-l", self._get_username(),
208217
self.networkservice.address
209218
] + cmd.split(" ")
@@ -238,7 +247,7 @@ def interact(self, cmd=None):
238247
if not self._check_keepalive():
239248
raise ExecutionError("Keepalive no longer running")
240249

241-
complete_cmd = ["ssh", "-x", *self.ssh_prefix,
250+
complete_cmd = [self._ssh, "-x", *self.ssh_prefix,
242251
"-t",
243252
self.networkservice.address
244253
]
@@ -252,7 +261,7 @@ def interact(self, cmd=None):
252261

253262
@contextlib.contextmanager
254263
def _forward(self, forward):
255-
cmd = ["ssh", *self.ssh_prefix,
264+
cmd = [self._ssh, *self.ssh_prefix,
256265
"-O", "forward", forward,
257266
self.networkservice.address
258267
]
@@ -261,7 +270,7 @@ def _forward(self, forward):
261270
try:
262271
yield
263272
finally:
264-
cmd = ["ssh", *self.ssh_prefix,
273+
cmd = [self._ssh, *self.ssh_prefix,
265274
"-O", "cancel", forward,
266275
self.networkservice.address
267276
]
@@ -361,7 +370,8 @@ def scp(self, *, src, dst):
361370
if dst.startswith(':'):
362371
dst = '_' + dst
363372

364-
complete_cmd = ["scp",
373+
complete_cmd = [self._scp,
374+
"-S", self._ssh,
365375
"-F", "none",
366376
"-o", f"ControlPath={self.control.replace('%', '%%')}",
367377
src, dst,
@@ -391,12 +401,12 @@ def rsync(self, *, src, dst, extra=[]):
391401
if dst.startswith(':'):
392402
dst = '_' + dst
393403

394-
ssh_cmd = ["ssh",
404+
ssh_cmd = [self._ssh,
395405
"-F", "none",
396406
"-o", f"ControlPath={self.control.replace('%', '%%')}",
397407
]
398408

399-
complete_cmd = ["rsync",
409+
complete_cmd = [self._rsync,
400410
"-v",
401411
f"--rsh={' '.join(ssh_cmd)}",
402412
"-rlpt", # --recursive --links --perms --times
@@ -417,7 +427,7 @@ def sshfs(self, *, path, mountpoint):
417427
if not self._check_keepalive():
418428
raise ExecutionError("Keepalive no longer running")
419429

420-
complete_cmd = ["sshfs",
430+
complete_cmd = [self._sshfs,
421431
"-F", "none",
422432
"-f",
423433
"-o", f"ControlPath={self.control.replace('%', '%%')}",
@@ -445,7 +455,7 @@ def get_status(self):
445455

446456
@cached_property
447457
def _ssh_version(self):
448-
version = subprocess.run(["ssh", "-V"], capture_output=True, text=True)
458+
version = subprocess.run([self._ssh, "-V"], capture_output=True, text=True)
449459
version = re.match(r"^OpenSSH_(\d+)\.(\d+)", version.stderr)
450460
return tuple(int(x) for x in version.groups())
451461

@@ -472,7 +482,8 @@ def _scp_supports_explicit_scp_mode(self):
472482
@step(args=['filename', 'remotepath'])
473483
def put(self, filename, remotepath=''):
474484
transfer_cmd = [
475-
"scp",
485+
self._scp,
486+
"-S", self._ssh,
476487
*self.ssh_prefix,
477488
"-P", str(self.networkservice.port),
478489
"-r",
@@ -502,7 +513,8 @@ def put(self, filename, remotepath=''):
502513
@step(args=['filename', 'destination'])
503514
def get(self, filename, destination="."):
504515
transfer_cmd = [
505-
"scp",
516+
self._scp,
517+
"-S", self._ssh,
506518
*self.ssh_prefix,
507519
"-P", str(self.networkservice.port),
508520
"-r",
@@ -530,7 +542,7 @@ def get(self, filename, destination="."):
530542

531543
def _cleanup_own_master(self):
532544
"""Exit the controlmaster and delete the tmpdir"""
533-
complete_cmd = f"ssh -x -o ControlPath={self.control.replace('%', '%%')} -O exit -p {self.networkservice.port} -l {self._get_username()} {self.networkservice.address}".split(' ') # pylint: disable=line-too-long
545+
complete_cmd = f"{self._ssh} -x -o ControlPath={self.control.replace('%', '%%')} -O exit -p {self.networkservice.port} -l {self._get_username()} {self.networkservice.address}".split(' ') # pylint: disable=line-too-long
534546
res = subprocess.call(
535547
complete_cmd,
536548
stdin=subprocess.DEVNULL,
@@ -547,7 +559,7 @@ def _cleanup_own_master(self):
547559

548560
def _start_keepalive(self):
549561
"""Starts a keepalive connection via the own or external master."""
550-
args = ["ssh", *self.ssh_prefix, self.networkservice.address, "cat"]
562+
args = [self._ssh, *self.ssh_prefix, self.networkservice.address, "cat"]
551563

552564
assert self._keepalive is None
553565
self._keepalive = subprocess.Popen(

labgrid/remote/client.py

+11-4
Original file line numberDiff line numberDiff line change
@@ -448,9 +448,13 @@ def _check_allowed(self, place):
448448
if f"{self.gethostname()}/{self.getuser()}" not in place.allowed:
449449
host, user = place.acquired.split("/")
450450
if user != self.getuser():
451-
raise UserError(f"place {place.name} is not acquired by your user, acquired by {user}")
451+
raise UserError(
452+
f"place {place.name} is not acquired by your user, acquired by {user}. To work simultaneously, {user} can execute labgrid-client -p {place.name} allow {self.gethostname()}/{self.getuser()}"
453+
)
452454
if host != self.gethostname():
453-
raise UserError(f"place {place.name} is not acquired on this computer, acquired on {host}")
455+
raise UserError(
456+
f"place {place.name} is not acquired on this computer, acquired on {host}. To allow this host, use labgrid-client -p {place.name} allow {self.gethostname()}/{self.getuser()} on the other host"
457+
)
454458

455459
def get_place(self, place=None):
456460
pattern = place or self.args.place
@@ -468,7 +472,10 @@ def get_place(self, place=None):
468472
def get_idle_place(self, place=None):
469473
place = self.get_place(place)
470474
if place.acquired:
471-
raise UserError(f"place {place.name} is not idle (acquired by {place.acquired})")
475+
_, user = place.acquired.split("/")
476+
raise UserError(
477+
f"place {place.name} is not idle (acquired by {place.acquired}). To work simultaneously, {user} can execute labgrid-client -p {place.name} allow {self.gethostname()}/{self.getuser()}"
478+
)
472479
return place
473480

474481
def get_acquired_place(self, place=None):
@@ -1425,7 +1432,7 @@ async def create_reservation(self):
14251432
raise UserError(f"'{pair}' is not a valid filter (must contain a '=')")
14261433
if not TAG_KEY.match(k):
14271434
raise UserError(f"Key '{k}' in filter '{pair}' is invalid")
1428-
if not TAG_KEY.match(v):
1435+
if not TAG_VAL.match(v):
14291436
raise UserError(f"Value '{v}' in filter '{pair}' is invalid")
14301437
fltr[k] = v
14311438

0 commit comments

Comments
 (0)