Repository: osbuild/osbuild
Pull request #389 (2020-05-12 06:00:32)

buildroot: use `bwrap` to contain stages
This needs a rebase and minor tweaks to the CI. It works on my machine to build all the fedora images, so if we want to go that route, we can easily pick it up.


*Commit Message:*


This swaps the `systemd-nspawn` implementation for `bubblewrap` to
contain sub-processes. It also adjusts the `BuildRoot` implementation
to reduce the number of mounts required to keep locally.

This has the following advantages:

  * We know exactly how the build-root looks like. Only the bits and
    pieces we select will end up in the build-root. We can let RPM
    authors know what environment their post-install scripts need to
    run in, and we can reliably test this.

  * We no longer need any D-Bus access or access to other PID1
    facilities. Bubblewrap allows us to execute from any environment,
    including containers and sandboxes.

  * Bubblewrap setup is significantly faster than nspawn. This is a
    minor point though, since nspawn is still fast enough compared to
    the operations we perform in the container.

  * Bubblewrap does not require root.

At the same time, we have a bunch of downsides which might increase the
workload in the future:

  * We now control the build-root, which also means we have to make sure
    it works on all our supported architectures, all quirks are
    included, and all required resources are accessible from within the
    build-root.
    The good thing here is that we have lots of previous-art we can
    follow, and all the other ones just play whack-a-mole, so we can
    join that fun.

The `bubblewrap` project is used by podman and flatpak, it is packaged
for all major distributions, and looks like a stable dependency.

dvdhrm: (rebased on master; specfile and README adjusted as well)

Patch:
diff --git a/.pylintrc b/.pylintrc
index ce564d6d..1a7c8a30 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -4,3 +4,6 @@ max-line-length=120
 
 [TYPECHECK]
 ignored-classes=osbuild.loop.LoopInfo
+
+[DESIGN]
+max-attributes=10
diff --git a/Makefile b/Makefile
index 6391246d..24622a4e 100644
--- a/Makefile
+++ b/Makefile
@@ -215,6 +215,7 @@ $(TEST_MANIFESTS_GEN): $(SRCDIR)/test/data/manifests/%.json: $(SRCDIR)/test/data
 
 $(SRCDIR)/test/data/manifests/f32-base.json: $(SRCDIR)/test/data/manifests/f32-build.json
 $(SRCDIR)/test/data/manifests/fedora-boot.json: $(SRCDIR)/test/data/manifests/f32-build.json
+$(SRCDIR)/test/data/manifests/filesystem.json: $(SRCDIR)/test/data/manifests/f32-build.json
 
 .PHONY: test-data
 test-data: $(TEST_MANIFESTS_GEN)
diff --git a/README.md b/README.md
index 6a1eb6ec..13304e5f 100644
--- a/README.md
+++ b/README.md
@@ -20,8 +20,8 @@ of the pipeline description, and more.
 
 The requirements for this project are:
 
+ * `bubblewrap >= 0.4.0`
  * `python >= 3.7`
- * `systemd-nspawn >= 244`
 
 Additionally, the built-in stages require:
 
diff --git a/assemblers/org.osbuild.qemu b/assemblers/org.osbuild.qemu
index 257c43d2..dbd50963 100755
--- a/assemblers/org.osbuild.qemu
+++ b/assemblers/org.osbuild.qemu
@@ -201,7 +201,6 @@ class Filesystem:
         maker(device, self.uuid, self.label)
 
 
-# pylint: disable=too-many-instance-attributes
 class Partition:
     def __init__(self,
                  pttype: str = None,
diff --git a/osbuild.spec b/osbuild.spec
index 296c1b87..45c5cdc4 100644
--- a/osbuild.spec
+++ b/osbuild.spec
@@ -23,6 +23,7 @@ BuildRequires:  python3-devel
 BuildRequires:  python3-docutils
 
 Requires:       bash
+Requires:       bubblewrap
 Requires:       coreutils
 Requires:       curl
 Requires:       dnf
@@ -31,7 +32,6 @@ Requires:       glibc
 Requires:       policycoreutils
 Requires:       qemu-img
 Requires:       systemd
-Requires:       systemd-container
 Requires:       tar
 Requires:       util-linux
 Requires:       python3-%{pypi_name} = %{version}-%{release}
diff --git a/osbuild/api.py b/osbuild/api.py
index 6fdb11a2..4d77d2b2 100644
--- a/osbuild/api.py
+++ b/osbuild/api.py
@@ -1,25 +1,26 @@
 import asyncio
+import io
 import json
 import os
-import sys
 import tempfile
 import threading
 from .util import jsoncomm
 
 
 class API:
-    def __init__(self, socket_address, args, interactive):
+    def __init__(self, socket_address, args, monitor):
         self.socket_address = socket_address
         self.input = args
-        self.interactive = interactive
-        self._output = None
+        self._output_data = io.StringIO()
+        self._output_pipe = None
+        self.monitor = monitor
         self.event_loop = asyncio.new_event_loop()
         self.thread = threading.Thread(target=self._run_event_loop)
         self.barrier = threading.Barrier(2)
 
     @property
     def output(self):
-        return self._output and self._output.read()
+        return self._output_data.getvalue()
 
     def _prepare_input(self):
         with tempfile.TemporaryFile() as fd:
@@ -28,12 +29,18 @@ class API:
             return open(f"/proc/self/fd/{fd.fileno()}", "r")
 
     def _prepare_output(self):
-        if self.interactive:
-            return os.fdopen(os.dup(sys.stdout.fileno()), 'w')
-        out = tempfile.TemporaryFile(mode="wb")
-        fd = os.open(f"/proc/self/fd/{out.fileno()}", os.O_RDONLY|os.O_CLOEXEC)
-        self._output = os.fdopen(fd)
-        return out
+        r, w = os.pipe()
+        self._output_pipe = r
+        self._output_data.truncate(0)
+        self._output_data.seek(0)
+        self.event_loop.add_reader(r, self._output_ready)
+        return os.fdopen(w)
+
+    def _output_ready(self):
+        raw = os.read(self._output_pipe, 4096)
+        data = raw.decode("utf-8")
+        self._output_data.write(data)
+        self.monitor.log(data)
 
     def _setup_stdio(self, server, addr):
         with self._prepare_input() as stdin, \
@@ -70,3 +77,7 @@ class API:
     def __exit__(self, *args):
         self.event_loop.call_soon_threadsafe(self.event_loop.stop)
         self.thread.join()
+        self.event_loop.close()
+        if self._output_pipe:
+            os.close(self._output_pipe)
+            self._output_pipe = None
diff --git a/osbuild/buildroot.py b/osbuild/buildroot.py
index c861cd63..decf9906 100644
--- a/osbuild/buildroot.py
+++ b/osbuild/buildroot.py
@@ -1,10 +1,15 @@
+"""Build Roots
+
+This implements the file-system environment available to osbuild modules. It
+uses `bubblewrap` to contain osbuild modules in a private environment with as
+little access to the outside as possible.
+"""
 
 import contextlib
 import importlib
 import importlib.util
 import os
-import platform
-import shutil
+import stat
 import subprocess
 import tempfile
 
@@ -14,115 +19,167 @@ __all__ = [
 ]
 
 
+# pylint: disable=too-many-instance-attributes
 class BuildRoot(contextlib.AbstractContextManager):
+    """Build Root
+
+    This class implements a context-manager that maintains a root file-system
+    for contained environments. When entering the context, the required
+    file-system setup is performed, and it is automatically torn down when
+    exiting.
+
+    The `run()` method allows running applications in this environment. Some
+    state is persistent across runs, including data in `/var`. It is deleted
+    only when exiting the context manager.
+    """
+
     def __init__(self, root, runner, path="/run/osbuild", libdir=None, var="/var/tmp"):
-        self.root = tempfile.mkdtemp(prefix="osbuild-buildroot-", dir=path)
-        self.api = tempfile.mkdtemp(prefix="osbuild-api-", dir=path)
-        self.var = tempfile.mkdtemp(prefix="osbuild-var-", dir=var)
-        self.mounts = []
-        self.libdir = libdir
-        self.runner = runner
-
-        self.mount_root(root)
-        self.mount_var()
-
-    def mount_root(self, root):
-        for p in ["boot", "usr", "bin", "sbin", "lib", "lib64"]:
-            source = os.path.join(root, p)
-            target = os.path.join(self.root, p)
-            if not os.path.isdir(source) or os.path.islink(source):
-                continue # only bind-mount real dirs
-            os.mkdir(target)
-            try:
-                subprocess.run(["mount", "-o", "bind,ro", source, target], check=True)
-            except subprocess.CalledProcessError:
-                self.unmount()
-                raise
-            self.mounts.append(target)
-
-        if platform.machine() == "s390x" or platform.machine() == "ppc64le":
-            # work around a combination of systemd not creating the link from
-            # /lib64 -> /usr/lib64 (see systemd issue #14311) and the dynamic
-            # linker is being set to (/lib/ld64.so.1 -> /lib64/ld64.so.1)
-            # on s390x or /lib64/ld64.so.2 on ppc64le
-            # Therefore we manually create the link before calling nspawn
-            os.symlink("/usr/lib64", f"{self.root}/lib64")
-
-    def mount_var(self):
-        target = os.path.join(self.root, "var")
-        os.mkdir(target)
-        try:
-            subprocess.run(["mount", "-o", "bind", self.var, target], check=True)
-        except subprocess.CalledProcessError:
-            self.unmount()
-            raise
-        self.mounts.append(target)
-
-    def unmount(self):
-        for path in self.mounts:
-            subprocess.run(["umount", "--lazy", path], check=True)
-            os.rmdir(path)
-        self.mounts = []
-        if self.root:
-            shutil.rmtree(self.root)
-            self.root = None
-        if self.api:
-            shutil.rmtree(self.api)
-            self.api = None
-        if self.var:
-            shutil.rmtree(self.var)
-            self.var = None
+        self._exitstack = None
+        self._rootdir = root
+        self._rundir = path
+        self._vardir = var
+        self._libdir = libdir
+        self._runner = runner
+        self.api = None
+        self.dev = None
+        self.var = None
+
+    @staticmethod
+    def _mknod(path, name, mode, major, minor):
+        os.mknod(os.path.join(path, name),
+                 mode=(stat.S_IMODE(mode) | stat.S_IFCHR),
+                 device=os.makedev(major, minor))
+
+    def __enter__(self):
+        self._exitstack = contextlib.ExitStack()
+        with self._exitstack:
+            # We create almost everything directly in the container as temporary
+            # directories and mounts. However, for some things we need external
+            # setup. For these, we create temporary directories which are then
+            # bind-mounted into the container.
+            #
+            # For now, this includes:
+            #
+            #   * We create an API directory where the caller can place sockets
+            #     before we bind-mount it into the container on
+            #     `/run/osbuild/api`.
+            #
+            #   * We create a tmpfs instance *without* `nodev` which we then use
+            #     as `/dev` in the container. This is required for the container
+            #     to create device nodes for loop-devices.
+            #
+            #   * We create a temporary directory for variable data and then use
+            #     it as '/var' in the container. This allows the container to
+            #     create throw-away data that it does not want to put into a
+            #     tmpfs.
+
+            api = tempfile.TemporaryDirectory(prefix="osbuild-api-", dir=self._rundir)
+            self.api = self._exitstack.enter_context(api)
+
+            dev = tempfile.TemporaryDirectory(prefix="osbuild-dev-", dir=self._rundir)
+            self.dev = self._exitstack.enter_context(dev)
+
+            var = tempfile.TemporaryDirectory(prefix="osbuild-var-", dir=self._vardir)
+            self.var = self._exitstack.enter_context(var)
+
+            subprocess.run(["mount", "-t", "tmpfs", "-o", "nosuid", "none", self.dev], check=True)
+            self._exitstack.callback(lambda: subprocess.run(["umount", "--lazy", self.dev], check=True))
+
+            self._mknod(self.dev, "full", 0o666, 1, 7)
+            self._mknod(self.dev, "null", 0o666, 1, 3)
+            self._mknod(self.dev, "random", 0o666, 1, 8)
+            self._mknod(self.dev, "urandom", 0o666, 1, 9)
+            self._mknod(self.dev, "tty", 0o666, 5, 0)
+            self._mknod(self.dev, "zero", 0o666, 1, 5)
+
+            self._exitstack = self._exitstack.pop_all()
+
+        return self
+
+    def __exit__(self, exc_type, exc_value, exc_tb):
+        self._exitstack.close()
+        self._exitstack = None
 
     def run(self, argv, binds=None, readonly_binds=None):
         """Runs a command in the buildroot.
 
-        Its arguments mean the same as those for subprocess.run().
+        Takes the command and arguments, as well as bind mounts to mirror
+        in the build-root for this command.
+
+        This must be called from within an active context of this buildroot
+        context-manager.
         """
 
-        nspawn_ro_binds = []
-
-        # make osbuild API-calls accessible to the container
-        nspawn_ro_binds.append(f"{self.api}:/run/osbuild/api")
-
-        # We want to execute our stages and other scripts in the container. So
-        # far, we do not install osbuild as a package in the container, but
-        # provide it from the outside. Therefore, we need to provide `libdir`
-        # via bind-mount. Furthermore, a system-installed `libdir` has the
-        # python packages separate in `site-packages`, so we need to bind-mount
-        # them as well.
-        # In the future, we want to work towards mandating an osbuild package to
-        # be installed in the container, so the build is self-contained and does
-        # not take scripts from the host. However, this requires osbuild
-        # packaged for those containers. Furthermore, we want to keep supporting
-        # the current import-model for testing and development.
-        if self.libdir is not None:
-            # caller-specified `libdir` must be self-contained
-            nspawn_ro_binds.append(f"{self.libdir}:/run/osbuild/lib")
+        if not self._exitstack:
+            raise RuntimeError("No active context")
+
+        mounts = []
+
+        # Import directories from the caller-provided root.
+        for p in ["boot", "usr"]:
+            source = os.path.join(self._rootdir, p)
+            if os.path.isdir(source) and not os.path.islink(source):
+                mounts += ["--ro-bind", source, os.path.join("/", p)]
+
+        # Create /usr symlinks.
+        mounts += ["--symlink", "usr/lib", "/lib"]
+        mounts += ["--symlink", "usr/lib64", "/lib64"]
+        mounts += ["--symlink", "usr/bin", "/bin"]
+        mounts += ["--symlink", "usr/sbin", "/sbin"]
+
+        # Setup /dev.
+        mounts += ["--dev-bind", self.dev, "/dev"]
+        mounts += ["--tmpfs", "/dev/shm"]
+
+        # Setup temporary/data file-systems.
+        mounts += ["--dir", "/etc"]
+        mounts += ["--tmpfs", "/run"]
+        mounts += ["--tmpfs", "/tmp"]
+        mounts += ["--bind", self.var, "/var"]
+
+        # Setup API file-systems.
+        mounts += ["--proc", "/proc"]
+        mounts += ["--bind", "/sys", "/sys"]
+
+        # Make osbuild API-calls accessible to the container.
+        mounts += ["--ro-bind", f"{self.api}", "/run/osbuild/api"]
+
+        # We execute our own modules by bind-mounting them from the host into
+        # the build-root. We have minimal requirements on the build-root, so
+        # these modules can be executed. Everything else we provide ourselves.
+        # In case you pass `--libdir`, it must be self-contained and we provide
+        # nothing else. If you use the system libdir, we additionally look for
+        # the installed `osbuild` module and bind-mount it as well.
+        if self._libdir is not None:
+            mounts += ["--ro-bind", f"{self._libdir}", "/run/osbuild/lib"]
         else:
-            # system `libdir` requires importing the python module
-            nspawn_ro_binds.append("/usr/lib/osbuild:/run/osbuild/lib")
+            mounts += ["--ro-bind", "/usr/lib/osbuild", "/run/osbuild/lib"]
             modorigin = importlib.util.find_spec("osbuild").origin
             modpath = os.path.dirname(modorigin)
-            nspawn_ro_binds.append(f"{modpath}:/run/osbuild/lib/osbuild")
-
-        return subprocess.run([
-            "systemd-nspawn",
-            "--quiet",
-            "--register=no",
-            "--keep-unit",
-            "--as-pid2",
-            "--link-journal=no",
-            "--capability=CAP_MAC_ADMIN",  # for SELinux labeling
-            f"--directory={self.root}",
-            "--setenv=PYTHONPATH=/run/osbuild/lib",
-            *[f"--bind-ro={b}" for b in nspawn_ro_binds],
-            *[f"--bind={b}" for b in (binds or [])],
-            *[f"--bind-ro={b}" for b in (readonly_binds or [])],
-            f"/run/osbuild/lib/runners/{self.runner}"
-            ] + argv, check=False, stdin=subprocess.DEVNULL)
-
-    def __del__(self):
-        self.unmount()
-
-    def __exit__(self, exc_type, exc_value, exc_tb):
-        self.unmount()
+            mounts += ["--ro-bind", f"{modpath}", "/run/osbuild/lib/osbuild"]
+
+        # Make caller-provided mounts available as well.
+        for b in binds or []:
+            mounts += ["--bind"] + b.split(":")
+        for b in readonly_binds or []:
+            mounts += ["--ro-bind"] + b.split(":")
+
+        cmd = [
+            "bwrap",
+            "--cap-add", "CAP_MAC_ADMIN",
+            "--chdir", "/",
+            "--die-with-parent",
+            "--new-session",
+            "--setenv", "PATH", "/usr/sbin:/usr/bin",
+            "--setenv", "PYTHONPATH", "/run/osbuild/lib",
+            "--unshare-ipc",
+            "--unshare-pid",
+        ]
+
+        cmd += mounts
+        cmd += ["--", f"/run/osbuild/lib/runners/{self._runner}"]
+        cmd += argv
+
+        return subprocess.run(cmd,
+                              check=False,
+                              stdin=subprocess.DEVNULL)
diff --git a/osbuild/main_cli.py b/osbuild/main_cli.py
index c29d93a8..5a34ec57 100644
--- a/osbuild/main_cli.py
+++ b/osbuild/main_cli.py
@@ -13,6 +13,7 @@ import sys
 
 import osbuild
 import osbuild.meta
+import osbuild.monitor
 
 
 RESET = "\033[0m"
@@ -141,10 +142,17 @@ def osbuild_cli():
         sys.stdout.write("\n")
         return 0
 
+    if not args.output_directory and not args.checkpoint:
+        print("No output directory or checkpoints specified, exited without building.")
+        return 0
+
+    monitor_name = "NullMonitor" if args.json else "LogMonitor"
+    monitor = osbuild.monitor.make(monitor_name, sys.stdout.fileno())
+
     try:
         r = pipeline.run(
             args.store,
-            interactive=not args.json,
+            monitor,
             libdir=args.libdir,
             output_directory=args.output_directory
         )
diff --git a/osbuild/monitor.py b/osbuild/monitor.py
new file mode 100644
index 00000000..4d3c9d06
--- /dev/null
+++ b/osbuild/monitor.py
@@ -0,0 +1,126 @@
+"""
+Monitor pipeline activity
+
+The osbuild `Pipeline` class supports monitoring of its activities
+by providing a monitor object that implements the `BaseMonitor`
+interface. During the execution of the pipeline various functions
+are called on the monitor object at certain events. Consult the
+`BaseMonitor` class for the description of all available events.
+"""
+
+import abc
+import json
+import os
+import sys
+
+from typing import Dict
+
+import osbuild
+
+
+RESET = "\033[0m"
+BOLD = "\033[1m"
+
+
+class TextWriter:
+    """Helper class for writing text to file descriptors"""
+    def __init__(self, fd: int):
+        self.fd = fd
+        self.isatty = os.isatty(fd)
+
+    def term(self, text, *, clear=False):
+        """Write text if attached to a terminal."""
+        if not self.isatty:
+            return
+
+        if clear:
+            self.write(RESET)
+
+        self.write(text)
+
+    def write(self, text: str):
+        """Write all of text to the log file descriptor"""
+        data = text.encode("utf-8")
+        n = len(data)
+        while n:
+            k = os.write(self.fd, data)
+            n -= k
+            if n:
+                data = data[n:]
+
+
+class BaseMonitor(abc.ABC):
+    """Base class for all pipeline monitors"""
+
+    def __init__(self, fd: int):
+        """Logging will be done to file descriptor `fd`"""
+        self.out = TextWriter(fd)
+
+    def begin(self, pipeline: osbuild.Pipeline):
+        """Called once at the beginning of a build"""
+
+    def finish(self, result: Dict):
+        """Called at the very end of the build"""
+
+    def stage(self, stage: osbuild.Stage):
+        """Called when a stage is being built"""
+
+    def assembler(self, assembler: osbuild.Assembler):
+        """Called when an assembler is being built"""
+
+    def result(self, result: osbuild.pipeline.BuildResult):
+        """Called when a module is done with its result"""
+
+    def log(self, message: str):
+        """Called for all module log outputs"""
+
+
+class NullMonitor(BaseMonitor):
+    """Monitor class that does not report anything"""
+
+
+class LogMonitor(BaseMonitor):
+    """Monitor that follows show the log output of modules
+
+    This monitor will print a header with `name: id` followed
+    by the options for each module as it is being built. The
+    full log messages of the modules will be print as soon as
+    they become available.
+    The constructor argument `fd` is a file descriptor, where
+    the log will get written to. If `fd`  is a `TTY`, escape
+    sequences will be used to highlight sections of the log.
+    """
+    def stage(self, stage):
+        self.module(stage)
+
+    def assembler(self, assembler):
+        self.out.term(BOLD, clear=True)
+        self.out.write("Assembler ")
+        self.out.term(RESET)
+
+        self.module(assembler)
+
+    def module(self, module):
+        options = module.options or {}
+        title = f"{module.name}: {module.id}"
+
+        self.out.term(BOLD, clear=True)
+        self.out.write(title)
+        self.out.term(RESET)
+        self.out.write(" ")
+
+        json.dump(options, self.out, indent=2)
+        self.out.write("\n")
+
+    def log(self, message):
+        self.out.write(message)
+
+
+def make(name, fd):
+    module = sys.modules[__name__]
+    monitor = getattr(module, name, None)
+    if not monitor:
+        raise ValueError(f"Unknown monitor: {name}")
+    if not issubclass(monitor, BaseMonitor):
+        raise ValueError(f"Invalid monitor: {name}")
+    return monitor(fd)
diff --git a/osbuild/objectstore.py b/osbuild/objectstore.py
index 5a292313..3b6529fd 100644
--- a/osbuild/objectstore.py
+++ b/osbuild/objectstore.py
@@ -40,7 +40,6 @@ def umount(target, lazy=True):
     subprocess.run(["umount"] + args + [target], check=True)
 
 
-# pylint: disable=too-many-instance-attributes
 class Object:
     def __init__(self, store: "ObjectStore"):
         self._init = True
diff --git a/osbuild/pipeline.py b/osbuild/pipeline.py
index 78126786..d80e561c 100644
--- a/osbuild/pipeline.py
+++ b/osbuild/pipeline.py
@@ -13,10 +13,6 @@ from . import sources
 from .util import osrelease
 
 
-RESET = "\033[0m"
-BOLD = "\033[1m"
-
-
 def cleanup(*objs):
     """Call cleanup method for all objects, filters None values out"""
     _ = map(lambda o: o.cleanup(), filter(None, objs))
@@ -34,12 +30,6 @@ class BuildResult:
         return vars(self)
 
 
-def print_header(title, options):
-    print()
-    print(f"{RESET}{BOLD}{title}{RESET} " + json.dumps(options or {}, indent=2))
-    print()
-
-
 class Stage:
     def __init__(self, name, source_options, build, base, options):
         self.name = name
@@ -71,13 +61,11 @@ class Stage:
             runner,
             build_tree,
             cache,
-            interactive=False,
+            monitor,
             libdir=None,
             var="/var/tmp"):
         with buildroot.BuildRoot(build_tree, runner, libdir=libdir, var=var) as build_root, \
             tempfile.TemporaryDirectory(prefix="osbuild-sources-output-", dir=var) as sources_output:
