Skip to content

Commit

Permalink
fix: overlay installer operations
Browse files Browse the repository at this point in the history
1. Use overlay installer to build the `cmdline` when running in
   install/upgrade mode.

2. Pull down the overlay installer with the arch specific to the
   installer being generated, vs. the arch of the `imager`.

3. Print a message when running an overlay installer.

Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
  • Loading branch information
smira committed Apr 16, 2024
1 parent b1b63f6 commit 0a78580
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 24 deletions.
2 changes: 2 additions & 0 deletions cmd/installer/cmd/imager/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ var rootCmd = &cobra.Command{
},
ExtraOptions: extraOverlayOptions,
}

prof.Input.OverlayInstaller.ImageRef = cmdFlags.OverlayImage
}

prof.Input.SystemExtensions = xslices.Map(
Expand Down
11 changes: 8 additions & 3 deletions cmd/installer/cmd/installer/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,21 @@ func Execute() {
}
}

var options = &install.Options{}
var options = &install.Options{
Board: constants.BoardNone,
}

var bootloader bool
var (
bootloader bool
dummy string
)

func init() {
rootCmd.PersistentFlags().StringVar(&options.ConfigSource, "config", "", "The value of "+constants.KernelParamConfig)
rootCmd.PersistentFlags().StringVar(&options.Disk, "disk", "", "The path to the disk to install to")
rootCmd.PersistentFlags().StringVar(&options.Platform, "platform", "", "The value of "+constants.KernelParamPlatform)
rootCmd.PersistentFlags().StringVar(&options.Arch, "arch", runtime.GOARCH, "The target architecture")
rootCmd.PersistentFlags().StringVar(&options.Board, "board", constants.BoardNone, "Deprecated: no op")
rootCmd.PersistentFlags().StringVar(&dummy, "board", constants.BoardNone, "Deprecated: no op")
rootCmd.PersistentFlags().StringArrayVar(&options.ExtraKernelArgs, "extra-kernel-arg", []string{}, "Extra argument to pass to the kernel")
rootCmd.PersistentFlags().BoolVar(&bootloader, "bootloader", true, "Deprecated: no op")
rootCmd.PersistentFlags().BoolVar(&options.Upgrade, "upgrade", false, "Indicates that the install is being performed by an upgrade")
Expand Down
52 changes: 33 additions & 19 deletions cmd/installer/pkg/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type Options struct {
LegacyBIOSSupport bool
MetaValues MetaValues
OverlayInstaller overlay.Installer[overlay.ExtraOptions]
OverlayName string
OverlayExtractedDir string
ExtraOptions overlay.ExtraOptions

Expand Down Expand Up @@ -85,6 +86,25 @@ func Install(ctx context.Context, p runtime.Platform, mode Mode, opts *Options)
return fmt.Errorf("using standard installer image is not supported for board: %s, use an installer with overlay", b)
}

if overlayPresent {
extraOptionsBytes, err := os.ReadFile(constants.ImagerOverlayExtraOptionsPath)
if err != nil {
return err
}

var extraOptions overlay.ExtraOptions

decoder := yaml.NewDecoder(bytes.NewReader(extraOptionsBytes))
decoder.KnownFields(true)

if err := decoder.Decode(&extraOptions); err != nil {
return fmt.Errorf("failed to decode extra options: %w", err)
}

opts.OverlayInstaller = executor.New(constants.ImagerOverlayInstallerDefaultPath)
opts.ExtraOptions = extraOptions
}

cmdline := procfs.NewCmdline("")
cmdline.Append(constants.KernelParamPlatform, p.Name())

Expand Down Expand Up @@ -117,6 +137,17 @@ func Install(ctx context.Context, p runtime.Platform, mode Mode, opts *Options)
cmdline.SetAll(b.KernelArgs().Strings())
}

if opts.OverlayInstaller != nil {
overlayOpts, getOptsErr := opts.OverlayInstaller.GetOptions(opts.ExtraOptions)
if getOptsErr != nil {
return fmt.Errorf("failed to get overlay installer options: %w", getOptsErr)
}

opts.OverlayName = overlayOpts.Name

cmdline.SetAll(overlayOpts.KernelArgs)
}

