diff --git a/cmd/kops/get_assets.go b/cmd/kops/get_assets.go index 2b51599215a1c..7d86cda2516db 100644 --- a/cmd/kops/get_assets.go +++ b/cmd/kops/get_assets.go @@ -132,7 +132,7 @@ func RunGetAssets(ctx context.Context, f *util.Factory, out io.Writer, options * file := File{ Canonical: fileAsset.CanonicalURL.String(), Download: fileAsset.DownloadURL.String(), - SHA: fileAsset.SHAValue, + SHA: fileAsset.SHAValue.Hex(), } if !seen[file.Canonical] { result.Files = append(result.Files, &file) diff --git a/hack/generate-asset-hashes.sh b/hack/generate-asset-hashes.sh index 0942032db20f4..7359b0be1bc20 100755 --- a/hack/generate-asset-hashes.sh +++ b/hack/generate-asset-hashes.sh @@ -35,7 +35,7 @@ filestores: files: EOF - for ((patch = 0 ; patch < max_patch ; patch++ )); do + for ((patch = 0 ; patch <= max_patch ; patch++ )); do version="${prefix}.${patch}" echo "k8s ${version}" @@ -62,12 +62,12 @@ function generate_runc_hashes() { # This file is generated by generate-asset-hashes.sh filestores: -- base: https://dl.k8s.io/release/ +- base: https://github.com/opencontainers/runc/releases/download/ files: EOF - for ((patch = 0 ; patch < max_patch ; patch++ )); do + for ((patch = 0 ; patch <= max_patch ; patch++ )); do version="${prefix}.${patch}" echo "runc ${version}" @@ -83,9 +83,10 @@ EOF generate_k8s_hashes 1.24 17 generate_k8s_hashes 1.25 16 generate_k8s_hashes 1.26 15 -generate_k8s_hashes 1.27 12 -generate_k8s_hashes 1.28 8 -generate_k8s_hashes 1.29 3 +generate_k8s_hashes 1.27 13 +generate_k8s_hashes 1.28 9 +generate_k8s_hashes 1.29 4 +generate_k8s_hashes 1.30 0 generate_runc_hashes 1.1 12 diff --git a/pkg/assets/assetdata/data_test.go b/pkg/assets/assetdata/data_test.go index c641fe08fd388..40bf36a8c92dc 100644 --- a/pkg/assets/assetdata/data_test.go +++ b/pkg/assets/assetdata/data_test.go @@ -26,7 +26,22 @@ func TestGetHash(t *testing.T) { Name string Hash string }{ - {Name: "https://dl.k8s.io/release/v1.26.0/bin/linux/amd64/kubelet", Hash: "sha256:b64949fe696c77565edbe4100a315b6bf8f0e2325daeb762f7e865f16a6e54b5"}, + { + Name: "https://dl.k8s.io/release/v1.26.0/bin/linux/amd64/kubelet", + Hash: "b64949fe696c77565edbe4100a315b6bf8f0e2325daeb762f7e865f16a6e54b5", + }, + { + Name: "https://github.com/opencontainers/runc/releases/download/v1.1.0/runc.amd64", + Hash: "ab1c67fbcbdddbe481e48a55cf0ef9a86b38b166b5079e0010737fd87d7454bb", + }, + { + Name: "https://github.com/opencontainers/runc/releases/download/v1.1.0/runc.arm64", + Hash: "9ec8e68feabc4e7083a4cfa45ebe4d529467391e0b03ee7de7ddda5770b05e68", + }, + { + Name: "https://github.com/opencontainers/runc/releases/download/v1.1.12/runc.amd64", + Hash: "aadeef400b8f05645768c1476d1023f7875b78f52c7ff1967a6dbce236b8cbd8", + }, } for _, g := range grid { @@ -41,7 +56,7 @@ func TestGetHash(t *testing.T) { if !found { t.Fatalf("hash for %q was not found", g.Name) } - got := h.String() + got := h.Hex() want := g.Hash if got != g.Hash { t.Errorf("unexpected hash for %q; got %q, want %q", g.Name, got, want) diff --git a/pkg/assets/assetdata/runc-1.1.yaml b/pkg/assets/assetdata/runc-1.1.yaml index 6803584aebf19..949e4bef9f70e 100644 --- a/pkg/assets/assetdata/runc-1.1.yaml +++ b/pkg/assets/assetdata/runc-1.1.yaml @@ -1,7 +1,7 @@ # This file is generated by generate-asset-hashes.sh filestores: -- base: https://dl.k8s.io/release/ +- base: https://github.com/opencontainers/runc/releases/download/ files: # runc 1.1.0 diff --git a/pkg/assets/builder.go b/pkg/assets/builder.go index 2e985539435d5..4102a85ecab85 100644 --- a/pkg/assets/builder.go +++ b/pkg/assets/builder.go @@ -32,6 +32,7 @@ import ( "k8s.io/klog/v2" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops/util" + "k8s.io/kops/pkg/assets/assetdata" "k8s.io/kops/pkg/featureflag" "k8s.io/kops/pkg/kubemanifest" "k8s.io/kops/pkg/values" @@ -97,7 +98,7 @@ type FileAsset struct { // CanonicalURL is the canonical location of the asset, for example as distributed by the kops project CanonicalURL *url.URL // SHAValue is the SHA hash of the FileAsset. - SHAValue string + SHAValue *hashing.Hash } // NewAssetBuilder creates a new AssetBuilder. @@ -235,73 +236,49 @@ func (a *AssetBuilder) RemapImage(image string) (string, error) { return image + "@" + digest, nil } -// RemapFileAndSHA returns a remapped URL for the file, if AssetsLocation is defined. -// It also returns the SHA hash of the file. -func (a *AssetBuilder) RemapFileAndSHA(fileURL *url.URL) (*url.URL, *hashing.Hash, error) { - if fileURL == nil { - return nil, nil, fmt.Errorf("unable to remap a nil URL") +// RemapFile returns a remapped URL for the file, if AssetsLocation is defined. +// It is returns in a FileAsset, alongside the SHA hash of the file. +// The SHA hash is is knownHash is provided, and otherwise will be found first by +// checking the canonical URL against our well-known hashes, and failing that via download. +func (a *AssetBuilder) RemapFile(canonicalURL *url.URL, knownHash *hashing.Hash) (*FileAsset, error) { + if canonicalURL == nil { + return nil, fmt.Errorf("unable to remap a nil URL") } fileAsset := &FileAsset{ - DownloadURL: fileURL, - CanonicalURL: fileURL, + DownloadURL: canonicalURL, + CanonicalURL: canonicalURL, } if a.AssetsLocation != nil && a.AssetsLocation.FileRepository != nil { - - normalizedFile, err := a.remapURL(fileURL) + normalizedFile, err := a.remapURL(canonicalURL) if err != nil { - return nil, nil, err + return nil, err } - if fileURL.Host != normalizedFile.Host { + if canonicalURL.Host != normalizedFile.Host { fileAsset.DownloadURL = normalizedFile klog.V(4).Infof("adding remapped file: %q", fileAsset.DownloadURL.String()) } } - h, err := a.findHash(fileAsset) - if err != nil { - return nil, nil, err - } - fileAsset.SHAValue = h.Hex() - - klog.V(8).Infof("adding file: %+v", fileAsset) - a.FileAssets = append(a.FileAssets, fileAsset) - - return fileAsset.DownloadURL, h, nil -} - -// RemapFileAndSHAValue returns a remapped URL for the file without a SHA file in object storage, if AssetsLocation is defined. -func (a *AssetBuilder) RemapFileAndSHAValue(fileURL *url.URL, shaValue string) (*url.URL, error) { - if fileURL == nil { - return nil, fmt.Errorf("unable to remap a nil URL") - } - - fileAsset := &FileAsset{ - DownloadURL: fileURL, - CanonicalURL: fileURL, - SHAValue: shaValue, - } - - if a.AssetsLocation != nil && a.AssetsLocation.FileRepository != nil { - normalizedFile, err := a.remapURL(fileURL) + if knownHash == nil { + h, err := a.findHash(fileAsset) if err != nil { return nil, err } - if fileURL.Host != normalizedFile.Host { - fileAsset.DownloadURL = normalizedFile - klog.V(4).Infof("adding remapped file: %q", fileAsset.DownloadURL.String()) - } + knownHash = h } + fileAsset.SHAValue = knownHash + klog.V(8).Infof("adding file: %+v", fileAsset) a.FileAssets = append(a.FileAssets, fileAsset) - return fileAsset.DownloadURL, nil + return fileAsset, nil } -// FindHash returns the hash value of a FileAsset. +// findHash returns the hash value of a FileAsset. func (a *AssetBuilder) findHash(file *FileAsset) (*hashing.Hash, error) { // If the phase is "assets" we use the CanonicalFileURL, // but during other phases we use the hash from the FileRepository or the base kops path. @@ -324,6 +301,16 @@ func (a *AssetBuilder) findHash(file *FileAsset) (*hashing.Hash, error) { return nil, fmt.Errorf("file url is not defined") } + knownHash, found, err := assetdata.GetHash(file.CanonicalURL) + if err != nil { + return nil, err + } + if found { + return knownHash, nil + } + + klog.Infof("asset %q is not well-known, downloading hash", file.CanonicalURL) + // We now prefer sha256 hashes for backoffSteps := 1; backoffSteps <= 3; backoffSteps++ { // We try first with a short backoff, so we don't @@ -338,7 +325,7 @@ func (a *AssetBuilder) findHash(file *FileAsset) (*hashing.Hash, error) { for _, ext := range []string{".sha256", ".sha256sum"} { for _, mirror := range FindURLMirrors(u.String()) { hashURL := mirror + ext - klog.V(3).Infof("Trying to read hash fie: %q", hashURL) + klog.V(3).Infof("Trying to read hash file: %q", hashURL) b, err := a.vfsContext.ReadFile(hashURL, vfs.WithBackoff(backoff)) if err != nil { // Try to log without being too alarming - issue #7550 diff --git a/pkg/assets/copy.go b/pkg/assets/copy.go index a561a9cd12070..134dbac920318 100644 --- a/pkg/assets/copy.go +++ b/pkg/assets/copy.go @@ -56,7 +56,7 @@ func Copy(imageAssets []*ImageAsset, fileAssets []*FileAsset, vfsContext *vfs.VF Name: fileAsset.CanonicalURL.String(), TargetFile: fileAsset.DownloadURL.String(), SourceFile: fileAsset.CanonicalURL.String(), - SHA: fileAsset.SHAValue, + SHA: fileAsset.SHAValue.Hex(), VFSContext: vfsContext, Cluster: cluster, } diff --git a/pkg/assets/mirrored_asset.go b/pkg/assets/mirrored_asset.go index 7c764eb0ca656..0aea8be35f4af 100644 --- a/pkg/assets/mirrored_asset.go +++ b/pkg/assets/mirrored_asset.go @@ -17,7 +17,6 @@ limitations under the License. package assets import ( - "net/url" "strings" "k8s.io/klog/v2" @@ -30,12 +29,14 @@ type MirroredAsset struct { } // BuildMirroredAsset checks to see if this is a file under the standard base location, and if so constructs some mirror locations -func BuildMirroredAsset(u *url.URL, hash *hashing.Hash) *MirroredAsset { +func BuildMirroredAsset(asset *FileAsset) *MirroredAsset { + u := asset.DownloadURL + a := &MirroredAsset{ - Hash: hash, + Hash: asset.SHAValue, } - if hash == nil { + if asset.SHAValue == nil { klog.Warningf("not using mirrors for asset %s as it does not have a known hash", u) a.Locations = []string{u.String()} } else { diff --git a/pkg/nodemodel/fileassets.go b/pkg/nodemodel/fileassets.go index f03e8053118bc..76f1e59464cf3 100644 --- a/pkg/nodemodel/fileassets.go +++ b/pkg/nodemodel/fileassets.go @@ -75,11 +75,11 @@ func (c *FileAssets) AddFileAssets(assetBuilder *assets.AssetBuilder) error { } k.Path = path.Join(k.Path, an) - u, hash, err := assetBuilder.RemapFileAndSHA(k) + asset, err := assetBuilder.RemapFile(k, nil) if err != nil { return err } - c.Assets[arch] = append(c.Assets[arch], assets.BuildMirroredAsset(u, hash)) + c.Assets[arch] = append(c.Assets[arch], assets.BuildMirroredAsset(asset)) } kubernetesVersion, _ := util.ParseKubernetesVersion(c.Cluster.Spec.KubernetesVersion) @@ -98,6 +98,7 @@ func (c *FileAssets) AddFileAssets(assetBuilder *assets.AssetBuilder) error { return err } + // TODO: Move these hashes to assetdata hashes := map[architectures.Architecture]string{ "amd64": "827d558953d861b81a35c3b599191a73f53c1f63bce42c61e7a3fee21a717a89", "arm64": "f1617c0ef77f3718e12a3efc6f650375d5b5e96eebdbcbad3e465e89e781bdfa", @@ -106,70 +107,69 @@ func (c *FileAssets) AddFileAssets(assetBuilder *assets.AssetBuilder) error { if err != nil { return fmt.Errorf("unable to parse auth-provider-gcp binary asset hash %q: %v", hashes[arch], err) } - u, err := assetBuilder.RemapFileAndSHAValue(k, hashes[arch]) + asset, err := assetBuilder.RemapFile(k, hash) if err != nil { return err } - c.Assets[arch] = append(c.Assets[arch], assets.BuildMirroredAsset(u, hash)) + c.Assets[arch] = append(c.Assets[arch], assets.BuildMirroredAsset(asset)) case kops.CloudProviderAWS: binaryLocation := c.Cluster.Spec.CloudProvider.AWS.BinariesLocation if binaryLocation == nil { binaryLocation = fi.PtrTo("https://artifacts.k8s.io/binaries/cloud-provider-aws/v1.27.1") } - k, err := url.Parse(fmt.Sprintf("%s/linux/%s/ecr-credential-provider-linux-%s", *binaryLocation, arch, arch)) + u, err := url.Parse(fmt.Sprintf("%s/linux/%s/ecr-credential-provider-linux-%s", *binaryLocation, arch, arch)) if err != nil { return err } - u, hash, err := assetBuilder.RemapFileAndSHA(k) + asset, err := assetBuilder.RemapFile(u, nil) if err != nil { return err } - - c.Assets[arch] = append(c.Assets[arch], assets.BuildMirroredAsset(u, hash)) + c.Assets[arch] = append(c.Assets[arch], assets.BuildMirroredAsset(asset)) } } { - cniAsset, cniAssetHash, err := wellknownassets.FindCNIAssets(c.Cluster, assetBuilder, arch) + cniAsset, err := wellknownassets.FindCNIAssets(c.Cluster, assetBuilder, arch) if err != nil { return err } - c.Assets[arch] = append(c.Assets[arch], assets.BuildMirroredAsset(cniAsset, cniAssetHash)) + c.Assets[arch] = append(c.Assets[arch], assets.BuildMirroredAsset(cniAsset)) } if c.Cluster.Spec.Containerd == nil || !c.Cluster.Spec.Containerd.SkipInstall { - containerdAssetUrl, containerdAssetHash, err := wellknownassets.FindContainerdAsset(c.Cluster, assetBuilder, arch) + containerdAsset, err := wellknownassets.FindContainerdAsset(c.Cluster, assetBuilder, arch) if err != nil { return err } - if containerdAssetUrl != nil && containerdAssetHash != nil { - c.Assets[arch] = append(c.Assets[arch], assets.BuildMirroredAsset(containerdAssetUrl, containerdAssetHash)) + if containerdAsset != nil { + c.Assets[arch] = append(c.Assets[arch], assets.BuildMirroredAsset(containerdAsset)) } - runcAssetUrl, runcAssetHash, err := wellknownassets.FindRuncAsset(c.Cluster, assetBuilder, arch) + runcAsset, err := wellknownassets.FindRuncAsset(c.Cluster, assetBuilder, arch) if err != nil { return err } - if runcAssetUrl != nil && runcAssetHash != nil { - c.Assets[arch] = append(c.Assets[arch], assets.BuildMirroredAsset(runcAssetUrl, runcAssetHash)) + if runcAsset != nil { + c.Assets[arch] = append(c.Assets[arch], assets.BuildMirroredAsset(runcAsset)) } - nerdctlAssetUrl, nerdctlAssetHash, err := wellknownassets.FindNerdctlAsset(c.Cluster, assetBuilder, arch) + nerdctlAsset, err := wellknownassets.FindNerdctlAsset(c.Cluster, assetBuilder, arch) if err != nil { return err } - if nerdctlAssetUrl != nil && nerdctlAssetHash != nil { - c.Assets[arch] = append(c.Assets[arch], assets.BuildMirroredAsset(nerdctlAssetUrl, nerdctlAssetHash)) + if nerdctlAsset != nil { + c.Assets[arch] = append(c.Assets[arch], assets.BuildMirroredAsset(nerdctlAsset)) } } - crictlAssetUrl, crictlAssetHash, err := wellknownassets.FindCrictlAsset(c.Cluster, assetBuilder, arch) + crictlAsset, err := wellknownassets.FindCrictlAsset(c.Cluster, assetBuilder, arch) if err != nil { return err } - if crictlAssetUrl != nil && crictlAssetHash != nil { - c.Assets[arch] = append(c.Assets[arch], assets.BuildMirroredAsset(crictlAssetUrl, crictlAssetHash)) + if crictlAsset != nil { + c.Assets[arch] = append(c.Assets[arch], assets.BuildMirroredAsset(crictlAsset)) } asset, err := wellknownassets.NodeUpAsset(assetBuilder, arch) diff --git a/pkg/nodemodel/nodeupconfigbuilder.go b/pkg/nodemodel/nodeupconfigbuilder.go index 66b04d3ad50f0..6acbbbfb47ffd 100644 --- a/pkg/nodemodel/nodeupconfigbuilder.go +++ b/pkg/nodemodel/nodeupconfigbuilder.go @@ -117,14 +117,14 @@ func NewNodeUpConfigBuilder(cluster *kops.Cluster, assetBuilder *assets.AssetBui baseURL.Path = path.Join(baseURL.Path, "/bin/linux", string(arch), component+".tar") - u, hash, err := assetBuilder.RemapFileAndSHA(baseURL) + asset, err := assetBuilder.RemapFile(baseURL, nil) if err != nil { return nil, err } image := &nodeup.Image{ - Sources: []string{u.String()}, - Hash: hash.Hex(), + Sources: []string{asset.DownloadURL.String()}, + Hash: asset.SHAValue.Hex(), } images[role][arch] = append(images[role][arch], image) } @@ -143,14 +143,14 @@ func NewNodeUpConfigBuilder(cluster *kops.Cluster, assetBuilder *assets.AssetBui baseURL.Path = path.Join(baseURL.Path, "/images/"+name+"-"+string(arch)+".tar.gz") - u, hash, err := assetBuilder.RemapFileAndSHA(baseURL) + asset, err := assetBuilder.RemapFile(baseURL, nil) if err != nil { return nil, err } image := &nodeup.Image{ - Sources: []string{u.String()}, - Hash: hash.Hex(), + Sources: []string{asset.DownloadURL.String()}, + Hash: asset.SHAValue.Hex(), } images[role][arch] = append(images[role][arch], image) } @@ -166,14 +166,14 @@ func NewNodeUpConfigBuilder(cluster *kops.Cluster, assetBuilder *assets.AssetBui baseURL.Path = path.Join(baseURL.Path, "/images/"+name+"-"+string(arch)+".tar.gz") - u, hash, err := assetBuilder.RemapFileAndSHA(baseURL) + asset, err := assetBuilder.RemapFile(baseURL, nil) if err != nil { return nil, err } image := &nodeup.Image{ - Sources: []string{u.String()}, - Hash: hash.Hex(), + Sources: []string{asset.DownloadURL.String()}, + Hash: asset.SHAValue.Hex(), } images[role][arch] = append(images[role][arch], image) } diff --git a/pkg/nodemodel/wellknownassets/cni.go b/pkg/nodemodel/wellknownassets/cni.go index b529c0ab8a4bb..58addeb1b6804 100644 --- a/pkg/nodemodel/wellknownassets/cni.go +++ b/pkg/nodemodel/wellknownassets/cni.go @@ -47,7 +47,7 @@ const ( ENV_VAR_CNI_ASSET_HASH = "CNI_ASSET_HASH_STRING" ) -func FindCNIAssets(c *kopsapi.Cluster, assetBuilder *assets.AssetBuilder, arch architectures.Architecture) (*url.URL, *hashing.Hash, error) { +func FindCNIAssets(c *kopsapi.Cluster, assetBuilder *assets.AssetBuilder, arch architectures.Architecture) (*assets.FileAsset, error) { // Override CNI packages from env vars cniAssetURL := os.Getenv(ENV_VAR_CNI_ASSET_URL) cniAssetHash := os.Getenv(ENV_VAR_CNI_ASSET_HASH) @@ -58,20 +58,20 @@ func FindCNIAssets(c *kopsapi.Cluster, assetBuilder *assets.AssetBuilder, arch a u, err := url.Parse(cniAssetURL) if err != nil { - return nil, nil, fmt.Errorf("unable to parse CNI plugin binaries asset URL %q: %v", cniAssetURL, err) + return nil, fmt.Errorf("unable to parse CNI plugin binaries asset URL %q: %v", cniAssetURL, err) } h, err := hashing.FromString(cniAssetHash) if err != nil { - return nil, nil, fmt.Errorf("unable to parse CNI plugin binaries asset hash %q: %v", cniAssetHash, err) + return nil, fmt.Errorf("unable to parse CNI plugin binaries asset hash %q: %v", cniAssetHash, err) } - u, err = assetBuilder.RemapFileAndSHAValue(u, cniAssetHash) + asset, err := assetBuilder.RemapFile(u, h) if err != nil { - return nil, nil, fmt.Errorf("unable to remap CNI plugin binaries asset: %v", err) + return nil, fmt.Errorf("unable to remap CNI plugin binaries asset: %v", err) } - return u, h, nil + return asset, nil } switch arch { @@ -90,18 +90,18 @@ func FindCNIAssets(c *kopsapi.Cluster, assetBuilder *assets.AssetBuilder, arch a } klog.V(2).Infof("Adding default AMD64 CNI plugin binaries asset: %s", cniAssetURL) default: - return nil, nil, fmt.Errorf("unknown arch for CNI plugin binaries asset: %s", arch) + return nil, fmt.Errorf("unknown arch for CNI plugin binaries asset: %s", arch) } u, err := url.Parse(cniAssetURL) if err != nil { - return nil, nil, fmt.Errorf("unable to parse CNI plugin binaries asset URL %q: %v", cniAssetURL, err) + return nil, fmt.Errorf("unable to parse CNI plugin binaries asset URL %q: %v", cniAssetURL, err) } - u, h, err := assetBuilder.RemapFileAndSHA(u) + asset, err := assetBuilder.RemapFile(u, nil) if err != nil { - return nil, nil, fmt.Errorf("unable to remap CNI plugin binaries asset: %v", err) + return nil, fmt.Errorf("unable to remap CNI plugin binaries asset: %v", err) } - return u, h, nil + return asset, nil } diff --git a/pkg/nodemodel/wellknownassets/cni_test.go b/pkg/nodemodel/wellknownassets/cni_test.go index 28a033a299827..9425fa008ea42 100644 --- a/pkg/nodemodel/wellknownassets/cni_test.go +++ b/pkg/nodemodel/wellknownassets/cni_test.go @@ -36,17 +36,17 @@ func Test_FindCNIAssetFromEnvironmentVariable(t *testing.T) { cluster.Spec.KubernetesVersion = "v1.18.0" assetBuilder := assets.NewAssetBuilder(vfs.Context, cluster.Spec.Assets, cluster.Spec.KubernetesVersion, false) - cniAsset, cniAssetHash, err := FindCNIAssets(cluster, assetBuilder, architectures.ArchitectureAmd64) + asset, err := FindCNIAssets(cluster, assetBuilder, architectures.ArchitectureAmd64) if err != nil { - t.Errorf("Unable to parse CNI version %s", err) + t.Fatalf("Unable to parse CNI version: %v", err) } - if cniAsset.String() != desiredCNIVersion { - t.Errorf("Expected CNI version from env var %q, but got %q instead", desiredCNIVersion, cniAsset) + if asset.DownloadURL.String() != desiredCNIVersion { + t.Errorf("Expected CNI version from env var %q, but got %q instead", desiredCNIVersion, asset.DownloadURL.String()) } - if cniAssetHash.String() != desiredCNIVersionHash { - t.Errorf("Expected empty CNI version hash, but got %v instead", cniAssetHash) + if asset.SHAValue.String() != desiredCNIVersionHash { + t.Errorf("Expected empty CNI version hash, but got %v instead", asset.SHAValue.String()) } } @@ -58,16 +58,16 @@ func Test_FindCNIAssetFromDefaults122(t *testing.T) { cluster.Spec.KubernetesVersion = "v1.22.0" assetBuilder := assets.NewAssetBuilder(vfs.Context, cluster.Spec.Assets, cluster.Spec.KubernetesVersion, false) - cniAsset, cniAssetHash, err := FindCNIAssets(cluster, assetBuilder, architectures.ArchitectureAmd64) + asset, err := FindCNIAssets(cluster, assetBuilder, architectures.ArchitectureAmd64) if err != nil { - t.Errorf("Unable to parse CNI version %s", err) + t.Fatalf("Unable to parse CNI version: %s", err) } - if cniAsset.String() != desiredCNIVersionURL { - t.Errorf("Expected default CNI version %q, but got %q instead", desiredCNIVersionURL, cniAsset) + if asset.DownloadURL.String() != desiredCNIVersionURL { + t.Errorf("Expected default CNI version %q, but got %q instead", desiredCNIVersionURL, asset.DownloadURL) } - if cniAssetHash.String() != desiredCNIVersionHash { - t.Errorf("Expected default CNI version hash %q, but got %q instead", desiredCNIVersionHash, cniAssetHash) + if asset.SHAValue.String() != desiredCNIVersionHash { + t.Errorf("Expected default CNI version hash %q, but got %q instead", desiredCNIVersionHash, asset.SHAValue.String()) } } diff --git a/pkg/nodemodel/wellknownassets/containerd.go b/pkg/nodemodel/wellknownassets/containerd.go index 3173ec8b5a9e4..8c0e7c2cf5f94 100644 --- a/pkg/nodemodel/wellknownassets/containerd.go +++ b/pkg/nodemodel/wellknownassets/containerd.go @@ -37,53 +37,49 @@ const ( containerdBundleUrlAmd64 = "https://github.com/containerd/containerd/releases/download/v%s/cri-containerd-cni-%s-linux-amd64.tar.gz" ) -func FindContainerdAsset(c *kops.Cluster, assetBuilder *assets.AssetBuilder, arch architectures.Architecture) (*url.URL, *hashing.Hash, error) { +func FindContainerdAsset(c *kops.Cluster, assetBuilder *assets.AssetBuilder, arch architectures.Architecture) (*assets.FileAsset, error) { if c.Spec.Containerd == nil { - return nil, nil, fmt.Errorf("unable to find containerd config") + return nil, fmt.Errorf("unable to find containerd config") } containerd := c.Spec.Containerd + canonicalURL := "" + knownHash := "" + if containerd.Packages != nil { if arch == architectures.ArchitectureAmd64 && containerd.Packages.UrlAmd64 != nil && containerd.Packages.HashAmd64 != nil { - assetUrl := fi.ValueOf(containerd.Packages.UrlAmd64) - assetHash := fi.ValueOf(containerd.Packages.HashAmd64) - return findAssetsUrlHash(assetBuilder, assetUrl, assetHash) + canonicalURL = fi.ValueOf(containerd.Packages.UrlAmd64) + knownHash = fi.ValueOf(containerd.Packages.HashAmd64) } if arch == architectures.ArchitectureArm64 && containerd.Packages.UrlArm64 != nil && containerd.Packages.HashArm64 != nil { - assetUrl := fi.ValueOf(containerd.Packages.UrlArm64) - assetHash := fi.ValueOf(containerd.Packages.HashArm64) - return findAssetsUrlHash(assetBuilder, assetUrl, assetHash) + canonicalURL = fi.ValueOf(containerd.Packages.UrlArm64) + knownHash = fi.ValueOf(containerd.Packages.HashArm64) } } - version := fi.ValueOf(containerd.Version) - if version == "" { - return nil, nil, fmt.Errorf("unable to find containerd version") - } - - return findContainerdVersionUrlHash(assetBuilder, arch, version) -} + if canonicalURL == "" { + version := fi.ValueOf(containerd.Version) + if version == "" { + return nil, fmt.Errorf("unable to find containerd version") + } -func findContainerdVersionUrlHash(assetBuilder *assets.AssetBuilder, arch architectures.Architecture, version string) (u *url.URL, h *hashing.Hash, e error) { - assetUrl, err := findContainerdVersionUrl(arch, version) - if err != nil { - return nil, nil, err - } - fileUrl, err := url.Parse(assetUrl) - if err != nil { - return nil, nil, err + assetURL, err := findContainerdVersionUrl(arch, version) + if err != nil { + return nil, err + } + canonicalURL = assetURL.String() } - return assetBuilder.RemapFileAndSHA(fileUrl) + return buildFileAsset(assetBuilder, canonicalURL, knownHash) } -func findContainerdVersionUrl(arch architectures.Architecture, version string) (string, error) { +func findContainerdVersionUrl(arch architectures.Architecture, version string) (*url.URL, error) { sv, err := semver.ParseTolerant(version) if err != nil { - return "", fmt.Errorf("unable to parse version string: %q", version) + return nil, fmt.Errorf("unable to parse version string: %q", version) } if sv.LT(semver.MustParse("1.4.0")) { - return "", fmt.Errorf("unsupported legacy containerd version: %q", version) + return nil, fmt.Errorf("unsupported legacy containerd version: %q", version) } var u string @@ -99,31 +95,35 @@ func findContainerdVersionUrl(arch architectures.Architecture, version string) ( u = fmt.Sprintf(containerdReleaseUrlArm64, version, version) } default: - return "", fmt.Errorf("unknown arch: %q", arch) + return nil, fmt.Errorf("unknown arch: %q", arch) } if u == "" { - return "", fmt.Errorf("unknown url for containerd version: %s - %s", arch, version) + return nil, fmt.Errorf("unknown url for containerd version: %s - %s", arch, version) } - return u, nil + return url.Parse(u) } -func findAssetsUrlHash(assetBuilder *assets.AssetBuilder, assetUrl string, assetHash string) (*url.URL, *hashing.Hash, error) { - u, err := url.Parse(assetUrl) +func buildFileAsset(assetBuilder *assets.AssetBuilder, canonicalURL string, knownHashString string) (*assets.FileAsset, error) { + u, err := url.Parse(canonicalURL) if err != nil { - return nil, nil, fmt.Errorf("unable to parse asset URL %q: %v", assetUrl, err) + return nil, fmt.Errorf("unable to parse asset URL %q: %w", canonicalURL, err) } - h, err := hashing.FromString(assetHash) - if err != nil { - return nil, nil, fmt.Errorf("unable to parse asset hash %q: %v", assetHash, err) + var knownHash *hashing.Hash + if knownHashString != "" { + h, err := hashing.FromString(knownHashString) + if err != nil { + return nil, fmt.Errorf("unable to parse asset hash %q: %w", knownHashString, err) + } + knownHash = h } - u, err = assetBuilder.RemapFileAndSHAValue(u, assetHash) + asset, err := assetBuilder.RemapFile(u, knownHash) if err != nil { - return nil, nil, fmt.Errorf("unable to remap asset: %v", err) + return nil, fmt.Errorf("unable to remap asset: %w", err) } - return u, h, nil + return asset, nil } diff --git a/pkg/nodemodel/wellknownassets/containerd_test.go b/pkg/nodemodel/wellknownassets/containerd_test.go index f990571a87f07..5820df1ef1262 100644 --- a/pkg/nodemodel/wellknownassets/containerd_test.go +++ b/pkg/nodemodel/wellknownassets/containerd_test.go @@ -87,7 +87,11 @@ func TestContainerdVersionUrl(t *testing.T) { t.Errorf("actual error %q differs from expected error %q", err, test.err) return } - if url != test.url { + got := "" + if url != nil { + got = url.String() + } + if got != test.url { t.Errorf("actual url %q differs from expected url %q", url, test.url) return } diff --git a/pkg/nodemodel/wellknownassets/crictl.go b/pkg/nodemodel/wellknownassets/crictl.go index ae24263c0f2b2..0edaa94e57463 100644 --- a/pkg/nodemodel/wellknownassets/crictl.go +++ b/pkg/nodemodel/wellknownassets/crictl.go @@ -23,7 +23,6 @@ import ( "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/assets" "k8s.io/kops/util/pkg/architectures" - "k8s.io/kops/util/pkg/hashing" ) const ( @@ -31,7 +30,7 @@ const ( crictlAssetUrlArm64 = "https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.29.0/crictl-v1.29.0-linux-arm64.tar.gz" ) -func FindCrictlAsset(c *kops.Cluster, assetBuilder *assets.AssetBuilder, arch architectures.Architecture) (*url.URL, *hashing.Hash, error) { +func FindCrictlAsset(c *kops.Cluster, assetBuilder *assets.AssetBuilder, arch architectures.Architecture) (*assets.FileAsset, error) { var assetURL string switch arch { case architectures.ArchitectureAmd64: @@ -39,18 +38,18 @@ func FindCrictlAsset(c *kops.Cluster, assetBuilder *assets.AssetBuilder, arch ar case architectures.ArchitectureArm64: assetURL = crictlAssetUrlArm64 default: - return nil, nil, fmt.Errorf("unknown arch for crictl binaries asset: %s", arch) + return nil, fmt.Errorf("unknown arch for crictl binaries asset: %s", arch) } u, err := url.Parse(assetURL) if err != nil { - return nil, nil, fmt.Errorf("unable to parse crictl binaries asset URL %q: %v", assetURL, err) + return nil, fmt.Errorf("unable to parse crictl binaries asset URL %q: %v", assetURL, err) } - u, h, err := assetBuilder.RemapFileAndSHA(u) + asset, err := assetBuilder.RemapFile(u, nil) if err != nil { - return nil, nil, fmt.Errorf("unable to remap crictl binaries asset: %v", err) + return nil, fmt.Errorf("unable to remap crictl binaries asset: %v", err) } - return u, h, err + return asset, err } diff --git a/pkg/nodemodel/wellknownassets/crictl_test.go b/pkg/nodemodel/wellknownassets/crictl_test.go index b869d65dc0afb..0977f6ccb7a4e 100644 --- a/pkg/nodemodel/wellknownassets/crictl_test.go +++ b/pkg/nodemodel/wellknownassets/crictl_test.go @@ -33,14 +33,14 @@ func Test_FindCrictlVersionHash(t *testing.T) { cluster.Spec.KubernetesVersion = "v1.29.0" assetBuilder := assets.NewAssetBuilder(vfs.Context, cluster.Spec.Assets, cluster.Spec.KubernetesVersion, false) - crictlAsset, crictlAssetHash, err := FindCrictlAsset(cluster, assetBuilder, architectures.ArchitectureAmd64) + crictlAsset, err := FindCrictlAsset(cluster, assetBuilder, architectures.ArchitectureAmd64) if err != nil { t.Errorf("Unable to parse crictl version %s", err) } - if crictlAsset.String() != desiredCrictlURL { - t.Errorf("Expected crictl version %q, but got %q instead", desiredCrictlURL, crictlAsset) + if crictlAsset.DownloadURL.String() != desiredCrictlURL { + t.Errorf("Expected crictl version %q, but got %q instead", desiredCrictlURL, crictlAsset.DownloadURL) } - if crictlAssetHash.String() != desiredCirctlHash { - t.Errorf("Expected crictl version hash %q, but got %q instead", desiredCirctlHash, crictlAssetHash) + if crictlAsset.SHAValue.String() != desiredCirctlHash { + t.Errorf("Expected crictl version hash %q, but got %q instead", desiredCirctlHash, crictlAsset.SHAValue) } } diff --git a/pkg/nodemodel/wellknownassets/kopsassets.go b/pkg/nodemodel/wellknownassets/kopsassets.go index 0bb206d53bbc1..5b979df2b5770 100644 --- a/pkg/nodemodel/wellknownassets/kopsassets.go +++ b/pkg/nodemodel/wellknownassets/kopsassets.go @@ -26,7 +26,6 @@ import ( "k8s.io/kops" "k8s.io/kops/pkg/assets" "k8s.io/kops/util/pkg/architectures" - "k8s.io/kops/util/pkg/hashing" ) const ( @@ -93,12 +92,12 @@ func NodeUpAsset(assetsBuilder *assets.AssetBuilder, arch architectures.Architec return nodeUpAsset[arch], nil } - u, hash, err := KopsFileURL(fmt.Sprintf("linux/%s/nodeup", arch), assetsBuilder) + asset, err := KopsFileURL(fmt.Sprintf("linux/%s/nodeup", arch), assetsBuilder) if err != nil { return nil, err } - nodeUpAsset[arch] = assets.BuildMirroredAsset(u, hash) - klog.V(8).Infof("Using default nodeup location for %s: %q", arch, u.String()) + nodeUpAsset[arch] = assets.BuildMirroredAsset(asset) + klog.V(8).Infof("Using default nodeup location for %s: %q", arch, asset.DownloadURL.String()) return nodeUpAsset[arch], nil } @@ -113,12 +112,12 @@ func ProtokubeAsset(assetsBuilder *assets.AssetBuilder, arch architectures.Archi return protokubeAsset[arch], nil } - u, hash, err := KopsFileURL(fmt.Sprintf("linux/%s/protokube", arch), assetsBuilder) + asset, err := KopsFileURL(fmt.Sprintf("linux/%s/protokube", arch), assetsBuilder) if err != nil { return nil, err } - protokubeAsset[arch] = assets.BuildMirroredAsset(u, hash) - klog.V(8).Infof("Using default protokube location for %s: %q", arch, u.String()) + protokubeAsset[arch] = assets.BuildMirroredAsset(asset) + klog.V(8).Infof("Using default protokube location for %s: %q", arch, asset.DownloadURL.String()) return protokubeAsset[arch], nil } @@ -133,29 +132,29 @@ func ChannelsAsset(assetsBuilder *assets.AssetBuilder, arch architectures.Archit return channelsAsset[arch], nil } - u, hash, err := KopsFileURL(fmt.Sprintf("linux/%s/channels", arch), assetsBuilder) + asset, err := KopsFileURL(fmt.Sprintf("linux/%s/channels", arch), assetsBuilder) if err != nil { return nil, err } - channelsAsset[arch] = assets.BuildMirroredAsset(u, hash) - klog.V(8).Infof("Using default channels location for %s: %q", arch, u.String()) + channelsAsset[arch] = assets.BuildMirroredAsset(asset) + klog.V(8).Infof("Using default channels location for %s: %q", arch, asset.DownloadURL.String()) return channelsAsset[arch], nil } // KopsFileURL returns the base url for the distribution of kops - in particular for nodeup & docker images -func KopsFileURL(file string, assetBuilder *assets.AssetBuilder) (*url.URL, *hashing.Hash, error) { +func KopsFileURL(file string, assetBuilder *assets.AssetBuilder) (*assets.FileAsset, error) { base, err := BaseURL() if err != nil { - return nil, nil, err + return nil, err } base.Path = path.Join(base.Path, file) - fileURL, hash, err := assetBuilder.RemapFileAndSHA(base) + asset, err := assetBuilder.RemapFile(base, nil) if err != nil { - return nil, nil, err + return nil, err } - return fileURL, hash, nil + return asset, nil } diff --git a/pkg/nodemodel/wellknownassets/kopsassets_test.go b/pkg/nodemodel/wellknownassets/kopsassets_test.go index e7c16d9fe6282..88434f9d558b6 100644 --- a/pkg/nodemodel/wellknownassets/kopsassets_test.go +++ b/pkg/nodemodel/wellknownassets/kopsassets_test.go @@ -56,7 +56,12 @@ func Test_BuildMirroredAsset(t *testing.T) { t.Errorf("cannot parse URL: %s", fmt.Sprintf(tc.url, kops.Version)) return } - actual := assets.BuildMirroredAsset(u, h) + asset := &assets.FileAsset{ + DownloadURL: u, + CanonicalURL: u, + SHAValue: h, + } + actual := assets.BuildMirroredAsset(asset) if !reflect.DeepEqual(actual.Locations, tc.expected) { t.Errorf("Locations differ:\nActual: %+v\nExpect: %+v", actual.Locations, tc.expected) diff --git a/pkg/nodemodel/wellknownassets/nerdctl.go b/pkg/nodemodel/wellknownassets/nerdctl.go index 25b9afb8b9f4b..e002009f27c1b 100644 --- a/pkg/nodemodel/wellknownassets/nerdctl.go +++ b/pkg/nodemodel/wellknownassets/nerdctl.go @@ -18,12 +18,10 @@ package wellknownassets import ( "fmt" - "net/url" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/assets" "k8s.io/kops/util/pkg/architectures" - "k8s.io/kops/util/pkg/hashing" ) const ( @@ -33,7 +31,7 @@ const ( nerdctlAssetHashArm64 = "d8df47708ca57b9cd7f498055126ba7dcfc811d9ba43aae1830c93a09e70e22d" ) -func FindNerdctlAsset(c *kops.Cluster, assetBuilder *assets.AssetBuilder, arch architectures.Architecture) (*url.URL, *hashing.Hash, error) { +func FindNerdctlAsset(c *kops.Cluster, assetBuilder *assets.AssetBuilder, arch architectures.Architecture) (*assets.FileAsset, error) { var assetURL, assetHash string switch arch { case architectures.ArchitectureAmd64: @@ -43,8 +41,8 @@ func FindNerdctlAsset(c *kops.Cluster, assetBuilder *assets.AssetBuilder, arch a assetURL = nerdctlAssetUrlArm64 assetHash = nerdctlAssetHashArm64 default: - return nil, nil, fmt.Errorf("unknown arch for nerdctl binaries asset: %s", arch) + return nil, fmt.Errorf("unknown arch for nerdctl binaries asset: %s", arch) } - return findAssetsUrlHash(assetBuilder, assetURL, assetHash) + return buildFileAsset(assetBuilder, assetURL, assetHash) } diff --git a/pkg/nodemodel/wellknownassets/runc.go b/pkg/nodemodel/wellknownassets/runc.go index c9d2a586ab433..c5683281d7d78 100644 --- a/pkg/nodemodel/wellknownassets/runc.go +++ b/pkg/nodemodel/wellknownassets/runc.go @@ -18,7 +18,6 @@ package wellknownassets import ( "fmt" - "net/url" "github.com/blang/semver/v4" @@ -26,7 +25,6 @@ import ( "k8s.io/kops/pkg/assets" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/util/pkg/architectures" - "k8s.io/kops/util/pkg/hashing" ) const ( @@ -34,70 +32,54 @@ const ( runcVersionUrlArm64 = "https://github.com/opencontainers/runc/releases/download/v%s/runc.arm64" ) -func FindRuncAsset(c *kops.Cluster, assetBuilder *assets.AssetBuilder, arch architectures.Architecture) (*url.URL, *hashing.Hash, error) { +func FindRuncAsset(c *kops.Cluster, assetBuilder *assets.AssetBuilder, arch architectures.Architecture) (*assets.FileAsset, error) { if c.Spec.Containerd == nil { - return nil, nil, fmt.Errorf("unable to find containerd config") + return nil, fmt.Errorf("unable to find containerd config") } containerd := c.Spec.Containerd containerdVersion, err := semver.ParseTolerant(fi.ValueOf(containerd.Version)) if err != nil { - return nil, nil, fmt.Errorf("unable to parse version string: %q", fi.ValueOf(containerd.Version)) + return nil, fmt.Errorf("unable to parse version string: %q", fi.ValueOf(containerd.Version)) } // A compatible runc binary is bundled with containerd builds < v1.6.0 // https://github.com/containerd/containerd/issues/6541 if containerdVersion.LT(semver.MustParse("1.6.0")) { - return nil, nil, nil + return nil, nil } if containerd.Runc == nil { - return nil, nil, fmt.Errorf("unable to find runc config") + return nil, fmt.Errorf("unable to find runc config") } runc := containerd.Runc + canonicalURL := "" + knownHash := "" + if runc.Packages != nil { if arch == architectures.ArchitectureAmd64 && runc.Packages.UrlAmd64 != nil && runc.Packages.HashAmd64 != nil { - assetUrl := fi.ValueOf(runc.Packages.UrlAmd64) - assetHash := fi.ValueOf(runc.Packages.HashAmd64) - return findAssetsUrlHash(assetBuilder, assetUrl, assetHash) + canonicalURL = fi.ValueOf(runc.Packages.UrlAmd64) + knownHash = fi.ValueOf(runc.Packages.HashAmd64) } if arch == architectures.ArchitectureArm64 && runc.Packages.UrlArm64 != nil && runc.Packages.HashArm64 != nil { - assetUrl := fi.ValueOf(runc.Packages.UrlArm64) - assetHash := fi.ValueOf(runc.Packages.HashArm64) - return findAssetsUrlHash(assetBuilder, assetUrl, assetHash) + canonicalURL = fi.ValueOf(runc.Packages.UrlArm64) + knownHash = fi.ValueOf(runc.Packages.HashArm64) } } - version := fi.ValueOf(runc.Version) - if version == "" { - return nil, nil, fmt.Errorf("unable to find runc version") - } - assetUrl, assetHash, err := findRuncVersionUrlHash(arch, version) - if err != nil { - return nil, nil, err - } - - return findAssetsUrlHash(assetBuilder, assetUrl, assetHash) -} - -func findRuncVersionUrlHash(arch architectures.Architecture, version string) (u string, h string, e error) { - var runcAssetUrl, runcAssetHash string - - if findAllRuncHashesAmd64()[version] != "" { - var err error - runcAssetUrl, err = findRuncVersionUrl(arch, version) - if err != nil { - return "", "", err + if canonicalURL == "" { + version := fi.ValueOf(runc.Version) + if version == "" { + return nil, fmt.Errorf("unable to find runc version") } - runcAssetHash, err = findRuncVersionHash(arch, version) + u, err := findRuncVersionUrl(arch, version) if err != nil { - return "", "", err + return nil, err } - } else { - return "", "", fmt.Errorf("unknown url and hash for runc version: %s - %s", arch, version) + canonicalURL = u } - return runcAssetUrl, runcAssetHash, nil + return buildFileAsset(assetBuilder, canonicalURL, knownHash) } func findRuncVersionUrl(arch architectures.Architecture, version string) (string, error) { @@ -125,69 +107,3 @@ func findRuncVersionUrl(arch architectures.Architecture, version string) (string return u, nil } - -func findRuncVersionHash(arch architectures.Architecture, version string) (string, error) { - sv, err := semver.ParseTolerant(version) - if err != nil { - return "", fmt.Errorf("unable to parse version string: %q", version) - } - if sv.LT(semver.MustParse("1.1.0")) { - return "", fmt.Errorf("unsupported runc version: %q", version) - } - - var h string - switch arch { - case architectures.ArchitectureAmd64: - h = findAllRuncHashesAmd64()[version] - case architectures.ArchitectureArm64: - h = findAllRuncHashesArm64()[version] - default: - return "", fmt.Errorf("unknown arch: %q", arch) - } - - if h == "" { - return "", fmt.Errorf("unknown hash for runc version: %s - %s", arch, version) - } - - return h, nil -} - -func findAllRuncHashesAmd64() map[string]string { - hashes := map[string]string{ - "1.1.0": "ab1c67fbcbdddbe481e48a55cf0ef9a86b38b166b5079e0010737fd87d7454bb", - "1.1.1": "5798c85d2c8b6942247ab8d6830ef362924cd72a8e236e77430c3ab1be15f080", - "1.1.2": "e0436dfc5d26ca88f00e84cbdab5801dd9829b1e5ded05dcfc162ce5718c32ce", - "1.1.3": "6e8b24be90fffce6b025d254846da9d2ca6d65125f9139b6354bab0272253d01", - "1.1.4": "db772be63147a4e747b4fe286c7c16a2edc4a8458bd3092ea46aaee77750e8ce", - "1.1.5": "f00b144e86f8c1db347a2e8f22caade07d55382c5f76dd5c0a5b1ab64eaec8bb", - "1.1.6": "868bee5b8dc2a01df0ca41d0accfad6a3372dc1165ebfb76143d2c6672e86115", - "1.1.7": "c3aadb419e5872af49504b6de894055251d2e685fddddb981a79703e7f895cbd", - "1.1.8": "1d05ed79854efc707841dfc7afbf3b86546fc1d0b3a204435ca921c14af8385b", - "1.1.9": "b9bfdd4cb27cddbb6172a442df165a80bfc0538a676fbca1a6a6c8f4c6933b43", - "1.1.10": "81f73a59be3d122ab484d7dfe9ddc81030f595cc59968f61c113a9a38a2c113a", - "1.1.11": "77ae134de014613c44d25e6310a57a219a7a91155cd47d069a0f22a2cad5caea", - "1.1.12": "aadeef400b8f05645768c1476d1023f7875b78f52c7ff1967a6dbce236b8cbd8", - } - - return hashes -} - -func findAllRuncHashesArm64() map[string]string { - hashes := map[string]string{ - "1.1.0": "9ec8e68feabc4e7083a4cfa45ebe4d529467391e0b03ee7de7ddda5770b05e68", - "1.1.1": "20c436a736547309371c7ac2a335f5fe5a42b450120e497d09c8dc3902c28444", - "1.1.2": "6ebd968d46d00a3886e9a0cae2e0a7b399e110cf5d7b26e63ce23c1d81ea10ef", - "1.1.3": "00c9ad161a77a01d9dcbd25b1d76fa9822e57d8e4abf26ba8907c98f6bcfcd0f", - "1.1.4": "dbb71e737eaef454a406ce21fd021bd8f1b35afb7635016745992bbd7c17a223", - "1.1.5": "54e79e4d48b9e191767e4abc08be1a8476a1c757e9a9f8c45c6ded001226867f", - "1.1.6": "da5b2ed26a173a69ea66eae7c369feebf59c1031e14985f512a0a293bb5f76fb", - "1.1.7": "1b309c4d5aa4cc7b888b2f79c385ecee26ca3d55dae0852e7c4a692196d5faab", - "1.1.8": "7c22cb618116d1d5216d79e076349f93a672253d564b19928a099c20e4acd658", - "1.1.9": "b43e9f561e85906f469eef5a7b7992fc586f750f44a0e011da4467e7008c33a0", - "1.1.10": "4830afd426bdeacbdf9cb8729524aa2ed51790b8c4b28786995925593708f1c8", - "1.1.11": "9f1ee53f06b78cc4a115ca6ae4eec10567999539ce828a22c5351edba043ed12", - "1.1.12": "879f910a05c95c10c64ad8eb7d5e3aa8e4b30e65587b3d68e009a3565aed5bb8", - } - - return hashes -} diff --git a/pkg/nodemodel/wellknownassets/runc_test.go b/pkg/nodemodel/wellknownassets/runc_test.go index 2d164dcc2459c..187f214790619 100644 --- a/pkg/nodemodel/wellknownassets/runc_test.go +++ b/pkg/nodemodel/wellknownassets/runc_test.go @@ -18,72 +18,12 @@ package wellknownassets import ( "fmt" - "os" - "path" - "path/filepath" "reflect" "testing" - "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/util/pkg/architectures" ) -func TestRuncVersionUrlHash(t *testing.T) { - tests := []struct { - version string - arch architectures.Architecture - hash string - url string - err error - }{ - { - arch: architectures.ArchitectureAmd64, - version: "1.100.0", - url: "", - hash: "", - err: fmt.Errorf("unknown url and hash for runc version: amd64 - 1.100.0"), - }, - { - arch: architectures.ArchitectureArm64, - version: "1.100.0", - url: "", - hash: "", - err: fmt.Errorf("unknown url and hash for runc version: arm64 - 1.100.0"), - }, - { - arch: architectures.ArchitectureAmd64, - version: "1.1.0", - url: "https://github.com/opencontainers/runc/releases/download/v1.1.0/runc.amd64", - hash: "ab1c67fbcbdddbe481e48a55cf0ef9a86b38b166b5079e0010737fd87d7454bb", - err: nil, - }, - { - arch: architectures.ArchitectureArm64, - version: "1.1.0", - url: "https://github.com/opencontainers/runc/releases/download/v1.1.0/runc.arm64", - hash: "9ec8e68feabc4e7083a4cfa45ebe4d529467391e0b03ee7de7ddda5770b05e68", - err: nil, - }, - } - for _, test := range tests { - t.Run(fmt.Sprintf("%s-%s", test.version, test.arch), func(t *testing.T) { - url, hash, err := findRuncVersionUrlHash(test.arch, test.version) - if !reflect.DeepEqual(err, test.err) { - t.Errorf("actual error %q differs from expected error %q", err, test.err) - return - } - if url != test.url { - t.Errorf("actual url %q differs from expected url %q", url, test.url) - return - } - if hash != test.hash { - t.Errorf("actual hash %q differs from expected hash %q", hash, test.hash) - return - } - }) - } -} - func TestRuncVersionUrl(t *testing.T) { tests := []struct { version string @@ -154,137 +94,3 @@ func TestRuncVersionUrl(t *testing.T) { }) } } - -func TestRuncVersionHash(t *testing.T) { - tests := []struct { - version string - arch architectures.Architecture - hash string - err error - }{ - { - arch: "", - version: "1.1.0", - hash: "", - err: fmt.Errorf("unknown arch: \"\""), - }, - { - arch: "arm", - version: "1.1.0", - hash: "", - err: fmt.Errorf("unknown arch: \"arm\""), - }, - { - arch: architectures.ArchitectureAmd64, - version: "", - hash: "", - err: fmt.Errorf("unable to parse version string: \"\""), - }, - { - arch: architectures.ArchitectureArm64, - version: "", - hash: "", - err: fmt.Errorf("unable to parse version string: \"\""), - }, - { - arch: architectures.ArchitectureAmd64, - version: "1.0.0", - hash: "", - err: fmt.Errorf("unsupported runc version: \"1.0.0\""), - }, - { - arch: architectures.ArchitectureArm64, - version: "1.0.0", - hash: "", - err: fmt.Errorf("unsupported runc version: \"1.0.0\""), - }, - { - arch: architectures.ArchitectureAmd64, - version: "1.100.0", - hash: "", - err: fmt.Errorf("unknown hash for runc version: amd64 - 1.100.0"), - }, - { - arch: architectures.ArchitectureArm64, - version: "1.100.0", - hash: "", - err: fmt.Errorf("unknown hash for runc version: arm64 - 1.100.0"), - }, - { - arch: architectures.ArchitectureAmd64, - version: "1.1.0", - hash: "ab1c67fbcbdddbe481e48a55cf0ef9a86b38b166b5079e0010737fd87d7454bb", - err: nil, - }, - { - arch: architectures.ArchitectureArm64, - version: "1.1.0", - hash: "9ec8e68feabc4e7083a4cfa45ebe4d529467391e0b03ee7de7ddda5770b05e68", - err: nil, - }, - } - for _, test := range tests { - t.Run(fmt.Sprintf("%s-%s", test.version, test.arch), func(t *testing.T) { - hash, err := findRuncVersionHash(test.arch, test.version) - if !reflect.DeepEqual(err, test.err) { - t.Errorf("actual error %q differs from expected error %q", err, test.err) - return - } - if hash != test.hash { - t.Errorf("actual hash %q differs from expected hash %q", hash, test.hash) - return - } - }) - } -} - -func TestRuncVersionsHashesAmd64(t *testing.T) { - if os.Getenv("VERIFY_HASHES") == "" { - t.Skip("VERIFY_HASHES not set, won't download & verify runc hashes") - } - - for version, hash := range findAllRuncHashesAmd64() { - t.Run(version+"-amd64", func(t *testing.T) { - url, _ := findRuncVersionUrl(architectures.ArchitectureAmd64, version) - if err := verifyPackageHash(url, hash); err != nil { - t.Errorf("error verifying package %q: %v", url, err) - } - }) - } -} - -func TestRuncVersionsHashesArm64(t *testing.T) { - if os.Getenv("VERIFY_HASHES") == "" { - t.Skip("VERIFY_HASHES not set, won't download & verify runc hashes") - } - - for version, hash := range findAllRuncHashesArm64() { - t.Run(version+"-arm64", func(t *testing.T) { - url, _ := findRuncVersionUrl(architectures.ArchitectureArm64, version) - if err := verifyPackageHash(url, hash); err != nil { - t.Errorf("error verifying package %q: %v", url, err) - } - }) - } -} - -func verifyPackageHash(u string, h string) error { - name := fmt.Sprintf("%s-%s", h, path.Base(u)) - path := filepath.Join("/tmp", name) - - actualHash, err := fi.DownloadURL(u, path, nil) - if err != nil { - return err - } - - err = os.Remove(path) - if err != nil { - return err - } - - if h != actualHash.Hex() { - return fmt.Errorf("actual hash %q differs from expected hash %q", actualHash.Hex(), h) - } - - return nil -}