Skip to content

feat(clean): Remove OS state by default - #76

Open
aaljewarane wants to merge 2 commits into
aws:masterfrom
aaljewarane:clean-os-state
Open

feat(clean): Remove OS state by default#76
aaljewarane wants to merge 2 commits into
aws:masterfrom
aaljewarane:clean-os-state

Conversation

@aaljewarane

Copy link
Copy Markdown

Summary

ec2-macos-init clean now also invokes ec2-macos-utils system cleanup-state by default, with subprocess STDIO passed through to the calling shell. A new -init-state-only flag limits cleanup to init's own state.

This fixes the recurring issue where AMIs built after clean still carried macOS's cached network interface configuration (NetworkInterfaces.plist), delaying or breaking networking on instances launched from those images.

Behavior:

  • OS cleanup always runs (with or without init history), so a cleaned system is always ready for imaging. Absent instance history is treated as nothing to remove instead of a fatal error, and a history removal failure is logged, OS cleanup still runs, and clean exits non-zero so a partially cleaned system is never reported as success.
  • If ec2-macos-utils is missing or fails, clean exits non-zero with a pointer to -init-state-only; a half-cleaned image is the bug being fixed.
  • ec2-macos-utils is resolved from its install path (/usr/local/bin/ec2-macos-utils) first, falling back to PATH, since sudo's default PATH excludes /usr/local/bin for the documented sudo ec2-macos-init clean usage.

Dependency

Requires aws/ec2-macos-utils#41 to merge and release first.

Testing

  • Builds darwin/amd64 + arm64; go vet clean; existing tests pass.
  • Validated on mac1.metal (x86_64, macOS 15.7.7) and mac2.metal (arm64, macOS 26.3.1): removal, idempotence, plist regeneration on reboot, STDIO pass-through, -init-state-only opt-out, non-zero exit when utils is missing, history-failure ordering (OS cleanup still runs, then non-zero exit), install-path-preferred resolution, and PATH fallback.
  • End to end on mac1: clean -> AMI -> instance launched from the derived image booted with healthy networking and a clean first boot.

… now also removes well-known OS state by invoking 'ec2-macos-utils system cleanup-state' as a subprocess, with its output passed through to the calling shell. This removes state such as the macOS cached network interface configuration (NetworkInterfaces.plist) that breaks or delays networking on instances launched from a derived image (AMI). Pass -init-state-only to limit cleanup to ec2-macos-init's own state. Instance history removal no longer aborts the run: absent history is treated as nothing to remove, and a removal failure is logged, OS state cleanup still runs, and clean exits non-zero so a partially cleaned system is never reported as success. ec2-macos-utils is resolved from its install path (/usr/local/bin/ec2-macos-utils) first, falling back to PATH, since sudo's default PATH does not include /usr/local/bin for the documented 'sudo ec2-macos-init clean' usage.
@aaljewarane aaljewarane changed the title feat(clean): Remove cached OS state by default feat(clean): Remove OS state by default Jul 20, 2026
@aaljewarane

Copy link
Copy Markdown
Author

Note: Lint failures are pre-existing on master.

Comment thread clean.go Outdated
…state cleanup is opt-out default behavior, so systems without ec2-macos-utils, or with a version predating 'system cleanup-state', would break existing clean workflows on init update. Differentiate the cases: warn and continue when utils is absent or too old (probed via --help), and fail only when the command exists but errors. The lenient cases may become errors in a future release.
@aaljewarane

aaljewarane commented Jul 23, 2026

Copy link
Copy Markdown
Author

Validation on EC2 Mac hardware

Validated ec2-macos-init clean on:

Family Arch macOS
mac1.metal x86_64 15.7.7
mac2.metal arm64 26.3.1

New init built from this branch (b63e025). "Old utils" is a real build of ec2-macos-utils origin/main (f5848d0, predates system cleanup-state) — confirms the --help probe against genuine cobra behavior, not a mock. Identical results on both families.

Backwards-compat / three-case handling

Case Setup Expected Result
A new utils installed history + plist removed via delegation, STDIO passed through, exit 0 PASS
B old utils (no command) probe → warn + continue, exit 0, plist retained PASS
C no utils installed warn + continue, exit 0, plist retained PASS
D utils present, command errors hard-fail exit 1 (history already removed first) PASS

Original functionality + flag

Case Expected Result
default clean removes current instance history PASS
-init-state-only removes history, skips OS state, plist retained, exit 0 PASS
-all (multiple dirs) removes all instance history, exit 0 PASS
-all, history absent "nothing to remove", exit 0 PASS

Sample (case B, old utils):

Skipping OS state cleanup: installed ec2-macos-utils does not support 'system cleanup-state'
Cached OS state (e.g. NetworkInterfaces.plist) was not removed and may affect instances launched from an image of this system; update ec2-macos-utils to enable this cleanup
Clean complete   # exit 0

Sample (case D, real error):

Removing OS state with ec2-macos-utils
Unable to remove OS state: ec2-macos-utils system cleanup-state failed: exit status 1
Clean incomplete: unable to remove OS state: ...   # exit 1

Note: to avoid reboots, cases after the first real removal used a placeholder at the plist path; the Lstat+remove path is identical, and the first dry-run/removal exercised the genuine boot-generated plist.

Further notes: Escape hatch is still -init-state-only if someone needs to bypass.

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.

4 participants