Skip to content

Pin apt child process locale in UpdatesCollector - #117

Merged
LarsLaskowski merged 1 commit into
mainfrom
claude/issue-100-h0u4ne
Aug 21, 2026
Merged

Pin apt child process locale in UpdatesCollector#117
LarsLaskowski merged 1 commit into
mainfrom
claude/issue-100-h0u4ne

Conversation

@LarsLaskowski

@LarsLaskowski LarsLaskowski commented Aug 21, 2026

Copy link
Copy Markdown
Owner

📖 Description

UpdatesCollector.Collect (internal/collector/updates.go) shells out to apt list --upgradable and parses its output with an English-only regex. The child process environment was built by appending DEBIAN_FRONTEND=noninteractive to os.Environ(), so on any host running a non-English locale (e.g. de_DE.UTF-8), apt localises its output via gettext ([upgradable from: ...] becomes [aktualisierbar von: ...]), the parser regex never matches, and Updates.Count silently reports 0 forever — with no error, no log warning, and no visible symptom other than a dashboard that always looks fully up to date.

This is a fix, not a feature: it builds the child environment explicitly instead of inheriting the operator's, forcing LC_ALL=C, LANG=C, and LANGUAGE= so apt output is always in the English form the parser expects, while preserving PATH so the bare "apt" command still resolves via exec.LookPath.

🎫 Issues

Closes #100

👩‍💻 Reviewer Notes

The only functional change is the cmd.Env assignment in UpdatesCollector.Collect. parseAptListUpgradable and the strings.HasPrefix(line, "Listing...") skip are unchanged — they were already correct for LC_ALL=C output, they just never received it in a non-English environment.

📑 Test Plan

Added TestUpdatesCollector_Collect_PinsLocale to internal/collector/updates_test.go, following the existing writeFakeVcgencmd stub-binary pattern used elsewhere in this file (no real apt binary or real locale data involved, per docs/TESTS.md):

  • Points aptPath at a small shell script that dumps its own environment (env > file) instead of a real apt binary.
  • Asserts the captured child environment has LC_ALL=C, LANG=C, and an empty LANGUAGE.
  • Asserts PATH is still present in the child environment — a regression guard, since building cmd.Env from scratch instead of appending to os.Environ() could otherwise silently drop PATH and break command resolution.

Ran locally:

  • go build ./...
  • go vet ./...
  • go test ./... -race -cover — all packages pass, internal/collector at 90.8% coverage
  • golangci-lint run — 0 issues

✅ Checklist

General

  • I have added/updated tests for my changes (go test ./... -race -cover passes locally).
  • go vet ./... and golangci-lint run are clean.
  • I have tested my changes.
  • I have read the CONTRIBUTING documentation and followed the project's code style guidelines.
  • I have updated ARCHITECTURE.md if this changes a documented design decision. (N/A — internal parsing detail, no documented design decision changes.)

REST API / configuration / packaging

Not applicable — no REST API, configuration, or packaging changes.

⏭ Next Steps

None. As noted in the issue, a more robust long-term option (parsing apt-get --just-print upgrade or reading dpkg/apt state directly) is a larger change and intentionally out of scope here.

apt list --upgradable localises its output via gettext. Collect built the
child environment by appending to os.Environ(), so on any non-English
locale (e.g. de_DE) apt prints "aktualisierbar von:" instead of "upgradable
from:", the parser regex never matches, and Updates.Count silently reports
0 forever with no error or log warning.

Build the child environment explicitly instead of inheriting the host's:
set LC_ALL, LANG and LANGUAGE to force English/C output, and preserve PATH
so the bare "apt" command name still resolves via exec.LookPath.
@sonarqubecloud

Copy link
Copy Markdown

@LarsLaskowski
LarsLaskowski merged commit 1fa70a9 into main Aug 21, 2026
5 checks passed
@LarsLaskowski
LarsLaskowski deleted the claude/issue-100-h0u4ne branch August 21, 2026 18:35
LarsLaskowski added a commit that referenced this pull request Aug 22, 2026
vcgencmdRunner.run() left cmd.Env nil, so vcgencmd inherited the full
service environment, including PIMONITOR_API_KEY when it is configured
via the environment as SECURITY.md recommends. That put the secret in
vcgencmd's /proc/<pid>/environ for no reason, the same class of
exposure the -api-key flag warning already exists to avoid.

updates.go was already fixed for the same issue by #117, which built
an explicit cmd.Env while pinning apt's locale. Apply the same
approach to vcgencmd: since it is invoked by the absolute path
resolved at detection time, it needs no PATH at all, so its child
environment can be empty.
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.

apt update count is always 0 on non-English systems (locale not pinned)

2 participants