Skip to content

Commit 8ee9bab

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

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,35 @@ 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
2833
}
2934

3035
func (c tomlCliSource) Load() (*Tree, error) {
36+
var errs error
37+
for _, clicmd := range c.cliCommands {
38+
out, err := executeCommand(clicmd.cmd, clicmd.args)
39+
if err == nil {
40+
return LoadBytes(out)
41+
}
42+
errs = errors.Join(err)
43+
}
44+
return nil, errs
45+
}
46+
47+
func executeCommand(command string, args []string) ([]byte, error) {
3148
//nolint:gosec // Subprocess launched with a potential tainted input or cmd arguments
32-
cmd := exec.Command(c.command, c.args...)
49+
cmd := exec.Command(command, args...)
3350

3451
var outb bytes.Buffer
3552
var errb bytes.Buffer
@@ -38,8 +55,15 @@ func (c tomlCliSource) Load() (*Tree, error) {
3855
cmd.Stderr = &errb
3956
if err := cmd.Run(); err != nil {
4057
// 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)
58+
return nil, fmt.Errorf("failed to run command %v %v: %w", command, args, err)
4259
}
4360

44-
return LoadBytes(outb.Bytes())
61+
return outb.Bytes(), nil
62+
}
63+
64+
func NewCLICommand(command string, args []string) CLICommand {
65+
return CLICommand{
66+
cmd: command,
67+
args: args,
68+
}
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)