Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Buildkit Option #434

Merged
merged 6 commits into from
Dec 5, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion provider/cmd/pulumi-resource-docker/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3039,6 +3039,11 @@
},
"description": "An optional map of named build-time argument variables to set during the Docker build. This flag allows you to pass built-time variablesthat can be accessed like environment variables inside the RUN instruction."
},
"builderVersion": {
"type": "string",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"description": "The version of the Docker builder. Valid inputs are: \n`BuilderV1` - the first generation builder in docker daemon\n`BuilderBuildKit - the builder based on moby/buildkit project\n Defaults to `BuilderBuildKit`.",
"default": "BuilderBuildKit"
},
"cacheFrom": {
"oneOf": [
{
Expand Down Expand Up @@ -4419,7 +4424,7 @@
}
},
"docker:index/image:Image": {
"description": "A real CRUD docker image we hope",
"description": "Builds a Docker Image and pushes to a Docker registry.",
"properties": {
"baseImageName": {
"type": "string",
Expand Down
63 changes: 48 additions & 15 deletions provider/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
)

const defaultDockerfile = "Dockerfile"
const defaultBuilder = "2"

type Image struct {
Name string
Expand All @@ -33,13 +34,14 @@ type Registry struct {
}

type Build struct {
Context string
Dockerfile string
CachedImages []string
Env map[string]string
Args map[string]*string
ExtraOptions []string
Target string
Context string
Dockerfile string
CachedImages []string
Env map[string]string
Args map[string]*string
ExtraOptions []string
Target string
BuilderVersion types.BuilderVersion
}

func (p *dockerNativeProvider) dockerBuild(ctx context.Context,
Expand All @@ -59,7 +61,10 @@ func (p *dockerNativeProvider) dockerBuild(ctx context.Context,
Registry: reg,
}

build := marshalBuildAndApplyDefaults(inputs["build"])
build, err := marshalBuildAndApplyDefaults(inputs["build"])
if err != nil {
return "", nil, err
}
cache := marshalCachedImages(img, inputs["build"])

build.CachedImages = cache
Expand Down Expand Up @@ -91,7 +96,7 @@ func (p *dockerNativeProvider) dockerBuild(ctx context.Context,
Remove: true,
//CacheFrom: img.Build.CachedImages, // TODO: this needs a login, so needs to be handled differently.
BuildArgs: build.Args,
//Version: types.BuilderBuildKit, // TODO: parse this setting from the `env` input
Version: build.BuilderVersion,
}

imgBuildResp, err := docker.ImageBuild(ctx, tar, opts)
Expand Down Expand Up @@ -199,21 +204,21 @@ func (p *dockerNativeProvider) dockerBuild(ctx context.Context,
return img.Name, pbstruct, err
}

func marshalBuildAndApplyDefaults(b resource.PropertyValue) Build {
func marshalBuildAndApplyDefaults(b resource.PropertyValue) (Build, error) {

// build can be nil, a string or an object; we will also use reasonable defaults here.
var build Build
if b.IsNull() {
// use the default build context
//// use the default build context
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo?

build.Dockerfile = defaultDockerfile
build.Context = "."
return build
return build, nil
}
if b.IsString() {
// use the filepath as context
build.Context = b.StringValue()
build.Dockerfile = defaultDockerfile
return build
return build, nil
}

// read in the build type fields
Expand All @@ -232,8 +237,16 @@ func marshalBuildAndApplyDefaults(b resource.PropertyValue) Build {
} else {
build.Context = buildObject["context"].StringValue()
}
// Envs

// BuildKit
version, err := marshalBuilder(buildObject["builderVersion"])

if err != nil {
return build, err
}
build.BuilderVersion = version

// Envs
build.Env = marshalEnvs(buildObject["env"])

// Args
Expand All @@ -251,7 +264,7 @@ func marshalBuildAndApplyDefaults(b resource.PropertyValue) Build {
if !buildObject["target"].IsNull() {
build.Target = buildObject["target"].StringValue()
}
return build
return build, nil
}

func marshalCachedImages(img Image, b resource.PropertyValue) []string {
Expand Down Expand Up @@ -328,3 +341,23 @@ func marshalEnvs(e resource.PropertyValue) map[string]string {
}
return envs
}

func marshalBuilder(builder resource.PropertyValue) (types.BuilderVersion, error) {
var version types.BuilderVersion

if builder.IsNull() {
//set default
return defaultBuilder, nil
}
// verify valid input
switch builder.StringValue() {
case "BuilderV1":
return "1", nil
case "BuilderBuildKit":
return "2", nil
default:
// because the Docker client will default to `BuilderV1`
// when version isn't set, we return an error
return version, errors.Errorf("Invalid Docker Builder version")
}
}
67 changes: 58 additions & 9 deletions provider/image_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package provider

import (
"github.com/docker/docker/api/types"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
"github.com/stretchr/testify/assert"
"testing"
Expand Down Expand Up @@ -53,7 +54,7 @@ func TestMarshalBuildAndApplyDefaults(t *testing.T) {
Dockerfile: "Dockerfile",
}
input := resource.NewObjectProperty(resource.PropertyMap{})
actual := marshalBuildAndApplyDefaults(input)
actual, _ := marshalBuildAndApplyDefaults(input)
assert.Equal(t, expected, actual)
})

Expand All @@ -63,7 +64,7 @@ func TestMarshalBuildAndApplyDefaults(t *testing.T) {
Dockerfile: "Dockerfile",
}
input := resource.NewStringProperty("/twilight/sparkle/bin")
actual := marshalBuildAndApplyDefaults(input)
actual, _ := marshalBuildAndApplyDefaults(input)
assert.Equal(t, expected, actual)
})

Expand All @@ -75,7 +76,7 @@ func TestMarshalBuildAndApplyDefaults(t *testing.T) {
input := resource.NewObjectProperty(resource.PropertyMap{
"dockerfile": resource.NewStringProperty("TheLastUnicorn"),
})
actual := marshalBuildAndApplyDefaults(input)
actual, _ := marshalBuildAndApplyDefaults(input)
assert.Equal(t, expected, actual)
})

Expand All @@ -89,7 +90,7 @@ func TestMarshalBuildAndApplyDefaults(t *testing.T) {
"context": resource.NewStringProperty("/twilight/sparkle/bin"),
})

actual := marshalBuildAndApplyDefaults(input)
actual, _ := marshalBuildAndApplyDefaults(input)
assert.Equal(t, expected, actual)
})

