Merge pull request #946 from crazy-max/metadata-output

build: enhance metadata json output
pull/949/head
Tõnis Tiigi 3 years ago committed by GitHub
commit e5f590a7fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -31,6 +31,7 @@ jobs:
- mnode-false - mnode-false
- mnode-true - mnode-true
platforms: platforms:
- linux/amd64
- linux/amd64,linux/arm64 - linux/amd64,linux/arm64
include: include:
- driver: kubernetes - driver: kubernetes

@ -13,7 +13,6 @@ import (
"github.com/docker/buildx/util/progress" "github.com/docker/buildx/util/progress"
"github.com/docker/buildx/util/tracing" "github.com/docker/buildx/util/tracing"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/docker/pkg/ioutils"
"github.com/moby/buildkit/util/appcontext" "github.com/moby/buildkit/util/appcontext"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -152,18 +151,22 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions) (err error
} }
if len(in.metadataFile) > 0 && resp != nil { if len(in.metadataFile) > 0 && resp != nil {
mdata := map[string]map[string]string{} if len(resp) == 1 {
for k, r := range resp { for _, r := range resp {
mdata[k] = r.ExporterResponse if err := writeMetadataFile(in.metadataFile, decodeExporterResponse(r.ExporterResponse)); err != nil {
}
mdatab, err := json.MarshalIndent(mdata, "", " ")
if err != nil {
return err return err
} }
if err := ioutils.AtomicWriteFile(in.metadataFile, mdatab, 0644); err != nil { }
} else {
dt := make(map[string]interface{})
for t, r := range resp {
dt[t] = decodeExporterResponse(r.ExporterResponse)
}
if err := writeMetadataFile(in.metadataFile, dt); err != nil {
return err return err
} }
} }
}
return err return err
} }

