Repository navigation
fix(cli): fail closed when uninstall targets a missing directory - #430
Conversation
Fleet review (glm)Lens: requirements + adversarial. The fix satisfies the #358 acceptance criterion quoted from #342 ("Running update/uninstall against a directory with no prior Cortex ownership fails closed with an explicit diagnostic"): a missing --target-dir now returns exitConflict (3) with uninstall=not_installed on stdout and empty stderr, identical to the already-accepted empty-directory behavior, and the missing path is not created on disk. Both cases are pinned by new tests (TestUninstallDirectoryTargetFailsClosedWhenRootMissing and ...WhenNotInstalled), grouped uninstall is confirmed unchanged via the existing uninstall_test.go, the shared helpers are untouched, and docs/operating.md documents the exit-code split. The change is minimal and consistent; the absence of a distinct reason token for a missing directory is documented as out of scope and the exit code is the discriminator, matching the previously approved behavior. No findings. Verdict: ready to merge |
Pull Request
Linked Issue
Fixes #358
PR Type
type:featureFeaturetype:bugBug fixtype:docsDocumentationtype:refactorRefactoringtype:choreMaintenancetype:breaking-changeBreaking changeSummary
uninstall --target-diragainst a directory that does not exist reportednot_installedwith exit 0, while the same command against an existing empty directory exits 3. #342 requires both to fail closed. A missing directory now returns the same refusal as an existing directory with no Cortex ownership records.Changes
internal/cli/doctor.go: the missing-root branch ofrunDirectoryUninstallreturnsexitConflict(3) instead ofexitOK.internal/cli/directory_lifecycle_test.go: tests for a missing root (new behavior) and an existing empty directory (existing behavior pinned).docs/operating.md: documents exit 3 for a missing or never-installed--target-dirand exit 0 for the grouped uninstall.Focused Tests
go test ./internal/cli -count=1 -run TestUninstallDirectoryTargetbefore the fixexit = 0, want 3runWithDependencies, not the shell binaryok; stdoutruntime=directory uninstall=not_installed remove=0 absent=0 conflict=0, exit 3, empty stderr, target still absentTestUninstallDirectoryTargetFailsClosedWhenNotInstalledinternal/cli/uninstall_test.gogo vet ./...;go test ./... -count=1;python3 -m unittest discover -s testsSide effects:
runDirectoryUninstallhas one caller (uninstall --target-dir). Its shared helpers (uninstallRootExists,writeUninstallResult) are unchanged, so grouped uninstall,updateanddoctorkeep their behavior.Not tested: the real
cortexbinary from a shell.Failed or not done: none.
Warnings: scripts that call
uninstall --target-diron a missing path now get exit 3 instead of 0. This is the behavior #358 requires. The refusal reuses the empty-directory output, which has no separate reason field.Runtime Harness
N/A: CLI exit-code change covered by CLI tests; no runtime projection change.
Rollback
Revert the single commit.
Chain Dependencies / Out of Scope
Checklist
status:approved.type:*label is applied.