Skip to content

Commit

Permalink
Merge pull request #2095 from rittneje/add-option-to-output-metadata
Browse files Browse the repository at this point in the history
Add --metadata-file flag to output build metadata
  • Loading branch information
tonistiigi committed May 1, 2021
2 parents 3e80895 + 0406194 commit 1baea15
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 1 deletion.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,20 @@ consider client-side load balancing using consistent hashing.

See [`./examples/kubernetes/consistenthash`](./examples/kubernetes/consistenthash).

## Metadata

To output build metadata such as the image digest, pass the `--metadata-file` flag.
The metadata will be written as a JSON object to the specified file.
The directory of the specified file must already exist and be writable.

```
buildctl build ... --metadata-file metadata.json
```

```
{"containerimage.digest": "sha256:ea0cfb27fd41ea0405d3095880c1efa45710f5bcdddb7d7d5a7317ad4825ae14",...}
```

## Systemd socket activation

On Systemd based systems, you can communicate with the daemon via [Systemd socket activation](http://0pointer.de/blog/projects/socket-activation.html), use `buildkitd --addr fd://`.
Expand Down
23 changes: 22 additions & 1 deletion cmd/buildctl/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"io"
"os"

"github.com/containerd/continuity"
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/cmd/buildctl/build"
Expand Down Expand Up @@ -101,6 +102,10 @@ var buildCommand = cli.Command{
Name: "ssh",
Usage: "Allow forwarding SSH agent to the builder. Format default|<id>[=<socket>|<key>[,<key>]]",
},
cli.StringFlag{
Name: "metadata-file",
Usage: "Output build metadata (e.g., image digest) to a file as JSON",
},
},
}

Expand Down Expand Up @@ -290,7 +295,15 @@ func buildAction(clicontext *cli.Context) error {
for k, v := range resp.ExporterResponse {
logrus.Debugf("exporter response: %s=%s", k, v)
}
return err

metadataFile := clicontext.String("metadata-file")
if metadataFile != "" && resp.ExporterResponse != nil {
if err := writeMetadataFile(metadataFile, resp.ExporterResponse); err != nil {
return err
}
}

return nil
})

eg.Go(func() error {
Expand All @@ -300,3 +313,11 @@ func buildAction(clicontext *cli.Context) error {

return eg.Wait()
}

func writeMetadataFile(filename string, exporterResponse map[string]string) error {
b, err := json.Marshal(exporterResponse)
if err != nil {
return err
}
return continuity.AtomicWriteFile(filename, b, 0666)
}
56 changes: 56 additions & 0 deletions cmd/buildctl/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
Expand Down Expand Up @@ -111,6 +112,61 @@ func testBuildContainerdExporter(t *testing.T, sb integration.Sandbox) {
require.Equal(t, ok, true)
}

func testBuildMetadataFile(t *testing.T, sb integration.Sandbox) {
st := llb.Image("busybox").
Run(llb.Shlex("sh -c 'echo -n bar > /foo'"))

rdr, err := marshal(st.Root())
require.NoError(t, err)

tmpDir, err := ioutil.TempDir("", "buildkit-buildctl")
require.NoError(t, err)
defer os.RemoveAll(tmpDir)

imageName := "example.com/moby/metadata:test"
metadataFile := filepath.Join(tmpDir, "metadata.json")

buildCmd := []string{
"build", "--progress=plain",
"--output type=image,name=" + imageName + ",push=false",
"--metadata-file", metadataFile,
}

cmd := sb.Cmd(strings.Join(buildCmd, " "))
cmd.Stdin = rdr
err = cmd.Run()
require.NoError(t, err)

require.FileExists(t, metadataFile)
metadataBytes, err := ioutil.ReadFile(metadataFile)
require.NoError(t, err)

var metadata map[string]string
err = json.Unmarshal(metadataBytes, &metadata)
require.NoError(t, err)

require.Equal(t, imageName, metadata["image.name"])

digest := metadata["containerimage.digest"]
require.NotEmpty(t, digest)

cdAddress := sb.ContainerdAddress()
if cdAddress == "" {
t.Log("no containerd worker, skipping digest verification")
} else {
client, err := containerd.New(cdAddress, containerd.WithTimeout(60*time.Second))
require.NoError(t, err)
defer client.Close()

ctx := namespaces.WithNamespace(context.Background(), "buildkit")

img, err := client.GetImage(ctx, imageName)
require.NoError(t, err)

require.Equal(t, img.Metadata().Target.Digest.String(), digest)
}
}

func marshal(st llb.State) (io.Reader, error) {
def, err := st.Marshal(context.TODO())
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions cmd/buildctl/buildctl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func TestCLIIntegration(t *testing.T) {
testBuildWithLocalFiles,
testBuildLocalExporter,
testBuildContainerdExporter,
testBuildMetadataFile,
testPrune,
testUsage,
},
Expand Down

0 comments on commit 1baea15

Please sign in to comment.