pipeline: deliver stage arguments via a file

Instead of using the jsoncomm API to transmit stagge arguments,
write them out to a file that is then mapped into the container.
The `api.arguments` function is re-written just read that file
from within the container.
This commit is contained in:
Christian Kellner 2021-07-08 07:27:26 +00:00 committed by Tom Gundersen
parent 82d33a35ae
commit affd384669
2 changed files with 34 additions and 30 deletions

View file

@ -207,32 +207,11 @@ def exception_handler(path="/run/osbuild/api/osbuild"):
exception(e, path)
def arguments(path="/run/osbuild/api/osbuild"):
def arguments(path="/run/osbuild/api/arguments"):
"""Retrieve the input arguments that were supplied to API"""
with jsoncomm.Socket.new_client(path) as client:
req = {"method": "get-arguments"}
client.send(req)
msg, fds, _ = client.recv()
assert msg["type"] == "fd"
fd = msg["fd"]
with os.fdopen(fds.steal(fd), encoding="utf-8") as f:
data = json.load(f)
# Root relative paths: since paths are different on the
# host and in the container they are transmitted not as
# absolute but relative paths. For all items that have
# registered roots, re-root their path entries here
for name, root in data.get("paths", {}).items():
group = data.get(name)
if not group or not isinstance(group, dict):
continue
for item in group.values():
path = item.get("path")
if not path:
continue
item["path"] = os.path.join(root, path)
return data
with open(path, "r", encoding="utf-8") as fp:
data = json.load(fp)
return data
def metadata(data: Dict, path="/run/osbuild/api/osbuild"):

View file

@ -79,6 +79,29 @@ class Stage:
self.mounts[name] = mount
return mount
def prepare_arguments(self, args, location):
args["options"] = self.options
args["meta"] = {
"id": self.id
}
# Root relative paths: since paths are different on the
# host and in the container they need to be mapped to
# their path within the container. For all items that
# have registered roots, re-root their path entries here
for name, root in args.get("paths", {}).items():
group = args.get(name)
if not group or not isinstance(group, dict):
continue
for item in group.values():
path = item.get("path")
if not path:
continue
item["path"] = os.path.join(root, path)
with open(location, "w", encoding="utf-8") as fp:
json.dump(args, fp)
def run(self, tree, runner, build_tree, store, monitor, libdir):
with contextlib.ExitStack() as cm:
@ -101,9 +124,11 @@ class Stage:
mounts_mapped = "/run/osbuild/mounts"
mounts = {}
os.makedirs(os.path.join(tmpdir, "api"))
args_path = os.path.join(tmpdir, "api", "arguments")
args = {
"tree": "/run/osbuild/tree",
"options": self.options,
"paths": {
"devices": devices_mapped,
"inputs": inputs_mapped,
@ -112,14 +137,12 @@ class Stage:
"devices": devices,
"inputs": inputs,
"mounts": mounts,
"meta": {
"id": self.id
}
}
ro_binds = [
f"{self.info.path}:/run/osbuild/bin/{self.name}",
f"{inputs_tmpdir}:{inputs_mapped}"
f"{inputs_tmpdir}:{inputs_mapped}",
f"{args_path}:/run/osbuild/api/arguments"
]
binds = [
@ -147,6 +170,8 @@ class Stage:
data = mount.mount(mgr, abspath, mounts_tmpdir)
mounts[key] = data
self.prepare_arguments(args, args_path)
api = API(args)
build_root.register_api(api)