diff --git a/cmd/nvidia-container-runtime/main.go b/cmd/nvidia-container-runtime/main.go index 4b8651fb..ea935aca 100644 --- a/cmd/nvidia-container-runtime/main.go +++ b/cmd/nvidia-container-runtime/main.go @@ -3,11 +3,19 @@ package main import ( "fmt" "os" + "strings" "github.com/NVIDIA/nvidia-container-toolkit/internal/config" + "github.com/NVIDIA/nvidia-container-toolkit/internal/info" + "github.com/opencontainers/runtime-spec/specs-go" ) -var Version string +// version must be set by go build's -X main.version= option in the Makefile. +var version = "unknown" + +// gitCommit will be the hash that the binary was built from +// and will be populated by the Makefile +var gitCommit = "" var logger = NewLogger() @@ -22,6 +30,11 @@ func main() { // run is an entry point that allows for idiomatic handling of errors // when calling from the main function. func run(argv []string) (rerr error) { + printVersion := hasVersionFlag(argv) + if printVersion { + fmt.Printf("%v version %v\n", "NVIDIA Container Runtime", info.GetVersionString(fmt.Sprintf("spec: %v", specs.Version))) + } + cfg, err := config.GetConfig() if err != nil { return fmt.Errorf("error loading config: %v", err) @@ -43,5 +56,29 @@ func run(argv []string) (rerr error) { return fmt.Errorf("failed to create NVIDIA Container Runtime: %v", err) } + if printVersion { + fmt.Print("\n") + } return runtime.Exec(argv) } + +// TODO: This should be refactored / combined with parseArgs in logger. +func hasVersionFlag(args []string) bool { + for i := 0; i < len(args); i++ { + param := args[i] + + parts := strings.SplitN(param, "=", 2) + trimmed := strings.TrimLeft(parts[0], "-") + // If this is not a flag we continue + if parts[0] == trimmed { + continue + } + + // Check the version flag + if trimmed == "version" { + return true + } + } + + return false +} diff --git a/cmd/nvidia-container-toolkit/main.go b/cmd/nvidia-container-toolkit/main.go index 3ecf1ba0..6b29da8b 100644 --- a/cmd/nvidia-container-toolkit/main.go +++ b/cmd/nvidia-container-toolkit/main.go @@ -18,8 +18,9 @@ import ( ) var ( - debugflag = flag.Bool("debug", false, "enable debug output") - configflag = flag.String("config", "", "configuration file") + debugflag = flag.Bool("debug", false, "enable debug output") + versionflag = flag.Bool("version", false, "enable version output") + configflag = flag.String("config", "", "configuration file") ) func exit() { @@ -159,6 +160,11 @@ func main() { flag.Usage = usage flag.Parse() + if *versionflag { + fmt.Printf("%v version %v\n", "NVIDIA Container Runtime Hook", info.GetVersionString()) + return + } + args := flag.Args() if len(args) == 0 { flag.Usage() diff --git a/cmd/nvidia-ctk/main.go b/cmd/nvidia-ctk/main.go index ca9de11b..c635e3cc 100644 --- a/cmd/nvidia-ctk/main.go +++ b/cmd/nvidia-ctk/main.go @@ -20,12 +20,11 @@ import ( "os" "github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-ctk/hook" + "github.com/NVIDIA/nvidia-container-toolkit/internal/info" log "github.com/sirupsen/logrus" cli "github.com/urfave/cli/v2" ) -var version string - var logger = log.New() // config defines the options that can be set for the CLI through config files, @@ -41,10 +40,11 @@ func main() { // Create the top-level CLI c := cli.NewApp() + c.Name = "NVIDIA Container Toolkit CLI" c.UseShortOptionHandling = true c.EnableBashCompletion = true c.Usage = "Tools to configure the NVIDIA Container Toolkit" - c.Version = version + c.Version = info.GetVersionString() // Setup the flags for this command c.Flags = []cli.Flag{ diff --git a/internal/info/version.go b/internal/info/version.go new file mode 100644 index 00000000..86d8cf08 --- /dev/null +++ b/internal/info/version.go @@ -0,0 +1,43 @@ +/** +# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +package info + +import "strings" + +// version must be set by go build's -X main.version= option in the Makefile. +var version = "unknown" + +// gitCommit will be the hash that the binary was built from +// and will be populated by the Makefile +var gitCommit = "" + +// GetVersionParts returns the different version components +func GetVersionParts() []string { + v := []string{version} + + if gitCommit != "" { + v = append(v, "commit: "+gitCommit) + } + + return v +} + +// GetVersionString returns the string representation of the version +func GetVersionString(more ...string) string { + v := append(GetVersionParts(), more...) + return strings.Join(v, "\n") +}