Add option to configure runc version for containerd

This commit is contained in:
Ciprian Hacman 2022-08-04 08:49:47 +03:00
parent 9661894261
commit 11a0f64cd8
14 changed files with 573 additions and 7 deletions

View File

@ -1229,6 +1229,30 @@ tar tf cri-containerd-cni-1.4.4-linux-amd64.tar.gz
usr/local/sbin/runc
```
### Runc Version and Packages
{{ kops_feature_table(kops_added_default='1.24.2') }}
kOps uses the binaries from https://github.com/opencontainers/runc for installing runc on any supported OS. This makes it easy to specify the desired release version:
```yaml
spec:
containerd:
runc:
version: 1.1.2
```
It also makes it possible to use a newer version than the kOps binary, pre-release packages, or even a custom build, by specifying its URL and sha256:
```yaml
spec:
containerd:
runc:
version: 1.100.0
packages:
urlAmd64: https://cdn.example.com/k8s/runc/releases/download/v1.100.0/runc.amd64
hashAmd64: ab1c67fbcbdddbe481e48a55cf0ef9a86b38b166b5079e0010737fd87d7454bb
```
### Registry Mirrors
{{ kops_feature_table(kops_added_default='1.19') }}

View File

@ -790,6 +790,33 @@ spec:
root:
description: Root directory for persistent data (default "/var/lib/containerd").
type: string
runc:
description: Runc configures the runc runtime.
properties:
packages:
description: Packages overrides the URL and hash for the packages.
properties:
hashAmd64:
description: HashAmd64 overrides the hash for the AMD64
package.
type: string
hashArm64:
description: HashArm64 overrides the hash for the ARM64
package.
type: string
urlAmd64:
description: UrlAmd64 overrides the URL for the AMD64
package.
type: string
urlArm64:
description: UrlArm64 overrides the URL for the ARM64
package.
type: string
type: object
version:
description: Version used to pick the runc package.
type: string
type: object
skipInstall:
description: SkipInstall prevents kOps from installing and modifying
containerd in any way (default "false").

View File

@ -155,6 +155,33 @@ spec:
root:
description: Root directory for persistent data (default "/var/lib/containerd").
type: string
runc:
description: Runc configures the runc runtime.
properties:
packages:
description: Packages overrides the URL and hash for the packages.
properties:
hashAmd64:
description: HashAmd64 overrides the hash for the AMD64
package.
type: string
hashArm64:
description: HashArm64 overrides the hash for the ARM64
package.
type: string
urlAmd64:
description: UrlAmd64 overrides the URL for the AMD64
package.
type: string
urlArm64:
description: UrlArm64 overrides the URL for the ARM64
package.
type: string
type: object
version:
description: Version used to pick the runc package.
type: string
type: object
skipInstall:
description: SkipInstall prevents kOps from installing and modifying
containerd in any way (default "false").

View File

@ -41,6 +41,8 @@ type ContainerdConfig struct {
Version *string `json:"version,omitempty"`
// NvidiaGPU configures the Nvidia GPU runtime.
NvidiaGPU *NvidiaGPUConfig `json:"nvidiaGPU,omitempty"`
// Runc configures the runc runtime.
Runc *Runc `json:"runc,omitempty"`
}
type NvidiaGPUConfig struct {
@ -51,3 +53,10 @@ type NvidiaGPUConfig struct {
// They will only be installed on intances that has an Nvidia GPU.
Enabled *bool `json:"enabled,omitempty"`
}
type Runc struct {
// Version used to pick the runc package.
Version *string `json:"version,omitempty"`
// Packages overrides the URL and hash for the packages.
Packages *PackagesConfig `json:"packages,omitempty"`
}

View File

@ -38,6 +38,8 @@ type ContainerdConfig struct {
Version *string `json:"version,omitempty"`
// NvidiaGPU configures the Nvidia GPU runtime.
NvidiaGPU *NvidiaGPUConfig `json:"nvidiaGPU,omitempty"`
// Runc configures the runc runtime.
Runc *Runc `json:"runc,omitempty"`
}
type NvidiaGPUConfig struct {
@ -48,3 +50,10 @@ type NvidiaGPUConfig struct {
// They will only be installed on intances that has an Nvidia GPU.
Enabled *bool `json:"enabled,omitempty"`
}
type Runc struct {
// Version used to pick the runc package.
Version *string `json:"version,omitempty"`
// Packages overrides the URL and hash for the packages.
Packages *PackagesConfig `json:"packages,omitempty"`
}

View File

@ -1044,6 +1044,16 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*Runc)(nil), (*kops.Runc)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha2_Runc_To_kops_Runc(a.(*Runc), b.(*kops.Runc), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*kops.Runc)(nil), (*Runc)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kops_Runc_To_v1alpha2_Runc(a.(*kops.Runc), b.(*Runc), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*SSHCredential)(nil), (*kops.SSHCredential)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha2_SSHCredential_To_kops_SSHCredential(a.(*SSHCredential), b.(*kops.SSHCredential), scope)
}); err != nil {
@ -3322,6 +3332,15 @@ func autoConvert_v1alpha2_ContainerdConfig_To_kops_ContainerdConfig(in *Containe
} else {
out.NvidiaGPU = nil
}
if in.Runc != nil {
in, out := &in.Runc, &out.Runc
*out = new(kops.Runc)
if err := Convert_v1alpha2_Runc_To_kops_Runc(*in, *out, s); err != nil {
return err
}
} else {
out.Runc = nil
}
return nil
}
@ -3357,6 +3376,15 @@ func autoConvert_kops_ContainerdConfig_To_v1alpha2_ContainerdConfig(in *kops.Con
} else {
out.NvidiaGPU = nil
}
if in.Runc != nil {
in, out := &in.Runc, &out.Runc
*out = new(Runc)
if err := Convert_kops_Runc_To_v1alpha2_Runc(*in, *out, s); err != nil {
return err
}
} else {
out.Runc = nil
}
return nil
}
@ -6934,6 +6962,44 @@ func Convert_kops_RouteSpec_To_v1alpha2_RouteSpec(in *kops.RouteSpec, out *Route
return autoConvert_kops_RouteSpec_To_v1alpha2_RouteSpec(in, out, s)
}
func autoConvert_v1alpha2_Runc_To_kops_Runc(in *Runc, out *kops.Runc, s conversion.Scope) error {
out.Version = in.Version
if in.Packages != nil {
in, out := &in.Packages, &out.Packages
*out = new(kops.PackagesConfig)
if err := Convert_v1alpha2_PackagesConfig_To_kops_PackagesConfig(*in, *out, s); err != nil {
return err
}
} else {
out.Packages = nil
}
return nil
}
// Convert_v1alpha2_Runc_To_kops_Runc is an autogenerated conversion function.
func Convert_v1alpha2_Runc_To_kops_Runc(in *Runc, out *kops.Runc, s conversion.Scope) error {
return autoConvert_v1alpha2_Runc_To_kops_Runc(in, out, s)
}
func autoConvert_kops_Runc_To_v1alpha2_Runc(in *kops.Runc, out *Runc, s conversion.Scope) error {
out.Version = in.Version
if in.Packages != nil {
in, out := &in.Packages, &out.Packages
*out = new(PackagesConfig)
if err := Convert_kops_PackagesConfig_To_v1alpha2_PackagesConfig(*in, *out, s); err != nil {
return err
}
} else {
out.Packages = nil
}
return nil
}
// Convert_kops_Runc_To_v1alpha2_Runc is an autogenerated conversion function.
func Convert_kops_Runc_To_v1alpha2_Runc(in *kops.Runc, out *Runc, s conversion.Scope) error {
return autoConvert_kops_Runc_To_v1alpha2_Runc(in, out, s)
}
func autoConvert_v1alpha2_SSHCredential_To_kops_SSHCredential(in *SSHCredential, out *kops.SSHCredential, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
if err := Convert_v1alpha2_SSHCredentialSpec_To_kops_SSHCredentialSpec(&in.Spec, &out.Spec, s); err != nil {

View File

@ -1412,6 +1412,11 @@ func (in *ContainerdConfig) DeepCopyInto(out *ContainerdConfig) {
*out = new(NvidiaGPUConfig)
(*in).DeepCopyInto(*out)
}
if in.Runc != nil {
in, out := &in.Runc, &out.Runc
*out = new(Runc)
(*in).DeepCopyInto(*out)
}
return
}
@ -4992,6 +4997,32 @@ func (in *RouteSpec) DeepCopy() *RouteSpec {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Runc) DeepCopyInto(out *Runc) {
*out = *in
if in.Version != nil {
in, out := &in.Version, &out.Version
*out = new(string)
**out = **in
}
if in.Packages != nil {
in, out := &in.Packages, &out.Packages
*out = new(PackagesConfig)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Runc.
func (in *Runc) DeepCopy() *Runc {
if in == nil {
return nil
}
out := new(Runc)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SSHCredential) DeepCopyInto(out *SSHCredential) {
*out = *in

View File

@ -38,6 +38,8 @@ type ContainerdConfig struct {
Version *string `json:"version,omitempty"`
// NvidiaGPU configures the Nvidia GPU runtime.
NvidiaGPU *NvidiaGPUConfig `json:"nvidiaGPU,omitempty"`
// Runc configures the runc runtime.
Runc *Runc `json:"runc,omitempty"`
}
type NvidiaGPUConfig struct {
@ -48,3 +50,10 @@ type NvidiaGPUConfig struct {
// They will only be installed on intances that has an Nvidia GPU.
Enabled *bool `json:"enabled,omitempty"`
}
type Runc struct {
// Version used to pick the runc package.
Version *string `json:"version,omitempty"`
// Packages overrides the URL and hash for the packages.
Packages *PackagesConfig `json:"packages,omitempty"`
}

View File

@ -1084,6 +1084,16 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*Runc)(nil), (*kops.Runc)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha3_Runc_To_kops_Runc(a.(*Runc), b.(*kops.Runc), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*kops.Runc)(nil), (*Runc)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kops_Runc_To_v1alpha3_Runc(a.(*kops.Runc), b.(*Runc), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*SSHCredential)(nil), (*kops.SSHCredential)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha3_SSHCredential_To_kops_SSHCredential(a.(*SSHCredential), b.(*kops.SSHCredential), scope)
}); err != nil {
@ -3402,6 +3412,15 @@ func autoConvert_v1alpha3_ContainerdConfig_To_kops_ContainerdConfig(in *Containe
} else {
out.NvidiaGPU = nil
}
if in.Runc != nil {
in, out := &in.Runc, &out.Runc
*out = new(kops.Runc)
if err := Convert_v1alpha3_Runc_To_kops_Runc(*in, *out, s); err != nil {
return err
}
} else {
out.Runc = nil
}
return nil
}
@ -3437,6 +3456,15 @@ func autoConvert_kops_ContainerdConfig_To_v1alpha3_ContainerdConfig(in *kops.Con
} else {
out.NvidiaGPU = nil
}
if in.Runc != nil {
in, out := &in.Runc, &out.Runc
*out = new(Runc)
if err := Convert_kops_Runc_To_v1alpha3_Runc(*in, *out, s); err != nil {
return err
}
} else {
out.Runc = nil
}
return nil
}
@ -6911,6 +6939,44 @@ func Convert_kops_RouteSpec_To_v1alpha3_RouteSpec(in *kops.RouteSpec, out *Route
return autoConvert_kops_RouteSpec_To_v1alpha3_RouteSpec(in, out, s)
}
func autoConvert_v1alpha3_Runc_To_kops_Runc(in *Runc, out *kops.Runc, s conversion.Scope) error {
out.Version = in.Version
if in.Packages != nil {
in, out := &in.Packages, &out.Packages
*out = new(kops.PackagesConfig)
if err := Convert_v1alpha3_PackagesConfig_To_kops_PackagesConfig(*in, *out, s); err != nil {
return err
}
} else {
out.Packages = nil
}
return nil
}
// Convert_v1alpha3_Runc_To_kops_Runc is an autogenerated conversion function.
func Convert_v1alpha3_Runc_To_kops_Runc(in *Runc, out *kops.Runc, s conversion.Scope) error {
return autoConvert_v1alpha3_Runc_To_kops_Runc(in, out, s)
}
func autoConvert_kops_Runc_To_v1alpha3_Runc(in *kops.Runc, out *Runc, s conversion.Scope) error {
out.Version = in.Version
if in.Packages != nil {
in, out := &in.Packages, &out.Packages
*out = new(PackagesConfig)
if err := Convert_kops_PackagesConfig_To_v1alpha3_PackagesConfig(*in, *out, s); err != nil {
return err
}
} else {
out.Packages = nil
}
return nil
}
// Convert_kops_Runc_To_v1alpha3_Runc is an autogenerated conversion function.
func Convert_kops_Runc_To_v1alpha3_Runc(in *kops.Runc, out *Runc, s conversion.Scope) error {
return autoConvert_kops_Runc_To_v1alpha3_Runc(in, out, s)
}
func autoConvert_v1alpha3_SSHCredential_To_kops_SSHCredential(in *SSHCredential, out *kops.SSHCredential, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
if err := Convert_v1alpha3_SSHCredentialSpec_To_kops_SSHCredentialSpec(&in.Spec, &out.Spec, s); err != nil {

View File

@ -1375,6 +1375,11 @@ func (in *ContainerdConfig) DeepCopyInto(out *ContainerdConfig) {
*out = new(NvidiaGPUConfig)
(*in).DeepCopyInto(*out)
}
if in.Runc != nil {
in, out := &in.Runc, &out.Runc
*out = new(Runc)
(*in).DeepCopyInto(*out)
}
return
}
@ -4902,6 +4907,32 @@ func (in *RouteSpec) DeepCopy() *RouteSpec {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Runc) DeepCopyInto(out *Runc) {
*out = *in
if in.Version != nil {
in, out := &in.Version, &out.Version
*out = new(string)
**out = **in
}
if in.Packages != nil {
in, out := &in.Packages, &out.Packages
*out = new(PackagesConfig)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Runc.
func (in *Runc) DeepCopy() *Runc {
if in == nil {
return nil
}
out := new(Runc)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SSHCredential) DeepCopyInto(out *SSHCredential) {
*out = *in

View File

@ -1495,6 +1495,11 @@ func (in *ContainerdConfig) DeepCopyInto(out *ContainerdConfig) {
*out = new(NvidiaGPUConfig)
(*in).DeepCopyInto(*out)
}
if in.Runc != nil {
in, out := &in.Runc, &out.Runc
*out = new(Runc)
(*in).DeepCopyInto(*out)
}
return
}
@ -5209,6 +5214,32 @@ func (in *RouteSpec) DeepCopy() *RouteSpec {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Runc) DeepCopyInto(out *Runc) {
*out = *in
if in.Version != nil {
in, out := &in.Version, &out.Version
*out = new(string)
**out = **in
}
if in.Packages != nil {
in, out := &in.Packages, &out.Packages
*out = new(PackagesConfig)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Runc.
func (in *Runc) DeepCopy() *Runc {
if in == nil {
return nil
}
out := new(Runc)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SSHCredential) DeepCopyInto(out *SSHCredential) {
*out = *in

View File

@ -48,6 +48,9 @@ func (b *ContainerdOptionsBuilder) BuildOptions(o interface{}) error {
if fi.StringValue(containerd.Version) == "" {
if b.IsKubernetesGTE("1.23") {
containerd.Version = fi.String("1.6.6")
containerd.Runc = &kops.Runc{
Version: fi.String("1.1.3"),
}
} else {
containerd.Version = fi.String("1.4.13")
}

View File

@ -30,27 +30,48 @@ import (
)
const (
runcVersion = "1.1.3"
runcVersionUrlAmd64 = "https://github.com/opencontainers/runc/releases/download/v%s/runc.amd64"
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) {
if c.Spec.Containerd == nil || c.Spec.Containerd.Version == nil {
return nil, nil, fmt.Errorf("unable to find containerd version, used to determine runc version")
if c.Spec.Containerd == nil {
return nil, nil, fmt.Errorf("unable to find containerd config")
}
containerd := c.Spec.Containerd
containerdVersion, err := semver.ParseTolerant(fi.StringValue(c.Spec.Containerd.Version))
containerdVersion, err := semver.ParseTolerant(fi.StringValue(containerd.Version))
if err != nil {
return nil, nil, fmt.Errorf("unable to parse version string: %q", fi.StringValue(c.Spec.Containerd.Version))
return nil, nil, fmt.Errorf("unable to parse version string: %q", fi.StringValue(containerd.Version))
}
// The a compatible runc binary is bundled with containerd builds < v1.6.0
// 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
}
version := runcVersion
if containerd.Runc == nil {
return nil, nil, fmt.Errorf("unable to find runc config")
}
runc := containerd.Runc
if runc.Packages != nil {
if arch == architectures.ArchitectureAmd64 && runc.Packages.UrlAmd64 != nil && runc.Packages.HashAmd64 != nil {
assetUrl := fi.StringValue(runc.Packages.UrlAmd64)
assetHash := fi.StringValue(runc.Packages.HashAmd64)
return findAssetsUrlHash(assetBuilder, assetUrl, assetHash)
}
if arch == architectures.ArchitectureArm64 && runc.Packages.UrlArm64 != nil && runc.Packages.HashArm64 != nil {
assetUrl := fi.StringValue(runc.Packages.UrlArm64)
assetHash := fi.StringValue(runc.Packages.HashArm64)
return findAssetsUrlHash(assetBuilder, assetUrl, assetHash)
}
}
version := fi.StringValue(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

View File

@ -17,12 +17,224 @@ limitations under the License.
package cloudup
import (
"fmt"
"os"
"reflect"
"testing"
"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
arch architectures.Architecture
url string
err error
}{
{
arch: "",
version: "1.1.0",
url: "",
err: fmt.Errorf("unknown arch: \"\""),
},
{
arch: "arm",
version: "1.1.0",
url: "",
err: fmt.Errorf("unknown arch: \"arm\""),
},
{
arch: architectures.ArchitectureAmd64,
version: "",
url: "",
err: fmt.Errorf("unable to parse version string: \"\""),
},
{
arch: architectures.ArchitectureArm64,
version: "",
url: "",
err: fmt.Errorf("unable to parse version string: \"\""),
},
{
arch: architectures.ArchitectureAmd64,
version: "1.0.0",
url: "",
err: fmt.Errorf("unsupported runc version: \"1.0.0\""),
},
{
arch: architectures.ArchitectureArm64,
version: "1.0.0",
url: "",
err: fmt.Errorf("unsupported runc version: \"1.0.0\""),
},
{
arch: architectures.ArchitectureAmd64,
version: "1.1.0",
url: "https://github.com/opencontainers/runc/releases/download/v1.1.0/runc.amd64",
err: nil,
},
{
arch: architectures.ArchitectureArm64,
version: "1.1.0",
url: "https://github.com/opencontainers/runc/releases/download/v1.1.0/runc.arm64",
err: nil,
},
}
for _, test := range tests {
t.Run(fmt.Sprintf("%s-%s", test.version, test.arch), func(t *testing.T) {
url, err := findRuncVersionUrl(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
}
})
}
}
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")