Skip to content

Commit 51d272b

Browse files
merge main
2 parents 811ffbe + f7a9801 commit 51d272b

660 files changed

Lines changed: 744502 additions & 23569 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
name: add-api-version
3+
description: Add a new version to a Dropshot HTTP API. Use when the user wants to make versioned changes to a Dropshot-managed HTTP API, such as adding, making changes to, or removing an API endpoint.
4+
---
5+
6+
# Add API version
7+
8+
Add a new version to a Dropshot API in this repository.
9+
10+
## Instructions
11+
12+
Follow these steps in order. Do not skip ahead.
13+
14+
### Step 1: Fetch the guide
15+
16+
Fetch the guide from the dropshot-api-manager repository:
17+
18+
```bash
19+
curl -fsSL https://raw.githubusercontent.com/oxidecomputer/dropshot-api-manager/refs/heads/main/guides/new-version.md
20+
```
21+
22+
**Do not summarize the guide.** Read and follow it exactly as written. Remember to fetch RFD 619 for context.
23+
24+
### Step 2: Ascertain the scope of the request
25+
26+
If not already provided, ask the user:
27+
28+
* Which API they would like to change.
29+
* What changes to make.
30+
31+
### Step 3: Make the change
32+
33+
Follow the guide carefully and systematically to add a new version to the provided API which makes the given changes.
34+
35+
Follow the guide step by step; do not skip any steps.
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# API Docstring Style Guide
2+
3+
This guide covers public docstrings (`///`) on endpoint handlers in
4+
`nexus/external-api/src/lib.rs` and on structs, fields, and enums in
5+
`nexus/types/src/external_api/`. These docstrings become user-facing API
6+
documentation.
7+
8+
## Capitalization
9+
10+
Start all docstrings with a capital letter.
11+
12+
```rust
13+
// Bad
14+
/// the source of an identity provider metadata descriptor
15+
pub idp_metadata_source: IdpMetadataSource,
16+
17+
// Good
18+
/// The source of an identity provider metadata descriptor.
19+
pub idp_metadata_source: IdpMetadataSource,
20+
```
21+
22+
## Punctuation
23+
24+
Short, label-like descriptions do not need periods. This includes endpoint
25+
summary lines, struct-level descriptions, and brief field annotations. Longer
26+
explanatory text (especially multi-clause or multi-sentence docstrings) should
27+
end sentences with periods.
28+
29+
```rust
30+
// Endpoint summary lines: no period
31+
/// Fetch silo
32+
/// List identity providers for silo
33+
/// Create IP pool
34+
35+
// Struct-level descriptions: no period
36+
/// View of a Silo
37+
/// A collection of resource counts used to describe capacity and utilization
38+
39+
// Short field descriptions: no period
40+
/// Number of virtual CPUs
41+
/// Common identifying metadata
42+
/// Size of blocks in bytes
43+
44+
// Longer explanatory text: use periods
45+
/// Accounts for resources allocated to running instances or storage
46+
/// allocated via disks or snapshots.
47+
///
48+
/// Note that CPU and memory resources associated with stopped instances
49+
/// are not counted here, whereas associated disks will still be counted.
50+
```
51+
52+
## Articles
53+
54+
Omit articles ("a", "an", "the") in endpoint summary lines. Look at existing
55+
endpoints in `nexus/external-api/src/lib.rs` for reference. A few examples of
56+
the different shapes:
57+
58+
```rust
59+
// Bad
60+
/// Fetch a silo
61+
/// Create an IP pool
62+
/// Delete the project
63+
/// List the silos
64+
65+
// Good
66+
/// Fetch silo
67+
/// Create IP pool
68+
/// Delete project
69+
/// List silos
70+
/// Fetch resource utilization for user's current silo
71+
/// List identity providers for silo
72+
/// Add range to IP pool
73+
```
74+
75+
## Paragraph Separation
76+
77+
Separate distinct thoughts or notes with a blank `///` line. This produces
78+
proper paragraph breaks in rendered documentation.
79+
80+
```rust
81+
// Bad - renders as one run-on paragraph
82+
/// A unique, immutable, system-controlled identifier for the token.
83+
/// Note that this ID is not the bearer token itself, which starts with
84+
/// "oxide-token-".
85+
pub id: Uuid,
86+
87+
// Good - renders as two paragraphs
88+
/// A unique, immutable, system-controlled identifier for the token.
89+
///
90+
/// Note that this ID is not the bearer token itself, which starts with
91+
/// "oxide-token-".
92+
pub id: Uuid,
93+
```
94+
95+
## Acronyms and Abbreviations
96+
97+
Use standard casing for acronyms:
98+
- "IdP" (Identity Provider)
99+
- "SP" (Service Provider)
100+
- "SAML", "ID", "IP", "VPC", "CPU", "RAM", "DER"
101+
102+
## Doc Comments vs Regular Comments
103+
104+
Use `///` for public API documentation that users will see. Use `//` for
105+
internal implementation notes that should not appear in generated docs.
106+
107+
```rust
108+
// Bad - this won't appear in API docs
109+
// A list containing the IDs of the secret keys.
110+
pub secrets: Vec<WebhookSecret>,
111+
112+
// Good - this will appear in API docs
113+
/// A list containing the IDs of the secret keys.
114+
pub secrets: Vec<WebhookSecret>,
115+
```
116+
117+
## Scope
118+
119+
These rules apply to:
120+
- Endpoint handler docstrings (`/// Fetch silo`)
121+
- Public struct docstrings (`/// View of a Silo`)
122+
- Public field docstrings (`/// The IP address held by this resource.`)
123+
- Public enum variant docstrings (`/// The sled is currently active.`)
124+
125+
These rules do NOT apply to:
126+
- Private functions or structs
127+
- Internal comments (`//`)
128+
- Module-level documentation (`//!`)
129+
130+
## General
131+
132+
Follow standard English grammatical rules: correct articles ("a" vs "an"),
133+
subject-verb agreement, proper spelling, etc.
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
---
2+
name: crdb-change
3+
description: Generate CockroachDB SQL and migrations for schema changes. Use when creating migrations, updating the database schema, or when the user mentions migrations, schema changes, or dbinit.sql.
4+
---
5+
6+
# CockroachDB database changes
7+
8+
Generate database changes for this repository. This includes changes to:
9+
10+
- `schema/crdb/dbinit.sql`
11+
- Migrations for changes
12+
13+
## Instructions
14+
15+
Follow these steps in order. Do not skip ahead.
16+
17+
### Step 1: Ascertain the scope of the request
18+
19+
If not already provided, prompt the user whether they'd like to:
20+
21+
- **Perform both a dbinit.sql change and a migration**: If this is the case, then:
22+
1. Ask the user to describe the changes they'd like to perform to `dbinit.sql`.
23+
2. Make those changes, asking the user followup questions as necessary.
24+
3. Go directly to step 3, with the scope of the migration being to cover those changes.
25+
- **Write migrations for pre-existing changes**: In this case, changes need to be fetched from version control. Go to step 2.
26+
27+
### Step 2: Get the diff
28+
29+
Check if `.jj` exists in the repository to determine whether to use jj or git commands.
30+
31+
Prompt the user to ask where the schema changes are:
32+
33+
- **Uncommitted changes**: Changes not yet committed.
34+
- git: `git diff -- schema/crdb/dbinit.sql` (unstaged) or `git diff --cached -- schema/crdb/dbinit.sql` (staged)
35+
- jj: `jj diff -- schema/crdb/dbinit.sql`
36+
37+
- **This commit only** (stacked diff workflow): Changes are in the current commit only.
38+
- git: `git diff HEAD^ -- schema/crdb/dbinit.sql`
39+
- jj: `jj diff --from @-- -- schema/crdb/dbinit.sql`
40+
41+
- **This branch** (feature branch workflow): Changes span the entire branch.
42+
- git: `git diff $(git merge-base HEAD main) -- schema/crdb/dbinit.sql`
43+
- jj: `jj diff --from 'fork_point(trunk() | @)' -- schema/crdb/dbinit.sql`
44+
45+
If the diff doesn't show anything, ask the user which ref to diff from.
46+
47+
### Step 3: Create migration folder
48+
49+
Create a new folder under `schema/crdb/` using the provided name or a short descriptive name derived from the schema changes.
50+
51+
Use existing folder names in `schema/crdb/` as examples for naming conventions.
52+
53+
NOTE: The numbered folders, e.g. 1.0.0, are for legacy support only. No additional numbered directories should be added.
54+
55+
### Step 4: Write migration files
56+
57+
Based on the diff from step 1, write migration files in order:
58+
59+
- Use `up01.sql`, `up02.sql` etc. (zero-padded) if you have more than 10 files.
60+
- Use `up1.sql`, `up2.sql` etc. if you have 10 or fewer files.
61+
- For Data Definition Language (DDL) statements, **one statement per file!**
62+
- For Data Modifying Language (DML) statements, multiple statements are allowed per file.
63+
- For `ALTER TABLE` with multiple columns, you can add them all in one statement.
64+
- When adding `NOT NULL` columns to existing tables, add temporary defaults, then remove them in later migration files.
65+
- Use `IF NOT EXISTS` for idempotency where supported.
66+
- Individual `up.sql` files are executed within a transaction (this always happens), and should be idempotent (this is an expectation that the migration author must uphold, with, e.g. `IF NOT EXISTS`).
67+
68+
### Step 5: Update dbinit.sql version
69+
70+
Bump the version number at the end of `schema/crdb/dbinit.sql`.
71+
72+
### Step 6: Update SCHEMA_VERSION
73+
74+
In `nexus/db-model/src/schema_versions.rs`, bump `SCHEMA_VERSION`.
75+
76+
### Step 7: Add to KNOWN_VERSIONS
77+
78+
In `nexus/db-model/src/schema_versions.rs`, add the new version to the `KNOWN_VERSIONS` list.
79+
80+
### Step 8: Test the migration
81+
82+
Run `cargo nextest run -p omicron-nexus schema` to verify that the migration is correct.
83+
84+
## Common issues
85+
86+
- Don't guess table names—use the diff from step 1 to find the correct table.
87+
- When adding constraints, always use `IF NOT EXISTS` for idempotency.
88+
- For columns with defaults in migration but not in final schema, add the defaults during migration then remove them.
89+
- Don't skip step 1—always run the diff command first to understand what needs to be migrated.
90+
91+
## Data migration tests
92+
93+
When creating a migration that affects existing data (like adding columns to existing tables), also add a data migration test in `nexus/tests/integration_tests/schema.rs`:
94+
95+
- Add `before_X_0_0` function to create test data in the old format.
96+
- Add `after_X_0_0` function to verify the migration worked correctly.
97+
- Add the version to the `get_migration_checks()` map.
98+
99+
This ensures old rows can be migrated smoothly in production.
100+
101+
## Reference
102+
103+
Consult `schema/crdb/README.adoc` for more information.

