From c4b49afad37b4e64a1aa2b90f4d3b04626fabd44 Mon Sep 17 00:00:00 2001
From: Jhon Honce <jhonce@redhat.com>
Date: Fri, 18 Sep 2020 14:10:14 -0700
Subject: [PATCH] Refactor version handling in cmd tree

* Move from simple string to semver objects
* Change client API Version from '1' to 2.0.0

Signed-off-by: Jhon Honce <jhonce@redhat.com>
---
 cmd/podman/root.go                     |  2 +-
 cmd/podman/system/version.go           |  2 +-
 hack/release.sh                        |  2 +-
 libpod/define/version.go               | 10 +++++-----
 pkg/bindings/bindings.go               |  2 +-
 pkg/bindings/system/system.go          | 10 ++++++++--
 pkg/domain/infra/abi/system_varlink.go |  2 +-
 pkg/systemd/generate/containers.go     |  2 +-
 pkg/systemd/generate/pods.go           |  2 +-
 test/e2e/version_test.go               |  6 +++---
 version/version.go                     |  8 ++++++--
 11 files changed, 29 insertions(+), 19 deletions(-)

diff --git a/cmd/podman/root.go b/cmd/podman/root.go
index 8def7112fc..6424ec12e1 100644
--- a/cmd/podman/root.go
+++ b/cmd/podman/root.go
@@ -63,7 +63,7 @@ var (
 		PersistentPreRunE:  persistentPreRunE,
 		RunE:               validate.SubCommandExists,
 		PersistentPostRunE: persistentPostRunE,
-		Version:            version.Version,
+		Version:            version.Version.String(),
 	}
 
 	logLevels = []string{"debug", "info", "warn", "error", "fatal", "panic"}
