mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-08-15 08:15:55 +08:00
Compare commits
11 Commits
v0.22.0-rc
...
v0.21.0-rc
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d9f8c73375 | ||
![]() |
af5d0d4ab5 | ||
![]() |
20256b6999 | ||
![]() |
c09d38af8a | ||
![]() |
9430ed6752 | ||
![]() |
3b31a33d59 | ||
![]() |
5e5568f3cd | ||
![]() |
9ac9a4170b | ||
![]() |
8d1ba91dcb | ||
![]() |
0df7a75961 | ||
![]() |
de5fbc38b8 |
26
.github/workflows/build.yml
vendored
26
.github/workflows/build.yml
vendored
@@ -54,9 +54,9 @@ jobs:
|
||||
- master
|
||||
- latest
|
||||
- buildx-stable-1
|
||||
- v0.20.1
|
||||
- v0.19.0
|
||||
- v0.18.2
|
||||
- v0.17.2
|
||||
worker:
|
||||
- docker-container
|
||||
- remote
|
||||
@@ -76,16 +76,6 @@ jobs:
|
||||
- worker: docker+containerd # same as docker, but with containerd snapshotter
|
||||
pkg: ./tests
|
||||
mode: experimental
|
||||
- worker: "docker@27.5"
|
||||
pkg: ./tests
|
||||
- worker: "docker+containerd@27.5" # same as docker, but with containerd snapshotter
|
||||
pkg: ./tests
|
||||
- worker: "docker@27.5"
|
||||
pkg: ./tests
|
||||
mode: experimental
|
||||
- worker: "docker+containerd@27.5" # same as docker, but with containerd snapshotter
|
||||
pkg: ./tests
|
||||
mode: experimental
|
||||
- worker: "docker@26.1"
|
||||
pkg: ./tests
|
||||
- worker: "docker+containerd@26.1" # same as docker, but with containerd snapshotter
|
||||
@@ -258,17 +248,12 @@ jobs:
|
||||
matrix:
|
||||
os:
|
||||
- freebsd
|
||||
- netbsd
|
||||
- openbsd
|
||||
steps:
|
||||
-
|
||||
name: Prepare
|
||||
run: |
|
||||
echo "VAGRANT_FILE=hack/Vagrantfile.${{ matrix.os }}" >> $GITHUB_ENV
|
||||
|
||||
# Sets semver Go version to be able to download tarball during vagrant setup
|
||||
goVersion=$(curl --silent "https://go.dev/dl/?mode=json&include=all" | jq -r '.[].files[].version' | uniq | sed -e 's/go//' | sort -V | grep $GO_VERSION | tail -1)
|
||||
echo "GO_VERSION=$goVersion" >> $GITHUB_ENV
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
@@ -411,15 +396,6 @@ jobs:
|
||||
- test-unit
|
||||
if: ${{ github.event_name != 'pull_request' && github.repository == 'docker/buildx' }}
|
||||
steps:
|
||||
-
|
||||
name: Free disk space
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1
|
||||
with:
|
||||
android: true
|
||||
dotnet: true
|
||||
haskell: true
|
||||
large-packages: true
|
||||
swap-storage: true
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
2
.github/workflows/docs-release.yml
vendored
2
.github/workflows/docs-release.yml
vendored
@@ -77,7 +77,7 @@ jobs:
|
||||
VENDOR_MODULE: github.com/docker/buildx@${{ env.RELEASE_NAME }}
|
||||
-
|
||||
name: Create PR on docs repo
|
||||
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
||||
uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # v7.0.6
|
||||
with:
|
||||
token: ${{ secrets.GHPAT_DOCS_DISPATCH }}
|
||||
push-to-fork: docker-tools-robot/docker.github.io
|
||||
|
6
.github/workflows/e2e.yml
vendored
6
.github/workflows/e2e.yml
vendored
@@ -29,7 +29,7 @@ env:
|
||||
SETUP_BUILDX_VERSION: "edge"
|
||||
SETUP_BUILDKIT_IMAGE: "moby/buildkit:latest"
|
||||
DESTDIR: "./bin"
|
||||
K3S_VERSION: "v1.32.2+k3s1"
|
||||
K3S_VERSION: "v1.21.2-k3s1"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -65,7 +65,7 @@ jobs:
|
||||
retention-days: 7
|
||||
|
||||
driver:
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ubuntu-20.04
|
||||
needs:
|
||||
- build
|
||||
strategy:
|
||||
@@ -153,7 +153,7 @@ jobs:
|
||||
-
|
||||
name: Install k3s
|
||||
if: matrix.driver == 'kubernetes'
|
||||
uses: crazy-max/.github/.github/actions/install-k3s@7730d1434364d4b9aded32735b078a7ace5ea79a
|
||||
uses: crazy-max/.github/.github/actions/install-k3s@fa6141aedf23596fb8bdcceab9cce8dadaa31bd9
|
||||
with:
|
||||
version: ${{ env.K3S_VERSION }}
|
||||
-
|
||||
|
20
Dockerfile
20
Dockerfile
@@ -5,23 +5,20 @@ ARG ALPINE_VERSION=3.21
|
||||
ARG XX_VERSION=1.6.1
|
||||
|
||||
# for testing
|
||||
ARG DOCKER_VERSION=28.0.0
|
||||
ARG DOCKER_VERSION_ALT_27=27.5.1
|
||||
ARG DOCKER_VERSION=28.0.0-rc.1
|
||||
ARG DOCKER_VERSION_ALT_26=26.1.3
|
||||
ARG DOCKER_CLI_VERSION=${DOCKER_VERSION}
|
||||
ARG GOTESTSUM_VERSION=v1.12.0
|
||||
ARG REGISTRY_VERSION=2.8.3
|
||||
ARG BUILDKIT_VERSION=v0.20.1
|
||||
ARG BUILDKIT_VERSION=v0.19.0
|
||||
ARG UNDOCK_VERSION=0.9.0
|
||||
|
||||
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
|
||||
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS golatest
|
||||
FROM moby/moby-bin:$DOCKER_VERSION AS docker-engine
|
||||
FROM dockereng/cli-bin:$DOCKER_CLI_VERSION AS docker-cli
|
||||
FROM moby/moby-bin:$DOCKER_VERSION_ALT_27 AS docker-engine-alt27
|
||||
FROM moby/moby-bin:$DOCKER_VERSION_ALT_26 AS docker-engine-alt26
|
||||
FROM dockereng/cli-bin:$DOCKER_VERSION_ALT_27 AS docker-cli-alt27
|
||||
FROM dockereng/cli-bin:$DOCKER_VERSION_ALT_26 AS docker-cli-alt26
|
||||
FROM moby/moby-bin:$DOCKER_VERSION_ALT_26 AS docker-engine-alt
|
||||
FROM dockereng/cli-bin:$DOCKER_VERSION_ALT_26 AS docker-cli-alt
|
||||
FROM registry:$REGISTRY_VERSION AS registry
|
||||
FROM moby/buildkit:$BUILDKIT_VERSION AS buildkit
|
||||
FROM crazymax/undock:$UNDOCK_VERSION AS undock
|
||||
@@ -105,7 +102,6 @@ COPY --link --from=buildx-build /usr/bin/docker-buildx /buildx
|
||||
FROM binaries-unix AS binaries-darwin
|
||||
FROM binaries-unix AS binaries-freebsd
|
||||
FROM binaries-unix AS binaries-linux
|
||||
FROM binaries-unix AS binaries-netbsd
|
||||
FROM binaries-unix AS binaries-openbsd
|
||||
|
||||
FROM scratch AS binaries-windows
|
||||
@@ -131,15 +127,13 @@ COPY --link --from=gotestsum /out /usr/bin/
|
||||
COPY --link --from=registry /bin/registry /usr/bin/
|
||||
COPY --link --from=docker-engine / /usr/bin/
|
||||
COPY --link --from=docker-cli / /usr/bin/
|
||||
COPY --link --from=docker-engine-alt27 / /opt/docker-alt-27/
|
||||
COPY --link --from=docker-engine-alt26 / /opt/docker-alt-26/
|
||||
COPY --link --from=docker-cli-alt27 / /opt/docker-alt-27/
|
||||
COPY --link --from=docker-cli-alt26 / /opt/docker-alt-26/
|
||||
COPY --link --from=docker-engine-alt / /opt/docker-alt-26/
|
||||
COPY --link --from=docker-cli-alt / /opt/docker-alt-26/
|
||||
COPY --link --from=buildkit /usr/bin/buildkitd /usr/bin/
|
||||
COPY --link --from=buildkit /usr/bin/buildctl /usr/bin/
|
||||
COPY --link --from=undock /usr/local/bin/undock /usr/bin/
|
||||
COPY --link --from=binaries /buildx /usr/bin/
|
||||
ENV TEST_DOCKER_EXTRA="docker@27.5=/opt/docker-alt-27,docker@26.1=/opt/docker-alt-26"
|
||||
ENV TEST_DOCKER_EXTRA="docker@26.1=/opt/docker-alt-26"
|
||||
|
||||
FROM integration-test-base AS integration-test
|
||||
COPY . .
|
||||
|
86
bake/bake.go
86
bake/bake.go
@@ -45,7 +45,6 @@ type File struct {
|
||||
type Override struct {
|
||||
Value string
|
||||
ArrValue []string
|
||||
Append bool
|
||||
}
|
||||
|
||||
func defaultFilenames() []string {
|
||||
@@ -486,8 +485,10 @@ func (c Config) loadLinks(name string, t *Target, m map[string]*Target, o map[st
|
||||
if target == name {
|
||||
return errors.Errorf("target %s cannot link to itself", target)
|
||||
}
|
||||
if slices.Contains(visited, target) {
|
||||
return errors.Errorf("infinite loop from %s to %s", name, target)
|
||||
for _, v := range visited {
|
||||
if v == target {
|
||||
return errors.Errorf("infinite loop from %s to %s", name, target)
|
||||
}
|
||||
}
|
||||
t2, ok := m[target]
|
||||
if !ok {
|
||||
@@ -527,12 +528,9 @@ func (c Config) newOverrides(v []string) (map[string]map[string]Override, error)
|
||||
m := map[string]map[string]Override{}
|
||||
for _, v := range v {
|
||||
parts := strings.SplitN(v, "=", 2)
|
||||
|
||||
skey := strings.TrimSuffix(parts[0], "+")
|
||||
appendTo := strings.HasSuffix(parts[0], "+")
|
||||
keys := strings.SplitN(skey, ".", 3)
|
||||
keys := strings.SplitN(parts[0], ".", 3)
|
||||
if len(keys) < 2 {
|
||||
return nil, errors.Errorf("invalid override key %s, expected target.name", skey)
|
||||
return nil, errors.Errorf("invalid override key %s, expected target.name", parts[0])
|
||||
}
|
||||
|
||||
pattern := keys[0]
|
||||
@@ -545,7 +543,8 @@ func (c Config) newOverrides(v []string) (map[string]map[string]Override, error)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
okey := strings.Join(keys[1:], ".")
|
||||
kk := strings.SplitN(parts[0], ".", 2)
|
||||
|
||||
for _, name := range names {
|
||||
t, ok := m[name]
|
||||
if !ok {
|
||||
@@ -553,15 +552,14 @@ func (c Config) newOverrides(v []string) (map[string]map[string]Override, error)
|
||||
m[name] = t
|
||||
}
|
||||
|
||||
override := t[okey]
|
||||
o := t[kk[1]]
|
||||
|
||||
// IMPORTANT: if you add more fields here, do not forget to update
|
||||
// docs/reference/buildx_bake.md (--set) and https://docs.docker.com/build/bake/overrides/
|
||||
// docs/bake-reference.md and https://docs.docker.com/build/bake/overrides/
|
||||
switch keys[1] {
|
||||
case "output", "cache-to", "cache-from", "tags", "platform", "secrets", "ssh", "attest", "entitlements", "network", "annotations":
|
||||
case "output", "cache-to", "cache-from", "tags", "platform", "secrets", "ssh", "attest", "entitlements", "network":
|
||||
if len(parts) == 2 {
|
||||
override.Append = appendTo
|
||||
override.ArrValue = append(override.ArrValue, parts[1])
|
||||
o.ArrValue = append(o.ArrValue, parts[1])
|
||||
}
|
||||
case "args":
|
||||
if len(keys) != 3 {
|
||||
@@ -572,7 +570,7 @@ func (c Config) newOverrides(v []string) (map[string]map[string]Override, error)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
override.Value = v
|
||||
o.Value = v
|
||||
}
|
||||
fallthrough
|
||||
case "contexts":
|
||||
@@ -582,11 +580,11 @@ func (c Config) newOverrides(v []string) (map[string]map[string]Override, error)
|
||||
fallthrough
|
||||
default:
|
||||
if len(parts) == 2 {
|
||||
override.Value = parts[1]
|
||||
o.Value = parts[1]
|
||||
}
|
||||
}
|
||||
|
||||
t[okey] = override
|
||||
t[kk[1]] = o
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
@@ -898,21 +896,13 @@ func (t *Target) AddOverrides(overrides map[string]Override, ent *EntitlementCon
|
||||
}
|
||||
t.Labels[keys[1]] = &value
|
||||
case "tags":
|
||||
if o.Append {
|
||||
t.Tags = append(t.Tags, o.ArrValue...)
|
||||
} else {
|
||||
t.Tags = o.ArrValue
|
||||
}
|
||||
t.Tags = o.ArrValue
|
||||
case "cache-from":
|
||||
cacheFrom, err := buildflags.ParseCacheEntry(o.ArrValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if o.Append {
|
||||
t.CacheFrom = t.CacheFrom.Merge(cacheFrom)
|
||||
} else {
|
||||
t.CacheFrom = cacheFrom
|
||||
}
|
||||
t.CacheFrom = cacheFrom
|
||||
for _, c := range t.CacheFrom {
|
||||
if c.Type == "local" {
|
||||
if v, ok := c.Attrs["src"]; ok {
|
||||
@@ -925,11 +915,7 @@ func (t *Target) AddOverrides(overrides map[string]Override, ent *EntitlementCon
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if o.Append {
|
||||
t.CacheTo = t.CacheTo.Merge(cacheTo)
|
||||
} else {
|
||||
t.CacheTo = cacheTo
|
||||
}
|
||||
t.CacheTo = cacheTo
|
||||
for _, c := range t.CacheTo {
|
||||
if c.Type == "local" {
|
||||
if v, ok := c.Attrs["dest"]; ok {
|
||||
@@ -946,11 +932,7 @@ func (t *Target) AddOverrides(overrides map[string]Override, ent *EntitlementCon
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "invalid value for outputs")
|
||||
}
|
||||
if o.Append {
|
||||
t.Secrets = t.Secrets.Merge(secrets)
|
||||
} else {
|
||||
t.Secrets = secrets
|
||||
}
|
||||
t.Secrets = secrets
|
||||
for _, s := range t.Secrets {
|
||||
if s.FilePath != "" {
|
||||
ent.FSRead = append(ent.FSRead, s.FilePath)
|
||||
@@ -961,30 +943,18 @@ func (t *Target) AddOverrides(overrides map[string]Override, ent *EntitlementCon
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "invalid value for outputs")
|
||||
}
|
||||
if o.Append {
|
||||
t.SSH = t.SSH.Merge(ssh)
|
||||
} else {
|
||||
t.SSH = ssh
|
||||
}
|
||||
t.SSH = ssh
|
||||
for _, s := range t.SSH {
|
||||
ent.FSRead = append(ent.FSRead, s.Paths...)
|
||||
}
|
||||
case "platform":
|
||||
if o.Append {
|
||||
t.Platforms = append(t.Platforms, o.ArrValue...)
|
||||
} else {
|
||||
t.Platforms = o.ArrValue
|
||||
}
|
||||
t.Platforms = o.ArrValue
|
||||
case "output":
|
||||
outputs, err := parseArrValue[buildflags.ExportEntry](o.ArrValue)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "invalid value for outputs")
|
||||
}
|
||||
if o.Append {
|
||||
t.Outputs = t.Outputs.Merge(outputs)
|
||||
} else {
|
||||
t.Outputs = outputs
|
||||
}
|
||||
t.Outputs = outputs
|
||||
for _, o := range t.Outputs {
|
||||
if o.Destination != "" {
|
||||
ent.FSWrite = append(ent.FSWrite, o.Destination)
|
||||
@@ -1014,19 +984,11 @@ func (t *Target) AddOverrides(overrides map[string]Override, ent *EntitlementCon
|
||||
}
|
||||
t.NoCache = &noCache
|
||||
case "no-cache-filter":
|
||||
if o.Append {
|
||||
t.NoCacheFilter = append(t.NoCacheFilter, o.ArrValue...)
|
||||
} else {
|
||||
t.NoCacheFilter = o.ArrValue
|
||||
}
|
||||
t.NoCacheFilter = o.ArrValue
|
||||
case "shm-size":
|
||||
t.ShmSize = &value
|
||||
case "ulimits":
|
||||
if o.Append {
|
||||
t.Ulimits = append(t.Ulimits, o.ArrValue...)
|
||||
} else {
|
||||
t.Ulimits = o.ArrValue
|
||||
}
|
||||
t.Ulimits = o.ArrValue
|
||||
case "network":
|
||||
t.NetworkMode = &value
|
||||
case "pull":
|
||||
|
@@ -34,18 +34,6 @@ target "webapp" {
|
||||
args = {
|
||||
VAR_BOTH = "webapp"
|
||||
}
|
||||
annotations = [
|
||||
"index,manifest:org.opencontainers.image.authors=dvdksn"
|
||||
]
|
||||
attest = [
|
||||
"type=provenance,mode=max"
|
||||
]
|
||||
platforms = [
|
||||
"linux/amd64"
|
||||
]
|
||||
secret = [
|
||||
"id=FOO,env=FOO"
|
||||
]
|
||||
inherits = ["webDEP"]
|
||||
}`),
|
||||
}
|
||||
@@ -127,31 +115,6 @@ target "webapp" {
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("AnnotationsOverrides", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
m, g, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.annotations=index,manifest:org.opencontainers.image.vendor=docker"}, nil, &EntitlementConf{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []string{"index,manifest:org.opencontainers.image.authors=dvdksn", "index,manifest:org.opencontainers.image.vendor=docker"}, m["webapp"].Annotations)
|
||||
require.Equal(t, 1, len(g))
|
||||
require.Equal(t, []string{"webapp"}, g["default"].Targets)
|
||||
})
|
||||
|
||||
t.Run("AttestOverride", func(t *testing.T) {
|
||||
m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.attest=type=sbom"}, nil, &EntitlementConf{})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, m["webapp"].Attest, 2)
|
||||
require.Equal(t, "provenance", m["webapp"].Attest[0].Type)
|
||||
require.Equal(t, "sbom", m["webapp"].Attest[1].Type)
|
||||
})
|
||||
|
||||
t.Run("AttestAppend", func(t *testing.T) {
|
||||
m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.attest+=type=sbom"}, nil, &EntitlementConf{})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, m["webapp"].Attest, 2)
|
||||
require.Equal(t, "provenance", m["webapp"].Attest[0].Type)
|
||||
require.Equal(t, "sbom", m["webapp"].Attest[1].Type)
|
||||
})
|
||||
|
||||
t.Run("ContextOverride", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.context"}, nil, &EntitlementConf{})
|
||||
@@ -173,49 +136,6 @@ target "webapp" {
|
||||
require.Equal(t, []string{"webapp"}, g["default"].Targets)
|
||||
})
|
||||
|
||||
t.Run("PlatformOverride", func(t *testing.T) {
|
||||
m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.platform=linux/arm64"}, nil, &EntitlementConf{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []string{"linux/arm64"}, m["webapp"].Platforms)
|
||||
})
|
||||
|
||||
t.Run("PlatformAppend", func(t *testing.T) {
|
||||
m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.platform+=linux/arm64"}, nil, &EntitlementConf{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []string{"linux/amd64", "linux/arm64"}, m["webapp"].Platforms)
|
||||
})
|
||||
|
||||
t.Run("PlatformAppendMulti", func(t *testing.T) {
|
||||
m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.platform+=linux/arm64", "webapp.platform+=linux/riscv64"}, nil, &EntitlementConf{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []string{"linux/amd64", "linux/arm64", "linux/riscv64"}, m["webapp"].Platforms)
|
||||
})
|
||||
|
||||
t.Run("PlatformAppendMultiLastOverride", func(t *testing.T) {
|
||||
m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.platform+=linux/arm64", "webapp.platform=linux/riscv64"}, nil, &EntitlementConf{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []string{"linux/arm64", "linux/riscv64"}, m["webapp"].Platforms)
|
||||
})
|
||||
|
||||
t.Run("SecretsOverride", func(t *testing.T) {
|
||||
t.Setenv("FOO", "foo")
|
||||
t.Setenv("BAR", "bar")
|
||||
m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.secrets=id=BAR,env=BAR"}, nil, &EntitlementConf{})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, m["webapp"].Secrets, 1)
|
||||
require.Equal(t, "BAR", m["webapp"].Secrets[0].ID)
|
||||
})
|
||||
|
||||
t.Run("SecretsAppend", func(t *testing.T) {
|
||||
t.Setenv("FOO", "foo")
|
||||
t.Setenv("BAR", "bar")
|
||||
m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.secrets+=id=BAR,env=BAR"}, nil, &EntitlementConf{})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, m["webapp"].Secrets, 2)
|
||||
require.Equal(t, "FOO", m["webapp"].Secrets[0].ID)
|
||||
require.Equal(t, "BAR", m["webapp"].Secrets[1].ID)
|
||||
})
|
||||
|
||||
t.Run("ShmSizeOverride", func(t *testing.T) {
|
||||
m, _, err := ReadTargets(ctx, []File{fp}, []string{"webapp"}, []string{"webapp.shm-size=256m"}, nil, &EntitlementConf{})
|
||||
require.NoError(t, err)
|
||||
|
@@ -315,7 +315,7 @@ type (
|
||||
stringArray []string
|
||||
)
|
||||
|
||||
func (sa *stringArray) UnmarshalYAML(unmarshal func(any) error) error {
|
||||
func (sa *stringArray) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
var multi []string
|
||||
err := unmarshal(&multi)
|
||||
if err != nil {
|
||||
@@ -332,7 +332,7 @@ func (sa *stringArray) UnmarshalYAML(unmarshal func(any) error) error {
|
||||
|
||||
// composeExtTarget converts Compose build extension x-bake to bake Target
|
||||
// https://github.com/compose-spec/compose-spec/blob/master/spec.md#extension
|
||||
func (t *Target) composeExtTarget(exts map[string]any) error {
|
||||
func (t *Target) composeExtTarget(exts map[string]interface{}) error {
|
||||
var xb xbake
|
||||
|
||||
ext, ok := exts["x-bake"]
|
||||
|
@@ -306,7 +306,7 @@ func (c EntitlementConf) Prompt(ctx context.Context, isRemote bool, out io.Write
|
||||
fmt.Fprintf(out, "\nPass %q to grant requested privileges.\n", strings.Join(slices.Concat(flags, flagsFS), " "))
|
||||
}
|
||||
|
||||
args := slices.Clone(os.Args)
|
||||
args := append([]string(nil), os.Args...)
|
||||
if v, ok := os.LookupEnv("DOCKER_CLI_PLUGIN_ORIGINAL_CLI_COMMAND"); ok && v != "" {
|
||||
args[0] = v
|
||||
}
|
||||
|
@@ -608,7 +608,7 @@ func TestHCLAttrsCapsuleType(t *testing.T) {
|
||||
target "app" {
|
||||
attest = [
|
||||
{ type = "provenance", mode = "max" },
|
||||
"type=sbom,disabled=true,generator=foo,\"ENV1=bar,baz\",ENV2=hello",
|
||||
"type=sbom,disabled=true",
|
||||
]
|
||||
|
||||
cache-from = [
|
||||
@@ -641,7 +641,7 @@ func TestHCLAttrsCapsuleType(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, 1, len(c.Targets))
|
||||
require.Equal(t, []string{"type=provenance,mode=max", "type=sbom,disabled=true,\"ENV1=bar,baz\",ENV2=hello,generator=foo"}, stringify(c.Targets[0].Attest))
|
||||
require.Equal(t, []string{"type=provenance,mode=max", "type=sbom,disabled=true"}, stringify(c.Targets[0].Attest))
|
||||
require.Equal(t, []string{"type=local,dest=../out", "type=oci,dest=../out.tar"}, stringify(c.Targets[0].Outputs))
|
||||
require.Equal(t, []string{"type=local,src=path/to/cache", "user/app:cache"}, stringify(c.Targets[0].CacheFrom))
|
||||
require.Equal(t, []string{"type=local,dest=path/to/cache"}, stringify(c.Targets[0].CacheTo))
|
||||
@@ -1645,7 +1645,7 @@ func TestHCLIndexOfFunc(t *testing.T) {
|
||||
require.Empty(t, c.Targets[1].Tags[1])
|
||||
}
|
||||
|
||||
func ptrstr(s any) *string {
|
||||
func ptrstr(s interface{}) *string {
|
||||
var n *string
|
||||
if reflect.ValueOf(s).Kind() == reflect.String {
|
||||
ss := s.(string)
|
||||
|
@@ -15,11 +15,11 @@ import (
|
||||
|
||||
// DecodeOptions allows customizing sections of the decoding process.
|
||||
type DecodeOptions struct {
|
||||
ImpliedType func(gv any) (cty.Type, error)
|
||||
ImpliedType func(gv interface{}) (cty.Type, error)
|
||||
Convert func(in cty.Value, want cty.Type) (cty.Value, error)
|
||||
}
|
||||
|
||||
func (o DecodeOptions) DecodeBody(body hcl.Body, ctx *hcl.EvalContext, val any) hcl.Diagnostics {
|
||||
func (o DecodeOptions) DecodeBody(body hcl.Body, ctx *hcl.EvalContext, val interface{}) hcl.Diagnostics {
|
||||
o = o.withDefaults()
|
||||
|
||||
rv := reflect.ValueOf(val)
|
||||
@@ -46,7 +46,7 @@ func (o DecodeOptions) DecodeBody(body hcl.Body, ctx *hcl.EvalContext, val any)
|
||||
// are returned then the given value may have been partially-populated but
|
||||
// may still be accessed by a careful caller for static analysis and editor
|
||||
// integration use-cases.
|
||||
func DecodeBody(body hcl.Body, ctx *hcl.EvalContext, val any) hcl.Diagnostics {
|
||||
func DecodeBody(body hcl.Body, ctx *hcl.EvalContext, val interface{}) hcl.Diagnostics {
|
||||
return DecodeOptions{}.DecodeBody(body, ctx, val)
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ func (o DecodeOptions) decodeBlockToValue(block *hcl.Block, ctx *hcl.EvalContext
|
||||
return diags
|
||||
}
|
||||
|
||||
func (o DecodeOptions) DecodeExpression(expr hcl.Expression, ctx *hcl.EvalContext, val any) hcl.Diagnostics {
|
||||
func (o DecodeOptions) DecodeExpression(expr hcl.Expression, ctx *hcl.EvalContext, val interface{}) hcl.Diagnostics {
|
||||
o = o.withDefaults()
|
||||
|
||||
srcVal, diags := expr.Value(ctx)
|
||||
@@ -332,7 +332,7 @@ func (o DecodeOptions) DecodeExpression(expr hcl.Expression, ctx *hcl.EvalContex
|
||||
// are returned then the given value may have been partially-populated but
|
||||
// may still be accessed by a careful caller for static analysis and editor
|
||||
// integration use-cases.
|
||||
func DecodeExpression(expr hcl.Expression, ctx *hcl.EvalContext, val any) hcl.Diagnostics {
|
||||
func DecodeExpression(expr hcl.Expression, ctx *hcl.EvalContext, val interface{}) hcl.Diagnostics {
|
||||
return DecodeOptions{}.DecodeExpression(expr, ctx, val)
|
||||
}
|
||||
|
||||
|
@@ -16,8 +16,8 @@ import (
|
||||
)
|
||||
|
||||
func TestDecodeBody(t *testing.T) {
|
||||
deepEquals := func(other any) func(v any) bool {
|
||||
return func(v any) bool {
|
||||
deepEquals := func(other interface{}) func(v interface{}) bool {
|
||||
return func(v interface{}) bool {
|
||||
return reflect.DeepEqual(v, other)
|
||||
}
|
||||
}
|
||||
@@ -45,19 +45,19 @@ func TestDecodeBody(t *testing.T) {
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
Body map[string]any
|
||||
Target func() any
|
||||
Check func(v any) bool
|
||||
Body map[string]interface{}
|
||||
Target func() interface{}
|
||||
Check func(v interface{}) bool
|
||||
DiagCount int
|
||||
}{
|
||||
{
|
||||
map[string]any{},
|
||||
map[string]interface{}{},
|
||||
makeInstantiateType(struct{}{}),
|
||||
deepEquals(struct{}{}),
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{},
|
||||
map[string]interface{}{},
|
||||
makeInstantiateType(struct {
|
||||
Name string `hcl:"name"`
|
||||
}{}),
|
||||
@@ -67,7 +67,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
1, // name is required
|
||||
},
|
||||
{
|
||||
map[string]any{},
|
||||
map[string]interface{}{},
|
||||
makeInstantiateType(struct {
|
||||
Name *string `hcl:"name"`
|
||||
}{}),
|
||||
@@ -77,7 +77,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
0,
|
||||
}, // name nil
|
||||
{
|
||||
map[string]any{},
|
||||
map[string]interface{}{},
|
||||
makeInstantiateType(struct {
|
||||
Name string `hcl:"name,optional"`
|
||||
}{}),
|
||||
@@ -87,9 +87,9 @@ func TestDecodeBody(t *testing.T) {
|
||||
0,
|
||||
}, // name optional
|
||||
{
|
||||
map[string]any{},
|
||||
map[string]interface{}{},
|
||||
makeInstantiateType(withNameExpression{}),
|
||||
func(v any) bool {
|
||||
func(v interface{}) bool {
|
||||
if v == nil {
|
||||
return false
|
||||
}
|
||||
@@ -109,11 +109,11 @@ func TestDecodeBody(t *testing.T) {
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
map[string]interface{}{
|
||||
"name": "Ermintrude",
|
||||
},
|
||||
makeInstantiateType(withNameExpression{}),
|
||||
func(v any) bool {
|
||||
func(v interface{}) bool {
|
||||
if v == nil {
|
||||
return false
|
||||
}
|
||||
@@ -133,7 +133,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
map[string]interface{}{
|
||||
"name": "Ermintrude",
|
||||
},
|
||||
makeInstantiateType(struct {
|
||||
@@ -145,7 +145,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
map[string]interface{}{
|
||||
"name": "Ermintrude",
|
||||
"age": 23,
|
||||
},
|
||||
@@ -158,7 +158,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
1, // Extraneous "age" property
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
map[string]interface{}{
|
||||
"name": "Ermintrude",
|
||||
"age": 50,
|
||||
},
|
||||
@@ -166,7 +166,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
Name string `hcl:"name"`
|
||||
Attrs hcl.Attributes `hcl:",remain"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
got := gotI.(struct {
|
||||
Name string `hcl:"name"`
|
||||
Attrs hcl.Attributes `hcl:",remain"`
|
||||
@@ -176,7 +176,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
map[string]interface{}{
|
||||
"name": "Ermintrude",
|
||||
"age": 50,
|
||||
},
|
||||
@@ -184,7 +184,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
Name string `hcl:"name"`
|
||||
Remain hcl.Body `hcl:",remain"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
got := gotI.(struct {
|
||||
Name string `hcl:"name"`
|
||||
Remain hcl.Body `hcl:",remain"`
|
||||
@@ -197,7 +197,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
map[string]interface{}{
|
||||
"name": "Ermintrude",
|
||||
"living": true,
|
||||
},
|
||||
@@ -217,7 +217,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
map[string]interface{}{
|
||||
"name": "Ermintrude",
|
||||
"age": 50,
|
||||
},
|
||||
@@ -226,7 +226,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
Body hcl.Body `hcl:",body"`
|
||||
Remain hcl.Body `hcl:",remain"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
got := gotI.(struct {
|
||||
Name string `hcl:"name"`
|
||||
Body hcl.Body `hcl:",body"`
|
||||
@@ -241,76 +241,76 @@ func TestDecodeBody(t *testing.T) {
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
"noodle": map[string]any{},
|
||||
map[string]interface{}{
|
||||
"noodle": map[string]interface{}{},
|
||||
},
|
||||
makeInstantiateType(struct {
|
||||
Noodle struct{} `hcl:"noodle,block"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
// Generating no diagnostics is good enough for this one.
|
||||
return true
|
||||
},
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
"noodle": []map[string]any{{}},
|
||||
map[string]interface{}{
|
||||
"noodle": []map[string]interface{}{{}},
|
||||
},
|
||||
makeInstantiateType(struct {
|
||||
Noodle struct{} `hcl:"noodle,block"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
// Generating no diagnostics is good enough for this one.
|
||||
return true
|
||||
},
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
"noodle": []map[string]any{{}, {}},
|
||||
map[string]interface{}{
|
||||
"noodle": []map[string]interface{}{{}, {}},
|
||||
},
|
||||
makeInstantiateType(struct {
|
||||
Noodle struct{} `hcl:"noodle,block"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
// Generating one diagnostic is good enough for this one.
|
||||
return true
|
||||
},
|
||||
1,
|
||||
},
|
||||
{
|
||||
map[string]any{},
|
||||
map[string]interface{}{},
|
||||
makeInstantiateType(struct {
|
||||
Noodle struct{} `hcl:"noodle,block"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
// Generating one diagnostic is good enough for this one.
|
||||
return true
|
||||
},
|
||||
1,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
"noodle": []map[string]any{},
|
||||
map[string]interface{}{
|
||||
"noodle": []map[string]interface{}{},
|
||||
},
|
||||
makeInstantiateType(struct {
|
||||
Noodle struct{} `hcl:"noodle,block"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
// Generating one diagnostic is good enough for this one.
|
||||
return true
|
||||
},
|
||||
1,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
"noodle": map[string]any{},
|
||||
map[string]interface{}{
|
||||
"noodle": map[string]interface{}{},
|
||||
},
|
||||
makeInstantiateType(struct {
|
||||
Noodle *struct{} `hcl:"noodle,block"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
return gotI.(struct {
|
||||
Noodle *struct{} `hcl:"noodle,block"`
|
||||
}).Noodle != nil
|
||||
@@ -318,13 +318,13 @@ func TestDecodeBody(t *testing.T) {
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
"noodle": []map[string]any{{}},
|
||||
map[string]interface{}{
|
||||
"noodle": []map[string]interface{}{{}},
|
||||
},
|
||||
makeInstantiateType(struct {
|
||||
Noodle *struct{} `hcl:"noodle,block"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
return gotI.(struct {
|
||||
Noodle *struct{} `hcl:"noodle,block"`
|
||||
}).Noodle != nil
|
||||
@@ -332,13 +332,13 @@ func TestDecodeBody(t *testing.T) {
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
"noodle": []map[string]any{},
|
||||
map[string]interface{}{
|
||||
"noodle": []map[string]interface{}{},
|
||||
},
|
||||
makeInstantiateType(struct {
|
||||
Noodle *struct{} `hcl:"noodle,block"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
return gotI.(struct {
|
||||
Noodle *struct{} `hcl:"noodle,block"`
|
||||
}).Noodle == nil
|
||||
@@ -346,26 +346,26 @@ func TestDecodeBody(t *testing.T) {
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
"noodle": []map[string]any{{}, {}},
|
||||
map[string]interface{}{
|
||||
"noodle": []map[string]interface{}{{}, {}},
|
||||
},
|
||||
makeInstantiateType(struct {
|
||||
Noodle *struct{} `hcl:"noodle,block"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
// Generating one diagnostic is good enough for this one.
|
||||
return true
|
||||
},
|
||||
1,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
"noodle": []map[string]any{},
|
||||
map[string]interface{}{
|
||||
"noodle": []map[string]interface{}{},
|
||||
},
|
||||
makeInstantiateType(struct {
|
||||
Noodle []struct{} `hcl:"noodle,block"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
noodle := gotI.(struct {
|
||||
Noodle []struct{} `hcl:"noodle,block"`
|
||||
}).Noodle
|
||||
@@ -374,13 +374,13 @@ func TestDecodeBody(t *testing.T) {
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
"noodle": []map[string]any{{}},
|
||||
map[string]interface{}{
|
||||
"noodle": []map[string]interface{}{{}},
|
||||
},
|
||||
makeInstantiateType(struct {
|
||||
Noodle []struct{} `hcl:"noodle,block"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
noodle := gotI.(struct {
|
||||
Noodle []struct{} `hcl:"noodle,block"`
|
||||
}).Noodle
|
||||
@@ -389,13 +389,13 @@ func TestDecodeBody(t *testing.T) {
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
"noodle": []map[string]any{{}, {}},
|
||||
map[string]interface{}{
|
||||
"noodle": []map[string]interface{}{{}, {}},
|
||||
},
|
||||
makeInstantiateType(struct {
|
||||
Noodle []struct{} `hcl:"noodle,block"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
noodle := gotI.(struct {
|
||||
Noodle []struct{} `hcl:"noodle,block"`
|
||||
}).Noodle
|
||||
@@ -404,15 +404,15 @@ func TestDecodeBody(t *testing.T) {
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
"noodle": map[string]any{},
|
||||
map[string]interface{}{
|
||||
"noodle": map[string]interface{}{},
|
||||
},
|
||||
makeInstantiateType(struct {
|
||||
Noodle struct {
|
||||
Name string `hcl:"name,label"`
|
||||
} `hcl:"noodle,block"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
//nolint:misspell
|
||||
// Generating two diagnostics is good enough for this one.
|
||||
// (one for the missing noodle block and the other for
|
||||
@@ -423,9 +423,9 @@ func TestDecodeBody(t *testing.T) {
|
||||
2,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
"noodle": map[string]any{
|
||||
"foo_foo": map[string]any{},
|
||||
map[string]interface{}{
|
||||
"noodle": map[string]interface{}{
|
||||
"foo_foo": map[string]interface{}{},
|
||||
},
|
||||
},
|
||||
makeInstantiateType(struct {
|
||||
@@ -433,7 +433,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
Name string `hcl:"name,label"`
|
||||
} `hcl:"noodle,block"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
noodle := gotI.(struct {
|
||||
Noodle struct {
|
||||
Name string `hcl:"name,label"`
|
||||
@@ -444,10 +444,10 @@ func TestDecodeBody(t *testing.T) {
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
"noodle": map[string]any{
|
||||
"foo_foo": map[string]any{},
|
||||
"bar_baz": map[string]any{},
|
||||
map[string]interface{}{
|
||||
"noodle": map[string]interface{}{
|
||||
"foo_foo": map[string]interface{}{},
|
||||
"bar_baz": map[string]interface{}{},
|
||||
},
|
||||
},
|
||||
makeInstantiateType(struct {
|
||||
@@ -455,17 +455,17 @@ func TestDecodeBody(t *testing.T) {
|
||||
Name string `hcl:"name,label"`
|
||||
} `hcl:"noodle,block"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
// One diagnostic is enough for this one.
|
||||
return true
|
||||
},
|
||||
1,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
"noodle": map[string]any{
|
||||
"foo_foo": map[string]any{},
|
||||
"bar_baz": map[string]any{},
|
||||
map[string]interface{}{
|
||||
"noodle": map[string]interface{}{
|
||||
"foo_foo": map[string]interface{}{},
|
||||
"bar_baz": map[string]interface{}{},
|
||||
},
|
||||
},
|
||||
makeInstantiateType(struct {
|
||||
@@ -473,7 +473,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
Name string `hcl:"name,label"`
|
||||
} `hcl:"noodle,block"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
noodles := gotI.(struct {
|
||||
Noodles []struct {
|
||||
Name string `hcl:"name,label"`
|
||||
@@ -484,9 +484,9 @@ func TestDecodeBody(t *testing.T) {
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
"noodle": map[string]any{
|
||||
"foo_foo": map[string]any{
|
||||
map[string]interface{}{
|
||||
"noodle": map[string]interface{}{
|
||||
"foo_foo": map[string]interface{}{
|
||||
"type": "rice",
|
||||
},
|
||||
},
|
||||
@@ -497,7 +497,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
Type string `hcl:"type"`
|
||||
} `hcl:"noodle,block"`
|
||||
}{}),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
noodle := gotI.(struct {
|
||||
Noodle struct {
|
||||
Name string `hcl:"name,label"`
|
||||
@@ -510,7 +510,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
},
|
||||
|
||||
{
|
||||
map[string]any{
|
||||
map[string]interface{}{
|
||||
"name": "Ermintrude",
|
||||
"age": 34,
|
||||
},
|
||||
@@ -522,31 +522,31 @@ func TestDecodeBody(t *testing.T) {
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
map[string]interface{}{
|
||||
"name": "Ermintrude",
|
||||
"age": 89,
|
||||
},
|
||||
makeInstantiateType(map[string]*hcl.Attribute(nil)),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
got := gotI.(map[string]*hcl.Attribute)
|
||||
return len(got) == 2 && got["name"] != nil && got["age"] != nil
|
||||
},
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
map[string]interface{}{
|
||||
"name": "Ermintrude",
|
||||
"age": 13,
|
||||
},
|
||||
makeInstantiateType(map[string]hcl.Expression(nil)),
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
got := gotI.(map[string]hcl.Expression)
|
||||
return len(got) == 2 && got["name"] != nil && got["age"] != nil
|
||||
},
|
||||
0,
|
||||
},
|
||||
{
|
||||
map[string]any{
|
||||
map[string]interface{}{
|
||||
"name": "Ermintrude",
|
||||
"living": true,
|
||||
},
|
||||
@@ -559,10 +559,10 @@ func TestDecodeBody(t *testing.T) {
|
||||
},
|
||||
{
|
||||
// Retain "nested" block while decoding
|
||||
map[string]any{
|
||||
map[string]interface{}{
|
||||
"plain": "foo",
|
||||
},
|
||||
func() any {
|
||||
func() interface{} {
|
||||
return &withNestedBlock{
|
||||
Plain: "bar",
|
||||
Nested: &withTwoAttributes{
|
||||
@@ -570,7 +570,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
},
|
||||
}
|
||||
},
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
foo := gotI.(withNestedBlock)
|
||||
return foo.Plain == "foo" && foo.Nested != nil && foo.Nested.A == "bar"
|
||||
},
|
||||
@@ -578,19 +578,19 @@ func TestDecodeBody(t *testing.T) {
|
||||
},
|
||||
{
|
||||
// Retain values in "nested" block while decoding
|
||||
map[string]any{
|
||||
"nested": map[string]any{
|
||||
map[string]interface{}{
|
||||
"nested": map[string]interface{}{
|
||||
"a": "foo",
|
||||
},
|
||||
},
|
||||
func() any {
|
||||
func() interface{} {
|
||||
return &withNestedBlock{
|
||||
Nested: &withTwoAttributes{
|
||||
B: "bar",
|
||||
},
|
||||
}
|
||||
},
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
foo := gotI.(withNestedBlock)
|
||||
return foo.Nested.A == "foo" && foo.Nested.B == "bar"
|
||||
},
|
||||
@@ -598,14 +598,14 @@ func TestDecodeBody(t *testing.T) {
|
||||
},
|
||||
{
|
||||
// Retain values in "nested" block list while decoding
|
||||
map[string]any{
|
||||
"nested": []map[string]any{
|
||||
map[string]interface{}{
|
||||
"nested": []map[string]interface{}{
|
||||
{
|
||||
"a": "foo",
|
||||
},
|
||||
},
|
||||
},
|
||||
func() any {
|
||||
func() interface{} {
|
||||
return &withListofNestedBlocks{
|
||||
Nested: []*withTwoAttributes{
|
||||
{
|
||||
@@ -614,7 +614,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
},
|
||||
}
|
||||
},
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
n := gotI.(withListofNestedBlocks)
|
||||
return n.Nested[0].A == "foo" && n.Nested[0].B == "bar"
|
||||
},
|
||||
@@ -622,14 +622,14 @@ func TestDecodeBody(t *testing.T) {
|
||||
},
|
||||
{
|
||||
// Remove additional elements from the list while decoding nested blocks
|
||||
map[string]any{
|
||||
"nested": []map[string]any{
|
||||
map[string]interface{}{
|
||||
"nested": []map[string]interface{}{
|
||||
{
|
||||
"a": "foo",
|
||||
},
|
||||
},
|
||||
},
|
||||
func() any {
|
||||
func() interface{} {
|
||||
return &withListofNestedBlocks{
|
||||
Nested: []*withTwoAttributes{
|
||||
{
|
||||
@@ -641,7 +641,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
},
|
||||
}
|
||||
},
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
n := gotI.(withListofNestedBlocks)
|
||||
return len(n.Nested) == 1
|
||||
},
|
||||
@@ -649,8 +649,8 @@ func TestDecodeBody(t *testing.T) {
|
||||
},
|
||||
{
|
||||
// Make sure decoding value slices works the same as pointer slices.
|
||||
map[string]any{
|
||||
"nested": []map[string]any{
|
||||
map[string]interface{}{
|
||||
"nested": []map[string]interface{}{
|
||||
{
|
||||
"b": "bar",
|
||||
},
|
||||
@@ -659,7 +659,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
func() any {
|
||||
func() interface{} {
|
||||
return &withListofNestedBlocksNoPointers{
|
||||
Nested: []withTwoAttributes{
|
||||
{
|
||||
@@ -668,7 +668,7 @@ func TestDecodeBody(t *testing.T) {
|
||||
},
|
||||
}
|
||||
},
|
||||
func(gotI any) bool {
|
||||
func(gotI interface{}) bool {
|
||||
n := gotI.(withListofNestedBlocksNoPointers)
|
||||
return n.Nested[0].B == "bar" && len(n.Nested) == 2
|
||||
},
|
||||
@@ -710,8 +710,8 @@ func TestDecodeBody(t *testing.T) {
|
||||
func TestDecodeExpression(t *testing.T) {
|
||||
tests := []struct {
|
||||
Value cty.Value
|
||||
Target any
|
||||
Want any
|
||||
Target interface{}
|
||||
Want interface{}
|
||||
DiagCount int
|
||||
}{
|
||||
{
|
||||
@@ -799,8 +799,8 @@ func (e *fixedExpression) Variables() []hcl.Traversal {
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeInstantiateType(target any) func() any {
|
||||
return func() any {
|
||||
func makeInstantiateType(target interface{}) func() interface{} {
|
||||
return func() interface{} {
|
||||
return reflect.New(reflect.TypeOf(target)).Interface()
|
||||
}
|
||||
}
|
||||
|
@@ -34,9 +34,9 @@ import (
|
||||
// The layout of the resulting HCL source is derived from the ordering of
|
||||
// the struct fields, with blank lines around nested blocks of different types.
|
||||
// Fields representing attributes should usually precede those representing
|
||||
// blocks so that the attributes can group together in the result. For more
|
||||
// blocks so that the attributes can group togather in the result. For more
|
||||
// control, use the hclwrite API directly.
|
||||
func EncodeIntoBody(val any, dst *hclwrite.Body) {
|
||||
func EncodeIntoBody(val interface{}, dst *hclwrite.Body) {
|
||||
rv := reflect.ValueOf(val)
|
||||
ty := rv.Type()
|
||||
if ty.Kind() == reflect.Ptr {
|
||||
@@ -60,7 +60,7 @@ func EncodeIntoBody(val any, dst *hclwrite.Body) {
|
||||
//
|
||||
// This function has the same constraints as EncodeIntoBody and will panic
|
||||
// if they are violated.
|
||||
func EncodeAsBlock(val any, blockType string) *hclwrite.Block {
|
||||
func EncodeAsBlock(val interface{}, blockType string) *hclwrite.Block {
|
||||
rv := reflect.ValueOf(val)
|
||||
ty := rv.Type()
|
||||
if ty.Kind() == reflect.Ptr {
|
||||
@@ -158,7 +158,7 @@ func populateBody(rv reflect.Value, ty reflect.Type, tags *fieldTags, dst *hclwr
|
||||
|
||||
if isSeq {
|
||||
l := fieldVal.Len()
|
||||
for i := range l {
|
||||
for i := 0; i < l; i++ {
|
||||
elemVal := fieldVal.Index(i)
|
||||
if !elemVal.IsValid() {
|
||||
continue // ignore (elem value is nil pointer)
|
||||
|
@@ -22,7 +22,7 @@ import (
|
||||
// This uses the tags on the fields of the struct to discover how each
|
||||
// field's value should be expressed within configuration. If an invalid
|
||||
// mapping is attempted, this function will panic.
|
||||
func ImpliedBodySchema(val any) (schema *hcl.BodySchema, partial bool) {
|
||||
func ImpliedBodySchema(val interface{}) (schema *hcl.BodySchema, partial bool) {
|
||||
ty := reflect.TypeOf(val)
|
||||
|
||||
if ty.Kind() == reflect.Ptr {
|
||||
@@ -134,7 +134,7 @@ func getFieldTags(ty reflect.Type) *fieldTags {
|
||||
}
|
||||
|
||||
ct := ty.NumField()
|
||||
for i := range ct {
|
||||
for i := 0; i < ct; i++ {
|
||||
field := ty.Field(i)
|
||||
tag := field.Tag.Get("hcl")
|
||||
if tag == "" {
|
||||
|
@@ -14,7 +14,7 @@ import (
|
||||
|
||||
func TestImpliedBodySchema(t *testing.T) {
|
||||
tests := []struct {
|
||||
val any
|
||||
val interface{}
|
||||
wantSchema *hcl.BodySchema
|
||||
wantPartial bool
|
||||
}{
|
||||
|
@@ -7,7 +7,6 @@ import (
|
||||
"math"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -590,7 +589,7 @@ type ParseMeta struct {
|
||||
AllVariables []*Variable
|
||||
}
|
||||
|
||||
func Parse(b hcl.Body, opt Opt, val any) (*ParseMeta, hcl.Diagnostics) {
|
||||
func Parse(b hcl.Body, opt Opt, val interface{}) (*ParseMeta, hcl.Diagnostics) {
|
||||
reserved := map[string]struct{}{}
|
||||
schema, _ := gohcl.ImpliedBodySchema(val)
|
||||
|
||||
@@ -764,7 +763,7 @@ func Parse(b hcl.Body, opt Opt, val any) (*ParseMeta, hcl.Diagnostics) {
|
||||
types := map[string]field{}
|
||||
renamed := map[string]map[string][]string{}
|
||||
vt := reflect.ValueOf(val).Elem().Type()
|
||||
for i := range vt.NumField() {
|
||||
for i := 0; i < vt.NumField(); i++ {
|
||||
tags := strings.Split(vt.Field(i).Tag.Get("hcl"), ",")
|
||||
|
||||
p.blockTypes[tags[0]] = vt.Field(i).Type.Elem().Elem()
|
||||
@@ -832,7 +831,7 @@ func Parse(b hcl.Body, opt Opt, val any) (*ParseMeta, hcl.Diagnostics) {
|
||||
oldValue, exists := t.values[lblName]
|
||||
if !exists && lblExists {
|
||||
if v.Elem().Field(t.idx).Type().Kind() == reflect.Slice {
|
||||
for i := range v.Elem().Field(t.idx).Len() {
|
||||
for i := 0; i < v.Elem().Field(t.idx).Len(); i++ {
|
||||
if lblName == v.Elem().Field(t.idx).Index(i).Elem().Field(lblIndex).String() {
|
||||
exists = true
|
||||
oldValue = value{Value: v.Elem().Field(t.idx).Index(i), idx: i}
|
||||
@@ -899,7 +898,7 @@ func wrapErrorDiagnostic(message string, err error, subject *hcl.Range, context
|
||||
|
||||
func setName(v reflect.Value, name string) {
|
||||
numFields := v.Elem().Type().NumField()
|
||||
for i := range numFields {
|
||||
for i := 0; i < numFields; i++ {
|
||||
parts := strings.Split(v.Elem().Type().Field(i).Tag.Get("hcl"), ",")
|
||||
for _, t := range parts[1:] {
|
||||
if t == "label" {
|
||||
@@ -911,10 +910,12 @@ func setName(v reflect.Value, name string) {
|
||||
|
||||
func getName(v reflect.Value) (string, bool) {
|
||||
numFields := v.Elem().Type().NumField()
|
||||
for i := range numFields {
|
||||
for i := 0; i < numFields; i++ {
|
||||
parts := strings.Split(v.Elem().Type().Field(i).Tag.Get("hcl"), ",")
|
||||
if slices.Contains(parts[1:], "label") {
|
||||
return v.Elem().Field(i).String(), true
|
||||
for _, t := range parts[1:] {
|
||||
if t == "label" {
|
||||
return v.Elem().Field(i).String(), true
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
@@ -922,10 +923,12 @@ func getName(v reflect.Value) (string, bool) {
|
||||
|
||||
func getNameIndex(v reflect.Value) (int, bool) {
|
||||
numFields := v.Elem().Type().NumField()
|
||||
for i := range numFields {
|
||||
for i := 0; i < numFields; i++ {
|
||||
parts := strings.Split(v.Elem().Type().Field(i).Tag.Get("hcl"), ",")
|
||||
if slices.Contains(parts[1:], "label") {
|
||||
return i, true
|
||||
for _, t := range parts[1:] {
|
||||
if t == "label" {
|
||||
return i, true
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0, false
|
||||
@@ -985,7 +988,7 @@ func key(ks ...any) uint64 {
|
||||
return hash.Sum64()
|
||||
}
|
||||
|
||||
func decodeBody(body hcl.Body, ctx *hcl.EvalContext, val any) hcl.Diagnostics {
|
||||
func decodeBody(body hcl.Body, ctx *hcl.EvalContext, val interface{}) hcl.Diagnostics {
|
||||
dec := gohcl.DecodeOptions{ImpliedType: ImpliedType}
|
||||
return dec.DecodeBody(body, ctx, val)
|
||||
}
|
||||
|
@@ -43,7 +43,7 @@ import (
|
||||
// In particular, ImpliedType will never use capsule types in its returned
|
||||
// type, because it cannot know the capsule types supported by the calling
|
||||
// program.
|
||||
func ImpliedType(gv any) (cty.Type, error) {
|
||||
func ImpliedType(gv interface{}) (cty.Type, error) {
|
||||
rt := reflect.TypeOf(gv)
|
||||
var path cty.Path
|
||||
return impliedType(rt, path)
|
||||
@@ -148,7 +148,7 @@ func structTagIndices(st reflect.Type) map[string]int {
|
||||
ct := st.NumField()
|
||||
ret := make(map[string]int, ct)
|
||||
|
||||
for i := range ct {
|
||||
for i := 0; i < ct; i++ {
|
||||
field := st.Field(i)
|
||||
attrName := field.Tag.Get("cty")
|
||||
if attrName != "" {
|
||||
|
@@ -539,7 +539,7 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opts map[
|
||||
node := dp.Node().Driver
|
||||
if node.IsMobyDriver() {
|
||||
for _, e := range so.Exports {
|
||||
if e.Type == "moby" && e.Attrs["push"] != "" && !node.Features(ctx)[driver.DirectPush] {
|
||||
if e.Type == "moby" && e.Attrs["push"] != "" {
|
||||
if ok, _ := strconv.ParseBool(e.Attrs["push"]); ok {
|
||||
pushNames = e.Attrs["name"]
|
||||
if pushNames == "" {
|
||||
@@ -622,7 +622,7 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opts map[
|
||||
// This is fallback for some very old buildkit versions.
|
||||
// Note that the mediatype isn't really correct as most of the time it is image manifest and
|
||||
// not manifest list but actually both are handled because for Docker mediatypes the
|
||||
// mediatype value in the Accept header does not seem to matter.
|
||||
// mediatype value in the Accpet header does not seem to matter.
|
||||
s, ok = r.ExporterResponse[exptypes.ExporterImageDigestKey]
|
||||
if ok {
|
||||
descs = append(descs, specs.Descriptor{
|
||||
|
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
stderrors "errors"
|
||||
"net"
|
||||
"slices"
|
||||
|
||||
"github.com/containerd/platforms"
|
||||
"github.com/docker/buildx/builder"
|
||||
@@ -38,7 +37,15 @@ func Dial(ctx context.Context, nodes []builder.Node, pw progress.Writer, platfor
|
||||
for _, ls := range resolved {
|
||||
for _, rn := range ls {
|
||||
if platform != nil {
|
||||
if !slices.ContainsFunc(rn.platforms, platforms.Only(*platform).Match) {
|
||||
p := *platform
|
||||
var found bool
|
||||
for _, pp := range rn.platforms {
|
||||
if platforms.Only(p).Match(pp) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
@@ -3,7 +3,6 @@ package build
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"slices"
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/platforms"
|
||||
@@ -222,7 +221,7 @@ func (r *nodeResolver) get(p specs.Platform, matcher matchMaker, additionalPlatf
|
||||
for i, node := range r.nodes {
|
||||
platforms := node.Platforms
|
||||
if additionalPlatforms != nil {
|
||||
platforms = slices.Clone(platforms)
|
||||
platforms = append([]specs.Platform{}, platforms...)
|
||||
platforms = append(platforms, additionalPlatforms(i, node)...)
|
||||
}
|
||||
for _, p2 := range platforms {
|
||||
|
@@ -28,11 +28,11 @@ func TestSyncMultiReaderParallel(t *testing.T) {
|
||||
|
||||
readers := make([]io.ReadCloser, numReaders)
|
||||
|
||||
for i := range numReaders {
|
||||
for i := 0; i < numReaders; i++ {
|
||||
readers[i] = mr.NewReadCloser()
|
||||
}
|
||||
|
||||
for i := range numReaders {
|
||||
for i := 0; i < numReaders; i++ {
|
||||
wg.Add(1)
|
||||
go func(readerId int) {
|
||||
defer wg.Done()
|
||||
|
@@ -5,7 +5,6 @@ import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"os"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -200,7 +199,7 @@ func (b *Builder) Boot(ctx context.Context) (bool, error) {
|
||||
err = err1
|
||||
}
|
||||
|
||||
if err == nil && len(errCh) > 0 {
|
||||
if err == nil && len(errCh) == len(toBoot) {
|
||||
return false, <-errCh
|
||||
}
|
||||
return true, err
|
||||
@@ -657,7 +656,13 @@ func parseBuildkitdFlags(inp string, driver string, driverOpts map[string]string
|
||||
flags.StringArrayVar(&allowInsecureEntitlements, "allow-insecure-entitlement", nil, "")
|
||||
_ = flags.Parse(res)
|
||||
|
||||
hasNetworkHostEntitlement := slices.Contains(allowInsecureEntitlements, "network.host")
|
||||
var hasNetworkHostEntitlement bool
|
||||
for _, e := range allowInsecureEntitlements {
|
||||
if e == "network.host" {
|
||||
hasNetworkHostEntitlement = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var hasNetworkHostEntitlementInConf bool
|
||||
if buildkitdConfigFile != "" {
|
||||
@@ -666,8 +671,11 @@ func parseBuildkitdFlags(inp string, driver string, driverOpts map[string]string
|
||||
return nil, err
|
||||
} else if btoml != nil {
|
||||
if ies := btoml.GetArray("insecure-entitlements"); ies != nil {
|
||||
if slices.Contains(ies.([]string), "network.host") {
|
||||
hasNetworkHostEntitlementInConf = true
|
||||
for _, e := range ies.([]string) {
|
||||
if e == "network.host" {
|
||||
hasNetworkHostEntitlementInConf = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -169,7 +169,7 @@ func (b *Builder) LoadNodes(ctx context.Context, opts ...LoadNodesOption) (_ []N
|
||||
// dynamic nodes are used in Kubernetes driver.
|
||||
// Kubernetes' pods are dynamically mapped to BuildKit Nodes.
|
||||
if di.DriverInfo != nil && len(di.DriverInfo.DynamicNodes) > 0 {
|
||||
for i := range di.DriverInfo.DynamicNodes {
|
||||
for i := 0; i < len(di.DriverInfo.DynamicNodes); i++ {
|
||||
diClone := di
|
||||
if pl := di.DriverInfo.DynamicNodes[i].Platforms; len(pl) > 0 {
|
||||
diClone.Platforms = pl
|
||||
|
@@ -66,11 +66,7 @@ type bakeOptions struct {
|
||||
func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in bakeOptions, cFlags commonFlags) (err error) {
|
||||
mp := dockerCli.MeterProvider()
|
||||
|
||||
ctx, end, err := tracing.TraceCurrentCommand(ctx, append([]string{"bake"}, targets...),
|
||||
attribute.String("builder", in.builder),
|
||||
attribute.StringSlice("targets", targets),
|
||||
attribute.StringSlice("files", in.files),
|
||||
)
|
||||
ctx, end, err := tracing.TraceCurrentCommand(ctx, "bake")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -287,7 +283,7 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
|
||||
}
|
||||
}
|
||||
|
||||
if err := saveLocalStateGroup(dockerCli, in, targets, bo); err != nil {
|
||||
if err := saveLocalStateGroup(dockerCli, in, targets, bo, overrides, def); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -309,7 +305,7 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
|
||||
desktop.PrintBuildDetails(os.Stderr, printer.BuildRefs(), term)
|
||||
}
|
||||
if len(in.metadataFile) > 0 {
|
||||
dt := make(map[string]any)
|
||||
dt := make(map[string]interface{})
|
||||
for t, r := range resp {
|
||||
dt[t] = decodeExporterResponse(r.ExporterResponse)
|
||||
}
|
||||
@@ -492,14 +488,7 @@ func bakeCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func saveLocalStateGroup(dockerCli command.Cli, in bakeOptions, targets []string, bo map[string]build.Options) error {
|
||||
l, err := localstate.New(confutil.NewConfig(dockerCli))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer l.MigrateIfNeeded()
|
||||
|
||||
func saveLocalStateGroup(dockerCli command.Cli, in bakeOptions, targets []string, bo map[string]build.Options, overrides []string, def any) error {
|
||||
prm := confutil.MetadataProvenance()
|
||||
if len(in.metadataFile) == 0 {
|
||||
prm = confutil.MetadataProvenanceModeDisabled
|
||||
@@ -519,10 +508,19 @@ func saveLocalStateGroup(dockerCli command.Cli, in bakeOptions, targets []string
|
||||
if len(refs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
l, err := localstate.New(confutil.NewConfig(dockerCli))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dtdef, err := json.MarshalIndent(def, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return l.SaveGroup(groupRef, localstate.StateGroup{
|
||||
Refs: refs,
|
||||
Targets: targets,
|
||||
Definition: dtdef,
|
||||
Targets: targets,
|
||||
Inputs: overrides,
|
||||
Refs: refs,
|
||||
})
|
||||
}
|
||||
|
||||
|
@@ -11,7 +11,6 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -157,7 +156,7 @@ func (o *buildOptions) toControllerOptions() (*controllerapi.BuildOptions, error
|
||||
return nil, err
|
||||
}
|
||||
|
||||
inAttests := slices.Clone(o.attests)
|
||||
inAttests := append([]string{}, o.attests...)
|
||||
if o.provenance != "" {
|
||||
inAttests = append(inAttests, buildflags.CanonicalizeAttest("provenance", o.provenance))
|
||||
}
|
||||
@@ -286,11 +285,7 @@ func (o *buildOptionsHash) String() string {
|
||||
func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions) (err error) {
|
||||
mp := dockerCli.MeterProvider()
|
||||
|
||||
ctx, end, err := tracing.TraceCurrentCommand(ctx, []string{"build", options.contextPath},
|
||||
attribute.String("builder", options.builder),
|
||||
attribute.String("context", options.contextPath),
|
||||
attribute.String("dockerfile", options.dockerfileName),
|
||||
)
|
||||
ctx, end, err := tracing.TraceCurrentCommand(ctx, "build")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -745,7 +740,7 @@ func checkWarnedFlags(f *pflag.Flag) {
|
||||
}
|
||||
}
|
||||
|
||||
func writeMetadataFile(filename string, dt any) error {
|
||||
func writeMetadataFile(filename string, dt interface{}) error {
|
||||
b, err := json.MarshalIndent(dt, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -753,7 +748,7 @@ func writeMetadataFile(filename string, dt any) error {
|
||||
return atomicwriter.WriteFile(filename, b, 0644)
|
||||
}
|
||||
|
||||
func decodeExporterResponse(exporterResponse map[string]string) map[string]any {
|
||||
func decodeExporterResponse(exporterResponse map[string]string) map[string]interface{} {
|
||||
decFunc := func(k, v string) ([]byte, error) {
|
||||
if k == "result.json" {
|
||||
// result.json is part of metadata response for subrequests which
|
||||
@@ -762,16 +757,16 @@ func decodeExporterResponse(exporterResponse map[string]string) map[string]any {
|
||||
}
|
||||
return base64.StdEncoding.DecodeString(v)
|
||||
}
|
||||
out := make(map[string]any)
|
||||
out := make(map[string]interface{})
|
||||
for k, v := range exporterResponse {
|
||||
dt, err := decFunc(k, v)
|
||||
if err != nil {
|
||||
out[k] = v
|
||||
continue
|
||||
}
|
||||
var raw map[string]any
|
||||
var raw map[string]interface{}
|
||||
if err = json.Unmarshal(dt, &raw); err != nil || len(raw) == 0 {
|
||||
var rawList []map[string]any
|
||||
var rawList []map[string]interface{}
|
||||
if err = json.Unmarshal(dt, &rawList); err != nil || len(rawList) == 0 {
|
||||
out[k] = v
|
||||
continue
|
||||
|
@@ -124,7 +124,7 @@ func duCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func printKV(w io.Writer, k string, v any) {
|
||||
func printKV(w io.Writer, k string, v interface{}) {
|
||||
fmt.Fprintf(w, "%s:\t%v\n", k, v)
|
||||
}
|
||||
|
||||
|
@@ -1,135 +0,0 @@
|
||||
package history
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
remoteutil "github.com/docker/buildx/driver/remote/util"
|
||||
"github.com/docker/buildx/util/cobrautil/completion"
|
||||
"github.com/docker/buildx/util/desktop"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/pkg/browser"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type importOptions struct {
|
||||
file []string
|
||||
}
|
||||
|
||||
func runImport(ctx context.Context, dockerCli command.Cli, opts importOptions) error {
|
||||
sock, err := desktop.BuildServerAddr()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tr := http.DefaultTransport.(*http.Transport).Clone()
|
||||
tr.DialContext = func(ctx context.Context, _, _ string) (net.Conn, error) {
|
||||
network, addr, ok := strings.Cut(sock, "://")
|
||||
if !ok {
|
||||
return nil, errors.Errorf("invalid endpoint address: %s", sock)
|
||||
}
|
||||
return remoteutil.DialContext(ctx, network, addr)
|
||||
}
|
||||
|
||||
client := &http.Client{
|
||||
Transport: tr,
|
||||
}
|
||||
|
||||
var urls []string
|
||||
|
||||
if len(opts.file) == 0 {
|
||||
u, err := importFrom(ctx, client, os.Stdin)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
urls = append(urls, u...)
|
||||
} else {
|
||||
for _, fn := range opts.file {
|
||||
var f *os.File
|
||||
var rdr io.Reader = os.Stdin
|
||||
if fn != "-" {
|
||||
f, err = os.Open(fn)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to open file %s", fn)
|
||||
}
|
||||
rdr = f
|
||||
}
|
||||
u, err := importFrom(ctx, client, rdr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
urls = append(urls, u...)
|
||||
if f != nil {
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(urls) == 0 {
|
||||
return errors.New("no build records found in the bundle")
|
||||
}
|
||||
|
||||
for i, url := range urls {
|
||||
fmt.Fprintln(dockerCli.Err(), url)
|
||||
if i == 0 {
|
||||
err = browser.OpenURL(url)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func importFrom(ctx context.Context, c *http.Client, rdr io.Reader) ([]string, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "http://docker-desktop/upload", rdr)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to create request")
|
||||
}
|
||||
|
||||
resp, err := c.Do(req)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to send request, check if Docker Desktop is running")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
return nil, errors.Errorf("failed to import build: %s", string(body))
|
||||
}
|
||||
|
||||
var refs []string
|
||||
dec := json.NewDecoder(resp.Body)
|
||||
if err := dec.Decode(&refs); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to decode response")
|
||||
}
|
||||
|
||||
var urls []string
|
||||
for _, ref := range refs {
|
||||
urls = append(urls, desktop.BuildURL(fmt.Sprintf(".imported/_/%s", ref)))
|
||||
}
|
||||
return urls, err
|
||||
}
|
||||
|
||||
func importCmd(dockerCli command.Cli, _ RootOptions) *cobra.Command {
|
||||
var options importOptions
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "import [OPTIONS] < bundle.dockerbuild",
|
||||
Short: "Import a build into Docker Desktop",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runImport(cmd.Context(), dockerCli, options)
|
||||
},
|
||||
ValidArgsFunction: completion.Disable,
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
flags.StringArrayVarP(&options.file, "file", "f", nil, "Import from a file path")
|
||||
|
||||
return cmd
|
||||
}
|
@@ -173,7 +173,7 @@ func runInspect(ctx context.Context, dockerCli command.Cli, opts inspectOptions)
|
||||
}
|
||||
}
|
||||
|
||||
recs, err := queryRecords(ctx, opts.ref, nodes, nil)
|
||||
recs, err := queryRecords(ctx, opts.ref, nodes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -185,7 +185,14 @@ func runInspect(ctx context.Context, dockerCli command.Cli, opts inspectOptions)
|
||||
return errors.Errorf("no record found for ref %q", opts.ref)
|
||||
}
|
||||
|
||||
if opts.ref == "" {
|
||||
slices.SortFunc(recs, func(a, b historyRecord) int {
|
||||
return b.CreatedAt.AsTime().Compare(a.CreatedAt.AsTime())
|
||||
})
|
||||
}
|
||||
|
||||
rec := &recs[0]
|
||||
|
||||
c, err := rec.node.Driver.Client(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -346,7 +353,7 @@ workers0:
|
||||
out.Error.Name = name
|
||||
out.Error.Logs = logs
|
||||
}
|
||||
out.Error.Stack = fmt.Appendf(nil, "%+v", stack.Formatter(retErr))
|
||||
out.Error.Stack = []byte(fmt.Sprintf("%+v", stack.Formatter(retErr)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -3,6 +3,7 @@ package history
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"slices"
|
||||
|
||||
"github.com/containerd/containerd/v2/core/content/proxy"
|
||||
"github.com/containerd/platforms"
|
||||
@@ -41,7 +42,7 @@ func runAttachment(ctx context.Context, dockerCli command.Cli, opts attachmentOp
|
||||
}
|
||||
}
|
||||
|
||||
recs, err := queryRecords(ctx, opts.ref, nodes, nil)
|
||||
recs, err := queryRecords(ctx, opts.ref, nodes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -53,6 +54,12 @@ func runAttachment(ctx context.Context, dockerCli command.Cli, opts attachmentOp
|
||||
return errors.Errorf("no record found for ref %q", opts.ref)
|
||||
}
|
||||
|
||||
if opts.ref == "" {
|
||||
slices.SortFunc(recs, func(a, b historyRecord) int {
|
||||
return b.CreatedAt.AsTime().Compare(a.CreatedAt.AsTime())
|
||||
})
|
||||
}
|
||||
|
||||
rec := &recs[0]
|
||||
|
||||
c, err := rec.node.Driver.Client(ctx)
|
||||
|
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"slices"
|
||||
|
||||
"github.com/docker/buildx/builder"
|
||||
"github.com/docker/buildx/util/cobrautil/completion"
|
||||
@@ -38,7 +39,7 @@ func runLogs(ctx context.Context, dockerCli command.Cli, opts logsOptions) error
|
||||
}
|
||||
}
|
||||
|
||||
recs, err := queryRecords(ctx, opts.ref, nodes, nil)
|
||||
recs, err := queryRecords(ctx, opts.ref, nodes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -50,6 +51,12 @@ func runLogs(ctx context.Context, dockerCli command.Cli, opts logsOptions) error
|
||||
return errors.Errorf("no record found for ref %q", opts.ref)
|
||||
}
|
||||
|
||||
if opts.ref == "" {
|
||||
slices.SortFunc(recs, func(a, b historyRecord) int {
|
||||
return b.CreatedAt.AsTime().Compare(a.CreatedAt.AsTime())
|
||||
})
|
||||
}
|
||||
|
||||
rec := &recs[0]
|
||||
c, err := rec.node.Driver.Client(ctx)
|
||||
if err != nil {
|
||||
|
@@ -56,7 +56,7 @@ func runLs(ctx context.Context, dockerCli command.Cli, opts lsOptions) error {
|
||||
}
|
||||
}
|
||||
|
||||
out, err := queryRecords(ctx, "", nodes, nil)
|
||||
out, err := queryRecords(ctx, "", nodes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -161,7 +161,7 @@ type lsContext struct {
|
||||
}
|
||||
|
||||
func (c *lsContext) MarshalJSON() ([]byte, error) {
|
||||
m := map[string]any{
|
||||
m := map[string]interface{}{
|
||||
"ref": c.FullRef(),
|
||||
"name": c.Name(),
|
||||
"status": c.Status(),
|
||||
|
@@ -3,6 +3,7 @@ package history
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"slices"
|
||||
|
||||
"github.com/docker/buildx/builder"
|
||||
"github.com/docker/buildx/util/cobrautil/completion"
|
||||
@@ -34,7 +35,7 @@ func runOpen(ctx context.Context, dockerCli command.Cli, opts openOptions) error
|
||||
}
|
||||
}
|
||||
|
||||
recs, err := queryRecords(ctx, opts.ref, nodes, nil)
|
||||
recs, err := queryRecords(ctx, opts.ref, nodes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -46,6 +47,12 @@ func runOpen(ctx context.Context, dockerCli command.Cli, opts openOptions) error
|
||||
return errors.Errorf("no record found for ref %q", opts.ref)
|
||||
}
|
||||
|
||||
if opts.ref == "" {
|
||||
slices.SortFunc(recs, func(a, b historyRecord) int {
|
||||
return b.CreatedAt.AsTime().Compare(a.CreatedAt.AsTime())
|
||||
})
|
||||
}
|
||||
|
||||
rec := &recs[0]
|
||||
|
||||
url := desktop.BuildURL(fmt.Sprintf("%s/%s/%s", rec.node.Builder, rec.node.Name, rec.Ref))
|
||||
|
@@ -25,7 +25,6 @@ func RootCmd(rootcmd *cobra.Command, dockerCli command.Cli, opts RootOptions) *c
|
||||
inspectCmd(dockerCli, opts),
|
||||
openCmd(dockerCli, opts),
|
||||
traceCmd(dockerCli, opts),
|
||||
importCmd(dockerCli, opts),
|
||||
)
|
||||
|
||||
return cmd
|
||||
|
@@ -8,6 +8,9 @@ import (
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/console"
|
||||
@@ -34,20 +37,51 @@ type traceOptions struct {
|
||||
}
|
||||
|
||||
func loadTrace(ctx context.Context, ref string, nodes []builder.Node) (string, []byte, error) {
|
||||
recs, err := queryRecords(ctx, ref, nodes, &queryOptions{
|
||||
CompletedOnly: true,
|
||||
})
|
||||
var offset *int
|
||||
if strings.HasPrefix(ref, "^") {
|
||||
off, err := strconv.Atoi(ref[1:])
|
||||
if err != nil {
|
||||
return "", nil, errors.Wrapf(err, "invalid offset %q", ref)
|
||||
}
|
||||
offset = &off
|
||||
ref = ""
|
||||
}
|
||||
|
||||
recs, err := queryRecords(ctx, ref, nodes)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
if len(recs) == 0 {
|
||||
var rec *historyRecord
|
||||
|
||||
if ref == "" {
|
||||
slices.SortFunc(recs, func(a, b historyRecord) int {
|
||||
return b.CreatedAt.AsTime().Compare(a.CreatedAt.AsTime())
|
||||
})
|
||||
for _, r := range recs {
|
||||
if r.CompletedAt != nil {
|
||||
if offset != nil {
|
||||
if *offset > 0 {
|
||||
*offset--
|
||||
continue
|
||||
}
|
||||
}
|
||||
rec = &r
|
||||
break
|
||||
}
|
||||
}
|
||||
if offset != nil && *offset > 0 {
|
||||
return "", nil, errors.Errorf("no completed build found with offset %d", *offset)
|
||||
}
|
||||
} else {
|
||||
rec = &recs[0]
|
||||
}
|
||||
if rec == nil {
|
||||
if ref == "" {
|
||||
return "", nil, errors.New("no records found")
|
||||
}
|
||||
return "", nil, errors.Errorf("no record found for ref %q", ref)
|
||||
}
|
||||
rec := &recs[0]
|
||||
|
||||
if rec.CompletedAt == nil {
|
||||
return "", nil, errors.Errorf("build %q is not completed, only completed builds can be traced", rec.Ref)
|
||||
@@ -69,9 +103,7 @@ func loadTrace(ctx context.Context, ref string, nodes []builder.Node) (string, [
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
recs, err := queryRecords(ctx, rec.Ref, []builder.Node{*rec.node}, &queryOptions{
|
||||
CompletedOnly: true,
|
||||
})
|
||||
recs, err := queryRecords(ctx, rec.Ref, []builder.Node{*rec.node})
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
@@ -5,8 +5,6 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -108,24 +106,10 @@ type historyRecord struct {
|
||||
name string
|
||||
}
|
||||
|
||||
type queryOptions struct {
|
||||
CompletedOnly bool
|
||||
}
|
||||
|
||||
func queryRecords(ctx context.Context, ref string, nodes []builder.Node, opts *queryOptions) ([]historyRecord, error) {
|
||||
func queryRecords(ctx context.Context, ref string, nodes []builder.Node) ([]historyRecord, error) {
|
||||
var mu sync.Mutex
|
||||
var out []historyRecord
|
||||
|
||||
var offset *int
|
||||
if strings.HasPrefix(ref, "^") {
|
||||
off, err := strconv.Atoi(ref[1:])
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "invalid offset %q", ref)
|
||||
}
|
||||
offset = &off
|
||||
ref = ""
|
||||
}
|
||||
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
for _, node := range nodes {
|
||||
node := node
|
||||
@@ -169,10 +153,6 @@ func queryRecords(ctx context.Context, ref string, nodes []builder.Node, opts *q
|
||||
if he.Type == controlapi.BuildHistoryEventType_DELETED || he.Record == nil {
|
||||
continue
|
||||
}
|
||||
if opts != nil && opts.CompletedOnly && he.Type != controlapi.BuildHistoryEventType_COMPLETE {
|
||||
continue
|
||||
}
|
||||
|
||||
records = append(records, historyRecord{
|
||||
BuildHistoryRecord: he.Record,
|
||||
currentTimestamp: ts,
|
||||
@@ -189,27 +169,6 @@ func queryRecords(ctx context.Context, ref string, nodes []builder.Node, opts *q
|
||||
if err := eg.Wait(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
slices.SortFunc(out, func(a, b historyRecord) int {
|
||||
return b.CreatedAt.AsTime().Compare(a.CreatedAt.AsTime())
|
||||
})
|
||||
|
||||
if offset != nil {
|
||||
var filtered []historyRecord
|
||||
for _, r := range out {
|
||||
if *offset > 0 {
|
||||
*offset--
|
||||
continue
|
||||
}
|
||||
filtered = append(filtered, r)
|
||||
break
|
||||
}
|
||||
if *offset > 0 {
|
||||
return nil, errors.Errorf("no completed build found with offset %d", *offset)
|
||||
}
|
||||
out = filtered
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
|
@@ -194,7 +194,7 @@ func runCreate(ctx context.Context, dockerCli command.Cli, in createOptions, arg
|
||||
}
|
||||
s := s
|
||||
eg2.Go(func() error {
|
||||
sub.Log(1, fmt.Appendf(nil, "copying %s from %s to %s\n", s.Desc.Digest.String(), s.Ref.String(), t.String()))
|
||||
sub.Log(1, []byte(fmt.Sprintf("copying %s from %s to %s\n", s.Desc.Digest.String(), s.Ref.String(), t.String())))
|
||||
return r.Copy(ctx, s, t)
|
||||
})
|
||||
}
|
||||
@@ -202,7 +202,7 @@ func runCreate(ctx context.Context, dockerCli command.Cli, in createOptions, arg
|
||||
if err := eg2.Wait(); err != nil {
|
||||
return err
|
||||
}
|
||||
sub.Log(1, fmt.Appendf(nil, "pushing %s to %s\n", desc.Digest.String(), t.String()))
|
||||
sub.Log(1, []byte(fmt.Sprintf("pushing %s to %s\n", desc.Digest.String(), t.String())))
|
||||
return r.Push(ctx, t, desc, dt)
|
||||
})
|
||||
})
|
||||
|
@@ -13,8 +13,8 @@ import (
|
||||
type BuildxController interface {
|
||||
Build(ctx context.Context, options *controllerapi.BuildOptions, in io.ReadCloser, progress progress.Writer) (ref string, resp *client.SolveResponse, inputs *build.Inputs, err error)
|
||||
// Invoke starts an IO session into the specified process.
|
||||
// If pid doesn't match to any running processes, it starts a new process with the specified config.
|
||||
// If there is no container running or InvokeConfig.Rollback is specified, the process will start in a newly created container.
|
||||
// If pid doesn't matche to any running processes, it starts a new process with the specified config.
|
||||
// If there is no container running or InvokeConfig.Rollback is speicfied, the process will start in a newly created container.
|
||||
// NOTE: If needed, in the future, we can split this API into three APIs (NewContainer, NewProcess and Attach).
|
||||
Invoke(ctx context.Context, ref, pid string, options *controllerapi.InvokeConfig, ioIn io.ReadCloser, ioOut io.WriteCloser, ioErr io.WriteCloser) error
|
||||
Kill(ctx context.Context) error
|
||||
|
@@ -24,11 +24,11 @@ func (w *writer) Write(status *client.SolveStatus) {
|
||||
|
||||
func (w *writer) WriteBuildRef(target string, ref string) {}
|
||||
|
||||
func (w *writer) ValidateLogSource(digest.Digest, any) bool {
|
||||
func (w *writer) ValidateLogSource(digest.Digest, interface{}) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (w *writer) ClearLogSource(any) {}
|
||||
func (w *writer) ClearLogSource(interface{}) {}
|
||||
|
||||
func ToControlStatus(s *client.SolveStatus) *StatusResponse {
|
||||
resp := StatusResponse{}
|
||||
|
@@ -1,8 +1,6 @@
|
||||
package pb
|
||||
|
||||
import (
|
||||
"slices"
|
||||
|
||||
"github.com/moby/buildkit/session"
|
||||
"github.com/moby/buildkit/session/sshforward/sshprovider"
|
||||
)
|
||||
@@ -12,7 +10,7 @@ func CreateSSH(ssh []*SSH) (session.Attachable, error) {
|
||||
for _, ssh := range ssh {
|
||||
cfg := sshprovider.AgentConfig{
|
||||
ID: ssh.ID,
|
||||
Paths: slices.Clone(ssh.Paths),
|
||||
Paths: append([]string{}, ssh.Paths...),
|
||||
}
|
||||
configs = append(configs, cfg)
|
||||
}
|
||||
|
@@ -39,7 +39,7 @@ func (p *Process) Done() <-chan error {
|
||||
return p.errCh
|
||||
}
|
||||
|
||||
// Manager manages a set of processes.
|
||||
// Manager manages a set of proceses.
|
||||
type Manager struct {
|
||||
container atomic.Value
|
||||
processes sync.Map
|
||||
|
@@ -140,7 +140,7 @@ func serveCmd(dockerCli command.Cli) *cobra.Command {
|
||||
return err
|
||||
}
|
||||
pidF := filepath.Join(root, defaultPIDFilename)
|
||||
if err := os.WriteFile(pidF, fmt.Appendf(nil, "%d", os.Getpid()), 0600); err != nil {
|
||||
if err := os.WriteFile(pidF, []byte(fmt.Sprintf("%d", os.Getpid())), 0600); err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
|
@@ -48,8 +48,6 @@ target "lint" {
|
||||
"linux/s390x",
|
||||
"linux/ppc64le",
|
||||
"linux/riscv64",
|
||||
"netbsd/amd64",
|
||||
"netbsd/arm64",
|
||||
"openbsd/amd64",
|
||||
"openbsd/arm64",
|
||||
"windows/amd64",
|
||||
@@ -169,8 +167,6 @@ target "binaries-cross" {
|
||||
"linux/ppc64le",
|
||||
"linux/riscv64",
|
||||
"linux/s390x",
|
||||
"netbsd/amd64",
|
||||
"netbsd/arm64",
|
||||
"openbsd/amd64",
|
||||
"openbsd/arm64",
|
||||
"windows/amd64",
|
||||
|
@@ -347,22 +347,18 @@ is defined in https://golang.org/pkg/path/#Match.
|
||||
```console
|
||||
$ docker buildx bake --set target.args.mybuildarg=value
|
||||
$ docker buildx bake --set target.platform=linux/arm64
|
||||
$ docker buildx bake --set foo*.args.mybuildarg=value # overrides build arg for all targets starting with 'foo'
|
||||
$ docker buildx bake --set *.platform=linux/arm64 # overrides platform for all targets
|
||||
$ docker buildx bake --set foo*.no-cache # bypass caching only for targets starting with 'foo'
|
||||
$ docker buildx bake --set target.platform+=linux/arm64 # appends 'linux/arm64' to the platform list
|
||||
$ docker buildx bake --set foo*.args.mybuildarg=value # overrides build arg for all targets starting with 'foo'
|
||||
$ docker buildx bake --set *.platform=linux/arm64 # overrides platform for all targets
|
||||
$ docker buildx bake --set foo*.no-cache # bypass caching only for targets starting with 'foo'
|
||||
```
|
||||
|
||||
You can override the following fields:
|
||||
|
||||
* `annotations`
|
||||
* `attest`
|
||||
* `args`
|
||||
* `cache-from`
|
||||
* `cache-to`
|
||||
* `context`
|
||||
* `dockerfile`
|
||||
* `entitlements`
|
||||
* `labels`
|
||||
* `load`
|
||||
* `no-cache`
|
||||
@@ -375,20 +371,3 @@ You can override the following fields:
|
||||
* `ssh`
|
||||
* `tags`
|
||||
* `target`
|
||||
|
||||
You can append using `+=` operator for the following fields:
|
||||
|
||||
* `annotations`¹
|
||||
* `attest`¹
|
||||
* `cache-from`
|
||||
* `cache-to`
|
||||
* `entitlements`¹
|
||||
* `no-cache-filter`
|
||||
* `output`
|
||||
* `platform`
|
||||
* `secrets`
|
||||
* `ssh`
|
||||
* `tags`
|
||||
|
||||
> [!NOTE]
|
||||
> ¹ These fields already append by default.
|
||||
|
@@ -7,7 +7,6 @@ Commands to work on build records
|
||||
|
||||
| Name | Description |
|
||||
|:---------------------------------------|:-----------------------------------------------|
|
||||
| [`import`](buildx_history_import.md) | Import a build into Docker Desktop |
|
||||
| [`inspect`](buildx_history_inspect.md) | Inspect a build |
|
||||
| [`logs`](buildx_history_logs.md) | Print the logs of a build |
|
||||
| [`ls`](buildx_history_ls.md) | List build records |
|
||||
|
@@ -1,16 +0,0 @@
|
||||
# docker buildx history import
|
||||
|
||||
<!---MARKER_GEN_START-->
|
||||
Import a build into Docker Desktop
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:----------------|:--------------|:--------|:-----------------------------------------|
|
||||
| `--builder` | `string` | | Override the configured builder instance |
|
||||
| `-D`, `--debug` | `bool` | | Enable debug logging |
|
||||
| `-f`, `--file` | `stringArray` | | Import from a file path |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
@@ -56,7 +56,6 @@ type Driver struct {
|
||||
restartPolicy container.RestartPolicy
|
||||
env []string
|
||||
defaultLoad bool
|
||||
gpus []container.DeviceRequest
|
||||
}
|
||||
|
||||
func (d *Driver) IsMobyDriver() bool {
|
||||
@@ -159,9 +158,6 @@ func (d *Driver) create(ctx context.Context, l progress.SubLogger) error {
|
||||
if d.cpusetMems != "" {
|
||||
hc.Resources.CpusetMems = d.cpusetMems
|
||||
}
|
||||
if len(d.gpus) > 0 && d.hasGPUCapability(ctx, cfg.Image, d.gpus) {
|
||||
hc.Resources.DeviceRequests = d.gpus
|
||||
}
|
||||
if info, err := d.DockerAPI.Info(ctx); err == nil {
|
||||
if info.CgroupDriver == "cgroupfs" {
|
||||
// Place all buildkit containers inside this cgroup by default so limits can be attached
|
||||
@@ -424,7 +420,6 @@ func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool {
|
||||
driver.DockerExporter: true,
|
||||
driver.CacheExport: true,
|
||||
driver.MultiPlatform: true,
|
||||
driver.DirectPush: true,
|
||||
driver.DefaultLoad: d.defaultLoad,
|
||||
}
|
||||
}
|
||||
@@ -433,31 +428,6 @@ func (d *Driver) HostGatewayIP(ctx context.Context) (net.IP, error) {
|
||||
return nil, errors.New("host-gateway is not supported by the docker-container driver")
|
||||
}
|
||||
|
||||
// hasGPUCapability checks if docker daemon has GPU capability. We need to run
|
||||
// a dummy container with GPU device to check if the daemon has this capability
|
||||
// because there is no API to check it yet.
|
||||
func (d *Driver) hasGPUCapability(ctx context.Context, image string, gpus []container.DeviceRequest) bool {
|
||||
cfg := &container.Config{
|
||||
Image: image,
|
||||
Entrypoint: []string{"/bin/true"},
|
||||
}
|
||||
hc := &container.HostConfig{
|
||||
NetworkMode: container.NetworkMode(container.IPCModeNone),
|
||||
AutoRemove: true,
|
||||
Resources: container.Resources{
|
||||
DeviceRequests: gpus,
|
||||
},
|
||||
}
|
||||
resp, err := d.DockerAPI.ContainerCreate(ctx, cfg, hc, &network.NetworkingConfig{}, nil, "")
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if err := d.DockerAPI.ContainerStart(ctx, resp.ID, container.StartOptions{}); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func demuxConn(c net.Conn) net.Conn {
|
||||
pr, pw := io.Pipe()
|
||||
// TODO: rewrite parser with Reader() to avoid goroutine switch
|
||||
|
@@ -51,12 +51,6 @@ func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver
|
||||
InitConfig: cfg,
|
||||
restartPolicy: rp,
|
||||
}
|
||||
var gpus dockeropts.GpuOpts
|
||||
if err := gpus.Set("all"); err == nil {
|
||||
if v := gpus.Value(); len(v) > 0 {
|
||||
d.gpus = v
|
||||
}
|
||||
}
|
||||
for k, v := range cfg.DriverOpts {
|
||||
switch {
|
||||
case k == "network":
|
||||
|
@@ -93,7 +93,6 @@ func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool {
|
||||
driver.DockerExporter: useContainerdSnapshotter,
|
||||
driver.CacheExport: useContainerdSnapshotter,
|
||||
driver.MultiPlatform: useContainerdSnapshotter,
|
||||
driver.DirectPush: useContainerdSnapshotter,
|
||||
driver.DefaultLoad: true,
|
||||
}
|
||||
})
|
||||
|
@@ -7,6 +7,5 @@ const DockerExporter Feature = "Docker exporter"
|
||||
|
||||
const CacheExport Feature = "Cache export"
|
||||
const MultiPlatform Feature = "Multi-platform build"
|
||||
const DirectPush Feature = "Direct push"
|
||||
|
||||
const DefaultLoad Feature = "Automatically load images to the Docker Engine image store"
|
||||
|
@@ -35,10 +35,10 @@ func testEndpoint(server, defaultNamespace string, ca, cert, key []byte, skipTLS
|
||||
}
|
||||
|
||||
var testStoreCfg = store.NewConfig(
|
||||
func() any {
|
||||
return &map[string]any{}
|
||||
func() interface{} {
|
||||
return &map[string]interface{}{}
|
||||
},
|
||||
store.EndpointTypeGetter(KubernetesEndpoint, func() any { return &EndpointMeta{} }),
|
||||
store.EndpointTypeGetter(KubernetesEndpoint, func() interface{} { return &EndpointMeta{} }),
|
||||
)
|
||||
|
||||
func TestSaveLoadContexts(t *testing.T) {
|
||||
@@ -197,7 +197,7 @@ func checkClientConfig(t *testing.T, ep Endpoint, server, namespace string, ca,
|
||||
|
||||
func save(s store.Writer, ep Endpoint, name string) error {
|
||||
meta := store.Metadata{
|
||||
Endpoints: map[string]any{
|
||||
Endpoints: map[string]interface{}{
|
||||
KubernetesEndpoint: ep.EndpointMeta,
|
||||
},
|
||||
Name: name,
|
||||
|
@@ -43,7 +43,7 @@ type Endpoint struct {
|
||||
|
||||
func init() {
|
||||
command.RegisterDefaultStoreEndpoints(
|
||||
store.EndpointTypeGetter(KubernetesEndpoint, func() any { return &EndpointMeta{} }),
|
||||
store.EndpointTypeGetter(KubernetesEndpoint, func() interface{} { return &EndpointMeta{} }),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ func (c *Endpoint) KubernetesConfig() clientcmd.ClientConfig {
|
||||
|
||||
// ResolveDefault returns endpoint metadata for the default Kubernetes
|
||||
// endpoint, which is derived from the env-based kubeconfig.
|
||||
func (c *EndpointMeta) ResolveDefault() (any, *store.EndpointTLSData, error) {
|
||||
func (c *EndpointMeta) ResolveDefault() (interface{}, *store.EndpointTLSData, error) {
|
||||
kubeconfig := os.Getenv("KUBECONFIG")
|
||||
if kubeconfig == "" {
|
||||
kubeconfig = filepath.Join(homedir.Get(), ".kube/config")
|
||||
|
@@ -238,7 +238,6 @@ func (d *Driver) Features(_ context.Context) map[driver.Feature]bool {
|
||||
driver.DockerExporter: d.DockerAPI != nil,
|
||||
driver.CacheExport: true,
|
||||
driver.MultiPlatform: true, // Untested (needs multiple Driver instances)
|
||||
driver.DirectPush: true,
|
||||
driver.DefaultLoad: d.defaultLoad,
|
||||
}
|
||||
}
|
||||
|
@@ -90,7 +90,7 @@ func ListRunningPods(ctx context.Context, client clientcorev1.PodInterface, depl
|
||||
for i := range podList.Items {
|
||||
pod := &podList.Items[i]
|
||||
if pod.Status.Phase == corev1.PodRunning {
|
||||
logrus.Debugf("pod running: %q", pod.Name)
|
||||
logrus.Debugf("pod runnning: %q", pod.Name)
|
||||
runningPods = append(runningPods, pod)
|
||||
}
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ func GenerateNodeName(builderName string, txn *store.Txn) (string, error) {
|
||||
}
|
||||
|
||||
var name string
|
||||
for range 6 {
|
||||
for i := 0; i < 6; i++ {
|
||||
name, err = randomName()
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@@ -164,7 +164,6 @@ func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool {
|
||||
driver.DockerExporter: true,
|
||||
driver.CacheExport: true,
|
||||
driver.MultiPlatform: true,
|
||||
driver.DirectPush: true,
|
||||
driver.DefaultLoad: d.defaultLoad,
|
||||
}
|
||||
}
|
||||
|
10
go.mod
10
go.mod
@@ -6,9 +6,9 @@ require (
|
||||
github.com/Masterminds/semver/v3 v3.2.1
|
||||
github.com/Microsoft/go-winio v0.6.2
|
||||
github.com/aws/aws-sdk-go-v2/config v1.27.27
|
||||
github.com/compose-spec/compose-go/v2 v2.4.8
|
||||
github.com/compose-spec/compose-go/v2 v2.4.7
|
||||
github.com/containerd/console v1.0.4
|
||||
github.com/containerd/containerd/v2 v2.0.3
|
||||
github.com/containerd/containerd/v2 v2.0.2
|
||||
github.com/containerd/continuity v0.4.5
|
||||
github.com/containerd/errdefs v1.0.0
|
||||
github.com/containerd/log v0.1.0
|
||||
@@ -17,9 +17,9 @@ require (
|
||||
github.com/creack/pty v1.1.24
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/distribution/reference v0.6.0
|
||||
github.com/docker/cli v28.0.1+incompatible
|
||||
github.com/docker/cli v28.0.0-rc.2+incompatible
|
||||
github.com/docker/cli-docs-tool v0.9.0
|
||||
github.com/docker/docker v28.0.1+incompatible
|
||||
github.com/docker/docker v28.0.0-rc.2+incompatible
|
||||
github.com/docker/go-units v0.5.0
|
||||
github.com/gofrs/flock v0.12.1
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||
@@ -29,7 +29,7 @@ require (
|
||||
github.com/hashicorp/hcl/v2 v2.23.0
|
||||
github.com/in-toto/in-toto-golang v0.5.0
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2
|
||||
github.com/moby/buildkit v0.20.1
|
||||
github.com/moby/buildkit v0.20.0-rc3
|
||||
github.com/moby/sys/mountinfo v0.7.2
|
||||
github.com/moby/sys/signal v0.7.1
|
||||
github.com/morikuni/aec v1.0.0
|
||||
|
30
go.sum
30
go.sum
@@ -77,16 +77,16 @@ github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e
|
||||
github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
|
||||
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
|
||||
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4=
|
||||
github.com/compose-spec/compose-go/v2 v2.4.8 h1:7Myl8wDRl/4mRz77S+eyDJymGGEHu0diQdGSSeyq90A=
|
||||
github.com/compose-spec/compose-go/v2 v2.4.8/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc=
|
||||
github.com/compose-spec/compose-go/v2 v2.4.7 h1:WNpz5bIbKG+G+w9pfu72B1ZXr+Og9jez8TMEo8ecXPk=
|
||||
github.com/compose-spec/compose-go/v2 v2.4.7/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc=
|
||||
github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo=
|
||||
github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
|
||||
github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro=
|
||||
github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
|
||||
github.com/containerd/containerd/api v1.8.0 h1:hVTNJKR8fMc/2Tiw60ZRijntNMd1U+JVMyTRdsD2bS0=
|
||||
github.com/containerd/containerd/api v1.8.0/go.mod h1:dFv4lt6S20wTu/hMcP4350RL87qPWLVa/OHOwmmdnYc=
|
||||
github.com/containerd/containerd/v2 v2.0.3 h1:zBKgwgZsuu+LPCMzCLgA4sC4MiZzZ59ZT31XkmiISQM=
|
||||
github.com/containerd/containerd/v2 v2.0.3/go.mod h1:5j9QUUaV/cy9ZeAx4S+8n9ffpf+iYnEj4jiExgcbuLY=
|
||||
github.com/containerd/containerd/v2 v2.0.2 h1:GmH/tRBlTvrXOLwSpWE2vNAm8+MqI6nmxKpKBNKY8Wc=
|
||||
github.com/containerd/containerd/v2 v2.0.2/go.mod h1:wIqEvQ/6cyPFUGJ5yMFanspPabMLor+bF865OHvNTTI=
|
||||
github.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4=
|
||||
github.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=
|
||||
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
|
||||
@@ -122,15 +122,15 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/cli v28.0.1+incompatible h1:g0h5NQNda3/CxIsaZfH4Tyf6vpxFth7PYl3hgCPOKzs=
|
||||
github.com/docker/cli v28.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli v28.0.0-rc.2+incompatible h1:2N1dpr3qtlJwIQpqXm7oNwWNAUGzpKlsCeJ32ejvpTk=
|
||||
github.com/docker/cli v28.0.0-rc.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli-docs-tool v0.9.0 h1:CVwQbE+ZziwlPqrJ7LRyUF6GvCA+6gj7MTCsayaK9t0=
|
||||
github.com/docker/cli-docs-tool v0.9.0/go.mod h1:ClrwlNW+UioiRyH9GiAOe1o3J/TsY3Tr1ipoypjAUtc=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v28.0.1+incompatible h1:FCHjSRdXhNRFjlHMTv4jUNlIBbTeRjrWfeFuJp7jpo0=
|
||||
github.com/docker/docker v28.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v28.0.0-rc.2+incompatible h1:p+Ri+C0mmbPkhYVD9Sxnp/TnNnZoQWEj/EwOC465Uq4=
|
||||
github.com/docker/docker v28.0.0-rc.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
|
||||
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
|
||||
@@ -152,6 +152,8 @@ github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE=
|
||||
github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
||||
@@ -295,8 +297,8 @@ github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/z
|
||||
github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/buildkit v0.20.1 h1:sT0ZXhhNo5rVbMcYfgttma3TdUHfO5JjFA0UAL8p9fY=
|
||||
github.com/moby/buildkit v0.20.1/go.mod h1:Rq9nB/fJImdk6QeM0niKtOHJqwKeYMrK847hTTDVuA4=
|
||||
github.com/moby/buildkit v0.20.0-rc3 h1:iExrfuZZuFgFudeNJhXfp/5vzJWTNrlqZ/LYJk4dG2Q=
|
||||
github.com/moby/buildkit v0.20.0-rc3/go.mod h1:kMXf90l/f3zygRK8bYbyetfyzoJYntb6Bpi2VsLfXgQ=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
||||
@@ -349,6 +351,8 @@ github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQ
|
||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||
github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk=
|
||||
github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 h1:DmNGcqH3WDbV5k8OJ+esPWbqUOX5rMLR2PMvziDMJi0=
|
||||
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626/go.mod h1:BRHJJd0E+cx42OybVYSgUvZmU0B8P9gZuRXlZUP7TKI=
|
||||
github.com/opencontainers/selinux v1.11.1 h1:nHFvthhM0qY8/m+vfhJylliSshm8G1jJ2jDMcgULaH8=
|
||||
github.com/opencontainers/selinux v1.11.1/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
|
||||
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
|
||||
@@ -433,6 +437,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c=
|
||||
github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw=
|
||||
github.com/tonistiigi/dchapes-mode v0.0.0-20241001053921-ca0759fec205 h1:eUk79E1w8yMtXeHSzjKorxuC8qJOnyXQnLaJehxpJaI=
|
||||
@@ -626,3 +632,7 @@ sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+s
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
|
||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||
tags.cncf.io/container-device-interface v0.8.0 h1:8bCFo/g9WODjWx3m6EYl3GfUG31eKJbaggyBDxEldRc=
|
||||
tags.cncf.io/container-device-interface v0.8.0/go.mod h1:Apb7N4VdILW0EVdEMRYXIDVRZfNJZ+kmEUss2kRRQ6Y=
|
||||
tags.cncf.io/container-device-interface/specs-go v0.8.0 h1:QYGFzGxvYK/ZLMrjhvY0RjpUavIn4KcmRmVP/JjdBTA=
|
||||
tags.cncf.io/container-device-interface/specs-go v0.8.0/go.mod h1:BhJIkjjPh4qpys+qm4DAYtUyryaTDg9zris+AczXyws=
|
||||
|
@@ -9,13 +9,10 @@ Vagrant.configure("2") do |config|
|
||||
|
||||
config.vm.provision "init", type: "shell", run: "once" do |sh|
|
||||
sh.inline = <<~SHELL
|
||||
set -x
|
||||
pkg bootstrap
|
||||
pkg install -y git
|
||||
|
||||
fetch https://go.dev/dl/go#{ENV['GO_VERSION']}.freebsd-amd64.tar.gz
|
||||
tar -C /usr/local -xzf go#{ENV['GO_VERSION']}.freebsd-amd64.tar.gz
|
||||
ln -s /usr/local/go/bin/go /usr/local/bin/go
|
||||
pkg install -y go123 git
|
||||
ln -s /usr/local/bin/go123 /usr/local/bin/go
|
||||
go install gotest.tools/gotestsum@#{ENV['GOTESTSUM_VERSION']}
|
||||
SHELL
|
||||
end
|
||||
end
|
||||
|
@@ -1,32 +0,0 @@
|
||||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
Vagrant.configure("2") do |config|
|
||||
config.vm.box = "generic/netbsd9"
|
||||
config.vm.boot_timeout = 900
|
||||
config.vm.synced_folder ".", "/vagrant", type: "rsync"
|
||||
config.ssh.keep_alive = true
|
||||
|
||||
config.vm.provision "init", type: "shell", run: "once" do |sh|
|
||||
sh.inline = <<~SHELL
|
||||
set -x
|
||||
mkdir -p /var/tmp
|
||||
chmod 1777 /var/tmp
|
||||
|
||||
pkgin -y install git mozilla-rootcerts
|
||||
mozilla-rootcerts install
|
||||
|
||||
ftp https://go.dev/dl/go#{ENV['GO_VERSION']}.netbsd-amd64.tar.gz
|
||||
tar -C /var/tmp -xzf go#{ENV['GO_VERSION']}.netbsd-amd64.tar.gz
|
||||
|
||||
cat << 'EOF' > /usr/bin/go-wrapper
|
||||
#!/bin/sh
|
||||
export TMPDIR="/var/tmp"
|
||||
exec /var/tmp/go/bin/go "$@"
|
||||
EOF
|
||||
chmod +x /usr/bin/go-wrapper
|
||||
|
||||
ln -s /usr/bin/go-wrapper /usr/bin/go
|
||||
SHELL
|
||||
end
|
||||
end
|
@@ -10,12 +10,12 @@ Vagrant.configure("2") do |config|
|
||||
|
||||
config.vm.provision "init", type: "shell", run: "once" do |sh|
|
||||
sh.inline = <<~SHELL
|
||||
set -x
|
||||
pkg_add -x git
|
||||
|
||||
ftp https://go.dev/dl/go#{ENV['GO_VERSION']}.openbsd-amd64.tar.gz
|
||||
tar -C /usr/local -xzf go#{ENV['GO_VERSION']}.openbsd-amd64.tar.gz
|
||||
ftp https://go.dev/dl/go1.23.3.openbsd-amd64.tar.gz
|
||||
tar -C /usr/local -xzf go1.23.3.openbsd-amd64.tar.gz
|
||||
ln -s /usr/local/go/bin/go /usr/local/bin/go
|
||||
go install gotest.tools/gotestsum@#{ENV['GOTESTSUM_VERSION']}
|
||||
SHELL
|
||||
end
|
||||
end
|
||||
|
@@ -5,10 +5,9 @@ ARG ALPINE_VERSION=3.21
|
||||
ARG XX_VERSION=1.6.1
|
||||
|
||||
ARG GOLANGCI_LINT_VERSION=1.62.0
|
||||
# v0.31 requires go1.24
|
||||
ARG GOPLS_VERSION=v0.30.0
|
||||
ARG GOPLS_VERSION=v0.26.0
|
||||
# disabled: deprecated unusedvariable simplifyrange
|
||||
ARG GOPLS_ANALYZERS="embeddirective fillreturns hostport infertypeargs modernize nonewvars noresultvalues simplifycompositelit simplifyslice unusedparams yield"
|
||||
ARG GOPLS_ANALYZERS="embeddirective fillreturns infertypeargs nonewvars noresultvalues simplifycompositelit simplifyslice undeclaredname unusedparams useany"
|
||||
|
||||
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
|
||||
|
||||
|
@@ -6,7 +6,6 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/buildx/util/confutil"
|
||||
@@ -15,7 +14,6 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
version = 2
|
||||
refsDir = "refs"
|
||||
groupDir = "__group__"
|
||||
)
|
||||
@@ -33,8 +31,12 @@ type State struct {
|
||||
}
|
||||
|
||||
type StateGroup struct {
|
||||
// Definition is the raw representation of the group (bake definition)
|
||||
Definition []byte
|
||||
// Targets are the targets invoked
|
||||
Targets []string `json:",omitempty"`
|
||||
// Inputs are the user inputs (bake overrides)
|
||||
Inputs []string `json:",omitempty"`
|
||||
// Refs are used to track all the refs that belong to the same group
|
||||
Refs []string
|
||||
}
|
||||
@@ -50,7 +52,9 @@ func New(cfg *confutil.Config) (*LocalState, error) {
|
||||
if err := cfg.MkdirAll(refsDir, 0700); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &LocalState{cfg: cfg}, nil
|
||||
return &LocalState{
|
||||
cfg: cfg,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (ls *LocalState) ReadRef(builderName, nodeName, id string) (*State, error) {
|
||||
@@ -83,12 +87,8 @@ func (ls *LocalState) SaveRef(builderName, nodeName, id string, st State) error
|
||||
return ls.cfg.AtomicWriteFile(filepath.Join(refDir, id), dt, 0644)
|
||||
}
|
||||
|
||||
func (ls *LocalState) GroupDir() string {
|
||||
return filepath.Join(ls.cfg.Dir(), refsDir, groupDir)
|
||||
}
|
||||
|
||||
func (ls *LocalState) ReadGroup(id string) (*StateGroup, error) {
|
||||
dt, err := os.ReadFile(filepath.Join(ls.GroupDir(), id))
|
||||
dt, err := os.ReadFile(filepath.Join(ls.cfg.Dir(), refsDir, groupDir, id))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -208,7 +208,7 @@ func (ls *LocalState) removeGroup(id string) error {
|
||||
if id == "" {
|
||||
return errors.Errorf("group ref empty")
|
||||
}
|
||||
f := filepath.Join(ls.GroupDir(), id)
|
||||
f := filepath.Join(ls.cfg.Dir(), refsDir, groupDir, id)
|
||||
if _, err := os.Lstat(f); err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return err
|
||||
@@ -230,16 +230,3 @@ func (ls *LocalState) validate(builderName, nodeName, id string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ls *LocalState) readVersion() int {
|
||||
if vdt, err := os.ReadFile(filepath.Join(ls.cfg.Dir(), refsDir, "version")); err == nil {
|
||||
if v, err := strconv.Atoi(string(vdt)); err == nil {
|
||||
return v
|
||||
}
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
func (ls *LocalState) writeVersion(version int) error {
|
||||
return ls.cfg.AtomicWriteFile(filepath.Join(refsDir, "version"), []byte(strconv.Itoa(version)), 0600)
|
||||
}
|
||||
|
@@ -68,8 +68,10 @@ var (
|
||||
|
||||
testStateGroupID = "kvqs0sgly2rmitz84r25u9qd0"
|
||||
testStateGroup = StateGroup{
|
||||
Targets: []string{"pre-checkin"},
|
||||
Refs: []string{"builder/builder0/hx2qf1w11qvz1x3k471c5i8xw", "builder/builder0/968zj0g03jmlx0s8qslnvh6rl", "builder/builder0/naf44f9i1710lf7y12lv5hb1z"},
|
||||
Definition: []byte(`{"group":{"default":{"targets":["pre-checkin"]},"pre-checkin":{"targets":["vendor-update","format","build"]}},"target":{"build":{"context":".","dockerfile":"dev.Dockerfile","target":"build-update","platforms":["linux/amd64"],"output":["."]},"format":{"context":".","dockerfile":"dev.Dockerfile","target":"format-update","platforms":["linux/amd64"],"output":["."]},"vendor-update":{"context":".","dockerfile":"dev.Dockerfile","target":"vendor-update","platforms":["linux/amd64"],"output":["."]}}}`),
|
||||
Targets: []string{"pre-checkin"},
|
||||
Inputs: []string{"*.platform=linux/amd64"},
|
||||
Refs: []string{"builder/builder0/hx2qf1w11qvz1x3k471c5i8xw", "builder/builder0/968zj0g03jmlx0s8qslnvh6rl", "builder/builder0/naf44f9i1710lf7y12lv5hb1z"},
|
||||
}
|
||||
|
||||
testStateGroupRef1ID = "hx2qf1w11qvz1x3k471c5i8xw"
|
||||
|
@@ -1,56 +0,0 @@
|
||||
package localstate
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (ls *LocalState) MigrateIfNeeded() error {
|
||||
currentVersion := ls.readVersion()
|
||||
if currentVersion == version {
|
||||
return nil
|
||||
}
|
||||
migrations := map[int]func(*LocalState) error{
|
||||
2: (*LocalState).migration2,
|
||||
}
|
||||
for v := currentVersion + 1; v <= version; v++ {
|
||||
migration, found := migrations[v]
|
||||
if !found {
|
||||
return errors.Errorf("localstate migration v%d not found", v)
|
||||
}
|
||||
if err := migration(ls); err != nil {
|
||||
return errors.Wrapf(err, "localstate migration v%d failed", v)
|
||||
}
|
||||
}
|
||||
return ls.writeVersion(version)
|
||||
}
|
||||
|
||||
func (ls *LocalState) migration2() error {
|
||||
return filepath.Walk(ls.GroupDir(), func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
dt, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var stg StateGroup
|
||||
if err := json.Unmarshal(dt, &stg); err != nil {
|
||||
return err
|
||||
}
|
||||
mdt, err := json.Marshal(stg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.WriteFile(path, mdt, 0600); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"slices"
|
||||
|
||||
"github.com/docker/buildx/monitor/types"
|
||||
"github.com/pkg/errors"
|
||||
@@ -51,7 +50,14 @@ func (cm *AttachCmd) Exec(ctx context.Context, args []string) error {
|
||||
if err != nil {
|
||||
return errors.Errorf("failed to get the list of sessions: %v", err)
|
||||
}
|
||||
if !slices.Contains(refs, ref) {
|
||||
found := false
|
||||
for _, s := range refs {
|
||||
if s == ref {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return errors.Errorf("unknown ID: %q", ref)
|
||||
}
|
||||
cm.m.Detach() // Finish existing attach
|
||||
|
@@ -2,7 +2,6 @@ package store
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/platforms"
|
||||
@@ -45,7 +44,7 @@ func (ng *NodeGroup) Leave(name string) error {
|
||||
if len(ng.Nodes) == 1 {
|
||||
return errors.Errorf("can not leave last node, do you want to rm instance instead?")
|
||||
}
|
||||
ng.Nodes = slices.Delete(ng.Nodes, i, i+1)
|
||||
ng.Nodes = append(ng.Nodes[:i], ng.Nodes[i+1:]...)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@@ -39,7 +39,7 @@ func ValidateName(s string) (string, error) {
|
||||
|
||||
func GenerateName(txn *Txn) (string, error) {
|
||||
var name string
|
||||
for i := range 6 {
|
||||
for i := 0; i < 6; i++ {
|
||||
name = namesgenerator.GetRandomName(i)
|
||||
if _, err := txn.NodeGroupByName(name); err != nil {
|
||||
if !os.IsNotExist(errors.Cause(err)) {
|
||||
|
@@ -38,7 +38,6 @@ func bakeCmd(sb integration.Sandbox, opts ...cmdOpt) (string, error) {
|
||||
var bakeTests = []func(t *testing.T, sb integration.Sandbox){
|
||||
testBakePrint,
|
||||
testBakePrintSensitive,
|
||||
testBakePrintOverrideEmpty,
|
||||
testBakeLocal,
|
||||
testBakeLocalMulti,
|
||||
testBakeRemote,
|
||||
@@ -287,47 +286,6 @@ RUN echo "Hello ${HELLO}"
|
||||
}
|
||||
}
|
||||
|
||||
func testBakePrintOverrideEmpty(t *testing.T, sb integration.Sandbox) {
|
||||
dockerfile := []byte(`
|
||||
FROM scratch
|
||||
COPY foo /foo
|
||||
`)
|
||||
bakefile := []byte(`
|
||||
target "default" {
|
||||
cache-to = ["type=gha,mode=min,scope=integration-tests"]
|
||||
}
|
||||
`)
|
||||
dir := tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
|
||||
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
||||
fstest.CreateFile("foo", []byte("foo"), 0600),
|
||||
)
|
||||
|
||||
cmd := buildxCmd(sb, withDir(dir), withArgs("bake", "--print", "--set", "*.cache-to="))
|
||||
stdout := bytes.Buffer{}
|
||||
stderr := bytes.Buffer{}
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
require.NoError(t, cmd.Run(), stdout.String(), stderr.String())
|
||||
|
||||
require.JSONEq(t, `{
|
||||
"group": {
|
||||
"default": {
|
||||
"targets": [
|
||||
"default"
|
||||
]
|
||||
}
|
||||
},
|
||||
"target": {
|
||||
"default": {
|
||||
"context": ".",
|
||||
"dockerfile": "Dockerfile"
|
||||
}
|
||||
}
|
||||
}`, stdout.String())
|
||||
}
|
||||
|
||||
func testBakeLocal(t *testing.T, sb integration.Sandbox) {
|
||||
dockerfile := []byte(`
|
||||
FROM scratch
|
||||
@@ -913,7 +871,6 @@ target "default" {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testBakeSetNonExistingOutsideNoParallel(t *testing.T, sb integration.Sandbox) {
|
||||
for _, ent := range []bool{true, false} {
|
||||
t.Run(fmt.Sprintf("ent=%v", ent), func(t *testing.T) {
|
||||
@@ -1016,11 +973,11 @@ FROM scratch
|
||||
COPY foo /foo
|
||||
`)
|
||||
destDir := t.TempDir()
|
||||
bakefile := fmt.Appendf(nil, `
|
||||
bakefile := []byte(fmt.Sprintf(`
|
||||
target "default" {
|
||||
output = ["type=local,dest=%s/not/exists"]
|
||||
}
|
||||
`, destDir)
|
||||
`, destDir))
|
||||
dir := tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
|
||||
@@ -1050,11 +1007,11 @@ FROM scratch
|
||||
COPY foo /foo
|
||||
`)
|
||||
destDir := t.TempDir()
|
||||
bakefile := fmt.Appendf(nil, `
|
||||
bakefile := []byte(fmt.Sprintf(`
|
||||
target "default" {
|
||||
output = ["type=local,dest=%s"]
|
||||
}
|
||||
`, destDir)
|
||||
`, destDir))
|
||||
dir := tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
|
||||
@@ -1151,11 +1108,11 @@ COPY Dockerfile /foo
|
||||
keyDir := t.TempDir()
|
||||
err := writeTempPrivateKey(filepath.Join(keyDir, "id_rsa"))
|
||||
require.NoError(t, err)
|
||||
bakefile := fmt.Appendf(nil, `
|
||||
bakefile := []byte(fmt.Sprintf(`
|
||||
target "default" {
|
||||
ssh = ["key=%s"]
|
||||
}
|
||||
`, filepath.Join(keyDir, "id_rsa"))
|
||||
`, filepath.Join(keyDir, "id_rsa")))
|
||||
dir := tmpdir(
|
||||
t,
|
||||
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
|
||||
@@ -1314,8 +1271,8 @@ target "default" {
|
||||
|
||||
type mdT struct {
|
||||
Default struct {
|
||||
BuildRef string `json:"buildx.build.ref"`
|
||||
BuildProvenance map[string]any `json:"buildx.build.provenance"`
|
||||
BuildRef string `json:"buildx.build.ref"`
|
||||
BuildProvenance map[string]interface{} `json:"buildx.build.provenance"`
|
||||
} `json:"default"`
|
||||
}
|
||||
var md mdT
|
||||
|
@@ -804,8 +804,8 @@ func buildMetadataProvenance(t *testing.T, sb integration.Sandbox, metadataMode
|
||||
require.NoError(t, err)
|
||||
|
||||
type mdT struct {
|
||||
BuildRef string `json:"buildx.build.ref"`
|
||||
BuildProvenance map[string]any `json:"buildx.build.provenance"`
|
||||
BuildRef string `json:"buildx.build.ref"`
|
||||
BuildProvenance map[string]interface{} `json:"buildx.build.provenance"`
|
||||
}
|
||||
var md mdT
|
||||
err = json.Unmarshal(dt, &md)
|
||||
|
@@ -50,7 +50,7 @@ func withDir(dir string) cmdOpt {
|
||||
|
||||
func buildxCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd {
|
||||
cmd := exec.Command("buildx")
|
||||
cmd.Env = os.Environ()
|
||||
cmd.Env = append([]string{}, os.Environ()...)
|
||||
for _, opt := range opts {
|
||||
opt(cmd)
|
||||
}
|
||||
@@ -77,7 +77,7 @@ func buildxCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd {
|
||||
|
||||
func dockerCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd {
|
||||
cmd := exec.Command("docker")
|
||||
cmd.Env = os.Environ()
|
||||
cmd.Env = append([]string{}, os.Environ()...)
|
||||
for _, opt := range opts {
|
||||
opt(cmd)
|
||||
}
|
||||
@@ -214,7 +214,7 @@ func skipNoCompatBuildKit(t *testing.T, sb integration.Sandbox, constraint strin
|
||||
}
|
||||
}
|
||||
|
||||
func ptrstr(s any) *string {
|
||||
func ptrstr(s interface{}) *string {
|
||||
var n *string
|
||||
if reflect.ValueOf(s).Kind() == reflect.String {
|
||||
ss := s.(string)
|
||||
|
@@ -45,7 +45,7 @@ func testRmMulti(t *testing.T, sb integration.Sandbox) {
|
||||
}
|
||||
|
||||
var builderNames []string
|
||||
for range 3 {
|
||||
for i := 0; i < 3; i++ {
|
||||
out, err := createCmd(sb, withArgs("--driver", "docker-container"))
|
||||
require.NoError(t, err, out)
|
||||
builderName := strings.TrimSpace(out)
|
||||
|
@@ -2,7 +2,6 @@ package workers
|
||||
|
||||
import (
|
||||
"os"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/moby/buildkit/util/testutil/integration"
|
||||
@@ -50,14 +49,23 @@ func (s *backend) ExtraEnv() []string {
|
||||
|
||||
func (s backend) Supports(feature string) bool {
|
||||
if enabledFeatures := os.Getenv("BUILDKIT_TEST_ENABLE_FEATURES"); enabledFeatures != "" {
|
||||
if slices.Contains(strings.Split(enabledFeatures, ","), feature) {
|
||||
return true
|
||||
for _, enabledFeature := range strings.Split(enabledFeatures, ",") {
|
||||
if feature == enabledFeature {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
if disabledFeatures := os.Getenv("BUILDKIT_TEST_DISABLE_FEATURES"); disabledFeatures != "" {
|
||||
if slices.Contains(strings.Split(disabledFeatures, ","), feature) {
|
||||
for _, disabledFeature := range strings.Split(disabledFeatures, ",") {
|
||||
if feature == disabledFeature {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, unsupportedFeature := range s.unsupportedFeatures {
|
||||
if feature == unsupportedFeature {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return !slices.Contains(s.unsupportedFeatures, feature)
|
||||
return true
|
||||
}
|
||||
|
@@ -90,7 +90,7 @@ func (a *Attest) ToPB() *controllerapi.Attest {
|
||||
}
|
||||
|
||||
func (a *Attest) MarshalJSON() ([]byte, error) {
|
||||
m := make(map[string]any, len(a.Attrs)+2)
|
||||
m := make(map[string]interface{}, len(a.Attrs)+2)
|
||||
for k, v := range a.Attrs {
|
||||
m[k] = v
|
||||
}
|
||||
@@ -102,7 +102,7 @@ func (a *Attest) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
|
||||
func (a *Attest) UnmarshalJSON(data []byte) error {
|
||||
var m map[string]any
|
||||
var m map[string]interface{}
|
||||
if err := json.Unmarshal(data, &m); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -148,8 +148,9 @@ func (a *Attest) UnmarshalText(text []byte) error {
|
||||
if !ok {
|
||||
return errors.Errorf("invalid value %s", field)
|
||||
}
|
||||
key = strings.TrimSpace(strings.ToLower(key))
|
||||
|
||||
switch strings.TrimSpace(strings.ToLower(key)) {
|
||||
switch key {
|
||||
case "type":
|
||||
a.Type = value
|
||||
case "disabled":
|
||||
|
@@ -13,21 +13,16 @@ func TestAttests(t *testing.T) {
|
||||
attests := Attests{
|
||||
{Type: "provenance", Attrs: map[string]string{"mode": "max"}},
|
||||
{Type: "sbom", Disabled: true},
|
||||
{Type: "sbom", Attrs: map[string]string{
|
||||
"generator": "scanner",
|
||||
"ENV1": `"foo,bar"`,
|
||||
"Env2": "hello",
|
||||
}},
|
||||
}
|
||||
|
||||
expected := `[{"type":"provenance","mode":"max"},{"type":"sbom","disabled":true},{"ENV1":"\"foo,bar\"","Env2":"hello","generator":"scanner","type":"sbom"}]`
|
||||
expected := `[{"type":"provenance","mode":"max"},{"type":"sbom","disabled":true}]`
|
||||
actual, err := json.Marshal(attests)
|
||||
require.NoError(t, err)
|
||||
require.JSONEq(t, expected, string(actual))
|
||||
})
|
||||
|
||||
t.Run("UnmarshalJSON", func(t *testing.T) {
|
||||
in := `[{"type":"provenance","mode":"max"},{"type":"sbom","disabled":true},{"ENV1":"\"foo,bar\"","Env2":"hello","generator":"scanner","type":"sbom"}]`
|
||||
in := `[{"type":"provenance","mode":"max"},{"type":"sbom","disabled":true}]`
|
||||
|
||||
var actual Attests
|
||||
err := json.Unmarshal([]byte(in), &actual)
|
||||
@@ -36,11 +31,6 @@ func TestAttests(t *testing.T) {
|
||||
expected := Attests{
|
||||
{Type: "provenance", Attrs: map[string]string{"mode": "max"}},
|
||||
{Type: "sbom", Disabled: true, Attrs: map[string]string{}},
|
||||
{Type: "sbom", Disabled: false, Attrs: map[string]string{
|
||||
"generator": "scanner",
|
||||
"ENV1": `"foo,bar"`,
|
||||
"Env2": "hello",
|
||||
}},
|
||||
}
|
||||
require.Equal(t, expected, actual)
|
||||
})
|
||||
@@ -51,14 +41,7 @@ func TestAttests(t *testing.T) {
|
||||
"type": cty.StringVal("provenance"),
|
||||
"mode": cty.StringVal("max"),
|
||||
}),
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"type": cty.StringVal("sbom"),
|
||||
"generator": cty.StringVal("scan"),
|
||||
"ENV1": cty.StringVal(`foo,bar`),
|
||||
"Env2": cty.StringVal(`hello`),
|
||||
}),
|
||||
cty.StringVal("type=sbom,disabled=true"),
|
||||
cty.StringVal(`type=sbom,generator=scan,"FOO=bar,baz",Hello=World`),
|
||||
})
|
||||
|
||||
var actual Attests
|
||||
@@ -67,17 +50,7 @@ func TestAttests(t *testing.T) {
|
||||
|
||||
expected := Attests{
|
||||
{Type: "provenance", Attrs: map[string]string{"mode": "max"}},
|
||||
{Type: "sbom", Attrs: map[string]string{
|
||||
"generator": "scan",
|
||||
"ENV1": "foo,bar",
|
||||
"Env2": "hello",
|
||||
}},
|
||||
{Type: "sbom", Disabled: true, Attrs: map[string]string{}},
|
||||
{Type: "sbom", Attrs: map[string]string{
|
||||
"generator": "scan",
|
||||
"FOO": "bar,baz",
|
||||
"Hello": "World",
|
||||
}},
|
||||
}
|
||||
require.Equal(t, expected, actual)
|
||||
})
|
||||
@@ -86,11 +59,6 @@ func TestAttests(t *testing.T) {
|
||||
attests := Attests{
|
||||
{Type: "provenance", Attrs: map[string]string{"mode": "max"}},
|
||||
{Type: "sbom", Disabled: true},
|
||||
{Type: "sbom", Attrs: map[string]string{
|
||||
"generator": "scan",
|
||||
"ENV1": `"foo,bar"`,
|
||||
"Env2": "hello",
|
||||
}},
|
||||
}
|
||||
|
||||
actual := attests.ToCtyValue()
|
||||
@@ -103,12 +71,6 @@ func TestAttests(t *testing.T) {
|
||||
"type": cty.StringVal("sbom"),
|
||||
"disabled": cty.StringVal("true"),
|
||||
}),
|
||||
cty.MapVal(map[string]cty.Value{
|
||||
"type": cty.StringVal("sbom"),
|
||||
"generator": cty.StringVal("scan"),
|
||||
"ENV1": cty.StringVal(`"foo,bar"`),
|
||||
"Env2": cty.StringVal("hello"),
|
||||
}),
|
||||
})
|
||||
|
||||
result := actual.Equals(expected)
|
||||
|
@@ -150,7 +150,7 @@ func (e *CacheOptionsEntry) UnmarshalText(text []byte) error {
|
||||
return e.validate(text)
|
||||
}
|
||||
|
||||
func (e *CacheOptionsEntry) validate(gv any) error {
|
||||
func (e *CacheOptionsEntry) validate(gv interface{}) error {
|
||||
if e.Type == "" {
|
||||
var text []byte
|
||||
switch gv := gv.(type) {
|
||||
@@ -175,10 +175,6 @@ func ParseCacheEntry(in []string) (CacheOptions, error) {
|
||||
|
||||
opts := make(CacheOptions, 0, len(in))
|
||||
for _, in := range in {
|
||||
if in == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if !strings.Contains(in, "=") {
|
||||
// This is ref only format. Each field in the CSV is its own entry.
|
||||
fields, err := csvvalue.Fields(in, nil)
|
||||
|
@@ -1,11 +1,14 @@
|
||||
package buildflags
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/moby/buildkit/util/entitlements"
|
||||
)
|
||||
|
||||
func ParseEntitlements(in []string) ([]string, error) {
|
||||
out := make([]string, 0, len(in))
|
||||
log.Printf("in: %#v", in)
|
||||
for _, v := range in {
|
||||
if v == "" {
|
||||
continue
|
||||
@@ -16,5 +19,6 @@ func ParseEntitlements(in []string) ([]string, error) {
|
||||
}
|
||||
out = append(out, v)
|
||||
}
|
||||
log.Printf("Parsed entitlements: %v", out)
|
||||
return out, nil
|
||||
}
|
||||
|
@@ -1,7 +1,6 @@
|
||||
package buildflags
|
||||
|
||||
import (
|
||||
"encoding/csv"
|
||||
"encoding/json"
|
||||
"maps"
|
||||
"regexp"
|
||||
@@ -260,18 +259,9 @@ func (w *csvBuilder) Write(key, value string) {
|
||||
if w.sb.Len() > 0 {
|
||||
w.sb.WriteByte(',')
|
||||
}
|
||||
|
||||
pair := key + "=" + value
|
||||
if strings.ContainsRune(pair, ',') || strings.ContainsRune(pair, '"') {
|
||||
var attr strings.Builder
|
||||
writer := csv.NewWriter(&attr)
|
||||
writer.Write([]string{pair})
|
||||
writer.Flush()
|
||||
// Strips the extra newline added by the csv writer
|
||||
pair = strings.TrimSpace(attr.String())
|
||||
}
|
||||
|
||||
w.sb.WriteString(pair)
|
||||
w.sb.WriteString(key)
|
||||
w.sb.WriteByte('=')
|
||||
w.sb.WriteString(value)
|
||||
}
|
||||
|
||||
func (w *csvBuilder) WriteAttributes(attrs map[string]string) {
|
||||
|
@@ -27,7 +27,7 @@ func (s Secrets) Normalize() Secrets {
|
||||
if len(s) == 0 {
|
||||
return nil
|
||||
}
|
||||
return removeSecretDupes(s)
|
||||
return removeDupes(s)
|
||||
}
|
||||
|
||||
func (s Secrets) ToPB() []*controllerapi.Secret {
|
||||
@@ -155,17 +155,3 @@ func parseSecret(value string) (*controllerapi.Secret, error) {
|
||||
}
|
||||
return s.ToPB(), nil
|
||||
}
|
||||
|
||||
func removeSecretDupes(s []*Secret) []*Secret {
|
||||
var res []*Secret
|
||||
m := map[string]int{}
|
||||
for _, sec := range s {
|
||||
if i, ok := m[sec.ID]; ok {
|
||||
res[i] = sec
|
||||
} else {
|
||||
m[sec.ID] = len(res)
|
||||
res = append(res, sec)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
@@ -81,17 +81,4 @@ func TestSecrets(t *testing.T) {
|
||||
result := actual.Equals(expected)
|
||||
require.True(t, result.True())
|
||||
})
|
||||
|
||||
t.Run("RemoveDupes", func(t *testing.T) {
|
||||
secrets := Secrets{
|
||||
{ID: "mysecret", Env: "FOO"},
|
||||
{ID: "mysecret", Env: "BAR"},
|
||||
{ID: "mysecret2", Env: "BAZ"},
|
||||
}.Normalize()
|
||||
|
||||
expected := `[{"id":"mysecret","env":"BAR"},{"id":"mysecret2","env":"BAZ"}]`
|
||||
actual, err := json.Marshal(secrets)
|
||||
require.NoError(t, err)
|
||||
require.JSONEq(t, expected, string(actual))
|
||||
})
|
||||
}
|
||||
|
@@ -28,7 +28,7 @@ func (s SSHKeys) Normalize() SSHKeys {
|
||||
if len(s) == 0 {
|
||||
return nil
|
||||
}
|
||||
return removeSSHDupes(s)
|
||||
return removeDupes(s)
|
||||
}
|
||||
|
||||
func (s SSHKeys) ToPB() []*controllerapi.SSH {
|
||||
@@ -131,17 +131,3 @@ func IsGitSSH(repo string) bool {
|
||||
}
|
||||
return url.Scheme == gitutil.SSHProtocol
|
||||
}
|
||||
|
||||
func removeSSHDupes(s []*SSH) []*SSH {
|
||||
var res []*SSH
|
||||
m := map[string]int{}
|
||||
for _, ssh := range s {
|
||||
if i, ok := m[ssh.ID]; ok {
|
||||
res[i] = ssh
|
||||
} else {
|
||||
m[ssh.ID] = len(res)
|
||||
res = append(res, ssh)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
@@ -82,17 +82,4 @@ func TestSSHKeys(t *testing.T) {
|
||||
result := actual.Equals(expected)
|
||||
require.True(t, result.True())
|
||||
})
|
||||
|
||||
t.Run("RemoveDupes", func(t *testing.T) {
|
||||
sshkeys := SSHKeys{
|
||||
{ID: "default"},
|
||||
{ID: "key", Paths: []string{"path/to/foo"}},
|
||||
{ID: "key", Paths: []string{"path/to/bar"}},
|
||||
}.Normalize()
|
||||
|
||||
expected := `[{"id":"default"},{"id":"key","paths":["path/to/bar"]}]`
|
||||
actual, err := json.Marshal(sshkeys)
|
||||
require.NoError(t, err)
|
||||
require.JSONEq(t, expected, string(actual))
|
||||
})
|
||||
}
|
||||
|
@@ -33,7 +33,7 @@ func removeDupes[E comparable[E]](s []E) []E {
|
||||
return s
|
||||
}
|
||||
|
||||
func getAndDelete(m map[string]cty.Value, attr string, gv any) error {
|
||||
func getAndDelete(m map[string]cty.Value, attr string, gv interface{}) error {
|
||||
if v, ok := m[attr]; ok && v.IsKnown() {
|
||||
delete(m, attr)
|
||||
return gocty.FromCtyValue(v, gv)
|
||||
|
@@ -1,21 +0,0 @@
|
||||
package desktop
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
socketName = "docker-desktop-build.sock"
|
||||
socketPath = "Library/Containers/com.docker.docker/Data"
|
||||
)
|
||||
|
||||
func BuildServerAddr() (string, error) {
|
||||
dir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "failed to get user home directory")
|
||||
}
|
||||
return "unix://" + filepath.Join(dir, socketPath, socketName), nil
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
package desktop
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
socketName = "docker-desktop-build.sock"
|
||||
socketPath = ".docker/desktop"
|
||||
wslSocketPath = "/mnt/wsl/docker-desktop/shared-sockets/host-services"
|
||||
)
|
||||
|
||||
func BuildServerAddr() (string, error) {
|
||||
if os.Getenv("WSL_DISTRO_NAME") != "" {
|
||||
socket := filepath.Join(wslSocketPath, socketName)
|
||||
if _, err := os.Stat(socket); os.IsNotExist(err) {
|
||||
return "", errors.New("Docker Desktop Build backend is not yet supported on WSL. Please run this command on Windows host instead.") //nolint:revive
|
||||
}
|
||||
return "unix://" + socket, nil
|
||||
}
|
||||
dir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "failed to get user home directory")
|
||||
}
|
||||
return "unix://" + filepath.Join(dir, socketPath, socketName), nil
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
//go:build !windows && !darwin && !linux
|
||||
|
||||
package desktop
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func BuildServerAddr() (string, error) {
|
||||
return "", errors.Errorf("Docker Desktop unsupported on %s", runtime.GOOS)
|
||||
}
|
@@ -1,5 +0,0 @@
|
||||
package desktop
|
||||
|
||||
func BuildServerAddr() (string, error) {
|
||||
return "npipe:////./pipe/dockerDesktopBuildServer", nil
|
||||
}
|
@@ -156,7 +156,7 @@ func (r *Resolver) Combine(ctx context.Context, srcs []*Source, ann map[exptypes
|
||||
case exptypes.AnnotationIndex:
|
||||
indexAnnotation[k.Key] = v
|
||||
case exptypes.AnnotationManifestDescriptor:
|
||||
for i := range newDescs {
|
||||
for i := 0; i < len(newDescs); i++ {
|
||||
if newDescs[i].Annotations == nil {
|
||||
newDescs[i].Annotations = map[string]string{}
|
||||
}
|
||||
@@ -194,11 +194,8 @@ func (r *Resolver) Combine(ctx context.Context, srcs []*Source, ann map[exptypes
|
||||
func (r *Resolver) Push(ctx context.Context, ref reference.Named, desc ocispec.Descriptor, dt []byte) error {
|
||||
ctx = remotes.WithMediaTypeKeyPrefix(ctx, "application/vnd.in-toto+json", "intoto")
|
||||
|
||||
fullRef, err := reference.WithDigest(reference.TagNameOnly(ref), desc.Digest)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to combine ref %s with digest %s", ref, desc.Digest)
|
||||
}
|
||||
p, err := r.resolver().Pusher(ctx, fullRef.String())
|
||||
ref = reference.TagNameOnly(ref)
|
||||
p, err := r.resolver().Pusher(ctx, ref.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -220,8 +217,8 @@ func (r *Resolver) Push(ctx context.Context, ref reference.Named, desc ocispec.D
|
||||
func (r *Resolver) Copy(ctx context.Context, src *Source, dest reference.Named) error {
|
||||
ctx = remotes.WithMediaTypeKeyPrefix(ctx, "application/vnd.in-toto+json", "intoto")
|
||||
|
||||
// push by digest
|
||||
p, err := r.resolver().Pusher(ctx, dest.Name())
|
||||
dest = reference.TagNameOnly(dest)
|
||||
p, err := r.resolver().Pusher(ctx, dest.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -278,8 +278,8 @@ func (l *loader) scanConfig(ctx context.Context, fetcher remotes.Fetcher, desc o
|
||||
}
|
||||
|
||||
type sbomStub struct {
|
||||
SPDX any `json:",omitempty"`
|
||||
AdditionalSPDXs []any `json:",omitempty"`
|
||||
SPDX interface{} `json:",omitempty"`
|
||||
AdditionalSPDXs []interface{} `json:",omitempty"`
|
||||
}
|
||||
|
||||
func (l *loader) scanSBOM(ctx context.Context, fetcher remotes.Fetcher, r *result, refs []digest.Digest, as *asset) error {
|
||||
@@ -309,7 +309,7 @@ func (l *loader) scanSBOM(ctx context.Context, fetcher remotes.Fetcher, r *resul
|
||||
}
|
||||
|
||||
var spdx struct {
|
||||
Predicate any `json:"predicate"`
|
||||
Predicate interface{} `json:"predicate"`
|
||||
}
|
||||
if err := json.Unmarshal(dt, &spdx); err != nil {
|
||||
return nil, err
|
||||
@@ -330,7 +330,7 @@ func (l *loader) scanSBOM(ctx context.Context, fetcher remotes.Fetcher, r *resul
|
||||
}
|
||||
|
||||
type provenanceStub struct {
|
||||
SLSA any `json:",omitempty"`
|
||||
SLSA interface{} `json:",omitempty"`
|
||||
}
|
||||
|
||||
func (l *loader) scanProvenance(ctx context.Context, fetcher remotes.Fetcher, r *result, refs []digest.Digest, as *asset) error {
|
||||
@@ -360,7 +360,7 @@ func (l *loader) scanProvenance(ctx context.Context, fetcher remotes.Fetcher, r
|
||||
}
|
||||
|
||||
var slsa struct {
|
||||
Predicate any `json:"predicate"`
|
||||
Predicate interface{} `json:"predicate"`
|
||||
}
|
||||
if err := json.Unmarshal(dt, &slsa); err != nil {
|
||||
return nil, err
|
||||
|
@@ -89,7 +89,7 @@ func (p *Printer) Print(raw bool, out io.Writer) error {
|
||||
}
|
||||
|
||||
tpl, err := template.New("").Funcs(template.FuncMap{
|
||||
"json": func(v any) string {
|
||||
"json": func(v interface{}) string {
|
||||
b, _ := json.MarshalIndent(v, "", " ")
|
||||
return string(b)
|
||||
},
|
||||
@@ -101,7 +101,7 @@ func (p *Printer) Print(raw bool, out io.Writer) error {
|
||||
imageconfigs := res.Configs()
|
||||
format := tpl.Root.String()
|
||||
|
||||
var mfst any
|
||||
var mfst interface{}
|
||||
switch p.manifest.MediaType {
|
||||
case images.MediaTypeDockerSchema2Manifest, ocispecs.MediaTypeImageManifest:
|
||||
mfst = p.manifest
|
||||
@@ -206,7 +206,7 @@ func (p *Printer) printManifestList(out io.Writer) error {
|
||||
|
||||
type tplInput struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Manifest any `json:"manifest,omitempty"`
|
||||
Manifest interface{} `json:"manifest,omitempty"`
|
||||
Image *ocispecs.Image `json:"image,omitempty"`
|
||||
|
||||
result *result
|
||||
@@ -236,7 +236,7 @@ func (inp tplInput) Provenance() (provenanceStub, error) {
|
||||
|
||||
type tplInputs struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Manifest any `json:"manifest,omitempty"`
|
||||
Manifest interface{} `json:"manifest,omitempty"`
|
||||
Image map[string]*ocispecs.Image `json:"image,omitempty"`
|
||||
|
||||
result *result
|
||||
|
@@ -126,7 +126,7 @@ func TestMuxIO(t *testing.T) {
|
||||
if tt.outputsNum != len(tt.wants) {
|
||||
t.Fatalf("wants != outputsNum")
|
||||
}
|
||||
for i := range tt.outputsNum {
|
||||
for i := 0; i < tt.outputsNum; i++ {
|
||||
outBuf, out := newTestOut(i)
|
||||
outBufs = append(outBufs, outBuf)
|
||||
outs = append(outs, MuxOut{out, nil, nil})
|
||||
@@ -304,7 +304,7 @@ func writeMasked(w io.Writer, s string) io.Writer {
|
||||
return
|
||||
}
|
||||
var masked string
|
||||
for range n {
|
||||
for i := 0; i < n; i++ {
|
||||
masked += s
|
||||
}
|
||||
if _, err := w.Write([]byte(masked)); err != nil {
|
||||
|
@@ -83,9 +83,9 @@ type Log struct {
|
||||
|
||||
// KeyValue is a key-value pair with typed value.
|
||||
type KeyValue struct {
|
||||
Key string `json:"key"`
|
||||
Type ValueType `json:"type,omitempty"`
|
||||
Value any `json:"value"`
|
||||
Key string `json:"key"`
|
||||
Type ValueType `json:"type,omitempty"`
|
||||
Value interface{} `json:"value"`
|
||||
}
|
||||
|
||||
// DependencyLink shows dependencies between services
|
||||
|
@@ -149,7 +149,7 @@ type keyValue struct {
|
||||
// value is a custom type used to unmarshal otel Value correctly.
|
||||
type value struct {
|
||||
Type string
|
||||
Value any
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler for Span which allows correctly
|
||||
@@ -318,7 +318,7 @@ func (kv *keyValue) asAttributeKeyValue() (attribute.KeyValue, error) {
|
||||
switch sli := kv.Value.Value.(type) {
|
||||
case []string:
|
||||
strSli = sli
|
||||
case []any:
|
||||
case []interface{}:
|
||||
for i := range sli {
|
||||
var v string
|
||||
// best case we have a string, otherwise, cast it using
|
||||
|
@@ -131,7 +131,7 @@ func TestAsAttributeKeyValue(t *testing.T) {
|
||||
name: "stringslice (interface of string)",
|
||||
args: args{
|
||||
Type: attribute.STRINGSLICE.String(),
|
||||
value: []any{"value1", "value2"},
|
||||
value: []interface{}{"value1", "value2"},
|
||||
},
|
||||
want: attribute.StringSlice("key", []string{"value1", "value2"}),
|
||||
},
|
||||
@@ -139,7 +139,7 @@ func TestAsAttributeKeyValue(t *testing.T) {
|
||||
name: "stringslice (interface mixed)",
|
||||
args: args{
|
||||
Type: attribute.STRINGSLICE.String(),
|
||||
value: []any{"value1", 2},
|
||||
value: []interface{}{"value1", 2},
|
||||
},
|
||||
want: attribute.StringSlice("key", []string{"value1", "2"}),
|
||||
},
|
||||
|
@@ -27,7 +27,7 @@ type Printer struct {
|
||||
err error
|
||||
warnings []client.VertexWarning
|
||||
logMu sync.Mutex
|
||||
logSourceMap map[digest.Digest]any
|
||||
logSourceMap map[digest.Digest]interface{}
|
||||
metrics *metricWriter
|
||||
|
||||
// TODO: remove once we can use result context to pass build ref
|
||||
@@ -74,7 +74,7 @@ func (p *Printer) Warnings() []client.VertexWarning {
|
||||
return dedupWarnings(p.warnings)
|
||||
}
|
||||
|
||||
func (p *Printer) ValidateLogSource(dgst digest.Digest, v any) bool {
|
||||
func (p *Printer) ValidateLogSource(dgst digest.Digest, v interface{}) bool {
|
||||
p.logMu.Lock()
|
||||
defer p.logMu.Unlock()
|
||||
src, ok := p.logSourceMap[dgst]
|
||||
@@ -89,7 +89,7 @@ func (p *Printer) ValidateLogSource(dgst digest.Digest, v any) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *Printer) ClearLogSource(v any) {
|
||||
func (p *Printer) ClearLogSource(v interface{}) {
|
||||
p.logMu.Lock()
|
||||
defer p.logMu.Unlock()
|
||||
for d := range p.logSourceMap {
|
||||
@@ -125,7 +125,7 @@ func NewPrinter(ctx context.Context, out console.File, mode progressui.DisplayMo
|
||||
pw.closeOnce = sync.Once{}
|
||||
|
||||
pw.logMu.Lock()
|
||||
pw.logSourceMap = map[digest.Digest]any{}
|
||||
pw.logSourceMap = map[digest.Digest]interface{}{}
|
||||
pw.logMu.Unlock()
|
||||
|
||||
resumeLogs := logutil.Pause(logrus.StandardLogger())
|
||||
|
@@ -11,8 +11,8 @@ import (
|
||||
type Writer interface {
|
||||
Write(*client.SolveStatus)
|
||||
WriteBuildRef(string, string)
|
||||
ValidateLogSource(digest.Digest, any) bool
|
||||
ClearLogSource(any)
|
||||
ValidateLogSource(digest.Digest, interface{}) bool
|
||||
ClearLogSource(interface{})
|
||||
}
|
||||
|
||||
func Write(w Writer, name string, f func() error) error {
|
||||
|
@@ -2,6 +2,7 @@ package tracing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/moby/buildkit/util/tracing/delegated"
|
||||
@@ -12,7 +13,7 @@ import (
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
func TraceCurrentCommand(ctx context.Context, args []string, attrs ...attribute.KeyValue) (context.Context, func(error), error) {
|
||||
func TraceCurrentCommand(ctx context.Context, name string) (context.Context, func(error), error) {
|
||||
opts := []sdktrace.TracerProviderOption{
|
||||
sdktrace.WithResource(detect.Resource()),
|
||||
sdktrace.WithBatcher(delegated.DefaultExporter),
|
||||
@@ -24,8 +25,8 @@ func TraceCurrentCommand(ctx context.Context, args []string, attrs ...attribute.
|
||||
}
|
||||
|
||||
tp := sdktrace.NewTracerProvider(opts...)
|
||||
ctx, span := tp.Tracer("").Start(ctx, strings.Join(args, " "), trace.WithAttributes(
|
||||
attrs...,
|
||||
ctx, span := tp.Tracer("").Start(ctx, name, trace.WithAttributes(
|
||||
attribute.String("command", strings.Join(os.Args, " ")),
|
||||
))
|
||||
|
||||
return ctx, func(err error) {
|
||||
|
@@ -7,18 +7,18 @@ import (
|
||||
|
||||
type Map struct {
|
||||
mu sync.RWMutex
|
||||
m map[string]any
|
||||
m map[string]interface{}
|
||||
ch map[string]chan struct{}
|
||||
}
|
||||
|
||||
func New() *Map {
|
||||
return &Map{
|
||||
m: make(map[string]any),
|
||||
m: make(map[string]interface{}),
|
||||
ch: make(map[string]chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Map) Set(key string, value any) {
|
||||
func (m *Map) Set(key string, value interface{}) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
@@ -32,13 +32,13 @@ func (m *Map) Set(key string, value any) {
|
||||
m.ch[key] = nil
|
||||
}
|
||||
|
||||
func (m *Map) Get(ctx context.Context, keys ...string) (map[string]any, error) {
|
||||
func (m *Map) Get(ctx context.Context, keys ...string) (map[string]interface{}, error) {
|
||||
if len(keys) == 0 {
|
||||
return map[string]any{}, nil
|
||||
return map[string]interface{}{}, nil
|
||||
}
|
||||
|
||||
if len(keys) > 1 {
|
||||
out := make(map[string]any)
|
||||
out := make(map[string]interface{})
|
||||
for _, key := range keys {
|
||||
mm, err := m.Get(ctx, key)
|
||||
if err != nil {
|
||||
@@ -70,5 +70,5 @@ func (m *Map) Get(ctx context.Context, keys ...string) (map[string]any, error) {
|
||||
res := m.m[key]
|
||||
m.mu.Unlock()
|
||||
|
||||
return map[string]any{key: res}, nil
|
||||
return map[string]interface{}{key: res}, nil
|
||||
}
|
||||
|
26
vendor/github.com/compose-spec/compose-go/v2/cli/options.go
generated
vendored
26
vendor/github.com/compose-spec/compose-go/v2/cli/options.go
generated
vendored
@@ -26,7 +26,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/compose-spec/compose-go/v2/consts"
|
||||
"github.com/compose-spec/compose-go/v2/dotenv"
|
||||
@@ -483,27 +482,8 @@ func (o *ProjectOptions) prepare(ctx context.Context) (*types.ConfigDetails, err
|
||||
return configDetails, err
|
||||
}
|
||||
|
||||
isNamed := false
|
||||
if o.Name == "" {
|
||||
type named struct {
|
||||
Name string `yaml:"name,omitempty"`
|
||||
}
|
||||
// if any of the compose file is named, this is equivalent to user passing --project-name
|
||||
for _, cfg := range configDetails.ConfigFiles {
|
||||
var n named
|
||||
err = yaml.Unmarshal(cfg.Content, &n)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n.Name != "" {
|
||||
isNamed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
o.loadOptions = append(o.loadOptions,
|
||||
withNamePrecedenceLoad(defaultDir, isNamed, o),
|
||||
withNamePrecedenceLoad(defaultDir, o),
|
||||
withConvertWindowsPaths(o),
|
||||
withListeners(o))
|
||||
|
||||
@@ -516,13 +496,13 @@ func ProjectFromOptions(ctx context.Context, options *ProjectOptions) (*types.Pr
|
||||
return options.LoadProject(ctx)
|
||||
}
|
||||
|
||||
func withNamePrecedenceLoad(absWorkingDir string, namedInYaml bool, options *ProjectOptions) func(*loader.Options) {
|
||||
func withNamePrecedenceLoad(absWorkingDir string, options *ProjectOptions) func(*loader.Options) {
|
||||
return func(opts *loader.Options) {
|
||||
if options.Name != "" {
|
||||
opts.SetProjectName(options.Name, true)
|
||||
} else if nameFromEnv, ok := options.Environment[consts.ComposeProjectName]; ok && nameFromEnv != "" {
|
||||
opts.SetProjectName(nameFromEnv, true)
|
||||
} else if !namedInYaml {
|
||||
} else {
|
||||
dirname := filepath.Base(absWorkingDir)
|
||||
symlink, err := filepath.EvalSymlinks(absWorkingDir)
|
||||
if err == nil && filepath.Base(symlink) != dirname {
|
||||
|
7
vendor/github.com/compose-spec/compose-go/v2/loader/extends.go
generated
vendored
7
vendor/github.com/compose-spec/compose-go/v2/loader/extends.go
generated
vendored
@@ -27,6 +27,10 @@ import (
|
||||
"github.com/compose-spec/compose-go/v2/types"
|
||||
)
|
||||
|
||||
// as we use another service definition by `extends`, we must exclude attributes which creates dependency to another service
|
||||
// see https://github.com/compose-spec/compose-spec/blob/main/05-services.md#restrictions
|
||||
var exclusions = []string{"depends_on", "volumes_from"}
|
||||
|
||||
func ApplyExtends(ctx context.Context, dict map[string]any, opts *Options, tracker *cycleTracker, post ...PostProcessor) error {
|
||||
a, ok := dict["services"]
|
||||
if !ok {
|
||||
@@ -119,6 +123,9 @@ func applyServiceExtends(ctx context.Context, name string, services map[string]a
|
||||
},
|
||||
})
|
||||
}
|
||||
for _, exclusion := range exclusions {
|
||||
delete(source, exclusion)
|
||||
}
|
||||
merged, err := override.ExtendService(source, service)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
1
vendor/github.com/compose-spec/compose-go/v2/loader/interpolate.go
generated
vendored
1
vendor/github.com/compose-spec/compose-go/v2/loader/interpolate.go
generated
vendored
@@ -64,7 +64,6 @@ var interpolateTypeCastMapping = map[tree.Path]interp.Cast{
|
||||
iPath("networks", tree.PathMatchAll, "external"): toBoolean,
|
||||
iPath("networks", tree.PathMatchAll, "internal"): toBoolean,
|
||||
iPath("networks", tree.PathMatchAll, "attachable"): toBoolean,
|
||||
iPath("networks", tree.PathMatchAll, "enable_ipv4"): toBoolean,
|
||||
iPath("networks", tree.PathMatchAll, "enable_ipv6"): toBoolean,
|
||||
iPath("volumes", tree.PathMatchAll, "external"): toBoolean,
|
||||
iPath("secrets", tree.PathMatchAll, "external"): toBoolean,
|
||||
|
14
vendor/github.com/compose-spec/compose-go/v2/loader/validate.go
generated
vendored
14
vendor/github.com/compose-spec/compose-go/v2/loader/validate.go
generated
vendored
@@ -28,7 +28,7 @@ import (
|
||||
|
||||
// checkConsistency validate a compose model is consistent
|
||||
func checkConsistency(project *types.Project) error {
|
||||
for name, s := range project.Services {
|
||||
for _, s := range project.Services {
|
||||
if s.Build == nil && s.Image == "" {
|
||||
return fmt.Errorf("service %q has neither an image nor a build context specified: %w", s.Name, errdefs.ErrInvalid)
|
||||
}
|
||||
@@ -38,18 +38,6 @@ func checkConsistency(project *types.Project) error {
|
||||
return fmt.Errorf("service %q declares mutualy exclusive dockerfile and dockerfile_inline: %w", s.Name, errdefs.ErrInvalid)
|
||||
}
|
||||
|
||||
for add, c := range s.Build.AdditionalContexts {
|
||||
if target, ok := strings.CutPrefix(c, types.ServicePrefix); ok {
|
||||
t, err := project.GetService(target)
|
||||
if err != nil {
|
||||
return fmt.Errorf("service %q declares unknown service %q as additional contexts %s", name, target, add)
|
||||
}
|
||||
if t.Build == nil {
|
||||
return fmt.Errorf("service %q declares non-buildable service %q as additional contexts %s", name, target, add)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(s.Build.Platforms) > 0 && s.Platform != "" {
|
||||
var found bool
|
||||
for _, platform := range s.Build.Platforms {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user