Skip to content

Commit

Permalink
refactor(action): add buildFirmware methods
Browse files Browse the repository at this point in the history
- add DockerOutputDirs and DockerOutputFiles to CommonOpts to give
  higher control to users (required needed for Intel FSP)
- add GetArtifacts methods to simplify code and accommodate use of
  DockerOutputDirs and DockerOutputFiles
  • Loading branch information
AtomicFS committed Jan 31, 2024
1 parent 8fca0aa commit 7457ad2
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 104 deletions.
51 changes: 51 additions & 0 deletions action/recipes/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
package recipes

import (
"context"
"encoding/json"
"log"
"os"
"path/filepath"

"dagger.io/dagger"
"github.com/9elements/firmware-action/action/container"
"github.com/go-playground/validator/v10"
)

Expand Down Expand Up @@ -52,12 +56,57 @@ type CommonOpts struct {
// had been previously checked out.
RepoPath string `json:"repo_path" validate:"required,dirpath"`

// Specifies the (relative) paths to directories where are produced files (inside Docker).
DockerOutputDirs []string `json:"docker_output_dirs" validate:"dive,dirpath"`

// Specifies the (relative) paths to produced files (inside Docker).
DockerOutputFiles []string `json:"docker_output_files" validate:"dive,filepath"`

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

// ANCHOR_END: CommonOpts

// GetArtifacts returns list of wanted artifacts from container
func (opts CommonOpts) GetArtifacts() *[]container.Artifacts {
var artifacts []container.Artifacts

// Directories
for _, pathDir := range opts.DockerOutputDirs {
artifacts = append(artifacts, container.Artifacts{
ContainerPath: filepath.Join(ContainerWorkDir, pathDir),
ContainerDir: true,
HostPath: opts.OutputDir,
HostDir: true,
})
}

// Files
for _, pathFile := range opts.DockerOutputFiles {
artifacts = append(artifacts, container.Artifacts{
ContainerPath: filepath.Join(ContainerWorkDir, pathFile),
ContainerDir: false,
HostPath: opts.OutputDir,
HostDir: true,
})
}

return &artifacts
}

// Config is for storing parsed configuration file
type Config struct {
// defined in coreboot.go
Expand Down Expand Up @@ -88,6 +137,8 @@ func (c Config) AllModules() map[string]FirmwareModule {
// FirmwareModule interface
type FirmwareModule interface {
GetDepends() []string
GetArtifacts() *[]container.Artifacts
buildFirmware(ctx context.Context, client *dagger.Client, dockerfileDirectoryPath string) error
}

// ===========
Expand Down
12 changes: 9 additions & 3 deletions action/recipes/coreboot.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ func (opts CorebootOpts) GetDepends() []string {
return opts.Depends
}

// GetArtifacts returns list of wanted artifacts from container
func (opts CorebootOpts) GetArtifacts() *[]container.Artifacts {
return opts.CommonOpts.GetArtifacts()
}

// corebootProcessBlobs is used to fill figure out blobs from provided data.
func corebootProcessBlobs(opts CorebootBlobs) ([]BlobDef, error) {
blobMap := map[string]BlobDef{
Expand Down Expand Up @@ -188,8 +193,8 @@ func corebootProcessBlobs(opts CorebootBlobs) ([]BlobDef, error) {
return blobs, nil
}

// coreboot builds coreboot with all blobs and stuff.
func coreboot(ctx context.Context, client *dagger.Client, opts *CorebootOpts, dockerfileDirectoryPath string, artifacts *[]container.Artifacts) error {
// buildFirmware builds coreboot with all blobs and stuff
func (opts CorebootOpts) buildFirmware(ctx context.Context, client *dagger.Client, dockerfileDirectoryPath string) error {
// Spin up container
containerOpts := container.SetupOpts{
ContainerURL: opts.SdkURL,
Expand Down Expand Up @@ -311,7 +316,8 @@ func coreboot(ctx context.Context, client *dagger.Client, opts *CorebootOpts, do
return fmt.Errorf("coreboot build failed: %w", err)
}
}
log.Print(opts.CommonOpts.GetArtifacts())

// Extract artifacts
return container.GetArtifacts(ctx, myContainer, artifacts)
return container.GetArtifacts(ctx, myContainer, opts.CommonOpts.GetArtifacts())
}
22 changes: 6 additions & 16 deletions action/recipes/coreboot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"testing"

"dagger.io/dagger"
"github.com/9elements/firmware-action/action/container"
"github.com/9elements/firmware-action/action/filesystem"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -67,6 +66,10 @@ func TestCoreboot(t *testing.T) {
common := CommonOpts{
Arch: "x86",
OutputDir: "output",
DockerOutputFiles: []string{
"build/coreboot.rom",
"defconfig",
},
}

testCases := []struct {
Expand Down Expand Up @@ -152,28 +155,15 @@ func TestCoreboot(t *testing.T) {
outputPath := filepath.Join(tmpDir, tc.corebootOptions.OutputDir)
err = os.MkdirAll(outputPath, os.ModePerm)
assert.NoError(t, err)
artifacts := []container.Artifacts{
{
ContainerPath: filepath.Join(ContainerWorkDir, "build", "coreboot.rom"),
ContainerDir: false,
HostPath: outputPath,
HostDir: true,
},
{
ContainerPath: filepath.Join(ContainerWorkDir, "defconfig"),
ContainerDir: false,
HostPath: outputPath,
HostDir: true,
},
}
tc.corebootOptions.OutputDir = outputPath

// Prep
for cmd := range tc.cmds {
err = exec.Command(tc.cmds[cmd][0], tc.cmds[cmd][1:]...).Run()
assert.NoError(t, err)
}
// Try to build coreboot
err = coreboot(ctx, client, &tc.corebootOptions, "", &artifacts)
err = tc.corebootOptions.buildFirmware(ctx, client, "")
assert.ErrorIs(t, err, tc.wantErr)

// Check artifacts
Expand Down
11 changes: 8 additions & 3 deletions action/recipes/edk2.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,13 @@ func (opts Edk2Opts) GetDepends() []string {
return opts.Depends
}

// edk2 builds edk2
func edk2(ctx context.Context, client *dagger.Client, opts *Edk2Opts, dockerfileDirectoryPath string, artifacts *[]container.Artifacts) error {
// GetArtifacts returns list of wanted artifacts from container
func (opts Edk2Opts) GetArtifacts() *[]container.Artifacts {
return opts.CommonOpts.GetArtifacts()
}

// buildFirmware builds edk2 or Intel FSP
func (opts Edk2Opts) buildFirmware(ctx context.Context, client *dagger.Client, dockerfileDirectoryPath string) error {
envVars := map[string]string{
"WORKSPACE": ContainerWorkDir,
"EDK_TOOLS_PATH": "/tools/Edk2/BaseTools",
Expand Down Expand Up @@ -161,5 +166,5 @@ func edk2(ctx context.Context, client *dagger.Client, opts *Edk2Opts, dockerfile
}

// Extract artifacts
return container.GetArtifacts(ctx, myContainer, artifacts)
return container.GetArtifacts(ctx, myContainer, opts.GetArtifacts())
}
19 changes: 6 additions & 13 deletions action/recipes/edk2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"testing"

"dagger.io/dagger"
"github.com/9elements/firmware-action/action/container"
"github.com/stretchr/testify/assert"
)

Expand All @@ -34,9 +33,10 @@ func TestEdk2(t *testing.T) {
}

common := CommonOpts{
SdkURL: "ghcr.io/9elements/firmware-action/edk2-stable202105:main",
Arch: "X64",
OutputDir: "output",
SdkURL: "ghcr.io/9elements/firmware-action/edk2-stable202105:main",
Arch: "X64",
OutputDir: "output",
DockerOutputDirs: []string{"Build/"},
}

testCases := []struct {
Expand Down Expand Up @@ -105,17 +105,10 @@ func TestEdk2(t *testing.T) {
outputPath := filepath.Join(tmpDir, tc.edk2Options.OutputDir)
err = os.MkdirAll(outputPath, os.ModePerm)
assert.NoError(t, err)
artifacts := []container.Artifacts{
{
ContainerPath: filepath.Join(ContainerWorkDir, "Build"),
ContainerDir: true,
HostPath: outputPath,
HostDir: true,
},
}
tc.edk2Options.OutputDir = outputPath

// Try to build edk2
err = edk2(ctx, client, &tc.edk2Options, dockerfilePath, &artifacts)
err = tc.edk2Options.buildFirmware(ctx, client, dockerfilePath)
assert.NoError(t, err)

// Check artifacts
Expand Down
11 changes: 8 additions & 3 deletions action/recipes/linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,15 @@ func (opts LinuxOpts) GetDepends() []string {
return opts.Depends
}

// linux builds linux kernel
// GetArtifacts returns list of wanted artifacts from container
func (opts LinuxOpts) GetArtifacts() *[]container.Artifacts {
return opts.CommonOpts.GetArtifacts()
}

// buildFirmware builds linux kernel
//
// docs: https://www.kernel.org/doc/html/latest/kbuild/index.html
func linux(ctx context.Context, client *dagger.Client, opts *LinuxOpts, dockerfileDirectoryPath string, artifacts *[]container.Artifacts) error {
func (opts LinuxOpts) buildFirmware(ctx context.Context, client *dagger.Client, dockerfileDirectoryPath string) error {
// Spin up container
containerOpts := container.SetupOpts{
ContainerURL: opts.SdkURL,
Expand Down Expand Up @@ -142,5 +147,5 @@ func linux(ctx context.Context, client *dagger.Client, opts *LinuxOpts, dockerfi
}

// Extract artifacts
return container.GetArtifacts(ctx, myContainer, artifacts)
return container.GetArtifacts(ctx, myContainer, opts.GetArtifacts())
}
22 changes: 6 additions & 16 deletions action/recipes/linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"testing"

"dagger.io/dagger"
"github.com/9elements/firmware-action/action/container"
"github.com/9elements/firmware-action/action/filesystem"
"github.com/Masterminds/semver"
"github.com/stretchr/testify/assert"
Expand All @@ -40,6 +39,10 @@ func TestLinux(t *testing.T) {
linuxOpts := LinuxOpts{
CommonOpts: CommonOpts{
OutputDir: "output",
DockerOutputFiles: []string{
"vmlinux",
"defconfig",
},
},
DefconfigPath: "custom_defconfig",
}
Expand Down Expand Up @@ -145,23 +148,10 @@ func TestLinux(t *testing.T) {
outputPath := filepath.Join(tmpDir, myLinuxOpts.OutputDir)
err = os.MkdirAll(outputPath, os.ModePerm)
assert.NoError(t, err)
artifacts := []container.Artifacts{
{
ContainerPath: filepath.Join(ContainerWorkDir, "vmlinux"),
ContainerDir: false,
HostPath: outputPath,
HostDir: true,
},
{
ContainerPath: filepath.Join(ContainerWorkDir, "defconfig"),
ContainerDir: false,
HostPath: outputPath,
HostDir: true,
},
}
myLinuxOpts.OutputDir = outputPath

// Try to build linux kernel
err = linux(ctx, client, &myLinuxOpts, dockerfilePath, &artifacts)
err = myLinuxOpts.buildFirmware(ctx, client, dockerfilePath)
assert.ErrorIs(t, err, tc.wantErr)

// Check artifacts
Expand Down
53 changes: 3 additions & 50 deletions action/recipes/recipes.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@ import (
"fmt"
"log"
"os"
"path/filepath"
"slices"
"sync"

"dagger.io/dagger"
"github.com/9elements/firmware-action/action/container"
"github.com/heimdalr/dag"
)

Expand Down Expand Up @@ -121,54 +119,9 @@ func Execute(ctx context.Context, target string, config Config) error {
defer client.Close()

// Find requested target
if _, ok := config.Coreboot[target]; ok {
// Coreboot
opts := config.Coreboot[target]
artifacts := []container.Artifacts{
{
ContainerPath: filepath.Join(ContainerWorkDir, "build", "coreboot.rom"),
ContainerDir: false,
HostPath: config.Coreboot[target].OutputDir,
HostDir: true,
},
{
ContainerPath: filepath.Join(ContainerWorkDir, "defconfig"),
ContainerDir: false,
HostPath: config.Coreboot[target].OutputDir,
HostDir: true,
},
}
return coreboot(ctx, client, &opts, "", &artifacts)
} else if _, ok = config.Linux[target]; ok {
// Linux
opts := config.Linux[target]
artifacts := []container.Artifacts{
{
ContainerPath: filepath.Join(ContainerWorkDir, "vmlinux"),
ContainerDir: false,
HostPath: config.Linux[target].OutputDir,
HostDir: true,
},
{
ContainerPath: filepath.Join(ContainerWorkDir, "defconfig"),
ContainerDir: false,
HostPath: config.Linux[target].OutputDir,
HostDir: true,
},
}
return linux(ctx, client, &opts, "", &artifacts)
} else if _, ok = config.Edk2[target]; ok {
// Edk2
opts := config.Edk2[target]
artifacts := []container.Artifacts{
{
ContainerPath: filepath.Join(ContainerWorkDir, "Build"),
ContainerDir: true,
HostPath: config.Edk2[target].OutputDir,
HostDir: true,
},
}
return edk2(ctx, client, &opts, "", &artifacts)
modules := config.AllModules()
if _, ok := modules[target]; ok {
return modules[target].buildFirmware(ctx, client, "")
}
return ErrTargetMissing
}

0 comments on commit 7457ad2

Please sign in to comment.