Skip to content

Commit 3ad03a5

Browse files
committed
populate SMBIOS system version with Git metadata
Currently, the SMBIOS system (type 1) table has a hard-coded version field. It would be nice if this was instead populated with details about the Propolis version, as described in issue #701. This branch adds a `build.rs`` script that uses [the `vergen` crate][1] to emit information about the Git revision that Propolis was build from. Now, we can generate a version string that describes the git branch, commit hash, and commit depth, as described in [this comment][2]. This is generated in a `propolis::version()` function, which also includes the Bhyve API version (detected at runtime). This results in version strings like: ``` Propolis v0.1.0-658 (0d8efa1) eliza/somebios-version, <unknown Bhyve API version> ``` (on a Linux machine; the Bhyve version would be present on illumos) In addition to populating the SMBIOS system version, this commit also sets the Clap version for CLI commands, so that the `--version` flag will print out the same value that's set in SMBIOS. [1]: https://docs.rs/vergen [2]: #701 (comment)
1 parent 0d8efa1 commit 3ad03a5

File tree

8 files changed

+84
-2
lines changed

8 files changed

+84
-2
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,4 @@ tracing-bunyan-formatter = "0.3.3"
160160
tracing-subscriber = "0.3.14"
161161
usdt = { version = "0.5", default-features = false }
162162
uuid = "1.3.2"
163+
vergen = { version = "8.0.0", features = ["git", "gitcl"]}

bin/propolis-server/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use propolis_server::{
1919
};
2020

2121
#[derive(Debug, Parser)]
22-
#[clap(about, version)]
22+
#[clap(about, version = propolis::version())]
2323
/// An HTTP server providing access to Propolis
2424
enum Args {
2525
/// Generates the OpenAPI specification.

bin/propolis-standalone/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,7 @@ fn api_version_checks(log: &slog::Logger) -> std::io::Result<()> {
12811281
}
12821282

12831283
#[derive(clap::Parser)]
1284+
#[clap(version = propolis::version())]
12841285
/// Propolis command-line frontend for running a VM.
12851286
struct Args {
12861287
/// Either the VM config file or a previously captured snapshot image.

lib/propolis/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ rand = { workspace = true, optional = true }
4343
softnpu-lib = { workspace = true, optional = true }
4444
dlpi = { workspace = true, optional = true }
4545

46+
[build-dependencies]
47+
anyhow.workspace = true
48+
vergen.workspace = true
49+
4650
[dev-dependencies]
4751
crossbeam-channel.workspace = true
4852
tempfile.workspace = true

lib/propolis/build.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this
3+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4+
5+
fn main() -> anyhow::Result<()> {
6+
// Generate Git version information.
7+
vergen::EmitBuilder::builder()
8+
// Don't emit timestamps and build info.
9+
.idempotent()
10+
.git_branch()
11+
.git_sha(true)
12+
.git_commit_count()
13+
.emit()?;
14+
15+
Ok(())
16+
}

lib/propolis/src/firmware/smbios/table.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ pub mod type0 {
351351
BiosExtCharacteristics => u16,
352352
}
353353
}
354-
#[derive(Default)]
354+
355355
pub struct Type1 {
356356
pub manufacturer: SmbString,
357357
pub product_name: SmbString,
@@ -381,6 +381,22 @@ impl Table for Type1 {
381381
}
382382
}
383383

384+
impl Default for Type1 {
385+
fn default() -> Self {
386+
Type1 {
387+
manufacturer: SmbString::default(),
388+
product_name: SmbString::default(),
389+
version: SmbString::try_from(crate::version())
390+
.expect("version string should not contain NULs"),
391+
serial_number: SmbString::default(),
392+
uuid: [0; 16],
393+
wake_up_type: type1::WakeUpType::default(),
394+
sku_number: SmbString::default(),
395+
family: SmbString::default(),
396+
}
397+
}
398+
}
399+
384400
pub mod type1 {
385401
use super::*;
386402

lib/propolis/src/lib.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,46 @@ pub mod vmm;
3535

3636
pub use exits::{VmEntry, VmExit};
3737
pub use vmm::Machine;
38+
39+
pub fn version() -> &'static str {
40+
lazy_static::lazy_static! {
41+
static ref VERSION: String = {
42+
use std::fmt::Write;
43+
44+
let git = option_env!("VERGEN_GIT_BRANCH")
45+
.and_then(|branch| Some((branch, option_env!("VERGEN_GIT_SHA")?)))
46+
.and_then(|(branch, sha)| Some((branch, sha, option_env!("VERGEN_GIT_COMMIT_COUNT")?)));
47+
48+
let mut version = format!("Propolis v{}", env!("CARGO_PKG_VERSION"));
49+
if let Some((branch, sha, commit)) = git {
50+
write!(version, "-{commit} ({sha}) {branch}, ")
51+
.expect("writing to a string never fails");
52+
} else {
53+
version.push_str(" <unknown git commit>, ");
54+
}
55+
match bhyve_api::api_version() {
56+
Ok(v) => {
57+
write!(version, "Bhyve API v{v}")
58+
.expect("writing to a string never fails");
59+
}
60+
Err(_) => {
61+
version.push_str("<unknown Bhyve API version>");
62+
}
63+
}
64+
version
65+
};
66+
};
67+
&VERSION
68+
}
69+
70+
#[cfg(test)]
71+
mod tests {
72+
use super::*;
73+
74+
#[test]
75+
fn print_version() {
76+
let v = version();
77+
eprintln!("version: {v}");
78+
assert!(v.starts_with("Propolis v"));
79+
}
80+
}

0 commit comments

Comments
 (0)