查看v0.5.1 的kfserving go.mod 文件,我看到了a big block of replace directives。按照设计,replace directives“只适用于主模块的go.mod 文件,而在其他模块中被忽略”,所以看起来kfserving 在这里有一些技术债务,他们正在转嫁给你。
我从一个空的go.mod 文件开始,然后粘贴到那些replace 指令中。那么:
$ go get -d github.com/kubeflow/kfserving/pkg/client/clientset/versioned@v0.5.1
go get: added github.com/PuerkitoBio/purell v1.1.1
…
go get: added sigs.k8s.io/yaml v1.2.0
.go 源文件需要对拼写错误和不匹配的类型进行一些修复。我捏造了它:
package main
import (
"fmt"
kfs "github.com/kubeflow/kfserving/pkg/client/clientset/versioned"
)
func main() {
var clientset *kfs.Clientset
clientset = kfs.NewForConfigOrDie(nil)
fmt.Println(clientset)
}
然后go build . 成功:
$ go build -o /dev/null .
现在我将运行 go mod tidy 来清理 go.mod 和 go.sum 文件:
$ go mod tidy
go: downloading github.com/stretchr/testify v1.5.1
…
go: downloading github.com/jmespath/go-jmespath v0.3.0
但是等等!我仍然从kfserving/go.mod 那里得到了所有的技术债务——没有任何 cmets 解释版本的选择! ——我将把技术债务转嫁给任何下游用户。让我们看看我在这里是否可以改善情况。
Go 1.16 处理 exclude 指令比以前的 Go 版本好很多,所以也许我可以使用几个有针对性的 exclude 指令而不是(相当大的)replace 锤子。
我将从提交到目前为止的修复开始。 (如果不出意外,我希望能够git diff 要求查看发生了什么变化。)
$ git add *.go go.mod go.sum
$ git commit -m 'fixed kfserving build'
[main fd93b1d] fixed kfserving build
3 files changed, 1643 insertions(+), 2 deletions(-)
create mode 100644 go.sum
我注意到所有replace 指令都适用于k8s.io 路径,因此我将列出这些路径的当前版本以查看需要修复的内容:
$ go list -m k8s.io/...
k8s.io/api v0.19.2 => k8s.io/api v0.19.2
k8s.io/apiextensions-apiserver v0.19.2 => k8s.io/apiextensions-apiserver v0.19.2
k8s.io/apimachinery v0.19.2 => k8s.io/apimachinery v0.19.2
k8s.io/apiserver v0.19.2 => k8s.io/apiserver v0.19.2
k8s.io/client-go v11.0.1-0.20190805182717-6502b5e7b1b5+incompatible => k8s.io/client-go v0.19.2
k8s.io/cloud-provider v0.19.2 => k8s.io/cloud-provider v0.19.2
k8s.io/code-generator v0.19.2 => k8s.io/code-generator v0.19.2
k8s.io/component-base v0.19.2 => k8s.io/component-base v0.19.2
k8s.io/csi-translation-lib v0.19.2 => k8s.io/csi-translation-lib v0.19.2
k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14
k8s.io/klog v1.0.0 => k8s.io/klog v1.0.0
k8s.io/klog/v2 v2.2.0
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6
k8s.io/legacy-cloud-providers v0.17.4 => k8s.io/legacy-cloud-providers v0.19.2
k8s.io/test-infra v0.0.0-20200803112140-d8aa4e063646 => k8s.io/test-infra v0.0.0-20200803112140-d8aa4e063646
k8s.io/utils v0.0.0-20200912215256-4140de9c8800 => k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89
大部分看起来都不错,但有三个不匹配的版本:
k8s.io/client-go v11.0.1-0.20190805182717-6502b5e7b1b5+incompatible => k8s.io/client-go v0.19.2
…
k8s.io/legacy-cloud-providers v0.17.4 => k8s.io/legacy-cloud-providers v0.19.2
…
k8s.io/utils v0.0.0-20200912215256-4140de9c8800 => k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89
legacy-cloud-providers 只需要升级,所以用go get 修复应该很容易——但无论如何它与这个包无关,所以我可以让它浮动到它最终的任何版本。我将把 replace 指令减少到剩下的两个模块,看看我能走多远:
replace (
k8s.io/client-go => k8s.io/client-go v0.19.2
k8s.io/utils => k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89
)
现在:
$ go mod tidy
$ go build -o /dev/null .
好的,所以构建仍然很好——我已经取得了渐进的进展,所以我会锁定它:
$ git add go.mod go.sum
$ git commit -m 'go.mod: remove irrelevant replacements'
[main cdbc1db] go.mod: remove irrelevant replacements
3 files changed, 456 insertions(+), 43 deletions(-)
rewrite go.mod (85%)
create mode 100755 m
现在让我们尝试使用exclude 指令剔除不良的client-go 版本:
$ go mod edit -exclude=k8s.io/client-go@v11.0.1-0.20190805182717-6502b5e7b1b5+incompatible
$ go list -m k8s.io/client-go
k8s.io/client-go v9.0.0+incompatible => k8s.io/client-go v0.19.2
$ go mod edit -exclude=k8s.io/client-go@v9.0.0+incompatible
$ go list -m k8s.io/client-go
k8s.io/client-go v0.19.2 => k8s.io/client-go v0.19.2
现在我处于我需要的 client-go 版本,所以我可以放弃 replace 指令:
$ go mod edit -dropreplace=k8s.io/client-go
$ go mod tidy
$ go build -o /dev/null .
再次将其锁定:
$ git add go.mod go.sum
$ git commit -m 'go.mod: use exclude instead of replace to notch out unwanted client-go versions'
[main de69965] go.mod: use exclude instead of replace to notch out unwanted client-go versions
2 files changed, 21 insertions(+), 3 deletions(-)
现在让我们看看这个 k8s.io/utils 替换发生了什么。我怀疑它并不是真正需要的——版本会升级一点,但我打赌它不会破坏构建。而且,确实,这似乎很好:
$ go list -m k8s.io/utils
k8s.io/utils v0.0.0-20200912215256-4140de9c8800 => k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89
$ go mod edit -dropreplace=k8s.io/utils
$ go mod tidy
$ go build -o /dev/null .
$ go list -m k8s.io/utils
k8s.io/utils v0.0.0-20200912215256-4140de9c8800
所以现在我已经成功地将 replace 指令的大巢从 kfserving 减少到只有几个 exclude 指令针对 k8s.io/client-go 的撤回版本。这是我在此过程结束时的整个go.mod 文件:
module example.com/m
go 1.16
exclude (
k8s.io/client-go v11.0.1-0.20190805182717-6502b5e7b1b5+incompatible
k8s.io/client-go v9.0.0+incompatible
)
require github.com/kubeflow/kfserving v0.5.1