ostree: add convenience function for using default OSTree deployment

This adds a `default: true` option for all cases where OSTree
information is specified in schemas and allows for the information
to be picked up from the filesystem.

This is a safe operation because when building disk images there is
no known case where having two deployments makes sense. In the case
there ever were a case then the osname, ref, and serial options still
exist and can be used.

Co-authored-by: Luke Yang <luyang@redhat.com>
Co-authored-by: Michael Vogt <michael.vogt@gmail.com>
This commit is contained in:
Dusty Mabe 2024-01-25 13:57:51 -05:00
parent 2021b915f1
commit e1cbf92673
11 changed files with 264 additions and 49 deletions

View file

@ -32,7 +32,26 @@ SCHEMA_2 = r"""
"deployment": {
"type": "object",
"additionalProperties": false,
"required": ["osname", "ref"],
"oneOf": [
{
"properties": {
"default": {"enum": [false]}
},
"required": ["osname", "ref"]
},
{
"properties": {
"default": {"enum": [true]}
},
"not": {
"anyOf": [
{"required": ["osname"]},
{"required": ["ref"]},
{"required": ["serial"]}
]
}
}
],
"properties": {
"osname": {
"description": "Name of the stateroot to be used in the deployment",
@ -46,6 +65,11 @@ SCHEMA_2 = r"""
"description": "The deployment serial (usually '0')",
"type": "number",
"default": 0
},
"default": {
"description": "Find and use the default ostree deployment",
"type": "boolean",
"default": false
}
}
},
@ -101,9 +125,7 @@ def main(args, options):
# we'll call ostree.deployment_path() helper to find it for us.
root = mounts
if deployment:
osname = deployment["osname"]
ref = deployment["ref"]
serial = deployment.get("serial", 0)
osname, ref, serial = ostree.parse_deployment_option(mounts, deployment)
root = ostree.deployment_path(mounts, osname, ref, serial)
bootupd_args = []

View file

@ -29,7 +29,26 @@ SCHEMA = """
"deployment": {
"type": "object",
"additionalProperties": false,
"required": ["osname","ref"],
"oneOf": [
{
"properties": {
"default": {"enum": [false]}
},
"required": ["osname", "ref"]
},
{
"properties": {
"default": {"enum": [true]}
},
"not": {
"anyOf": [
{"required": ["osname"]},
{"required": ["ref"]},
{"required": ["serial"]}
]
}
}
],
"properties": {
"osname": {
"description": "Name of the stateroot to be used in the deployment",
@ -43,6 +62,11 @@ SCHEMA = """
"description": "The deployment serial (usually '0')",
"type": "number",
"default": 0
},
"default": {
"description": "Find and use the default ostree deployment",
"type": "boolean",
"default": false
}
}
}
@ -118,9 +142,7 @@ def main(tree, options):
if ostree_options:
deployment = ostree_options["deployment"]
osname = deployment["osname"]
ref = deployment["ref"]
serial = deployment.get("serial", 0)
osname, ref, serial = ostree.parse_deployment_option(tree, deployment)
root = ostree.deployment_path(tree, osname, ref, serial)

View file

