Skip to content

Commit

Permalink
Support docker buildkit build flags
Browse files Browse the repository at this point in the history
This adds support for the following docker flags:

--build-arg: Pass build arguments that can be used in the template
dockerfile
--ssh: Provide a ssh configuration to the container while building
--secret: Provide a secret to the container while building

Closes getporter#1769

Signed-off-by: Carolyn Van Slyck <[email protected]>
  • Loading branch information
carolynvs committed Apr 1, 2022
1 parent 09cb6ab commit 429f76f
Show file tree
Hide file tree
Showing 26 changed files with 214 additions and 157 deletions.
5 changes: 4 additions & 1 deletion cmd/porter/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -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|<id>[=<socket>|<key>[,<key>]]). 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"},
Expand Down
18 changes: 10 additions & 8 deletions docs/content/cli/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -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|<id>[=<socket>|<key>[,<key>]]). May be specified multiple times.
-v, --verbose Enable verbose logging
--version string Override the bundle version
```

### Options inherited from parent commands
Expand Down
18 changes: 10 additions & 8 deletions docs/content/cli/bundles_build.md
Original file line number Diff line number Diff line change
Expand Up @@ -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|<id>[=<socket>|<key>[,<key>]]). May be specified multiple times.
-v, --verbose Enable verbose logging
--version string Override the bundle version
```

### Options inherited from parent commands
Expand Down
5 changes: 5 additions & 0 deletions examples/private-assets/.dockerignore
Original file line number Diff line number Diff line change
@@ -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/
1 change: 1 addition & 0 deletions examples/private-assets/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.cnab/
33 changes: 33 additions & 0 deletions examples/private-assets/README.md
Original file line number Diff line number Diff line change
@@ -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 __/
\ \ __/
\____\______/
```
7 changes: 7 additions & 0 deletions examples/private-assets/check-secrets.sh
Original file line number Diff line number Diff line change
@@ -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
17 changes: 17 additions & 0 deletions examples/private-assets/helpers.sh
Original file line number Diff line number Diff line change
@@ -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
"$@"
28 changes: 28 additions & 0 deletions examples/private-assets/porter.yaml
Original file line number Diff line number Diff line change
@@ -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
14 changes: 14 additions & 0 deletions examples/private-assets/secret
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
__________________________
< yarr, I'm a secret whale >
--------------------------
\
\
\
## .
## ## ## ==
## ## ## ## ===
/""""""""""""""""___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\______/
1 change: 1 addition & 0 deletions examples/private-assets/secrets/token
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
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
19 changes: 19 additions & 0 deletions examples/private-assets/template.Dockerfile
Original file line number Diff line number Diff line change
@@ -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
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
7 changes: 6 additions & 1 deletion pkg/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
21 changes: 17 additions & 4 deletions pkg/build/buildkit/buildx.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand All @@ -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{
Expand All @@ -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,
},
}

Expand All @@ -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 {
Expand Down
1 change: 0 additions & 1 deletion pkg/build/docker/doc.go

This file was deleted.

102 changes: 0 additions & 102 deletions pkg/build/docker/docker.go

This file was deleted.

Loading

0 comments on commit 429f76f

Please sign in to comment.