Skip to content

Commit 1f989df

Browse files
committed
fix: read multi-doc machine config with newer talosctl
This affects reading multi-doc machine config via `talosctl` from Talos machines v1.11 and below by `talosctl` of v1.12 and up. The problem is that before v1.12 Talos returned machine config as embedded document instead of the spec if the resource, which was not valid YAML. It worked via hacks we used in our fork of yaml library. Talos v1.12+ cleans that up by marshaling the config as a string, and drops the forked library. The problem is that we can't still pass multi-doc YAML via this path, so we have to resort to going into COSI internals to retrieve the actual value as written by Talos API. Note: there is no problem for Omni, as it goes via protobuf path which hasn't been affected. Fixes #12787 Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com> (cherry picked from commit f118ee4)
1 parent 40ba6e3 commit 1f989df

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

cmd/talosctl/cmd/talos/output/yaml.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/cosi-project/runtime/pkg/resource"
1313
"github.com/cosi-project/runtime/pkg/resource/meta"
14+
"github.com/cosi-project/runtime/pkg/resource/protobuf"
1415
"github.com/cosi-project/runtime/pkg/state"
1516
yaml "go.yaml.in/yaml/v4"
1617

@@ -80,6 +81,20 @@ func (m *mcYamlRepr) Spec() any { return &mcYamlSpec{res: m.Resource} }
8081
type mcYamlSpec struct{ res resource.Resource }
8182

8283
func (m *mcYamlSpec) MarshalYAML() (any, error) {
84+
// this is backwards compatibility for versions of Talos which marshaled the MachineConfig spec as a YAML document
85+
// instead of putting it as string
86+
//
87+
// if try to go via yaml.Marshal path, it will cut off all documents after the first one (as there is no way to return
88+
// multiple documents from MarshalYAML), so we need to extract the original body from the resource
89+
if pb, ok := m.res.(*protobuf.Resource); ok {
90+
p, err := pb.Marshal()
91+
if err != nil {
92+
return nil, fmt.Errorf("marshal protobuf resource: %w", err)
93+
}
94+
95+
return p.GetSpec().GetYamlSpec(), nil
96+
}
97+
8398
out, err := yaml.Marshal(m.res.Spec())
8499
if err != nil {
85100
return nil, err

cmd/talosctl/cmd/talos/patch.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"time"
1414

1515
"github.com/cosi-project/runtime/pkg/resource"
16+
"github.com/cosi-project/runtime/pkg/resource/protobuf"
1617
"github.com/spf13/cobra"
1718
"go.yaml.in/yaml/v4"
1819
"google.golang.org/protobuf/types/known/durationpb"
@@ -38,6 +39,20 @@ var patchCmdFlags struct {
3839

3940
func extractMachineConfigBody(mc resource.Resource) ([]byte, error) {
4041
if mc.Metadata().Annotations().Empty() {
42+
// this is backwards compatibility for versions of Talos which marshaled the MachineConfig spec as a YAML document
43+
// instead of putting it as string
44+
//
45+
// if try to go via yaml.Marshal path, it will cut off all documents after the first one (as there is no way to return
46+
// multiple documents from MarshalYAML), so we need to extract the original body from the resource
47+
if pb, ok := mc.(*protobuf.Resource); ok {
48+
p, err := pb.Marshal()
49+
if err != nil {
50+
return nil, fmt.Errorf("marshal protobuf resource: %w", err)
51+
}
52+
53+
return []byte(p.GetSpec().GetYamlSpec()), nil
54+
}
55+
4156
return yaml.Marshal(mc.Spec())
4257
}
4358

0 commit comments

Comments
 (0)