Expand All @@ -109,7 +110,7 @@ func TestMarshalBuildAndApplyDefaults(t *testing.T) {
}),
})

actual := marshalBuildAndApplyDefaults(input)
actual, _ := marshalBuildAndApplyDefaults(input)
assert.Equal(t, expected, actual)
})

Expand All @@ -129,7 +130,7 @@ func TestMarshalBuildAndApplyDefaults(t *testing.T) {
}),
})

actual := marshalBuildAndApplyDefaults(input)
actual, _ := marshalBuildAndApplyDefaults(input)
assert.Equal(t, expected, actual)
})

Expand All @@ -148,7 +149,7 @@ func TestMarshalBuildAndApplyDefaults(t *testing.T) {
}),
})

actual := marshalBuildAndApplyDefaults(input)
actual, _ := marshalBuildAndApplyDefaults(input)
assert.Equal(t, expected, actual)
})

Expand All @@ -162,7 +163,7 @@ func TestMarshalBuildAndApplyDefaults(t *testing.T) {
"extraOptions": resource.NewArrayProperty([]resource.PropertyValue{}),
})

actual := marshalBuildAndApplyDefaults(input)
actual, _ := marshalBuildAndApplyDefaults(input)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit more verbose but could use

actual, err := ...
assert.NoError(t, err)

