Skip to content

Commit 1c9ccb7

Browse files
committed
[TOML ConfigSource] add support for executing fallback CLI commands
Signed-off-by: Tariq Ibrahim <[email protected]>
1 parent 3c07ea0 commit 1c9ccb7

File tree

4 files changed

+48
-13
lines changed

4 files changed

+48
-13
lines changed

pkg/config/engine/containerd/containerd.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,11 @@ func (c *Config) GetRuntimeConfig(name string) (engine.RuntimeConfig, error) {
129129
// CommandLineSource returns the CLI-based containerd config loader
130130
func CommandLineSource(hostRoot string) toml.Loader {
131131
commandLine := chrootIfRequired(hostRoot, "containerd", "config", "dump")
132-
return toml.FromCommandLine(commandLine[0], commandLine[1:]...)
132+
133+
var cliCommands []toml.CLICommand
134+
cliCommands = append(cliCommands, toml.NewCLICommand(commandLine[0], commandLine[1:]))
135+
136+
return toml.FromCommandLine(cliCommands)
133137
}
134138

135139
func chrootIfRequired(hostRoot string, commandLine ...string) []string {

pkg/config/engine/crio/crio.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,14 @@ func (c *Config) GetRuntimeConfig(name string) (engine.RuntimeConfig, error) {
155155

156156
// CommandLineSource returns the CLI-based crio config loader
157157
func CommandLineSource(hostRoot string) toml.Loader {
158-
commandLine := chrootIfRequired(hostRoot, "crio", "status", "config")
159-
return toml.FromCommandLine(commandLine[0], commandLine[1:]...)
158+
crioCommandLine := chrootIfRequired(hostRoot, "crio", "status", "config")
159+
crioCommandLineFallback := chrootIfRequired(hostRoot, "crio-status", "config")
160+
161+
var cliCommands []toml.CLICommand
162+
cliCommands = append(cliCommands, toml.NewCLICommand(crioCommandLine[0], crioCommandLine[1:]))
163+
cliCommands = append(cliCommands, toml.NewCLICommand(crioCommandLineFallback[0], crioCommandLineFallback[1:]))
164+
165+
return toml.FromCommandLine(cliCommands)
160166
}
161167

162168
func chrootIfRequired(hostRoot string, commandLine ...string) []string {

pkg/config/toml/source-cli.go

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,42 @@ package toml
1818

1919
import (
2020
"bytes"
21+
"errors"
2122
"fmt"
2223
"os/exec"
2324
)
2425

26+
type CLICommand struct {
27+
cmd string
28+
args []string
29+
}
30+
2531
type tomlCliSource struct {
26-
command string
27-
args []string
32+
cliCommands []CLICommand
33+
}
34+
35+
func NewCLICommand(command string, args []string) CLICommand {
36+
return CLICommand{
37+
cmd: command,
38+
args: args,
39+
}
2840
}
2941

3042
func (c tomlCliSource) Load() (*Tree, error) {
43+
var errs error
44+
for _, clicmd := range c.cliCommands {
45+
out, err := executeCommand(clicmd.cmd, clicmd.args)
46+
if err == nil {
47+
return LoadBytes(out)
48+
}
49+
errs = errors.Join(err)
50+
}
51+
return nil, errs
52+
}
53+
54+
func executeCommand(command string, args []string) ([]byte, error) {
3155
//nolint:gosec // Subprocess launched with a potential tainted input or cmd arguments
32-
cmd := exec.Command(c.command, c.args...)
56+
cmd := exec.Command(command, args...)
3357

3458
var outb bytes.Buffer
3559
var errb bytes.Buffer
@@ -38,8 +62,8 @@ func (c tomlCliSource) Load() (*Tree, error) {
3862
cmd.Stderr = &errb
3963
if err := cmd.Run(); err != nil {
4064
// TODO: Log to stderr in case of failure
41-
return nil, fmt.Errorf("failed to run command %v %v: %w", c.command, c.args, err)
65+
return nil, fmt.Errorf("failed to run command %v %v: %w", command, args, err)
4266
}
4367

44-
return LoadBytes(outb.Bytes())
68+
return outb.Bytes(), nil
4569
}

pkg/config/toml/source.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,14 @@ func FromFile(path string) Loader {
3535
}
3636

3737
// FromCommandLine creates a TOML source from the output of a shell command and its corresponding args.
38-
// If the command is empty, an empty config is returned.
39-
func FromCommandLine(cmd string, args ...string) Loader {
40-
if len(cmd) == 0 {
38+
// It accepts multiple commands as input, executing commands and returning on the first sccessful output
39+
// or falling back to the next command in the input slice. If the command slice is empty,
40+
// an empty config is returned.
41+
func FromCommandLine(cliCmds []CLICommand) Loader {
42+
if len(cliCmds) == 0 {
4143
return Empty
4244
}
4345
return &tomlCliSource{
44-
command: cmd,
45-
args: args,
46+
cliCommands: cliCmds,
4647
}
4748
}

0 commit comments

Comments
 (0)