@ -3,6 +3,7 @@ package commands
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
@ -251,11 +252,7 @@ func buildTargets(ctx context.Context, dockerCli command.Cli, opts map[string]bu
} }
if len(metadataFile) > 0 && resp != nil { if len(metadataFile) > 0 && resp != nil {
mdatab, err := json.MarshalIndent(resp[defaultTargetName].ExporterResponse, "", " ") if err := writeMetadataFile(metadataFile, decodeExporterResponse(resp[defaultTargetName].ExporterResponse)); err != nil {
if err != nil {
return "", err
}
if err := ioutils.AtomicWriteFile(metadataFile, mdatab, 0644); err != nil {
return "", err return "", err
} }
} }
@ -496,6 +493,32 @@ func parseContextNames(values []string) (map[string]string, error) {
return result, nil return result, nil
} }
func writeMetadataFile(filename string, dt interface{}) error {
b, err := json.MarshalIndent(dt, "", " ")
if err != nil {
return err
}
return ioutils.AtomicWriteFile(filename, b, 0644)
}
func decodeExporterResponse(exporterResponse map[string]string) map[string]interface{} {
out := make(map[string]interface{})
for k, v := range exporterResponse {
dt, err := base64.StdEncoding.DecodeString(v)
if err != nil {
out[k] = v
continue
}
var raw map[string]interface{}
if err = json.Unmarshal(dt, &raw); err != nil || len(raw) == 0 {
out[k] = v
continue
}
out[k] = json.RawMessage(dt)
}
return out
}
func wrapBuildError(err error) error { func wrapBuildError(err error) error {
if err == nil { if err == nil {
return nil return nil

@ -10,13 +10,20 @@ set -eu -o pipefail
: ${MULTI_NODE=0} : ${MULTI_NODE=0}
: ${PLATFORMS=linux/amd64,linux/arm64} : ${PLATFORMS=linux/amd64,linux/arm64}
function buildxCmd {
(set -x ; $BUILDX_CMD "$@")
}
function clean { function clean {
rm -rf "$context" rm -rf "$context"
${BUILDX_CMD} rm "$builderName" if [ "$builderName" != "default" ]; then
buildxCmd rm "$builderName"
fi
} }
context=$(mktemp -d -t buildx-output.XXXXXXXXXX) context=$(mktemp -d -t buildx-output.XXXXXXXXXX)
dockerfile=${context}/Dockerfile dockerfile=${context}/Dockerfile
bakedef=${context}/docker-bake.hcl
trap clean EXIT trap clean EXIT
builderName=buildx-test-$(openssl rand -hex 16) builderName=buildx-test-$(openssl rand -hex 16)
@ -44,15 +51,12 @@ if [ "$DRIVER" != "docker" ]; then
if [ "$firstNode" = "0" ]; then if [ "$firstNode" = "0" ]; then
createFlags="$createFlags --append" createFlags="$createFlags --append"
fi fi
( buildxCmd create ${createFlags} \
set -x
${BUILDX_CMD} create ${createFlags} \
--name="${builderName}" \ --name="${builderName}" \
--node="${builderName}-${platform/\//-}" \ --node="${builderName}-${platform/\//-}" \
--driver="${DRIVER}" \ --driver="${DRIVER}" \
--driver-opt="${driverOpt}" \ --driver-opt="${driverOpt}" \
--platform="${platform}" --platform="${platform}"
)
firstNode=0 firstNode=0
done done
else else
@ -60,27 +64,37 @@ if [ "$DRIVER" != "docker" ]; then
if [ -f "$BUILDKIT_CFG" ]; then if [ -f "$BUILDKIT_CFG" ]; then
createFlags="$createFlags --config=${BUILDKIT_CFG}" createFlags="$createFlags --config=${BUILDKIT_CFG}"
fi fi
( buildxCmd create ${createFlags} \
set -x
${BUILDX_CMD} create ${createFlags} \
--name="${builderName}" \ --name="${builderName}" \
--driver="${DRIVER}" \ --driver="${DRIVER}" \
--driver-opt="${driverOpt}" \ --driver-opt="${driverOpt}" \
--platform="${PLATFORMS}" --platform="${PLATFORMS}"
)
fi fi
fi fi
function buildOutput {
local name=$1
if [ "$DRIVER" != "docker" ]; then
if [ "${MULTI_NODE}" = "1" ]; then
echo "type=cacheonly"
else
echo "type=oci,dest=${context}/${name}.tar"
fi
else
echo "type=docker,name=${name}"
fi
}
# multi-platform not supported by docker driver # multi-platform not supported by docker driver
buildPlatformFlag= buildPlatformFlag=
bakePlatformFlag=
if [ "$DRIVER" != "docker" ]; then if [ "$DRIVER" != "docker" ]; then
buildPlatformFlag=--platform="${PLATFORMS}" buildPlatformFlag=--platform="${PLATFORMS}"
bakePlatformFlag=--set="*.platform=${PLATFORMS}"
fi fi
set -x
# inspect and bootstrap # inspect and bootstrap
${BUILDX_CMD} inspect --bootstrap --builder="${builderName}" buildxCmd inspect --bootstrap --builder="${builderName}"
# create dockerfile # create dockerfile
cat > "${dockerfile}" <<EOL cat > "${dockerfile}" <<EOL
@ -88,14 +102,60 @@ FROM busybox as build
ARG TARGETPLATFORM ARG TARGETPLATFORM
ARG BUILDPLATFORM ARG BUILDPLATFORM
RUN echo "I am running on \$BUILDPLATFORM, building for \$TARGETPLATFORM" > /log RUN echo "I am running on \$BUILDPLATFORM, building for \$TARGETPLATFORM" > /log
FROM busybox
FROM busybox AS log
COPY --from=build /log /log COPY --from=build /log /log
RUN cat /log RUN cat /log
RUN uname -a RUN uname -a
FROM busybox AS hello
RUN echo hello > /hello
FROM scratch
COPY --from=log /log /log
COPY --from=hello /hello /hello
EOL EOL
# build # build
${BUILDX_CMD} build ${buildPlatformFlag} \ buildxCmd build ${buildPlatformFlag} \
--output="type=cacheonly" \ --output="$(buildOutput buildx-test-build)" \
--builder="${builderName}" \ --builder="${builderName}" \
--metadata-file="${context}/metadata-build.json" \
"${context}" "${context}"
cat "${context}/metadata-build.json"
# create bake def
cat > "${bakedef}" <<EOL
group "default" {
targets = ["release"]
}
group "all" {
targets = ["log", "hello"]
}
target "release" {
output = ["$(buildOutput buildx-test-bake-release)"]
}
target "log" {
output = ["$(buildOutput buildx-test-bake-log)"]
}
target "hello" {
output = ["$(buildOutput buildx-test-bake-hello)"]
}
EOL
# bake default target
buildxCmd bake ${bakePlatformFlag} \
--file="${bakedef}" \
--builder="${builderName}" \
--set "*.context=${context}" \
--metadata-file="${context}/metadata-bake-def.json"
cat "${context}/metadata-bake-def.json"
# bake all target
buildxCmd bake ${bakePlatformFlag} \
--file="${bakedef}" \
--builder="${builderName}" \
--set "*.context=${context}" \
--metadata-file="${context}/metadata-bake-all.json" \
all
cat "${context}/metadata-bake-all.json"

Loading…
Cancel
Save