mirror of https://github.com/kubernetes/kops.git
Add test for image name remap
This commit is contained in:
parent
df47310e41
commit
c74f956697
|
@ -0,0 +1,19 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["version.go"],
|
||||
importpath = "k8s.io/kops/pkg/k8sversion",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/apis/kops/util:go_default_library",
|
||||
"//vendor/github.com/blang/semver:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["version_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kops/pkg/k8sversion",
|
||||
)
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package k8sversion
|
||||
|
||||
import (
|
||||
"github.com/blang/semver"
|
||||
|
||||
"k8s.io/kops/pkg/apis/kops/util"
|
||||
)
|
||||
|
||||
// KubernetesVersion holds a semver-version of kubernetes
|
||||
type KubernetesVersion struct {
|
||||
semver semver.Version
|
||||
}
|
||||
|
||||
// Parse parses the string to determine the KubernetesVersion.
|
||||
// The version may be a semver version, or it may be a URL with the kubernetes version in the path
|
||||
func Parse(version string) (*KubernetesVersion, error) {
|
||||
sv, err := util.ParseKubernetesVersion(version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &KubernetesVersion{semver: *sv}, nil
|
||||
}
|
||||
|
||||
// IsGTE checks if the version is greater than or equal to the passed version. Pre and Build fields are ignored.
|
||||
// Panic if version is not valid, so version should only be used with static strings like "1.10"
|
||||
func (k *KubernetesVersion) IsGTE(version string) bool {
|
||||
return util.IsKubernetesGTE(version, k.semver)
|
||||
}
|
||||
|
||||
// String returns a string representation of the semver, like 1.10.1. It does not include a leading 'v'
|
||||
func (k *KubernetesVersion) String() string {
|
||||
return k.semver.String()
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package k8sversion
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
grid := []struct {
|
||||
Input string
|
||||
Expected string
|
||||
}{
|
||||
{Input: "1.1.0", Expected: "1.1.0"},
|
||||
{Input: "1.2.0", Expected: "1.2.0"},
|
||||
{Input: "1.3.0", Expected: "1.3.0"},
|
||||
{Input: "1.4.0", Expected: "1.4.0"},
|
||||
{Input: "1.5.0", Expected: "1.5.0"},
|
||||
{Input: "1.6.0", Expected: "1.6.0"},
|
||||
{Input: "1.7.0", Expected: "1.7.0"},
|
||||
{Input: "1.8.0", Expected: "1.8.0"},
|
||||
{Input: "1.9.0", Expected: "1.9.0"},
|
||||
{Input: "1.10.0", Expected: "1.10.0"},
|
||||
{Input: "v1.1.0-alpha1", Expected: "1.1.0-alpha1"},
|
||||
{Input: "https://example.com/v1.8.0-downloads", Expected: "1.8.0"},
|
||||
}
|
||||
|
||||
for _, g := range grid {
|
||||
actual, err := Parse(g.Input)
|
||||
if err != nil {
|
||||
t.Errorf("error parsing %q: %v", g.Input, err)
|
||||
continue
|
||||
}
|
||||
if actual.String() != g.Expected {
|
||||
t.Errorf("unexpected result parsing %q: actual=%q expected=%q", g.Input, actual.String(), g.Expected)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,6 +21,7 @@ go_library(
|
|||
"//pkg/apis/kops:go_default_library",
|
||||
"//pkg/apis/kops/util:go_default_library",
|
||||
"//pkg/assets:go_default_library",
|
||||
"//pkg/k8sversion:go_default_library",
|
||||
"//upup/pkg/fi:go_default_library",
|
||||
"//upup/pkg/fi/cloudup/gce:go_default_library",
|
||||
"//upup/pkg/fi/loader:go_default_library",
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
"k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/apis/kops/util"
|
||||
"k8s.io/kops/pkg/assets"
|
||||
"k8s.io/kops/pkg/k8sversion"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/gce"
|
||||
"k8s.io/kops/util/pkg/vfs"
|
||||
|
||||
|
@ -120,7 +121,7 @@ func WellKnownServiceIP(clusterSpec *kops.ClusterSpec, id int) (net.IP, error) {
|
|||
}
|
||||
|
||||
func IsBaseURL(kubernetesVersion string) bool {
|
||||
return strings.HasPrefix(kubernetesVersion, "http:") || strings.HasPrefix(kubernetesVersion, "https:")
|
||||
return strings.HasPrefix(kubernetesVersion, "http:") || strings.HasPrefix(kubernetesVersion, "https:") || strings.HasPrefix(kubernetesVersion, "memfs:")
|
||||
}
|
||||
|
||||
// Image returns the docker image name for the specified component
|
||||
|
@ -134,8 +135,13 @@ func Image(component string, clusterSpec *kops.ClusterSpec, assetsBuilder *asset
|
|||
return "k8s.gcr.io/kubedns-amd64:1.3", nil
|
||||
}
|
||||
|
||||
kubernetesVersion, err := k8sversion.Parse(clusterSpec.KubernetesVersion)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if !IsBaseURL(clusterSpec.KubernetesVersion) {
|
||||
image := "k8s.gcr.io/" + component + ":" + "v" + clusterSpec.KubernetesVersion
|
||||
image := "k8s.gcr.io/" + component + ":" + "v" + kubernetesVersion.String()
|
||||
|
||||
image, err := assetsBuilder.RemapImage(image)
|
||||
if err != nil {
|
||||
|
@ -158,7 +164,18 @@ func Image(component string, clusterSpec *kops.ClusterSpec, assetsBuilder *asset
|
|||
tag := strings.TrimSpace(string(b))
|
||||
glog.V(2).Infof("Found tag %q for %q", tag, component)
|
||||
|
||||
return "k8s.gcr.io/" + component + ":" + tag, nil
|
||||
image := "k8s.gcr.io/" + component + ":" + tag
|
||||
|
||||
// When we're using a docker load-ed image, we are likely a CI build.
|
||||
// But the k8s.gcr.io prefix is an alias, and we only double-tagged from 1.10 onwards.
|
||||
// For versions prior to 1.10, remap k8s.gcr.io to the old name.
|
||||
// This also means that we won't start using the aliased names on existing clusters,
|
||||
// which could otherwise be surprising to users.
|
||||
if !kubernetesVersion.IsGTE("1.10") {
|
||||
image = "gcr.io/google_containers/" + strings.TrimPrefix(image, "k8s.gcr.io/")
|
||||
}
|
||||
|
||||
return image, nil
|
||||
}
|
||||
|
||||
func GCETagForRole(clusterName string, role kops.InstanceGroupRole) string {
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package components
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/assets"
|
||||
"k8s.io/kops/util/pkg/vfs"
|
||||
)
|
||||
|
||||
func TestImage(t *testing.T) {
|
||||
grid := []struct {
|
||||
Component string
|
||||
Cluster *kops.Cluster
|
||||
|
||||
// File to put into VFS for the test
|
||||
VFS map[string]string
|
||||
|
||||
Expected string
|
||||
}{
|
||||
{
|
||||
Component: "kube-apiserver",
|
||||
Cluster: &kops.Cluster{
|
||||
Spec: kops.ClusterSpec{
|
||||
KubernetesVersion: "v1.9.0",
|
||||
},
|
||||
},
|
||||
Expected: "gcr.io/google_containers/kube-apiserver:v1.9.0",
|
||||
},
|
||||
{
|
||||
Component: "kube-apiserver",
|
||||
Cluster: &kops.Cluster{
|
||||
Spec: kops.ClusterSpec{
|
||||
KubernetesVersion: "v1.10.0",
|
||||
},
|
||||
},
|
||||
Expected: "k8s.gcr.io/kube-apiserver:v1.10.0",
|
||||
},
|
||||
{
|
||||
Component: "kube-apiserver",
|
||||
Cluster: &kops.Cluster{
|
||||
Spec: kops.ClusterSpec{
|
||||
KubernetesVersion: "1.10.0",
|
||||
},
|
||||
},
|
||||
Expected: "k8s.gcr.io/kube-apiserver:v1.10.0",
|
||||
},
|
||||
{
|
||||
Component: "kube-apiserver",
|
||||
Cluster: &kops.Cluster{
|
||||
Spec: kops.ClusterSpec{
|
||||
KubernetesVersion: "memfs://v1.9.0-download/",
|
||||
},
|
||||
},
|
||||
VFS: map[string]string{
|
||||
"memfs://v1.9.0-download/bin/linux/amd64/kube-apiserver.docker_tag": "1-9-0dockertag",
|
||||
},
|
||||
Expected: "gcr.io/google_containers/kube-apiserver:1-9-0dockertag",
|
||||
},
|
||||
{
|
||||
Component: "kube-apiserver",
|
||||
Cluster: &kops.Cluster{
|
||||
Spec: kops.ClusterSpec{
|
||||
KubernetesVersion: "memfs://v1.10.0-download/",
|
||||
},
|
||||
},
|
||||
VFS: map[string]string{
|
||||
"memfs://v1.10.0-download/bin/linux/amd64/kube-apiserver.docker_tag": "1-10-0dockertag",
|
||||
},
|
||||
Expected: "k8s.gcr.io/kube-apiserver:1-10-0dockertag",
|
||||
},
|
||||
}
|
||||
|
||||
for _, g := range grid {
|
||||
vfs.Context.ResetMemfsContext(true)
|
||||
|
||||
// Populate VFS files
|
||||
for k, v := range g.VFS {
|
||||
p, err := vfs.Context.BuildVfsPath(k)
|
||||
if err != nil {
|
||||
t.Errorf("error building vfs path for %s: %v", k, err)
|
||||
continue
|
||||
}
|
||||
if err := p.WriteFile([]byte(v), nil); err != nil {
|
||||
t.Errorf("error writing vfs path %s: %v", k, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
assetBuilder := assets.NewAssetBuilder(g.Cluster, "")
|
||||
actual, err := Image(g.Component, &g.Cluster.Spec, assetBuilder)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error from image %q %v: %v",
|
||||
g.Component, g.Cluster.Spec.KubernetesVersion, err)
|
||||
continue
|
||||
}
|
||||
if actual != g.Expected {
|
||||
t.Errorf("unexpected result from image %q %v: actual=%q, expected=%q",
|
||||
g.Component, g.Cluster.Spec.KubernetesVersion, actual, g.Expected)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue