#!/usr/bin/python3
"""
Assemble a file system tree into a ostree commit
Needs a file system tree that is already conforming to the ostree
system layout[1], specified via the `tree` input and commits it
to a repository. The repository must have been created at `/repo`.
Additional metadata is stored in `/compose.json` which contains
the commit compose information. This is also returned via the
metadata API to osbuild.
[1] https://ostree.readthedocs.io/en/stable/manual/adapting-existing/
"""
import json
import os
import subprocess
import sys
import tempfile
from osbuild import api
from osbuild.util import ostree
SCHEMA_2 = """
"options": {
"additionalProperties": false,
"required": ["ref"],
"properties": {
"ref": {
"description": "OStree ref to create for the commit",
"type": "string",
"default": ""
},
"os_version": {
"description": "Set the version of the OS as commit metadata",
"type": "string"
},
"parent": {
"description": "commit id of the parent commit",
"type": "string"
}
}
},
"inputs": {
"type": "object",
"additionalProperties": false,
"required": ["tree"],
"properties": {
"tree": {
"type": "object",
"additionalProperties": true
}
}
}
"""
def main(inputs, output_dir, options, meta):
tree = inputs["tree"]["path"]
ref = options["ref"]
os_version = options.get("os_version", None)
parent = options.get("parent", None)
# rpm-ostree compose commit wants to consume the commit
# so for now, we copy the whole tree and let it have its
# way
with tempfile.TemporaryDirectory(dir=output_dir) as root:
subprocess.run(["cp", "--reflink=auto", "-a",
f"{tree}/.", root],
check=True)
repo = os.path.join(output_dir, "repo")
treefile = ostree.Treefile()
treefile["ref"] = ref
argv = ["rpm-ostree", "compose", "commit"]
argv += [f"--repo={repo}"]
if parent:
argv += [f"--parent={parent}"]
if os_version:
argv += [
f"--add-metadata-string=version={os_version}",
]
argv += [
f"--add-metadata-string=rpmostree.inputhash={meta['id']}",
f"--write-composejson-to={output_dir}/compose.json"
]
with treefile.as_tmp_file() as path:
argv += [path, root]
subprocess.run(argv,
stdout=sys.stderr,
check=True)
with open(os.path.join(output_dir, "compose.json"), "r") as f:
compose = json.load(f)
api.metadata({"compose": compose})
if __name__ == '__main__':
args = api.arguments()
r = main(args["inputs"],
args["tree"],
args["options"],
args["meta"])
sys.exit(r)