Skip to content

Filter support bundle log collection by zone type - #11204

Draft
smklein wants to merge 5 commits into
support-bundle-data-selection-apifrom
support-bundle-zone-types
Draft

Filter support bundle log collection by zone type#11204
smklein wants to merge 5 commits into
support-bundle-data-selection-apifrom
support-bundle-zone-types

Conversation

@smklein

@smklein smklein commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #11190.

Support bundle log collection can now be filtered by zone type
(#10372). BundleZoneType names every category of zone a sled can
hold logs for: one variant per Omicron zone-name prefix, plus the
global zone, the switch zone, and instance (propolis) zones. A
bundle's host-info selection carries a ZoneSelection alongside its
sled selection: all zones (the default, preserving today's behavior)
or only zones of specific types.

POST /v1/system/support-bundles
{
  "user_comment": "nexus crash loop on BRM42",
  "data_selection": {
    "data": {
      "type": "explicit",
      "host_info": {
        "zones": { "type": "specific", "types": ["nexus", "cockroachdb"] }
      }
    },
    "start_time": "2026-08-29T00:00:00Z"
  }
}

A few design points worth calling out:

Zone types are derived from zone names, not from ZoneKind. The zone
list comes from on-disk log directories, which outlive the zones
themselves, so the name is the only typing available; and zone names
cannot distinguish boundary from internal NTP zones, so ntp covers
both. A From<ZoneKind> impl plus a coverage test over
ZoneKind::iter() keep the classification exhaustive as zone kinds
are added.

Filtering happens in the collector, after listing a sled's zones and
before requesting their logs, which is where the cost lives: each
download makes the sled-agent take ZFS snapshots and assemble a zip
file. The sled-agent API is untouched.

The selection is persisted as a TEXT[] of the enum's stable strings
on both host-info selection tables (the bundle's and the FM
support-bundle-request twin), mirroring how sled selections are
stored. Existing rows backfill to "all zone types". Reading back an
unrecognized stored string is an error rather than a silent drop.

omdb support-bundle collect and omdb nexus support-bundles create
grow a repeatable --zone-type flag.

Test coverage

The first commit unit-tests the classifier: every zone-name shape,
the prefix-shadowing pairs (crucible/crucible_pantry and the
clickhouse trio), malformed and unknown names, plus the
ZoneKind::iter() coverage test and a test pinning that the serde,
persistence, and FromStr string forms agree. Builder composition
(zone types surviving a later sled selection and vice versa) is
covered as well.

The second commit adds a datastore test round-tripping selections
with specific zone types and with an empty type set through the
bundle tables, extends the FM sitrep round-trip test with a zone-type
selection, and adds a data-migration check verifying pre-existing
host-info rows backfill to "all zone types" and that the new CHECK
constraint rejects inconsistent rows.

The third commit's integration test injects a log for one zone of
each name shape into a simulated sled-agent and inspects the
collected archive: no selection collects every zone (including one
with an unclassifiable name), a type subset collects exactly its
matches, and an empty type set collects no zone logs at all.

The fourth commit extends the explicit-selection API round-trip test
with a zone-type selection, which also pins that the view reports the
set in canonical order, and the existing proptest now round-trips
arbitrary zone selections through the API type.

The fifth commit is covered by the omdb usage tests; the flag error
path (naming zone types while excluding host-info) is exercised by
the shared selection-building code.

BundleZoneType names every category of zone a sled can hold logs
for, distinguishable from a zone name alone: one variant per Omicron
zone-name prefix, plus the global zone, the switch zone, and instance
(propolis) zones. Both NTP zone kinds share a variant because their
zone names do not distinguish them. classify() maps a zone name (or
zone log directory name) to its type; a From<ZoneKind> impl and a
coverage test keep the mapping exhaustive as zone kinds are added.

ZoneSelection bounds host-info zone-log collection the way
SledSelection bounds the sleds queried: BundleData::HostInfo now
carries both. Nothing sets a non-default selection yet; persistence,
collection, API, and omdb support follow.
The host-info selection tables (the bundle's, and its FM
support-bundle-request twin) grow an all_zone_types flag and a
zone_types TEXT[] holding BundleZoneType's stable strings, mirroring
how the sled selection is stored. Existing rows backfill to all zone
types, the selection every bundle collected before zone-type
filtering existed; a CHECK enforces the same mutual exclusion the
sled columns have. Reading back an unrecognized stored string is an
error rather than a silent drop from the selection.
The collector drops zones the bundle's zone-type selection excludes
after listing a sled's zones and before requesting their logs, which
is where the cost lives: each download makes the sled-agent take ZFS
snapshots and assemble a zip file. Only Nexus needs to change; the
sled-agent API is untouched.

The integration test injects a log for one zone of each name shape
(Omicron zones, the global zone, an instance zone, and an
unclassifiable name) and checks the collected archive: no selection
collects everything, a type subset collects exactly its matches, and
an empty type set collects no zone logs at all.
External API version SUPPORT_BUNDLE_ZONE_TYPES gives
SupportBundleHostInfo a zones field: all zones (the default, and the
meaning of an omitted field), or only zones of specific types. The
view endpoint reports the selection back; the type list is treated
as a set, so the view reports it in a canonical order. Requests from
the prior version convert with the all-zones selection, matching
their behavior before the field existed.

The end-to-end test round-trips a specific zone-type selection
through creation and the view endpoint alongside the other
per-category settings.
Both `omdb support-bundle collect` and `omdb nexus support-bundles
create` accept a repeatable --zone-type restricting zone-log
collection to zones of those types. Omitting the flag collects from
every zone. Since the flag only affects zone logs, supplying it while
--include excludes host-info is an error rather than a silent no-op;
with no --include at all it applies on top of the every-category
default.
@smklein
smklein marked this pull request as draft August 31, 2026 21:06
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.

1 participant