2023-10-03 09:15:17 +00:00
|
|
|
package uki
|
|
|
|
|
|
|
|
import (
|
2024-02-20 15:54:59 +00:00
|
|
|
"fmt"
|
|
|
|
|
2024-02-21 09:44:32 +00:00
|
|
|
"github.com/kairos-io/kairos-agent/v2/pkg/action"
|
2023-10-03 09:15:17 +00:00
|
|
|
"github.com/kairos-io/kairos-agent/v2/pkg/config"
|
2024-02-20 15:54:59 +00:00
|
|
|
"github.com/kairos-io/kairos-agent/v2/pkg/constants"
|
2024-02-02 12:20:06 +00:00
|
|
|
"github.com/kairos-io/kairos-agent/v2/pkg/elemental"
|
2023-10-03 09:15:17 +00:00
|
|
|
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
|
|
|
|
elementalUtils "github.com/kairos-io/kairos-agent/v2/pkg/utils"
|
|
|
|
events "github.com/kairos-io/kairos-sdk/bus"
|
2024-02-02 12:20:06 +00:00
|
|
|
"github.com/kairos-io/kairos-sdk/utils"
|
2023-10-03 09:15:17 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type ResetAction struct {
|
|
|
|
cfg *config.Config
|
|
|
|
spec *v1.ResetUkiSpec
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewResetAction(cfg *config.Config, spec *v1.ResetUkiSpec) *ResetAction {
|
|
|
|
return &ResetAction{cfg: cfg, spec: spec}
|
|
|
|
}
|
|
|
|
|
2024-02-02 12:20:06 +00:00
|
|
|
func (r *ResetAction) Run() (err error) {
|
2023-10-03 09:15:17 +00:00
|
|
|
// Run pre-install stage
|
2024-02-02 12:20:06 +00:00
|
|
|
_ = elementalUtils.RunStage(r.cfg, "kairos-uki-reset.pre")
|
2023-10-03 09:15:17 +00:00
|
|
|
_ = events.RunHookScript("/usr/bin/kairos-agent.uki.reset.pre.hook")
|
|
|
|
|
2024-02-02 12:20:06 +00:00
|
|
|
e := elemental.NewElemental(r.cfg)
|
|
|
|
cleanup := utils.NewCleanStack()
|
|
|
|
defer func() { err = cleanup.Cleanup(err) }()
|
2023-10-03 09:15:17 +00:00
|
|
|
|
2024-02-02 12:20:06 +00:00
|
|
|
// Unmount partitions if any is already mounted before formatting
|
|
|
|
err = e.UnmountPartitions(r.spec.Partitions.PartitionsByMountPoint(true))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reformat persistent partition
|
|
|
|
if r.spec.FormatPersistent {
|
|
|
|
persistent := r.spec.Partitions.Persistent
|
|
|
|
if persistent != nil {
|
|
|
|
err = e.FormatPartition(persistent)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reformat OEM
|
|
|
|
if r.spec.FormatOEM {
|
|
|
|
oem := r.spec.Partitions.OEM
|
|
|
|
if oem != nil {
|
|
|
|
err = e.FormatPartition(oem)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-20 16:16:57 +00:00
|
|
|
// REMOUNT /efi as RW (its RO by default)
|
|
|
|
umount, err := e.MountRWPartition(r.spec.Partitions.EFI)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
cleanup.Push(umount)
|
|
|
|
|
2024-02-20 15:54:59 +00:00
|
|
|
// Copy "recovery" to "active"
|
|
|
|
err = overwriteArtifactSetRole(r.cfg.Fs, constants.UkiEfiDir, "recovery", "active", r.cfg.Logger)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("copying recovery to active: %w", err)
|
|
|
|
}
|
2024-02-21 09:44:32 +00:00
|
|
|
// SelectBootEntry sets the default boot entry to the selected entry
|
|
|
|
err = action.SelectBootEntry(r.cfg, "active")
|
|
|
|
// Should we fail? Or warn?
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-02-20 15:54:59 +00:00
|
|
|
|
2024-03-11 15:44:41 +00:00
|
|
|
if mnt, err := elementalUtils.IsMounted(r.cfg, r.spec.Partitions.OEM); !mnt && err == nil {
|
|
|
|
err = e.MountPartition(r.spec.Partitions.OEM)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
err = Hook(r.cfg, constants.AfterResetHook)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-02-02 12:20:06 +00:00
|
|
|
_ = elementalUtils.RunStage(r.cfg, "kairos-uki-reset.after")
|
2023-10-03 09:15:17 +00:00
|
|
|
_ = events.RunHookScript("/usr/bin/kairos-agent.uki.reset.after.hook") //nolint:errcheck
|
|
|
|
|
2024-02-02 12:20:06 +00:00
|
|
|
// Do not reboot/poweroff on cleanup errors
|
|
|
|
err = cleanup.Cleanup(err)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
2023-10-03 09:15:17 +00:00
|
|
|
}
|