[PR #12] [MERGED] Capture image VOLUME declarations #14

Closed
opened 2026-10-15 12:51:17 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/games-on-whales/LXC2Docker/pull/12
Author: @JBailes
Created: 4/17/2026
Status: ✅ Merged
Merged: 4/17/2026
Merged by: @JBailes

Base: docker-lxc-daemon ← Head: aimee/session/portainer-image-volumes


📝 Commits (10+)

  • a919b16 Capture image VOLUME declarations
  • 5b1fa8d Inherit image Volumes into container inspect
  • c59e313 Support Dockerfile SHELL and named-volume mount inspect
  • b5a9b90 Round-trip modern HostConfig fields through inspect
  • 5e5dda2 Round-trip endpoint IPAM and inherit container Config.Shell
  • c3d1c8e Enrich NetworkSettings on container inspect
  • 349fa58 Track PreCPUStats across stats samples
  • 7a5d8ad Read memory.peak and memory.events for stats
  • 47262f9 Persist HostConfig.Devices and DeviceCgroupRules
  • e9f28fb Round-trip more HostConfig fields

📊 Changes

9 files changed (+581 additions, -78 deletions)

View changed files

📝 internal/api/build.go (+54 -2)
📝 internal/api/containers.go (+228 -26)
📝 internal/api/containers_extra.go (+114 -3)
📝 internal/api/images.go (+29 -1)
📝 internal/api/system.go (+1 -0)
📝 internal/api/types.go (+77 -28)
📝 internal/lxc/manager.go (+6 -0)
📝 internal/oci/pull.go (+12 -0)
📝 internal/store/store.go (+60 -18)

📄 Description

Summary

Capture images' declared VOLUMEs so Portainer's "Image > Volumes" tab renders, and Compose manifests built from VOLUME-carrying images see the declaration preserved.

Why

Images declare VOLUME /path to signal to Docker (and to Compose's anonymous-volume generator) that a path should be backed by a dedicated volume when the container starts. Portainer displays this on the image detail page. We were dropping the field end-to-end:

  • oci.Pull didn't read config.Volumes from the OCI manifest.
  • The Dockerfile builder treated VOLUME as an unknown instruction.
  • /images/{name}/json's Config block had no Volumes field.

What changed

  • oci.ImageConfig gets a Volumes []string; oci.Pull reads config.Volumes from the manifest config JSON.
  • store.ImageRecord persists it as OCIVolumes; pullOCI populates both the AddImage call and the oci-meta.json sidecar.
  • The Dockerfile builder accepts VOLUME (shell form VOLUME /a /b and JSON array form VOLUME ["/a","/b"]) via a small parseVolumeInstruction helper and attaches the set to the built image.
  • api.ImageConfig gains Volumes map[string]struct{} (omitempty); imageConfigFromRecord materialises it for inspect.

Validation

Built on a transient daemon socket on root@192.168.1.253:

  • Pull path: POST /images/create?fromImage=postgres&tag=16 followed by inspect returns Config.Volumes = {"/var/lib/postgresql/data": {}} (and preserves the unrelated StopSignal = "SIGINT" previously captured).
  • Build path: a Dockerfile with
    FROM nginx:alpine
    VOLUME ["/data", "/logs"]
    VOLUME /cache
    
    produces an image whose Config.Volumes is {"/cache":{}, "/data":{}, "/logs":{}}. Both the JSON array and shell forms are parsed.

Notes

  • This PR is intentionally scoped to metadata fidelity; it does not auto-create anonymous volumes at container-create time (Docker's behaviour). That can follow in a later change without breaking the surface added here.
  • Branched from docker-lxc-daemon after PR #10 merged; independent of the in-flight PR #11 (image save/load) — no file overlap.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/games-on-whales/LXC2Docker/pull/12 **Author:** [@JBailes](https://github.com/JBailes) **Created:** 4/17/2026 **Status:** ✅ Merged **Merged:** 4/17/2026 **Merged by:** [@JBailes](https://github.com/JBailes) **Base:** `docker-lxc-daemon` ← **Head:** `aimee/session/portainer-image-volumes` --- ### 📝 Commits (10+) - [`a919b16`](https://github.com/games-on-whales/LXC2Docker/commit/a919b16b240d40fe8c050195b44d331a267136cc) Capture image VOLUME declarations - [`5b1fa8d`](https://github.com/games-on-whales/LXC2Docker/commit/5b1fa8d788d28e7f296f65b31dce2ceb9e73cb0d) Inherit image Volumes into container inspect - [`c59e313`](https://github.com/games-on-whales/LXC2Docker/commit/c59e313113e2949a671041cfa2c0fdf57205a4f5) Support Dockerfile SHELL and named-volume mount inspect - [`b5a9b90`](https://github.com/games-on-whales/LXC2Docker/commit/b5a9b90632be799aa9da7efb2a04f677bed5f322) Round-trip modern HostConfig fields through inspect - [`5e5dda2`](https://github.com/games-on-whales/LXC2Docker/commit/5e5dda23f6f20e6707bd8938360ee4b4e4e1b89f) Round-trip endpoint IPAM and inherit container Config.Shell - [`c3d1c8e`](https://github.com/games-on-whales/LXC2Docker/commit/c3d1c8e136dd001cac0858c6f19e983b2f198773) Enrich NetworkSettings on container inspect - [`349fa58`](https://github.com/games-on-whales/LXC2Docker/commit/349fa58bff24be073f4a531dc673fa375701dcb0) Track PreCPUStats across stats samples - [`7a5d8ad`](https://github.com/games-on-whales/LXC2Docker/commit/7a5d8ad82b52a0de68501fe8cfe04fb88eb716f3) Read memory.peak and memory.events for stats - [`47262f9`](https://github.com/games-on-whales/LXC2Docker/commit/47262f95d81af9e0811d4c7184132934247a003d) Persist HostConfig.Devices and DeviceCgroupRules - [`e9f28fb`](https://github.com/games-on-whales/LXC2Docker/commit/e9f28fb54c832776c19227fa95017d235e385f3d) Round-trip more HostConfig fields ### 📊 Changes **9 files changed** (+581 additions, -78 deletions) <details> <summary>View changed files</summary> 📝 `internal/api/build.go` (+54 -2) 📝 `internal/api/containers.go` (+228 -26) 📝 `internal/api/containers_extra.go` (+114 -3) 📝 `internal/api/images.go` (+29 -1) 📝 `internal/api/system.go` (+1 -0) 📝 `internal/api/types.go` (+77 -28) 📝 `internal/lxc/manager.go` (+6 -0) 📝 `internal/oci/pull.go` (+12 -0) 📝 `internal/store/store.go` (+60 -18) </details> ### 📄 Description ## Summary Capture images' declared VOLUMEs so Portainer's "Image > Volumes" tab renders, and Compose manifests built from VOLUME-carrying images see the declaration preserved. ## Why Images declare `VOLUME /path` to signal to Docker (and to Compose's anonymous-volume generator) that a path should be backed by a dedicated volume when the container starts. Portainer displays this on the image detail page. We were dropping the field end-to-end: - `oci.Pull` didn't read `config.Volumes` from the OCI manifest. - The Dockerfile builder treated `VOLUME` as an unknown instruction. - `/images/{name}/json`'s `Config` block had no `Volumes` field. ## What changed - `oci.ImageConfig` gets a `Volumes []string`; `oci.Pull` reads `config.Volumes` from the manifest config JSON. - `store.ImageRecord` persists it as `OCIVolumes`; `pullOCI` populates both the AddImage call and the oci-meta.json sidecar. - The Dockerfile builder accepts `VOLUME` (shell form `VOLUME /a /b` and JSON array form `VOLUME ["/a","/b"]`) via a small `parseVolumeInstruction` helper and attaches the set to the built image. - `api.ImageConfig` gains `Volumes map[string]struct{}` (`omitempty`); `imageConfigFromRecord` materialises it for inspect. ## Validation Built on a transient daemon socket on `root@192.168.1.253`: - **Pull path**: `POST /images/create?fromImage=postgres&tag=16` followed by inspect returns `Config.Volumes = {"/var/lib/postgresql/data": {}}` (and preserves the unrelated `StopSignal = "SIGINT"` previously captured). - **Build path**: a Dockerfile with ``` FROM nginx:alpine VOLUME ["/data", "/logs"] VOLUME /cache ``` produces an image whose `Config.Volumes` is `{"/cache":{}, "/data":{}, "/logs":{}}`. Both the JSON array and shell forms are parsed. ## Notes - This PR is intentionally scoped to metadata fidelity; it does not auto-create anonymous volumes at container-create time (Docker's behaviour). That can follow in a later change without breaking the surface added here. - Branched from `docker-lxc-daemon` after PR #10 merged; independent of the in-flight PR #11 (image save/load) — no file overlap. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-15 12:51:17 +00:00
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
games-on-whales/LXC2Docker#14
No description provided.