Skip to content

Commit

Permalink
bake: load override
Browse files Browse the repository at this point in the history
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
  • Loading branch information
crazy-max committed Mar 13, 2024
1 parent 7eb3dfb commit 5bba069
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 17 deletions.
63 changes: 52 additions & 11 deletions bake/bake.go
Original file line number Diff line number Diff line change
Expand Up @@ -894,18 +894,51 @@ func (t *Target) AddOverrides(overrides map[string]Override) error {
}
t.Pull = &pull
case "push":
_, err := strconv.ParseBool(value)
push, err := strconv.ParseBool(value)
if err != nil {
return errors.Errorf("invalid value %s for boolean key push", value)
}
if len(t.Outputs) == 0 {
setPush := true
for i, output := range t.Outputs {
if typ := parseOutputType(output); typ == "image" || typ == "registry" {
t.Outputs[i] = t.Outputs[i] + ",push=" + value
setPush = false
break
} else if typ != "docker" {
// if there is any output that is not docker, don't set
// "push"
setPush = false
break
}
}
if push && setPush {
t.Outputs = append(t.Outputs, "type=image,push=true")
} else {
for i, output := range t.Outputs {
if typ := parseOutputType(output); typ == "image" || typ == "registry" {
t.Outputs[i] = t.Outputs[i] + ",push=" + value
}
case "load":
load, err := strconv.ParseBool(value)
if err != nil {
return errors.Errorf("invalid value %s for boolean key load", value)
}
if load {
setLoad := true
for _, output := range t.Outputs {
if typ := parseOutputType(output); typ == "docker" {
if v := parseOutput(output); v != nil {
if _, ok := v["dest"]; !ok {
setLoad = false
break
}
}
} else if typ != "image" && typ != "registry" {
// if there is any output that is not an image or
// registry, don't set "load" similar to push override
setLoad = false
break
}
}
if setLoad {
t.Outputs = append(t.Outputs, "type=docker")
}
}
default:
return errors.Errorf("unknown key: %s", keys[0])
Expand Down Expand Up @@ -1394,18 +1427,26 @@ func removeAttestDupes(s []string) []string {
return res
}

func parseOutputType(str string) string {
func parseOutput(str string) map[string]string {
csvReader := csv.NewReader(strings.NewReader(str))
fields, err := csvReader.Read()
if err != nil {
return ""
return nil
}
res := map[string]string{}
for _, field := range fields {
parts := strings.SplitN(field, "=", 2)
if len(parts) == 2 {
if parts[0] == "type" {
return parts[1]
}
res[parts[0]] = parts[1]
}
}
return res
}

func parseOutputType(str string) string {
if out := parseOutput(str); out != nil {
if v, ok := out["type"]; ok {
return v
}
}
return ""
Expand Down
95 changes: 95 additions & 0 deletions bake/bake_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,101 @@ func TestPushOverride(t *testing.T) {
require.Equal(t, []string{"type=image,push=true"}, m["bar"].Outputs)
}

func TestLoadOverride(t *testing.T) {
t.Parallel()

fp := File{
Name: "docker-bake.hcl",
Data: []byte(
`target "app" {
}`),
}
ctx := context.TODO()
m, _, err := ReadTargets(ctx, []File{fp}, []string{"app"}, []string{"*.load=true"}, nil)
require.NoError(t, err)

require.Equal(t, 1, len(m["app"].Outputs))
require.Equal(t, "type=docker", m["app"].Outputs[0])

fp = File{
Name: "docker-bake.hcl",
Data: []byte(
`target "app" {
output = ["type=image"]
}`),
}
ctx = context.TODO()
m, _, err = ReadTargets(ctx, []File{fp}, []string{"app"}, []string{"*.load=true"}, nil)
require.NoError(t, err)

require.Equal(t, 2, len(m["app"].Outputs))
require.Equal(t, []string{"type=image", "type=docker"}, m["app"].Outputs)

fp = File{
Name: "docker-bake.hcl",
Data: []byte(
`target "app" {
output = ["type=docker,dest=out"]
}`),
}
ctx = context.TODO()
m, _, err = ReadTargets(ctx, []File{fp}, []string{"app"}, []string{"*.load=true"}, nil)
require.NoError(t, err)

require.Equal(t, 2, len(m["app"].Outputs))
require.Equal(t, []string{"type=docker,dest=out", "type=docker"}, m["app"].Outputs)

fp = File{
Name: "docker-bake.hcl",
Data: []byte(
`target "foo" {
output = [ "type=local,dest=out" ]
}
target "bar" {
}`),
}
ctx = context.TODO()
m, _, err = ReadTargets(ctx, []File{fp}, []string{"foo", "bar"}, []string{"*.load=true"}, nil)
require.NoError(t, err)

require.Equal(t, 2, len(m))
require.Equal(t, 1, len(m["foo"].Outputs))
require.Equal(t, []string{"type=local,dest=out"}, m["foo"].Outputs)
require.Equal(t, 1, len(m["bar"].Outputs))
require.Equal(t, []string{"type=docker"}, m["bar"].Outputs)
}

func TestLoadAndPushOverride(t *testing.T) {
t.Parallel()

fp := File{
Name: "docker-bake.hcl",
Data: []byte(
`target "foo" {
output = [ "type=local,dest=out" ]
}
target "bar" {
}`),
}
ctx := context.TODO()

m, _, err := ReadTargets(ctx, []File{fp}, []string{"foo", "bar"}, []string{"*.load=true", "*.push=true"}, nil)
require.NoError(t, err)
require.Equal(t, 2, len(m))
require.Equal(t, 1, len(m["foo"].Outputs))
require.Equal(t, []string{"type=local,dest=out"}, m["foo"].Outputs)
require.Equal(t, 2, len(m["bar"].Outputs))
require.Equal(t, []string{"type=docker", "type=image,push=true"}, m["bar"].Outputs)

m, _, err = ReadTargets(ctx, []File{fp}, []string{"foo", "bar"}, []string{"*.push=true", "*.load=true"}, nil)
require.NoError(t, err)
require.Equal(t, 2, len(m))
require.Equal(t, 1, len(m["foo"].Outputs))
require.Equal(t, []string{"type=local,dest=out"}, m["foo"].Outputs)
require.Equal(t, 2, len(m["bar"].Outputs))
require.Equal(t, []string{"type=image,push=true", "type=docker"}, m["bar"].Outputs)
}

func TestReadTargetsCompose(t *testing.T) {
t.Parallel()

Expand Down
2 changes: 1 addition & 1 deletion commands/bake.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
overrides = append(overrides, "*.push=true")
}
if in.exportLoad {
overrides = append(overrides, "*.output=type=docker")
overrides = append(overrides, "*.load=true")
}
if cFlags.noCache != nil {
overrides = append(overrides, fmt.Sprintf("*.no-cache=%t", *cFlags.noCache))
Expand Down
1 change: 1 addition & 0 deletions docs/reference/buildx_bake.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ You can override the following fields:
* `context`
* `dockerfile`
* `labels`
* `load`
* `no-cache`
* `no-cache-filter`
* `output`
Expand Down
10 changes: 5 additions & 5 deletions tests/bake.go
Original file line number Diff line number Diff line change
Expand Up @@ -778,11 +778,11 @@ target "default" {
outb, err := cmd.CombinedOutput()
require.NoError(t, err, string(outb))

// TODO: test registry when --load case fixed for bake (currently overrides --push)
//desc, provider, err := contentutil.ProviderFromRef(target)
//require.NoError(t, err)
//_, err = testutil.ReadImages(sb.Context(), provider, desc)
//require.NoError(t, err)
// test registry
desc, provider, err := contentutil.ProviderFromRef(target)
require.NoError(t, err)
_, err = testutil.ReadImages(sb.Context(), provider, desc)
require.NoError(t, err)

// test docker store
cmd = dockerCmd(sb, withArgs("image", "inspect", target))
Expand Down

0 comments on commit 5bba069

Please sign in to comment.