Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions labgrid/driver/sshdriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,24 +356,31 @@ def forward_unix_socket(self, unixsocket, localport=None):
yield localport

@Driver.check_active
@step(args=['src', 'dst'])
def scp(self, *, src, dst):
@step(args=['src', 'dst', 'recursive'])
def scp(self, *, src, dst, recursive=False):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to consider backwards compatibility here. So, if src is a string, wrap it in a list.

if not self._check_keepalive():
raise ExecutionError("Keepalive no longer running")

if src.startswith(':') == dst.startswith(':'):
raise ValueError("Either source or destination must be remote (start with :)")
if src.startswith(':'):
src = '_' + src
if dst.startswith(':'):
if all([f.startswith(':') for f in src]):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to check that either all src elements start with ':' or none of them do.

So perhaps first something like

remote_src = [f.startswith(':') for f in src]
if any(remote_src) != all(remote_src):
   raise ValueError("All sources must be consistently local or remote (start with :)")

before the other checks?

if dst.startswith(':'):
raise ValueError("Either source or destination must be remote (start with :)")
src = ['_' + f for f in src]
else:
if not dst.startswith(':'):
raise ValueError("Either source or destination must be remote (start with :)")
dst = '_' + dst

complete_cmd = [self._scp,
"-S", self._ssh,
"-F", "none",
"-o", f"ControlPath={self.control.replace('%', '%%')}",
src, dst,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use *src to avoid the insert loop below.

dst,
]
for f in src:
complete_cmd.insert(-1, f)

if recursive:
complete_cmd.insert(1, "-r")

if self.explicit_sftp_mode and self._scp_supports_explicit_sftp_mode():
complete_cmd.insert(1, "-s")
Expand Down
40 changes: 15 additions & 25 deletions labgrid/remote/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ class ServerError(Error):


class InteractiveCommandError(Error):
pass
def __init__(self: Error, msg: str, exitcode: int):
super(InteractiveCommandError, self).__init__(msg)
self.exitcode = exitcode


@attr.s(eq=False)
Expand Down Expand Up @@ -1049,9 +1051,7 @@ async def console(self, place, target):
break
if not self.args.loop:
if res:
exc = InteractiveCommandError("microcom error")
exc.exitcode = res
raise exc
raise InteractiveCommandError("microcom error", res)
break
await asyncio.sleep(1.0)

Expand Down Expand Up @@ -1251,27 +1251,21 @@ def ssh(self):

res = drv.interact(self.args.leftover)
if res:
exc = InteractiveCommandError("ssh error")
exc.exitcode = res
raise exc
raise InteractiveCommandError("ssh error", res)

def scp(self):
drv = self._get_ssh()

res = drv.scp(src=self.args.src, dst=self.args.dst)
res = drv.scp(src=self.args.files[:-1], dst=self.args.files[-1], recursive=self.args.recursive)
if res:
exc = InteractiveCommandError("scp error")
exc.exitcode = res
raise exc
raise InteractiveCommandError("scp error", res)

def rsync(self):
drv = self._get_ssh()

res = drv.rsync(src=self.args.src, dst=self.args.dst, extra=self.args.leftover)
if res:
exc = InteractiveCommandError("rsync error")
exc.exitcode = res
raise exc
raise InteractiveCommandError("rsync error", res)

def sshfs(self):
drv = self._get_ssh()
Expand Down Expand Up @@ -1309,9 +1303,7 @@ def telnet(self):
args = ["telnet", str(ip)]
res = subprocess.call(args)
if res:
exc = InteractiveCommandError("telnet error")
exc.exitcode = res
raise exc
raise InteractiveCommandError("telnet error", res)

def video(self):
place = self.get_acquired_place()
Expand Down Expand Up @@ -1347,9 +1339,7 @@ def video(self):
else:
res = drv.stream(quality, controls=controls)
if res:
exc = InteractiveCommandError("gst-launch-1.0 error")
exc.exitcode = res
raise exc
raise InteractiveCommandError("gst-launch-1.0 error", res)

def audio(self):
place = self.get_acquired_place()
Expand All @@ -1358,9 +1348,7 @@ def audio(self):
drv = self._get_driver_or_new(target, "USBAudioInputDriver", name=name)
res = drv.play()
if res:
exc = InteractiveCommandError("gst-launch-1.0 error")
exc.exitcode = res
raise exc
raise InteractiveCommandError("gst-launch-1.0 error", res)

def _get_tmc(self):
place = self.get_acquired_place()
Expand Down Expand Up @@ -1934,8 +1922,10 @@ def main():

subparser = subparsers.add_parser("scp", help="transfer file via scp")
subparser.add_argument("--name", "-n", help="optional resource name")
subparser.add_argument("src", help="source path (use :dir/file for remote side)")
subparser.add_argument("dst", help="destination path (use :dir/file for remote side)")
subparser.add_argument("--recursive", "-r", action="store_true", help="copy recursive")
subparser.add_argument(
"files", nargs="+", metavar="SRC/DST", help="source and destination path (use :dir/file for remote side)"
)
Comment on lines -1937 to +1928
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to just use nargs="+" for src and keep the separate dst argument.

subparser.set_defaults(func=ClientSession.scp)

subparser = subparsers.add_parser(
Expand Down
2 changes: 1 addition & 1 deletion man/labgrid-client.1
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ not at all.
.sp
\fBssh\fP \fB[command]\fP Connect via SSH. Additional arguments are passed to ssh.
.sp
\fBscp\fP \fB[source]\fP \fB[destination]\fP Transfer file via scp (use \(aq:dir/file\(aq for the remote side)
\fBscp\fP \fB[sources...]\fP \fB[destination]\fP Transfer file via scp (use \(aq:dir/file\(aq for the remote side)
.sp
\fBrsync\fP \fB[source]\fP \fB[destination]\fP Transfer files via rsync (use \(aq:dir/file\(aq for the remote side)
.sp
Expand Down
2 changes: 1 addition & 1 deletion man/labgrid-client.rst
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ LABGRID-CLIENT COMMANDS

``ssh`` ``[command]`` Connect via SSH. Additional arguments are passed to ssh.

``scp`` ``[source]`` ``[destination]`` Transfer file via scp (use ':dir/file' for the remote side)
``scp`` ``[sources...]`` ``[destination]`` Transfer file via scp (use ':dir/file' for the remote side)

``rsync`` ``[source]`` ``[destination]`` Transfer files via rsync (use ':dir/file' for the remote side)

Expand Down