build: fix writing correct image ID with -q

Container driver wrote manifest digest that had a
mismatch with --iidfile output.

When --iidfile was set the --metadata-file was not
written.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
Tonis Tiigi 2023-05-26 00:20:29 -07:00
parent b273db20c3
commit 68ae67720a
No known key found for this signature in database
GPG Key ID: AFA9DE5F8AB7AF39
2 changed files with 68 additions and 5 deletions

View File

@ -274,14 +274,12 @@ func runBuild(dockerCli command.Cli, options buildOptions) (err error) {
}
if options.quiet {
fmt.Println(resp.ExporterResponse[exptypes.ExporterImageDigestKey])
fmt.Println(getImageID(resp.ExporterResponse))
}
if options.imageIDFile != "" {
dgst := resp.ExporterResponse[exptypes.ExporterImageDigestKey]
if v, ok := resp.ExporterResponse[exptypes.ExporterImageConfigDigestKey]; ok {
dgst = v
if err := os.WriteFile(options.imageIDFile, []byte(getImageID(resp.ExporterResponse)), 0644); err != nil {
return errors.Wrap(err, "writing image ID file")
}
return os.WriteFile(options.imageIDFile, []byte(dgst), 0644)
}
if options.metadataFile != "" {
if err := writeMetadataFile(options.metadataFile, decodeExporterResponse(resp.ExporterResponse)); err != nil {
@ -296,6 +294,15 @@ func runBuild(dockerCli command.Cli, options buildOptions) (err error) {
return nil
}
// getImageID returns the image ID - the digest of the image config
func getImageID(resp map[string]string) string {
dgst := resp[exptypes.ExporterImageDigestKey]
if v, ok := resp[exptypes.ExporterImageConfigDigestKey]; ok {
dgst = v
}
return dgst
}
func runBasicBuild(ctx context.Context, dockerCli command.Cli, opts *controllerapi.BuildOptions, options buildOptions, printer *progress.Printer) (*client.SolveResponse, error) {
resp, _, err := cbuild.RunBuild(ctx, dockerCli, *opts, os.Stdin, printer, false)
return resp, err

View File

@ -1,9 +1,13 @@
package tests
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"testing"
"github.com/containerd/containerd/platforms"
@ -11,6 +15,7 @@ import (
"github.com/moby/buildkit/util/contentutil"
"github.com/moby/buildkit/util/testutil"
"github.com/moby/buildkit/util/testutil/integration"
"github.com/opencontainers/go-digest"
"github.com/stretchr/testify/require"
)
@ -23,6 +28,7 @@ func buildCmd(sb integration.Sandbox, args ...string) (string, error) {
var buildTests = []func(t *testing.T, sb integration.Sandbox){
testBuild,
testImageIDOutput,
testBuildLocalExport,
testBuildRegistryExport,
testBuildTarExport,
@ -83,6 +89,56 @@ func testBuildRegistryExport(t *testing.T, sb integration.Sandbox) {
require.Equal(t, img.Layers[0]["bar"].Data, []byte("foo"))
}
func testImageIDOutput(t *testing.T, sb integration.Sandbox) {
dockerfile := []byte(`FROM busybox:latest`)
dir, err := tmpdir(t,
fstest.CreateFile("Dockerfile", dockerfile, 0600),
)
require.NoError(t, err)
targetDir := t.TempDir()
outFlag := "--output=type=docker"
if sb.Name() == "remote" {
// there is no Docker atm to load the image
outFlag += ",dest=" + targetDir + "/image.tar"
}
cmd := buildxCmd(sb, "build", "-q", outFlag, "--iidfile", filepath.Join(targetDir, "iid.txt"), "--metadata-file", filepath.Join(targetDir, "md.json"), dir)
stdout := bytes.NewBuffer(nil)
cmd.Stdout = stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
require.NoError(t, err)
dt, err := os.ReadFile(filepath.Join(targetDir, "iid.txt"))
require.NoError(t, err)
imageID := string(dt)
require.NotEmpty(t, imageID)
dgst, err := digest.Parse(string(dt))
require.NoError(t, err)
require.Equal(t, dgst.String(), strings.TrimSpace(stdout.String()))
dt, err = os.ReadFile(filepath.Join(targetDir, "md.json"))
require.NoError(t, err)
type mdT struct {
ConfigDigest string `json:"containerimage.config.digest"`
}
var md mdT
err = json.Unmarshal(dt, &md)
require.NoError(t, err)
require.NotEmpty(t, md.ConfigDigest)
require.Equal(t, dgst, digest.Digest(md.ConfigDigest))
}
func createTestProject(t *testing.T) string {
dockerfile := []byte(`
FROM busybox:latest AS base