-            if interactive:
-                print_header(f"{self.name}: {self.id}", self.options)
 
             args = {
                 "tree": "/run/osbuild/tree",
@@ -90,7 +78,7 @@ class Stage:
 
             ro_binds = [f"{sources_output}:/run/osbuild/sources"]
 
-            with API(f"{build_root.api}/osbuild", args, interactive) as api, \
+            with API(f"{build_root.api}/osbuild", args, monitor) as api, \
                 sources.SourcesServer(f"{build_root.api}/sources",
                                       libdir or "/usr/lib/osbuild",
                                       self.sources,
@@ -129,10 +117,8 @@ class Assembler:
             description["id"] = self.id
         return description
 
-    def run(self, tree, runner, build_tree, output_dir=None, interactive=False, libdir=None, var="/var/tmp"):
+    def run(self, tree, runner, build_tree, monitor, output_dir=None, libdir=None, var="/var/tmp"):
         with buildroot.BuildRoot(build_tree, runner, libdir=libdir, var=var) as build_root:
-            if interactive:
-                print_header(f"Assembler {self.name}: {self.id}", self.options)
 
             args = {
                 "tree": "/run/osbuild/tree",
@@ -151,7 +137,7 @@ class Assembler:
             ro_binds = [f"{tree}:/run/osbuild/tree"]
 
             with remoteloop.LoopServer(f"{build_root.api}/remoteloop"), \
-                API(f"{build_root.api}/osbuild", args, interactive) as api:
+                API(f"{build_root.api}/osbuild", args, monitor) as api:
                 r = build_root.run(
                     [f"/run/osbuild/lib/assemblers/{self.name}"],
                     binds=binds,
@@ -202,7 +188,7 @@ class Pipeline:
 
         return description
 
-    def build_stages(self, object_store, interactive, libdir):
+    def build_stages(self, object_store, monitor, libdir):
         results = {"success": True}
 
         # We need a build tree for the stages below, which is either
@@ -217,7 +203,7 @@ class Pipeline:
             build = self.build
 
             r, t, tree = build.build_stages(object_store,
-                                            interactive,
+                                            monitor,
                                             libdir)
 
             results["build"] = r
@@ -266,14 +252,19 @@ class Pipeline:
 
         for stage in self.stages[base_idx + 1:]:
             with build_tree.read() as build_path, tree.write() as path:
+
+                monitor.stage(stage)
+
                 r = stage.run(path,
                               self.runner,
                               build_path,
                               object_store.store,
-                              interactive=interactive,
+                              monitor,
                               libdir=libdir,
                               var=object_store.store)
 
+                monitor.result(r)
+
             results["stages"].append(r.as_dict())
             if not r.success:
                 cleanup(build_tree, tree)
@@ -285,7 +276,7 @@ class Pipeline:
 
         return results, build_tree, tree
 
-    def assemble(self, object_store, build_tree, tree, interactive, libdir, output_directory: Optional[str]):
+    def assemble(self, object_store, build_tree, tree, monitor, libdir, output_directory: Optional[str]):
         results = {"success": True}
 
         if not self.assembler:
@@ -297,14 +288,18 @@ class Pipeline:
              tree.read() as input_dir, \
              output.write() as output_dir:
 
+            monitor.assembler(self.assembler)
+
             r = self.assembler.run(input_dir,
                                    self.runner,
                                    build_dir,
+                                   monitor,
                                    output_dir=output_dir,
-                                   interactive=interactive,
                                    libdir=libdir,
                                    var=object_store.store)
 
+            monitor.result(r)
+
         results["assembler"] = r.as_dict()
         if not r.success:
             output.cleanup()
@@ -319,10 +314,12 @@ class Pipeline:
 
         return results
 
-    def run(self, store, interactive=False, libdir=None, output_directory=None):
+    def run(self, store, monitor, libdir=None, output_directory=None):
         os.makedirs("/run/osbuild", exist_ok=True)
         results = {}
 
+        monitor.begin(self)
+
         with objectstore.ObjectStore(store) as object_store:
             # If the final result is already in the store, no need to attempt
             # building it. Just fetch the cached information. If the associated
@@ -336,7 +333,7 @@ class Pipeline:
                         output.export(output_directory)
             else:
                 results, build_tree, tree = self.build_stages(object_store,
-                                                              interactive,
+                                                              monitor,
                                                               libdir)
 
                 if not results["success"]:
@@ -345,12 +342,14 @@ class Pipeline:
                 r = self.assemble(object_store,
                                   build_tree,
                                   tree,
-                                  interactive,
+                                  monitor,
                                   libdir,
                                   output_directory)
 
                 results.update(r)  # This will also update 'success'
 
+        monitor.finish(results)
+
         return results
 
 
diff --git a/osbuild/remoteloop.py b/osbuild/remoteloop.py
index b014b5f6..75b0eea9 100644
--- a/osbuild/remoteloop.py
+++ b/osbuild/remoteloop.py
@@ -101,6 +101,7 @@ class LoopServer:
     def __exit__(self, *args):
         self.event_loop.call_soon_threadsafe(self.event_loop.stop)
         self.thread.join()
+        self.event_loop.close()
         for lo in self.devs:
             lo.close()
 
diff --git a/osbuild/sources.py b/osbuild/sources.py
index 254aff15..459188fb 100644
--- a/osbuild/sources.py
+++ b/osbuild/sources.py
@@ -6,7 +6,6 @@ from .util import jsoncomm
 
 
 class SourcesServer:
-    # pylint: disable=too-many-instance-attributes
     def __init__(self, socket_address, libdir, options, cache, output):
         self.socket_address = socket_address
         self.libdir = libdir
diff --git a/schutzbot/Jenkinsfile b/schutzbot/Jenkinsfile
index 9cb78f28..367bc9a5 100644
--- a/schutzbot/Jenkinsfile
+++ b/schutzbot/Jenkinsfile
@@ -158,12 +158,22 @@ pipeline {
 
     post {
         success {
-            when { branch 'master' }
-            telegramSend "💚 CI passed for osbuild-composer master branch!. ${env.BUILD_URL}"
+            node('schutzbot') {
+                script {
+                    if (env.BRANCH_NAME == 'master') {
+                        telegramSend "💚 CI passed for osbuild master branch ${env.BUILD_URL}"
+                    }
+                }
+            }
         }
         unsuccessful {
-            when { branch 'master' }
-            telegramSend "💣 CI failed for osbuild-composer master branch! ${env.BUILD_URL}"
+            node('schutzbot') {
+                script {
+                    if (env.BRANCH_NAME == 'master') {
+                        telegramSend "💣 CI failed for osbuild master branch ${env.BUILD_URL}"
+                    }
+                }
+            }
         }
     }
 


Test patch:
diff --git a/test/data/README.md b/test/data/README.md
index bead26e2..46dee8a3 100644
--- a/test/data/README.md
+++ b/test/data/README.md
@@ -27,6 +27,11 @@ do not allow comments, this file shortly describes their purpose.
    The `rhel` prefix is used for Red Hat Enterprise Linux images. Since they are
    not available publicly, the test-suite usually skips them.
 
+   The `filesystem` manifest is used to test assemblers. These tests doesn't
+   need a big filesystem tree representing a whole operating system. Instead,
+   this manifest's tree is constructed just from the filesystem package and is
+   marked using the selinux stage.
+
    Manifests prefixed with `mpp-*` are fed through the ManifestPreProcessors and
    then stored in the same directory with the `mpp-*` prefix dropped. The
    generated files are committed to the repository. Nevertheless, if you need to
diff --git a/test/data/manifests/filesystem.json b/test/data/manifests/filesystem.json
new file mode 100644
index 00000000..f4eb1554
--- /dev/null
+++ b/test/data/manifests/filesystem.json
@@ -0,0 +1,614 @@
+{
+  "pipeline": {
+    "build": {
+      "runner": "org.osbuild.fedora32",
+      "pipeline": {
+        "stages": [
+          {
+            "name": "org.osbuild.rpm",
+            "options": {
+              "gpgkeys": [
+                "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBF1RVqsBEADWMBqYv/G1r4PwyiPQCfg5fXFGXV1FCZ32qMi9gLUTv1CX7rYy\nH4Inj93oic+lt1kQ0kQCkINOwQczOkm6XDkEekmMrHknJpFLwrTK4AS28bYF2RjL\nM+QJ/dGXDMPYsP0tkLvoxaHr9WTRq89A+AmONcUAQIMJg3JxXAAafBi2UszUUEPI\nU35MyufFt2ePd1k/6hVAO8S2VT72TxXSY7Ha4X2J0pGzbqQ6Dq3AVzogsnoIi09A\n7fYutYZPVVAEGRUqavl0th8LyuZShASZ38CdAHBMvWV4bVZghd/wDV5ev3LXUE0o\nitLAqNSeiDJ3grKWN6v0qdU0l3Ya60sugABd3xaE+ROe8kDCy3WmAaO51Q880ZA2\niXOTJFObqkBTP9j9+ZeQ+KNE8SBoiH1EybKtBU8HmygZvu8ZC1TKUyL5gwGUJt8v\nergy5Bw3Q7av520sNGD3cIWr4fBAVYwdBoZT8RcsnU1PP67NmOGFcwSFJ/LpiOMC\npZ1IBvjOC7KyKEZY2/63kjW73mB7OHOd18BHtGVkA3QAdVlcSule/z68VOAy6bih\nE6mdxP28D4INsts8w6yr4G+3aEIN8u0qRQq66Ri5mOXTyle+ONudtfGg3U9lgicg\nz6oVk17RT0jV9uL6K41sGZ1sH/6yTXQKagdAYr3w1ix2L46JgzC+/+6SSwARAQAB\ntDFGZWRvcmEgKDMyKSA8ZmVkb3JhLTMyLXByaW1hcnlAZmVkb3JhcHJvamVjdC5v\ncmc+iQI4BBMBAgAiBQJdUVarAhsPBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAK\nCRBsEwJtEslE0LdAD/wKdAMtfzr7O2y06/sOPnrb3D39Y2DXbB8y0iEmRdBL29Bq\n5btxwmAka7JZRJVFxPsOVqZ6KARjS0/oCBmJc0jCRANFCtM4UjVHTSsxrJfuPkel\nvrlNE9tcR6OCRpuj/PZgUa39iifF/FTUfDgh4Q91xiQoLqfBxOJzravQHoK9VzrM\nNTOu6J6l4zeGzY/ocj6DpT+5fdUO/3HgGFNiNYPC6GVzeiA3AAVR0sCyGENuqqdg\nwUxV3BIht05M5Wcdvxg1U9x5I3yjkLQw+idvX4pevTiCh9/0u+4g80cT/21Cxsdx\n7+DVHaewXbF87QQIcOAing0S5QE67r2uPVxmWy/56TKUqDoyP8SNsV62lT2jutsj\nLevNxUky011g5w3bc61UeaeKrrurFdRs+RwBVkXmtqm/i6g0ZTWZyWGO6gJd+HWA\nqY1NYiq4+cMvNLatmA2sOoCsRNmE9q6jM/ESVgaH8hSp8GcLuzt9/r4PZZGl5CvU\neldOiD221u8rzuHmLs4dsgwJJ9pgLT0cUAsOpbMPI0JpGIPQ2SG6yK7LmO6HFOxb\nAkz7IGUt0gy1MzPTyBvnB+WgD1I+IQXXsJbhP5+d+d3mOnqsd6oDM/grKBzrhoUe\noNadc9uzjqKlOrmrdIR3Bz38SSiWlde5fu6xPqJdmGZRNjXtcyJlbSPVDIloxw==\n=QWRO\n-----END PGP PUBLIC KEY BLOCK-----\n"
+              ],
+              "packages": [
+                "sha256:705bdb96aab3a0f9d9e2ff48ead1208e2dbc1927d713d8637632af936235217b",
+                "sha256:c574c5432197acbe08ea15c7837be7577cd0b49902a3e65227792f051d73ce5c",
+                "sha256:22d311f22902d592f72bd0fb4010a682f796e5a4698d5ea209848468a2d5aa96",
+                "sha256:a346990bb07adca8c323a15f31b093ef6e639bde6ca84adf1a3abebc4dc9adce",
+                "sha256:7a97e71cd552285ead303d07dbb6417403edf45c0a531e02cf4ebfb0efda4975",
+                "sha256:cd01ae91895e60f189106a159bb551f906a8b663110f421ad6ee83c9e008851e",
+                "sha256:842f7a38be2e8dbb14eff3ede4091db214ebe241e1fde7a128e88c4e686b63b0",
+                "sha256:73f6a9108f7d5ec3cd89c31dbbaa874ae28cd5cb443ef69700a1218903ee2fc4",
+                "sha256:7023687eb65baa56a9b4c3ffde1e439b3d41b03ac4ad35a1a1fc3903464548f7",
+                "sha256:5323eb8d89b2d0c905a633513e04ca7df633c21eec288ee8c50f3f5170534e37",
+                "sha256:116b9d121fad9886f245cd5e1ef678fdba889cd23a39e91447e75649214a6a8d",
+                "sha256:862e75c10377098a9cc50407a0395e5f3a81d14b5b6fecfb3f223325c8867829",
+                "sha256:1aee865249b031e591a5e94d62d05b69ad1a6118a26adccf2dfd46b0002716e5",
+                "sha256:3f8dcae27ad3609b7de298d0ca8d34a2790b9898f5f1b03f3f9f8784374e307b",
+                "sha256:b821e9e8bf66abacaed4a386f9ed8ffa17f4f8be3db55e1ac31d52ba2d1faa1b",
+                "sha256:eaffaa8de8fd28ad124da12524a2ca5db86252404d70d66c7c42921dad6b69c1",
+                "sha256:6eeebf21f245bf0d6f58962dc49b6dfb51f55acb6a595c6b9cbe9628806b80a4",
+                "sha256:fefa4162a563eba24714ac43874c508d1ba036afb5127c5d21bbcbeaf238a740",
+                "sha256:ed36d759746e75a2834866fbeaa783df397f8813cae2ed79fcc4d146656bf6a6",
+                "sha256:213c17fb822ffa50fad16989ed363aa023de106c6262ccc3f16e52a154b7133f",
+                "sha256:6fc1b9a27eeb368a98f50dba5fc514f20a5eb23f8e0ee7dd92c4051ef8b4a940",
+                "sha256:474fd088c7e7234221d251153e9fda6081b0aa8979bf5ae25810c9862e1e9960",
+                "sha256:b70d1c93e3448b1a0b5e3f50488290283a260ff46e22bff4fb704469e6017fa8",
+                "sha256:c132999a3f110029cd427f7578965ad558e91374637087d5230ee11c626ebcd4",
+                "sha256:61cae80187ef2924857fdfc48a240646d23b331482cf181e7d8c661b02c15949",
+                "sha256:187dd61be71efcca6adf9819a523d432217abb335afcb2b95ef27b72928aff4b",
+                "sha256:78e1aa11379eec2906eedf843216f47bcbdfe4da4713d566fb44ca313c893f3f",
+                "sha256:80d407bbc5f6bb8d95504cfdb51faaca937f6c4c08df4c4aadcd46fe703c8a57",
+                "sha256:c3f7089ae50f79cf4d2cb59e01091d33c70cab89ae08f95c547339a87404c3ec",
+                "sha256:993680d5cd133a0c21184be92b3df405d757613d0ca25c4abf08b203d8d26b79",
+                "sha256:2fa5e252441852dae918b522a2ff3f46a5bbee4ce8936e06702bf65f57d7ff99",
+                "sha256:26db62c2bc52c3eee5f3039cdbdf19498f675d0f45aec0c2a1c61c635f01479e",
+                "sha256:4f318cec61cb69fc233ba5505b7e24f679afdfb0b5defbaef507f1b471e7dbb5",
+                "sha256:af62d0611b995b9f2b2c7b4d4852e03e521d66979534871ccb5a71275a15518d",
+                "sha256:f3eb795f68c80ccf870f1d27f8fd019878db748c0c19275634c48cf5cea5bc46",
+                "sha256:99f87b4ec7c5852d45028f3eae65fc813f3ef107e128777f265b09a19ce262e0",
+                "sha256:8fc2ae85f242105987d8fa7f05e4fa19358a7c81dff5fa163cf021eb6b9905e9",
+                "sha256:09fea9af8b695af862b19c1a8fbe1b1e8854257825ee4f663f67b3782a75d58a",
+                "sha256:1f2ba0fc562864ad1bea31a42da124030fc188d23a84d144be616c2d066e1531",
+                "sha256:a1835a7929d3c1613f3890caef878e9bdf857dcc0f63eb4d63a1140370b3f21b",
+                "sha256:21e3fd914a3bcc65b79de022782967903c55a4aed9a3c7d3464bc2fef32d02b3",
+                "sha256:28656826cb0dfbae9b6e8d1e5c5691773d84000493c4be47f727092fec6dc6f4",
+                "sha256:e0b1da98020a740991dbb70b42c0ff1eece9e268a461e555a5ec763bda1645f5",
+                "sha256:1110261787146443e089955912255d99daf7ba042c3743e13648a9eb3d80ceb4",
+                "sha256:0b7cd6f6cb3b7cd9e0704dd6c62b65254b04cb870ab638b9bed4951564436e24",
+                "sha256:9369d4fed30402f45705b7a5cb51b6eeefb1dabbe0942c84514c6fdf1edac5e0",
+                "sha256:45132e53c649def28d63c199d8c3a3b9fd16fa8bca7426ad4e9c202e52a233b4",
+                "sha256:53992752850779218421994f61f1589eda5d368e28d340dccaae3f67de06e7f2",
+                "sha256:d0e5d0104cf20c8dd332053a5903aab9b7fdadb84b35a1bfb3a6456f3399eb32",
+                "sha256:9899cfd32ada2537693af30b60051da21c6264b0d0db51ba709fceb179d4c836",
+                "sha256:349af433b2f6d45ff2e1ea5a38f847ec692fef0a8dd656a9a07d423a981946d0",
+                "sha256:fdb9bc612957a16fc44b717605a5a26e16a33850c0ff74a80a299cc2bab740e4",
+                "sha256:6fe524feb38312f9c370b2190aeb42330acc9ce42f3a45e9cd05748b4aa00db2",
+                "sha256:dc9c0401522bcf73fe5a692184c141b214947ad83364be97de0413ab46b712e5",
+                "sha256:129d919e55c09edecaa8edd0fd4058dbf7460aaae5d1c5625ca11f6df7defefe",
+                "sha256:e80533822e2a892345b869395b2c17c0bcc98d3c3c47787da30123096835db00",
+                "sha256:178e4470a6dfca84ec133932606737bfe167094560bf473940504c511354ddc9",
+                "sha256:cc3396df93ce0e8f439b83fb6b4d210903876846b0bd3a22c19c7770cf5a9050",
+                "sha256:966084f83e0fedb7a217aa102b484ac8a63082ccfe99517544ed2cb102191204",
+                "sha256:9d4f1290565b852e56f9e9babc14b141b0283998121f78b0eb83dec367cf0abb",
+                "sha256:13a0c9c767f71164cc678ee36d89b7fddcdd6fb8243e3daf8b47cca0d1d14c4f",
+                "sha256:759165656ac8141b0c0ada230c258ffcd4516c4c8d132d7fbaf762cd5a5e4095",
+                "sha256:01173d218dccdf88c1159bba4af332ce703fc0dcd7171cd279cb3e16f12b30a9",
+                "sha256:110f538d82f15f009d95e89d8c1e3669dc7358feb9aa7724301fef037f8b67fe",
+                "sha256:c2197913bc8db9548b0a40ffddf840a31956b18e932ad4eec77a48d87d2289ce",
+                "sha256:7f6d2841ec9402ee5e57f1a46b9886935138c02005d860899f3c746c7885c7b9",
+                "sha256:d1c6f183b9deaf6127db4ad7040046bd7f1aa62de177961aac39501605d2c815",
+                "sha256:53f1e8570b175e8b58895646df6d8068a7e1f3cb1bafdde714ddd038bcf91e85",
+                "sha256:c1f957511b5e011e6f7995ed7bca9196703cf1214068f209e86b1dc4fd0e98bf",
+                "sha256:f4eb6d332b9aea8d8ef0a6ea8dc2b073d6bf5f2599d64f24111d8da2ee82ad48",
+                "sha256:d3a64fcef3de79a97541b21c71ddd00d4cca9039c930bc660d6c5479eabf5f26",
+                "sha256:8a03d482b5294f7452b2f9ce31ebb6aea9eefac002281c1b9152fbb1a0341987",
+                "sha256:a05178831a546e2001e52f065fc6969f36d2292efaee2971fe7a7e882cc8c813",
+                "sha256:3be681b78e919bfd82eb186c7393718f1d37abd0b1bb8b1a8571aefa11e7a248",
+                "sha256:60774007011889671c28158f599032f0db253c153ccae70f5e2f5840f2dc490b",
+                "sha256:ccc3cb2dcb7a534361cc911f27ff4e869902a150b68e236cf6eb209a99d4ee22",
+                "sha256:3f9c95f3827b785f49ac4a270d4c3a703dceba673c452838744ec5064cf43cbd",
+                "sha256:56187c1c980cc0680f4dbc433ed2c8507e7dc9ab00000615b63ea08c086b7ab2",
+                "sha256:fbb81a7811f7a11b1c95eec20c3df63beef9e007f0b3d2713f13ad80029d7249",
+                "sha256:e2b2dddbce49fab5f01ba75fae8796ab7c9fd8280c652f78d06a2644246bd16d",
+                "sha256:f826f984b23d0701a1b72de5882b9c0e7bae87ef49d9edfea156654f489f8b2b",
+                "sha256:a410db5c56d4f39f6ea71e7d5bb6d4a2bd518015d1e34f38fbc0d7bbd4e872d4",
+                "sha256:88f4bd19a6cf6eba5e6f2b5bba80819b5ccddb0476aadc53c8df13f9c45b1e58",
+                "sha256:7d9bd2fe016ca8860e8fab4a430b3aae4c7b7bea55f8ccd7775ad470172e2886",
+                "sha256:598a136b7027cb9b4fef6bfa34715979d41c2f62c9d8bec5d50b633a17790f7b",
+                "sha256:65e0cfe367ae4d54cf8bf509cb05e063c9eb6f2fea8dadcf746cdd85adc31d88",
+                "sha256:1830b4aa42ef492c13b62f63fe941970869ba19bd9abde4dea5c97f9e38ffd68",
+                "sha256:ac8b1fea0b678d7630033a8900be5641b934306961b39a29c79c6d72f34f7d1c",
+                "sha256:1bc0542cf8a3746d0fe25c397a93c8206963f1f287246c6fb864eedfc9ffa4a7",
+                "sha256:b60670fdcf91b50d97720f601d92277efedbd690bd887000ccd9a46b3fa8b314",
+                "sha256:4494013eac1ad337673f084242aa8ebffb4a149243475b448bee9266401f2896",
+                "sha256:e9a3ace2c71c2388ed6402e92ba148acb8d19b5c3495a47148b9e88cc6d6d1eb",
+                "sha256:63400fedea4a6ddb8fced58d33e60560791f29cd439169998f337d09fb50a7d4",
+                "sha256:7dfe1e8dac6d759479ae3dfd415fdd2662bbed9ff0f4da6093279efd1bacae31",
+                "sha256:688fcc0b7ef3c48cf7d602eefd7fefae7bcad4f0dc71c9fe9432c2ce5bbd9daa",
+                "sha256:431d836b2be015212d8c15b4290d5ce5bb45282cbf3fc52696f632d84ce34dfe",
+                "sha256:fa08dccd7a2e38dfbab999613bdb41df2034b506d21964d0ef368af6e56c4cf9",
+                "sha256:7bf42ff57ce2a31db0da7d6c5926552f4e51e9f25cded77bd634eb5cd35eadab",
+                "sha256:942d06ec1f7033ea4c729b84ee09f5491481770efe10151ba581479ac7f3f9dc",
+                "sha256:86c87a4169bdf75c6d3a2f11d3a7e20b6364b2db97c74bc7eb62b1b22bc54401",
+                "sha256:48cf5ab32f6af8f2283d4d4834e8dd262aa412be7ea07c2292483e150d614bef",
+                "sha256:5f0ae954b5955c86623e68cd81ccf8505a89f260003b8a3be6a93bd76f18452c",
+                "sha256:d65b4bb6fa49198237f9b704ec471d71dfd94b87290f4d03c1c34d12f6efeb95",
+                "sha256:9bd5cb588664e8427bc8bebde0cdf5e14315916624ab6b1979dde60f6eae4278",
+                "sha256:20787251df57a108bbf9c40e30f041b71ac36c8a10900fb699e574ee7e259bf2",
+                "sha256:8677b34fa73f258b1a599d18419f6fbbb8961bb1ca2ae5b0f9abdcc4f93b319e",
+                "sha256:5d5c8c7e9c78e3b8827ad38771efb44951d1c3c1692cf4e07b138c1c8c42bd5b",
+                "sha256:1b05dd5abad5a31380c859bc33e7851158c24333fda837ca9facf869005f81fe",
+                "sha256:6eb95e39b9771c4dde5f9954a74cef6be90522c28c7c4aa767ebe7a9d55fcdf9",
+                "sha256:1c68255945533ed4e3368125bc46e19f3fe348d7ec507a85a35038dbb976003f",
+                "sha256:f98f854a86c68b534f71e1f35852fabddbe2cbfe481b01bb15291b3363013b2a",
+                "sha256:aa5b658fd4a95c724b61eddadecdbcbc1b2a813ae681318ab092a2ed03954825",
+                "sha256:e740cc0a580639b887bda0039a779e750a32835be1fd8c64aa01183b4cbb98bf",
+                "sha256:884357540f4be2a74e608e2c7a31f2371ee3b4d29be2fe39a371c0b131d84aa6",
+                "sha256:ec6abd65541b5bded814de19c9d064e6c21e3d8b424dba7cb25b2fdc52d45a2b",
+                "sha256:a8ce7406c87f64972f0b70f1823c2aad05516c71fe375c6c97737459c2448825",
+                "sha256:3b4ce7fc4e2778758881feedf6ea19b65e99aa3672e19a7dd62977efe3b910b9",
+                "sha256:b3230630a471b806a9153669d187508350cdb2b368a68f8c439c82abad038c3f",
+                "sha256:ce8c1f1ce3cb2cc0166dcaad17f35e84278ec39ea9bf232e24130d3ff3271923",
+                "sha256:9ecc8aa9af05ba704cec879618afeda5ff92d8233811e2d6080aa02e0b5ceddf",
+                "sha256:aa783a91b1823b7b056575e6276df35910eb2e0d4b72121cf5649651c7d23a16",
+                "sha256:3d33c29bcc4a39be16d6647a70a0d7ae2f08baf26dcea5c802289df1128d5f21",
+                "sha256:df0a39eb6b91c4a8f481c22445cbbd88334bf5e0a6e1dd5fb240981eb031c4eb",
+                "sha256:251fd875421da4708b76c15c7f5ba478d50b74d7e4242071a621625eac51a767",
+                "sha256:0e59b422e35eee975ba68e6e4de022c8f145feec7e169e86e0244d2fdad2f590",
+                "sha256:1446032720fb8e0090190828fcea294a86fc7f83edd70f6089e3446770ba0438",
+                "sha256:54cb827278ae474cbab1f05e0fbee0355bee2674d46a804f1c2b78ff80a48caa",
+                "sha256:29e2b62e9e63f25139a6863c863c3b534660440d7dec0c985807302a6895dbaf",
+                "sha256:942707884401498938fba6e2439dc923d4e2d81f4bac205f4e73d458e9879927",
+                "sha256:ddad78d00b09c6c85d46c06dcba4c951f7f7dfc9b2dab195bf45aa3f5a1fdc41",
+                "sha256:be899d3e806441b1c46811c0ffe9f4e01f4ea4e1544f9cc32630254853e3f3a5",
+                "sha256:27701cda24f5f6386e0173745aabc4f6df28052975e73529854432c35399cfc8",
+                "sha256:32f8cbb3be91f589d569a2e737130f29c752f78eebc61e287af17f207e1b8c58",
+                "sha256:49bac21d5cdf863fccfcc32bf070e582d204706e35ee9f60b3e69df694bff87d",
+                "sha256:be998dfbcc9ca8e3021ac4f56ed723cfa3fa1517524e89ee0b636f623abe995f",
+                "sha256:052d04c9a6697c6e5aa546546ae5058d547fc4a4f474d2805a3e45dbf69193c6",
+                "sha256:b35256e417fd94c7efb1212f2f36b5e6b224ff5b9e8733774d4fbdc652078099",
+                "sha256:c1d754773972b5f4ca157c0afa45d6767901d965a91f381660c72740d682df63",
+                "sha256:fb06aa3d8059406a23694ddafe0ef340ca627dd68bf3f351f094de58ef30fb2c",
+                "sha256:729fb595040f1e2e71ff0a8c1c22ebe4b7187f78b816af8e6a8d93c03fc5d844",
+                "sha256:f9ccea65ecf98f4dfac65d25986d08efa62a1d1c0db9db0a061e7408d6805a1a",
+                "sha256:8402d3aabfc02c16f3789f3f93338dbee2448db8a49956002b83aff5390922d9",
+                "sha256:ed84414c9b2190d3026f58db78dffd8bc3a9ad40311cb0adb8ff8e3c7c06ca60",
+                "sha256:7c1a229f4a36ac8b077e0514f68f311229652121528b0f8a2a7434c618276dcb",
+                "sha256:cb4fb9b3733440ea15b3309c88d9471c4165aa7b71b4dbc5d0fb5bfcd97b2f2e",
+                "sha256:ae219ad5ecc0233271c3fd61263f817c646eecece19a8f075e7aa4dd9ff8698e",
+                "sha256:a7f040de29d2414cc99fcffcd9ed3fa9d06ecc7aecd783ec3d2eef769e2389f1",
+                "sha256:9c8a274158a6fe97598e33900cd51e171f7e7517ccfc8ad6351873e69b225986",
+                "sha256:9465f2f1103697207a52d15edd716ab72dc6c281823c60f424cd064d706c7a51",
+                "sha256:10883ce95852cc9ae9b4e0d435b100a25f8fe5c0ea4677eb4a0b39f4f8def886",
+                "sha256:44cfb58b368fba586981aa838a7f3974ac1d66d2b3b695f88d7b1d2e9c81a0b6",
+                "sha256:640afe5b9d499c9a7efc1d23cce8c54e3e3704d92eb7e7a93a048f97d1e983e1",
+                "sha256:2b098bc6f8004270ee9eac9f63980b364b5fe19394dc73a230b3c846cf488b1b",
+                "sha256:b2e862283ac97b1d8b1ede2034ead452ac7dc4ff308593306275b1b0ae5b4102",
+                "sha256:25fc5d288536e1973436da38357690575ed58e03e17ca48d2b3840364f830659",
+                "sha256:04152a3a608d022a58830c0e3dac0818e2c060469b0f41d8d731f659981a4464",
+                "sha256:c019d23ed2cb3ceb0ac9757a72c3e8b1d31f2a524b889e18049cc7d923bc9466",
+                "sha256:3c2a641f118ab2e8b08df6dd2da72a60121d02df8d932b4afa2920eb80392875",
+                "sha256:ade8105796f5c1201a3efc8bcc654788cfc88c3815297b346845062a8c29cd59",
+                "sha256:d7b8b5815b72fb157de26579362383e357e026ae6ac2599c451fb336fe995555",
+                "sha256:ad6d7d9767e05978b14a39c08dba59ddc4396584576df194f77ed310a0816ae0",
+                "sha256:3f2cb9092d6f55f84dd9eacd5359dfb354772e5f38308328027c7758f4a06fb6",
+                "sha256:45fc2608b746fd841dd25919e9e4d44834154758aec8fb8b529c014b11c7917d",
+                "sha256:ec64add7d60a70fbaf14a083929f22bd2637c33d20d2a30b7e842caa6040f817",
+                "sha256:3343d9e7c90bd58e1e44ee07e7c59bb570ffc74da50f0607c5f5681a00b70e76",
+                "sha256:dedd37a96262c35763ab2dcbc19838f5cc39a2a3a392a650a80bd6d5ae42ff8b",
+                "sha256:3589b982ac0c2f5f6b47cde5cb7ec33c2c01d756dabf8c4ca64f6d9d0d78b35e",
+                "sha256:4c80ade4ac0889316930a8d181ea43fa2d1b2f1a6a5703c22f2b3ba191346eec",
+                "sha256:933bdb4cc6e14b2ebb1ca76c14ca176c13d271a2d1e88632f237392777d11808",
+                "sha256:6794fe48004c0403c29fc779b49f0fbea436123b96783a2df225eef2f0858795",
+                "sha256:5db7c0e949bd9172b9645237e72f6139d4ffcf14defad487262b8ad25b427daf",
+                "sha256:15f08ce979e48fd25be5e16d63d1c95c57f9abff7704005137ea00b958442939",
+                "sha256:7df4fa1a29772696d92866e890af6fbe006088f3407ed3e67b0e7867ef58d899",
+                "sha256:8df97dcfb42c1667b5d2e4150012eaf96f58eeac4f7b879e0928c8c36e3a7604",
+                "sha256:d439ffbe20c8c0e8244e31c0324d60cf959dc1cd6cecc575d7b34509a73e9386",
+                "sha256:8a0c00a69f9cb3a9ffacaf1cdc162c38a1faca76c9b976cb177bdc988902f2d4",
+                "sha256:f3908831ae53f43b07a4e196850d0e59cc89b50c97d838538c3185fd0eb0d569",
+                "sha256:af992ad02594b68f17d2da41104a26aee41d02639edf22332d7dbb1fe9af58a5",
+                "sha256:a7da5590635b9c19afafc7dd247604194a5ce7d8d863dc600b8cb86accb2e469",
+                "sha256:7dd93baaf69a8004ae2cd3b9e6660b862d0b6f399d53c05a27a48a2e276ef1ee",
+                "sha256:0b290954bc2868b3dfc976b2b7a13ea8aeade76eeafc17674ff8e721049a5bf7",
+                "sha256:b79bb6af3e1650ba812c8affe42772ea566b164222a7d4d8e2f7efa867dc6849",
+                "sha256:632aedc06003e319a1c3fa98876055fc3bd3b44c1188b44d3b7a455cef0d40e4",
+                "sha256:9de8eb13fbdf8b8c5c3e04c52a890ccc5b667351ff17152786d12ffc66210433",
+                "sha256:6a2f4706a37bc5ad229f6fdddbd70fbcf82da85ec577a8deeb455513cbedc174",
+                "sha256:0d9d80adb91ccc8eed62bea68b23da5edb77675b1ec93227e2179d028449a2f7",
+                "sha256:44fabecae31a5900fe10837863ed231303f6863bd9fa5efa40a93a0fc059344f",
+                "sha256:ec58d03c60386bfb8aed2af3d2a49f8c6e5ccb4d3fd592cf75fef3342be137c3",
+                "sha256:9ade87dbb32f27e7f38ec981002ddc5a2189cc6f5ad5f24bada3b71cfa9167fd",
+                "sha256:355a095bb3c6d58f927277ff53267f88eb0729adbcafd8082b8d97e4815ee206",
+                "sha256:724cca9919bb7b0183b030aca216d4d51de70bf35c2cc5e8325a21a52ca15ceb",
+                "sha256:517ff9662e5a1897b74f4ab4fbc8a88eccaad9880bc18be9cf4df6aba9824bd5",
+                "sha256:475b6de876914aec2187ac4858a13ae75585f5c4cb5d739c637f79a5ca6f05f9",
+                "sha256:f1150f9e17beaef09aca0f291e10db8c3ee5566fbf4c929b7672334410fa74e9",
+                "sha256:f1c79039f4c6ba0fad88590c2cb55a96489449c334a671cc18c0bf424a4548b8",
+                "sha256:136a9cbae9c225be60718fdc8cc8988a55235d6502e451df77d1c5c765143850",
+                "sha256:3151132084577032b4c827eb577a1509950601888c6ff13a0a30b24252ee26d2",
+                "sha256:54b740cf7a75a7215168970378d9a1d6b9a5e4eb81159a874ce8ea5990436641",
+                "sha256:ee664c392a97cdd272f57980c6856b2c57567005fa0ad9cb16c388b645d014f1",
+                "sha256:9d220d8ee28cd0adf28e8fef547af92c3ec66e238747165939cf8e1a413ddf83",
+                "sha256:e2a04f4de125ff60a3cdc3d2b3718a4530a9c9240c9cf14f55938444c229539f",
+                "sha256:630ad20496ff00f76764e01b9302ccbe94e3e91d76ececef88bd9e8a890b1ac3",
+                "sha256:ffe5076b9018efdb1612c487f637af39ab6c3c79ec37311978935cfa357ecd61",
+                "sha256:a336d2e77255df4783f52762e44efcc8d77b044a3e39c7f577d5535212848280",
+                "sha256:4dd6100e477d88a4987b6eebfddecff168f38c7ff47cbb12f2fecba1e87c10d9",
+                "sha256:a280c633b73517da167b91298fc97aeee2eb5fcc253c038ae0ce4b8478d3a103",
+                "sha256:7f555c600b35ba798d8c0a63e30a1a12e917231730e1a44f48161ba0fe4b5973",
+                "sha256:1de2be4fe5280ec3097305d9e671f5f2c768267f90d255edf2075eecb0c0afe9",
+                "sha256:78db9007c08fa51f177210e47343b8e733ce0751826abb357ca96429836588db",
+                "sha256:750da30da0289d5e2ad9ca297dda44e5ca18dbed0c3e0d4200379bc1818c22f3",
+                "sha256:97197411bca68cfba1ef6bab1fdd4b41c95ec71c36f1e67f525b963cf60598fd",
+                "sha256:334d63914e7ff6fe8cfce0c8f80006c6cf2ab0615cd044a6ee588809395499e5",
+                "sha256:2cee64e12b295b74d2f4b008c7628ef3a01ef4149905fc4a7ae14b304da5f53b",
+                "sha256:5f156c2a950699d5cb9a21349cce049b3c8bfdcc4fcc780665fe2d3103f576c1",
+                "sha256:cc1be420582afb6360f380ff301c5e3d873f69fe1f7e00e4450bf2daa40ef9ff",
+                "sha256:6f669ae6f70cfa80917adf4ae9d5e86fbd9d31ee308a9a3408a19be3afc46f7b",
+                "sha256:2db6d80760ab0e99f4e9c9816615e4f06b967bbb23a8c8c941b3f2d4b5f176c2",
+                "sha256:29d7df69d66f51f6dddd637d3f599e70bdaa9bd476669002250bc038735a318c",
+                "sha256:9976e6228a10fa2761f1265a2a7666578d79ca57819837e5d1fbecc53324f1b9",
+                "sha256:82e0d8f1e0dccc6d18acd04b7806350343140d9c91da7a216f93167dcf650a61",
+                "sha256:d027a3ff0712e3e98d7d2358f8c526fb8d143b2386c353aadcc27199cffe125b",
+                "sha256:ec12fef82d73314e3e4cb6e962f8de27e78989fa104dde0599a4480a53817647",
+                "sha256:1bdde5dc99a5588a8983f70b7b3e45e7006215d529c72adfec118c3bcbf7b01c",
+                "sha256:84702d6395a9577c1a268184f123cfd4b15bc2287f01033625ba388a34ec2338",
+                "sha256:140708561a2ec1c7709fd38d8b1b115d02da710b80eeecd65c2b8387d9d78ef9",
+                "sha256:c0fff40dc1092e18ed3e608bc6143c89a0d7775b9e0553319bb2caca7d324d80"
+              ]
+            }
+          }
+        ]
+      }
+    },
+    "stages": [
+      {
+        "name": "org.osbuild.rpm",
+        "options": {
+          "gpgkeys": [
+            "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBF1RVqsBEADWMBqYv/G1r4PwyiPQCfg5fXFGXV1FCZ32qMi9gLUTv1CX7rYy\nH4Inj93oic+lt1kQ0kQCkINOwQczOkm6XDkEekmMrHknJpFLwrTK4AS28bYF2RjL\nM+QJ/dGXDMPYsP0tkLvoxaHr9WTRq89A+AmONcUAQIMJg3JxXAAafBi2UszUUEPI\nU35MyufFt2ePd1k/6hVAO8S2VT72TxXSY7Ha4X2J0pGzbqQ6Dq3AVzogsnoIi09A\n7fYutYZPVVAEGRUqavl0th8LyuZShASZ38CdAHBMvWV4bVZghd/wDV5ev3LXUE0o\nitLAqNSeiDJ3grKWN6v0qdU0l3Ya60sugABd3xaE+ROe8kDCy3WmAaO51Q880ZA2\niXOTJFObqkBTP9j9+ZeQ+KNE8SBoiH1EybKtBU8HmygZvu8ZC1TKUyL5gwGUJt8v\nergy5Bw3Q7av520sNGD3cIWr4fBAVYwdBoZT8RcsnU1PP67NmOGFcwSFJ/LpiOMC\npZ1IBvjOC7KyKEZY2/63kjW73mB7OHOd18BHtGVkA3QAdVlcSule/z68VOAy6bih\nE6mdxP28D4INsts8w6yr4G+3aEIN8u0qRQq66Ri5mOXTyle+ONudtfGg3U9lgicg\nz6oVk17RT0jV9uL6K41sGZ1sH/6yTXQKagdAYr3w1ix2L46JgzC+/+6SSwARAQAB\ntDFGZWRvcmEgKDMyKSA8ZmVkb3JhLTMyLXByaW1hcnlAZmVkb3JhcHJvamVjdC5v\ncmc+iQI4BBMBAgAiBQJdUVarAhsPBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAK\nCRBsEwJtEslE0LdAD/wKdAMtfzr7O2y06/sOPnrb3D39Y2DXbB8y0iEmRdBL29Bq\n5btxwmAka7JZRJVFxPsOVqZ6KARjS0/oCBmJc0jCRANFCtM4UjVHTSsxrJfuPkel\nvrlNE9tcR6OCRpuj/PZgUa39iifF/FTUfDgh4Q91xiQoLqfBxOJzravQHoK9VzrM\nNTOu6J6l4zeGzY/ocj6DpT+5fdUO/3HgGFNiNYPC6GVzeiA3AAVR0sCyGENuqqdg\nwUxV3BIht05M5Wcdvxg1U9x5I3yjkLQw+idvX4pevTiCh9/0u+4g80cT/21Cxsdx\n7+DVHaewXbF87QQIcOAing0S5QE67r2uPVxmWy/56TKUqDoyP8SNsV62lT2jutsj\nLevNxUky011g5w3bc61UeaeKrrurFdRs+RwBVkXmtqm/i6g0ZTWZyWGO6gJd+HWA\nqY1NYiq4+cMvNLatmA2sOoCsRNmE9q6jM/ESVgaH8hSp8GcLuzt9/r4PZZGl5CvU\neldOiD221u8rzuHmLs4dsgwJJ9pgLT0cUAsOpbMPI0JpGIPQ2SG6yK7LmO6HFOxb\nAkz7IGUt0gy1MzPTyBvnB+WgD1I+IQXXsJbhP5+d+d3mOnqsd6oDM/grKBzrhoUe\noNadc9uzjqKlOrmrdIR3Bz38SSiWlde5fu6xPqJdmGZRNjXtcyJlbSPVDIloxw==\n=QWRO\n-----END PGP PUBLIC KEY BLOCK-----\n"
+          ],
+          "packages": [
+            "sha256:c574c5432197acbe08ea15c7837be7577cd0b49902a3e65227792f051d73ce5c",
+            "sha256:22d311f22902d592f72bd0fb4010a682f796e5a4698d5ea209848468a2d5aa96",
+            "sha256:a346990bb07adca8c323a15f31b093ef6e639bde6ca84adf1a3abebc4dc9adce",
+            "sha256:7a97e71cd552285ead303d07dbb6417403edf45c0a531e02cf4ebfb0efda4975",
+            "sha256:842f7a38be2e8dbb14eff3ede4091db214ebe241e1fde7a128e88c4e686b63b0",
+            "sha256:73f6a9108f7d5ec3cd89c31dbbaa874ae28cd5cb443ef69700a1218903ee2fc4",
+            "sha256:7023687eb65baa56a9b4c3ffde1e439b3d41b03ac4ad35a1a1fc3903464548f7",
+            "sha256:5323eb8d89b2d0c905a633513e04ca7df633c21eec288ee8c50f3f5170534e37",
+            "sha256:862e75c10377098a9cc50407a0395e5f3a81d14b5b6fecfb3f223325c8867829",
+            "sha256:1aee865249b031e591a5e94d62d05b69ad1a6118a26adccf2dfd46b0002716e5",
+            "sha256:3f8dcae27ad3609b7de298d0ca8d34a2790b9898f5f1b03f3f9f8784374e307b",
+            "sha256:b821e9e8bf66abacaed4a386f9ed8ffa17f4f8be3db55e1ac31d52ba2d1faa1b",
+            "sha256:6eeebf21f245bf0d6f58962dc49b6dfb51f55acb6a595c6b9cbe9628806b80a4",
+            "sha256:fefa4162a563eba24714ac43874c508d1ba036afb5127c5d21bbcbeaf238a740",
+            "sha256:187dd61be71efcca6adf9819a523d432217abb335afcb2b95ef27b72928aff4b",
+            "sha256:8fc2ae85f242105987d8fa7f05e4fa19358a7c81dff5fa163cf021eb6b9905e9",
+            "sha256:09fea9af8b695af862b19c1a8fbe1b1e8854257825ee4f663f67b3782a75d58a",
+            "sha256:1f2ba0fc562864ad1bea31a42da124030fc188d23a84d144be616c2d066e1531",
+            "sha256:a1835a7929d3c1613f3890caef878e9bdf857dcc0f63eb4d63a1140370b3f21b",
+            "sha256:21e3fd914a3bcc65b79de022782967903c55a4aed9a3c7d3464bc2fef32d02b3",
+            "sha256:1110261787146443e089955912255d99daf7ba042c3743e13648a9eb3d80ceb4",
+            "sha256:d0e5d0104cf20c8dd332053a5903aab9b7fdadb84b35a1bfb3a6456f3399eb32",
+            "sha256:9899cfd32ada2537693af30b60051da21c6264b0d0db51ba709fceb179d4c836",
+            "sha256:dc9c0401522bcf73fe5a692184c141b214947ad83364be97de0413ab46b712e5",
+            "sha256:129d919e55c09edecaa8edd0fd4058dbf7460aaae5d1c5625ca11f6df7defefe",
+            "sha256:e80533822e2a892345b869395b2c17c0bcc98d3c3c47787da30123096835db00",
+            "sha256:178e4470a6dfca84ec133932606737bfe167094560bf473940504c511354ddc9",
+            "sha256:759165656ac8141b0c0ada230c258ffcd4516c4c8d132d7fbaf762cd5a5e4095",
+            "sha256:53f1e8570b175e8b58895646df6d8068a7e1f3cb1bafdde714ddd038bcf91e85",
+            "sha256:ccc3cb2dcb7a534361cc911f27ff4e869902a150b68e236cf6eb209a99d4ee22",
+            "sha256:e2b2dddbce49fab5f01ba75fae8796ab7c9fd8280c652f78d06a2644246bd16d",
+            "sha256:f826f984b23d0701a1b72de5882b9c0e7bae87ef49d9edfea156654f489f8b2b",
+            "sha256:88f4bd19a6cf6eba5e6f2b5bba80819b5ccddb0476aadc53c8df13f9c45b1e58",
+            "sha256:65e0cfe367ae4d54cf8bf509cb05e063c9eb6f2fea8dadcf746cdd85adc31d88",
+            "sha256:1830b4aa42ef492c13b62f63fe941970869ba19bd9abde4dea5c97f9e38ffd68",
+            "sha256:ac8b1fea0b678d7630033a8900be5641b934306961b39a29c79c6d72f34f7d1c",
+            "sha256:1bc0542cf8a3746d0fe25c397a93c8206963f1f287246c6fb864eedfc9ffa4a7",
+            "sha256:b60670fdcf91b50d97720f601d92277efedbd690bd887000ccd9a46b3fa8b314",
+            "sha256:4494013eac1ad337673f084242aa8ebffb4a149243475b448bee9266401f2896",
+            "sha256:7dfe1e8dac6d759479ae3dfd415fdd2662bbed9ff0f4da6093279efd1bacae31",
+            "sha256:688fcc0b7ef3c48cf7d602eefd7fefae7bcad4f0dc71c9fe9432c2ce5bbd9daa",
+            "sha256:431d836b2be015212d8c15b4290d5ce5bb45282cbf3fc52696f632d84ce34dfe",
+            "sha256:942d06ec1f7033ea4c729b84ee09f5491481770efe10151ba581479ac7f3f9dc",
+            "sha256:86c87a4169bdf75c6d3a2f11d3a7e20b6364b2db97c74bc7eb62b1b22bc54401",
+            "sha256:48cf5ab32f6af8f2283d4d4834e8dd262aa412be7ea07c2292483e150d614bef",
+            "sha256:5f0ae954b5955c86623e68cd81ccf8505a89f260003b8a3be6a93bd76f18452c",
+            "sha256:9bd5cb588664e8427bc8bebde0cdf5e14315916624ab6b1979dde60f6eae4278",
+            "sha256:20787251df57a108bbf9c40e30f041b71ac36c8a10900fb699e574ee7e259bf2",
+            "sha256:6eb95e39b9771c4dde5f9954a74cef6be90522c28c7c4aa767ebe7a9d55fcdf9",
+            "sha256:e740cc0a580639b887bda0039a779e750a32835be1fd8c64aa01183b4cbb98bf",
+            "sha256:a8ce7406c87f64972f0b70f1823c2aad05516c71fe375c6c97737459c2448825",
+            "sha256:3b4ce7fc4e2778758881feedf6ea19b65e99aa3672e19a7dd62977efe3b910b9",
+            "sha256:ce8c1f1ce3cb2cc0166dcaad17f35e84278ec39ea9bf232e24130d3ff3271923",
+            "sha256:9ecc8aa9af05ba704cec879618afeda5ff92d8233811e2d6080aa02e0b5ceddf",
+            "sha256:0e59b422e35eee975ba68e6e4de022c8f145feec7e169e86e0244d2fdad2f590",
+            "sha256:1446032720fb8e0090190828fcea294a86fc7f83edd70f6089e3446770ba0438",
+            "sha256:54cb827278ae474cbab1f05e0fbee0355bee2674d46a804f1c2b78ff80a48caa",
+            "sha256:29e2b62e9e63f25139a6863c863c3b534660440d7dec0c985807302a6895dbaf",
+            "sha256:942707884401498938fba6e2439dc923d4e2d81f4bac205f4e73d458e9879927",
+            "sha256:ddad78d00b09c6c85d46c06dcba4c951f7f7dfc9b2dab195bf45aa3f5a1fdc41",
+            "sha256:32f8cbb3be91f589d569a2e737130f29c752f78eebc61e287af17f207e1b8c58",
+            "sha256:49bac21d5cdf863fccfcc32bf070e582d204706e35ee9f60b3e69df694bff87d",
+            "sha256:052d04c9a6697c6e5aa546546ae5058d547fc4a4f474d2805a3e45dbf69193c6",
+            "sha256:c1d754773972b5f4ca157c0afa45d6767901d965a91f381660c72740d682df63",
+            "sha256:fb06aa3d8059406a23694ddafe0ef340ca627dd68bf3f351f094de58ef30fb2c",
+            "sha256:f9ccea65ecf98f4dfac65d25986d08efa62a1d1c0db9db0a061e7408d6805a1a",
+            "sha256:8402d3aabfc02c16f3789f3f93338dbee2448db8a49956002b83aff5390922d9",
+            "sha256:ed84414c9b2190d3026f58db78dffd8bc3a9ad40311cb0adb8ff8e3c7c06ca60",
+            "sha256:7c1a229f4a36ac8b077e0514f68f311229652121528b0f8a2a7434c618276dcb",
+            "sha256:cb4fb9b3733440ea15b3309c88d9471c4165aa7b71b4dbc5d0fb5bfcd97b2f2e",
+            "sha256:a7f040de29d2414cc99fcffcd9ed3fa9d06ecc7aecd783ec3d2eef769e2389f1",
+            "sha256:9465f2f1103697207a52d15edd716ab72dc6c281823c60f424cd064d706c7a51",
+            "sha256:10883ce95852cc9ae9b4e0d435b100a25f8fe5c0ea4677eb4a0b39f4f8def886",
+            "sha256:44cfb58b368fba586981aa838a7f3974ac1d66d2b3b695f88d7b1d2e9c81a0b6",
+            "sha256:640afe5b9d499c9a7efc1d23cce8c54e3e3704d92eb7e7a93a048f97d1e983e1",
+            "sha256:2b098bc6f8004270ee9eac9f63980b364b5fe19394dc73a230b3c846cf488b1b",
+            "sha256:b2e862283ac97b1d8b1ede2034ead452ac7dc4ff308593306275b1b0ae5b4102",
+            "sha256:25fc5d288536e1973436da38357690575ed58e03e17ca48d2b3840364f830659",
+            "sha256:04152a3a608d022a58830c0e3dac0818e2c060469b0f41d8d731f659981a4464",
+            "sha256:ade8105796f5c1201a3efc8bcc654788cfc88c3815297b346845062a8c29cd59",
+            "sha256:ad6d7d9767e05978b14a39c08dba59ddc4396584576df194f77ed310a0816ae0",
+            "sha256:3f2cb9092d6f55f84dd9eacd5359dfb354772e5f38308328027c7758f4a06fb6",
+            "sha256:dedd37a96262c35763ab2dcbc19838f5cc39a2a3a392a650a80bd6d5ae42ff8b",
+            "sha256:3589b982ac0c2f5f6b47cde5cb7ec33c2c01d756dabf8c4ca64f6d9d0d78b35e",
+            "sha256:4c80ade4ac0889316930a8d181ea43fa2d1b2f1a6a5703c22f2b3ba191346eec",
+            "sha256:933bdb4cc6e14b2ebb1ca76c14ca176c13d271a2d1e88632f237392777d11808",
+            "sha256:6794fe48004c0403c29fc779b49f0fbea436123b96783a2df225eef2f0858795",
+            "sha256:5db7c0e949bd9172b9645237e72f6139d4ffcf14defad487262b8ad25b427daf",
+            "sha256:8df97dcfb42c1667b5d2e4150012eaf96f58eeac4f7b879e0928c8c36e3a7604",
+            "sha256:8a0c00a69f9cb3a9ffacaf1cdc162c38a1faca76c9b976cb177bdc988902f2d4",
+            "sha256:af992ad02594b68f17d2da41104a26aee41d02639edf22332d7dbb1fe9af58a5",
+            "sha256:a7da5590635b9c19afafc7dd247604194a5ce7d8d863dc600b8cb86accb2e469",
+            "sha256:7dd93baaf69a8004ae2cd3b9e6660b862d0b6f399d53c05a27a48a2e276ef1ee",
+            "sha256:0b290954bc2868b3dfc976b2b7a13ea8aeade76eeafc17674ff8e721049a5bf7",
+            "sha256:b79bb6af3e1650ba812c8affe42772ea566b164222a7d4d8e2f7efa867dc6849",
+            "sha256:ec58d03c60386bfb8aed2af3d2a49f8c6e5ccb4d3fd592cf75fef3342be137c3",
+            "sha256:9ade87dbb32f27e7f38ec981002ddc5a2189cc6f5ad5f24bada3b71cfa9167fd",
+            "sha256:724cca9919bb7b0183b030aca216d4d51de70bf35c2cc5e8325a21a52ca15ceb",
+            "sha256:f1c79039f4c6ba0fad88590c2cb55a96489449c334a671cc18c0bf424a4548b8",
+            "sha256:136a9cbae9c225be60718fdc8cc8988a55235d6502e451df77d1c5c765143850",
+            "sha256:54b740cf7a75a7215168970378d9a1d6b9a5e4eb81159a874ce8ea5990436641",
+            "sha256:27dd9c78e41c04b5151a2b9ac150d3ebb89f2ca7a23e4896dfc718f19a000be3",
+            "sha256:ffe5076b9018efdb1612c487f637af39ab6c3c79ec37311978935cfa357ecd61",
+            "sha256:932a37ddd2a990a22a1ee7811d204552e8860e39a3e0c050ed618a535ae8c78c",
+            "sha256:684aae86de55bd42215c136777613211f596788d3b6405d8fa645fb967904354",
+            "sha256:a336d2e77255df4783f52762e44efcc8d77b044a3e39c7f577d5535212848280",
+            "sha256:4dd6100e477d88a4987b6eebfddecff168f38c7ff47cbb12f2fecba1e87c10d9",
+            "sha256:7f555c600b35ba798d8c0a63e30a1a12e917231730e1a44f48161ba0fe4b5973",
+            "sha256:78db9007c08fa51f177210e47343b8e733ce0751826abb357ca96429836588db",
+            "sha256:2db6d80760ab0e99f4e9c9816615e4f06b967bbb23a8c8c941b3f2d4b5f176c2",
+            "sha256:9976e6228a10fa2761f1265a2a7666578d79ca57819837e5d1fbecc53324f1b9",
+            "sha256:d027a3ff0712e3e98d7d2358f8c526fb8d143b2386c353aadcc27199cffe125b",
+            "sha256:84702d6395a9577c1a268184f123cfd4b15bc2287f01033625ba388a34ec2338",
+            "sha256:c0fff40dc1092e18ed3e608bc6143c89a0d7775b9e0553319bb2caca7d324d80"
+          ]
+        }
+      },
+      {
+        "name": "org.osbuild.selinux",
+        "options": {
+          "file_contexts": "etc/selinux/targeted/contexts/files/file_contexts"
+        }
+      }
+    ]
+  },
+  "sources": {
+    "org.osbuild.files": {
+      "urls": {
+        "sha256:c574c5432197acbe08ea15c7837be7577cd0b49902a3e65227792f051d73ce5c": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/a/alternatives-1.11-6.fc32.x86_64.rpm",
+        "sha256:22d311f22902d592f72bd0fb4010a682f796e5a4698d5ea209848468a2d5aa96": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/a/audit-libs-3.0-0.19.20191104git1c2f876.fc32.x86_64.rpm",
+        "sha256:a346990bb07adca8c323a15f31b093ef6e639bde6ca84adf1a3abebc4dc9adce": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/b/basesystem-11-9.fc32.noarch.rpm",
+        "sha256:7a97e71cd552285ead303d07dbb6417403edf45c0a531e02cf4ebfb0efda4975": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/b/bash-5.0.11-2.fc32.x86_64.rpm",
+        "sha256:842f7a38be2e8dbb14eff3ede4091db214ebe241e1fde7a128e88c4e686b63b0": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/b/bzip2-libs-1.0.8-2.fc32.x86_64.rpm",
+        "sha256:73f6a9108f7d5ec3cd89c31dbbaa874ae28cd5cb443ef69700a1218903ee2fc4": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/c/ca-certificates-2020.2.40-3.fc32.noarch.rpm",
+        "sha256:7023687eb65baa56a9b4c3ffde1e439b3d41b03ac4ad35a1a1fc3903464548f7": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/c/coreutils-8.32-3.fc32.1.x86_64.rpm",
+        "sha256:5323eb8d89b2d0c905a633513e04ca7df633c21eec288ee8c50f3f5170534e37": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/c/coreutils-common-8.32-3.fc32.1.x86_64.rpm",
+        "sha256:862e75c10377098a9cc50407a0395e5f3a81d14b5b6fecfb3f223325c8867829": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/c/cracklib-2.9.6-22.fc32.x86_64.rpm",
+        "sha256:1aee865249b031e591a5e94d62d05b69ad1a6118a26adccf2dfd46b0002716e5": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/c/cracklib-dicts-2.9.6-22.fc32.x86_64.rpm",
+        "sha256:3f8dcae27ad3609b7de298d0ca8d34a2790b9898f5f1b03f3f9f8784374e307b": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/c/crypto-policies-20191128-5.gitcd267a5.fc32.noarch.rpm",
+        "sha256:b821e9e8bf66abacaed4a386f9ed8ffa17f4f8be3db55e1ac31d52ba2d1faa1b": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/c/crypto-policies-scripts-20191128-5.gitcd267a5.fc32.noarch.rpm",
+        "sha256:6eeebf21f245bf0d6f58962dc49b6dfb51f55acb6a595c6b9cbe9628806b80a4": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/c/curl-7.69.1-1.fc32.x86_64.rpm",
+        "sha256:fefa4162a563eba24714ac43874c508d1ba036afb5127c5d21bbcbeaf238a740": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/c/cyrus-sasl-lib-2.1.27-4.fc32.x86_64.rpm",
+        "sha256:187dd61be71efcca6adf9819a523d432217abb335afcb2b95ef27b72928aff4b": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/d/diffutils-3.7-4.fc32.x86_64.rpm",
+        "sha256:8fc2ae85f242105987d8fa7f05e4fa19358a7c81dff5fa163cf021eb6b9905e9": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/e/expat-2.2.8-2.fc32.x86_64.rpm",
+        "sha256:09fea9af8b695af862b19c1a8fbe1b1e8854257825ee4f663f67b3782a75d58a": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/f/fedora-gpg-keys-32-1.noarch.rpm",
+        "sha256:1f2ba0fc562864ad1bea31a42da124030fc188d23a84d144be616c2d066e1531": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/f/fedora-release-32-1.noarch.rpm",
+        "sha256:a1835a7929d3c1613f3890caef878e9bdf857dcc0f63eb4d63a1140370b3f21b": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/f/fedora-release-common-32-1.noarch.rpm",
+        "sha256:21e3fd914a3bcc65b79de022782967903c55a4aed9a3c7d3464bc2fef32d02b3": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/f/fedora-repos-32-1.noarch.rpm",
+        "sha256:1110261787146443e089955912255d99daf7ba042c3743e13648a9eb3d80ceb4": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/f/filesystem-3.14-2.fc32.x86_64.rpm",
+        "sha256:d0e5d0104cf20c8dd332053a5903aab9b7fdadb84b35a1bfb3a6456f3399eb32": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/gawk-5.0.1-7.fc32.x86_64.rpm",
+        "sha256:9899cfd32ada2537693af30b60051da21c6264b0d0db51ba709fceb179d4c836": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/gdbm-libs-1.18.1-3.fc32.x86_64.rpm",
+        "sha256:dc9c0401522bcf73fe5a692184c141b214947ad83364be97de0413ab46b712e5": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/glibc-2.31-2.fc32.x86_64.rpm",
+        "sha256:129d919e55c09edecaa8edd0fd4058dbf7460aaae5d1c5625ca11f6df7defefe": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/glibc-all-langpacks-2.31-2.fc32.x86_64.rpm",
+        "sha256:e80533822e2a892345b869395b2c17c0bcc98d3c3c47787da30123096835db00": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/glibc-common-2.31-2.fc32.x86_64.rpm",
+        "sha256:178e4470a6dfca84ec133932606737bfe167094560bf473940504c511354ddc9": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/gmp-6.1.2-13.fc32.x86_64.rpm",
+        "sha256:759165656ac8141b0c0ada230c258ffcd4516c4c8d132d7fbaf762cd5a5e4095": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/grep-3.3-4.fc32.x86_64.rpm",
+        "sha256:53f1e8570b175e8b58895646df6d8068a7e1f3cb1bafdde714ddd038bcf91e85": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/gzip-1.10-2.fc32.x86_64.rpm",
+        "sha256:ccc3cb2dcb7a534361cc911f27ff4e869902a150b68e236cf6eb209a99d4ee22": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/k/keyutils-libs-1.6-4.fc32.x86_64.rpm",
+        "sha256:e2b2dddbce49fab5f01ba75fae8796ab7c9fd8280c652f78d06a2644246bd16d": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/k/krb5-libs-1.18-1.fc32.x86_64.rpm",
+        "sha256:f826f984b23d0701a1b72de5882b9c0e7bae87ef49d9edfea156654f489f8b2b": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libacl-2.2.53-5.fc32.x86_64.rpm",
+        "sha256:88f4bd19a6cf6eba5e6f2b5bba80819b5ccddb0476aadc53c8df13f9c45b1e58": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libarchive-3.4.2-1.fc32.x86_64.rpm",
+        "sha256:65e0cfe367ae4d54cf8bf509cb05e063c9eb6f2fea8dadcf746cdd85adc31d88": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libattr-2.4.48-8.fc32.x86_64.rpm",
+        "sha256:1830b4aa42ef492c13b62f63fe941970869ba19bd9abde4dea5c97f9e38ffd68": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libblkid-2.35.1-7.fc32.x86_64.rpm",
+        "sha256:ac8b1fea0b678d7630033a8900be5641b934306961b39a29c79c6d72f34f7d1c": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libbrotli-1.0.7-10.fc32.x86_64.rpm",
+        "sha256:1bc0542cf8a3746d0fe25c397a93c8206963f1f287246c6fb864eedfc9ffa4a7": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libcap-2.26-7.fc32.x86_64.rpm",
+        "sha256:b60670fdcf91b50d97720f601d92277efedbd690bd887000ccd9a46b3fa8b314": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libcap-ng-0.7.10-2.fc32.x86_64.rpm",
+        "sha256:4494013eac1ad337673f084242aa8ebffb4a149243475b448bee9266401f2896": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libcom_err-1.45.5-3.fc32.x86_64.rpm",
+        "sha256:7dfe1e8dac6d759479ae3dfd415fdd2662bbed9ff0f4da6093279efd1bacae31": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libcurl-7.69.1-1.fc32.x86_64.rpm",
+        "sha256:688fcc0b7ef3c48cf7d602eefd7fefae7bcad4f0dc71c9fe9432c2ce5bbd9daa": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libdb-5.3.28-40.fc32.x86_64.rpm",
+        "sha256:431d836b2be015212d8c15b4290d5ce5bb45282cbf3fc52696f632d84ce34dfe": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libdb-utils-5.3.28-40.fc32.x86_64.rpm",
+        "sha256:942d06ec1f7033ea4c729b84ee09f5491481770efe10151ba581479ac7f3f9dc": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libfdisk-2.35.1-7.fc32.x86_64.rpm",
+        "sha256:86c87a4169bdf75c6d3a2f11d3a7e20b6364b2db97c74bc7eb62b1b22bc54401": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libffi-3.1-24.fc32.x86_64.rpm",
+        "sha256:48cf5ab32f6af8f2283d4d4834e8dd262aa412be7ea07c2292483e150d614bef": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libgcc-10.0.1-0.11.fc32.x86_64.rpm",
+        "sha256:5f0ae954b5955c86623e68cd81ccf8505a89f260003b8a3be6a93bd76f18452c": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libgcrypt-1.8.5-3.fc32.x86_64.rpm",
+        "sha256:9bd5cb588664e8427bc8bebde0cdf5e14315916624ab6b1979dde60f6eae4278": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libgpg-error-1.36-3.fc32.x86_64.rpm",
+        "sha256:20787251df57a108bbf9c40e30f041b71ac36c8a10900fb699e574ee7e259bf2": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libidn2-2.3.0-2.fc32.x86_64.rpm",
+        "sha256:6eb95e39b9771c4dde5f9954a74cef6be90522c28c7c4aa767ebe7a9d55fcdf9": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libmetalink-0.1.3-10.fc32.x86_64.rpm",
+        "sha256:e740cc0a580639b887bda0039a779e750a32835be1fd8c64aa01183b4cbb98bf": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libmount-2.35.1-7.fc32.x86_64.rpm",
+        "sha256:a8ce7406c87f64972f0b70f1823c2aad05516c71fe375c6c97737459c2448825": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libnghttp2-1.40.0-2.fc32.x86_64.rpm",
+        "sha256:3b4ce7fc4e2778758881feedf6ea19b65e99aa3672e19a7dd62977efe3b910b9": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libnsl2-1.2.0-6.20180605git4a062cf.fc32.x86_64.rpm",
+        "sha256:ce8c1f1ce3cb2cc0166dcaad17f35e84278ec39ea9bf232e24130d3ff3271923": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libpsl-0.21.0-4.fc32.x86_64.rpm",
+        "sha256:9ecc8aa9af05ba704cec879618afeda5ff92d8233811e2d6080aa02e0b5ceddf": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libpwquality-1.4.2-2.fc32.x86_64.rpm",
+        "sha256:0e59b422e35eee975ba68e6e4de022c8f145feec7e169e86e0244d2fdad2f590": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libselinux-3.0-3.fc32.x86_64.rpm",
+        "sha256:1446032720fb8e0090190828fcea294a86fc7f83edd70f6089e3446770ba0438": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libselinux-utils-3.0-3.fc32.x86_64.rpm",
+        "sha256:54cb827278ae474cbab1f05e0fbee0355bee2674d46a804f1c2b78ff80a48caa": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libsemanage-3.0-3.fc32.x86_64.rpm",
+        "sha256:29e2b62e9e63f25139a6863c863c3b534660440d7dec0c985807302a6895dbaf": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libsepol-3.0-3.fc32.x86_64.rpm",
+        "sha256:942707884401498938fba6e2439dc923d4e2d81f4bac205f4e73d458e9879927": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libsigsegv-2.11-10.fc32.x86_64.rpm",
+        "sha256:ddad78d00b09c6c85d46c06dcba4c951f7f7dfc9b2dab195bf45aa3f5a1fdc41": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libsmartcols-2.35.1-7.fc32.x86_64.rpm",
+        "sha256:32f8cbb3be91f589d569a2e737130f29c752f78eebc61e287af17f207e1b8c58": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libssh-0.9.3-2.fc32.x86_64.rpm",
+        "sha256:49bac21d5cdf863fccfcc32bf070e582d204706e35ee9f60b3e69df694bff87d": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libssh-config-0.9.3-2.fc32.noarch.rpm",
+        "sha256:052d04c9a6697c6e5aa546546ae5058d547fc4a4f474d2805a3e45dbf69193c6": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libtasn1-4.16.0-1.fc32.x86_64.rpm",
+        "sha256:c1d754773972b5f4ca157c0afa45d6767901d965a91f381660c72740d682df63": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libtirpc-1.2.5-1.rc2.fc32.x86_64.rpm",
+        "sha256:fb06aa3d8059406a23694ddafe0ef340ca627dd68bf3f351f094de58ef30fb2c": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libunistring-0.9.10-7.fc32.x86_64.rpm",
+        "sha256:f9ccea65ecf98f4dfac65d25986d08efa62a1d1c0db9db0a061e7408d6805a1a": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libutempter-1.1.6-18.fc32.x86_64.rpm",
+        "sha256:8402d3aabfc02c16f3789f3f93338dbee2448db8a49956002b83aff5390922d9": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libuuid-2.35.1-7.fc32.x86_64.rpm",
+        "sha256:ed84414c9b2190d3026f58db78dffd8bc3a9ad40311cb0adb8ff8e3c7c06ca60": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libverto-0.3.0-9.fc32.x86_64.rpm",
+        "sha256:7c1a229f4a36ac8b077e0514f68f311229652121528b0f8a2a7434c618276dcb": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libxcrypt-4.4.16-1.fc32.x86_64.rpm",
+        "sha256:cb4fb9b3733440ea15b3309c88d9471c4165aa7b71b4dbc5d0fb5bfcd97b2f2e": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libxcrypt-compat-4.4.16-1.fc32.x86_64.rpm",
+        "sha256:a7f040de29d2414cc99fcffcd9ed3fa9d06ecc7aecd783ec3d2eef769e2389f1": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libxml2-2.9.10-3.fc32.x86_64.rpm",
+        "sha256:9465f2f1103697207a52d15edd716ab72dc6c281823c60f424cd064d706c7a51": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libzstd-1.4.4-2.fc32.x86_64.rpm",
+        "sha256:10883ce95852cc9ae9b4e0d435b100a25f8fe5c0ea4677eb4a0b39f4f8def886": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/lua-libs-5.3.5-7.fc32.x86_64.rpm",
+        "sha256:44cfb58b368fba586981aa838a7f3974ac1d66d2b3b695f88d7b1d2e9c81a0b6": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/lz4-libs-1.9.1-2.fc32.x86_64.rpm",
+        "sha256:640afe5b9d499c9a7efc1d23cce8c54e3e3704d92eb7e7a93a048f97d1e983e1": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/m/mkpasswd-5.5.6-1.fc32.x86_64.rpm",
+        "sha256:2b098bc6f8004270ee9eac9f63980b364b5fe19394dc73a230b3c846cf488b1b": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/m/mpfr-4.0.2-3.fc32.x86_64.rpm",
+        "sha256:b2e862283ac97b1d8b1ede2034ead452ac7dc4ff308593306275b1b0ae5b4102": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/n/ncurses-6.1-15.20191109.fc32.x86_64.rpm",
+        "sha256:25fc5d288536e1973436da38357690575ed58e03e17ca48d2b3840364f830659": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/n/ncurses-base-6.1-15.20191109.fc32.noarch.rpm",
+        "sha256:04152a3a608d022a58830c0e3dac0818e2c060469b0f41d8d731f659981a4464": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/n/ncurses-libs-6.1-15.20191109.fc32.x86_64.rpm",
+        "sha256:ade8105796f5c1201a3efc8bcc654788cfc88c3815297b346845062a8c29cd59": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/o/openldap-2.4.47-4.fc32.x86_64.rpm",
+        "sha256:ad6d7d9767e05978b14a39c08dba59ddc4396584576df194f77ed310a0816ae0": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/o/openssl-libs-1.1.1d-7.fc32.x86_64.rpm",
+        "sha256:3f2cb9092d6f55f84dd9eacd5359dfb354772e5f38308328027c7758f4a06fb6": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/o/openssl-pkcs11-0.4.10-5.fc32.x86_64.rpm",
+        "sha256:dedd37a96262c35763ab2dcbc19838f5cc39a2a3a392a650a80bd6d5ae42ff8b": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/p11-kit-0.23.20-1.fc32.x86_64.rpm",
+        "sha256:3589b982ac0c2f5f6b47cde5cb7ec33c2c01d756dabf8c4ca64f6d9d0d78b35e": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/p11-kit-trust-0.23.20-1.fc32.x86_64.rpm",
+        "sha256:4c80ade4ac0889316930a8d181ea43fa2d1b2f1a6a5703c22f2b3ba191346eec": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/pam-1.3.1-24.fc32.x86_64.rpm",
+        "sha256:933bdb4cc6e14b2ebb1ca76c14ca176c13d271a2d1e88632f237392777d11808": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/pcre-8.44-1.fc32.x86_64.rpm",
+        "sha256:6794fe48004c0403c29fc779b49f0fbea436123b96783a2df225eef2f0858795": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/pcre2-10.34-9.fc32.x86_64.rpm",
+        "sha256:5db7c0e949bd9172b9645237e72f6139d4ffcf14defad487262b8ad25b427daf": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/pcre2-syntax-10.34-9.fc32.noarch.rpm",
+        "sha256:8df97dcfb42c1667b5d2e4150012eaf96f58eeac4f7b879e0928c8c36e3a7604": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/policycoreutils-3.0-2.fc32.x86_64.rpm",
+        "sha256:8a0c00a69f9cb3a9ffacaf1cdc162c38a1faca76c9b976cb177bdc988902f2d4": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/popt-1.16-19.fc32.x86_64.rpm",
+        "sha256:af992ad02594b68f17d2da41104a26aee41d02639edf22332d7dbb1fe9af58a5": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/publicsuffix-list-dafsa-20190417-3.fc32.noarch.rpm",
+        "sha256:a7da5590635b9c19afafc7dd247604194a5ce7d8d863dc600b8cb86accb2e469": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/python-pip-wheel-19.3.1-2.fc32.noarch.rpm",
+        "sha256:7dd93baaf69a8004ae2cd3b9e6660b862d0b6f399d53c05a27a48a2e276ef1ee": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/python-setuptools-wheel-41.6.0-2.fc32.noarch.rpm",
+        "sha256:0b290954bc2868b3dfc976b2b7a13ea8aeade76eeafc17674ff8e721049a5bf7": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/python-unversioned-command-3.8.2-2.fc32.noarch.rpm",
+        "sha256:b79bb6af3e1650ba812c8affe42772ea566b164222a7d4d8e2f7efa867dc6849": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/python3-3.8.2-2.fc32.x86_64.rpm",
+        "sha256:ec58d03c60386bfb8aed2af3d2a49f8c6e5ccb4d3fd592cf75fef3342be137c3": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/python3-libs-3.8.2-2.fc32.x86_64.rpm",
+        "sha256:9ade87dbb32f27e7f38ec981002ddc5a2189cc6f5ad5f24bada3b71cfa9167fd": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/python3-pip-19.3.1-2.fc32.noarch.rpm",
+        "sha256:724cca9919bb7b0183b030aca216d4d51de70bf35c2cc5e8325a21a52ca15ceb": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/python3-setuptools-41.6.0-2.fc32.noarch.rpm",
+        "sha256:f1c79039f4c6ba0fad88590c2cb55a96489449c334a671cc18c0bf424a4548b8": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/r/readline-8.0-4.fc32.x86_64.rpm",
+        "sha256:136a9cbae9c225be60718fdc8cc8988a55235d6502e451df77d1c5c765143850": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/r/rpm-4.15.1-2.fc32.1.x86_64.rpm",
+        "sha256:54b740cf7a75a7215168970378d9a1d6b9a5e4eb81159a874ce8ea5990436641": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/r/rpm-libs-4.15.1-2.fc32.1.x86_64.rpm",
+        "sha256:27dd9c78e41c04b5151a2b9ac150d3ebb89f2ca7a23e4896dfc718f19a000be3": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/r/rpm-plugin-selinux-4.15.1-2.fc32.1.x86_64.rpm",
+        "sha256:ffe5076b9018efdb1612c487f637af39ab6c3c79ec37311978935cfa357ecd61": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/s/sed-4.5-5.fc32.x86_64.rpm",
+        "sha256:932a37ddd2a990a22a1ee7811d204552e8860e39a3e0c050ed618a535ae8c78c": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/s/selinux-policy-3.14.5-32.fc32.noarch.rpm",
+        "sha256:684aae86de55bd42215c136777613211f596788d3b6405d8fa645fb967904354": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/s/selinux-policy-targeted-3.14.5-32.fc32.noarch.rpm",
+        "sha256:a336d2e77255df4783f52762e44efcc8d77b044a3e39c7f577d5535212848280": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/s/setup-2.13.6-2.fc32.noarch.rpm",
+        "sha256:4dd6100e477d88a4987b6eebfddecff168f38c7ff47cbb12f2fecba1e87c10d9": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/s/shadow-utils-4.8.1-2.fc32.x86_64.rpm",
+        "sha256:7f555c600b35ba798d8c0a63e30a1a12e917231730e1a44f48161ba0fe4b5973": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/s/sqlite-libs-3.31.1-1.fc32.x86_64.rpm",
+        "sha256:78db9007c08fa51f177210e47343b8e733ce0751826abb357ca96429836588db": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/s/systemd-libs-245.4-1.fc32.x86_64.rpm",
+        "sha256:2db6d80760ab0e99f4e9c9816615e4f06b967bbb23a8c8c941b3f2d4b5f176c2": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/t/tzdata-2019c-3.fc32.noarch.rpm",
+        "sha256:9976e6228a10fa2761f1265a2a7666578d79ca57819837e5d1fbecc53324f1b9": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/u/util-linux-2.35.1-7.fc32.x86_64.rpm",
+        "sha256:d027a3ff0712e3e98d7d2358f8c526fb8d143b2386c353aadcc27199cffe125b": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/w/whois-nls-5.5.6-1.fc32.noarch.rpm",
+        "sha256:84702d6395a9577c1a268184f123cfd4b15bc2287f01033625ba388a34ec2338": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/x/xz-libs-5.2.5-1.fc32.x86_64.rpm",
+        "sha256:c0fff40dc1092e18ed3e608bc6143c89a0d7775b9e0553319bb2caca7d324d80": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/z/zlib-1.2.11-21.fc32.x86_64.rpm",
+        "sha256:705bdb96aab3a0f9d9e2ff48ead1208e2dbc1927d713d8637632af936235217b": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/a/acl-2.2.53-5.fc32.x86_64.rpm",
+        "sha256:cd01ae91895e60f189106a159bb551f906a8b663110f421ad6ee83c9e008851e": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/b/bubblewrap-0.4.1-1.fc32.x86_64.rpm",
+        "sha256:116b9d121fad9886f245cd5e1ef678fdba889cd23a39e91447e75649214a6a8d": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/c/cpio-2.13-4.fc32.x86_64.rpm",
+        "sha256:eaffaa8de8fd28ad124da12524a2ca5db86252404d70d66c7c42921dad6b69c1": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/c/cryptsetup-libs-2.3.0-1.fc32.x86_64.rpm",
+        "sha256:ed36d759746e75a2834866fbeaa783df397f8813cae2ed79fcc4d146656bf6a6": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/d/dbus-1.12.16-4.fc32.x86_64.rpm",
+        "sha256:213c17fb822ffa50fad16989ed363aa023de106c6262ccc3f16e52a154b7133f": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/d/dbus-broker-22-1.fc32.x86_64.rpm",
+        "sha256:6fc1b9a27eeb368a98f50dba5fc514f20a5eb23f8e0ee7dd92c4051ef8b4a940": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/d/dbus-common-1.12.16-4.fc32.noarch.rpm",
+        "sha256:474fd088c7e7234221d251153e9fda6081b0aa8979bf5ae25810c9862e1e9960": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/d/dbus-libs-1.12.16-4.fc32.x86_64.rpm",
+        "sha256:b70d1c93e3448b1a0b5e3f50488290283a260ff46e22bff4fb704469e6017fa8": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/d/deltarpm-3.6.2-5.fc32.x86_64.rpm",
+        "sha256:c132999a3f110029cd427f7578965ad558e91374637087d5230ee11c626ebcd4": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/d/device-mapper-1.02.171-1.fc32.x86_64.rpm",
+        "sha256:61cae80187ef2924857fdfc48a240646d23b331482cf181e7d8c661b02c15949": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/d/device-mapper-libs-1.02.171-1.fc32.x86_64.rpm",
+        "sha256:78e1aa11379eec2906eedf843216f47bcbdfe4da4713d566fb44ca313c893f3f": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/d/dnf-4.2.19-1.fc32.noarch.rpm",
+        "sha256:80d407bbc5f6bb8d95504cfdb51faaca937f6c4c08df4c4aadcd46fe703c8a57": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/d/dnf-data-4.2.19-1.fc32.noarch.rpm",
+        "sha256:c3f7089ae50f79cf4d2cb59e01091d33c70cab89ae08f95c547339a87404c3ec": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/d/dosfstools-4.1-10.fc32.x86_64.rpm",
+        "sha256:993680d5cd133a0c21184be92b3df405d757613d0ca25c4abf08b203d8d26b79": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/d/dracut-050-26.git20200316.fc32.x86_64.rpm",
+        "sha256:2fa5e252441852dae918b522a2ff3f46a5bbee4ce8936e06702bf65f57d7ff99": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/e/e2fsprogs-1.45.5-3.fc32.x86_64.rpm",
+        "sha256:26db62c2bc52c3eee5f3039cdbdf19498f675d0f45aec0c2a1c61c635f01479e": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/e/e2fsprogs-libs-1.45.5-3.fc32.x86_64.rpm",
+        "sha256:4f318cec61cb69fc233ba5505b7e24f679afdfb0b5defbaef507f1b471e7dbb5": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/e/elfutils-debuginfod-client-0.179-1.fc32.x86_64.rpm",
+        "sha256:af62d0611b995b9f2b2c7b4d4852e03e521d66979534871ccb5a71275a15518d": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/e/elfutils-default-yama-scope-0.179-1.fc32.noarch.rpm",
+        "sha256:f3eb795f68c80ccf870f1d27f8fd019878db748c0c19275634c48cf5cea5bc46": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/e/elfutils-libelf-0.179-1.fc32.x86_64.rpm",
+        "sha256:99f87b4ec7c5852d45028f3eae65fc813f3ef107e128777f265b09a19ce262e0": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/e/elfutils-libs-0.179-1.fc32.x86_64.rpm",
+        "sha256:28656826cb0dfbae9b6e8d1e5c5691773d84000493c4be47f727092fec6dc6f4": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/f/file-5.38-2.fc32.x86_64.rpm",
+        "sha256:e0b1da98020a740991dbb70b42c0ff1eece9e268a461e555a5ec763bda1645f5": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/f/file-libs-5.38-2.fc32.x86_64.rpm",
+        "sha256:0b7cd6f6cb3b7cd9e0704dd6c62b65254b04cb870ab638b9bed4951564436e24": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/f/findutils-4.7.0-3.fc32.x86_64.rpm",
+        "sha256:9369d4fed30402f45705b7a5cb51b6eeefb1dabbe0942c84514c6fdf1edac5e0": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/f/fuse-2.9.9-9.fc32.x86_64.rpm",
+        "sha256:45132e53c649def28d63c199d8c3a3b9fd16fa8bca7426ad4e9c202e52a233b4": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/f/fuse-common-3.9.1-1.fc32.x86_64.rpm",
+        "sha256:53992752850779218421994f61f1589eda5d368e28d340dccaae3f67de06e7f2": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/f/fuse-libs-2.9.9-9.fc32.x86_64.rpm",
+        "sha256:349af433b2f6d45ff2e1ea5a38f847ec692fef0a8dd656a9a07d423a981946d0": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/gettext-0.20.1-4.fc32.x86_64.rpm",
+        "sha256:fdb9bc612957a16fc44b717605a5a26e16a33850c0ff74a80a299cc2bab740e4": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/gettext-libs-0.20.1-4.fc32.x86_64.rpm",
+        "sha256:6fe524feb38312f9c370b2190aeb42330acc9ce42f3a45e9cd05748b4aa00db2": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/glib2-2.64.1-1.fc32.x86_64.rpm",
+        "sha256:cc3396df93ce0e8f439b83fb6b4d210903876846b0bd3a22c19c7770cf5a9050": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/gnupg2-2.2.19-1.fc32.x86_64.rpm",
+        "sha256:966084f83e0fedb7a217aa102b484ac8a63082ccfe99517544ed2cb102191204": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/gnupg2-smime-2.2.19-1.fc32.x86_64.rpm",
+        "sha256:9d4f1290565b852e56f9e9babc14b141b0283998121f78b0eb83dec367cf0abb": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/gnutls-3.6.13-1.fc32.x86_64.rpm",
+        "sha256:13a0c9c767f71164cc678ee36d89b7fddcdd6fb8243e3daf8b47cca0d1d14c4f": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/gpgme-1.13.1-6.fc32.x86_64.rpm",
+        "sha256:01173d218dccdf88c1159bba4af332ce703fc0dcd7171cd279cb3e16f12b30a9": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/grub2-common-2.04-12.fc32.noarch.rpm",
+        "sha256:110f538d82f15f009d95e89d8c1e3669dc7358feb9aa7724301fef037f8b67fe": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/grub2-pc-2.04-12.fc32.x86_64.rpm",
+        "sha256:c2197913bc8db9548b0a40ffddf840a31956b18e932ad4eec77a48d87d2289ce": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/grub2-pc-modules-2.04-12.fc32.noarch.rpm",
+        "sha256:7f6d2841ec9402ee5e57f1a46b9886935138c02005d860899f3c746c7885c7b9": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/grub2-tools-2.04-12.fc32.x86_64.rpm",
+        "sha256:d1c6f183b9deaf6127db4ad7040046bd7f1aa62de177961aac39501605d2c815": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/g/grub2-tools-minimal-2.04-12.fc32.x86_64.rpm",
+        "sha256:c1f957511b5e011e6f7995ed7bca9196703cf1214068f209e86b1dc4fd0e98bf": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/i/ima-evm-utils-1.2.1-3.fc32.x86_64.rpm",
+        "sha256:f4eb6d332b9aea8d8ef0a6ea8dc2b073d6bf5f2599d64f24111d8da2ee82ad48": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/i/iptables-libs-1.8.4-7.fc32.x86_64.rpm",
+        "sha256:d3a64fcef3de79a97541b21c71ddd00d4cca9039c930bc660d6c5479eabf5f26": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/j/json-c-0.13.1-9.fc32.x86_64.rpm",
+        "sha256:8a03d482b5294f7452b2f9ce31ebb6aea9eefac002281c1b9152fbb1a0341987": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/j/json-glib-1.4.4-4.fc32.x86_64.rpm",
+        "sha256:a05178831a546e2001e52f065fc6969f36d2292efaee2971fe7a7e882cc8c813": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/k/kbd-2.2.0-1.fc32.x86_64.rpm",
+        "sha256:3be681b78e919bfd82eb186c7393718f1d37abd0b1bb8b1a8571aefa11e7a248": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/k/kbd-legacy-2.2.0-1.fc32.noarch.rpm",
+        "sha256:60774007011889671c28158f599032f0db253c153ccae70f5e2f5840f2dc490b": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/k/kbd-misc-2.2.0-1.fc32.noarch.rpm",
+        "sha256:3f9c95f3827b785f49ac4a270d4c3a703dceba673c452838744ec5064cf43cbd": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/k/kmod-27-1.fc32.x86_64.rpm",
+        "sha256:56187c1c980cc0680f4dbc433ed2c8507e7dc9ab00000615b63ea08c086b7ab2": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/k/kmod-libs-27-1.fc32.x86_64.rpm",
+        "sha256:fbb81a7811f7a11b1c95eec20c3df63beef9e007f0b3d2713f13ad80029d7249": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/k/kpartx-0.8.2-3.fc32.x86_64.rpm",
+        "sha256:a410db5c56d4f39f6ea71e7d5bb6d4a2bd518015d1e34f38fbc0d7bbd4e872d4": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libaio-0.3.111-7.fc32.x86_64.rpm",
+        "sha256:7d9bd2fe016ca8860e8fab4a430b3aae4c7b7bea55f8ccd7775ad470172e2886": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libargon2-20171227-4.fc32.x86_64.rpm",
+        "sha256:598a136b7027cb9b4fef6bfa34715979d41c2f62c9d8bec5d50b633a17790f7b": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libassuan-2.5.3-3.fc32.x86_64.rpm",
+        "sha256:e9a3ace2c71c2388ed6402e92ba148acb8d19b5c3495a47148b9e88cc6d6d1eb": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libcomps-0.1.14-4.fc32.x86_64.rpm",
+        "sha256:63400fedea4a6ddb8fced58d33e60560791f29cd439169998f337d09fb50a7d4": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libcroco-0.6.13-3.fc32.x86_64.rpm",
+        "sha256:fa08dccd7a2e38dfbab999613bdb41df2034b506d21964d0ef368af6e56c4cf9": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libdnf-0.45.0-3.fc32.x86_64.rpm",
+        "sha256:7bf42ff57ce2a31db0da7d6c5926552f4e51e9f25cded77bd634eb5cd35eadab": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libevent-2.1.8-8.fc32.x86_64.rpm",
+        "sha256:d65b4bb6fa49198237f9b704ec471d71dfd94b87290f4d03c1c34d12f6efeb95": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libgomp-10.0.1-0.11.fc32.x86_64.rpm",
+        "sha256:8677b34fa73f258b1a599d18419f6fbbb8961bb1ca2ae5b0f9abdcc4f93b319e": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libkcapi-1.1.5-2.fc32.x86_64.rpm",
+        "sha256:5d5c8c7e9c78e3b8827ad38771efb44951d1c3c1692cf4e07b138c1c8c42bd5b": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libkcapi-hmaccalc-1.1.5-2.fc32.x86_64.rpm",
+        "sha256:1b05dd5abad5a31380c859bc33e7851158c24333fda837ca9facf869005f81fe": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libksba-1.3.5-11.fc32.x86_64.rpm",
+        "sha256:1c68255945533ed4e3368125bc46e19f3fe348d7ec507a85a35038dbb976003f": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libmnl-1.0.4-11.fc32.x86_64.rpm",
+        "sha256:f98f854a86c68b534f71e1f35852fabddbe2cbfe481b01bb15291b3363013b2a": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libmodulemd-2.9.1-1.fc32.x86_64.rpm",
+        "sha256:aa5b658fd4a95c724b61eddadecdbcbc1b2a813ae681318ab092a2ed03954825": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libmodulemd1-1.8.16-2.fc32.x86_64.rpm",
+        "sha256:884357540f4be2a74e608e2c7a31f2371ee3b4d29be2fe39a371c0b131d84aa6": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libnetfilter_conntrack-1.0.7-4.fc32.x86_64.rpm",
+        "sha256:ec6abd65541b5bded814de19c9d064e6c21e3d8b424dba7cb25b2fdc52d45a2b": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libnfnetlink-1.0.1-17.fc32.x86_64.rpm",
+        "sha256:b3230630a471b806a9153669d187508350cdb2b368a68f8c439c82abad038c3f": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libpcap-1.9.1-3.fc32.x86_64.rpm",
+        "sha256:aa783a91b1823b7b056575e6276df35910eb2e0d4b72121cf5649651c7d23a16": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/librepo-1.11.1-4.fc32.x86_64.rpm",
+        "sha256:3d33c29bcc4a39be16d6647a70a0d7ae2f08baf26dcea5c802289df1128d5f21": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libreport-filesystem-2.12.0-3.fc32.noarch.rpm",
+        "sha256:df0a39eb6b91c4a8f481c22445cbbd88334bf5e0a6e1dd5fb240981eb031c4eb": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libseccomp-2.4.2-3.fc32.x86_64.rpm",
+        "sha256:251fd875421da4708b76c15c7f5ba478d50b74d7e4242071a621625eac51a767": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libsecret-0.20.2-2.fc32.x86_64.rpm",
+        "sha256:be899d3e806441b1c46811c0ffe9f4e01f4ea4e1544f9cc32630254853e3f3a5": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libsolv-0.7.11-2.fc32.x86_64.rpm",
+        "sha256:27701cda24f5f6386e0173745aabc4f6df28052975e73529854432c35399cfc8": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libss-1.45.5-3.fc32.x86_64.rpm",
+        "sha256:be998dfbcc9ca8e3021ac4f56ed723cfa3fa1517524e89ee0b636f623abe995f": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libstdc++-10.0.1-0.11.fc32.x86_64.rpm",
+        "sha256:b35256e417fd94c7efb1212f2f36b5e6b224ff5b9e8733774d4fbdc652078099": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libtextstyle-0.20.1-4.fc32.x86_64.rpm",
+        "sha256:729fb595040f1e2e71ff0a8c1c22ebe4b7187f78b816af8e6a8d93c03fc5d844": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libusbx-1.0.23-1.fc32.x86_64.rpm",
+        "sha256:ae219ad5ecc0233271c3fd61263f817c646eecece19a8f075e7aa4dd9ff8698e": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libxkbcommon-0.10.0-2.fc32.x86_64.rpm",
+        "sha256:9c8a274158a6fe97598e33900cd51e171f7e7517ccfc8ad6351873e69b225986": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/l/libyaml-0.2.2-3.fc32.x86_64.rpm",
+        "sha256:c019d23ed2cb3ceb0ac9757a72c3e8b1d31f2a524b889e18049cc7d923bc9466": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/n/nettle-3.5.1-5.fc32.x86_64.rpm",
+        "sha256:3c2a641f118ab2e8b08df6dd2da72a60121d02df8d932b4afa2920eb80392875": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/n/npth-1.6-4.fc32.x86_64.rpm",
+        "sha256:d7b8b5815b72fb157de26579362383e357e026ae6ac2599c451fb336fe995555": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/o/openssl-1.1.1d-7.fc32.x86_64.rpm",
+        "sha256:45fc2608b746fd841dd25919e9e4d44834154758aec8fb8b529c014b11c7917d": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/o/os-prober-1.77-4.fc32.x86_64.rpm",
+        "sha256:ec64add7d60a70fbaf14a083929f22bd2637c33d20d2a30b7e842caa6040f817": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/o/ostree-2020.3-2.fc32.x86_64.rpm",
+        "sha256:3343d9e7c90bd58e1e44ee07e7c59bb570ffc74da50f0607c5f5681a00b70e76": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/o/ostree-libs-2020.3-2.fc32.x86_64.rpm",
+        "sha256:15f08ce979e48fd25be5e16d63d1c95c57f9abff7704005137ea00b958442939": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/pigz-2.4-6.fc32.x86_64.rpm",
+        "sha256:7df4fa1a29772696d92866e890af6fbe006088f3407ed3e67b0e7867ef58d899": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/pinentry-1.1.0-7.fc32.x86_64.rpm",
+        "sha256:d439ffbe20c8c0e8244e31c0324d60cf959dc1cd6cecc575d7b34509a73e9386": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/polkit-libs-0.116-7.fc32.x86_64.rpm",
+        "sha256:f3908831ae53f43b07a4e196850d0e59cc89b50c97d838538c3185fd0eb0d569": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/procps-ng-3.3.15-7.fc32.x86_64.rpm",
+        "sha256:632aedc06003e319a1c3fa98876055fc3bd3b44c1188b44d3b7a455cef0d40e4": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/python3-dnf-4.2.19-1.fc32.noarch.rpm",
+        "sha256:9de8eb13fbdf8b8c5c3e04c52a890ccc5b667351ff17152786d12ffc66210433": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/python3-gpg-1.13.1-6.fc32.x86_64.rpm",
+        "sha256:6a2f4706a37bc5ad229f6fdddbd70fbcf82da85ec577a8deeb455513cbedc174": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/python3-hawkey-0.45.0-3.fc32.x86_64.rpm",
+        "sha256:0d9d80adb91ccc8eed62bea68b23da5edb77675b1ec93227e2179d028449a2f7": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/python3-libcomps-0.1.14-4.fc32.x86_64.rpm",
+        "sha256:44fabecae31a5900fe10837863ed231303f6863bd9fa5efa40a93a0fc059344f": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/python3-libdnf-0.45.0-3.fc32.x86_64.rpm",
+        "sha256:355a095bb3c6d58f927277ff53267f88eb0729adbcafd8082b8d97e4815ee206": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/python3-rpm-4.15.1-2.fc32.1.x86_64.rpm",
+        "sha256:517ff9662e5a1897b74f4ab4fbc8a88eccaad9880bc18be9cf4df6aba9824bd5": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/p/python3-unbound-1.9.6-2.fc32.x86_64.rpm",
+        "sha256:475b6de876914aec2187ac4858a13ae75585f5c4cb5d739c637f79a5ca6f05f9": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/q/qemu-img-4.2.0-7.fc32.x86_64.rpm",
+        "sha256:f1150f9e17beaef09aca0f291e10db8c3ee5566fbf4c929b7672334410fa74e9": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/q/qrencode-libs-4.0.2-5.fc32.x86_64.rpm",
+        "sha256:3151132084577032b4c827eb577a1509950601888c6ff13a0a30b24252ee26d2": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/r/rpm-build-libs-4.15.1-2.fc32.1.x86_64.rpm",
+        "sha256:ee664c392a97cdd272f57980c6856b2c57567005fa0ad9cb16c388b645d014f1": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/r/rpm-ostree-2020.1-1.fc32.x86_64.rpm",
+        "sha256:9d220d8ee28cd0adf28e8fef547af92c3ec66e238747165939cf8e1a413ddf83": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/r/rpm-ostree-libs-2020.1-1.fc32.x86_64.rpm",
+        "sha256:e2a04f4de125ff60a3cdc3d2b3718a4530a9c9240c9cf14f55938444c229539f": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/r/rpm-plugin-systemd-inhibit-4.15.1-2.fc32.1.x86_64.rpm",
+        "sha256:630ad20496ff00f76764e01b9302ccbe94e3e91d76ececef88bd9e8a890b1ac3": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/r/rpm-sign-libs-4.15.1-2.fc32.1.x86_64.rpm",
+        "sha256:a280c633b73517da167b91298fc97aeee2eb5fcc253c038ae0ce4b8478d3a103": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/s/shared-mime-info-1.15-3.fc32.x86_64.rpm",
+        "sha256:1de2be4fe5280ec3097305d9e671f5f2c768267f90d255edf2075eecb0c0afe9": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/s/systemd-245.4-1.fc32.x86_64.rpm",
+        "sha256:750da30da0289d5e2ad9ca297dda44e5ca18dbed0c3e0d4200379bc1818c22f3": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/s/systemd-pam-245.4-1.fc32.x86_64.rpm",
+        "sha256:97197411bca68cfba1ef6bab1fdd4b41c95ec71c36f1e67f525b963cf60598fd": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/s/systemd-rpm-macros-245.4-1.fc32.noarch.rpm",
+        "sha256:334d63914e7ff6fe8cfce0c8f80006c6cf2ab0615cd044a6ee588809395499e5": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/s/systemd-udev-245.4-1.fc32.x86_64.rpm",
+        "sha256:2cee64e12b295b74d2f4b008c7628ef3a01ef4149905fc4a7ae14b304da5f53b": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/t/tar-1.32-4.fc32.x86_64.rpm",
+        "sha256:5f156c2a950699d5cb9a21349cce049b3c8bfdcc4fcc780665fe2d3103f576c1": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/t/trousers-0.3.13-13.fc31.x86_64.rpm",
+        "sha256:cc1be420582afb6360f380ff301c5e3d873f69fe1f7e00e4450bf2daa40ef9ff": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/t/trousers-lib-0.3.13-13.fc31.x86_64.rpm",
+        "sha256:6f669ae6f70cfa80917adf4ae9d5e86fbd9d31ee308a9a3408a19be3afc46f7b": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/t/tss2-1331-4.fc32.x86_64.rpm",
+        "sha256:29d7df69d66f51f6dddd637d3f599e70bdaa9bd476669002250bc038735a318c": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/u/unbound-libs-1.9.6-2.fc32.x86_64.rpm",
+        "sha256:82e0d8f1e0dccc6d18acd04b7806350343140d9c91da7a216f93167dcf650a61": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/w/which-2.21-19.fc32.x86_64.rpm",
+        "sha256:ec12fef82d73314e3e4cb6e962f8de27e78989fa104dde0599a4480a53817647": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/x/xkeyboard-config-2.29-1.fc32.noarch.rpm",
+        "sha256:1bdde5dc99a5588a8983f70b7b3e45e7006215d529c72adfec118c3bcbf7b01c": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/x/xz-5.2.5-1.fc32.x86_64.rpm",
+        "sha256:140708561a2ec1c7709fd38d8b1b115d02da710b80eeecd65c2b8387d9d78ef9": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os/Packages/z/zchunk-libs-1.1.5-2.fc32.x86_64.rpm"
+      }
+    }
+  }
+}
diff --git a/test/data/manifests/mpp-filesystem.json b/test/data/manifests/mpp-filesystem.json
new file mode 100644
index 00000000..ea776801
--- /dev/null
+++ b/test/data/manifests/mpp-filesystem.json
@@ -0,0 +1,41 @@
+{
+  "pipeline": {
+    "build": {
+      "mpp-import-pipeline": {
+        "path": "f32-build.json"
+      },
+      "runner": "org.osbuild.fedora32"
+    },
+    "stages": [
+      {
+        "name": "org.osbuild.rpm",
+        "options": {
+          "gpgkeys": [
+            "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBF1RVqsBEADWMBqYv/G1r4PwyiPQCfg5fXFGXV1FCZ32qMi9gLUTv1CX7rYy\nH4Inj93oic+lt1kQ0kQCkINOwQczOkm6XDkEekmMrHknJpFLwrTK4AS28bYF2RjL\nM+QJ/dGXDMPYsP0tkLvoxaHr9WTRq89A+AmONcUAQIMJg3JxXAAafBi2UszUUEPI\nU35MyufFt2ePd1k/6hVAO8S2VT72TxXSY7Ha4X2J0pGzbqQ6Dq3AVzogsnoIi09A\n7fYutYZPVVAEGRUqavl0th8LyuZShASZ38CdAHBMvWV4bVZghd/wDV5ev3LXUE0o\nitLAqNSeiDJ3grKWN6v0qdU0l3Ya60sugABd3xaE+ROe8kDCy3WmAaO51Q880ZA2\niXOTJFObqkBTP9j9+ZeQ+KNE8SBoiH1EybKtBU8HmygZvu8ZC1TKUyL5gwGUJt8v\nergy5Bw3Q7av520sNGD3cIWr4fBAVYwdBoZT8RcsnU1PP67NmOGFcwSFJ/LpiOMC\npZ1IBvjOC7KyKEZY2/63kjW73mB7OHOd18BHtGVkA3QAdVlcSule/z68VOAy6bih\nE6mdxP28D4INsts8w6yr4G+3aEIN8u0qRQq66Ri5mOXTyle+ONudtfGg3U9lgicg\nz6oVk17RT0jV9uL6K41sGZ1sH/6yTXQKagdAYr3w1ix2L46JgzC+/+6SSwARAQAB\ntDFGZWRvcmEgKDMyKSA8ZmVkb3JhLTMyLXByaW1hcnlAZmVkb3JhcHJvamVjdC5v\ncmc+iQI4BBMBAgAiBQJdUVarAhsPBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAK\nCRBsEwJtEslE0LdAD/wKdAMtfzr7O2y06/sOPnrb3D39Y2DXbB8y0iEmRdBL29Bq\n5btxwmAka7JZRJVFxPsOVqZ6KARjS0/oCBmJc0jCRANFCtM4UjVHTSsxrJfuPkel\nvrlNE9tcR6OCRpuj/PZgUa39iifF/FTUfDgh4Q91xiQoLqfBxOJzravQHoK9VzrM\nNTOu6J6l4zeGzY/ocj6DpT+5fdUO/3HgGFNiNYPC6GVzeiA3AAVR0sCyGENuqqdg\nwUxV3BIht05M5Wcdvxg1U9x5I3yjkLQw+idvX4pevTiCh9/0u+4g80cT/21Cxsdx\n7+DVHaewXbF87QQIcOAing0S5QE67r2uPVxmWy/56TKUqDoyP8SNsV62lT2jutsj\nLevNxUky011g5w3bc61UeaeKrrurFdRs+RwBVkXmtqm/i6g0ZTWZyWGO6gJd+HWA\nqY1NYiq4+cMvNLatmA2sOoCsRNmE9q6jM/ESVgaH8hSp8GcLuzt9/r4PZZGl5CvU\neldOiD221u8rzuHmLs4dsgwJJ9pgLT0cUAsOpbMPI0JpGIPQ2SG6yK7LmO6HFOxb\nAkz7IGUt0gy1MzPTyBvnB+WgD1I+IQXXsJbhP5+d+d3mOnqsd6oDM/grKBzrhoUe\noNadc9uzjqKlOrmrdIR3Bz38SSiWlde5fu6xPqJdmGZRNjXtcyJlbSPVDIloxw==\n=QWRO\n-----END PGP PUBLIC KEY BLOCK-----\n"
+          ],
+          "mpp-depsolve": {
+            "architecture": "x86_64",
+            "module-platform-id": "f32",
+            "baseurl": "http://mirrors.kernel.org/fedora/releases/32/Everything/x86_64/os",
+            "repos": [
+              {
+                "id": "default",
+                "metalink": "https://mirrors.fedoraproject.org/metalink?repo=fedora-32&arch=$basearch"
+              }
+            ],
+            "packages": [
+              "filesystem",
+              "selinux-policy-targeted"
+            ]
+          }
+        }
+      },
+      {
+        "name": "org.osbuild.selinux",
+        "options": {
+          "file_contexts": "etc/selinux/targeted/contexts/files/file_contexts"
+        }
+      }
+    ]
+  }
+}
diff --git a/test/mod/test_monitor.py b/test/mod/test_monitor.py
new file mode 100644
index 00000000..36a2ddd3
--- /dev/null
+++ b/test/mod/test_monitor.py
@@ -0,0 +1,166 @@
+#
+# Test for monitoring classes and integration
+#
+
+import io
+import json
+import os
+import multiprocessing as mp
+import sys
+import tempfile
+import unittest
+from collections import defaultdict
+
+import osbuild
+import osbuild.meta
+from osbuild.api import API
+from osbuild.monitor import LogMonitor
+from osbuild.util import jsoncomm
+from .. import test
+
+
+def setup_stdio(path):
+    """Copy of what the osbuild runners do to setup stdio"""
+    with jsoncomm.Socket.new_client(path) as client:
+        req = {'method': 'setup-stdio'}
+        client.send(req)
+        msg, fds, _ = client.recv()
+        for sio in ['stdin', 'stdout', 'stderr']:
+            target = getattr(sys, sio)
+            source = fds[msg[sio]]
+            os.dup2(source, target.fileno())
+        fds.close()
+
+
+def echo(path):
+    """echo stdin to stdout after setting stdio up via API
+
+    Meant to be called as the main function in a process
+    simulating an osbuild runner and a stage run which does
+    nothing but returns the supplied options to stdout again.
+    """
+    setup_stdio(path)
+    data = json.load(sys.stdin)
+    json.dump(data, sys.stdout)
+    sys.exit(0)
+
+
+class TapeMonitor(osbuild.monitor.BaseMonitor):
+    """Record the usage of all called functions"""
+    def __init__(self):
+        super().__init__(sys.stderr.fileno())
+        self.counter = defaultdict(int)
+        self.stages = set()
+        self.asm = None
+        self.results = set()
+        self.logger = io.StringIO()
+
+    def begin(self, pipeline: osbuild.Pipeline):
+        self.counter["begin"] += 1
+
+    def finish(self, result):
+        self.counter["finish"] += 1
+        self.output = self.logger.getvalue()
+
+    def stage(self, stage: osbuild.Stage):
+        self.counter["stages"] += 1
+        self.stages.add(stage.id)
+
+    def assembler(self, assembler: osbuild.Assembler):
+        self.counter["assembler"] += 1
+        self.asm = assembler.id
+
+    def result(self, result: osbuild.pipeline.BuildResult):
+        self.counter["result"] += 1
+        self.results.add(result.id)
+
+    def log(self, message: str):
+        self.counter["log"] += 1
+        self.logger.write(message)
+
+
+class TestMonitor(unittest.TestCase):
+    def test_log_monitor_api(self):
+        # Basic log and API integration check
+        with tempfile.TemporaryDirectory() as tmpdir:
+            args = {"foo": "bar"}
+            path = os.path.join(tmpdir, "osbuild-api")
+            logfile = os.path.join(tmpdir, "log.txt")
+
+            with open(logfile, "w") as log, \
+                 API(path, args, LogMonitor(log.fileno())) as api:
+                p = mp.Process(target=echo, args=(path, ))
+                p.start()
+                p.join()
+                self.assertEqual(p.exitcode, 0)
+                output = api.output
+                assert output
+
+            self.assertEqual(json.dumps(args), output)
+            with open(logfile) as f:
+                log = f.read()
+            self.assertEqual(log, output)
+
+    @unittest.skipUnless(test.TestBase.can_bind_mount(), "root-only")
+    def test_log_monitor_vfuncs(self):
+        # Checks the basic functioning of the LogMonitor
+        pipeline = osbuild.Pipeline("org.osbuild.linux")
+        pipeline.add_stage("org.osbuild.noop", {}, {
+            "isthisthereallife": False
+        })
+        pipeline.set_assembler("org.osbuild.noop")
+
+        with tempfile.TemporaryDirectory() as tmpdir:
+            storedir = os.path.join(tmpdir, "store")
+            outputdir = os.path.join(tmpdir, "output")
+
+            logfile = os.path.join(tmpdir, "log.txt")
+
+            with open(logfile, "w") as log:
+                monitor = LogMonitor(log.fileno())
+                res = pipeline.run(storedir,
+                                   monitor,
+                                   libdir=os.path.abspath(os.curdir),
+                                   output_directory=outputdir)
+
+                with open(logfile) as f:
+                    log = f.read()
+
+            assert res
+            self.assertIn(pipeline.stages[0].id, log)
+            self.assertIn(pipeline.assembler.id, log)
+            self.assertIn("isthisthereallife", log)
+
+    @unittest.skipUnless(test.TestBase.can_bind_mount(), "root-only")
+    def test_monitor_integration(self):
+        # Checks the monitoring API is called properly from the pipeline
+        pipeline = osbuild.Pipeline("org.osbuild.linux")
+        pipeline.add_stage("org.osbuild.noop", {}, {
+            "isthisthereallife": False
+        })
+        pipeline.add_stage("org.osbuild.noop", {}, {
+            "isthisjustfantasy": True
+        })
+        pipeline.set_assembler("org.osbuild.noop")
+
+        with tempfile.TemporaryDirectory() as tmpdir:
+            storedir = os.path.join(tmpdir, "store")
+            outputdir = os.path.join(tmpdir, "output")
+
+            tape = TapeMonitor()
+            res = pipeline.run(storedir,
+                               tape,
+                               libdir=os.path.abspath(os.curdir),
+                               output_directory=outputdir)
+
+        assert res
+        self.assertEqual(tape.counter["begin"], 1)
+        self.assertEqual(tape.counter["finish"], 1)
+        self.assertEqual(tape.counter["stages"], 2)
+        self.assertEqual(tape.counter["assembler"], 1)
+        self.assertEqual(tape.counter["stages"], 2)
+        self.assertEqual(tape.counter["result"], 3)
+        self.assertIn(pipeline.stages[0].id, tape.stages)
+        self.assertIn(pipeline.assembler.id, tape.asm)
+        self.assertIn("isthisthereallife", tape.output)
+        self.assertIn("isthisjustfantasy", tape.output)
diff --git a/test/run/test_assemblers.py b/test/run/test_assemblers.py
index eda83b82..3d470b4b 100644
--- a/test/run/test_assemblers.py
+++ b/test/run/test_assemblers.py
@@ -28,7 +28,7 @@ class TestAssemblers(test.TestBase):
     def run_assembler(self, name, options, output_path):
         with self.osbuild as osb:
             with open(os.path.join(self.locate_test_data(),
-                                   "manifests/fedora-boot.json")) as f:
+                                   "manifests/filesystem.json")) as f:
                 manifest = json.load(f)
             manifest["pipeline"] = dict(
                 manifest["pipeline"],