|
| 1 | +# Support Bundles |
| 2 | + |
| 3 | +**Support Bundles** provide a mechanism for extracting information about a |
| 4 | +running Oxide system, and giving operators control over the exfiltration of that |
| 5 | +data. |
| 6 | + |
| 7 | +This README is intended for developers trying to add data to the bundle. |
| 8 | + |
| 9 | +## Step Execution Framework |
| 10 | + |
| 11 | +Support Bundles are collected using **steps**, which are named functions acting |
| 12 | +on the `BundleCollection` that can: |
| 13 | + |
| 14 | +* Read from the database, or query arbitrary services |
| 15 | +* Emit data to the output zipfile |
| 16 | +* Produce additional follow-up **steps**, if necessary |
| 17 | + |
| 18 | +If you're interested in adding data to a support bundle, you will probably be |
| 19 | +adding data to an existing **step**, or creating a new one. |
| 20 | + |
| 21 | +The set of all initial steps is defined in |
| 22 | +`nexus/src/app/background/tasks/support_bundle/steps/mod.rs`, within a function |
| 23 | +called `all()`. Some of these steps may themselves spawn additional steps, |
| 24 | +such as `STEP_SPAWN_SLEDS`, which spawns a per-sled step to query the sled |
| 25 | +host OS itself. |
| 26 | + |
| 27 | +### Tracing |
| 28 | + |
| 29 | +**Steps** are automatically instrumented, and their durations are emitted to an |
| 30 | +output file in the bundle named `meta/trace.json`. These traces are in a format |
| 31 | +which can be understood by **Perfetto**, a trace-viewer, and which provides |
| 32 | +a browser-based interface at <https://ui.perfetto.dev/>. |
| 33 | + |
| 34 | +## Filtering Bundle Contents |
| 35 | + |
| 36 | +Support Bundles are collected by the `support_bundle_collector` |
| 37 | +background task. They are collected as zipfiles within a single Nexus instance, |
| 38 | +which are then transferred to durable storage. |
| 39 | + |
| 40 | +The contents of a bundle may be controlled by modifying the **BundleRequest** |
| 41 | +structure. This request provides filters for controlling the categories of |
| 42 | +data which are collected (e.g., "Host OS info") as well as arguments for |
| 43 | +more specific constraints (e.g., "Collect info from a specific Sled"). |
| 44 | + |
| 45 | +Bundle **steps** may query the `BundleRequest` to identify whether or not their |
| 46 | +contents should be included. |
| 47 | + |
| 48 | +## Overview for adding new data |
| 49 | + |
| 50 | +* **Determine if your data should exist in a new step**. The existing set of |
| 51 | + steps exists in `support_bundle/steps`. Adding a new step provides a new unit |
| 52 | + of execution (it can be executed concurrently with other steps), and a unit of |
| 53 | + tracing (it will be instrumented independently of other steps). |
| 54 | +* If you're adding a new step... |
| 55 | +** **Add it as a new module**, within `support_bundle/steps`. |
| 56 | +** **Ensure it's part of `steps::all()`, or spawned by an existing step**. This |
| 57 | + will be necessary for your step to be executed. |
| 58 | +** **Provide a way for bundles to opt-out of collecting this data**. Check the |
| 59 | + `BundleRequest` to see if your data exists in one of the current filters, or |
| 60 | + consider adding a new one if your step involves a new category of data. Either |
| 61 | + way, your new step should read `BundleRequest` to decide if it should trigger |
| 62 | + before performing any subsequent operations. |
| 63 | +* **Consider Caching**. If your new data requires performing any potentially |
| 64 | + expensive operations which might be shared with other steps (e.g., reading |
| 65 | + from the database, creating and using progenitor clients, etc) consider adding |
| 66 | + that data to `support_bundle/cache`. |
0 commit comments