Skip to content

Commit

Permalink
Merge pull request #4117 from twz123/containerd-config-detection
Browse files Browse the repository at this point in the history
Improve k0s-managed containerd config detection
  • Loading branch information
twz123 authored Apr 22, 2024
2 parents ae27910 + 0780516 commit 4c0b3bd
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 13 deletions.
26 changes: 14 additions & 12 deletions pkg/component/worker/containerd/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"context"
"crypto/md5"
"encoding/hex"
"errors"
"fmt"
"io"
"os"
Expand All @@ -47,10 +48,7 @@ import (
"github.com/k0sproject/k0s/pkg/supervisor"
)

const magicMarker = "# k0s_managed=true"

const confTmpl = `
# k0s_managed=true
const confTmpl = `# k0s_managed=true
# This is a placeholder configuration for k0s managed containerd.
# If you wish to override the config, remove the first line and replace this file with your custom configuration.
# For reference see https://github.com/containerd/containerd/blob/main/docs/man/containerd-config.toml.5.md
Expand Down Expand Up @@ -322,11 +320,12 @@ func (c *Component) Stop() error {
// This is the md5sum of the default k0s containerd config file before 1.27
const pre1_27ConfigSum = "59039b43303742a5496b13fd57f9beec"

// isK0sManagedConfig checks if the config file is k0s managed
// - If the config file does not exist, it's k0s managed
// - If the config file md5sum matches the pre 1.27 config, it's k0s managed
// - If the config file has the magic marker, it's k0s managed
func isK0sManagedConfig(path string) (bool, error) {
// isK0sManagedConfig checks if the config file is k0s managed:
// - If the config file doesn't exist, it's k0s managed.
// - If the config file's md5sum matches the pre 1.27 config, it's k0s managed.
// - If the config file starts with the magic marker line "# k0s_managed=true",
// it's k0s managed.
func isK0sManagedConfig(path string) (_ bool, err error) {
// If the file does not exist, it's k0s managed (new install)
if !file.Exists(path) {
return true, nil
Expand All @@ -343,14 +342,17 @@ func isK0sManagedConfig(path string) (bool, error) {
if err != nil {
return false, err
}
defer f.Close()
defer func() { err = errors.Join(err, f.Close()) }()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
if strings.Contains(scanner.Text(), magicMarker) {
switch scanner.Text() {
case "": // K0s versions before 1.30 had a leading empty line.
continue
case "# k0s_managed=true":
return true, nil
}
}
return false, nil
return false, scanner.Err()
}

func isPre1_27ManagedConfig(path string) (bool, error) {
Expand Down
56 changes: 55 additions & 1 deletion pkg/component/worker/containerd/component_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,67 @@ import (
"path/filepath"
"testing"

"github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1"
workerconfig "github.com/k0sproject/k0s/pkg/component/worker/config"
"github.com/k0sproject/k0s/pkg/config"

"github.com/stretchr/testify/require"
)

func Test_isK0sManagedConfig(t *testing.T) {

t.Run("should return true if file does not exist", func(t *testing.T) {
isManaged, err := isK0sManagedConfig("non-existent.toml")
isManaged, err := isK0sManagedConfig(filepath.Join(t.TempDir(), "non-existent.toml"))
require.NoError(t, err)
require.True(t, isManaged)
})

t.Run("should return true for generated default config", func(t *testing.T) {
defaultConfigPath := filepath.Join(t.TempDir(), "default.toml")

underTest := Component{
K0sVars: &config.CfgVars{
RunDir: /* The merged config file will be written here: */ t.TempDir(),
},
confPath:/* The main config file will be written here: */ defaultConfigPath,
importsPath:/* some empty dir: */ t.TempDir(),
Profile:/* Some non-nil pause image: */ &workerconfig.Profile{PauseImage: &v1beta1.ImageSpec{}},
}
err := underTest.setupConfig()

require.NoError(t, err)
require.FileExists(t, defaultConfigPath, "The generated config file is missing.")

isManaged, err := isK0sManagedConfig(defaultConfigPath)
require.NoError(t, err)
require.True(t, isManaged, "The generated config file should qualify as k0s-managed, but doesn't.")
})

t.Run("should return false if file has no marker", func(t *testing.T) {
unmanagedPath := filepath.Join(t.TempDir(), "unmanaged.toml")
require.NoError(t, os.WriteFile(unmanagedPath, []byte(" # k0s_managed=true"), 0644))

isManaged, err := isK0sManagedConfig(unmanagedPath)
require.NoError(t, err)
require.False(t, isManaged)
})

t.Run("should return true for pre-1.30 generated config", func(t *testing.T) {
tmpDir := t.TempDir()
configPath := filepath.Join(tmpDir, "containerd.toml")
cfg := `
# k0s_managed=true
# This is a placeholder configuration for k0s managed containerD.
# If you wish to override the config, remove the first line and replace this file with your custom configuration.
# For reference see https://github.com/containerd/containerd/blob/main/docs/man/containerd-config.toml.5.md
version = 2
imports = [
"/run/k0s/containerd-cri.toml",
]
`
err := os.WriteFile(configPath, []byte(cfg), 0644)
require.NoError(t, err)
isManaged, err := isK0sManagedConfig(configPath)
require.NoError(t, err)
require.True(t, isManaged)
})
Expand Down

0 comments on commit 4c0b3bd

Please sign in to comment.