diff --git a/bake/bake.go b/bake/bake.go index 10f6cf1e..f3eea4f7 100644 --- a/bake/bake.go +++ b/bake/bake.go @@ -1329,7 +1329,8 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) { if err != nil { return nil, err } - bo.Exports, err = controllerapi.CreateExports(outputs) + + bo.Exports, bo.ExportsLocalPathsTemporary, err = controllerapi.CreateExports(outputs) if err != nil { return nil, err } diff --git a/bake/entitlements.go b/bake/entitlements.go index b7160481..116051ff 100644 --- a/bake/entitlements.go +++ b/bake/entitlements.go @@ -113,17 +113,8 @@ func (c EntitlementConf) check(bo build.Options, expected *EntitlementConf) erro roPaths[p] = struct{}{} } - for _, out := range bo.Exports { - if out.Type == "local" { - if dest, ok := out.Attrs["dest"]; ok { - rwPaths[dest] = struct{}{} - } - } - if out.Type == "tar" { - if dest, ok := out.Attrs["dest"]; ok && dest != "-" { - rwPaths[dest] = struct{}{} - } - } + for _, p := range bo.ExportsLocalPathsTemporary { + rwPaths[p] = struct{}{} } for _, ce := range bo.CacheTo { diff --git a/bake/entitlements_test.go b/bake/entitlements_test.go index 16cd8bc6..ef1bbdec 100644 --- a/bake/entitlements_test.go +++ b/bake/entitlements_test.go @@ -10,7 +10,6 @@ import ( "github.com/docker/buildx/build" "github.com/docker/buildx/controller/pb" "github.com/docker/buildx/util/osutil" - "github.com/moby/buildkit/client" "github.com/moby/buildkit/client/llb" "github.com/moby/buildkit/util/entitlements" "github.com/stretchr/testify/require" @@ -279,25 +278,10 @@ func TestValidateEntitlements(t *testing.T) { { name: "ExportLocal", opt: build.Options{ - Exports: []client.ExportEntry{ - { - Type: "local", - Attrs: map[string]string{ - "dest": dir1, - }, - }, - { - Type: "local", - Attrs: map[string]string{ - "dest": filepath.Join(dir1, "subdir"), - }, - }, - { - Type: "local", - Attrs: map[string]string{ - "dest": dir2, - }, - }, + ExportsLocalPathsTemporary: []string{ + dir1, + filepath.Join(dir1, "subdir"), + dir2, }, }, expected: EntitlementConf{ diff --git a/build/build.go b/build/build.go index 3a2e7663..4663d1f4 100644 --- a/build/build.go +++ b/build/build.go @@ -62,27 +62,28 @@ const ( type Options struct { Inputs Inputs - Ref string - Allow []entitlements.Entitlement - Attests map[string]*string - BuildArgs map[string]string - CacheFrom []client.CacheOptionsEntry - CacheTo []client.CacheOptionsEntry - CgroupParent string - Exports []client.ExportEntry - ExtraHosts []string - Labels map[string]string - NetworkMode string - NoCache bool - NoCacheFilter []string - Platforms []specs.Platform - Pull bool - SecretSpecs []*controllerapi.Secret - SSHSpecs []*controllerapi.SSH - ShmSize opts.MemBytes - Tags []string - Target string - Ulimits *opts.UlimitOpt + Ref string + Allow []entitlements.Entitlement + Attests map[string]*string + BuildArgs map[string]string + CacheFrom []client.CacheOptionsEntry + CacheTo []client.CacheOptionsEntry + CgroupParent string + Exports []client.ExportEntry + ExportsLocalPathsTemporary []string // should be removed after client.ExportEntry update in buildkit v0.19.0 + ExtraHosts []string + Labels map[string]string + NetworkMode string + NoCache bool + NoCacheFilter []string + Platforms []specs.Platform + Pull bool + SecretSpecs []*controllerapi.Secret + SSHSpecs []*controllerapi.SSH + ShmSize opts.MemBytes + Tags []string + Target string + Ulimits *opts.UlimitOpt Session []session.Attachable Linked bool // Linked marks this target as exclusively linked (not requested by the user). diff --git a/controller/build/build.go b/controller/build/build.go index 7a57dc7d..5e0c89c2 100644 --- a/controller/build/build.go +++ b/controller/build/build.go @@ -93,7 +93,7 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in *controllerapi.Buil } opts.Session = append(opts.Session, ssh) - outputs, err := controllerapi.CreateExports(in.Exports) + outputs, _, err := controllerapi.CreateExports(in.Exports) if err != nil { return nil, nil, nil, err } diff --git a/controller/pb/export.go b/controller/pb/export.go index 3de33eb3..af60bc88 100644 --- a/controller/pb/export.go +++ b/controller/pb/export.go @@ -10,15 +10,16 @@ import ( "github.com/pkg/errors" ) -func CreateExports(entries []*ExportEntry) ([]client.ExportEntry, error) { +func CreateExports(entries []*ExportEntry) ([]client.ExportEntry, []string, error) { var outs []client.ExportEntry + var localPaths []string if len(entries) == 0 { - return nil, nil + return nil, nil, nil } var stdoutUsed bool for _, entry := range entries { if entry.Type == "" { - return nil, errors.Errorf("type is required for output") + return nil, nil, errors.Errorf("type is required for output") } out := client.ExportEntry{ @@ -49,20 +50,21 @@ func CreateExports(entries []*ExportEntry) ([]client.ExportEntry, error) { if supportDir { if entry.Destination == "" { - return nil, errors.Errorf("dest is required for %s exporter", out.Type) + return nil, nil, errors.Errorf("dest is required for %s exporter", out.Type) } if entry.Destination == "-" { - return nil, errors.Errorf("dest cannot be stdout for %s exporter", out.Type) + return nil, nil, errors.Errorf("dest cannot be stdout for %s exporter", out.Type) } fi, err := os.Stat(entry.Destination) if err != nil && !os.IsNotExist(err) { - return nil, errors.Wrapf(err, "invalid destination directory: %s", entry.Destination) + return nil, nil, errors.Wrapf(err, "invalid destination directory: %s", entry.Destination) } if err == nil && !fi.IsDir() { - return nil, errors.Errorf("destination directory %s is a file", entry.Destination) + return nil, nil, errors.Errorf("destination directory %s is a file", entry.Destination) } out.OutputDir = entry.Destination + localPaths = append(localPaths, entry.Destination) } if supportFile { if entry.Destination == "" && out.Type != client.ExporterDocker { @@ -70,32 +72,33 @@ func CreateExports(entries []*ExportEntry) ([]client.ExportEntry, error) { } if entry.Destination == "-" { if stdoutUsed { - return nil, errors.Errorf("multiple outputs configured to write to stdout") + return nil, nil, errors.Errorf("multiple outputs configured to write to stdout") } if _, err := console.ConsoleFromFile(os.Stdout); err == nil { - return nil, errors.Errorf("dest file is required for %s exporter. refusing to write to console", out.Type) + return nil, nil, errors.Errorf("dest file is required for %s exporter. refusing to write to console", out.Type) } out.Output = wrapWriteCloser(os.Stdout) stdoutUsed = true } else if entry.Destination != "" { fi, err := os.Stat(entry.Destination) if err != nil && !os.IsNotExist(err) { - return nil, errors.Wrapf(err, "invalid destination file: %s", entry.Destination) + return nil, nil, errors.Wrapf(err, "invalid destination file: %s", entry.Destination) } if err == nil && fi.IsDir() { - return nil, errors.Errorf("destination file %s is a directory", entry.Destination) + return nil, nil, errors.Errorf("destination file %s is a directory", entry.Destination) } f, err := os.Create(entry.Destination) if err != nil { - return nil, errors.Errorf("failed to open %s", err) + return nil, nil, errors.Errorf("failed to open %s", err) } out.Output = wrapWriteCloser(f) + localPaths = append(localPaths, entry.Destination) } } outs = append(outs, out) } - return outs, nil + return outs, localPaths, nil } func wrapWriteCloser(wc io.WriteCloser) func(map[string]string) (io.WriteCloser, error) {