Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4df08551f | ||
|
|
f581942d7d | ||
|
|
5159571dfc | ||
|
|
86a5c77c2b | ||
|
|
1602b491f9 | ||
|
|
94baaf3c90 | ||
|
|
c5e279f295 | ||
|
|
a0f91eb87e | ||
|
|
cb1812ec6a | ||
|
|
47e4c2576b | ||
|
|
3702e17ed5 | ||
|
|
8b85dbea72 | ||
|
|
afcb118e10 | ||
|
|
cb4fea66e0 | ||
|
|
74fa66b496 | ||
|
|
ff87dd183a | ||
|
|
9f844df9f7 | ||
|
|
bc597e6b5e |
@@ -1,25 +0,0 @@
|
|||||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
|
||||||
// README at: https://github.com/devcontainers/templates/tree/main/src/go
|
|
||||||
{
|
|
||||||
"name": "Go",
|
|
||||||
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
|
||||||
"image": "mcr.microsoft.com/devcontainers/go:1-1.21-bullseye",
|
|
||||||
"features": {
|
|
||||||
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Features to add to the dev container. More info: https://containers.dev/features.
|
|
||||||
// "features": {},
|
|
||||||
|
|
||||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
|
||||||
// "forwardPorts": [],
|
|
||||||
|
|
||||||
// Use 'postCreateCommand' to run commands after the container is created.
|
|
||||||
// "postCreateCommand": "go version",
|
|
||||||
|
|
||||||
// Configure tool-specific properties.
|
|
||||||
// "customizations": {},
|
|
||||||
|
|
||||||
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
|
||||||
// "remoteUser": "root"
|
|
||||||
}
|
|
||||||
21
.github/workflows/build.yml
vendored
21
.github/workflows/build.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
-
|
-
|
||||||
name: Set up QEMU
|
name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v2
|
uses: docker/setup-qemu-action@v2
|
||||||
@@ -66,7 +66,6 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
worker:
|
worker:
|
||||||
- docker
|
- docker
|
||||||
- docker\+containerd # same as docker, but with containerd snapshotter
|
|
||||||
- docker-container
|
- docker-container
|
||||||
- remote
|
- remote
|
||||||
pkg:
|
pkg:
|
||||||
@@ -77,9 +76,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
-
|
-
|
||||||
name: Set up QEMU
|
name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v2
|
uses: docker/setup-qemu-action@v2
|
||||||
@@ -104,8 +101,8 @@ jobs:
|
|||||||
export TEST_REPORT_SUFFIX=-${{ github.job }}-$(echo "${{ matrix.pkg }}-${{ matrix.skip-integration-tests }}-${{ matrix.worker }}" | tr -dc '[:alnum:]-\n\r' | tr '[:upper:]' '[:lower:]')
|
export TEST_REPORT_SUFFIX=-${{ github.job }}-$(echo "${{ matrix.pkg }}-${{ matrix.skip-integration-tests }}-${{ matrix.worker }}" | tr -dc '[:alnum:]-\n\r' | tr '[:upper:]' '[:lower:]')
|
||||||
./hack/test
|
./hack/test
|
||||||
env:
|
env:
|
||||||
TEST_DOCKERD: "${{ startsWith(matrix.worker, 'docker') && '1' || '0' }}"
|
TEST_DOCKERD: "${{ (matrix.worker == 'docker' || matrix.worker == 'docker-container') && '1' || '0' }}"
|
||||||
TESTFLAGS: "${{ (matrix.worker == 'docker' || matrix.worker == 'docker\\+containerd') && env.TESTFLAGS_DOCKER || env.TESTFLAGS }} --run=//worker=${{ matrix.worker }}$"
|
TESTFLAGS: "${{ (matrix.worker == 'docker' || matrix.worker == 'docker-container') && env.TESTFLAGS_DOCKER || env.TESTFLAGS }} --run=//worker=${{ matrix.worker }}$"
|
||||||
TESTPKGS: "${{ matrix.pkg }}"
|
TESTPKGS: "${{ matrix.pkg }}"
|
||||||
SKIP_INTEGRATION_TESTS: "${{ matrix.skip-integration-tests }}"
|
SKIP_INTEGRATION_TESTS: "${{ matrix.skip-integration-tests }}"
|
||||||
-
|
-
|
||||||
@@ -135,7 +132,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
-
|
-
|
||||||
name: Create matrix
|
name: Create matrix
|
||||||
id: platforms
|
id: platforms
|
||||||
@@ -162,7 +159,7 @@ jobs:
|
|||||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
-
|
-
|
||||||
name: Set up QEMU
|
name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v2
|
uses: docker/setup-qemu-action@v2
|
||||||
@@ -197,7 +194,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
-
|
-
|
||||||
name: Set up QEMU
|
name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v2
|
uses: docker/setup-qemu-action@v2
|
||||||
@@ -249,7 +246,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
-
|
-
|
||||||
name: Download binaries
|
name: Download binaries
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v3
|
||||||
@@ -283,7 +280,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
-
|
-
|
||||||
name: Set up QEMU
|
name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v2
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|||||||
4
.github/workflows/docs-release.yml
vendored
4
.github/workflows/docs-release.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout docs repo
|
name: Checkout docs repo
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GHPAT_DOCS_DISPATCH }}
|
token: ${{ secrets.GHPAT_DOCS_DISPATCH }}
|
||||||
repository: docker/docs
|
repository: docker/docs
|
||||||
@@ -44,7 +44,7 @@ jobs:
|
|||||||
git add -A .
|
git add -A .
|
||||||
-
|
-
|
||||||
name: Create PR on docs repo
|
name: Create PR on docs repo
|
||||||
uses: peter-evans/create-pull-request@153407881ec5c347639a548ade7d8ad1d6740e38
|
uses: peter-evans/create-pull-request@284f54f989303d2699d373481a0cfa13ad5a6666
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GHPAT_DOCS_DISPATCH }}
|
token: ${{ secrets.GHPAT_DOCS_DISPATCH }}
|
||||||
push-to-fork: docker-tools-robot/docker.github.io
|
push-to-fork: docker-tools-robot/docker.github.io
|
||||||
|
|||||||
2
.github/workflows/docs-upstream.yml
vendored
2
.github/workflows/docs-upstream.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
-
|
-
|
||||||
name: Set up Docker Buildx
|
name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v2
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|||||||
4
.github/workflows/e2e.yml
vendored
4
.github/workflows/e2e.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
|||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
-
|
-
|
||||||
name: Set up Docker Buildx
|
name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v2
|
uses: docker/setup-buildx-action@v2
|
||||||
@@ -96,7 +96,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
-
|
-
|
||||||
name: Set up QEMU
|
name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v2
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|||||||
2
.github/workflows/validate.yml
vendored
2
.github/workflows/validate.yml
vendored
@@ -30,7 +30,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
-
|
-
|
||||||
name: Set up Docker Buildx
|
name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v2
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
ARG GO_VERSION=1.20.7
|
ARG GO_VERSION=1.20
|
||||||
ARG XX_VERSION=1.2.1
|
ARG XX_VERSION=1.2.1
|
||||||
|
|
||||||
ARG DOCKER_VERSION=24.0.2
|
ARG DOCKER_VERSION=24.0.2
|
||||||
@@ -121,7 +121,7 @@ RUN --mount=from=binaries \
|
|||||||
--mount=type=bind,from=buildx-version,source=/buildx-version,target=/buildx-version <<EOT
|
--mount=type=bind,from=buildx-version,source=/buildx-version,target=/buildx-version <<EOT
|
||||||
set -e
|
set -e
|
||||||
mkdir -p /out
|
mkdir -p /out
|
||||||
cp buildx* "/out/buildx"
|
cp buildx* "/out/buildx-$(cat /buildx-version/version).$(echo $TARGETPLATFORM | sed 's/\//-/g')$(ls buildx* | sed -e 's/^buildx//')"
|
||||||
EOT
|
EOT
|
||||||
|
|
||||||
FROM scratch AS release
|
FROM scratch AS release
|
||||||
|
|||||||
@@ -71,9 +71,8 @@ for Windows and macOS.
|
|||||||
|
|
||||||
## Linux packages
|
## Linux packages
|
||||||
|
|
||||||
Docker Engine package repositories contain Docker Buildx packages when installed according to the
|
Docker Linux packages also include Docker Buildx when installed using the
|
||||||
[Docker Engine install documentation](https://docs.docker.com/engine/install/). Install the
|
[DEB or RPM packages](https://docs.docker.com/engine/install/).
|
||||||
`docker-buildx-plugin` package to install the Buildx plugin.
|
|
||||||
|
|
||||||
## Manual download
|
## Manual download
|
||||||
|
|
||||||
|
|||||||
@@ -587,9 +587,9 @@ type Target struct {
|
|||||||
Name string `json:"-" hcl:"name,label" cty:"name"`
|
Name string `json:"-" hcl:"name,label" cty:"name"`
|
||||||
|
|
||||||
// Inherits is the only field that cannot be overridden with --set
|
// Inherits is the only field that cannot be overridden with --set
|
||||||
|
Attest []string `json:"attest,omitempty" hcl:"attest,optional" cty:"attest"`
|
||||||
Inherits []string `json:"inherits,omitempty" hcl:"inherits,optional" cty:"inherits"`
|
Inherits []string `json:"inherits,omitempty" hcl:"inherits,optional" cty:"inherits"`
|
||||||
|
|
||||||
Attest []string `json:"attest,omitempty" hcl:"attest,optional" cty:"attest"`
|
|
||||||
Context *string `json:"context,omitempty" hcl:"context,optional" cty:"context"`
|
Context *string `json:"context,omitempty" hcl:"context,optional" cty:"context"`
|
||||||
Contexts map[string]string `json:"contexts,omitempty" hcl:"contexts,optional" cty:"contexts"`
|
Contexts map[string]string `json:"contexts,omitempty" hcl:"contexts,optional" cty:"contexts"`
|
||||||
Dockerfile *string `json:"dockerfile,omitempty" hcl:"dockerfile,optional" cty:"dockerfile"`
|
Dockerfile *string `json:"dockerfile,omitempty" hcl:"dockerfile,optional" cty:"dockerfile"`
|
||||||
@@ -1048,12 +1048,12 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
|
|||||||
bi.DockerfileInline = *t.DockerfileInline
|
bi.DockerfileInline = *t.DockerfileInline
|
||||||
}
|
}
|
||||||
updateContext(&bi, inp)
|
updateContext(&bi, inp)
|
||||||
if strings.HasPrefix(bi.ContextPath, "cwd://") {
|
|
||||||
bi.ContextPath = path.Clean(strings.TrimPrefix(bi.ContextPath, "cwd://"))
|
|
||||||
}
|
|
||||||
if !build.IsRemoteURL(bi.ContextPath) && bi.ContextState == nil && !path.IsAbs(bi.DockerfilePath) {
|
if !build.IsRemoteURL(bi.ContextPath) && bi.ContextState == nil && !path.IsAbs(bi.DockerfilePath) {
|
||||||
bi.DockerfilePath = path.Join(bi.ContextPath, bi.DockerfilePath)
|
bi.DockerfilePath = path.Join(bi.ContextPath, bi.DockerfilePath)
|
||||||
}
|
}
|
||||||
|
if strings.HasPrefix(bi.ContextPath, "cwd://") {
|
||||||
|
bi.ContextPath = path.Clean(strings.TrimPrefix(bi.ContextPath, "cwd://"))
|
||||||
|
}
|
||||||
for k, v := range bi.NamedContexts {
|
for k, v := range bi.NamedContexts {
|
||||||
if strings.HasPrefix(v.Path, "cwd://") {
|
if strings.HasPrefix(v.Path, "cwd://") {
|
||||||
bi.NamedContexts[k] = build.NamedContext{Path: path.Clean(strings.TrimPrefix(v.Path, "cwd://"))}
|
bi.NamedContexts[k] = build.NamedContext{Path: path.Clean(strings.TrimPrefix(v.Path, "cwd://"))}
|
||||||
|
|||||||
@@ -295,9 +295,6 @@ services:
|
|||||||
|
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
|
|
||||||
cwd, err := os.Getwd()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
m, g, err := ReadTargets(ctx, []File{fp, fp2, fp3}, []string{"default"}, nil, nil)
|
m, g, err := ReadTargets(ctx, []File{fp, fp2, fp3}, []string{"default"}, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -306,7 +303,7 @@ services:
|
|||||||
|
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
require.Equal(t, "Dockerfile.webapp", *m["webapp"].Dockerfile)
|
require.Equal(t, "Dockerfile.webapp", *m["webapp"].Dockerfile)
|
||||||
require.Equal(t, cwd, *m["webapp"].Context)
|
require.Equal(t, ".", *m["webapp"].Context)
|
||||||
require.Equal(t, ptrstr("1"), m["webapp"].Args["buildno"])
|
require.Equal(t, ptrstr("1"), m["webapp"].Args["buildno"])
|
||||||
require.Equal(t, ptrstr("12"), m["webapp"].Args["buildno2"])
|
require.Equal(t, ptrstr("12"), m["webapp"].Args["buildno2"])
|
||||||
|
|
||||||
@@ -345,9 +342,6 @@ services:
|
|||||||
|
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
|
|
||||||
cwd, err := os.Getwd()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
m, _, err := ReadTargets(ctx, []File{fp}, []string{"web.app"}, nil, nil)
|
m, _, err := ReadTargets(ctx, []File{fp}, []string{"web.app"}, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 1, len(m))
|
require.Equal(t, 1, len(m))
|
||||||
@@ -370,7 +364,7 @@ services:
|
|||||||
_, ok = m["web_app"]
|
_, ok = m["web_app"]
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
require.Equal(t, "Dockerfile.webapp", *m["web_app"].Dockerfile)
|
require.Equal(t, "Dockerfile.webapp", *m["web_app"].Dockerfile)
|
||||||
require.Equal(t, cwd, *m["web_app"].Context)
|
require.Equal(t, ".", *m["web_app"].Context)
|
||||||
require.Equal(t, ptrstr("1"), m["web_app"].Args["buildno"])
|
require.Equal(t, ptrstr("1"), m["web_app"].Args["buildno"])
|
||||||
require.Equal(t, ptrstr("12"), m["web_app"].Args["buildno2"])
|
require.Equal(t, ptrstr("12"), m["web_app"].Args["buildno2"])
|
||||||
|
|
||||||
@@ -392,19 +386,18 @@ func TestHCLCwdPrefix(t *testing.T) {
|
|||||||
m, g, err := ReadTargets(ctx, []File{fp}, []string{"app"}, nil, nil)
|
m, g, err := ReadTargets(ctx, []File{fp}, []string{"app"}, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
bo, err := TargetsToBuildOpt(m, &Input{})
|
require.Equal(t, 1, len(m))
|
||||||
|
_, ok := m["app"]
|
||||||
|
require.True(t, ok)
|
||||||
|
|
||||||
|
_, err = TargetsToBuildOpt(m, &Input{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Equal(t, 1, len(g))
|
|
||||||
require.Equal(t, []string{"app"}, g["default"].Targets)
|
|
||||||
|
|
||||||
require.Equal(t, 1, len(m))
|
|
||||||
require.Contains(t, m, "app")
|
|
||||||
require.Equal(t, "test", *m["app"].Dockerfile)
|
require.Equal(t, "test", *m["app"].Dockerfile)
|
||||||
require.Equal(t, "foo", *m["app"].Context)
|
require.Equal(t, "foo", *m["app"].Context)
|
||||||
|
|
||||||
require.Equal(t, "foo/test", bo["app"].Inputs.DockerfilePath)
|
require.Equal(t, 1, len(g))
|
||||||
require.Equal(t, "foo", bo["app"].Inputs.ContextPath)
|
require.Equal(t, []string{"app"}, g["default"].Targets)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOverrideMerge(t *testing.T) {
|
func TestOverrideMerge(t *testing.T) {
|
||||||
@@ -549,9 +542,6 @@ services:
|
|||||||
|
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
|
|
||||||
cwd, err := os.Getwd()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
m, _, err := ReadTargets(ctx, []File{fp, fp2}, []string{"app1", "app2"}, nil, nil)
|
m, _, err := ReadTargets(ctx, []File{fp, fp2}, []string{"app1", "app2"}, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -564,7 +554,7 @@ services:
|
|||||||
require.Equal(t, "Dockerfile", *m["app1"].Dockerfile)
|
require.Equal(t, "Dockerfile", *m["app1"].Dockerfile)
|
||||||
require.Equal(t, ".", *m["app1"].Context)
|
require.Equal(t, ".", *m["app1"].Context)
|
||||||
require.Equal(t, "Dockerfile", *m["app2"].Dockerfile)
|
require.Equal(t, "Dockerfile", *m["app2"].Dockerfile)
|
||||||
require.Equal(t, cwd, *m["app2"].Context)
|
require.Equal(t, ".", *m["app2"].Context)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadContextFromTargetChain(t *testing.T) {
|
func TestReadContextFromTargetChain(t *testing.T) {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: ./dir
|
context: ./dir
|
||||||
additional_contexts:
|
additional_contexts:
|
||||||
foo: ./bar
|
foo: /bar
|
||||||
dockerfile: Dockerfile-alternate
|
dockerfile: Dockerfile-alternate
|
||||||
network:
|
network:
|
||||||
none
|
none
|
||||||
@@ -49,9 +49,6 @@ secrets:
|
|||||||
file: /root/.aws/credentials
|
file: /root/.aws/credentials
|
||||||
`)
|
`)
|
||||||
|
|
||||||
cwd, err := os.Getwd()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
|
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -65,12 +62,12 @@ secrets:
|
|||||||
return c.Targets[i].Name < c.Targets[j].Name
|
return c.Targets[i].Name < c.Targets[j].Name
|
||||||
})
|
})
|
||||||
require.Equal(t, "db", c.Targets[0].Name)
|
require.Equal(t, "db", c.Targets[0].Name)
|
||||||
require.Equal(t, filepath.Join(cwd, "db"), *c.Targets[0].Context)
|
require.Equal(t, "./db", *c.Targets[0].Context)
|
||||||
require.Equal(t, []string{"docker.io/tonistiigi/db"}, c.Targets[0].Tags)
|
require.Equal(t, []string{"docker.io/tonistiigi/db"}, c.Targets[0].Tags)
|
||||||
|
|
||||||
require.Equal(t, "webapp", c.Targets[1].Name)
|
require.Equal(t, "webapp", c.Targets[1].Name)
|
||||||
require.Equal(t, filepath.Join(cwd, "dir"), *c.Targets[1].Context)
|
require.Equal(t, "./dir", *c.Targets[1].Context)
|
||||||
require.Equal(t, map[string]string{"foo": filepath.Join(cwd, "bar")}, c.Targets[1].Contexts)
|
require.Equal(t, map[string]string{"foo": "/bar"}, c.Targets[1].Contexts)
|
||||||
require.Equal(t, "Dockerfile-alternate", *c.Targets[1].Dockerfile)
|
require.Equal(t, "Dockerfile-alternate", *c.Targets[1].Dockerfile)
|
||||||
require.Equal(t, 1, len(c.Targets[1].Args))
|
require.Equal(t, 1, len(c.Targets[1].Args))
|
||||||
require.Equal(t, ptrstr("123"), c.Targets[1].Args["buildno"])
|
require.Equal(t, ptrstr("123"), c.Targets[1].Args["buildno"])
|
||||||
@@ -83,7 +80,7 @@ secrets:
|
|||||||
}, c.Targets[1].Secrets)
|
}, c.Targets[1].Secrets)
|
||||||
|
|
||||||
require.Equal(t, "webapp2", c.Targets[2].Name)
|
require.Equal(t, "webapp2", c.Targets[2].Name)
|
||||||
require.Equal(t, filepath.Join(cwd, "dir"), *c.Targets[2].Context)
|
require.Equal(t, "./dir", *c.Targets[2].Context)
|
||||||
require.Equal(t, "FROM alpine\n", *c.Targets[2].DockerfileInline)
|
require.Equal(t, "FROM alpine\n", *c.Targets[2].DockerfileInline)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -659,66 +656,6 @@ services:
|
|||||||
require.Equal(t, map[string]*string{"bar": ptrstr("baz")}, c.Targets[0].Args)
|
require.Equal(t, map[string]*string{"bar": ptrstr("baz")}, c.Targets[0].Args)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDependsOn(t *testing.T) {
|
|
||||||
var dt = []byte(`
|
|
||||||
services:
|
|
||||||
foo:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
ports:
|
|
||||||
- 3306:3306
|
|
||||||
depends_on:
|
|
||||||
- bar
|
|
||||||
bar:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
`)
|
|
||||||
_, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInclude(t *testing.T) {
|
|
||||||
tmpdir := t.TempDir()
|
|
||||||
|
|
||||||
err := os.WriteFile(filepath.Join(tmpdir, "compose-foo.yml"), []byte(`
|
|
||||||
services:
|
|
||||||
foo:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
target: buildfoo
|
|
||||||
ports:
|
|
||||||
- 3306:3306
|
|
||||||
`), 0644)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
var dt = []byte(`
|
|
||||||
include:
|
|
||||||
- compose-foo.yml
|
|
||||||
|
|
||||||
services:
|
|
||||||
bar:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
target: buildbar
|
|
||||||
`)
|
|
||||||
|
|
||||||
chdir(t, tmpdir)
|
|
||||||
c, err := ParseComposeFiles([]File{{
|
|
||||||
Name: "compose.yml",
|
|
||||||
Data: dt,
|
|
||||||
}})
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
require.Equal(t, 2, len(c.Targets))
|
|
||||||
sort.Slice(c.Targets, func(i, j int) bool {
|
|
||||||
return c.Targets[i].Name < c.Targets[j].Name
|
|
||||||
})
|
|
||||||
require.Equal(t, "bar", c.Targets[0].Name)
|
|
||||||
require.Equal(t, "buildbar", *c.Targets[0].Target)
|
|
||||||
require.Equal(t, "foo", c.Targets[1].Name)
|
|
||||||
require.Equal(t, "buildfoo", *c.Targets[1].Target)
|
|
||||||
}
|
|
||||||
|
|
||||||
// chdir changes the current working directory to the named directory,
|
// chdir changes the current working directory to the named directory,
|
||||||
// and then restore the original working directory at the end of the test.
|
// and then restore the original working directory at the end of the test.
|
||||||
func chdir(t *testing.T, dir string) {
|
func chdir(t *testing.T, dir string) {
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ func ReadRemoteFiles(ctx context.Context, nodes []builder.Node, url string, name
|
|||||||
|
|
||||||
ch, done := progress.NewChannel(pw)
|
ch, done := progress.NewChannel(pw)
|
||||||
defer func() { <-done }()
|
defer func() { <-done }()
|
||||||
_, err = c.Build(ctx, client.SolveOpt{Session: session, Internal: true}, "buildx", func(ctx context.Context, c gwclient.Client) (*gwclient.Result, error) {
|
_, err = c.Build(ctx, client.SolveOpt{Session: session}, "buildx", func(ctx context.Context, c gwclient.Client) (*gwclient.Result, error) {
|
||||||
def, err := st.Marshal(ctx)
|
def, err := st.Marshal(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -267,11 +267,11 @@ func resolveDriversBase(ctx context.Context, nodes []builder.Node, opt map[strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
undetectedPlatform := false
|
undetectedPlatform := false
|
||||||
allPlatforms := map[string]struct{}{}
|
allPlatforms := map[string]int{}
|
||||||
for _, opt := range opt {
|
for _, opt := range opt {
|
||||||
for _, p := range opt.Platforms {
|
for _, p := range opt.Platforms {
|
||||||
k := platforms.Format(p)
|
k := platforms.Format(p)
|
||||||
allPlatforms[k] = struct{}{}
|
allPlatforms[k] = -1
|
||||||
if _, ok := availablePlatforms[k]; !ok {
|
if _, ok := availablePlatforms[k]; !ok {
|
||||||
undetectedPlatform = true
|
undetectedPlatform = true
|
||||||
}
|
}
|
||||||
@@ -454,7 +454,7 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op
|
|||||||
attests[k] = *v
|
attests[k] = *v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
supportsAttestations := bopts.LLBCaps.Contains(apicaps.CapID("exporter.image.attestations")) && nodeDriver.Features(ctx)[driver.MultiPlatform]
|
supportsAttestations := bopts.LLBCaps.Contains(apicaps.CapID("exporter.image.attestations"))
|
||||||
if len(attests) > 0 {
|
if len(attests) > 0 {
|
||||||
if !supportsAttestations {
|
if !supportsAttestations {
|
||||||
return nil, nil, errors.Errorf("attestations are not supported by the current buildkitd")
|
return nil, nil, errors.Errorf("attestations are not supported by the current buildkitd")
|
||||||
@@ -593,10 +593,7 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op
|
|||||||
}
|
}
|
||||||
|
|
||||||
if opt.Pull {
|
if opt.Pull {
|
||||||
so.FrontendAttrs["image-resolve-mode"] = pb.AttrImageResolveModeForcePull
|
so.FrontendAttrs["image-resolve-mode"] = "pull"
|
||||||
} else if nodeDriver.IsMobyDriver() {
|
|
||||||
// moby driver always resolves local images by default
|
|
||||||
so.FrontendAttrs["image-resolve-mode"] = pb.AttrImageResolveModePreferLocal
|
|
||||||
}
|
}
|
||||||
if opt.Target != "" {
|
if opt.Target != "" {
|
||||||
so.FrontendAttrs["target"] = opt.Target
|
so.FrontendAttrs["target"] = opt.Target
|
||||||
@@ -737,7 +734,7 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
|
|||||||
hasMobyDriver := false
|
hasMobyDriver := false
|
||||||
gitattrs, err := getGitAttributes(ctx, opt.Inputs.ContextPath, opt.Inputs.DockerfilePath)
|
gitattrs, err := getGitAttributes(ctx, opt.Inputs.ContextPath, opt.Inputs.DockerfilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).Warn("current commit information was not captured by the build")
|
logrus.Warn(err)
|
||||||
}
|
}
|
||||||
for i, np := range m[k] {
|
for i, np := range m[k] {
|
||||||
node := nodes[np.driverIndex]
|
node := nodes[np.driverIndex]
|
||||||
@@ -1101,7 +1098,7 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dt, desc, err := itpull.Combine(ctx, srcs, nil)
|
dt, desc, err := itpull.Combine(ctx, srcs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
10
build/git.go
10
build/git.go
@@ -51,21 +51,21 @@ func getGitAttributes(ctx context.Context, contextPath string, dockerfilePath st
|
|||||||
|
|
||||||
gitc, err := gitutil.New(gitutil.WithContext(ctx), gitutil.WithWorkingDir(wd))
|
gitc, err := gitutil.New(gitutil.WithContext(ctx), gitutil.WithWorkingDir(wd))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if st, err1 := os.Stat(path.Join(wd, ".git")); err1 == nil && st.IsDir() {
|
if st, err := os.Stat(path.Join(wd, ".git")); err == nil && st.IsDir() {
|
||||||
return res, errors.Wrap(err, "git was not found in the system")
|
return res, errors.New("buildx: git was not found in the system. Current commit information was not captured by the build")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !gitc.IsInsideWorkTree() {
|
if !gitc.IsInsideWorkTree() {
|
||||||
if st, err := os.Stat(path.Join(wd, ".git")); err == nil && st.IsDir() {
|
if st, err := os.Stat(path.Join(wd, ".git")); err == nil && st.IsDir() {
|
||||||
return res, errors.New("failed to read current commit information with git rev-parse --is-inside-work-tree")
|
return res, errors.New("buildx: failed to read current commit information with git rev-parse --is-inside-work-tree")
|
||||||
}
|
}
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if sha, err := gitc.FullCommit(); err != nil && !gitutil.IsUnknownRevision(err) {
|
if sha, err := gitc.FullCommit(); err != nil && !gitutil.IsUnknownRevision(err) {
|
||||||
return res, errors.Wrap(err, "failed to get git commit")
|
return res, errors.Wrapf(err, "buildx: failed to get git commit")
|
||||||
} else if sha != "" {
|
} else if sha != "" {
|
||||||
checkDirty := false
|
checkDirty := false
|
||||||
if v, ok := os.LookupEnv("BUILDX_GIT_CHECK_DIRTY"); ok {
|
if v, ok := os.LookupEnv("BUILDX_GIT_CHECK_DIRTY"); ok {
|
||||||
@@ -95,7 +95,7 @@ func getGitAttributes(ctx context.Context, contextPath string, dockerfilePath st
|
|||||||
|
|
||||||
if setGitLabels {
|
if setGitLabels {
|
||||||
if root, err := gitc.RootDir(); err != nil {
|
if root, err := gitc.RootDir(); err != nil {
|
||||||
return res, errors.Wrap(err, "failed to get git root dir")
|
return res, errors.Wrapf(err, "buildx: failed to get git root dir")
|
||||||
} else if root != "" {
|
} else if root != "" {
|
||||||
if dockerfilePath == "" {
|
if dockerfilePath == "" {
|
||||||
dockerfilePath = filepath.Join(wd, "Dockerfile")
|
dockerfilePath = filepath.Join(wd, "Dockerfile")
|
||||||
|
|||||||
@@ -160,7 +160,6 @@ func NewResultHandle(ctx context.Context, cc *client.Client, opt client.SolveOpt
|
|||||||
opt.Ref = ""
|
opt.Ref = ""
|
||||||
opt.Exports = nil
|
opt.Exports = nil
|
||||||
opt.CacheExports = nil
|
opt.CacheExports = nil
|
||||||
opt.Internal = true
|
|
||||||
_, respErr = cc.Build(ctx, opt, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
|
_, respErr = cc.Build(ctx, opt, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
|
||||||
res, err := evalDefinition(ctx, c, def)
|
res, err := evalDefinition(ctx, c, def)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -388,7 +387,7 @@ func populateProcessConfigFromResult(req *gateway.StartRequest, res *gateway.Res
|
|||||||
} else if img != nil {
|
} else if img != nil {
|
||||||
args = append(args, img.Config.Entrypoint...)
|
args = append(args, img.Config.Entrypoint...)
|
||||||
}
|
}
|
||||||
if !cfg.NoCmd {
|
if cfg.Cmd != nil {
|
||||||
args = append(args, cfg.Cmd...)
|
args = append(args, cfg.Cmd...)
|
||||||
} else if img != nil {
|
} else if img != nil {
|
||||||
args = append(args, img.Config.Cmd...)
|
args = append(args, img.Config.Cmd...)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func createTempDockerfileFromURL(ctx context.Context, d *driver.DriverHandle, ur
|
|||||||
var out string
|
var out string
|
||||||
ch, done := progress.NewChannel(pw)
|
ch, done := progress.NewChannel(pw)
|
||||||
defer func() { <-done }()
|
defer func() { <-done }()
|
||||||
_, err = c.Build(ctx, client.SolveOpt{Internal: true}, "buildx", func(ctx context.Context, c gwclient.Client) (*gwclient.Result, error) {
|
_, err = c.Build(ctx, client.SolveOpt{}, "buildx", func(ctx context.Context, c gwclient.Client) (*gwclient.Result, error) {
|
||||||
def, err := llb.HTTP(url, llb.Filename("Dockerfile"), llb.WithCustomNamef("[internal] load %s", url)).Marshal(ctx)
|
def, err := llb.HTTP(url, llb.Filename("Dockerfile"), llb.WithCustomNamef("[internal] load %s", url)).Marshal(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -82,12 +82,12 @@ func (b *Builder) LoadNodes(ctx context.Context, withData bool) (_ []Node, err e
|
|||||||
contextStore := b.opts.dockerCli.ContextStore()
|
contextStore := b.opts.dockerCli.ContextStore()
|
||||||
|
|
||||||
var kcc driver.KubeClientConfig
|
var kcc driver.KubeClientConfig
|
||||||
kcc, err = ctxkube.ConfigFromEndpoint(n.Endpoint, contextStore)
|
kcc, err = ctxkube.ConfigFromContext(n.Endpoint, contextStore)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// err is returned if n.Endpoint is non-context name like "unix:///var/run/docker.sock".
|
// err is returned if n.Endpoint is non-context name like "unix:///var/run/docker.sock".
|
||||||
// try again with name="default".
|
// try again with name="default".
|
||||||
// FIXME(@AkihiroSuda): n should retain real context name.
|
// FIXME(@AkihiroSuda): n should retain real context name.
|
||||||
kcc, err = ctxkube.ConfigFromEndpoint("default", contextStore)
|
kcc, err = ctxkube.ConfigFromContext("default", contextStore)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Error(err)
|
logrus.Error(err)
|
||||||
}
|
}
|
||||||
@@ -109,7 +109,7 @@ func (b *Builder) LoadNodes(ctx context.Context, withData bool) (_ []Node, err e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d, err := driver.GetDriver(ctx, "buildx_buildkit_"+n.Name, factory, n.Endpoint, dockerapi, imageopt.Auth, kcc, n.Flags, n.Files, n.DriverOpts, n.SecurityOpts, n.Platforms, b.opts.contextPathHash)
|
d, err := driver.GetDriver(ctx, "buildx_buildkit_"+n.Name, factory, n.Endpoint, dockerapi, imageopt.Auth, kcc, n.Flags, n.Files, n.DriverOpts, n.Platforms, b.opts.contextPathHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
node.Err = err
|
node.Err = err
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -464,7 +464,7 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
|
|||||||
|
|
||||||
flags.StringArrayVar(&options.cacheTo, "cache-to", []string{}, `Cache export destinations (e.g., "user/app:cache", "type=local,dest=path/to/dir")`)
|
flags.StringArrayVar(&options.cacheTo, "cache-to", []string{}, `Cache export destinations (e.g., "user/app:cache", "type=local,dest=path/to/dir")`)
|
||||||
|
|
||||||
flags.StringVar(&options.cgroupParent, "cgroup-parent", "", `Set the parent cgroup for the "RUN" instructions during build`)
|
flags.StringVar(&options.cgroupParent, "cgroup-parent", "", "Optional parent cgroup for the container")
|
||||||
flags.SetAnnotation("cgroup-parent", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#cgroup-parent"})
|
flags.SetAnnotation("cgroup-parent", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#cgroup-parent"})
|
||||||
|
|
||||||
flags.StringArrayVar(&options.contexts, "build-context", []string{}, "Additional build contexts (e.g., name=path)")
|
flags.StringArrayVar(&options.contexts, "build-context", []string{}, "Additional build contexts (e.g., name=path)")
|
||||||
@@ -698,7 +698,6 @@ func (cfg *invokeConfig) needsMonitor(retErr error) bool {
|
|||||||
func parseInvokeConfig(invoke string) (cfg invokeConfig, err error) {
|
func parseInvokeConfig(invoke string) (cfg invokeConfig, err error) {
|
||||||
cfg.invokeFlag = invoke
|
cfg.invokeFlag = invoke
|
||||||
cfg.Tty = true
|
cfg.Tty = true
|
||||||
cfg.NoCmd = true
|
|
||||||
switch invoke {
|
switch invoke {
|
||||||
case "default", "debug-shell":
|
case "default", "debug-shell":
|
||||||
return cfg, nil
|
return cfg, nil
|
||||||
@@ -707,7 +706,6 @@ func parseInvokeConfig(invoke string) (cfg invokeConfig, err error) {
|
|||||||
// TODO: make this configurable via flags or restorable from LLB.
|
// TODO: make this configurable via flags or restorable from LLB.
|
||||||
// Discussion: https://github.com/docker/buildx/pull/1640#discussion_r1113295900
|
// Discussion: https://github.com/docker/buildx/pull/1640#discussion_r1113295900
|
||||||
cfg.Cmd = []string{"/bin/sh"}
|
cfg.Cmd = []string{"/bin/sh"}
|
||||||
cfg.NoCmd = false
|
|
||||||
return cfg, nil
|
return cfg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -719,7 +717,6 @@ func parseInvokeConfig(invoke string) (cfg invokeConfig, err error) {
|
|||||||
}
|
}
|
||||||
if len(fields) == 1 && !strings.Contains(fields[0], "=") {
|
if len(fields) == 1 && !strings.Contains(fields[0], "=") {
|
||||||
cfg.Cmd = []string{fields[0]}
|
cfg.Cmd = []string{fields[0]}
|
||||||
cfg.NoCmd = false
|
|
||||||
return cfg, nil
|
return cfg, nil
|
||||||
}
|
}
|
||||||
cfg.NoUser = true
|
cfg.NoUser = true
|
||||||
@@ -734,12 +731,10 @@ func parseInvokeConfig(invoke string) (cfg invokeConfig, err error) {
|
|||||||
switch key {
|
switch key {
|
||||||
case "args":
|
case "args":
|
||||||
cfg.Cmd = append(cfg.Cmd, maybeJSONArray(value)...)
|
cfg.Cmd = append(cfg.Cmd, maybeJSONArray(value)...)
|
||||||
cfg.NoCmd = false
|
|
||||||
case "entrypoint":
|
case "entrypoint":
|
||||||
cfg.Entrypoint = append(cfg.Entrypoint, maybeJSONArray(value)...)
|
cfg.Entrypoint = append(cfg.Entrypoint, maybeJSONArray(value)...)
|
||||||
if cfg.Cmd == nil {
|
if cfg.Cmd == nil {
|
||||||
cfg.Cmd = []string{}
|
cfg.Cmd = []string{}
|
||||||
cfg.NoCmd = false
|
|
||||||
}
|
}
|
||||||
case "env":
|
case "env":
|
||||||
cfg.Env = append(cfg.Env, maybeJSONArray(value)...)
|
cfg.Env = append(cfg.Env, maybeJSONArray(value)...)
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ type createOptions struct {
|
|||||||
flags string
|
flags string
|
||||||
configFile string
|
configFile string
|
||||||
driverOpts []string
|
driverOpts []string
|
||||||
securityOpts []string
|
|
||||||
bootstrap bool
|
bootstrap bool
|
||||||
// upgrade bool // perform upgrade of the driver
|
// upgrade bool // perform upgrade of the driver
|
||||||
}
|
}
|
||||||
@@ -240,11 +239,6 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := csvToMap(in.securityOpts)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if in.configFile == "" {
|
if in.configFile == "" {
|
||||||
// if buildkit config is not provided, check if the default one is
|
// if buildkit config is not provided, check if the default one is
|
||||||
// available and use it
|
// available and use it
|
||||||
@@ -254,7 +248,7 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ng.Update(in.nodeName, ep, in.platform, setEp, in.actionAppend, flags, in.configFile, m, s); err != nil {
|
if err := ng.Update(in.nodeName, ep, in.platform, setEp, in.actionAppend, flags, in.configFile, m); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,7 +340,6 @@ func createCmd(dockerCli command.Cli) *cobra.Command {
|
|||||||
flags.StringVar(&options.configFile, "config", "", "BuildKit config file")
|
flags.StringVar(&options.configFile, "config", "", "BuildKit config file")
|
||||||
flags.StringArrayVar(&options.platform, "platform", []string{}, "Fixed platforms for current node")
|
flags.StringArrayVar(&options.platform, "platform", []string{}, "Fixed platforms for current node")
|
||||||
flags.StringArrayVar(&options.driverOpts, "driver-opt", []string{}, "Options for the driver")
|
flags.StringArrayVar(&options.driverOpts, "driver-opt", []string{}, "Options for the driver")
|
||||||
flags.StringArrayVar(&options.securityOpts, "security-opt", []string{}, "Options for the security profile of driver")
|
|
||||||
flags.BoolVar(&options.bootstrap, "bootstrap", false, "Boot builder after creation")
|
flags.BoolVar(&options.bootstrap, "bootstrap", false, "Boot builder after creation")
|
||||||
|
|
||||||
flags.BoolVar(&options.actionAppend, "append", false, "Append a node to builder instead of changing it")
|
flags.BoolVar(&options.actionAppend, "append", false, "Append a node to builder instead of changing it")
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ type createOptions struct {
|
|||||||
builder string
|
builder string
|
||||||
files []string
|
files []string
|
||||||
tags []string
|
tags []string
|
||||||
annotations []string
|
|
||||||
dryrun bool
|
dryrun bool
|
||||||
actionAppend bool
|
actionAppend bool
|
||||||
progress string
|
progress string
|
||||||
@@ -83,11 +82,6 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
|
|||||||
return errors.Errorf("no repositories specified, please set a reference in tag or source")
|
return errors.Errorf("no repositories specified, please set a reference in tag or source")
|
||||||
}
|
}
|
||||||
|
|
||||||
ann, err := parseAnnotations(in.annotations)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultRepo *string
|
var defaultRepo *string
|
||||||
if len(repos) == 1 {
|
if len(repos) == 1 {
|
||||||
for repo := range repos {
|
for repo := range repos {
|
||||||
@@ -160,7 +154,7 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dt, desc, err := r.Combine(ctx, srcs, ann)
|
dt, desc, err := r.Combine(ctx, srcs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -270,18 +264,6 @@ func parseSource(in string) (*imagetools.Source, error) {
|
|||||||
return &s, nil
|
return &s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseAnnotations(in []string) (map[string]string, error) {
|
|
||||||
out := make(map[string]string)
|
|
||||||
for _, i := range in {
|
|
||||||
kv := strings.SplitN(i, "=", 2)
|
|
||||||
if len(kv) != 2 {
|
|
||||||
return nil, errors.Errorf("invalid annotation %q, expected key=value", in)
|
|
||||||
}
|
|
||||||
out[kv[0]] = kv[1]
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func createCmd(dockerCli command.Cli, opts RootOptions) *cobra.Command {
|
func createCmd(dockerCli command.Cli, opts RootOptions) *cobra.Command {
|
||||||
var options createOptions
|
var options createOptions
|
||||||
|
|
||||||
@@ -301,7 +283,6 @@ func createCmd(dockerCli command.Cli, opts RootOptions) *cobra.Command {
|
|||||||
flags.BoolVar(&options.dryrun, "dry-run", false, "Show final image instead of pushing")
|
flags.BoolVar(&options.dryrun, "dry-run", false, "Show final image instead of pushing")
|
||||||
flags.BoolVar(&options.actionAppend, "append", false, "Append to existing manifest")
|
flags.BoolVar(&options.actionAppend, "append", false, "Append to existing manifest")
|
||||||
flags.StringVar(&options.progress, "progress", "auto", `Set type of progress output ("auto", "plain", "tty"). Use plain to show container output`)
|
flags.StringVar(&options.progress, "progress", "auto", `Set type of progress output ("auto", "plain", "tty"). Use plain to show container output`)
|
||||||
flags.StringArrayVarP(&options.annotations, "annotation", "", []string{}, "Add annotation to the image")
|
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,13 +82,6 @@ func runInspect(dockerCli command.Cli, in inspectOptions) error {
|
|||||||
if len(driverOpts) > 0 {
|
if len(driverOpts) > 0 {
|
||||||
fmt.Fprintf(w, "Driver Options:\t%s\n", strings.Join(driverOpts, " "))
|
fmt.Fprintf(w, "Driver Options:\t%s\n", strings.Join(driverOpts, " "))
|
||||||
}
|
}
|
||||||
var securityOpts []string
|
|
||||||
for k, v := range n.SecurityOpts {
|
|
||||||
securityOpts = append(securityOpts, fmt.Sprintf("%s=%q", k, v))
|
|
||||||
}
|
|
||||||
if len(securityOpts) > 0 {
|
|
||||||
fmt.Fprintf(w, "Security Options:\t%s\n", strings.Join(driverOpts, " "))
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := n.Err; err != nil {
|
if err := n.Err; err != nil {
|
||||||
fmt.Fprintf(w, "Error:\t%s\n", err.Error())
|
fmt.Fprintf(w, "Error:\t%s\n", err.Error())
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import (
|
|||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli-plugins/plugin"
|
"github.com/docker/cli/cli-plugins/plugin"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/debug"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
@@ -41,11 +40,6 @@ func NewRootCmd(name string, isPlugin bool, dockerCli command.Cli) *cobra.Comman
|
|||||||
cmd.TraverseChildren = true
|
cmd.TraverseChildren = true
|
||||||
cmd.DisableFlagsInUseLine = true
|
cmd.DisableFlagsInUseLine = true
|
||||||
cli.DisableFlagsInUseLine(cmd)
|
cli.DisableFlagsInUseLine(cmd)
|
||||||
|
|
||||||
// DEBUG=1 should perform the same as --debug at the docker root level
|
|
||||||
if debug.IsEnabled() {
|
|
||||||
debug.Enable()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.SetFormatter(&logutil.Formatter{})
|
logrus.SetFormatter(&logutil.Formatter{})
|
||||||
@@ -58,6 +52,17 @@ func NewRootCmd(name string, isPlugin bool, dockerCli command.Cli) *cobra.Comman
|
|||||||
"using default config store",
|
"using default config store",
|
||||||
))
|
))
|
||||||
|
|
||||||
|
// filter out useless commandConn.CloseWrite warning message that can occur
|
||||||
|
// when listing builder instances with "buildx ls" for those that are
|
||||||
|
// unreachable: "commandConn.CloseWrite: commandconn: failed to wait: signal: killed"
|
||||||
|
// https://github.com/docker/cli/blob/3fb4fb83dfb5db0c0753a8316f21aea54dab32c5/cli/connhelper/commandconn/commandconn.go#L203-L214
|
||||||
|
logrus.AddHook(logutil.NewFilter([]logrus.Level{
|
||||||
|
logrus.WarnLevel,
|
||||||
|
},
|
||||||
|
"commandConn.CloseWrite:",
|
||||||
|
"commandConn.CloseRead:",
|
||||||
|
))
|
||||||
|
|
||||||
addCommands(cmd, dockerCli)
|
addCommands(cmd, dockerCli)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1527,7 +1527,6 @@ func (m *InitMessage) GetInvokeConfig() *InvokeConfig {
|
|||||||
type InvokeConfig struct {
|
type InvokeConfig struct {
|
||||||
Entrypoint []string `protobuf:"bytes,1,rep,name=Entrypoint,proto3" json:"Entrypoint,omitempty"`
|
Entrypoint []string `protobuf:"bytes,1,rep,name=Entrypoint,proto3" json:"Entrypoint,omitempty"`
|
||||||
Cmd []string `protobuf:"bytes,2,rep,name=Cmd,proto3" json:"Cmd,omitempty"`
|
Cmd []string `protobuf:"bytes,2,rep,name=Cmd,proto3" json:"Cmd,omitempty"`
|
||||||
NoCmd bool `protobuf:"varint,11,opt,name=NoCmd,proto3" json:"NoCmd,omitempty"`
|
|
||||||
Env []string `protobuf:"bytes,3,rep,name=Env,proto3" json:"Env,omitempty"`
|
Env []string `protobuf:"bytes,3,rep,name=Env,proto3" json:"Env,omitempty"`
|
||||||
User string `protobuf:"bytes,4,opt,name=User,proto3" json:"User,omitempty"`
|
User string `protobuf:"bytes,4,opt,name=User,proto3" json:"User,omitempty"`
|
||||||
NoUser bool `protobuf:"varint,5,opt,name=NoUser,proto3" json:"NoUser,omitempty"`
|
NoUser bool `protobuf:"varint,5,opt,name=NoUser,proto3" json:"NoUser,omitempty"`
|
||||||
@@ -1579,13 +1578,6 @@ func (m *InvokeConfig) GetCmd() []string {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *InvokeConfig) GetNoCmd() bool {
|
|
||||||
if m != nil {
|
|
||||||
return m.NoCmd
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *InvokeConfig) GetEnv() []string {
|
func (m *InvokeConfig) GetEnv() []string {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.Env
|
return m.Env
|
||||||
@@ -2054,126 +2046,125 @@ func init() {
|
|||||||
func init() { proto.RegisterFile("controller.proto", fileDescriptor_ed7f10298fa1d90f) }
|
func init() { proto.RegisterFile("controller.proto", fileDescriptor_ed7f10298fa1d90f) }
|
||||||
|
|
||||||
var fileDescriptor_ed7f10298fa1d90f = []byte{
|
var fileDescriptor_ed7f10298fa1d90f = []byte{
|
||||||
// 1890 bytes of a gzipped FileDescriptorProto
|
// 1881 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0x5f, 0x6f, 0xdb, 0xc8,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0x5f, 0x6f, 0xdb, 0xc8,
|
||||||
0x11, 0x2f, 0x25, 0x59, 0x7f, 0x46, 0x96, 0xe3, 0x6c, 0x9d, 0x74, 0xc3, 0xa4, 0x17, 0x87, 0x49,
|
0x11, 0x2f, 0x25, 0x59, 0x7f, 0x46, 0x96, 0xe3, 0x6c, 0x9d, 0x74, 0xc3, 0xa4, 0x17, 0x87, 0x49,
|
||||||
0xae, 0x42, 0x53, 0x48, 0x77, 0xbe, 0xa6, 0xbe, 0x5c, 0xee, 0x80, 0xda, 0xb2, 0x05, 0xfb, 0x90,
|
0xae, 0x42, 0x53, 0x48, 0x77, 0xbe, 0xa6, 0xbe, 0x5c, 0xee, 0x80, 0xda, 0xb2, 0x05, 0xfb, 0x90,
|
||||||
0xd8, 0xc6, 0xca, 0xc9, 0xa1, 0x2d, 0xd0, 0x80, 0x92, 0xd6, 0x32, 0x21, 0x8a, 0xab, 0x72, 0x57,
|
0xd8, 0xc6, 0xca, 0xc9, 0xa1, 0x2d, 0xd0, 0x80, 0x92, 0xd6, 0x32, 0x21, 0x8a, 0xab, 0x72, 0x57,
|
||||||
0xb6, 0xd5, 0xa7, 0x3e, 0xb4, 0x6f, 0x45, 0xbf, 0x47, 0xd1, 0x8f, 0xd0, 0x97, 0xf6, 0x1b, 0xf5,
|
0xb6, 0xd5, 0xa7, 0xbe, 0xf4, 0xad, 0xe8, 0xf7, 0x28, 0xfa, 0x11, 0xfa, 0xd2, 0x7e, 0xa1, 0xa2,
|
||||||
0x23, 0x14, 0xfb, 0x87, 0x14, 0x69, 0x89, 0xb2, 0xdd, 0x3e, 0x69, 0x67, 0xf8, 0xfb, 0xcd, 0xec,
|
0x1f, 0xa1, 0xd8, 0x3f, 0xa4, 0x48, 0x4b, 0x94, 0xed, 0xf6, 0x49, 0x3b, 0xc3, 0xdf, 0x6f, 0x76,
|
||||||
0x2c, 0x67, 0x67, 0x86, 0x82, 0xf5, 0x1e, 0x0b, 0x44, 0xc8, 0x7c, 0x9f, 0x86, 0x8d, 0x71, 0xc8,
|
0x67, 0x38, 0x3b, 0x33, 0x14, 0xac, 0xf7, 0x58, 0x20, 0x42, 0xe6, 0xfb, 0x34, 0x6c, 0x8c, 0x43,
|
||||||
0x04, 0x43, 0x1b, 0xdd, 0x89, 0xe7, 0xf7, 0xaf, 0x1a, 0x89, 0x07, 0x17, 0x5f, 0xda, 0x6f, 0x07,
|
0x26, 0x18, 0xda, 0xe8, 0x4e, 0x3c, 0xbf, 0x7f, 0xd5, 0x48, 0x3c, 0xb8, 0xf8, 0xd2, 0x7e, 0x3b,
|
||||||
0x9e, 0x38, 0x9f, 0x74, 0x1b, 0x3d, 0x36, 0x6a, 0x8e, 0x58, 0x77, 0xda, 0x54, 0xa8, 0xa1, 0x27,
|
0xf0, 0xc4, 0xf9, 0xa4, 0xdb, 0xe8, 0xb1, 0x51, 0x73, 0xc4, 0xba, 0xd3, 0xa6, 0x42, 0x0d, 0x3d,
|
||||||
0x9a, 0xee, 0xd8, 0x6b, 0x72, 0x1a, 0x5e, 0x78, 0x3d, 0xca, 0x9b, 0x86, 0x14, 0xfd, 0x6a, 0x93,
|
0xd1, 0x74, 0xc7, 0x5e, 0x93, 0xd3, 0xf0, 0xc2, 0xeb, 0x51, 0xde, 0x34, 0xa4, 0xe8, 0x57, 0x9b,
|
||||||
0xf6, 0xeb, 0x4c, 0x32, 0x67, 0x93, 0xb0, 0x47, 0xc7, 0xcc, 0xf7, 0x7a, 0xd3, 0xe6, 0xb8, 0xdb,
|
0xb4, 0x5f, 0x67, 0x92, 0x39, 0x9b, 0x84, 0x3d, 0x3a, 0x66, 0xbe, 0xd7, 0x9b, 0x36, 0xc7, 0xdd,
|
||||||
0xd4, 0x2b, 0x4d, 0x73, 0xea, 0xb0, 0xf1, 0xce, 0xe3, 0xe2, 0x24, 0x64, 0x3d, 0xca, 0x39, 0xe5,
|
0xa6, 0x5e, 0x69, 0x9a, 0x53, 0x87, 0x8d, 0x77, 0x1e, 0x17, 0x27, 0x21, 0xeb, 0x51, 0xce, 0x29,
|
||||||
0x84, 0xfe, 0x61, 0x42, 0xb9, 0x40, 0xeb, 0x90, 0x27, 0xf4, 0x0c, 0x5b, 0x9b, 0x56, 0xbd, 0x42,
|
0x27, 0xf4, 0x0f, 0x13, 0xca, 0x05, 0x5a, 0x87, 0x3c, 0xa1, 0x67, 0xd8, 0xda, 0xb4, 0xea, 0x15,
|
||||||
0xe4, 0xd2, 0x39, 0x81, 0x07, 0xd7, 0x90, 0x7c, 0xcc, 0x02, 0x4e, 0xd1, 0x36, 0xac, 0x1c, 0x06,
|
0x22, 0x97, 0xce, 0x09, 0x3c, 0xb8, 0x86, 0xe4, 0x63, 0x16, 0x70, 0x8a, 0xb6, 0x61, 0xe5, 0x30,
|
||||||
0x67, 0x8c, 0x63, 0x6b, 0x33, 0x5f, 0xaf, 0x6e, 0x3d, 0x6b, 0x2c, 0x0a, 0xae, 0x61, 0x78, 0x12,
|
0x38, 0x63, 0x1c, 0x5b, 0x9b, 0xf9, 0x7a, 0x75, 0xeb, 0x59, 0x63, 0x91, 0x73, 0x0d, 0xc3, 0x93,
|
||||||
0x49, 0x34, 0xde, 0xe1, 0x50, 0x4d, 0x68, 0xd1, 0x13, 0xa8, 0x44, 0xe2, 0x9e, 0x71, 0x3c, 0x53,
|
0x48, 0xa2, 0xf1, 0x0e, 0x87, 0x6a, 0x42, 0x8b, 0x9e, 0x40, 0x25, 0x12, 0xf7, 0xcc, 0xc6, 0x33,
|
||||||
0xa0, 0x36, 0xac, 0x1e, 0x06, 0x17, 0x6c, 0x48, 0x5b, 0x2c, 0x38, 0xf3, 0x06, 0x38, 0xb7, 0x69,
|
0x05, 0x6a, 0xc3, 0xea, 0x61, 0x70, 0xc1, 0x86, 0xb4, 0xc5, 0x82, 0x33, 0x6f, 0x80, 0x73, 0x9b,
|
||||||
0xd5, 0xab, 0x5b, 0xce, 0x62, 0x67, 0x49, 0x24, 0x49, 0xf1, 0x9c, 0xef, 0x01, 0xef, 0x79, 0xbc,
|
0x56, 0xbd, 0xba, 0xe5, 0x2c, 0xde, 0x2c, 0x89, 0x24, 0x29, 0x9e, 0xf3, 0x3d, 0xe0, 0x3d, 0x8f,
|
||||||
0xc7, 0x82, 0x80, 0xf6, 0xa2, 0x60, 0x32, 0x83, 0x4e, 0xef, 0x29, 0x77, 0x6d, 0x4f, 0xce, 0x63,
|
0xf7, 0x58, 0x10, 0xd0, 0x5e, 0xe4, 0x4c, 0xa6, 0xd3, 0xe9, 0x33, 0xe5, 0xae, 0x9d, 0xc9, 0x79,
|
||||||
0x78, 0xb4, 0xc0, 0x96, 0x3e, 0x16, 0xe7, 0xf7, 0xb0, 0xba, 0x2b, 0xf7, 0x96, 0x6d, 0xfc, 0x5b,
|
0x0c, 0x8f, 0x16, 0xd8, 0xd2, 0x61, 0x71, 0x7e, 0x0f, 0xab, 0xbb, 0xf2, 0x6c, 0xd9, 0xc6, 0xbf,
|
||||||
0x28, 0x1d, 0x8f, 0x85, 0xc7, 0x02, 0xbe, 0x3c, 0x1a, 0x65, 0xc6, 0x20, 0x49, 0x44, 0x71, 0xfe,
|
0x85, 0xd2, 0xf1, 0x58, 0x78, 0x2c, 0xe0, 0xcb, 0xbd, 0x51, 0x66, 0x0c, 0x92, 0x44, 0x14, 0xe7,
|
||||||
0x55, 0x35, 0x0e, 0x8c, 0x02, 0x6d, 0x42, 0xb5, 0xc5, 0x02, 0x41, 0xaf, 0xc4, 0x89, 0x2b, 0xce,
|
0x9f, 0x55, 0xb3, 0x81, 0x51, 0xa0, 0x4d, 0xa8, 0xb6, 0x58, 0x20, 0xe8, 0x95, 0x38, 0x71, 0xc5,
|
||||||
0x8d, 0xa3, 0xa4, 0x0a, 0x7d, 0x0e, 0x6b, 0x7b, 0xac, 0x37, 0xa4, 0xe1, 0x99, 0xe7, 0xd3, 0x23,
|
0xb9, 0xd9, 0x28, 0xa9, 0x42, 0x9f, 0xc3, 0xda, 0x1e, 0xeb, 0x0d, 0x69, 0x78, 0xe6, 0xf9, 0xf4,
|
||||||
0x77, 0x44, 0x4d, 0x48, 0xd7, 0xb4, 0xe8, 0x3b, 0x19, 0xb5, 0x17, 0x88, 0xf6, 0x24, 0xe8, 0xe1,
|
0xc8, 0x1d, 0x51, 0xe3, 0xd2, 0x35, 0x2d, 0xfa, 0x4e, 0x7a, 0xed, 0x05, 0xa2, 0x3d, 0x09, 0x7a,
|
||||||
0xbc, 0xda, 0xda, 0xd3, 0xac, 0xb7, 0x6a, 0x60, 0x64, 0xc6, 0x40, 0xbf, 0x83, 0x9a, 0x34, 0xd3,
|
0x38, 0xaf, 0x8e, 0xf6, 0x34, 0xeb, 0xad, 0x1a, 0x18, 0x99, 0x31, 0xd0, 0xef, 0xa0, 0x26, 0xcd,
|
||||||
0x37, 0xae, 0x39, 0x2e, 0xa8, 0xc4, 0x78, 0x7d, 0x73, 0x74, 0x8d, 0x14, 0x6f, 0x3f, 0x10, 0xe1,
|
0xf4, 0xcd, 0xd6, 0x1c, 0x17, 0x54, 0x62, 0xbc, 0xbe, 0xd9, 0xbb, 0x46, 0x8a, 0xb7, 0x1f, 0x88,
|
||||||
0x94, 0xa4, 0x6d, 0xa1, 0x0d, 0x58, 0xd9, 0xf1, 0x7d, 0x76, 0x89, 0x57, 0x36, 0xf3, 0xf5, 0x0a,
|
0x70, 0x4a, 0xd2, 0xb6, 0xd0, 0x06, 0xac, 0xec, 0xf8, 0x3e, 0xbb, 0xc4, 0x2b, 0x9b, 0xf9, 0x7a,
|
||||||
0xd1, 0x02, 0xfa, 0x15, 0x94, 0x76, 0x84, 0xa0, 0x5c, 0x70, 0x5c, 0x54, 0xce, 0x9e, 0x2c, 0x76,
|
0x85, 0x68, 0x01, 0xfd, 0x0a, 0x4a, 0x3b, 0x42, 0x50, 0x2e, 0x38, 0x2e, 0xaa, 0xcd, 0x9e, 0x2c,
|
||||||
0xa6, 0x41, 0x24, 0x02, 0xa3, 0x63, 0xa8, 0x28, 0xff, 0x3b, 0xe1, 0x80, 0xe3, 0x92, 0x62, 0x7e,
|
0xde, 0x4c, 0x83, 0x48, 0x04, 0x46, 0xc7, 0x50, 0x51, 0xfb, 0xef, 0x84, 0x03, 0x8e, 0x4b, 0x8a,
|
||||||
0x79, 0x8b, 0x6d, 0xc6, 0x1c, 0xbd, 0xc5, 0x99, 0x0d, 0xb4, 0x0f, 0x95, 0x96, 0xdb, 0x3b, 0xa7,
|
0xf9, 0xe5, 0x2d, 0x8e, 0x19, 0x73, 0xf4, 0x11, 0x67, 0x36, 0xd0, 0x3e, 0x54, 0x5a, 0x6e, 0xef,
|
||||||
0xed, 0x90, 0x8d, 0x70, 0x59, 0x19, 0xfc, 0xd9, 0x62, 0x83, 0x0a, 0x66, 0x0c, 0x1a, 0x33, 0x31,
|
0x9c, 0xb6, 0x43, 0x36, 0xc2, 0x65, 0x65, 0xf0, 0x67, 0x8b, 0x0d, 0x2a, 0x98, 0x31, 0x68, 0xcc,
|
||||||
0x13, 0xed, 0x40, 0x49, 0x09, 0xa7, 0x0c, 0x57, 0xee, 0x66, 0x24, 0xe2, 0x21, 0x07, 0x56, 0x5b,
|
0xc4, 0x4c, 0xb4, 0x03, 0x25, 0x25, 0x9c, 0x32, 0x5c, 0xb9, 0x9b, 0x91, 0x88, 0x87, 0x1c, 0x58,
|
||||||
0x83, 0x90, 0x4d, 0xc6, 0x27, 0x6e, 0x48, 0x03, 0x81, 0x41, 0xbd, 0xea, 0x94, 0x0e, 0xbd, 0x85,
|
0x6d, 0x0d, 0x42, 0x36, 0x19, 0x9f, 0xb8, 0x21, 0x0d, 0x04, 0x06, 0xf5, 0xaa, 0x53, 0x3a, 0xf4,
|
||||||
0xd2, 0xfe, 0xd5, 0x98, 0x85, 0x82, 0xe3, 0xea, 0xb2, 0xcb, 0xab, 0x41, 0xc6, 0x81, 0x61, 0xa0,
|
0x16, 0x4a, 0xfb, 0x57, 0x63, 0x16, 0x0a, 0x8e, 0xab, 0xcb, 0x2e, 0xaf, 0x06, 0x99, 0x0d, 0x0c,
|
||||||
0xcf, 0x00, 0xf6, 0xaf, 0x44, 0xe8, 0x1e, 0x30, 0x79, 0xec, 0xab, 0xea, 0x75, 0x24, 0x34, 0xa8,
|
0x03, 0x7d, 0x06, 0xb0, 0x7f, 0x25, 0x42, 0xf7, 0x80, 0xc9, 0xb0, 0xaf, 0xaa, 0xd7, 0x91, 0xd0,
|
||||||
0x0d, 0xc5, 0x77, 0x6e, 0x97, 0xfa, 0x1c, 0xd7, 0x94, 0xed, 0xc6, 0x2d, 0x0e, 0x56, 0x13, 0xb4,
|
0xa0, 0x36, 0x14, 0xdf, 0xb9, 0x5d, 0xea, 0x73, 0x5c, 0x53, 0xb6, 0x1b, 0xb7, 0x08, 0xac, 0x26,
|
||||||
0x23, 0xc3, 0x96, 0x79, 0x7d, 0x44, 0xc5, 0x25, 0x0b, 0x87, 0xef, 0x59, 0x9f, 0xe2, 0x35, 0x9d,
|
0xe8, 0x8d, 0x0c, 0x5b, 0xe6, 0xf5, 0x11, 0x15, 0x97, 0x2c, 0x1c, 0xbe, 0x67, 0x7d, 0x8a, 0xd7,
|
||||||
0xd7, 0x09, 0x15, 0x7a, 0x01, 0xb5, 0x23, 0xa6, 0x0f, 0xcf, 0xf3, 0x05, 0x0d, 0xf1, 0x3d, 0xb5,
|
0x74, 0x5e, 0x27, 0x54, 0xe8, 0x05, 0xd4, 0x8e, 0x98, 0x0e, 0x9e, 0xe7, 0x0b, 0x1a, 0xe2, 0x7b,
|
||||||
0x99, 0xb4, 0x52, 0xdd, 0x65, 0xdf, 0x15, 0x67, 0x2c, 0x1c, 0x71, 0xbc, 0xae, 0x10, 0x33, 0x85,
|
0xea, 0x30, 0x69, 0xa5, 0xba, 0xcb, 0xbe, 0x2b, 0xce, 0x58, 0x38, 0xe2, 0x78, 0x5d, 0x21, 0x66,
|
||||||
0xcc, 0xa0, 0x0e, 0xed, 0x85, 0x54, 0x70, 0x7c, 0x7f, 0x59, 0x06, 0x69, 0x10, 0x89, 0xc0, 0x08,
|
0x0a, 0x99, 0x41, 0x1d, 0xda, 0x0b, 0xa9, 0xe0, 0xf8, 0xfe, 0xb2, 0x0c, 0xd2, 0x20, 0x12, 0x81,
|
||||||
0x43, 0xa9, 0x73, 0x3e, 0xea, 0x78, 0x7f, 0xa4, 0x18, 0x6d, 0x5a, 0xf5, 0x3c, 0x89, 0x44, 0xf4,
|
0x11, 0x86, 0x52, 0xe7, 0x7c, 0xd4, 0xf1, 0xfe, 0x48, 0x31, 0xda, 0xb4, 0xea, 0x79, 0x12, 0x89,
|
||||||
0x0a, 0xf2, 0x9d, 0xce, 0x01, 0xfe, 0xb1, 0xb2, 0xf6, 0x28, 0xc3, 0x5a, 0xe7, 0x80, 0x48, 0x14,
|
0xe8, 0x15, 0xe4, 0x3b, 0x9d, 0x03, 0xfc, 0x63, 0x65, 0xed, 0x51, 0x86, 0xb5, 0xce, 0x01, 0x91,
|
||||||
0x42, 0x50, 0x38, 0x75, 0x07, 0x1c, 0x6f, 0xa8, 0x7d, 0xa9, 0x35, 0x7a, 0x08, 0xc5, 0x53, 0x37,
|
0x28, 0x84, 0xa0, 0x70, 0xea, 0x0e, 0x38, 0xde, 0x50, 0xe7, 0x52, 0x6b, 0xf4, 0x10, 0x8a, 0xa7,
|
||||||
0x1c, 0x50, 0x81, 0x1f, 0xa8, 0x98, 0x8d, 0x84, 0xde, 0x40, 0xe9, 0x83, 0xef, 0x8d, 0x3c, 0xc1,
|
0x6e, 0x38, 0xa0, 0x02, 0x3f, 0x50, 0x3e, 0x1b, 0x09, 0xbd, 0x81, 0xd2, 0x07, 0xdf, 0x1b, 0x79,
|
||||||
0xf1, 0xc3, 0x65, 0x97, 0x53, 0x83, 0x8e, 0xc7, 0x82, 0x44, 0x78, 0xb9, 0x5b, 0x75, 0xde, 0x34,
|
0x82, 0xe3, 0x87, 0xcb, 0x2e, 0xa7, 0x06, 0x1d, 0x8f, 0x05, 0x89, 0xf0, 0xf2, 0xb4, 0x2a, 0xde,
|
||||||
0xc4, 0x3f, 0x51, 0x36, 0x23, 0x51, 0x3e, 0x31, 0xc7, 0x85, 0xf1, 0xa6, 0x55, 0x2f, 0x93, 0x48,
|
0x34, 0xc4, 0x3f, 0x51, 0x36, 0x23, 0x51, 0x3e, 0x31, 0xe1, 0xc2, 0x78, 0xd3, 0xaa, 0x97, 0x49,
|
||||||
0x94, 0x5b, 0x3b, 0x99, 0xf8, 0x3e, 0x7e, 0xa4, 0xd4, 0x6a, 0xad, 0xdf, 0xbd, 0x4c, 0x83, 0x93,
|
0x24, 0xca, 0xa3, 0x9d, 0x4c, 0x7c, 0x1f, 0x3f, 0x52, 0x6a, 0xb5, 0xd6, 0xef, 0x5e, 0xa6, 0xc1,
|
||||||
0x09, 0x3f, 0xc7, 0xb6, 0x7a, 0x92, 0xd0, 0xcc, 0x9e, 0xbf, 0x63, 0x6e, 0x1f, 0x3f, 0x4e, 0x3e,
|
0xc9, 0x84, 0x9f, 0x63, 0x5b, 0x3d, 0x49, 0x68, 0x66, 0xcf, 0xdf, 0x31, 0xb7, 0x8f, 0x1f, 0x27,
|
||||||
0x97, 0x1a, 0x74, 0x08, 0xab, 0x1d, 0xd5, 0x96, 0x4e, 0x54, 0x33, 0xc2, 0x4f, 0x54, 0x1c, 0x2f,
|
0x9f, 0x4b, 0x0d, 0x3a, 0x84, 0xd5, 0x8e, 0x6a, 0x4b, 0x27, 0xaa, 0x19, 0xe1, 0x27, 0xca, 0x8f,
|
||||||
0x1b, 0xb2, 0x73, 0x35, 0xa2, 0xce, 0x25, 0x63, 0x48, 0x36, 0xaf, 0x86, 0x06, 0x93, 0x14, 0xd5,
|
0x97, 0x0d, 0xd9, 0xb9, 0x1a, 0x51, 0xe7, 0x92, 0x3e, 0x24, 0x9b, 0x57, 0x43, 0x83, 0x49, 0x8a,
|
||||||
0xfe, 0x35, 0xa0, 0xf9, 0xaa, 0x21, 0xab, 0xed, 0x90, 0x4e, 0xa3, 0x6a, 0x3b, 0xa4, 0x53, 0x59,
|
0x6a, 0xff, 0x1a, 0xd0, 0x7c, 0xd5, 0x90, 0xd5, 0x76, 0x48, 0xa7, 0x51, 0xb5, 0x1d, 0xd2, 0xa9,
|
||||||
0x38, 0x2e, 0x5c, 0x7f, 0x12, 0xd5, 0x3c, 0x2d, 0x7c, 0x93, 0xfb, 0xda, 0xb2, 0xbf, 0x85, 0xb5,
|
0x2c, 0x1c, 0x17, 0xae, 0x3f, 0x89, 0x6a, 0x9e, 0x16, 0xbe, 0xc9, 0x7d, 0x6d, 0xd9, 0xdf, 0xc2,
|
||||||
0xf4, 0x85, 0xbe, 0x13, 0xfb, 0x0d, 0x54, 0x13, 0x59, 0x7b, 0x17, 0xaa, 0xf3, 0x6f, 0x0b, 0xaa,
|
0x5a, 0xfa, 0x42, 0xdf, 0x89, 0xfd, 0x06, 0xaa, 0x89, 0xac, 0xbd, 0x0b, 0xd5, 0xf9, 0x97, 0x05,
|
||||||
0x89, 0xab, 0xa5, 0x92, 0x60, 0x3a, 0xa6, 0x86, 0xac, 0xd6, 0x68, 0x17, 0x56, 0x76, 0x84, 0x08,
|
0xd5, 0xc4, 0xd5, 0x52, 0x49, 0x30, 0x1d, 0x53, 0x43, 0x56, 0x6b, 0xb4, 0x0b, 0x2b, 0x3b, 0x42,
|
||||||
0x65, 0x8b, 0x90, 0x79, 0xf4, 0x8b, 0x1b, 0x2f, 0x68, 0x43, 0xc1, 0xf5, 0x15, 0xd2, 0x54, 0x79,
|
0x84, 0xb2, 0x45, 0xc8, 0x3c, 0xfa, 0xc5, 0x8d, 0x17, 0xb4, 0xa1, 0xe0, 0xfa, 0x0a, 0x69, 0xaa,
|
||||||
0x83, 0xf6, 0x28, 0x17, 0x5e, 0xe0, 0xca, 0x5b, 0xa6, 0x2a, 0x7a, 0x85, 0x24, 0x55, 0xf6, 0xd7,
|
0xbc, 0x41, 0x7b, 0x94, 0x0b, 0x2f, 0x70, 0xe5, 0x2d, 0x53, 0x15, 0xbd, 0x42, 0x92, 0x2a, 0xfb,
|
||||||
0x00, 0x33, 0xda, 0x9d, 0x62, 0xf8, 0x87, 0x05, 0xf7, 0xe7, 0xaa, 0xd0, 0xc2, 0x48, 0x0e, 0xd2,
|
0x6b, 0x80, 0x19, 0xed, 0x4e, 0x3e, 0xfc, 0xdd, 0x82, 0xfb, 0x73, 0x55, 0x68, 0xa1, 0x27, 0x07,
|
||||||
0x91, 0x6c, 0xdd, 0xb2, 0xa2, 0xcd, 0xc7, 0xf3, 0x7f, 0xec, 0xf6, 0x08, 0x8a, 0xba, 0xf4, 0x2f,
|
0x69, 0x4f, 0xb6, 0x6e, 0x59, 0xd1, 0xe6, 0xfd, 0xf9, 0x3f, 0x4e, 0x7b, 0x04, 0x45, 0x5d, 0xfa,
|
||||||
0xdc, 0xa1, 0x0d, 0xe5, 0x3d, 0x8f, 0xbb, 0x5d, 0x9f, 0xf6, 0x15, 0xb5, 0x4c, 0x62, 0x59, 0xf5,
|
0x17, 0x9e, 0xd0, 0x86, 0xf2, 0x9e, 0xc7, 0xdd, 0xae, 0x4f, 0xfb, 0x8a, 0x5a, 0x26, 0xb1, 0xac,
|
||||||
0x1d, 0xb5, 0x7b, 0x7d, 0x7a, 0x5a, 0x70, 0xf4, 0x1d, 0x47, 0x6b, 0x90, 0x8b, 0x67, 0x96, 0xdc,
|
0xfa, 0x8e, 0x3a, 0xbd, 0x8e, 0x9e, 0x16, 0x1c, 0x7d, 0xc7, 0xd1, 0x1a, 0xe4, 0xe2, 0x99, 0x25,
|
||||||
0xe1, 0x9e, 0x04, 0xcb, 0x86, 0xab, 0x43, 0xad, 0x10, 0x2d, 0x38, 0x6d, 0x28, 0xea, 0xaa, 0x31,
|
0x77, 0xb8, 0x27, 0xc1, 0xb2, 0xe1, 0x6a, 0x57, 0x2b, 0x44, 0x0b, 0x4e, 0x1b, 0x8a, 0xba, 0x6a,
|
||||||
0x87, 0xb7, 0xa1, 0xdc, 0xf6, 0x7c, 0xaa, 0xfa, 0xb6, 0xde, 0x73, 0x2c, 0xcb, 0xf0, 0xf6, 0x83,
|
0xcc, 0xe1, 0x6d, 0x28, 0xb7, 0x3d, 0x9f, 0xaa, 0xbe, 0xad, 0xcf, 0x1c, 0xcb, 0xd2, 0xbd, 0xfd,
|
||||||
0x0b, 0xe3, 0x56, 0x2e, 0x9d, 0xed, 0x44, 0x7b, 0x96, 0x71, 0xa8, 0x4e, 0x6e, 0xe2, 0x50, 0xfd,
|
0xe0, 0xc2, 0x6c, 0x2b, 0x97, 0xce, 0x76, 0xa2, 0x3d, 0x4b, 0x3f, 0x54, 0x27, 0x37, 0x7e, 0xa8,
|
||||||
0xfb, 0x21, 0x14, 0xdb, 0x2c, 0x1c, 0xb9, 0xc2, 0x18, 0x33, 0x92, 0xe3, 0xc0, 0xda, 0x61, 0xc0,
|
0xfe, 0xfd, 0x10, 0x8a, 0x6d, 0x16, 0x8e, 0x5c, 0x61, 0x8c, 0x19, 0xc9, 0x71, 0x60, 0xed, 0x30,
|
||||||
0xc7, 0xb4, 0x27, 0xb2, 0xc7, 0xbc, 0x63, 0xb8, 0x17, 0x63, 0xcc, 0x80, 0x97, 0x98, 0x53, 0xac,
|
0xe0, 0x63, 0xda, 0x13, 0xd9, 0x63, 0xde, 0x31, 0xdc, 0x8b, 0x31, 0x66, 0xc0, 0x4b, 0xcc, 0x29,
|
||||||
0xbb, 0xcf, 0x29, 0x7f, 0xb7, 0xa0, 0x12, 0x57, 0x22, 0xd4, 0x82, 0xa2, 0x7a, 0x1b, 0xd1, 0xb4,
|
0xd6, 0xdd, 0xe7, 0x94, 0xbf, 0x59, 0x50, 0x89, 0x2b, 0x11, 0x6a, 0x41, 0x51, 0xbd, 0x8d, 0x68,
|
||||||
0xf8, 0xea, 0x86, 0xd2, 0xd5, 0xf8, 0xa8, 0xd0, 0xa6, 0x23, 0x68, 0xaa, 0xfd, 0x03, 0x54, 0x13,
|
0x5a, 0x7c, 0x75, 0x43, 0xe9, 0x6a, 0x7c, 0x54, 0x68, 0xd3, 0x11, 0x34, 0xd5, 0xfe, 0x01, 0xaa,
|
||||||
0xea, 0x05, 0x09, 0xb0, 0x95, 0x4c, 0x80, 0xcc, 0x52, 0xae, 0x9d, 0x24, 0xd3, 0x63, 0x0f, 0x8a,
|
0x09, 0xf5, 0x82, 0x04, 0xd8, 0x4a, 0x26, 0x40, 0x66, 0x29, 0xd7, 0x9b, 0x24, 0xd3, 0x63, 0x0f,
|
||||||
0x5a, 0xb9, 0xf0, 0x58, 0x11, 0x14, 0x0e, 0xdc, 0x50, 0xa7, 0x46, 0x9e, 0xa8, 0xb5, 0xd4, 0x75,
|
0x8a, 0x5a, 0xb9, 0x30, 0xac, 0x08, 0x0a, 0x07, 0x6e, 0xa8, 0x53, 0x23, 0x4f, 0xd4, 0x5a, 0xea,
|
||||||
0xd8, 0x99, 0x50, 0xaf, 0x27, 0x4f, 0xd4, 0xda, 0xf9, 0xa7, 0x05, 0x35, 0x33, 0xfa, 0x99, 0x13,
|
0x3a, 0xec, 0x4c, 0xa8, 0xd7, 0x93, 0x27, 0x6a, 0xed, 0xfc, 0xc3, 0x82, 0x9a, 0x19, 0xfd, 0x4c,
|
||||||
0xa4, 0xb0, 0xae, 0x6f, 0x28, 0x0d, 0x23, 0x9d, 0x89, 0xff, 0xcd, 0x92, 0xa3, 0x8c, 0xa0, 0x8d,
|
0x04, 0x29, 0xac, 0xeb, 0x1b, 0x4a, 0xc3, 0x48, 0x67, 0xfc, 0x7f, 0xb3, 0x24, 0x94, 0x11, 0xb4,
|
||||||
0xeb, 0x5c, 0x7d, 0x1a, 0x73, 0x26, 0xed, 0x16, 0x3c, 0x58, 0x08, 0xbd, 0xd3, 0x15, 0x79, 0x09,
|
0x71, 0x9d, 0xab, 0xa3, 0x31, 0x67, 0xd2, 0x6e, 0xc1, 0x83, 0x85, 0xd0, 0x3b, 0x5d, 0x91, 0x97,
|
||||||
0xf7, 0x67, 0x43, 0x6d, 0x76, 0x9e, 0x6c, 0x00, 0x4a, 0xc2, 0xcc, 0xd0, 0xfb, 0x14, 0xaa, 0xf2,
|
0x70, 0x7f, 0x36, 0xd4, 0x66, 0xe7, 0xc9, 0x06, 0xa0, 0x24, 0xcc, 0x0c, 0xbd, 0x4f, 0xa1, 0x2a,
|
||||||
0x23, 0x21, 0x9b, 0xe6, 0xc0, 0xaa, 0x06, 0x98, 0x93, 0x41, 0x50, 0x18, 0xd2, 0xa9, 0xce, 0x86,
|
0x3f, 0x12, 0xb2, 0x69, 0x0e, 0xac, 0x6a, 0x80, 0x89, 0x0c, 0x82, 0xc2, 0x90, 0x4e, 0x75, 0x36,
|
||||||
0x0a, 0x51, 0x6b, 0xe7, 0x6f, 0x96, 0x9c, 0xf5, 0xc7, 0x13, 0xf1, 0x9e, 0x72, 0xee, 0x0e, 0x64,
|
0x54, 0x88, 0x5a, 0x3b, 0x7f, 0xb5, 0xe4, 0xac, 0x3f, 0x9e, 0x88, 0xf7, 0x94, 0x73, 0x77, 0x20,
|
||||||
0x02, 0x16, 0x0e, 0x03, 0x4f, 0x98, 0xec, 0xfb, 0x3c, 0x6b, 0xe6, 0x1f, 0x4f, 0x84, 0x84, 0x19,
|
0x13, 0xb0, 0x70, 0x18, 0x78, 0xc2, 0x64, 0xdf, 0xe7, 0x59, 0x33, 0xff, 0x78, 0x22, 0x24, 0xcc,
|
||||||
0xd6, 0xc1, 0x8f, 0x88, 0x62, 0xa1, 0x6d, 0x28, 0xec, 0xb9, 0xc2, 0x35, 0xb9, 0x90, 0x31, 0xe1,
|
0xb0, 0x0e, 0x7e, 0x44, 0x14, 0x0b, 0x6d, 0x43, 0x61, 0xcf, 0x15, 0xae, 0xc9, 0x85, 0x8c, 0x09,
|
||||||
0x48, 0x44, 0x82, 0x28, 0xc5, 0xdd, 0x92, 0xfc, 0xb0, 0x19, 0x4f, 0x84, 0xf3, 0x02, 0xd6, 0xaf,
|
0x47, 0x22, 0x12, 0x44, 0x29, 0xee, 0x96, 0xe4, 0x87, 0xcd, 0x78, 0x22, 0x9c, 0x17, 0xb0, 0x7e,
|
||||||
0x5b, 0x5f, 0x10, 0xda, 0x57, 0x50, 0x4d, 0x58, 0x51, 0xf7, 0xf6, 0xb8, 0xad, 0x00, 0x65, 0x22,
|
0xdd, 0xfa, 0x02, 0xd7, 0xbe, 0x82, 0x6a, 0xc2, 0x8a, 0xba, 0xb7, 0xc7, 0x6d, 0x05, 0x28, 0x13,
|
||||||
0x97, 0x32, 0xd6, 0x78, 0x23, 0xab, 0xda, 0x87, 0x73, 0x0f, 0x6a, 0xca, 0x74, 0x7c, 0x82, 0x7f,
|
0xb9, 0x94, 0xbe, 0xc6, 0x07, 0x59, 0xd5, 0x7b, 0x38, 0xf7, 0xa0, 0xa6, 0x4c, 0xc7, 0x11, 0xfc,
|
||||||
0xca, 0x41, 0x29, 0x32, 0xb1, 0x9d, 0x8a, 0xfb, 0x59, 0x56, 0xdc, 0xf3, 0x21, 0xbf, 0x86, 0x82,
|
0x53, 0x0e, 0x4a, 0x91, 0x89, 0xed, 0x94, 0xdf, 0xcf, 0xb2, 0xfc, 0x9e, 0x77, 0xf9, 0x35, 0x14,
|
||||||
0xac, 0x1f, 0x26, 0xe4, 0x8c, 0xf1, 0xa0, 0xdd, 0x4f, 0xd0, 0x24, 0x1c, 0x7d, 0x07, 0x45, 0x42,
|
0x64, 0xfd, 0x30, 0x2e, 0x67, 0x8c, 0x07, 0xed, 0x7e, 0x82, 0x26, 0xe1, 0xe8, 0x3b, 0x28, 0x12,
|
||||||
0xb9, 0x1c, 0x65, 0xf4, 0xd0, 0xff, 0x7c, 0x31, 0x51, 0x63, 0x66, 0x64, 0x43, 0x92, 0xf4, 0x8e,
|
0xca, 0xe5, 0x28, 0xa3, 0x87, 0xfe, 0xe7, 0x8b, 0x89, 0x1a, 0x33, 0x23, 0x1b, 0x92, 0xa4, 0x77,
|
||||||
0x37, 0x08, 0x5c, 0x1f, 0x17, 0x96, 0xd1, 0x35, 0x26, 0x41, 0xd7, 0x8a, 0xd9, 0x71, 0xff, 0xc5,
|
0xbc, 0x41, 0xe0, 0xfa, 0xb8, 0xb0, 0x8c, 0xae, 0x31, 0x09, 0xba, 0x56, 0xcc, 0xc2, 0xfd, 0x67,
|
||||||
0x82, 0xea, 0xd2, 0xa3, 0x5e, 0xfe, 0x59, 0x36, 0xf7, 0xa9, 0x98, 0xff, 0x1f, 0x3f, 0x15, 0xff,
|
0x0b, 0xaa, 0x4b, 0x43, 0xbd, 0xfc, 0xb3, 0x6c, 0xee, 0x53, 0x31, 0xff, 0x3f, 0x7e, 0x2a, 0xfe,
|
||||||
0x9c, 0x4b, 0x1b, 0x52, 0x53, 0x8d, 0xbc, 0x4f, 0x63, 0xe6, 0x05, 0xc2, 0xa4, 0x6c, 0x42, 0x23,
|
0xdb, 0x4a, 0x1b, 0x52, 0x53, 0x8d, 0xbc, 0x4f, 0x63, 0xe6, 0x05, 0xc2, 0xa4, 0x6c, 0x42, 0x23,
|
||||||
0x37, 0xda, 0x1a, 0xf5, 0x4d, 0xd1, 0x97, 0x4b, 0x79, 0xcd, 0x8e, 0x98, 0xd4, 0x55, 0x55, 0x1a,
|
0x0f, 0xda, 0x1a, 0xf5, 0x4d, 0xd1, 0x97, 0xcb, 0x59, 0xf1, 0xce, 0x9b, 0xe2, 0x2d, 0x93, 0xe0,
|
||||||
0x68, 0x61, 0x56, 0xd2, 0xf3, 0xa6, 0xa4, 0xcb, 0xd4, 0xf8, 0xc0, 0x69, 0xa8, 0x0e, 0xae, 0x42,
|
0x03, 0xa7, 0xa1, 0x0a, 0x51, 0x85, 0xa8, 0xb5, 0xac, 0xd7, 0x47, 0x4c, 0x69, 0x57, 0x54, 0xb6,
|
||||||
0xd4, 0x5a, 0x56, 0xf1, 0x23, 0xa6, 0xb4, 0x2b, 0x8a, 0x6c, 0x24, 0xe5, 0xe5, 0xb2, 0x8f, 0x8b,
|
0x18, 0x49, 0xd9, 0xbb, 0xec, 0xe3, 0xa2, 0x76, 0xbc, 0x75, 0xa9, 0xba, 0xd0, 0x11, 0x93, 0xba,
|
||||||
0xfa, 0x38, 0x5a, 0x97, 0x91, 0x97, 0xcb, 0x3e, 0x2e, 0xc5, 0x5e, 0x2e, 0x95, 0x97, 0x53, 0x31,
|
0x92, 0x02, 0x6a, 0x41, 0xe2, 0x4e, 0xc5, 0x14, 0x97, 0x75, 0xaa, 0x9d, 0x8a, 0xa9, 0x6c, 0x28,
|
||||||
0xc5, 0x65, 0x9d, 0x80, 0xa7, 0x62, 0x2a, 0xdb, 0x0c, 0x61, 0xbe, 0xdf, 0x75, 0x7b, 0x43, 0x5c,
|
0x84, 0xf9, 0x7e, 0xd7, 0xed, 0x0d, 0x71, 0x45, 0x77, 0xb2, 0x48, 0x96, 0x93, 0x9e, 0x8c, 0xae,
|
||||||
0xd1, 0xfd, 0x2d, 0x92, 0xe5, 0xfc, 0x27, 0xcf, 0xdc, 0x73, 0x7d, 0xf5, 0xa5, 0x50, 0x26, 0x91,
|
0xe7, 0xfa, 0xea, 0x9b, 0xa0, 0x4c, 0x22, 0xd1, 0xd9, 0x81, 0x4a, 0x9c, 0x14, 0xb2, 0x47, 0xb5,
|
||||||
0xe8, 0xec, 0x40, 0x25, 0x4e, 0x15, 0xd9, 0xb9, 0xda, 0x7d, 0xf5, 0x2a, 0x6a, 0x24, 0xd7, 0xee,
|
0xfb, 0x2a, 0xe8, 0x35, 0x92, 0x6b, 0xf7, 0xa3, 0x7c, 0xce, 0xcd, 0xe7, 0x73, 0x3e, 0x91, 0xcf,
|
||||||
0x47, 0x59, 0x9e, 0x9b, 0xcf, 0xf2, 0x7c, 0x22, 0xcb, 0xb7, 0xa1, 0x96, 0x4a, 0x1a, 0x09, 0x22,
|
0xdb, 0x50, 0x4b, 0xa5, 0x87, 0x04, 0x11, 0x76, 0xc9, 0x8d, 0x21, 0xb5, 0x96, 0xba, 0x16, 0xf3,
|
||||||
0xec, 0x92, 0x1b, 0x43, 0x6a, 0x2d, 0x75, 0x2d, 0xe6, 0xeb, 0x6f, 0xe1, 0x1a, 0x51, 0x6b, 0xe7,
|
0xf5, 0x57, 0x6f, 0x8d, 0xa8, 0xb5, 0xf3, 0x1c, 0x6a, 0xa9, 0xc4, 0x58, 0x54, 0x81, 0x9d, 0x67,
|
||||||
0x39, 0xd4, 0x52, 0xe9, 0xb2, 0xa8, 0x2e, 0x3b, 0xcf, 0xa0, 0xd6, 0x11, 0xae, 0x98, 0x2c, 0xf9,
|
0x50, 0xeb, 0x08, 0x57, 0x4c, 0x96, 0xfc, 0x4d, 0xf1, 0x1f, 0x0b, 0xd6, 0x22, 0x8c, 0xa9, 0x31,
|
||||||
0xf3, 0xe2, 0x3f, 0x16, 0xac, 0x45, 0x18, 0x53, 0x79, 0x7e, 0x09, 0xe5, 0x0b, 0x1a, 0x0a, 0x7a,
|
0xbf, 0x84, 0xf2, 0x05, 0x0d, 0x05, 0xbd, 0x8a, 0xbb, 0x0e, 0x9e, 0x1f, 0x34, 0x3f, 0x2a, 0x04,
|
||||||
0x15, 0xf7, 0x22, 0x3c, 0x3f, 0x7e, 0x7e, 0x54, 0x08, 0x12, 0x23, 0xd1, 0x37, 0x50, 0xe6, 0xca,
|
0x89, 0x91, 0xe8, 0x1b, 0x28, 0x73, 0x65, 0x87, 0x46, 0x13, 0xcb, 0x67, 0x59, 0x2c, 0xb3, 0x5f,
|
||||||
0x0e, 0x8d, 0xe6, 0x98, 0xcf, 0xb2, 0x58, 0xc6, 0x5f, 0x8c, 0x47, 0x4d, 0x28, 0xf8, 0x6c, 0xc0,
|
0x8c, 0x47, 0x4d, 0x28, 0xf8, 0x6c, 0xc0, 0xd5, 0x7b, 0xaf, 0x6e, 0x3d, 0xce, 0xe2, 0xbd, 0x63,
|
||||||
0xd5, 0x7b, 0xaf, 0x6e, 0x3d, 0xce, 0xe2, 0xbd, 0x63, 0x03, 0xa2, 0x80, 0xe8, 0x2d, 0x94, 0x2f,
|
0x03, 0xa2, 0x80, 0xe8, 0x2d, 0x94, 0x2f, 0xdd, 0x30, 0xf0, 0x82, 0x41, 0xf4, 0xb5, 0xfc, 0x34,
|
||||||
0xdd, 0x30, 0xf0, 0x82, 0x41, 0xf4, 0x0d, 0xfd, 0x34, 0x8b, 0xf4, 0x83, 0xc6, 0x91, 0x98, 0xe0,
|
0x8b, 0xf4, 0x83, 0xc6, 0x91, 0x98, 0xe0, 0xd4, 0xe4, 0x75, 0x39, 0x63, 0x26, 0x26, 0xce, 0x6f,
|
||||||
0xd4, 0xe4, 0x25, 0x3a, 0x63, 0xe6, 0x4c, 0x9c, 0xdf, 0xc8, 0x5c, 0x96, 0xa2, 0x09, 0xff, 0x10,
|
0x64, 0xd6, 0x4a, 0xd1, 0xb8, 0x7f, 0x08, 0x35, 0x9d, 0xf9, 0x1f, 0x69, 0xc8, 0xe5, 0xfc, 0x67,
|
||||||
0x6a, 0xfa, 0x3e, 0x7c, 0xa4, 0x21, 0x97, 0x53, 0xa1, 0xb5, 0xec, 0xce, 0xee, 0x26, 0xa1, 0x24,
|
0x2d, 0xbb, 0x9d, 0xbb, 0x49, 0x28, 0x49, 0x33, 0x9d, 0x4f, 0xa6, 0xb1, 0x45, 0x0a, 0x99, 0x4b,
|
||||||
0xcd, 0x74, 0x3e, 0x99, 0x76, 0x17, 0x29, 0x64, 0x2e, 0x8d, 0xdd, 0xde, 0xd0, 0x1d, 0x44, 0xef,
|
0x63, 0xb7, 0x37, 0x74, 0x07, 0xd1, 0x7b, 0x8a, 0x44, 0xf9, 0xe4, 0xc2, 0xec, 0xa7, 0x2f, 0x68,
|
||||||
0x29, 0x12, 0xe5, 0x93, 0x0b, 0xe3, 0x4f, 0x5f, 0xdb, 0x48, 0x94, 0xb9, 0x19, 0xd2, 0x0b, 0x8f,
|
0x24, 0xca, 0xdc, 0x0c, 0xe9, 0x85, 0xc7, 0x67, 0xa3, 0x68, 0x2c, 0x6f, 0xfd, 0xa5, 0x04, 0xd0,
|
||||||
0xcf, 0x06, 0xd4, 0x58, 0xde, 0xfa, 0x6b, 0x09, 0xa0, 0x15, 0xef, 0x07, 0x9d, 0xc0, 0x8a, 0xf2,
|
0x8a, 0xcf, 0x83, 0x4e, 0x60, 0x45, 0xed, 0x87, 0x9c, 0xa5, 0x6d, 0x52, 0xf9, 0x6d, 0x3f, 0xbf,
|
||||||
0x87, 0x9c, 0xa5, 0xcd, 0x53, 0xc5, 0x6d, 0x3f, 0xbf, 0x45, 0x83, 0x45, 0x1f, 0x65, 0xf2, 0xab,
|
0x45, 0x2b, 0x45, 0x1f, 0x65, 0xf2, 0xab, 0xf1, 0x06, 0xbd, 0xc8, 0x2a, 0x08, 0xc9, 0x09, 0xc9,
|
||||||
0xa1, 0x07, 0xbd, 0xc8, 0x2a, 0x13, 0xc9, 0xb9, 0xc9, 0x7e, 0x79, 0x03, 0xca, 0xd8, 0xfd, 0x00,
|
0x7e, 0x79, 0x03, 0xca, 0xd8, 0xfd, 0x00, 0x45, 0x9d, 0x05, 0x28, 0xab, 0xea, 0x25, 0xf3, 0xd6,
|
||||||
0x45, 0x9d, 0x05, 0x28, 0xab, 0x16, 0x26, 0xf3, 0xd6, 0x7e, 0xb1, 0x1c, 0xa4, 0x8d, 0x7e, 0x61,
|
0x7e, 0xb1, 0x1c, 0xa4, 0x8d, 0x7e, 0x61, 0x21, 0x62, 0x6a, 0x22, 0x72, 0x96, 0x34, 0x3d, 0x73,
|
||||||
0x21, 0x62, 0x2a, 0x25, 0x72, 0x96, 0xb4, 0x42, 0x73, 0x63, 0xb2, 0x0e, 0x20, 0xd5, 0x75, 0xea,
|
0x63, 0xb2, 0x02, 0x90, 0xea, 0x2f, 0x75, 0x0b, 0x7d, 0x0f, 0x45, 0x5d, 0xd5, 0xd0, 0x4f, 0x17,
|
||||||
0x16, 0xfa, 0x1e, 0x8a, 0xba, 0xd6, 0xa1, 0x9f, 0x2e, 0x26, 0x44, 0xf6, 0x96, 0x3f, 0xae, 0x5b,
|
0x13, 0x22, 0x7b, 0xcb, 0x1f, 0xd7, 0xad, 0x2f, 0x2c, 0xf4, 0x1e, 0x0a, 0xb2, 0x9d, 0xa3, 0x8c,
|
||||||
0x5f, 0x58, 0xe8, 0x3d, 0x14, 0x64, 0x93, 0x47, 0x19, 0x1d, 0x2b, 0x31, 0x21, 0xd8, 0xce, 0x32,
|
0xde, 0x94, 0x98, 0x05, 0x6c, 0x67, 0x19, 0xc4, 0x44, 0xf1, 0x13, 0xc0, 0x6c, 0xa8, 0x40, 0x19,
|
||||||
0x88, 0x39, 0xc5, 0x4f, 0x00, 0xb3, 0x51, 0x03, 0x65, 0xfc, 0x13, 0x32, 0x37, 0xb3, 0xd8, 0xf5,
|
0xff, 0x79, 0xcc, 0x4d, 0x27, 0x76, 0xfd, 0x66, 0xa0, 0xd9, 0xe0, 0xbd, 0xec, 0xa8, 0x67, 0x0c,
|
||||||
0x9b, 0x81, 0xc6, 0xc1, 0x7b, 0xd9, 0x67, 0xcf, 0x18, 0xca, 0xec, 0xb0, 0xf1, 0x35, 0xb2, 0x9d,
|
0x65, 0xf6, 0xd2, 0xf8, 0x1a, 0xd9, 0xce, 0x32, 0x88, 0x31, 0x77, 0x0e, 0xb5, 0xd4, 0x7f, 0xa2,
|
||||||
0x65, 0x10, 0x63, 0xee, 0x1c, 0x6a, 0xa9, 0x7f, 0x4a, 0xd1, 0xcf, 0xb3, 0x83, 0xbc, 0xfe, 0xc7,
|
0xe8, 0xe7, 0xd9, 0x4e, 0x5e, 0xff, 0x8b, 0xd5, 0x7e, 0x75, 0x2b, 0xac, 0xd9, 0x49, 0x24, 0xa7,
|
||||||
0xab, 0xfd, 0xea, 0x56, 0x58, 0xe3, 0x49, 0x24, 0x67, 0x35, 0xf3, 0x18, 0x35, 0x6e, 0x8a, 0x3b,
|
0x32, 0xf3, 0x18, 0x35, 0x6e, 0xf2, 0x3b, 0xfd, 0xff, 0xa6, 0xdd, 0xbc, 0x35, 0x5e, 0xef, 0xba,
|
||||||
0xfd, 0xaf, 0xa7, 0xdd, 0xbc, 0x35, 0x5e, 0x7b, 0xdd, 0x2d, 0xfc, 0x36, 0x37, 0xee, 0x76, 0x8b,
|
0x5b, 0xf8, 0x6d, 0x6e, 0xdc, 0xed, 0x16, 0xd5, 0x5f, 0xc5, 0x5f, 0xfd, 0x37, 0x00, 0x00, 0xff,
|
||||||
0xea, 0x0f, 0xe4, 0xaf, 0xfe, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x18, 0x4b, 0xe5, 0x8f, 0xde, 0x16,
|
0xff, 0xc1, 0x4b, 0x2d, 0x65, 0xc8, 0x16, 0x00, 0x00,
|
||||||
0x00, 0x00,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reference imports to suppress errors if they are not otherwise used.
|
// Reference imports to suppress errors if they are not otherwise used.
|
||||||
|
|||||||
@@ -192,7 +192,6 @@ message InitMessage {
|
|||||||
message InvokeConfig {
|
message InvokeConfig {
|
||||||
repeated string Entrypoint = 1;
|
repeated string Entrypoint = 1;
|
||||||
repeated string Cmd = 2;
|
repeated string Cmd = 2;
|
||||||
bool NoCmd = 11; // Do not set cmd but use the image's default
|
|
||||||
repeated string Env = 3;
|
repeated string Env = 3;
|
||||||
string User = 4;
|
string User = 4;
|
||||||
bool NoUser = 5; // Do not set user but use the image's default
|
bool NoUser = 5; // Do not set user but use the image's default
|
||||||
|
|||||||
@@ -57,7 +57,9 @@ func (m *Server) ListProcesses(ctx context.Context, req *pb.ListProcessesRequest
|
|||||||
return nil, errors.Errorf("unknown ref %q", req.Ref)
|
return nil, errors.Errorf("unknown ref %q", req.Ref)
|
||||||
}
|
}
|
||||||
res = new(pb.ListProcessesResponse)
|
res = new(pb.ListProcessesResponse)
|
||||||
res.Infos = append(res.Infos, s.processes.ListProcesses()...)
|
for _, p := range s.processes.ListProcesses() {
|
||||||
|
res.Infos = append(res.Infos, p)
|
||||||
|
}
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
variable "GO_VERSION" {
|
variable "GO_VERSION" {
|
||||||
default = null
|
default = "1.20"
|
||||||
}
|
}
|
||||||
variable "DOCS_FORMATS" {
|
variable "DOCS_FORMATS" {
|
||||||
default = "md"
|
default = "md"
|
||||||
|
|||||||
@@ -116,12 +116,12 @@ Available commands are:
|
|||||||
disconnect disconnect a client from a buildx server. Specific session ID can be specified an arg
|
disconnect disconnect a client from a buildx server. Specific session ID can be specified an arg
|
||||||
exec execute a process in the interactive container
|
exec execute a process in the interactive container
|
||||||
exit exits monitor
|
exit exits monitor
|
||||||
help shows this message. Optionally pass a command name as an argument to print the detailed usage.
|
help shows this message
|
||||||
kill kill buildx server
|
kill kill buildx server
|
||||||
list list buildx sessions
|
list list buildx sessions
|
||||||
ps list processes invoked by "exec". Use "attach" to attach IO to that process
|
ps list processes invoked by "exec". Use "attach" to attach IO to that process
|
||||||
reload reloads the context and build it
|
reload reloads the context and build it
|
||||||
rollback re-runs the interactive container with the step's rootfs contents
|
rollback re-runs the interactive container with initial rootfs contents
|
||||||
```
|
```
|
||||||
|
|
||||||
## Build controllers
|
## Build controllers
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Start a build
|
|||||||
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
|
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
|
||||||
| [`--cache-from`](#cache-from) | `stringArray` | | External cache sources (e.g., `user/app:cache`, `type=local,src=path/to/dir`) |
|
| [`--cache-from`](#cache-from) | `stringArray` | | External cache sources (e.g., `user/app:cache`, `type=local,src=path/to/dir`) |
|
||||||
| [`--cache-to`](#cache-to) | `stringArray` | | Cache export destinations (e.g., `user/app:cache`, `type=local,dest=path/to/dir`) |
|
| [`--cache-to`](#cache-to) | `stringArray` | | Cache export destinations (e.g., `user/app:cache`, `type=local,dest=path/to/dir`) |
|
||||||
| [`--cgroup-parent`](https://docs.docker.com/engine/reference/commandline/build/#cgroup-parent) | `string` | | Set the parent cgroup for the `RUN` instructions during build |
|
| [`--cgroup-parent`](https://docs.docker.com/engine/reference/commandline/build/#cgroup-parent) | `string` | | Optional parent cgroup for the container |
|
||||||
| `--detach` | | | Detach buildx server (supported only on linux) |
|
| `--detach` | | | Detach buildx server (supported only on linux) |
|
||||||
| [`-f`](https://docs.docker.com/engine/reference/commandline/build/#file), [`--file`](https://docs.docker.com/engine/reference/commandline/build/#file) | `string` | | Name of the Dockerfile (default: `PATH/Dockerfile`) |
|
| [`-f`](https://docs.docker.com/engine/reference/commandline/build/#file), [`--file`](https://docs.docker.com/engine/reference/commandline/build/#file) | `string` | | Name of the Dockerfile (default: `PATH/Dockerfile`) |
|
||||||
| `--iidfile` | `string` | | Write the image ID to the file |
|
| `--iidfile` | `string` | | Write the image ID to the file |
|
||||||
@@ -125,6 +125,7 @@ Same as [`docker build` command](https://docs.docker.com/engine/reference/comman
|
|||||||
There are also useful built-in build args like:
|
There are also useful built-in build args like:
|
||||||
|
|
||||||
* `BUILDKIT_CONTEXT_KEEP_GIT_DIR=<bool>` trigger git context to keep the `.git` directory
|
* `BUILDKIT_CONTEXT_KEEP_GIT_DIR=<bool>` trigger git context to keep the `.git` directory
|
||||||
|
* `BUILDKIT_INLINE_BUILDINFO_ATTRS=<bool>` inline build info attributes in image config or not
|
||||||
* `BUILDKIT_INLINE_CACHE=<bool>` inline cache metadata to image config or not
|
* `BUILDKIT_INLINE_CACHE=<bool>` inline cache metadata to image config or not
|
||||||
* `BUILDKIT_MULTI_PLATFORM=<bool>` opt into deterministic output regardless of multi-platform output or not
|
* `BUILDKIT_MULTI_PLATFORM=<bool>` opt into deterministic output regardless of multi-platform output or not
|
||||||
|
|
||||||
@@ -285,6 +286,26 @@ $ cat metadata.json
|
|||||||
```
|
```
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
"containerimage.buildinfo": {
|
||||||
|
"frontend": "dockerfile.v0",
|
||||||
|
"attrs": {
|
||||||
|
"context": "https://github.com/crazy-max/buildkit-buildsources-test.git#master",
|
||||||
|
"filename": "Dockerfile",
|
||||||
|
"source": "docker/dockerfile:master"
|
||||||
|
},
|
||||||
|
"sources": [
|
||||||
|
{
|
||||||
|
"type": "docker-image",
|
||||||
|
"ref": "docker.io/docker/buildx-bin:0.6.1@sha256:a652ced4a4141977c7daaed0a074dcd9844a78d7d2615465b12f433ae6dd29f0",
|
||||||
|
"pin": "sha256:a652ced4a4141977c7daaed0a074dcd9844a78d7d2615465b12f433ae6dd29f0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "docker-image",
|
||||||
|
"ref": "docker.io/library/alpine:3.13",
|
||||||
|
"pin": "sha256:026f721af4cf2843e07bba648e158fb35ecc876d822130633cc49f707f0fc88c"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"containerimage.config.digest": "sha256:2937f66a9722f7f4a2df583de2f8cb97fc9196059a410e7f00072fc918930e66",
|
"containerimage.config.digest": "sha256:2937f66a9722f7f4a2df583de2f8cb97fc9196059a410e7f00072fc918930e66",
|
||||||
"containerimage.descriptor": {
|
"containerimage.descriptor": {
|
||||||
"annotations": {
|
"annotations": {
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ to achieve that.
|
|||||||
|
|
||||||
Passes additional driver-specific options.
|
Passes additional driver-specific options.
|
||||||
|
|
||||||
Note: When using quoted values for the `nodeselector`, `annotations`, `labels` or
|
Note: When using quoted values for example for the `nodeselector` or
|
||||||
`tolerations` options, ensure that quotes are escaped correctly for your shell.
|
`tolerations` options, ensure that quotes are escaped correctly for your shell.
|
||||||
|
|
||||||
#### `docker` driver
|
#### `docker` driver
|
||||||
@@ -165,8 +165,6 @@ No driver options.
|
|||||||
- `limits.memory` - Sets the limit memory value specified in bytes or with a valid suffix. Example `limits.memory=500Mi`, `limits.memory=4G`
|
- `limits.memory` - Sets the limit memory value specified in bytes or with a valid suffix. Example `limits.memory=500Mi`, `limits.memory=4G`
|
||||||
- `serviceaccount` - Sets the created pod's service account. Example `serviceaccount=example-sa`
|
- `serviceaccount` - Sets the created pod's service account. Example `serviceaccount=example-sa`
|
||||||
- `"nodeselector=label1=value1,label2=value2"` - Sets the kv of `Pod` nodeSelector. No Defaults. Example `nodeselector=kubernetes.io/arch=arm64`
|
- `"nodeselector=label1=value1,label2=value2"` - Sets the kv of `Pod` nodeSelector. No Defaults. Example `nodeselector=kubernetes.io/arch=arm64`
|
||||||
- `"annotations=domain/thing1=value1,domain/thing2=value2"` - Sets additional annotations on the deployments and pods. No Defaults. Example `annotations=example.com/owner=sarah`
|
|
||||||
- `"labels=domain/thing1=value1,domain/thing2=value2"` - Sets additional labels on the deployments and pods. No Defaults. Example `labels=example.com/team=rd`
|
|
||||||
- `"tolerations=key=foo,value=bar;key=foo2,operator=exists;key=foo3,effect=NoSchedule"` - Sets the `Pod` tolerations. Accepts the same values as the kube manifest tolera>tions. Key-value pairs are separated by `,`, tolerations are separated by `;`. No Defaults. Example `tolerations=operator=exists`
|
- `"tolerations=key=foo,value=bar;key=foo2,operator=exists;key=foo3,effect=NoSchedule"` - Sets the `Pod` tolerations. Accepts the same values as the kube manifest tolera>tions. Key-value pairs are separated by `,`, tolerations are separated by `;`. No Defaults. Example `tolerations=operator=exists`
|
||||||
- `rootless=(true|false)` - Run the container as a non-root user without `securityContext.privileged`. Needs Kubernetes 1.19 or later. [Using Ubuntu host kernel is recommended](https://github.com/moby/buildkit/blob/master/docs/rootless.md). Defaults to false.
|
- `rootless=(true|false)` - Run the container as a non-root user without `securityContext.privileged`. Needs Kubernetes 1.19 or later. [Using Ubuntu host kernel is recommended](https://github.com/moby/buildkit/blob/master/docs/rootless.md). Defaults to false.
|
||||||
- `loadbalance=(sticky|random)` - Load-balancing strategy. If set to "sticky", the pod is chosen using the hash of the context path. Defaults to "sticky"
|
- `loadbalance=(sticky|random)` - Load-balancing strategy. If set to "sticky", the pod is chosen using the hash of the context path. Defaults to "sticky"
|
||||||
@@ -223,7 +221,7 @@ building for the same platform.
|
|||||||
|
|
||||||
```console
|
```console
|
||||||
$ docker buildx create --platform linux/amd64
|
$ docker buildx create --platform linux/amd64
|
||||||
$ docker buildx create --platform linux/arm64,linux/arm/v7
|
$ docker buildx create --platform linux/arm64,linux/arm/v8
|
||||||
```
|
```
|
||||||
|
|
||||||
### <a name="use"></a> Automatically switch to the newly created builder (--use)
|
### <a name="use"></a> Automatically switch to the newly created builder (--use)
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ Create a new image based on source images
|
|||||||
|
|
||||||
| Name | Type | Default | Description |
|
| Name | Type | Default | Description |
|
||||||
|:---------------------------------|:--------------|:--------|:-----------------------------------------------------------------------------------------|
|
|:---------------------------------|:--------------|:--------|:-----------------------------------------------------------------------------------------|
|
||||||
| `--annotation` | `stringArray` | | Add annotation to the image |
|
|
||||||
| [`--append`](#append) | | | Append to existing manifest |
|
| [`--append`](#append) | | | Append to existing manifest |
|
||||||
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
|
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
|
||||||
| [`--dry-run`](#dry-run) | | | Show final image instead of pushing |
|
| [`--dry-run`](#dry-run) | | | Show final image instead of pushing |
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@@ -23,7 +22,6 @@ import (
|
|||||||
"github.com/docker/docker/api/types/mount"
|
"github.com/docker/docker/api/types/mount"
|
||||||
"github.com/docker/docker/api/types/network"
|
"github.com/docker/docker/api/types/network"
|
||||||
dockerclient "github.com/docker/docker/client"
|
dockerclient "github.com/docker/docker/client"
|
||||||
"github.com/docker/docker/errdefs"
|
|
||||||
dockerarchive "github.com/docker/docker/pkg/archive"
|
dockerarchive "github.com/docker/docker/pkg/archive"
|
||||||
"github.com/docker/docker/pkg/idtools"
|
"github.com/docker/docker/pkg/idtools"
|
||||||
"github.com/docker/docker/pkg/stdcopy"
|
"github.com/docker/docker/pkg/stdcopy"
|
||||||
@@ -42,7 +40,6 @@ type Driver struct {
|
|||||||
netMode string
|
netMode string
|
||||||
image string
|
image string
|
||||||
cgroupParent string
|
cgroupParent string
|
||||||
securityOpts map[string]string
|
|
||||||
env []string
|
env []string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,6 +108,7 @@ func (d *Driver) create(ctx context.Context, l progress.SubLogger) error {
|
|||||||
if d.InitConfig.BuildkitFlags != nil {
|
if d.InitConfig.BuildkitFlags != nil {
|
||||||
cfg.Cmd = d.InitConfig.BuildkitFlags
|
cfg.Cmd = d.InitConfig.BuildkitFlags
|
||||||
}
|
}
|
||||||
|
|
||||||
useInit := true // let it cleanup exited processes created by BuildKit's container API
|
useInit := true // let it cleanup exited processes created by BuildKit's container API
|
||||||
if err := l.Wrap("creating container "+d.Name, func() error {
|
if err := l.Wrap("creating container "+d.Name, func() error {
|
||||||
hc := &container.HostConfig{
|
hc := &container.HostConfig{
|
||||||
@@ -128,13 +126,6 @@ func (d *Driver) create(ctx context.Context, l progress.SubLogger) error {
|
|||||||
hc.NetworkMode = container.NetworkMode(d.netMode)
|
hc.NetworkMode = container.NetworkMode(d.netMode)
|
||||||
}
|
}
|
||||||
if info, err := d.DockerAPI.Info(ctx); err == nil {
|
if info, err := d.DockerAPI.Info(ctx); err == nil {
|
||||||
secOpts, err := dockertypes.DecodeSecurityOptions(info.SecurityOptions)
|
|
||||||
l.Wrap("driverOpts"+info.CgroupDriver, func() error {
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if info.CgroupDriver == "cgroupfs" {
|
if info.CgroupDriver == "cgroupfs" {
|
||||||
// Place all buildkit containers inside this cgroup by default so limits can be attached
|
// Place all buildkit containers inside this cgroup by default so limits can be attached
|
||||||
// to all build activity on the host.
|
// to all build activity on the host.
|
||||||
@@ -143,39 +134,28 @@ func (d *Driver) create(ctx context.Context, l progress.SubLogger) error {
|
|||||||
hc.CgroupParent = d.cgroupParent
|
hc.CgroupParent = d.cgroupParent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
secOpts, err := dockertypes.DecodeSecurityOptions(info.SecurityOptions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
for _, f := range secOpts {
|
for _, f := range secOpts {
|
||||||
if f.Name == "userns" {
|
if f.Name == "userns" {
|
||||||
hc.UsernsMode = "host"
|
hc.UsernsMode = "host"
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i, k := range d.securityOpts {
|
|
||||||
switch {
|
|
||||||
case i == "systempaths":
|
|
||||||
hc.MaskedPaths = []string{}
|
|
||||||
hc.ReadonlyPaths = []string{}
|
|
||||||
case i == "privileged":
|
|
||||||
val, err := strconv.ParseBool(k)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Errorf("invalid value privleged security option, options are true/false")
|
|
||||||
}
|
|
||||||
hc.Privileged = val
|
|
||||||
default:
|
|
||||||
hc.SecurityOpt = append(hc.SecurityOpt, i+"="+k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_, err := d.DockerAPI.ContainerCreate(ctx, cfg, hc, &network.NetworkingConfig{}, nil, d.Name)
|
_, err := d.DockerAPI.ContainerCreate(ctx, cfg, hc, &network.NetworkingConfig{}, nil, d.Name)
|
||||||
if err != nil && !errdefs.IsConflict(err) {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err := d.copyToContainer(ctx, d.InitConfig.Files); err != nil {
|
||||||
if err := d.copyToContainer(ctx, d.InitConfig.Files); err != nil {
|
return err
|
||||||
return err
|
}
|
||||||
}
|
if err := d.start(ctx, l); err != nil {
|
||||||
if err := d.start(ctx, l); err != nil {
|
return err
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if err := d.wait(ctx, l); err != nil {
|
if err := d.wait(ctx, l); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver
|
|||||||
return nil, errors.Errorf("%s driver requires docker API access", f.Name())
|
return nil, errors.Errorf("%s driver requires docker API access", f.Name())
|
||||||
}
|
}
|
||||||
d := &Driver{factory: f, InitConfig: cfg}
|
d := &Driver{factory: f, InitConfig: cfg}
|
||||||
d.securityOpts = make(map[string]string)
|
|
||||||
for k, v := range cfg.DriverOpts {
|
for k, v := range cfg.DriverOpts {
|
||||||
switch {
|
switch {
|
||||||
case k == "network":
|
case k == "network":
|
||||||
@@ -58,32 +57,11 @@ func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver
|
|||||||
return nil, errors.Errorf("invalid env option %q, expecting env.FOO=bar", k)
|
return nil, errors.Errorf("invalid env option %q, expecting env.FOO=bar", k)
|
||||||
}
|
}
|
||||||
d.env = append(d.env, fmt.Sprintf("%s=%s", envName, v))
|
d.env = append(d.env, fmt.Sprintf("%s=%s", envName, v))
|
||||||
case k == "seccomp":
|
|
||||||
d.securityOpts[k] = v
|
|
||||||
case k == "apparmor":
|
|
||||||
d.securityOpts[k] = v
|
|
||||||
case k == "systempaths":
|
|
||||||
d.securityOpts[k] = v
|
|
||||||
case k == "privileged":
|
|
||||||
d.securityOpts[k] = v
|
|
||||||
default:
|
default:
|
||||||
return nil, errors.Errorf("invalid driver option %s for docker-container driver", k)
|
return nil, errors.Errorf("invalid driver option %s for docker-container driver", k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i, _ := range cfg.SecurityOpts {
|
|
||||||
switch {
|
|
||||||
case i == "seccomp":
|
|
||||||
continue
|
|
||||||
case i == "apparmor":
|
|
||||||
continue
|
|
||||||
case i == "systempaths":
|
|
||||||
continue
|
|
||||||
case i == "privileged":
|
|
||||||
continue
|
|
||||||
default:
|
|
||||||
return nil, errors.Errorf("invalid Security option %s for docker-container driver", i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return d, nil
|
return d, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ func Boot(ctx, clientContext context.Context, d *DriverHandle, pw progress.Write
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c, err := d.Client(clientContext)
|
c, err := d.Client(clientContext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Cause(err) == ErrNotRunning && try <= 2 {
|
if errors.Cause(err) == ErrNotRunning && try <= 2 {
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ type EndpointMeta struct {
|
|||||||
AuthProvider *clientcmdapi.AuthProviderConfig `json:",omitempty"`
|
AuthProvider *clientcmdapi.AuthProviderConfig `json:",omitempty"`
|
||||||
Exec *clientcmdapi.ExecConfig `json:",omitempty"`
|
Exec *clientcmdapi.ExecConfig `json:",omitempty"`
|
||||||
UsernamePassword *UsernamePassword `json:"usernamePassword,omitempty"`
|
UsernamePassword *UsernamePassword `json:"usernamePassword,omitempty"`
|
||||||
Token string `json:"token,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UsernamePassword contains username/password auth info
|
// UsernamePassword contains username/password auth info
|
||||||
@@ -78,9 +77,6 @@ func (c *Endpoint) KubernetesConfig() clientcmd.ClientConfig {
|
|||||||
authInfo.Username = c.UsernamePassword.Username
|
authInfo.Username = c.UsernamePassword.Username
|
||||||
authInfo.Password = c.UsernamePassword.Password
|
authInfo.Password = c.UsernamePassword.Password
|
||||||
}
|
}
|
||||||
if c.Token != "" {
|
|
||||||
authInfo.Token = c.Token
|
|
||||||
}
|
|
||||||
authInfo.AuthProvider = c.AuthProvider
|
authInfo.AuthProvider = c.AuthProvider
|
||||||
authInfo.Exec = c.Exec
|
authInfo.Exec = c.Exec
|
||||||
cfg.Clusters["cluster"] = cluster
|
cfg.Clusters["cluster"] = cluster
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ func FromKubeConfig(kubeconfig, kubeContext, namespaceOverride string) (Endpoint
|
|||||||
AuthProvider: clientcfg.AuthProvider,
|
AuthProvider: clientcfg.AuthProvider,
|
||||||
Exec: clientcfg.ExecProvider,
|
Exec: clientcfg.ExecProvider,
|
||||||
UsernamePassword: usernamePassword,
|
UsernamePassword: usernamePassword,
|
||||||
Token: clientcfg.BearerToken,
|
|
||||||
},
|
},
|
||||||
TLSData: tlsData,
|
TLSData: tlsData,
|
||||||
}, nil
|
}, nil
|
||||||
|
|||||||
@@ -148,20 +148,15 @@ func (f *factory) processDriverOpts(deploymentName string, namespace string, cfg
|
|||||||
case "serviceaccount":
|
case "serviceaccount":
|
||||||
deploymentOpt.ServiceAccountName = v
|
deploymentOpt.ServiceAccountName = v
|
||||||
case "nodeselector":
|
case "nodeselector":
|
||||||
deploymentOpt.NodeSelector, err = splitMultiValues(v, ",", "=")
|
kvs := strings.Split(strings.Trim(v, `"`), ",")
|
||||||
if err != nil {
|
s := map[string]string{}
|
||||||
return nil, "", "", errors.Wrap(err, "cannot parse node selector")
|
for i := range kvs {
|
||||||
}
|
kv := strings.Split(kvs[i], "=")
|
||||||
case "annotations":
|
if len(kv) == 2 {
|
||||||
deploymentOpt.CustomAnnotations, err = splitMultiValues(v, ",", "=")
|
s[kv[0]] = kv[1]
|
||||||
if err != nil {
|
}
|
||||||
return nil, "", "", errors.Wrap(err, "cannot parse annotations")
|
|
||||||
}
|
|
||||||
case "labels":
|
|
||||||
deploymentOpt.CustomLabels, err = splitMultiValues(v, ",", "=")
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", "", errors.Wrap(err, "cannot parse labels")
|
|
||||||
}
|
}
|
||||||
|
deploymentOpt.NodeSelector = s
|
||||||
case "tolerations":
|
case "tolerations":
|
||||||
ts := strings.Split(v, ";")
|
ts := strings.Split(v, ";")
|
||||||
deploymentOpt.Tolerations = []corev1.Toleration{}
|
deploymentOpt.Tolerations = []corev1.Toleration{}
|
||||||
@@ -222,19 +217,6 @@ func (f *factory) processDriverOpts(deploymentName string, namespace string, cfg
|
|||||||
return deploymentOpt, loadbalance, namespace, nil
|
return deploymentOpt, loadbalance, namespace, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func splitMultiValues(in string, itemsep string, kvsep string) (map[string]string, error) {
|
|
||||||
kvs := strings.Split(strings.Trim(in, `"`), itemsep)
|
|
||||||
s := map[string]string{}
|
|
||||||
for i := range kvs {
|
|
||||||
kv := strings.Split(kvs[i], kvsep)
|
|
||||||
if len(kv) != 2 {
|
|
||||||
return nil, errors.Errorf("invalid key-value pair: %s", kvs[i])
|
|
||||||
}
|
|
||||||
s[kv[0]] = kv[1]
|
|
||||||
}
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *factory) AllowsInstances() bool {
|
func (f *factory) AllowsInstances() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,13 +47,13 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
"rootless": "true",
|
"rootless": "true",
|
||||||
"nodeselector": "selector1=value1,selector2=value2",
|
"nodeselector": "selector1=value1,selector2=value2",
|
||||||
"tolerations": "key=tolerationKey1,value=tolerationValue1,operator=Equal,effect=NoSchedule,tolerationSeconds=60;key=tolerationKey2,operator=Exists",
|
"tolerations": "key=tolerationKey1,value=tolerationValue1,operator=Equal,effect=NoSchedule,tolerationSeconds=60;key=tolerationKey2,operator=Exists",
|
||||||
"annotations": "example.com/expires-after=annotation1,example.com/other=annotation2",
|
|
||||||
"labels": "example.com/owner=label1,example.com/other=label2",
|
|
||||||
"loadbalance": "random",
|
"loadbalance": "random",
|
||||||
"qemu.install": "true",
|
"qemu.install": "true",
|
||||||
"qemu.image": "qemu:latest",
|
"qemu.image": "qemu:latest",
|
||||||
}
|
}
|
||||||
r, loadbalance, ns, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
ns := "test"
|
||||||
|
|
||||||
|
r, loadbalance, ns, err := f.processDriverOpts(cfg.Name, ns, cfg)
|
||||||
|
|
||||||
nodeSelectors := map[string]string{
|
nodeSelectors := map[string]string{
|
||||||
"selector1": "value1",
|
"selector1": "value1",
|
||||||
@@ -75,16 +75,6 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
customAnnotations := map[string]string{
|
|
||||||
"example.com/expires-after": "annotation1",
|
|
||||||
"example.com/other": "annotation2",
|
|
||||||
}
|
|
||||||
|
|
||||||
customLabels := map[string]string{
|
|
||||||
"example.com/owner": "label1",
|
|
||||||
"example.com/other": "label2",
|
|
||||||
}
|
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Equal(t, "test-ns", ns)
|
require.Equal(t, "test-ns", ns)
|
||||||
@@ -96,8 +86,6 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
require.Equal(t, "64Mi", r.LimitsMemory)
|
require.Equal(t, "64Mi", r.LimitsMemory)
|
||||||
require.True(t, r.Rootless)
|
require.True(t, r.Rootless)
|
||||||
require.Equal(t, nodeSelectors, r.NodeSelector)
|
require.Equal(t, nodeSelectors, r.NodeSelector)
|
||||||
require.Equal(t, customAnnotations, r.CustomAnnotations)
|
|
||||||
require.Equal(t, customLabels, r.CustomLabels)
|
|
||||||
require.Equal(t, tolerations, r.Tolerations)
|
require.Equal(t, tolerations, r.Tolerations)
|
||||||
require.Equal(t, LoadbalanceRandom, loadbalance)
|
require.Equal(t, LoadbalanceRandom, loadbalance)
|
||||||
require.True(t, r.Qemu.Install)
|
require.True(t, r.Qemu.Install)
|
||||||
@@ -122,8 +110,6 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
require.Equal(t, "", r.LimitsMemory)
|
require.Equal(t, "", r.LimitsMemory)
|
||||||
require.False(t, r.Rootless)
|
require.False(t, r.Rootless)
|
||||||
require.Empty(t, r.NodeSelector)
|
require.Empty(t, r.NodeSelector)
|
||||||
require.Empty(t, r.CustomAnnotations)
|
|
||||||
require.Empty(t, r.CustomLabels)
|
|
||||||
require.Empty(t, r.Tolerations)
|
require.Empty(t, r.Tolerations)
|
||||||
require.Equal(t, LoadbalanceSticky, loadbalance)
|
require.Equal(t, LoadbalanceSticky, loadbalance)
|
||||||
require.False(t, r.Qemu.Install)
|
require.False(t, r.Qemu.Install)
|
||||||
@@ -151,8 +137,6 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
require.Equal(t, "", r.LimitsMemory)
|
require.Equal(t, "", r.LimitsMemory)
|
||||||
require.True(t, r.Rootless)
|
require.True(t, r.Rootless)
|
||||||
require.Empty(t, r.NodeSelector)
|
require.Empty(t, r.NodeSelector)
|
||||||
require.Empty(t, r.CustomAnnotations)
|
|
||||||
require.Empty(t, r.CustomLabels)
|
|
||||||
require.Empty(t, r.Tolerations)
|
require.Empty(t, r.Tolerations)
|
||||||
require.Equal(t, LoadbalanceSticky, loadbalance)
|
require.Equal(t, LoadbalanceSticky, loadbalance)
|
||||||
require.False(t, r.Qemu.Install)
|
require.False(t, r.Qemu.Install)
|
||||||
@@ -165,7 +149,9 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
cfg.DriverOpts = map[string]string{
|
cfg.DriverOpts = map[string]string{
|
||||||
"replicas": "invalid",
|
"replicas": "invalid",
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
|
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -175,7 +161,9 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
cfg.DriverOpts = map[string]string{
|
cfg.DriverOpts = map[string]string{
|
||||||
"rootless": "invalid",
|
"rootless": "invalid",
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
|
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -185,7 +173,9 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
cfg.DriverOpts = map[string]string{
|
cfg.DriverOpts = map[string]string{
|
||||||
"tolerations": "key=foo,value=bar,invalid=foo2",
|
"tolerations": "key=foo,value=bar,invalid=foo2",
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
|
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -195,27 +185,9 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
cfg.DriverOpts = map[string]string{
|
cfg.DriverOpts = map[string]string{
|
||||||
"tolerations": "key=foo,value=bar,tolerationSeconds=invalid",
|
"tolerations": "key=foo,value=bar,tolerationSeconds=invalid",
|
||||||
}
|
}
|
||||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
|
||||||
require.Error(t, err)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
t.Run(
|
|
||||||
"InvalidCustomAnnotation", func(t *testing.T) {
|
|
||||||
cfg.DriverOpts = map[string]string{
|
|
||||||
"annotations": "key,value",
|
|
||||||
}
|
|
||||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
require.Error(t, err)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
t.Run(
|
|
||||||
"InvalidCustomLabel", func(t *testing.T) {
|
|
||||||
cfg.DriverOpts = map[string]string{
|
|
||||||
"labels": "key=value=foo",
|
|
||||||
}
|
|
||||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -225,7 +197,9 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
cfg.DriverOpts = map[string]string{
|
cfg.DriverOpts = map[string]string{
|
||||||
"loadbalance": "invalid",
|
"loadbalance": "invalid",
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
|
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -235,7 +209,9 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
cfg.DriverOpts = map[string]string{
|
cfg.DriverOpts = map[string]string{
|
||||||
"qemu.install": "invalid",
|
"qemu.install": "invalid",
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
|
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -245,7 +221,9 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
cfg.DriverOpts = map[string]string{
|
cfg.DriverOpts = map[string]string{
|
||||||
"invalid": "foo",
|
"invalid": "foo",
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
|
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
|
|
||||||
"github.com/docker/buildx/util/platformutil"
|
"github.com/docker/buildx/util/platformutil"
|
||||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/pkg/errors"
|
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
@@ -32,32 +31,24 @@ type DeploymentOpt struct {
|
|||||||
// files mounted at /etc/buildkitd
|
// files mounted at /etc/buildkitd
|
||||||
ConfigFiles map[string][]byte
|
ConfigFiles map[string][]byte
|
||||||
|
|
||||||
Rootless bool
|
Rootless bool
|
||||||
NodeSelector map[string]string
|
NodeSelector map[string]string
|
||||||
CustomAnnotations map[string]string
|
Tolerations []corev1.Toleration
|
||||||
CustomLabels map[string]string
|
RequestsCPU string
|
||||||
Tolerations []corev1.Toleration
|
RequestsMemory string
|
||||||
RequestsCPU string
|
LimitsCPU string
|
||||||
RequestsMemory string
|
LimitsMemory string
|
||||||
LimitsCPU string
|
Platforms []v1.Platform
|
||||||
LimitsMemory string
|
|
||||||
Platforms []v1.Platform
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
containerName = "buildkitd"
|
containerName = "buildkitd"
|
||||||
AnnotationPlatform = "buildx.docker.com/platform"
|
AnnotationPlatform = "buildx.docker.com/platform"
|
||||||
LabelApp = "app"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrReservedAnnotationPlatform = errors.Errorf("the annotation \"%s\" is reserved and cannot be customized", AnnotationPlatform)
|
|
||||||
ErrReservedLabelApp = errors.Errorf("the label \"%s\" is reserved and cannot be customized", LabelApp)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewDeployment(opt *DeploymentOpt) (d *appsv1.Deployment, c []*corev1.ConfigMap, err error) {
|
func NewDeployment(opt *DeploymentOpt) (d *appsv1.Deployment, c []*corev1.ConfigMap, err error) {
|
||||||
labels := map[string]string{
|
labels := map[string]string{
|
||||||
LabelApp: opt.Name,
|
"app": opt.Name,
|
||||||
}
|
}
|
||||||
annotations := map[string]string{}
|
annotations := map[string]string{}
|
||||||
replicas := int32(opt.Replicas)
|
replicas := int32(opt.Replicas)
|
||||||
@@ -68,20 +59,6 @@ func NewDeployment(opt *DeploymentOpt) (d *appsv1.Deployment, c []*corev1.Config
|
|||||||
annotations[AnnotationPlatform] = strings.Join(platformutil.Format(opt.Platforms), ",")
|
annotations[AnnotationPlatform] = strings.Join(platformutil.Format(opt.Platforms), ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range opt.CustomAnnotations {
|
|
||||||
if k == AnnotationPlatform {
|
|
||||||
return nil, nil, ErrReservedAnnotationPlatform
|
|
||||||
}
|
|
||||||
annotations[k] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
for k, v := range opt.CustomLabels {
|
|
||||||
if k == LabelApp {
|
|
||||||
return nil, nil, ErrReservedLabelApp
|
|
||||||
}
|
|
||||||
labels[k] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
d = &appsv1.Deployment{
|
d = &appsv1.Deployment{
|
||||||
TypeMeta: metav1.TypeMeta{
|
TypeMeta: metav1.TypeMeta{
|
||||||
APIVersion: appsv1.SchemeGroupVersion.String(),
|
APIVersion: appsv1.SchemeGroupVersion.String(),
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ type InitConfig struct {
|
|||||||
BuildkitFlags []string
|
BuildkitFlags []string
|
||||||
Files map[string][]byte
|
Files map[string][]byte
|
||||||
DriverOpts map[string]string
|
DriverOpts map[string]string
|
||||||
SecurityOpts map[string]string
|
|
||||||
Auth Auth
|
Auth Auth
|
||||||
Platforms []specs.Platform
|
Platforms []specs.Platform
|
||||||
// ContextPathHash can be used for determining pods in the driver instance
|
// ContextPathHash can be used for determining pods in the driver instance
|
||||||
@@ -105,7 +104,7 @@ func GetFactory(name string, instanceRequired bool) (Factory, error) {
|
|||||||
return nil, errors.Errorf("failed to find driver %q", name)
|
return nil, errors.Errorf("failed to find driver %q", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDriver(ctx context.Context, name string, f Factory, endpointAddr string, api dockerclient.APIClient, auth Auth, kcc KubeClientConfig, flags []string, files map[string][]byte, do map[string]string, so map[string]string, platforms []specs.Platform, contextPathHash string) (*DriverHandle, error) {
|
func GetDriver(ctx context.Context, name string, f Factory, endpointAddr string, api dockerclient.APIClient, auth Auth, kcc KubeClientConfig, flags []string, files map[string][]byte, do map[string]string, platforms []specs.Platform, contextPathHash string) (*DriverHandle, error) {
|
||||||
ic := InitConfig{
|
ic := InitConfig{
|
||||||
EndpointAddr: endpointAddr,
|
EndpointAddr: endpointAddr,
|
||||||
DockerAPI: api,
|
DockerAPI: api,
|
||||||
@@ -113,7 +112,6 @@ func GetDriver(ctx context.Context, name string, f Factory, endpointAddr string,
|
|||||||
Name: name,
|
Name: name,
|
||||||
BuildkitFlags: flags,
|
BuildkitFlags: flags,
|
||||||
DriverOpts: do,
|
DriverOpts: do,
|
||||||
SecurityOpts: so,
|
|
||||||
Auth: auth,
|
Auth: auth,
|
||||||
Platforms: platforms,
|
Platforms: platforms,
|
||||||
ContextPathHash: contextPathHash,
|
ContextPathHash: contextPathHash,
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ import (
|
|||||||
"github.com/docker/buildx/driver"
|
"github.com/docker/buildx/driver"
|
||||||
"github.com/docker/buildx/util/progress"
|
"github.com/docker/buildx/util/progress"
|
||||||
"github.com/moby/buildkit/client"
|
"github.com/moby/buildkit/client"
|
||||||
"google.golang.org/grpc"
|
|
||||||
"google.golang.org/grpc/backoff"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Driver struct {
|
type Driver struct {
|
||||||
@@ -25,11 +23,25 @@ type tlsOpts struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) Bootstrap(ctx context.Context, l progress.Logger) error {
|
func (d *Driver) Bootstrap(ctx context.Context, l progress.Logger) error {
|
||||||
c, err := d.Client(ctx)
|
for i := 0; ; i++ {
|
||||||
if err != nil {
|
info, err := d.Info(ctx)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if info.Status != driver.Inactive {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
default:
|
||||||
|
if i > 10 {
|
||||||
|
i = 10
|
||||||
|
}
|
||||||
|
time.Sleep(time.Duration(i) * time.Second)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return c.Wait(ctx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) Info(ctx context.Context) (*driver.Info, error) {
|
func (d *Driver) Info(ctx context.Context) (*driver.Info, error) {
|
||||||
@@ -65,13 +77,6 @@ func (d *Driver) Rm(ctx context.Context, force, rmVolume, rmDaemon bool) error {
|
|||||||
|
|
||||||
func (d *Driver) Client(ctx context.Context) (*client.Client, error) {
|
func (d *Driver) Client(ctx context.Context) (*client.Client, error) {
|
||||||
opts := []client.ClientOpt{}
|
opts := []client.ClientOpt{}
|
||||||
|
|
||||||
backoffConfig := backoff.DefaultConfig
|
|
||||||
backoffConfig.MaxDelay = 1 * time.Second
|
|
||||||
opts = append(opts, client.WithGRPCDialOption(
|
|
||||||
grpc.WithConnectParams(grpc.ConnectParams{Backoff: backoffConfig}),
|
|
||||||
))
|
|
||||||
|
|
||||||
if d.tlsOpts != nil {
|
if d.tlsOpts != nil {
|
||||||
opts = append(opts, []client.ClientOpt{
|
opts = append(opts, []client.ClientOpt{
|
||||||
client.WithServerConfig(d.tlsOpts.serverName, d.tlsOpts.caCert),
|
client.WithServerConfig(d.tlsOpts.serverName, d.tlsOpts.caCert),
|
||||||
|
|||||||
38
go.mod
38
go.mod
@@ -5,16 +5,15 @@ go 1.20
|
|||||||
require (
|
require (
|
||||||
github.com/Masterminds/semver/v3 v3.2.1
|
github.com/Masterminds/semver/v3 v3.2.1
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.18.16
|
github.com/aws/aws-sdk-go-v2/config v1.18.16
|
||||||
github.com/compose-spec/compose-go v1.17.0
|
github.com/compose-spec/compose-go v1.14.0
|
||||||
github.com/containerd/console v1.0.3
|
github.com/containerd/console v1.0.3
|
||||||
github.com/containerd/containerd v1.7.2
|
github.com/containerd/containerd v1.7.2
|
||||||
github.com/containerd/continuity v0.4.1
|
github.com/containerd/continuity v0.4.1
|
||||||
github.com/containerd/typeurl/v2 v2.1.1
|
github.com/containerd/typeurl/v2 v2.1.1
|
||||||
github.com/creack/pty v1.1.18
|
github.com/docker/cli v24.0.2+incompatible
|
||||||
github.com/docker/cli v24.0.5+incompatible
|
|
||||||
github.com/docker/cli-docs-tool v0.6.0
|
github.com/docker/cli-docs-tool v0.6.0
|
||||||
github.com/docker/distribution v2.8.2+incompatible
|
github.com/docker/distribution v2.8.2+incompatible
|
||||||
github.com/docker/docker v24.0.5+incompatible
|
github.com/docker/docker v24.0.2+incompatible
|
||||||
github.com/docker/go-units v0.5.0
|
github.com/docker/go-units v0.5.0
|
||||||
github.com/gofrs/flock v0.8.1
|
github.com/gofrs/flock v0.8.1
|
||||||
github.com/gogo/protobuf v1.3.2
|
github.com/gogo/protobuf v1.3.2
|
||||||
@@ -23,7 +22,7 @@ require (
|
|||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
github.com/hashicorp/go-cty-funcs v0.0.0-20200930094925-2721b1e36840
|
github.com/hashicorp/go-cty-funcs v0.0.0-20200930094925-2721b1e36840
|
||||||
github.com/hashicorp/hcl/v2 v2.8.2
|
github.com/hashicorp/hcl/v2 v2.8.2
|
||||||
github.com/moby/buildkit v0.12.1-0.20230804094609-b49a8873179b
|
github.com/moby/buildkit v0.11.0-rc3.0.20230609092854-67a08623b95a
|
||||||
github.com/moby/sys/mountinfo v0.6.2
|
github.com/moby/sys/mountinfo v0.6.2
|
||||||
github.com/moby/sys/signal v0.7.0
|
github.com/moby/sys/signal v0.7.0
|
||||||
github.com/morikuni/aec v1.0.0
|
github.com/morikuni/aec v1.0.0
|
||||||
@@ -32,22 +31,21 @@ require (
|
|||||||
github.com/pelletier/go-toml v1.9.5
|
github.com/pelletier/go-toml v1.9.5
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002
|
github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.0
|
||||||
github.com/spf13/cobra v1.7.0
|
github.com/spf13/cobra v1.7.0
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.8.4
|
||||||
github.com/zclconf/go-cty v1.10.0
|
github.com/zclconf/go-cty v1.10.0
|
||||||
go.opentelemetry.io/otel v1.14.0
|
go.opentelemetry.io/otel v1.14.0
|
||||||
go.opentelemetry.io/otel/trace v1.14.0
|
go.opentelemetry.io/otel/trace v1.14.0
|
||||||
golang.org/x/mod v0.11.0
|
golang.org/x/sync v0.2.0
|
||||||
golang.org/x/sync v0.3.0
|
golang.org/x/term v0.6.0
|
||||||
golang.org/x/term v0.8.0
|
|
||||||
google.golang.org/grpc v1.53.0
|
google.golang.org/grpc v1.53.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
k8s.io/api v0.26.7
|
k8s.io/api v0.26.2
|
||||||
k8s.io/apimachinery v0.26.7
|
k8s.io/apimachinery v0.26.2
|
||||||
k8s.io/apiserver v0.26.7
|
k8s.io/apiserver v0.26.2
|
||||||
k8s.io/client-go v0.26.7
|
k8s.io/client-go v0.26.2
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -105,7 +103,7 @@ require (
|
|||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect
|
||||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
|
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
|
||||||
github.com/imdario/mergo v0.3.16 // indirect
|
github.com/imdario/mergo v0.3.15 // indirect
|
||||||
github.com/in-toto/in-toto-golang v0.5.0 // indirect
|
github.com/in-toto/in-toto-golang v0.5.0 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/jinzhu/gorm v1.9.2 // indirect
|
github.com/jinzhu/gorm v1.9.2 // indirect
|
||||||
@@ -140,10 +138,10 @@ require (
|
|||||||
github.com/shibumi/go-pathspec v1.3.0 // indirect
|
github.com/shibumi/go-pathspec v1.3.0 // indirect
|
||||||
github.com/spf13/viper v1.14.0 // indirect
|
github.com/spf13/viper v1.14.0 // indirect
|
||||||
github.com/theupdateframework/notary v0.6.1 // indirect
|
github.com/theupdateframework/notary v0.6.1 // indirect
|
||||||
github.com/tonistiigi/fsutil v0.0.0-20230629203738-36ef4d8c0dbb // indirect
|
github.com/tonistiigi/fsutil v0.0.0-20230407161946-9e7a6df48576 // indirect
|
||||||
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
|
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
|
||||||
github.com/tonistiigi/vt100 v0.0.0-20230623042737-f9a4f7ef6531 // indirect
|
github.com/tonistiigi/vt100 v0.0.0-20230623042737-f9a4f7ef6531 // indirect
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.40.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.40.0 // indirect
|
||||||
@@ -157,11 +155,11 @@ require (
|
|||||||
go.opentelemetry.io/otel/sdk v1.14.0 // indirect
|
go.opentelemetry.io/otel/sdk v1.14.0 // indirect
|
||||||
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
|
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
|
||||||
golang.org/x/crypto v0.2.0 // indirect
|
golang.org/x/crypto v0.2.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
|
golang.org/x/mod v0.9.0 // indirect
|
||||||
golang.org/x/net v0.10.0 // indirect
|
golang.org/x/net v0.8.0 // indirect
|
||||||
golang.org/x/oauth2 v0.5.0 // indirect
|
golang.org/x/oauth2 v0.5.0 // indirect
|
||||||
golang.org/x/sys v0.8.0 // indirect
|
golang.org/x/sys v0.7.0 // indirect
|
||||||
golang.org/x/text v0.9.0 // indirect
|
golang.org/x/text v0.8.0 // indirect
|
||||||
golang.org/x/time v0.3.0 // indirect
|
golang.org/x/time v0.3.0 // indirect
|
||||||
golang.org/x/tools v0.7.0 // indirect
|
golang.org/x/tools v0.7.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
|
|||||||
74
go.sum
74
go.sum
@@ -122,8 +122,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH
|
|||||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
|
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
|
||||||
github.com/compose-spec/compose-go v1.17.0 h1:cvje90CU94dQyTnJoHJYjx9yE4Iggse1XmGcO3Qi5ts=
|
github.com/compose-spec/compose-go v1.14.0 h1:/+tQxBEPIrfsi87Qh7/VjMzcJN3BRNER/RO71ku+u6E=
|
||||||
github.com/compose-spec/compose-go v1.17.0/go.mod h1:zR2tP1+kZHi5vJz7PjpW6oMoDji/Js3GHjP+hfjf70Q=
|
github.com/compose-spec/compose-go v1.14.0/go.mod h1:m0o4G6MQDHjjz9rY7No9FpnNi+9sKic262rzrwuCqic=
|
||||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
||||||
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
|
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
|
||||||
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
||||||
@@ -142,7 +142,6 @@ github.com/containerd/typeurl/v2 v2.1.1/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3H
|
|||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
|
||||||
github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=
|
github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=
|
||||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@@ -150,14 +149,14 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa h1:L9Ay/slwQ4ERSPaurC+TVkZrM0K98GNrEEo1En3e8as=
|
github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa h1:L9Ay/slwQ4ERSPaurC+TVkZrM0K98GNrEEo1En3e8as=
|
||||||
github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI=
|
github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI=
|
||||||
github.com/docker/cli v24.0.5+incompatible h1:WeBimjvS0eKdH4Ygx+ihVq1Q++xg36M/rMi4aXAvodc=
|
github.com/docker/cli v24.0.2+incompatible h1:QdqR7znue1mtkXIJ+ruQMGQhpw2JzMJLRXp6zpzF6tM=
|
||||||
github.com/docker/cli v24.0.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
github.com/docker/cli v24.0.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||||
github.com/docker/cli-docs-tool v0.6.0 h1:Z9x10SaZgFaB6jHgz3OWooynhSa40CsWkpe5hEnG/qA=
|
github.com/docker/cli-docs-tool v0.6.0 h1:Z9x10SaZgFaB6jHgz3OWooynhSa40CsWkpe5hEnG/qA=
|
||||||
github.com/docker/cli-docs-tool v0.6.0/go.mod h1:zMjqTFCU361PRh8apiXzeAZ1Q/xupbIwTusYpzCXS/o=
|
github.com/docker/cli-docs-tool v0.6.0/go.mod h1:zMjqTFCU361PRh8apiXzeAZ1Q/xupbIwTusYpzCXS/o=
|
||||||
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
||||||
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY=
|
github.com/docker/docker v24.0.2+incompatible h1:eATx+oLz9WdNVkQrr0qjQ8HvRJ4bOOxfzEo8R+dA3cg=
|
||||||
github.com/docker/docker v24.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v24.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
|
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
|
||||||
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
|
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
|
||||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
|
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
|
||||||
@@ -316,8 +315,8 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
|||||||
github.com/hashicorp/hcl/v2 v2.8.2 h1:wmFle3D1vu0okesm8BTLVDyJ6/OL9DCLUwn0b2OptiY=
|
github.com/hashicorp/hcl/v2 v2.8.2 h1:wmFle3D1vu0okesm8BTLVDyJ6/OL9DCLUwn0b2OptiY=
|
||||||
github.com/hashicorp/hcl/v2 v2.8.2/go.mod h1:bQTN5mpo+jewjJgh8jr0JUguIi7qPHUF6yIfAEN3jqY=
|
github.com/hashicorp/hcl/v2 v2.8.2/go.mod h1:bQTN5mpo+jewjJgh8jr0JUguIi7qPHUF6yIfAEN3jqY=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
|
||||||
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||||
github.com/in-toto/in-toto-golang v0.5.0 h1:hb8bgwr0M2hGdDsLjkJ3ZqJ8JFLL/tgYdAxF/XEFBbY=
|
github.com/in-toto/in-toto-golang v0.5.0 h1:hb8bgwr0M2hGdDsLjkJ3ZqJ8JFLL/tgYdAxF/XEFBbY=
|
||||||
github.com/in-toto/in-toto-golang v0.5.0/go.mod h1:/Rq0IZHLV7Ku5gielPT4wPHJfH1GdHMCq8+WPxw8/BE=
|
github.com/in-toto/in-toto-golang v0.5.0/go.mod h1:/Rq0IZHLV7Ku5gielPT4wPHJfH1GdHMCq8+WPxw8/BE=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
@@ -372,8 +371,8 @@ github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzC
|
|||||||
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
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/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
github.com/moby/buildkit v0.12.1-0.20230804094609-b49a8873179b h1:LUpEbvxcyM0NuWk54WwNjDVZ5YujyCm1CudzZpqaohE=
|
github.com/moby/buildkit v0.11.0-rc3.0.20230609092854-67a08623b95a h1:1k3bAXwxC2N1FncWijq/43sLj2OVIZ11FT0APIXWhMg=
|
||||||
github.com/moby/buildkit v0.12.1-0.20230804094609-b49a8873179b/go.mod h1:bs0LeDdh7AQpYXLiPNUt+hzDjRxMg+QeLq1a1r0awFM=
|
github.com/moby/buildkit v0.11.0-rc3.0.20230609092854-67a08623b95a/go.mod h1:4sM7BBBqXOQ+vV6LrVAOAMhZI9cVNYV5RhZCl906a64=
|
||||||
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
||||||
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
||||||
github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo=
|
github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo=
|
||||||
@@ -457,8 +456,8 @@ github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh
|
|||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/spdx/tools-golang v0.5.1 h1:fJg3SVOGG+eIva9ZUBm/hvyA7PIPVFjRxUKe6fdAgwE=
|
github.com/spdx/tools-golang v0.5.1 h1:fJg3SVOGG+eIva9ZUBm/hvyA7PIPVFjRxUKe6fdAgwE=
|
||||||
github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw=
|
github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw=
|
||||||
@@ -485,8 +484,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
|
|||||||
github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
|
github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
|
||||||
github.com/theupdateframework/notary v0.6.1 h1:7wshjstgS9x9F5LuB1L5mBI2xNMObWqjz+cjWoom6l0=
|
github.com/theupdateframework/notary v0.6.1 h1:7wshjstgS9x9F5LuB1L5mBI2xNMObWqjz+cjWoom6l0=
|
||||||
github.com/theupdateframework/notary v0.6.1/go.mod h1:MOfgIfmox8s7/7fduvB2xyPPMJCrjRLRizA8OFwpnKY=
|
github.com/theupdateframework/notary v0.6.1/go.mod h1:MOfgIfmox8s7/7fduvB2xyPPMJCrjRLRizA8OFwpnKY=
|
||||||
github.com/tonistiigi/fsutil v0.0.0-20230629203738-36ef4d8c0dbb h1:uUe8rNyVXM8moActoBol6Xf6xX2GMr7SosR2EywMvGg=
|
github.com/tonistiigi/fsutil v0.0.0-20230407161946-9e7a6df48576 h1:fZXPQDVh5fm2x7pA0CH1TtH80tiZ0L7i834kZqZN8Pw=
|
||||||
github.com/tonistiigi/fsutil v0.0.0-20230629203738-36ef4d8c0dbb/go.mod h1:SxX/oNQ/ag6Vaoli547ipFK9J7BZn5JqJG0JE8lf8bA=
|
github.com/tonistiigi/fsutil v0.0.0-20230407161946-9e7a6df48576/go.mod h1:q1CxMSzcAbjUkVGHoZeQUcCaALnaE4XdWk+zJcgMYFw=
|
||||||
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea h1:SXhTLE6pb6eld/v/cCndK0AMpt1wiVFb/YYmqB3/QG0=
|
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea h1:SXhTLE6pb6eld/v/cCndK0AMpt1wiVFb/YYmqB3/QG0=
|
||||||
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk=
|
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk=
|
||||||
github.com/tonistiigi/vt100 v0.0.0-20230623042737-f9a4f7ef6531 h1:Y/M5lygoNPKwVNLMPXgVfsRT40CSFKXCxuU8LoHySjs=
|
github.com/tonistiigi/vt100 v0.0.0-20230623042737-f9a4f7ef6531 h1:Y/M5lygoNPKwVNLMPXgVfsRT40CSFKXCxuU8LoHySjs=
|
||||||
@@ -495,9 +494,8 @@ github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlI
|
|||||||
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||||
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
|
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
|
||||||
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
||||||
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||||
@@ -565,8 +563,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
|||||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||||
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
|
|
||||||
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
|
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
@@ -587,8 +583,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
|||||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
|
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
|
||||||
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@@ -620,8 +616,8 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R
|
|||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
@@ -640,8 +636,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
|
||||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@@ -683,19 +679,19 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
|
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
|
||||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
@@ -876,14 +872,14 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
k8s.io/api v0.26.7 h1:Lf4iEBEJb5OFNmawtBfSZV/UNi9riSJ0t1qdhyZqI40=
|
k8s.io/api v0.26.2 h1:dM3cinp3PGB6asOySalOZxEG4CZ0IAdJsrYZXE/ovGQ=
|
||||||
k8s.io/api v0.26.7/go.mod h1:Vk9bMadzA49UHPmHB//lX7VRCQSXGoVwfLd3Sc1SSXI=
|
k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU=
|
||||||
k8s.io/apimachinery v0.26.7 h1:590jSBwaSHCAFCqltaEogY/zybFlhGsnLteLpuF2wig=
|
k8s.io/apimachinery v0.26.2 h1:da1u3D5wfR5u2RpLhE/ZtZS2P7QvDgLZTi9wrNZl/tQ=
|
||||||
k8s.io/apimachinery v0.26.7/go.mod h1:qYzLkrQ9lhrZRh0jNKo2cfvf/R1/kQONnSiyB7NUJU0=
|
k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I=
|
||||||
k8s.io/apiserver v0.26.7 h1:NX/zBZZn4R+Cq6shwyn8Pn8REd0yJJ16dbtv9WkEVEU=
|
k8s.io/apiserver v0.26.2 h1:Pk8lmX4G14hYqJd1poHGC08G03nIHVqdJMR0SD3IH3o=
|
||||||
k8s.io/apiserver v0.26.7/go.mod h1:r0wDRWHI7VL/KlQLTkJJBVGZ3KeNfv+VetlyRtr86xs=
|
k8s.io/apiserver v0.26.2/go.mod h1:GHcozwXgXsPuOJ28EnQ/jXEM9QeG6HT22YxSNmpYNh8=
|
||||||
k8s.io/client-go v0.26.7 h1:hyU9aKHlwVOykgyxzGYkrDSLCc4+mimZVyUJjPyUn1E=
|
k8s.io/client-go v0.26.2 h1:s1WkVujHX3kTp4Zn4yGNFK+dlDXy1bAAkIl+cFAiuYI=
|
||||||
k8s.io/client-go v0.26.7/go.mod h1:okYjy0jtq6sdeztALDvCh24tg4opOQS1XNvsJlERDAo=
|
k8s.io/client-go v0.26.2/go.mod h1:u5EjOuSyBa09yqqyY7m3abZeovO/7D/WehVVlZ2qcqU=
|
||||||
k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
|
k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
|
||||||
k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E=
|
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E=
|
||||||
|
|||||||
@@ -9,9 +9,8 @@ set -e
|
|||||||
|
|
||||||
: "${CGO_ENABLED=0}"
|
: "${CGO_ENABLED=0}"
|
||||||
: "${GO_PKG=github.com/docker/buildx}"
|
: "${GO_PKG=github.com/docker/buildx}"
|
||||||
: "${GO_EXTRA_FLAGS=}"
|
|
||||||
: "${GO_LDFLAGS=-X ${GO_PKG}/version.Version=${VERSION} -X ${GO_PKG}/version.Revision=${REVISION} -X ${GO_PKG}/version.Package=${PACKAGE}}"
|
: "${GO_LDFLAGS=-X ${GO_PKG}/version.Version=${VERSION} -X ${GO_PKG}/version.Revision=${REVISION} -X ${GO_PKG}/version.Package=${PACKAGE}}"
|
||||||
: "${GO_EXTRA_LDFLAGS=}"
|
: "${GO_EXTRA_LDFLAGS=}"
|
||||||
|
|
||||||
set -x
|
set -x
|
||||||
CGO_ENABLED=$CGO_ENABLED go build -mod vendor -trimpath ${GO_EXTRA_FLAGS} -ldflags "${GO_LDFLAGS} ${GO_EXTRA_LDFLAGS}" -o "${DESTDIR}/docker-buildx" ./cmd/buildx
|
CGO_ENABLED=$CGO_ENABLED go build -mod vendor -trimpath -ldflags "${GO_LDFLAGS} ${GO_EXTRA_LDFLAGS}" -o "${DESTDIR}/docker-buildx" ./cmd/buildx
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
ARG GO_VERSION=1.20.7
|
ARG GO_VERSION=1.20
|
||||||
ARG FORMATS=md,yaml
|
ARG FORMATS=md,yaml
|
||||||
|
|
||||||
FROM golang:${GO_VERSION}-alpine AS docsgen
|
FROM golang:${GO_VERSION}-alpine AS docsgen
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
# Copyright The Buildx Authors.
|
# Copyright The Buildx Authors.
|
||||||
# Licensed under the Apache License, Version 2.0
|
# Licensed under the Apache License, Version 2.0
|
||||||
|
|
||||||
ARG GO_VERSION="1.20.7"
|
ARG GO_VERSION="1.20"
|
||||||
ARG PROTOC_VERSION="3.11.4"
|
ARG PROTOC_VERSION="3.11.4"
|
||||||
|
|
||||||
# protoc is dynamically linked to glibc so can't use alpine base
|
# protoc is dynamically linked to glibc so can't use alpine base
|
||||||
FROM golang:${GO_VERSION}-bookworm AS base
|
FROM golang:${GO_VERSION}-buster AS base
|
||||||
RUN apt-get update && apt-get --no-install-recommends install -y git unzip
|
RUN apt-get update && apt-get --no-install-recommends install -y git unzip
|
||||||
ARG PROTOC_VERSION
|
ARG PROTOC_VERSION
|
||||||
ARG TARGETOS
|
ARG TARGETOS
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
ARG GO_VERSION=1.20.7
|
ARG GO_VERSION=1.20
|
||||||
|
|
||||||
FROM golang:${GO_VERSION}-alpine
|
FROM golang:${GO_VERSION}-alpine
|
||||||
RUN apk add --no-cache git gcc musl-dev
|
RUN apk add --no-cache git gcc musl-dev
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
ARG GO_VERSION=1.20.7
|
ARG GO_VERSION=1.20
|
||||||
ARG MODOUTDATED_VERSION=v0.8.0
|
ARG MODOUTDATED_VERSION=v0.8.0
|
||||||
|
|
||||||
FROM golang:${GO_VERSION}-alpine AS base
|
FROM golang:${GO_VERSION}-alpine AS base
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ Usage:
|
|||||||
attach ID
|
attach ID
|
||||||
|
|
||||||
ID is for a session (visible via list command) or a process (visible via ps command).
|
ID is for a session (visible via list command) or a process (visible via ps command).
|
||||||
If you attached to a process, use Ctrl-a-c for switching the monitor to that process's STDIO.
|
If you attached to a process, use Ctrl-c-a for switching the monitor to that process's STDIO.
|
||||||
`,
|
`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ func (cm *ExecCmd) Exec(ctx context.Context, args []string) error {
|
|||||||
cfg := controllerapi.InvokeConfig{
|
cfg := controllerapi.InvokeConfig{
|
||||||
Entrypoint: []string{args[1]},
|
Entrypoint: []string{args[1]},
|
||||||
Cmd: args[2:],
|
Cmd: args[2:],
|
||||||
NoCmd: false,
|
|
||||||
// TODO: support other options as well via flags
|
// TODO: support other options as well via flags
|
||||||
Env: cm.invokeConfig.Env,
|
Env: cm.invokeConfig.Env,
|
||||||
User: cm.invokeConfig.User,
|
User: cm.invokeConfig.User,
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ func (cm *RollbackCmd) Exec(ctx context.Context, args []string) error {
|
|||||||
if len(cmds) > 0 {
|
if len(cmds) > 0 {
|
||||||
cfg.Entrypoint = []string{cmds[0]}
|
cfg.Entrypoint = []string{cmds[0]}
|
||||||
cfg.Cmd = cmds[1:]
|
cfg.Cmd = cmds[1:]
|
||||||
cfg.NoCmd = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
id := cm.m.Rollback(ctx, cfg)
|
id := cm.m.Rollback(ctx, cfg)
|
||||||
|
|||||||
@@ -283,7 +283,6 @@ func (m *monitor) startInvoke(ctx context.Context, pid string, cfg controllerapi
|
|||||||
if len(cfg.Entrypoint) == 0 && len(cfg.Cmd) == 0 {
|
if len(cfg.Entrypoint) == 0 && len(cfg.Cmd) == 0 {
|
||||||
cfg.Entrypoint = []string{"sh"} // launch shell by default
|
cfg.Entrypoint = []string{"sh"} // launch shell by default
|
||||||
cfg.Cmd = []string{}
|
cfg.Cmd = []string{}
|
||||||
cfg.NoCmd = false
|
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
// Start a new invoke
|
// Start a new invoke
|
||||||
|
|||||||
BIN
out/buildx
BIN
out/buildx
Binary file not shown.
@@ -24,12 +24,11 @@ type NodeGroup struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Node struct {
|
type Node struct {
|
||||||
Name string
|
Name string
|
||||||
Endpoint string
|
Endpoint string
|
||||||
Platforms []specs.Platform
|
Platforms []specs.Platform
|
||||||
Flags []string
|
Flags []string
|
||||||
DriverOpts map[string]string
|
DriverOpts map[string]string
|
||||||
SecurityOpts map[string]string
|
|
||||||
|
|
||||||
Files map[string][]byte
|
Files map[string][]byte
|
||||||
}
|
}
|
||||||
@@ -49,7 +48,7 @@ func (ng *NodeGroup) Leave(name string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ng *NodeGroup) Update(name, endpoint string, platforms []string, endpointsSet bool, actionAppend bool, flags []string, configFile string, do map[string]string, so map[string]string) error {
|
func (ng *NodeGroup) Update(name, endpoint string, platforms []string, endpointsSet bool, actionAppend bool, flags []string, configFile string, do map[string]string) error {
|
||||||
if ng.Dynamic {
|
if ng.Dynamic {
|
||||||
return errors.New("dynamic node group does not support Update")
|
return errors.New("dynamic node group does not support Update")
|
||||||
}
|
}
|
||||||
@@ -92,10 +91,6 @@ func (ng *NodeGroup) Update(name, endpoint string, platforms []string, endpoints
|
|||||||
n.DriverOpts = do
|
n.DriverOpts = do
|
||||||
needsRestart = true
|
needsRestart = true
|
||||||
}
|
}
|
||||||
if so != nil {
|
|
||||||
n.SecurityOpts = so
|
|
||||||
needsRestart = true
|
|
||||||
}
|
|
||||||
if configFile != "" {
|
if configFile != "" {
|
||||||
for k, v := range files {
|
for k, v := range files {
|
||||||
n.Files[k] = v
|
n.Files[k] = v
|
||||||
@@ -123,13 +118,12 @@ func (ng *NodeGroup) Update(name, endpoint string, platforms []string, endpoints
|
|||||||
}
|
}
|
||||||
|
|
||||||
n := Node{
|
n := Node{
|
||||||
Name: name,
|
Name: name,
|
||||||
Endpoint: endpoint,
|
Endpoint: endpoint,
|
||||||
Platforms: pp,
|
Platforms: pp,
|
||||||
Flags: flags,
|
Flags: flags,
|
||||||
DriverOpts: do,
|
DriverOpts: do,
|
||||||
SecurityOpts: so,
|
Files: files,
|
||||||
Files: files,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ng.Nodes = append(ng.Nodes, n)
|
ng.Nodes = append(ng.Nodes, n)
|
||||||
@@ -162,10 +156,6 @@ func (n *Node) Copy() *Node {
|
|||||||
for k, v := range n.DriverOpts {
|
for k, v := range n.DriverOpts {
|
||||||
driverOpts[k] = v
|
driverOpts[k] = v
|
||||||
}
|
}
|
||||||
securityOpts := map[string]string{}
|
|
||||||
for k, v := range n.SecurityOpts {
|
|
||||||
securityOpts[k] = v
|
|
||||||
}
|
|
||||||
files := map[string][]byte{}
|
files := map[string][]byte{}
|
||||||
for k, v := range n.Files {
|
for k, v := range n.Files {
|
||||||
vv := []byte{}
|
vv := []byte{}
|
||||||
@@ -173,13 +163,12 @@ func (n *Node) Copy() *Node {
|
|||||||
files[k] = vv
|
files[k] = vv
|
||||||
}
|
}
|
||||||
return &Node{
|
return &Node{
|
||||||
Name: n.Name,
|
Name: n.Name,
|
||||||
Endpoint: n.Endpoint,
|
Endpoint: n.Endpoint,
|
||||||
Platforms: platforms,
|
Platforms: platforms,
|
||||||
Flags: flags,
|
Flags: flags,
|
||||||
DriverOpts: driverOpts,
|
DriverOpts: driverOpts,
|
||||||
SecurityOpts: securityOpts,
|
Files: files,
|
||||||
Files: files,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ func bakeCmd(sb integration.Sandbox, opts ...cmdOpt) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var bakeTests = []func(t *testing.T, sb integration.Sandbox){
|
var bakeTests = []func(t *testing.T, sb integration.Sandbox){
|
||||||
testBakeLocal,
|
|
||||||
testBakeRemote,
|
testBakeRemote,
|
||||||
testBakeRemoteCmdContext,
|
testBakeRemoteCmdContext,
|
||||||
testBakeRemoteCmdContextOverride,
|
testBakeRemoteCmdContextOverride,
|
||||||
@@ -27,29 +26,6 @@ var bakeTests = []func(t *testing.T, sb integration.Sandbox){
|
|||||||
testBakeRemoteCmdContextEscapeRelative,
|
testBakeRemoteCmdContextEscapeRelative,
|
||||||
}
|
}
|
||||||
|
|
||||||
func testBakeLocal(t *testing.T, sb integration.Sandbox) {
|
|
||||||
dockerfile := []byte(`
|
|
||||||
FROM scratch
|
|
||||||
COPY foo /foo
|
|
||||||
`)
|
|
||||||
bakefile := []byte(`
|
|
||||||
target "default" {
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
dir := tmpdir(
|
|
||||||
t,
|
|
||||||
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
|
|
||||||
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
|
||||||
fstest.CreateFile("foo", []byte("foo"), 0600),
|
|
||||||
)
|
|
||||||
dirDest := t.TempDir()
|
|
||||||
|
|
||||||
out, err := bakeCmd(sb, withDir(dir), withArgs("--set", "*.output=type=local,dest="+dirDest))
|
|
||||||
require.NoError(t, err, out)
|
|
||||||
|
|
||||||
require.FileExists(t, filepath.Join(dirDest, "foo"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func testBakeRemote(t *testing.T, sb integration.Sandbox) {
|
func testBakeRemote(t *testing.T, sb integration.Sandbox) {
|
||||||
bakefile := []byte(`
|
bakefile := []byte(`
|
||||||
target "default" {
|
target "default" {
|
||||||
|
|||||||
117
tests/build.go
117
tests/build.go
@@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -14,7 +13,6 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/containerd/platforms"
|
"github.com/containerd/containerd/platforms"
|
||||||
"github.com/containerd/continuity/fs/fstest"
|
"github.com/containerd/continuity/fs/fstest"
|
||||||
"github.com/creack/pty"
|
|
||||||
"github.com/moby/buildkit/util/contentutil"
|
"github.com/moby/buildkit/util/contentutil"
|
||||||
"github.com/moby/buildkit/util/testutil"
|
"github.com/moby/buildkit/util/testutil"
|
||||||
"github.com/moby/buildkit/util/testutil/integration"
|
"github.com/moby/buildkit/util/testutil/integration"
|
||||||
@@ -35,11 +33,8 @@ var buildTests = []func(t *testing.T, sb integration.Sandbox){
|
|||||||
testImageIDOutput,
|
testImageIDOutput,
|
||||||
testBuildLocalExport,
|
testBuildLocalExport,
|
||||||
testBuildRegistryExport,
|
testBuildRegistryExport,
|
||||||
testBuildRegistryExportAttestations,
|
|
||||||
testBuildTarExport,
|
testBuildTarExport,
|
||||||
testBuildMobyFromLocalImage,
|
|
||||||
testBuildDetailsLink,
|
testBuildDetailsLink,
|
||||||
testBuildProgress,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testBuild(t *testing.T, sb integration.Sandbox) {
|
func testBuild(t *testing.T, sb integration.Sandbox) {
|
||||||
@@ -97,40 +92,6 @@ func testBuildRegistryExport(t *testing.T, sb integration.Sandbox) {
|
|||||||
require.Equal(t, img.Layers[0]["bar"].Data, []byte("foo"))
|
require.Equal(t, img.Layers[0]["bar"].Data, []byte("foo"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testBuildRegistryExportAttestations(t *testing.T, sb integration.Sandbox) {
|
|
||||||
dir := createTestProject(t)
|
|
||||||
|
|
||||||
registry, err := sb.NewRegistry()
|
|
||||||
if errors.Is(err, integration.ErrRequirements) {
|
|
||||||
t.Skip(err.Error())
|
|
||||||
}
|
|
||||||
require.NoError(t, err)
|
|
||||||
target := registry + "/buildx/registry:latest"
|
|
||||||
|
|
||||||
out, err := buildCmd(sb, withArgs(fmt.Sprintf("--output=type=image,name=%s,push=true", target), "--provenance=true", dir))
|
|
||||||
if sb.Name() == "docker" {
|
|
||||||
require.Error(t, err)
|
|
||||||
require.Contains(t, out, "attestations are not supported")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
require.NoError(t, err, string(out))
|
|
||||||
|
|
||||||
desc, provider, err := contentutil.ProviderFromRef(target)
|
|
||||||
require.NoError(t, err)
|
|
||||||
imgs, err := testutil.ReadImages(sb.Context(), provider, desc)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
pk := platforms.Format(platforms.Normalize(platforms.DefaultSpec()))
|
|
||||||
img := imgs.Find(pk)
|
|
||||||
require.NotNil(t, img)
|
|
||||||
require.Len(t, img.Layers, 1)
|
|
||||||
require.Equal(t, img.Layers[0]["bar"].Data, []byte("foo"))
|
|
||||||
|
|
||||||
att := imgs.FindAttestation(pk)
|
|
||||||
require.NotNil(t, att)
|
|
||||||
require.Len(t, att.Layers, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testImageIDOutput(t *testing.T, sb integration.Sandbox) {
|
func testImageIDOutput(t *testing.T, sb integration.Sandbox) {
|
||||||
dockerfile := []byte(`FROM busybox:latest`)
|
dockerfile := []byte(`FROM busybox:latest`)
|
||||||
|
|
||||||
@@ -141,14 +102,14 @@ func testImageIDOutput(t *testing.T, sb integration.Sandbox) {
|
|||||||
|
|
||||||
outFlag := "--output=type=docker"
|
outFlag := "--output=type=docker"
|
||||||
|
|
||||||
if sb.DockerAddress() == "" {
|
if sb.Name() == "remote" {
|
||||||
// there is no Docker atm to load the image
|
// there is no Docker atm to load the image
|
||||||
outFlag += ",dest=" + targetDir + "/image.tar"
|
outFlag += ",dest=" + targetDir + "/image.tar"
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := buildxCmd(
|
cmd := buildxCmd(
|
||||||
sb,
|
sb,
|
||||||
withArgs("build", "-q", "--provenance", "false", outFlag, "--iidfile", filepath.Join(targetDir, "iid.txt"), "--metadata-file", filepath.Join(targetDir, "md.json"), dir),
|
withArgs("build", "-q", outFlag, "--iidfile", filepath.Join(targetDir, "iid.txt"), "--metadata-file", filepath.Join(targetDir, "md.json"), dir),
|
||||||
)
|
)
|
||||||
stdout := bytes.NewBuffer(nil)
|
stdout := bytes.NewBuffer(nil)
|
||||||
cmd.Stdout = stdout
|
cmd.Stdout = stdout
|
||||||
@@ -181,54 +142,6 @@ func testImageIDOutput(t *testing.T, sb integration.Sandbox) {
|
|||||||
require.Equal(t, dgst, digest.Digest(md.ConfigDigest))
|
require.Equal(t, dgst, digest.Digest(md.ConfigDigest))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testBuildMobyFromLocalImage(t *testing.T, sb integration.Sandbox) {
|
|
||||||
if !isDockerWorker(sb) {
|
|
||||||
t.Skip("skipping test for non-docker workers")
|
|
||||||
}
|
|
||||||
|
|
||||||
// pull image
|
|
||||||
cmd := dockerCmd(sb, withArgs("pull", "-q", "busybox:latest"))
|
|
||||||
stdout := bytes.NewBuffer(nil)
|
|
||||||
cmd.Stdout = stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
require.NoError(t, cmd.Run())
|
|
||||||
require.Equal(t, "docker.io/library/busybox:latest", strings.TrimSpace(stdout.String()))
|
|
||||||
|
|
||||||
// create local tag
|
|
||||||
cmd = dockerCmd(sb, withArgs("tag", "busybox:latest", "buildx-test:busybox"))
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
require.NoError(t, cmd.Run())
|
|
||||||
|
|
||||||
// build image
|
|
||||||
dockerfile := []byte(`FROM buildx-test:busybox`)
|
|
||||||
dir := tmpdir(t, fstest.CreateFile("Dockerfile", dockerfile, 0600))
|
|
||||||
cmd = buildxCmd(
|
|
||||||
sb,
|
|
||||||
withArgs("build", "-q", "--output=type=cacheonly", dir),
|
|
||||||
)
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
require.NoError(t, cmd.Run())
|
|
||||||
|
|
||||||
// create local tag matching a remote one
|
|
||||||
cmd = dockerCmd(sb, withArgs("tag", "busybox:latest", "busybox:1.35"))
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
require.NoError(t, cmd.Run())
|
|
||||||
|
|
||||||
// build image and check that it uses the local tag
|
|
||||||
// (note: the version check should match the version of busybox in pins.go)
|
|
||||||
dockerfile = []byte(`
|
|
||||||
FROM busybox:1.35
|
|
||||||
RUN busybox | head -1 | grep v1.36.1
|
|
||||||
`)
|
|
||||||
dir = tmpdir(t, fstest.CreateFile("Dockerfile", dockerfile, 0600))
|
|
||||||
cmd = buildxCmd(
|
|
||||||
sb,
|
|
||||||
withArgs("build", "-q", "--output=type=cacheonly", dir),
|
|
||||||
)
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
require.NoError(t, cmd.Run())
|
|
||||||
}
|
|
||||||
|
|
||||||
func testBuildDetailsLink(t *testing.T, sb integration.Sandbox) {
|
func testBuildDetailsLink(t *testing.T, sb integration.Sandbox) {
|
||||||
buildDetailsPattern := regexp.MustCompile(`(?m)^View build details: docker-desktop://dashboard/build/[^/]+/[^/]+/[^/]+\n$`)
|
buildDetailsPattern := regexp.MustCompile(`(?m)^View build details: docker-desktop://dashboard/build/[^/]+/[^/]+/[^/]+\n$`)
|
||||||
|
|
||||||
@@ -287,29 +200,3 @@ COPY --from=base /etc/bar /bar
|
|||||||
)
|
)
|
||||||
return dir
|
return dir
|
||||||
}
|
}
|
||||||
|
|
||||||
func testBuildProgress(t *testing.T, sb integration.Sandbox) {
|
|
||||||
dir := createTestProject(t)
|
|
||||||
driver, _, _ := strings.Cut(sb.Name(), "+")
|
|
||||||
name := sb.Address()
|
|
||||||
|
|
||||||
// progress=tty
|
|
||||||
cmd := buildxCmd(sb, withArgs("build", "--progress=tty", "--output=type=cacheonly", dir))
|
|
||||||
f, err := pty.Start(cmd)
|
|
||||||
require.NoError(t, err)
|
|
||||||
buf := bytes.NewBuffer(nil)
|
|
||||||
io.Copy(buf, f)
|
|
||||||
ttyOutput := buf.String()
|
|
||||||
require.Contains(t, ttyOutput, "[+] Building")
|
|
||||||
require.Contains(t, ttyOutput, fmt.Sprintf("%s:%s", driver, name))
|
|
||||||
require.Contains(t, ttyOutput, "=> [internal] load build definition from Dockerfile")
|
|
||||||
require.Contains(t, ttyOutput, "=> [base 1/3] FROM docker.io/library/busybox:latest")
|
|
||||||
|
|
||||||
// progress=plain
|
|
||||||
cmd = buildxCmd(sb, withArgs("build", "--progress=plain", "--output=type=cacheonly", dir))
|
|
||||||
plainOutput, err := cmd.CombinedOutput()
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Contains(t, string(plainOutput), fmt.Sprintf(`#0 building with "%s" instance using %s driver`, name, driver))
|
|
||||||
require.Contains(t, string(plainOutput), "[internal] load build definition from Dockerfile")
|
|
||||||
require.Contains(t, string(plainOutput), "[base 1/3] FROM docker.io/library/busybox:latest")
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,267 +0,0 @@
|
|||||||
package tests
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"os/exec"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/containerd/containerd/images"
|
|
||||||
"github.com/containerd/containerd/platforms"
|
|
||||||
"github.com/containerd/continuity/fs/fstest"
|
|
||||||
"github.com/moby/buildkit/util/testutil/integration"
|
|
||||||
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
var imagetoolsTests = []func(t *testing.T, sb integration.Sandbox){
|
|
||||||
testImagetoolsCopyManifest,
|
|
||||||
testImagetoolsCopyIndex,
|
|
||||||
testImagetoolsInspectAndFilter,
|
|
||||||
testImagetoolsAnnotation,
|
|
||||||
}
|
|
||||||
|
|
||||||
func testImagetoolsCopyManifest(t *testing.T, sb integration.Sandbox) {
|
|
||||||
if sb.Name() != "docker-container" {
|
|
||||||
t.Skip("imagetools tests are not driver specific and only run on docker-container")
|
|
||||||
}
|
|
||||||
|
|
||||||
dir := createDockerfile(t)
|
|
||||||
registry, err := sb.NewRegistry()
|
|
||||||
if errors.Is(err, integration.ErrRequirements) {
|
|
||||||
t.Skip(err.Error())
|
|
||||||
}
|
|
||||||
require.NoError(t, err)
|
|
||||||
target := registry + "/buildx/imtools-manifest:latest"
|
|
||||||
|
|
||||||
out, err := buildCmd(sb, withArgs("-t", target, "--push", "--platform=linux/amd64", "--provenance=false", dir))
|
|
||||||
require.NoError(t, err, string(out))
|
|
||||||
|
|
||||||
cmd := buildxCmd(sb, withArgs("imagetools", "inspect", target, "--raw"))
|
|
||||||
dt, err := cmd.CombinedOutput()
|
|
||||||
require.NoError(t, err, string(dt))
|
|
||||||
|
|
||||||
var mfst ocispecs.Manifest
|
|
||||||
err = json.Unmarshal(dt, &mfst)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, images.MediaTypeDockerSchema2Manifest, mfst.MediaType)
|
|
||||||
|
|
||||||
registry2, err := sb.NewRegistry()
|
|
||||||
require.NoError(t, err)
|
|
||||||
target2 := registry2 + "/buildx/imtools2-manifest:latest"
|
|
||||||
|
|
||||||
cmd = buildxCmd(sb, withArgs("imagetools", "create", "-t", target2, target))
|
|
||||||
dt, err = cmd.CombinedOutput()
|
|
||||||
require.NoError(t, err, string(dt))
|
|
||||||
|
|
||||||
cmd = buildxCmd(sb, withArgs("imagetools", "inspect", target2, "--raw"))
|
|
||||||
dt, err = cmd.CombinedOutput()
|
|
||||||
require.NoError(t, err, string(dt))
|
|
||||||
|
|
||||||
var idx2 ocispecs.Index
|
|
||||||
err = json.Unmarshal(dt, &idx2)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, images.MediaTypeDockerSchema2ManifestList, idx2.MediaType)
|
|
||||||
require.Equal(t, 1, len(idx2.Manifests))
|
|
||||||
|
|
||||||
cmd = buildxCmd(sb, withArgs("imagetools", "inspect", target2+"@"+string(idx2.Manifests[0].Digest), "--raw"))
|
|
||||||
dt, err = cmd.CombinedOutput()
|
|
||||||
require.NoError(t, err, string(dt))
|
|
||||||
|
|
||||||
var mfst2 ocispecs.Manifest
|
|
||||||
err = json.Unmarshal(dt, &mfst2)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, images.MediaTypeDockerSchema2Manifest, mfst2.MediaType)
|
|
||||||
|
|
||||||
require.Equal(t, mfst.Config.Digest, mfst2.Config.Digest)
|
|
||||||
require.Equal(t, len(mfst.Layers), len(mfst2.Layers))
|
|
||||||
for i := range mfst.Layers {
|
|
||||||
require.Equal(t, mfst.Layers[i].Digest, mfst2.Layers[i].Digest)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testImagetoolsCopyIndex(t *testing.T, sb integration.Sandbox) {
|
|
||||||
if sb.Name() != "docker-container" {
|
|
||||||
t.Skip("imagetools tests are not driver specific and only run on docker-container")
|
|
||||||
}
|
|
||||||
|
|
||||||
dir := createDockerfile(t)
|
|
||||||
registry, err := sb.NewRegistry()
|
|
||||||
if errors.Is(err, integration.ErrRequirements) {
|
|
||||||
t.Skip(err.Error())
|
|
||||||
}
|
|
||||||
require.NoError(t, err)
|
|
||||||
target := registry + "/buildx/imtools:latest"
|
|
||||||
|
|
||||||
out, err := buildCmd(sb, withArgs("-t", target, "--push", "--platform=linux/amd64,linux/arm64", "--provenance=false", dir))
|
|
||||||
require.NoError(t, err, string(out))
|
|
||||||
|
|
||||||
cmd := buildxCmd(sb, withArgs("imagetools", "inspect", target, "--raw"))
|
|
||||||
dt, err := cmd.CombinedOutput()
|
|
||||||
require.NoError(t, err, string(dt))
|
|
||||||
|
|
||||||
var idx ocispecs.Index
|
|
||||||
err = json.Unmarshal(dt, &idx)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, images.MediaTypeDockerSchema2ManifestList, idx.MediaType)
|
|
||||||
require.Equal(t, 2, len(idx.Manifests))
|
|
||||||
|
|
||||||
registry2, err := sb.NewRegistry()
|
|
||||||
require.NoError(t, err)
|
|
||||||
target2 := registry2 + "/buildx/imtools2:latest"
|
|
||||||
|
|
||||||
cmd = buildxCmd(sb, withArgs("imagetools", "create", "-t", target2, target))
|
|
||||||
dt, err = cmd.CombinedOutput()
|
|
||||||
require.NoError(t, err, string(dt))
|
|
||||||
|
|
||||||
cmd = buildxCmd(sb, withArgs("imagetools", "inspect", target2, "--raw"))
|
|
||||||
dt, err = cmd.CombinedOutput()
|
|
||||||
require.NoError(t, err, string(dt))
|
|
||||||
|
|
||||||
var idx2 ocispecs.Index
|
|
||||||
err = json.Unmarshal(dt, &idx2)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, images.MediaTypeDockerSchema2ManifestList, idx2.MediaType)
|
|
||||||
|
|
||||||
require.Equal(t, len(idx.Manifests), len(idx2.Manifests))
|
|
||||||
for i := range idx.Manifests {
|
|
||||||
require.Equal(t, idx.Manifests[i].Digest, idx2.Manifests[i].Digest)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testImagetoolsInspectAndFilter(t *testing.T, sb integration.Sandbox) {
|
|
||||||
if sb.Name() != "docker-container" {
|
|
||||||
t.Skip("imagetools tests are not driver specific and only run on docker-container")
|
|
||||||
}
|
|
||||||
|
|
||||||
dir := createDockerfile(t)
|
|
||||||
registry, err := sb.NewRegistry()
|
|
||||||
if errors.Is(err, integration.ErrRequirements) {
|
|
||||||
t.Skip(err.Error())
|
|
||||||
}
|
|
||||||
require.NoError(t, err)
|
|
||||||
target := registry + "/buildx/imtools:latest"
|
|
||||||
|
|
||||||
out, err := buildCmd(sb, withArgs("-t", target, "--push", "--platform=linux/amd64,linux/arm64", "--provenance=false", dir))
|
|
||||||
require.NoError(t, err, string(out))
|
|
||||||
|
|
||||||
cmd := buildxCmd(sb, withArgs("imagetools", "inspect", target, "--raw"))
|
|
||||||
dt, err := cmd.CombinedOutput()
|
|
||||||
require.NoError(t, err, string(dt))
|
|
||||||
|
|
||||||
var idx ocispecs.Index
|
|
||||||
err = json.Unmarshal(dt, &idx)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
require.Equal(t, 2, len(idx.Manifests))
|
|
||||||
|
|
||||||
mfst := idx.Manifests[0]
|
|
||||||
require.Equal(t, "linux/amd64", platforms.Format(*mfst.Platform))
|
|
||||||
|
|
||||||
mfst = idx.Manifests[1]
|
|
||||||
require.Equal(t, "linux/arm64", platforms.Format(*mfst.Platform))
|
|
||||||
|
|
||||||
// create amd64 only image
|
|
||||||
cmd = buildxCmd(sb, withArgs("imagetools", "create", "-t", target+"-arm64", target+"@"+string(idx.Manifests[1].Digest)))
|
|
||||||
dt, err = cmd.CombinedOutput()
|
|
||||||
require.NoError(t, err, string(dt))
|
|
||||||
|
|
||||||
cmd = buildxCmd(sb, withArgs("imagetools", "inspect", target+"-arm64", "--raw"))
|
|
||||||
dt, err = cmd.CombinedOutput()
|
|
||||||
require.NoError(t, err, string(dt))
|
|
||||||
|
|
||||||
var idx2 ocispecs.Index
|
|
||||||
err = json.Unmarshal(dt, &idx2)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
require.Equal(t, 1, len(idx2.Manifests))
|
|
||||||
|
|
||||||
require.Equal(t, idx.Manifests[1].Digest, idx2.Manifests[0].Digest)
|
|
||||||
require.Equal(t, platforms.Format(*idx.Manifests[1].Platform), platforms.Format(*idx2.Manifests[0].Platform))
|
|
||||||
}
|
|
||||||
|
|
||||||
func testImagetoolsAnnotation(t *testing.T, sb integration.Sandbox) {
|
|
||||||
if sb.Name() != "docker-container" {
|
|
||||||
t.Skip("imagetools tests are not driver specific and only run on docker-container")
|
|
||||||
}
|
|
||||||
|
|
||||||
dir := createDockerfile(t)
|
|
||||||
registry, err := sb.NewRegistry()
|
|
||||||
if errors.Is(err, integration.ErrRequirements) {
|
|
||||||
t.Skip(err.Error())
|
|
||||||
}
|
|
||||||
require.NoError(t, err)
|
|
||||||
target := registry + "/buildx/imtools:latest"
|
|
||||||
|
|
||||||
out, err := buildCmd(sb, withArgs("--output", "type=registry,oci-mediatypes=true,name="+target, "--platform=linux/amd64,linux/arm64", "--provenance=false", dir))
|
|
||||||
require.NoError(t, err, string(out))
|
|
||||||
|
|
||||||
cmd := buildxCmd(sb, withArgs("imagetools", "inspect", target, "--raw"))
|
|
||||||
dt, err := cmd.CombinedOutput()
|
|
||||||
require.NoError(t, err, string(dt))
|
|
||||||
|
|
||||||
var idx ocispecs.Index
|
|
||||||
err = json.Unmarshal(dt, &idx)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Empty(t, idx.Annotations)
|
|
||||||
|
|
||||||
imagetoolsCmd := func(source []string) *exec.Cmd {
|
|
||||||
args := []string{"imagetools", "create", "-t", target, "--annotation", "index:foo=bar", "--annotation", "index:bar=baz",
|
|
||||||
"--annotation", "manifest-descriptor:foo=bar", "--annotation", "manifest-descriptor[linux/amd64]:bar=baz"}
|
|
||||||
args = append(args, source...)
|
|
||||||
return buildxCmd(sb, withArgs(args...))
|
|
||||||
}
|
|
||||||
sources := [][]string{
|
|
||||||
{
|
|
||||||
target,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
target + "@" + string(idx.Manifests[0].Digest),
|
|
||||||
target + "@" + string(idx.Manifests[1].Digest),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, source := range sources {
|
|
||||||
cmd = imagetoolsCmd(source)
|
|
||||||
dt, err = cmd.CombinedOutput()
|
|
||||||
require.NoError(t, err, string(dt))
|
|
||||||
|
|
||||||
newTarget := registry + "/buildx/imtools:annotations"
|
|
||||||
cmd = buildxCmd(sb, withArgs("imagetools", "create", "-t", newTarget, target))
|
|
||||||
dt, err = cmd.CombinedOutput()
|
|
||||||
require.NoError(t, err, string(dt))
|
|
||||||
|
|
||||||
cmd = buildxCmd(sb, withArgs("imagetools", "inspect", newTarget, "--raw"))
|
|
||||||
dt, err = cmd.CombinedOutput()
|
|
||||||
require.NoError(t, err, string(dt))
|
|
||||||
|
|
||||||
err = json.Unmarshal(dt, &idx)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Len(t, idx.Annotations, 2)
|
|
||||||
require.Equal(t, "bar", idx.Annotations["foo"])
|
|
||||||
require.Equal(t, "baz", idx.Annotations["bar"])
|
|
||||||
require.Len(t, idx.Manifests, 2)
|
|
||||||
for _, mfst := range idx.Manifests {
|
|
||||||
require.Equal(t, "bar", mfst.Annotations["foo"])
|
|
||||||
if platforms.Format(*mfst.Platform) == "linux/amd64" {
|
|
||||||
require.Equal(t, "baz", mfst.Annotations["bar"])
|
|
||||||
} else {
|
|
||||||
require.Empty(t, mfst.Annotations["bar"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func createDockerfile(t *testing.T) string {
|
|
||||||
dockerfile := []byte(`
|
|
||||||
FROM scratch
|
|
||||||
ARG TARGETARCH
|
|
||||||
COPY foo-${TARGETARCH} /foo
|
|
||||||
`)
|
|
||||||
dir := tmpdir(
|
|
||||||
t,
|
|
||||||
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
|
||||||
fstest.CreateFile("foo-amd64", []byte("foo-amd64"), 0600),
|
|
||||||
fstest.CreateFile("foo-arm64", []byte("foo-arm64"), 0600),
|
|
||||||
)
|
|
||||||
return dir
|
|
||||||
}
|
|
||||||
@@ -33,8 +33,6 @@ func testInspect(t *testing.T, sb integration.Sandbox) {
|
|||||||
driver = strings.TrimSpace(v)
|
driver = strings.TrimSpace(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
require.Equal(t, sb.Address(), name)
|
require.Equal(t, sb.Address(), name)
|
||||||
sbDriver, _, _ := strings.Cut(sb.Name(), "+")
|
require.Equal(t, sb.Name(), driver)
|
||||||
require.Equal(t, sbDriver, driver)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package tests
|
|||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/containerd/continuity/fs/fstest"
|
"github.com/containerd/continuity/fs/fstest"
|
||||||
@@ -48,7 +47,6 @@ func buildxCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd {
|
|||||||
|
|
||||||
if builder := sb.Address(); builder != "" {
|
if builder := sb.Address(); builder != "" {
|
||||||
cmd.Args = append(cmd.Args, "--builder="+builder)
|
cmd.Args = append(cmd.Args, "--builder="+builder)
|
||||||
cmd.Env = append(cmd.Env, "BUILDX_CONFIG=/tmp/buildx-"+builder)
|
|
||||||
}
|
}
|
||||||
if context := sb.DockerAddress(); context != "" {
|
if context := sb.DockerAddress(); context != "" {
|
||||||
cmd.Env = append(cmd.Env, "DOCKER_CONTEXT="+context)
|
cmd.Env = append(cmd.Env, "DOCKER_CONTEXT="+context)
|
||||||
@@ -56,20 +54,3 @@ func buildxCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd {
|
|||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func dockerCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd {
|
|
||||||
cmd := exec.Command("docker")
|
|
||||||
cmd.Env = append([]string{}, os.Environ()...)
|
|
||||||
for _, opt := range opts {
|
|
||||||
opt(cmd)
|
|
||||||
}
|
|
||||||
if context := sb.DockerAddress(); context != "" {
|
|
||||||
cmd.Env = append(cmd.Env, "DOCKER_CONTEXT="+context)
|
|
||||||
}
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func isDockerWorker(sb integration.Sandbox) bool {
|
|
||||||
sbDriver, _, _ := strings.Cut(sb.Name(), "+")
|
|
||||||
return sbDriver == "docker"
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -7,11 +7,10 @@ import (
|
|||||||
"github.com/docker/buildx/tests/workers"
|
"github.com/docker/buildx/tests/workers"
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
"github.com/moby/buildkit/util/testutil/integration"
|
"github.com/moby/buildkit/util/testutil/integration"
|
||||||
bkworkers "github.com/moby/buildkit/util/testutil/workers"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
if bkworkers.IsTestDockerd() {
|
if integration.IsTestDockerd() {
|
||||||
workers.InitDockerWorker()
|
workers.InitDockerWorker()
|
||||||
workers.InitDockerContainerWorker()
|
workers.InitDockerContainerWorker()
|
||||||
} else {
|
} else {
|
||||||
@@ -25,15 +24,13 @@ func TestIntegration(t *testing.T) {
|
|||||||
tests = append(tests, bakeTests...)
|
tests = append(tests, bakeTests...)
|
||||||
tests = append(tests, inspectTests...)
|
tests = append(tests, inspectTests...)
|
||||||
tests = append(tests, lsTests...)
|
tests = append(tests, lsTests...)
|
||||||
tests = append(tests, imagetoolsTests...)
|
|
||||||
tests = append(tests, versionTests...)
|
|
||||||
testIntegration(t, tests...)
|
testIntegration(t, tests...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testIntegration(t *testing.T, funcs ...func(t *testing.T, sb integration.Sandbox)) {
|
func testIntegration(t *testing.T, funcs ...func(t *testing.T, sb integration.Sandbox)) {
|
||||||
mirroredImages := integration.OfficialImages("busybox:latest", "alpine:latest")
|
mirroredImages := integration.OfficialImages("busybox:latest", "alpine:latest")
|
||||||
buildkitImage := "docker.io/moby/buildkit:buildx-stable-1"
|
buildkitImage := "docker.io/moby/buildkit:buildx-stable-1"
|
||||||
if bkworkers.IsTestDockerd() {
|
if integration.IsTestDockerd() {
|
||||||
if img, ok := os.LookupEnv("TEST_BUILDKIT_IMAGE"); ok {
|
if img, ok := os.LookupEnv("TEST_BUILDKIT_IMAGE"); ok {
|
||||||
ref, err := reference.ParseNormalizedNamed(img)
|
ref, err := reference.ParseNormalizedNamed(img)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|||||||
@@ -23,10 +23,9 @@ func testLs(t *testing.T, sb integration.Sandbox) {
|
|||||||
out, err := lsCmd(sb)
|
out, err := lsCmd(sb)
|
||||||
require.NoError(t, err, string(out))
|
require.NoError(t, err, string(out))
|
||||||
|
|
||||||
sbDriver, _, _ := strings.Cut(sb.Name(), "+")
|
|
||||||
for _, line := range strings.Split(out, "\n") {
|
for _, line := range strings.Split(out, "\n") {
|
||||||
if strings.Contains(line, sb.Address()) {
|
if strings.Contains(line, sb.Address()) {
|
||||||
require.Contains(t, line, sbDriver)
|
require.Contains(t, line, sb.Name())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
package tests
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/moby/buildkit/util/testutil/integration"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"golang.org/x/mod/module"
|
|
||||||
"golang.org/x/mod/semver"
|
|
||||||
)
|
|
||||||
|
|
||||||
var versionTests = []func(t *testing.T, sb integration.Sandbox){
|
|
||||||
testVersion,
|
|
||||||
}
|
|
||||||
|
|
||||||
func testVersion(t *testing.T, sb integration.Sandbox) {
|
|
||||||
cmd := buildxCmd(sb, withArgs("version"))
|
|
||||||
out, err := cmd.CombinedOutput()
|
|
||||||
require.NoError(t, err, string(out))
|
|
||||||
|
|
||||||
// There should be at least one newline and the first line
|
|
||||||
// of output should contain the name, version, and possibly a revision.
|
|
||||||
firstLine, _, hasNewline := strings.Cut(string(out), "\n")
|
|
||||||
require.True(t, hasNewline, "At least one newline is required in the output")
|
|
||||||
|
|
||||||
// Log the output to make debugging easier.
|
|
||||||
t.Log(firstLine)
|
|
||||||
|
|
||||||
// Split by spaces into at least 2 fields.
|
|
||||||
fields := strings.Fields(firstLine)
|
|
||||||
require.GreaterOrEqual(t, len(fields), 2, "Expected at least 2 fields in the first line")
|
|
||||||
|
|
||||||
// First field should be an import path.
|
|
||||||
// This can be any valid import path for Go
|
|
||||||
// so don't set too many restrictions here.
|
|
||||||
// Just checking if the import path is a valid Go
|
|
||||||
// path should be suitable enough to make sure this is ok.
|
|
||||||
// Using CheckImportPath instead of CheckPath as it is less
|
|
||||||
// restrictive.
|
|
||||||
importPath := fields[0]
|
|
||||||
require.NoError(t, module.CheckImportPath(importPath), "First field was not a valid import path: %+v", importPath)
|
|
||||||
|
|
||||||
// Second field should be a version.
|
|
||||||
// This defaults to something that's still compatible
|
|
||||||
// with semver.
|
|
||||||
version := fields[1]
|
|
||||||
require.True(t, semver.IsValid(version), "Second field was not valid semver: %+v", version)
|
|
||||||
|
|
||||||
// Revision should be empty or should look like a git hash.
|
|
||||||
if len(fields) > 2 && len(fields[2]) > 0 {
|
|
||||||
revision := fields[2]
|
|
||||||
require.Regexp(t, `[0-9a-f]{40}`, revision, "Third field was not a git revision: %+v", revision)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +1,10 @@
|
|||||||
package workers
|
package workers
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/moby/buildkit/util/testutil/integration"
|
|
||||||
)
|
|
||||||
|
|
||||||
type backend struct {
|
type backend struct {
|
||||||
builder string
|
builder string
|
||||||
context string
|
context string
|
||||||
unsupportedFeatures []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ integration.Backend = &backend{}
|
|
||||||
|
|
||||||
func (s *backend) Address() string {
|
func (s *backend) Address() string {
|
||||||
return s.builder
|
return s.builder
|
||||||
}
|
}
|
||||||
@@ -34,26 +24,3 @@ func (s *backend) Snapshotter() string {
|
|||||||
func (s *backend) Rootless() bool {
|
func (s *backend) Rootless() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s backend) Supports(feature string) bool {
|
|
||||||
if enabledFeatures := os.Getenv("BUILDKIT_TEST_ENABLE_FEATURES"); enabledFeatures != "" {
|
|
||||||
for _, enabledFeature := range strings.Split(enabledFeatures, ",") {
|
|
||||||
if feature == enabledFeature {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if disabledFeatures := os.Getenv("BUILDKIT_TEST_DISABLE_FEATURES"); disabledFeatures != "" {
|
|
||||||
for _, disabledFeature := range strings.Split(disabledFeatures, ",") {
|
|
||||||
if feature == disabledFeature {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, unsupportedFeature := range s.unsupportedFeatures {
|
|
||||||
if feature == unsupportedFeature {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/moby/buildkit/identity"
|
"github.com/moby/buildkit/identity"
|
||||||
"github.com/moby/buildkit/util/testutil/integration"
|
"github.com/moby/buildkit/util/testutil/integration"
|
||||||
@@ -19,13 +18,6 @@ func InitDockerContainerWorker() {
|
|||||||
|
|
||||||
type containerWorker struct {
|
type containerWorker struct {
|
||||||
id string
|
id string
|
||||||
|
|
||||||
unsupported []string
|
|
||||||
|
|
||||||
docker integration.Backend
|
|
||||||
dockerClose func() error
|
|
||||||
dockerErr error
|
|
||||||
dockerOnce sync.Once
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *containerWorker) Name() string {
|
func (w *containerWorker) Name() string {
|
||||||
@@ -37,11 +29,9 @@ func (w *containerWorker) Rootless() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *containerWorker) New(ctx context.Context, cfg *integration.BackendConfig) (integration.Backend, func() error, error) {
|
func (w *containerWorker) New(ctx context.Context, cfg *integration.BackendConfig) (integration.Backend, func() error, error) {
|
||||||
w.dockerOnce.Do(func() {
|
bk, bkclose, err := dockerWorker{id: w.id}.New(ctx, cfg)
|
||||||
w.docker, w.dockerClose, w.dockerErr = dockerWorker{id: w.id}.New(ctx, cfg)
|
if err != nil {
|
||||||
})
|
return bk, bkclose, err
|
||||||
if w.dockerErr != nil {
|
|
||||||
return w.docker, w.dockerClose, w.dockerErr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
name := "integration-container-" + identity.NewID()
|
name := "integration-container-" + identity.NewID()
|
||||||
@@ -52,37 +42,25 @@ func (w *containerWorker) New(ctx context.Context, cfg *integration.BackendConfi
|
|||||||
"--driver=docker-container",
|
"--driver=docker-container",
|
||||||
"--driver-opt=network=host",
|
"--driver-opt=network=host",
|
||||||
)
|
)
|
||||||
cmd.Env = append(
|
cmd.Env = append(os.Environ(), "DOCKER_CONTEXT="+bk.DockerAddress())
|
||||||
os.Environ(),
|
|
||||||
"BUILDX_CONFIG=/tmp/buildx-"+name,
|
|
||||||
"DOCKER_CONTEXT="+w.docker.DockerAddress(),
|
|
||||||
)
|
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
return nil, nil, errors.Wrapf(err, "failed to create buildx instance %s", name)
|
return nil, nil, errors.Wrapf(err, "failed to create buildx instance %s", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
cl := func() error {
|
cl := func() error {
|
||||||
|
var err error
|
||||||
|
if err1 := bkclose(); err == nil {
|
||||||
|
err = err1
|
||||||
|
}
|
||||||
cmd := exec.Command("buildx", "rm", "-f", name)
|
cmd := exec.Command("buildx", "rm", "-f", name)
|
||||||
return cmd.Run()
|
if err1 := cmd.Run(); err == nil {
|
||||||
|
err = err1
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &backend{
|
return &backend{
|
||||||
context: w.docker.DockerAddress(),
|
context: bk.DockerAddress(),
|
||||||
builder: name,
|
builder: name,
|
||||||
unsupportedFeatures: w.unsupported,
|
|
||||||
}, cl, nil
|
}, cl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *containerWorker) Close() error {
|
|
||||||
if close := w.dockerClose; close != nil {
|
|
||||||
return close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset the worker to be ready to go again
|
|
||||||
w.docker = nil
|
|
||||||
w.dockerClose = nil
|
|
||||||
w.dockerErr = nil
|
|
||||||
w.dockerOnce = sync.Once{}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,12 +2,10 @@ package workers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"os"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
||||||
"github.com/moby/buildkit/identity"
|
"github.com/moby/buildkit/identity"
|
||||||
"github.com/moby/buildkit/util/testutil/integration"
|
"github.com/moby/buildkit/util/testutil/integration"
|
||||||
bkworkers "github.com/moby/buildkit/util/testutil/workers"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -15,16 +13,10 @@ func InitDockerWorker() {
|
|||||||
integration.Register(&dockerWorker{
|
integration.Register(&dockerWorker{
|
||||||
id: "docker",
|
id: "docker",
|
||||||
})
|
})
|
||||||
integration.Register(&dockerWorker{
|
|
||||||
id: "docker+containerd",
|
|
||||||
containerdSnapshotter: true,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type dockerWorker struct {
|
type dockerWorker struct {
|
||||||
id string
|
id string
|
||||||
containerdSnapshotter bool
|
|
||||||
unsupported []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c dockerWorker) Name() string {
|
func (c dockerWorker) Name() string {
|
||||||
@@ -36,9 +28,8 @@ func (c dockerWorker) Rootless() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c dockerWorker) New(ctx context.Context, cfg *integration.BackendConfig) (b integration.Backend, cl func() error, err error) {
|
func (c dockerWorker) New(ctx context.Context, cfg *integration.BackendConfig) (b integration.Backend, cl func() error, err error) {
|
||||||
moby := bkworkers.Moby{
|
moby := integration.Moby{
|
||||||
ID: c.id,
|
ID: c.id,
|
||||||
ContainerdSnapshotter: c.containerdSnapshotter,
|
|
||||||
}
|
}
|
||||||
bk, bkclose, err := moby.New(ctx, cfg)
|
bk, bkclose, err := moby.New(ctx, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -50,9 +41,8 @@ func (c dockerWorker) New(ctx context.Context, cfg *integration.BackendConfig) (
|
|||||||
name,
|
name,
|
||||||
"--docker", "host="+bk.DockerAddress(),
|
"--docker", "host="+bk.DockerAddress(),
|
||||||
)
|
)
|
||||||
cmd.Env = append(os.Environ(), "BUILDX_CONFIG=/tmp/buildx-"+name)
|
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
return bk, cl, errors.Wrapf(err, "failed to create buildx instance %s", name)
|
return nil, cl, errors.Wrapf(err, "failed to create buildx instance %s", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
cl = func() error {
|
cl = func() error {
|
||||||
@@ -68,12 +58,7 @@ func (c dockerWorker) New(ctx context.Context, cfg *integration.BackendConfig) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &backend{
|
return &backend{
|
||||||
builder: name,
|
builder: name,
|
||||||
context: name,
|
context: name,
|
||||||
unsupportedFeatures: c.unsupported,
|
|
||||||
}, cl, nil
|
}, cl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c dockerWorker) Close() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
package workers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/moby/buildkit/util/testutil/integration"
|
|
||||||
)
|
|
||||||
|
|
||||||
var features = map[string]struct{}{}
|
|
||||||
|
|
||||||
func CheckFeatureCompat(t *testing.T, sb integration.Sandbox, reason ...string) {
|
|
||||||
integration.CheckFeatureCompat(t, sb, features, reason...)
|
|
||||||
}
|
|
||||||
@@ -2,12 +2,10 @@ package workers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"os"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
||||||
"github.com/moby/buildkit/identity"
|
"github.com/moby/buildkit/identity"
|
||||||
"github.com/moby/buildkit/util/testutil/integration"
|
"github.com/moby/buildkit/util/testutil/integration"
|
||||||
bkworkers "github.com/moby/buildkit/util/testutil/workers"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -18,8 +16,7 @@ func InitRemoteWorker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type remoteWorker struct {
|
type remoteWorker struct {
|
||||||
id string
|
id string
|
||||||
unsupported []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w remoteWorker) Name() string {
|
func (w remoteWorker) Name() string {
|
||||||
@@ -31,7 +28,7 @@ func (w remoteWorker) Rootless() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w remoteWorker) New(ctx context.Context, cfg *integration.BackendConfig) (b integration.Backend, cl func() error, err error) {
|
func (w remoteWorker) New(ctx context.Context, cfg *integration.BackendConfig) (b integration.Backend, cl func() error, err error) {
|
||||||
oci := bkworkers.OCI{ID: w.id}
|
oci := integration.OCI{ID: w.id}
|
||||||
bk, bkclose, err := oci.New(ctx, cfg)
|
bk, bkclose, err := oci.New(ctx, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return bk, cl, err
|
return bk, cl, err
|
||||||
@@ -44,7 +41,6 @@ func (w remoteWorker) New(ctx context.Context, cfg *integration.BackendConfig) (
|
|||||||
"--driver=remote",
|
"--driver=remote",
|
||||||
bk.Address(),
|
bk.Address(),
|
||||||
)
|
)
|
||||||
cmd.Env = append(os.Environ(), "BUILDX_CONFIG=/tmp/buildx-"+name)
|
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
return nil, nil, errors.Wrapf(err, "failed to create buildx instance %s", name)
|
return nil, nil, errors.Wrapf(err, "failed to create buildx instance %s", name)
|
||||||
}
|
}
|
||||||
@@ -62,11 +58,6 @@ func (w remoteWorker) New(ctx context.Context, cfg *integration.BackendConfig) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &backend{
|
return &backend{
|
||||||
builder: name,
|
builder: name,
|
||||||
unsupportedFeatures: w.unsupported,
|
|
||||||
}, cl, nil
|
}, cl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w remoteWorker) Close() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,15 +1,21 @@
|
|||||||
package buildflags
|
package buildflags
|
||||||
|
|
||||||
import "github.com/moby/buildkit/util/entitlements"
|
import (
|
||||||
|
"github.com/moby/buildkit/util/entitlements"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
func ParseEntitlements(in []string) ([]entitlements.Entitlement, error) {
|
func ParseEntitlements(in []string) ([]entitlements.Entitlement, error) {
|
||||||
out := make([]entitlements.Entitlement, 0, len(in))
|
out := make([]entitlements.Entitlement, 0, len(in))
|
||||||
for _, v := range in {
|
for _, v := range in {
|
||||||
e, err := entitlements.Parse(v)
|
switch v {
|
||||||
if err != nil {
|
case "security.insecure":
|
||||||
return nil, err
|
out = append(out, entitlements.EntitlementSecurityInsecure)
|
||||||
|
case "network.host":
|
||||||
|
out = append(out, entitlements.EntitlementNetworkHost)
|
||||||
|
default:
|
||||||
|
return nil, errors.Errorf("invalid entitlement: %v", v)
|
||||||
}
|
}
|
||||||
out = append(out, e)
|
|
||||||
}
|
}
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,24 +46,17 @@ func (c *Client) LoadImage(ctx context.Context, name string, status progress.Wri
|
|||||||
w = &waitingWriter{
|
w = &waitingWriter{
|
||||||
PipeWriter: pw,
|
PipeWriter: pw,
|
||||||
f: func() {
|
f: func() {
|
||||||
handleErr := func(err error) {
|
resp, err := dapi.ImageLoad(ctx, pr, false)
|
||||||
|
defer close(done)
|
||||||
|
if err != nil {
|
||||||
pr.CloseWithError(err)
|
pr.CloseWithError(err)
|
||||||
w.mu.Lock()
|
w.mu.Lock()
|
||||||
w.err = err
|
w.err = err
|
||||||
w.mu.Unlock()
|
w.mu.Unlock()
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := dapi.ImageLoad(ctx, pr, false)
|
|
||||||
defer close(done)
|
|
||||||
if err != nil {
|
|
||||||
handleErr(err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
prog := progress.WithPrefix(status, "", false)
|
prog := progress.WithPrefix(status, "", false)
|
||||||
if err := fromReader(prog, "importing to docker", resp.Body); err != nil {
|
progress.FromReader(prog, "importing to docker", resp.Body)
|
||||||
handleErr(err)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
done: done,
|
done: done,
|
||||||
cancel: cancel,
|
cancel: cancel,
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ func New(opts ...Option) (*Git, error) {
|
|||||||
|
|
||||||
c.gitpath, err = gitPath(c.wd)
|
c.gitpath, err = gitPath(c.wd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.New("git not found in PATH")
|
||||||
}
|
}
|
||||||
|
|
||||||
return c, nil
|
return c, nil
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containerd/containerd/content"
|
"github.com/containerd/containerd/content"
|
||||||
@@ -14,7 +13,6 @@ import (
|
|||||||
"github.com/containerd/containerd/platforms"
|
"github.com/containerd/containerd/platforms"
|
||||||
"github.com/containerd/containerd/remotes"
|
"github.com/containerd/containerd/remotes"
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
"github.com/moby/buildkit/exporter/containerimage/exptypes"
|
|
||||||
"github.com/moby/buildkit/util/contentutil"
|
"github.com/moby/buildkit/util/contentutil"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
"github.com/opencontainers/image-spec/specs-go"
|
"github.com/opencontainers/image-spec/specs-go"
|
||||||
@@ -28,7 +26,7 @@ type Source struct {
|
|||||||
Ref reference.Named
|
Ref reference.Named
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) Combine(ctx context.Context, srcs []*Source, ann map[string]string) ([]byte, ocispec.Descriptor, error) {
|
func (r *Resolver) Combine(ctx context.Context, srcs []*Source) ([]byte, ocispec.Descriptor, error) {
|
||||||
eg, ctx := errgroup.WithContext(ctx)
|
eg, ctx := errgroup.WithContext(ctx)
|
||||||
|
|
||||||
dts := make([][]byte, len(srcs))
|
dts := make([][]byte, len(srcs))
|
||||||
@@ -77,7 +75,7 @@ func (r *Resolver) Combine(ctx context.Context, srcs []*Source, ann map[string]s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// on single source, return original bytes
|
// on single source, return original bytes
|
||||||
if len(srcs) == 1 && len(ann) == 0 {
|
if len(srcs) == 1 {
|
||||||
if mt := srcs[0].Desc.MediaType; mt == images.MediaTypeDockerSchema2ManifestList || mt == ocispec.MediaTypeImageIndex {
|
if mt := srcs[0].Desc.MediaType; mt == images.MediaTypeDockerSchema2ManifestList || mt == ocispec.MediaTypeImageIndex {
|
||||||
return dts[0], srcs[0].Desc, nil
|
return dts[0], srcs[0].Desc, nil
|
||||||
}
|
}
|
||||||
@@ -140,39 +138,12 @@ func (r *Resolver) Combine(ctx context.Context, srcs []*Source, ann map[string]s
|
|||||||
mt = ocispec.MediaTypeImageIndex
|
mt = ocispec.MediaTypeImageIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
// annotations are only allowed on OCI indexes
|
|
||||||
indexAnnotation := make(map[string]string)
|
|
||||||
if mt == ocispec.MediaTypeImageIndex {
|
|
||||||
annotations, err := parseAnnotations(ann)
|
|
||||||
if err != nil {
|
|
||||||
return nil, ocispec.Descriptor{}, err
|
|
||||||
}
|
|
||||||
if len(annotations[exptypes.AnnotationIndex]) > 0 {
|
|
||||||
for k, v := range annotations[exptypes.AnnotationIndex] {
|
|
||||||
indexAnnotation[k.Key] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(annotations[exptypes.AnnotationManifestDescriptor]) > 0 {
|
|
||||||
for i := 0; i < len(newDescs); i++ {
|
|
||||||
if newDescs[i].Annotations == nil {
|
|
||||||
newDescs[i].Annotations = map[string]string{}
|
|
||||||
}
|
|
||||||
for k, v := range annotations[exptypes.AnnotationManifestDescriptor] {
|
|
||||||
if k.Platform == nil || k.PlatformString() == platforms.Format(*newDescs[i].Platform) {
|
|
||||||
newDescs[i].Annotations[k.Key] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
idxBytes, err := json.MarshalIndent(ocispec.Index{
|
idxBytes, err := json.MarshalIndent(ocispec.Index{
|
||||||
MediaType: mt,
|
MediaType: mt,
|
||||||
Versioned: specs.Versioned{
|
Versioned: specs.Versioned{
|
||||||
SchemaVersion: 2,
|
SchemaVersion: 2,
|
||||||
},
|
},
|
||||||
Manifests: newDescs,
|
Manifests: newDescs,
|
||||||
Annotations: indexAnnotation,
|
|
||||||
}, "", " ")
|
}, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, ocispec.Descriptor{}, errors.Wrap(err, "failed to marshal index")
|
return nil, ocispec.Descriptor{}, errors.Wrap(err, "failed to marshal index")
|
||||||
@@ -295,52 +266,3 @@ func detectMediaType(dt []byte) (string, error) {
|
|||||||
|
|
||||||
return images.MediaTypeDockerSchema2ManifestList, nil
|
return images.MediaTypeDockerSchema2ManifestList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseAnnotations(ann map[string]string) (map[string]map[exptypes.AnnotationKey]string, error) {
|
|
||||||
// TODO: use buildkit's annotation parser once it supports setting custom prefix and ":" separator
|
|
||||||
annotationRegexp := regexp.MustCompile(`^([a-z-]+)(?:\[([A-Za-z0-9_/-]+)\])?:(\S+)$`)
|
|
||||||
indexAnnotations := make(map[exptypes.AnnotationKey]string)
|
|
||||||
manifestDescriptorAnnotations := make(map[exptypes.AnnotationKey]string)
|
|
||||||
for k, v := range ann {
|
|
||||||
groups := annotationRegexp.FindStringSubmatch(k)
|
|
||||||
if groups == nil {
|
|
||||||
return nil, errors.Errorf("invalid annotation format, expected <type>:<key>=<value>, got %q", k)
|
|
||||||
}
|
|
||||||
|
|
||||||
typ, platform, key := groups[1], groups[2], groups[3]
|
|
||||||
var ociPlatform *ocispec.Platform
|
|
||||||
if platform != "" {
|
|
||||||
p, err := platforms.Parse(platform)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "invalid platform %q", platform)
|
|
||||||
}
|
|
||||||
ociPlatform = &p
|
|
||||||
}
|
|
||||||
switch typ {
|
|
||||||
case exptypes.AnnotationIndex:
|
|
||||||
ak := exptypes.AnnotationKey{
|
|
||||||
Type: typ,
|
|
||||||
Platform: ociPlatform,
|
|
||||||
Key: key,
|
|
||||||
}
|
|
||||||
indexAnnotations[ak] = v
|
|
||||||
case exptypes.AnnotationManifestDescriptor:
|
|
||||||
ak := exptypes.AnnotationKey{
|
|
||||||
Type: typ,
|
|
||||||
Platform: ociPlatform,
|
|
||||||
Key: key,
|
|
||||||
}
|
|
||||||
manifestDescriptorAnnotations[ak] = v
|
|
||||||
case exptypes.AnnotationManifest:
|
|
||||||
return nil, errors.Errorf("%q annotations are not supported yet", typ)
|
|
||||||
case exptypes.AnnotationIndexDescriptor:
|
|
||||||
return nil, errors.Errorf("%q annotations are invalid while creating an image", typ)
|
|
||||||
default:
|
|
||||||
return nil, errors.Errorf("unknown annotation type %q", typ)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map[string]map[exptypes.AnnotationKey]string{
|
|
||||||
exptypes.AnnotationIndex: indexAnnotations,
|
|
||||||
exptypes.AnnotationManifestDescriptor: manifestDescriptorAnnotations,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import (
|
|||||||
clitypes "github.com/docker/cli/cli/config/types"
|
clitypes "github.com/docker/cli/cli/config/types"
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
"github.com/moby/buildkit/util/contentutil"
|
"github.com/moby/buildkit/util/contentutil"
|
||||||
|
"github.com/moby/buildkit/util/imageutil"
|
||||||
"github.com/moby/buildkit/util/tracing"
|
"github.com/moby/buildkit/util/tracing"
|
||||||
|
"github.com/opencontainers/go-digest"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@@ -160,3 +162,11 @@ func RegistryAuthForRef(ref string, a Auth) (string, error) {
|
|||||||
}
|
}
|
||||||
return base64.URLEncoding.EncodeToString(buf), nil
|
return base64.URLEncoding.EncodeToString(buf), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Resolver) ImageConfig(ctx context.Context, in string, platform *ocispec.Platform) (digest.Digest, []byte, error) {
|
||||||
|
in, _, err := r.Resolve(ctx, in)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
return imageutil.Config(ctx, in, r.resolver(), r.buffer, nil, platform)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,19 +1,15 @@
|
|||||||
package dockerutil
|
package progress
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/buildx/util/progress"
|
|
||||||
"github.com/docker/cli/cli/streams"
|
|
||||||
"github.com/docker/docker/pkg/jsonmessage"
|
|
||||||
"github.com/moby/buildkit/client"
|
"github.com/moby/buildkit/client"
|
||||||
"github.com/moby/buildkit/identity"
|
"github.com/moby/buildkit/identity"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func fromReader(w progress.Writer, name string, rc io.ReadCloser) error {
|
func FromReader(w Writer, name string, rc io.ReadCloser) {
|
||||||
dgst := digest.FromBytes([]byte(identity.NewID()))
|
dgst := digest.FromBytes([]byte(identity.NewID()))
|
||||||
tm := time.Now()
|
tm := time.Now()
|
||||||
|
|
||||||
@@ -27,12 +23,7 @@ func fromReader(w progress.Writer, name string, rc io.ReadCloser) error {
|
|||||||
Vertexes: []*client.Vertex{&vtx},
|
Vertexes: []*client.Vertex{&vtx},
|
||||||
})
|
})
|
||||||
|
|
||||||
err := jsonmessage.DisplayJSONMessagesToStream(rc, streams.NewOut(io.Discard), nil)
|
_, err := io.Copy(io.Discard, rc)
|
||||||
if err != nil {
|
|
||||||
if jerr, ok := err.(*jsonmessage.JSONError); ok {
|
|
||||||
err = errors.New(jerr.Message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tm2 := time.Now()
|
tm2 := time.Now()
|
||||||
vtx2 := vtx
|
vtx2 := vtx
|
||||||
@@ -43,5 +34,4 @@ func fromReader(w progress.Writer, name string, rc io.ReadCloser) error {
|
|||||||
w.Write(&client.SolveStatus{
|
w.Write(&client.SolveStatus{
|
||||||
Vertexes: []*client.Vertex{&vtx2},
|
Vertexes: []*client.Vertex{&vtx2},
|
||||||
})
|
})
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
@@ -20,9 +20,7 @@ func (w *pw) Write(st *client.SolveStatus) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if w.diff != nil {
|
if w.diff != nil {
|
||||||
vertexes := make([]*client.Vertex, 0, len(st.Vertexes))
|
|
||||||
for _, v := range st.Vertexes {
|
for _, v := range st.Vertexes {
|
||||||
v := *v
|
|
||||||
if v.Started != nil {
|
if v.Started != nil {
|
||||||
d := v.Started.Add(-*w.diff)
|
d := v.Started.Add(-*w.diff)
|
||||||
v.Started = &d
|
v.Started = &d
|
||||||
@@ -31,12 +29,8 @@ func (w *pw) Write(st *client.SolveStatus) {
|
|||||||
d := v.Completed.Add(-*w.diff)
|
d := v.Completed.Add(-*w.diff)
|
||||||
v.Completed = &d
|
v.Completed = &d
|
||||||
}
|
}
|
||||||
vertexes = append(vertexes, &v)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
statuses := make([]*client.VertexStatus, 0, len(st.Statuses))
|
|
||||||
for _, v := range st.Statuses {
|
for _, v := range st.Statuses {
|
||||||
v := *v
|
|
||||||
if v.Started != nil {
|
if v.Started != nil {
|
||||||
d := v.Started.Add(-*w.diff)
|
d := v.Started.Add(-*w.diff)
|
||||||
v.Started = &d
|
v.Started = &d
|
||||||
@@ -46,21 +40,9 @@ func (w *pw) Write(st *client.SolveStatus) {
|
|||||||
v.Completed = &d
|
v.Completed = &d
|
||||||
}
|
}
|
||||||
v.Timestamp = v.Timestamp.Add(-*w.diff)
|
v.Timestamp = v.Timestamp.Add(-*w.diff)
|
||||||
statuses = append(statuses, &v)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logs := make([]*client.VertexLog, 0, len(st.Logs))
|
|
||||||
for _, v := range st.Logs {
|
for _, v := range st.Logs {
|
||||||
v := *v
|
|
||||||
v.Timestamp = v.Timestamp.Add(-*w.diff)
|
v.Timestamp = v.Timestamp.Add(-*w.diff)
|
||||||
logs = append(logs, &v)
|
|
||||||
}
|
|
||||||
|
|
||||||
st = &client.SolveStatus{
|
|
||||||
Vertexes: vertexes,
|
|
||||||
Statuses: statuses,
|
|
||||||
Logs: logs,
|
|
||||||
Warnings: st.Warnings,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.Writer.Write(st)
|
w.Writer.Write(st)
|
||||||
|
|||||||
62
vendor/github.com/compose-spec/compose-go/cli/options.go
generated
vendored
62
vendor/github.com/compose-spec/compose-go/cli/options.go
generated
vendored
@@ -17,6 +17,7 @@
|
|||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -249,7 +250,7 @@ func WithDotEnv(o *ProjectOptions) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
envMap, err := dotenv.GetEnvFromFile(o.Environment, wd, o.EnvFiles)
|
envMap, err := GetEnvFromFile(o.Environment, wd, o.EnvFiles)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -261,6 +262,65 @@ func WithDotEnv(o *ProjectOptions) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetEnvFromFile(currentEnv map[string]string, workingDir string, filenames []string) (map[string]string, error) {
|
||||||
|
envMap := make(map[string]string)
|
||||||
|
|
||||||
|
dotEnvFiles := filenames
|
||||||
|
if len(dotEnvFiles) == 0 {
|
||||||
|
dotEnvFiles = append(dotEnvFiles, filepath.Join(workingDir, ".env"))
|
||||||
|
}
|
||||||
|
for _, dotEnvFile := range dotEnvFiles {
|
||||||
|
abs, err := filepath.Abs(dotEnvFile)
|
||||||
|
if err != nil {
|
||||||
|
return envMap, err
|
||||||
|
}
|
||||||
|
dotEnvFile = abs
|
||||||
|
|
||||||
|
s, err := os.Stat(dotEnvFile)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
if len(filenames) == 0 {
|
||||||
|
return envMap, nil
|
||||||
|
}
|
||||||
|
return envMap, errors.Errorf("Couldn't find env file: %s", dotEnvFile)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return envMap, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.IsDir() {
|
||||||
|
if len(filenames) == 0 {
|
||||||
|
return envMap, nil
|
||||||
|
}
|
||||||
|
return envMap, errors.Errorf("%s is a directory", dotEnvFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := os.ReadFile(dotEnvFile)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return nil, errors.Errorf("Couldn't read env file: %s", dotEnvFile)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return envMap, err
|
||||||
|
}
|
||||||
|
|
||||||
|
env, err := dotenv.ParseWithLookup(bytes.NewReader(b), func(k string) (string, bool) {
|
||||||
|
v, ok := currentEnv[k]
|
||||||
|
if ok {
|
||||||
|
return v, true
|
||||||
|
}
|
||||||
|
v, ok = envMap[k]
|
||||||
|
return v, ok
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return envMap, errors.Wrapf(err, "failed to read %s", dotEnvFile)
|
||||||
|
}
|
||||||
|
for k, v := range env {
|
||||||
|
envMap[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return envMap, nil
|
||||||
|
}
|
||||||
|
|
||||||
// WithInterpolation set ProjectOptions to enable/skip interpolation
|
// WithInterpolation set ProjectOptions to enable/skip interpolation
|
||||||
func WithInterpolation(interpolation bool) ProjectOptionsFn {
|
func WithInterpolation(interpolation bool) ProjectOptionsFn {
|
||||||
return func(o *ProjectOptions) error {
|
return func(o *ProjectOptions) error {
|
||||||
|
|||||||
84
vendor/github.com/compose-spec/compose-go/dotenv/env.go
generated
vendored
84
vendor/github.com/compose-spec/compose-go/dotenv/env.go
generated
vendored
@@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2020 The Compose Specification Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package dotenv
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetEnvFromFile(currentEnv map[string]string, workingDir string, filenames []string) (map[string]string, error) {
|
|
||||||
envMap := make(map[string]string)
|
|
||||||
|
|
||||||
dotEnvFiles := filenames
|
|
||||||
if len(dotEnvFiles) == 0 {
|
|
||||||
dotEnvFiles = append(dotEnvFiles, filepath.Join(workingDir, ".env"))
|
|
||||||
}
|
|
||||||
for _, dotEnvFile := range dotEnvFiles {
|
|
||||||
abs, err := filepath.Abs(dotEnvFile)
|
|
||||||
if err != nil {
|
|
||||||
return envMap, err
|
|
||||||
}
|
|
||||||
dotEnvFile = abs
|
|
||||||
|
|
||||||
s, err := os.Stat(dotEnvFile)
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
if len(filenames) == 0 {
|
|
||||||
return envMap, nil
|
|
||||||
}
|
|
||||||
return envMap, errors.Errorf("Couldn't find env file: %s", dotEnvFile)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return envMap, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if s.IsDir() {
|
|
||||||
if len(filenames) == 0 {
|
|
||||||
return envMap, nil
|
|
||||||
}
|
|
||||||
return envMap, errors.Errorf("%s is a directory", dotEnvFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := os.ReadFile(dotEnvFile)
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return nil, errors.Errorf("Couldn't read env file: %s", dotEnvFile)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return envMap, err
|
|
||||||
}
|
|
||||||
|
|
||||||
env, err := ParseWithLookup(bytes.NewReader(b), func(k string) (string, bool) {
|
|
||||||
v, ok := currentEnv[k]
|
|
||||||
if ok {
|
|
||||||
return v, true
|
|
||||||
}
|
|
||||||
v, ok = envMap[k]
|
|
||||||
return v, ok
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return envMap, errors.Wrapf(err, "failed to read %s", dotEnvFile)
|
|
||||||
}
|
|
||||||
for k, v := range env {
|
|
||||||
envMap[k] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return envMap, nil
|
|
||||||
}
|
|
||||||
13
vendor/github.com/compose-spec/compose-go/dotenv/parser.go
generated
vendored
13
vendor/github.com/compose-spec/compose-go/dotenv/parser.go
generated
vendored
@@ -123,8 +123,8 @@ loop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
return "", "", inherited, fmt.Errorf(
|
return "", "", inherited, fmt.Errorf(
|
||||||
`line %d: unexpected character %q in variable name %q`,
|
`line %d: unexpected character %q in variable name`,
|
||||||
p.line, string(rune), strings.Split(src, "\n")[0])
|
p.line, string(rune))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,24 +153,17 @@ func (p *parser) extractVarValue(src string, envMap map[string]string, lookupFn
|
|||||||
return retVal, rest, err
|
return retVal, rest, err
|
||||||
}
|
}
|
||||||
|
|
||||||
previousCharIsEscape := false
|
|
||||||
// lookup quoted string terminator
|
// lookup quoted string terminator
|
||||||
for i := 1; i < len(src); i++ {
|
for i := 1; i < len(src); i++ {
|
||||||
if src[i] == '\n' {
|
if src[i] == '\n' {
|
||||||
p.line++
|
p.line++
|
||||||
}
|
}
|
||||||
if char := src[i]; char != quote {
|
if char := src[i]; char != quote {
|
||||||
if !previousCharIsEscape && char == '\\' {
|
|
||||||
previousCharIsEscape = true
|
|
||||||
} else {
|
|
||||||
previousCharIsEscape = false
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip escaped quote symbol (\" or \', depends on quote)
|
// skip escaped quote symbol (\" or \', depends on quote)
|
||||||
if previousCharIsEscape {
|
if prevChar := src[i-1]; prevChar == '\\' {
|
||||||
previousCharIsEscape = false
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
3
vendor/github.com/compose-spec/compose-go/loader/full-example.yml
generated
vendored
3
vendor/github.com/compose-spec/compose-go/loader/full-example.yml
generated
vendored
@@ -24,7 +24,7 @@ services:
|
|||||||
- bar
|
- bar
|
||||||
labels: [FOO=BAR]
|
labels: [FOO=BAR]
|
||||||
additional_contexts:
|
additional_contexts:
|
||||||
foo: ./bar
|
foo: /bar
|
||||||
secrets:
|
secrets:
|
||||||
- secret1
|
- secret1
|
||||||
- source: secret2
|
- source: secret2
|
||||||
@@ -181,7 +181,6 @@ services:
|
|||||||
timeout: 1s
|
timeout: 1s
|
||||||
retries: 5
|
retries: 5
|
||||||
start_period: 15s
|
start_period: 15s
|
||||||
start_interval: 5s
|
|
||||||
|
|
||||||
# Any valid image reference - repo, tag, id, sha
|
# Any valid image reference - repo, tag, id, sha
|
||||||
image: redis
|
image: redis
|
||||||
|
|||||||
120
vendor/github.com/compose-spec/compose-go/loader/include.go
generated
vendored
120
vendor/github.com/compose-spec/compose-go/loader/include.go
generated
vendored
@@ -1,120 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2020 The Compose Specification Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package loader
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/dotenv"
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LoadIncludeConfig parse the require config from raw yaml
|
|
||||||
func LoadIncludeConfig(source []interface{}) ([]types.IncludeConfig, error) {
|
|
||||||
var requires []types.IncludeConfig
|
|
||||||
err := Transform(source, &requires)
|
|
||||||
return requires, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var transformIncludeConfig TransformerFunc = func(data interface{}) (interface{}, error) {
|
|
||||||
switch value := data.(type) {
|
|
||||||
case string:
|
|
||||||
return map[string]interface{}{"path": value}, nil
|
|
||||||
case map[string]interface{}:
|
|
||||||
return value, nil
|
|
||||||
default:
|
|
||||||
return data, errors.Errorf("invalid type %T for `include` configuration", value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadInclude(configDetails types.ConfigDetails, model *types.Config, options *Options, loaded []string) (*types.Config, error) {
|
|
||||||
for _, r := range model.Include {
|
|
||||||
for i, p := range r.Path {
|
|
||||||
if !filepath.IsAbs(p) {
|
|
||||||
r.Path[i] = filepath.Join(configDetails.WorkingDir, p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if r.ProjectDirectory == "" {
|
|
||||||
r.ProjectDirectory = filepath.Dir(r.Path[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
loadOptions := options.clone()
|
|
||||||
loadOptions.SetProjectName(model.Name, true)
|
|
||||||
loadOptions.ResolvePaths = true
|
|
||||||
loadOptions.SkipNormalization = true
|
|
||||||
loadOptions.SkipConsistencyCheck = true
|
|
||||||
|
|
||||||
env, err := dotenv.GetEnvFromFile(configDetails.Environment, r.ProjectDirectory, r.EnvFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
imported, err := load(types.ConfigDetails{
|
|
||||||
WorkingDir: r.ProjectDirectory,
|
|
||||||
ConfigFiles: types.ToConfigFiles(r.Path),
|
|
||||||
Environment: env,
|
|
||||||
}, loadOptions, loaded)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = importResources(model, imported, r.Path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
model.Include = nil
|
|
||||||
return model, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// importResources import into model all resources defined by imported, and report error on conflict
|
|
||||||
func importResources(model *types.Config, imported *types.Project, path []string) error {
|
|
||||||
services := mapByName(model.Services)
|
|
||||||
for _, service := range imported.Services {
|
|
||||||
if _, ok := services[service.Name]; ok {
|
|
||||||
return fmt.Errorf("imported compose file %s defines conflicting service %s", path, service.Name)
|
|
||||||
}
|
|
||||||
model.Services = append(model.Services, service)
|
|
||||||
}
|
|
||||||
for n, network := range imported.Networks {
|
|
||||||
if _, ok := model.Networks[n]; ok {
|
|
||||||
return fmt.Errorf("imported compose file %s defines conflicting network %s", path, n)
|
|
||||||
}
|
|
||||||
model.Networks[n] = network
|
|
||||||
}
|
|
||||||
for n, volume := range imported.Volumes {
|
|
||||||
if _, ok := model.Volumes[n]; ok {
|
|
||||||
return fmt.Errorf("imported compose file %s defines conflicting volume %s", path, n)
|
|
||||||
}
|
|
||||||
model.Volumes[n] = volume
|
|
||||||
}
|
|
||||||
for n, secret := range imported.Secrets {
|
|
||||||
if _, ok := model.Secrets[n]; ok {
|
|
||||||
return fmt.Errorf("imported compose file %s defines conflicting secret %s", path, n)
|
|
||||||
}
|
|
||||||
model.Secrets[n] = secret
|
|
||||||
}
|
|
||||||
for n, config := range imported.Configs {
|
|
||||||
if _, ok := model.Configs[n]; ok {
|
|
||||||
return fmt.Errorf("imported compose file %s defines conflicting config %s", path, n)
|
|
||||||
}
|
|
||||||
model.Configs[n] = config
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
203
vendor/github.com/compose-spec/compose-go/loader/loader.go
generated
vendored
203
vendor/github.com/compose-spec/compose-go/loader/loader.go
generated
vendored
@@ -56,8 +56,6 @@ type Options struct {
|
|||||||
SkipConsistencyCheck bool
|
SkipConsistencyCheck bool
|
||||||
// Skip extends
|
// Skip extends
|
||||||
SkipExtends bool
|
SkipExtends bool
|
||||||
// SkipInclude will ignore `include` and only load model from file(s) set by ConfigDetails
|
|
||||||
SkipInclude bool
|
|
||||||
// Interpolation options
|
// Interpolation options
|
||||||
Interpolate *interp.Options
|
Interpolate *interp.Options
|
||||||
// Discard 'env_file' entries after resolving to 'environment' section
|
// Discard 'env_file' entries after resolving to 'environment' section
|
||||||
@@ -70,24 +68,6 @@ type Options struct {
|
|||||||
Profiles []string
|
Profiles []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Options) clone() *Options {
|
|
||||||
return &Options{
|
|
||||||
SkipValidation: o.SkipValidation,
|
|
||||||
SkipInterpolation: o.SkipInterpolation,
|
|
||||||
SkipNormalization: o.SkipNormalization,
|
|
||||||
ResolvePaths: o.ResolvePaths,
|
|
||||||
ConvertWindowsPaths: o.ConvertWindowsPaths,
|
|
||||||
SkipConsistencyCheck: o.SkipConsistencyCheck,
|
|
||||||
SkipExtends: o.SkipExtends,
|
|
||||||
SkipInclude: o.SkipInclude,
|
|
||||||
Interpolate: o.Interpolate,
|
|
||||||
discardEnvFiles: o.discardEnvFiles,
|
|
||||||
projectName: o.projectName,
|
|
||||||
projectNameImperativelySet: o.projectNameImperativelySet,
|
|
||||||
Profiles: o.Profiles,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *Options) SetProjectName(name string, imperativelySet bool) {
|
func (o *Options) SetProjectName(name string, imperativelySet bool) {
|
||||||
o.projectName = name
|
o.projectName = name
|
||||||
o.projectNameImperativelySet = imperativelySet
|
o.projectNameImperativelySet = imperativelySet
|
||||||
@@ -205,7 +185,6 @@ func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types.
|
|||||||
LookupValue: configDetails.LookupEnv,
|
LookupValue: configDetails.LookupEnv,
|
||||||
TypeCastMapping: interpolateTypeCastMapping,
|
TypeCastMapping: interpolateTypeCastMapping,
|
||||||
},
|
},
|
||||||
ResolvePaths: true,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, op := range options {
|
for _, op := range options {
|
||||||
@@ -216,22 +195,8 @@ func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
opts.projectName = projectName
|
|
||||||
return load(configDetails, opts, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func load(configDetails types.ConfigDetails, opts *Options, loaded []string) (*types.Project, error) {
|
|
||||||
var model *types.Config
|
var model *types.Config
|
||||||
|
|
||||||
mainFile := configDetails.ConfigFiles[0].Filename
|
|
||||||
for _, f := range loaded {
|
|
||||||
if f == mainFile {
|
|
||||||
loaded = append(loaded, mainFile)
|
|
||||||
return nil, errors.Errorf("include cycle detected:\n%s\n include %s", loaded[0], strings.Join(loaded[1:], "\n include "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loaded = append(loaded, mainFile)
|
|
||||||
|
|
||||||
for i, file := range configDetails.ConfigFiles {
|
for i, file := range configDetails.ConfigFiles {
|
||||||
var postProcessor PostProcessor
|
var postProcessor PostProcessor
|
||||||
configDict := file.Config
|
configDict := file.Config
|
||||||
@@ -266,18 +231,10 @@ func load(configDetails types.ConfigDetails, opts *Options, loaded []string) (*t
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !opts.SkipInclude {
|
|
||||||
cfg, err = loadInclude(configDetails, cfg, opts, loaded)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
model = cfg
|
model = cfg
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
merged, err := merge([]*types.Config{model, cfg})
|
merged, err := merge([]*types.Config{model, cfg})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -291,8 +248,16 @@ func load(configDetails types.ConfigDetails, opts *Options, loaded []string) (*t
|
|||||||
model = merged
|
model = merged
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, s := range model.Services {
|
||||||
|
var newEnvFiles types.StringList
|
||||||
|
for _, ef := range s.EnvFile {
|
||||||
|
newEnvFiles = append(newEnvFiles, absPath(configDetails.WorkingDir, ef))
|
||||||
|
}
|
||||||
|
s.EnvFile = newEnvFiles
|
||||||
|
}
|
||||||
|
|
||||||
project := &types.Project{
|
project := &types.Project{
|
||||||
Name: opts.projectName,
|
Name: projectName,
|
||||||
WorkingDir: configDetails.WorkingDir,
|
WorkingDir: configDetails.WorkingDir,
|
||||||
Services: model.Services,
|
Services: model.Services,
|
||||||
Networks: model.Networks,
|
Networks: model.Networks,
|
||||||
@@ -304,30 +269,14 @@ func load(configDetails types.ConfigDetails, opts *Options, loaded []string) (*t
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !opts.SkipNormalization {
|
if !opts.SkipNormalization {
|
||||||
err := Normalize(project)
|
err = Normalize(project, opts.ResolvePaths)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.ResolvePaths {
|
|
||||||
err := ResolveRelativePaths(project)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.ConvertWindowsPaths {
|
|
||||||
for i, service := range project.Services {
|
|
||||||
for j, volume := range service.Volumes {
|
|
||||||
service.Volumes[j] = convertVolumePath(volume)
|
|
||||||
}
|
|
||||||
project.Services[i] = service
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !opts.SkipConsistencyCheck {
|
if !opts.SkipConsistencyCheck {
|
||||||
err := checkConsistency(project)
|
err = checkConsistency(project)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -338,7 +287,7 @@ func load(configDetails types.ConfigDetails, opts *Options, loaded []string) (*t
|
|||||||
}
|
}
|
||||||
project.ApplyProfiles(opts.Profiles)
|
project.ApplyProfiles(opts.Profiles)
|
||||||
|
|
||||||
err := project.ResolveServicesEnvironment(opts.discardEnvFiles)
|
err = project.ResolveServicesEnvironment(opts.discardEnvFiles)
|
||||||
|
|
||||||
return project, err
|
return project, err
|
||||||
}
|
}
|
||||||
@@ -470,6 +419,7 @@ func loadSections(filename string, config map[string]interface{}, configDetails
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.Networks, err = LoadNetworks(getSection(config, "networks"))
|
cfg.Networks, err = LoadNetworks(getSection(config, "networks"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -478,15 +428,11 @@ func loadSections(filename string, config map[string]interface{}, configDetails
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cfg.Secrets, err = LoadSecrets(getSection(config, "secrets"))
|
cfg.Secrets, err = LoadSecrets(getSection(config, "secrets"), configDetails, opts.ResolvePaths)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cfg.Configs, err = LoadConfigObjs(getSection(config, "configs"))
|
cfg.Configs, err = LoadConfigObjs(getSection(config, "configs"), configDetails, opts.ResolvePaths)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
cfg.Include, err = LoadIncludeConfig(getSequence(config, "include"))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -505,14 +451,6 @@ func getSection(config map[string]interface{}, key string) map[string]interface{
|
|||||||
return section.(map[string]interface{})
|
return section.(map[string]interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSequence(config map[string]interface{}, key string) []interface{} {
|
|
||||||
section, ok := config[key]
|
|
||||||
if !ok {
|
|
||||||
return make([]interface{}, 0)
|
|
||||||
}
|
|
||||||
return section.([]interface{})
|
|
||||||
}
|
|
||||||
|
|
||||||
// ForbiddenPropertiesError is returned when there are properties in the Compose
|
// ForbiddenPropertiesError is returned when there are properties in the Compose
|
||||||
// file that are forbidden.
|
// file that are forbidden.
|
||||||
type ForbiddenPropertiesError struct {
|
type ForbiddenPropertiesError struct {
|
||||||
@@ -577,7 +515,6 @@ func createTransformHook(additionalTransformers ...Transformer) mapstructure.Dec
|
|||||||
reflect.TypeOf(types.ExtendsConfig{}): transformExtendsConfig,
|
reflect.TypeOf(types.ExtendsConfig{}): transformExtendsConfig,
|
||||||
reflect.TypeOf(types.DeviceRequest{}): transformServiceDeviceRequest,
|
reflect.TypeOf(types.DeviceRequest{}): transformServiceDeviceRequest,
|
||||||
reflect.TypeOf(types.SSHConfig{}): transformSSHConfig,
|
reflect.TypeOf(types.SSHConfig{}): transformSSHConfig,
|
||||||
reflect.TypeOf(types.IncludeConfig{}): transformIncludeConfig,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, transformer := range additionalTransformers {
|
for _, transformer := range additionalTransformers {
|
||||||
@@ -668,7 +605,6 @@ func LoadServices(filename string, servicesDict map[string]interface{}, workingD
|
|||||||
for k, v := range x.(map[string]interface{}) {
|
for k, v := range x.(map[string]interface{}) {
|
||||||
servicesDict[k] = v
|
servicesDict[k] = v
|
||||||
}
|
}
|
||||||
delete(servicesDict, extensions)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for name := range servicesDict {
|
for name := range servicesDict {
|
||||||
@@ -697,7 +633,7 @@ func loadServiceWithExtends(filename, name string, servicesDict map[string]inter
|
|||||||
target = map[string]interface{}{}
|
target = map[string]interface{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceConfig, err := LoadService(name, target.(map[string]interface{}))
|
serviceConfig, err := LoadService(name, target.(map[string]interface{}), workingDir, lookupEnv, opts.ResolvePaths, opts.ConvertWindowsPaths)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -735,9 +671,21 @@ func loadServiceWithExtends(filename, name string, servicesDict map[string]inter
|
|||||||
// make the paths relative to `file` rather than `baseFilePath` so
|
// make the paths relative to `file` rather than `baseFilePath` so
|
||||||
// that the resulting paths won't be absolute if `file` isn't an
|
// that the resulting paths won't be absolute if `file` isn't an
|
||||||
// absolute path.
|
// absolute path.
|
||||||
|
|
||||||
baseFileParent := filepath.Dir(file)
|
baseFileParent := filepath.Dir(file)
|
||||||
ResolveServiceRelativePaths(baseFileParent, baseService)
|
if baseService.Build != nil {
|
||||||
|
baseService.Build.Context = resolveBuildContextPath(baseFileParent, baseService.Build.Context)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, vol := range baseService.Volumes {
|
||||||
|
if vol.Type != types.VolumeTypeBind {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
baseService.Volumes[i].Source = resolveMaybeUnixPath(vol.Source, baseFileParent, lookupEnv)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, envFile := range baseService.EnvFile {
|
||||||
|
baseService.EnvFile[i] = resolveMaybeUnixPath(envFile, baseFileParent, lookupEnv)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceConfig, err = _merge(baseService, serviceConfig)
|
serviceConfig, err = _merge(baseService, serviceConfig)
|
||||||
@@ -750,9 +698,22 @@ func loadServiceWithExtends(filename, name string, servicesDict map[string]inter
|
|||||||
return serviceConfig, nil
|
return serviceConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resolveBuildContextPath(baseFileParent string, context string) string {
|
||||||
|
// Checks if the context is an HTTP(S) URL or a remote git repository URL
|
||||||
|
for _, prefix := range []string{"https://", "http://", "git://", "github.com/", "git@"} {
|
||||||
|
if strings.HasPrefix(context, prefix) {
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that the Dockerfile is always defined relative to the
|
||||||
|
// build context, so there's no need to update the Dockerfile field.
|
||||||
|
return absPath(baseFileParent, context)
|
||||||
|
}
|
||||||
|
|
||||||
// LoadService produces a single ServiceConfig from a compose file Dict
|
// LoadService produces a single ServiceConfig from a compose file Dict
|
||||||
// the serviceDict is not validated if directly used. Use Load() to enable validation
|
// the serviceDict is not validated if directly used. Use Load() to enable validation
|
||||||
func LoadService(name string, serviceDict map[string]interface{}) (*types.ServiceConfig, error) {
|
func LoadService(name string, serviceDict map[string]interface{}, workingDir string, lookupEnv template.Mapping, resolvePaths bool, convertPaths bool) (*types.ServiceConfig, error) {
|
||||||
serviceConfig := &types.ServiceConfig{
|
serviceConfig := &types.ServiceConfig{
|
||||||
Scale: 1,
|
Scale: 1,
|
||||||
}
|
}
|
||||||
@@ -769,6 +730,13 @@ func LoadService(name string, serviceDict map[string]interface{}) (*types.Servic
|
|||||||
return nil, errors.New(`invalid mount config for type "bind": field Source must not be empty`)
|
return nil, errors.New(`invalid mount config for type "bind": field Source must not be empty`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if resolvePaths || convertPaths {
|
||||||
|
volume = resolveVolumePath(volume, workingDir, lookupEnv)
|
||||||
|
}
|
||||||
|
|
||||||
|
if convertPaths {
|
||||||
|
volume = convertVolumePath(volume)
|
||||||
|
}
|
||||||
serviceConfig.Volumes[i] = volume
|
serviceConfig.Volumes[i] = volume
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -790,8 +758,8 @@ func convertVolumePath(volume types.ServiceVolumeConfig) types.ServiceVolumeConf
|
|||||||
return volume
|
return volume
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveMaybeUnixPath(workingDir string, path string) string {
|
func resolveMaybeUnixPath(path string, workingDir string, lookupEnv template.Mapping) string {
|
||||||
filePath := expandUser(path)
|
filePath := expandUser(path, lookupEnv)
|
||||||
// Check if source is an absolute path (either Unix or Windows), to
|
// Check if source is an absolute path (either Unix or Windows), to
|
||||||
// handle a Windows client with a Unix daemon or vice-versa.
|
// handle a Windows client with a Unix daemon or vice-versa.
|
||||||
//
|
//
|
||||||
@@ -804,8 +772,20 @@ func resolveMaybeUnixPath(workingDir string, path string) string {
|
|||||||
return filePath
|
return filePath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resolveVolumePath(volume types.ServiceVolumeConfig, workingDir string, lookupEnv template.Mapping) types.ServiceVolumeConfig {
|
||||||
|
volume.Source = resolveMaybeUnixPath(volume.Source, workingDir, lookupEnv)
|
||||||
|
return volume
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveSecretsPath(secret types.SecretConfig, workingDir string, lookupEnv template.Mapping) types.SecretConfig {
|
||||||
|
if !secret.External.External && secret.File != "" {
|
||||||
|
secret.File = resolveMaybeUnixPath(secret.File, workingDir, lookupEnv)
|
||||||
|
}
|
||||||
|
return secret
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: make this more robust
|
// TODO: make this more robust
|
||||||
func expandUser(path string) string {
|
func expandUser(path string, lookupEnv template.Mapping) string {
|
||||||
if strings.HasPrefix(path, "~") {
|
if strings.HasPrefix(path, "~") {
|
||||||
home, err := os.UserHomeDir()
|
home, err := os.UserHomeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -905,39 +885,44 @@ func LoadVolumes(source map[string]interface{}) (map[string]types.VolumeConfig,
|
|||||||
|
|
||||||
// LoadSecrets produces a SecretConfig map from a compose file Dict
|
// LoadSecrets produces a SecretConfig map from a compose file Dict
|
||||||
// the source Dict is not validated if directly used. Use Load() to enable validation
|
// the source Dict is not validated if directly used. Use Load() to enable validation
|
||||||
func LoadSecrets(source map[string]interface{}) (map[string]types.SecretConfig, error) {
|
func LoadSecrets(source map[string]interface{}, details types.ConfigDetails, resolvePaths bool) (map[string]types.SecretConfig, error) {
|
||||||
secrets := make(map[string]types.SecretConfig)
|
secrets := make(map[string]types.SecretConfig)
|
||||||
if err := Transform(source, &secrets); err != nil {
|
if err := Transform(source, &secrets); err != nil {
|
||||||
return secrets, err
|
return secrets, err
|
||||||
}
|
}
|
||||||
for name, secret := range secrets {
|
for name, secret := range secrets {
|
||||||
obj, err := loadFileObjectConfig(name, "secret", types.FileObjectConfig(secret))
|
obj, err := loadFileObjectConfig(name, "secret", types.FileObjectConfig(secret), details, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
secrets[name] = types.SecretConfig(obj)
|
secretConfig := types.SecretConfig(obj)
|
||||||
|
if resolvePaths {
|
||||||
|
secretConfig = resolveSecretsPath(secretConfig, details.WorkingDir, details.LookupEnv)
|
||||||
|
}
|
||||||
|
secrets[name] = secretConfig
|
||||||
}
|
}
|
||||||
return secrets, nil
|
return secrets, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadConfigObjs produces a ConfigObjConfig map from a compose file Dict
|
// LoadConfigObjs produces a ConfigObjConfig map from a compose file Dict
|
||||||
// the source Dict is not validated if directly used. Use Load() to enable validation
|
// the source Dict is not validated if directly used. Use Load() to enable validation
|
||||||
func LoadConfigObjs(source map[string]interface{}) (map[string]types.ConfigObjConfig, error) {
|
func LoadConfigObjs(source map[string]interface{}, details types.ConfigDetails, resolvePaths bool) (map[string]types.ConfigObjConfig, error) {
|
||||||
configs := make(map[string]types.ConfigObjConfig)
|
configs := make(map[string]types.ConfigObjConfig)
|
||||||
if err := Transform(source, &configs); err != nil {
|
if err := Transform(source, &configs); err != nil {
|
||||||
return configs, err
|
return configs, err
|
||||||
}
|
}
|
||||||
for name, config := range configs {
|
for name, config := range configs {
|
||||||
obj, err := loadFileObjectConfig(name, "config", types.FileObjectConfig(config))
|
obj, err := loadFileObjectConfig(name, "config", types.FileObjectConfig(config), details, resolvePaths)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
configs[name] = types.ConfigObjConfig(obj)
|
configConfig := types.ConfigObjConfig(obj)
|
||||||
|
configs[name] = configConfig
|
||||||
}
|
}
|
||||||
return configs, nil
|
return configs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadFileObjectConfig(name string, objType string, obj types.FileObjectConfig) (types.FileObjectConfig, error) {
|
func loadFileObjectConfig(name string, objType string, obj types.FileObjectConfig, details types.ConfigDetails, resolvePaths bool) (types.FileObjectConfig, error) {
|
||||||
// if "external: true"
|
// if "external: true"
|
||||||
switch {
|
switch {
|
||||||
case obj.External.External:
|
case obj.External.External:
|
||||||
@@ -957,11 +942,26 @@ func loadFileObjectConfig(name string, objType string, obj types.FileObjectConfi
|
|||||||
if obj.File != "" {
|
if obj.File != "" {
|
||||||
return obj, errors.Errorf("%[1]s %[2]s: %[1]s.driver and %[1]s.file conflict; only use %[1]s.driver", objType, name)
|
return obj, errors.Errorf("%[1]s %[2]s: %[1]s.driver and %[1]s.file conflict; only use %[1]s.driver", objType, name)
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
if obj.File != "" && resolvePaths {
|
||||||
|
obj.File = absPath(details.WorkingDir, obj.File)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func absPath(workingDir string, filePath string) string {
|
||||||
|
if strings.HasPrefix(filePath, "~") {
|
||||||
|
home, _ := os.UserHomeDir()
|
||||||
|
return filepath.Join(home, filePath[1:])
|
||||||
|
}
|
||||||
|
if filepath.IsAbs(filePath) {
|
||||||
|
return filePath
|
||||||
|
}
|
||||||
|
return filepath.Join(workingDir, filePath)
|
||||||
|
}
|
||||||
|
|
||||||
var transformMapStringString TransformerFunc = func(data interface{}) (interface{}, error) {
|
var transformMapStringString TransformerFunc = func(data interface{}) (interface{}, error) {
|
||||||
switch value := data.(type) {
|
switch value := data.(type) {
|
||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
@@ -1088,24 +1088,13 @@ var transformDependsOnConfig TransformerFunc = func(data interface{}) (interface
|
|||||||
for _, serviceIntf := range value {
|
for _, serviceIntf := range value {
|
||||||
service, ok := serviceIntf.(string)
|
service, ok := serviceIntf.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return data, errors.Errorf("invalid type %T for service depends_on element, expected string", value)
|
return data, errors.Errorf("invalid type %T for service depends_on elementn, expected string", value)
|
||||||
}
|
}
|
||||||
transformed[service] = map[string]interface{}{"condition": types.ServiceConditionStarted, "required": true}
|
transformed[service] = map[string]interface{}{"condition": types.ServiceConditionStarted}
|
||||||
}
|
}
|
||||||
return transformed, nil
|
return transformed, nil
|
||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
transformed := map[string]interface{}{}
|
return groupXFieldsIntoExtensions(data.(map[string]interface{})), nil
|
||||||
for service, val := range value {
|
|
||||||
dependsConfigIntf, ok := val.(map[string]interface{})
|
|
||||||
if !ok {
|
|
||||||
return data, errors.Errorf("invalid type %T for service depends_on element", value)
|
|
||||||
}
|
|
||||||
if _, ok := dependsConfigIntf["required"]; !ok {
|
|
||||||
dependsConfigIntf["required"] = true
|
|
||||||
}
|
|
||||||
transformed[service] = dependsConfigIntf
|
|
||||||
}
|
|
||||||
return groupXFieldsIntoExtensions(transformed), nil
|
|
||||||
default:
|
default:
|
||||||
return data, errors.Errorf("invalid type %T for service depends_on", value)
|
return data, errors.Errorf("invalid type %T for service depends_on", value)
|
||||||
}
|
}
|
||||||
|
|||||||
11
vendor/github.com/compose-spec/compose-go/loader/merge.go
generated
vendored
11
vendor/github.com/compose-spec/compose-go/loader/merge.go
generated
vendored
@@ -150,12 +150,13 @@ func unique(slice []string) []string {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
uniqMap := make(map[string]struct{})
|
uniqMap := make(map[string]struct{})
|
||||||
var uniqSlice []string
|
|
||||||
for _, v := range slice {
|
for _, v := range slice {
|
||||||
if _, ok := uniqMap[v]; !ok {
|
uniqMap[v] = struct{}{}
|
||||||
uniqSlice = append(uniqSlice, v)
|
}
|
||||||
uniqMap[v] = struct{}{}
|
|
||||||
}
|
uniqSlice := make([]string, 0, len(uniqMap))
|
||||||
|
for v := range uniqMap {
|
||||||
|
uniqSlice = append(uniqSlice, v)
|
||||||
}
|
}
|
||||||
return uniqSlice
|
return uniqSlice
|
||||||
}
|
}
|
||||||
|
|||||||
71
vendor/github.com/compose-spec/compose-go/loader/normalize.go
generated
vendored
71
vendor/github.com/compose-spec/compose-go/loader/normalize.go
generated
vendored
@@ -18,6 +18,8 @@ package loader
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/errdefs"
|
"github.com/compose-spec/compose-go/errdefs"
|
||||||
@@ -27,7 +29,19 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Normalize compose project by moving deprecated attributes to their canonical position and injecting implicit defaults
|
// Normalize compose project by moving deprecated attributes to their canonical position and injecting implicit defaults
|
||||||
func Normalize(project *types.Project) error {
|
func Normalize(project *types.Project, resolvePaths bool) error {
|
||||||
|
absWorkingDir, err := filepath.Abs(project.WorkingDir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
project.WorkingDir = absWorkingDir
|
||||||
|
|
||||||
|
absComposeFiles, err := absComposeFiles(project.ComposeFiles)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
project.ComposeFiles = absComposeFiles
|
||||||
|
|
||||||
if project.Networks == nil {
|
if project.Networks == nil {
|
||||||
project.Networks = make(map[string]types.NetworkConfig)
|
project.Networks = make(map[string]types.NetworkConfig)
|
||||||
}
|
}
|
||||||
@@ -37,7 +51,8 @@ func Normalize(project *types.Project) error {
|
|||||||
project.Networks["default"] = types.NetworkConfig{}
|
project.Networks["default"] = types.NetworkConfig{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := relocateExternalName(project); err != nil {
|
err = relocateExternalName(project)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,16 +72,38 @@ func Normalize(project *types.Project) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if s.Build != nil {
|
if s.Build != nil {
|
||||||
if s.Build.Context == "" {
|
|
||||||
s.Build.Context = "."
|
|
||||||
}
|
|
||||||
if s.Build.Dockerfile == "" && s.Build.DockerfileInline == "" {
|
if s.Build.Dockerfile == "" && s.Build.DockerfileInline == "" {
|
||||||
s.Build.Dockerfile = "Dockerfile"
|
s.Build.Dockerfile = "Dockerfile"
|
||||||
}
|
}
|
||||||
|
if resolvePaths {
|
||||||
|
// Build context might be a remote http/git context. Unfortunately supported "remote"
|
||||||
|
// syntax is highly ambiguous in moby/moby and not defined by compose-spec,
|
||||||
|
// so let's assume runtime will check
|
||||||
|
localContext := absPath(project.WorkingDir, s.Build.Context)
|
||||||
|
if _, err := os.Stat(localContext); err == nil {
|
||||||
|
s.Build.Context = localContext
|
||||||
|
}
|
||||||
|
for name, path := range s.Build.AdditionalContexts {
|
||||||
|
if strings.Contains(path, "://") { // `docker-image://` or any builder specific context type
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
path = absPath(project.WorkingDir, path)
|
||||||
|
if _, err := os.Stat(path); err == nil {
|
||||||
|
s.Build.AdditionalContexts[name] = path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
s.Build.Args = s.Build.Args.Resolve(fn)
|
s.Build.Args = s.Build.Args.Resolve(fn)
|
||||||
}
|
}
|
||||||
|
for j, f := range s.EnvFile {
|
||||||
|
s.EnvFile[j] = absPath(project.WorkingDir, f)
|
||||||
|
}
|
||||||
s.Environment = s.Environment.Resolve(fn)
|
s.Environment = s.Environment.Resolve(fn)
|
||||||
|
|
||||||
|
if s.Extends != nil && s.Extends.File != "" {
|
||||||
|
s.Extends.File = absPath(project.WorkingDir, s.Extends.File)
|
||||||
|
}
|
||||||
|
|
||||||
for _, link := range s.Links {
|
for _, link := range s.Links {
|
||||||
parts := strings.Split(link, ":")
|
parts := strings.Split(link, ":")
|
||||||
if len(parts) == 2 {
|
if len(parts) == 2 {
|
||||||
@@ -75,7 +112,6 @@ func Normalize(project *types.Project) error {
|
|||||||
s.DependsOn = setIfMissing(s.DependsOn, link, types.ServiceDependency{
|
s.DependsOn = setIfMissing(s.DependsOn, link, types.ServiceDependency{
|
||||||
Condition: types.ServiceConditionStarted,
|
Condition: types.ServiceConditionStarted,
|
||||||
Restart: true,
|
Restart: true,
|
||||||
Required: true,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +121,6 @@ func Normalize(project *types.Project) error {
|
|||||||
s.DependsOn = setIfMissing(s.DependsOn, name, types.ServiceDependency{
|
s.DependsOn = setIfMissing(s.DependsOn, name, types.ServiceDependency{
|
||||||
Condition: types.ServiceConditionStarted,
|
Condition: types.ServiceConditionStarted,
|
||||||
Restart: true,
|
Restart: true,
|
||||||
Required: true,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,7 +131,6 @@ func Normalize(project *types.Project) error {
|
|||||||
s.DependsOn = setIfMissing(s.DependsOn, spec[0], types.ServiceDependency{
|
s.DependsOn = setIfMissing(s.DependsOn, spec[0], types.ServiceDependency{
|
||||||
Condition: types.ServiceConditionStarted,
|
Condition: types.ServiceConditionStarted,
|
||||||
Restart: false,
|
Restart: false,
|
||||||
Required: true,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,6 +160,14 @@ func Normalize(project *types.Project) error {
|
|||||||
project.Services[i] = s
|
project.Services[i] = s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for name, config := range project.Volumes {
|
||||||
|
if config.Driver == "local" && config.DriverOpts["o"] == "bind" {
|
||||||
|
// This is actually a bind mount
|
||||||
|
config.DriverOpts["device"] = absPath(project.WorkingDir, config.DriverOpts["device"])
|
||||||
|
project.Volumes[name] = config
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setNameFromKey(project)
|
setNameFromKey(project)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -181,7 +223,6 @@ func inferImplicitDependencies(service *types.ServiceConfig) {
|
|||||||
if _, ok := service.DependsOn[d]; !ok {
|
if _, ok := service.DependsOn[d]; !ok {
|
||||||
service.DependsOn[d] = types.ServiceDependency{
|
service.DependsOn[d] = types.ServiceDependency{
|
||||||
Condition: types.ServiceConditionStarted,
|
Condition: types.ServiceConditionStarted,
|
||||||
Required: true,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -213,6 +254,18 @@ func relocateScale(s *types.ServiceConfig) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func absComposeFiles(composeFiles []string) ([]string, error) {
|
||||||
|
absComposeFiles := make([]string, len(composeFiles))
|
||||||
|
for i, composeFile := range composeFiles {
|
||||||
|
absComposefile, err := filepath.Abs(composeFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
absComposeFiles[i] = absComposefile
|
||||||
|
}
|
||||||
|
return absComposeFiles, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Resources with no explicit name are actually named by their key in map
|
// Resources with no explicit name are actually named by their key in map
|
||||||
func setNameFromKey(project *types.Project) {
|
func setNameFromKey(project *types.Project) {
|
||||||
for i, n := range project.Networks {
|
for i, n := range project.Networks {
|
||||||
|
|||||||
135
vendor/github.com/compose-spec/compose-go/loader/paths.go
generated
vendored
135
vendor/github.com/compose-spec/compose-go/loader/paths.go
generated
vendored
@@ -1,135 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2020 The Compose Specification Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package loader
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ResolveRelativePaths resolves relative paths based on project WorkingDirectory
|
|
||||||
func ResolveRelativePaths(project *types.Project) error {
|
|
||||||
absWorkingDir, err := filepath.Abs(project.WorkingDir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
project.WorkingDir = absWorkingDir
|
|
||||||
|
|
||||||
absComposeFiles, err := absComposeFiles(project.ComposeFiles)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
project.ComposeFiles = absComposeFiles
|
|
||||||
|
|
||||||
for i, s := range project.Services {
|
|
||||||
ResolveServiceRelativePaths(project.WorkingDir, &s)
|
|
||||||
project.Services[i] = s
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, obj := range project.Configs {
|
|
||||||
if obj.File != "" {
|
|
||||||
obj.File = absPath(project.WorkingDir, obj.File)
|
|
||||||
project.Configs[i] = obj
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, obj := range project.Secrets {
|
|
||||||
if obj.File != "" {
|
|
||||||
obj.File = resolveMaybeUnixPath(project.WorkingDir, obj.File)
|
|
||||||
project.Secrets[i] = obj
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for name, config := range project.Volumes {
|
|
||||||
if config.Driver == "local" && config.DriverOpts["o"] == "bind" {
|
|
||||||
// This is actually a bind mount
|
|
||||||
config.DriverOpts["device"] = resolveMaybeUnixPath(project.WorkingDir, config.DriverOpts["device"])
|
|
||||||
project.Volumes[name] = config
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ResolveServiceRelativePaths(workingDir string, s *types.ServiceConfig) {
|
|
||||||
if s.Build != nil {
|
|
||||||
if !isRemoteContext(s.Build.Context) {
|
|
||||||
s.Build.Context = absPath(workingDir, s.Build.Context)
|
|
||||||
}
|
|
||||||
for name, path := range s.Build.AdditionalContexts {
|
|
||||||
if strings.Contains(path, "://") { // `docker-image://` or any builder specific context type
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if isRemoteContext(path) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
s.Build.AdditionalContexts[name] = absPath(workingDir, path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for j, f := range s.EnvFile {
|
|
||||||
s.EnvFile[j] = absPath(workingDir, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
if s.Extends != nil && s.Extends.File != "" {
|
|
||||||
s.Extends.File = absPath(workingDir, s.Extends.File)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, vol := range s.Volumes {
|
|
||||||
if vol.Type != types.VolumeTypeBind {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
s.Volumes[i].Source = resolveMaybeUnixPath(workingDir, vol.Source)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func absPath(workingDir string, filePath string) string {
|
|
||||||
if strings.HasPrefix(filePath, "~") {
|
|
||||||
home, _ := os.UserHomeDir()
|
|
||||||
return filepath.Join(home, filePath[1:])
|
|
||||||
}
|
|
||||||
if filepath.IsAbs(filePath) {
|
|
||||||
return filePath
|
|
||||||
}
|
|
||||||
return filepath.Join(workingDir, filePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
func absComposeFiles(composeFiles []string) ([]string, error) {
|
|
||||||
for i, composeFile := range composeFiles {
|
|
||||||
absComposefile, err := filepath.Abs(composeFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
composeFiles[i] = absComposefile
|
|
||||||
}
|
|
||||||
return composeFiles, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// isRemoteContext returns true if the value is a Git reference or HTTP(S) URL.
|
|
||||||
//
|
|
||||||
// Any other value is assumed to be a local filesystem path and returns false.
|
|
||||||
//
|
|
||||||
// See: https://github.com/moby/buildkit/blob/18fc875d9bfd6e065cd8211abc639434ba65aa56/frontend/dockerui/context.go#L76-L79
|
|
||||||
func isRemoteContext(maybeURL string) bool {
|
|
||||||
for _, prefix := range []string{"https://", "http://", "git://", "ssh://", "github.com/", "git@"} {
|
|
||||||
if strings.HasPrefix(maybeURL, prefix) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
35
vendor/github.com/compose-spec/compose-go/schema/compose-spec.json
generated
vendored
35
vendor/github.com/compose-spec/compose-go/schema/compose-spec.json
generated
vendored
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json-schema.org/draft/2019-09/schema#",
|
"$schema": "http://json-schema.org/draft/2019-09/schema#",
|
||||||
"id": "compose_spec.json",
|
"id": "compose_spec.json",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"title": "Compose Specification",
|
"title": "Compose Specification",
|
||||||
@@ -17,15 +17,6 @@
|
|||||||
"description": "define the Compose project name, until user defines one explicitly."
|
"description": "define the Compose project name, until user defines one explicitly."
|
||||||
},
|
},
|
||||||
|
|
||||||
"include": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"$ref": "#/definitions/include"
|
|
||||||
},
|
|
||||||
"description": "compose sub-projects to be included."
|
|
||||||
},
|
|
||||||
|
|
||||||
"services": {
|
"services": {
|
||||||
"id": "#/properties/services",
|
"id": "#/properties/services",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@@ -93,7 +84,6 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"deploy": {"$ref": "#/definitions/deployment"},
|
"deploy": {"$ref": "#/definitions/deployment"},
|
||||||
"annotations": {"$ref": "#/definitions/list_or_dict"},
|
"annotations": {"$ref": "#/definitions/list_or_dict"},
|
||||||
"attach": {"type": "boolean"},
|
|
||||||
"build": {
|
"build": {
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{"type": "string"},
|
{"type": "string"},
|
||||||
@@ -191,10 +181,6 @@
|
|||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"properties": {
|
"properties": {
|
||||||
"restart": {"type": "boolean"},
|
"restart": {"type": "boolean"},
|
||||||
"required": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
"condition": {
|
"condition": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["service_started", "service_healthy", "service_completed_successfully"]
|
"enum": ["service_started", "service_healthy", "service_completed_successfully"]
|
||||||
@@ -457,8 +443,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"timeout": {"type": "string", "format": "duration"},
|
"timeout": {"type": "string", "format": "duration"},
|
||||||
"start_period": {"type": "string", "format": "duration"},
|
"start_period": {"type": "string", "format": "duration"}
|
||||||
"start_interval": {"type": "string", "format": "duration"}
|
|
||||||
},
|
},
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"patternProperties": {"^x-": {}}
|
"patternProperties": {"^x-": {}}
|
||||||
@@ -603,22 +588,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"include": {
|
|
||||||
"id": "#/definitions/include",
|
|
||||||
"oneOf": [
|
|
||||||
{"type": "string"},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"path": {"$ref": "#/definitions/string_or_list"},
|
|
||||||
"env_file": {"$ref": "#/definitions/string_or_list"},
|
|
||||||
"project_directory": {"type": "string"}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
"network": {
|
"network": {
|
||||||
"id": "#/definitions/network",
|
"id": "#/definitions/network",
|
||||||
"type": ["object", "null"],
|
"type": ["object", "null"],
|
||||||
|
|||||||
7
vendor/github.com/compose-spec/compose-go/schema/schema.go
generated
vendored
7
vendor/github.com/compose-spec/compose-go/schema/schema.go
generated
vendored
@@ -17,18 +17,19 @@
|
|||||||
package schema
|
package schema
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// Enable support for embedded static resources
|
|
||||||
_ "embed"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/xeipuuv/gojsonschema"
|
"github.com/xeipuuv/gojsonschema"
|
||||||
|
|
||||||
|
// Enable support for embedded static resources
|
||||||
|
_ "embed"
|
||||||
)
|
)
|
||||||
|
|
||||||
type portsFormatChecker struct{}
|
type portsFormatChecker struct{}
|
||||||
|
|
||||||
func (checker portsFormatChecker) IsFormat(_ interface{}) bool {
|
func (checker portsFormatChecker) IsFormat(input interface{}) bool {
|
||||||
// TODO: implement this
|
// TODO: implement this
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
202
vendor/github.com/compose-spec/compose-go/template/template.go
generated
vendored
202
vendor/github.com/compose-spec/compose-go/template/template.go
generated
vendored
@@ -17,7 +17,6 @@
|
|||||||
package template
|
package template
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
@@ -72,146 +71,75 @@ type Mapping func(string) (string, bool)
|
|||||||
// the substitution and an error.
|
// the substitution and an error.
|
||||||
type SubstituteFunc func(string, Mapping) (string, bool, error)
|
type SubstituteFunc func(string, Mapping) (string, bool, error)
|
||||||
|
|
||||||
// ReplacementFunc is a user-supplied function that is apply to the matching
|
|
||||||
// substring. Returns the value as a string and an error.
|
|
||||||
type ReplacementFunc func(string, Mapping, *Config) (string, error)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
pattern *regexp.Regexp
|
|
||||||
substituteFunc SubstituteFunc
|
|
||||||
replacementFunc ReplacementFunc
|
|
||||||
logging bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type Option func(*Config)
|
|
||||||
|
|
||||||
func WithPattern(pattern *regexp.Regexp) Option {
|
|
||||||
return func(cfg *Config) {
|
|
||||||
cfg.pattern = pattern
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WithSubstitutionFunction(subsFunc SubstituteFunc) Option {
|
|
||||||
return func(cfg *Config) {
|
|
||||||
cfg.substituteFunc = subsFunc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WithReplacementFunction(replacementFunc ReplacementFunc) Option {
|
|
||||||
return func(cfg *Config) {
|
|
||||||
cfg.replacementFunc = replacementFunc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WithoutLogging(cfg *Config) {
|
|
||||||
cfg.logging = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// SubstituteWithOptions substitute variables in the string with their values.
|
|
||||||
// It accepts additional options such as a custom function or pattern.
|
|
||||||
func SubstituteWithOptions(template string, mapping Mapping, options ...Option) (string, error) {
|
|
||||||
var returnErr error
|
|
||||||
|
|
||||||
cfg := &Config{
|
|
||||||
pattern: defaultPattern,
|
|
||||||
replacementFunc: DefaultReplacementFunc,
|
|
||||||
logging: true,
|
|
||||||
}
|
|
||||||
for _, o := range options {
|
|
||||||
o(cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
result := cfg.pattern.ReplaceAllStringFunc(template, func(substring string) string {
|
|
||||||
replacement, err := cfg.replacementFunc(substring, mapping, cfg)
|
|
||||||
if err != nil {
|
|
||||||
// Add the template for template errors
|
|
||||||
var tmplErr *InvalidTemplateError
|
|
||||||
if errors.As(err, &tmplErr) {
|
|
||||||
if tmplErr.Template == "" {
|
|
||||||
tmplErr.Template = template
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Save the first error to be returned
|
|
||||||
if returnErr == nil {
|
|
||||||
returnErr = err
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return replacement
|
|
||||||
})
|
|
||||||
|
|
||||||
return result, returnErr
|
|
||||||
}
|
|
||||||
|
|
||||||
func DefaultReplacementFunc(substring string, mapping Mapping, cfg *Config) (string, error) {
|
|
||||||
value, _, err := DefaultReplacementAppliedFunc(substring, mapping, cfg)
|
|
||||||
return value, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func DefaultReplacementAppliedFunc(substring string, mapping Mapping, cfg *Config) (string, bool, error) {
|
|
||||||
pattern := cfg.pattern
|
|
||||||
subsFunc := cfg.substituteFunc
|
|
||||||
if subsFunc == nil {
|
|
||||||
_, subsFunc = getSubstitutionFunctionForTemplate(substring)
|
|
||||||
}
|
|
||||||
|
|
||||||
closingBraceIndex := getFirstBraceClosingIndex(substring)
|
|
||||||
rest := ""
|
|
||||||
if closingBraceIndex > -1 {
|
|
||||||
rest = substring[closingBraceIndex+1:]
|
|
||||||
substring = substring[0 : closingBraceIndex+1]
|
|
||||||
}
|
|
||||||
|
|
||||||
matches := pattern.FindStringSubmatch(substring)
|
|
||||||
groups := matchGroups(matches, pattern)
|
|
||||||
if escaped := groups["escaped"]; escaped != "" {
|
|
||||||
return escaped, true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
braced := false
|
|
||||||
substitution := groups["named"]
|
|
||||||
if substitution == "" {
|
|
||||||
substitution = groups["braced"]
|
|
||||||
braced = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if substitution == "" {
|
|
||||||
return "", false, &InvalidTemplateError{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if braced {
|
|
||||||
value, applied, err := subsFunc(substitution, mapping)
|
|
||||||
if err != nil {
|
|
||||||
return "", false, err
|
|
||||||
}
|
|
||||||
if applied {
|
|
||||||
interpolatedNested, err := SubstituteWith(rest, mapping, pattern)
|
|
||||||
if err != nil {
|
|
||||||
return "", false, err
|
|
||||||
}
|
|
||||||
return value + interpolatedNested, true, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
value, ok := mapping(substitution)
|
|
||||||
if !ok && cfg.logging {
|
|
||||||
logrus.Warnf("The %q variable is not set. Defaulting to a blank string.", substitution)
|
|
||||||
}
|
|
||||||
|
|
||||||
return value, ok, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SubstituteWith substitute variables in the string with their values.
|
// SubstituteWith substitute variables in the string with their values.
|
||||||
// It accepts additional substitute function.
|
// It accepts additional substitute function.
|
||||||
func SubstituteWith(template string, mapping Mapping, pattern *regexp.Regexp, subsFuncs ...SubstituteFunc) (string, error) {
|
func SubstituteWith(template string, mapping Mapping, pattern *regexp.Regexp, subsFuncs ...SubstituteFunc) (string, error) {
|
||||||
options := []Option{
|
var outerErr error
|
||||||
WithPattern(pattern),
|
var returnErr error
|
||||||
}
|
|
||||||
if len(subsFuncs) > 0 {
|
|
||||||
options = append(options, WithSubstitutionFunction(subsFuncs[0]))
|
|
||||||
}
|
|
||||||
|
|
||||||
return SubstituteWithOptions(template, mapping, options...)
|
result := pattern.ReplaceAllStringFunc(template, func(substring string) string {
|
||||||
|
_, subsFunc := getSubstitutionFunctionForTemplate(substring)
|
||||||
|
if len(subsFuncs) > 0 {
|
||||||
|
subsFunc = subsFuncs[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
closingBraceIndex := getFirstBraceClosingIndex(substring)
|
||||||
|
rest := ""
|
||||||
|
if closingBraceIndex > -1 {
|
||||||
|
rest = substring[closingBraceIndex+1:]
|
||||||
|
substring = substring[0 : closingBraceIndex+1]
|
||||||
|
}
|
||||||
|
|
||||||
|
matches := pattern.FindStringSubmatch(substring)
|
||||||
|
groups := matchGroups(matches, pattern)
|
||||||
|
if escaped := groups["escaped"]; escaped != "" {
|
||||||
|
return escaped
|
||||||
|
}
|
||||||
|
|
||||||
|
braced := false
|
||||||
|
substitution := groups["named"]
|
||||||
|
if substitution == "" {
|
||||||
|
substitution = groups["braced"]
|
||||||
|
braced = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if substitution == "" {
|
||||||
|
outerErr = &InvalidTemplateError{Template: template}
|
||||||
|
if returnErr == nil {
|
||||||
|
returnErr = outerErr
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if braced {
|
||||||
|
var (
|
||||||
|
value string
|
||||||
|
applied bool
|
||||||
|
)
|
||||||
|
value, applied, outerErr = subsFunc(substitution, mapping)
|
||||||
|
if outerErr != nil {
|
||||||
|
if returnErr == nil {
|
||||||
|
returnErr = outerErr
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if applied {
|
||||||
|
interpolatedNested, err := SubstituteWith(rest, mapping, pattern)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return value + interpolatedNested
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
value, ok := mapping(substitution)
|
||||||
|
if !ok {
|
||||||
|
logrus.Warnf("The %q variable is not set. Defaulting to a blank string.", substitution)
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
})
|
||||||
|
|
||||||
|
return result, returnErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSubstitutionFunctionForTemplate(template string) (string, SubstituteFunc) {
|
func getSubstitutionFunctionForTemplate(template string) (string, SubstituteFunc) {
|
||||||
|
|||||||
24
vendor/github.com/compose-spec/compose-go/types/config.go
generated
vendored
24
vendor/github.com/compose-spec/compose-go/types/config.go
generated
vendored
@@ -67,24 +67,16 @@ type ConfigFile struct {
|
|||||||
Config map[string]interface{}
|
Config map[string]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ToConfigFiles(path []string) (f []ConfigFile) {
|
|
||||||
for _, p := range path {
|
|
||||||
f = append(f, ConfigFile{Filename: p})
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Config is a full compose file configuration and model
|
// Config is a full compose file configuration and model
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Filename string `yaml:"-" json:"-"`
|
Filename string `yaml:"-" json:"-"`
|
||||||
Name string `yaml:"name,omitempty" json:"name,omitempty"`
|
Name string `yaml:",omitempty" json:"name,omitempty"`
|
||||||
Services Services `yaml:"services" json:"services"`
|
Services Services `json:"services"`
|
||||||
Networks Networks `yaml:"networks,omitempty" json:"networks,omitempty"`
|
Networks Networks `yaml:",omitempty" json:"networks,omitempty"`
|
||||||
Volumes Volumes `yaml:"volumes,omitempty" json:"volumes,omitempty"`
|
Volumes Volumes `yaml:",omitempty" json:"volumes,omitempty"`
|
||||||
Secrets Secrets `yaml:"secrets,omitempty" json:"secrets,omitempty"`
|
Secrets Secrets `yaml:",omitempty" json:"secrets,omitempty"`
|
||||||
Configs Configs `yaml:"configs,omitempty" json:"configs,omitempty"`
|
Configs Configs `yaml:",omitempty" json:"configs,omitempty"`
|
||||||
Extensions Extensions `yaml:",inline" json:"-"`
|
Extensions Extensions `yaml:",inline" json:"-"`
|
||||||
Include []IncludeConfig `yaml:"include,omitempty" json:"include,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Volumes is a map of VolumeConfig
|
// Volumes is a map of VolumeConfig
|
||||||
|
|||||||
50
vendor/github.com/compose-spec/compose-go/types/project.go
generated
vendored
50
vendor/github.com/compose-spec/compose-go/types/project.go
generated
vendored
@@ -24,8 +24,6 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/utils"
|
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/dotenv"
|
"github.com/compose-spec/compose-go/dotenv"
|
||||||
"github.com/distribution/distribution/v3/reference"
|
"github.com/distribution/distribution/v3/reference"
|
||||||
godigest "github.com/opencontainers/go-digest"
|
godigest "github.com/opencontainers/go-digest"
|
||||||
@@ -104,19 +102,10 @@ func (p *Project) ConfigNames() []string {
|
|||||||
|
|
||||||
// GetServices retrieve services by names, or return all services if no name specified
|
// GetServices retrieve services by names, or return all services if no name specified
|
||||||
func (p *Project) GetServices(names ...string) (Services, error) {
|
func (p *Project) GetServices(names ...string) (Services, error) {
|
||||||
services, servicesNotFound := p.getServicesByNames(names...)
|
|
||||||
if len(servicesNotFound) > 0 {
|
|
||||||
return services, fmt.Errorf("no such service: %s", servicesNotFound[0])
|
|
||||||
}
|
|
||||||
return services, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Project) getServicesByNames(names ...string) (Services, []string) {
|
|
||||||
if len(names) == 0 {
|
if len(names) == 0 {
|
||||||
return p.Services, nil
|
return p.Services, nil
|
||||||
}
|
}
|
||||||
services := Services{}
|
services := Services{}
|
||||||
var servicesNotFound []string
|
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
var serviceConfig *ServiceConfig
|
var serviceConfig *ServiceConfig
|
||||||
for _, s := range p.Services {
|
for _, s := range p.Services {
|
||||||
@@ -126,12 +115,11 @@ func (p *Project) getServicesByNames(names ...string) (Services, []string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if serviceConfig == nil {
|
if serviceConfig == nil {
|
||||||
servicesNotFound = append(servicesNotFound, name)
|
return services, fmt.Errorf("no such service: %s", name)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
services = append(services, *serviceConfig)
|
services = append(services, *serviceConfig)
|
||||||
}
|
}
|
||||||
return services, servicesNotFound
|
return services, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDisabledService retrieve disabled service by name
|
// GetDisabledService retrieve disabled service by name
|
||||||
@@ -171,30 +159,26 @@ func (p *Project) WithServices(names []string, fn ServiceFunc, options ...Depend
|
|||||||
// backward compatibility
|
// backward compatibility
|
||||||
options = []DependencyOption{IncludeDependencies}
|
options = []DependencyOption{IncludeDependencies}
|
||||||
}
|
}
|
||||||
return p.withServices(names, fn, map[string]bool{}, options, map[string]ServiceDependency{})
|
return p.withServices(names, fn, map[string]bool{}, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Project) withServices(names []string, fn ServiceFunc, seen map[string]bool, options []DependencyOption, dependencies map[string]ServiceDependency) error {
|
func (p *Project) withServices(names []string, fn ServiceFunc, seen map[string]bool, options []DependencyOption) error {
|
||||||
services, servicesNotFound := p.getServicesByNames(names...)
|
services, err := p.GetServices(names...)
|
||||||
if len(servicesNotFound) > 0 {
|
if err != nil {
|
||||||
for _, serviceNotFound := range servicesNotFound {
|
return err
|
||||||
if dependency, ok := dependencies[serviceNotFound]; !ok || dependency.Required {
|
|
||||||
return fmt.Errorf("no such service: %s", serviceNotFound)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for _, service := range services {
|
for _, service := range services {
|
||||||
if seen[service.Name] {
|
if seen[service.Name] {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
seen[service.Name] = true
|
seen[service.Name] = true
|
||||||
var dependencies map[string]ServiceDependency
|
var dependencies []string
|
||||||
for _, policy := range options {
|
for _, policy := range options {
|
||||||
switch policy {
|
switch policy {
|
||||||
case IncludeDependents:
|
case IncludeDependents:
|
||||||
dependencies = utils.MapsAppend(dependencies, p.dependentsForService(service))
|
dependencies = append(dependencies, p.GetDependentsForService(service)...)
|
||||||
case IncludeDependencies:
|
case IncludeDependencies:
|
||||||
dependencies = utils.MapsAppend(dependencies, service.DependsOn)
|
dependencies = append(dependencies, service.GetDependencies()...)
|
||||||
case IgnoreDependencies:
|
case IgnoreDependencies:
|
||||||
// Noop
|
// Noop
|
||||||
default:
|
default:
|
||||||
@@ -202,7 +186,7 @@ func (p *Project) withServices(names []string, fn ServiceFunc, seen map[string]b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(dependencies) > 0 {
|
if len(dependencies) > 0 {
|
||||||
err := p.withServices(utils.MapKeys(dependencies), fn, seen, options, dependencies)
|
err := p.withServices(dependencies, fn, seen, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -215,15 +199,11 @@ func (p *Project) withServices(names []string, fn ServiceFunc, seen map[string]b
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Project) GetDependentsForService(s ServiceConfig) []string {
|
func (p *Project) GetDependentsForService(s ServiceConfig) []string {
|
||||||
return utils.MapKeys(p.dependentsForService(s))
|
var dependent []string
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Project) dependentsForService(s ServiceConfig) map[string]ServiceDependency {
|
|
||||||
dependent := make(map[string]ServiceDependency)
|
|
||||||
for _, service := range p.Services {
|
for _, service := range p.Services {
|
||||||
for name, dependency := range service.DependsOn {
|
for name := range service.DependsOn {
|
||||||
if name == s.Name {
|
if name == s.Name {
|
||||||
dependent[service.Name] = dependency
|
dependent = append(dependent, service.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -527,7 +507,7 @@ func (p Project) ResolveServicesEnvironment(discardEnvFiles bool) error {
|
|||||||
|
|
||||||
fileVars, err := dotenv.ParseWithLookup(bytes.NewBuffer(b), resolve)
|
fileVars, err := dotenv.ParseWithLookup(bytes.NewBuffer(b), resolve)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "failed to read %s", envFile)
|
return err
|
||||||
}
|
}
|
||||||
environment.OverrideBy(Mapping(fileVars).ToMappingWithEquals())
|
environment.OverrideBy(Mapping(fileVars).ToMappingWithEquals())
|
||||||
}
|
}
|
||||||
|
|||||||
23
vendor/github.com/compose-spec/compose-go/types/types.go
generated
vendored
23
vendor/github.com/compose-spec/compose-go/types/types.go
generated
vendored
@@ -89,7 +89,6 @@ type ServiceConfig struct {
|
|||||||
Profiles []string `yaml:"profiles,omitempty" json:"profiles,omitempty"`
|
Profiles []string `yaml:"profiles,omitempty" json:"profiles,omitempty"`
|
||||||
|
|
||||||
Annotations Mapping `yaml:"annotations,omitempty" json:"annotations,omitempty"`
|
Annotations Mapping `yaml:"annotations,omitempty" json:"annotations,omitempty"`
|
||||||
Attach *bool `yaml:"attach,omitempty" json:"attach,omitempty"`
|
|
||||||
Build *BuildConfig `yaml:"build,omitempty" json:"build,omitempty"`
|
Build *BuildConfig `yaml:"build,omitempty" json:"build,omitempty"`
|
||||||
BlkioConfig *BlkioConfig `yaml:"blkio_config,omitempty" json:"blkio_config,omitempty"`
|
BlkioConfig *BlkioConfig `yaml:"blkio_config,omitempty" json:"blkio_config,omitempty"`
|
||||||
CapAdd []string `yaml:"cap_add,omitempty" json:"cap_add,omitempty"`
|
CapAdd []string `yaml:"cap_add,omitempty" json:"cap_add,omitempty"`
|
||||||
@@ -603,13 +602,12 @@ type DeployConfig struct {
|
|||||||
|
|
||||||
// HealthCheckConfig the healthcheck configuration for a service
|
// HealthCheckConfig the healthcheck configuration for a service
|
||||||
type HealthCheckConfig struct {
|
type HealthCheckConfig struct {
|
||||||
Test HealthCheckTest `yaml:"test,omitempty" json:"test,omitempty"`
|
Test HealthCheckTest `yaml:"test,omitempty" json:"test,omitempty"`
|
||||||
Timeout *Duration `yaml:"timeout,omitempty" json:"timeout,omitempty"`
|
Timeout *Duration `yaml:"timeout,omitempty" json:"timeout,omitempty"`
|
||||||
Interval *Duration `yaml:"interval,omitempty" json:"interval,omitempty"`
|
Interval *Duration `yaml:"interval,omitempty" json:"interval,omitempty"`
|
||||||
Retries *uint64 `yaml:"retries,omitempty" json:"retries,omitempty"`
|
Retries *uint64 `yaml:"retries,omitempty" json:"retries,omitempty"`
|
||||||
StartPeriod *Duration `yaml:"start_period,omitempty" json:"start_period,omitempty"`
|
StartPeriod *Duration `yaml:"start_period,omitempty" json:"start_period,omitempty"`
|
||||||
StartInterval *Duration `yaml:"start_interval,omitempty" json:"start_interval,omitempty"`
|
Disable bool `yaml:"disable,omitempty" json:"disable,omitempty"`
|
||||||
Disable bool `yaml:"disable,omitempty" json:"disable,omitempty"`
|
|
||||||
|
|
||||||
Extensions Extensions `yaml:"#extensions,inline" json:"-"`
|
Extensions Extensions `yaml:"#extensions,inline" json:"-"`
|
||||||
}
|
}
|
||||||
@@ -817,8 +815,6 @@ const (
|
|||||||
VolumeTypeTmpfs = "tmpfs"
|
VolumeTypeTmpfs = "tmpfs"
|
||||||
// VolumeTypeNamedPipe is the type for mounting Windows named pipes
|
// VolumeTypeNamedPipe is the type for mounting Windows named pipes
|
||||||
VolumeTypeNamedPipe = "npipe"
|
VolumeTypeNamedPipe = "npipe"
|
||||||
// VolumeTypeCluster is the type for mounting container storage interface (CSI) volumes
|
|
||||||
VolumeTypeCluster = "cluster"
|
|
||||||
|
|
||||||
// SElinuxShared share the volume content
|
// SElinuxShared share the volume content
|
||||||
SElinuxShared = "z"
|
SElinuxShared = "z"
|
||||||
@@ -1027,7 +1023,6 @@ type ServiceDependency struct {
|
|||||||
Condition string `yaml:"condition,omitempty" json:"condition,omitempty"`
|
Condition string `yaml:"condition,omitempty" json:"condition,omitempty"`
|
||||||
Restart bool `yaml:"restart,omitempty" json:"restart,omitempty"`
|
Restart bool `yaml:"restart,omitempty" json:"restart,omitempty"`
|
||||||
Extensions Extensions `yaml:"#extensions,inline" json:"-"`
|
Extensions Extensions `yaml:"#extensions,inline" json:"-"`
|
||||||
Required bool `yaml:"required" json:"required"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExtendsConfig struct {
|
type ExtendsConfig struct {
|
||||||
@@ -1040,9 +1035,3 @@ type SecretConfig FileObjectConfig
|
|||||||
|
|
||||||
// ConfigObjConfig is the config for the swarm "Config" object
|
// ConfigObjConfig is the config for the swarm "Config" object
|
||||||
type ConfigObjConfig FileObjectConfig
|
type ConfigObjConfig FileObjectConfig
|
||||||
|
|
||||||
type IncludeConfig struct {
|
|
||||||
Path StringList `yaml:"path,omitempty" json:"path,omitempty"`
|
|
||||||
ProjectDirectory string `yaml:"project_directory,omitempty" json:"project_directory,omitempty"`
|
|
||||||
EnvFile StringList `yaml:"env_file,omitempty" json:"env_file,omitempty"`
|
|
||||||
}
|
|
||||||
|
|||||||
51
vendor/github.com/compose-spec/compose-go/utils/collectionutils.go
generated
vendored
51
vendor/github.com/compose-spec/compose-go/utils/collectionutils.go
generated
vendored
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2020 The Compose Specification Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package utils
|
|
||||||
|
|
||||||
import "golang.org/x/exp/slices"
|
|
||||||
|
|
||||||
func MapKeys[T comparable, U any](theMap map[T]U) []T {
|
|
||||||
var result []T
|
|
||||||
for key := range theMap {
|
|
||||||
result = append(result, key)
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func MapsAppend[T comparable, U any](target map[T]U, source map[T]U) map[T]U {
|
|
||||||
if target == nil {
|
|
||||||
return source
|
|
||||||
}
|
|
||||||
if source == nil {
|
|
||||||
return target
|
|
||||||
}
|
|
||||||
for key, value := range source {
|
|
||||||
if _, ok := target[key]; !ok {
|
|
||||||
target[key] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return target
|
|
||||||
}
|
|
||||||
|
|
||||||
func ArrayContains[T comparable](source []T, toCheck []T) bool {
|
|
||||||
for _, value := range toCheck {
|
|
||||||
if !slices.Contains(source, value) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
4
vendor/github.com/creack/pty/.gitignore
generated
vendored
4
vendor/github.com/creack/pty/.gitignore
generated
vendored
@@ -1,4 +0,0 @@
|
|||||||
[568].out
|
|
||||||
_go*
|
|
||||||
_test*
|
|
||||||
_obj
|
|
||||||
17
vendor/github.com/creack/pty/Dockerfile.golang
generated
vendored
17
vendor/github.com/creack/pty/Dockerfile.golang
generated
vendored
@@ -1,17 +0,0 @@
|
|||||||
ARG GOVERSION=1.14
|
|
||||||
FROM golang:${GOVERSION}
|
|
||||||
|
|
||||||
# Set base env.
|
|
||||||
ARG GOOS=linux
|
|
||||||
ARG GOARCH=amd64
|
|
||||||
ENV GOOS=${GOOS} GOARCH=${GOARCH} CGO_ENABLED=0 GOFLAGS='-v -ldflags=-s -ldflags=-w'
|
|
||||||
|
|
||||||
# Pre compile the stdlib for 386/arm (32bits).
|
|
||||||
RUN go build -a std
|
|
||||||
|
|
||||||
# Add the code to the image.
|
|
||||||
WORKDIR pty
|
|
||||||
ADD . .
|
|
||||||
|
|
||||||
# Build the lib.
|
|
||||||
RUN go build
|
|
||||||
23
vendor/github.com/creack/pty/Dockerfile.riscv
generated
vendored
23
vendor/github.com/creack/pty/Dockerfile.riscv
generated
vendored
@@ -1,23 +0,0 @@
|
|||||||
# NOTE: Using 1.13 as a base to build the RISCV compiler, the resulting version is based on go1.6.
|
|
||||||
FROM golang:1.13
|
|
||||||
|
|
||||||
# Clone and complie a riscv compatible version of the go compiler.
|
|
||||||
RUN git clone https://review.gerrithub.io/riscv/riscv-go /riscv-go
|
|
||||||
# riscvdev branch HEAD as of 2019-06-29.
|
|
||||||
RUN cd /riscv-go && git checkout 04885fddd096d09d4450726064d06dd107e374bf
|
|
||||||
ENV PATH=/riscv-go/misc/riscv:/riscv-go/bin:$PATH
|
|
||||||
RUN cd /riscv-go/src && GOROOT_BOOTSTRAP=$(go env GOROOT) ./make.bash
|
|
||||||
ENV GOROOT=/riscv-go
|
|
||||||
|
|
||||||
# Set the base env.
|
|
||||||
ENV GOOS=linux GOARCH=riscv CGO_ENABLED=0 GOFLAGS='-v -ldflags=-s -ldflags=-w'
|
|
||||||
|
|
||||||
# Pre compile the stdlib.
|
|
||||||
RUN go build -a std
|
|
||||||
|
|
||||||
# Add the code to the image.
|
|
||||||
WORKDIR pty
|
|
||||||
ADD . .
|
|
||||||
|
|
||||||
# Build the lib.
|
|
||||||
RUN go build
|
|
||||||
23
vendor/github.com/creack/pty/LICENSE
generated
vendored
23
vendor/github.com/creack/pty/LICENSE
generated
vendored
@@ -1,23 +0,0 @@
|
|||||||
Copyright (c) 2011 Keith Rarick
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
|
||||||
obtaining a copy of this software and associated
|
|
||||||
documentation files (the "Software"), to deal in the
|
|
||||||
Software without restriction, including without limitation
|
|
||||||
the rights to use, copy, modify, merge, publish, distribute,
|
|
||||||
sublicense, and/or sell copies of the Software, and to
|
|
||||||
permit persons to whom the Software is furnished to do so,
|
|
||||||
subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall
|
|
||||||
be included in all copies or substantial portions of the
|
|
||||||
Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
|
||||||
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
|
||||||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
|
||||||
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
||||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
107
vendor/github.com/creack/pty/README.md
generated
vendored
107
vendor/github.com/creack/pty/README.md
generated
vendored
@@ -1,107 +0,0 @@
|
|||||||
# pty
|
|
||||||
|
|
||||||
Pty is a Go package for using unix pseudo-terminals.
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
```sh
|
|
||||||
go get github.com/creack/pty
|
|
||||||
```
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
Note that those examples are for demonstration purpose only, to showcase how to use the library. They are not meant to be used in any kind of production environment.
|
|
||||||
|
|
||||||
### Command
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
|
|
||||||
"github.com/creack/pty"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
c := exec.Command("grep", "--color=auto", "bar")
|
|
||||||
f, err := pty.Start(c)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
f.Write([]byte("foo\n"))
|
|
||||||
f.Write([]byte("bar\n"))
|
|
||||||
f.Write([]byte("baz\n"))
|
|
||||||
f.Write([]byte{4}) // EOT
|
|
||||||
}()
|
|
||||||
io.Copy(os.Stdout, f)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Shell
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"os/signal"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/creack/pty"
|
|
||||||
"golang.org/x/term"
|
|
||||||
)
|
|
||||||
|
|
||||||
func test() error {
|
|
||||||
// Create arbitrary command.
|
|
||||||
c := exec.Command("bash")
|
|
||||||
|
|
||||||
// Start the command with a pty.
|
|
||||||
ptmx, err := pty.Start(c)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Make sure to close the pty at the end.
|
|
||||||
defer func() { _ = ptmx.Close() }() // Best effort.
|
|
||||||
|
|
||||||
// Handle pty size.
|
|
||||||
ch := make(chan os.Signal, 1)
|
|
||||||
signal.Notify(ch, syscall.SIGWINCH)
|
|
||||||
go func() {
|
|
||||||
for range ch {
|
|
||||||
if err := pty.InheritSize(os.Stdin, ptmx); err != nil {
|
|
||||||
log.Printf("error resizing pty: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
ch <- syscall.SIGWINCH // Initial resize.
|
|
||||||
defer func() { signal.Stop(ch); close(ch) }() // Cleanup signals when done.
|
|
||||||
|
|
||||||
// Set stdin in raw mode.
|
|
||||||
oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer func() { _ = term.Restore(int(os.Stdin.Fd()), oldState) }() // Best effort.
|
|
||||||
|
|
||||||
// Copy stdin to the pty and the pty to stdout.
|
|
||||||
// NOTE: The goroutine will keep reading until the next keystroke before returning.
|
|
||||||
go func() { _, _ = io.Copy(ptmx, os.Stdin) }()
|
|
||||||
_, _ = io.Copy(os.Stdout, ptmx)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
if err := test(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
18
vendor/github.com/creack/pty/asm_solaris_amd64.s
generated
vendored
18
vendor/github.com/creack/pty/asm_solaris_amd64.s
generated
vendored
@@ -1,18 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
//go:build gc
|
|
||||||
//+build gc
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go
|
|
||||||
//
|
|
||||||
|
|
||||||
TEXT ·sysvicall6(SB),NOSPLIT,$0-88
|
|
||||||
JMP syscall·sysvicall6(SB)
|
|
||||||
|
|
||||||
TEXT ·rawSysvicall6(SB),NOSPLIT,$0-88
|
|
||||||
JMP syscall·rawSysvicall6(SB)
|
|
||||||
16
vendor/github.com/creack/pty/doc.go
generated
vendored
16
vendor/github.com/creack/pty/doc.go
generated
vendored
@@ -1,16 +0,0 @@
|
|||||||
// Package pty provides functions for working with Unix terminals.
|
|
||||||
package pty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ErrUnsupported is returned if a function is not
|
|
||||||
// available on the current platform.
|
|
||||||
var ErrUnsupported = errors.New("unsupported")
|
|
||||||
|
|
||||||
// Open a pty and its corresponding tty.
|
|
||||||
func Open() (pty, tty *os.File, err error) {
|
|
||||||
return open()
|
|
||||||
}
|
|
||||||
19
vendor/github.com/creack/pty/ioctl.go
generated
vendored
19
vendor/github.com/creack/pty/ioctl.go
generated
vendored
@@ -1,19 +0,0 @@
|
|||||||
//go:build !windows && !solaris && !aix
|
|
||||||
// +build !windows,!solaris,!aix
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
const (
|
|
||||||
TIOCGWINSZ = syscall.TIOCGWINSZ
|
|
||||||
TIOCSWINSZ = syscall.TIOCSWINSZ
|
|
||||||
)
|
|
||||||
|
|
||||||
func ioctl(fd, cmd, ptr uintptr) error {
|
|
||||||
_, _, e := syscall.Syscall(syscall.SYS_IOCTL, fd, cmd, ptr)
|
|
||||||
if e != 0 {
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
40
vendor/github.com/creack/pty/ioctl_bsd.go
generated
vendored
40
vendor/github.com/creack/pty/ioctl_bsd.go
generated
vendored
@@ -1,40 +0,0 @@
|
|||||||
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
|
|
||||||
// +build darwin dragonfly freebsd netbsd openbsd
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
// from <sys/ioccom.h>
|
|
||||||
const (
|
|
||||||
_IOC_VOID uintptr = 0x20000000
|
|
||||||
_IOC_OUT uintptr = 0x40000000
|
|
||||||
_IOC_IN uintptr = 0x80000000
|
|
||||||
_IOC_IN_OUT uintptr = _IOC_OUT | _IOC_IN
|
|
||||||
_IOC_DIRMASK = _IOC_VOID | _IOC_OUT | _IOC_IN
|
|
||||||
|
|
||||||
_IOC_PARAM_SHIFT = 13
|
|
||||||
_IOC_PARAM_MASK = (1 << _IOC_PARAM_SHIFT) - 1
|
|
||||||
)
|
|
||||||
|
|
||||||
func _IOC_PARM_LEN(ioctl uintptr) uintptr {
|
|
||||||
return (ioctl >> 16) & _IOC_PARAM_MASK
|
|
||||||
}
|
|
||||||
|
|
||||||
func _IOC(inout uintptr, group byte, ioctl_num uintptr, param_len uintptr) uintptr {
|
|
||||||
return inout | (param_len&_IOC_PARAM_MASK)<<16 | uintptr(group)<<8 | ioctl_num
|
|
||||||
}
|
|
||||||
|
|
||||||
func _IO(group byte, ioctl_num uintptr) uintptr {
|
|
||||||
return _IOC(_IOC_VOID, group, ioctl_num, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _IOR(group byte, ioctl_num uintptr, param_len uintptr) uintptr {
|
|
||||||
return _IOC(_IOC_OUT, group, ioctl_num, param_len)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _IOW(group byte, ioctl_num uintptr, param_len uintptr) uintptr {
|
|
||||||
return _IOC(_IOC_IN, group, ioctl_num, param_len)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _IOWR(group byte, ioctl_num uintptr, param_len uintptr) uintptr {
|
|
||||||
return _IOC(_IOC_IN_OUT, group, ioctl_num, param_len)
|
|
||||||
}
|
|
||||||
48
vendor/github.com/creack/pty/ioctl_solaris.go
generated
vendored
48
vendor/github.com/creack/pty/ioctl_solaris.go
generated
vendored
@@ -1,48 +0,0 @@
|
|||||||
//go:build solaris
|
|
||||||
// +build solaris
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
//go:cgo_import_dynamic libc_ioctl ioctl "libc.so"
|
|
||||||
//go:linkname procioctl libc_ioctl
|
|
||||||
var procioctl uintptr
|
|
||||||
|
|
||||||
const (
|
|
||||||
// see /usr/include/sys/stropts.h
|
|
||||||
I_PUSH = uintptr((int32('S')<<8 | 002))
|
|
||||||
I_STR = uintptr((int32('S')<<8 | 010))
|
|
||||||
I_FIND = uintptr((int32('S')<<8 | 013))
|
|
||||||
|
|
||||||
// see /usr/include/sys/ptms.h
|
|
||||||
ISPTM = (int32('P') << 8) | 1
|
|
||||||
UNLKPT = (int32('P') << 8) | 2
|
|
||||||
PTSSTTY = (int32('P') << 8) | 3
|
|
||||||
ZONEPT = (int32('P') << 8) | 4
|
|
||||||
OWNERPT = (int32('P') << 8) | 5
|
|
||||||
|
|
||||||
// see /usr/include/sys/termios.h
|
|
||||||
TIOCSWINSZ = (uint32('T') << 8) | 103
|
|
||||||
TIOCGWINSZ = (uint32('T') << 8) | 104
|
|
||||||
)
|
|
||||||
|
|
||||||
type strioctl struct {
|
|
||||||
icCmd int32
|
|
||||||
icTimeout int32
|
|
||||||
icLen int32
|
|
||||||
icDP unsafe.Pointer
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defined in asm_solaris_amd64.s.
|
|
||||||
func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
|
||||||
|
|
||||||
func ioctl(fd, cmd, ptr uintptr) error {
|
|
||||||
if _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, fd, cmd, ptr, 0, 0, 0); errno != 0 {
|
|
||||||
return errno
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
13
vendor/github.com/creack/pty/ioctl_unsupported.go
generated
vendored
13
vendor/github.com/creack/pty/ioctl_unsupported.go
generated
vendored
@@ -1,13 +0,0 @@
|
|||||||
//go:build aix
|
|
||||||
// +build aix
|
|
||||||
|
|
||||||
package pty
|
|
||||||
|
|
||||||
const (
|
|
||||||
TIOCGWINSZ = 0
|
|
||||||
TIOCSWINSZ = 0
|
|
||||||
)
|
|
||||||
|
|
||||||
func ioctl(fd, cmd, ptr uintptr) error {
|
|
||||||
return ErrUnsupported
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user