Skip to content

Commit 9e6b013

Browse files
phyrogvdice
authored andcommitted
implement some basic k8s distro detection
1 parent 3c90630 commit 9e6b013

File tree

5 files changed

+138
-8
lines changed

5 files changed

+138
-8
lines changed

cmd/node-installer/detect.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
Copyright The SpinKube Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package main
18+
19+
import (
20+
"errors"
21+
"fmt"
22+
"log/slog"
23+
24+
"github.com/spf13/afero"
25+
"github.com/spinkube/runtime-class-manager/internal/preset"
26+
)
27+
28+
var containerdConfigLocations = map[string]preset.Settings{
29+
// Microk8s
30+
"/var/snap/microk8s/current/args/containerd-template.toml": preset.MicroK8s,
31+
// RKE2
32+
"/var/lib/rancher/rke2/agent/etc/containerd/config.toml": preset.RKE2,
33+
// K3s
34+
"/var/lib/rancher/k3s/agent/etc/containerd/config.toml": preset.K3s,
35+
// default
36+
"/etc/containerd/config.toml": preset.Default,
37+
}
38+
39+
func DetectDistro(config Config, hostFs afero.Fs) (preset.Settings, error) {
40+
if config.Runtime.ConfigPath != "" {
41+
// containerd config path has been set explicitly
42+
if distro, ok := containerdConfigLocations[config.Runtime.ConfigPath]; ok {
43+
return distro, nil
44+
}
45+
slog.Warn("could not determine distro from containerd config, falling back to defaults", "config", config.Runtime.ConfigPath)
46+
return preset.Default.WithConfigPath(config.Runtime.ConfigPath), nil
47+
}
48+
49+
var errs []error
50+
51+
for loc, distro := range containerdConfigLocations {
52+
_, err := hostFs.Stat(loc)
53+
if err == nil {
54+
// config file found, return corresponding distro settings
55+
return distro, nil
56+
}
57+
errs = append(errs, err)
58+
}
59+
60+
return preset.Settings{}, fmt.Errorf("failed to detect containerd config path: %w", errors.Join(errs...))
61+
}

cmd/node-installer/install.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/spf13/afero"
2727
"github.com/spf13/cobra"
2828
"github.com/spinkube/runtime-class-manager/internal/containerd"
29+
"github.com/spinkube/runtime-class-manager/internal/preset"
2930
"github.com/spinkube/runtime-class-manager/internal/shim"
3031
)
3132

@@ -36,9 +37,16 @@ var installCmd = &cobra.Command{
3637
Run: func(_ *cobra.Command, _ []string) {
3738
rootFs := afero.NewOsFs()
3839
hostFs := afero.NewBasePathFs(rootFs, config.Host.RootPath)
39-
restarter := containerd.NewRestarter()
4040

41-
if err := RunInstall(config, rootFs, hostFs, restarter); err != nil {
41+
distro, err := DetectDistro(config, hostFs)
42+
if err != nil {
43+
slog.Error("failed to detect containerd config", "error", err)
44+
os.Exit(1)
45+
}
46+
47+
config.Runtime.ConfigPath = distro.ConfigPath
48+
49+
if err := RunInstall(config, rootFs, hostFs, distro.Restarter(preset.Env{ConfigPath: distro.ConfigPath, HostFs: hostFs})); err != nil {
4250
slog.Error("failed to install", "error", err)
4351
os.Exit(1)
4452
}

cmd/node-installer/root.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func Execute() {
5151

5252
func init() {
5353
rootCmd.PersistentFlags().StringVarP(&config.Runtime.Name, "runtime", "r", "containerd", "Set the container runtime to configure (containerd, cri-o)")
54-
rootCmd.PersistentFlags().StringVarP(&config.Runtime.ConfigPath, "runtime-config", "c", "/etc/containerd/config.toml", "Path to the runtime config file")
54+
rootCmd.PersistentFlags().StringVarP(&config.Runtime.ConfigPath, "runtime-config", "c", "", "Path to the runtime config file. Will try to autodetect if left empty")
5555
rootCmd.PersistentFlags().StringVarP(&config.Kwasm.Path, "kwasm-path", "k", "/opt/kwasm", "Working directory for kwasm on the host")
5656
rootCmd.PersistentFlags().StringVarP(&config.Host.RootPath, "host-root", "H", "/", "Path to the host root path")
5757
}

cmd/node-installer/uninstall.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/spf13/cobra"
2727

2828
"github.com/spinkube/runtime-class-manager/internal/containerd"
29+
"github.com/spinkube/runtime-class-manager/internal/preset"
2930
"github.com/spinkube/runtime-class-manager/internal/shim"
3031
)
3132

@@ -36,13 +37,18 @@ var uninstallCmd = &cobra.Command{
3637
Run: func(_ *cobra.Command, _ []string) {
3738
rootFs := afero.NewOsFs()
3839
hostFs := afero.NewBasePathFs(rootFs, config.Host.RootPath)
39-
restarter := containerd.NewRestarter()
4040

41-
if err := RunUninstall(config, rootFs, hostFs, restarter); err != nil {
42-
slog.Error("failed to uninstall shim", "error", err)
41+
distro, err := DetectDistro(config, hostFs)
42+
if err != nil {
43+
slog.Error("failed to detect containerd config", "error", err)
44+
os.Exit(1)
45+
}
46+
47+
config.Runtime.ConfigPath = distro.ConfigPath
4348

44-
// Exiting with 0 to prevent Kubernetes Jobs from running repetitively
45-
os.Exit(0)
49+
if err := RunUninstall(config, rootFs, hostFs, distro.Restarter(preset.Env{ConfigPath: distro.ConfigPath, HostFs: hostFs})); err != nil {
50+
slog.Error("failed to uninstall", "error", err)
51+
os.Exit(1)
4652
}
4753
},
4854
}

internal/preset/preset.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package preset
2+
3+
import (
4+
"errors"
5+
"os"
6+
7+
"github.com/spf13/afero"
8+
"github.com/spinkube/runtime-class-manager/internal/containerd"
9+
)
10+
11+
type Settings struct {
12+
ConfigPath string
13+
Setup func(Env) error
14+
Restarter func(Env) containerd.Restarter
15+
}
16+
17+
type Env struct {
18+
HostFs afero.Fs
19+
ConfigPath string
20+
}
21+
22+
var Default = Settings{
23+
ConfigPath: "/etc/containerd/config.toml",
24+
Setup: func(_ Env) error { return nil },
25+
Restarter: func(_ Env) containerd.Restarter { return containerd.NewRestarter() },
26+
}
27+
28+
func (s Settings) WithConfigPath(path string) Settings {
29+
s.ConfigPath = path
30+
return s
31+
}
32+
33+
func (s Settings) WithSetup(setup func(env Env) error) Settings {
34+
s.Setup = setup
35+
return s
36+
}
37+
38+
var MicroK8s = Default.WithConfigPath("/var/snap/microk8s/current/args/containerd-template.toml")
39+
40+
var RKE2 = Default.WithConfigPath("/var/lib/rancher/rke2/agent/etc/containerd/config.toml.tmpl").
41+
WithSetup(func(env Env) error {
42+
_, err := env.HostFs.Stat(env.ConfigPath)
43+
if err == nil {
44+
return nil
45+
}
46+
47+
if errors.Is(err, os.ErrNotExist) {
48+
// TODO: Copy file from original file to new config file
49+
return nil
50+
}
51+
52+
return err
53+
})
54+
55+
var K3s = RKE2.WithConfigPath("/var/lib/rancher/k3s/agent/etc/containerd/config.toml.tmpl")

0 commit comments

Comments
 (0)