#!/usr/bin/python3 """ Inputs for ostree commits Pull the commits specified by `references` into a newly created repository. Optionally, if `ref` was specified, create an new reference for that commit. The returned data in `refs` is a dictionary where the keys are commit ids and the values are dictionaries. The latter will contain `ref` it was specified. """ import json import os import sys from osbuild import inputs from osbuild.util import ostree SCHEMA = """ "definitions": { "options": { "type": "object", "additionalProperties": false, "properties": { "ref": { "type": "string", "description": "OSTree reference to create for this commit" } } } }, "additionalProperties": false, "required": ["type", "origin", "references"], "properties": { "type": { "enum": ["org.osbuild.ostree"] }, "origin": { "description": "The origin of the input (pipeline or source)", "type": "string", "enum": ["org.osbuild.source", "org.osbuild.pipeline"] }, "references": { "description": "Commit identifier", "oneOf": [{ "type": "array", "minItems": 1, "items": { "type": "string" } }, { "type": "object", "additionalProperties": false, "minProperties": 1, "patternProperties": { ".*": { "$ref": "#/definitions/options" } } }, { "type": "array", "additionalItems": false, "minItems": 1, "maxItems": 1, "items": [{ "type": "object", "additionalProperties": false, "required": ["id"], "properties": { "id": { "type": "string" }, "options": { "$ref": "#/definitions/options" } } }] }] } } """ def export(checksums, cache, output): repo_cache = os.path.join(cache, "repo") repo_out = os.path.join(output, "repo") ostree.cli("init", mode="archive", repo=repo_out) refs = {} for commit, options in checksums.items(): # Transfer the commit: remote → cache print(f"exporting {commit}", file=sys.stderr) ostree.cli("pull-local", repo_cache, commit, repo=repo_out) ref = options.get("ref") if ref: ostree.cli("refs", "--create", ref, commit, repo=repo_out) refs[commit] = options reply = { "path": repo_out, "data": { "refs": refs } } return reply class OSTreeInput(inputs.InputService): def map(self, store, origin, refs, target, _options): 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", encoding="utf8") as f: compose = json.load(f) commit_id = compose["ostree-commit"] reply = export({commit_id: options}, source, target) else: source = store.source("org.osbuild.ostree") reply = export(refs, source, target) return reply def main(): service = OSTreeInput.from_args(sys.argv[1:]) service.main() if __name__ == '__main__': main()