osbuild/util: hoist ostree code into util/ostree

Prep for sharing with other stages later.
This commit is contained in:
Dusty Mabe 2023-09-28 16:52:31 -04:00 committed by Simon de Vlieger
parent 34d3471fdd
commit 4e99e80c4a
9 changed files with 57 additions and 120 deletions

View file

@ -153,6 +153,25 @@ def show(repo: PathLike, checksum: str) -> str:
return msg
def cli(*args, _input=None, **kwargs):
"""Thin wrapper for running the ostree CLI"""
args = list(args) + [f'--{k}={v}' for k, v in kwargs.items()]
print("ostree " + " ".join(args), file=sys.stderr)
subprocess.run(["ostree"] + args,
encoding="utf8",
stdout=sys.stderr,
input=_input,
check=True)
def parse_input_commits(commits):
"""Parse ostree input commits and return the repo path and refs specified"""
data = commits["data"]
refs = data["refs"]
assert refs, "Need at least one commit"
return commits["path"], data["refs"]
def deployment_path(root: PathLike, osname: str, ref: str, serial: int):
"""Return the path to a deployment given the parameters"""

View file

@ -11,10 +11,10 @@ See `ostree.repo-config(5)` for more information.
"""
import os
import subprocess
import sys
import osbuild.api
from osbuild.util import ostree
SCHEMA = """
"additionalProperties": false,
@ -51,28 +51,18 @@ SCHEMA = """
"""
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="utf8",
stdout=sys.stderr,
input=_input,
check=True)
def main(tree, options):
repo = os.path.join(tree, options["repo"].lstrip("/"))
sysroot_options = options["config"].get("sysroot", {})
bootloader = sysroot_options.get("bootloader")
if bootloader:
ostree("config", "set", "sysroot.bootloader", bootloader, repo=repo)
ostree.cli("config", "set", "sysroot.bootloader", bootloader, repo=repo)
readonly = sysroot_options.get("readonly")
if readonly is not None: # can be False, which we would want to set
ro = "true" if readonly else "false"
ostree("config", "set", "sysroot.readonly", ro, repo=repo)
ostree.cli("config", "set", "sysroot.readonly", ro, repo=repo)
if __name__ == '__main__':

View file

