Files
kubevpn/pkg/util/version.go
2025-04-03 21:41:35 +08:00

120 lines
3.1 KiB
Go

package util
import (
"fmt"
"github.com/distribution/reference"
"github.com/hashicorp/go-version"
"github.com/pkg/errors"
)
// CmpClientVersionAndClientImage
/**
version: MAJOR.MINOR.PATCH
client version should match client image
MAJOR and MINOR different should be same, otherwise just exit let use to special matched image with options --image
*/
func CmpClientVersionAndClientImage(clientVersion, clientImgStr string) (int, error) {
clientImg, err := reference.ParseNormalizedNamed(clientImgStr)
if err != nil {
return 0, err
}
clientImgTag, ok := clientImg.(reference.NamedTagged)
if !ok {
return 0, fmt.Errorf("can not convert client image")
}
// 1. if client image version is match client cli version, does not need to upgrade
// kubevpn connect --image=ghcr.io/kubenetworks/kubevpn:v2.3.0 or --kubevpnconfig
// the kubevpn version is v2.3.1
if cmp := CmpVersionMajorOrMinor(clientVersion, clientImgTag.Tag()); cmp != 0 {
// exit the process
return cmp, nil
}
return 0, nil
}
// CmpClientVersionAndPodImageTag version MAJOR.MINOR.PATCH
// if MAJOR or MINOR different, needs to upgrade
// otherwise not need upgrade
func CmpClientVersionAndPodImageTag(clientVersion string, serverImgStr string) int {
serverImg, err := reference.ParseNormalizedNamed(serverImgStr)
if err != nil {
return 0
}
serverImgTag, ok := serverImg.(reference.NamedTagged)
if !ok {
return 0
}
return CmpVersionMajorOrMinor(clientVersion, serverImgTag.Tag())
}
func CmpVersionMajorOrMinor(v1 string, v2 string) int {
version1, err := version.NewVersion(v1)
if err != nil {
return 0
}
version2, err := version.NewVersion(v2)
if err != nil {
return 0
}
if len(version1.Segments64()) != 3 {
return 0
}
if len(version2.Segments64()) != 3 {
return 0
}
if version1.Segments64()[0] > version2.Segments64()[0] {
return 1
} else if version1.Segments64()[0] < version2.Segments64()[0] {
return -1
}
if version1.Segments64()[1] > version2.Segments64()[1] {
return 1
} else if version1.Segments64()[1] < version2.Segments64()[1] {
return -1
}
return 0
}
func GetTargetImage(version string, image string) string {
serverImg, err := reference.ParseNormalizedNamed(image)
if err != nil {
return ""
}
serverImgTag, ok := serverImg.(reference.NamedTagged)
if !ok {
return ""
}
tag, err := reference.WithTag(serverImgTag, version)
if err != nil {
return ""
}
return tag.String()
}
// IsNewer
/**
version: MAJOR.MINOR.PATCH
MAJOR and MINOR different should be same, otherwise needs upgrade
*/
func IsNewer(clientVer string, clientImg string, serverImg string) (bool, error) {
isNeedUpgrade, _ := CmpClientVersionAndClientImage(clientVer, clientImg)
if isNeedUpgrade != 0 {
err := errors.New("\n" + PrintStr(fmt.Sprintf("Client version and image tag not compatible. client version: %s, image: %s", clientVer, clientImg)))
return true, err
}
cmp := CmpClientVersionAndPodImageTag(clientVer, serverImg)
if cmp > 0 {
return true, nil
} else if cmp < 0 {
err := errors.New("\n" + PrintStr(fmt.Sprintf("Client version too old. client version: %s, server version: %s", clientVer, serverImg)))
return true, err
}
return false, nil
}