Skip to content

Commit

Permalink
Embed version info; print benchmark config
Browse files Browse the repository at this point in the history
Update how we set/read the version and commit information, so that it
can be set via writing to files instead of needing to update all `go
build` commands to add (or update) `-ldflags` with
`-X main.version=... -X manin.gitCommit=...".

Augment benchmark configuration with additional information, such as the
go version, number of CPUs available, start time, version, and git
branch and commit.

This allows standardizing the configuration data across different
benchmarking suites.

Benchmark config follow the benchmark raw data format:
https://go.googlesource.com/proposal/+/master/design/14313-benchmark-format.md

Signed-off-by: Hamza El-Saawy <hamzaelsaawy@microsoft.com>
  • Loading branch information
helsaawy committed Aug 17, 2023
1 parent 7dfb07b commit 1c1949b
Show file tree
Hide file tree
Showing 14 changed files with 304 additions and 59 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,18 @@ jobs:
with:
go-version: ${{ env.GO_VERSION }}

- name: Set version info
shell: pwsh
run: |
# ignore errors since they won't affect build
try {
./scripts/Set-VersionInfo.ps1
} catch {
Write-Output "::warning::Could not set hcsshim version info: $_"
} finally {
$LASTEXITCODE = 0
}
- run: go build ./cmd/containerd-shim-runhcs-v1
- run: go build ./cmd/runhcs
- run: go build ./cmd/tar2ext4
Expand Down Expand Up @@ -558,6 +570,18 @@ jobs:
with:
go-version: ${{ env.GO_VERSION }}

- name: Set version info
shell: pwsh
run: |
# ignore errors since they won't affect build
try {
./scripts/Set-VersionInfo.ps1
} catch {
Write-Output "::warning::Could not set hcsshim version info: $_"
} finally {
$LASTEXITCODE = 0
}
- name: Test
run: make test

Expand Down
27 changes: 20 additions & 7 deletions cmd/containerd-shim-runhcs-v1/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/shimdiag"
hcsversion "github.com/Microsoft/hcsshim/internal/version"

// register common types spec with typeurl
_ "github.com/containerd/containerd/runtime"
Expand All @@ -32,13 +33,15 @@ const ttrpcAddressEnv = "TTRPC_ADDRESS"
// Add a manifest to get proper Windows version detection.
//go:generate go run github.com/josephspurrier/goversioninfo/cmd/goversioninfo -platform-specific

// version will be populated by the Makefile, read from
// VERSION file of the source code.
var version = ""

// gitCommit will be the hash that the binary was built from
// and will be populated by the Makefile
var gitCommit = ""
// `-ldflags '-X ...'` only works if the variable is uninitialized or set to a constant value.
// keep empty and override with data from [internal/version] only if empty to allow
// workflows currently setting these values to work.
var (
// version will be the repo version that the binary was built from
version = ""
// gitCommit will be the hash that the binary was built from
gitCommit = ""
)

var (
namespaceFlag string
Expand Down Expand Up @@ -81,11 +84,21 @@ func main() {
}
}

// fall back on embedded version info (if any), if variables above were not set
if version == "" {
version = hcsversion.Version
}
if gitCommit == "" {
gitCommit = hcsversion.Commit
}

_ = provider.WriteEvent(
"ShimLaunched",
nil,
etw.WithFields(
etw.StringArray("Args", os.Args),
etw.StringField("version", version),
etw.StringField("commit", gitCommit),
),
)

Expand Down
7 changes: 6 additions & 1 deletion cmd/gcs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/Microsoft/hcsshim/internal/guestpath"
"github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/version"
"github.com/Microsoft/hcsshim/pkg/securitypolicy"
)

Expand Down Expand Up @@ -271,7 +272,11 @@ func main() {

baseLogPath := guestpath.LCOWRootPrefixInUVM

logrus.Info("GCS started")
logrus.WithFields(logrus.Fields{
"branch": version.Branch,
"commit": version.Commit,
"version": version.Version,
}).Info("GCS started")

// Set the process core dump location. This will be global to all containers as it's a kernel configuration.
// If no path is specified core dumps will just be placed in the working directory of wherever the process
Expand Down
30 changes: 21 additions & 9 deletions cmd/runhcs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,27 @@ import (

"github.com/Microsoft/go-winio"
"github.com/Microsoft/go-winio/pkg/etwlogrus"
"github.com/Microsoft/hcsshim/internal/regstate"
"github.com/Microsoft/hcsshim/internal/runhcs"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"

"github.com/Microsoft/hcsshim/internal/regstate"
"github.com/Microsoft/hcsshim/internal/runhcs"
hcsversion "github.com/Microsoft/hcsshim/internal/version"
)

// Add a manifest to get proper Windows version detection.
//go:generate go run github.com/josephspurrier/goversioninfo/cmd/goversioninfo -platform-specific

// version will be populated by the Makefile, read from
// VERSION file of the source code.
var version = ""

// gitCommit will be the hash that the binary was built from
// and will be populated by the Makefile
var gitCommit = ""
// `-ldflags '-X ...'` only works if the variable is uninitialized or set to a constant value.
// keep empty and override with data from [internal/version] only if empty to allow
// workflows currently setting these values to work.
var (
// version will be the repo version that the binary was built from
version = ""
// gitCommit will be the hash that the binary was built from
gitCommit = ""
)

var stateKey *regstate.Key

Expand Down Expand Up @@ -62,6 +66,14 @@ func main() {
app.Name = "runhcs"
app.Usage = usage

// fall back on embedded version info (if any), if variables above were not set
if version == "" {
version = hcsversion.Version
}
if gitCommit == "" {
gitCommit = hcsversion.Commit
}

var v []string
if version != "" {
v = append(v, version)
Expand Down
2 changes: 1 addition & 1 deletion internal/uvm/create_lcow.go
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ Example JSON document produced once the hcsschema.ComputeSytem returned by makeL
}
*/

// Make the ComputeSystem document object that will be serialised to json to be presented to the HCS api.
// Make the ComputeSystem document object that will be serialized to json to be presented to the HCS api.
func makeLCOWDoc(ctx context.Context, opts *OptionsLCOW, uvm *UtilityVM) (_ *hcsschema.ComputeSystem, err error) {
logrus.Tracef("makeLCOWDoc %v\n", opts)

Expand Down
4 changes: 4 additions & 0 deletions internal/version/data/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# DO NOT MOVE: this file prevents `//go:embed data/*` from failing at build time
BRANCH
COMMIT
VERSION
41 changes: 41 additions & 0 deletions internal/version/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package version

