fix: generate images for SBCs using imager

See https://github.com/siderolabs/image-factory/issues/43

Two fixes:

* pass path to the dtb, uboot and rpi-firmware explicitly
* include dtb, uboot and rpi-firmware into arm64 installer image when
  generated via imager (regular arm64 installer was fine)

(The generation of SBC images was not broken for Talos itself, but only
when used via Image Factory).

Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
This commit is contained in:
Andrey Smirnov 2023-10-27 21:55:38 +04:00
parent 5dff164f1c
commit cbe6e7622d
No known key found for this signature in database
GPG Key ID: FE042E3D4085A811
17 changed files with 213 additions and 95 deletions

View File

@ -285,7 +285,13 @@ func (i *Installer) Install(ctx context.Context, mode Mode) (err error) {
i.options.Printf("installing U-Boot for %q", b.Name())
if err = b.Install(i.options.Disk); err != nil {
if err = b.Install(runtime.BoardInstallOptions{
InstallDisk: i.options.Disk,
UBootPath: i.options.BootAssets.UBootPath,
DTBPath: i.options.BootAssets.DTBPath,
RPiFirmwarePath: i.options.BootAssets.RPiFirmwarePath,
Printf: i.options.Printf,
}); err != nil {
return err
}
}

View File

@ -12,10 +12,19 @@ type PartitionOptions struct {
PartitionsOffset uint64
}
// BoardInstallOptions are the board specific options for installation of various boot assets.
type BoardInstallOptions struct {
InstallDisk string
DTBPath string
UBootPath string
RPiFirmwarePath string
Printf func(string, ...any)
}
// Board defines the requirements for a SBC.
type Board interface {
Name() string
Install(string) error
Install(options BoardInstallOptions) error
KernelArgs() procfs.Parameters
PartitionOptions() *PartitionOptions
}

View File

@ -6,8 +6,6 @@
package bananapim64
import (
"fmt"
"log"
"os"
"path/filepath"
@ -20,9 +18,9 @@ import (
)
var (
bin = fmt.Sprintf("/usr/install/arm64/u-boot/%s/u-boot-sunxi-with-spl.bin", constants.BoardBananaPiM64)
bin = constants.BoardBananaPiM64 + "/u-boot-sunxi-with-spl.bin"
off int64 = 1024 * 8
dtb = "/dtb/allwinner/sun50i-a64-bananapi-m64.dtb"
dtb = "allwinner/sun50i-a64-bananapi-m64.dtb"
)
// BananaPiM64 represents the Banana Pi M64.
@ -39,10 +37,10 @@ func (b *BananaPiM64) Name() string {
}
// Install implements the runtime.Board.
func (b *BananaPiM64) Install(disk string) (err error) {
func (b *BananaPiM64) Install(options runtime.BoardInstallOptions) (err error) {
var f *os.File
if f, err = os.OpenFile(disk, os.O_RDWR|unix.O_CLOEXEC, 0o666); err != nil {
if f, err = os.OpenFile(options.InstallDisk, os.O_RDWR|unix.O_CLOEXEC, 0o666); err != nil {
return err
}
//nolint:errcheck
@ -50,12 +48,12 @@ func (b *BananaPiM64) Install(disk string) (err error) {
var uboot []byte
uboot, err = os.ReadFile(bin)
uboot, err = os.ReadFile(filepath.Join(options.UBootPath, bin))
if err != nil {
return err
}
log.Printf("writing %s at offset %d", bin, off)
options.Printf("writing %s at offset %d", bin, off)
var n int
@ -64,7 +62,7 @@ func (b *BananaPiM64) Install(disk string) (err error) {
return err
}
log.Printf("wrote %d bytes", n)
options.Printf("wrote %d bytes", n)
// NB: In the case that the block device is a loopback device, we sync here
// to esure that the file is written before the loopback device is
@ -74,8 +72,8 @@ func (b *BananaPiM64) Install(disk string) (err error) {
return err
}
src := "/usr/install/arm64" + dtb
dst := "/boot/EFI" + dtb
src := filepath.Join(options.DTBPath, dtb)
dst := filepath.Join("/boot/EFI/dtb", dtb)
err = os.MkdirAll(filepath.Dir(dst), 0o600)
if err != nil {

View File

@ -21,7 +21,7 @@ import (
// - https://github.com/u-boot/u-boot/blob/v2021.10/configs/p3450-0000_defconfig#L8
// - https://github.com/u-boot/u-boot/blob/v2021.10/include/configs/tegra-common.h#L53
// - https://github.com/u-boot/u-boot/blob/v2021.10/include/configs/tegra210-common.h#L49
var dtb = "/dtb/nvidia/tegra210-p3450-0000.dtb"
var dtb = "nvidia/tegra210-p3450-0000.dtb"
// JetsonNano represents the JetsonNano board
//
@ -35,10 +35,10 @@ func (b *JetsonNano) Name() string {
}
// Install implements the runtime.Board.
func (b JetsonNano) Install(disk string) (err error) {
func (b JetsonNano) Install(options runtime.BoardInstallOptions) (err error) {
var f *os.File
if f, err = os.OpenFile(disk, os.O_RDWR|unix.O_CLOEXEC, 0o666); err != nil {
if f, err = os.OpenFile(options.InstallDisk, os.O_RDWR|unix.O_CLOEXEC, 0o666); err != nil {
return err
}
//nolint:errcheck
@ -52,8 +52,8 @@ func (b JetsonNano) Install(disk string) (err error) {
return err
}
src := "/usr/install/arm64" + dtb
dst := "/boot/EFI" + dtb
src := filepath.Join(options.DTBPath, dtb)
dst := filepath.Join("/boot/EFI/dtb", dtb)
err = os.MkdirAll(filepath.Dir(dst), 0o600)
if err != nil {

View File

@ -6,8 +6,6 @@
package libretechallh3cch5
import (
"fmt"
"log"
"os"
"path/filepath"
@ -20,9 +18,9 @@ import (
)
var (
bin = fmt.Sprintf("/usr/install/arm64/u-boot/%s/u-boot-sunxi-with-spl.bin", constants.BoardLibretechAllH3CCH5)
bin = constants.BoardLibretechAllH3CCH5 + "/u-boot-sunxi-with-spl.bin"
off int64 = 1024 * 8
dtb = "/dtb/allwinner/sun50i-h5-libretech-all-h3-cc.dtb"
dtb = "allwinner/sun50i-h5-libretech-all-h3-cc.dtb"
)
// LibretechAllH3CCH5 represents the Libre Computer ALL-H3-CC (Tritium).
@ -36,10 +34,10 @@ func (l *LibretechAllH3CCH5) Name() string {
}
// Install implements the runtime.Board.
func (l *LibretechAllH3CCH5) Install(disk string) (err error) {
func (l *LibretechAllH3CCH5) Install(options runtime.BoardInstallOptions) (err error) {
var f *os.File
if f, err = os.OpenFile(disk, os.O_RDWR|unix.O_CLOEXEC, 0o666); err != nil {
if f, err = os.OpenFile(options.InstallDisk, os.O_RDWR|unix.O_CLOEXEC, 0o666); err != nil {
return err
}
//nolint:errcheck
@ -47,12 +45,12 @@ func (l *LibretechAllH3CCH5) Install(disk string) (err error) {
var uboot []byte
uboot, err = os.ReadFile(bin)
uboot, err = os.ReadFile(filepath.Join(options.UBootPath, bin))
if err != nil {
return err
}
log.Printf("writing %s at offset %d", bin, off)
options.Printf("writing %s at offset %d", bin, off)
var n int
@ -61,7 +59,7 @@ func (l *LibretechAllH3CCH5) Install(disk string) (err error) {
return err
}
log.Printf("wrote %d bytes", n)
options.Printf("wrote %d bytes", n)
// NB: In the case that the block device is a loopback device, we sync here
// to esure that the file is written before the loopback device is
@ -71,8 +69,8 @@ func (l *LibretechAllH3CCH5) Install(disk string) (err error) {
return err
}
src := "/usr/install/arm64" + dtb
dst := "/boot/EFI" + dtb
src := filepath.Join(options.DTBPath, dtb)
dst := filepath.Join("/boot/EFI/dtb", dtb)
err = os.MkdirAll(filepath.Dir(dst), 0o600)
if err != nil {

View File

@ -6,8 +6,6 @@
package nanopir4s
import (
"fmt"
"log"
"os"
"path/filepath"
@ -20,9 +18,9 @@ import (
)
var (
bin = fmt.Sprintf("/usr/install/arm64/u-boot/%s/u-boot-rockchip.bin", constants.BoardNanoPiR4S)
bin = constants.BoardNanoPiR4S + "u-boot-rockchip.bin"
off int64 = 512 * 64
dtb = "/dtb/rockchip/rk3399-nanopi-r4s.dtb"
dtb = "rockchip/rk3399-nanopi-r4s.dtb"
)
// NanoPiR4S represents the Friendlyelec Nano Pi R4S board.
@ -36,27 +34,27 @@ func (n *NanoPiR4S) Name() string {
}
// Install implements the runtime.Board.
func (n *NanoPiR4S) Install(disk string) (err error) {
file, err := os.OpenFile(disk, os.O_RDWR|unix.O_CLOEXEC, 0o666)
func (n *NanoPiR4S) Install(options runtime.BoardInstallOptions) (err error) {
file, err := os.OpenFile(options.InstallDisk, os.O_RDWR|unix.O_CLOEXEC, 0o666)
if err != nil {
return err
}
defer file.Close() //nolint:errcheck
uboot, err := os.ReadFile(bin)
uboot, err := os.ReadFile(filepath.Join(options.UBootPath, bin))
if err != nil {
return err
}
log.Printf("writing %s at offset %d", bin, off)
options.Printf("writing %s at offset %d", bin, off)
amount, err := file.WriteAt(uboot, off)
if err != nil {
return err
}
log.Printf("wrote %d bytes", amount)
options.Printf("wrote %d bytes", amount)
// NB: In the case that the block device is a loopback device, we sync here
// to esure that the file is written before the loopback device is
@ -65,8 +63,8 @@ func (n *NanoPiR4S) Install(disk string) (err error) {
return err
}
src := "/usr/install/arm64" + dtb
dst := "/boot/EFI" + dtb
src := filepath.Join(options.DTBPath, dtb)
dst := filepath.Join("/boot/EFI/dtb", dtb)
if err := os.MkdirAll(filepath.Dir(dst), 0o600); err != nil {
return err

View File

@ -6,8 +6,6 @@
package pine64
import (
"fmt"
"log"
"os"
"path/filepath"
@ -20,9 +18,9 @@ import (
)
var (
bin = fmt.Sprintf("usr/install/arm64/u-boot/%s/u-boot-sunxi-with-spl.bin", constants.BoardPine64)
bin = constants.BoardPine64 + "/u-boot-sunxi-with-spl.bin"
off int64 = 1024 * 8
dtb = "/dtb/allwinner/sun50i-a64-pine64-plus.dtb"
dtb = "allwinner/sun50i-a64-pine64-plus.dtb"
)
// Pine64 represents the Pine64 board
@ -37,10 +35,10 @@ func (b *Pine64) Name() string {
}
// Install implements the runtime.Board.
func (b Pine64) Install(disk string) (err error) {
func (b Pine64) Install(options runtime.BoardInstallOptions) (err error) {
var f *os.File
if f, err = os.OpenFile(disk, os.O_RDWR|unix.O_CLOEXEC, 0o666); err != nil {
if f, err = os.OpenFile(options.InstallDisk, os.O_RDWR|unix.O_CLOEXEC, 0o666); err != nil {
return err
}
//nolint:errcheck
@ -48,12 +46,12 @@ func (b Pine64) Install(disk string) (err error) {
var uboot []byte
uboot, err = os.ReadFile(bin)
uboot, err = os.ReadFile(filepath.Join(options.UBootPath, bin))
if err != nil {
return err
}
log.Printf("writing %s at offset %d", bin, off)
options.Printf("writing %s at offset %d", bin, off)
var n int
@ -62,7 +60,7 @@ func (b Pine64) Install(disk string) (err error) {
return err
}
log.Printf("wrote %d bytes", n)
options.Printf("wrote %d bytes", n)
// NB: In the case that the block device is a loopback device, we sync here
// to esure that the file is written before the loopback device is
@ -72,8 +70,8 @@ func (b Pine64) Install(disk string) (err error) {
return err
}
src := "/usr/install/arm64" + dtb
dst := "/boot/EFI" + dtb
src := filepath.Join(options.DTBPath, dtb)
dst := filepath.Join("/boot/EFI/dtb", dtb)
err = os.MkdirAll(filepath.Dir(dst), 0o600)
if err != nil {

View File

@ -6,8 +6,6 @@
package rock64
import (
"fmt"
"log"
"os"
"path/filepath"
@ -20,9 +18,9 @@ import (
)
var (
bin = fmt.Sprintf("/usr/install/arm64/u-boot/%s/u-boot-rockchip.bin", constants.BoardRock64)
bin = constants.BoardRock64 + "/u-boot-rockchip.bin"
off int64 = 512 * 64
dtb = "/dtb/rockchip/rk3328-rock64.dtb"
dtb = "rockchip/rk3328-rock64.dtb"
)
// Rock64 represents the Pine64 Rock64 board.
@ -36,10 +34,10 @@ func (r *Rock64) Name() string {
}
// Install implements the runtime.Board.
func (r *Rock64) Install(disk string) (err error) {
func (r *Rock64) Install(options runtime.BoardInstallOptions) (err error) {
var f *os.File
if f, err = os.OpenFile(disk, os.O_RDWR|unix.O_CLOEXEC, 0o666); err != nil {
if f, err = os.OpenFile(options.InstallDisk, os.O_RDWR|unix.O_CLOEXEC, 0o666); err != nil {
return err
}
//nolint:errcheck
@ -47,12 +45,12 @@ func (r *Rock64) Install(disk string) (err error) {
var uboot []byte
uboot, err = os.ReadFile(bin)
uboot, err = os.ReadFile(filepath.Join(options.UBootPath, bin))
if err != nil {
return err
}
log.Printf("writing %s at offset %d", bin, off)
options.Printf("writing %s at offset %d", bin, off)
var n int
@ -61,7 +59,7 @@ func (r *Rock64) Install(disk string) (err error) {
return err
}
log.Printf("wrote %d bytes", n)
options.Printf("wrote %d bytes", n)
// NB: In the case that the block device is a loopback device, we sync here
// to esure that the file is written before the loopback device is
@ -71,8 +69,8 @@ func (r *Rock64) Install(disk string) (err error) {
return err
}
src := "/usr/install/arm64" + dtb
dst := "/boot/EFI" + dtb
src := filepath.Join(options.DTBPath, dtb)
dst := filepath.Join("/boot/EFI/dtb", dtb)
err = os.MkdirAll(filepath.Dir(dst), 0o600)
if err != nil {

View File

@ -6,8 +6,6 @@
package rockpi4
import (
"fmt"
"log"
"os"
"path/filepath"
@ -20,11 +18,11 @@ import (
)
var (
bin = fmt.Sprintf("/usr/install/arm64/u-boot/%s/u-boot-rockchip.bin", constants.BoardRockpi4)
bin = constants.BoardRockpi4 + "/u-boot-rockchip.bin"
off int64 = 512 * 64
// https://github.com/u-boot/u-boot/blob/4de720e98d552dfda9278516bf788c4a73b3e56f/configs/rock-pi-4-rk3399_defconfig#L7=
// 4a and 4b uses the same overlay.
dtb = "/dtb/rockchip/rk3399-rock-pi-4b.dtb"
dtb = "rockchip/rk3399-rock-pi-4b.dtb"
)
// Rockpi4 represents the Radxa rock pi board.
@ -38,21 +36,21 @@ func (r *Rockpi4) Name() string {
}
// Install implements the runtime.Board.
func (r *Rockpi4) Install(disk string) (err error) {
func (r *Rockpi4) Install(options runtime.BoardInstallOptions) (err error) {
var f *os.File
if f, err = os.OpenFile(disk, os.O_RDWR|unix.O_CLOEXEC, 0o666); err != nil {
if f, err = os.OpenFile(options.InstallDisk, os.O_RDWR|unix.O_CLOEXEC, 0o666); err != nil {
return err
}
defer f.Close() //nolint:errcheck
uboot, err := os.ReadFile(bin)
uboot, err := os.ReadFile(filepath.Join(options.UBootPath, bin))
if err != nil {
return err
}
log.Printf("writing %s at offset %d", bin, off)
options.Printf("writing %s at offset %d", bin, off)
var n int
@ -61,7 +59,7 @@ func (r *Rockpi4) Install(disk string) (err error) {
return err
}
log.Printf("wrote %d bytes", n)
options.Printf("wrote %d bytes", n)
// NB: In the case that the block device is a loopback device, we sync here
// to esure that the file is written before the loopback device is
@ -71,8 +69,8 @@ func (r *Rockpi4) Install(disk string) (err error) {
return err
}
src := "/usr/install/arm64" + dtb
dst := "/boot/EFI" + dtb
src := filepath.Join(options.DTBPath, dtb)
dst := filepath.Join("/boot/EFI/dtb", dtb)
err = os.MkdirAll(filepath.Dir(dst), 0o600)
if err != nil {

View File

@ -6,8 +6,6 @@
package rockpi4c
import (
"fmt"
"log"
"os"
"path/filepath"
@ -20,10 +18,10 @@ import (
)
var (
bin = fmt.Sprintf("/usr/install/arm64/u-boot/%s/u-boot-rockchip.bin", constants.BoardRockpi4)
bin = constants.BoardRockpi4 + "/u-boot-rockchip.bin"
off int64 = 512 * 64
// https://github.com/u-boot/u-boot/blob/4de720e98d552dfda9278516bf788c4a73b3e56f/configs/rock-pi-4c-rk3399_defconfig#L7=
dtb = "/dtb/rockchip/rk3399-rock-pi-4c.dtb"
dtb = "rockchip/rk3399-rock-pi-4c.dtb"
)
// Rockpi4c represents the Radxa rock pi board.
@ -37,21 +35,21 @@ func (r *Rockpi4c) Name() string {
}
// Install implements the runtime.Board.
func (r *Rockpi4c) Install(disk string) (err error) {
func (r *Rockpi4c) Install(options runtime.BoardInstallOptions) (err error) {
var f *os.File
if f, err = os.OpenFile(disk, os.O_RDWR|unix.O_CLOEXEC, 0o666); err != nil {
if f, err = os.OpenFile(options.InstallDisk, os.O_RDWR|unix.O_CLOEXEC, 0o666); err != nil {
return err
}
defer f.Close() //nolint:errcheck
uboot, err := os.ReadFile(bin)
uboot, err := os.ReadFile(filepath.Join(options.UBootPath, bin))
if err != nil {
return err
}
log.Printf("writing %s at offset %d", bin, off)
options.Printf("writing %s at offset %d", bin, off)
var n int
@ -60,7 +58,7 @@ func (r *Rockpi4c) Install(disk string) (err error) {
return err
}
log.Printf("wrote %d bytes", n)
options.Printf("wrote %d bytes", n)
// NB: In the case that the block device is a loopback device, we sync here
// to esure that the file is written before the loopback device is
@ -70,8 +68,8 @@ func (r *Rockpi4c) Install(disk string) (err error) {
return err
}
src := "/usr/install/arm64" + dtb
dst := "/boot/EFI" + dtb
src := filepath.Join(options.DTBPath, dtb)
dst := filepath.Join("/boot/EFI/dtb", dtb)
err = os.MkdirAll(filepath.Dir(dst), 0o600)
if err != nil {

View File

@ -8,6 +8,7 @@ package rpigeneric
import (
_ "embed"
"os"
"path/filepath"
"github.com/siderolabs/go-procfs/procfs"
@ -30,13 +31,13 @@ func (r *RPiGeneric) Name() string {
}
// Install implements the runtime.Board.
func (r *RPiGeneric) Install(disk string) (err error) {
err = copy.Dir("/usr/install/arm64/raspberrypi-firmware/boot", "/boot/EFI")
func (r *RPiGeneric) Install(options runtime.BoardInstallOptions) (err error) {
err = copy.Dir(filepath.Join(options.RPiFirmwarePath, "boot"), "/boot/EFI")
if err != nil {
return err
}
err = copy.File("/usr/install/arm64/u-boot/rpi_generic/u-boot.bin", "/boot/EFI/u-boot.bin")
err = copy.File(filepath.Join(options.UBootPath, "rpi_generic/u-boot.bin"), "/boot/EFI/u-boot.bin")
if err != nil {
return err
}

View File

@ -35,13 +35,17 @@ type InstallOptions struct {
Printf func(format string, v ...any)
}
// BootAssets describes the assets to be installed by the booloader.
// BootAssets describes the assets to be installed by the bootloader.
type BootAssets struct {
KernelPath string
InitramfsPath string
UKIPath string
SDBootPath string
DTBPath string
UBootPath string
RPiFirmwarePath string
}
// FillDefaults fills in default paths to be used when in the context of the installer.
@ -61,4 +65,18 @@ func (assets *BootAssets) FillDefaults(arch string) {
if assets.SDBootPath == "" {
assets.SDBootPath = fmt.Sprintf(constants.SDBootAssetPath, arch)
}
if arch == "arm64" {
if assets.DTBPath == "" {
assets.DTBPath = fmt.Sprintf(constants.DTBAssetPath, arch)
}
if assets.UBootPath == "" {
assets.UBootPath = fmt.Sprintf(constants.UBootAssetPath, arch)
}
if assets.RPiFirmwarePath == "" {
assets.RPiFirmwarePath = fmt.Sprintf(constants.RPiFirmwareAssetPath, arch)
}
}
}

View File

@ -10,6 +10,7 @@ import (
"bytes"
"io"
"os"
"path/filepath"
"sort"
v1 "github.com/google/go-containerregistry/pkg/v1"
@ -22,6 +23,35 @@ type File struct {
SourcePath string
}
// Walk the filesystem generating a filemap.
func Walk(sourceBasePath, imageBasePath string) ([]File, error) {
var filemap []File
err := filepath.WalkDir(sourceBasePath, func(path string, d os.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return nil
}
rel, err := filepath.Rel(sourceBasePath, path)
if err != nil {
return err
}
filemap = append(filemap, File{
ImagePath: filepath.Join(imageBasePath, rel),
SourcePath: path,
})
return nil
})
return filemap, err
}
// Layer creates a layer from a single file map.
//
// These layers are reproducible and consistent.

View File

@ -188,10 +188,13 @@ func (i *Imager) buildImage(ctx context.Context, path string, printf func(string
ImageSecureboot: i.prof.SecureBootEnabled(),
Version: i.prof.Version,
BootAssets: options.BootAssets{
KernelPath: i.prof.Input.Kernel.Path,
InitramfsPath: i.initramfsPath,
UKIPath: i.ukiPath,
SDBootPath: i.sdBootPath,
KernelPath: i.prof.Input.Kernel.Path,
InitramfsPath: i.initramfsPath,
UKIPath: i.ukiPath,
SDBootPath: i.sdBootPath,
DTBPath: i.prof.Input.DTB.Path,
UBootPath: i.prof.Input.UBoot.Path,
RPiFirmwarePath: i.prof.Input.RPiFirmware.Path,
},
MountPrefix: scratchSpace,
Printf: printf,
@ -282,6 +285,37 @@ func (i *Imager) outInstaller(ctx context.Context, path string, report *reporter
)
}
for _, extraArtifact := range []struct {
sourcePath string
imagePath string
}{
{
sourcePath: i.prof.Input.DTB.Path,
imagePath: strings.TrimLeft(fmt.Sprintf(constants.DTBAssetPath, i.prof.Arch), "/"),
},
{
sourcePath: i.prof.Input.UBoot.Path,
imagePath: strings.TrimLeft(fmt.Sprintf(constants.UBootAssetPath, i.prof.Arch), "/"),
},
{
sourcePath: i.prof.Input.RPiFirmware.Path,
imagePath: strings.TrimLeft(fmt.Sprintf(constants.RPiFirmwareAssetPath, i.prof.Arch), "/"),
},
} {
if extraArtifact.sourcePath == "" {
continue
}
var extraFiles []filemap.File
extraFiles, err = filemap.Walk(extraArtifact.sourcePath, extraArtifact.imagePath)
if err != nil {
return fmt.Errorf("failed to walk extra artifact %s: %w", extraArtifact.sourcePath, err)
}
artifacts = append(artifacts, extraFiles...)
}
artifactsLayer, err := filemap.Layer(artifacts)
if err != nil {
return fmt.Errorf("failed to create artifacts layer: %w", err)

View File

@ -21,6 +21,11 @@ import (
"github.com/siderolabs/talos/pkg/machinery/constants"
)
const (
arm64 = "arm64"
amd64 = "amd64"
)
// Input describes inputs for image generation.
type Input struct {
// Kernel is a vmlinuz file.
@ -31,6 +36,12 @@ type Input struct {
SDStub FileAsset `yaml:"sdStub,omitempty"`
// SDBoot is a sd-boot file (only for SecureBoot).
SDBoot FileAsset `yaml:"sdBoot,omitempty"`
// DTB is a path to the device tree blobs (arm64 only).
DTB FileAsset `yaml:"dtb,omitempty"`
// UBoot is a path to the u-boot binary (arm64 only).
UBoot FileAsset `yaml:"uBoot,omitempty"`
// RPiFirmware is a path to the Raspberry Pi firmware (arm64 only).
RPiFirmware FileAsset `yaml:"rpiFirmware,omitempty"`
// Base installer image to mutate.
BaseInstaller ContainerAsset `yaml:"baseInstaller,omitempty"`
// SecureBoot is a section with secureboot keys, only for SecureBoot enabled builds.
@ -79,7 +90,7 @@ const defaultSecureBootPrefix = "/secureboot"
// FillDefaults fills default values for the input.
//
//nolint:gocyclo
//nolint:gocyclo,cyclop
func (i *Input) FillDefaults(arch, version string, secureboot bool) {
var (
zeroFileAsset FileAsset
@ -94,6 +105,20 @@ func (i *Input) FillDefaults(arch, version string, secureboot bool) {
i.Initramfs.Path = fmt.Sprintf(constants.InitramfsAssetPath, arch)
}
if arch == arm64 {
if i.DTB == zeroFileAsset {
i.DTB.Path = fmt.Sprintf(constants.DTBAssetPath, arch)
}
if i.UBoot == zeroFileAsset {
i.UBoot.Path = fmt.Sprintf(constants.UBootAssetPath, arch)
}
if i.RPiFirmware == zeroFileAsset {
i.RPiFirmware.Path = fmt.Sprintf(constants.RPiFirmwareAssetPath, arch)
}
}
if i.BaseInstaller == zeroContainerAsset {
i.BaseInstaller.ImageRef = fmt.Sprintf("%s:%s", images.DefaultInstallerImageRepository, version)
}

View File

@ -57,7 +57,7 @@ func (p *Profile) SecureBootEnabled() bool {
//
//nolint:gocyclo,cyclop
func (p *Profile) Validate() error {
if p.Arch != "amd64" && p.Arch != "arm64" {
if p.Arch != amd64 && p.Arch != arm64 {
return fmt.Errorf("invalid arch %q", p.Arch)
}
@ -66,7 +66,7 @@ func (p *Profile) Validate() error {
}
if p.Board != "" {
if !(p.Arch == "arm64" && p.Platform == "metal") {
if !(p.Arch == arm64 && p.Platform == "metal") {
return fmt.Errorf("board is only supported for metal arm64")
}
}

View File

@ -529,6 +529,15 @@ const (
// SDBootAssetPath is the path to the SDBoot in the installer.
SDBootAssetPath = "/usr/install/%s/" + SDBootAsset
// DTBAssetPath is the path to the device tree blobs in the installer.
DTBAssetPath = "/usr/install/%s/dtb"
// UBootAssetPath is the path to the u-boot in the installer.
UBootAssetPath = "/usr/install/%s/u-boot"
// RPiFirmwareAssetPath is the path to the raspberrypi firmware in the installer.
RPiFirmwareAssetPath = "/usr/install/%s/raspberrypi-firmware"
// PlatformKeyAsset defines a well known name for the platform key filename used for auto-enrolling.
PlatformKeyAsset = "PK.auth"