mirror of
https://github.com/games-on-whales/LXC2Docker.git
synced 2026-10-16 05:12:04 +00:00
[PR #11] [MERGED] Implement image save for Portainer backup #13
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
games-on-whales/LXC2Docker#13
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/games-on-whales/LXC2Docker/pull/11
Author: @JBailes
Created: 4/17/2026
Status: ✅ Merged
Merged: 4/17/2026
Merged by: @JBailes
Base:
docker-lxc-daemon← Head:aimee/session/portainer-image-save📝 Commits (3)
2e14270Implement image save for Portainer backup302e640Implement image load as the counterpart of image save70795cfAdd multi-image /images/get?names= bulk save📊 Changes
2 files changed (+588 additions, -0 deletions)
View changed files
➕
internal/api/image_save.go(+585 -0)📝
internal/api/router.go(+3 -0)📄 Description
Summary
GET /images/{name}/getreturning a proper Docker-save-format tarball so Portainer's "Download image" button anddocker image savework end-to-end against our daemon.Why
Users had no way to back images out of the daemon: the endpoint was 404'ing, and the recent runs of PR #10 surfaced this as the next blocker for Portainer's backup UX. A clean save also enables round-trips into a real Docker daemon for offline inspection.
What changed
layer.taris produced by invoking hosttaragainst the rootfs:<mountpoint>/.zfs/snapshot/tmpl/, so no clone/mount dance is neededdiff_idsentry matches the byte payload — a hard requirement fordocker loadImageRecord(Entrypoint/Cmd/Env/ExposedPorts/User/StopSignal/Healthcheck/Labels/WorkingDir) plusrootfs.diff_idsmanifest.jsonand a legacy v1repositoriesfile wrap the bundle so older docker CLIs can still load itValidation
root@192.168.1.253against the running storeportainer/portainer-ce:latest→ ~180 MB tar with the expected structure:manifest.jsonlistsConfig=<sha>.json,Layers=["layer.tar"],RepoTags=["portainer/portainer-ce:latest"]Entrypoint=["/portainer"],ExposedPorts={8000,9000,9443}/tcp,WorkingDir=/layer.tarcontents begin with./,./tmp/,./metadata.json,./README.md,./public/— the real portainer rootfssha256(layer.tar)==config.rootfs.diff_ids[0](critical for docker-load acceptance)nginx:alpineproduced the expected 63 MB tar with matching shaNotes
GET /images/get?names=a,bis not implemented yet; single-image save via the named endpoint is the one Portainer uses for its "Download image" button.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.