Skip to content

Commit

Permalink
feat: move dashboard package & run it in tty2
Browse files Browse the repository at this point in the history
Move dashboard package into a common location where both Talos and talosctl can use it.

Add support for overriding stdin, stdout, stderr and ctt in process runner.

Create a dashboard service which runs the dashboard on /dev/tty2.

Redirect kernel messages to tty1 and switch to tty2 after starting the dashboard on it.

Related to #6841, #4791.

Signed-off-by: Utku Ozdemir <utku.ozdemir@siderolabs.com>
  • Loading branch information
utkuozdemir committed Feb 28, 2023
1 parent 36e077e commit f55f5df
Show file tree
Hide file tree
Showing 42 changed files with 510 additions and 54 deletions.
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,8 @@ RUN ln /rootfs/sbin/init /rootfs/sbin/poweroff
RUN chmod +x /rootfs/sbin/poweroff
RUN ln /rootfs/sbin/init /rootfs/sbin/wrapperd
RUN chmod +x /rootfs/sbin/wrapperd
RUN ln /rootfs/sbin/init /rootfs/sbin/dashboard
RUN chmod +x /rootfs/sbin/dashboard
# NB: We run the cleanup step before creating extra directories, files, and
# symlinks to avoid accidentally cleaning them up.
COPY ./hack/cleanup.sh /toolchain/bin/cleanup.sh
Expand Down Expand Up @@ -525,6 +527,8 @@ RUN ln /rootfs/sbin/init /rootfs/sbin/poweroff
RUN chmod +x /rootfs/sbin/poweroff
RUN ln /rootfs/sbin/init /rootfs/sbin/wrapperd
RUN chmod +x /rootfs/sbin/wrapperd
RUN ln /rootfs/sbin/init /rootfs/sbin/dashboard
RUN chmod +x /rootfs/sbin/dashboard
# NB: We run the cleanup step before creating extra directories, files, and
# symlinks to avoid accidentally cleaning them up.
COPY ./hack/cleanup.sh /toolchain/bin/cleanup.sh
Expand Down
4 changes: 2 additions & 2 deletions cmd/talosctl/cmd/talos/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

"github.com/spf13/cobra"

"github.com/siderolabs/talos/cmd/talosctl/cmd/talos/dashboard"
"github.com/siderolabs/talos/internal/pkg/dashboard"
"github.com/siderolabs/talos/pkg/machinery/client"
)

Expand Down Expand Up @@ -38,7 +38,7 @@ Keyboard shortcuts:
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return WithClient(func(ctx context.Context, c *client.Client) error {
return dashboard.Main(ctx, c, dashboardCmdFlags.interval)
return dashboard.Main(ctx, c, dashboardCmdFlags.interval, true)
})
},
}
Expand Down
13 changes: 13 additions & 0 deletions hack/release.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,19 @@ machine:
title = "Machine Configuration"
description="""\
Strategic merge config patches correctly support merging `.vlans` sections of the network interface.
"""

[notes.dashboard]
title = "Talos Dashboard on TTY2"
description="""\
Talos now starts a text-based UI dashboard on virtual console `/dev/tty2` and switches to it by default upon boot.
Kernel logs remain available on `/dev/tty1`.
To switch TTYs, use the `Alt+F1` through `Alt+F2` keys.
You can disable this behavior by setting the kernel parameter `talos.dashboard.disabled=1`.
This behavior is disabled by default on SBCs.
"""

[make_deps]
Expand Down
49 changes: 49 additions & 0 deletions internal/app/dashboard/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

// Package dashboard implements dashboard functionality.
package dashboard

import (
"context"
"fmt"
"log"
"time"

"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/metadata"

"github.com/siderolabs/talos/internal/pkg/dashboard"
"github.com/siderolabs/talos/pkg/grpc/middleware/authz"
"github.com/siderolabs/talos/pkg/machinery/client"
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/machinery/role"
"github.com/siderolabs/talos/pkg/startup"
)

