recipes

package
v0.19.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 4, 2025 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

Package recipes / config

Package recipes / coreboot

Package recipes yay!

Package recipes / edk2

Package recipes / linux

Package recipes yay!

Package recipes / stitching

Package recipes / uboot

Package recipes / universal

Package recipes / uroot

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrVerboseJSON is raised when JSONVerboseError can't find location of problem in JSON configuration file
	ErrVerboseJSON = errors.New("unable to pinpoint the problem in JSON file")
	// ErrEnvVarUndefined is raised when undefined environment variable is found in JSON configuration file
	ErrEnvVarUndefined = errors.New("environment variable used in JSON file is not present in the environment")
	// ErrNestedOutputDirs is raised when one module's output directory is a subdirectory of another module's output directory
	ErrNestedOutputDirs = errors.New("nested output directories detected")
	// ErrDuplicateOutputDirs is raised when multiple modules use the same output directory
	ErrDuplicateOutputDirs = errors.New("duplicate output directories detected")
)
View Source
var (
	ErrBuildFailed               = errors.New("build failed")
	ErrBuildUpToDate             = errors.New("build is up-to-date")
	ErrDependencyTreeUndefDep    = errors.New("module has invalid dependency")
	ErrDependencyTreeUnderTarget = errors.New("target not found in dependency tree")
	ErrDependencyOutputMissing   = errors.New("output of one or more dependencies is missing")
	ErrFailedValidation          = errors.New("config failed validation")
	ErrTargetInvalid             = errors.New("unsupported target")
	ErrTargetMissing             = errors.New("no target specified")
)

Errors for recipes

View Source
var (
	// ContainerWorkDir specifies directory in container used as work directory
	ContainerWorkDir = "/workdir"
	// StatusDir is directory for temporary files generated by firmware-action to aid change detection
	StatusDir = ".firmware-action"
	// TimestampsDir specifies directory for timestamps to detect changes in sources
	TimestampsDir = filepath.Join(StatusDir, "timestamps")
	// CompiledConfigsDir specifies directory for successfully compiled module configurations to detect changes in
	//   configuration
	CompiledConfigsDir = filepath.Join(StatusDir, "configs")
	// GitRepoHashDir specifies directory for git hashes to detect changes in sources
	GitRepoHashDir = filepath.Join(StatusDir, "git-hashes")
	// ArtifactDir specifies directory where to store a copy of artifacts for caching in CI
	ArtifactDir = filepath.Join(StatusDir, "artifacts")
)

Functions

func Execute

func Execute(ctx context.Context, target string, config *Config) error

Execute a build step func Execute(ctx context.Context, target string, config *Config, bulldozeMode bool) error {

func ExtractSizeFromString

func ExtractSizeFromString(text string) ([]uint64, error)

ExtractSizeFromString uses regex to find size of ROM in MB

func FindAllEnvVars

func FindAllEnvVars(text string) []string

FindAllEnvVars returns all environment variables found in the provided string

func IsDirEmpty

func IsDirEmpty(path string) (bool, error)

IsDirEmpty returns whether given directory is empty or not

func JSONVerboseError

func JSONVerboseError(jsonString string, err error)

JSONVerboseError is for getting more information out of json.Unmarshal() or Decoder.Decode()

Inspiration:
- https://adrianhesketh.com/2017/03/18/getting-line-and-character-positions-from-gos-json-unmarshal-errors/
Docs:
- https://pkg.go.dev/encoding/json#Unmarshal

func LinuxCrossCompilationArchMap

func LinuxCrossCompilationArchMap(arch string) (map[string]string, error)

LinuxCrossCompilationArchMap is to handle cross-compilation 'CROSS_COMPILE' environment variable for Linux builds

func NormalizeArchitecture

func NormalizeArchitecture(arch string) string

NormalizeArchitecture will translate various architecture strings into expected format

func NormalizeArchitectureForLinux

func NormalizeArchitectureForLinux(arch string) string

NormalizeArchitectureForLinux will translate various architecture strings into format expected by Linux

func StringToSizeMB

func StringToSizeMB(text string) (uint64, error)

StringToSizeMB parses string and returns size in MB

func ValidateConfig

func ValidateConfig(conf Config) error

ValidateConfig is used to validate the configuration struct read out of JSON file

func ValidateLinuxDefconfigFilename

func ValidateLinuxDefconfigFilename(defconfigPath string) error

ValidateLinuxDefconfigFilename checks if defconfig filename is valid

func WriteConfig

func WriteConfig(filepath string, config *Config) error

WriteConfig is for writing Config struct into JSON configuration file

Types

type AllChanges

type AllChanges struct {
	TimeStamp     ChangeTimeStamp
	Configuration ChangeConfig
	GitHash       ChangeGitHash
}

AllChanges is congregation of all methods of change detection

func (*AllChanges) DetectChanges

func (c *AllChanges) DetectChanges(target string) bool

DetectChanges is a method for detecting changes based on combination of multiple methods

func (*AllChanges) SaveCheckpoint

func (c *AllChanges) SaveCheckpoint(target string, override bool)

SaveCheckpoint is a method for saving checkpoint files for future change detection

type BlobDef

type BlobDef struct {
	// Path to the blob (either file or directory)
	Path string

	// Blobs get renamed when moved to this string
	DestinationFilename string

	// Kconfig key specifying the filepath to the blob in defconfig
	KconfigKey string
}

BlobDef is used to store information about a single blob. This structure is not exposed to the user, it is filled in automatically based on user input.

type BuildResults

type BuildResults struct {
	Name        string
	BuildResult error
}

BuildResults contains target name and result of its build

func Build

func Build(
	ctx context.Context,
	target string,
	recursive bool,
	pruneDocker bool,
	config *Config,
	executor func(context.Context, string, *Config) error,
) ([]BuildResults, error)

Build recipes, possibly recursively

type Change

type Change struct {
	// ResultFile stores path to a temporary file where information needed to detect changes is stored
	ResultFile string
	// ChangesDetected stores if changes were detected
	ChangesDetected bool
}

Change is generic struct to hold commonly needed variables for all change detection modules

type ChangeConfig

type ChangeConfig struct {
	Change

	Config *Config
}

ChangeConfig is for detecting any change in firmware-action configuration

func (*ChangeConfig) DetectChanges

func (c *ChangeConfig) DetectChanges(target string) bool

DetectChanges is a method for detecting changes based on Configuration file

func (*ChangeConfig) SaveCheckpoint

func (c *ChangeConfig) SaveCheckpoint(override bool)

SaveCheckpoint is a method for saving checkpoint file for future change detection

type ChangeGitHash

type ChangeGitHash struct {
	Change

	RepoPath string
	// contains filtered or unexported fields
}

ChangeGitHash is for detecting any change in git current commit hash

func (*ChangeGitHash) DetectChanges

func (c *ChangeGitHash) DetectChanges() bool

DetectChanges is a method for detecting changes based on Git commit hash

func (*ChangeGitHash) SaveCheckpoint

func (c *ChangeGitHash) SaveCheckpoint(target string, override bool)

SaveCheckpoint is a method for saving checkpoint file for future change detection

type ChangeTimeStamp

type ChangeTimeStamp struct {
	Change

	Sources []string
}

ChangeTimeStamp is for detecting any change in source files based on time-stamps

func (*ChangeTimeStamp) DetectChanges

func (c *ChangeTimeStamp) DetectChanges() bool

DetectChanges is a method for detecting changes based on Time-Stamp

func (*ChangeTimeStamp) SaveCheckpoint

func (c *ChangeTimeStamp) SaveCheckpoint(override bool)

SaveCheckpoint is a method for saving checkpoint file for future change detection

type CommonOpts

type CommonOpts struct {
	// Specifies the container toolchain tag to use when building the image.
	// This has an influence on the IASL, GCC and host GCC version that is used to build
	//   the target. You must match the source level and sdk_version.
	// Can also be a absolute or relative path to Dockerfile to build the image on the fly.
	// Can also be a path to tarfile.
	// NOTE: Updating the sdk_version might result in different binaries using the
	//   same source code.
	// ANCHOR: CommonOptsSdkURLExamples
	// Examples:
	//   https://ghcr.io/9elements/firmware-action/coreboot_4.19:main
	//   https://ghcr.io/9elements/firmware-action/coreboot_4.19:latest
	//   https://ghcr.io/9elements/firmware-action/edk2-stable202111:latest
	//   file://./my-image/Dockerfile
	//   file://./my-image/
	//   file://my-image/Dockerfile
	//   file:///home/user/my-image/Dockerfile
	//   file:///home/user/my-image/
	//   file:///home/user/ubuntu-latest.tar
	// ANCHOR_END: CommonOptsSdkURLExamples
	// NOTE:
	//   'file://' path cannot contain '..'
	// See https://github.com/orgs/9elements/packages
	SdkURL string `json:"sdk_url" validate:"required"`

	// Gives the (relative) path to the target (firmware) repository.
	// If the current repository contains the selected target, specify: '.'
	// Otherwise the path should point to the target (firmware) repository submodule that
	//   had been previously checked out.
	RepoPath string `json:"repo_path" validate:"required,dirpath"`

	// Specifies the (relative) paths to directories where are produced files (inside Container).
	ContainerOutputDirs []string `json:"container_output_dirs" validate:"dive,filepath|dirpath"`

	// Specifies the (relative) paths to produced files (inside Container).
	ContainerOutputFiles []string `json:"container_output_files" validate:"dive,filepath|dirpath"`

	// Specifies the (relative) path to directory into which place the produced files.
	//   Directories listed in ContainerOutputDirs and files listed in ContainerOutputFiles
	//   will be exported here.
	// Example:
	//   Following setting:
	//     ContainerOutputDirs = []string{"Build/"}
	//     ContainerOutputFiles = []string{"coreboot.rom", "defconfig"}
	//     OutputDir = "myOutput"
	//   Will result in following structure being copied out of the container:
	//     myOutput/
	//     ├── Build/
	//     ├── coreboot.rom
	//     └── defconfig
	OutputDir string `json:"output_dir" validate:"required,filepath|dirpath"`

	// Specifies the (relative) paths to directories which should be copied into the container.
	InputDirs []string `json:"input_dirs" validate:"dive,filepath|dirpath"`

	// Specifies the (relative) paths to file which should be copied into the container.
	InputFiles []string `json:"input_files" validate:"dive,filepath|dirpath"`

	// Specifies the path to directory where to place input files and directories inside container.
	//   Directories listed in ContainerInputDirs and files listed in ContainerInputFiles
	//   will be copied there.
	// Example:
	//   Following setting:
	//     InputDirs = []string{"config-files/"}
	//     InputFiles = []string{"README.md", "Taskfile.yml"}
	//     ContainerInputDir = "myInput"
	//   Will result in following structure being copied into the container:
	//     myInput/
	//     ├── config-files/
	//     ├── README.md
	//     └── Taskfile.yml
	ContainerInputDir string `json:"container_input_dir" validate:"filepath|dirpath"`
}

CommonOpts is common to all targets Used to store data from githubaction.Action For details see action.yml ANCHOR: CommonOpts

func (CommonOpts) GetArtifacts

func (opts CommonOpts) GetArtifacts() *[]container.Artifacts

GetArtifacts returns list of wanted artifacts from container

func (CommonOpts) GetContainerOutputDirs

func (opts CommonOpts) GetContainerOutputDirs() []string

GetContainerOutputDirs returns list of output directories

func (CommonOpts) GetContainerOutputFiles

func (opts CommonOpts) GetContainerOutputFiles() []string

GetContainerOutputFiles returns list of output directories

func (CommonOpts) GetOutputDir

func (opts CommonOpts) GetOutputDir() string

GetOutputDir returns output directory

func (CommonOpts) GetRepoPath

func (opts CommonOpts) GetRepoPath() string

GetRepoPath returns Repository path

func (CommonOpts) GetSources

func (opts CommonOpts) GetSources() []string

GetSources returns slice of paths to all sources which are used for build

type Config

type Config struct {
	// defined in coreboot.go
	Coreboot map[string]CorebootOpts `json:"coreboot" validate:"dive"`

	// defined in linux.go
	Linux map[string]LinuxOpts `json:"linux" validate:"dive"`

	// defined in edk2.go
	Edk2 map[string]Edk2Opts `json:"edk2" validate:"dive"`

	// defined in stitching.go
	FirmwareStitching map[string]FirmwareStitchingOpts `json:"firmware_stitching" validate:"dive"`

	// defined in uroot.go
	URoot map[string]URootOpts `json:"u-root" validate:"dive"`

	// defined in universal.go
	Universal map[string]UniversalOpts `json:"universal" validate:"dive"`

	// defined in uboot.go
	UBoot map[string]UBootOpts `json:"u-boot" validate:"dive"`
}

Config is for storing parsed configuration file

func ReadConfig

func ReadConfig(filepath string) (*Config, error)

ReadConfig is for reading and parsing JSON configuration file into Config struct

func ReadConfigs

func ReadConfigs(filepaths []string) (*Config, error)

ReadConfigs is for reading and parsing multiple JSON configuration files into single Config struct

func (Config) AllModules

func (c Config) AllModules() map[string]FirmwareModule

AllModules method returns slice with all modules

func (Config) Merge

func (c Config) Merge(other Config) (Config, error)

Merge method will take other Config instance and adopt all of its modules

type CorebootOpts

type CorebootOpts struct {
	// Common options like paths etc.
	CommonOpts

	// List of IDs this instance depends on
	Depends []string `json:"depends"`

	// Gives the (relative) path to the defconfig that should be used to build the target.
	DefconfigPath string `json:"defconfig_path" validate:"required,filepath"`

	// Blobs
	// The blobs will be copied into the container into directory:
	//   3rdparty/blobs/mainboard/${CONFIG_MAINBOARD_DIR}/
	// And the blobs will remain their name
	// NOTE: The blobs may not be added to the ROM, depends on provided defconfig.
	// Example:
	//   Config:
	//     "CONFIG_PAYLOAD_FILE": "./my-payload.bin"
	//   Will result in blob "my-payload.bin" at
	//     "3rdparty/blobs/mainboard/${CONFIG_MAINBOARD_DIR}/my-payload.bin"
	Blobs map[string]string `json:"blobs"`
}

CorebootOpts is used to store all data needed to build coreboot.

func (CorebootOpts) GetArtifacts

func (opts CorebootOpts) GetArtifacts() *[]container.Artifacts

GetArtifacts returns list of wanted artifacts from container

func (CorebootOpts) GetDepends

func (opts CorebootOpts) GetDepends() []string

GetDepends is used to return list of dependencies

func (CorebootOpts) GetSources

func (opts CorebootOpts) GetSources() []string

GetSources returns slice of paths to all sources which are used for build

func (CorebootOpts) ProcessBlobs

func (opts CorebootOpts) ProcessBlobs() ([]BlobDef, error)

ProcessBlobs is used to figure out blobs from provided data

type Edk2Opts

type Edk2Opts struct {
	// Common options like paths etc.
	CommonOpts

	// Coreboot specific options
	Edk2Specific `validate:"required"`

	// List of IDs this instance depends on
	// Example: [ "MyLittleCoreboot", "MyLittleLinux"]
	Depends []string `json:"depends"`

	// Specifies target architecture, such as 'x86' or 'arm64'. Currently unused for coreboot.
	// Supported options:
	//   - 'AARCH64'
	//   - 'ARM'
	//   - 'IA32'
	//   - 'IA32X64'
	//   - 'X64'
	Arch string `json:"arch"`

	// Gives the (relative) path to the defconfig that should be used to build the target.
	// For EDK2 this is a one-line file containing the build arguments such as
	//   '-D BOOTLOADER=COREBOOT -D TPM_ENABLE=TRUE -D NETWORK_IPXE=TRUE'.
	DefconfigPath string `json:"defconfig_path" validate:"filepath"`
}

Edk2Opts is used to store all data needed to build edk2.

func (Edk2Opts) GetArtifacts

func (opts Edk2Opts) GetArtifacts() *[]container.Artifacts

GetArtifacts returns list of wanted artifacts from container

func (Edk2Opts) GetDepends

func (opts Edk2Opts) GetDepends() []string

GetDepends is used to return list of dependencies

func (Edk2Opts) GetSources

func (opts Edk2Opts) GetSources() []string

GetSources returns slice of paths to all sources which are used for build

type Edk2Specific

type Edk2Specific struct {
	// Specifies which build command to use
	// GCC version is exposed in the container as USE_GCC_VERSION environment variable
	// Examples:
	//   "source ./edksetup.sh; build -t GCC5 -a IA32 -p UefiPayloadPkg/UefiPayloadPkg.dsc"
	//   "python UefiPayloadPkg/UniversalPayloadBuild.py"
	//   "Intel/AlderLakeFspPkg/BuildFv.sh"
	BuildCommand string `json:"build_command" validate:"required"`
}

Edk2Specific is used to store data specific to coreboot.

simplified because of issue #92

type FirmwareModule

type FirmwareModule interface {
	GetDepends() []string
	GetArtifacts() *[]container.Artifacts
	GetContainerOutputDirs() []string
	GetContainerOutputFiles() []string
	GetOutputDir() string
	GetSources() []string

	GetRepoPath() string
	// contains filtered or unexported methods
}

FirmwareModule interface

type FirmwareStitchingOpts

type FirmwareStitchingOpts struct {
	// Common options like paths etc.
	CommonOpts

	// List of IDs this instance depends on
	Depends []string `json:"depends"`

	// BaseFile into which inject files.
	// !!! Must contain IFD !!!
	// Examples:
	//   - coreboot.rom
	//   - ifd.bin
	BaseFilePath string `json:"base_file_path" validate:"required,filepath"`

	// Platform - passed to all `ifdtool` calls with `--platform`
	Platform string `json:"platform"`

	// List of instructions for ifdtool
	IfdtoolEntries []IfdtoolEntry `json:"ifdtool_entries"`
}

FirmwareStitchingOpts is used to store all data needed to stitch firmware

func (FirmwareStitchingOpts) GetArtifacts

func (opts FirmwareStitchingOpts) GetArtifacts() *[]container.Artifacts

GetArtifacts returns list of wanted artifacts from container

func (FirmwareStitchingOpts) GetDepends

func (opts FirmwareStitchingOpts) GetDepends() []string

GetDepends is used to return list of dependencies

type IfdtoolEntry

type IfdtoolEntry struct {
	// Gives the (relative) path to the binary blob
	Path string `json:"path" validate:"required,filepath"`

	// Region where to inject the file
	// For supported options see `ifdtool --help`
	TargetRegion string `json:"target_region" validate:"required"`

	// Additional (optional) arguments and flags
	// For example:
	//   `--platform adl`
	// For supported options see `ifdtool --help`
	OptionalArguments []string `json:"optional_arguments"`

	// Ignore entry if the file is missing
	IgnoreIfMissing bool `json:"ignore_if_missing" type:"boolean"`

	// For internal use only - whether or not the blob should be injected
	// Firstly it is checked if the blob file exists, if not a if `IgnoreIfMissing` is set to `true`,
	//   then `Skip` is set to `true` to remove need for additional repetitive checks later in program
	Skip bool
}

IfdtoolEntry is for injecting a file at `path` into region `TargetRegion`

type LinuxOpts

type LinuxOpts struct {
	// Common options like paths etc.
	CommonOpts

	// Linux specific options
	LinuxSpecific

	// List of IDs this instance depends on
	// Example: [ "MyLittleCoreboot", "MyLittleEdk2"]
	Depends []string `json:"depends"`

	// Specifies target architecture, such as 'x86' or 'arm64'.
	// Supported options:
	//   - 'i386'
	//   - 'amd64'
	//   - 'arm'
	//   - 'arm64'
	Arch string `json:"arch"`

	// Gives the (relative) path to the defconfig that should be used to build the target.
	DefconfigPath string `json:"defconfig_path" validate:"required,filepath"`
}

LinuxOpts is used to store all data needed to build linux

func (LinuxOpts) GetArtifacts

func (opts LinuxOpts) GetArtifacts() *[]container.Artifacts

GetArtifacts returns list of wanted artifacts from container

func (LinuxOpts) GetDepends

func (opts LinuxOpts) GetDepends() []string

GetDepends is used to return list of dependencies

func (LinuxOpts) GetSources

func (opts LinuxOpts) GetSources() []string

GetSources returns slice of paths to all sources which are used for build

type LinuxSpecific

type LinuxSpecific struct {
	// TODO: either use or remove
	GccVersion string `json:"gcc_version"`
}

LinuxSpecific is used to store data specific to linux

type UBootOpts

type UBootOpts struct {
	// Common options like paths etc.
	CommonOpts

	// List of IDs this instance depends on
	// Example: [ "MyLittleCoreboot", "MyLittleEdk2"]
	Depends []string `json:"depends"`

	// Specifies target architecture, such as 'x86' or 'arm64'
	Arch string `json:"arch"`

	// Gives the (relative) path to the defconfig that should be used to build the target.
	DefconfigPath string `json:"defconfig_path" validate:"required,filepath"`
}

UBootOpts is used to store all data needed to build u-root

func (UBootOpts) GetArtifacts

func (opts UBootOpts) GetArtifacts() *[]container.Artifacts

GetArtifacts returns list of wanted artifacts from container

func (UBootOpts) GetDepends

func (opts UBootOpts) GetDepends() []string

GetDepends is used to return list of dependencies

type URootOpts

type URootOpts struct {
	// Common options like paths etc.
	CommonOpts

	// u-root specific options
	URootSpecific

	// List of IDs this instance depends on
	// Example: [ "MyLittleCoreboot", "MyLittleEdk2"]
	Depends []string `json:"depends"`
}

URootOpts is used to store all data needed to build u-root

func (URootOpts) GetArtifacts

func (opts URootOpts) GetArtifacts() *[]container.Artifacts

GetArtifacts returns list of wanted artifacts from container

func (URootOpts) GetDepends

func (opts URootOpts) GetDepends() []string

GetDepends is used to return list of dependencies

type URootSpecific

type URootSpecific struct {
	// Specifies build command to use
	BuildCommand string `json:"build_command" validate:"required"`
}

URootSpecific is used to store data specific to u-root ANCHOR: URootSpecific

type UniversalOpts

type UniversalOpts struct {
	// Common options like paths etc.
	CommonOpts

	// Universal specific options
	UniversalSpecific

	// List of IDs this instance depends on
	// Example: [ "MyLittleCoreboot", "MyLittleEdk2"]
	Depends []string `json:"depends"`
}

UniversalOpts is used to store all data needed to run universal commands

func (UniversalOpts) GetArtifacts

func (opts UniversalOpts) GetArtifacts() *[]container.Artifacts

GetArtifacts returns list of wanted artifacts from container

func (UniversalOpts) GetDepends

func (opts UniversalOpts) GetDepends() []string

GetDepends is used to return list of dependencies

type UniversalSpecific

type UniversalSpecific struct {
	// Specifies build commands to execute inside container
	BuildCommands []string `json:"build_commands" validate:"required"`
}

UniversalSpecific is used to store data specific to the universal command module ANCHOR: UniversalSpecific

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL