Skip to content

Commit

Permalink
Emit distinguishable version info (linkerd#2432)
Browse files Browse the repository at this point in the history
The proxy currently emits very little useful version information.

This change updates the proxy to support new build-time environment
variables that are used to report version information:

* LINKERD2_PROXY_BUILD_TIME
* LINKERD2_PROXY_VENDOR
* LINKERD2_PROXY_VERSION

Additionally, several pre-existing Git-oriented metadata have been
removed, as they were generally redundant or uninformative. The Rustc
version has also been removed (since it has no real user-facing value
and can be easily determined by the version/tag).
  • Loading branch information
olix0r authored Jun 23, 2023
1 parent f0277cc commit d6172c5
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 69 deletions.
11 changes: 7 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ jobs:
exit 1
fi
( echo publish=true
echo version="$ver"
echo version="${ver#v}"
) >> "$GITHUB_OUTPUT"
else
sha="${{ github.sha }}"
echo version="test-${sha:0:7}" >> "$GITHUB_OUTPUT"
echo version="0.0.0-test.${sha:0:7}" >> "$GITHUB_OUTPUT"
fi
outputs:
publish: ${{ steps.meta.outputs.publish }}
Expand All @@ -60,13 +60,16 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 40
container: docker://ghcr.io/linkerd/dev:v40-rust-musl
env:
LINKERD2_PROXY_VENDOR: ${{ github.repository_owner }}
LINKERD2_PROXY_VERSION: ${{ needs.meta.outputs.version }}
steps:
- uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3
- run: git config --global --add safe.directory "$PWD" # actions/runner#2033
- run: just fetch
- run: just arch=${{ matrix.arch }} libc=${{ matrix.libc }} rustup
- run: just arch=${{ matrix.arch }} libc=${{ matrix.libc }} profile=release build
- run: just arch=${{ matrix.arch }} libc=${{ matrix.libc }} profile=release package_version=${{ needs.meta.outputs.version }} package
- run: just arch=${{ matrix.arch }} libc=${{ matrix.libc }} profile=release package
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce
with:
name: ${{ matrix.arch }}-artifacts
Expand All @@ -84,6 +87,6 @@ jobs:
- if: needs.meta.outputs.publish
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844
with:
name: ${{ needs.meta.outputs.version }}
name: v${{ needs.meta.outputs.version }}
files: artifacts/**/*
generate_release_notes: true
9 changes: 8 additions & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -938,6 +938,7 @@ dependencies = [
"pin-project",
"quickcheck",
"regex",
"semver 1.0.17",
"serde_json",
"thiserror",
"tokio",
Expand Down Expand Up @@ -2396,7 +2397,7 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver",
"semver 0.9.0",
]

[[package]]
Expand Down Expand Up @@ -2471,6 +2472,12 @@ dependencies = [
"semver-parser",
]

[[package]]
name = "semver"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"

[[package]]
name = "semver-parser"
version = "0.7.0"
Expand Down
5 changes: 3 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ RUN --mount=type=cache,id=cargo,target=/usr/local/cargo/registry \
just fetch
ARG TARGETARCH="amd64"
ARG PROFILE="release"
RUN --mount=type=cache,id=target,target=target \
--mount=type=cache,id=cargo,target=/usr/local/cargo/registry \
ARG LINKERD2_PROXY_VERSION=""
ARG LINKERD2_PROXY_VENDOR=""
RUN --mount=type=cache,id=cargo,target=/usr/local/cargo/registry \
just arch="$TARGETARCH" features="$PROXY_FEATURES" profile="$PROFILE" build && \
mkdir -p /out && \
mv $(just --evaluate profile="$PROFILE" _target_bin) /out/linkerd2-proxy
Expand Down
8 changes: 7 additions & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ toolchain := ""

features := ""

export LINKERD2_PROXY_VERSION := env_var_or_default("LINKERD2_PROXY_VERSION", "0.0.0-dev." + `git rev-parse --short HEAD`)
export LINKERD2_PROXY_VENDOR := env_var_or_default("LINKERD2_PROXY_VENDOR", `whoami` + "@" + `hostname`)

# The version name to use for packages.
package_version := `git rev-parse --short HEAD`
package_version := "v" + LINKERD2_PROXY_VERSION

# Docker image name & tag.
docker-repo := "localhost/linkerd/proxy"
Expand Down Expand Up @@ -175,6 +178,9 @@ docker *args='--output=type=docker': && _clean-cache
--pull \
--tag={{ docker-image }} \
--build-arg PROFILE='{{ profile }}' \
--build-arg LINKERD2_PROXY_VENDOR='{{ LINKERD2_PROXY_VENDOR }}' \
--build-arg LINKERD2_PROXY_VERSION='{{ LINKERD2_PROXY_VERSION }}' \
--no-cache-filter=runtime \
{{ if linkerd-tag == '' { '' } else { '--build-arg=RUNTIME_IMAGE=ghcr.io/linkerd/proxy:' + linkerd-tag } }} \
{{ if features != "" { "--build-arg PROXY_FEATURES=" + features } else { "" } }} \
{{ if DOCKER_BUILDX_CACHE_DIR == '' { '' } else { '--cache-from=type=local,src=' + DOCKER_BUILDX_CACHE_DIR + ' --cache-to=type=local,dest=' + DOCKER_BUILDX_CACHE_DIR } }} \
Expand Down
3 changes: 3 additions & 0 deletions linkerd/app/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,8 @@ features = ["make", "spawn-ready", "timeout", "util", "limit"]
[target.'cfg(target_os = "linux")'.dependencies]
linkerd-system = { path = "../../system" }

[build-dependencies]
semver = "1"

[dev-dependencies]
quickcheck = { version = "1", default-features = false }
36 changes: 26 additions & 10 deletions linkerd/app/core/build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::process::Command;
use std::string::String;

fn set_env(name: &str, cmd: &mut Command) {
let value = match cmd.output() {
Expand All @@ -12,21 +11,38 @@ fn set_env(name: &str, cmd: &mut Command) {
println!("cargo:rustc-env={}={}", name, value);
}

fn version() -> String {
if let Ok(v) = std::env::var("LINKERD2_PROXY_VERSION") {
if !v.is_empty() {
if semver::Version::parse(&v).is_err() {
panic!("LINKERD2_PROXY_VERSION must be semver");
}
return v;
}
}

"0.0.0-dev".to_string()
}

fn vendor() -> String {
std::env::var("LINKERD2_PROXY_VENDOR").unwrap_or_default()
}

fn main() {
set_env(
"GIT_BRANCH",
Command::new("git").args(["rev-parse", "--abbrev-ref", "HEAD"]),
);
set_env(
"GIT_SHA",
Command::new("git").args(["rev-parse", "--short", "HEAD"]),
);

// Capture the ISO 8601 formatted UTC time.
set_env(
"GIT_VERSION",
Command::new("git").args(["describe", "--always", "HEAD"]),
"LINKERD2_PROXY_BUILD_DATE",
Command::new("date").args(["-u", "+%Y-%m-%dT%H:%M:%SZ"]),
);
set_env("RUST_VERSION", Command::new("rustc").arg("--version"));

let profile = std::env::var("PROFILE").unwrap();
println!("cargo:rustc-env=PROFILE={}", profile);
println!("cargo:rustc-env=LINKERD2_PROXY_VERSION={}", version());
println!("cargo:rustc-env=LINKERD2_PROXY_VENDOR={}", vendor());

let profile = std::env::var("PROFILE").expect("PROFILE must be set");
println!("cargo:rustc-env=PROFILE={profile}");
}
2 changes: 1 addition & 1 deletion linkerd/app/core/src/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ impl Metrics {
) -> (Self, impl FmtMetrics + Clone + Send + 'static) {
let process = telemetry::process::Report::new(start_time);

let build_info = telemetry::build_info::Report::new();
let build_info = telemetry::build_info::Report::default();

let (control, control_report) = {
let m = metrics::Requests::<ControlLabels, Class>::default();
Expand Down
64 changes: 15 additions & 49 deletions linkerd/app/core/src/telemetry/build_info.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
use linkerd_metrics::{metrics, FmtLabels, FmtMetric, FmtMetrics, Gauge};
use std::env;
use std::fmt;
use std::string::String;
use std::sync::Arc;
use std::{env, fmt};

const GIT_BRANCH: &str = env!("GIT_BRANCH");
const GIT_SHA: &str = env!("GIT_SHA");
const GIT_VERSION: &str = env!("GIT_VERSION");
const PROFILE: &str = env!("PROFILE");
const RUST_VERSION: &str = env!("RUST_VERSION");
pub const VERSION: &str = env!("LINKERD2_PROXY_VERSION");
pub const DATE: &str = env!("LINKERD2_PROXY_BUILD_DATE");
pub const VENDOR: &str = env!("LINKERD2_PROXY_VENDOR");
pub const GIT_SHA: &str = env!("GIT_SHA");
pub const PROFILE: &str = env!("PROFILE");

metrics! {
proxy_build_info: Gauge {
Expand All @@ -17,56 +14,25 @@ metrics! {
}

#[derive(Clone, Debug, Default)]
pub struct Report {
name: String,
// `value` remains constant over the lifetime of the proxy so that
// build information in `labels` remains accurate
value: Arc<Gauge>,
labels: Arc<BuildInfoLabels>,
}

#[derive(Clone, Debug, Default)]
struct BuildInfoLabels {
git_branch: String,
git_sha: String,
git_version: String,
profile: String,
rust_version: String,
}
pub struct Report(());

impl Report {
pub fn new() -> Self {
let labels = Arc::new(BuildInfoLabels {
git_branch: GIT_BRANCH.to_string(),
git_sha: GIT_SHA.to_string(),
git_version: GIT_VERSION.to_string(),
profile: PROFILE.to_string(),
rust_version: RUST_VERSION.to_string(),
});
Self {
name: "proxy_build_info".to_string(),
value: Arc::new(1.into()),
labels,
}
}
}
struct Labels;

impl FmtMetrics for Report {
fn fmt_metrics(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
proxy_build_info.fmt_help(f)?;
self.value
.fmt_metric_labeled(f, self.name.as_str(), self.labels.as_ref())?;
Gauge::from(1).fmt_metric_labeled(f, "proxy_build_info", &Labels)?;
Ok(())
}
}

impl FmtLabels for BuildInfoLabels {
impl FmtLabels for Labels {
fn fmt_labels(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "git_branch=\"{}\"", self.git_branch)?;
write!(f, ",git_sha=\"{}\"", self.git_sha)?;
write!(f, ",git_version=\"{}\"", self.git_version)?;
write!(f, ",profile=\"{}\"", self.profile)?;
write!(f, ",rust_version=\"{}\"", self.rust_version)?;
write!(f, "version=\"{VERSION}\"")?;
write!(f, ",git_sha=\"{GIT_SHA}\"")?;
write!(f, ",profile=\"{PROFILE}\"")?;
write!(f, ",date=\"{DATE}\"")?;
write!(f, ",vendor=\"{VENDOR}\"")?;
Ok(())
}
}
14 changes: 13 additions & 1 deletion linkerd2-proxy/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ compile_error!(
);

use linkerd_app::{
core::{telemetry::StartTime, transport::BindTcp},
core::{
telemetry::{build_info, StartTime},
transport::BindTcp,
},
trace, Config,
};
use linkerd_signal as signal;
Expand All @@ -37,6 +40,15 @@ fn main() {
}
};

info!(
"{profile} {version} ({sha}) by {vendor} on {date}",
date = build_info::DATE,
sha = build_info::GIT_SHA,
version = build_info::VERSION,
profile = build_info::PROFILE,
vendor = build_info::VENDOR,
);

// Load configuration from the environment without binding ports.
let config = match Config::try_from_env() {
Ok(config) => config,
Expand Down

0 comments on commit d6172c5

Please sign in to comment.