I tried to do a Nexus-driven update from 8571be3 (a commit on main) to 544f608 (the next commit on main), and the request to set the target system version was rejected with
Error Response: status: 400 Bad Request; headers: {"content-type": "application/json", "x-request-id": "68a82eaa-0b69-4da0-a9f0-e5eb67d2552a", "content-length": "240", "date": "Wed, 24 Sep 2025 14:55:29 GMT"}; value: Error { error_code: None, message: "The requested target system release (16.0.0-0.ci+git544f608e05a) is older than the current target system release (16.0.0-0.ci+git8571be38c0b). This is not supported.", request_id: "68a82eaa-0b69-4da0-a9f0-e5eb67d2552a" }
The source of this is where we do a comparison between two semver::Versions:
|
if version > system_version { |
|
return Err(HttpError::for_bad_request( |
|
None, |
|
format!( |
|
"The requested target system release ({system_version}) \ |
|
is older than the current target system release ({version}). \ |
|
This is not supported." |
|
), |
|
)); |
|
} |
Because these versions match in their major/minor/patch, we're falling back to comparing the BuildMetadata, which is ordered lexicographically:
However for comparing build metadatas among one another, they do have a total order which is determined by lexicographic ordering of dot-separated components. Identifiers consisting of only digits are compared numerically. Otherwise, identifiers are compared in ASCII sort order. Any numeric identifier is always less than any non-numeric identifier.
We discussed a bunch of options for unblocking testing:
- Relax this check to ignore the build metadata
- Add a flag to the external API to override the version check in some way (e.g., "override: ignore build metadata")
- Add an internal API to set the target release version, and give it an override flag
We're going to go with option 1; it's not any less safe than what we have today (where you can upgrade from commit to commit if the build metadata sometimes) and is very easy to implement.
At the update watercooler, we also discussed ways to make this more closely match requirements we'd actually like to enforce, such as upgrading from a commit on main to a newer commit on main (but not the other way around); upgrading from a release branch back to main (as long as the main commit is newer than the point of main where the release branch was forked); etc. A bunch of edge cases and subtleties came up in this discussion. @davepacheco plans to write an RFD to discuss this, but it's not an R17 ship blocker.
I tried to do a Nexus-driven update from 8571be3 (a commit on main) to 544f608 (the next commit on main), and the request to set the target system version was rejected with
The source of this is where we do a comparison between two
semver::Versions:omicron/nexus/src/external_api/http_entrypoints.rs
Lines 6853 to 6862 in 2648592
Because these versions match in their major/minor/patch, we're falling back to comparing the
BuildMetadata, which is ordered lexicographically:We discussed a bunch of options for unblocking testing:
We're going to go with option 1; it's not any less safe than what we have today (where you can upgrade from commit to commit if the build metadata sometimes) and is very easy to implement.
At the update watercooler, we also discussed ways to make this more closely match requirements we'd actually like to enforce, such as upgrading from a commit on main to a newer commit on main (but not the other way around); upgrading from a release branch back to main (as long as the main commit is newer than the point of main where the release branch was forked); etc. A bunch of edge cases and subtleties came up in this discussion. @davepacheco plans to write an RFD to discuss this, but it's not an R17 ship blocker.