diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/boot_label.go b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/boot_label.go index 9c5b5b67e..69eb51b18 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/boot_label.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/boot_label.go @@ -19,6 +19,8 @@ func FlipBootLabel(e BootLabel) (BootLabel, error) { return BootB, nil case BootB: return BootA, nil + case BootReset: + fallthrough default: return "", fmt.Errorf("invalid entry: %s", e) } @@ -26,13 +28,14 @@ func FlipBootLabel(e BootLabel) (BootLabel, error) { // ParseBootLabel parses the given human-readable boot label to a grub.BootLabel. func ParseBootLabel(name string) (BootLabel, error) { - if strings.HasPrefix(name, string(BootA)) { + switch { + case strings.HasPrefix(name, string(BootA)): return BootA, nil - } - - if strings.HasPrefix(name, string(BootB)) { + case strings.HasPrefix(name, string(BootB)): return BootB, nil + case strings.HasPrefix(name, "Reset"): + return BootReset, nil + default: + return "", fmt.Errorf("could not parse boot entry from name: %s", name) } - - return "", fmt.Errorf("could not parse boot entry from name: %s", name) } diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/constants.go b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/constants.go index 14925dbcf..4ff48e19b 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/constants.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/constants.go @@ -13,6 +13,9 @@ const ( // BootB is a bootloader label. BootB BootLabel = "B" + // BootReset is a bootloader label. + BootReset BootLabel = "Reset" + // ConfigPath is the path to the grub config. ConfigPath = constants.BootMountPoint + "/grub/grub.cfg" ) diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/decode.go b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/decode.go index bdc66804d..160352ec7 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/decode.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/decode.go @@ -106,6 +106,10 @@ func parseEntries(conf []byte) (map[BootLabel]MenuEntry, error) { return nil, err } + if bootEntry == BootReset { + continue + } + entries[bootEntry] = MenuEntry{ Name: name, Linux: linux, diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/grub_test.go b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/grub_test.go index 5733ad703..fbe7a6824 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/grub_test.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/grub_test.go @@ -77,6 +77,10 @@ func TestParseBootLabel(t *testing.T) { assert.NoError(t, err) assert.Equal(t, grub.BootB, label) + label, err = grub.ParseBootLabel("Reset Talos installation and return to maintenance mode\n") + assert.NoError(t, err) + assert.Equal(t, grub.BootReset, label) + _, err = grub.ParseBootLabel("C - v3") assert.Error(t, err) } @@ -94,7 +98,7 @@ func TestWrite(t *testing.T) { tempFile, _ := os.CreateTemp("", "talos-test-grub-*.cfg") - defer os.Remove(tempFile.Name()) + t.Cleanup(func() { require.NoError(t, os.Remove(tempFile.Name())) }) config := grub.NewConfig("cmdline A") diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/testdata/grub_parse_test.cfg b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/testdata/grub_parse_test.cfg index 8a40810a9..90b2a2576 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/testdata/grub_parse_test.cfg +++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/testdata/grub_parse_test.cfg @@ -20,3 +20,10 @@ menuentry "B - v2" { linux /B/vmlinuz cmdline B initrd /B/initramfs.xz } + +menuentry "Reset Talos installation and return to maintenance mode" { + set gfxmode=auto + set gfxpayload=text + linux /A/vmlinuz cmdline A talos.experimental.wipe=system:EPHEMERAL,STATE + initrd /A/initramfs.xz +}