Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,19 @@ pub fn format_time_delta(time_delta: chrono::TimeDelta) -> String {
}
}

/// The system version of the Oxide software (RFD 557): the `N.P.C` form,
/// without the `+gitHHHH` build metadata that a published release carries.
///
/// Under current policy, each new release is a major version bump, and
/// generally referred to only by the major version (e.g. 8.0.0 is referred
/// to as "v8", "version 8", or "release 8" to customers). The use of semantic
/// versioning is mostly to hedge for perhaps wanting something more granular in
/// the future.
///
/// The releng build process appends build metadata to this to produce the full
/// version string; the `/v1/version` API endpoint returns it as-is.
pub const SYSTEM_VERSION: semver::Version = semver::Version::new(22, 0, 0);

pub const OMICRON_DPD_TAG: &str = "omicron";

/// A wrapper struct that does nothing other than elide the inner value from
Expand Down
1 change: 1 addition & 0 deletions dev-tools/releng/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ dev-tools-common.workspace = true
fs-err = { workspace = true, features = ["tokio"] }
futures.workspace = true
hex.workspace = true
omicron-common.workspace = true
omicron-pins.workspace = true
omicron-workspace-hack.workspace = true
omicron-zone-package.workspace = true
Expand Down
12 changes: 1 addition & 11 deletions dev-tools/releng/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,6 @@ use tufaceous_artifact_v2::OsVariant;
use crate::cmd::Command;
use crate::job::Jobs;

/// The base version we're currently building. Build information is appended to
/// this later on.
///
/// Under current policy, each new release is a major version bump, and
/// generally referred to only by the major version (e.g. 8.0.0 is referred
/// to as "v8", "version 8", or "release 8" to customers). The use of semantic
/// versioning is mostly to hedge for perhaps wanting something more granular in
/// the future.
const BASE_VERSION: Version = Version::new(22, 0, 0);

const RETRY_ATTEMPTS: usize = 3;

#[derive(Debug, Clone, Copy)]
Expand Down Expand Up @@ -1163,7 +1153,7 @@ async fn host_add_root_profile(host_proto_root: Utf8PathBuf) -> Result<()> {
fn generate_version(commit: &str) -> Result<Version> {
const PADDED_WIDTH: usize = 8;

let mut version = BASE_VERSION.clone();
let mut version = omicron_common::SYSTEM_VERSION.clone();
// Differentiate between CI and local builds. We use `0.word` as the
// prerelease field because it comes before `alpha`.
version.pre =
Expand Down
1 change: 1 addition & 0 deletions nexus/external-api/output/nexus_tags.txt
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ user_builtin_view GET /v1/system/users-builtin/{user
API operations found with tag "system/status"
OPERATION ID METHOD URL PATH
ping GET /v1/ping
version GET /v1/version

API operations found with tag "system/subnet-pools"
OPERATION ID METHOD URL PATH
Expand Down
20 changes: 20 additions & 0 deletions nexus/external-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ api_versions!([
// | date-based version should be at the top of the list.
// v
// (next_yyyy_mm_dd_nn, IDENT),
(2026_07_15_00, API_VERSION),
(2026_06_10_00, BGP_CONFIGURATION_UPDATE),
(2026_06_08_00, INSTANCE_CPU_TYPE_TURIN_V2),
(2026_06_05_00, EXTERNAL_JUMBO_FRAMES),
Expand Down Expand Up @@ -417,6 +418,25 @@ pub trait NexusExternalApi {
}))
}

/// Fetch version information
///
/// Returns the version of the Oxide API currently being served and the
/// version of the system software serving it.
#[endpoint {
method = GET,
path = "/v1/version",
tags = ["system/status"],
versions = VERSION_API_VERSION..,
}]
async fn version(
_rqctx: RequestContext<Self::Context>,
) -> Result<HttpResponseOk<latest::system::Version>, HttpError> {
Ok(HttpResponseOk(latest::system::Version {
api_version: latest_version(),
system_version: omicron_common::SYSTEM_VERSION,
}))
}

/// Fetch top-level IAM policy
#[endpoint {
method = GET,
Expand Down
11 changes: 11 additions & 0 deletions nexus/tests/integration_tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,17 @@ async fn test_ping(cptestctx: &ControlPlaneTestContext) {
assert_eq!(health.status, system::PingStatus::Ok);
}

