diff --git a/internal/agent/install.go b/internal/agent/install.go index b199a9a..adfa6c3 100644 --- a/internal/agent/install.go +++ b/internal/agent/install.go @@ -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 diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index 94c1832..b2f5340 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -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 { diff --git a/pkg/utils/common.go b/pkg/utils/common.go index 11ef9c1..d727bd2 100644 --- a/pkg/utils/common.go +++ b/pkg/utils/common.go @@ -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 -} diff --git a/pkg/utils/loop/loopback.go b/pkg/utils/loop/loopback.go index 19987bc..74673f0 100644 --- a/pkg/utils/loop/loopback.go +++ b/pkg/utils/loop/loopback.go @@ -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