kairos-agent/internal/agent/reset.go
Itxaka 14e562bb16
🐛 Read upgrade/install values from config (#55)
We were ignoring the values in the /etc/elemental/config.yaml file that
we loaded into viper by not reading those values and their keys into the
final spec.

This meant that for example the defautl entry name was being lost as we
generated a new install spec from scratch and ignored those values that
we read on the config

Signed-off-by: Itxaka <itxaka.garcia@spectrocloud.com>
2023-06-08 09:50:19 +00:00

146 lines
3.7 KiB
Go

package agent
import (
"encoding/json"
"fmt"
"github.com/sanity-io/litter"
"github.com/sirupsen/logrus"
"os"
"sync"
"time"
sdk "github.com/kairos-io/kairos-sdk/bus"
"github.com/kairos-io/kairos-sdk/machine"
"github.com/kairos-io/kairos-sdk/utils"
hook "github.com/kairos-io/kairos/v2/internal/agent/hooks"
"github.com/kairos-io/kairos/v2/internal/bus"
"github.com/kairos-io/kairos/v2/internal/cmd"
"github.com/kairos-io/kairos/v2/pkg/action"
"github.com/kairos-io/kairos/v2/pkg/config"
"github.com/kairos-io/kairos/v2/pkg/config/collector"
"github.com/kairos-io/kairos/v2/pkg/elementalConfig"
"github.com/mudler/go-pluggable"
"github.com/pterm/pterm"
)
func Reset(debug bool, dir ...string) error {
// TODO: Enable args? No args for now so no possibility of reset persistent or overriding the source for the reset
// Nor the auto-reboot via cmd?
// This comment pertains calling reset via cmdline when wanting to override configs
bus.Manager.Initialize()
options := map[string]string{}
bus.Manager.Response(sdk.EventBeforeReset, func(p *pluggable.Plugin, r *pluggable.EventResponse) {
err := json.Unmarshal([]byte(r.Data), &options)
if err != nil {
fmt.Println(err)
}
})
cmd.PrintBranding(DefaultBanner)
// This loads yet another config ¬_¬
// TODO: merge this somehow with the rest so there is no 5 places to configure stuff?
// Also this reads the elemental config.yaml
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
utils.Prompt("") //nolint:errcheck
// give tty1 back
svc, err := machine.Getty(1)
if err == nil {
svc.Start() //nolint:errcheck
}
lock.Lock()
fmt.Println("Reset aborted")
panic(utils.Shell().Run())
}()
if !agentConfig.Fast {
time.Sleep(60 * time.Second)
}
lock.Lock()
ensureDataSourceReady()
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)
resetConfig, err := elementalConfig.ReadConfigRun("/etc/elemental")
if err != nil {
return err
}
if debug {
resetConfig.Logger.SetLevel(logrus.DebugLevel)
}
resetConfig.Logger.Debugf("Full config: %s\n", litter.Sdump(resetConfig))
resetSpec, err := elementalConfig.ReadResetSpec(resetConfig)
if err != nil {
return err
}
// Not even sure what opts can come from here to be honest. Where is the struct that supports this options?
// Where is the docs to support this? This is generic af and not easily identifiable
if len(options) == 0 {
resetSpec.FormatPersistent = true
} else {
fmt.Println(options)
}
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
utils.Prompt("") //nolint:errcheck
// give tty1 back
svc, err := machine.Getty(1)
if err == nil {
svc.Start() //nolint:errcheck
}
lock2.Lock()
fmt.Println("Reboot aborted")
panic(utils.Shell().Run())
}()
if !agentConfig.Fast {
time.Sleep(60 * time.Second)
}
lock2.Lock()
utils.Reboot()
return nil
}