import (
"embed"
"strings"
)

// Using `//go:embed data/VERSION` (similarly for `data/COMMIT` and `data/BRANCH`) will
// fail at build time if the files don't exist, which will break existing build workflows.
//
// Alternatively, committing those files in git will cause problems as they will be constantly
// updated and overwitten if devs update them locally and commit the changes.
//
// Therefore, we embed a (non-empty) directory and look up the files at run-time so builds
// succeed regardless of whether the files are exist or not.
// `data/.gitignore` is our fallback file, which keeps `data/` non-empty and prevents [embed]
// from failing.

// Using a dedicated `data` directory allows us to separate out what files to embed.
// (Writing `//go:embed *` would include everything in this directory, including this file.)

// See scripts/Set-VersionInfo.ps1 for an example of setting these values via files in data/.

//go:embed data/*
var data embed.FS

var (
// Branch is the git branch the binary was built from.
Branch = readDataFile("BRANCH")

// Commit is the git commit the binary was built from.
Commit = readDataFile("COMMIT")

// Version is the complete semver.
Version = readDataFile("VERSION")
)

func readDataFile(f string) string {
b, _ := data.ReadFile("data/" + f)
return strings.TrimSpace(string(b))
}
3 changes: 0 additions & 3 deletions scripts/Run-Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,4 @@ Invoke-TestCommand `
-TestCmd $testcmd `
-OutputFile $out `
-OutputCmd (& { if ( $Action -eq 'Bench' ) { $BenchstatPath } }) `
-Preamble `
-Date $Date `
-Note $Note `
-Verbose:$Verbose
58 changes: 58 additions & 0 deletions scripts/Set-VersionInfo.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Example of who to set the version/git information in ./internal/version so
# that the binaries will report the appropriate information.

$ErrorActionPreference = 'Continue'
$VerbosePreference = 'Continue'

$root = Split-Path -Path $PSScriptRoot -Parent
$dataDir = Join-Path $root 'internal/version/data'

function run([string]$cmd, [string[]]$params) {
Write-Verbose "$cmd $params"
$s = & $cmd @params 2>&1
if ( $LASTEXITCODE -ne 0 ) {
$err = "Command '$cmd $params' failed"
if ( -not [string]::IsNullOrWhiteSpace("$s") ) {
$err += ": $s"
}
Write-Warning $err
} else {
$s
}
}

function writeto([string]$f, [string]$v) {
if ( [string]::IsNullOrWhiteSpace($v) ) {
return
}
$v = $v.Trim()

Write-Output "${f}: $v"
$v | Out-File -Encoding ascii -FilePath (Join-Path $dataDir $f) -NoNewline
}

$branch = run 'git' @('rev-parse', '--abbrev-ref', 'HEAD')
if ( $branch -ceq 'HEAD') {
Write-Warning 'Detected detached head'
$branch = run 'git' @('name-rev', '--name-only', 'HEAD')
if ( [string]::IsNullOrWhiteSpace($branch) -or $branch -eq 'undefined' ) {
Write-Warning "'git name-rev' failed: $branch"
$branch = run 'git' @('branch', '-r', '--contains=HEAD') | Select-Object -First 1
}
}
$branch = $branch -replace '^(origin|remotes/origin|refs/heads)/', ''
writeto 'BRANCH' $branch

$commit = run 'git' @('rev-parse', 'HEAD')
try {
run 'git' @('diff', '--no-ext-diff', '--quiet', '--exit-code', 'HEAD')
if ( $LASTEXITCODE -ne 0 ) {
Write-Warning 'Dirty repo'
$commit += '-dirty'
}
} catch { }
writeto 'COMMIT' $commit

# don't use `--always`; we we're okay with an empty version since commit will likely be non-empty
$version = run 'git' @('describe', '--match=v[0-9]*', '--tags', '--dirty')
writeto 'VERSION' $version
13 changes: 1 addition & 12 deletions scripts/Test-LCOW-UVM.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,7 @@ if ( $shell ) {
$gcspath = "$GCSTestMount/gcs.test"
}

$pre = "wait-paths -p $waitfiles -t 5 ; " + `
'echo nproc: `$(nproc) ; ' + `
'echo kernel: `$(uname -a) ; ' + `
'echo gcs.commit: `$(cat /info/gcs.commit 2>/dev/null) ; ' + `
'echo gcs.branch: `$(cat /info/gcs.branch 2>/dev/null) ; ' + `
'echo tar.date: `$(cat /info/tar.date 2>/dev/null) ; ' + `
'echo image.name: `$(cat /info/image.name 2>/dev/null) ; ' + `
'echo build.date: `$(cat /info/build.date 2>/dev/null) ; '
$pre = "wait-paths -p $waitfiles -t 5 ; "

