Skip to content

Commit b6b16b3

Browse files
committed
chore: pause sequencer when talos installed and iso booted
Pause sequencer till the boot timeout if talos is booted from ISO/PXE, but an existing talos is installed to disk and `talos.iso.boot.halt_if_installed` kernel argument is set. Fixes: #9232 Signed-off-by: Noel Georgi <git@frezbo.dev>
1 parent eade0a9 commit b6b16b3

File tree

7 files changed

+63
-0
lines changed

7 files changed

+63
-0
lines changed

hack/release.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,16 @@ Starting with Talos 1.8, `console=ttyS0` kernel argument is removed from the met
208208
This should fix slow boot or no console output issues on most bare metal hardware.
209209
"""
210210

211+
[notes.kernel-args]
212+
title = "`talos.halt_if_installed` kernel argument"
213+
description = """\
214+
Starting with Talos 1.8, ISO's generated from Boot Assets would have a new kernel argument `talos.halt_if_installed` which would pause the boot sequence until boot timeout if Talos is already installed on the disk.
215+
ISO generated for pre 1.8 versions would not have this kernel argument.
216+
217+
This can be also explicitly enabled by setting `talos.halt_if_installed=1` in kernel argument.
218+
"""
219+
220+
211221
[make_deps]
212222

213223
[make_deps.tools]

internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,15 @@ func (*Sequencer) Initialize(r runtime.Runtime) []runtime.Phase {
131131
},
132132
"wipeDisks",
133133
ResetSystemDiskPartitions,
134+
).AppendWithDeferredCheck(
135+
func() bool {
136+
haltIfInstalledStr := procfs.ProcCmdline().Get(constants.KernelParamHaltIfInstalled).First()
137+
haltIfInstalled, _ := strconv.ParseBool(pointer.SafeDeref(haltIfInstalledStr)) //nolint:errcheck
138+
139+
return r.State().Machine().Installed() && haltIfInstalled
140+
},
141+
"haltIfInstalled",
142+
haltIfInstalled,
134143
).AppendWithDeferredCheck(
135144
func() bool {
136145
return r.State().Machine().Installed()

internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer_tasks.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1924,6 +1924,25 @@ func UnmountEFIPartition(runtime.Sequence, any) (runtime.TaskExecutionFunc, stri
19241924
}, "unmountEFIPartition"
19251925
}
19261926

1927+
// haltIfInstalled halts the boot process if Talos is installed to disk but booted from ISO.
1928+
func haltIfInstalled(seq runtime.Sequence, _ any) (runtime.TaskExecutionFunc, string) {
1929+
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) error {
1930+
ctx, cancel := context.WithTimeout(ctx, constants.BootTimeout)
1931+
defer cancel()
1932+
1933+
timer := time.NewTicker(30 * time.Second)
1934+
defer timer.Stop()
1935+
1936+
select {
1937+
case <-timer.C:
1938+
logger.Printf("Talos is already installed to disk but booted from another media and %s kernel parameter is set. Please reboot from the disk.", constants.KernelParamHaltIfInstalled)
1939+
case <-ctx.Done():
1940+
}
1941+
1942+
return nil
1943+
}, "haltIfInstalled"
1944+
}
1945+
19271946
// MountStatePartition mounts the system partition.
19281947
func MountStatePartition(seq runtime.Sequence, _ any) (runtime.TaskExecutionFunc, string) {
19291948
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) (err error) {

pkg/imager/imager.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,10 @@ func (i *Imager) buildCmdline() error {
336336
// platform kernel args
337337
cmdline.Append(constants.KernelParamPlatform, p.Name())
338338

339+
if quirks.New(i.prof.Version).SupportsHaltIfInstalled() && i.prof.Output.Kind == profile.OutKindISO {
340+
cmdline.Append(constants.KernelParamHaltIfInstalled, "1")
341+
}
342+
339343
if quirks.New(i.prof.Version).SupportsMetalPlatformConsoleTTYS0() && i.prof.Platform == constants.PlatformMetal {
340344
cmdline.Append("console", "ttyS0")
341345
}

pkg/machinery/constants/constants.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ const (
8484
// KernelParamNetIfnames is the kernel parameter name to control predictable network interface names.
8585
KernelParamNetIfnames = "net.ifnames"
8686

87+
// KernelParamHaltIfInstalled is the kernel parameter name to control if Talos should pause if booting from boot media while Talos is already installed.
88+
KernelParamHaltIfInstalled = "talos.halt_if_installed"
89+
8790
// BoardNone indicates that the install is not for a specific board.
8891
BoardNone = "none"
8992

pkg/machinery/imager/quirks/quirks.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,16 @@ func (q Quirks) SupportsMetalPlatformConsoleTTYS0() bool {
111111

112112
return q.v.LT(maxVersionMetalPlatformConsoleTTYS0Dropped)
113113
}
114+
115+
// minVersionSupportsHalfIfInstalled is the version that supports half if installed.
116+
var minVersionSupportsHalfIfInstalled = semver.MustParse("1.8.0")
117+
118+
// SupportsHaltIfInstalled returns true if the Talos version supports half if installed.
119+
func (q Quirks) SupportsHaltIfInstalled() bool {
120+
// if the version doesn't parse, we assume it's latest Talos
121+
if q.v == nil {
122+
return true
123+
}
124+
125+
return q.v.GTE(minVersionSupportsHalfIfInstalled)
126+
}

website/content/v1.8/reference/kernel.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,3 +259,8 @@ Example:
259259
```text
260260
talos.device.settle_time=3m
261261
```
262+
263+
#### `talos.halt_if_installed`
264+
265+
If set to `1`, Talos will pause the boot sequence and keeps printing a message until the boot timeout is reached if it detects that it is already installed.
266+
This is useful if booting from ISO/PXE and you want to prevent the machine accidentally booting from the ISO/PXE after installation to the disk.

0 commit comments

Comments
 (0)