@ -19,6 +19,7 @@ COREOS_ALEPH_FILENAME = ".coreos-aleph-version.json"
SCHEMA_2 = """
"options": {
"additionalProperties": false,
"required": ["deployment"],
"properties": {
"coreos_compat": {
"description": "boolean to allow for CoreOS aleph version backwards compatibility",
@ -26,7 +27,26 @@ SCHEMA_2 = """
},
"deployment": {
"additionalProperties": false,
"required": ["osname", "ref"],
"oneOf": [
{
"properties": {
"default": {"enum": [false]}
},
"required": ["osname", "ref"]
},
{
"properties": {
"default": {"enum": [true]}
},
"not": {
"anyOf": [
{"required": ["osname"]},
{"required": ["ref"]},
{"required": ["serial"]}
]
}
}
],
"properties": {
"osname": {
"description": "Name of the stateroot to be used in the deployment",
@ -40,6 +60,11 @@ SCHEMA_2 = """
"description": "The deployment serial (usually '0')",
"type": "number",
"default": 0
},
"default": {
"description": "Find and use the default ostree deployment",
"type": "boolean",
"default": false
}
}
}
@ -131,9 +156,7 @@ def construct_aleph_json(tree, origin):
def main(tree, options):
coreos_compat = options.get("coreos_compat", False)
dep = options["deployment"]
osname = dep["osname"]
ref = dep["ref"]
serial = dep.get("serial", 0)
osname, ref, serial = ostree.parse_deployment_option(tree, dep)
origin = ostree.deployment_path(tree, osname, ref, serial) + ".origin"
data = construct_aleph_json(tree, origin)

View file

@ -18,7 +18,26 @@ SCHEMA = """
"properties": {
"deployment": {
"additionalProperties": false,
"required": ["osname", "ref"],
"oneOf": [
{
"properties": {
"default": {"enum": [false]}
},
"required": ["osname", "ref"]
},
{
"properties": {
"default": {"enum": [true]}
},
"not": {
"anyOf": [
{"required": ["osname"]},
{"required": ["ref"]},
{"required": ["serial"]}
]
}
}
],
"properties": {
"osname": {
"description": "Name of the stateroot to be used in the deployment",
@ -32,6 +51,11 @@ SCHEMA = """
"description": "The deployment serial (usually '0')",
"type": "number",
"default": 0
},
"default": {
"description": "Find and use the default ostree deployment",
"type": "boolean",
"default": false
}
}
}
@ -71,9 +95,7 @@ def populate_var(sysroot):
def main(tree, options):
dep = options["deployment"]
osname = dep["osname"]
ref = dep["ref"]
serial = dep.get("serial", 0)
osname, ref, serial = ostree.parse_deployment_option(tree, dep)
deployment = ostree.deployment_path(tree, osname, ref, serial)
var = os.path.join(tree, "ostree", "deploy", osname, "var")

View file

@ -21,7 +21,26 @@ SCHEMA = """
"properties": {
"deployment": {
"additionalProperties": false,
"required": ["osname", "ref"],
"oneOf": [
{
"properties": {
"default": {"enum": [false]}
},
"required": ["osname", "ref"]
},
{
"properties": {
"default": {"enum": [true]}
},
"not": {
"anyOf": [
{"required": ["osname"]},
{"required": ["ref"]},
{"required": ["serial"]}
]
}
}
],
"properties": {
"osname": {
"description": "Name of the stateroot to be used in the deployment",
@ -35,6 +54,11 @@ SCHEMA = """
"description": "The deployment serial (usually '0')",
"type": "number",
"default": 0
},
"default": {
"description": "Find and use the default ostree deployment",
"type": "boolean",
"default": false
}
}
}
@ -44,9 +68,7 @@ SCHEMA = """
def main(tree, options):
dep = options["deployment"]
osname = dep["osname"]
ref = dep["ref"]
serial = dep.get("serial", 0)
osname, ref, serial = ostree.parse_deployment_option(tree, dep)
# this created a state root at `osname`
stateroot = f"{tree}/ostree/deploy/{osname}"

View file

@ -12,10 +12,17 @@ STAGE_NAME = "org.osbuild.bootupd"
@pytest.mark.parametrize("test_data,expected_err", [
# bad
({"deployment": "must-be-object"}, "'must-be-object' is not of type 'object'"),
({"deployment": {"osname": "some-os"}}, "'ref' is a required property"),
({"deployment": {"ref": "some-ref"}}, "'osname' is a required property"),
({"deployment": {"osname": "some-os"}}, "{'osname': 'some-os'} is not valid under any of the given schemas"),
({"deployment": {"ref": "some-ref"}}, "{'ref': 'some-ref'} is not valid under any of the given schemas"),
({"deployment": {"osname": "some-os", "ref": "some-ref", "serial": "must-be-number"}},
"'must-be-number' is not of type 'number'"),
({"deployment": {"default": False}}, "{'default': False} is not valid under any of the given schemas"),
({"deployment": {
"osname": "some-os",
"ref": "some-ref",
"serial": 0,
"default": True}
}, "{'osname': 'some-os', 'ref': 'some-ref', 'serial': 0, 'default': True} is not valid under any of the given schemas"),
({"random": "property"}, "Additional properties are not allowed"),
({"bios": {}}, "'device' is a required property"),
({"bios": "must-be-object"}, "'must-be-object' is not of type 'object'"),
@ -33,6 +40,17 @@ STAGE_NAME = "org.osbuild.bootupd"
{
"device": "/dev/sda",
},
}, ""),
({
"deployment":
{
"default": True,
},
"static-configs": True,
"bios":
{
"device": "/dev/sda",
},
}, "")
])