Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,8 @@ patch_osbuild() {
/usr/lib/coreos-assembler/0002-osbuild-util-containers.py-rename-variable.patch \
/usr/lib/coreos-assembler/0003-osbuild-util-containers.py-drop-copy-when-using-cont.patch \
/usr/lib/coreos-assembler/0004-drop-remove_signatures-from-org.osbuild.container-de.patch \
/usr/lib/coreos-assembler/0005-tools-osbuild-mpp-support-mpp-resolve-for-org.osbuil.patch |
/usr/lib/coreos-assembler/0005-tools-osbuild-mpp-support-mpp-resolve-for-org.osbuil.patch \
/usr/lib/coreos-assembler/0001-stages-add-new-link-stage.patch |
patch -d /usr/lib/osbuild -p1

# And then move the files back; supermin appliance creation will need it back
Expand Down
132 changes: 132 additions & 0 deletions src/0001-stages-add-new-link-stage.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
From f53b6e1c5a8f0c26ee4f92641274a8cdba4b1d5a Mon Sep 17 00:00:00 2001
From: jbtrystram <[email protected]>
Date: Tue, 21 Oct 2025 13:13:57 +0200
Subject: [PATCH 1/2] stages: add new link stage

This introduces a new stage, `org.osbuild.ln`, for creating
links within the filesystem tree.

This takes a list of paths, each with a `target` and a `link_name`
parameters, inspired by the copy stage.

The target is a simple string because we want the link to be either
absolute or relative.
---
stages/org.osbuild.ln | 31 ++++++++++++++++
stages/org.osbuild.ln.meta.json | 66 +++++++++++++++++++++++++++++++++
2 files changed, 97 insertions(+)
create mode 100755 stages/org.osbuild.ln
create mode 100644 stages/org.osbuild.ln.meta.json

diff --git a/stages/org.osbuild.ln b/stages/org.osbuild.ln
new file mode 100755
index 00000000..8268685d
--- /dev/null
+++ b/stages/org.osbuild.ln
@@ -0,0 +1,31 @@
+#!/usr/bin/python3
+import os
+import sys
+
+import osbuild.api
+from osbuild.util import parsing
+
+
+def main(args, options):
+ items = options["paths"]
+
+ for path in items:
+ target = path["target"]
+ link_name = parsing.parse_location(path["link_name"], args)
+ symbolic = path.get("symbolic", False)
+
+ print(f"Linking '{link_name}' -> '{target}'")
+ if symbolic:
+ print(f"Creating symbolic link: '{link_name}' -> '{target}'")
+ os.symlink(target, link_name)
+ else:
+ print(f"Creating hard link: '{link_name}' -> '{target}'")
+ os.link(target, link_name)
+
+ return 0
+
+
+if __name__ == '__main__':
+ _args = osbuild.api.arguments()
+ r = main(_args, _args["options"])
+ sys.exit(r)
diff --git a/stages/org.osbuild.ln.meta.json b/stages/org.osbuild.ln.meta.json
new file mode 100644
index 00000000..81f297be
--- /dev/null
+++ b/stages/org.osbuild.ln.meta.json
@@ -0,0 +1,66 @@
+{
+ "summary": "Create links",
+ "description": [
+ "Creates links within the tree or mounts. The target and link_name are specified as URLs.",
+ "Only allows tree or mounts URLs."
+ ],
+ "schema_2": {
+ "options": {
+ "additionalProperties": false,
+ "required": [
+ "paths"
+ ],
+ "properties": {
+ "paths": {
+ "description": "Array of links to create.",
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "target",
+ "link_name"
+ ],
+ "properties": {
+ "target": {
+ "type": "string",
+ "description": "The target for the link, relative or absolute"
+ },
+ "link_name": {
+ "oneOf": [
+ {
+ "type": "string",
+ "description": "The link path, if in a mount",
+ "pattern": "^mount://[^/]+/"
+ },
+ {
+ "type": "string",
+ "description": "The link path, if in a tree",
+ "pattern": "^tree://"
+ }
+ ]
+ },
+ "symbolic": {
+ "type": "boolean",
+ "description": "Use a symbolic link instead of hard-linking. Defaults to False.",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ },
+ "devices": {
+ "type": "object",
+ "additionalProperties": true
+ },
+ "mounts": {
+ "type": "array"
+ },
+ "inputs": {
+ "type": "object",
+ "additionalProperties": true
+ }
+ }
+}
--
2.51.0

21 changes: 17 additions & 4 deletions src/cmd-osbuild
Original file line number Diff line number Diff line change
Expand Up @@ -408,10 +408,23 @@ main() {
else
cmd="runvm_with_cache"
fi
$cmd -- /usr/lib/coreos-assembler/runvm-osbuild \
--config "${runvm_osbuild_config_json}" \
--mpp "/usr/lib/coreos-assembler/osbuild-manifests/coreos.osbuild.${basearch}.mpp.yaml" \
--outdir "${outdir}" \

# Use the bootc install to-filesystem manifest if applicable
bootc_suffix=""
if should_use_bootc_install; then
bootc_suffix=".bootc"
fi

manifest_path="/usr/lib/coreos-assembler/osbuild-manifests/coreos.osbuild.${basearch}${bootc_suffix}.mpp.yaml"

# To get a shell in the osbuild supermin VM uncomment this.
# osbuild can then be started with `bash tmp/build.<artifact>/cmd.sh`
# See comment about checkpoints in runvm-osbuild
# RUNVM_SHELL=1 \
$cmd -- /usr/lib/coreos-assembler/runvm-osbuild \
--config "${runvm_osbuild_config_json}" \
--mpp "${manifest_path}" \
--outdir "${outdir}" \
--platforms "$(IFS=,; echo "${platforms[*]}")"

for platform in "${platforms[@]}"; do
Expand Down
49 changes: 37 additions & 12 deletions src/cmdlib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -148,28 +148,53 @@ yaml2json() {
python3 -c 'import sys, json, yaml; json.dump(yaml.safe_load(sys.stdin), sys.stdout, sort_keys=True)' < "$1" > "$2"
}

should_build_with_buildah() {
local variant manifest
if [ -n "${COSA_BUILD_WITH_BUILDAH:-}" ]; then
if [ "${COSA_BUILD_WITH_BUILDAH:-}" = 1 ]; then
# Common helper to check for features that can be enabled via an env var or
# in the manifest metadata.
_should_enable_feature() {
local env_var_name=$1
local metadata_key=$2
local env_var_value
# Indirect expansion
env_var_value=${!env_var_name:-}

if [ -n "${env_var_value}" ]; then
if [ "${env_var_value}" = 1 ]; then
return 0
else
return 1
fi
fi

# Make sure we are in the config directory (e.g. cmd-osbuild set a different working directory).
# When called very early (e.g. cmd-fetch), configdir isn't initialized yet so we assume we are in the top
# cosa initialized dir and use `src/config`.
# We redirect the output to /dev/null to avoid the noisy `dirs` output.
set +u
pushd "${configdir:-src/config}" > /dev/null
set -u
# this slightly duplicates some logic in `prepare_build`, but meh...
if [[ -f "src/config.json" ]]; then
variant="$(jq --raw-output '."coreos-assembler.config-variant"' src/config.json)"
manifest="src/config/manifest-${variant}.yaml"
if [[ -f "../config.json" ]]; then
variant="$(jq --raw-output '."coreos-assembler.config-variant"' ../config.json)"
manifest="manifest-${variant}.yaml"
else
manifest="src/config/manifest.yaml"
manifest="manifest.yaml"
fi
if [ "$(yq .metadata.build_with_buildah "${manifest}")" = true ]; then
if [ "$(yq ".metadata.${metadata_key}" "${manifest}")" = true ]; then
popd > /dev/null
return 0
fi
popd > /dev/null
return 1
}

should_use_bootc_install() {
_should_enable_feature "COSA_OSBUILD_USE_BOOTC_INSTALL" "use_bootc_install"
}

should_build_with_buildah() {
_should_enable_feature "COSA_BUILD_WITH_BUILDAH" "build_with_buildah"
}

prepare_build() {
preflight
preflight_kvm
Expand Down Expand Up @@ -759,8 +784,8 @@ runvm() {
# include COSA in the image
find /usr/lib/coreos-assembler/ -type f > "${vmpreparedir}/hostfiles"
cat <<EOF >> "${vmpreparedir}/hostfiles"
/usr/lib/osbuild/stages/org.osbuild.coreos.live-artifacts.mono
/usr/lib/osbuild/stages/org.osbuild.coreos.live-artifacts.mono.meta.json
/usr/lib/osbuild/stages/org.osbuild.ln
/usr/lib/osbuild/stages/org.osbuild.ln.meta.json
EOF

# and include all GPG keys
Expand All @@ -787,7 +812,7 @@ rc=0
if [ -z "${RUNVM_SHELL:-}" ]; then
(cd ${workdir}; bash ${tmp_builddir}/cmd.sh |& tee /dev/virtio-ports/cosa-cmdout) || rc=\$?
else
(cd ${workdir}; bash)
(cd ${workdir}; RUNVM_SHELL=${RUNVM_SHELL:-} bash)
fi
echo \$rc > ${rc_file}
if [ -n "\${cachedev}" ]; then
Expand Down
Loading
Loading