Blame stages/org.osbuild.rpm-ostree

Packit a20ca0
#!/usr/bin/python3
Packit a20ca0
"""
Packit a20ca0
Transforms the tree to an ostree layout
Packit a20ca0
Packit a20ca0
Uses `rpm-ostree compose` to transform a "normal" file system tree into
Packit a20ca0
an OSTree conforming layout (see [1]). Among other things the main steps
Packit a20ca0
are:
Packit a20ca0
  - moves /etc to /usr/etc
Packit a20ca0
  - move /boot to /usr/lib/ostree-boot
Packit a20ca0
  - potentially moving /var/lib/rpm
Packit a20ca0
  - re-creates the initramfs (via dracut)
Packit a20ca0
  - adds altfiles module to NSS
Packit a20ca0
  - Re-compiles SELinux policy (semodule -nB)
Packit a20ca0
  - Migrates /usr/etc/{passwd, group} to /usr/lib/
Packit a20ca0
  - Postprocess SELinux policy
Packit a20ca0
  - Convert /var to use tmpfiles.d
Packit a20ca0
  - Prepares symlinks
Packit a20ca0
    - /usr/local -> /var/usrlocal
Packit a20ca0
    - /var/lib/alternatives -> /usr/lib/alternatives
Packit a20ca0
    - /var/lib/vagrant -> /usr/lib/vagrant
Packit a20ca0
  - copies the rpmdb
Packit a20ca0
Packit a20ca0
The configuration options, `etc_group_members` corresponds to the
Packit a20ca0
Treefile[2] option of rpm-ostree. In brief: The groups mentioned
Packit a20ca0
in `etc_group_members` will be stored in /etc/groups instead of
Packit a20ca0
/usr/etc/groups (which is read-only). Therefore all groups that
Packit a20ca0
human users need to be part of.
Packit a20ca0
Packit a20ca0
[1] https://ostree.readthedocs.io/en/latest/manual/adapting-existing/
Packit a20ca0
[2] https://rpm-ostree.readthedocs.io/en/latest/manual/treefile/
Packit a20ca0
"""
Packit a20ca0
Packit a20ca0
Packit a20ca0
import json
Packit a20ca0
import os
Packit a20ca0
import subprocess
Packit a20ca0
import sys
Packit a20ca0
Packit a20ca0
from osbuild.util import ostree
Packit a20ca0
Packit a20ca0
Packit a20ca0
SCHEMA = """
Packit a20ca0
"additionalProperties": false,
Packit a20ca0
"properties": {
Packit a20ca0
  "etc_group_members": {
Packit a20ca0
    "description": "Array of group names to still keep in /etc/group",
Packit a20ca0
    "type": "array",
Packit a20ca0
    "items": { "type": "string" }
Packit a20ca0
  },
Packit a20ca0
  "initramfs-args": {
Packit a20ca0
    "description": "Array of arguments passed to dracut",
Packit a20ca0
    "type": "array",
Packit a20ca0
    "items": { "type": "string" }
Packit a20ca0
  }
Packit a20ca0
}
Packit a20ca0
"""
Packit a20ca0
Packit a20ca0
Packit a20ca0
def main(tree, options):
Packit a20ca0
    etc_group_members = options.get("etc_group_members", [])
Packit a20ca0
    initramfs = options.get("initramfs-args", [])
Packit a20ca0
Packit a20ca0
    # rpm-ostree will either ensure that machine-id is empty
Packit a20ca0
    # when machineid-compat is 'true' is or will remove it
Packit a20ca0
    # otherwise. Since we have to decide, detect the current
Packit a20ca0
    # state and make rpm-ostree follow suit
Packit a20ca0
    machineid_compat = os.path.exists(f"{tree}/etc/machine-id")
Packit a20ca0
    print(f"ostree: machineid-compat: {machineid_compat}")
Packit a20ca0
Packit a20ca0
    treefile = ostree.Treefile()
Packit a20ca0
    treefile["boot-location"] = "new"
Packit a20ca0
    treefile["machineid-compat"] = machineid_compat
Packit a20ca0
    treefile["etc-group-members"] = etc_group_members
Packit a20ca0
    treefile["initramfs-args"] = initramfs
Packit a20ca0
Packit a20ca0
    with treefile.as_tmp_file() as path:
Packit a20ca0
        subprocess.run(["rpm-ostree", "compose", "postprocess",
Packit a20ca0
                        tree, path],
Packit a20ca0
                       check=True)
Packit a20ca0
Packit a20ca0
Packit a20ca0
if __name__ == '__main__':
Packit a20ca0
    args = json.load(sys.stdin)
Packit a20ca0
    r = main(args["tree"], args["options"])
Packit a20ca0
    sys.exit(r)