)
+def run_postoutput_scripts(context: Context) -> None:
+ if not context.config.postoutput_scripts:
+ return
+
+ env = dict(
+ DISTRIBUTION=str(context.config.distribution),
+ RELEASE=context.config.release,
+ ARCHITECTURE=str(context.config.architecture),
+ SRCDIR="/work/src",
+ OUTPUTDIR="/work/out",
+ MKOSI_UID=str(INVOKING_USER.uid),
+ MKOSI_GID=str(INVOKING_USER.gid),
+ MKOSI_CONFIG="/work/config.json",
+ )
+
+ if context.config.profile:
+ env["PROFILE"] = context.config.profile
+
+ with (
+ finalize_source_mounts(context.config, ephemeral=context.config.build_sources_ephemeral) as sources,
+ finalize_config_json(context.config) as json,
+ ):
+ for script in context.config.postoutput_scripts:
+ with complete_step(f"Running post-output script {script}…"):
+ run(
+ ["/work/postoutput"],
+ env=env | context.config.environment,
+ sandbox=context.config.sandbox(
+ binary=None,
+ mounts=[
+ *sources,
+ Mount(script, "/work/postoutput", ro=True),
+ Mount(json, "/work/config.json", ro=True),
+ Mount(context.staging, "/work/out"),
+ ],
+ options=["--dir", "/work/src", "--chdir", "/work/src", "--dir", "/work/out"]
+ ),
+ stdin=sys.stdin,
+ )
+
+
def certificate_common_name(context: Context, certificate: Path) -> str:
output = run(
[
config.build_scripts,
config.postinst_scripts,
config.finalize_scripts,
+ config.postoutput_scripts,
):
if not os.access(script, os.X_OK):
die(f"{script} is not executable")
output_base.unlink(missing_ok=True)
output_base.symlink_to(context.config.output_with_compression)
+ run_postoutput_scripts(context)
finalize_staging(context)
print_output_size(context.config.output_dir_or_cwd() / context.config.output_with_compression)
build_scripts: list[Path]
postinst_scripts: list[Path]
finalize_scripts: list[Path]
+ postoutput_scripts: list[Path]
clean_scripts: list[Path]
build_sources: list[ConfigTree]
build_sources_ephemeral: bool
help="Postinstall script to run outside image",
compat_names=("FinalizeScript",),
),
+ ConfigSetting(
+ dest="postoutput_scripts",
+ long="--postoutput-script",
+ metavar="PATH",
+ name="PostOutputScripts",
+ section="Content",
+ parse=config_make_list_parser(delimiter=",", parse=make_path_parser()),
+ paths=("mkosi.postoutput",),
+ path_default=False,
+ help="Output postprocessing script to run outside image",
+ ),
ConfigSetting(
dest="build_sources",
metavar="PATH",
*config.build_scripts,
*config.postinst_scripts,
*config.finalize_scripts,
+ *config.postoutput_scripts,
)
with chdir(path if path.is_dir() else Path.cwd()):
Build Scripts: {line_join_list(config.build_scripts)}
Postinstall Scripts: {line_join_list(config.postinst_scripts)}
Finalize Scripts: {line_join_list(config.finalize_scripts)}
+ Postoutput Scripts: {line_join_list(config.postoutput_scripts)}
Build Sources: {line_join_list(config.build_sources)}
Build Sources Ephemeral: {yes_no(config.build_sources_ephemeral)}
Script Environment: {line_join_list(env)}
the finalize scripts for this image. See the **Scripts** section for more
information.
+`PostOutputScripts=`, `--postoutput-script`
+: Takes a comma-separated list of paths to executables that are used as
+ the post output scripts for this image. See the **Scripts** section for more
+ information.
+
`BuildSources=`, `--build-sources=`
: Takes a comma separated list of colon separated path pairs. The first
path of each pair refers to a directory to mount from the host. The
1. Run finalize scripts (`mkosi.finalize`)
1. Generate unified kernel image if configured to do so
1. Generate final output format
+1. Run post-output scripts (`mkosi.postoutput`)
# Scripts
* If **`mkosi.finalize`** (`FinalizeScripts=`) exists, it is executed as
the last step of preparing an image.
+* If **`mkosi.postoutput`** (`PostOutputScripts=`) exists, it is executed right
+ after all the output files have been generated, before they are finally
+ moved into the output directory. This can be used to generate additional or
+ alternative outputs, e.g. `SHA256FILES` or SBOM manifests.
+
* If **`mkosi.clean`** (`CleanScripts=`) exists, it is executed right
after the outputs of a previous build have been cleaned up. A clean
script can clean up any outputs that mkosi does not know about (e.g.
Consult this table for which script receives which environment variables:
-| Variable | `configure` | `sync` | `prepare` | `build` | `postinst` | `finalize` | `clean` |
-|---------------------|:-----------:|:------:|:---------:|:-------:|:----------:|:----------:|:-------:|
-| `ARCHITECTURE` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
-| `QEMU_ARCHITECTURE` | ✓ | | | | | | |
-| `DISTRIBUTION` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
-| `RELEASE` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
-| `PROFILE` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
-| `CACHED` | | ✓ | | | | | |
-| `CHROOT_SCRIPT` | | | ✓ | ✓ | ✓ | ✓ | |
-| `SRCDIR` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
-| `CHROOT_SRCDIR` | | | ✓ | ✓ | ✓ | ✓ | |
-| `BUILDDIR` | | | | ✓ | | | |
-| `CHROOT_BUILDDIR` | | | | ✓ | | | |
-| `DESTDIR` | | | | ✓ | | | |
-| `CHROOT_DESTDIR` | | | | ✓ | | | |
-| `OUTPUTDIR` | | | | ✓ | ✓ | ✓ | ✓ |
-| `CHROOT_OUTPUTDIR` | | | | ✓ | ✓ | ✓ | |
-| `BUILDROOT` | | | ✓ | ✓ | ✓ | ✓ | |
-| `PACKAGEDIR` | | | ✓ | ✓ | ✓ | ✓ | |
-| `ARTIFACTDIR` | | | ✓ | ✓ | ✓ | ✓ | |
-| `WITH_DOCS` | | | ✓ | ✓ | | | |
-| `WITH_TESTS` | | | ✓ | ✓ | | | |
-| `WITH_NETWORK` | | | ✓ | ✓ | ✓ | ✓ | |
-| `SOURCE_DATE_EPOCH` | | | ✓ | ✓ | ✓ | ✓ | ✓ |
-| `MKOSI_UID` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
-| `MKOSI_GID` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
-| `MKOSI_CONFIG` | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Variable | `configure` | `sync` | `prepare` | `build` | `postinst` | `finalize` | `postoutput` | `clean` |
+|---------------------|:-----------:|:------:|:---------:|:-------:|:----------:|:----------:|:------------:|:-------:|
+| `ARCHITECTURE` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| `QEMU_ARCHITECTURE` | ✓ | | | | | | | |
+| `DISTRIBUTION` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| `RELEASE` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| `PROFILE` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | ✓ |
+| `CACHED` | | ✓ | | | | | | |
+| `CHROOT_SCRIPT` | | | ✓ | ✓ | ✓ | ✓ | | |
+| `SRCDIR` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| `CHROOT_SRCDIR` | | | ✓ | ✓ | ✓ | ✓ | | |
+| `BUILDDIR` | | | | ✓ | | | | |
+| `CHROOT_BUILDDIR` | | | | ✓ | | | | |
+| `DESTDIR` | | | | ✓ | | | | |
+| `CHROOT_DESTDIR` | | | | ✓ | | | | |
+| `OUTPUTDIR` | | | | ✓ | ✓ | ✓ | ✓ | ✓ |
+| `CHROOT_OUTPUTDIR` | | | | ✓ | ✓ | ✓ | | |
+| `BUILDROOT` | | | ✓ | ✓ | ✓ | ✓ | | |
+| `PACKAGEDIR` | | | ✓ | ✓ | ✓ | ✓ | | |
+| `ARTIFACTDIR` | | | ✓ | ✓ | ✓ | ✓ | | |
+| `WITH_DOCS` | | | ✓ | ✓ | | | | |
+| `WITH_TESTS` | | | ✓ | ✓ | | | | |
+| `WITH_NETWORK` | | | ✓ | ✓ | ✓ | ✓ | | |
+| `SOURCE_DATE_EPOCH` | | | ✓ | ✓ | ✓ | ✓ | | ✓ |
+| `MKOSI_UID` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| `MKOSI_GID` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| `MKOSI_CONFIG` | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Additionally, when a script is executed, a few scripts are made
available via `$PATH` to simplify common usecases.