debian-forge/inputs/org.osbuild.ostree.checkout
Christian Kellner 99abc1373d inputs: support array of objects references
This extends the possible ways of passing references to inputs. The
current ways possible are:
 1) "plain references", an array of strings:
    ["ref1", "ref2", ...]
 2) "object references", a mapping of keys to objects:
    {"ref1": { <options> }, "ref2": { <options> }, ...}

This patch adds a new way:
  3) "array of object references":
    [{"id": "ref1", "options": { ... }}, {"id": ... }, ]

While osbuild promises to preserves the order for "object references"
not all JSON serialization libraries preserve the order since the
JSON specification does leave this up to the implementation.

The new "array of object references" thus allows for specifying the
references together with reference specific options and this in a
specific order.

Additionally this paves the way for specifying the same input twice,
e.g. in the case of the `org.osbuild.files` input where a pipeline
could then be specified twice with different files. This needs core
rework though, since internally we use dictionaries right now.
2022-04-21 16:39:58 +02:00

132 lines
3 KiB
Python
Executable file

#!/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
}
}
}, {
"type": "array",
"additionalItems": false,
"minItems": 1,
"items": [{
"type": "object",
"additionalProperties": false,
"required": ["id"],
"properties": {
"id": {
"type": "string"
},
"options": {
"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):
ids = []
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"]
ids.append(checkout({commit_id: options}, source, target))
else:
source = store.source("org.osbuild.ostree")
ids = checkout(refs, source, target)
reply = {
"path": target,
"data": {
"refs": {i: {"path": i} for i in ids}
}
}
return reply
def main():
service = OSTreeCheckoutInput.from_args(sys.argv[1:])
service.main()
if __name__ == '__main__':
main()