diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7c0f59227ff6..ae1218d1812f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,9 +24,13 @@ env: REPO_SLUG: "docker/buildx-bin" DESTDIR: "./bin" TEST_CACHE_SCOPE: "test" + TESTFLAGS: "-v --parallel=6 --timeout=30m" + GOTESTSUM_FORMAT: "standard-verbose" + GO_VERSION: "1.21.6" + GOTESTSUM_VERSION: "v1.9.0" # same as one in Dockerfile jobs: - prepare-test: + prepare-test-integration: runs-on: ubuntu-22.04 steps: - @@ -51,14 +55,12 @@ jobs: *.cache-from=type=gha,scope=${{ env.TEST_CACHE_SCOPE }} *.cache-to=type=gha,scope=${{ env.TEST_CACHE_SCOPE }} - test: + test-integration: runs-on: ubuntu-22.04 needs: - - prepare-test + - prepare-test-integration env: - TESTFLAGS: "-v --parallel=6 --timeout=30m" TESTFLAGS_DOCKER: "-v --parallel=1 --timeout=30m" - GOTESTSUM_FORMAT: "standard-verbose" TEST_IMAGE_BUILD: "0" TEST_IMAGE_ID: "buildx-tests" strategy: @@ -71,9 +73,6 @@ jobs: - remote pkg: - ./tests - include: - - pkg: ./... - skip-integration-tests: 1 steps: - name: Checkout @@ -101,19 +100,19 @@ jobs: - name: Test run: | - 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.worker }}" | tr -dc '[:alnum:]-\n\r' | tr '[:upper:]' '[:lower:]') ./hack/test env: TEST_DOCKERD: "${{ startsWith(matrix.worker, 'docker') && '1' || '0' }}" TESTFLAGS: "${{ (matrix.worker == 'docker' || matrix.worker == 'docker\\+containerd') && env.TESTFLAGS_DOCKER || env.TESTFLAGS }} --run=//worker=${{ matrix.worker }}$" TESTPKGS: "${{ matrix.pkg }}" - SKIP_INTEGRATION_TESTS: "${{ matrix.skip-integration-tests }}" - name: Send to Codecov if: always() uses: codecov/codecov-action@v3 with: directory: ./bin/testreports + flags: integration - name: Generate annotations if: always() @@ -128,6 +127,75 @@ jobs: name: test-reports path: ./bin/testreports + test-unit: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: + - ubuntu-22.04 + - macos-12 + - windows-2022 + env: + SKIP_INTEGRATION_TESTS: 1 + steps: + - + name: Checkout + uses: actions/checkout@v4 + - + name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: "${{ env.GO_VERSION }}" + - + name: Prepare + run: | + testreportsBaseDir=./bin/testreports + testreportsDir=$testreportsBaseDir/unit-${{ matrix.os }} + echo "TESTREPORTS_BASEDIR=$testreportsBaseDir" >> $GITHUB_ENV + echo "TESTREPORTS_DIR=$testreportsDir" >> $GITHUB_ENV + mkdir -p $testreportsDir + shell: bash + - + name: Install gotestsum + run: | + go install gotest.tools/gotestsum@${{ env.GOTESTSUM_VERSION }} + - + name: Test + env: + TMPDIR: ${{ runner.temp }} + run: | + gotestsum \ + --jsonfile="${{ env.TESTREPORTS_DIR }}/go-test-report.json" \ + --junitfile="${{ env.TESTREPORTS_DIR }}/junit-report.xml" \ + --packages="./..." \ + -- \ + "-mod=vendor" \ + "-coverprofile" "${{ env.TESTREPORTS_DIR }}/coverage.txt" \ + "-covermode" "atomic" ${{ env.TESTFLAGS }} + shell: bash + - + name: Send to Codecov + if: always() + uses: codecov/codecov-action@v3 + with: + directory: ${{ env.TESTREPORTS_DIR }} + env_vars: RUNNER_OS + flags: unit + - + name: Generate annotations + if: always() + uses: crazy-max/.github/.github/actions/gotest-annotations@1a64ea6d01db9a48aa61954cb20e265782c167d9 + with: + directory: ${{ env.TESTREPORTS_DIR }} + - + name: Upload test reports + if: always() + uses: actions/upload-artifact@v3 + with: + name: test-reports + path: ${{ env.TESTREPORTS_BASEDIR }} + prepare-binaries: runs-on: ubuntu-22.04 outputs: @@ -192,7 +260,8 @@ jobs: bin-image: runs-on: ubuntu-22.04 needs: - - test + - test-integration + - test-unit if: ${{ github.event_name != 'pull_request' && github.repository == 'docker/buildx' }} steps: - @@ -244,7 +313,8 @@ jobs: release: runs-on: ubuntu-22.04 needs: - - test + - test-integration + - test-unit - binaries steps: - diff --git a/.github/workflows/docs-upstream.yml b/.github/workflows/docs-upstream.yml index 45cd4932fa33..2182e2f0bac4 100644 --- a/.github/workflows/docs-upstream.yml +++ b/.github/workflows/docs-upstream.yml @@ -45,18 +45,18 @@ jobs: DOCS_FORMATS: yaml - name: Upload reference YAML docs - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: docs-yaml path: /tmp/buildx-docs/out/reference retention-days: 1 validate: - uses: docker/docs/.github/workflows/validate-upstream.yml@e864c797e391fa35aecf1ddcecdbdeb683546424 # pin for artifact v3 support + uses: docker/docs/.github/workflows/validate-upstream.yml@6b73b05acb21edf7995cc5b3c6672d8e314cee7a # pin for artifact v4 support: https://github.com/docker/docs/pull/19220 needs: - docs-yaml with: module-name: docker/buildx data-files-id: docs-yaml data-files-folder: buildx - data-files-placeholder-folder: engine/reference/commandline + create-placeholder-stubs: true diff --git a/build/git.go b/build/git.go index 1e0a284de59b..8cba17dc63a3 100644 --- a/build/git.go +++ b/build/git.go @@ -45,9 +45,9 @@ func getGitAttributes(ctx context.Context, contextPath string, dockerfilePath st if filepath.IsAbs(contextPath) { wd = contextPath } else { - cwd, _ := os.Getwd() - wd, _ = filepath.Abs(filepath.Join(cwd, contextPath)) + wd, _ = filepath.Abs(filepath.Join(getWd(), contextPath)) } + wd = gitutil.SanitizePath(wd) gitc, err := gitutil.New(gitutil.WithContext(ctx), gitutil.WithWorkingDir(wd)) if err != nil { @@ -101,8 +101,7 @@ func getGitAttributes(ctx context.Context, contextPath string, dockerfilePath st dockerfilePath = filepath.Join(wd, "Dockerfile") } if !filepath.IsAbs(dockerfilePath) { - cwd, _ := os.Getwd() - dockerfilePath = filepath.Join(cwd, dockerfilePath) + dockerfilePath = filepath.Join(getWd(), dockerfilePath) } dockerfilePath, _ = filepath.Rel(root, dockerfilePath) if !strings.HasPrefix(dockerfilePath, "..") { @@ -113,3 +112,11 @@ func getGitAttributes(ctx context.Context, contextPath string, dockerfilePath st return } + +func getWd() string { + wd, _ := os.Getwd() + if lp, err := getLongPathName(wd); err == nil { + return lp + } + return wd +} diff --git a/build/git_unix.go b/build/git_unix.go new file mode 100644 index 000000000000..5bd8e4d9f282 --- /dev/null +++ b/build/git_unix.go @@ -0,0 +1,9 @@ +//go:build !windows +// +build !windows + +package build + +// getLongPathName is a no-op on non-Windows platforms. +func getLongPathName(path string) (string, error) { + return path, nil +} diff --git a/build/git_windows.go b/build/git_windows.go new file mode 100644 index 000000000000..b3ec71540aa4 --- /dev/null +++ b/build/git_windows.go @@ -0,0 +1,26 @@ +package build + +import "golang.org/x/sys/windows" + +// getLongPathName converts Windows short pathnames to full pathnames. +// For example C:\Users\ADMIN~1 --> C:\Users\Administrator. +func getLongPathName(path string) (string, error) { + // See https://groups.google.com/forum/#!topic/golang-dev/1tufzkruoTg + p, err := windows.UTF16FromString(path) + if err != nil { + return "", err + } + b := p // GetLongPathName says we can reuse buffer + n, err := windows.GetLongPathName(&p[0], &b[0], uint32(len(b))) + if err != nil { + return "", err + } + if n > uint32(len(b)) { + b = make([]uint16, n) + _, err = windows.GetLongPathName(&p[0], &b[0], uint32(len(b))) + if err != nil { + return "", err + } + } + return windows.UTF16ToString(b), nil +} diff --git a/commands/bake.go b/commands/bake.go index 77ad7529d086..431cecfc1a57 100644 --- a/commands/bake.go +++ b/commands/bake.go @@ -141,7 +141,7 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions, cFlags com if err == nil { err = err1 } - if err == nil && progressMode != progressui.QuietMode { + if err == nil && progressMode != progressui.QuietMode && progressMode != progressui.RawJSONMode { desktop.PrintBuildDetails(os.Stderr, printer.BuildRefs(), term) } } @@ -295,13 +295,17 @@ func saveLocalStateGroup(dockerCli command.Cli, ref string, lsg localstate.State } func readBakeFiles(ctx context.Context, nodes []builder.Node, url string, names []string, stdin io.Reader, pw progress.Writer) (files []bake.File, inp *bake.Input, err error) { - var lnames []string - var rnames []string + var lnames []string // local + var rnames []string // remote + var anames []string // both for _, v := range names { if strings.HasPrefix(v, "cwd://") { - lnames = append(lnames, strings.TrimPrefix(v, "cwd://")) + tname := strings.TrimPrefix(v, "cwd://") + lnames = append(lnames, tname) + anames = append(anames, tname) } else { rnames = append(rnames, v) + anames = append(anames, v) } } @@ -320,7 +324,7 @@ func readBakeFiles(ctx context.Context, nodes []builder.Node, url string, names if url != "" { lfiles, err = bake.ReadLocalFiles(lnames, stdin, sub) } else { - lfiles, err = bake.ReadLocalFiles(append(lnames, rnames...), stdin, sub) + lfiles, err = bake.ReadLocalFiles(anames, stdin, sub) } return nil }) diff --git a/commands/build.go b/commands/build.go index 41f341676ba7..af8af4723006 100644 --- a/commands/build.go +++ b/commands/build.go @@ -288,10 +288,13 @@ func runBuild(dockerCli command.Cli, options buildOptions) (err error) { return retErr } - if progressMode != progressui.QuietMode { - desktop.PrintBuildDetails(os.Stderr, printer.BuildRefs(), term) - } else { + switch progressMode { + case progressui.RawJSONMode: + // no additional display + case progressui.QuietMode: fmt.Println(getImageID(resp.ExporterResponse)) + default: + desktop.PrintBuildDetails(os.Stderr, printer.BuildRefs(), term) } if options.imageIDFile != "" { if err := os.WriteFile(options.imageIDFile, []byte(getImageID(resp.ExporterResponse)), 0644); err != nil { @@ -749,7 +752,7 @@ func dockerUlimitToControllerUlimit(u *dockeropts.UlimitOpt) *controllerapi.Ulim } func printWarnings(w io.Writer, warnings []client.VertexWarning, mode progressui.DisplayMode) { - if len(warnings) == 0 || mode == progressui.QuietMode { + if len(warnings) == 0 || mode == progressui.QuietMode || mode == progressui.RawJSONMode { return } fmt.Fprintf(w, "\n ") diff --git a/docs/reference/buildx_build.md b/docs/reference/buildx_build.md index a7b17ad34640..abd1e11ca46a 100644 --- a/docs/reference/buildx_build.md +++ b/docs/reference/buildx_build.md @@ -33,7 +33,7 @@ Start a build | [`--metadata-file`](#metadata-file) | `string` | | Write build result metadata to the file | | `--network` | `string` | `default` | Set the networking mode for the `RUN` instructions during build | | `--no-cache` | | | Do not use cache when building the image | -| `--no-cache-filter` | `stringArray` | | Do not cache specified stages | +| [`--no-cache-filter`](#no-cache-filter) | `stringArray` | | Do not cache specified stages | | [`-o`](#output), [`--output`](#output) | `stringArray` | | Output destination (format: `type=local,dest=path`) | | [`--platform`](#platform) | `stringArray` | | Set target platform for build | | `--print` | `string` | | Print result of information request (e.g., outline, targets) | @@ -341,6 +341,61 @@ $ cat metadata.json } ``` +### Ignore build cache for specific stages (--no-cache-filter) + +The `--no-cache-filter` lets you specify one or more stages of a multi-stage +Dockerfile for which build cache should be ignored. To specify multiple stages, +use a comma-separated syntax: + +```console +$ docker buildx build --no-cache-filter stage1,stage2,stage3 . +``` + +For example, the following Dockerfile contains four stages: + +- `base` +- `install` +- `test` +- `release` + +```dockerfile +# syntax=docker/dockerfile:1 + +FROM oven/bun:1 as base +WORKDIR /app + +FROM base AS install +WORKDIR /temp/dev +RUN --mount=type=bind,source=package.json,target=package.json \ + --mount=type=bind,source=bun.lockb,target=bun.lockb \ + bun install --frozen-lockfile + +FROM base AS test +COPY --from=install /temp/dev/node_modules node_modules +COPY . . +RUN bun test + +FROM base AS release +ENV NODE_ENV=production +COPY --from=install /temp/dev/node_modules node_modules +COPY . . +ENTRYPOINT ["bun", "run", "index.js"] +``` + +To ignore the cache for the `install` stage: + +```console +$ docker buildx build --no-cache-filter install . +``` + +To ignore the cache the `install` and `release` stages: + +```console +$ docker buildx build --no-cache-filter install,release . +``` + +The arguments for the `--no-cache-filter` flag must be names of stages. + ### Set the export action for the build result (-o, --output) ```text diff --git a/docs/reference/buildx_du.md b/docs/reference/buildx_du.md index 043f58131b8e..b1fdbcbf1c1d 100644 --- a/docs/reference/buildx_du.md +++ b/docs/reference/buildx_du.md @@ -13,13 +13,106 @@ Disk usage |:------------------------|:---------|:--------|:-----------------------------------------| | [`--builder`](#builder) | `string` | | Override the configured builder instance | | `--filter` | `filter` | | Provide filter values | -| `--verbose` | | | Provide a more verbose output | +| [`--verbose`](#verbose) | | | Provide a more verbose output | ## Examples +### Show disk usage + +The `docker buildx du` command shows the disk usage for the currently selected +builder. + +```console +$ docker buildx du +ID RECLAIMABLE SIZE LAST ACCESSED +12wgll9os87pazzft8lt0yztp* true 1.704GB 13 days ago +iupsv3it5ubh92aweb7c1wojc* true 1.297GB 36 minutes ago +ek4ve8h4obyv5kld6vicmtqyn true 811.7MB 13 days ago +isovrfnmkelzhtdx942w9vjcb* true 811.7MB 13 days ago +0jty7mjrndi1yo7xkv1baralh true 810.5MB 13 days ago +jyzkefmsysqiaakgwmjgxjpcz* true 810.5MB 13 days ago +z8w1y95jn93gvj92jtaj6uhwk true 318MB 2 weeks ago +rz2zgfcwlfxsxd7d41w2sz2tt true 8.224kB* 43 hours ago +n5bkzpewmk2eiu6hn9tzx18jd true 8.224kB* 43 hours ago +ao94g6vtbzdl6k5zgdmrmnwpt true 8.224kB* 43 hours ago +2pyjep7njm0wh39vcingxb97i true 8.224kB* 43 hours ago +Shared: 115.5MB +Private: 10.25GB +Reclaimable: 10.36GB +Total: 10.36GB +``` + +If `RECLAIMABLE` is false, the `docker buildx du prune` command won't delete +the record, even if you use `--all`. That's because the record is actively in +use by some component of the builder. + +The asterisks (\*) in the default output indicate the following: + +- An asterisk next to an ID (`zu7m6evdpebh5h8kfkpw9dlf2*`) indicates that the record + is mutable. The size of the record may change, or another build can take ownership of + it and change or commit to it. If you run the `du` command again, this item may + not be there anymore, or the size might be different. +- An asterisk next to a size (`8.288kB*`) indicates that the record is shared. + Storage of the record is shared with some other resource, typically an image. + If you prune such a record then you will lose build cache but only metadata + will be deleted as the image still needs to actual storage layers. + +### Use verbose output (--verbose) + +The verbose output of the `docker buildx du` command is useful for inspecting +the disk usage records in more detail. The verbose output shows the mutable and +shared states more clearly, as well as additional information about the +corresponding layer. + +```console +$ docker buildx du --verbose +... +Last used: 2 days ago +Type: regular + +ID: 05d0elirb4mmvpmnzbrp3ssrg +Parent: e8sfdn4mygrg7msi9ak1dy6op +Created at: 2023-11-20 09:53:30.881558721 +0000 UTC +Mutable: false +Reclaimable: true +Shared: false +Size: 0B +Description: [gobase 3/3] WORKDIR /src +Usage count: 3 +Last used: 24 hours ago +Type: regular + +Reclaimable: 4.453GB +Total: 4.453GB +``` + ### Override the configured builder instance (--builder) -Same as [`buildx --builder`](buildx.md#builder). +Use the `--builder` flag to inspect the disk usage of a particular builder. + +```console +$ docker buildx du --builder youthful_shtern +ID RECLAIMABLE SIZE LAST ACCESSED +g41agepgdczekxg2mtw0dujsv* true 1.312GB 47 hours ago +e6ycrsa0bn9akigqgzu0sc6kr true 318MB 47 hours ago +our9zg4ndly65ze1ccczdksiz true 204.9MB 45 hours ago +b7xv3xpxnwupc81tc9ya3mgq6* true 120.6MB 47 hours ago +zihgye15ss6vum3wmck9egdoy* true 79.81MB 2 days ago +aaydharssv1ug98yhuwclkfrh* true 79.81MB 2 days ago +ta1r4vmnjug5dhub76as4kkol* true 74.51MB 47 hours ago +murma9f83j9h8miifbq68udjf* true 74.51MB 47 hours ago +47f961866a49g5y8myz80ixw1* true 74.51MB 47 hours ago +tzh99xtzlaf6txllh3cobag8t true 74.49MB 47 hours ago +ld6laoeuo1kwapysu6afwqybl* true 59.89MB 47 hours ago +yitxizi5kaplpyomqpos2cryp* true 59.83MB 47 hours ago +iy8aa4b7qjn0qmy9wiga9cj8w true 33.65MB 47 hours ago +mci7okeijyp8aqqk16j80dy09 true 19.86MB 47 hours ago +lqvj091he652slxdla4wom3pz true 14.08MB 47 hours ago +fkt31oiv793nd26h42llsjcw7* true 11.87MB 2 days ago +uj802yxtvkcjysnjb4kgwvn2v true 11.68MB 45 hours ago +Reclaimable: 2.627GB +Total: 2.627GB +``` diff --git a/go.mod b/go.mod index 9903a6f3109c..e7839c55f20e 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/Masterminds/semver/v3 v3.2.1 github.com/aws/aws-sdk-go-v2/config v1.18.16 github.com/compose-spec/compose-go v1.20.0 - github.com/containerd/console v1.0.3 + github.com/containerd/console v1.0.4 github.com/containerd/containerd v1.7.7 github.com/containerd/continuity v0.4.2 github.com/containerd/log v0.1.0 @@ -42,6 +42,7 @@ require ( go.opentelemetry.io/otel/trace v1.14.0 golang.org/x/mod v0.11.0 golang.org/x/sync v0.3.0 + golang.org/x/sys v0.13.0 golang.org/x/term v0.13.0 google.golang.org/grpc v1.53.0 gopkg.in/yaml.v3 v3.0.1 @@ -146,7 +147,6 @@ require ( golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.5.0 // indirect - golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.7.0 // indirect diff --git a/go.sum b/go.sum index 372cc4abb99e..4c91b461aa5b 100644 --- a/go.sum +++ b/go.sum @@ -127,8 +127,8 @@ github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUo github.com/compose-spec/compose-go v1.20.0 h1:h4ZKOst1EF/DwZp7dWkb+wbTVE4nEyT9Lc89to84Ol4= github.com/compose-spec/compose-go v1.20.0/go.mod h1:+MdqXV4RA7wdFsahh/Kb8U0pAJqkg7mr4PM9tFKU8RM= 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/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= +github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro= +github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/containerd/containerd v1.7.7 h1:QOC2K4A42RQpcrZyptP6z9EJZnlHfHJUfZrAAHe15q4= github.com/containerd/containerd v1.7.7/go.mod h1:3c4XZv6VeT9qgf9GMTxNTMFxGJrGpI2vz1yk4ye+YY8= github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= diff --git a/tests/bake.go b/tests/bake.go index be4b27a66012..a2af62cf0f7d 100644 --- a/tests/bake.go +++ b/tests/bake.go @@ -24,6 +24,7 @@ var bakeTests = []func(t *testing.T, sb integration.Sandbox){ testBakeRemote, testBakeRemoteCmdContext, testBakeRemoteLocalOverride, + testBakeLocalCwdOverride, testBakeRemoteCmdContextOverride, testBakeRemoteContextSubdir, testBakeRemoteCmdContextEscapeRoot, @@ -173,6 +174,41 @@ EOT require.FileExists(t, filepath.Join(dirDest, "bar")) } +func testBakeLocalCwdOverride(t *testing.T, sb integration.Sandbox) { + bakeFile := []byte(` +target "default" { + dockerfile-inline = < 0 { + return errs[0] + } + return nil } diff --git a/vendor/github.com/containerd/console/console_zos.go b/vendor/github.com/containerd/console/console_zos.go deleted file mode 100644 index b348a839a03b..000000000000 --- a/vendor/github.com/containerd/console/console_zos.go +++ /dev/null @@ -1,163 +0,0 @@ -// +build zos - -/* - Copyright The containerd 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 console - -import ( - "fmt" - "os" - - "golang.org/x/sys/unix" -) - -// NewPty creates a new pty pair -// The master is returned as the first console and a string -// with the path to the pty slave is returned as the second -func NewPty() (Console, string, error) { - var f File - var err error - var slave string - for i := 0;; i++ { - ptyp := fmt.Sprintf("/dev/ptyp%04d", i) - f, err = os.OpenFile(ptyp, os.O_RDWR, 0600) - if err == nil { - slave = fmt.Sprintf("/dev/ttyp%04d", i) - break - } - if os.IsNotExist(err) { - return nil, "", err - } - // else probably Resource Busy - } - m, err := newMaster(f) - if err != nil { - return nil, "", err - } - return m, slave, nil -} - -type master struct { - f File - original *unix.Termios -} - -func (m *master) Read(b []byte) (int, error) { - return m.f.Read(b) -} - -func (m *master) Write(b []byte) (int, error) { - return m.f.Write(b) -} - -func (m *master) Close() error { - return m.f.Close() -} - -func (m *master) Resize(ws WinSize) error { - return tcswinsz(m.f.Fd(), ws) -} - -func (m *master) ResizeFrom(c Console) error { - ws, err := c.Size() - if err != nil { - return err - } - return m.Resize(ws) -} - -func (m *master) Reset() error { - if m.original == nil { - return nil - } - return tcset(m.f.Fd(), m.original) -} - -func (m *master) getCurrent() (unix.Termios, error) { - var termios unix.Termios - if err := tcget(m.f.Fd(), &termios); err != nil { - return unix.Termios{}, err - } - return termios, nil -} - -func (m *master) SetRaw() error { - rawState, err := m.getCurrent() - if err != nil { - return err - } - rawState = cfmakeraw(rawState) - rawState.Oflag = rawState.Oflag | unix.OPOST - return tcset(m.f.Fd(), &rawState) -} - -func (m *master) DisableEcho() error { - rawState, err := m.getCurrent() - if err != nil { - return err - } - rawState.Lflag = rawState.Lflag &^ unix.ECHO - return tcset(m.f.Fd(), &rawState) -} - -func (m *master) Size() (WinSize, error) { - return tcgwinsz(m.f.Fd()) -} - -func (m *master) Fd() uintptr { - return m.f.Fd() -} - -func (m *master) Name() string { - return m.f.Name() -} - -// checkConsole checks if the provided file is a console -func checkConsole(f File) error { - var termios unix.Termios - if tcget(f.Fd(), &termios) != nil { - return ErrNotAConsole - } - return nil -} - -func newMaster(f File) (Console, error) { - m := &master{ - f: f, - } - t, err := m.getCurrent() - if err != nil { - return nil, err - } - m.original = &t - return m, nil -} - -// ClearONLCR sets the necessary tty_ioctl(4)s to ensure that a pty pair -// created by us acts normally. In particular, a not-very-well-known default of -// Linux unix98 ptys is that they have +onlcr by default. While this isn't a -// problem for terminal emulators, because we relay data from the terminal we -// also relay that funky line discipline. -func ClearONLCR(fd uintptr) error { - return setONLCR(fd, false) -} - -// SetONLCR sets the necessary tty_ioctl(4)s to ensure that a pty pair -// created by us acts as intended for a terminal emulator. -func SetONLCR(fd uintptr) error { - return setONLCR(fd, true) -} diff --git a/vendor/github.com/containerd/console/pty_freebsd_cgo.go b/vendor/github.com/containerd/console/pty_freebsd_cgo.go index cbd3cd7ea43d..22368623aab2 100644 --- a/vendor/github.com/containerd/console/pty_freebsd_cgo.go +++ b/vendor/github.com/containerd/console/pty_freebsd_cgo.go @@ -1,3 +1,4 @@ +//go:build freebsd && cgo // +build freebsd,cgo /* diff --git a/vendor/github.com/containerd/console/pty_freebsd_nocgo.go b/vendor/github.com/containerd/console/pty_freebsd_nocgo.go index b5e43181d4f3..ceb90a47b818 100644 --- a/vendor/github.com/containerd/console/pty_freebsd_nocgo.go +++ b/vendor/github.com/containerd/console/pty_freebsd_nocgo.go @@ -1,3 +1,4 @@ +//go:build freebsd && !cgo // +build freebsd,!cgo /* diff --git a/vendor/github.com/containerd/console/pty_unix.go b/vendor/github.com/containerd/console/pty_unix.go index d5a6bd8ca2e8..f5a5b8058c65 100644 --- a/vendor/github.com/containerd/console/pty_unix.go +++ b/vendor/github.com/containerd/console/pty_unix.go @@ -1,4 +1,5 @@ -// +build darwin linux netbsd openbsd solaris +//go:build darwin || linux || netbsd || openbsd +// +build darwin linux netbsd openbsd /* Copyright The containerd Authors. diff --git a/vendor/github.com/containerd/console/pty_zos.go b/vendor/github.com/containerd/console/pty_zos.go new file mode 100644 index 000000000000..58f59aba58c9 --- /dev/null +++ b/vendor/github.com/containerd/console/pty_zos.go @@ -0,0 +1,43 @@ +//go:build zos +// +build zos + +/* + Copyright The containerd 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 console + +import ( + "fmt" + "os" +) + +// openpt allocates a new pseudo-terminal by opening the first available /dev/ptypXX device +func openpt() (*os.File, error) { + var f *os.File + var err error + for i := 0; ; i++ { + ptyp := fmt.Sprintf("/dev/ptyp%04d", i) + f, err = os.OpenFile(ptyp, os.O_RDWR, 0600) + if err == nil { + break + } + if os.IsNotExist(err) { + return nil, err + } + // else probably Resource Busy + } + return f, nil +} diff --git a/vendor/github.com/containerd/console/tc_freebsd_cgo.go b/vendor/github.com/containerd/console/tc_freebsd_cgo.go index 0f3d27273094..33282579411e 100644 --- a/vendor/github.com/containerd/console/tc_freebsd_cgo.go +++ b/vendor/github.com/containerd/console/tc_freebsd_cgo.go @@ -1,3 +1,4 @@ +//go:build freebsd && cgo // +build freebsd,cgo /* diff --git a/vendor/github.com/containerd/console/tc_freebsd_nocgo.go b/vendor/github.com/containerd/console/tc_freebsd_nocgo.go index 087fc158a169..18a9b9cbea97 100644 --- a/vendor/github.com/containerd/console/tc_freebsd_nocgo.go +++ b/vendor/github.com/containerd/console/tc_freebsd_nocgo.go @@ -1,3 +1,4 @@ +//go:build freebsd && !cgo // +build freebsd,!cgo /* diff --git a/vendor/github.com/containerd/console/tc_openbsd_cgo.go b/vendor/github.com/containerd/console/tc_openbsd_cgo.go index f0cec06a72dc..0e76f6cc3e0a 100644 --- a/vendor/github.com/containerd/console/tc_openbsd_cgo.go +++ b/vendor/github.com/containerd/console/tc_openbsd_cgo.go @@ -1,3 +1,4 @@ +//go:build openbsd && cgo // +build openbsd,cgo /* diff --git a/vendor/github.com/containerd/console/tc_openbsd_nocgo.go b/vendor/github.com/containerd/console/tc_openbsd_nocgo.go index daccce20585a..dca92418b0e5 100644 --- a/vendor/github.com/containerd/console/tc_openbsd_nocgo.go +++ b/vendor/github.com/containerd/console/tc_openbsd_nocgo.go @@ -1,3 +1,4 @@ +//go:build openbsd && !cgo // +build openbsd,!cgo /* diff --git a/vendor/github.com/containerd/console/tc_solaris_cgo.go b/vendor/github.com/containerd/console/tc_solaris_cgo.go deleted file mode 100644 index e36a68edd1ed..000000000000 --- a/vendor/github.com/containerd/console/tc_solaris_cgo.go +++ /dev/null @@ -1,51 +0,0 @@ -// +build solaris,cgo - -/* - Copyright The containerd 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 console - -import ( - "os" - - "golang.org/x/sys/unix" -) - -//#include -import "C" - -const ( - cmdTcGet = unix.TCGETS - cmdTcSet = unix.TCSETS -) - -// ptsname retrieves the name of the first available pts for the given master. -func ptsname(f *os.File) (string, error) { - ptspath, err := C.ptsname(C.int(f.Fd())) - if err != nil { - return "", err - } - return C.GoString(ptspath), nil -} - -// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f. -// unlockpt should be called before opening the slave side of a pty. -func unlockpt(f *os.File) error { - if _, err := C.grantpt(C.int(f.Fd())); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/containerd/console/tc_solaris_nocgo.go b/vendor/github.com/containerd/console/tc_solaris_nocgo.go deleted file mode 100644 index eb0bd2c36b83..000000000000 --- a/vendor/github.com/containerd/console/tc_solaris_nocgo.go +++ /dev/null @@ -1,47 +0,0 @@ -// +build solaris,!cgo - -/* - Copyright The containerd 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. -*/ - -// -// Implementing the functions below requires cgo support. Non-cgo stubs -// versions are defined below to enable cross-compilation of source code -// that depends on these functions, but the resultant cross-compiled -// binaries cannot actually be used. If the stub function(s) below are -// actually invoked they will display an error message and cause the -// calling process to exit. -// - -package console - -import ( - "os" - - "golang.org/x/sys/unix" -) - -const ( - cmdTcGet = unix.TCGETS - cmdTcSet = unix.TCSETS -) - -func ptsname(f *os.File) (string, error) { - panic("ptsname() support requires cgo.") -} - -func unlockpt(f *os.File) error { - panic("unlockpt() support requires cgo.") -} diff --git a/vendor/github.com/containerd/console/tc_unix.go b/vendor/github.com/containerd/console/tc_unix.go index a6bf01e8d1a2..2ecf188fca33 100644 --- a/vendor/github.com/containerd/console/tc_unix.go +++ b/vendor/github.com/containerd/console/tc_unix.go @@ -1,4 +1,5 @@ -// +build darwin freebsd linux netbsd openbsd solaris zos +//go:build darwin || freebsd || linux || netbsd || openbsd || zos +// +build darwin freebsd linux netbsd openbsd zos /* Copyright The containerd Authors. @@ -83,7 +84,7 @@ func cfmakeraw(t unix.Termios) unix.Termios { t.Oflag &^= unix.OPOST t.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN) t.Cflag &^= (unix.CSIZE | unix.PARENB) - t.Cflag &^= unix.CS8 + t.Cflag |= unix.CS8 t.Cc[unix.VMIN] = 1 t.Cc[unix.VTIME] = 0 diff --git a/vendor/github.com/containerd/console/tc_zos.go b/vendor/github.com/containerd/console/tc_zos.go index 4262eaf4cc07..fc90ba5fb86e 100644 --- a/vendor/github.com/containerd/console/tc_zos.go +++ b/vendor/github.com/containerd/console/tc_zos.go @@ -17,6 +17,9 @@ package console import ( + "os" + "strings" + "golang.org/x/sys/unix" ) @@ -24,3 +27,13 @@ const ( cmdTcGet = unix.TCGETS cmdTcSet = unix.TCSETS ) + +// unlockpt is a no-op on zos. +func unlockpt(_ *os.File) error { + return nil +} + +// ptsname retrieves the name of the first available pts for the given master. +func ptsname(f *os.File) (string, error) { + return "/dev/ttyp" + strings.TrimPrefix(f.Name(), "/dev/ptyp"), nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 8e499581b6ce..3fe6c9a9c03b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -134,7 +134,7 @@ github.com/compose-spec/compose-go/template github.com/compose-spec/compose-go/tree github.com/compose-spec/compose-go/types github.com/compose-spec/compose-go/utils -# github.com/containerd/console v1.0.3 +# github.com/containerd/console v1.0.4 ## explicit; go 1.13 github.com/containerd/console # github.com/containerd/containerd v1.7.7