if err := cmdline.AppendAll(
opts.ExtraKernelArgs,
procfs.WithOverwriteArgs("console"),
Expand All @@ -126,25 +157,6 @@ func Install(ctx context.Context, p runtime.Platform, mode Mode, opts *Options)
return err
}

if overlayPresent {
extraOptionsBytes, err := os.ReadFile(constants.ImagerOverlayExtraOptionsPath)
if err != nil {
return err
}

var extraOptions overlay.ExtraOptions

decoder := yaml.NewDecoder(bytes.NewReader(extraOptionsBytes))
decoder.KnownFields(true)

if err := decoder.Decode(&extraOptions); err != nil {
return fmt.Errorf("failed to decode extra options: %w", err)
}

opts.OverlayInstaller = executor.New(constants.ImagerOverlayInstallerDefaultPath)
opts.ExtraOptions = extraOptions
}

i, err := NewInstaller(ctx, cmdline, mode, opts)
if err != nil {
return err
Expand Down Expand Up @@ -338,6 +350,8 @@ func (i *Installer) Install(ctx context.Context, mode Mode) (err error) {
}

if i.options.OverlayInstaller != nil {
i.options.Printf("running overlay installer %q", i.options.OverlayName)

if err = i.options.OverlayInstaller.Install(overlay.InstallOptions[overlay.ExtraOptions]{
InstallDisk: i.options.Disk,
MountPrefix: i.options.MountPrefix,
Expand Down
19 changes: 17 additions & 2 deletions pkg/imager/out.go
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,21 @@ func (i *Imager) outInstaller(ctx context.Context, path string, report *reporter
}

if i.overlayInstaller != nil {
tempOverlayPath := filepath.Join(i.tempDir, "overlay-installer", constants.ImagerOverlayBasePath)

if err := os.MkdirAll(tempOverlayPath, 0o755); err != nil {
return fmt.Errorf("failed to create overlay directory: %w", err)
}

if err := i.prof.Input.OverlayInstaller.Extract(
ctx,
tempOverlayPath,
i.prof.Arch,
progressPrintf(report, reporter.Update{Message: "pulling overlay for installer...", Status: reporter.StatusRunning}),
); err != nil {
return err
}

extraOpts, internalErr := yaml.Marshal(i.prof.Overlay.ExtraOptions)
if internalErr != nil {
return fmt.Errorf("failed to marshal extra options: %w", internalErr)
Expand All @@ -430,11 +445,11 @@ func (i *Imager) outInstaller(ctx context.Context, path string, report *reporter
mode os.FileMode
}{
{
sourcePath: filepath.Join(i.tempDir, constants.ImagerOverlayArtifactsPath),
sourcePath: filepath.Join(i.tempDir, "overlay-installer", constants.ImagerOverlayArtifactsPath),
imagePath: strings.TrimLeft(constants.ImagerOverlayArtifactsPath, "/"),
},
{
sourcePath: filepath.Join(i.tempDir, constants.ImagerOverlayInstallersPath, i.prof.Overlay.Name),
sourcePath: filepath.Join(i.tempDir, "overlay-installer", constants.ImagerOverlayInstallersPath, i.prof.Overlay.Name),
imagePath: strings.TrimLeft(constants.ImagerOverlayInstallerDefaultPath, "/"),
mode: 0o755,
},
Expand Down
4 changes: 4 additions & 0 deletions pkg/imager/profile/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ type Input struct {
RPiFirmware FileAsset `yaml:"rpiFirmware,omitempty"`
// Base installer image to mutate.
BaseInstaller ContainerAsset `yaml:"baseInstaller,omitempty"`
// OverlayInstaller is an overlay image to inject into the installer.
//
// OverlayInstaller architecture should match the output installer architecture.
OverlayInstaller ContainerAsset `yaml:"overlayInstaller,omitempty"`
// SecureBoot is a section with secureboot keys, only for SecureBoot enabled builds.
SecureBoot *SecureBootAssets `yaml:"secureboot,omitempty"`
// SystemExtensions is a list of system extensions to install.
Expand Down

0 comments on commit 0a78580

Please sign in to comment.