Make unattended reset work (#110)

Our current example for cloud images on the docs on how to use the reset
with a cloud-config and a stage does not actually work as the tty
adquisition and such seems to be failing due tto not being properly run
in a tty.

This pathc introduces 2 new flags to the reset command.

reboot: Enable reboot after reset, overriding any config in the system.
This is only a enable switch, so if the flag is disabled but the config
says reset it will NOT override it.

unattended: Disables printing stuff into the screen, locking the
terminal and falling back to a new tty on run. Also enables fast mode
automatically.

Signed-off-by: Itxaka <itxaka@kairos.io>
This commit is contained in:
Itxaka 2023-08-04 20:39:22 +02:00 committed by GitHub
parent d98a0047d9
commit f5c01f73a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 26 deletions

View File

@ -3,10 +3,6 @@ package agent
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"os"
"sync"
"time"
hook "github.com/kairos-io/kairos-agent/v2/internal/agent/hooks" hook "github.com/kairos-io/kairos-agent/v2/internal/agent/hooks"
"github.com/kairos-io/kairos-agent/v2/internal/bus" "github.com/kairos-io/kairos-agent/v2/internal/bus"
"github.com/kairos-io/kairos-agent/v2/internal/cmd" "github.com/kairos-io/kairos-agent/v2/internal/cmd"
@ -16,43 +12,48 @@ import (
"github.com/kairos-io/kairos-sdk/collector" "github.com/kairos-io/kairos-sdk/collector"
"github.com/kairos-io/kairos-sdk/machine" "github.com/kairos-io/kairos-sdk/machine"
"github.com/kairos-io/kairos-sdk/utils" "github.com/kairos-io/kairos-sdk/utils"
"os"
"sync"
"time"
"github.com/mudler/go-pluggable" "github.com/mudler/go-pluggable"
) )
func Reset(dir ...string) error { func Reset(reboot, unattended bool, dir ...string) error {
bus.Manager.Initialize() bus.Manager.Initialize()
cmd.PrintBranding(DefaultBanner)
// This config is only for reset branding. // This config is only for reset branding.
agentConfig, err := LoadConfig() agentConfig, err := LoadConfig()
if err != nil { if err != nil {
return err return err
} }
cmd.PrintText(agentConfig.Branding.Reset, "Reset") if !unattended {
cmd.PrintBranding(DefaultBanner)
cmd.PrintText(agentConfig.Branding.Reset, "Reset")
// We don't close the lock, as none of the following actions are expected to return // We don't close the lock, as none of the following actions are expected to return
lock := sync.Mutex{} lock := sync.Mutex{}
go func() { go func() {
// Wait for user input and go back to shell // Wait for user input and go back to shell
utils.Prompt("") //nolint:errcheck utils.Prompt("") //nolint:errcheck
// give tty1 back // give tty1 back
svc, err := machine.Getty(1) svc, err := machine.Getty(1)
if err == nil { if err == nil {
svc.Start() //nolint:errcheck svc.Start() //nolint:errcheck
}
lock.Lock()
fmt.Println("Reset aborted")
panic(utils.Shell().Run())
}()
if !agentConfig.Fast {
time.Sleep(60 * time.Second)
} }
lock.Lock() lock.Lock()
fmt.Println("Reset aborted")
panic(utils.Shell().Run())
}()
if !agentConfig.Fast {
time.Sleep(60 * time.Second)
} }
lock.Lock()
ensureDataSourceReady() ensureDataSourceReady()
@ -95,6 +96,11 @@ func Reset(dir ...string) error {
} }
} }
// Override with flags
if reboot {
resetSpec.Reboot = reboot
}
resetAction := action.NewResetAction(c, resetSpec) resetAction := action.NewResetAction(c, resetSpec)
if err := resetAction.Run(); err != nil { if err := resetAction.Run(); err != nil {
fmt.Println(err) fmt.Println(err)

14
main.go
View File

@ -446,9 +446,21 @@ This command is meant to be used from the boot GRUB menu, but can likely be used
}, },
{ {
Name: "reset", Name: "reset",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "reboot",
Usage: "Enable automated reboot after reset. Has precedence over any config in the system.",
},
&cli.BoolFlag{
Name: "unattended",
Usage: "Do not wait for user input and provide ttys after reset. Also sets the fast mode (do not wait 60 seconds before reset)",
},
},
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
reboot := c.Bool("reboot")
unattended := c.Bool("unattended")
return agent.Reset(configScanDir...) return agent.Reset(reboot, unattended, configScanDir...)
}, },
Usage: "Starts kairos reset mode", Usage: "Starts kairos reset mode",
Description: ` Description: `