mirror of
https://github.com/kairos-io/kairos-agent.git
synced 2025-06-03 01:44:53 +00:00
parent
75edc8b146
commit
a6f34820fb
@ -13,22 +13,23 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/uki"
|
||||
internalutils "github.com/kairos-io/kairos-agent/v2/pkg/utils"
|
||||
|
||||
fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
|
||||
"github.com/sanity-io/litter"
|
||||
|
||||
qr "github.com/kairos-io/go-nodepair/qrcode"
|
||||
"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/constants"
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/uki"
|
||||
internalutils "github.com/kairos-io/kairos-agent/v2/pkg/utils"
|
||||
fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
|
||||
events "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"
|
||||
"github.com/sanity-io/litter"
|
||||
)
|
||||
|
||||
func displayInfo(agentConfig *Config) {
|
||||
@ -235,13 +236,6 @@ func RunInstall(c *config.Config) error {
|
||||
|
||||
// runInstallUki runs the UKI path install
|
||||
func runInstallUki(c *config.Config) error {
|
||||
// Check if we are running in PXE
|
||||
err := internalutils.SetPXEEnv(c)
|
||||
if err != nil {
|
||||
c.Logger.Logger.Error().Err(err).Msg("Error setting PXE environment")
|
||||
return err
|
||||
}
|
||||
|
||||
// Load the spec from the config
|
||||
installSpec, err := config.ReadUkiInstallSpecFromConfig(c)
|
||||
if err != nil {
|
||||
@ -264,24 +258,7 @@ func runInstallUki(c *config.Config) error {
|
||||
c.CloudInitPaths = append(c.CloudInitPaths, installSpec.CloudInit...)
|
||||
|
||||
installAction := uki.NewInstallAction(c, installSpec)
|
||||
err = installAction.Run()
|
||||
|
||||
if err == nil && utils.Exists(constants.PXEVarFile) {
|
||||
// TODO: do we fail here?
|
||||
err = internalutils.RemoveEfivarPXE(c.Logger)
|
||||
if err != nil {
|
||||
c.Logger.Logger.Error().Err(err).Msg("Error removing PXE Efivar")
|
||||
return err
|
||||
}
|
||||
// Now remove the boot entry
|
||||
// TODO: Do we fail here?
|
||||
err = internalutils.RemoveBootEntry("kairos", c.Logger)
|
||||
if err != nil {
|
||||
c.Logger.Logger.Error().Err(err).Msg("Error removing PXE boot entry")
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
return installAction.Run()
|
||||
}
|
||||
|
||||
// runInstall runs the non-UKI path install
|
||||
|
@ -50,7 +50,6 @@ const (
|
||||
LinuxImgFs = "ext2"
|
||||
SquashFs = "squashfs"
|
||||
EfiFs = "vfat"
|
||||
IsoFS = "iso9660"
|
||||
EfiSize = uint(64)
|
||||
OEMSize = uint(64)
|
||||
PersistentSize = uint(0)
|
||||
@ -131,11 +130,6 @@ const (
|
||||
UpgradeRecoveryNoSourceError = "could not find a proper source for the recovery upgrade.\nThis can be configured in the cloud config files under the 'upgrade.recovery-system.uri' key or via cmdline using the '--source' flag"
|
||||
MultipleEntriesAssessmentError = "multiple boot entries found for %s"
|
||||
NoBootAssessmentWarning = "No boot assessment found in current boot entry config file"
|
||||
|
||||
// PXEVarFile is the path to the PXE boot entry file
|
||||
PXEVarFile = "/sys/firmware/efi/efivars/PXEBoot-3c909ff1-80a9-5970-94f1-fefb255c88bd"
|
||||
PXEIsoFile = "/tmp/pxe-source.iso"
|
||||
PXEEfiBootFile = "efiboot.img"
|
||||
)
|
||||
|
||||
func UkiDefaultMenuEntries() []string {
|
||||
|
@ -21,8 +21,6 @@ import (
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/foxboron/go-uefi/efi/attr"
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/utils/loop"
|
||||
"io"
|
||||
"io/fs"
|
||||
random "math/rand"
|
||||
@ -35,18 +33,19 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/distribution/reference"
|
||||
"github.com/foxboron/go-uefi/efi/attributes"
|
||||
"github.com/foxboron/go-uefi/efivarfs"
|
||||
"github.com/joho/godotenv"
|
||||
agentConfig "github.com/kairos-io/kairos-agent/v2/pkg/config"
|
||||
cnst "github.com/kairos-io/kairos-agent/v2/pkg/constants"
|
||||
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
|
||||
fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/utils/partitions"
|
||||
sdkTypes "github.com/kairos-io/kairos-sdk/types"
|
||||
|
||||
"github.com/kairos-io/kairos-sdk/state"
|
||||
"github.com/kairos-io/kairos-sdk/types"
|
||||
sdkTypes "github.com/kairos-io/kairos-sdk/types"
|
||||
|
||||
agentConfig "github.com/kairos-io/kairos-agent/v2/pkg/config"
|
||||
fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
|
||||
"github.com/kairos-io/kairos-agent/v2/pkg/utils/partitions"
|
||||
|
||||
"github.com/distribution/reference"
|
||||
"github.com/joho/godotenv"
|
||||
cnst "github.com/kairos-io/kairos-agent/v2/pkg/constants"
|
||||
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
|
||||
"github.com/twpayne/go-vfs/v5"
|
||||
)
|
||||
|
||||
@ -708,106 +707,3 @@ func ReadAssessmentFromEntry(fs v1.FS, entry string, logger sdkTypes.KairosLogge
|
||||
}
|
||||
return re.FindStringSubmatch(currentfile[0])[1], nil
|
||||
}
|
||||
|
||||
// ReadEfivar reads the content of an efivar file, skipping the first 4 bytes (attributes).
|
||||
func ReadEfivar(path string) ([]byte, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// Skip the first 4 bytes (attributes)
|
||||
attr := make([]byte, 4)
|
||||
_, err = io.ReadFull(f, attr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
content, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return content, nil
|
||||
}
|
||||
|
||||
func RemoveBootEntry(entryName string, l types.KairosLogger) error {
|
||||
// Remove any boot entries that match kairos
|
||||
efifs := efivarfs.NewFS().CheckImmutable().UnsetImmutable().Open()
|
||||
for _, entry := range efifs.GetBootOrder() {
|
||||
e, err := efifs.GetBootEntry(entry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO: maybe contains? so we match any variations that migth appear in the future?
|
||||
if strings.ToLower(e.Description) == strings.ToLower(entryName) {
|
||||
fileName := fmt.Sprintf("/sys/firmware/efi/efivars/%s-%s", entry, attributes.EFI_GLOBAL_VARIABLE.Format())
|
||||
l.Logger.Debug().Str("entry", e.Description).Str("filename", fileName).Msg("Removing boot entry")
|
||||
err = os.Remove(fileName)
|
||||
if err != nil {
|
||||
l.Logger.Err(err).Str("entry", e.Description).Str("filename", fileName).Msg("Error removing boot entry")
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func RemoveEfivarPXE(l types.KairosLogger) error {
|
||||
// Disable immutability
|
||||
err := attr.UnsetImmutable(cnst.PXEVarFile)
|
||||
if err != nil {
|
||||
l.Logger.Err(err).Str("file", cnst.PXEVarFile).Msg("Error unsetting immutable attribute")
|
||||
return err
|
||||
}
|
||||
return os.Remove(cnst.PXEVarFile)
|
||||
}
|
||||
|
||||
func SetPXEEnv(c *agentConfig.Config) error {
|
||||
efivar, err := ReadEfivar(cnst.PXEVarFile)
|
||||
// We dont care if we fail to read it, that means its not there
|
||||
if err == nil {
|
||||
c.Logger.Logger.Info().Str("iso", string(efivar)).Msg("PXE boot detected, downloading and mounting the iso locally")
|
||||
err = c.Client.GetURL(c.Logger, string(efivar), cnst.PXEIsoFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
isoLoop, err := loop.LoopRO(&v1.Image{File: cnst.PXEIsoFile}, c)
|
||||
if err != nil {
|
||||
c.Logger.Logger.Error().Err(err).Msg("Error creating loop device for iso image")
|
||||
return err
|
||||
}
|
||||
defer loop.Unloop(isoLoop, c)
|
||||
c.Logger.Logger.Debug().Str("iso", isoLoop).Msg("Mounted iso loop device")
|
||||
|
||||
// Mount the iso under /run/initramfs/live
|
||||
err = c.Mounter.Mount(isoLoop, cnst.UkiCdromSource, cnst.IsoFS, nil)
|
||||
if err != nil {
|
||||
c.Logger.Errorf("Error mounting iso: %s", err.Error())
|
||||
return err
|
||||
}
|
||||
c.Logger.Infof("Mounted iso under %s", cnst.UkiCdromSource)
|
||||
defer c.Mounter.Unmount(cnst.UkiCdromSource)
|
||||
|
||||
// Now mount the efi image inside the iso
|
||||
efiLoop, err := loop.LoopRO(&v1.Image{File: filepath.Join(cnst.UkiCdromSource, cnst.PXEEfiBootFile)}, c)
|
||||
if err != nil {
|
||||
c.Logger.Logger.Error().Err(err).Msg("Error creating loop device for efi image")
|
||||
return err
|
||||
}
|
||||
defer loop.Unloop(efiLoop, c)
|
||||
c.Logger.Logger.Debug().Str("efi", efiLoop).Msg("Mounted efi loop device")
|
||||
|
||||
// Mount the efi image under /run/rootfsbase which is the same as to other boot paths mount it at
|
||||
err = c.Mounter.Mount(efiLoop, cnst.IsoBaseTree, cnst.EfiFs, nil)
|
||||
if err != nil {
|
||||
c.Logger.Errorf("Error mounting iso: %s", err.Error())
|
||||
return err
|
||||
}
|
||||
c.Logger.Infof("Mounted Efi source under %s", cnst.IsoBaseTree)
|
||||
defer c.Mounter.Unmount(cnst.IsoBaseTree)
|
||||
// Now the system should have the same paths and sources as the normal install from usb/cdrom
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -23,15 +23,6 @@ func errnoIsErr(err error) error {
|
||||
|
||||
// Loop will setup a /dev/loopX device linked to the image file by using syscalls directly to set it
|
||||
func Loop(img *v1.Image, cfg *config.Config) (loopDevice string, err error) {
|
||||
return loop(img, cfg, os.O_RDWR)
|
||||
}
|
||||
|
||||
// LoopRO will setup a /dev/loopX device linked to the image file by using syscalls directly to set it. Will open it RO
|
||||
func LoopRO(img *v1.Image, cfg *config.Config) (loopDevice string, err error) {
|
||||
return loop(img, cfg, os.O_RDONLY)
|
||||
}
|
||||
|
||||
func loop(img *v1.Image, cfg *config.Config, openPerm int) (loopDevice string, err error) {
|
||||
log := cfg.Logger
|
||||
log.Debugf("Opening loop control device")
|
||||
fd, err := cfg.Fs.OpenFile("/dev/loop-control", os.O_RDONLY, 0o644)
|
||||
@ -56,7 +47,7 @@ func loop(img *v1.Image, cfg *config.Config, openPerm int) (loopDevice string, e
|
||||
return loopDevice, err
|
||||
}
|
||||
log.Logger.Debug().Str("image", img.File).Msg("Opening img file")
|
||||
imageFile, err := cfg.Fs.OpenFile(img.File, openPerm, os.ModePerm)
|
||||
imageFile, err := cfg.Fs.OpenFile(img.File, os.O_RDWR, os.ModePerm)
|
||||
if err != nil {
|
||||
log.Error("failed to open image file")
|
||||
return loopDevice, err
|
||||
|
Loading…
Reference in New Issue
Block a user