From 2a9cdde5ec8392f3f70ca88d751b6cbe63f7386f Mon Sep 17 00:00:00 2001 From: Christian Kellner Date: Thu, 28 May 2020 17:26:50 +0200 Subject: [PATCH] osbuild: refactor stage information For all currently supported modules, i.e. stages and assemblers, convert the STAGE_DESC and STAGE_INFO into a proper doc-string. Rename the STAGE_OPTS into SCHEMA. Refactor meta.ModuleInfo loading accordingly. The script to be used for the conversion is: --- 8< --- 8< --- 8< --- 8< --- 8< --- 8< --- 8< --- 8< --- import os import sys import osbuild import osbuild.meta from osbuild.meta import ModuleInfo def find_line(lines, start): for i, l in enumerate(lines): if l.startswith(start): return i return None def del_block(lines, prefix): start = find_line(lines, prefix) end = find_line(lines[start:], '"""') print(start, end) del lines[start:start+end+1] def main(): index = osbuild.meta.Index(os.curdir) modules = [] for klass in ("Stage", "Assembler"): mods = index.list_modules_for_class(klass) modules += [(klass, module) for module in mods] for m in modules: print(m) klass, name = m info = ModuleInfo.load(os.curdir, klass, name) module_path = ModuleInfo.module_class_to_directory(klass) path = os.path.join(os.curdir, module_path, name) with open(path, "r") as f: data = list(f.readlines()) i = find_line(data, "STAGE_DESC") print(i) del data[i] del_block(data, "STAGE_INFO") i = find_line(data, "STAGE_OPTS") data[i] = 'SCHEMA = """\n' docstr = '"""\n' + info.desc + "\n" + info.info + '"""\n' doclst = docstr.split("\n") doclst = [l + "\n" for l in doclst] data = [data[0]] + doclst + data[1:] with open(path, "w") as f: f.writelines(data) if __name__ == "__main__": main() --- assemblers/org.osbuild.noop | 14 +++++++------ assemblers/org.osbuild.oci-archive | 30 +++++++++++++++------------- assemblers/org.osbuild.ostree.commit | 26 +++++++++++++----------- assemblers/org.osbuild.qemu | 30 +++++++++++++++------------- assemblers/org.osbuild.rawfs | 22 ++++++++++---------- assemblers/org.osbuild.tar | 16 ++++++++------- osbuild/meta.py | 20 +++++++++++++------ stages/org.osbuild.chrony | 14 +++++++------ stages/org.osbuild.copy | 26 +++++++++++++----------- stages/org.osbuild.debug-shell | 16 ++++++++------- stages/org.osbuild.error | 14 +++++++------ stages/org.osbuild.firewall | 16 ++++++++------- stages/org.osbuild.first-boot | 16 ++++++++------- stages/org.osbuild.fix-bls | 18 +++++++++-------- stages/org.osbuild.fstab | 14 +++++++------ stages/org.osbuild.groups | 14 +++++++------ stages/org.osbuild.grub2 | 18 +++++++++-------- stages/org.osbuild.hostname | 18 +++++++++-------- stages/org.osbuild.kernel-cmdline | 14 +++++++------ stages/org.osbuild.keymap | 18 +++++++++-------- stages/org.osbuild.locale | 18 +++++++++-------- stages/org.osbuild.noop | 14 +++++++------ stages/org.osbuild.ostree | 28 ++++++++++++++------------ stages/org.osbuild.rpm | 28 ++++++++++++++------------ stages/org.osbuild.rpm-ostree | 24 ++++++++++++---------- stages/org.osbuild.script | 23 +++++++++++---------- stages/org.osbuild.selinux | 18 +++++++++-------- stages/org.osbuild.systemd | 16 ++++++++------- stages/org.osbuild.test | 16 ++++++++------- stages/org.osbuild.timezone | 18 +++++++++-------- stages/org.osbuild.users | 18 +++++++++-------- stages/org.osbuild.zipl | 14 +++++++------ 32 files changed, 340 insertions(+), 269 deletions(-) diff --git a/assemblers/org.osbuild.noop b/assemblers/org.osbuild.noop index 615ee5f7..77b6aed3 100755 --- a/assemblers/org.osbuild.noop +++ b/assemblers/org.osbuild.noop @@ -1,14 +1,16 @@ #!/usr/bin/python3 +""" +No-op assembler + +No-op assembler. Produces no output, just prints a JSON dump of its options +and then exits. +""" + import json import sys -STAGE_DESC = "No-op assembler" -STAGE_INFO = """ -No-op assembler. Produces no output, just prints a JSON dump of its options -and then exits. -""" -STAGE_OPTS = """ +SCHEMA = """ "additionalProperties": false """ def main(_tree, _output_dir, options): diff --git a/assemblers/org.osbuild.oci-archive b/assemblers/org.osbuild.oci-archive index 9a9ccdf6..bcd23daa 100755 --- a/assemblers/org.osbuild.oci-archive +++ b/assemblers/org.osbuild.oci-archive @@ -1,18 +1,7 @@ #!/usr/bin/python3 +""" +Assemble an OCI image archive -import datetime -import json -import os -import subprocess -import sys -import tempfile - - -DEFAULT_PATH = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - - -STAGE_DESC = "Assemble an OCI image archive" -STAGE_INFO = """ Assemble an Open Container Initiative[1] image[2] archive, i.e. a tarball whose contents is in the OCI image layout. @@ -30,7 +19,20 @@ podman[3] with `podman pull oci-archive:`. [2] https://github.com/opencontainers/image-spec/ [3] https://podman.io/ """ -STAGE_OPTS = """ + + +import datetime +import json +import os +import subprocess +import sys +import tempfile + + +DEFAULT_PATH = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + + +SCHEMA = """ "additionalProperties": false, "required": ["architecture", "filename"], "properties": { diff --git a/assemblers/org.osbuild.ostree.commit b/assemblers/org.osbuild.ostree.commit index 8f888044..1a8302c4 100755 --- a/assemblers/org.osbuild.ostree.commit +++ b/assemblers/org.osbuild.ostree.commit @@ -1,16 +1,7 @@ #!/usr/bin/python3 +""" +Assemble a file system tree into a ostree commit -import json -import os -import subprocess -import sys -import tempfile - -from osbuild.util import ostree - - -STAGE_DESC = "Assemble a file system tree into a ostree commit" -STAGE_INFO = """ Takes a file system tree that is already conforming to the ostree system layout[1] and commits it to an archive repository. @@ -26,7 +17,18 @@ in the build root. [1] https://ostree.readthedocs.io/en/stable/manual/adapting-existing/ """ -STAGE_OPTS = """ + + +import json +import os +import subprocess +import sys +import tempfile + +from osbuild.util import ostree + + +SCHEMA = """ "additionalProperties": false, "required": ["ref"], "properties": { diff --git a/assemblers/org.osbuild.qemu b/assemblers/org.osbuild.qemu index 41e94dfb..e5f5f2e9 100755 --- a/assemblers/org.osbuild.qemu +++ b/assemblers/org.osbuild.qemu @@ -1,18 +1,7 @@ #!/usr/bin/python3 +""" +Assemble a bootable partitioned disk image with qemu-img -import contextlib -import json -import os -import shutil -import struct -import subprocess -import sys -import tempfile -from typing import List, BinaryIO -import osbuild.remoteloop as remoteloop - -STAGE_DESC = "Assemble a bootable partitioned disk image with qemu-img" -STAGE_INFO = """ Assemble a bootable partitioned disk image using `qemu-img`. Creates a sparse partitioned disk image of type `pttype` of a given `size`, @@ -29,7 +18,20 @@ sparse image into the format requested with the `fmt` option. Buildhost commands used: `truncate`, `mount`, `umount`, `sfdisk`, `grub2-mkimage`, `mkfs.ext4` or `mkfs.xfs`, `qemu-img`. """ -STAGE_OPTS = """ + + +import contextlib +import json +import os +import shutil +import struct +import subprocess +import sys +import tempfile +from typing import List, BinaryIO +import osbuild.remoteloop as remoteloop + +SCHEMA = """ "additionalProperties": false, "required": ["format", "filename", "ptuuid", "size"], "oneOf": [{ diff --git a/assemblers/org.osbuild.rawfs b/assemblers/org.osbuild.rawfs index b8dc5b75..8b5f16bf 100755 --- a/assemblers/org.osbuild.rawfs +++ b/assemblers/org.osbuild.rawfs @@ -1,14 +1,7 @@ #!/usr/bin/python3 +""" +Assemble tree into a raw filesystem image -import contextlib -import json -import os -import subprocess -import sys -import osbuild.remoteloop as remoteloop - -STAGE_DESC = "Assemble tree into a raw filesystem image" -STAGE_INFO = """ Assemble the tree into a raw filesystem image named `filename`, with the UUID `root_fs_uuid`. @@ -25,7 +18,16 @@ The filesystem UUID should be a standard (RFC4122) UUID, which you can generate with uuid.uuid4() in Python, `uuidgen(1)` in a shell script, or read from `/proc/sys/kernel/random/uuid` if your kernel provides it. """ -STAGE_OPTS = """ + + +import contextlib +import json +import os +import subprocess +import sys +import osbuild.remoteloop as remoteloop + +SCHEMA = """ "additionalProperties": false, "required": ["filename", "root_fs_uuid", "size"], "properties": { diff --git a/assemblers/org.osbuild.tar b/assemblers/org.osbuild.tar index 17088510..bfa93b3d 100755 --- a/assemblers/org.osbuild.tar +++ b/assemblers/org.osbuild.tar @@ -1,11 +1,7 @@ #!/usr/bin/python3 +""" +Assemble a tar archive -import json -import subprocess -import sys - -STAGE_DESC = "Assemble a tar archive" -STAGE_INFO = """ Assembles the tree into a tar archive named `filename`. Uses the buildhost's `tar` command, like: `tar -cf $FILENAME -C $TREE` @@ -21,7 +17,13 @@ caller is responsible for making sure that `compression` and `filename` match. Buildhost commands used: `tar` and any named `compression` program. """ -STAGE_OPTS = """ + + +import json +import subprocess +import sys + +SCHEMA = """ "additionalProperties": false, "required": ["filename"], "properties": { diff --git a/osbuild/meta.py b/osbuild/meta.py index 4862b47e..b836f2b3 100644 --- a/osbuild/meta.py +++ b/osbuild/meta.py @@ -277,10 +277,9 @@ class ModuleInfo: self.name = name self.type = klass - opts = info.get("STAGE_OPTS") or "" - self.info = info.get("STAGE_INFO") - self.desc = info.get("STAGE_DESC") - self.opts = info.get("STAGE_OPTS") + opts = info.get("schema") or "" + self.info = info.get("info") + self.desc = info.get("desc") self.opts = json.loads("{" + opts + "}") @property @@ -312,7 +311,7 @@ class ModuleInfo: @classmethod def load(cls, root, klass, name) -> Optional["ModuleInfo"]: - names = ['STAGE_INFO', 'STAGE_DESC', 'STAGE_OPTS'] + names = ['SCHEMA'] def value(a): v = a.value @@ -338,9 +337,18 @@ class ModuleInfo: return None tree = ast.parse(data, name) + + docstring = ast.get_docstring(tree) + doclist = docstring.split("\n") + assigns = filter_type(tree.body, ast.Assign) targets = [(t, a) for a in assigns for t in targets(a)] - info = {k: value(v) for k, v in targets if k in names} + values = {k: value(v) for k, v in targets if k in names} + info = { + 'schema': values.get("SCHEMA"), + 'desc': doclist[0], + 'info': "\n".join(doclist[1:]) + } return cls(klass, name, info) @staticmethod diff --git a/stages/org.osbuild.chrony b/stages/org.osbuild.chrony index d159966a..036c44e4 100755 --- a/stages/org.osbuild.chrony +++ b/stages/org.osbuild.chrony @@ -1,16 +1,18 @@ #!/usr/bin/python3 -import json -import sys -import re +""" +Configure chrony to set system time from the network -STAGE_DESC = "Configure chrony to set system time from the network" -STAGE_INFO = """ Configures `chrony` to set the system time from the given `timeservers`. Modifies /etc/chrony.conf, removing all "server" or "pool" lines and adding a "server" line for each server listed in `timeservers`. """ -STAGE_OPTS = """ + +import json +import sys +import re + +SCHEMA = """ "additionalProperties": false, "required": ["timeservers"], "properties": { diff --git a/stages/org.osbuild.copy b/stages/org.osbuild.copy index 880ecd6a..a3fa3f16 100755 --- a/stages/org.osbuild.copy +++ b/stages/org.osbuild.copy @@ -1,16 +1,7 @@ #!/usr/bin/python3 +""" +Copy files from a source to the tree -import json -import os -import sys -import subprocess -import tempfile - -import osbuild.sources - - -STAGE_DESC = "Copy files from a source to the tree" -STAGE_INFO = """ Copies files obtained via a `source` to the tree. Multiple files or directories can be copied by specifying multiple entries in `paths`. If no paths are specified the whole contents of `source` is copied. @@ -25,7 +16,18 @@ Supported sources are currently: are supported. """ -STAGE_OPTS = """ + + +import json +import os +import sys +import subprocess +import tempfile + +import osbuild.sources + + +SCHEMA = """ "additionalProperties": false, "definitions": { "source-archive": { diff --git a/stages/org.osbuild.debug-shell b/stages/org.osbuild.debug-shell index 56241c0d..53e0870c 100755 --- a/stages/org.osbuild.debug-shell +++ b/stages/org.osbuild.debug-shell @@ -1,17 +1,19 @@ #!/usr/bin/python3 +""" +Set up an early root shell on a certain tty -import json -import os -import sys - -STAGE_DESC = "Set up an early root shell on a certain tty" -STAGE_INFO = """ Creates a systemd unit file at /etc/systemd/system/osbuild-debug-shell.service which starts an early-boot root shell on the given `tty`. Also symlinks the service file into /etc/systemd/system/sysinit.target.wants/. """ -STAGE_OPTS = """ + + +import json +import os +import sys + +SCHEMA = """ "additionalProperties": false, "required": ["tty"], "properties": { diff --git a/stages/org.osbuild.error b/stages/org.osbuild.error index 88041dbb..de2ee19a 100755 --- a/stages/org.osbuild.error +++ b/stages/org.osbuild.error @@ -1,14 +1,16 @@ #!/usr/bin/python3 +""" +Return an error + +Error stage. Return the given error. Useful for testing, debugging, and +wasting time. +""" + import json import sys -STAGE_DESC = "Return an error" -STAGE_INFO = """ -Error stage. Return the given error. Useful for testing, debugging, and -wasting time. -""" -STAGE_OPTS = """ +SCHEMA = """ "additionalProperties": false, "properties": { "returncode": { diff --git a/stages/org.osbuild.firewall b/stages/org.osbuild.firewall index d5d156cf..5df93809 100755 --- a/stages/org.osbuild.firewall +++ b/stages/org.osbuild.firewall @@ -1,11 +1,7 @@ #!/usr/bin/python3 +""" +Configure firewall -import json -import subprocess -import sys - -STAGE_DESC = "Configure firewall" -STAGE_INFO = """ Configure firewalld using the `firewall-offline-cmd` from inside the target. This stage adds each of the given `ports` and `enabled_services` to the default @@ -28,7 +24,13 @@ WARNING: this stage uses `chroot` to run `firewall-offline-cmd` inside the target tree, which means it may fail unexpectedly when the buildhost and target are different arches or OSes. """ -STAGE_OPTS = """ + + +import json +import subprocess +import sys + +SCHEMA = """ "additionalProperties": false, "properties": { "ports": { diff --git a/stages/org.osbuild.first-boot b/stages/org.osbuild.first-boot index c071eb23..7ca9499b 100755 --- a/stages/org.osbuild.first-boot +++ b/stages/org.osbuild.first-boot @@ -1,11 +1,7 @@ #!/usr/bin/python3 +""" +Execute commands on first-boot -import json -import os -import sys - -STAGE_DESC = "Execute commands on first-boot" -STAGE_INFO = """ Sequentially execute a list of commands on first-boot / instantiation. This stage uses a logic similar to systemd's first-boot to execute a given @@ -18,7 +14,13 @@ before executing the given commands. If the flag-file cannot be removed, the service fails without executing any further first-boot commands. """ -STAGE_OPTS = """ + + +import json +import os +import sys + +SCHEMA = """ "additionalProperties": false, "required": ["commands"], "properties": { diff --git a/stages/org.osbuild.fix-bls b/stages/org.osbuild.fix-bls index 2233248b..11f1765c 100755 --- a/stages/org.osbuild.fix-bls +++ b/stages/org.osbuild.fix-bls @@ -1,12 +1,7 @@ #!/usr/bin/python3 +""" +Fix paths in /boot/loader/entries -import glob -import json -import re -import sys - -STAGE_DESC = "Fix paths in /boot/loader/entries" -STAGE_INFO = """ Fixes paths in /boot/loader/entries that have incorrect paths for /boot. This happens because some boot loader config tools (e.g. grub2-mkrelpath) @@ -21,7 +16,14 @@ By default it is `/boot`, i.e. assumes `/boot` is on the root file-system. This stage reads and (re)writes all .conf files in /boot/loader/entries. """ -STAGE_OPTS = """ + + +import glob +import json +import re +import sys + +SCHEMA = """ "additionalProperties": false, "properties": { "prefix": { diff --git a/stages/org.osbuild.fstab b/stages/org.osbuild.fstab index 2df985d7..1aed644d 100755 --- a/stages/org.osbuild.fstab +++ b/stages/org.osbuild.fstab @@ -1,10 +1,7 @@ #!/usr/bin/python3 +""" +Create /etc/fstab entries for filesystems -import json -import sys - -STAGE_DESC = "Create /etc/fstab entries for filesystems" -STAGE_INFO = """ Create /etc/fstab entries for the given `filesystems`. Each filesystem item must have at least `uuid` or `label` and @@ -12,7 +9,12 @@ a `path` (mount point). This stage replaces /etc/fstab, removing any existing entries. """ -STAGE_OPTS = """ + + +import json +import sys + +SCHEMA = """ "additionalProperties": false, "required": ["filesystems"], "properties": { diff --git a/stages/org.osbuild.groups b/stages/org.osbuild.groups index dd17170e..9fd3962c 100755 --- a/stages/org.osbuild.groups +++ b/stages/org.osbuild.groups @@ -1,10 +1,7 @@ #!/usr/bin/python3 -import json -import subprocess -import sys +""" +Create group accounts -STAGE_DESC = "Create group accounts" -STAGE_INFO = """ Create group accounts, optionally assigning them static GIDs. Runs `groupadd` from the buildhost to create the groups listed in `groups`. @@ -12,7 +9,12 @@ If no `gid` is given, `groupadd` will choose one. If the specified group name or GID is already in use, this stage will fail. """ -STAGE_OPTS = """ + +import json +import subprocess +import sys + +SCHEMA = """ "additionalProperties": false, "properties": { "groups": { diff --git a/stages/org.osbuild.grub2 b/stages/org.osbuild.grub2 index 60594312..a4543e28 100755 --- a/stages/org.osbuild.grub2 +++ b/stages/org.osbuild.grub2 @@ -1,12 +1,7 @@ #!/usr/bin/python3 +""" +Configure GRUB2 bootloader and set boot options -import json -import os -import shutil -import sys - -STAGE_DESC = "Configure GRUB2 bootloader and set boot options" -STAGE_INFO = """ Configure the system to use GRUB2 as the bootloader, and set boot options. Sets the GRUB2 boot/root filesystem to `rootfs`. If a separated boot @@ -41,7 +36,14 @@ and accompanying data can be installed from the built root via `uefi.install`. Both UEFI and Legacy can be specified at the same time. """ -STAGE_OPTS = """ + + +import json +import os +import shutil +import sys + +SCHEMA = """ "additionalProperties": false, "oneOf": [{ "required": ["root_fs_uuid"] diff --git a/stages/org.osbuild.hostname b/stages/org.osbuild.hostname index 2e169aa4..35037e57 100755 --- a/stages/org.osbuild.hostname +++ b/stages/org.osbuild.hostname @@ -1,19 +1,21 @@ #!/usr/bin/python3 +""" +Set system hostname -import json -import os -import subprocess -import sys - -STAGE_DESC = "Set system hostname" -STAGE_INFO = """ Sets system hostname. Deletes /etc/hostname if present, then runs `systemd-firstboot` from the buildhost with `--hostname={hostname}`, which checks the validity of the hostname and writes it to /etc/hostname. """ -STAGE_OPTS = """ + + +import json +import os +import subprocess +import sys + +SCHEMA = """ "additionalProperties": false, "required": ["hostname"], "properties": { diff --git a/stages/org.osbuild.kernel-cmdline b/stages/org.osbuild.kernel-cmdline index f1ba73db..0ef7555e 100755 --- a/stages/org.osbuild.kernel-cmdline +++ b/stages/org.osbuild.kernel-cmdline @@ -1,16 +1,18 @@ #!/usr/bin/python3 -import json -import os -import sys +""" +Configure the kernel command-line parameters -STAGE_DESC = "Configure the kernel command-line parameters" -STAGE_INFO = """ Configures the kernel boot parameters, also known as the kernel command line. https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html """ -STAGE_OPTS = """ + +import json +import os +import sys + +SCHEMA = """ "additionalProperties": false, "properties": { "root_fs_uuid": { diff --git a/stages/org.osbuild.keymap b/stages/org.osbuild.keymap index 89f8c1e0..ac6cc8aa 100755 --- a/stages/org.osbuild.keymap +++ b/stages/org.osbuild.keymap @@ -1,12 +1,7 @@ #!/usr/bin/python3 +""" +Set image's default keymap -import json -import subprocess -import sys -import os - -STAGE_DESC = "Set image's default keymap" -STAGE_INFO = """ Sets the default console keyboard layout to `keymap`, like 'us' or 'de-latin1'. Removes any existing /etc/vconsole.conf, then runs `systemd-firstboot` with the @@ -14,7 +9,14 @@ Removes any existing /etc/vconsole.conf, then runs `systemd-firstboot` with the Valid keymaps are generally found in /lib/kbd/keymaps. """ -STAGE_OPTS = """ + + +import json +import subprocess +import sys +import os + +SCHEMA = """ "additionalProperties": false, "required": ["keymap"], "properties": { diff --git a/stages/org.osbuild.locale b/stages/org.osbuild.locale index d65a2dd8..26a4dbbb 100755 --- a/stages/org.osbuild.locale +++ b/stages/org.osbuild.locale @@ -1,12 +1,7 @@ #!/usr/bin/python3 +""" +Set system language. -import json -import subprocess -import sys -import os - -STAGE_DESC = "Set system language." -STAGE_INFO = """ Sets the system language to the given `language`, which must be a valid locale identifier, like "en_US.UTF-8". @@ -14,7 +9,14 @@ Removes `/etc/locale.conf` and then uses `systemd-firstboot` from the buildhost, with the `--locale` flag, which will write a new `/etc/locale.conf` in the target system with `LANG={language}`. """ -STAGE_OPTS = """ + + +import json +import subprocess +import sys +import os + +SCHEMA = """ "additionalProperties": false, "required": ["language"], "properties": { diff --git a/stages/org.osbuild.noop b/stages/org.osbuild.noop index e77c3439..4c7aa08b 100755 --- a/stages/org.osbuild.noop +++ b/stages/org.osbuild.noop @@ -1,14 +1,16 @@ #!/usr/bin/python3 +""" +Do Nothing + +No-op stage. Prints a JSON dump of the options passed into this stage and +leaves the tree untouched. Useful for testing, debugging, and wasting time. +""" + import json import sys -STAGE_DESC = "Do Nothing" -STAGE_INFO = """ -No-op stage. Prints a JSON dump of the options passed into this stage and -leaves the tree untouched. Useful for testing, debugging, and wasting time. -""" -STAGE_OPTS = """ +SCHEMA = """ "additionalProperties": false """ diff --git a/stages/org.osbuild.ostree b/stages/org.osbuild.ostree index 2e886ec4..e4b255bc 100755 --- a/stages/org.osbuild.ostree +++ b/stages/org.osbuild.ostree @@ -1,17 +1,7 @@ #!/usr/bin/python3 +""" +Initialize the sysroot and pull and deploy an OStree commit -import contextlib -import json -import os -import sys -import subprocess - -import osbuild.sources -from osbuild.util import selinux - - -STAGE_DESC = "Initialize the sysroot and pull and deploy an OStree commit" -STAGE_INFO = """ Initializes a clean ostree based system root, pulls the given `commit` and creates a deployment from it using `osname` as the new stateroot (see [1]). @@ -29,7 +19,19 @@ the sysroot and the deployments. Additional kernel options can be passed via [1] https://ostree.readthedocs.io/en/latest/manual/deployment/ """ -STAGE_OPTS = """ + + +import contextlib +import json +import os +import sys +import subprocess + +import osbuild.sources +from osbuild.util import selinux + + +SCHEMA = """ "required": ["commit", "osname", "rootfs"], "properties": { "commit": { diff --git a/stages/org.osbuild.rpm b/stages/org.osbuild.rpm index af6caf6e..32d8ddbe 100755 --- a/stages/org.osbuild.rpm +++ b/stages/org.osbuild.rpm @@ -1,17 +1,7 @@ #!/usr/bin/python3 +""" +Verify, and install RPM packages -import contextlib -import json -import os -import pathlib -import subprocess -import sys -import tempfile - -import osbuild.sources - -STAGE_DESC = "Verify, and install RPM packages" -STAGE_INFO = """ Verify, and install RPM packages. `gpgkeys` should be an array of strings containing each GPG key to be used @@ -33,7 +23,19 @@ Uses the following binaries from the host: * `sh`, `mkdir`, `mount`, `chmod` to prepare the target tree for `rpm` * `rpm` to install packages into the target tree """ -STAGE_OPTS = """ + + +import contextlib +import json +import os +import pathlib +import subprocess +import sys +import tempfile + +import osbuild.sources + +SCHEMA = """ "additionalProperties": false, "properties": { "gpgkeys": { diff --git a/stages/org.osbuild.rpm-ostree b/stages/org.osbuild.rpm-ostree index d2e99429..061fd8c1 100755 --- a/stages/org.osbuild.rpm-ostree +++ b/stages/org.osbuild.rpm-ostree @@ -1,15 +1,7 @@ #!/usr/bin/python3 +""" +Transforms the tree to an ostree layout -import json -import os -import subprocess -import sys - -from osbuild.util import ostree - - -STAGE_DESC = "Transforms the tree to an ostree layout" -STAGE_INFO = """ Uses `rpm-ostree compose` to transform a "normal" file system tree into an OSTree conforming layout (see [1]). Among other things the main steps are: @@ -37,7 +29,17 @@ human users need to be part of. [1] https://ostree.readthedocs.io/en/latest/manual/adapting-existing/ [2] https://rpm-ostree.readthedocs.io/en/latest/manual/treefile/ """ -STAGE_OPTS = """ + + +import json +import os +import subprocess +import sys + +from osbuild.util import ostree + + +SCHEMA = """ "additionalProperties": false, "properties": { "etc_group_members": { diff --git a/stages/org.osbuild.script b/stages/org.osbuild.script index bbd9f733..9eeab56b 100755 --- a/stages/org.osbuild.script +++ b/stages/org.osbuild.script @@ -1,13 +1,7 @@ #!/usr/bin/python3 +""" +Run an arbitrary script inside the target tree -import atexit -import json -import os -import subprocess -import sys - -STAGE_DESC = "Run an arbitrary script inside the target tree" -STAGE_INFO = """ Runs an arbitrary script inside the target tree. Writes the contents of the `script` item to `/osbuild-script`, sets the @@ -19,12 +13,21 @@ WARNING: running code inside the tree is unsafe, unreliable, and generally discouraged. Using this stage may result in unexplained failures or other undefined behavior, and should only be done as a last resort. -NOTE: if `script` does not start with a line like '#!/bin/bash\n', executing +NOTE: if `script` does not start with a line like '#!/bin/bash +', executing it will fail with ENOEXEC. Some `chroot` binaries will try to run the script through `/bin/sh` in that case, so it might still work, but that behavior is not guaranteed. """ -STAGE_OPTS = """ + + +import atexit +import json +import os +import subprocess +import sys + +SCHEMA = """ "additionalProperties": false, "required": ["script"], "properties": { diff --git a/stages/org.osbuild.selinux b/stages/org.osbuild.selinux index 4cb5c569..a7f1fc1c 100755 --- a/stages/org.osbuild.selinux +++ b/stages/org.osbuild.selinux @@ -1,12 +1,7 @@ #!/usr/bin/python3 +""" +Set SELinux file contexts -import json -import os -import subprocess -import sys - -STAGE_DESC = "Set SELinux file contexts" -STAGE_INFO = """ Sets correct SELinux labels for every file in the tree, according to the SELinux policy installed inside the tree. @@ -23,7 +18,14 @@ This stage should run after all other stages that create (or move) files, since labels for newly-created files are determined by the host's SELinux policy and may not match the tree's policy. """ -STAGE_OPTS = """ + + +import json +import os +import subprocess +import sys + +SCHEMA = """ "additionalProperties": false, "required": ["file_contexts"], "properties": { diff --git a/stages/org.osbuild.systemd b/stages/org.osbuild.systemd index 0ddf79c5..c9ff2094 100755 --- a/stages/org.osbuild.systemd +++ b/stages/org.osbuild.systemd @@ -1,11 +1,7 @@ #!/usr/bin/python3 +""" +Enable or disable systemd services -import json -import subprocess -import sys - -STAGE_DESC = "Enable or disable systemd services" -STAGE_INFO = """ Enable or disable systemd units (service, socket, path, etc.) This stage runs `systemctl enable` for all `enabled_services` items, which may @@ -15,7 +11,13 @@ items, which will delete _all_ symlinks to the named services. Uses `systemctl` from the buildhost. """ -STAGE_OPTS = """ + + +import json +import subprocess +import sys + +SCHEMA = """ "additionalProperties": false, "required": ["enabled_services"], "properties": { diff --git a/stages/org.osbuild.test b/stages/org.osbuild.test index 7a4a9f88..5ab2f868 100755 --- a/stages/org.osbuild.test +++ b/stages/org.osbuild.test @@ -1,18 +1,20 @@ #!/usr/bin/python3 +""" +Enable osbuild Boot Test service -import json -import os -import sys - -STAGE_DESC = "Enable osbuild Boot Test service" -STAGE_INFO = """ Creates a Boot Test service that executes the given `script` (sending output to /dev/vport0p1) then immediately shuts down the system. Creates `/etc/systemd/system/osbuild-test.service`, and a symlink to it in `/etc/systemd/system/multi-user.target.wants/`. """ -STAGE_OPTS = """ + + +import json +import os +import sys + +SCHEMA = """ "additionalProperties": false, "required": ["script"], "properties": { diff --git a/stages/org.osbuild.timezone b/stages/org.osbuild.timezone index 4ac01e2c..13fb6e50 100755 --- a/stages/org.osbuild.timezone +++ b/stages/org.osbuild.timezone @@ -1,19 +1,21 @@ #!/usr/bin/python3 +""" +Set system timezone -import json -import subprocess -import sys -import os - -STAGE_DESC = "Set system timezone" -STAGE_INFO = """ Set the system's timezone to `zone`, which should be a valid time zone identifier from the tz database - like "America/New York" or "Europe/Berlin". Removes `/etc/localtime`, then runs the host's `systemd-firstboot` binary with the `--timezone` option, which will re-create `/etc/localtime`. """ -STAGE_OPTS = """ + + +import json +import subprocess +import sys +import os + +SCHEMA = """ "additionalProperties": false, "required": ["zone"], "properties": { diff --git a/stages/org.osbuild.users b/stages/org.osbuild.users index 4c30af4f..9020d7fd 100755 --- a/stages/org.osbuild.users +++ b/stages/org.osbuild.users @@ -1,12 +1,7 @@ #!/usr/bin/python3 +""" +Add or modify user accounts -import json -import subprocess -import sys -import os - -STAGE_DESC = "Add or modify user accounts" -STAGE_INFO = """ Add or modify user accounts inside the tree. WARNING: This stage uses chroot() to run the `useradd` or `usermod` binary @@ -14,7 +9,14 @@ from inside the tree. This will fail for cross-arch builds and may fail or misbehave if the `usermod`/`useradd` binary inside the tree makes incorrect assumptions about its host system. """ -STAGE_OPTS = """ + + +import json +import subprocess +import sys +import os + +SCHEMA = """ "additionalProperties": false, "properties": { "users": { diff --git a/stages/org.osbuild.zipl b/stages/org.osbuild.zipl index efed206c..6bce59bf 100755 --- a/stages/org.osbuild.zipl +++ b/stages/org.osbuild.zipl @@ -1,15 +1,17 @@ #!/usr/bin/python3 +""" +Configure the z Initial Program Loader (zipl) + +Configures `zipl` with a minimal config so it can be used in +the assembler to write the bootmap and bootloader code. +""" + import json import os import sys -STAGE_DESC = "Configure the z Initial Program Loader (zipl)" -STAGE_INFO = """ -Configures `zipl` with a minimal config so it can be used in -the assembler to write the bootmap and bootloader code. -""" -STAGE_OPTS = """ +SCHEMA = """ "additionalProperties": false, "properties": { "timeout": {