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.
153 lines
3.5 KiB
Python
Executable file
153 lines
3.5 KiB
Python
Executable file
#!/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 os
|
|
import json
|
|
import sys
|
|
import subprocess
|
|
|
|
from osbuild import inputs
|
|
|
|
|
|
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 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 export(checksums, cache, output):
|
|
repo_cache = os.path.join(cache, "repo")
|
|
|
|
repo_out = os.path.join(output, "repo")
|
|
ostree("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("pull-local", repo_cache, commit,
|
|
repo=repo_out)
|
|
|
|
ref = options.get("ref")
|
|
if ref:
|
|
ostree("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") 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()
|