#[nexus_test]
async fn test_version(cptestctx: &ControlPlaneTestContext) {
let client = &cptestctx.external_client;

let version = NexusRequest::object_get(client, "/v1/version")
.execute_and_parse_unwrap::<system::Version>()
.await;
assert_eq!(version.api_version, nexus_external_api::latest_version());
assert_eq!(version.system_version, omicron_common::SYSTEM_VERSION);
}

/// Test that the external API returns gzip-compressed responses when the
/// client sends Accept-Encoding: gzip.
#[nexus_test]
Expand Down
1 change: 1 addition & 0 deletions nexus/tests/output/uncovered-authz-endpoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ console_settings_page (get "/settings/{path}")
console_system_page (get "/system/{path}")
console_silo_utilization (get "/utilization")
ping (get "/v1/ping")
version (get "/v1/version")
device_auth_request (post "/device/auth")
device_auth_confirm (post "/device/confirm")
device_access_token (post "/device/token")
Expand Down
9 changes: 9 additions & 0 deletions nexus/types/versions/src/api_version/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//! Version `API_VERSION` of the Nexus external API.
//!
//! Adds the `Version` type for the new `/v1/version` endpoint.

pub mod system;
23 changes: 23 additions & 0 deletions nexus/types/versions/src/api_version/system.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//! System types for version `API_VERSION`.

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

/// Version information for the API and the system software serving it
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct Version {
/// The API version, e.g., `2026071500.0.0`, matching the `version` field
/// of the OpenAPI schema. Clients should send it in the `api-version`
/// header to select this version of the API. The official SDKs do this
/// automatically.
pub api_version: semver::Version,

/// The version of the system software serving this API, e.g., `22.0.0`.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will want to update the example version to the full length one when #10839 is proven out.

/// Use this version to find the right docs and release notes. During an
/// update, some components of the system may be running a newer version.
pub system_version: semver::Version,
}
1 change: 1 addition & 0 deletions nexus/types/versions/src/latest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ pub mod system {
pub use crate::v2025_11_20_00::system::AllowListUpdate;
pub use crate::v2025_11_20_00::system::Ping;
pub use crate::v2025_11_20_00::system::PingStatus;
pub use crate::v2026_07_15_00::system::Version;
}

pub mod system_networking {
Expand Down
2 changes: 2 additions & 0 deletions nexus/types/versions/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,5 @@ pub mod v2026_06_05_00;
pub mod v2026_06_08_00;
#[path = "bgp_configuration_update/mod.rs"]
pub mod v2026_06_10_00;
#[path = "api_version/mod.rs"]
pub mod v2026_07_15_00;
1 change: 1 addition & 0 deletions openapi/nexus/nexus-2026061000.0.0-9779e2.json.gitstub
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3a8796bc025128e4df2fe38ebc4404755823fa1d:openapi/nexus/nexus-2026061000.0.0-9779e2.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://oxide.computer",
"email": "api@oxide.computer"
},
"version": "2026061000.0.0"
"version": "2026071500.0.0"
},
"paths": {
"/device/auth": {
Expand Down Expand Up @@ -14062,6 +14062,34 @@
}
}
},
"/v1/version": {
"get": {
"tags": [
"system/status"
],
"summary": "Fetch version information",
"description": "Returns the version of the Oxide API currently being served and the version of the system software serving it.",
"operationId": "version",
"responses": {
"200": {
"description": "successful operation",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Version"
}
}
}
},
"4XX": {
"$ref": "#/components/responses/Error"
},
"5XX": {
"$ref": "#/components/responses/Error"
}
}
}
},
"/v1/vpc-firewall-rules": {
"get": {
"tags": [
Expand Down Expand Up @@ -30655,6 +30683,26 @@
"values"
]
},
"Version": {
"description": "Version information for the API and the system software serving it",
"type": "object",
"properties": {
"api_version": {
"description": "The API version, e.g., `2026071500.0.0`, matching the `version` field of the OpenAPI schema. Clients should send it in the `api-version` header to select this version of the API. The official SDKs do this automatically.",
"type": "string",
"pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$"
},
"system_version": {
"description": "The version of the system software serving this API, e.g., `22.0.0`. Use this version to find the right docs and release notes. During an update, some components of the system may be running a newer version.",
"type": "string",
"pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$"
}
},
"required": [
"api_version",
"system_version"
]
},
"VirtualResourceCounts": {
"description": "A collection of resource counts used to describe capacity and utilization",
"type": "object",
Expand Down
2 changes: 1 addition & 1 deletion openapi/nexus/nexus-latest.json
Loading