Skip to content

Commit

Permalink
Support docker build --build-context parameter
Browse files Browse the repository at this point in the history
Signed-off-by: jonnyry <jonnyry@users.noreply.github.com>
  • Loading branch information
jonnyry committed Dec 3, 2024
1 parent dcd45df commit 0f1857c
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 24 deletions.
2 changes: 2 additions & 0 deletions cmd/porter/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ The docker driver builds the bundle image using the local Docker host. To use a
_ = f.MarkHidden("driver") // Hide the driver flag since there aren't any choices to make right now
f.StringArrayVar(&opts.BuildArgs, "build-arg", nil,
"Set build arguments in the template Dockerfile (format: NAME=VALUE). May be specified multiple times. Max length is 5,000 characters.")
f.StringArrayVar(&opts.BuildContexts, "build-context", nil,
"Define additional build context with specified contents. May be specified multiple times.")
f.StringArrayVar(&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,
Expand Down
25 changes: 13 additions & 12 deletions docs/content/docs/references/cli/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,19 @@ porter build [flags]
### Options

```
--build-arg stringArray Set build arguments in the template Dockerfile (format: NAME=VALUE). May be specified multiple times. Max length is 5,000 characters.
--custom stringArray Define an individual key-value pair for the custom section in the form of NAME=VALUE. Use dot notation to specify a nested custom field. May be specified multiple times. Max length is 5,000 characters when used as a build argument.
-d, --dir string Path to the build context directory where all bundle assets are located. Defaults to the current directory.
-f, --file string Path to the Porter manifest. The path is relative to the build context directory. Defaults to porter.yaml in the current directory.
-h, --help help for build
--insecure-registry Don't require TLS when pulling referenced images
--name string Override the bundle name
--no-cache Do not use the Docker cache when building the bundle image.
--no-lint Do not run the linter
--secret stringArray Secret file to expose to the build (format: id=mysecret,src=/local/secret). Custom values are accessible as build arguments in the template Dockerfile and in the manifest using template variables. May be specified multiple times.
--ssh stringArray SSH agent socket or keys to expose to the build (format: default|<id>[=<socket>|<key>[,<key>]]). May be specified multiple times.
--version string Override the bundle version
--build-arg stringArray Set build arguments in the template Dockerfile (format: NAME=VALUE). May be specified multiple times. Max length is 5,000 characters.
--build-context stringArray Define additional build context with specified contents. May be specified multiple times.
--custom stringArray Define an individual key-value pair for the custom section in the form of NAME=VALUE. Use dot notation to specify a nested custom field. May be specified multiple times. Max length is 5,000 characters when used as a build argument.
-d, --dir string Path to the build context directory where all bundle assets are located. Defaults to the current directory.
-f, --file string Path to the Porter manifest. The path is relative to the build context directory. Defaults to porter.yaml in the current directory.
-h, --help help for build
--insecure-registry Don't require TLS when pulling referenced images
--name string Override the bundle name
--no-cache Do not use the Docker cache when building the bundle image.
--no-lint Do not run the linter
--secret stringArray Secret file to expose to the build (format: id=mysecret,src=/local/secret). Custom values are accessible as build arguments in the template Dockerfile and in the manifest using template variables. May be specified multiple times.
--ssh stringArray SSH agent socket or keys to expose to the build (format: default|<id>[=<socket>|<key>[,<key>]]). May be specified multiple times.
--version string Override the bundle version
```

### Options inherited from parent commands
Expand Down
25 changes: 13 additions & 12 deletions docs/content/docs/references/cli/bundles_build.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,19 @@ porter bundles build [flags]
### Options

```
--build-arg stringArray Set build arguments in the template Dockerfile (format: NAME=VALUE). May be specified multiple times. Max length is 5,000 characters.
--custom stringArray Define an individual key-value pair for the custom section in the form of NAME=VALUE. Use dot notation to specify a nested custom field. May be specified multiple times. Max length is 5,000 characters when used as a build argument.
-d, --dir string Path to the build context directory where all bundle assets are located. Defaults to the current directory.
-f, --file string Path to the Porter manifest. The path is relative to the build context directory. Defaults to porter.yaml in the current directory.
-h, --help help for build
--insecure-registry Don't require TLS when pulling referenced images
--name string Override the bundle name
--no-cache Do not use the Docker cache when building the bundle image.
--no-lint Do not run the linter
--secret stringArray Secret file to expose to the build (format: id=mysecret,src=/local/secret). Custom values are accessible as build arguments in the template Dockerfile and in the manifest using template variables. May be specified multiple times.
--ssh stringArray SSH agent socket or keys to expose to the build (format: default|<id>[=<socket>|<key>[,<key>]]). May be specified multiple times.
--version string Override the bundle version
--build-arg stringArray Set build arguments in the template Dockerfile (format: NAME=VALUE). May be specified multiple times. Max length is 5,000 characters.
--build-context stringArray Define additional build context with specified contents. May be specified multiple times.
--custom stringArray Define an individual key-value pair for the custom section in the form of NAME=VALUE. Use dot notation to specify a nested custom field. May be specified multiple times. Max length is 5,000 characters when used as a build argument.
-d, --dir string Path to the build context directory where all bundle assets are located. Defaults to the current directory.
-f, --file string Path to the Porter manifest. The path is relative to the build context directory. Defaults to porter.yaml in the current directory.
-h, --help help for build
--insecure-registry Don't require TLS when pulling referenced images
--name string Override the bundle name
--no-cache Do not use the Docker cache when building the bundle image.
--no-lint Do not run the linter
--secret stringArray Secret file to expose to the build (format: id=mysecret,src=/local/secret). Custom values are accessible as build arguments in the template Dockerfile and in the manifest using template variables. May be specified multiple times.
--ssh stringArray SSH agent socket or keys to expose to the build (format: default|<id>[=<socket>|<key>[,<key>]]). May be specified multiple times.
--version string Override the bundle version
```

### Options inherited from parent commands
Expand Down
3 changes: 3 additions & 0 deletions pkg/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ type BuildImageOptions struct {
// BuildArgs is the set of docker build --build-arg specified.
BuildArgs []string

// BuildContexts is the set of docker build --build-context specified.
BuildContexts []string

// NoCache is the docker build --no-cache flag specified.
NoCache bool
}
23 changes: 23 additions & 0 deletions pkg/build/buildkit/buildx.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,16 @@ func (b *Builder) BuildBundleImage(ctx context.Context, manifest *manifest.Manif
}
span.SetAttributes(tracing.ObjectAttribute("build-args", args))

buildContexts := parseBuildContexts(opts.BuildContexts)

buildxOpts := map[string]buildx.Options{
"default": {
Tags: []string{manifest.Image},
Inputs: buildx.Inputs{
ContextPath: b.Getwd(),
DockerfilePath: b.getDockerfilePath(),
InStream: buildx.NewSyncMultiReader(b.In),
NamedContexts: buildContexts,
},
BuildArgs: args,
Session: currentSession,
Expand Down Expand Up @@ -243,6 +246,26 @@ func parseBuildArgs(unparsed []string, parsed map[string]string) {
}
}

func parseBuildContexts(unparsed []string) map[string]buildx.NamedContext {
parsed := make(map[string]buildx.NamedContext)

for _, arg := range unparsed {
parts := strings.SplitN(arg, "=", 2)
if len(parts) < 2 {
// ignore --build-context with only one part
continue
}

name := parts[0]
value := parts[1]
parsed[name] = buildx.NamedContext{
Path: value,
}
}

return parsed
}

func (b *Builder) TagBundleImage(ctx context.Context, origTag, newTag string) error {
ctx, log := tracing.StartSpan(ctx, attribute.String("source-tag", origTag), attribute.String("destination-tag", newTag))
defer log.EndSpan()
Expand Down
21 changes: 21 additions & 0 deletions pkg/build/buildkit/buildx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"get.porter.sh/porter/pkg/build"
"get.porter.sh/porter/pkg/config"
"get.porter.sh/porter/pkg/manifest"
buildx "github.com/docker/buildx/build"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand All @@ -33,6 +34,26 @@ func Test_parseBuildArgs(t *testing.T) {
}
}

func Test_parseBuildContexts(t *testing.T) {
testcases := []struct {
name string
inputArgs []string
wantArgs map[string]buildx.NamedContext
}{
{name: "valid args", inputArgs: []string{"A=1", "B=2=2", "C="},
wantArgs: map[string]buildx.NamedContext{"A": {Path: "1"}, "B": {Path: "2=2"}, "C": {}}},
{name: "missing equal sign", inputArgs: []string{"A"},
wantArgs: map[string]buildx.NamedContext{}},
}

for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
var gotArgs = parseBuildContexts(tc.inputArgs)
assert.Equal(t, tc.wantArgs, gotArgs)
})
}
}

func Test_flattenMap(t *testing.T) {
tt := []struct {
desc string
Expand Down

0 comments on commit 0f1857c

Please sign in to comment.