.config/nextest.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#
44
# The required version should be bumped up if we need new features, performance
55
# improvements or bugfixes that are present in newer versions of nextest.
6-
nextest-version = { required = "0.9.117", recommended = "0.9.118" }
6+
nextest-version = { required = "0.9.117", recommended = "0.9.125" }
77

88
experimental = ["benchmarks", "setup-scripts"]
99

.github/buildomat/build-and-test.sh

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ target_os=$1
1818
# NOTE: This version should be in sync with the recommended version in
1919
# .config/nextest.toml. (Maybe build an automated way to pull the recommended
2020
# version in the future.)
21-
NEXTEST_VERSION='0.9.118'
21+
NEXTEST_VERSION='0.9.125'
2222

2323
cargo --version
2424
rustc --version
@@ -132,9 +132,38 @@ ptime -m cargo build -Z unstable-options --timings=json \
132132
# 2 less (negative 2) than the default. This avoids many test flakes where
133133
# the test would have worked but the system was too overloaded and tests
134134
# take longer than their default timeouts.
135+
136+
# Create a user config file that enables test recording.
137+
RECORDING_CONFIG_DIR="/tmp/nextest-recording-config"
138+
RECORDING_CONFIG="$RECORDING_CONFIG_DIR/config.toml"
139+
NEXTEST_STATE_DIR="$(mktemp -d /tmp/nextest-state.XXXXXX)"
140+
ARCHIVE_PATH="/tmp/nextest-run-archive.zip"
141+
142+
mkdir -p "$RECORDING_CONFIG_DIR"
143+
printf '[experimental]\nrecord = true\n\n[record]\nenabled = true\n' \
144+
> "$RECORDING_CONFIG"
145+
146+
export NEXTEST_STATE_DIR
147+
135148
banner test
149+
150+
# Export an archive even on test failure.
151+
NEXTEST_EXIT=0
136152
ptime -m timeout 2h cargo nextest run --profile ci --locked \
137-
--test-threads -2
153+
--test-threads -2 \
154+
--user-config-file "$RECORDING_CONFIG" \
155+
|| NEXTEST_EXIT=$?
156+
157+
if ! ptime -m cargo nextest store export latest \
158+
--user-config-file "$RECORDING_CONFIG" \
159+
--archive-file "$ARCHIVE_PATH"; then
160+
echo "warning: failed to export recording archive" >&2
161+
fi
162+
163+
if [[ "$NEXTEST_EXIT" -ne 0 ]]; then
164+
echo "error: cargo nextest run failed with exit code $NEXTEST_EXIT" >&2
165+
exit "$NEXTEST_EXIT"
166+
fi
138167

