Skip to content

Commit 0327e77

Browse files
Pranavsmira
authored andcommitted
feat: add support for dashboard custom console parameter
Fixes #12070 Signed-off-by: Pranav <pranavppatil767@gmail.com> Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
1 parent fed948b commit 0327e77

File tree

3 files changed

+72
-1
lines changed

3 files changed

+72
-1
lines changed

internal/app/machined/pkg/system/services/dashboard.go

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import (
99
"context"
1010
"fmt"
1111
"strconv"
12+
"strings"
13+
14+
"github.com/siderolabs/go-pointer"
15+
"github.com/siderolabs/go-procfs/procfs"
1216

1317
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
1418
"github.com/siderolabs/talos/internal/app/machined/pkg/system/events"
@@ -25,18 +29,57 @@ import (
2529
// the required methods.
2630
type Dashboard struct{}
2731

32+
// getCustomConsole returns the custom console parameter value if specified, empty string otherwise.
33+
func (d *Dashboard) getCustomConsole() string {
34+
consoleParam := procfs.ProcCmdline().Get(constants.KernelParamDashboardConsole).First()
35+
36+
return pointer.SafeDeref(consoleParam)
37+
}
38+
39+
// hasCustomConsole checks if a custom console is specified via kernel parameter.
40+
func (d *Dashboard) hasCustomConsole() bool {
41+
return d.getCustomConsole() != ""
42+
}
43+
44+
// getConsoleDevice returns the console device path to use for the dashboard.
45+
func (d *Dashboard) getConsoleDevice() (string, error) {
46+
consoleName := d.getCustomConsole()
47+
48+
if consoleName != "" {
49+
// Validate that the console name starts with "tty"
50+
if !strings.HasPrefix(consoleName, "tty") || strings.Contains(consoleName, "/") {
51+
return "", fmt.Errorf("invalid console name %q: must start with 'tty'", consoleName)
52+
}
53+
54+
return fmt.Sprintf("/dev/%s", consoleName), nil
55+
}
56+
57+
// Default to the standard dashboard TTY
58+
return fmt.Sprintf("/dev/tty%d", constants.DashboardTTY), nil
59+
}
60+
2861
// ID implements the Service interface.
2962
func (d *Dashboard) ID(_ runtime.Runtime) string {
3063
return "dashboard"
3164
}
3265

3366
// PreFunc implements the Service interface.
3467
func (d *Dashboard) PreFunc(_ context.Context, _ runtime.Runtime) error {
68+
// Skip TTY switching if a custom console is specified
69+
if d.hasCustomConsole() {
70+
return nil
71+
}
72+
3573
return console.Switch(constants.DashboardTTY)
3674
}
3775

3876
// PostFunc implements the Service interface.
3977
func (d *Dashboard) PostFunc(_ runtime.Runtime, _ events.ServiceState) error {
78+
// Skip TTY switching if a custom console is specified
79+
if d.hasCustomConsole() {
80+
return nil
81+
}
82+
4083
return console.Switch(constants.KernelLogsTTY)
4184
}
4285

@@ -57,7 +100,10 @@ func (d *Dashboard) Volumes(runtime.Runtime) []string {
57100

58101
// Runner implements the Service interface.
59102
func (d *Dashboard) Runner(r runtime.Runtime) (runner.Runner, error) {
60-
tty := fmt.Sprintf("/dev/tty%d", constants.DashboardTTY)
103+
tty, err := d.getConsoleDevice()
104+
if err != nil {
105+
return nil, fmt.Errorf("failed to determine console device: %w", err)
106+
}
61107

62108
return restart.New(process.NewRunner(false, &runner.Args{
63109
ID: d.ID(r),

pkg/machinery/constants/constants.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ const (
8787
// KernelParamDashboardDisabled is the kernel parameter name for disabling the dashboard.
8888
KernelParamDashboardDisabled = "talos.dashboard.disabled"
8989

90+
// KernelParamDashboardConsole is the kernel parameter name for specifying the dashboard console.
91+
KernelParamDashboardConsole = "talos.dashboard.console"
92+
9093
// KernelParamEnvironment is the kernel parameter name for passing process environment.
9194
KernelParamEnvironment = "talos.environment"
9295

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,28 @@ Kernel logs will be sent to the currently active console and the dashboard will
257257

258258
It is set to be `1` by default on SBCs.
259259

260+
#### `talos.dashboard.console`
261+
262+
By default, the Talos dashboard runs on `/dev/tty2` with automatic TTY switching.
263+
You can specify a custom console device for the dashboard using this parameter.
264+
265+
For example, to run the dashboard on a serial console:
266+
267+
```text
268+
talos.dashboard.console=ttyS0
269+
```
270+
271+
When this parameter is specified:
272+
273+
* The dashboard will run on `/dev/ttyS0`
274+
* TTY switching will be disabled (no automatic switching between tty1 and tty2)
275+
* The console name must start with "tty"
276+
277+
This is useful for headless servers or systems where you want the dashboard accessible through a serial console connection.
278+
279+
> Note: If Talos dashboard is set to use ttyS0, make sure that Linux kernel command line doesn't include
280+
> `console=ttyS0` or similar, as it will conflict with the dashboard output.
281+
260282
#### `talos.environment`
261283

262284
Each value of the argument sets a default environment variable.

0 commit comments

Comments
 (0)