assert.Equal(t, expected, actual)
})
t.Run("Sets Target", func(t *testing.T) {
Expand All @@ -176,7 +177,21 @@ func TestMarshalBuildAndApplyDefaults(t *testing.T) {
"target": resource.NewStringProperty("bullseye"),
})

actual := marshalBuildAndApplyDefaults(input)
actual, _ := marshalBuildAndApplyDefaults(input)
assert.Equal(t, expected, actual)
})
t.Run("Sets Target", func(t *testing.T) {
expected := Build{
Context: ".",
Dockerfile: "Dockerfile",
Target: "bullseye",
}

input := resource.NewObjectProperty(resource.PropertyMap{
"target": resource.NewStringProperty("bullseye"),
})

actual, _ := marshalBuildAndApplyDefaults(input)
assert.Equal(t, expected, actual)
})
}
Expand Down Expand Up @@ -295,3 +310,37 @@ func TestMarshalCachedImages(t *testing.T) {
assert.Equal(t, expected, actual)
})
}

func TestMarshalBuilder(t *testing.T) {
t.Run("Test Builder Version Default", func(t *testing.T) {
expected := types.BuilderBuildKit
input := resource.NewPropertyValue(nil)
actual, _ := marshalBuilder(input)
assert.Equal(t, expected, actual)

})
t.Run("Test Builder BuildKit Version", func(t *testing.T) {
expected := types.BuilderBuildKit
input := resource.NewStringProperty("BuilderBuildKit")

actual, _ := marshalBuilder(input)
assert.Equal(t, expected, actual)

})
t.Run("Test Builder V1 Version", func(t *testing.T) {
expected := types.BuilderV1
input := resource.NewStringProperty("BuilderV1")

actual, _ := marshalBuilder(input)
assert.Equal(t, expected, actual)

})
t.Run("Test Invalid Builder Returns Error", func(t *testing.T) {
expected := types.BuilderV1
input := resource.NewStringProperty("BuilderV1")

actual, _ := marshalBuilder(input)
assert.Equal(t, expected, actual)

})
}
11 changes: 10 additions & 1 deletion provider/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,15 @@ func Provider() tfbridge.ProviderInfo {
Description: "The target of the Dockerfile to build",
TypeSpec: schema.TypeSpec{Type: "string"},
},
"builderVersion": {
Description: "The version of the Docker builder. " +
"Valid inputs are: \n" +
"`BuilderV1` - the first generation builder in docker daemon\n" + "" +
"`BuilderBuildKit - the builder based on moby/buildkit project\n " +
"Defaults to `BuilderBuildKit`.",
TypeSpec: schema.TypeSpec{Type: "string"},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above comment on perhaps representing this as an enum instead?

Default: "BuilderBuildKit",
},
},
},
},
Expand All @@ -224,7 +233,7 @@ func Provider() tfbridge.ProviderInfo {
dockerResource(dockerMod, "Image").String(): {
ObjectTypeSpec: schema.ObjectTypeSpec{
Type: "object",
Description: "A real CRUD docker image we hope", // TODO: update description
Description: "Builds a Docker Image and pushes to a Docker registry.",
Properties: map[string]schema.PropertySpec{
"imageName": {
Description: "The fully qualified image name",
Expand Down
2 changes: 1 addition & 1 deletion sdk/dotnet/Image.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
namespace Pulumi.Docker
{
/// <summary>
/// A real CRUD docker image we hope
/// Builds a Docker Image and pushes to a Docker registry.
/// </summary>
[DockerResourceType("docker:index/image:Image")]
public partial class Image : global::Pulumi.CustomResource
Expand Down
10 changes: 10 additions & 0 deletions sdk/dotnet/Inputs/DockerBuildArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ public InputMap<string> Args
set => _args = value;
}

/// <summary>
/// The version of the Docker builder. Valid inputs are:
/// `BuilderV1` - the first generation builder in docker daemon
/// `BuilderBuildKit - the builder based on moby/buildkit project
/// Defaults to `BuilderBuildKit`.
/// </summary>
[Input("builderVersion")]
public Input<string>? BuilderVersion { get; set; }

/// <summary>
/// A cached image or list of build stages to use as build cache
/// </summary>
Expand Down Expand Up @@ -77,6 +86,7 @@ public InputList<string> ExtraOptions

public DockerBuildArgs()
{
BuilderVersion = "BuilderBuildKit";
Context = ".";
Dockerfile = "Dockerfile";
}
Expand Down
2 changes: 1 addition & 1 deletion sdk/go/docker/image.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading