From 53f5bf8d2c97e91bee06bcb5948170015486ea77 Mon Sep 17 00:00:00 2001 From: Noel Georgi Date: Thu, 25 Dec 2025 15:33:58 +0530 Subject: [PATCH] fix: overlay installers Overlays installers assume the `/boot/EFI` path, so we generate assets into `/boot/EFI` then move that directory to the mountPrefix+/EFI. Signed-off-by: Noel Georgi --- cmd/installer/pkg/install/install.go | 13 ++++++++++++- .../runtime/v1alpha1/bootloader/bootloader.go | 2 +- .../runtime/v1alpha1/bootloader/dual/dual.go | 10 +++++----- .../runtime/v1alpha1/bootloader/grub/grub.go | 6 +++--- .../v1alpha1/bootloader/grub/install.go | 8 ++++---- .../v1alpha1/bootloader/grub/upgrade.go | 2 +- .../v1alpha1/bootloader/sdboot/sdboot.go | 18 +++++++++--------- 7 files changed, 35 insertions(+), 24 deletions(-) diff --git a/cmd/installer/pkg/install/install.go b/cmd/installer/pkg/install/install.go index 71cb1a5ab..731201483 100644 --- a/cmd/installer/pkg/install/install.go +++ b/cmd/installer/pkg/install/install.go @@ -544,7 +544,18 @@ func (i *Installer) getBootPartitions(ctx context.Context, mode Mode, bootloader bootloaderOptions := i.generateBootloaderOptions(ctx, mode, nil) - return bootloader.GenerateAssets("/efi", bootloaderOptions) + partitionOptions, err := bootloader.GenerateAssets(bootloaderOptions) + if err != nil { + return nil, fmt.Errorf("failed to generate bootloader assets: %w", err) + } + + // We need to move out bootloaderOptions.MountPrefix+/boot/EFI to bootloaderOptions.MountPrefix+/EFI otherwise + // BOOT partition will be populated with EFI directory inside boot directory. + if err := os.Rename(filepath.Join(bootloaderOptions.MountPrefix, constants.EFIMountPoint), filepath.Join(bootloaderOptions.MountPrefix, "EFI")); err != nil { + return nil, fmt.Errorf("failed to move EFI directory: %w", err) + } + + return partitionOptions, nil } func (i *Installer) installBootloader(ctx context.Context, mode Mode, bootloader bootloaderpkg.Bootloader, info *blkid.Info) (*bootloaderoptions.InstallResult, error) { diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/bootloader.go b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/bootloader.go index c050ddf7d..88a0752ca 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/bootloader.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/bootloader.go @@ -25,7 +25,7 @@ import ( // Bootloader describes a bootloader. type Bootloader interface { - GenerateAssets(efiAssetsPath string, opts options.InstallOptions) ([]partition.Options, error) + GenerateAssets(options options.InstallOptions) ([]partition.Options, error) // Install the bootloader. // // Install mounts the partitions as required. diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/dual/dual.go b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/dual/dual.go index f685c9178..3bc9f5d95 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/dual/dual.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/dual/dual.go @@ -33,22 +33,22 @@ func New() *Config { } // GenerateAssets generates the dual-boot bootloader assets and returns the partition options with source directory set. -func (c *Config) GenerateAssets(efiAssetsPath string, opts options.InstallOptions) ([]partition.Options, error) { +func (c *Config) GenerateAssets(opts options.InstallOptions) ([]partition.Options, error) { if opts.Arch == "arm64" { return nil, fmt.Errorf("dual-boot bootloader is not supported on arm64 architecture, either GRUB or sd-boot must be used") } // here we'll use the grub and sd-boot GenerateAssets logic // and remove the grub `EFI` directory after we're done - if _, err := grub.NewConfig().GenerateAssets(efiAssetsPath, opts); err != nil { + if _, err := grub.NewConfig().GenerateAssets(opts); err != nil { return nil, fmt.Errorf("failed to install GRUB bootloader: %w", err) } - if err := os.RemoveAll(filepath.Join(opts.MountPrefix, efiAssetsPath)); err != nil { + if err := os.RemoveAll(filepath.Join(opts.MountPrefix, constants.EFIMountPoint)); err != nil { return nil, fmt.Errorf("failed to cleanup GRUB EFI assets directory: %w", err) } - if _, err := sdboot.New().GenerateAssets(efiAssetsPath, opts); err != nil { + if _, err := sdboot.New().GenerateAssets(opts); err != nil { return nil, fmt.Errorf("failed to generate sd-boot assets: %w", err) } @@ -59,7 +59,7 @@ func (c *Config) GenerateAssets(efiAssetsPath string, opts options.InstallOption true, quirk, partition.WithLabel(constants.EFIPartitionLabel), - partition.WithSourceDirectory(filepath.Join(opts.MountPrefix, efiAssetsPath)), + partition.WithSourceDirectory(filepath.Join(opts.MountPrefix, "EFI")), ), partition.NewPartitionOptions(false, quirk, partition.WithLabel(constants.BIOSGrubPartitionLabel)), partition.NewPartitionOptions( diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/grub.go b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/grub.go index 0cc398ed2..0cb5b1d4d 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/grub.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/grub.go @@ -94,8 +94,8 @@ func (c *Config) KexecLoad(r runtime.Runtime, disk string) error { } // GenerateAssets generates the bootloader assets and returns partition options to create the bootloader partitions. -func (c *Config) GenerateAssets(efiAssetsPath string, opts options.InstallOptions) ([]partition.Options, error) { - if err := c.generateAssets(opts, efiAssetsPath); err != nil { +func (c *Config) GenerateAssets(opts options.InstallOptions) ([]partition.Options, error) { + if err := c.generateAssets(opts); err != nil { return nil, err } @@ -110,7 +110,7 @@ func (c *Config) GenerateAssets(efiAssetsPath string, opts options.InstallOption // so we don't need to set the source directory for the EFI partition efiFormatOptions = append( efiFormatOptions, - partition.WithSourceDirectory(filepath.Join(opts.MountPrefix, efiAssetsPath)), + partition.WithSourceDirectory(filepath.Join(opts.MountPrefix, "EFI")), ) } diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/install.go b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/install.go index 73da2e157..9d291deec 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/install.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/install.go @@ -94,7 +94,7 @@ func (c *Config) Install(opts options.InstallOptions) (*options.InstallResult, e }, err } -func (c *Config) generateGrubImage(opts options.InstallOptions, efiAssetsPath string) error { +func (c *Config) generateGrubImage(opts options.InstallOptions) error { var copyInstructions []utils.CopyInstruction grubSourceDirectory := "/usr/lib/grub" @@ -195,7 +195,7 @@ func (c *Config) generateGrubImage(opts options.InstallOptions, efiAssetsPath st copyInstructions = append(copyInstructions, utils.SourceDestination( grubEFIPath, - filepath.Join(opts.MountPrefix, efiAssetsPath, efiFile), + filepath.Join(opts.MountPrefix, constants.EFIMountPoint, efiFile), )) if err := utils.CopyFiles( @@ -209,7 +209,7 @@ func (c *Config) generateGrubImage(opts options.InstallOptions, efiAssetsPath st } //nolint:gocyclo -func (c *Config) generateAssets(opts options.InstallOptions, efiAssetsPath string) error { +func (c *Config) generateAssets(opts options.InstallOptions) error { cmdline := opts.Cmdline // if we have a kernel path, assume that the kernel and initramfs are available @@ -283,7 +283,7 @@ func (c *Config) generateAssets(opts options.InstallOptions, efiAssetsPath strin } if opts.ImageMode { - return c.generateGrubImage(opts, efiAssetsPath) + return c.generateGrubImage(opts) } return nil diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/upgrade.go b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/upgrade.go index b6d73f63d..8476b0f25 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/upgrade.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/upgrade.go @@ -62,7 +62,7 @@ func (c *Config) Upgrade(opts options.InstallOptions) (*options.InstallResult, e return err } - if err := c.generateAssets(opts, constants.EFIMountPoint); err != nil { + if err := c.generateAssets(opts); err != nil { return err } diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/sdboot/sdboot.go b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/sdboot/sdboot.go index dbaea787e..694ea11a0 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/sdboot/sdboot.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/sdboot/sdboot.go @@ -275,13 +275,13 @@ func (c *Config) KexecLoad(r runtime.Runtime, disk string) error { } // GenerateAssets generates the sd-boot bootloader assets and returns the partition options with source directory set. -func (c *Config) GenerateAssets(efiAssetsPath string, opts options.InstallOptions) ([]partition.Options, error) { +func (c *Config) GenerateAssets(opts options.InstallOptions) ([]partition.Options, error) { ukiFileName, err := generateNextUKIName(opts.Version, nil) if err != nil { return nil, err } - if err := c.generateAssets(opts, efiAssetsPath, ukiFileName); err != nil { + if err := c.generateAssets(opts, ukiFileName); err != nil { return nil, err } @@ -292,7 +292,7 @@ func (c *Config) GenerateAssets(efiAssetsPath string, opts options.InstallOption true, quirk, partition.WithLabel(constants.EFIPartitionLabel), - partition.WithSourceDirectory(filepath.Join(opts.MountPrefix, efiAssetsPath)), + partition.WithSourceDirectory(filepath.Join(opts.MountPrefix, "EFI")), ), } @@ -364,7 +364,7 @@ func (c *Config) Upgrade(opts options.InstallOptions) (*options.InstallResult, e } } - if err := c.generateAssets(opts, constants.EFIMountPoint, ukiPath); err != nil { + if err := c.generateAssets(opts, ukiPath); err != nil { return err } @@ -438,12 +438,12 @@ func (c *Config) setup(opts options.InstallOptions, ukiFileName string) (*option }, nil } -func (c *Config) generateAssets(opts options.InstallOptions, efiAssetsPath string, ukiFileName string) error { - if err := os.MkdirAll(filepath.Join(opts.MountPrefix, efiAssetsPath, "loader"), 0o755); err != nil { +func (c *Config) generateAssets(opts options.InstallOptions, ukiFileName string) error { + if err := os.MkdirAll(filepath.Join(opts.MountPrefix, constants.EFIMountPoint, "loader"), 0o755); err != nil { return err } - if err := os.WriteFile(filepath.Join(opts.MountPrefix, efiAssetsPath, "loader", "loader.conf"), LoaderConfBytes, 0o644); err != nil { + if err := os.WriteFile(filepath.Join(opts.MountPrefix, constants.EFIMountPoint, "loader", "loader.conf"), LoaderConfBytes, 0o644); err != nil { return err } @@ -456,11 +456,11 @@ func (c *Config) generateAssets(opts options.InstallOptions, efiAssetsPath strin opts.Printf, utils.SourceDestination( opts.BootAssets.UKIPath, - filepath.Join(opts.MountPrefix, efiAssetsPath, "EFI", "Linux", ukiFileName), + filepath.Join(opts.MountPrefix, constants.EFIMountPoint, "EFI", "Linux", ukiFileName), ), utils.SourceDestination( opts.BootAssets.SDBootPath, - filepath.Join(opts.MountPrefix, efiAssetsPath, sdbootFilename), + filepath.Join(opts.MountPrefix, constants.EFIMountPoint, sdbootFilename), ), ); err != nil { return err