139168
#
140169
# https://github.com/nextest-rs/nextest/issues/16

.github/buildomat/jobs/build-and-test-helios.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#: "%/work/*",
99
#: "%/work/oxidecomputer/omicron/target/nextest/ci/junit.xml",
1010
#: "%/work/oxidecomputer/omicron/target/live-tests-archive.tgz",
11+
#: "=/tmp/nextest-run-archive.zip",
1112
#: "%/var/tmp/omicron_tmp/**/*",
1213
#: "!/var/tmp/omicron_tmp/crdb-base*",
1314
#: "!/var/tmp/omicron_tmp/rustc*",
@@ -35,5 +36,10 @@
3536
#: series = "live-tests"
3637
#: name = "live-tests-archive.tgz"
3738
#: from_output = "/work/oxidecomputer/omicron/target/live-tests-archive.tgz"
39+
#:
40+
#: [[publish]]
41+
#: series = "nextest-recording-helios"
42+
#: name = "nextest-run-archive.zip"
43+
#: from_output = "/tmp/nextest-run-archive.zip"
3844

3945
exec .github/buildomat/build-and-test.sh illumos

.github/buildomat/jobs/build-and-test-linux.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#: output_rules = [
88
#: "%/work/*",
99
#: "%/work/oxidecomputer/omicron/target/nextest/ci/junit.xml",
10+
#: "=/tmp/nextest-run-archive.zip",
1011
#: "%/var/tmp/omicron_tmp/**/*",
1112
#: "!/var/tmp/omicron_tmp/crdb-base*",
1213
#: "!/var/tmp/omicron_tmp/rustc*",
@@ -29,6 +30,11 @@
2930
#: series = "build-info-linux"
3031
#: name = "crate-build-timings.json"
3132
#: from_output = "/work/crate-build-timings.json"
33+
#:
34+
#: [[publish]]
35+
#: series = "nextest-recording-linux"
36+
#: name = "nextest-run-archive.zip"
37+
#: from_output = "/tmp/nextest-run-archive.zip"
3238

3339

3440
sudo apt-get install -y jq

.github/buildomat/jobs/deploy.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#:
33
#: name = "helios / deploy"
44
#: variety = "basic"
5-
#: target = "lab-2.0-opte-0.37"
5+
#: target = "lab-2.0-opte-0.39"
66
#: output_rules = [
77
#: "%/var/svc/log/oxide-*.log*",
88
#: "%/zone/oxz_*/root/var/svc/log/oxide-*.log*",
@@ -359,10 +359,10 @@ OMICRON_NO_UNINSTALL=1 \
359359

360360
# Wait for switch zone to come up
361361
retry=0
362-
until curl --head --silent -o /dev/null "http://[fd00:1122:3344:101::2]:12224/"
362+
until curl --max-time 1 --head --silent --show-error -o /dev/null "http://[fd00:1122:3344:101::2]:12224/"
363363
do
364364
if [[ $retry -gt 30 ]]; then
365-
echo "Failed to reach switch zone after 30 seconds"
365+
echo "Failed to reach switch zone after 30 attempts"
366366
exit 1
367367
fi
368368
sleep 1

0 commit comments

Comments
 (0)