kairos-agent/internal/agent/reset.go

140 lines
3.3 KiB
Go
Raw Normal View History

package agent
import (
"encoding/json"
"fmt"
"os"
"sync"
"time"
2023-07-10 12:39:48 +00:00
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/cmd"
"github.com/kairos-io/kairos-agent/v2/pkg/action"
"github.com/kairos-io/kairos-agent/v2/pkg/config"
"github.com/kairos-io/kairos-agent/v2/pkg/elementalConfig"
sdk "github.com/kairos-io/kairos-sdk/bus"
"github.com/kairos-io/kairos-sdk/collector"
"github.com/kairos-io/kairos-sdk/machine"
"github.com/kairos-io/kairos-sdk/utils"
"github.com/mudler/go-pluggable"
"github.com/pterm/pterm"
)
func Reset(dir ...string) error {
bus.Manager.Initialize()
cmd.PrintBranding(DefaultBanner)
// This config is only for reset branding.
agentConfig, err := LoadConfig()
if err != nil {
return err
}
cmd.PrintText(agentConfig.Branding.Reset, "Reset")
// We don't close the lock, as none of the following actions are expected to return
lock := sync.Mutex{}
go func() {
// Wait for user input and go back to shell
2022-07-25 22:26:10 +00:00
utils.Prompt("") //nolint:errcheck
// give tty1 back
svc, err := machine.Getty(1)
if err == nil {
2022-07-25 22:26:10 +00:00
svc.Start() //nolint:errcheck
}
lock.Lock()
fmt.Println("Reset aborted")
panic(utils.Shell().Run())
}()
2022-10-01 00:23:10 +00:00
if !agentConfig.Fast {
time.Sleep(60 * time.Second)
}
lock.Lock()
ensureDataSourceReady()
optionsFromEvent := map[string]string{}
// This gets the options from an event that can be sent by anyone.
// This should override the default config as it's much more dynamic
bus.Manager.Response(sdk.EventBeforeReset, func(p *pluggable.Plugin, r *pluggable.EventResponse) {
err := json.Unmarshal([]byte(r.Data), &optionsFromEvent)
if err != nil {
fmt.Println(err)
}
})
bus.Manager.Publish(sdk.EventBeforeReset, sdk.EventPayload{}) //nolint:errcheck
c, err := config.Scan(collector.Directories(dir...))
if err != nil {
return err
}
utils.SetEnv(c.Env)
// Load the installation Config from the cloud-config data
resetConfig, resetSpec, err := elementalConfig.ReadResetConfigFromAgentConfig(c)
if err != nil {
return err
}
// Go over the possible options sent via event
if len(optionsFromEvent) > 0 {
if p := optionsFromEvent["reset-persistent"]; p != "" {
resetSpec.FormatPersistent = p == "true"
}
if o := optionsFromEvent["reset-oem"]; o != "" {
resetSpec.FormatOEM = o == "true"
}
if s := optionsFromEvent["strict"]; s != "" {
resetConfig.Strict = s == "true"
}
}
resetAction := action.NewResetAction(resetConfig, resetSpec)
if err := resetAction.Run(); err != nil {
fmt.Println(err)
os.Exit(1)
}
if err := hook.Run(*c, hook.AfterReset...); err != nil {
return err
}
bus.Manager.Publish(sdk.EventAfterReset, sdk.EventPayload{}) //nolint:errcheck
if !agentConfig.Fast {
pterm.Info.Println("Rebooting in 60 seconds, press Enter to abort...")
}
// We don't close the lock, as none of the following actions are expected to return
lock2 := sync.Mutex{}
go func() {
// Wait for user input and go back to shell
2022-07-25 22:26:10 +00:00
utils.Prompt("") //nolint:errcheck
// give tty1 back
svc, err := machine.Getty(1)
if err == nil {
2022-07-25 22:26:10 +00:00
svc.Start() //nolint:errcheck
}
lock2.Lock()
fmt.Println("Reboot aborted")
panic(utils.Shell().Run())
}()
2022-10-01 00:23:10 +00:00
if !agentConfig.Fast {
time.Sleep(60 * time.Second)
}
lock2.Lock()
utils.Reboot()
return nil
}