Skip to content

Commit 9d13c99

Browse files
committed
fix: allow crictl config to create a missing explicit file
1 parent c4657a3 commit 9d13c99

5 files changed

Lines changed: 193 additions & 6 deletions

File tree

.github/workflows/crio.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ jobs:
141141
142142
set +o errexit
143143
sudo -E PATH=$PATH make test-e2e \
144+
GINKGO_FLAGS="--flake-attempts=3" \
144145
TESTFLAGS="-crictl-runtime-endpoint=unix://var/run/crio/crio.sock"
145146
TEST_RC=$?
146147
set -o errexit

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ PRETTIER_VERSION = 3.8.3
6060
ZIZMOR_VERSION := v1.25.2
6161

6262
GINKGO := $(BUILD_BIN_PATH)/ginkgo
63+
GINKGO_FLAGS ?=
6364
GOLANGCI_LINT_DIR := $(BUILD_BIN_PATH)/golangci-lint-$(GOLANGCI_LINT_VERSION)
6465
GOLANGCI_LINT := $(GOLANGCI_LINT_DIR)/golangci-lint
6566
ZEITGEIST := $(BUILD_BIN_PATH)/zeitgeist
@@ -267,7 +268,7 @@ PARALLEL ?= 8
267268

268269
.PHONY: test-e2e
269270
test-e2e: $(GINKGO) ## Run the e2e test suite.
270-
$(GINKGO) \
271+
$(GINKGO) $(GINKGO_FLAGS) \
271272
-r \
272273
--randomize-all \
273274
--randomize-suites \

cmd/crictl/config.go

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package main
1818

1919
import (
20+
"errors"
2021
"fmt"
2122
"os"
2223
"strconv"
@@ -72,14 +73,26 @@ CRICTL OPTIONS:
7273
Action: func(c *cli.Context) error {
7374
configFile := c.String("config")
7475
if _, err := os.Stat(configFile); err != nil {
75-
if err := common.WriteConfig(nil, configFile); err != nil {
76+
if !errors.Is(err, os.ErrNotExist) {
7677
return err
7778
}
79+
80+
if shouldCreateConfigFile(c) {
81+
if err := common.WriteConfig(nil, configFile); err != nil {
82+
return err
83+
}
84+
}
7885
}
79-
// Get config from file.
80-
config, err := common.ReadConfig(configFile)
81-
if err != nil {
82-
return fmt.Errorf("load config file: %w", err)
86+
87+
config := &common.Config{}
88+
if _, err := os.Stat(configFile); err == nil {
89+
// Get config from file.
90+
config, err = common.ReadConfig(configFile)
91+
if err != nil {
92+
return fmt.Errorf("load config file: %w", err)
93+
}
94+
} else if !errors.Is(err, os.ErrNotExist) {
95+
return err
8396
}
8497

8598
if c.IsSet("get") {
@@ -157,6 +170,18 @@ CRICTL OPTIONS:
157170
},
158171
}
159172

173+
func shouldCreateConfigFile(c *cli.Context) bool {
174+
if c.IsSet("set") {
175+
return true
176+
}
177+
178+
if c.IsSet("get") || c.Bool("list") {
179+
return false
180+
}
181+
182+
return c.Args().First() != ""
183+
}
184+
160185
func setValue(key, value string, config *common.Config) error {
161186
switch key {
162187
case common.RuntimeEndpoint:

cmd/crictl/config_command_test.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
Copyright The Kubernetes 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+
"os"
22+
"path/filepath"
23+
"strings"
24+
"sync"
25+
"testing"
26+
)
27+
28+
var runWithArgsForTestMu sync.Mutex
29+
30+
func TestConfigCommandCreatesMissingExplicitConfigOnSet(t *testing.T) {
31+
t.Parallel()
32+
33+
configPath := filepath.Join(t.TempDir(), "nested", "crictl.yaml")
34+
35+
err := runWithArgsForTest(
36+
t,
37+
"crictl",
38+
"--config",
39+
configPath,
40+
"config",
41+
"--set",
42+
"debug=true",
43+
)
44+
if err != nil {
45+
t.Fatalf("run config --set: %v", err)
46+
}
47+
48+
content, err := os.ReadFile(configPath)
49+
if err != nil {
50+
t.Fatalf("read config file: %v", err)
51+
}
52+
53+
if !strings.Contains(string(content), "debug: true") {
54+
t.Fatalf("expected config file to contain debug=true, got:\n%s", string(content))
55+
}
56+
}
57+
58+
func TestConfigCommandCreatesMissingExplicitConfigOnPositionalSet(t *testing.T) {
59+
t.Parallel()
60+
61+
configPath := filepath.Join(t.TempDir(), "nested", "crictl.yaml")
62+
63+
err := runWithArgsForTest(
64+
t,
65+
"crictl",
66+
"--config",
67+
configPath,
68+
"config",
69+
"debug",
70+
"true",
71+
)
72+
if err != nil {
73+
t.Fatalf("run config positional set: %v", err)
74+
}
75+
76+
content, err := os.ReadFile(configPath)
77+
if err != nil {
78+
t.Fatalf("read config file: %v", err)
79+
}
80+
81+
if !strings.Contains(string(content), "debug: true") {
82+
t.Fatalf("expected config file to contain debug=true, got:\n%s", string(content))
83+
}
84+
}
85+
86+
func TestConfigCommandListDoesNotCreateMissingExplicitConfig(t *testing.T) {
87+
t.Parallel()
88+
89+
configPath := filepath.Join(t.TempDir(), "nested", "crictl.yaml")
90+
91+
err := runWithArgsForTest(
92+
t,
93+
"crictl",
94+
"--config",
95+
configPath,
96+
"config",
97+
"--list",
98+
)
99+
if err == nil {
100+
t.Fatal("expected config --list to fail for a missing explicit config file")
101+
}
102+
103+
_, err = os.Stat(configPath)
104+
if !errors.Is(err, os.ErrNotExist) {
105+
t.Fatalf("expected config file to remain absent, got err=%v", err)
106+
}
107+
}
108+
109+
func runWithArgsForTest(t *testing.T, args ...string) error {
110+
t.Helper()
111+
112+
runWithArgsForTestMu.Lock()
113+
t.Cleanup(func() {
114+
runWithArgsForTestMu.Unlock()
115+
})
116+
117+
oldArgs := os.Args
118+
os.Args = args
119+
120+
t.Cleanup(func() {
121+
os.Args = oldArgs
122+
})
123+
124+
return run()
125+
}

cmd/crictl/main.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package main
1818

1919
import (
2020
"context"
21+
"errors"
2122
"fmt"
2223
"os"
2324
"path/filepath"
@@ -213,6 +214,12 @@ func run() error {
213214
return fmt.Errorf("get executable path: %w", err)
214215
}
215216

217+
if shouldCreateMissingExplicitConfigFile(context) {
218+
if err := common.WriteConfig(nil, context.String("config")); err != nil {
219+
return fmt.Errorf("create config file: %w", err)
220+
}
221+
}
222+
216223
if config, err = common.GetServerConfigFromFile(context.String("config"), exePath); err != nil {
217224
if context.IsSet("config") {
218225
return fmt.Errorf("get server config: %w", err)
@@ -316,3 +323,31 @@ func run() error {
316323

317324
return err
318325
}
326+
327+
func shouldCreateMissingExplicitConfigFile(ctx *cli.Context) bool {
328+
args := ctx.Args().Slice()
329+
if !ctx.IsSet("config") || len(args) == 0 || args[0] != configCommand.Name {
330+
return false
331+
}
332+
333+
for _, arg := range args[1:] {
334+
switch {
335+
case arg == "--get" || strings.HasPrefix(arg, "--get="):
336+
return false
337+
case arg == "--list" || strings.HasPrefix(arg, "--list="):
338+
return false
339+
case arg == "--set" || strings.HasPrefix(arg, "--set="):
340+
return missingConfigFile(ctx.String("config"))
341+
case !strings.HasPrefix(arg, "-"):
342+
return missingConfigFile(ctx.String("config"))
343+
}
344+
}
345+
346+
return false
347+
}
348+
349+
func missingConfigFile(path string) bool {
350+
_, err := os.Stat(path)
351+
352+
return errors.Is(err, os.ErrNotExist)
353+
}

0 commit comments

Comments
 (0)