daax-dev / daax-dev/nanofuse

layer image build: local:// Dockerfile layers are not built (tarred as source), so composed rootfs has no real OS

Open
#309 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

nanofuse
Dominant language
Go
Stars
0
Forks
0
PR merge metrics
No merged PRs in 30d

Description

Summary

nanofuse image build fails to build multi-layer images because the layer composer runs each layer's post-install hook inside a chroot at /hooks/<layer>/post-install.sh, but the hooks are authored to run on the host with a ROOTFS_PATH pointing at the mounted layer rootfs.

Building images/falcondev-agents/image.manifest.yaml (the FalconDev AI-agent image: Claude Code / Codex / Gemini + Python 3.12 + Node 22 + SSH):

[2/9] Applying layer: base-os
Layer base-os applied successfully          # base-os has no hook, so it "works"
[3/9] Applying layer: python-runtime
Executing hook: /hooks/python-runtime/post-install.sh
[hook stderr] chroot: failed to run command '/hooks/python-runtime/post-install.sh': No such file or directory
Error: build failed: failed to apply layer python-runtime: post-install hook failed: ... exited with status 127

Root cause

  • The hook source exists in the repo: layers/python-runtime/hooks/post-install.sh (and each layer's hooks/).
  • internal/layerbuild chroots into the layer rootfs and executes /hooks/<layer>/post-install.sh — a path that does not exist inside the rootfs (the hook was never staged there).
  • The hooks are clearly designed to run on the host against the rootfs: e.g. layers/agent-tools/hooks/post-install.sh uses ${ROOTFS_PATH}/etc/skel/.claude, ${ROOTFS_PATH}/root/.claude, etc.

So the composer's execution model (chroot + in-rootfs path) contradicts the hooks' authored model (host + ROOTFS_PATH).

Fix direction

Run post-install hooks on the host with ROOTFS_PATH set to the mounted/extracted layer rootfs (matching how the hooks are written), rather than chrooting and executing an in-rootfs /hooks/... path. (Or, if chroot is intended, stage the hook into the rootfs and drop the ROOTFS_PATH convention — but the existing hooks assume host execution.)

Repro

cd /nanofuse   # repo root (layer local:// paths are repo-root-relative)
nanofuse image build -m images/falcondev-agents/image.manifest.yaml -o /tmp/out --no-cache --verbose

Impact

Blocks building any layer image whose layers have post-install hooks (python-runtime, node-runtime, agent-tools) — i.e. the AI-agent/devtools images. base-only images are unaffected.

Found while validating the post-merge daax-devtools SSH-coding capability. The coding-in-a-microVM capability itself is proven (base microVM + apt-installed toolchain over SSH); this bug blocks shipping it as a preinstalled FalconDev image.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in internal/layerbuild and inspect how it executes layers/post-install.sh, then compare that flow with layers/python-runtime/hooks/post-install.sh and layers/agent-tools/hooks/post-install.sh. Reproduce with images/falcondev-agents/image.manifest.yaml using the provided nanofuse image build command. Done means hooks run on the host with ROOTFS_PATH set to the layer rootfs and the multi-layer image builds successfully.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, shell
Domain
build-system
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.