summaryrefslogtreecommitdiff
path: root/mdbp/common.py
diff options
context:
space:
mode:
authorHelmut Grohne <helmut@subdivi.de>2021-05-11 14:52:29 +0200
committerHelmut Grohne <helmut@subdivi.de>2021-05-11 14:52:29 +0200
commit9faa39b400a155c9dddeea4fe712301462093d4f (patch)
tree4fbd8cde3a2d85509e3d71a46b3261071f392978 /mdbp/common.py
parent594bd93d1cb04d38c92910e5babb9f353154ebcf (diff)
downloadmdbp-9faa39b400a155c9dddeea4fe712301462093d4f.tar.gz
add ssh remote backend and streamapi wrapper
The ssh backend calls into another host and passes all information on stdin/stdout/stderr. To do so, it uses a streamapi wrapper on the remote side that itself calls into a regular backend.
Diffstat (limited to 'mdbp/common.py')
-rw-r--r--mdbp/common.py36
1 files changed, 30 insertions, 6 deletions
diff --git a/mdbp/common.py b/mdbp/common.py
index 097c7a3..830aad7 100644
--- a/mdbp/common.py
+++ b/mdbp/common.py
@@ -9,6 +9,7 @@ import importlib.resources
import json
import multiprocessing
import pathlib
+import tarfile
import tempfile
import typing
import urllib.parse
@@ -29,15 +30,21 @@ def json_load(filecontextmanager:
JsonObject = typing.Dict[str, typing.Any]
-def buildjson(filename: str) -> JsonObject:
- """Type constructor for argparse validating a build json file path and
- returning the parsed json object."""
- buildobj = json_load(argparse.FileType("r")(filename))
+def buildjson_validate(buildobj: JsonObject) -> None:
+ """Validate the given build json object against the schema."""
if jsonschema:
jsonschema.validate(
buildobj,
json_load(
importlib.resources.open_text("mdbp", "build_schema.json")))
+
+def buildjson_patch_relative(buildobj: JsonObject,
+ basedir: pathlib.PurePath) -> None:
+ """Resolve relative paths used in the buildobj using the given basedir:
+ * .input.dscpath
+ * .output.directory
+ The operation is performed in-place and modifes the given buildobj.
+ """
for attrs in (("input", "dscpath"), ("output", "directory")):
obj = buildobj
for attr in attrs[:-1]:
@@ -47,10 +54,16 @@ def buildjson(filename: str) -> JsonObject:
break
else:
try:
- obj[attrs[-1]] = str(pathlib.Path(filename).parent /
- pathlib.Path(obj[attrs[-1]]))
+ obj[attrs[-1]] = str(basedir / pathlib.Path(obj[attrs[-1]]))
except KeyError:
pass
+
+def buildjson(filename: str) -> JsonObject:
+ """Type constructor for argparse validating a build json file path and
+ returning the parsed json object."""
+ buildobj = json_load(argparse.FileType("r")(filename))
+ buildjson_validate(buildobj)
+ buildjson_patch_relative(buildobj, pathlib.Path(filename).parent)
assert isinstance(buildobj, dict)
return buildobj
@@ -153,3 +166,14 @@ def make_option(optname: str, value: typing.Optional[str]) -> typing.List[str]:
def profile_option(build: JsonObject, optname: str) -> typing.List[str]:
"""Construct the option for specifying build profiles if required."""
return make_option(optname, ",".join(build.get("profiles", ())))
+
+def tar_add(tarobj: tarfile.TarFile, path: pathlib.Path) -> None:
+ """Add the given file as its basename to the tarobj retaining its
+ modification time, but no mode or ownership information.
+ """
+ info = tarfile.TarInfo(path.name)
+ statres = path.stat()
+ info.size = statres.st_size
+ info.mtime = int(statres.st_mtime)
+ with path.open("rb") as fobj:
+ tarobj.addfile(info, fobj)