$testcmd, $out = New-TestCommand `
-Action $Action `
Expand Down Expand Up @@ -144,10 +137,6 @@ $boot += " -exec `"$cmd`" "

Invoke-TestCommand `
-TestCmd $boot `
-TestCmdPreamble $testcmd `
-OutputFile (& { if ( $Action -ne 'Shell' ) { $out } }) `
-OutputCmd (& { if ( $Action -eq 'Bench' ) { 'benchstat' } }) `
-Preamble `
-Date $Date `
-Note $Note `
-Verbose:$Verbose
27 changes: 1 addition & 26 deletions scripts/Testing.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -106,23 +106,11 @@ function Invoke-TestCommand {
[string]
$TestCmd,

[string]
$TestCmdPreamble = $TestCmd,

[string]
$OutputFile = '',

[string]
$OutputCmd,

[switch]
$Preamble,

[DateTime]
$Date = (Get-Date),

[string]
$Note
$OutputCmd
)
Write-Verbose "Running command: $TestCmd"

Expand All @@ -132,19 +120,6 @@ function Invoke-TestCommand {
Write-Verbose "Saving output to: $OutputFile"
}


if ( $Preamble ) {
& {
Write-Output "test.date: $(Get-Date -Date $Date -UFormat '%FT%R%Z' -AsUTC)"
if ( $Note ) {
Write-Output "note: $Note"
}
Write-Output "test.command: $TestCmdPreamble"
if ( Get-Command -ErrorAction Ignore 'git' ) {
Write-Output "pkg.commit: $(git rev-parse HEAD 2>$null)"
}
} | Tee-Object -Encoding utf8 -FilePath $OutputFile
}
Invoke-Expression $TestCmd |
Tee-Object -Encoding utf8 -Append -FilePath $OutputFile

Expand Down
5 changes: 5 additions & 0 deletions test/functional/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ func TestMain(m *testing.M) {
l.TempPath = *flagLayerTempDir
}

// print additional configuration options when running benchmarks, so we can better track performance.
if util.RunningBenchmarks() {
util.PrintAdditionalBenchmarkConfig()
}

e := m.Run()

// close any uVMs that escaped
Expand Down
Loading

0 comments on commit 1c1949b

Please sign in to comment.