Skip to content

Commit 61e95cb

Browse files
committed
feat: support bootloader option for ISO
Support selecting bootloader option for ISO. Signed-off-by: Noel Georgi <git@frezbo.dev>
1 parent d110727 commit 61e95cb

File tree

13 files changed

+350
-103
lines changed

13 files changed

+350
-103
lines changed

internal/app/machined/pkg/runtime/v1alpha1/bootloader/bootloader.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,14 @@ func NewAuto() Bootloader {
8383
// New returns a new bootloader based on the secureboot flag and architecture.
8484
func New(bootloader, talosVersion, arch string) (Bootloader, error) {
8585
switch bootloader {
86-
case profile.DiskImageBootloaderGrub.String():
86+
case profile.BootLoaderKindGrub.String():
8787
g := grub.NewConfig()
8888
g.AddResetOption = quirks.New(talosVersion).SupportsResetGRUBOption()
8989

9090
return g, nil
91-
case profile.DiskImageBootloaderSDBoot.String():
91+
case profile.BootLoaderKindSDBoot.String():
9292
return sdboot.New(), nil
93-
case profile.DiskImageBootloaderDualBoot.String():
93+
case profile.BootLoaderKindDualBoot.String():
9494
return dual.New(), nil
9595
default:
9696
return nil, fmt.Errorf("unsupported bootloader %q", bootloader)

internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ func (*Sequencer) Initialize(r runtime.Runtime) []runtime.Phase {
104104
return false
105105
}
106106

107-
return r.State().Machine().Installed() && val == profile.DiskImageBootloaderDualBoot.String()
107+
return r.State().Machine().Installed() && val == profile.BootLoaderKindDualBoot.String()
108108
},
109109
"cleanupBootloader",
110110
CleanupBootloader,

pkg/imager/iso/uefi.go

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,6 @@ import (
2020
"github.com/siderolabs/talos/pkg/makefs"
2121
)
2222

23-
// UEFIOptions describe the input for the CreateUEFI function.
24-
type UEFIOptions struct {
25-
UKIPath string
26-
SDBootPath string
27-
28-
// A value in loader.conf secure-boot-enroll: off, manual, if-safe, force.
29-
SDBootSecureBootEnrollKeys string
30-
31-
// UKISigningCertDer is the DER encoded UKI signing certificate.
32-
UKISigningCertDerPath string
33-
34-
// optional, for auto-enrolling secureboot keys
35-
PlatformKeyPath string
36-
KeyExchangeKeyPath string
37-
SignatureKeyPath string
38-
39-
Arch string
40-
Version string
41-
42-
ScratchDir string
43-
OutPath string
44-
}
45-
4623
const (
4724
// mib is the size of a megabyte.
4825
mib = 1024 * 1024

pkg/imager/out.go

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,43 @@ func (i *Imager) outISO(ctx context.Context, path string, report *reporter.Repor
188188
if err != nil {
189189
return err
190190
}
191+
case quirks.New(i.prof.Version).ISOSupportsSettingBootloader():
192+
options := iso.Options{
193+
KernelPath: i.prof.Input.Kernel.Path,
194+
InitramfsPath: i.initramfsPath,
195+
Cmdline: i.cmdline,
196+
197+
UKIPath: i.ukiPath,
198+
SDBootPath: i.sdBootPath,
199+
200+
SDBootSecureBootEnrollKeys: "off",
201+
202+
Arch: i.prof.Arch,
203+
Version: i.prof.Version,
204+
205+
ScratchDir: scratchSpace,
206+
OutPath: path,
207+
}
208+
209+
switch i.prof.Output.ISOOptions.Bootloader {
210+
case profile.BootLoaderKindDualBoot:
211+
generator, err = options.CreateHybrid(printf)
212+
if err != nil {
213+
return err
214+
}
215+
case profile.BootLoaderKindSDBoot:
216+
generator, err = options.CreateUEFI(printf)
217+
if err != nil {
218+
return err
219+
}
220+
case profile.BootLoaderKindGrub:
221+
generator, err = options.CreateGRUB(printf)
222+
if err != nil {
223+
return err
224+
}
225+
case profile.BootLoaderKindNone:
226+
return fmt.Errorf("cannot create ISO with no bootloader")
227+
}
191228
case quirks.New(i.prof.Version).UseSDBootForUEFI():
192229
options := iso.Options{
193230
KernelPath: i.prof.Input.Kernel.Path,
@@ -324,10 +361,10 @@ func (i *Imager) buildImage(ctx context.Context, path string, printf func(string
324361

325362
if i.prof.Arch == "amd64" && !i.prof.SecureBootEnabled() && quirks.New(i.prof.Version).UseSDBootForUEFI() {
326363
// allow overriding the bootloader if provided
327-
if i.prof.Output.ImageOptions.Bootloader == profile.DiskImageBootloaderDualBoot {
364+
if i.prof.Output.ImageOptions.Bootloader == profile.BootLoaderKindDualBoot {
328365
metaContents = append(metaContents, meta.Value{
329366
Key: meta.DiskImageBootloader,
330-
Value: profile.DiskImageBootloaderDualBoot.String(),
367+
Value: profile.BootLoaderKindDualBoot.String(),
331368
})
332369
}
333370
}

pkg/imager/profile/output.go

Lines changed: 52 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ type ImageOptions struct {
4343
DiskFormatOptions string `yaml:"diskFormatOptions,omitempty"`
4444
// Bootloader is the bootloader to use for the disk image.
4545
// If not set, it defaults to dual-boot.
46-
Bootloader DiskImageBootloader `yaml:"bootloader"`
46+
Bootloader BootloaderKind `yaml:"bootloader,omitempty"`
4747
}
4848

4949
// ISOOptions describes options for the 'iso' output.
@@ -52,6 +52,9 @@ type ISOOptions struct {
5252
//
5353
// If not set, it defaults to if-safe.
5454
SDBootEnrollKeys SDBootEnrollKeys `yaml:"sdBootEnrollKeys"`
55+
// Bootloader is the bootloader to use for the iso image.
56+
// If not set, it defaults to dual-boot.
57+
Bootloader BootloaderKind `yaml:"bootloader,omitempty"`
5558
}
5659

5760
// OutputKind is output specification.
@@ -105,53 +108,73 @@ const (
105108
SDBootEnrollKeysOff // off
106109
)
107110

108-
// DiskImageBootloader is a bootloader for the disk image.
109-
type DiskImageBootloader int
111+
// BootloaderKind is a bootloader for the disk image.
112+
type BootloaderKind int
110113

111114
const (
112-
// DiskImageBootloaderDualBoot is the dual-boot bootloader
115+
// BootLoaderKindNone is the zero value.
116+
BootLoaderKindNone BootloaderKind = iota // none
117+
// BootLoaderKindDualBoot is the dual-boot bootloader.
113118
// using sd-boot for UEFI and GRUB for BIOS.
114-
DiskImageBootloaderDualBoot DiskImageBootloader = iota // dual-boot
115-
// DiskImageBootloaderSDBoot is the sd-boot bootloader.
116-
DiskImageBootloaderSDBoot // sd-boot
117-
// DiskImageBootloaderGrub is the GRUB bootloader.
118-
DiskImageBootloaderGrub // grub
119+
BootLoaderKindDualBoot // dual-boot
120+
// BootLoaderKindSDBoot is the sd-boot bootloader.
121+
BootLoaderKindSDBoot // sd-boot
122+
// BootLoaderKindGrub is the GRUB bootloader.
123+
BootLoaderKindGrub // grub
119124
)
120125

121126
// FillDefaults fills default values for the output.
122127
func (o *Output) FillDefaults(arch, version string, secureboot bool) {
123-
if o.Kind == OutKindImage {
128+
switch o.Kind { //nolint:exhaustive
129+
case OutKindImage:
124130
if o.ImageOptions == nil {
125131
o.ImageOptions = &ImageOptions{}
126132
}
127133

128-
useSDBoot := quirks.New(version).UseSDBootForUEFI()
129-
130-
switch {
131-
case o.ImageOptions.Bootloader != DiskImageBootloaderDualBoot:
132-
// allow user to override bootloader
133-
case secureboot:
134-
// secureboot is always using sd-boot
135-
o.ImageOptions.Bootloader = DiskImageBootloaderSDBoot
136-
case arch == "arm64" && useSDBoot:
137-
// arm64 always uses sd-boot for Talos >= 1.10
138-
o.ImageOptions.Bootloader = DiskImageBootloaderSDBoot
139-
case !useSDBoot:
140-
// legacy versions of Talos use GRUB for BIOS/UEFI
141-
o.ImageOptions.Bootloader = DiskImageBootloaderGrub
142-
default:
143-
// Default to dual-boot.
144-
o.ImageOptions.Bootloader = DiskImageBootloaderDualBoot
145-
}
134+
o.ImageOptions.Bootloader = o.selectBootloader(o.ImageOptions.Bootloader, arch, version, secureboot)
146135

147136
ps := quirks.New(version).PartitionSizes()
148137

149138
// bump default image size for expanded boot
150139
o.ImageOptions.DiskSize += int64(ps.GrubBootSize()) - 1000*1024*1024 // 1000 MiB
151140

152-
if o.ImageOptions.Bootloader == DiskImageBootloaderDualBoot {
141+
if o.ImageOptions.Bootloader == BootLoaderKindDualBoot {
153142
// add extra space for BIOS and BOOT partitions
154143
o.ImageOptions.DiskSize += int64(ps.GrubBIOSSize()) + int64(ps.GrubBootSize())
155144
}
145+
146+
case OutKindISO:
147+
if !quirks.New(version).ISOSupportsSettingBootloader() {
148+
return
149+
}
150+
151+
if o.ISOOptions == nil {
152+
o.ISOOptions = &ISOOptions{}
153+
}
154+
155+
o.ISOOptions.Bootloader = o.selectBootloader(o.ISOOptions.Bootloader, arch, version, secureboot)
156+
}
157+
}
158+
159+
func (o *Output) selectBootloader(current BootloaderKind, arch, version string, secureboot bool) BootloaderKind {
160+
useSDBoot := quirks.New(version).UseSDBootForUEFI()
161+
162+
switch {
163+
case secureboot:
164+
// secureboot is always using sd-boot
165+
return BootLoaderKindSDBoot
166+
case arch == "arm64" && useSDBoot:
167+
// arm64 always uses sd-boot for Talos >= 1.10
168+
return BootLoaderKindSDBoot
169+
case !useSDBoot:
170+
// legacy versions of Talos use GRUB for BIOS/UEFI
171+
return BootLoaderKindGrub
172+
default:
173+
// Default to dual-boot if not overridden.
174+
if current == BootLoaderKindNone {
175+
return BootLoaderKindDualBoot
176+
}
177+
178+
return current
156179
}
157180
}

0 commit comments

Comments
 (0)