Skip to content

Commit

Permalink
populate SMBIOS system version with Git metadata
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
hawkw committed May 7, 2024
1 parent 0d8efa1 commit 3ad03a5
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 2 deletions.
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.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,4 @@ tracing-bunyan-formatter = "0.3.3"
tracing-subscriber = "0.3.14"
usdt = { version = "0.5", default-features = false }
uuid = "1.3.2"
vergen = { version = "8.0.0", features = ["git", "gitcl"]}
2 changes: 1 addition & 1 deletion bin/propolis-server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use propolis_server::{
};

#[derive(Debug, Parser)]
#[clap(about, version)]
#[clap(about, version = propolis::version())]
/// An HTTP server providing access to Propolis
enum Args {
/// Generates the OpenAPI specification.
Expand Down
1 change: 1 addition & 0 deletions bin/propolis-standalone/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1281,6 +1281,7 @@ fn api_version_checks(log: &slog::Logger) -> std::io::Result<()> {
}

#[derive(clap::Parser)]
#[clap(version = propolis::version())]
/// Propolis command-line frontend for running a VM.
struct Args {
/// Either the VM config file or a previously captured snapshot image.
Expand Down
4 changes: 4 additions & 0 deletions lib/propolis/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ rand = { workspace = true, optional = true }
softnpu-lib = { workspace = true, optional = true }
dlpi = { workspace = true, optional = true }

[build-dependencies]
anyhow.workspace = true
vergen.workspace = true

[dev-dependencies]
crossbeam-channel.workspace = true
tempfile.workspace = true
Expand Down
16 changes: 16 additions & 0 deletions lib/propolis/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// 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/.

fn main() -> anyhow::Result<()> {
// Generate Git version information.
vergen::EmitBuilder::builder()
// Don't emit timestamps and build info.
.idempotent()
.git_branch()
.git_sha(true)
.git_commit_count()
.emit()?;

Ok(())
}
18 changes: 17 additions & 1 deletion lib/propolis/src/firmware/smbios/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ pub mod type0 {
BiosExtCharacteristics => u16,
}
}
#[derive(Default)]

pub struct Type1 {
pub manufacturer: SmbString,
pub product_name: SmbString,
Expand Down Expand Up @@ -381,6 +381,22 @@ impl Table for Type1 {
}
}

impl Default for Type1 {
fn default() -> Self {
Type1 {
manufacturer: SmbString::default(),
product_name: SmbString::default(),
version: SmbString::try_from(crate::version())
.expect("version string should not contain NULs"),
serial_number: SmbString::default(),
uuid: [0; 16],
wake_up_type: type1::WakeUpType::default(),
sku_number: SmbString::default(),
family: SmbString::default(),
}
}
}

pub mod type1 {
use super::*;

Expand Down
43 changes: 43 additions & 0 deletions lib/propolis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,46 @@ pub mod vmm;

pub use exits::{VmEntry, VmExit};
pub use vmm::Machine;

pub fn version() -> &'static str {
lazy_static::lazy_static! {
static ref VERSION: String = {
use std::fmt::Write;

let git = option_env!("VERGEN_GIT_BRANCH")
.and_then(|branch| Some((branch, option_env!("VERGEN_GIT_SHA")?)))
.and_then(|(branch, sha)| Some((branch, sha, option_env!("VERGEN_GIT_COMMIT_COUNT")?)));

let mut version = format!("Propolis v{}", env!("CARGO_PKG_VERSION"));
if let Some((branch, sha, commit)) = git {
write!(version, "-{commit} ({sha}) {branch}, ")
.expect("writing to a string never fails");
} else {
version.push_str(" <unknown git commit>, ");
}
match bhyve_api::api_version() {
Ok(v) => {
write!(version, "Bhyve API v{v}")
.expect("writing to a string never fails");
}
Err(_) => {
version.push_str("<unknown Bhyve API version>");
}
}
version
};
};
&VERSION
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn print_version() {
let v = version();
eprintln!("version: {v}");
assert!(v.starts_with("Propolis v"));
}
}

0 comments on commit 3ad03a5

Please sign in to comment.