Skip to content

Commit a6bb8a7

Browse files
committed
to-disk: Fallback to signature removal on error
Try bootc install first using the image from additionalimagestore. If it fails with "Would invalidate signatures", automatically retry with skopeo copy --remove-signatures as a fallback. This avoids the deep copy when possible (e.g., for unsigned images or when containers/image#2590 is fixed), while still working with signed images like RHEL that currently fail. Fixes: #126 Assisted-by: Claude Code (Sonnet 4.5)
1 parent b664ecb commit a6bb8a7

File tree

1 file changed

+68
-5
lines changed

1 file changed

+68
-5
lines changed

crates/kit/src/to_disk.rs

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,17 @@ impl ToDiskOpts {
202202
.map_err(|e| eyre!("Failed to quote source imgref '{}': {}", source_imgref, e))?
203203
.to_string();
204204

205+
// Quote the source image name for local storage operations
206+
let quoted_source_image = shlex::try_quote(&self.source_image)
207+
.map_err(|e| {
208+
eyre!(
209+
"Failed to quote source image '{}': {}",
210+
self.source_image,
211+
e
212+
)
213+
})?
214+
.to_string();
215+
205216
let install_log = self
206217
.additional
207218
.install_log
@@ -247,25 +258,77 @@ impl ToDiskOpts {
247258
tty=--tty
248259
fi
249260
250-
# Execute bootc installation, having the outer podman pull from
251-
# the virtiofs store on the host, as well as the inner bootc.
252-
# Mount /var/tmp into inner container to avoid cross-device link errors (issue #125)
261+
# Try bootc install first with the image from additionalimagestore
262+
# This avoids a deep copy when possible (issue #126)
253263
export STORAGE_OPTS=additionalimagestore=${AIS}
264+
265+
# Execute bootc installation
266+
# Mount /var/tmp into inner container to avoid cross-device link errors (issue #125)
267+
set +e # Don't exit on error, we'll check for signature error and retry
268+
ERROR_OUTPUT=$(mktemp)
254269
podman run --rm -i ${tty} --privileged --pid=host --net=none -v /sys:/sys:ro \
255-
-v /var/lib/containers:/var/lib/containers -v /var/tmp:/var/tmp -v /dev:/dev -v ${AIS}:${AIS} --security-opt label=type:unconfined_t \
270+
-v /var/lib/containers:/var/lib/containers -v /var/tmp:/var/tmp -v /dev:/dev -v "${AIS}:${AIS}" \
271+
--security-opt label=type:unconfined_t \
256272
--env=STORAGE_OPTS \
257273
{INSTALL_LOG} \
258274
{SOURCE_IMGREF} \
259275
bootc install to-disk \
260276
--generic-image \
261277
--skip-fetch-check \
262278
{BOOTC_ARGS} \
263-
/dev/disk/by-id/virtio-output
279+
/dev/disk/by-id/virtio-output 2>&1 | tee "$ERROR_OUTPUT"
280+
BOOTC_EXIT=$?
281+
set -e
282+
283+
# Check if bootc failed with signature validation error
284+
if [ $BOOTC_EXIT -ne 0 ] && grep -q "Would invalidate signatures" "$ERROR_OUTPUT"; then
285+
echo "Signature validation error detected, retrying with signature removal..."
286+
287+
# Workaround for issue #126 and containers/image#2590:
288+
# Copy image to local storage without signatures when we hit the signature error.
289+
# This is a fallback - we only do the deep copy when necessary.
290+
# Note: containers/container-libs#144 would make this copy faster via reflinks.
291+
# The real fix is containers/image#2590 to carry signatures across representation changes.
292+
mkdir -p /etc/containers
293+
cat > /etc/containers/policy.json <<'EOF'
294+
{
295+
"default": [{"type": "insecureAcceptAnything"}],
296+
"transports": {
297+
"containers-storage": {"": [{"type": "insecureAcceptAnything"}]},
298+
"docker": {"": [{"type": "insecureAcceptAnything"}]}
299+
}
300+
}
301+
EOF
302+
303+
# Copy image without signatures
304+
skopeo copy --remove-signatures {SOURCE_IMGREF} containers-storage:{SOURCE_IMAGE}
305+
306+
# Retry bootc install with the unsigned local copy
307+
podman run --rm -i ${tty} --privileged --pid=host --net=none -v /sys:/sys:ro \
308+
-v /var/lib/containers:/var/lib/containers -v /var/tmp:/var/tmp -v /dev:/dev -v "${AIS}:${AIS}" \
309+
--security-opt label=type:unconfined_t \
310+
--env=STORAGE_OPTS \
311+
{INSTALL_LOG} \
312+
containers-storage:{SOURCE_IMAGE} \
313+
bootc install to-disk \
314+
--generic-image \
315+
--skip-fetch-check \
316+
{BOOTC_ARGS} \
317+
/dev/disk/by-id/virtio-output
318+
elif [ $BOOTC_EXIT -ne 0 ]; then
319+
# Some other error, re-display and fail
320+
cat "$ERROR_OUTPUT" >&2
321+
rm -f "$ERROR_OUTPUT"
322+
exit $BOOTC_EXIT
323+
fi
324+
325+
rm -f "$ERROR_OUTPUT"
264326
265327
echo "Installation completed successfully!"
266328
"#}
267329
.replace("{TMPFS_SIZE}", &tmpfs_size_quoted)
268330
.replace("{SOURCE_IMGREF}", &quoted_source_imgref)
331+
.replace("{SOURCE_IMAGE}", &quoted_source_image)
269332
.replace("{INSTALL_LOG}", &install_log)
270333
.replace("{BOOTC_ARGS}", &bootc_args);
271334

0 commit comments

Comments
 (0)