Skip to content

Commit 272c73d

Browse files
Install and start D-Bus after configuring runtime options
Signed-off-by: Kate Goldenring <[email protected]>
1 parent 63890e0 commit 272c73d

File tree

9 files changed

+118
-48
lines changed

9 files changed

+118
-48
lines changed

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 1 addition & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/node-installer/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ type Config struct {
2323
// Options is a map of containerd runtime options for the shim plugin.
2424
// See an example of the cgroup drive option here:
2525
// https://github.com/containerd/containerd/blob/main/docs/cri/config.md#cgroup-driver
26-
Options map[string]string
26+
Options map[string]string
2727
}
2828
RCM struct {
2929
Path string

cmd/node-installer/install.go

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,10 @@ var installCmd = &cobra.Command{
5151
os.Exit(1)
5252
}
5353

54-
optionsJson := os.Getenv("RUNTIME_OPTIONS")
55-
config.Runtime.Options = make(map[string]string)
56-
if optionsJson != "" {
57-
err := json.Unmarshal([]byte(optionsJson), &config.Runtime.Options)
58-
if err != nil {
59-
slog.Error("Error unmarshaling runtime options JSON", "error", err)
60-
return
61-
}
54+
config.Runtime.Options, err = RuntimeOptions()
55+
if err != nil {
56+
slog.Error("failed to get runtime options", "error", err)
57+
os.Exit(1)
6258
}
6359

6460
if err := RunInstall(config, rootFs, hostFs, distro.Restarter); err != nil {
@@ -120,6 +116,14 @@ func RunInstall(config Config, rootFs, hostFs afero.Fs, restarter containerd.Res
120116
return nil
121117
}
122118

119+
// Ensure D-Bus is installed and running if using systemd
120+
if containerd.UsesSystemd() {
121+
err = containerd.InstallDbus()
122+
if err != nil {
123+
return fmt.Errorf("failed to install D-Bus: %w", err)
124+
}
125+
}
126+
123127
slog.Info("restarting containerd")
124128
err = containerdConfig.RestartRuntime()
125129
if err != nil {
@@ -128,3 +132,16 @@ func RunInstall(config Config, rootFs, hostFs afero.Fs, restarter containerd.Res
128132

129133
return nil
130134
}
135+
136+
func RuntimeOptions() (map[string]string, error) {
137+
runtimeOptions := make(map[string]string)
138+
optionsJSON := os.Getenv("RUNTIME_OPTIONS")
139+
config.Runtime.Options = make(map[string]string)
140+
if optionsJSON != "" {
141+
err := json.Unmarshal([]byte(optionsJSON), &runtimeOptions)
142+
if err != nil {
143+
return nil, fmt.Errorf("failed to unmarshal runtime options JSON %s: %w", optionsJSON, err)
144+
}
145+
}
146+
return runtimeOptions, nil
147+
}

cmd/node-installer/uninstall.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package main
1818

1919
import (
20-
"encoding/json"
2120
"fmt"
2221
"log/slog"
2322
"os"
@@ -46,14 +45,10 @@ var uninstallCmd = &cobra.Command{
4645

4746
config.Runtime.ConfigPath = distro.ConfigPath
4847

49-
optionsJson := os.Getenv("RUNTIME_OPTIONS")
50-
config.Runtime.Options = make(map[string]string)
51-
if optionsJson != "" {
52-
err := json.Unmarshal([]byte(optionsJson), &config.Runtime.Options)
53-
if err != nil {
54-
slog.Error("Error unmarshaling runtime options JSON", "error", err)
55-
return
56-
}
48+
config.Runtime.Options, err = RuntimeOptions()
49+
if err != nil {
50+
slog.Error("failed to get runtime options", "error", err)
51+
os.Exit(1)
5752
}
5853

5954
if err := RunUninstall(config, rootFs, hostFs, distro.Restarter); err != nil {

config/crd/bases/runtime.spinkube.dev_shims.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ spec:
100100
type: string
101101
description: |-
102102
RuntimeOptions is a map of containerd runtime options for the shim plugin.
103-
Read more here: https://github.com/containerd/containerd/blob/main/docs/cri/config.md#cgroup-driver
103+
See an example of configuring cgroup driver via runtime options: https://github.com/containerd/containerd/blob/main/docs/cri/config.md#cgroup-driver
104104
type: object
105105
required:
106106
- fetchStrategy

images/installer/Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ COPY . .
1010
RUN CGO_ENABLED=0 go build -o rcm-node-installer ./cmd/node-installer
1111
RUN /app/rcm-node-installer -h
1212

13-
FROM scratch
13+
# Using busybox instead of scratch so that the nsenter utility is present, as used in restarter logic
14+
FROM busybox
1415
COPY --from=builder /app/rcm-node-installer /rcm-node-installer
1516

1617
ENTRYPOINT ["/rcm-node-installer"]

internal/containerd/configure.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,12 @@ runtime_type = "%s"
130130
`, runtimeName, domain, runtimeName, shimPath)
131131
// Add runtime options if any are provided
132132
if len(runtimeOptions) > 0 {
133-
options := fmt.Sprintf(`[plugins."%s".containerd.runtimes."%s".options]`, domain, runtimeName)
133+
options := fmt.Sprintf(`[plugins."%s".containerd.runtimes.%s.options]`, domain, runtimeName)
134134
for k, v := range runtimeOptions {
135135
options += fmt.Sprintf(`
136-
%s = "%s"\n`, k, v)
136+
%s = %s`, k, v)
137137
}
138-
runtimeConfiguration += "\n" + options
138+
runtimeConfiguration += options
139139
}
140140
return runtimeConfiguration
141141
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package containerd
2+
3+
import (
4+
"fmt"
5+
"log/slog"
6+
"os"
7+
"os/exec"
8+
)
9+
10+
// UsesSystemd checks if the system is using systemd
11+
// by running the "systemctl is-system-running" command.
12+
// NOTE: this limits support to systems using systemctl to manage systemd
13+
func UsesSystemd() bool {
14+
// Check if is a systemd system
15+
cmd := nsenterCmd("systemctl", "is-system-running", "--quiet")
16+
if err := cmd.Run(); err != nil {
17+
slog.Info("Error with systemctl: %w\n", "error", err)
18+
return false
19+
}
20+
return true
21+
}
22+
23+
// InstallDbus checks if D-Bus service is installed and active. If not, installs D-Bus
24+
// and starts the service.
25+
// NOTE: this limits support to systems using systemctl to manage systemd.
26+
func InstallDbus() error {
27+
cmd := nsenterCmd("systemctl", "is-active", "dbus", "--quiet")
28+
if err := cmd.Run(); err == nil {
29+
slog.Info("D-Bus is already installed and running")
30+
return nil
31+
}
32+
slog.Info("Installing D-Bus")
33+
whichApt := nsenterCmd("which", "apt-get")
34+
whichYum := nsenterCmd("which", "yum")
35+
whichDnf := nsenterCmd("which", "dnf")
36+
whichApk := nsenterCmd("which", "apk")
37+
if err := whichApt.Run(); err == nil {
38+
cmd = nsenterCmd("apt-get", "update", "--yes")
39+
if err := cmd.Run(); err != nil {
40+
return fmt.Errorf("failed to update apt: %w", err)
41+
}
42+
cmd = nsenterCmd("apt-get", "install", "--yes", "dbus")
43+
if err := cmd.Run(); err != nil {
44+
return fmt.Errorf("failed to install D-Bus with apt: %w", err)
45+
}
46+
} else if err = whichDnf.Run(); err == nil {
47+
cmd = nsenterCmd("dnf", "install", "--yes", "dbus")
48+
if err := cmd.Run(); err != nil {
49+
return fmt.Errorf("failed to install D-Bus with dnf: %w", err)
50+
}
51+
} else if err = whichApk.Run(); err == nil {
52+
cmd = nsenterCmd("apk", "add", "dbus")
53+
if err := cmd.Run(); err != nil {
54+
return fmt.Errorf("failed to install D-Bus with apk: %w", err)
55+
}
56+
} else if err = whichYum.Run(); err == nil {
57+
cmd = nsenterCmd("yum", "install", "--yes", "dbus")
58+
if err := cmd.Run(); err != nil {
59+
return fmt.Errorf("failed to install D-Bus with yum: %w", err)
60+
}
61+
} else {
62+
slog.Info("WARNING: Could not install D-Bus. No supported package manager found.")
63+
return nil
64+
}
65+
66+
slog.Info("Restarting D-Bus")
67+
cmd = nsenterCmd("systemctl", "restart", "dbus")
68+
if err := cmd.Run(); err != nil {
69+
return fmt.Errorf("failed to restart D-Bus: %w", err)
70+
}
71+
72+
return nil
73+
}
74+
75+
func nsenterCmd(cmd ...string) *exec.Cmd {
76+
return exec.Command("nsenter",
77+
append([]string{fmt.Sprintf("-m/%s/proc/1/ns/mnt", os.Getenv("HOST_ROOT")), "--"}, cmd...)...) // #nosec G204
78+
}

internal/controller/shim_controller.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -464,17 +464,17 @@ func (sr *ShimReconciler) createJobManifest(shim *rcmv1.Shim, node *corev1.Node,
464464
}
465465

466466
if shim.Spec.RuntimeOptions != nil {
467-
optionsJson, err := json.Marshal(shim.Spec.RuntimeOptions)
467+
optionsJSON, err := json.Marshal(shim.Spec.RuntimeOptions)
468468
if err != nil {
469469
log.Error().Msgf("Unable to marshal runtime options: %s", err)
470470
} else {
471471
job.Spec.Template.Spec.Containers[0].Env = append(job.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{
472472
Name: "RUNTIME_OPTIONS",
473-
Value: string(optionsJson),
473+
Value: string(optionsJSON),
474474
})
475475
}
476476
}
477-
477+
478478
// set ttl for the installer job only if specified by the user
479479
if ttlStr := os.Getenv("SHIM_NODE_INSTALLER_JOB_TTL"); ttlStr != "" {
480480
if ttl, err := strconv.ParseInt(ttlStr, 10, 32); err == nil && ttl > 0 {

0 commit comments

Comments
 (0)