@ -20,10 +20,10 @@ the sysroot and the deployments. Additional kernel options can be passed via
"""
import os
import subprocess
import sys
import osbuild.api
from osbuild.util import ostree
from osbuild.util.mnt import MountGuard
CAPABILITIES = ["CAP_MAC_ADMIN"]
@ -85,16 +85,6 @@ SCHEMA_2 = """
"""
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="utf8",
stdout=sys.stderr,
input=_input,
check=True)
def make_fs_identifier(desc):
for key in ["uuid", "label"]:
val = desc.get(key)
@ -129,10 +119,10 @@ def main(tree, options):
path = os.path.join(tree, path)
mounter.mount(path, path)
ostree("admin", "deploy", ref,
*kargs,
sysroot=tree,
os=osname)
ostree.cli("admin", "deploy", ref,
*kargs,
sysroot=tree,
os=osname)
if __name__ == '__main__':

View file

@ -10,10 +10,10 @@ See the ostree-init(1) man page for more details.
"""
import os
import subprocess
import sys
import osbuild.api
from osbuild.util import ostree
SCHEMA = """
"additionalProperties": false,
@ -41,13 +41,7 @@ def main(tree, options):
parent = os.path.dirname(repo)
os.makedirs(parent, exist_ok=True)
subprocess.run(["ostree",
"init",
"-v",
f"--mode={mode}",
f"--repo={repo}"],
stdout=sys.stderr,
check=True)
ostree.cli("init", "-v", mode=mode, repo=repo)
if __name__ == '__main__':

View file

@ -6,30 +6,20 @@ Creates the basic file system layout for an OSTree based system.
"""
import subprocess
import sys
import osbuild.api
from osbuild.util import ostree
SCHEMA = """
"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="utf8",
stdout=sys.stderr,
input=_input,
check=True)
def main(tree):
ostree("admin", "init-fs", "--modern", tree,
sysroot=tree)
ostree.cli("admin", "init-fs", "--modern", tree,
sysroot=tree)
return 0

View file

@ -8,10 +8,10 @@ name `osname`.
[1] https://ostree.readthedocs.io/en/latest/manual/deployment/
"""
import subprocess
import sys
import osbuild.api
from osbuild.util import ostree
SCHEMA = """
"required": ["osname"],
@ -24,20 +24,10 @@ SCHEMA = """
"""
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="utf8",
stdout=sys.stderr,
input=_input,
check=True)
def main(tree, options):
osname = options["osname"]
ostree("admin", "os-init", osname, sysroot=tree)
ostree.cli("admin", "os-init", osname, sysroot=tree)
return 0

View file

@ -17,7 +17,7 @@ import os
import sys
import osbuild.api
from osbuild.util.ostree import PasswdLike, SubIdsDB
from osbuild.util import ostree
SCHEMA_2 = """
"options": {
@ -41,24 +41,16 @@ SUBUID_PATH = "etc/subuid"
SUBGID_PATH = "etc/subgid"
def parse_input(inputs):
commits = inputs["commits"]
source_root = commits["path"]
data = commits["data"]
refs = data["refs"]
assert refs, "Need at least one commit"
assert len(refs) == 1, "Only one commit is currently supported"
return source_root, refs
# pylint: disable=too-many-statements
def main(tree, inputs, _options):
source_root, refs = parse_input(inputs)
source_root, refs = ostree.parse_input_commits(inputs["commits"])
assert refs, "Need at least one commit"
assert len(refs) == 1, "Only one commit is currently supported"
os.makedirs(os.path.join(tree, "etc"), exist_ok=True)
subuids = SubIdsDB()
subgids = SubIdsDB()
subuids = ostree.SubIdsDB()
subgids = ostree.SubIdsDB()
# Only once ref (commit) is currently supported, so this loop will run exactly once
for commit, data in refs.items():
@ -68,14 +60,14 @@ def main(tree, inputs, _options):
# Merge /usr/etc/passwd with /usr/lib/passwd from the checkout and store it in the buildroot
# "tree" directory. Entries in /usr/etc/passwd have a precedence, but the file does not
# necessarily exist.
passwd = PasswdLike.from_file(os.path.join(checkout_root, "usr/etc/passwd"), allow_missing_file=True)
passwd = ostree.PasswdLike.from_file(os.path.join(checkout_root, "usr/etc/passwd"), allow_missing_file=True)
passwd.merge_with_file(os.path.join(checkout_root, "usr/lib/passwd"), allow_missing_file=False)
passwd.dump_to_file(os.path.join(tree, "etc/passwd"))
# Merge /usr/etc/group with /usr/lib/group from the checkout and store it in the buildroot
# "tree" directory. Entries in /usr/etc/group have a precedence, but the file does not
# necessarily exist.
passwd = PasswdLike.from_file(os.path.join(checkout_root, "usr/etc/group"), allow_missing_file=True)
passwd = ostree.PasswdLike.from_file(os.path.join(checkout_root, "usr/etc/group"), allow_missing_file=True)
passwd.merge_with_file(os.path.join(checkout_root, "usr/lib/group"), allow_missing_file=False)
passwd.dump_to_file(os.path.join(tree, "etc/group"))

View file

@ -12,10 +12,10 @@ that to pull the commits.
import os
import subprocess
import sys
import osbuild.api
from osbuild.util import ostree
CAPABILITIES = ["CAP_MAC_ADMIN"]
@ -49,27 +49,9 @@ SCHEMA_2 = """
"""
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="utf8",
stdout=sys.stderr,
input=_input,
check=True)
def parse_input(inputs):
commits = inputs["commits"]
data = commits["data"]
refs = data["refs"]
assert refs, "Need at least one commit"
return commits["path"], data["refs"]
# pylint: disable=too-many-statements
def main(tree, inputs, options):
source_repo, commits = parse_input(inputs)
source_repo, commits = ostree.parse_input_commits(inputs["commits"])
repo = options["repo"]
remote = options.get("remote")
target = os.path.join(tree, repo.lstrip("/"))
@ -81,9 +63,9 @@ def main(tree, inputs, options):
if remote:
extra_args.append(f'--remote={remote}')
ostree("pull-local", source_repo, ref,
*extra_args,
repo=target)
ostree.cli("pull-local", source_repo, ref,
*extra_args,
repo=target)
if __name__ == '__main__':

View file

@ -5,10 +5,10 @@ Configure OSTree remotes for a repository.
import os
import subprocess
import sys
import osbuild.api
from osbuild.util import ostree
SCHEMA = """
"additionalProperties": false,
@ -66,16 +66,6 @@ SCHEMA = """
"""
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="utf8",
stdout=sys.stderr,
input=_input,
check=True)
def main(tree, options):
repo = options["repo"]
remotes = options.get("remotes", [])
@ -101,17 +91,17 @@ def main(tree, options):
if contenturl:
extra_args.append(f"--set=contenturl={contenturl}")
ostree("remote", "add",
"--if-not-exists",
*extra_args,
name, url,
*branches,
repo=target)
ostree.cli("remote", "add",
"--if-not-exists",
*extra_args,
name, url,
*branches,
repo=target)
for key in gpgkeys:
ostree("remote", "gpg-import", "--stdin", name,
repo=target,
_input=key)
ostree.cli("remote", "gpg-import", "--stdin", name,
repo=target,
_input=key)
if __name__ == '__main__':