[PR #43] [MERGED] fix(pve): hide image templates from the Proxmox UI + fix docker run -d deadlock #44

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

📋 Pull Request Information

Original PR: https://github.com/games-on-whales/LXC2Docker/pull/43
Author: @JBailes
Created: 5/31/2026
Status: ✅ Merged
Merged: 5/31/2026
Merged by: @JBailes

Base: main ← Head: fix/pve-hide-templates


📝 Commits (4)

  • 3e556c6 fix(pve): hide image templates from the Proxmox UI; fix docker run -d deadlock
  • ef17f58 fix(pve): treat instant-exit pct start as a successful fast-exit
  • 74d3040 fix(attach): frame non-TTY container output as Docker stdcopy stream
  • a660b17 feat(pve): reap leaked daemon-managed CTs from the Proxmox UI

📊 Changes

6 files changed (+524 additions, -83 deletions)

View changed files

📝 internal/api/containers.go (+97 -18)
📝 internal/lxc/config.go (+6 -2)
📝 internal/lxc/manager.go (+70 -63)
➕ internal/lxc/pve_tarball.go (+295 -0)
➕ internal/lxc/pve_tarball_test.go (+52 -0)
📝 internal/store/store.go (+4 -0)

📄 Description

What

PVE GUI cleanup + storage-agnostic image handling, plus a docker run -d deadlock fix. Reconciled onto the native-LLB main line (the storage-agnostic bits were ported from the deployed LVM WIP, preserved on origin/wip/deployed-lvm-buildx).

Templates no longer clutter the Proxmox UI

Previously every base image became a pct template CT (visible in the GUI), and they leaked duplicates. Now the rootfs is stored as a tarball under the state dir and containers are pct created from it directly:

  • storage-agnostic — works on lvmthin (the production storage), zfs, and dir
  • no Proxmox template CT → templates never appear in the UI
  • RemoveImage just deletes the tarball
  • store.ImageRecord.TemplateTarball; internal/lxc/pve_tarball.go (createPVEFromTarball, detectPVEStorageType, readPVERootfsSpec, mountPVERootfs)

Also ported from the WIP: storage-type detection, and cgroup:rw + features: nesting=1,keyctl=1 in the CT config (cgroup-v2 host fix + nested runtimes).

docker run -d deadlock fix

waitContainer only sent its HTTP response when the container exited. But the Docker SDK's ContainerWait (API ≥1.30) blocks on the POST until it gets the response header, and docker run calls ContainerWait before ContainerStart — so /start was never sent, the container stayed Created, and the wait never resolved. Deadlock (broken only by an external docker start). This is very likely the source of the lingering "Created" containers in the GUI.

Fix: flush the 200 header immediately, then stream the result when the wait resolves (matches the real docker daemon). Also detect fast-exiting containers in next-exit.

Validation

Live on the lvmthin host (isolated daemon, production untouched):

  • docker pull busybox → tarball, no GUI template ✓
  • docker run -d busybox sleep N → container running ✓
  • docker exec ✓
  • Unit suite + vet green.

Known remaining edge case (follow-up)

Foreground docker run <quick-cmd> / --rm (e.g. echo): pct start returns non-zero for a CT whose init exits instantly, and the foreground attach for an already-gone CT is a further layer. docker run -d with a long-running command (the common case + Wolf's pattern) is unaffected.

🤖 Generated with Claude Code


🔄 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/43 **Author:** [@JBailes](https://github.com/JBailes) **Created:** 5/31/2026 **Status:** ✅ Merged **Merged:** 5/31/2026 **Merged by:** [@JBailes](https://github.com/JBailes) **Base:** `main` ← **Head:** `fix/pve-hide-templates` --- ### 📝 Commits (4) - [`3e556c6`](https://github.com/games-on-whales/LXC2Docker/commit/3e556c66c8d138185ce681604d708497868aa7aa) fix(pve): hide image templates from the Proxmox UI; fix docker run -d deadlock - [`ef17f58`](https://github.com/games-on-whales/LXC2Docker/commit/ef17f58e2b87f0b8aaa182c581a7cf3fbcd0843c) fix(pve): treat instant-exit pct start as a successful fast-exit - [`74d3040`](https://github.com/games-on-whales/LXC2Docker/commit/74d3040f368a2f53f670f77e7398a7b71da8016c) fix(attach): frame non-TTY container output as Docker stdcopy stream - [`a660b17`](https://github.com/games-on-whales/LXC2Docker/commit/a660b17f869dd7b8880d4b3ccc0e0a723b901443) feat(pve): reap leaked daemon-managed CTs from the Proxmox UI ### 📊 Changes **6 files changed** (+524 additions, -83 deletions) <details> <summary>View changed files</summary> 📝 `internal/api/containers.go` (+97 -18) 📝 `internal/lxc/config.go` (+6 -2) 📝 `internal/lxc/manager.go` (+70 -63) ➕ `internal/lxc/pve_tarball.go` (+295 -0) ➕ `internal/lxc/pve_tarball_test.go` (+52 -0) 📝 `internal/store/store.go` (+4 -0) </details> ### 📄 Description ## What PVE GUI cleanup + storage-agnostic image handling, plus a `docker run -d` deadlock fix. Reconciled onto the native-LLB `main` line (the storage-agnostic bits were ported from the deployed LVM WIP, preserved on `origin/wip/deployed-lvm-buildx`). ## Templates no longer clutter the Proxmox UI Previously every base image became a `pct` template CT (visible in the GUI), and they leaked duplicates. Now the rootfs is stored as a **tarball** under the state dir and containers are `pct create`d from it directly: - storage-agnostic — works on **lvmthin** (the production storage), zfs, and dir - **no Proxmox template CT** → templates never appear in the UI - `RemoveImage` just deletes the tarball - `store.ImageRecord.TemplateTarball`; `internal/lxc/pve_tarball.go` (`createPVEFromTarball`, `detectPVEStorageType`, `readPVERootfsSpec`, `mountPVERootfs`) Also ported from the WIP: storage-type detection, and `cgroup:rw` + `features: nesting=1,keyctl=1` in the CT config (cgroup-v2 host fix + nested runtimes). ## `docker run -d` deadlock fix `waitContainer` only sent its HTTP response **when the container exited**. But the Docker SDK's `ContainerWait` (API ≥1.30) blocks on the POST until it gets the response **header**, and `docker run` calls `ContainerWait` **before** `ContainerStart` — so `/start` was never sent, the container stayed `Created`, and the wait never resolved. **Deadlock** (broken only by an external `docker start`). This is very likely the source of the lingering "Created" containers in the GUI. Fix: flush the `200` header immediately, then stream the result when the wait resolves (matches the real docker daemon). Also detect fast-exiting containers in `next-exit`. ## Validation Live on the lvmthin host (isolated daemon, production untouched): - `docker pull busybox` → tarball, **no GUI template** ✓ - `docker run -d busybox sleep N` → container **running** ✓ - `docker exec` ✓ - Unit suite + vet green. ## Known remaining edge case (follow-up) Foreground `docker run <quick-cmd>` / `--rm` (e.g. `echo`): `pct start` returns non-zero for a CT whose init exits *instantly*, and the foreground attach for an already-gone CT is a further layer. `docker run -d` with a long-running command (the common case + Wolf's pattern) is unaffected. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <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:34 +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#44
No description provided.