diff --git a/cmd/porter/bundle.go b/cmd/porter/bundle.go index 4d69673ef4..5438c46087 100644 --- a/cmd/porter/bundle.go +++ b/cmd/porter/bundle.go @@ -81,7 +81,10 @@ Porter uses the docker driver as the default build driver, an alternate driver m "Path to the build context directory where all bundle assets are located.") f.StringVar(&opts.Driver, "driver", porter.BuildDriverDefault, fmt.Sprintf("Experimental. Driver for building the invocation image. Allowed values are: %s", strings.Join(porter.BuildDriverAllowedValues, ", "))) - + f.StringSliceVar(&opts.SSH, "ssh", nil, + "SSH agent socket or keys to expose to the build (format: default|[=|[,]]). May be specified multiple times.") + f.StringArrayVar(&opts.Secrets, "secret", nil, + "Secret file to expose to the build (format: id=mysecret,src=/local/secret). May be specified multiple times.") // Allow configuring the --driver flag with build-driver, to avoid conflicts with other commands cmd.Flag("driver").Annotations = map[string][]string{ "viper-key": {"build-driver"}, diff --git a/docs/content/cli/build.md b/docs/content/cli/build.md index 5539bb047e..42bb2ae0e0 100644 --- a/docs/content/cli/build.md +++ b/docs/content/cli/build.md @@ -32,14 +32,16 @@ porter build [flags] ### Options ``` - -d, --dir string Path to the build context directory where all bundle assets are located. - --driver string Experimental. Driver for building the invocation image. Allowed values are: docker, buildkit (default "docker") - -f, --file porter.yaml Path to the Porter manifest. Defaults to porter.yaml in the current directory. - -h, --help help for build - --name string Override the bundle name - --no-lint Do not run the linter - -v, --verbose Enable verbose logging - --version string Override the bundle version + -d, --dir string Path to the build context directory where all bundle assets are located. + --driver string Experimental. Driver for building the invocation image. Allowed values are: buildkit (default "buildkit") + -f, --file porter.yaml Path to the Porter manifest. Defaults to porter.yaml in the current directory. + -h, --help help for build + --name string Override the bundle name + --no-lint Do not run the linter + --secret stringArray Secret file to expose to the build (format: id=mysecret,src=/local/secret). May be specified multiple times. + --ssh strings SSH agent socket or keys to expose to the build (format: default|[=|[,]]). May be specified multiple times. + -v, --verbose Enable verbose logging + --version string Override the bundle version ``` ### Options inherited from parent commands diff --git a/docs/content/cli/bundles_build.md b/docs/content/cli/bundles_build.md index 90a4a0762c..df2105612c 100644 --- a/docs/content/cli/bundles_build.md +++ b/docs/content/cli/bundles_build.md @@ -32,14 +32,16 @@ porter bundles build [flags] ### Options ``` - -d, --dir string Path to the build context directory where all bundle assets are located. - --driver string Experimental. Driver for building the invocation image. Allowed values are: docker, buildkit (default "docker") - -f, --file porter.yaml Path to the Porter manifest. Defaults to porter.yaml in the current directory. - -h, --help help for build - --name string Override the bundle name - --no-lint Do not run the linter - -v, --verbose Enable verbose logging - --version string Override the bundle version + -d, --dir string Path to the build context directory where all bundle assets are located. + --driver string Experimental. Driver for building the invocation image. Allowed values are: buildkit (default "buildkit") + -f, --file porter.yaml Path to the Porter manifest. Defaults to porter.yaml in the current directory. + -h, --help help for build + --name string Override the bundle name + --no-lint Do not run the linter + --secret stringArray Secret file to expose to the build (format: id=mysecret,src=/local/secret). May be specified multiple times. + --ssh strings SSH agent socket or keys to expose to the build (format: default|[=|[,]]). May be specified multiple times. + -v, --verbose Enable verbose logging + --version string Override the bundle version ``` ### Options inherited from parent commands diff --git a/examples/private-assets/.dockerignore b/examples/private-assets/.dockerignore new file mode 100644 index 0000000000..89ad1ef6d6 --- /dev/null +++ b/examples/private-assets/.dockerignore @@ -0,0 +1,5 @@ +# See https://docs.docker.com/engine/reference/builder/#dockerignore-file +# Put files here that you don't want copied into your bundle's invocation image +.gitignore +Dockerfile.tmpl +secrets/ \ No newline at end of file diff --git a/examples/private-assets/.gitignore b/examples/private-assets/.gitignore new file mode 100644 index 0000000000..e08a3e22b9 --- /dev/null +++ b/examples/private-assets/.gitignore @@ -0,0 +1 @@ +.cnab/ diff --git a/examples/private-assets/README.md b/examples/private-assets/README.md new file mode 100644 index 0000000000..dd45c52276 --- /dev/null +++ b/examples/private-assets/README.md @@ -0,0 +1,33 @@ +# Bundle with Private Assets + +Sometimes you need to include assets from secured locations, such as a private repository in your bundle. +You can use the \--secret flag to pass secrets into the bundle when it is built. + +## Try it out +1. Edit secrets/token and replace the contents with a [GitHub Personal Access Token](https://github.com/settings/tokens). + The permissions do not matter for this sample bundle. + There should not be a newline at the end of the file. + +1. Build the bundle and pass the secret into the bundle with \--secret + ``` + porter build --secret id=token,src=secrets/token + ``` + +1. Install the bundle to see the private assets embedded in the bundle + ``` + $ porter install example-private-assets --reference ghcr.io/getporter/examples/private-assets:v0.1.0 + __________________________ + < yarr, I'm a secret whale > + -------------------------- + \ + \ + \ + ## . + ## ## ## == + ## ## ## ## === + /""""""""""""""""___/ === + ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~ + \______ o __/ + \ \ __/ + \____\______/ + ``` diff --git a/examples/private-assets/check-secrets.sh b/examples/private-assets/check-secrets.sh new file mode 100755 index 0000000000..df916d015e --- /dev/null +++ b/examples/private-assets/check-secrets.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [[ ! -f "/run/secrets/token" ]]; then + echo "You forgot to use --secret id=token,src=secrets/token" + exit 1 +fi diff --git a/examples/private-assets/helpers.sh b/examples/private-assets/helpers.sh new file mode 100755 index 0000000000..788fee5544 --- /dev/null +++ b/examples/private-assets/helpers.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -euo pipefail + +install() { + echo Hello World +} + +upgrade() { + echo World 2.0 +} + +uninstall() { + echo Goodbye World +} + +# Call the requested function and pass the arguments as-is +"$@" diff --git a/examples/private-assets/porter.yaml b/examples/private-assets/porter.yaml new file mode 100644 index 0000000000..e4a92fccfb --- /dev/null +++ b/examples/private-assets/porter.yaml @@ -0,0 +1,28 @@ +schemaVersion: 1.0.0-alpha.1 + +name: private-assets +version: 0.1.0 +description: "Example bundle that contains private assets and prints it when run" +registry: ghcr.io/getporter/examples/ +dockerfile: template.Dockerfile + +mixins: + - exec + +install: + - exec: + command: cat + arguments: + - /secret + +upgrade: + - exec: + command: cat + arguments: + - /secret + +uninstall: + - exec: + command: cat + arguments: + - /secret diff --git a/examples/private-assets/secret b/examples/private-assets/secret new file mode 100644 index 0000000000..113e3ac0e1 --- /dev/null +++ b/examples/private-assets/secret @@ -0,0 +1,14 @@ + __________________________ +< yarr, I'm a secret whale > + -------------------------- + \ + \ + \ + ## . + ## ## ## == + ## ## ## ## === + /""""""""""""""""___/ === + ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~ + \______ o __/ + \ \ __/ + \____\______/ \ No newline at end of file diff --git a/examples/private-assets/secrets/token b/examples/private-assets/secrets/token new file mode 100644 index 0000000000..d947261bab --- /dev/null +++ b/examples/private-assets/secrets/token @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/examples/private-assets/template.Dockerfile b/examples/private-assets/template.Dockerfile new file mode 100644 index 0000000000..7a8a22407b --- /dev/null +++ b/examples/private-assets/template.Dockerfile @@ -0,0 +1,19 @@ +# syntax=docker/dockerfile-upstream:1.4.0-rc2 +FROM debian:stretch-slim + +# PORTER_INIT + +RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache +RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/var/lib/apt \ + apt-get update && apt-get install -y ca-certificates curl + +# PORTER_MIXINS + +# Use the BUNDLE_DIR build argument to copy files into the bundle's working directory +COPY --link . ${BUNDLE_DIR} + +# Check the secret was passed to the build command +RUN --mount=type=secret,id=token /cnab/app/check-secrets.sh + +# Use the injected secrets to build private assets into the bundle +RUN --mount=type=secret,id=token curl -O https://$(cat /run/secrets/token)@gist.githubusercontent.com/carolynvs/860a0d26de3af1468d290a075a91aac9/raw/c53223acd284830e8f541cf35eba94dde0ddf75d/secret diff --git a/go.mod b/go.mod index ff88fe077d..c8f8499e13 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,6 @@ require ( github.com/mitchellh/mapstructure v1.3.3 github.com/mmcdole/gofeed v1.0.0-beta2 github.com/moby/buildkit v0.9.0 - github.com/moby/term v0.0.0-20210610120745-9d4ed1856297 github.com/olekukonko/tablewriter v0.0.4 github.com/opencontainers/go-digest v1.0.0 github.com/osteele/liquid v1.3.0 @@ -148,7 +147,7 @@ require ( github.com/moby/locker v1.0.1 // indirect github.com/moby/sys/mount v0.2.0 // indirect github.com/moby/sys/mountinfo v0.6.0 // indirect - github.com/moby/sys/symlink v0.2.0 // indirect + github.com/moby/term v0.0.0-20210610120745-9d4ed1856297 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/morikuni/aec v1.0.0 // indirect diff --git a/go.sum b/go.sum index 1bcbeeea74..a636b74be4 100644 --- a/go.sum +++ b/go.sum @@ -1151,7 +1151,6 @@ github.com/moby/sys/mountinfo v0.6.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdx github.com/moby/sys/signal v0.6.0 h1:aDpY94H8VlhTGa9sNYUFCFsMZIUh5wm0B6XkIoJj/iY= github.com/moby/sys/signal v0.6.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= -github.com/moby/sys/symlink v0.2.0 h1:tk1rOM+Ljp0nFmfOIBtlV3rTDlWOwFRhjEeAhZB0nZc= github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= github.com/moby/term v0.0.0-20200915141129-7f0af18e79f2/go.mod h1:TjQg8pa4iejrUrjiz0MCtMV38jdMNW4doKSiBrEvCQQ= diff --git a/pkg/build/build.go b/pkg/build/build.go index e5c97686d0..d8dbd69cca 100644 --- a/pkg/build/build.go +++ b/pkg/build/build.go @@ -44,8 +44,13 @@ var ( type Builder interface { // BuildInvocationImage using the bundle in the build context directory - BuildInvocationImage(ctx context.Context, manifest *manifest.Manifest) error + BuildInvocationImage(ctx context.Context, manifest *manifest.Manifest, opts BuildKitOptions) error // TagInvocationImage using the origTag and newTag values supplied TagInvocationImage(ctx context.Context, origTag, newTag string) error } + +type BuildKitOptions struct { + SSH []string + Secrets []string +} diff --git a/pkg/build/buildkit/buildx.go b/pkg/build/buildkit/buildx.go index f862d3c33b..464d665c28 100644 --- a/pkg/build/buildkit/buildx.go +++ b/pkg/build/buildkit/buildx.go @@ -59,7 +59,7 @@ func (l unstructuredLogger) Write(p []byte) (n int, err error) { return len(p), nil } -func (b *Builder) BuildInvocationImage(ctx context.Context, manifest *manifest.Manifest) error { +func (b *Builder) BuildInvocationImage(ctx context.Context, manifest *manifest.Manifest, opts build.BuildKitOptions) error { ctx, log := tracing.StartSpan(ctx, attribute.String("image", manifest.Image)) defer log.EndSpan() @@ -85,7 +85,20 @@ func (b *Builder) BuildInvocationImage(ctx context.Context, manifest *manifest.M }, } - opts := map[string]buildx.Options{ + session := []session.Attachable{authprovider.NewDockerAuthProvider(b.Err)} + ssh, err := buildx.ParseSSHSpecs(opts.SSH) + if err != nil { + return errors.Wrap(err, "error parsing the --ssh flags") + } + session = append(session, ssh) + + secrets, err := buildx.ParseSecretSpecs(opts.Secrets) + if err != nil { + return errors.Wrap(err, "error parsing the --secret flags") + } + session = append(session, secrets) + + buildxOpts := map[string]buildx.Options{ "default": { Tags: []string{manifest.Image}, Inputs: buildx.Inputs{ @@ -96,7 +109,7 @@ func (b *Builder) BuildInvocationImage(ctx context.Context, manifest *manifest.M BuildArgs: map[string]string{ "BUNDLE_DIR": build.BUNDLE_DIR, }, - Session: []session.Attachable{authprovider.NewDockerAuthProvider(b.Err)}, + Session: session, }, } @@ -114,7 +127,7 @@ func (b *Builder) BuildInvocationImage(ctx context.Context, manifest *manifest.M defer dockerOut.Close() printer := progress.NewPrinter(ctx, dockerOut, "auto") - _, buildErr := buildx.Build(ctx, drivers, opts, dockerToBuildx{cli}, cli.ConfigFile(), printer) + _, buildErr := buildx.Build(ctx, drivers, buildxOpts, dockerToBuildx{cli}, cli.ConfigFile(), printer) printErr := printer.Wait() if buildErr == nil { diff --git a/pkg/build/docker/doc.go b/pkg/build/docker/doc.go deleted file mode 100644 index 1cdc3ff910..0000000000 --- a/pkg/build/docker/doc.go +++ /dev/null @@ -1 +0,0 @@ -package docker diff --git a/pkg/build/docker/docker.go b/pkg/build/docker/docker.go deleted file mode 100644 index c440bd6523..0000000000 --- a/pkg/build/docker/docker.go +++ /dev/null @@ -1,102 +0,0 @@ -package docker - -import ( - "context" - "fmt" - "io/ioutil" - "path/filepath" - - "get.porter.sh/porter/pkg/build" - "get.porter.sh/porter/pkg/manifest" - "get.porter.sh/porter/pkg/portercontext" - "get.porter.sh/porter/pkg/tracing" - "github.com/docker/cli/cli/command" - clibuild "github.com/docker/cli/cli/command/image/build" - cliflags "github.com/docker/cli/cli/flags" - "github.com/docker/docker/api/types" - "github.com/docker/docker/pkg/archive" - "github.com/docker/docker/pkg/jsonmessage" - "github.com/moby/term" - "github.com/pkg/errors" -) - -type Builder struct { - *portercontext.Context -} - -func NewBuilder(cxt *portercontext.Context) *Builder { - return &Builder{ - Context: cxt, - } -} - -func (b *Builder) BuildInvocationImage(ctx context.Context, manifest *manifest.Manifest) error { - fmt.Fprintf(b.Out, "\nStarting Invocation Image Build (%s) =======> \n", manifest.Image) - buildOptions := types.ImageBuildOptions{ - SuppressOutput: false, - PullParent: false, - Remove: true, - Tags: []string{manifest.Image}, - Dockerfile: filepath.ToSlash(build.DOCKER_FILE), - BuildArgs: map[string]*string{ - "BUNDLE_DIR": &build.BUNDLE_DIR, - }, - } - - excludes, err := clibuild.ReadDockerignore(b.Getwd()) - if err != nil { - return err - } - excludes = clibuild.TrimBuildFilesFromExcludes(excludes, buildOptions.Dockerfile, false) - - tar, err := archive.TarWithOptions(b.Getwd(), &archive.TarOptions{ExcludePatterns: excludes}) - if err != nil { - return err - } - - cli, err := command.NewDockerCli() - if err != nil { - return errors.Wrap(err, "could not create new docker client") - } - if err := cli.Initialize(cliflags.NewClientOptions()); err != nil { - return err - } - - response, err := cli.Client().ImageBuild(ctx, tar, buildOptions) - if err != nil { - return err - } - - dockerOutput := ioutil.Discard - if b.IsVerbose() { - dockerOutput = b.Out - } - - termFd, _ := term.GetFdInfo(dockerOutput) - // Setting this to false here because Moby os.Exit(1) all over the place and this fails on WSL (only) - // when Term is true. - isTerm := false - err = jsonmessage.DisplayJSONMessagesStream(response.Body, dockerOutput, termFd, isTerm, nil) - if err != nil { - return errors.Wrap(err, "failed to stream docker build output") - } - return nil -} - -func (b *Builder) TagInvocationImage(ctx context.Context, origTag, newTag string) error { - ctx, log := tracing.StartSpan(ctx) - defer log.EndSpan() - - cli, err := command.NewDockerCli() - if err != nil { - return errors.Wrap(err, "could not create new docker client") - } - if err := cli.Initialize(cliflags.NewClientOptions()); err != nil { - return err - } - - if err := cli.Client().ImageTag(ctx, origTag, newTag); err != nil { - return errors.Wrapf(err, "could not tag image %s with value %s", origTag, newTag) - } - return nil -} diff --git a/pkg/config/config.go b/pkg/config/config.go index 9b0ca8140e..edde60fd71 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -273,10 +273,7 @@ func (c *Config) SetExperimentalFlags(flags experimental.FeatureFlags) { // into account experimental flags. // Use this instead of Config.Data.BuildDriver directly. func (c *Config) GetBuildDriver() string { - if c.IsFeatureEnabled(experimental.FlagBuildDrivers) { - return c.Data.BuildDriver - } - return BuildDriverDocker + return BuildDriverBuildkit } // Load loads the configuration file, rendering any templating used in the config file diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 9d5fa122f6..0245f418ef 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -85,8 +85,8 @@ func TestConfigExperimentalFlags(t *testing.T) { func TestConfig_GetBuildDriver(t *testing.T) { c := NewTestConfig(t) - c.Data.BuildDriver = BuildDriverBuildkit - require.Equal(t, BuildDriverDocker, c.GetBuildDriver(), "Default to docker when experimental is false, even when a build driver is set") + c.Data.BuildDriver = "special" + require.Equal(t, BuildDriverBuildkit, c.GetBuildDriver(), "Default to docker when experimental is false, even when a build driver is set") c.SetExperimentalFlags(experimental.FlagBuildDrivers) require.Equal(t, BuildDriverBuildkit, c.GetBuildDriver(), "Use the specified driver when the build driver feature is enabled") diff --git a/pkg/config/datastore.go b/pkg/config/datastore.go index 0c99ba6450..f3b5e17f86 100644 --- a/pkg/config/datastore.go +++ b/pkg/config/datastore.go @@ -1,7 +1,11 @@ package config const ( - BuildDriverDocker = "docker" + // BuildDriverDocker is no longer supported. + BuildDriverDocker = "docker" + + // BuildDriverBuildkit is the configuration value for specifying BuildKit as + // the build driver. BuildDriverBuildkit = "buildkit" ) @@ -60,7 +64,7 @@ type Data struct { // DefaultDataStore used when no config file is found. func DefaultDataStore() Data { return Data{ - BuildDriver: BuildDriverDocker, + BuildDriver: BuildDriverBuildkit, DefaultStoragePlugin: "mongodb-docker", DefaultSecretsPlugin: "host", Logs: LogConfig{Level: "info"}, diff --git a/pkg/porter/build.go b/pkg/porter/build.go index fafb0b2ca9..0f62994475 100644 --- a/pkg/porter/build.go +++ b/pkg/porter/build.go @@ -22,6 +22,7 @@ type BuildOptions struct { bundleFileOptions contextOptions metadataOpts + build.BuildKitOptions // NoLint indicates if lint should be run before build. NoLint bool @@ -30,9 +31,9 @@ type BuildOptions struct { Driver string } -const BuildDriverDefault = config.BuildDriverDocker +const BuildDriverDefault = config.BuildDriverBuildkit -var BuildDriverAllowedValues = []string{config.BuildDriverDocker, config.BuildDriverBuildkit} +var BuildDriverAllowedValues = []string{config.BuildDriverBuildkit} func (o *BuildOptions) Validate(p *Porter) error { if o.Version != "" { @@ -120,8 +121,8 @@ func (p *Porter) Build(ctx context.Context, opts BuildOptions) error { return fmt.Errorf("unable to generate Dockerfile: %s", err) } - builder := p.GetBuilder() - return errors.Wrap(builder.BuildInvocationImage(ctx, m), "unable to build CNAB invocation image") + builder := p.GetBuilder(ctx) + return errors.Wrap(builder.BuildInvocationImage(ctx, m, opts.BuildKitOptions), "unable to build CNAB invocation image") } func (p *Porter) preLint() error { diff --git a/pkg/porter/helpers.go b/pkg/porter/helpers.go index 7e674ae7c7..2105f917f0 100644 --- a/pkg/porter/helpers.go +++ b/pkg/porter/helpers.go @@ -10,6 +10,7 @@ import ( "testing" "time" + "get.porter.sh/porter/pkg/build" "get.porter.sh/porter/pkg/cache" "get.porter.sh/porter/pkg/claims" "get.porter.sh/porter/pkg/cnab" @@ -232,7 +233,7 @@ func NewTestBuildProvider() *TestBuildProvider { return &TestBuildProvider{} } -func (t *TestBuildProvider) BuildInvocationImage(ctx context.Context, manifest *manifest.Manifest) error { +func (t *TestBuildProvider) BuildInvocationImage(ctx context.Context, manifest *manifest.Manifest, opts build.BuildKitOptions) error { return nil } diff --git a/pkg/porter/porter.go b/pkg/porter/porter.go index afbf22a486..cacf4b0f3d 100644 --- a/pkg/porter/porter.go +++ b/pkg/porter/porter.go @@ -7,7 +7,6 @@ import ( "get.porter.sh/porter/pkg/build" "get.porter.sh/porter/pkg/build/buildkit" - "get.porter.sh/porter/pkg/build/docker" "get.porter.sh/porter/pkg/cache" "get.porter.sh/porter/pkg/claims" cnabtooci "get.porter.sh/porter/pkg/cnab/cnab-to-oci" @@ -23,6 +22,7 @@ import ( "get.porter.sh/porter/pkg/storage/migrations" "get.porter.sh/porter/pkg/storage/pluginstore" "get.porter.sh/porter/pkg/templates" + "get.porter.sh/porter/pkg/tracing" "github.com/hashicorp/go-multierror" "github.com/pkg/errors" ) @@ -121,15 +121,21 @@ func (p *Porter) Close() error { return bigErr.ErrorOrNil() } -// NewBuilder creates a Builder based on the current configuration. -func (p *Porter) GetBuilder() build.Builder { +// GetBuilder creates a Builder based on the current configuration. +func (p *Porter) GetBuilder(ctx context.Context) build.Builder { + log := tracing.LoggerFromContext(ctx) + if p.builder == nil { - switch p.GetBuildDriver() { + driver := p.GetBuildDriver() + switch driver { case config.BuildDriverBuildkit: - p.builder = buildkit.NewBuilder(p.Config) + // supported, yay! + case config.BuildDriverDocker: + log.Warn("The docker build driver is no longer supported. Using buildkit instead.") default: - p.builder = docker.NewBuilder(p.Context) + log.Warnf("Unsupported build driver: %s. Using buildkit instead.", driver) } + p.builder = buildkit.NewBuilder(p.Config) } return p.builder } diff --git a/pkg/porter/porter_test.go b/pkg/porter/porter_test.go index c89b6c9cc1..c01d1a577c 100644 --- a/pkg/porter/porter_test.go +++ b/pkg/porter/porter_test.go @@ -1,28 +1,31 @@ package porter import ( + "context" "testing" "get.porter.sh/porter/pkg/build/buildkit" - "get.porter.sh/porter/pkg/build/docker" "get.porter.sh/porter/pkg/config" "get.porter.sh/porter/pkg/experimental" "github.com/stretchr/testify/assert" ) func TestPorter_GetBuilder(t *testing.T) { - t.Run("docker", func(t *testing.T) { + // Now that docker is deprecated, always use buildkit for now + // I didn't remove the config capabilities in case we need it later + + t.Run("docker deprecated, use buildkit", func(t *testing.T) { p := Porter{Config: &config.Config{}} p.SetExperimentalFlags(experimental.FlagBuildDrivers) p.Data.BuildDriver = config.BuildDriverDocker - driver := p.GetBuilder() - assert.IsType(t, &docker.Builder{}, driver) + driver := p.GetBuilder(context.Background()) + assert.IsType(t, &buildkit.Builder{}, driver) }) t.Run("buildkit", func(t *testing.T) { p := Porter{Config: &config.Config{}} p.SetExperimentalFlags(experimental.FlagBuildDrivers) p.Data.BuildDriver = config.BuildDriverBuildkit - driver := p.GetBuilder() + driver := p.GetBuilder(context.Background()) assert.IsType(t, &buildkit.Builder{}, driver) }) t.Run("unspecified", func(t *testing.T) { @@ -30,14 +33,14 @@ func TestPorter_GetBuilder(t *testing.T) { p := Porter{Config: &config.Config{}} p.SetExperimentalFlags(experimental.FlagBuildDrivers) p.Data.BuildDriver = "" - driver := p.GetBuilder() - assert.IsType(t, &docker.Builder{}, driver) + driver := p.GetBuilder(context.Background()) + assert.IsType(t, &buildkit.Builder{}, driver) }) t.Run("buildkit - experimental flag disabled", func(t *testing.T) { // Default to docker when the experimental flag isn't set p := Porter{Config: &config.Config{}} p.Data.BuildDriver = "buildkit" - driver := p.GetBuilder() - assert.IsType(t, &docker.Builder{}, driver) + driver := p.GetBuilder(context.Background()) + assert.IsType(t, &buildkit.Builder{}, driver) }) } diff --git a/pkg/porter/publish.go b/pkg/porter/publish.go index 3fbf6ec1ee..d5c2973357 100644 --- a/pkg/porter/publish.go +++ b/pkg/porter/publish.go @@ -152,7 +152,7 @@ func (p *Porter) publishFromFile(ctx context.Context, opts PublishOptions) error if origInvImg != m.Image { // Tag it so that it will be known/found by Docker for publishing - builder := p.GetBuilder() + builder := p.GetBuilder(ctx) if err := builder.TagInvocationImage(ctx, origInvImg, m.Image); err != nil { return err }