support-bundle

Reference for linuxguard-agent support-bundle — collect a redacted diagnostic archive locally or upload an existing bundle via a presigned S3 URL.

Synopsis

Collect a redacted diagnostic bundle from the host and (optionally) upload it to LinuxGuard for analysis by support staff. The command has two subcommands: collect (assemble a tar+zstd archive locally) and upload (send a previously-collected archive via a presigned S3 URL). Bundles include the current agent.log, rotated log segments, a system metadata file, a redacted copy of the agent config, and a BUNDLE-MANIFEST.json describing the archive.

linuxguard-agent support-bundle <subcommand> [args]

Important: agent.log is shipped in the bundle with attribute-key regex redaction only — values associated with attribute keys matching ^(api_key|enroll_token|.*_token|.*_secret)$ are masked, but other sensitive content (hostnames, IPs, usernames, file paths, command arguments) is not. Review bundles before sharing with parties outside your organisation.

Subcommands

Subcommand
Synopsis
Purpose

collect

linuxguard-agent support-bundle collect [--out <path>]

Assemble a .tar.zst bundle on the local filesystem. Prints the bundle path to stdout; emits sha256=... and size=... lines to stderr.

upload

linuxguard-agent support-bundle upload <bundle-file>

Upload an existing bundle to LinuxGuard via a three-step presigned-URL flow. Requires an enrolled agent (the API key carries the tenant scope).

Flags

collect is the only subcommand with a flag; upload takes a single positional argument (<bundle-file>).

collect flags

Flag
Type
Default
Description

--out <path>

string

/var/lib/linuxguard/support/<unix_timestamp>.tar.zst

Override the output path. The parent directory is created with mode 0750 if absent. The output file is opened with O_EXCL — a pre-existing file at the path causes the command to fail (symlink-attack mitigation).

upload arguments

Argument
Required
Description

<bundle-file>

yes

Path to a .tar.zst bundle produced by collect. The file's SHA-256 is computed on disk and included in the register call; the size is compared against the manifest.

Environment

support-bundle reads no LINUXGUARD_* environment variables. collect consults only the agent's persisted local config (for the log path and tenant identity); upload uses the API client built from the persisted enrolment (base_url, api_key) so the agent must already be enrolled.

upload performs three network calls: POST /v1/support/bundle/upload-url (returns a presigned S3 URL + object key + expiry), PUT <signedURL> (uploads the bundle bytes without an Authorization header — required for AWS Signature V4 verification), and POST /v1/support/bundle/register (records the upload metadata server-side). The presigned URL has a 15-minute server-enforced TTL.

Signals

support-bundle is a one-shot CLI invocation — neither subcommand installs signal handlers via signal.Notify. Ctrl-C aborts via Go's default SIGINT handler; in-progress archive writes use O_EXCL so a partially-written bundle does not linger as a stable file at the target path. upload is interruptible at the network layer via the standard library's HTTP client cancellation; partial uploads are discarded server-side when the presigned URL expires.

Exit codes

Code
Meaning

0

Successful operation. collect printed the bundle path; upload printed bundle_id, object_key, and uploaded_at.

1

General error — surfaced via log.Fatal after app.Run returns a non-nil error. Includes: pre-existing file at the --out path (O_EXCL rejection), output directory creation failure, missing or unreadable bundle file, SHA-256 / size mismatch between the file and the manifest, presign request failure, presigned PUT failure, register-call failure, or unrecoverable redaction error.

143

SIGTERM during a long-running upload — orchestrator-driven shutdown. Re-raised from main per the convention documented for start.

130

SIGINT (Ctrl-C) during a long-running upload. Re-raised from main.

Examples

Collect a bundle at the default path

Stdout:

Stderr:

The stdout path is the only token consumed by shell pipelines (bundle=$(sudo linuxguard-agent support-bundle collect)); diagnostic output is on stderr so it does not pollute the pipeline.

Collect to a specific path

Use a non-default path when collecting during incident response so the bundle does not collide with timestamped bundles in /var/lib/linuxguard/support/. The output directory is created if it does not exist.

Inspect the bundle contents before sharing

The bundle is a standard tar+zstd archive. Contents:

File
Description

agent.log

The current agent log file. Attribute-key regex redaction only — review before sharing externally.

<logBase>.<N>.gz

Rotated log segments included newest-first within the 180 MB pre-compress cap. Segments that exceed the cap are listed in BUNDLE-MANIFEST.json under trimmed_segments and not included.

system.json

Kernel version, distro identity, eBPF probe status, recent error count, and agent version.

config.redacted.json

The agent's runtime config with identity + credential fields removed.

BUNDLE-MANIFEST.json

Bundle version, agent version, generation timestamp, trigger (cli / console_push), contents list, trimmed-segment list, and redaction summary.

Pre-compress size cap

The bundle assembles rotated log segments newest-first, accumulating against a 180 MB pre-compression cap (MaxPreCompressBytes: 180 * 1024 * 1024 in the agent runtime). The current agent.log size counts toward the cap. Segments that would push the total above 180 MB are listed in BUNDLE-MANIFEST.json under trimmed_segments and NOT included in the archive. The cap is hard-coded — operators who need a larger bundle should collect logs out-of-band (e.g., journalctl).

Upload a previously-collected bundle

Expected stdout:

The local file is NEVER deleted by upload. After a successful upload, decide whether to retain or remove the bundle per your retention policy.

Collect-and-upload in one shell pipeline

collect prints the bundle path on stdout (one line); upload reads the path as a positional argument. The trailing rm is operator discretion — upload does not auto-delete.

Failure mode: pre-existing file at --out path

The O_EXCL open semantics prevent overwriting a previous bundle (and reject symlink swaps at the target path). Move or remove the prior bundle before re-running collect to the same path.


Related: start | config | signals | CLI Reference

Last updated

Was this helpful?