diff --git a/cmd/podman/system/version.go b/cmd/podman/system/version.go
index 5f39b4820b..9da7da54a3 100644
--- a/cmd/podman/system/version.go
+++ b/cmd/podman/system/version.go
@@ -83,7 +83,7 @@ func version(cmd *cobra.Command, args []string) error {
 
 func formatVersion(writer io.Writer, version *define.Version) {
 	fmt.Fprintf(writer, "Version:\t%s\n", version.Version)
-	fmt.Fprintf(writer, "API Version:\t%d\n", version.APIVersion)
+	fmt.Fprintf(writer, "API Version:\t%s\n", version.APIVersion)
 	fmt.Fprintf(writer, "Go Version:\t%s\n", version.GoVersion)
 	if version.GitCommit != "" {
 		fmt.Fprintf(writer, "Git Commit:\t%s\n", version.GitCommit)
diff --git a/hack/release.sh b/hack/release.sh
index 465fa6cd95..56cd040796 100755
--- a/hack/release.sh
+++ b/hack/release.sh
@@ -27,7 +27,7 @@ LAST_TAG=$(git describe --tags --abbrev=0)
 write_go_version()
 {
 	LOCAL_VERSION="$1"
-	sed -i "s/^\(const Version = \"\).*/\1${LOCAL_VERSION}\"/" version/version.go
+	sed -i "s/^\(var Version = semver.MustParse\( \"\).*/\1${LOCAL_VERSION}\"\)/" version/version.go
 }
 
 write_spec_version()
diff --git a/libpod/define/version.go b/libpod/define/version.go
index daa5cf7b24..d4cdd539de 100644
--- a/libpod/define/version.go
+++ b/libpod/define/version.go
@@ -18,9 +18,9 @@ var (
 	buildInfo string
 )
 
-// Version is an output struct for varlink
+// Version is an output struct for API
 type Version struct {
-	APIVersion int64
+	APIVersion string
 	Version    string
 	GoVersion  string
 	GitCommit  string
@@ -29,7 +29,7 @@ type Version struct {
 	OsArch     string
 }
 
-// GetVersion returns a VersionOutput struct for varlink and podman
+// GetVersion returns a VersionOutput struct for API and podman
 func GetVersion() (Version, error) {
 	var err error
 	var buildTime int64
@@ -42,8 +42,8 @@ func GetVersion() (Version, error) {
 		}
 	}
 	return Version{
-		APIVersion: podmanVersion.APIVersion,
-		Version:    podmanVersion.Version,
+		APIVersion: podmanVersion.APIVersion.String(),
+		Version:    podmanVersion.Version.String(),
 		GoVersion:  runtime.Version(),
 		GitCommit:  gitCommit,
 		BuiltTime:  time.Unix(buildTime, 0).Format(time.ANSIC),
diff --git a/pkg/bindings/bindings.go b/pkg/bindings/bindings.go
index ae5610b0f3..14f3069108 100644
--- a/pkg/bindings/bindings.go
+++ b/pkg/bindings/bindings.go
@@ -22,5 +22,5 @@ var (
 	PFalse = &pFalse
 
 	// APIVersion - podman will fail to run if this value is wrong
-	APIVersion = semver.MustParse("1.0.0")
+	APIVersion = semver.MustParse("2.0.0")
 )
diff --git a/pkg/bindings/system/system.go b/pkg/bindings/system/system.go
index e995770ba9..1203f5c3cb 100644
--- a/pkg/bindings/system/system.go
+++ b/pkg/bindings/system/system.go
@@ -118,10 +118,10 @@ func Version(ctx context.Context) (*entities.SystemVersionReport, error) {
 	if err = response.Process(&component); err != nil {
 		return nil, err
 	}
-	f, _ := strconv.ParseFloat(component.APIVersion, 64)
+
 	b, _ := time.Parse(time.RFC3339, component.BuildTime)
 	report.Server = &define.Version{
-		APIVersion: int64(f),
+		APIVersion: component.APIVersion,
 		Version:    component.Version.Version,
 		GoVersion:  component.GoVersion,
 		GitCommit:  component.GitCommit,
@@ -129,6 +129,12 @@ func Version(ctx context.Context) (*entities.SystemVersionReport, error) {
 		Built:      b.Unix(),
 		OsArch:     fmt.Sprintf("%s/%s", component.Os, component.Arch),
 	}
+
+	for _, c := range component.Components {
+		if c.Name == "Podman Engine" {
+			report.Server.APIVersion = c.Details["APIVersion"]
+		}
+	}
 	return &report, err
 }
 
diff --git a/pkg/domain/infra/abi/system_varlink.go b/pkg/domain/infra/abi/system_varlink.go
index d0a5c5407a..ead84fc844 100644
--- a/pkg/domain/infra/abi/system_varlink.go
+++ b/pkg/domain/infra/abi/system_varlink.go
@@ -22,7 +22,7 @@ func (ic *ContainerEngine) VarlinkService(_ context.Context, opts entities.Servi
 	service, err := varlink.NewService(
 		"Atomic",
 		"podman",
-		version.Version,
+		version.Version.String(),
 		"https://github.com/containers/podman",
 	)
 	if err != nil {
diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go
index a4fdae46ee..8090bcd3d3 100644
--- a/pkg/systemd/generate/containers.go
+++ b/pkg/systemd/generate/containers.go
@@ -256,7 +256,7 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
 	}
 
 	if info.PodmanVersion == "" {
-		info.PodmanVersion = version.Version
+		info.PodmanVersion = version.Version.String()
 	}
 	if info.GenerateTimestamp {
 		info.TimeStamp = fmt.Sprintf("%v", time.Now().Format(time.UnixDate))
diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go
index c41eedd17b..c0acba37d2 100644
--- a/pkg/systemd/generate/pods.go
+++ b/pkg/systemd/generate/pods.go
@@ -299,7 +299,7 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
 		info.ExecStopPost = "{{.Executable}} pod rm --ignore -f --pod-id-file {{.PodIDFile}}"
 	}
 	if info.PodmanVersion == "" {
-		info.PodmanVersion = version.Version
+		info.PodmanVersion = version.Version.String()
 	}
 	if info.GenerateTimestamp {
 		info.TimeStamp = fmt.Sprintf("%v", time.Now().Format(time.UnixDate))
diff --git a/test/e2e/version_test.go b/test/e2e/version_test.go
index 9ddbcc58fa..695cccc111 100644
--- a/test/e2e/version_test.go
+++ b/test/e2e/version_test.go
@@ -37,21 +37,21 @@ var _ = Describe("Podman version", func() {
 		session := podmanTest.Podman([]string{"version"})
 		session.WaitWithDefaultTimeout()
 		Expect(session).Should(Exit(0))
-		Expect(session.Out.Contents()).Should(ContainSubstring(version.Version))
+		Expect(session.Out.Contents()).Should(ContainSubstring(version.Version.String()))
 	})
 
 	It("podman -v", func() {
 		session := podmanTest.Podman([]string{"-v"})
 		session.WaitWithDefaultTimeout()
 		Expect(session).Should(Exit(0))
-		Expect(session.Out.Contents()).Should(ContainSubstring(version.Version))
+		Expect(session.Out.Contents()).Should(ContainSubstring(version.Version.String()))
 	})
 
 	It("podman --version", func() {
 		session := podmanTest.Podman([]string{"--version"})
 		session.WaitWithDefaultTimeout()
 		Expect(session).Should(Exit(0))
-		Expect(session.Out.Contents()).Should(ContainSubstring(version.Version))
+		Expect(session.Out.Contents()).Should(ContainSubstring(version.Version.String()))
 	})
 
 	It("podman version --format json", func() {
diff --git a/version/version.go b/version/version.go
index 2e1335d2dc..df2e4f2ba0 100644
--- a/version/version.go
+++ b/version/version.go
@@ -1,12 +1,16 @@
 package version
 
+import (
+	"github.com/blang/semver"
+)
+
 // Version is the version of the build.
 // NOTE: remember to bump the version at the top
 // of the top-level README.md file when this is
 // bumped.
-const Version = "2.1.0-dev"
+var Version = semver.MustParse("2.1.0-dev")
 
 // APIVersion is the version for the remote
 // client API.  It is used to determine compatibility
 // between a remote podman client and its backend
-const APIVersion = 1
+var APIVersion = semver.MustParse("2.0.0")