Skip to content

fix: install [packages] from claudebox install during image build - #116

Open
benjaminserguienko wants to merge 1 commit into
RchGrav:mainfrom
benjaminserguienko:fix/install-packages
Open

benjaminserguienko wants to merge 1 commit into
RchGrav:mainfrom
benjaminserguienko:fix/install-packages

Conversation

@benjaminserguienko

@benjaminserguienko benjaminserguienko commented Oct 24, 2026 •

Copy link
Copy Markdown

fix: install [packages] from claudebox install during image build

Problem

claudebox install <packages> saves packages to the [packages] section of the
project's profiles.ini, but they never reached the container, even after
claudebox rebuild.

The CLI overhaul in 1e621cc ("refactor: complete CLI architecture overhaul")
rewrote the image build in scripts/bin/claudebox and dropped the code that
turned [packages] into an apt-get install layer. A copy survived in
scripts/bin/claudebox.old until 42c6cf7 deleted it. Since then the build has
read only the [profiles] section.

Fix

build_docker_image in main.sh reads the [packages] section again. When it
lists packages, the build adds this step after the profile installations:

USER root
RUN export DEBIAN_FRONTEND=noninteractive && apt-get update && apt-get install -y <packages> && apt-get clean && rm -rf /var/lib/apt/lists/*
  • It runs as root explicitly, whatever user the profile steps end with.
  • Package names are joined with spaces explicitly, so IFS can't change how they are joined.
  • No layer is added when [packages] is empty or missing.

Tests

tests/test_dockerfile_generation.sh now writes a [packages] section
(pkg-config, libasound2-dev, libudev-dev) and checks that the generated
Dockerfile installs those packages as root.

  • The test failed before the fix and passes after it.
  • These tests also still pass: test_bash32_compat.sh, test_cli_bash32.sh,
    test_dockerfile_template.sh and test_runtime_regressions.sh.

Notes

The automatic rebuild check doesn't watch main.sh, so projects that already
ran claudebox install need one claudebox rebuild after upgrading to pick up
their packages.

Summary by Sourcery

Restore installation of packages managed by claudebox install during image builds and prevent unsafe package values from reaching generated Dockerfiles.

Bug Fixes:

  • Install packages listed in the profiles.ini [packages] section when building Docker images, including after profile installations and with root privileges.

Enhancements:

  • Validate package specifications before persisting or interpolating them into generated Dockerfiles, while allowing architecture qualifiers, version pins, and target releases.

Tests:

  • Extend Dockerfile generation coverage for package installation, root execution, unsafe package rejection, and valid apt package specifications.

@sourcery-ai

sourcery-ai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

The build now converts [packages] entries persisted by claudebox install into a root apt installation layer, with cleanup and no-op behavior for empty sections. Dockerfile generation tests cover package inclusion and user context while retaining existing build-generation checks.

Sequence diagram for installing project packages during image build

sequenceDiagram
    participant CLI as claudebox install
    participant Profiles as profiles.ini
    participant Build as build_docker_image
    participant Dockerfile as Generated Dockerfile
    participant Apt as apt-get

    CLI->>Profiles: Persist package names in [packages]
    Build->>Profiles: read_profile_section(profiles_file, packages)
    alt packages are present
        Build->>Dockerfile: Add USER root
        Build->>Dockerfile: Add apt-get update and apt-get install
        Dockerfile->>Apt: Install package_list
        Apt-->>Dockerfile: Clean package lists
    else packages are empty or missing
        Build->>Dockerfile: Omit package installation layer
    end
Loading

File-Level Changes

Change Details Files
Restore Dockerfile generation for packages listed in the profile's [packages] section.
  • Read and normalize non-empty package entries from profiles.ini.
  • Append a root-owned apt update/install/cleanup layer after profile installations.
  • Skip the layer when no packages are configured and join package names explicitly.
main.sh
Extend Dockerfile generation coverage to verify extra packages are installed as root.
  • Add representative packages to the test profile.
  • Assert the generated apt installation contains all packages and follows USER root.
tests/test_dockerfile_generation.sh

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="main.sh" line_range="586" />
<code_context>
+            local package_list
+            package_list=$(printf '%s ' "${extra_packages[@]}")
+            profile_installations+=$'\n'"USER root"
+            profile_installations+=$'\n'"RUN export DEBIAN_FRONTEND=noninteractive && apt-get update && apt-get install -y ${package_list% } && apt-get clean && rm -rf /var/lib/apt/lists/*"
+        fi
+
</code_context>
<issue_to_address>
**Package values execute as root**

When a `[packages]` entry contains shell metacharacters, `package_list` is interpolated into the Dockerfile `RUN` command, so the build shell executes the added commands as root instead of treating the entry only as an apt package name.

Validate or safely escape package entries before inserting them into the Dockerfile `RUN` command.

Also at `main.sh:587`.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread main.sh Resolved
The restructure in 0e9a882 dropped the code that turned the profiles.ini
[packages] section into an apt-get layer, so 'claudebox install' recorded
packages that never reached the container. Restore it, running as root
after the profile installations.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant