Skip to content

Commit 9a2f6d9

Browse files
smirashanduur
authored andcommitted
fix: support specifying patch file without '@' symbol
Try to be more smart while parsing `--config-patch` (and similar) flags: * we still support inline patches * if the flag value doesn't look like a patch, try to use it as a filename directly This avoids common confusion with `--config-patch=patch.yaml` returning an error "expected a mapping node". Also clarify/updated documentation for `talosctl edit` and `talosctl patch`, as they only work for the machineconfig, there is no other usecase now. Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com> (cherry picked from commit e2ee39b)
1 parent 582b0fe commit 9a2f6d9

File tree

6 files changed

+48
-18
lines changed

6 files changed

+48
-18
lines changed

cmd/talosctl/cmd/talos/edit.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,11 @@ func addEditingComment(in string) string {
178178

179179
// editCmd represents the edit command.
180180
var editCmd = &cobra.Command{
181-
Use: "edit <type> [<id>]",
182-
Short: "Edit a resource from the default editor.",
181+
Use: "edit machineconfig",
182+
Short: "Edit Talos node machine configuration with the default editor.",
183183
Args: cobra.RangeArgs(1, 2),
184-
Long: `The edit command allows you to directly edit any API resource
185-
you can retrieve via the command line tools.
184+
Long: `The edit command allows you to directly edit the machine configuration
185+
of a Talos node using your preferred text editor.
186186
187187
It will open the editor defined by your TALOS_EDITOR,
188188
or EDITOR environment variables, or fall back to 'vi' for Linux

cmd/talosctl/cmd/talos/patch.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ func patchFn(c *client.Client, patches []configpatcher.Patch) func(context.Conte
114114

115115
// patchCmd represents the edit command.
116116
var patchCmd = &cobra.Command{
117-
Use: "patch <type> [<id>]",
118-
Short: "Update field(s) of a resource using a JSON patch.",
117+
Use: "patch machineconfig",
118+
Short: "Patch machine configuration of a Talos node with a local patch.",
119119
Args: cobra.RangeArgs(1, 2),
120120
RunE: func(cmd *cobra.Command, args []string) error {
121121
return WithClient(func(ctx context.Context, c *client.Client) error {

internal/integration/cli/apply-config.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func (suite *ApplyConfigSuite) TestApplyWithPatch() {
5252
patchPath := filepath.Join(tmpDir, "patch.yaml")
5353
suite.Require().NoError(os.WriteFile(patchPath, dummyAPPatch, 0o777))
5454

55-
suite.RunCLI([]string{"apply-config", "--nodes", node, "--config-patch", "@" + patchPath, "-f", configPath},
55+
suite.RunCLI([]string{"apply-config", "--nodes", node, "--config-patch", patchPath, "-f", configPath},
5656
base.StdoutEmpty(),
5757
base.StderrNotEmpty(),
5858
base.StderrShouldMatch(regexp.MustCompile("Applied configuration without a reboot")),
@@ -71,12 +71,15 @@ func (suite *ApplyConfigSuite) TestApplyWithPatch() {
7171

7272
suite.Require().NoError(os.WriteFile(patchPath, deleteDummyAPPatch, 0o777))
7373

74-
suite.RunCLI([]string{"apply-config", "--nodes", node, "--config-patch", "@" + patchPath, "-f", configPath},
74+
suite.RunCLI([]string{"apply-config", "--nodes", node, "--config-patch", patchPath, "-f", configPath},
7575
base.StdoutEmpty(),
7676
base.StderrNotEmpty(),
7777
base.StderrShouldMatch(regexp.MustCompile("Applied configuration without a reboot")),
7878
)
7979

80+
// sleep a bit to let the config propagate
81+
time.Sleep(1 * time.Second)
82+
8083
suite.RunCLI([]string{"get", "--nodes", node, "links"},
8184
base.StdoutShouldNotMatch(regexp.MustCompile("dummy-ap-patch")),
8285
base.WithRetry(retry.Constant(15*time.Second, retry.WithUnits(time.Second))),

pkg/machinery/config/configpatcher/load.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ func LoadPatch(in []byte) (Patch, error) {
7171
}
7272

7373
// LoadPatches loads the JSON patch either from value literal or from a file if the patch starts with '@'.
74+
//
75+
// It also tries to guess if the filename was given without '@' prefix.
76+
//
77+
//nolint:gocyclo
7478
func LoadPatches(in []string) ([]Patch, error) {
7579
var result []Patch
7680

@@ -81,14 +85,24 @@ func LoadPatches(in []string) ([]Patch, error) {
8185
err error
8286
)
8387

84-
if strings.HasPrefix(patchString, "@") {
88+
switch {
89+
case strings.HasPrefix(patchString, "@"):
8590
filename := patchString[1:]
8691

8792
contents, err = os.ReadFile(filename)
8893
if err != nil {
8994
return result, err
9095
}
91-
} else {
96+
case !strings.ContainsAny(patchString, "\n ") &&
97+
!strings.HasPrefix(patchString, "[") &&
98+
!strings.HasPrefix(patchString, "{"):
99+
// any valid patch supplied inline should contain either '\n' or space, or start with '[' or '{'
100+
// so if none of this is true, assume it's a filename, but without '@' prefix
101+
contents, err = os.ReadFile(patchString)
102+
if err != nil {
103+
return result, err
104+
}
105+
default:
92106
contents = []byte(patchString)
93107
}
94108

pkg/machinery/config/configpatcher/load_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,16 @@ func TestLoadMixedPatches(t *testing.T) {
112112
assert.Implements(t, (*configpatcher.StrategicMergePatch)(nil), patchList[1])
113113
assert.IsType(t, jsonpatch.Patch{}, patchList[2])
114114
}
115+
116+
func TestLoadStraightFilename(t *testing.T) {
117+
patchList, err := configpatcher.LoadPatches([]string{
118+
"testdata/strategic.yaml",
119+
`[{"op":"replace","path":"/some","value": []}]`,
120+
})
121+
require.NoError(t, err)
122+
123+
require.Len(t, patchList, 2)
124+
125+
assert.Implements(t, (*configpatcher.StrategicMergePatch)(nil), patchList[0])
126+
assert.IsType(t, jsonpatch.Patch{}, patchList[1])
127+
}

website/content/v1.12/reference/cli.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -940,19 +940,19 @@ talosctl dmesg [flags]
940940

941941
## talosctl edit
942942

943-
Edit a resource from the default editor.
943+
Edit Talos node machine configuration with the default editor.
944944

945945
### Synopsis
946946

947-
The edit command allows you to directly edit any API resource
948-
you can retrieve via the command line tools.
947+
The edit command allows you to directly edit the machine configuration
948+
of a Talos node using your preferred text editor.
949949

950950
It will open the editor defined by your TALOS_EDITOR,
951951
or EDITOR environment variables, or fall back to 'vi' for Linux
952952
or 'notepad' for Windows.
953953

954954
```
955-
talosctl edit <type> [<id>] [flags]
955+
talosctl edit machineconfig [flags]
956956
```
957957

958958
### Options
@@ -2572,10 +2572,10 @@ talosctl netstat [flags]
25722572

25732573
## talosctl patch
25742574

2575-
Update field(s) of a resource using a JSON patch.
2575+
Patch machine configuration of a Talos node with a local patch.
25762576

25772577
```
2578-
talosctl patch <type> [<id>] [flags]
2578+
talosctl patch machineconfig [flags]
25792579
```
25802580

25812581
### Options
@@ -3248,7 +3248,7 @@ A CLI for out-of-band management of Kubernetes nodes created by Talos
32483248
* [talosctl copy](#talosctl-copy) - Copy data out from the node
32493249
* [talosctl dashboard](#talosctl-dashboard) - Cluster dashboard with node overview, logs and real-time metrics
32503250
* [talosctl dmesg](#talosctl-dmesg) - Retrieve kernel logs
3251-
* [talosctl edit](#talosctl-edit) - Edit a resource from the default editor.
3251+
* [talosctl edit](#talosctl-edit) - Edit Talos node machine configuration with the default editor.
32523252
* [talosctl etcd](#talosctl-etcd) - Manage etcd
32533253
* [talosctl events](#talosctl-events) - Stream runtime events
32543254
* [talosctl gen](#talosctl-gen) - Generate CAs, certificates, and private keys
@@ -3265,7 +3265,7 @@ A CLI for out-of-band management of Kubernetes nodes created by Talos
32653265
* [talosctl meta](#talosctl-meta) - Write and delete keys in the META partition
32663266
* [talosctl mounts](#talosctl-mounts) - List mounts
32673267
* [talosctl netstat](#talosctl-netstat) - Show network connections and sockets
3268-
* [talosctl patch](#talosctl-patch) - Update field(s) of a resource using a JSON patch.
3268+
* [talosctl patch](#talosctl-patch) - Patch machine configuration of a Talos node with a local patch.
32693269
* [talosctl pcap](#talosctl-pcap) - Capture the network packets from the node.
32703270
* [talosctl processes](#talosctl-processes) - List running processes
32713271
* [talosctl read](#talosctl-read) - Read a file on the machine

0 commit comments

Comments
 (0)