From 3695e223691d959a999afa81f88dafcb9825bfa6 Mon Sep 17 00:00:00 2001 From: Christian Kellner Date: Thu, 11 Mar 2021 12:09:44 +0000 Subject: [PATCH] inputs: add org.osbuild.ostree.checkout New input type that takes a ostree repo and checks out any number of commits inside that repo to a temporary directory. Each commit will be checked out to a separate sub-directory. The name of the dir is the commit id of the corresponding commit. This input can thus be used to access files and directories of commits in stages. --- inputs/org.osbuild.ostree.checkout | 114 +++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100755 inputs/org.osbuild.ostree.checkout diff --git a/inputs/org.osbuild.ostree.checkout b/inputs/org.osbuild.ostree.checkout new file mode 100755 index 00000000..c1ffee8a --- /dev/null +++ b/inputs/org.osbuild.ostree.checkout @@ -0,0 +1,114 @@ +#!/usr/bin/python3 +""" +Inputs for checkouts of ostree commits + +This input takes a number of commits and will check them out to a +temporary directory. The name of the directory is the commit id. +Internally uses `ostree checkout` +""" + + +import os +import json +import sys +import subprocess + +from osbuild import inputs + + +SCHEMA = """ +"additionalProperties": false, +"required": ["type", "origin", "references"], +"properties": { + "type": { + "enum": ["org.osbuild.ostree.checkout"] + }, + "origin": { + "description": "The origin of the input", + "type": "string", + "enum": ["org.osbuild.source", "org.osbuild.pipeline"] + }, + "references": { + "description": "Commit identifier to check out", + "oneOf": [{ + "type": "array", + "items": { + "type": "string" + } + }, { + "type": "object", + "additionalProperties": false, + "minProperties": 1, + "patternProperties": { + ".*": { + "type": "object", + "additionalProperties": false + } + } + }] + } +} +""" + + +def ostree(*args, _input=None, **kwargs): + args = list(args) + [f'--{k}={v}' for k, v in kwargs.items()] + print("ostree " + " ".join(args), file=sys.stderr) + subprocess.run(["ostree"] + args, + encoding="utf-8", + stdout=sys.stderr, + input=_input, + check=True) + + +def checkout(checksums, cache, output): + repo_cache = os.path.join(cache, "repo") + + refs = [] + for commit in checksums: + print(f"checkout {commit}", file=sys.stderr) + + dest = os.path.join(output, commit) + + ostree("checkout", commit, dest, + repo=repo_cache) + + refs.append(commit) + + return refs + + +class OSTreeCheckoutInput(inputs.InputService): + + def map(self, store, origin, refs, target, _options): + + refs = [] + + if origin == "org.osbuild.pipeline": + for ref, options in refs.items(): + source = store.read_tree(ref) + with open(os.path.join(source, "compose.json"), "r") as f: + compose = json.load(f) + commit_id = compose["ostree-commit"] + refs.append(checkout({commit_id: options}, source, target)) + else: + source = store.source("org.osbuild.ostree") + refs = checkout(refs, source, target) + + reply = { + "path": target, + "data": { + "refs": {ref: {"path": ref} for ref in refs} + } + } + + return reply + + +def main(): + service = OSTreeCheckoutInput.from_args(sys.argv[1:]) + service.main() + + +if __name__ == '__main__': + main()