mirror of
https://github.com/siderolabs/talos.git
synced 2026-05-05 12:26:21 +02:00
feat: support bootloader option for ISO
Support selecting bootloader option for ISO. Signed-off-by: Noel Georgi <git@frezbo.dev>
This commit is contained in:
parent
d110727263
commit
61e95cb4b7
@ -83,14 +83,14 @@ func NewAuto() Bootloader {
|
||||
// New returns a new bootloader based on the secureboot flag and architecture.
|
||||
func New(bootloader, talosVersion, arch string) (Bootloader, error) {
|
||||
switch bootloader {
|
||||
case profile.DiskImageBootloaderGrub.String():
|
||||
case profile.BootLoaderKindGrub.String():
|
||||
g := grub.NewConfig()
|
||||
g.AddResetOption = quirks.New(talosVersion).SupportsResetGRUBOption()
|
||||
|
||||
return g, nil
|
||||
case profile.DiskImageBootloaderSDBoot.String():
|
||||
case profile.BootLoaderKindSDBoot.String():
|
||||
return sdboot.New(), nil
|
||||
case profile.DiskImageBootloaderDualBoot.String():
|
||||
case profile.BootLoaderKindDualBoot.String():
|
||||
return dual.New(), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported bootloader %q", bootloader)
|
||||
|
||||
@ -104,7 +104,7 @@ func (*Sequencer) Initialize(r runtime.Runtime) []runtime.Phase {
|
||||
return false
|
||||
}
|
||||
|
||||
return r.State().Machine().Installed() && val == profile.DiskImageBootloaderDualBoot.String()
|
||||
return r.State().Machine().Installed() && val == profile.BootLoaderKindDualBoot.String()
|
||||
},
|
||||
"cleanupBootloader",
|
||||
CleanupBootloader,
|
||||
|
||||
@ -20,29 +20,6 @@ import (
|
||||
"github.com/siderolabs/talos/pkg/makefs"
|
||||
)
|
||||
|
||||
// UEFIOptions describe the input for the CreateUEFI function.
|
||||
type UEFIOptions struct {
|
||||
UKIPath string
|
||||
SDBootPath string
|
||||
|
||||
// A value in loader.conf secure-boot-enroll: off, manual, if-safe, force.
|
||||
SDBootSecureBootEnrollKeys string
|
||||
|
||||
// UKISigningCertDer is the DER encoded UKI signing certificate.
|
||||
UKISigningCertDerPath string
|
||||
|
||||
// optional, for auto-enrolling secureboot keys
|
||||
PlatformKeyPath string
|
||||
KeyExchangeKeyPath string
|
||||
SignatureKeyPath string
|
||||
|
||||
Arch string
|
||||
Version string
|
||||
|
||||
ScratchDir string
|
||||
OutPath string
|
||||
}
|
||||
|
||||
const (
|
||||
// mib is the size of a megabyte.
|
||||
mib = 1024 * 1024
|
||||
|
||||
@ -188,6 +188,43 @@ func (i *Imager) outISO(ctx context.Context, path string, report *reporter.Repor
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case quirks.New(i.prof.Version).ISOSupportsSettingBootloader():
|
||||
options := iso.Options{
|
||||
KernelPath: i.prof.Input.Kernel.Path,
|
||||
InitramfsPath: i.initramfsPath,
|
||||
Cmdline: i.cmdline,
|
||||
|
||||
UKIPath: i.ukiPath,
|
||||
SDBootPath: i.sdBootPath,
|
||||
|
||||
SDBootSecureBootEnrollKeys: "off",
|
||||
|
||||
Arch: i.prof.Arch,
|
||||
Version: i.prof.Version,
|
||||
|
||||
ScratchDir: scratchSpace,
|
||||
OutPath: path,
|
||||
}
|
||||
|
||||
switch i.prof.Output.ISOOptions.Bootloader {
|
||||
case profile.BootLoaderKindDualBoot:
|
||||
generator, err = options.CreateHybrid(printf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case profile.BootLoaderKindSDBoot:
|
||||
generator, err = options.CreateUEFI(printf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case profile.BootLoaderKindGrub:
|
||||
generator, err = options.CreateGRUB(printf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case profile.BootLoaderKindNone:
|
||||
return fmt.Errorf("cannot create ISO with no bootloader")
|
||||
}
|
||||
case quirks.New(i.prof.Version).UseSDBootForUEFI():
|
||||
options := iso.Options{
|
||||
KernelPath: i.prof.Input.Kernel.Path,
|
||||
@ -324,10 +361,10 @@ func (i *Imager) buildImage(ctx context.Context, path string, printf func(string
|
||||
|
||||
if i.prof.Arch == "amd64" && !i.prof.SecureBootEnabled() && quirks.New(i.prof.Version).UseSDBootForUEFI() {
|
||||
// allow overriding the bootloader if provided
|
||||
if i.prof.Output.ImageOptions.Bootloader == profile.DiskImageBootloaderDualBoot {
|
||||
if i.prof.Output.ImageOptions.Bootloader == profile.BootLoaderKindDualBoot {
|
||||
metaContents = append(metaContents, meta.Value{
|
||||
Key: meta.DiskImageBootloader,
|
||||
Value: profile.DiskImageBootloaderDualBoot.String(),
|
||||
Value: profile.BootLoaderKindDualBoot.String(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ type ImageOptions struct {
|
||||
DiskFormatOptions string `yaml:"diskFormatOptions,omitempty"`
|
||||
// Bootloader is the bootloader to use for the disk image.
|
||||
// If not set, it defaults to dual-boot.
|
||||
Bootloader DiskImageBootloader `yaml:"bootloader"`
|
||||
Bootloader BootloaderKind `yaml:"bootloader,omitempty"`
|
||||
}
|
||||
|
||||
// ISOOptions describes options for the 'iso' output.
|
||||
@ -52,6 +52,9 @@ type ISOOptions struct {
|
||||
//
|
||||
// If not set, it defaults to if-safe.
|
||||
SDBootEnrollKeys SDBootEnrollKeys `yaml:"sdBootEnrollKeys"`
|
||||
// Bootloader is the bootloader to use for the iso image.
|
||||
// If not set, it defaults to dual-boot.
|
||||
Bootloader BootloaderKind `yaml:"bootloader,omitempty"`
|
||||
}
|
||||
|
||||
// OutputKind is output specification.
|
||||
@ -105,53 +108,73 @@ const (
|
||||
SDBootEnrollKeysOff // off
|
||||
)
|
||||
|
||||
// DiskImageBootloader is a bootloader for the disk image.
|
||||
type DiskImageBootloader int
|
||||
// BootloaderKind is a bootloader for the disk image.
|
||||
type BootloaderKind int
|
||||
|
||||
const (
|
||||
// DiskImageBootloaderDualBoot is the dual-boot bootloader
|
||||
// BootLoaderKindNone is the zero value.
|
||||
BootLoaderKindNone BootloaderKind = iota // none
|
||||
// BootLoaderKindDualBoot is the dual-boot bootloader.
|
||||
// using sd-boot for UEFI and GRUB for BIOS.
|
||||
DiskImageBootloaderDualBoot DiskImageBootloader = iota // dual-boot
|
||||
// DiskImageBootloaderSDBoot is the sd-boot bootloader.
|
||||
DiskImageBootloaderSDBoot // sd-boot
|
||||
// DiskImageBootloaderGrub is the GRUB bootloader.
|
||||
DiskImageBootloaderGrub // grub
|
||||
BootLoaderKindDualBoot // dual-boot
|
||||
// BootLoaderKindSDBoot is the sd-boot bootloader.
|
||||
BootLoaderKindSDBoot // sd-boot
|
||||
// BootLoaderKindGrub is the GRUB bootloader.
|
||||
BootLoaderKindGrub // grub
|
||||
)
|
||||
|
||||
// FillDefaults fills default values for the output.
|
||||
func (o *Output) FillDefaults(arch, version string, secureboot bool) {
|
||||
if o.Kind == OutKindImage {
|
||||
switch o.Kind { //nolint:exhaustive
|
||||
case OutKindImage:
|
||||
if o.ImageOptions == nil {
|
||||
o.ImageOptions = &ImageOptions{}
|
||||
}
|
||||
|
||||
useSDBoot := quirks.New(version).UseSDBootForUEFI()
|
||||
|
||||
switch {
|
||||
case o.ImageOptions.Bootloader != DiskImageBootloaderDualBoot:
|
||||
// allow user to override bootloader
|
||||
case secureboot:
|
||||
// secureboot is always using sd-boot
|
||||
o.ImageOptions.Bootloader = DiskImageBootloaderSDBoot
|
||||
case arch == "arm64" && useSDBoot:
|
||||
// arm64 always uses sd-boot for Talos >= 1.10
|
||||
o.ImageOptions.Bootloader = DiskImageBootloaderSDBoot
|
||||
case !useSDBoot:
|
||||
// legacy versions of Talos use GRUB for BIOS/UEFI
|
||||
o.ImageOptions.Bootloader = DiskImageBootloaderGrub
|
||||
default:
|
||||
// Default to dual-boot.
|
||||
o.ImageOptions.Bootloader = DiskImageBootloaderDualBoot
|
||||
}
|
||||
o.ImageOptions.Bootloader = o.selectBootloader(o.ImageOptions.Bootloader, arch, version, secureboot)
|
||||
|
||||
ps := quirks.New(version).PartitionSizes()
|
||||
|
||||
// bump default image size for expanded boot
|
||||
o.ImageOptions.DiskSize += int64(ps.GrubBootSize()) - 1000*1024*1024 // 1000 MiB
|
||||
|
||||
if o.ImageOptions.Bootloader == DiskImageBootloaderDualBoot {
|
||||
if o.ImageOptions.Bootloader == BootLoaderKindDualBoot {
|
||||
// add extra space for BIOS and BOOT partitions
|
||||
o.ImageOptions.DiskSize += int64(ps.GrubBIOSSize()) + int64(ps.GrubBootSize())
|
||||
}
|
||||
|
||||
case OutKindISO:
|
||||
if !quirks.New(version).ISOSupportsSettingBootloader() {
|
||||
return
|
||||
}
|
||||
|
||||
if o.ISOOptions == nil {
|
||||
o.ISOOptions = &ISOOptions{}
|
||||
}
|
||||
|
||||
o.ISOOptions.Bootloader = o.selectBootloader(o.ISOOptions.Bootloader, arch, version, secureboot)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Output) selectBootloader(current BootloaderKind, arch, version string, secureboot bool) BootloaderKind {
|
||||
useSDBoot := quirks.New(version).UseSDBootForUEFI()
|
||||
|
||||
switch {
|
||||
case secureboot:
|
||||
// secureboot is always using sd-boot
|
||||
return BootLoaderKindSDBoot
|
||||
case arch == "arm64" && useSDBoot:
|
||||
// arm64 always uses sd-boot for Talos >= 1.10
|
||||
return BootLoaderKindSDBoot
|
||||
case !useSDBoot:
|
||||
// legacy versions of Talos use GRUB for BIOS/UEFI
|
||||
return BootLoaderKindGrub
|
||||
default:
|
||||
// Default to dual-boot if not overridden.
|
||||
if current == BootLoaderKindNone {
|
||||
return BootLoaderKindDualBoot
|
||||
}
|
||||
|
||||
return current
|
||||
}
|
||||
}
|
||||
|
||||
172
pkg/imager/profile/output_test.go
Normal file
172
pkg/imager/profile/output_test.go
Normal file
@ -0,0 +1,172 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package profile_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/siderolabs/talos/pkg/imager/profile"
|
||||
"github.com/siderolabs/talos/pkg/machinery/imager/quirks"
|
||||
)
|
||||
|
||||
func createOutputWithDefaults(kind profile.OutputKind, arch, version string, secureBoot bool) profile.Output {
|
||||
out := profile.Output{
|
||||
Kind: kind,
|
||||
}
|
||||
|
||||
out.FillDefaults(arch, version, secureBoot)
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func createOutputWithOverride(kind profile.OutputKind, bootloader profile.BootloaderKind, arch, version string, secureBoot bool) profile.Output {
|
||||
out := profile.Output{
|
||||
Kind: kind,
|
||||
}
|
||||
|
||||
switch kind { //nolint:exhaustive
|
||||
case profile.OutKindImage:
|
||||
out.ImageOptions = &profile.ImageOptions{
|
||||
Bootloader: bootloader,
|
||||
}
|
||||
case profile.OutKindISO:
|
||||
if quirks.New(version).ISOSupportsSettingBootloader() {
|
||||
out.ISOOptions = &profile.ISOOptions{
|
||||
Bootloader: bootloader,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out.FillDefaults(arch, version, secureBoot)
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func TestBootloaderSetting(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
arch string
|
||||
version string
|
||||
secureBoot bool
|
||||
wantImage profile.BootloaderKind
|
||||
}{
|
||||
// Talos < 1.10: GRUB for both amd64/arm64, ISO options not supported
|
||||
{"amd64", "1.9.0", false, profile.BootLoaderKindGrub},
|
||||
{"amd64", "1.9.0", true, profile.BootLoaderKindSDBoot},
|
||||
{"arm64", "1.9.0", false, profile.BootLoaderKindGrub},
|
||||
{"arm64", "1.9.0", true, profile.BootLoaderKindSDBoot},
|
||||
|
||||
// Talos 1.10-1.11: amd64=dual-boot, arm64=sd-boot, ISO options not supported
|
||||
{"amd64", "1.10.0", false, profile.BootLoaderKindDualBoot},
|
||||
{"amd64", "1.10.0", true, profile.BootLoaderKindSDBoot},
|
||||
{"arm64", "1.10.0", false, profile.BootLoaderKindSDBoot},
|
||||
{"arm64", "1.10.0", true, profile.BootLoaderKindSDBoot},
|
||||
{"amd64", "1.11.0", false, profile.BootLoaderKindDualBoot},
|
||||
{"amd64", "1.11.0", true, profile.BootLoaderKindSDBoot},
|
||||
{"arm64", "1.11.0", false, profile.BootLoaderKindSDBoot},
|
||||
{"arm64", "1.11.0", true, profile.BootLoaderKindSDBoot},
|
||||
|
||||
// Talos >= 1.12: amd64=dual-boot, arm64=sd-boot, ISO options supported
|
||||
{"amd64", "1.12.0", false, profile.BootLoaderKindDualBoot},
|
||||
{"amd64", "1.12.0", true, profile.BootLoaderKindSDBoot},
|
||||
{"arm64", "1.12.0", false, profile.BootLoaderKindSDBoot},
|
||||
{"arm64", "1.12.0", true, profile.BootLoaderKindSDBoot},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
name := tt.arch + "-" + tt.version
|
||||
if tt.secureBoot {
|
||||
name += "-secureboot"
|
||||
}
|
||||
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Test Image output
|
||||
img := createOutputWithDefaults(profile.OutKindImage, tt.arch, tt.version, tt.secureBoot)
|
||||
require.NotNil(t, img.ImageOptions)
|
||||
require.Equal(t, tt.wantImage, img.ImageOptions.Bootloader)
|
||||
|
||||
// Test ISO output
|
||||
iso := createOutputWithDefaults(profile.OutKindISO, tt.arch, tt.version, tt.secureBoot)
|
||||
if quirks.New(tt.version).ISOSupportsSettingBootloader() {
|
||||
require.NotNil(t, iso.ISOOptions)
|
||||
require.Equal(t, tt.wantImage, iso.ISOOptions.Bootloader)
|
||||
} else {
|
||||
require.Nil(t, iso.ISOOptions)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBootloaderOverride(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
arch string
|
||||
version string
|
||||
secureBoot bool
|
||||
override profile.BootloaderKind
|
||||
wantImage profile.BootloaderKind
|
||||
}{
|
||||
// Talos < 1.10: GRUB is forced, overrides are ignored
|
||||
{"amd64", "1.9.0", false, profile.BootLoaderKindGrub, profile.BootLoaderKindGrub},
|
||||
{"amd64", "1.9.0", false, profile.BootLoaderKindSDBoot, profile.BootLoaderKindGrub}, // forced to GRUB
|
||||
{"amd64", "1.9.0", false, profile.BootLoaderKindDualBoot, profile.BootLoaderKindGrub}, // forced to GRUB
|
||||
{"amd64", "1.9.0", true, profile.BootLoaderKindGrub, profile.BootLoaderKindSDBoot}, // secureboot forces sd-boot
|
||||
{"arm64", "1.9.0", false, profile.BootLoaderKindGrub, profile.BootLoaderKindGrub},
|
||||
{"arm64", "1.9.0", false, profile.BootLoaderKindSDBoot, profile.BootLoaderKindGrub}, // forced to GRUB
|
||||
{"arm64", "1.9.0", true, profile.BootLoaderKindGrub, profile.BootLoaderKindSDBoot}, // secureboot forces sd-boot
|
||||
|
||||
// Talos 1.10-1.11: amd64 respects override, arm64 forced to sd-boot
|
||||
{"amd64", "1.10.0", false, profile.BootLoaderKindGrub, profile.BootLoaderKindGrub},
|
||||
{"amd64", "1.10.0", false, profile.BootLoaderKindSDBoot, profile.BootLoaderKindSDBoot},
|
||||
{"amd64", "1.10.0", false, profile.BootLoaderKindDualBoot, profile.BootLoaderKindDualBoot},
|
||||
{"amd64", "1.10.0", true, profile.BootLoaderKindGrub, profile.BootLoaderKindSDBoot}, // secureboot forces sd-boot
|
||||
{"arm64", "1.10.0", false, profile.BootLoaderKindGrub, profile.BootLoaderKindSDBoot}, // arm64 >= 1.10 forces sd-boot
|
||||
{"arm64", "1.10.0", true, profile.BootLoaderKindGrub, profile.BootLoaderKindSDBoot}, // secureboot forces sd-boot
|
||||
{"amd64", "1.11.0", false, profile.BootLoaderKindGrub, profile.BootLoaderKindGrub},
|
||||
{"amd64", "1.11.0", false, profile.BootLoaderKindDualBoot, profile.BootLoaderKindDualBoot},
|
||||
{"amd64", "1.11.0", true, profile.BootLoaderKindGrub, profile.BootLoaderKindSDBoot}, // secureboot forces sd-boot
|
||||
{"arm64", "1.11.0", false, profile.BootLoaderKindGrub, profile.BootLoaderKindSDBoot}, // arm64 >= 1.10 forces sd-boot
|
||||
{"arm64", "1.11.0", true, profile.BootLoaderKindGrub, profile.BootLoaderKindSDBoot}, // secureboot forces sd-boot
|
||||
|
||||
// Talos >= 1.12: amd64 respects override, arm64 forced to sd-boot
|
||||
{"amd64", "1.12.0", false, profile.BootLoaderKindGrub, profile.BootLoaderKindGrub},
|
||||
{"amd64", "1.12.0", false, profile.BootLoaderKindSDBoot, profile.BootLoaderKindSDBoot},
|
||||
{"amd64", "1.12.0", false, profile.BootLoaderKindDualBoot, profile.BootLoaderKindDualBoot},
|
||||
{"amd64", "1.12.0", true, profile.BootLoaderKindGrub, profile.BootLoaderKindSDBoot}, // secureboot forces sd-boot
|
||||
{"arm64", "1.12.0", false, profile.BootLoaderKindGrub, profile.BootLoaderKindSDBoot}, // arm64 >= 1.10 forces sd-boot
|
||||
{"arm64", "1.12.0", true, profile.BootLoaderKindGrub, profile.BootLoaderKindSDBoot}, // secureboot forces sd-boot
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
name := tt.arch + "-" + tt.version + "-override-" + tt.override.String()
|
||||
if tt.secureBoot {
|
||||
name += "-secureboot"
|
||||
}
|
||||
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Test Image output with override
|
||||
img := createOutputWithOverride(profile.OutKindImage, tt.override, tt.arch, tt.version, tt.secureBoot)
|
||||
require.NotNil(t, img.ImageOptions)
|
||||
require.Equal(t, tt.wantImage, img.ImageOptions.Bootloader)
|
||||
|
||||
// Test ISO output with override
|
||||
iso := createOutputWithOverride(profile.OutKindISO, tt.override, tt.arch, tt.version, tt.secureBoot)
|
||||
if quirks.New(tt.version).ISOSupportsSettingBootloader() {
|
||||
require.NotNil(t, iso.ISOOptions)
|
||||
require.Equal(t, tt.wantImage, iso.ISOOptions.Bootloader)
|
||||
} else {
|
||||
require.Nil(t, iso.ISOOptions)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
// Code generated by "enumer -type OutputKind,OutFormat,DiskFormat,SDBootEnrollKeys,DiskImageBootloader -linecomment -text"; DO NOT EDIT.
|
||||
// Code generated by "enumer -type OutputKind,OutFormat,DiskFormat,SDBootEnrollKeys,BootloaderKind -linecomment -text"; DO NOT EDIT.
|
||||
|
||||
package profile
|
||||
|
||||
@ -395,73 +395,77 @@ func (i *SDBootEnrollKeys) UnmarshalText(text []byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
const _DiskImageBootloaderName = "dual-bootsd-bootgrub"
|
||||
const _BootloaderKindName = "nonedual-bootsd-bootgrub"
|
||||
|
||||
var _DiskImageBootloaderIndex = [...]uint8{0, 9, 16, 20}
|
||||
var _BootloaderKindIndex = [...]uint8{0, 4, 13, 20, 24}
|
||||
|
||||
const _DiskImageBootloaderLowerName = "dual-bootsd-bootgrub"
|
||||
const _BootloaderKindLowerName = "nonedual-bootsd-bootgrub"
|
||||
|
||||
func (i DiskImageBootloader) String() string {
|
||||
if i < 0 || i >= DiskImageBootloader(len(_DiskImageBootloaderIndex)-1) {
|
||||
return fmt.Sprintf("DiskImageBootloader(%d)", i)
|
||||
func (i BootloaderKind) String() string {
|
||||
if i < 0 || i >= BootloaderKind(len(_BootloaderKindIndex)-1) {
|
||||
return fmt.Sprintf("BootloaderKind(%d)", i)
|
||||
}
|
||||
return _DiskImageBootloaderName[_DiskImageBootloaderIndex[i]:_DiskImageBootloaderIndex[i+1]]
|
||||
return _BootloaderKindName[_BootloaderKindIndex[i]:_BootloaderKindIndex[i+1]]
|
||||
}
|
||||
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
func _DiskImageBootloaderNoOp() {
|
||||
func _BootloaderKindNoOp() {
|
||||
var x [1]struct{}
|
||||
_ = x[DiskImageBootloaderDualBoot-(0)]
|
||||
_ = x[DiskImageBootloaderSDBoot-(1)]
|
||||
_ = x[DiskImageBootloaderGrub-(2)]
|
||||
_ = x[BootLoaderKindNone-(0)]
|
||||
_ = x[BootLoaderKindDualBoot-(1)]
|
||||
_ = x[BootLoaderKindSDBoot-(2)]
|
||||
_ = x[BootLoaderKindGrub-(3)]
|
||||
}
|
||||
|
||||
var _DiskImageBootloaderValues = []DiskImageBootloader{DiskImageBootloaderDualBoot, DiskImageBootloaderSDBoot, DiskImageBootloaderGrub}
|
||||
var _BootloaderKindValues = []BootloaderKind{BootLoaderKindNone, BootLoaderKindDualBoot, BootLoaderKindSDBoot, BootLoaderKindGrub}
|
||||
|
||||
var _DiskImageBootloaderNameToValueMap = map[string]DiskImageBootloader{
|
||||
_DiskImageBootloaderName[0:9]: DiskImageBootloaderDualBoot,
|
||||
_DiskImageBootloaderLowerName[0:9]: DiskImageBootloaderDualBoot,
|
||||
_DiskImageBootloaderName[9:16]: DiskImageBootloaderSDBoot,
|
||||
_DiskImageBootloaderLowerName[9:16]: DiskImageBootloaderSDBoot,
|
||||
_DiskImageBootloaderName[16:20]: DiskImageBootloaderGrub,
|
||||
_DiskImageBootloaderLowerName[16:20]: DiskImageBootloaderGrub,
|
||||
var _BootloaderKindNameToValueMap = map[string]BootloaderKind{
|
||||
_BootloaderKindName[0:4]: BootLoaderKindNone,
|
||||
_BootloaderKindLowerName[0:4]: BootLoaderKindNone,
|
||||
_BootloaderKindName[4:13]: BootLoaderKindDualBoot,
|
||||
_BootloaderKindLowerName[4:13]: BootLoaderKindDualBoot,
|
||||
_BootloaderKindName[13:20]: BootLoaderKindSDBoot,
|
||||
_BootloaderKindLowerName[13:20]: BootLoaderKindSDBoot,
|
||||
_BootloaderKindName[20:24]: BootLoaderKindGrub,
|
||||
_BootloaderKindLowerName[20:24]: BootLoaderKindGrub,
|
||||
}
|
||||
|
||||
var _DiskImageBootloaderNames = []string{
|
||||
_DiskImageBootloaderName[0:9],
|
||||
_DiskImageBootloaderName[9:16],
|
||||
_DiskImageBootloaderName[16:20],
|
||||
var _BootloaderKindNames = []string{
|
||||
_BootloaderKindName[0:4],
|
||||
_BootloaderKindName[4:13],
|
||||
_BootloaderKindName[13:20],
|
||||
_BootloaderKindName[20:24],
|
||||
}
|
||||
|
||||
// DiskImageBootloaderString retrieves an enum value from the enum constants string name.
|
||||
// BootloaderKindString retrieves an enum value from the enum constants string name.
|
||||
// Throws an error if the param is not part of the enum.
|
||||
func DiskImageBootloaderString(s string) (DiskImageBootloader, error) {
|
||||
if val, ok := _DiskImageBootloaderNameToValueMap[s]; ok {
|
||||
func BootloaderKindString(s string) (BootloaderKind, error) {
|
||||
if val, ok := _BootloaderKindNameToValueMap[s]; ok {
|
||||
return val, nil
|
||||
}
|
||||
|
||||
if val, ok := _DiskImageBootloaderNameToValueMap[strings.ToLower(s)]; ok {
|
||||
if val, ok := _BootloaderKindNameToValueMap[strings.ToLower(s)]; ok {
|
||||
return val, nil
|
||||
}
|
||||
return 0, fmt.Errorf("%s does not belong to DiskImageBootloader values", s)
|
||||
return 0, fmt.Errorf("%s does not belong to BootloaderKind values", s)
|
||||
}
|
||||
|
||||
// DiskImageBootloaderValues returns all values of the enum
|
||||
func DiskImageBootloaderValues() []DiskImageBootloader {
|
||||
return _DiskImageBootloaderValues
|
||||
// BootloaderKindValues returns all values of the enum
|
||||
func BootloaderKindValues() []BootloaderKind {
|
||||
return _BootloaderKindValues
|
||||
}
|
||||
|
||||
// DiskImageBootloaderStrings returns a slice of all String values of the enum
|
||||
func DiskImageBootloaderStrings() []string {
|
||||
strs := make([]string, len(_DiskImageBootloaderNames))
|
||||
copy(strs, _DiskImageBootloaderNames)
|
||||
// BootloaderKindStrings returns a slice of all String values of the enum
|
||||
func BootloaderKindStrings() []string {
|
||||
strs := make([]string, len(_BootloaderKindNames))
|
||||
copy(strs, _BootloaderKindNames)
|
||||
return strs
|
||||
}
|
||||
|
||||
// IsADiskImageBootloader returns "true" if the value is listed in the enum definition. "false" otherwise
|
||||
func (i DiskImageBootloader) IsADiskImageBootloader() bool {
|
||||
for _, v := range _DiskImageBootloaderValues {
|
||||
// IsABootloaderKind returns "true" if the value is listed in the enum definition. "false" otherwise
|
||||
func (i BootloaderKind) IsABootloaderKind() bool {
|
||||
for _, v := range _BootloaderKindValues {
|
||||
if i == v {
|
||||
return true
|
||||
}
|
||||
@ -469,14 +473,14 @@ func (i DiskImageBootloader) IsADiskImageBootloader() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// MarshalText implements the encoding.TextMarshaler interface for DiskImageBootloader
|
||||
func (i DiskImageBootloader) MarshalText() ([]byte, error) {
|
||||
// MarshalText implements the encoding.TextMarshaler interface for BootloaderKind
|
||||
func (i BootloaderKind) MarshalText() ([]byte, error) {
|
||||
return []byte(i.String()), nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements the encoding.TextUnmarshaler interface for DiskImageBootloader
|
||||
func (i *DiskImageBootloader) UnmarshalText(text []byte) error {
|
||||
// UnmarshalText implements the encoding.TextUnmarshaler interface for BootloaderKind
|
||||
func (i *BootloaderKind) UnmarshalText(text []byte) error {
|
||||
var err error
|
||||
*i, err = DiskImageBootloaderString(string(text))
|
||||
*i, err = BootloaderKindString(string(text))
|
||||
return err
|
||||
}
|
||||
|
||||
@ -13,12 +13,13 @@ import (
|
||||
"github.com/siderolabs/go-pointer"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/siderolabs/talos/pkg/machinery/imager/quirks"
|
||||
"github.com/siderolabs/talos/pkg/machinery/overlay"
|
||||
)
|
||||
|
||||
//go:generate go tool github.com/siderolabs/deep-copy -type Profile -type SecureBootAssets -header-file ../../../hack/boilerplate.txt -o deep_copy.generated.go .
|
||||
|
||||
//go:generate go tool github.com/dmarkham/enumer -type OutputKind,OutFormat,DiskFormat,SDBootEnrollKeys,DiskImageBootloader -linecomment -text
|
||||
//go:generate go tool github.com/dmarkham/enumer -type OutputKind,OutFormat,DiskFormat,SDBootEnrollKeys,BootloaderKind -linecomment -text
|
||||
|
||||
// Profile describes image generation result.
|
||||
type Profile struct {
|
||||
@ -82,11 +83,20 @@ func (p *Profile) Validate() error {
|
||||
}
|
||||
}
|
||||
|
||||
if p.SecureBootEnabled() && !quirks.New(p.Version).SupportsUKI() {
|
||||
return fmt.Errorf("secureboot is not supported for Talos version %q", p.Version)
|
||||
}
|
||||
|
||||
switch p.Output.Kind {
|
||||
case OutKindUnknown:
|
||||
return errors.New("unknown output kind")
|
||||
case OutKindISO:
|
||||
// ISO supports all kinds of customization
|
||||
if quirks.New(p.Version).ISOSupportsSettingBootloader() {
|
||||
if p.Output.ISOOptions != nil && p.Output.ISOOptions.Bootloader == BootLoaderKindNone {
|
||||
return errors.New("bootloader cannot be 'none' for ISO output")
|
||||
}
|
||||
}
|
||||
case OutKindCmdline:
|
||||
// cmdline supports all kinds of customization
|
||||
case OutKindImage:
|
||||
@ -98,6 +108,10 @@ func (p *Profile) Validate() error {
|
||||
if p.Output.ImageOptions.DiskSize == 0 {
|
||||
return errors.New("disk size is required for image output")
|
||||
}
|
||||
|
||||
if p.Output.ImageOptions.Bootloader == BootLoaderKindNone {
|
||||
return errors.New("bootloader cannot be 'none' for disk image output")
|
||||
}
|
||||
case OutKindInstaller:
|
||||
if len(p.Customization.MetaContents) > 0 {
|
||||
return fmt.Errorf("customization of meta partition is not supported for %s output", p.Output.Kind)
|
||||
|
||||
@ -15,4 +15,7 @@ input:
|
||||
imageRef: ghcr.io/siderolabs/installer-base:1.12.0
|
||||
output:
|
||||
kind: iso
|
||||
isoOptions:
|
||||
sdBootEnrollKeys: if-safe
|
||||
bootloader: dual-boot
|
||||
outFormat: raw
|
||||
|
||||
@ -15,4 +15,7 @@ input:
|
||||
imageRef: ghcr.io/siderolabs/installer-base:1.12.0
|
||||
output:
|
||||
kind: iso
|
||||
isoOptions:
|
||||
sdBootEnrollKeys: if-safe
|
||||
bootloader: sd-boot
|
||||
outFormat: raw
|
||||
|
||||
@ -23,4 +23,5 @@ output:
|
||||
kind: iso
|
||||
isoOptions:
|
||||
sdBootEnrollKeys: if-safe
|
||||
bootloader: sd-boot
|
||||
outFormat: raw
|
||||
|
||||
@ -23,4 +23,5 @@ output:
|
||||
kind: iso
|
||||
isoOptions:
|
||||
sdBootEnrollKeys: if-safe
|
||||
bootloader: sd-boot
|
||||
outFormat: raw
|
||||
|
||||
@ -298,3 +298,15 @@ func (q Quirks) SupportsDisablingModuleSignatureVerification() bool {
|
||||
|
||||
return q.v.GTE(minTalosVersionDisableModSigVerify)
|
||||
}
|
||||
|
||||
var minTalosVersionISOSupportsSettingBootloader = semver.MustParse("1.12.0")
|
||||
|
||||
// ISOSupportsSettingBootloader returns true if the Talos version supports setting bootloader for ISO output.
|
||||
func (q Quirks) ISOSupportsSettingBootloader() bool {
|
||||
// if the version doesn't parse, we assume it's latest Talos
|
||||
if q.v == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
return q.v.GTE(minTalosVersionISOSupportsSettingBootloader)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user