Fix verification of Containerd configuration with suffixes

Signed-off-by: Philip Laine <philip.laine@gmail.com>
This commit is contained in:
Philip Laine 2025-03-26 09:23:56 +01:00
parent 3de348c349
commit 23c8b76cdd
No known key found for this signature in database
GPG Key ID: F6D0B743CA3EFF33
6 changed files with 61 additions and 10 deletions

View File

@ -66,6 +66,8 @@ linters:
alias: digest
- pkg: github.com/opencontainers/image-spec/specs-go/v1
alias: ocispec
- pkg: k8s.io/apimachinery/pkg/util/version
alias: utilversion
no-extra-aliases: true
nolintlint:
require-explanation: true

View File

@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#807](https://github.com/spegel-org/spegel/pull/807) Update golangci lint and fix new issues.
- [#810](https://github.com/spegel-org/spegel/pull/810) Increase timeout to avoid flakiness in conformance tests.
- [#806](https://github.com/spegel-org/spegel/pull/806) Fix verification of Containerd configuration with suffixes.
### Security

3
go.mod
View File

@ -5,7 +5,6 @@ go 1.23.6
toolchain go1.24.1
require (
github.com/Masterminds/semver/v3 v3.3.1
github.com/alexflint/go-arg v1.5.1
github.com/containerd/containerd/api v1.8.0
github.com/containerd/containerd/v2 v2.0.4
@ -29,6 +28,7 @@ require (
go.etcd.io/bbolt v1.4.0
golang.org/x/sync v0.12.0
google.golang.org/grpc v1.71.0
k8s.io/apimachinery v0.32.3
k8s.io/cri-api v0.32.3
k8s.io/klog/v2 v2.130.1
)
@ -37,6 +37,7 @@ require (
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 // indirect
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20231105174938-2b5cbb29f3e2 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.3.1 // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/Microsoft/hcsshim v0.12.9 // indirect

2
go.sum
View File

@ -793,6 +793,8 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
k8s.io/apimachinery v0.32.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U=
k8s.io/apimachinery v0.32.3/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/cri-api v0.32.3 h1:E8VXbXNn4yAgmuKTeNzg0C1MFSxzTdlHSwUvjuYlPTY=
k8s.io/cri-api v0.32.3/go.mod h1:DCzMuTh2padoinefWME0G678Mc3QFbLMF2vEweGzBAI=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=

View File

@ -15,7 +15,6 @@ import (
"strings"
"text/template"
"github.com/Masterminds/semver/v3"
eventtypes "github.com/containerd/containerd/api/events"
"github.com/containerd/containerd/v2/client"
"github.com/containerd/containerd/v2/core/content"
@ -28,6 +27,7 @@ import (
tomlu "github.com/pelletier/go-toml/v2/unstable"
"github.com/spf13/afero"
"google.golang.org/grpc"
utilversion "k8s.io/apimachinery/pkg/util/version"
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
)
@ -105,16 +105,12 @@ func (c *Containerd) Verify(ctx context.Context) error {
if err != nil {
return err
}
version, err := semver.NewVersion(versionResp.GetRuntimeVersion())
ok, err = canVerifyContainerdConfiguration(versionResp.RuntimeVersion)
if err != nil {
return err
return fmt.Errorf("could not check Containerd version %s: %w", versionResp.RuntimeVersion, err)
}
constraint, err := semver.NewConstraint(">1-0")
if err != nil {
return err
}
if constraint.Check(version) {
log.Info("unable to verify status response", "runtime_version", version.String())
if !ok {
log.Info("skipping verification of Containerd configuration", "version", versionResp.RuntimeVersion)
return nil
}
@ -129,6 +125,14 @@ func (c *Containerd) Verify(ctx context.Context) error {
return nil
}
func canVerifyContainerdConfiguration(version string) (bool, error) {
v, err := utilversion.Parse(version)
if err != nil {
return false, err
}
return v.LessThan(utilversion.MustParse("2.0")), nil
}
func verifyStatusResponse(resp *runtimeapi.StatusResponse, configPath string) error {
str, ok := resp.Info["config"]
if !ok {

View File

@ -31,6 +31,47 @@ func TestNewContainerd(t *testing.T) {
require.Equal(t, "local", c.contentPath)
}
func TestCanVerifyContainerdConfiguration(t *testing.T) {
t.Parallel()
tests := []struct {
version string
expected bool
}{
{
version: "v2.0.2",
expected: false,
},
{
version: "2.1.4",
expected: false,
},
{
version: "v1.7.27",
expected: true,
},
{
version: "1.6.0",
expected: true,
},
}
for _, tt := range tests {
// Testing with a suffix is important as some Linux distributions will modify the version
// with a non Semver compliant modification. Even if the version is supposed to comply with
// semver that may not always be the case.
for _, suffix := range []string{"", "~ds1"} {
version := tt.version + suffix
t.Run(version, func(t *testing.T) {
t.Parallel()
ok, err := canVerifyContainerdConfiguration(tt.version)
require.NoError(t, err)
require.Equal(t, tt.expected, ok)
})
}
}
}
func TestVerifyStatusResponse(t *testing.T) {
t.Parallel()