Files
pmg/.cursor/plans/system_install_design_98a8f15f.plan.md
T
Sahilb315andCursor 8f6d0fcce0 feat: add Linux system-wide setup
Install shared shims, managed configuration, and login-shell PATH integration so golden images and multi-user hosts can protect package installs for every user.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 02:19:59 +05:30

7.6 KiB
Raw Blame History

name, overview, todos, isProject
name overview todos isProject
System install design Design for `pmg setup install --system` (Linux): general system-wide shims + config + `/etc/profile.d`, motivated by Docker golden images but not Docker-specific. Venv-after-activate remains a documented limitation.
id content status
spec Write design spec to docs/specs/ after user approves design completed
id content status
eventlog-root Eventlog soft-fail + root-without--system warning completed
id content status
system-artifacts System shim manager, profile.d writer, WriteSystemTemplateConfig completed
id content status
cli-flags Wire --system on install/remove with uid checks completed
id content status
info-doctor Update setup info and doctor for system scope completed
id content status
docs-tests Docs (golden image, venv limit) + unit tests completed
false

PMG System Install (--system) — Design

Re-evaluation of issue #317 against current codebase. Prerequisite PR #323 (PMG_SHIM_PATH) is already merged.

Goal

Root can install PMG once for all users on a Linux host (golden Docker image, shared VM). Later USER appuser / non-root logins get interception without per-user pmg setup install.

Primary motivator: package installs inside docker build (host GHA PMG cannot see them). Feature itself is a general Linux system install, not a Docker mode.

Non-goals (v1)

  • macOS / Windows --system
  • Persistent proxy baked into images
  • In-place wrap of /usr/local/bin binaries
  • Shell function wrappers (venv interactive fix)
  • Making host PMG intercept docker build from outside the image
  • Closing the venv-after-activate PATH race via shims

Locked decisions

Topic Choice
Scope Linux only
Shim location /usr/local/lib/pmg/bin (not /usr/local/bin)
Config Write /etc/safedep/pmg/config.yml (read path already exists)
PATH on VMs / login shells /etc/profile.d/pmg.sh prepends shim dir
PATH in Docker builds Image author sets ENV PATH="/usr/local/lib/pmg/bin:$PATH" (documented; required for RUN)
Venv after activate Documented limitation → use pmg pip …
Proxy-in-image Rejected for this use case
Layers System and per-user installs independent

User flows

Golden Docker base

RUN curl -fsSL … | sh && pmg setup install --system
ENV PATH="/usr/local/lib/pmg/bin:$PATH"

Child images:

FROM company/golden:latest
USER appuser
RUN npm ci              # intercepted
RUN pip install pkg     # intercepted (system pip)
# RUN .venv/bin/activate && pip install x  # NOT intercepted — use pmg pip

Multi-user Linux VM

sudo pmg setup install --system
# new login shells get PATH via /etc/profile.d/pmg.sh

CLI UX

sudo pmg setup install --system   # root-only; fail fast otherwise
sudo pmg setup remove --system
pmg setup info                    # reports system / user / both
pmg setup doctor                  # checks system shim dir + on PATH
  • Root without --system → warn (other users not covered; point to --system), then proceed with per-user install into roots HOME.
  • Non-root --systemusefulerror + sudo guidance.

Architecture

flowchart TB
  subgraph install [pmg setup install --system]
    Cfg["/etc/safedep/pmg/config.yml"]
    Shims["/usr/local/lib/pmg/bin/*"]
    Profile["/etc/profile.d/pmg.sh"]
  end
  subgraph path [How PATH gets shims]
    Env["Docker ENV PATH"]
    Prof["profile.d on login shells"]
  end
  Shims --> Env
  Shims --> Prof
  Env --> Run["Dockerfile RUN / any process with ENV"]
  Prof --> Login["VM interactive/login shells"]

Components to add/change

  • [cmd/setup/setup.go](cmd/setup/setup.go)--system flag, uid-0 preflight, branch install/remove; root warning without flag
  • [config/config.go](config/config.go)WriteSystemTemplateConfig()globalConfigDir(); remove only with --system
  • [internal/shim/shim.go](internal/shim/shim.go)NewSystemShimManager() with BinDir=/usr/local/lib/pmg/bin, no per-user rc edits
  • New system profile writer — /etc/profile.d/pmg.sh (marker-gated, PATH prepend only)
  • [cmd/setup/info.go](cmd/setup/info.go) / [cmd/setup/doctor.go](cmd/setup/doctor.go) — system scope reporting + PATH check
  • [main.go](main.go) / eventlog — soft-fail when log init fails (unusable HOME); do not Fatalf

Reuse existing PMG_SHIM_PATH filtering in [internal/shim/path.go](internal/shim/path.go); no recursion work needed for the new shim dir.

Corner cases (handled or documented)

Case Handling
Docker RUN does not source profile.d Document ENV PATH=… in golden image
Login shell resets PATH via /etc/profile profile.d restores shim dir
Child Dockerfile overwrites PATH without shim dir Document; doctor can detect when run
Venv activate then pip Documented limitation → pmg pip
System + per-user both present Independent; remove is scoped
PMG_SHIM_PATH unset + direct pmg npm Legacy /.pmg/bin only; system dir not stripped — prefer shim invocation or ensure env from shim
Unwritable HOME Eventlog soft-fail
Windows --system → not supported

Testing

  • Unit tests with path overrides (same pattern as globalConfigDirOverride)
  • Install/remove idempotence for system shims + profile.d
  • Doctor/info system detection
  • Document a minimal Dockerfile golden-image smoke example in docs (not necessarily CI matrix in v1)

Docs

  • Setup / config docs: --system, golden-image snippet, VM vs Docker PATH, venv limitation
  • Clarify host GHA PMG does not protect in-image docker build installs — bake PMG into the image

Implementation order (after spec approval)

  1. Soft-fail eventlog + root warn (small, unblocks containers)
  2. System shim manager + profile.d writer + config write
  3. Wire --system on install/remove
  4. info/doctor
  5. Docs + tests