// Main is the entrypoint into dashboard.
func Main() {
if err := dashboardMain(); err != nil {
log.Fatal(err)
}
}

func dashboardMain() error {
startup.LimitMaxProcs(constants.DashboardMaxProcs)

md := metadata.Pairs()
authz.SetMetadata(md, role.MakeSet(role.Admin))
adminCtx := metadata.NewOutgoingContext(context.Background(), md)

c, err := client.New(adminCtx,
client.WithUnixSocket(constants.MachineSocketPath),
client.WithGRPCDialOptions(grpc.WithTransportCredentials(insecure.NewCredentials())),
)
if err != nil {
return fmt.Errorf("error connecting to the machine service: %w", err)
}

return dashboard.Main(adminCtx, c, 5*time.Second, false)
}
5 changes: 5 additions & 0 deletions internal/app/machined/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"golang.org/x/sys/unix"

"github.com/siderolabs/talos/internal/app/apid"
"github.com/siderolabs/talos/internal/app/dashboard"
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
v1alpha1runtime "github.com/siderolabs/talos/internal/app/machined/pkg/runtime/v1alpha1"
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime/v1alpha1/bootloader"
Expand Down Expand Up @@ -316,6 +317,10 @@ func main() {
case "/sbin/wrapperd":
wrapperd.Main()

return
case "/sbin/dashboard":
dashboard.Main()

return
default:
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ func (b *BananaPiM64) Install(disk string) (err error) {
func (b *BananaPiM64) KernelArgs() procfs.Parameters {
return []*procfs.Parameter{
procfs.NewParameter("console").Append("tty0").Append("ttyS0,115200"),
procfs.NewParameter(constants.KernelParamDashboardDisabled).Append("1"),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func (b JetsonNano) KernelArgs() procfs.Parameters {
// trying to kexec. Seems the drivers state is not reset properly.
// disabling kexec until we have further knowledge on this
procfs.NewParameter("sysctl.kernel.kexec_load_disabled").Append("1"),
procfs.NewParameter(constants.KernelParamDashboardDisabled).Append("1"),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ func (l *LibretechAllH3CCH5) Install(disk string) (err error) {
func (l *LibretechAllH3CCH5) KernelArgs() procfs.Parameters {
return []*procfs.Parameter{
procfs.NewParameter("console").Append("tty0").Append("ttyS0,115200"),
procfs.NewParameter(constants.KernelParamDashboardDisabled).Append("1"),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func (n *NanoPiR4S) KernelArgs() procfs.Parameters {
return []*procfs.Parameter{
procfs.NewParameter("console").Append("tty0").Append("ttyS2,1500000n8"),
procfs.NewParameter("sysctl.kernel.kexec_load_disabled").Append("1"),
procfs.NewParameter(constants.KernelParamDashboardDisabled).Append("1"),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ func (b Pine64) Install(disk string) (err error) {
func (b Pine64) KernelArgs() procfs.Parameters {
return []*procfs.Parameter{
procfs.NewParameter("console").Append("tty0").Append("ttyS0,115200"),
procfs.NewParameter(constants.KernelParamDashboardDisabled).Append("1"),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ func (r *Rock64) Install(disk string) (err error) {
func (r *Rock64) KernelArgs() procfs.Parameters {
return []*procfs.Parameter{
procfs.NewParameter("console").Append("tty0").Append("ttyS2,115200n8"),
procfs.NewParameter(constants.KernelParamDashboardDisabled).Append("1"),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ func (r *Rockpi4) KernelArgs() procfs.Parameters {
return []*procfs.Parameter{
procfs.NewParameter("console").Append("tty0").Append("ttyS2,1500000n8"),
procfs.NewParameter("sysctl.kernel.kexec_load_disabled").Append("1"),
procfs.NewParameter(constants.KernelParamDashboardDisabled).Append("1"),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ func (r *Rockpi4c) KernelArgs() procfs.Parameters {
return []*procfs.Parameter{
procfs.NewParameter("console").Append("tty0").Append("ttyS2,1500000n8"),
procfs.NewParameter("sysctl.kernel.kexec_load_disabled").Append("1"),
procfs.NewParameter(constants.KernelParamDashboardDisabled).Append("1"),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func (r *RPi4) KernelArgs() procfs.Parameters {
return []*procfs.Parameter{
procfs.NewParameter("console").Append("tty0").Append("ttyAMA0,115200"),
procfs.NewParameter("sysctl.kernel.kexec_load_disabled").Append("1"),
procfs.NewParameter(constants.KernelParamDashboardDisabled).Append("1"),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func (r *RPiGeneric) KernelArgs() procfs.Parameters {
return []*procfs.Parameter{
procfs.NewParameter("console").Append("tty0").Append("ttyAMA0,115200"),
procfs.NewParameter("sysctl.kernel.kexec_load_disabled").Append("1"),
procfs.NewParameter(constants.KernelParamDashboardDisabled).Append("1"),
}
}

Expand Down
12 changes: 12 additions & 0 deletions internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
package v1alpha1

import (
"strconv"

"github.com/siderolabs/go-pointer"
"github.com/siderolabs/go-procfs/procfs"

"github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
Expand Down Expand Up @@ -106,6 +109,15 @@ func (*Sequencer) Initialize(r runtime.Runtime) []runtime.Phase {
"earlyServices",
StartUdevd,
StartMachined,
).AppendWithDeferredCheck(
func() bool {
disabledStr := procfs.ProcCmdline().Get(constants.KernelParamDashboardDisabled).First()
disabled, _ := strconv.ParseBool(pointer.SafeDeref(disabledStr)) //nolint:errcheck

return !disabled
},
"dashboard",
StartDashboard,
).AppendWithDeferredCheck(
func() bool {
return r.State().Machine().Installed()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import (
"github.com/siderolabs/talos/internal/app/machined/pkg/system/events"
"github.com/siderolabs/talos/internal/app/machined/pkg/system/services"
"github.com/siderolabs/talos/internal/app/maintenance"
"github.com/siderolabs/talos/internal/pkg/console"
"github.com/siderolabs/talos/internal/pkg/cri"
"github.com/siderolabs/talos/internal/pkg/etcd"
"github.com/siderolabs/talos/internal/pkg/install"
Expand Down Expand Up @@ -203,6 +204,15 @@ func CreateSystemCgroups(seq runtime.Sequence, data interface{}) (runtime.TaskEx
},
},
},
{
name: constants.CgroupDashboard,
resources: &cgroupsv2.Resources{
Memory: &cgroupsv2.Memory{
Min: pointer.To[int64](constants.CgroupDashboardReservedMemory),
Low: pointer.To[int64](constants.CgroupDashboardLowMemory),
},
},
},
}

for _, c := range groups {
Expand Down Expand Up @@ -792,6 +802,19 @@ func StartMachined(_ runtime.Sequence, _ interface{}) (runtime.TaskExecutionFunc
}, "startMachined"
}

// StartDashboard represents the task to start dashboard.
func StartDashboard(_ runtime.Sequence, _ interface{}) (runtime.TaskExecutionFunc, string) {
return func(_ context.Context, _ *log.Logger, r runtime.Runtime) error {
ttyNumber := constants.DashboardTTY

system.Services(r).LoadAndStart(&services.Dashboard{
TTYNumber: ttyNumber,
})

return console.Switch(ttyNumber)
}, "startDashboard"
}

// StartUdevd represents the task to start udevd.
func StartUdevd(seq runtime.Sequence, data interface{}) (runtime.TaskExecutionFunc, string) {
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) (err error) {
Expand Down
Loading

0 comments on commit f55f5df

Please sign in to comment.