diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a5a0f55..7f7ac28 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -148,7 +148,7 @@ jobs: run: sudo chown -R "$(id -u):$(id -g)" mkosi.output/ - name: Save kernel cache - if: github.ref == 'refs/heads/main' + if: github.ref == 'refs/heads/main' && steps.kernel-cache.outputs.cache-hit != 'true' uses: actions/cache/save@v4 with: path: | @@ -198,7 +198,7 @@ jobs: run: ./build.py tools - name: Save tools cache - if: github.ref == 'refs/heads/main' + if: github.ref == 'refs/heads/main' && steps.tools-cache.outputs.cache-hit != 'true' uses: actions/cache/save@v4 with: path: | @@ -245,6 +245,13 @@ jobs: name: tools-${{ matrix.arch }} path: mkosi.output/tools/${{ matrix.arch }} + - name: Restore tool binary permissions + run: | + # GitHub Actions artifact upload/download strips execute permissions. + # Restore +x on all tool binaries so they work inside the initramfs. + chmod +x mkosi.output/tools/${{ matrix.arch }}/usr/local/bin/* + chmod +x mkosi.output/tools/${{ matrix.arch }}/opt/cni/bin/* + - name: Refresh apt cache run: sudo apt-get update diff --git a/captain/cli/_commands.py b/captain/cli/_commands.py index 4e2679e..2789757 100644 --- a/captain/cli/_commands.py +++ b/captain/cli/_commands.py @@ -123,7 +123,6 @@ def _clean_version(cfg: Config, clog: StageLogger) -> None: mkosi_output / "kernel" / kver / cfg.arch, mkosi_output / "initramfs" / kver / cfg.arch, mkosi_output / "iso" / kver / cfg.arch, - mkosi_output / "iso-staging" / kver / cfg.arch, ] has_docker = shutil.which("docker") is not None @@ -195,13 +194,12 @@ def _clean_all(cfg: Config, clog: StageLogger) -> None: " /work/mkosi.output/kernel" " /work/mkosi.output/tools" " /work/mkosi.output/iso" - " /work/mkosi.output/iso-staging" " /work/mkosi.cache", ], ) else: # No Docker available — remove directly (may need sudo for root-owned mkosi files) - for pattern in ("image*", "initramfs", "kernel", "tools", "iso", "iso-staging"): + for pattern in ("image*", "initramfs", "kernel", "tools", "iso"): for p in mkosi_output.glob(pattern): if p.is_dir(): shutil.rmtree(p, ignore_errors=True) diff --git a/captain/cli/_stages.py b/captain/cli/_stages.py index 326e606..4e359c2 100644 --- a/captain/cli/_stages.py +++ b/captain/cli/_stages.py @@ -188,7 +188,6 @@ def _build_iso_stage(cfg: Config) -> None: isolog, [ "/work/mkosi.output/iso", - "/work/mkosi.output/iso-staging", "/work/out", ], ) diff --git a/captain/config.py b/captain/config.py index 65434d0..90cd118 100644 --- a/captain/config.py +++ b/captain/config.py @@ -198,4 +198,4 @@ def iso_output(self) -> Path: @property def iso_staging(self) -> Path: """Per-version, per-arch staging directory for assembling the ISO filesystem.""" - return self.project_dir / "mkosi.output" / "iso-staging" / self.kernel_version / self.arch + return self.iso_output / "staging" diff --git a/captain/iso.py b/captain/iso.py index 4876482..8275b32 100644 --- a/captain/iso.py +++ b/captain/iso.py @@ -65,7 +65,7 @@ def build(cfg: Config) -> None: The ISO layout is:: - iso-staging/{arch}/ + iso/{version}/{arch}/staging/ ├── boot/ │ ├── grub/ │ │ └── grub.cfg diff --git a/mkosi.finalize b/mkosi.finalize index fc1d5f6..1057bcd 100755 --- a/mkosi.finalize +++ b/mkosi.finalize @@ -36,6 +36,18 @@ if [[ -f "$BUILDROOT/init" ]]; then echo " /init made executable" fi +# Ensure tool binaries are executable. +# GitHub Actions artifact upload/download and some archive tools strip +# the execute bit. Re-apply +x to every tool directory so containerd, +# runc, nerdctl, and CNI plugins can actually run. +for dir in usr/local/bin opt/cni/bin; do + target="$BUILDROOT/$dir" + if [[ -d "$target" ]]; then + find "$target" -type f -exec chmod +x {} + + echo " +x restored on $dir/*" + fi +done + # --------------------------------------------------------------------------- # Trim kernel modules not needed for provisioning. # The kernel is built with a broad defconfig (modules as =m) so the full set