From a261f607648e88bd62dd77b297fd433f3e65750b Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Tue, 3 Dec 2024 08:45:44 +1300 Subject: [PATCH] version: display dependencies versions (#188) Co-authored-by: LP B --- api/build/variables.go | 12 -- api/cmd/portainer/main.go | 2 +- api/http/handler/system/version.go | 31 ++--- .../portainer/system/useSystemVersion.ts | 8 ++ app/react/sidebar/Footer/BuildInfoModal.tsx | 34 +++++- binary-version.json | 2 +- build/build_binary.sh | 34 ++++-- pkg/build/info.go | 106 ++++++++++++++++++ 8 files changed, 177 insertions(+), 52 deletions(-) delete mode 100644 api/build/variables.go create mode 100644 pkg/build/info.go diff --git a/api/build/variables.go b/api/build/variables.go deleted file mode 100644 index 2d5ab4ec0..000000000 --- a/api/build/variables.go +++ /dev/null @@ -1,12 +0,0 @@ -package build - -import "runtime" - -// Variables to be set during the build time -var BuildNumber string -var ImageTag string -var NodejsVersion string -var YarnVersion string -var WebpackVersion string -var GoVersion string = runtime.Version() -var GitCommit string diff --git a/api/cmd/portainer/main.go b/api/cmd/portainer/main.go index 5fbe54484..edc9cb897 100644 --- a/api/cmd/portainer/main.go +++ b/api/cmd/portainer/main.go @@ -10,7 +10,6 @@ import ( portainer "github.com/portainer/portainer/api" "github.com/portainer/portainer/api/apikey" - "github.com/portainer/portainer/api/build" "github.com/portainer/portainer/api/chisel" "github.com/portainer/portainer/api/cli" "github.com/portainer/portainer/api/crypto" @@ -47,6 +46,7 @@ import ( "github.com/portainer/portainer/api/platform" "github.com/portainer/portainer/api/scheduler" "github.com/portainer/portainer/api/stacks/deployments" + "github.com/portainer/portainer/pkg/build" "github.com/portainer/portainer/pkg/featureflags" "github.com/portainer/portainer/pkg/libhelm" "github.com/portainer/portainer/pkg/libstack/compose" diff --git a/api/http/handler/system/version.go b/api/http/handler/system/version.go index 0c07182a0..5c0324882 100644 --- a/api/http/handler/system/version.go +++ b/api/http/handler/system/version.go @@ -2,12 +2,11 @@ package system import ( "net/http" - "os" portainer "github.com/portainer/portainer/api" - "github.com/portainer/portainer/api/build" "github.com/portainer/portainer/api/http/client" "github.com/portainer/portainer/api/http/security" + "github.com/portainer/portainer/pkg/build" httperror "github.com/portainer/portainer/pkg/libhttp/error" "github.com/portainer/portainer/pkg/libhttp/response" @@ -25,18 +24,9 @@ type versionResponse struct { ServerVersion string ServerEdition string `json:"ServerEdition" example:"CE/EE"` DatabaseVersion string - Build BuildInfo -} - -type BuildInfo struct { - BuildNumber string - ImageTag string - NodejsVersion string - YarnVersion string - WebpackVersion string - GoVersion string - GitCommit string - Env []string `json:",omitempty"` + Build build.BuildInfo + Dependencies build.DependenciesInfo + Runtime build.RuntimeInfo } // @id systemVersion @@ -59,19 +49,12 @@ func (handler *Handler) version(w http.ResponseWriter, r *http.Request) *httperr ServerVersion: portainer.APIVersion, DatabaseVersion: portainer.APIVersion, ServerEdition: portainer.Edition.GetEditionLabel(), - Build: BuildInfo{ - BuildNumber: build.BuildNumber, - ImageTag: build.ImageTag, - NodejsVersion: build.NodejsVersion, - YarnVersion: build.YarnVersion, - WebpackVersion: build.WebpackVersion, - GoVersion: build.GoVersion, - GitCommit: build.GitCommit, - }, + Build: build.GetBuildInfo(), + Dependencies: build.GetDependenciesInfo(), } if isAdmin { - result.Build.Env = os.Environ() + result.Runtime = build.GetRuntimeInfo() } latestVersion := GetLatestVersion() diff --git a/app/react/portainer/system/useSystemVersion.ts b/app/react/portainer/system/useSystemVersion.ts index b4b38fa17..c1ef47330 100644 --- a/app/react/portainer/system/useSystemVersion.ts +++ b/app/react/portainer/system/useSystemVersion.ts @@ -22,6 +22,14 @@ export interface VersionResponse { WebpackVersion: string; GoVersion: string; GitCommit: string; + }; + Dependencies: { + DockerVersion: string; + HelmVersion: string; + KubectlVersion: string; + ComposeVersion: string; + }; + Runtime: { Env?: string[]; }; } diff --git a/app/react/sidebar/Footer/BuildInfoModal.tsx b/app/react/sidebar/Footer/BuildInfoModal.tsx index bf503e2dd..3839e5707 100644 --- a/app/react/sidebar/Footer/BuildInfoModal.tsx +++ b/app/react/sidebar/Footer/BuildInfoModal.tsx @@ -3,6 +3,7 @@ import { Database, GitCommit, Hash, + Link as LinkIcon, Server, Tag, Variable, @@ -56,7 +57,8 @@ function BuildInfoModal({ closeModal }: { closeModal: () => void }) { } const { Edition } = statusQuery.data; - const { ServerVersion, DatabaseVersion, Build } = versionQuery.data; + const { ServerVersion, DatabaseVersion, Build, Dependencies, Runtime } = + versionQuery.data; return ( @@ -111,17 +113,39 @@ function BuildInfoModal({ closeModal }: { closeModal: () => void }) {
- Nodejs v{Build.NodejsVersion} + Nodejs {Build.NodejsVersion} Yarn v{Build.YarnVersion} Webpack v{Build.WebpackVersion} - Go v{Build.GoVersion} + Go {Build.GoVersion}
- {isAdmin && Build.Env && ( +
+ + + Dependencies: + + +
+ + Docker {Dependencies.DockerVersion} + + + Helm {Dependencies.HelmVersion} + + + Kubectl {Dependencies.KubectlVersion} + + + Compose {Dependencies.ComposeVersion} + +
+
+ + {isAdmin && Runtime.Env && (
@@ -131,7 +155,7 @@ function BuildInfoModal({ closeModal }: { closeModal: () => void }) {
- {Build.Env.map((envVar) => ( + {Runtime.Env.map((envVar) => (
{envVar}
diff --git a/binary-version.json b/binary-version.json index 6642df364..8ef3e4793 100644 --- a/binary-version.json +++ b/binary-version.json @@ -3,4 +3,4 @@ "helm": "v3.15.4", "kubectl": "v1.31.0", "mingit": "2.46.0.1" -} \ No newline at end of file +} diff --git a/build/build_binary.sh b/build/build_binary.sh index 67d8726fb..402323923 100755 --- a/build/build_binary.sh +++ b/build/build_binary.sh @@ -1,6 +1,14 @@ #!/usr/bin/env bash set -euo pipefail +BUILD_SOURCESDIRECTORY=${BUILD_SOURCESDIRECTORY:-$(pwd)} +BINARY_VERSION_FILE="$BUILD_SOURCESDIRECTORY/binary-version.json" + +if [[ ! -f $BINARY_VERSION_FILE ]] ; then + echo 'File $BINARY_VERSION_FILE not found, aborting build.' + exit 1 +fi + mkdir -p dist # populate tool versions @@ -13,6 +21,12 @@ WEBPACK_VERSION=${WEBPACK_VERSION:-$(yarn list webpack --depth=0 | grep webpack GO_VERSION=${GO_VERSION:-$(go version | awk '{print $3}')} GIT_COMMIT_HASH=${GIT_COMMIT_HASH:-$(git rev-parse --short HEAD)} +# populate dependencies versions +DOCKER_VERSION=$(jq -r '.docker' < "${BINARY_VERSION_FILE}") +HELM_VERSION=$(jq -r '.helm' < "${BINARY_VERSION_FILE}") +KUBECTL_VERSION=$(jq -r '.kubectl' < "${BINARY_VERSION_FILE}") +COMPOSE_VERSION=$(go list -m -f '{{.Version}}' github.com/docker/compose/v2) + # copy templates cp -r "./mustache-templates" "./dist" @@ -23,15 +37,17 @@ go get -t -d -v ./... ldflags="-s -X 'github.com/portainer/liblicense.LicenseServerBaseURL=https://api.portainer.io' \ --X 'github.com/portainer/portainer/api/build.BuildNumber=${BUILDNUMBER}' \ --X 'github.com/portainer/portainer/api/build.ImageTag=${CONTAINER_IMAGE_TAG}' \ --X 'github.com/portainer/portainer/api/build.NodejsVersion=${NODE_VERSION}' \ --X 'github.com/portainer/portainer/api/build.YarnVersion=${YARN_VERSION}' \ --X 'github.com/portainer/portainer/api/build.WebpackVersion=${WEBPACK_VERSION}' \ --X 'github.com/portainer/portainer/api/build.GitCommit=${GIT_COMMIT_HASH}' \ --X 'github.com/portainer/portainer/api/build.GoVersion=${GO_VERSION}'" - -BINARY_VERSION_FILE="../binary-version.json" +-X 'github.com/portainer/portainer/pkg/build.BuildNumber=${BUILDNUMBER}' \ +-X 'github.com/portainer/portainer/pkg/build.ImageTag=${CONTAINER_IMAGE_TAG}' \ +-X 'github.com/portainer/portainer/pkg/build.NodejsVersion=${NODE_VERSION}' \ +-X 'github.com/portainer/portainer/pkg/build.YarnVersion=${YARN_VERSION}' \ +-X 'github.com/portainer/portainer/pkg/build.WebpackVersion=${WEBPACK_VERSION}' \ +-X 'github.com/portainer/portainer/pkg/build.GitCommit=${GIT_COMMIT_HASH}' \ +-X 'github.com/portainer/portainer/pkg/build.GoVersion=${GO_VERSION}' \ +-X 'github.com/portainer/portainer/pkg/build.DepComposeVersion=${COMPOSE_VERSION}' \ +-X 'github.com/portainer/portainer/pkg/build.DepDockerVersion=${DOCKER_VERSION}' \ +-X 'github.com/portainer/portainer/pkg/build.DepHelmVersion=${HELM_VERSION}' \ +-X 'github.com/portainer/portainer/pkg/build.DepKubectlVersion=${KUBECTL_VERSION}'" echo "$ldflags" diff --git a/pkg/build/info.go b/pkg/build/info.go new file mode 100644 index 000000000..fac320b4f --- /dev/null +++ b/pkg/build/info.go @@ -0,0 +1,106 @@ +package build + +import "os" + +/* +Package build contains variables that are set at build time using the -X linker flag. + +These variables provide metadata about the build environment and specify the +versions of dependencies shipped with the application. + +These variables are typically set during the build process using the -X flag with +the go build command, allowing for dynamic injection of build-time information. + +It also contains structs and methods that can be used to display build, dependencies and runtime information. +*/ + +var ( + // BuildNumber is the build number of the application. + BuildNumber string + + // ImageTag is the Docker image tag associated with this build. + ImageTag string + + // NodejsVersion is the version of Node.js used in the build. + NodejsVersion string + + // YarnVersion is the version of Yarn used in the build. + YarnVersion string + + // WebpackVersion is the version of Webpack used in the build. + WebpackVersion string + + // GoVersion is the version of Go used to compile the application. + GoVersion string + + // GitCommit is the Git commit hash at the time of the build. + GitCommit string + + // DepComposeVersion is the version of the Docker Compose plugin shipped with the application. + DepComposeVersion string + + // DepDockerVersion is the version of the Docker binary shipped with the application. + DepDockerVersion string + + // DepHelmVersion is the version of the Helm binary shipped with the application. + DepHelmVersion string + + // DepKubectlVersion is the version of the Kubectl binary shipped with the application. + DepKubectlVersion string +) + +type ( + // BuildInfo contains information about how an application was built + BuildInfo struct { + BuildNumber string + ImageTag string + NodejsVersion string + YarnVersion string + WebpackVersion string + GoVersion string + GitCommit string + } + + // DependenciesInfo contains information about the dependencies of Portainer + DependenciesInfo struct { + DockerVersion string + HelmVersion string + KubectlVersion string + ComposeVersion string + } + + // RuntimeInfo contains information about the runtime environment an application + RuntimeInfo struct { + Env []string `json:",omitempty"` + } +) + +// GetBuildInfo is a shortcut method to return the build information +func GetBuildInfo() BuildInfo { + return BuildInfo{ + BuildNumber: BuildNumber, + ImageTag: ImageTag, + NodejsVersion: NodejsVersion, + YarnVersion: YarnVersion, + WebpackVersion: WebpackVersion, + GoVersion: GoVersion, + GitCommit: GitCommit, + } +} + +// GetDependenciesInfo is a shortcut method to return the dependencies information +func GetDependenciesInfo() DependenciesInfo { + return DependenciesInfo{ + DockerVersion: DepDockerVersion, + HelmVersion: DepHelmVersion, + KubectlVersion: DepKubectlVersion, + ComposeVersion: DepComposeVersion, + } +} + +// GetRuntimeInfo is a shortcut method to return the runtime information +func GetRuntimeInfo() RuntimeInfo { + return RuntimeInfo{ + Env: os.Environ(), + } +}