summaryrefslogtreecommitdiff
path: root/mdbp/ssh.py
diff options
context:
space:
mode:
Diffstat (limited to 'mdbp/ssh.py')
-rw-r--r--mdbp/ssh.py73
1 files changed, 73 insertions, 0 deletions
diff --git a/mdbp/ssh.py b/mdbp/ssh.py
new file mode 100644
index 0000000..8af6bde
--- /dev/null
+++ b/mdbp/ssh.py
@@ -0,0 +1,73 @@
+#!/usr/bin/python3
+# SPDX-License-Identifier: MIT
+"""mdbp backend wrapper via ssh"""
+
+import argparse
+import io
+import json
+import pathlib
+import subprocess
+import sys
+import tarfile
+import typing
+
+from .common import JsonObject, buildjson, get_dsc_files, tar_add
+
+def produce_request_tar(buildjsonobj: JsonObject,
+ fileobj: typing.IO[bytes]) -> None:
+ """Write a tar file suitable for mdbp-streamapi into the given `fileobj`
+ based on the given `buildjsonobj`.
+ * An .output.directory is discarded.
+ * A referenced .dsc file and its components is included.
+ """
+ sendjsonobj = buildjsonobj.copy()
+ sendjsonobj["output"] = sendjsonobj["output"].copy()
+ del sendjsonobj["output"]["directory"]
+ dscpath: typing.Optional[pathlib.Path]
+ try:
+ dscpath = pathlib.Path(buildjsonobj["input"]["dscpath"])
+ except KeyError:
+ dscpath = None
+ else:
+ sendjsonobj["input"] = sendjsonobj["input"].copy()
+ sendjsonobj["input"]["dscpath"] = dscpath.name
+ tar = tarfile.open(mode="w|", fileobj=fileobj)
+ info = tarfile.TarInfo("build.json")
+ sendjsonfile = io.BytesIO()
+ for chunk in json.JSONEncoder().iterencode(sendjsonobj):
+ sendjsonfile.write(chunk.encode("utf8"))
+ info.size = sendjsonfile.tell()
+ sendjsonfile.seek(0)
+ tar.addfile(info, sendjsonfile)
+ if dscpath:
+ for path in [dscpath] + get_dsc_files(dscpath):
+ tar_add(tar, path)
+
+def main() -> None:
+ """Entry point for mdbp-ssh backend"""
+ parser = argparse.ArgumentParser()
+ parser.add_argument("host", type=str)
+ parser.add_argument("command", nargs=argparse.REMAINDER)
+ args = parser.parse_args()
+ if len(args.command) < 2:
+ parser.error("missing command or json file")
+ build = buildjson(args.command.pop())
+
+ cmd = ["ssh", args.host, "mdbp-streamapi", *args.command]
+ proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+ stderr=sys.stdout
+ if build["output"].get("log", True)
+ else subprocess.DEVNULL)
+ assert proc.stdin is not None
+ produce_request_tar(build, proc.stdin)
+ proc.stdin.close()
+ with tarfile.open(fileobj=proc.stdout, mode="r|") as outtar:
+ for member in outtar:
+ if "/" in member.name or not member.isfile():
+ raise ValueError("expected flat tar as output")
+ outtar.extract(member, build["output"]["directory"],
+ set_attrs=False)
+ sys.exit(proc.wait())
+
+if __name__ == "__main__":
+ main()