diff --git a/exp/cluster-api-provider-kubekey/api/v1beta1/component_types.go b/exp/cluster-api-provider-kubekey/api/v1beta1/component_types.go new file mode 100644 index 00000000..5bf0b932 --- /dev/null +++ b/exp/cluster-api-provider-kubekey/api/v1beta1/component_types.go @@ -0,0 +1,51 @@ +/* + Copyright 2022 The KubeSphere 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 v1beta1 + +// Component is optional configuration for modifying the FTP server. +type Component struct { + // ZONE is the zone of the KKCluster where can get the binaries. + // If you have problem to access https://storage.googleapis.com, you can set "zone: cn". + ZONE string `json:"zone,omitempty"` + + // Host is the host to download the binaries. + Host string `json:"host,omitempty"` + + // Overrides is a list of components download information that need to be overridden. + Overrides []Override `json:"overrides,omitempty"` +} + +// Override is a component download information that need to be overridden. +type Override struct { + // ID is the component id name. e.g. kubeadm, kubelet, containerd, etc. + ID string `json:"id,omitempty"` + + // Arch is the component arch. e.g. amd64, arm64, etc. + Arch string `json:"arch,omitempty"` + + // Version is the component version. e.g. v1.21.1, v1.22.0, etc. + Version string `json:"version,omitempty"` + + // URL is the download url of the binaries. + URL string `json:"url,omitempty"` + + // Path defines the URL path, which is the string of information that comes after the top level domain name. + Path string `json:"path,omitempty"` + + // Checksum is the SHA256 checksum of the binary. + Checksum string `json:"checksum,omitempty"` +} diff --git a/exp/cluster-api-provider-kubekey/api/v1beta1/kkcluster_types.go b/exp/cluster-api-provider-kubekey/api/v1beta1/kkcluster_types.go index 4197c1d5..854fad95 100644 --- a/exp/cluster-api-provider-kubekey/api/v1beta1/kkcluster_types.go +++ b/exp/cluster-api-provider-kubekey/api/v1beta1/kkcluster_types.go @@ -30,9 +30,6 @@ const ( // KKClusterSpec defines the desired state of KKCluster type KKClusterSpec struct { - // ZONE is the zone of the KKCluster where can get the binaries. - // If you have problem to access https://storage.googleapis.com, you can set "zone: cn". - ZONE string `json:"zone,omitempty"` // Nodes represents the information about the nodes available to the cluster Nodes Nodes `json:"nodes"` @@ -45,6 +42,11 @@ type KKClusterSpec struct { // +optional ControlPlaneLoadBalancer *KKLoadBalancerSpec `json:"controlPlaneLoadBalancer,omitempty"` + // Component is optional configuration for modifying the FTP server + // that gets the necessary components for the cluster. + // +optional + Component *Component `json:"component,omitempty"` + // Registry represents the cluster image registry used to pull the images. // +optional Registry Registry `json:"registry"` diff --git a/exp/cluster-api-provider-kubekey/api/v1beta1/zz_generated.deepcopy.go b/exp/cluster-api-provider-kubekey/api/v1beta1/zz_generated.deepcopy.go index fd341bf8..05b012a2 100644 --- a/exp/cluster-api-provider-kubekey/api/v1beta1/zz_generated.deepcopy.go +++ b/exp/cluster-api-provider-kubekey/api/v1beta1/zz_generated.deepcopy.go @@ -53,6 +53,26 @@ func (in *Auth) DeepCopy() *Auth { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Component) DeepCopyInto(out *Component) { + *out = *in + if in.Overrides != nil { + in, out := &in.Overrides, &out.Overrides + *out = make([]Override, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Component. +func (in *Component) DeepCopy() *Component { + if in == nil { + return nil + } + out := new(Component) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ContainerManager) DeepCopyInto(out *ContainerManager) { *out = *in @@ -137,6 +157,11 @@ func (in *KKClusterSpec) DeepCopyInto(out *KKClusterSpec) { *out = new(KKLoadBalancerSpec) **out = **in } + if in.Component != nil { + in, out := &in.Component, &out.Component + *out = new(Component) + (*in).DeepCopyInto(*out) + } in.Registry.DeepCopyInto(&out.Registry) } @@ -648,6 +673,21 @@ func (in *Nodes) DeepCopy() *Nodes { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Override) DeepCopyInto(out *Override) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Override. +func (in *Override) DeepCopy() *Override { + if in == nil { + return nil + } + out := new(Override) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Registry) DeepCopyInto(out *Registry) { *out = *in diff --git a/exp/cluster-api-provider-kubekey/config/crd/bases/infrastructure.cluster.x-k8s.io_kkclusters.yaml b/exp/cluster-api-provider-kubekey/config/crd/bases/infrastructure.cluster.x-k8s.io_kkclusters.yaml index dd50551f..d6274396 100644 --- a/exp/cluster-api-provider-kubekey/config/crd/bases/infrastructure.cluster.x-k8s.io_kkclusters.yaml +++ b/exp/cluster-api-provider-kubekey/config/crd/bases/infrastructure.cluster.x-k8s.io_kkclusters.yaml @@ -53,6 +53,50 @@ spec: spec: description: KKClusterSpec defines the desired state of KKCluster properties: + component: + description: Component is optional configuration for modifying the + FTP server that gets the necessary components for the cluster. + properties: + host: + description: Host is the host to download the binaries. + type: string + overrides: + description: Overrides is a list of components download information + that need to be overridden. + items: + description: Override is a component download information that + need to be overridden. + properties: + arch: + description: Arch is the component arch. e.g. amd64, arm64, + etc. + type: string + checksum: + description: Checksum is the SHA256 checksum of the binary. + type: string + id: + description: ID is the component id name. e.g. kubeadm, + kubelet, containerd, etc. + type: string + path: + description: Path defines the URL path, which is the string + of information that comes after the top level domain name. + type: string + url: + description: URL is the download url of the binaries. + type: string + version: + description: Version is the component version. e.g. v1.21.1, + v1.22.0, etc. + type: string + type: object + type: array + zone: + description: 'ZONE is the zone of the KKCluster where can get + the binaries. If you have problem to access https://storage.googleapis.com, + you can set "zone: cn".' + type: string + type: object controlPlaneEndpoint: description: ControlPlaneEndpoint represents the endpoint used to communicate with the control plane. @@ -276,11 +320,6 @@ spec: - namespaceOverride - privateRegistry type: object - zone: - description: 'ZONE is the zone of the KKCluster where can get the - binaries. If you have problem to access https://storage.googleapis.com, - you can set "zone: cn".' - type: string required: - nodes type: object diff --git a/exp/cluster-api-provider-kubekey/config/crd/bases/infrastructure.cluster.x-k8s.io_kkclustertemplates.yaml b/exp/cluster-api-provider-kubekey/config/crd/bases/infrastructure.cluster.x-k8s.io_kkclustertemplates.yaml index b98f2c40..3c9bc15d 100644 --- a/exp/cluster-api-provider-kubekey/config/crd/bases/infrastructure.cluster.x-k8s.io_kkclustertemplates.yaml +++ b/exp/cluster-api-provider-kubekey/config/crd/bases/infrastructure.cluster.x-k8s.io_kkclustertemplates.yaml @@ -71,6 +71,53 @@ spec: spec: description: KKClusterSpec defines the desired state of KKCluster properties: + component: + description: Component is optional configuration for modifying + the FTP server that gets the necessary components for the + cluster. + properties: + host: + description: Host is the host to download the binaries. + type: string + overrides: + description: Overrides is a list of components download + information that need to be overridden. + items: + description: Override is a component download information + that need to be overridden. + properties: + arch: + description: Arch is the component arch. e.g. amd64, + arm64, etc. + type: string + checksum: + description: Checksum is the SHA256 checksum of + the binary. + type: string + id: + description: ID is the component id name. e.g. kubeadm, + kubelet, containerd, etc. + type: string + path: + description: Path defines the URL path, which is + the string of information that comes after the + top level domain name. + type: string + url: + description: URL is the download url of the binaries. + type: string + version: + description: Version is the component version. e.g. + v1.21.1, v1.22.0, etc. + type: string + type: object + type: array + zone: + description: 'ZONE is the zone of the KKCluster where + can get the binaries. If you have problem to access + https://storage.googleapis.com, you can set "zone: cn".' + type: string + type: object controlPlaneEndpoint: description: ControlPlaneEndpoint represents the endpoint used to communicate with the control plane. @@ -304,11 +351,6 @@ spec: - namespaceOverride - privateRegistry type: object - zone: - description: 'ZONE is the zone of the KKCluster where can - get the binaries. If you have problem to access https://storage.googleapis.com, - you can set "zone: cn".' - type: string required: - nodes type: object diff --git a/exp/cluster-api-provider-kubekey/pkg/interface.go b/exp/cluster-api-provider-kubekey/pkg/interface.go index 93f5c4c0..88fea39f 100644 --- a/exp/cluster-api-provider-kubekey/pkg/interface.go +++ b/exp/cluster-api-provider-kubekey/pkg/interface.go @@ -87,8 +87,6 @@ type ClusterScoper interface { KubernetesClusterName() string // RootFs is the cluster scope rootfs RootFs() rootfs.Interface - // Zone returns the cluster zone. - Zone() string // PatchObject persists the cluster configuration and status. PatchObject() error // Close closes the current scope persisting the cluster configuration and status. diff --git a/exp/cluster-api-provider-kubekey/pkg/scope/cluster.go b/exp/cluster-api-provider-kubekey/pkg/scope/cluster.go index ce47df5e..2940f3eb 100644 --- a/exp/cluster-api-provider-kubekey/pkg/scope/cluster.go +++ b/exp/cluster-api-provider-kubekey/pkg/scope/cluster.go @@ -226,9 +226,28 @@ func (s *ClusterScope) RootFs() rootfs.Interface { return s.rootFs } -// Zone returns the KKCluster binaries zone. -func (s *ClusterScope) Zone() string { - return s.KKCluster.Spec.ZONE +// ComponentZone returns the KKCluster binaries zone. +func (s *ClusterScope) ComponentZone() string { + if s.KKCluster.Spec.Component == nil { + return "" + } + return s.KKCluster.Spec.Component.ZONE +} + +// ComponentHost returns the KKCluster binaries host. +func (s *ClusterScope) ComponentHost() string { + if s.KKCluster.Spec.Component == nil { + return "" + } + return s.KKCluster.Spec.Component.Host +} + +// ComponentOverrides returns the KKCluster binaries overrides. +func (s *ClusterScope) ComponentOverrides() []infrav1.Override { + if s.KKCluster.Spec.Component == nil { + return []infrav1.Override{} + } + return s.KKCluster.Spec.Component.Overrides } // ControlPlaneLoadBalancer returns the KKLoadBalancerSpec. diff --git a/exp/cluster-api-provider-kubekey/pkg/scope/kkinstance.go b/exp/cluster-api-provider-kubekey/pkg/scope/kkinstance.go index 3e575a0e..07e32440 100644 --- a/exp/cluster-api-provider-kubekey/pkg/scope/kkinstance.go +++ b/exp/cluster-api-provider-kubekey/pkg/scope/kkinstance.go @@ -24,10 +24,17 @@ import ( // KKInstanceScope is a scope for global KKInstance. type KKInstanceScope interface { pkg.ClusterScoper + // ComponentZone returns the cluster zone. + ComponentZone() string + // ComponentHost returns the host to download the binaries. + ComponentHost() string + // ComponentOverrides returns the component overrides. + ComponentOverrides() []infrav1.Override // GlobalAuth returns the global auth configuration of all instances. GlobalAuth() *infrav1.Auth // GlobalContainerManager returns the global container manager configuration of all instances. GlobalContainerManager() *infrav1.ContainerManager + // GlobalRegistry returns the global registry configuration of all instances. GlobalRegistry() *infrav1.Registry // AllInstancesSpec returns the KKInstanceSpec AllInstancesSpec() []infrav1.KKInstanceSpec diff --git a/exp/cluster-api-provider-kubekey/pkg/service/binary/binary.go b/exp/cluster-api-provider-kubekey/pkg/service/binary/binary.go index 1ca2e61d..2fe1ba99 100644 --- a/exp/cluster-api-provider-kubekey/pkg/service/binary/binary.go +++ b/exp/cluster-api-provider-kubekey/pkg/service/binary/binary.go @@ -22,8 +22,10 @@ import ( "text/template" "time" + infrav1 "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/api/v1beta1" "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/service/operation" "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/service/operation/file" + "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/service/operation/file/checksum" ) //go:embed templates @@ -55,15 +57,44 @@ func (s *Service) DownloadAll(timeout time.Duration) error { kubectl, } + zone := s.scope.ComponentZone() + host := s.scope.ComponentHost() + overrideMap := make(map[string]infrav1.Override) + for _, o := range s.scope.ComponentOverrides() { + overrideMap[o.ID+o.Version+o.Arch] = o + } + for _, b := range binaries { - b.SetZone(s.scope.Zone()) - needGet := true - if b.LocalExist() && b.CompareChecksum() == nil { - needGet = false + if b.RemoteExist() { + if err := b.Chmod("+x"); err != nil { + return err + } + continue } - if needGet { + + if !(b.LocalExist() && b.CompareChecksum() == nil) { + // Only the host is an empty string, we can set ip the zone. + // Because the URL path which in the QingStor is not the same as the default. + if host == "" { + b.SetZone(zone) + } + + var path, url, checksumStr string + // If the override is match, we will use the override to replace the default. + if override, ok := overrideMap[b.ID()+b.Version()+b.Arch()]; ok { + path = override.Path + url = override.URL + checksumStr = override.Checksum + } + // Always try to set the "host, path, url, checksum". + // If the these vars are empty strings, it will not make any changes. + b.SetHost(host) + b.SetPath(path) + b.SetURL(url) + b.SetChecksum(checksum.NewStringChecksum(checksumStr)) + s.instanceScope.V(4).Info("download binary", "binary", b.Name(), - "version", b.Version(), "url", b.URL()) + "version", b.Version(), "url", b.URL().String()) if err := b.Get(timeout); err != nil { return err } @@ -71,6 +102,7 @@ func (s *Service) DownloadAll(timeout time.Duration) error { return err } } + if err := b.Copy(true); err != nil { return err } diff --git a/exp/cluster-api-provider-kubekey/pkg/service/containermanager/containerd.go b/exp/cluster-api-provider-kubekey/pkg/service/containermanager/containerd.go index c644132e..6971ceb4 100644 --- a/exp/cluster-api-provider-kubekey/pkg/service/containermanager/containerd.go +++ b/exp/cluster-api-provider-kubekey/pkg/service/containermanager/containerd.go @@ -32,6 +32,7 @@ import ( "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/scope" "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/service/operation" "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/service/operation/file" + "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/service/operation/file/checksum" ) // ContainerdService is a ContainerManager service implementation for containerd. @@ -129,15 +130,41 @@ func (s *ContainerdService) Get(timeout time.Duration) error { crictl, } + zone := s.scope.ComponentZone() + host := s.scope.ComponentHost() + overrideMap := make(map[string]infrav1.Override) + for _, o := range s.scope.ComponentOverrides() { + overrideMap[o.ID+o.Version+o.Arch] = o + } + for _, b := range binaries { - b.SetZone(s.scope.Zone()) - needGet := true - if b.LocalExist() && b.CompareChecksum() == nil { - needGet = false + if b.RemoteExist() { + continue } - if needGet { + + if !(b.LocalExist() && b.CompareChecksum() == nil) { + // Only the host is an empty string, we can set ip the zone. + // Because the URL path which in the QingStor is not the same as the default. + if host == "" { + b.SetZone(zone) + } + + var path, url, checksumStr string + // If the override is match, we will use the override to replace the default. + if override, ok := overrideMap[b.ID()+b.Version()+b.Arch()]; ok { + path = override.Path + url = override.URL + checksumStr = override.Checksum + } + // Always try to set the "host, path, url, checksum". + // If the these vars are empty strings, it will not make any changes. + b.SetHost(host) + b.SetPath(path) + b.SetURL(url) + b.SetChecksum(checksum.NewStringChecksum(checksumStr)) + s.instanceScope.V(4).Info("download binary", "binary", b.Name(), - "version", b.Version(), "url", b.URL()) + "version", b.Version(), "url", b.URL().String()) if err := b.Get(timeout); err != nil { return err } @@ -145,6 +172,7 @@ func (s *ContainerdService) Get(timeout time.Duration) error { return err } } + if err := b.Copy(true); err != nil { return err } diff --git a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/binary.go b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/binary.go index fcb295c7..c672e19b 100644 --- a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/binary.go +++ b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/binary.go @@ -20,27 +20,122 @@ import ( "crypto/sha256" "fmt" "io" + "net/url" "os" + "path" + "reflect" + "strings" "time" "github.com/hashicorp/go-getter" - urlhelper "github.com/hashicorp/go-getter/helper/url" "github.com/pkg/errors" "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/service/operation/file/checksum" ) +// Default +const ( + ZONE = "cn" + DefaultDownloadHost = "https://github.com" + DefaultDownloadHostGoogle = "https://storage.googleapis.com" + DefaultDownloadHostQingStor = "https://kubernetes-release.pek3b.qingstor.com" +) + +// BinaryParams represents the parameters of a Binary. +type BinaryParams struct { + File *File + ID string + Version string + Arch string + URL *url.URL + Checksum checksum.Interface +} + +// NewBinary returns a new Binary. +func NewBinary(params BinaryParams) *Binary { + b := &Binary{ + file: params.File, + id: params.ID, + version: params.Version, + arch: params.Arch, + url: params.URL, + checksum: params.Checksum, + } + return b +} + // Binary is a binary implementation of Binary interface. type Binary struct { - *File + file *File id string version string arch string - url string - cnURL string + url *url.URL checksum checksum.Interface } +// Name returns the name of the Binary file. +func (b *Binary) Name() string { + return b.file.Name() +} + +// Type returns the type of the Binary file. +func (b *Binary) Type() Type { + return b.file.Type() +} + +// LocalPath returns the local path of the Binary file. +func (b *Binary) LocalPath() string { + return b.file.LocalPath() +} + +// RemotePath returns the remote path of the Binary file. +func (b *Binary) RemotePath() string { + return b.file.RemotePath() +} + +// LocalExist returns true if the Binary file is existed in the local path. +func (b *Binary) LocalExist() bool { + return b.file.LocalExist() +} + +// RemoteExist returns true if the Binary file is existed (and the SHA256 check passes) in the remote path. +func (b *Binary) RemoteExist() bool { + if !b.file.RemoteExist() { + return false + } + + cmd := fmt.Sprintf("sha256sum %s | cut -d\" \" -f1", b.file.RemotePath()) + remoteSHA256, err := b.file.sshClient.SudoCmd(cmd) + if err != nil { + return false + } + + if err := b.checksum.Get(); err != nil { + return false + } + + if remoteSHA256 != b.checksum.Value() { + return false + } + return true +} + +// Copy copies the Binary file from the local path to the remote path. +func (b *Binary) Copy(override bool) error { + return b.file.Copy(override) +} + +// Fetch copies the Binary file from the remote path to the local path. +func (b *Binary) Fetch(override bool) error { + return b.file.Fetch(override) +} + +// Chmod changes the mode of the Binary file. +func (b *Binary) Chmod(option string) error { + return b.file.Chmod(option) +} + // ID returns the id of the binary. func (b *Binary) ID() string { return b.id @@ -57,29 +152,69 @@ func (b *Binary) Version() string { } // URL returns the download url of the binary. -func (b *Binary) URL() string { +func (b *Binary) URL() *url.URL { return b.url } +// SetURL sets the download url of the binary. +func (b *Binary) SetURL(urlStr string) { + if urlStr == "" { + return + } + u, err := url.Parse(urlStr) + if err != nil { + return + } + b.url = u +} + +// SetHost sets the host to download the binaries. +func (b *Binary) SetHost(host string) { + if host == "" { + return + } + u, err := url.Parse(host) + if err != nil { + return + } + u.Path = b.url.Path + b.url = u +} + +// SetPath sets the URL path of the binary. +func (b *Binary) SetPath(pathStr string) { + if pathStr == "" { + return + } + ref, err := url.Parse(pathStr) + if err != nil { + return + } + b.url = b.url.ResolveReference(ref) +} + // SetZone sets the zone of the binary. func (b *Binary) SetZone(zone string) { - if zone == "cn" { - b.url = b.cnURL + if strings.EqualFold(zone, ZONE) { + b.SetHost(DefaultDownloadHostQingStor) } } +// SetChecksum sets the checksum of the binary. +func (b *Binary) SetChecksum(c checksum.Interface) { + if reflect.ValueOf(c).IsNil() { + return + } + b.checksum = c +} + // Get downloads the binary from remote. func (b *Binary) Get(timeout time.Duration) error { client := &getter.HttpGetter{ ReadTimeout: timeout, } - url, err := urlhelper.Parse(b.url) - if err != nil { - return errors.Wrapf(err, "failed to parse url: %s", b.url) - } - - if err := client.GetFile(b.LocalPath(), url); err != nil { + if err := client.GetFile(b.LocalPath(), b.URL()); err != nil { return errors.Wrapf(err, "failed to http get file: %s", b.LocalPath()) } @@ -117,3 +252,9 @@ func (b *Binary) CompareChecksum() error { } return nil } + +func parseURL(host, pathStr string) *url.URL { + u, _ := url.Parse(host) + u.Path = path.Join(u.Path, pathStr) + return u +} diff --git a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/checksum/string_checksum.go b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/checksum/string_checksum.go new file mode 100644 index 00000000..b0bd23e3 --- /dev/null +++ b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/checksum/string_checksum.go @@ -0,0 +1,40 @@ +/* + Copyright 2022 The KubeSphere 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 checksum + +// StringChecksum is a simple checksum implementation for given strings. +type StringChecksum struct { + value string +} + +// NewStringChecksum returns a new StringChecksum for the given string. +func NewStringChecksum(value string) *StringChecksum { + if value == "" { + return nil + } + return &StringChecksum{value: value} +} + +// Get the StringChecksum Get() method will do nothing. +func (s *StringChecksum) Get() error { + return nil +} + +// Value returns the value of the StringChecksum. +func (s *StringChecksum) Value() string { + return s.value +} diff --git a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/containerd.go b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/containerd.go index c3651a61..08410373 100644 --- a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/containerd.go +++ b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/containerd.go @@ -27,16 +27,18 @@ import ( // Containerd info const ( - ContainerdName = "containerd-%s-linux-%s.tar.gz" - ContainerdID = "containerd" - ContainerdDownloadURLTmpl = "https://github.com/containerd/containerd/releases/download/v%s/containerd-%s-linux-%s.tar.gz" - ContainerdDownloadURLTmplCN = "https://kubernetes-release.pek3b.qingstor.com/containerd/containerd/releases/download/v%s/containerd-%s-linux-%s.tar.gz" + ContainerdName = "containerd-%s-linux-%s.tar.gz" + ContainerdID = "containerd" + ContainerdURLPathTmpl = "/containerd/containerd/releases/download/v%s/containerd-%s-linux-%s.tar.gz" ) -// NewContainerd returns a new Binary for containerd -func NewContainerd(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch string) (*Binary, error) { - internal := checksum.NewChecksum(ContainerdID, version, arch) +// Containerd is a Binary for containerd. +type Containerd struct { + *Binary +} +// NewContainerd returns a new Containerd. +func NewContainerd(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch string) (*Containerd, error) { fileName := fmt.Sprintf(ContainerdName, version, arch) file, err := NewFile(Params{ SSHClient: sshClient, @@ -50,13 +52,16 @@ func NewContainerd(sshClient ssh.Interface, rootFs rootfs.Interface, version, ar return nil, err } - return &Binary{ - file, - ContainerdID, - version, - arch, - fmt.Sprintf(ContainerdDownloadURLTmpl, version, version, arch), - fmt.Sprintf(ContainerdDownloadURLTmplCN, version, version, arch), - internal, - }, nil + u := parseURL(DefaultDownloadHost, fmt.Sprintf(ContainerdURLPathTmpl, version, version, arch)) + internal := checksum.NewChecksum(ContainerdID, version, arch) + binary := NewBinary(BinaryParams{ + File: file, + ID: ContainerdID, + Version: version, + Arch: arch, + URL: u, + Checksum: internal, + }) + + return &Containerd{binary}, nil } diff --git a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/crictl.go b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/crictl.go index 19084c5c..c5647f61 100644 --- a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/crictl.go +++ b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/crictl.go @@ -19,6 +19,7 @@ package file import ( "fmt" "path/filepath" + "strings" "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/clients/ssh" "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/rootfs" @@ -27,16 +28,19 @@ import ( // Crictl info const ( - CrictlName = "crictl-%s-linux-%s.tar.gz" - CrictlID = "crictl" - CrictlDownloadURLTmpl = "https://github.com/kubernetes-sigs/cri-tools/releases/download/%s/crictl-%s-linux-%s.tar.gz" - CrictlDownloadURLTmplCN = "https://kubernetes-release.pek3b.qingstor.com/cri-tools/releases/download/%s/crictl-%s-linux-%s.tar.gz" + CrictlName = "crictl-%s-linux-%s.tar.gz" + CrictlID = "crictl" + CrictlURLPathTmpl = "/kubernetes-sigs/cri-tools/releases/download/%s/crictl-%s-linux-%s.tar.gz" + CrictlURLPathTmplCN = "/cri-tools/releases/download/%s/crictl-%s-linux-%s.tar.gz" ) -// NewCrictl returns a new Binary for crictl -func NewCrictl(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch string) (*Binary, error) { - internal := checksum.NewChecksum(CrictlID, version, arch) +// Crictl is a Binary for crictl. +type Crictl struct { + *Binary +} +// NewCrictl returns a new Crictl. +func NewCrictl(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch string) (*Crictl, error) { fileName := fmt.Sprintf(CrictlName, version, arch) file, err := NewFile(Params{ SSHClient: sshClient, @@ -50,13 +54,24 @@ func NewCrictl(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch s return nil, err } - return &Binary{ - file, - CrictlID, - version, - arch, - fmt.Sprintf(CrictlDownloadURLTmpl, version, version, arch), - fmt.Sprintf(CrictlDownloadURLTmplCN, version, version, arch), - internal, - }, nil + u := parseURL(DefaultDownloadHost, fmt.Sprintf(CrictlURLPathTmpl, version, version, arch)) + internal := checksum.NewChecksum(CrictlID, version, arch) + binary := NewBinary(BinaryParams{ + File: file, + ID: CrictlID, + Version: version, + Arch: arch, + URL: u, + Checksum: internal, + }) + + return &Crictl{binary}, nil +} + +// SetZone override Binary's SetZone method. +func (c *Crictl) SetZone(zone string) { + if strings.EqualFold(zone, ZONE) { + c.SetHost(DefaultDownloadHostQingStor) + c.SetPath(fmt.Sprintf(CrictlURLPathTmplCN, c.version, c.version, c.arch)) + } } diff --git a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/docker.go b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/docker.go index 913f2c9c..9fd92e07 100644 --- a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/docker.go +++ b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/docker.go @@ -19,6 +19,7 @@ package file import ( "fmt" "path/filepath" + "strings" "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/clients/ssh" "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/rootfs" @@ -28,17 +29,22 @@ import ( // Docker info const ( - DockerName = "docker-%s.tgz" - DockerID = "docker" - DockerDownloadURLTmpl = "https://download.docker.com/linux/static/stable/%s/docker-%s.tgz" - DockerDownloadURLTmplCN = "https://mirrors.aliyun.com/docker-ce/linux/static/stable/%s/docker-%s.tgz" - DockerDefaultVersion = "20.10.8" + DockerName = "docker-%s.tgz" + DockerID = "docker" + DockerURL = "https://download.docker.com" + DockerURLPathTmpl = "/linux/static/stable/%s/docker-%s.tgz" + DockerURLCN = "https://mirrors.aliyun.com" + DockerURLPathTmplCN = "/docker-ce/linux/static/stable/%s/docker-%s.tgz" + DockerDefaultVersion = "20.10.8" ) -// NewDocker returns a new Binary for docker. -func NewDocker(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch string) (*Binary, error) { - internal := checksum.NewChecksum(DockerID, version, arch) +// Docker is a Binary for docker. +type Docker struct { + *Binary +} +// NewDocker returns a new Docker. +func NewDocker(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch string) (*Docker, error) { fileName := fmt.Sprintf(DockerName, version) file, err := NewFile(Params{ SSHClient: sshClient, @@ -52,13 +58,24 @@ func NewDocker(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch s return nil, err } - return &Binary{ - file, - DockerID, - version, - arch, - fmt.Sprintf(DockerDownloadURLTmpl, util.ArchAlias(arch), version), - fmt.Sprintf(DockerDownloadURLTmplCN, util.ArchAlias(arch), version), - internal, - }, nil + u := parseURL(DockerURL, fmt.Sprintf(DockerURLPathTmpl, util.ArchAlias(arch), version)) + internal := checksum.NewChecksum(DockerID, version, arch) + binary := NewBinary(BinaryParams{ + File: file, + ID: DockerID, + Version: version, + Arch: arch, + URL: u, + Checksum: internal, + }) + + return &Docker{binary}, nil +} + +// SetZone override Binary's SetZone method. +func (d *Docker) SetZone(zone string) { + if strings.EqualFold(zone, ZONE) { + d.SetHost(DockerURLCN) + d.SetPath(fmt.Sprintf(DockerURLPathTmplCN, util.ArchAlias(d.arch), d.version)) + } } diff --git a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/kubeadm.go b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/kubeadm.go index 15065c66..2ed1e36f 100644 --- a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/kubeadm.go +++ b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/kubeadm.go @@ -19,6 +19,7 @@ package file import ( "fmt" "path/filepath" + "strings" "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/clients/ssh" "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/rootfs" @@ -27,16 +28,19 @@ import ( // Kubeadm info const ( - KubeadmName = "kubeadm" - KubeadmID = "kubeadm" - KubeadmDownloadURLTmpl = "https://storage.googleapis.com/kubernetes-release/release/%s/bin/linux/%s/kubeadm" - KubeadmDownloadURLTmplCN = "https://kubernetes-release.pek3b.qingstor.com/release/%s/bin/linux/%s/kubeadm" + KubeadmName = "kubeadm" + KubeadmID = "kubeadm" + KubeadmURLPathTmpl = "/kubernetes-release/release/%s/bin/linux/%s/kubeadm" + KubeadmURLPathTmplCN = "/release/%s/bin/linux/%s/kubeadm" ) -// NewKubeadm returns a new Binary for kubeadm -func NewKubeadm(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch string) (*Binary, error) { - internal := checksum.NewChecksum(KubeadmID, version, arch) +// Kubeadm is a Binary for kubeadm. +type Kubeadm struct { + *Binary +} +// NewKubeadm returns a new Kubeadm. +func NewKubeadm(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch string) (*Kubeadm, error) { fileName := KubeadmName file, err := NewFile(Params{ SSHClient: sshClient, @@ -50,13 +54,24 @@ func NewKubeadm(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch return nil, err } - return &Binary{ - file, - KubeadmID, - version, - arch, - fmt.Sprintf(KubeadmDownloadURLTmpl, version, arch), - fmt.Sprintf(KubeadmDownloadURLTmplCN, version, arch), - internal, - }, nil + u := parseURL(DefaultDownloadHostGoogle, fmt.Sprintf(KubeadmURLPathTmpl, version, arch)) + internal := checksum.NewChecksum(KubeadmID, version, arch) + binary := NewBinary(BinaryParams{ + File: file, + ID: KubeadmID, + Version: version, + Arch: arch, + URL: u, + Checksum: internal, + }) + + return &Kubeadm{binary}, nil +} + +// SetZone override Binary's SetZone method. +func (k *Kubeadm) SetZone(zone string) { + if strings.EqualFold(zone, ZONE) { + k.SetHost(DefaultDownloadHostQingStor) + k.SetPath(fmt.Sprintf(KubeadmURLPathTmplCN, k.version, k.arch)) + } } diff --git a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/kubecni.go b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/kubecni.go index 752812a8..33315e65 100644 --- a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/kubecni.go +++ b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/kubecni.go @@ -19,6 +19,7 @@ package file import ( "fmt" "path/filepath" + "strings" "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/clients/ssh" "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/rootfs" @@ -27,17 +28,21 @@ import ( // Kubecni info const ( - KubecniName = "cni-plugins-linux-%s-%s.tgz" - KubecniID = "kubecni" - KubecniDownloadURLTmpl = "https://github.com/containernetworking/plugins/releases/download/%s/cni-plugins-linux-%s-%s.tgz" - KubecniDownloadURLTmplCN = "https://containernetworking.pek3b.qingstor.com/plugins/releases/download/%s/cni-plugins-linux-%s-%s.tgz" - KubecniDefaultVersion = "v0.9.1" + KubecniName = "cni-plugins-linux-%s-%s.tgz" + KubecniID = "kubecni" + KubecniURLPathTmpl = "/containernetworking/plugins/releases/download/%s/cni-plugins-linux-%s-%s.tgz" + KubecniURLCN = "https://containernetworking.pek3b.qingstor.com" + KubecniURLPathTmplCN = "/plugins/releases/download/%s/cni-plugins-linux-%s-%s.tgz" + KubecniDefaultVersion = "v0.9.1" ) -// NewKubecni returns a new Binary for kubecni -func NewKubecni(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch string) (*Binary, error) { - internal := checksum.NewChecksum(KubecniID, version, arch) +// Kubecni is a Binary for kubecni. +type Kubecni struct { + *Binary +} +// NewKubecni returns a new Kubecni. +func NewKubecni(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch string) (*Kubecni, error) { fileName := fmt.Sprintf(KubecniName, arch, version) file, err := NewFile(Params{ SSHClient: sshClient, @@ -51,13 +56,24 @@ func NewKubecni(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch return nil, err } - return &Binary{ - file, - KubecniID, - version, - arch, - fmt.Sprintf(KubecniDownloadURLTmpl, version, arch, version), - fmt.Sprintf(KubecniDownloadURLTmplCN, version, arch, version), - internal, - }, nil + u := parseURL(DefaultDownloadHost, fmt.Sprintf(KubecniURLPathTmpl, version, arch, version)) + internal := checksum.NewChecksum(KubecniID, version, arch) + binary := NewBinary(BinaryParams{ + File: file, + ID: KubecniID, + Version: version, + Arch: arch, + URL: u, + Checksum: internal, + }) + + return &Kubecni{binary}, nil +} + +// SetZone override Binary's SetZone method. +func (k *Kubecni) SetZone(zone string) { + if strings.EqualFold(zone, ZONE) { + k.SetHost(KubecniURLCN) + k.SetPath(fmt.Sprintf(KubecniURLPathTmplCN, k.version, k.arch, k.version)) + } } diff --git a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/kubectl.go b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/kubectl.go index f7990e96..14b30cd2 100644 --- a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/kubectl.go +++ b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/kubectl.go @@ -19,6 +19,7 @@ package file import ( "fmt" "path/filepath" + "strings" "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/clients/ssh" "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/rootfs" @@ -27,16 +28,19 @@ import ( // Kubectl info const ( - KubectlName = "kubectl" - KubectlID = "kubectl" - KubectlDownloadURLTmpl = "https://storage.googleapis.com/kubernetes-release/release/%s/bin/linux/%s/kubectl" - KubectlDownloadURLTmplCN = "https://kubernetes-release.pek3b.qingstor.com/release/%s/bin/linux/%s/kubectl" + KubectlName = "kubectl" + KubectlID = "kubectl" + KubectlURLPathTmpl = "/kubernetes-release/release/%s/bin/linux/%s/kubectl" + KubectlURLPathTmplCN = "/release/%s/bin/linux/%s/kubectl" ) -// NewKubectl returns a new Binary for kubectl -func NewKubectl(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch string) (*Binary, error) { - internal := checksum.NewChecksum(KubectlID, version, arch) +// Kubectl is a Binary for kubectl. +type Kubectl struct { + *Binary +} +// NewKubectl returns a new Kubectl. +func NewKubectl(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch string) (*Kubectl, error) { fileName := KubectlName file, err := NewFile(Params{ SSHClient: sshClient, @@ -50,13 +54,24 @@ func NewKubectl(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch return nil, err } - return &Binary{ - file, - KubectlID, - version, - arch, - fmt.Sprintf(KubectlDownloadURLTmpl, version, arch), - fmt.Sprintf(KubectlDownloadURLTmplCN, version, arch), - internal, - }, nil + u := parseURL(DefaultDownloadHostGoogle, fmt.Sprintf(KubectlURLPathTmpl, version, arch)) + internal := checksum.NewChecksum(KubectlID, version, arch) + binary := NewBinary(BinaryParams{ + File: file, + ID: KubectlID, + Version: version, + Arch: arch, + URL: u, + Checksum: internal, + }) + + return &Kubectl{binary}, nil +} + +// SetZone override Binary's SetZone method. +func (k *Kubectl) SetZone(zone string) { + if strings.EqualFold(zone, ZONE) { + k.SetHost(DefaultDownloadHostQingStor) + k.SetPath(fmt.Sprintf(KubectlURLPathTmplCN, k.version, k.arch)) + } } diff --git a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/kubelet.go b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/kubelet.go index 4bfc68df..0ae9c11a 100644 --- a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/kubelet.go +++ b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/kubelet.go @@ -19,6 +19,7 @@ package file import ( "fmt" "path/filepath" + "strings" "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/clients/ssh" "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/rootfs" @@ -27,16 +28,19 @@ import ( // kubelet info const ( - KubeletName = "kubelet" - KubeletID = "kubelet" - KubeletDownloadURLTmpl = "https://storage.googleapis.com/kubernetes-release/release/%s/bin/linux/%s/kubelet" - KubeletDownloadURLTmplCN = "https://kubernetes-release.pek3b.qingstor.com/release/%s/bin/linux/%s/kubelet" + KubeletName = "kubelet" + KubeletID = "kubelet" + KubeletURLPathTmpl = "/kubernetes-release/release/%s/bin/linux/%s/kubelet" + KubeletURLPathTmplCN = "/release/%s/bin/linux/%s/kubelet" ) -// NewKubelet returns a new Binary for kubelet -func NewKubelet(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch string) (*Binary, error) { - internal := checksum.NewChecksum(KubeletID, version, arch) +// Kubelet is a Binary for kubelet. +type Kubelet struct { + *Binary +} +// NewKubelet returns a new Kubelet. +func NewKubelet(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch string) (*Kubelet, error) { fileName := KubeletName file, err := NewFile(Params{ SSHClient: sshClient, @@ -50,13 +54,24 @@ func NewKubelet(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch return nil, err } - return &Binary{ - file, - KubeletID, - version, - arch, - fmt.Sprintf(KubeletDownloadURLTmpl, version, arch), - fmt.Sprintf(KubeletDownloadURLTmplCN, version, arch), - internal, - }, nil + u := parseURL(DefaultDownloadHostGoogle, fmt.Sprintf(KubeletURLPathTmpl, version, arch)) + internal := checksum.NewChecksum(KubeletID, version, arch) + binary := NewBinary(BinaryParams{ + File: file, + ID: KubeletID, + Version: version, + Arch: arch, + URL: u, + Checksum: internal, + }) + + return &Kubelet{binary}, nil +} + +// SetZone override Binary's SetZone method. +func (k *Kubelet) SetZone(zone string) { + if strings.EqualFold(zone, ZONE) { + k.SetHost(DefaultDownloadHostQingStor) + k.SetPath(fmt.Sprintf(KubeletURLPathTmplCN, k.version, k.arch)) + } } diff --git a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/runc.go b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/runc.go index 71915759..317468e2 100644 --- a/exp/cluster-api-provider-kubekey/pkg/service/operation/file/runc.go +++ b/exp/cluster-api-provider-kubekey/pkg/service/operation/file/runc.go @@ -27,17 +27,19 @@ import ( // runc info const ( - RuncName = "runc.%s" - RuncID = "runc" - RuncDownloadURLTmpl = "https://github.com/opencontainers/runc/releases/download/%s/runc.%s" - RuncDownloadURLTmplCN = "https://kubernetes-release.pek3b.qingstor.com/opencontainers/runc/releases/download/%s/runc.%s" - RuncDefaultVersion = "v1.1.1" + RuncName = "runc.%s" + RuncID = "runc" + RuncURLPathTmpl = "/opencontainers/runc/releases/download/%s/runc.%s" + RuncDefaultVersion = "v1.1.1" ) -// NewRunc returns a new Binary for runc -func NewRunc(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch string) (*Binary, error) { - internal := checksum.NewChecksum(RuncID, version, arch) +// Runc is a Binary for runc. +type Runc struct { + *Binary +} +// NewRunc returns a new Runc. +func NewRunc(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch string) (*Runc, error) { fileName := fmt.Sprintf(RuncName, arch) file, err := NewFile(Params{ SSHClient: sshClient, @@ -51,13 +53,16 @@ func NewRunc(sshClient ssh.Interface, rootFs rootfs.Interface, version, arch str return nil, err } - return &Binary{ - file, - RuncID, - version, - arch, - fmt.Sprintf(RuncDownloadURLTmpl, version, arch), - fmt.Sprintf(RuncDownloadURLTmplCN, version, arch), - internal, - }, nil + u := parseURL(DefaultDownloadHost, fmt.Sprintf(RuncURLPathTmpl, version, arch)) + internal := checksum.NewChecksum(RuncID, version, arch) + binary := NewBinary(BinaryParams{ + File: file, + ID: RuncID, + Version: version, + Arch: arch, + URL: u, + Checksum: internal, + }) + + return &Runc{binary}, nil } diff --git a/exp/cluster-api-provider-kubekey/pkg/service/operation/interface.go b/exp/cluster-api-provider-kubekey/pkg/service/operation/interface.go index 0679518d..f44c82c3 100644 --- a/exp/cluster-api-provider-kubekey/pkg/service/operation/interface.go +++ b/exp/cluster-api-provider-kubekey/pkg/service/operation/interface.go @@ -18,9 +18,11 @@ package operation import ( + "net/url" "time" "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/service/operation/file" + "github.com/kubesphere/kubekey/exp/cluster-api-provider-kubekey/pkg/service/operation/file/checksum" ) // File interface defines the operations for normal file which needed to be copied to remote. @@ -42,8 +44,12 @@ type Binary interface { ID() string Arch() string Version() string - URL() string + URL() *url.URL + SetURL(url string) + SetHost(host string) + SetPath(path string) SetZone(zone string) + SetChecksum(checksum checksum.Interface) Get(timeout time.Duration) error CompareChecksum() error } diff --git a/exp/cluster-api-provider-kubekey/test/e2e/data/infrastructure-kubekey/v1beta1/bases/cluster-with-kcp.yaml b/exp/cluster-api-provider-kubekey/test/e2e/data/infrastructure-kubekey/v1beta1/bases/cluster-with-kcp.yaml index 6a38c543..3ebee651 100644 --- a/exp/cluster-api-provider-kubekey/test/e2e/data/infrastructure-kubekey/v1beta1/bases/cluster-with-kcp.yaml +++ b/exp/cluster-api-provider-kubekey/test/e2e/data/infrastructure-kubekey/v1beta1/bases/cluster-with-kcp.yaml @@ -5,7 +5,8 @@ kind: KKCluster metadata: name: '${CLUSTER_NAME}' spec: - zone: '${KKZONE}' + component: + zone: '${KKZONE}' nodes: auth: user: '${USER_NAME}'