Skip to content

Commit

Permalink
Use BuildKit FDK (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
EricHripko authored May 1, 2021
1 parent 720642f commit 07986b4
Show file tree
Hide file tree
Showing 22 changed files with 292 additions and 1,712 deletions.
19 changes: 8 additions & 11 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,19 @@ module github.com/EricHripko/pack.yaml
go 1.15

require (
github.com/containerd/containerd v1.4.1-0.20201117152358-0edc412565dc
github.com/docker/distribution v2.7.1+incompatible
github.com/docker/docker v20.10.0-beta1.0.20201110211921-af34b94a78a1+incompatible
github.com/golang/mock v1.4.4
github.com/EricHripko/buildkit-fdk v0.0.2
github.com/containerd/containerd v1.4.4
github.com/golang/mock v1.5.0
github.com/mitchellh/mapstructure v1.3.1
github.com/moby/buildkit v0.8.1
github.com/opencontainers/go-digest v1.0.0
github.com/moby/buildkit v0.8.2
github.com/opencontainers/image-spec v1.0.1
github.com/pkg/errors v0.9.1
github.com/sirupsen/logrus v1.7.0
github.com/stretchr/testify v1.5.1
github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.7.0
github.com/tonistiigi/fsutil v0.0.0-20201103201449-0834f99b7b85
golang.org/x/mod v0.3.0
golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/sys v0.0.0-20210112080510-489259a85091 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d
gopkg.in/yaml.v2 v2.3.0
)
52 changes: 44 additions & 8 deletions go.sum

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions internal/app/packer-frontend/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import (
"fmt"
"strconv"

"github.com/EricHripko/pack.yaml/pkg/cib"
"github.com/EricHripko/pack.yaml/pkg/packer2llb"
"github.com/EricHripko/pack.yaml/pkg/packer2llb/config"

"github.com/EricHripko/buildkit-fdk/pkg/cib"
"github.com/containerd/containerd/platforms"
"github.com/moby/buildkit/exporter/containerimage/exptypes"
"github.com/moby/buildkit/frontend/gateway/client"
Expand Down Expand Up @@ -63,7 +64,7 @@ func BuildWithService(ctx context.Context, c client.Client, svc cib.Service) (*c
if err != nil {
return err
}
metadata, err := cib.ReadConfig(dtMetadata)
metadata, err := config.Read(dtMetadata)
if err != nil {
return err
}
Expand Down Expand Up @@ -106,7 +107,7 @@ func BuildWithService(ctx context.Context, c client.Client, svc cib.Service) (*c
} else {
// Find command
var cmd string
cmd, err = cib.FindCommand(ctx, ref)
cmd, err = findCommand(ctx, ref)
if err != nil {
return err
}
Expand Down
7 changes: 3 additions & 4 deletions internal/app/packer-frontend/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ import (
"path"
"testing"

"github.com/EricHripko/pack.yaml/pkg/cib"
cib_mock "github.com/EricHripko/pack.yaml/pkg/cib/mock"
"github.com/EricHripko/pack.yaml/pkg/packer2llb"
packer2llb_mock "github.com/EricHripko/pack.yaml/pkg/packer2llb/mock"

cib_mock "github.com/EricHripko/buildkit-fdk/pkg/cib/mock"
"github.com/golang/mock/gomock"
"github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb"
Expand Down Expand Up @@ -231,7 +230,7 @@ func (suite *singleTestSuite) TestFindCommandFails() {
_, err := BuildWithService(suite.ctx, suite.client, suite.build)

// Assert
require.Same(suite.T(), cib.ErrNoCommand, err)
require.Same(suite.T(), errNoCommand, err)
}

func (suite *singleTestSuite) TestSucceedsImplicitCommand() {
Expand All @@ -257,7 +256,7 @@ func (suite *singleTestSuite) TestSucceedsImplicitCommand() {

ref := cib_mock.NewMockReference(suite.ctrl)
files := []*fsutil.Stat{
{Path: path.Join(cib.DirInstall, "command"), Mode: 0755},
{Path: path.Join(packer2llb.DirInstall, "command"), Mode: 0755},
}
ref.EXPECT().
ReadDir(gomock.Any(), gomock.Any()).
Expand Down
3 changes: 3 additions & 0 deletions internal/app/packer-frontend/frontend.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Package frontend houses a custom BuildKit frontend for projects that use
// pack.yaml.
package frontend
47 changes: 47 additions & 0 deletions internal/app/packer-frontend/helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package frontend

import (
"context"
"errors"
"os"
"strings"

"github.com/EricHripko/pack.yaml/pkg/packer2llb"

"github.com/EricHripko/buildkit-fdk/pkg/cib"
"github.com/moby/buildkit/frontend/gateway/client"
fsutil "github.com/tonistiigi/fsutil/types"
)

// Returned when no command was found in the produced image.
var errNoCommand = errors.New("frontend: no command found")

// Looks in the known install directory and attempts to automatically detect
// the command for the image.
func findCommand(ctx context.Context, ref client.Reference) (command string, err error) {
prefix := packer2llb.DirInstall[1:]
err = cib.WalkRecursive(ctx, ref, func(file *fsutil.Stat) error {
// Must be in install location
if !strings.HasPrefix(file.Path, prefix) {
return nil
}
// Must not be a directory
if os.FileMode(file.Mode).IsDir() {
return nil
}
// Must be executable
if file.Mode&0100 == 0 {
return nil
}
// Multiple commands found
if command != "" {
return errors.New("frontend: multiple commands found (" + command + ")")
}
command = "/" + file.Path
return nil
})
if command == "" {
err = errNoCommand
}
return
}
139 changes: 139 additions & 0 deletions internal/app/packer-frontend/helper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package frontend

import (
"context"
"os"
"testing"

cib_mock "github.com/EricHripko/buildkit-fdk/pkg/cib/mock"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
fsutil "github.com/tonistiigi/fsutil/types"
)

type findCommandTestSuite struct {
suite.Suite
ctrl *gomock.Controller
ctx context.Context
ref *cib_mock.MockReference
}

func (suite *findCommandTestSuite) SetupTest() {
suite.ctrl = gomock.NewController(suite.T())
suite.ctx = context.Background()
suite.ref = cib_mock.NewMockReference(suite.ctrl)
}

func (suite *findCommandTestSuite) TearDownTest() {
suite.ctrl.Finish()
}

func (suite *findCommandTestSuite) TestNotFound() {
// Arrange
files := []*fsutil.Stat{}
suite.ref.EXPECT().
ReadDir(suite.ctx, gomock.Any()).
Return(files, nil)

// Act
cmd, err := findCommand(suite.ctx, suite.ref)

// Assert
require.Empty(suite.T(), cmd)
require.Same(suite.T(), errNoCommand, err)
}

func (suite *findCommandTestSuite) TestIgnoresNonPrefix() {
// Arrange
files := []*fsutil.Stat{
{Path: "README.md"},
}
suite.ref.EXPECT().
ReadDir(suite.ctx, gomock.Any()).
Return(files, nil)

// Act
cmd, err := findCommand(suite.ctx, suite.ref)

// Assert
require.Empty(suite.T(), cmd)
require.Same(suite.T(), errNoCommand, err)
}

func (suite *findCommandTestSuite) TestIgnoresDirs() {
// Arrange
files := []*fsutil.Stat{
{Path: "usr/local/bin/data", Mode: uint32(os.ModeDir)},
}
suite.ref.EXPECT().
ReadDir(suite.ctx, gomock.Any()).
Return(files, nil)
suite.ref.EXPECT().
ReadDir(suite.ctx, gomock.Any()).
Return([]*fsutil.Stat{}, nil)

// Act
cmd, err := findCommand(suite.ctx, suite.ref)

// Assert
require.Empty(suite.T(), cmd)
require.Same(suite.T(), errNoCommand, err)
}

func (suite *findCommandTestSuite) TestIgnoresNonExecutable() {
// Arrange
files := []*fsutil.Stat{
{Path: "usr/local/bin/README.md"},
}
suite.ref.EXPECT().
ReadDir(suite.ctx, gomock.Any()).
Return(files, nil)

// Act
cmd, err := findCommand(suite.ctx, suite.ref)

// Assert
require.Empty(suite.T(), cmd)
require.Same(suite.T(), errNoCommand, err)
}

func (suite *findCommandTestSuite) TestMultipleCommands() {
// Arrange
files := []*fsutil.Stat{
{Path: "usr/local/bin/hello1", Mode: 0755},
{Path: "usr/local/bin/hello2", Mode: 0755},
}
suite.ref.EXPECT().
ReadDir(suite.ctx, gomock.Any()).
Return(files, nil)

// Act
_, err := findCommand(suite.ctx, suite.ref)

// Assert
require.NotNil(suite.T(), err)
require.Contains(suite.T(), err.Error(), "multiple commands")
require.Contains(suite.T(), err.Error(), files[0].Path)
}

func (suite *findCommandTestSuite) TestSucceeds() {
// Arrange
files := []*fsutil.Stat{
{Path: "usr/local/bin/hello", Mode: 0755},
}
suite.ref.EXPECT().
ReadDir(suite.ctx, gomock.Any()).
Return(files, nil)

// Act
cmd, err := findCommand(suite.ctx, suite.ref)

// Assert
require.Equal(suite.T(), "/usr/local/bin/hello", cmd)
require.Nil(suite.T(), err)
}

func TestFindCommand(t *testing.T) {
suite.Run(t, new(findCommandTestSuite))
}
53 changes: 0 additions & 53 deletions pkg/cib/cib.go

This file was deleted.

Loading

0 comments on commit 07986b4

Please sign in to comment.