Skip to content

feat(sp-bundle-logs): one-shot diagnostic capture for support handoffs#580

Merged
ng merged 2 commits into
devfrom
feat/sp-bundle-logs
May 14, 2026
Merged

feat(sp-bundle-logs): one-shot diagnostic capture for support handoffs#580
ng merged 2 commits into
devfrom
feat/sp-bundle-logs

Conversation

@ng

@ng ng commented May 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #575. Adds scripts/bin/sp-bundle-logs, a single command that produces /tmp/sleepypod-bundle-<ts>.tar.gz containing everything support typically asks for: service journals (boot-scoped), systemctl status for every sleepypod unit, pod capabilities, network state (iptables-save, ip route, resolv.conf, nsswitch.conf, /etc/hosts), host state (uptime, free, df), tool versions, git HEAD, install log, and .env / homekit summaries.

  • Default redaction masks .env values for any key matching (TOKEN|SECRET|PASSWORD|PASSWD|KEY|CREDENTIAL|API) and replaces the homekit dir with a presence/count summary — bundle is safe to drop in Discord/GitHub.
  • --no-redact includes raw .env + raw homekit files for self-debugging.
  • Every capture wraps its command so a missing tool (e.g. Pod 3 without pnpm pre-install, no iptables-save) doesn't abort the bundle — each file ends with (exit: N) so failed captures are obvious.
  • Picked up automatically by the install/sp-update sp-* glob loops; no separate wiring needed.

Test plan

  • bash -n scripts/bin/sp-bundle-logs — syntax clean
  • sp-bundle-logs --help prints the header comment
  • sp-bundle-logs --bogus exits 2 with usage
  • Dry run on darwin produces a valid tarball with the expected layout (journals/, status/, network/, host/, versions/, data/, config/) — failing captures degrade gracefully
  • .env redaction verified against synthetic file: EXPORT_TOKEN, API_KEY, SUPABASE_SECRET all masked; DATABASE_URL, DAC_SOCK_PATH, NODE_ENV, PNPM_HOME preserved
  • Manual on a real pod: run sudo sp-bundle-logs, scp the tarball off, eyeball that journals/status/iptables-save have real content

Summary by CodeRabbit

  • New Features

    • Added sp-bundle-logs diagnostic command that bundles logs and system state into a timestamped archive for support assistance, with optional --no-redact flag to preserve raw configuration data.
  • Documentation

    • Updated installation guide and CLI command reference to document the new diagnostic bundle feature.

Review Change Stack

🛏️ Beam this PR onto a sleepypod

🚀 Latest build of feat/sp-bundle-logs — rebuilds every push, zero auth:

curl -fsSL https://raw.githubusercontent.com/sleepypod/core/feat/sp-bundle-logs/scripts/install \
  | sudo bash -s -- --branch feat/sp-bundle-logs

🎯 Pin to this exact build (run 25842085283 · 1fb24b5):

curl -fsSL https://raw.githubusercontent.com/sleepypod/core/1fb24b5ed9a29da1b417e034545a9909bb121989/scripts/install \
  | sudo bash -s -- \
      --branch feat/sp-bundle-logs \
      --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/25842085283/sleepypod-core.zip'

🧊 Artifact: sleepypod-core · self-destructs in 30 days 💥

Closes #575. Support sessions lose minutes per pod assembling journals,
systemctl status, network state, and version info by hand. This script
produces a single /tmp/sleepypod-bundle-<ts>.tar.gz the user can scp off
in one step. Redacts .env credential-suffixed keys and HomeKit pairing
material by default so the bundle is safe to drop in Discord/GH;
--no-redact is available for self-debugging.

Picked up automatically by the install/sp-update sp-* glob loops.
@coderabbitai

coderabbitai Bot commented May 14, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds sp-bundle-logs, a one-shot Bash diagnostic tool that collects systemd service logs, network state, version info, and pod capabilities into a timestamped tar.gz bundle with credential redaction enabled by default and optional --no-redact flag. Updates installation README and completion banner to document the new CLI command.

Changes

Diagnostic Bundle Capture

Layer / File(s) Summary
Script setup and initialization
scripts/bin/sp-bundle-logs
Command-line argument parsing for --no-redact, strict Bash mode, timestamped temp staging directory setup, exit trap cleanup, and a reusable capture() helper that records command output and exit status to per-item files.
Service logs, capabilities, and system state capture
scripts/bin/sp-bundle-logs
Captures boot-scoped journalctl logs and systemctl status for predefined systemd services, conditionally runs pod capability detection scripts, collects network state (iptables-save, routing, addresses, DNS), captures version info for node/pnpm/uv and git metadata, directory listings, and install logs.
Credential redaction and tarball creation
scripts/bin/sp-bundle-logs
Implements --no-redact toggled masking of credential-like env var keys and HomeKit identity files using awk pattern matching and summary substitution; packages staged files into /tmp/sleepypod-bundle-<ts>.tar.gz, reports bundle size/redaction status, and outputs an scp command template for off-pod retrieval.
Installation documentation and CLI visibility
scripts/README.md, scripts/install
Documents sp-bundle-logs in the CLI commands list with redaction behavior and flag details, updates script structure tree, and adds the tool to the post-install completion banner alongside existing sp-* CLI commands.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • sleepypod/core#115: Defines the installer's post-install CLI command shortcuts and documentation structure that this PR extends with the new sp-bundle-logs diagnostic tool.

Suggested labels

released

Poem

🐰 Logs bundled tight in tarballs bright,
Secrets masked from prying sight,
One command gathers all the state,
No more waiting, share with haste!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding sp-bundle-logs, a new diagnostic capture tool for support handoffs.
Linked Issues check ✅ Passed All core coding requirements from #575 are met: script creates timestamped tarball with service journals, systemctl status, install log, persistent data listing, capability reports, network/host state, version info, and git metadata; installed to /usr/local/bin; referenced in install/help; output path printed; secrets redacted by default with --no-redact option.
Out of Scope Changes check ✅ Passed All changes are in scope: sp-bundle-logs implementation, README documentation update, and install script CLI commands banner update all directly support the new diagnostic tool feature.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/sp-bundle-logs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented May 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/bin/sp-bundle-logs`:
- Around line 177-178: The tar invocation currently silences failures so the
script can still report success; after running tar -czf "$OUT" -C "$STAGE" .
capture its exit status (or check that "$OUT" exists and is a non-empty valid
archive) and if tar failed, log an error and exit non‑zero instead of continuing
to compute SIZE and printing "Bundle written"; update the section around the tar
command and the SIZE=$(du -h "$OUT" | ...) usage to gate the success message on
the tar success (use the OUT and STAGE variables and the tar invocation as the
referenced symbols).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 098635f8-f0ed-427c-a910-80d8174fb879

📥 Commits

Reviewing files that changed from the base of the PR and between 2a94725 and 27feeb9.

📒 Files selected for processing (3)
  • scripts/README.md
  • scripts/bin/sp-bundle-logs
  • scripts/install

Comment thread scripts/bin/sp-bundle-logs Outdated
CodeRabbit (#580): swallowing tar's exit status meant a missing or
corrupt archive could still print 'Bundle written'.
@ng ng merged commit 0610fb2 into dev May 14, 2026
7 checks passed
@ng ng deleted the feat/sp-bundle-logs branch May 14, 2026 05:32
ng added a commit that referenced this pull request May 14, 2026
…ning (#582)

## Summary

32 commits since v2.0.1 (#554). Highlights:

**Features**
- Alarms UI: create / edit / test scheduled alarms (#556)
- `sp-bundle-logs`: one-shot redacted diagnostic capture for support
handoffs (#580)

**Install hardening**
- Install sp-* CLI tools *before* starting the service so ExecStartPre
can find sp-maintenance (#547)
- Fetch CI artifacts via nightly.link; auto-inject install commands into
PR body (#577)
- Guard against Volta + symlink leftovers in `/usr/local/bin/`; remove
the now-stale free-sleep toggle path (`20bfc4d`)
- `sp-update` now runs the biometrics-archiver install on OTA upgrades,
fixing a regression where pods past v2.0.0 silently stopped populating
biometrics (#579)

**HomeKit stability**
- Rotate `AccessoryPairingID` on unpair so iOS isn't stranded (#566)
- Post-PR-566 follow-ups: orphan cleanup, wipe-stability docs,
transitioning flag (#571)
- Auto-rotate stranded identities + switch mDNS default to `ciao` (#578)

**Hardware**
- Classify real Pod 5 sensor labels as Pod 5, not Pod 3 (#550)

**Tests / CI**
- Coverage lift to 95% / 87% / 93% / 96% across the JS suite (#548#553,
#557#565, #569)
- Kill ~95 surviving Stryker mutants in sleep-stages (#570)
- Codecov pytest workflow + flag-scoped reports (#544)
- Mutation testing improvements (#541, #546)

## Test plan

- [x] All CI gates green on dev (build, lint, typecheck, unit, codecov,
coderabbit)
- [x] sp-bundle-logs validated end-to-end on Pod 5 (192.168.1.88) via
sp-update + bundle inspection
- [x] HomeKit stranded-identity rotation tested in #578
- [ ] Smoke-deploy to a fleet pod after merge; verify alarms UI,
sp-update OTA, biometrics still ingest

<!-- sleepypod:install-start -->
<!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block.
     Hello fellow agent / curious human! Anything between the
     sleepypod:install-start and sleepypod:install-end markers
     gets overwritten on the next CI run. Want to change what's
     here? Edit .github/workflows/build.yml instead. 💤 -->
<details open>
<summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary>

🚀 **Latest build of `dev`** — rebuilds every push, zero auth:
```bash
curl -fsSL https://raw.githubusercontent.com/sleepypod/core/dev/scripts/install \
  | sudo bash -s -- --branch dev
```

🎯 **Pin to this exact build** ([run
25843800709](https://github.com/sleepypod/core/actions/runs/25843800709)
· `8e27c3f`):
```bash
curl -fsSL https://raw.githubusercontent.com/sleepypod/core/8e27c3f63905f60cdfbfcc92d597d768628cfd54/scripts/install \
  | sudo bash -s -- \
      --branch dev \
      --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/25843800709/sleepypod-core.zip'
```

🧊 Artifact:
[`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/25843800709/artifacts/6987899043)
· self-destructs in 30 days 💥
</details>

<!-- sleepypod:install-end -->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 2.2.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add sp-bundle-logs helper for one-shot diagnostic capture

1 participant