前言

最近在使用 sealos 安装更新 k8s 的过程中发现了一个问题: nfo new cluster version v1.25.10 behind the current version v1.25.8

现在我来简单描述下过程: 我想要将 k8s 版本从 v1.25.8 升级到 v1.25.10,运行更新命令: sealos run labring/kubernetes:v1.25.10-4.2.0 -f 后,出现了以下错误信息: 2023-06-09T11:30:06 info new cluster version v1.25.10 behind the current version v1.25.8 ,通过对错误信息的理解,发现提示 v1.25.10 版本比 v1.25.8小,通过我对版本号的理解,这应该是个错误。

发现及解决问题

发现了问题,接下来要寻找出现问题的代码和解决问题。通过 Github 的代码搜索功能搜索关键字 behind the current version 顺利找到问题代码所在。

img.png

对找到的代码进行分析,发现是 versionutil.Compare(curversion, version) 方法出现了错误,我们来看看这个函数的代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
func Compare(v1, v2 string) bool {
	v1 = strings.Replace(v1, "v", "", -1)
	v2 = strings.Replace(v2, "v", "", -1)
	v1 = strings.Split(v1, "-")[0]
	v2 = strings.Split(v2, "-")[0]
	v1List := strings.Split(v1, ".")
	v2List := strings.Split(v2, ".")

	if len(v1List) != 3 || len(v2List) != 3 {
		logger.Error("error version format %s %s", v1, v2)
		return false
	}
	if v1List[0] > v2List[0] {
		return true
	} else if v1List[0] < v2List[0] {
		return false
	}
	if v1List[1] > v2List[1] {
		return true
	} else if v1List[1] < v2List[1] {
		return false
	}
	if v1List[2] >= v2List[2] {
		return true
	}
	return false
}

通过对代码的分析,发现是对主次修订版本号对比时出现了问题,代码中是简单的使用了字符串比较,字符串数字比较会以字典序进行比较,所以会出现 “8” 大于 “10"的情况。正常的数字比较应该是将字符串转为数字进行相应比较。

找到问题后,我就想着提个PR来解决问题,在提PR前,我将这段代码输给AI来看看还有哪些问题。

img_2.png

我们根据 AI发现的几个问题和前面的问题,进行了代码修改,修改后的代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
func Compare(v1, v2 string) bool {
	v1 = strings.Replace(v1, "v", "", -1)
	v2 = strings.Replace(v2, "v", "", -1)
	v1 = strings.Split(v1, "-")[0]
	v2 = strings.Split(v2, "-")[0]
	v1List := strings.Split(v1, ".")
	v2List := strings.Split(v2, ".")

	if len(v1List) != 3 || len(v2List) != 3 {
		logger.Error("error version format %s %s", v1, v2)
		return false
	}
	for i := 0; i < len(v1List); i++ {
		v1Num, _ := strconv.Atoi(v1List[i])
		v2Num, _ := strconv.Atoi(v2List[i])

		if v1Num > v2Num {
			return true
		} else if v1Num < v2Num {
			return false
		}
	}

	return true
}

小结

本文讲述了在使用开源项目的过程中发现了问题并解决问题的过程。

参考