diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 4e48d5f8802a..51141a5b00be 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -22,9 +22,13 @@ Please provide the following information: **- Description for the changelog** +```markdown changelog +``` + **- A picture of a cute animal (not mandatory but encouraged)** diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8487e4d3c3fe..9c33915d2e4a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,5 +1,14 @@ name: build +# Default to 'contents: read', which grants actions to read commits. +# +# If any permission is set, any permission not included in the list is +# implicitly set to "none". +# +# see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions +permissions: + contents: read + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -19,7 +28,7 @@ on: jobs: prepare: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 outputs: matrix: ${{ steps.platforms.outputs.matrix }} steps: @@ -37,7 +46,7 @@ jobs: echo ${{ steps.platforms.outputs.matrix }} build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: - prepare strategy: @@ -77,20 +86,20 @@ jobs: platformPair=${platform//\//-} tar -cvzf "/tmp/out/docker-${platformPair}.tar.gz" . if [ -z "${{ matrix.use_glibc }}" ]; then - echo "ARTIFACT_NAME=${{ matrix.target }}" >> $GITHUB_ENV + echo "ARTIFACT_NAME=${{ matrix.target }}-${platformPair}" >> $GITHUB_ENV else - echo "ARTIFACT_NAME=${{ matrix.target }}-glibc" >> $GITHUB_ENV + echo "ARTIFACT_NAME=${{ matrix.target }}-${platformPair}-glibc" >> $GITHUB_ENV fi - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ env.ARTIFACT_NAME }} path: /tmp/out/* if-no-files-found: error bin-image: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 if: ${{ github.event_name != 'pull_request' && github.repository == 'docker/cli' }} steps: - @@ -134,7 +143,7 @@ jobs: *.cache-to=type=gha,scope=bin-image,mode=max prepare-plugins: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 outputs: matrix: ${{ steps.platforms.outputs.matrix }} steps: @@ -152,7 +161,7 @@ jobs: echo ${{ steps.platforms.outputs.matrix }} plugins: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 needs: - prepare-plugins strategy: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index cb3413317b31..8090aab553b4 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,5 +1,14 @@ name: codeql +# Default to 'contents: read', which grants actions to read commits. +# +# If any permission is set, any permission not included in the list is +# implicitly set to "none". +# +# see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions +permissions: + contents: read + on: push: branches: @@ -26,6 +35,8 @@ jobs: codeql: runs-on: 'ubuntu-latest' timeout-minutes: 360 + env: + DISABLE_WARN_OUTSIDE_CONTAINER: '1' permissions: actions: read contents: read @@ -46,12 +57,22 @@ jobs: name: Update Go uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version: "1.22.10" - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: go + # CodeQL 2.16.4's auto-build added support for multi-module repositories, + # and is trying to be smart by searching for modules in every directory, + # including vendor directories. If no module is found, it's creating one + # which is ... not what we want, so let's give it a "go.mod". + # see: https://github.com/docker/cli/pull/4944#issuecomment-2002034698 + - + name: Create go.mod + run: | + ln -s vendor.mod go.mod + ln -s vendor.sum go.sum - name: Autobuild uses: github/codeql-action/autobuild@v3 diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 60f99c5690c6..39152158aa80 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -1,5 +1,14 @@ name: e2e +# Default to 'contents: read', which grants actions to read commits. +# +# If any permission is set, any permission not included in the list is +# implicitly set to "none". +# +# see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions +permissions: + contents: read + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -16,7 +25,7 @@ on: jobs: e2e: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: @@ -28,11 +37,11 @@ jobs: - alpine - debian engine-version: -# - 20.10-dind # FIXME: Fails on 20.10 - - stable-dind # TODO: Use 20.10-dind, stable-dind is deprecated - include: - - target: non-experimental - engine-version: 19.03-dind + - 25.0 # latest + - 24.0 # latest - 1 + - 23.0 # mirantis lts + # TODO(krissetto) 19.03 needs a look, doesn't work ubuntu 22.04 (cgroup errors). + # we could have a separate job that tests it against ubuntu 20.04 steps: - name: Checkout @@ -55,10 +64,10 @@ jobs: make -f docker.Makefile test-e2e-${{ matrix.target }} env: BASE_VARIANT: ${{ matrix.base }} - E2E_ENGINE_VERSION: ${{ matrix.engine-version }} + ENGINE_VERSION: ${{ matrix.engine-version }} TESTFLAGS: -coverprofile=/tmp/coverage/coverage.txt - name: Send to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: file: ./build/coverage/coverage.txt diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0972595137f0..6a0898ab43a6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,5 +1,14 @@ name: test +# Default to 'contents: read', which grants actions to read commits. +# +# If any permission is set, any permission not included in the list is +# implicitly set to "none". +# +# see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions +permissions: + contents: read + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -16,7 +25,7 @@ on: jobs: ctn: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Checkout @@ -31,7 +40,7 @@ jobs: targets: test-coverage - name: Send to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: file: ./build/coverage/coverage.txt @@ -45,7 +54,8 @@ jobs: fail-fast: false matrix: os: - - macos-12 + - macos-13 # macOS 13 on Intel + - macos-14 # macOS 14 on arm64 (Apple Silicon M1) # - windows-2022 # FIXME: some tests are failing on the Windows runner, as well as on Appveyor since June 24, 2018: https://ci.appveyor.com/project/docker/cli/history steps: - @@ -63,7 +73,7 @@ jobs: name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.21.6 + go-version: "1.22.10" - name: Test run: | @@ -73,7 +83,7 @@ jobs: shell: bash - name: Send to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: file: /tmp/coverage.txt working-directory: ${{ env.GOPATH }}/src/github.com/docker/cli diff --git a/.github/workflows/validate-pr.yml b/.github/workflows/validate-pr.yml new file mode 100644 index 000000000000..6674447693bf --- /dev/null +++ b/.github/workflows/validate-pr.yml @@ -0,0 +1,71 @@ +name: validate-pr + +# Default to 'contents: read', which grants actions to read commits. +# +# If any permission is set, any permission not included in the list is +# implicitly set to "none". +# +# see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions +permissions: + contents: read + +on: + pull_request: + types: [opened, edited, labeled, unlabeled] + +jobs: + check-area-label: + runs-on: ubuntu-20.04 + steps: + - name: Missing `area/` label + if: contains(join(github.event.pull_request.labels.*.name, ','), 'impact/') && !contains(join(github.event.pull_request.labels.*.name, ','), 'area/') + run: | + echo "::error::Every PR with an 'impact/*' label should also have an 'area/*' label" + exit 1 + - name: OK + run: exit 0 + + check-changelog: + if: contains(join(github.event.pull_request.labels.*.name, ','), 'impact/') + runs-on: ubuntu-20.04 + env: + PR_BODY: | + ${{ github.event.pull_request.body }} + steps: + - name: Check changelog description + run: | + # Extract the `markdown changelog` note code block + block=$(echo -n "$PR_BODY" | tr -d '\r' | awk '/^```markdown changelog$/{flag=1;next}/^```$/{flag=0}flag') + + # Strip empty lines + desc=$(echo "$block" | awk NF) + + if [ -z "$desc" ]; then + echo "::error::Changelog section is empty. Please provide a description for the changelog." + exit 1 + fi + + len=$(echo -n "$desc" | wc -c) + if [[ $len -le 6 ]]; then + echo "::error::Description looks too short: $desc" + exit 1 + fi + + echo "This PR will be included in the release notes with the following note:" + echo "$desc" + + check-pr-branch: + runs-on: ubuntu-20.04 + env: + PR_TITLE: ${{ github.event.pull_request.title }} + steps: + # Backports or PR that target a release branch directly should mention the target branch in the title, for example: + # [X.Y backport] Some change that needs backporting to X.Y + # [X.Y] Change directly targeting the X.Y branch + - name: Get branch from PR title + id: title_branch + run: echo "$PR_TITLE" | sed -n 's/^\[\([0-9]*\.[0-9]*\)[^]]*\].*/branch=\1/p' >> $GITHUB_OUTPUT + + - name: Check release branch + if: github.event.pull_request.base.ref != steps.title_branch.outputs.branch && !(github.event.pull_request.base.ref == 'master' && steps.title_branch.outputs.branch == '') + run: echo "::error::PR title suggests targetting the ${{ steps.title_branch.outputs.branch }} branch, but is opened against ${{ github.event.pull_request.base.ref }}" && exit 1 diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index ccd0493a329e..7813bfd56e42 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -1,5 +1,14 @@ name: validate +# Default to 'contents: read', which grants actions to read commits. +# +# If any permission is set, any permission not included in the list is +# implicitly set to "none". +# +# see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions +permissions: + contents: read + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -16,7 +25,7 @@ on: jobs: validate: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: @@ -37,7 +46,7 @@ jobs: # check that the generated Markdown and the checked-in files match validate-md: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Checkout @@ -57,7 +66,7 @@ jobs: fi validate-make: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: diff --git a/Dockerfile b/Dockerfile index 5a8f890af01c..f6455c8afbb7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,15 @@ # syntax=docker/dockerfile:1 ARG BASE_VARIANT=alpine -ARG ALPINE_VERSION=3.18 +ARG ALPINE_VERSION=3.20 ARG BASE_DEBIAN_DISTRO=bookworm -ARG GO_VERSION=1.21.6 -ARG XX_VERSION=1.2.1 +ARG GO_VERSION=1.22.10 +ARG XX_VERSION=1.6.1 ARG GOVERSIONINFO_VERSION=v1.3.0 ARG GOTESTSUM_VERSION=v1.10.0 ARG BUILDX_VERSION=0.12.1 -ARG COMPOSE_VERSION=v2.24.0 +ARG COMPOSE_VERSION=v2.24.3 FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx diff --git a/cli-plugins/socket/socket.go b/cli-plugins/socket/socket.go index beb46ae3a3e4..93d7a87b2849 100644 --- a/cli-plugins/socket/socket.go +++ b/cli-plugins/socket/socket.go @@ -65,6 +65,7 @@ func ConnectAndWait(cb func()) { _, err := conn.Read(b) if errors.Is(err, io.EOF) { cb() + return } } }() diff --git a/cli-plugins/socket/socket_nodarwin.go b/cli-plugins/socket/socket_nodarwin.go index 893e465e4b9f..aa6065ecb446 100644 --- a/cli-plugins/socket/socket_nodarwin.go +++ b/cli-plugins/socket/socket_nodarwin.go @@ -1,4 +1,4 @@ -//go:build !darwin +//go:build !darwin && !openbsd package socket @@ -15,5 +15,6 @@ func listen(socketname string) (*net.UnixListener, error) { func onAccept(conn *net.UnixConn, listener *net.UnixListener) { // do nothing - // while on darwin we would unlink here; on non-darwin the socket is abstract and not present on the filesystem + // while on darwin and OpenBSD we would unlink here; + // on non-darwin the socket is abstract and not present on the filesystem } diff --git a/cli-plugins/socket/socket_openbsd.go b/cli-plugins/socket/socket_openbsd.go new file mode 100644 index 000000000000..17ab6aa69e6e --- /dev/null +++ b/cli-plugins/socket/socket_openbsd.go @@ -0,0 +1,19 @@ +package socket + +import ( + "net" + "os" + "path/filepath" + "syscall" +) + +func listen(socketname string) (*net.UnixListener, error) { + return net.ListenUnix("unix", &net.UnixAddr{ + Name: filepath.Join(os.TempDir(), socketname), + Net: "unix", + }) +} + +func onAccept(conn *net.UnixConn, listener *net.UnixListener) { + syscall.Unlink(listener.Addr().String()) +} diff --git a/cli-plugins/socket/socket_test.go b/cli-plugins/socket/socket_test.go new file mode 100644 index 000000000000..409eb689485c --- /dev/null +++ b/cli-plugins/socket/socket_test.go @@ -0,0 +1,133 @@ +package socket + +import ( + "io/fs" + "net" + "os" + "runtime" + "strings" + "testing" + "time" + + "gotest.tools/v3/assert" + "gotest.tools/v3/poll" +) + +func TestSetupConn(t *testing.T) { + t.Run("updates conn when connected", func(t *testing.T) { + var conn *net.UnixConn + listener, err := SetupConn(&conn) + assert.NilError(t, err) + assert.Check(t, listener != nil, "returned nil listener but no error") + addr, err := net.ResolveUnixAddr("unix", listener.Addr().String()) + assert.NilError(t, err, "failed to resolve listener address") + + _, err = net.DialUnix("unix", nil, addr) + assert.NilError(t, err, "failed to dial returned listener") + + pollConnNotNil(t, &conn) + }) + + t.Run("allows reconnects", func(t *testing.T) { + var conn *net.UnixConn + listener, err := SetupConn(&conn) + assert.NilError(t, err) + assert.Check(t, listener != nil, "returned nil listener but no error") + addr, err := net.ResolveUnixAddr("unix", listener.Addr().String()) + assert.NilError(t, err, "failed to resolve listener address") + + otherConn, err := net.DialUnix("unix", nil, addr) + assert.NilError(t, err, "failed to dial returned listener") + + otherConn.Close() + + _, err = net.DialUnix("unix", nil, addr) + assert.NilError(t, err, "failed to redial listener") + }) + + t.Run("does not leak sockets to local directory", func(t *testing.T) { + var conn *net.UnixConn + listener, err := SetupConn(&conn) + assert.NilError(t, err) + assert.Check(t, listener != nil, "returned nil listener but no error") + checkDirNoPluginSocket(t) + + addr, err := net.ResolveUnixAddr("unix", listener.Addr().String()) + assert.NilError(t, err, "failed to resolve listener address") + _, err = net.DialUnix("unix", nil, addr) + assert.NilError(t, err, "failed to dial returned listener") + checkDirNoPluginSocket(t) + }) +} + +func checkDirNoPluginSocket(t *testing.T) { + t.Helper() + + files, err := os.ReadDir(".") + assert.NilError(t, err, "failed to list files in dir to check for leaked sockets") + + for _, f := range files { + info, err := f.Info() + assert.NilError(t, err, "failed to check file info") + // check for a socket with `docker_cli_` in the name (from `SetupConn()`) + if strings.Contains(f.Name(), "docker_cli_") && info.Mode().Type() == fs.ModeSocket { + t.Fatal("found socket in a local directory") + } + } +} + +func TestConnectAndWait(t *testing.T) { + t.Run("calls cancel func on EOF", func(t *testing.T) { + var conn *net.UnixConn + listener, err := SetupConn(&conn) + assert.NilError(t, err, "failed to setup listener") + + done := make(chan struct{}) + t.Setenv(EnvKey, listener.Addr().String()) + cancelFunc := func() { + done <- struct{}{} + } + ConnectAndWait(cancelFunc) + pollConnNotNil(t, &conn) + conn.Close() + + select { + case <-done: + case <-time.After(10 * time.Millisecond): + t.Fatal("cancel function not closed after 10ms") + } + }) + + // TODO: this test cannot be executed with `t.Parallel()`, due to + // relying on goroutine numbers to ensure correct behaviour + t.Run("connect goroutine exits after EOF", func(t *testing.T) { + var conn *net.UnixConn + listener, err := SetupConn(&conn) + assert.NilError(t, err, "failed to setup listener") + t.Setenv(EnvKey, listener.Addr().String()) + numGoroutines := runtime.NumGoroutine() + + ConnectAndWait(func() {}) + assert.Equal(t, runtime.NumGoroutine(), numGoroutines+1) + + pollConnNotNil(t, &conn) + conn.Close() + poll.WaitOn(t, func(t poll.LogT) poll.Result { + if runtime.NumGoroutine() > numGoroutines+1 { + return poll.Continue("waiting for connect goroutine to exit") + } + return poll.Success() + }, poll.WithDelay(1*time.Millisecond), poll.WithTimeout(10*time.Millisecond)) + }) +} + +func pollConnNotNil(t *testing.T, conn **net.UnixConn) { + t.Helper() + + poll.WaitOn(t, func(t poll.LogT) poll.Result { + if *conn == nil { + return poll.Continue("waiting for conn to not be nil") + } + return poll.Success() + }, poll.WithDelay(1*time.Millisecond), poll.WithTimeout(10*time.Millisecond)) +} diff --git a/cli/command/image/testdata/inspect-command-success.simple-many.golden b/cli/command/image/testdata/inspect-command-success.simple-many.golden index a43fc76299c1..f653d015e9d0 100644 --- a/cli/command/image/testdata/inspect-command-success.simple-many.golden +++ b/cli/command/image/testdata/inspect-command-success.simple-many.golden @@ -5,7 +5,6 @@ "RepoDigests": null, "Parent": "", "Comment": "", - "Created": "", "Container": "", "ContainerConfig": null, "DockerVersion": "", @@ -29,7 +28,6 @@ "RepoDigests": null, "Parent": "", "Comment": "", - "Created": "", "Container": "", "ContainerConfig": null, "DockerVersion": "", diff --git a/cli/command/image/testdata/inspect-command-success.simple.golden b/cli/command/image/testdata/inspect-command-success.simple.golden index 8c041319f2cb..4d595781fdd4 100644 --- a/cli/command/image/testdata/inspect-command-success.simple.golden +++ b/cli/command/image/testdata/inspect-command-success.simple.golden @@ -5,7 +5,6 @@ "RepoDigests": null, "Parent": "", "Comment": "", - "Created": "", "Container": "", "ContainerConfig": null, "DockerVersion": "", diff --git a/cli/command/volume/update.go b/cli/command/volume/update.go index c04c2ff8f507..42ce9ac586be 100644 --- a/cli/command/volume/update.go +++ b/cli/command/volume/update.go @@ -18,7 +18,7 @@ func newUpdateCommand(dockerCli command.Cli) *cobra.Command { cmd := &cobra.Command{ Use: "update [OPTIONS] [VOLUME]", Short: "Update a volume (cluster volumes only)", - Args: cli.RequiresMaxArgs(1), + Args: cli.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { return runUpdate(cmd.Context(), dockerCli, args[0], availability, cmd.Flags()) }, diff --git a/cli/command/volume/update_test.go b/cli/command/volume/update_test.go new file mode 100644 index 000000000000..13051a0056fa --- /dev/null +++ b/cli/command/volume/update_test.go @@ -0,0 +1,22 @@ +package volume + +import ( + "io" + "testing" + + "github.com/docker/cli/internal/test" + "gotest.tools/v3/assert" +) + +func TestUpdateCmd(t *testing.T) { + cmd := newUpdateCommand( + test.NewFakeCli(&fakeClient{}), + ) + cmd.SetArgs([]string{}) + cmd.SetOut(io.Discard) + cmd.SetErr(io.Discard) + + err := cmd.Execute() + + assert.ErrorContains(t, err, "requires exactly 1 argument") +} diff --git a/cli/compose/loader/loader.go b/cli/compose/loader/loader.go index c33bd9d1146d..84090075a7e0 100644 --- a/cli/compose/loader/loader.go +++ b/cli/compose/loader/loader.go @@ -328,7 +328,7 @@ func createTransformHook(additionalTransformers ...Transformer) mapstructure.Dec reflect.TypeOf(types.MappingWithEquals{}): transformMappingOrListFunc("=", true), reflect.TypeOf(types.Labels{}): transformMappingOrListFunc("=", false), reflect.TypeOf(types.MappingWithColon{}): transformMappingOrListFunc(":", false), - reflect.TypeOf(types.HostsList{}): transformListOrMappingFunc(":", false), + reflect.TypeOf(types.HostsList{}): transformHostsList, reflect.TypeOf(types.ServiceVolumeConfig{}): transformServiceVolumeConfig, reflect.TypeOf(types.BuildConfig{}): transformBuildConfig, reflect.TypeOf(types.Duration(0)): transformStringToDuration, @@ -808,28 +808,58 @@ var transformStringList TransformerFunc = func(data any) (any, error) { } } -func transformMappingOrListFunc(sep string, allowNil bool) TransformerFunc { - return func(data any) (any, error) { - return transformMappingOrList(data, sep, allowNil), nil - } -} +var transformHostsList TransformerFunc = func(data any) (any, error) { + hl := transformListOrMapping(data, ":", false, []string{"=", ":"}) -func transformListOrMappingFunc(sep string, allowNil bool) TransformerFunc { - return func(data any) (any, error) { - return transformListOrMapping(data, sep, allowNil), nil + // Remove brackets from IP addresses if present (for example "[::1]" -> "::1"). + result := make([]string, 0, len(hl)) + for _, hip := range hl { + host, ip, _ := strings.Cut(hip, ":") + if len(ip) > 2 && ip[0] == '[' && ip[len(ip)-1] == ']' { + ip = ip[1 : len(ip)-1] + } + result = append(result, fmt.Sprintf("%s:%s", host, ip)) } + return result, nil } -func transformListOrMapping(listOrMapping any, sep string, allowNil bool) any { +// transformListOrMapping transforms pairs of strings that may be represented as +// a map, or a list of '=' or ':' separated strings, into a list of ':' separated +// strings. +func transformListOrMapping(listOrMapping any, sep string, allowNil bool, allowSeps []string) []string { switch value := listOrMapping.(type) { case map[string]any: return toStringList(value, sep, allowNil) case []any: - return listOrMapping + result := make([]string, 0, len(value)) + for _, entry := range value { + for i, allowSep := range allowSeps { + entry := fmt.Sprint(entry) + k, v, ok := strings.Cut(entry, allowSep) + if ok { + // Entry uses this allowed separator. Add it to the result, using + // sep as a separator. + result = append(result, fmt.Sprintf("%s%s%s", k, sep, v)) + break + } else if i == len(allowSeps)-1 { + // No more separators to try, keep the entry if allowNil. + if allowNil { + result = append(result, k) + } + } + } + } + return result } panic(errors.Errorf("expected a map or a list, got %T: %#v", listOrMapping, listOrMapping)) } +func transformMappingOrListFunc(sep string, allowNil bool) TransformerFunc { + return func(data any) (any, error) { + return transformMappingOrList(data, sep, allowNil), nil + } +} + func transformMappingOrList(mappingOrList any, sep string, allowNil bool) any { switch values := mappingOrList.(type) { case map[string]any: diff --git a/cli/compose/loader/loader_test.go b/cli/compose/loader/loader_test.go index 94128ac465c4..cdeaa6d6011d 100644 --- a/cli/compose/loader/loader_test.go +++ b/cli/compose/loader/loader_test.go @@ -1302,12 +1302,14 @@ services: extra_hosts: "zulu": "162.242.195.82" "alpha": "50.31.209.229" + "beta": "[fd20:f8a7:6e5b::2]" "host.docker.internal": "host-gateway" `) assert.NilError(t, err) expected := types.HostsList{ "alpha:50.31.209.229", + "beta:fd20:f8a7:6e5b::2", "host.docker.internal:host-gateway", "zulu:162.242.195.82", } @@ -1324,16 +1326,25 @@ services: image: busybox extra_hosts: - "zulu:162.242.195.82" + - "whiskey=162.242.195.83" - "alpha:50.31.209.229" - "zulu:ff02::1" - - "host.docker.internal:host-gateway" + - "whiskey=ff02::2" + - "foxtrot=[ff02::3]" + - "bravo:[ff02::4]" + - "host.docker.internal=host-gateway" + - "noaddress" `) assert.NilError(t, err) expected := types.HostsList{ "zulu:162.242.195.82", + "whiskey:162.242.195.83", "alpha:50.31.209.229", "zulu:ff02::1", + "whiskey:ff02::2", + "foxtrot:ff02::3", + "bravo:ff02::4", "host.docker.internal:host-gateway", } diff --git a/cli/connhelper/commandconn/commandconn_unix_test.go b/cli/connhelper/commandconn/commandconn_unix_test.go index 03bc46936443..a8b19b8c7b78 100644 --- a/cli/connhelper/commandconn/commandconn_unix_test.go +++ b/cli/connhelper/commandconn/commandconn_unix_test.go @@ -48,7 +48,7 @@ func TestEOFWithoutError(t *testing.T) { func TestCloseRunningCommand(t *testing.T) { cmd := "sh" - args := []string{"-c", "while true; sleep 1; done"} + args := []string{"-c", "while true; do sleep 1; done"} done := make(chan struct{}) defer close(done) @@ -155,7 +155,7 @@ func (mockStdoutEOF) Close() error { func TestCloseWhileWriting(t *testing.T) { cmd := "sh" - args := []string{"-c", "while true; sleep 1; done"} + args := []string{"-c", "while true; do sleep 1; done"} c, err := New(context.TODO(), cmd, args...) assert.NilError(t, err) @@ -185,7 +185,7 @@ func TestCloseWhileWriting(t *testing.T) { func TestCloseWhileReading(t *testing.T) { cmd := "sh" - args := []string{"-c", "while true; sleep 1; done"} + args := []string{"-c", "while true; do sleep 1; done"} c, err := New(context.TODO(), cmd, args...) assert.NilError(t, err) diff --git a/contrib/completion/bash/docker b/contrib/completion/bash/docker index b8fa557cb573..d37cf66d3ffb 100644 --- a/contrib/completion/bash/docker +++ b/contrib/completion/bash/docker @@ -1146,6 +1146,7 @@ __docker_complete_plugin() { local path=$1 local completionCommand="__completeNoDesc" local resultArray=($path $completionCommand) + local current="$cur" for value in "${words[@]:2}"; do if [ -z "$value" ]; then resultArray+=( "''" ) diff --git a/docker-bake.hcl b/docker-bake.hcl index d8570f45034e..240e5ee7ed2b 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -1,5 +1,5 @@ variable "GO_VERSION" { - default = "1.21.6" + default = "1.22.10" } variable "VERSION" { default = "" @@ -186,6 +186,7 @@ target "bin-image-cross" { "linux/arm64", "linux/ppc64le", "linux/s390x", - "windows/amd64" + "windows/amd64", + "windows/arm64" ] } diff --git a/docker.Makefile b/docker.Makefile index bddd91a2a503..011bfd9b6877 100644 --- a/docker.Makefile +++ b/docker.Makefile @@ -14,13 +14,13 @@ PACKAGER_NAME ?= DEV_DOCKER_IMAGE_NAME = docker-cli-dev$(IMAGE_TAG) E2E_IMAGE_NAME = docker-cli-e2e -E2E_ENGINE_VERSION ?= +ENGINE_VERSION ?= CACHE_VOLUME_NAME := docker-cli-dev-cache ifeq ($(DOCKER_CLI_GO_BUILD_CACHE),y) DOCKER_CLI_MOUNTS += -v "$(CACHE_VOLUME_NAME):/root/.cache/go-build" endif VERSION = $(shell cat VERSION) -ENVVARS = -e VERSION=$(VERSION) -e GITCOMMIT -e PLATFORM -e TESTFLAGS -e TESTDIRS -e GOOS -e GOARCH -e GOARM -e TEST_ENGINE_VERSION=$(E2E_ENGINE_VERSION) +ENVVARS = -e VERSION=$(VERSION) -e GITCOMMIT -e PLATFORM -e TESTFLAGS -e TESTDIRS -e GOOS -e GOARCH -e GOARM -e ENGINE_VERSION # Some Dockerfiles use features that are only supported with BuildKit enabled export DOCKER_BUILDKIT=1 @@ -132,21 +132,21 @@ test-e2e: test-e2e-non-experimental test-e2e-experimental test-e2e-connhelper-ss .PHONY: test-e2e-experimental test-e2e-experimental: build-e2e-image # run experimental e2e tests - docker run --rm $(ENVVARS) -e DOCKERD_EXPERIMENTAL=1 -e TEST_ENGINE_VERSION=$(E2E_ENGINE_VERSION) \ + docker run --rm $(ENVVARS) -e DOCKERD_EXPERIMENTAL=1 \ --mount type=bind,src=$(CURDIR)/build/coverage,dst=/tmp/coverage \ --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \ $(E2E_IMAGE_NAME) .PHONY: test-e2e-non-experimental test-e2e-non-experimental: build-e2e-image # run non-experimental e2e tests - docker run --rm $(ENVVARS) -e TEST_ENGINE_VERSION=$(E2E_ENGINE_VERSION) \ + docker run --rm $(ENVVARS) \ --mount type=bind,src=$(CURDIR)/build/coverage,dst=/tmp/coverage \ --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \ $(E2E_IMAGE_NAME) .PHONY: test-e2e-connhelper-ssh test-e2e-connhelper-ssh: build-e2e-image # run experimental SSH-connection helper e2e tests - docker run --rm $(ENVVARS) -e DOCKERD_EXPERIMENTAL=1 -e TEST_ENGINE_VERSION=$(E2E_ENGINE_VERSION) -e TEST_CONNHELPER=ssh \ + docker run --rm $(ENVVARS) -e DOCKERD_EXPERIMENTAL=1 -e TEST_CONNHELPER=ssh \ --mount type=bind,src=$(CURDIR)/build/coverage,dst=/tmp/coverage \ --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \ $(E2E_IMAGE_NAME) diff --git a/dockerfiles/Dockerfile.authors b/dockerfiles/Dockerfile.authors index 278ad769fea1..321a752c47ef 100644 --- a/dockerfiles/Dockerfile.authors +++ b/dockerfiles/Dockerfile.authors @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1 -ARG ALPINE_VERSION=3.18 +ARG ALPINE_VERSION=3.20 FROM alpine:${ALPINE_VERSION} AS gen RUN apk add --no-cache bash git diff --git a/dockerfiles/Dockerfile.dev b/dockerfiles/Dockerfile.dev index d8b9356dd153..92b9bd480bfe 100644 --- a/dockerfiles/Dockerfile.dev +++ b/dockerfiles/Dockerfile.dev @@ -1,7 +1,7 @@ # syntax=docker/dockerfile:1 -ARG GO_VERSION=1.21.6 -ARG ALPINE_VERSION=3.18 +ARG GO_VERSION=1.22.10 +ARG ALPINE_VERSION=3.20 ARG BUILDX_VERSION=0.12.1 FROM docker/buildx-bin:${BUILDX_VERSION} AS buildx diff --git a/dockerfiles/Dockerfile.lint b/dockerfiles/Dockerfile.lint index 904b0ce6da64..38ed830717ca 100644 --- a/dockerfiles/Dockerfile.lint +++ b/dockerfiles/Dockerfile.lint @@ -1,7 +1,7 @@ # syntax=docker/dockerfile:1 -ARG GO_VERSION=1.21.6 -ARG ALPINE_VERSION=3.18 +ARG GO_VERSION=1.22.10 +ARG ALPINE_VERSION=3.20 ARG GOLANGCI_LINT_VERSION=v1.55.2 FROM golangci/golangci-lint:${GOLANGCI_LINT_VERSION}-alpine AS golangci-lint diff --git a/dockerfiles/Dockerfile.vendor b/dockerfiles/Dockerfile.vendor index a7d941fff2f6..56841e95bae1 100644 --- a/dockerfiles/Dockerfile.vendor +++ b/dockerfiles/Dockerfile.vendor @@ -1,7 +1,7 @@ # syntax=docker/dockerfile:1 -ARG GO_VERSION=1.21.6 -ARG ALPINE_VERSION=3.18 +ARG GO_VERSION=1.22.10 +ARG ALPINE_VERSION=3.20 ARG MODOUTDATED_VERSION=v0.8.0 FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS base diff --git a/docs/extend/config.md b/docs/extend/config.md index 1f96d3e00930..d2472a39f41e 100644 --- a/docs/extend/config.md +++ b/docs/extend/config.md @@ -55,11 +55,11 @@ the registry. - `entrypoint` string array - Entrypoint of the plugin, see [`ENTRYPOINT`](https://docs.docker.com/engine/reference/builder/#entrypoint) + Entrypoint of the plugin, see [`ENTRYPOINT`](https://docs.docker.com/reference/dockerfile/#entrypoint) - `workdir` string - Working directory of the plugin, see [`WORKDIR`](https://docs.docker.com/engine/reference/builder/#workdir) + Working directory of the plugin, see [`WORKDIR`](https://docs.docker.com/reference/dockerfile/#workdir) - `network` PluginNetwork diff --git a/docs/extend/legacy_plugins.md b/docs/extend/legacy_plugins.md index 0086761c1929..830a7dce9c27 100644 --- a/docs/extend/legacy_plugins.md +++ b/docs/extend/legacy_plugins.md @@ -60,6 +60,7 @@ The sections below provide an overview of available third-party plugins. | [Infinit volume plugin](https://infinit.sh/documentation/docker/volume-plugin) | A volume plugin that makes it easy to mount and manage Infinit volumes using Docker. | | [IPFS Volume Plugin](https://github.com/vdemeester/docker-volume-ipfs) | An open source volume plugin that allows using an [ipfs](https://ipfs.io/) filesystem as a volume. | | [Keywhiz plugin](https://github.com/calavera/docker-volume-keywhiz) | A plugin that provides credentials and secret management using Keywhiz as a central repository. | +| [Linode Volume Plugin](https://github.com/linode/docker-volume-linode) | A plugin that adds the ability to manage Linode Block Storage as Docker Volumes from within a Linode. | | [Local Persist Plugin](https://github.com/CWSpear/local-persist) | A volume plugin that extends the default `local` driver's functionality by allowing you specify a mountpoint anywhere on the host, which enables the files to *always persist*, even if the volume is removed via `docker volume rm`. | | [NetApp Plugin](https://github.com/NetApp/netappdvp) (nDVP) | A volume plugin that provides direct integration with the Docker ecosystem for the NetApp storage portfolio. The nDVP package supports the provisioning and management of storage resources from the storage platform to Docker hosts, with a robust framework for adding additional platforms in the future. | | [Netshare plugin](https://github.com/ContainX/docker-volume-netshare) | A volume plugin that provides volume management for NFS 3/4, AWS EFS and CIFS file systems. | diff --git a/docs/extend/plugins_authorization.md b/docs/extend/plugins_authorization.md index 8a646e50fa54..79201ec2367e 100644 --- a/docs/extend/plugins_authorization.md +++ b/docs/extend/plugins_authorization.md @@ -104,7 +104,7 @@ Enable the authorization plugin with a dedicated command line flag in the `--authorization-plugin=PLUGIN_ID` format. The flag supplies a `PLUGIN_ID` value. This value can be the plugin’s socket or a path to a specification file. Authorization plugins can be loaded without restarting the daemon. Refer -to the [`dockerd` documentation](../reference/commandline/dockerd.md#configuration-reload-behavior) for more information. +to the [`dockerd` documentation](https://docs.docker.com/reference/cli/dockerd/#configuration-reload-behavior) for more information. ```console $ dockerd --authorization-plugin=plugin1 --authorization-plugin=plugin2,... diff --git a/docs/reference/commandline/attach.md b/docs/reference/commandline/attach.md index ffbf58a81d6d..3a89574075b9 100644 --- a/docs/reference/commandline/attach.md +++ b/docs/reference/commandline/attach.md @@ -13,7 +13,7 @@ Attach local standard input, output, and error streams to a running container |:----------------|:---------|:--------|:----------------------------------------------------| | `--detach-keys` | `string` | | Override the key sequence for detaching a container | | `--no-stdin` | | | Do not attach STDIN | -| `--sig-proxy` | | | Proxy all received signals to the process | +| `--sig-proxy` | `bool` | `true` | Proxy all received signals to the process | diff --git a/docs/reference/commandline/build.md b/docs/reference/commandline/build.md index 40983fb0e717..c0dd7a676897 100644 --- a/docs/reference/commandline/build.md +++ b/docs/reference/commandline/build.md @@ -21,7 +21,7 @@ Build an image from a Dockerfile | `-c`, `--cpu-shares` | `int64` | `0` | CPU shares (relative weight) | | `--cpuset-cpus` | `string` | | CPUs in which to allow execution (0-3, 0,1) | | `--cpuset-mems` | `string` | | MEMs in which to allow execution (0-3, 0,1) | -| `--disable-content-trust` | | | Skip image verification | +| `--disable-content-trust` | `bool` | `true` | Skip image verification | | `-f`, `--file` | `string` | | Name of the Dockerfile (Default is `PATH/Dockerfile`) | | `--force-rm` | | | Always remove intermediate containers | | `--iidfile` | `string` | | Write the image ID to the file | @@ -34,7 +34,7 @@ Build an image from a Dockerfile | `--platform` | `string` | | Set platform if server is multi-platform capable | | `--pull` | | | Always attempt to pull a newer version of the image | | `-q`, `--quiet` | | | Suppress the build output and print image ID on success | -| `--rm` | | | Remove intermediate containers after a successful build | +| `--rm` | `bool` | `true` | Remove intermediate containers after a successful build | | `--security-opt` | `stringSlice` | | Security options | | `--shm-size` | `bytes` | `0` | Size of `/dev/shm` | | `--squash` | | | Squash newly built layers into a single new layer | diff --git a/docs/reference/commandline/builder_build.md b/docs/reference/commandline/builder_build.md index 56142103060c..b972d573fac1 100644 --- a/docs/reference/commandline/builder_build.md +++ b/docs/reference/commandline/builder_build.md @@ -21,7 +21,7 @@ Build an image from a Dockerfile | `-c`, `--cpu-shares` | `int64` | `0` | CPU shares (relative weight) | | `--cpuset-cpus` | `string` | | CPUs in which to allow execution (0-3, 0,1) | | `--cpuset-mems` | `string` | | MEMs in which to allow execution (0-3, 0,1) | -| `--disable-content-trust` | | | Skip image verification | +| `--disable-content-trust` | `bool` | `true` | Skip image verification | | `-f`, `--file` | `string` | | Name of the Dockerfile (Default is `PATH/Dockerfile`) | | `--force-rm` | | | Always remove intermediate containers | | `--iidfile` | `string` | | Write the image ID to the file | @@ -34,7 +34,7 @@ Build an image from a Dockerfile | `--platform` | `string` | | Set platform if server is multi-platform capable | | `--pull` | | | Always attempt to pull a newer version of the image | | `-q`, `--quiet` | | | Suppress the build output and print image ID on success | -| `--rm` | | | Remove intermediate containers after a successful build | +| `--rm` | `bool` | `true` | Remove intermediate containers after a successful build | | `--security-opt` | `stringSlice` | | Security options | | `--shm-size` | `bytes` | `0` | Size of `/dev/shm` | | `--squash` | | | Squash newly built layers into a single new layer | @@ -47,4 +47,4 @@ Build an image from a Dockerfile ## Description -See [docker build](build.md) for more information. +See [docker build](image_build.md) for more information. diff --git a/docs/reference/commandline/cli.md b/docs/reference/commandline/cli.md index e73580f1fc90..c6bd54337a9b 100644 --- a/docs/reference/commandline/cli.md +++ b/docs/reference/commandline/cli.md @@ -10,105 +10,8 @@ aliases: - /engine/reference/commandline/engine_update/ --- - - -# docker - -To list available commands, either run `docker` with no parameters -or execute `docker help`: - - -The base command for the Docker CLI. - -### Subcommands - -| Name | Description | -|:------------------------------|:------------------------------------------------------------------------------| -| [`attach`](attach.md) | Attach local standard input, output, and error streams to a running container | -| [`build`](build.md) | Build an image from a Dockerfile | -| [`builder`](builder.md) | Manage builds | -| [`checkpoint`](checkpoint.md) | Manage checkpoints | -| [`commit`](commit.md) | Create a new image from a container's changes | -| [`config`](config.md) | Manage Swarm configs | -| [`container`](container.md) | Manage containers | -| [`context`](context.md) | Manage contexts | -| [`cp`](cp.md) | Copy files/folders between a container and the local filesystem | -| [`create`](create.md) | Create a new container | -| [`diff`](diff.md) | Inspect changes to files or directories on a container's filesystem | -| [`events`](events.md) | Get real time events from the server | -| [`exec`](exec.md) | Execute a command in a running container | -| [`export`](export.md) | Export a container's filesystem as a tar archive | -| [`history`](history.md) | Show the history of an image | -| [`image`](image.md) | Manage images | -| [`images`](images.md) | List images | -| [`import`](import.md) | Import the contents from a tarball to create a filesystem image | -| [`info`](info.md) | Display system-wide information | -| [`inspect`](inspect.md) | Return low-level information on Docker objects | -| [`kill`](kill.md) | Kill one or more running containers | -| [`load`](load.md) | Load an image from a tar archive or STDIN | -| [`login`](login.md) | Log in to a registry | -| [`logout`](logout.md) | Log out from a registry | -| [`logs`](logs.md) | Fetch the logs of a container | -| [`manifest`](manifest.md) | Manage Docker image manifests and manifest lists | -| [`network`](network.md) | Manage networks | -| [`node`](node.md) | Manage Swarm nodes | -| [`pause`](pause.md) | Pause all processes within one or more containers | -| [`plugin`](plugin.md) | Manage plugins | -| [`port`](port.md) | List port mappings or a specific mapping for the container | -| [`ps`](ps.md) | List containers | -| [`pull`](pull.md) | Download an image from a registry | -| [`push`](push.md) | Upload an image to a registry | -| [`rename`](rename.md) | Rename a container | -| [`restart`](restart.md) | Restart one or more containers | -| [`rm`](rm.md) | Remove one or more containers | -| [`rmi`](rmi.md) | Remove one or more images | -| [`run`](run.md) | Create and run a new container from an image | -| [`save`](save.md) | Save one or more images to a tar archive (streamed to STDOUT by default) | -| [`search`](search.md) | Search Docker Hub for images | -| [`secret`](secret.md) | Manage Swarm secrets | -| [`service`](service.md) | Manage Swarm services | -| [`stack`](stack.md) | Manage Swarm stacks | -| [`start`](start.md) | Start one or more stopped containers | -| [`stats`](stats.md) | Display a live stream of container(s) resource usage statistics | -| [`stop`](stop.md) | Stop one or more running containers | -| [`swarm`](swarm.md) | Manage Swarm | -| [`system`](system.md) | Manage Docker | -| [`tag`](tag.md) | Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE | -| [`top`](top.md) | Display the running processes of a container | -| [`trust`](trust.md) | Manage trust on Docker images | -| [`unpause`](unpause.md) | Unpause all processes within one or more containers | -| [`update`](update.md) | Update configuration of one or more containers | -| [`version`](version.md) | Show the Docker version information | -| [`volume`](volume.md) | Manage volumes | -| [`wait`](wait.md) | Block until one or more containers stop, then print their exit codes | - - -### Options - -| Name | Type | Default | Description | -|:---------------------------------|:---------|:-------------------------|:--------------------------------------------------------------------------------------------------------------------------------------| -| `--config` | `string` | `/root/.docker` | Location of client config files | -| `-c`, `--context` | `string` | | Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with `docker context use`) | -| `-D`, `--debug` | | | Enable debug mode | -| [`-H`](#host), [`--host`](#host) | `list` | | Daemon socket to connect to | -| `-l`, `--log-level` | `string` | `info` | Set the logging level (`debug`, `info`, `warn`, `error`, `fatal`) | -| `--tls` | | | Use TLS; implied by --tlsverify | -| `--tlscacert` | `string` | `/root/.docker/ca.pem` | Trust certs signed only by this CA | -| `--tlscert` | `string` | `/root/.docker/cert.pem` | Path to TLS certificate file | -| `--tlskey` | `string` | `/root/.docker/key.pem` | Path to TLS key file | -| `--tlsverify` | | | Use TLS and verify the remote | - - - - -## Description +The base command for the Docker CLI is `docker`. For information about the +available flags and subcommands, refer to the [CLI reference](https://docs.docker.com/reference/cli/docker/) Depending on your Docker system configuration, you may be required to preface each `docker` command with `sudo`. To avoid having to use `sudo` with the @@ -123,20 +26,20 @@ the [installation](https://docs.docker.com/install/) instructions for your opera The following list of environment variables are supported by the `docker` command line: -| Variable | Description | -|:------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `DOCKER_API_VERSION` | Override the negotiated API version to use for debugging (e.g. `1.19`) | -| `DOCKER_CERT_PATH` | Location of your authentication keys. This variable is used both by the `docker` CLI and the [`dockerd` daemon](dockerd.md) | -| `DOCKER_CONFIG` | The location of your client configuration files. | -| `DOCKER_CONTENT_TRUST_SERVER` | The URL of the Notary server to use. Defaults to the same URL as the registry. | -| `DOCKER_CONTENT_TRUST` | When set Docker uses notary to sign and verify images. Equates to `--disable-content-trust=false` for build, create, pull, push, run. | -| `DOCKER_CONTEXT` | Name of the `docker context` to use (overrides `DOCKER_HOST` env var and default context set with `docker context use`) | -| `DOCKER_DEFAULT_PLATFORM` | Default platform for commands that take the `--platform` flag. | -| `DOCKER_HIDE_LEGACY_COMMANDS` | When set, Docker hides "legacy" top-level commands (such as `docker rm`, and `docker pull`) in `docker help` output, and only `Management commands` per object-type (e.g., `docker container`) are printed. This may become the default in a future release. | -| `DOCKER_HOST` | Daemon socket to connect to. | -| `DOCKER_TLS` | Enable TLS for connections made by the `docker` CLI (equivalent of the `--tls` command-line option). Set to a non-empty value to enable TLS. Note that TLS is enabled automatically if any of the other TLS options are set. | -| `DOCKER_TLS_VERIFY` | When set Docker uses TLS and verifies the remote. This variable is used both by the `docker` CLI and the [`dockerd` daemon](dockerd.md) | -| `BUILDKIT_PROGRESS` | Set type of progress output (`auto`, `plain`, `tty`) when [building](build.md) with [BuildKit backend](https://docs.docker.com/build/buildkit/). Use plain to show container output (default `auto`). | +| Variable | Description | +| :---------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `DOCKER_API_VERSION` | Override the negotiated API version to use for debugging (e.g. `1.19`) | +| `DOCKER_CERT_PATH` | Location of your authentication keys. This variable is used both by the `docker` CLI and the [`dockerd` daemon](https://docs.docker.com/reference/cli/dockerd/) | +| `DOCKER_CONFIG` | The location of your client configuration files. | +| `DOCKER_CONTENT_TRUST_SERVER` | The URL of the Notary server to use. Defaults to the same URL as the registry. | +| `DOCKER_CONTENT_TRUST` | When set Docker uses notary to sign and verify images. Equates to `--disable-content-trust=false` for build, create, pull, push, run. | +| `DOCKER_CONTEXT` | Name of the `docker context` to use (overrides `DOCKER_HOST` env var and default context set with `docker context use`) | +| `DOCKER_DEFAULT_PLATFORM` | Default platform for commands that take the `--platform` flag. | +| `DOCKER_HIDE_LEGACY_COMMANDS` | When set, Docker hides "legacy" top-level commands (such as `docker rm`, and `docker pull`) in `docker help` output, and only `Management commands` per object-type (e.g., `docker container`) are printed. This may become the default in a future release. | +| `DOCKER_HOST` | Daemon socket to connect to. | +| `DOCKER_TLS` | Enable TLS for connections made by the `docker` CLI (equivalent of the `--tls` command-line option). Set to a non-empty value to enable TLS. Note that TLS is enabled automatically if any of the other TLS options are set. | +| `DOCKER_TLS_VERIFY` | When set Docker uses TLS and verifies the remote. This variable is used both by the `docker` CLI and the [`dockerd` daemon](https://docs.docker.com/reference/cli/dockerd/) | +| `BUILDKIT_PROGRESS` | Set type of progress output (`auto`, `plain`, `tty`, `rawjson`) when [building](https://docs.docker.com/reference/cli/docker/image/build/) with [BuildKit backend](https://docs.docker.com/build/buildkit/). Use plain to show container output (default `auto`). | Because Docker is developed using Go, you can also use any environment variables used by the Go runtime. In particular, you may find these useful: @@ -212,20 +115,20 @@ different location. These fields lets you customize the default output format for some commands if no `--format` flag is provided. -| Property | Description | -| :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `configFormat` | Custom default format for `docker config ls` output. See [`docker config ls`](config_ls.md#format) for a list of supported formatting directives. | -| `imagesFormat` | Custom default format for `docker images` / `docker image ls` output. See [`docker images`](images.md#format) for a list of supported formatting directives. | -| `networksFormat` | Custom default format for `docker network ls` output. See [`docker network ls`](network_ls.md#format) for a list of supported formatting directives. | -| `nodesFormat` | Custom default format for `docker node ls` output. See [`docker node ls`](node_ls.md#format) for a list of supported formatting directives. | -| `pluginsFormat` | Custom default format for `docker plugin ls` output. See [`docker plugin ls`](plugin_ls.md#format) for a list of supported formatting directives. | -| `psFormat` | Custom default format for `docker ps` / `docker container ps` output. See [`docker ps`](ps.md#format) for a list of supported formatting directives. | -| `secretFormat` | Custom default format for `docker secret ls` output. See [`docker secret ls`](secret_ls.md#format) for a list of supported formatting directives. | -| `serviceInspectFormat` | Custom default format for `docker service inspect` output. See [`docker service inspect`](service_inspect.md#format) for a list of supported formatting directives. | -| `servicesFormat` | Custom default format for `docker service ls` output. See [`docker service ls`](service_ls.md#format) for a list of supported formatting directives. | -| `statsFormat` | Custom default format for `docker stats` output. See [`docker stats`](stats.md#format) for a list of supported formatting directives. | -| `tasksFormat` | Custom default format for `docker stack ps` output. See [`docker stack ps`](stack_ps.md#format) for a list of supported formatting directives. | -| `volumesFormat` | Custom default format for `docker volume ls` output. See [`docker volume ls`](volume_ls.md#format) for a list of supported formatting directives. | +| Property | Description | +| :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `configFormat` | Custom default format for `docker config ls` output. See [`docker config ls`](https://docs.docker.com/reference/cli/docker/config/ls/#format) for a list of supported formatting directives. | +| `imagesFormat` | Custom default format for `docker images` / `docker image ls` output. See [`docker images`](https://docs.docker.com/reference/cli/docker/image/ls/#format) for a list of supported formatting directives. | +| `networksFormat` | Custom default format for `docker network ls` output. See [`docker network ls`](https://docs.docker.com/reference/cli/docker/network/ls/#format) for a list of supported formatting directives. | +| `nodesFormat` | Custom default format for `docker node ls` output. See [`docker node ls`](https://docs.docker.com/reference/cli/docker/node/ls/#format) for a list of supported formatting directives. | +| `pluginsFormat` | Custom default format for `docker plugin ls` output. See [`docker plugin ls`](https://docs.docker.com/reference/cli/docker/plugin/ls/#format) for a list of supported formatting directives. | +| `psFormat` | Custom default format for `docker ps` / `docker container ps` output. See [`docker ps`](https://docs.docker.com/reference/cli/docker/container/ls/#format) for a list of supported formatting directives. | +| `secretFormat` | Custom default format for `docker secret ls` output. See [`docker secret ls`](https://docs.docker.com/reference/cli/docker/secret/ls/#format) for a list of supported formatting directives. | +| `serviceInspectFormat` | Custom default format for `docker service inspect` output. See [`docker service inspect`](https://docs.docker.com/reference/cli/docker/service/inspect/#format) for a list of supported formatting directives. | +| `servicesFormat` | Custom default format for `docker service ls` output. See [`docker service ls`](https://docs.docker.com/reference/cli/docker/service/ls/#format) for a list of supported formatting directives. | +| `statsFormat` | Custom default format for `docker stats` output. See [`docker stats`](https://docs.docker.com/reference/cli/docker/container/stats/#format) for a list of supported formatting directives. | +| `tasksFormat` | Custom default format for `docker stack ps` output. See [`docker stack ps`](https://docs.docker.com/reference/cli/docker/stack/ps/#format) for a list of supported formatting directives. | +| `volumesFormat` | Custom default format for `docker volume ls` output. See [`docker volume ls`](https://docs.docker.com/reference/cli/docker/volume/ls/#format) for a list of supported formatting directives. | ### Custom HTTP headers @@ -241,14 +144,14 @@ credential store. When this property is set, `docker login` will attempt to store credentials in the binary specified by `docker-credential-` which is visible on `$PATH`. If this property isn't set, credentials are stored in the `auths` property of the CLI configuration file. For more information, -see the [**Credential stores** section in the `docker login` documentation](login.md#credential-stores) +see the [**Credential stores** section in the `docker login` documentation](https://docs.docker.com/reference/cli/docker/login/#credential-stores) The property `credHelpers` specifies a set of credential helpers to use preferentially over `credsStore` or `auths` when storing and retrieving credentials for specific registries. If this property is set, the binary `docker-credential-` will be used when storing or retrieving credentials for a specific registry. For more information, see the -[**Credential helpers** section in the `docker login` documentation](login.md#credential-helpers) +[**Credential helpers** section in the `docker login` documentation](https://docs.docker.com/reference/cli/docker/login/#credential-helpers) ### Automatic proxy configuration for containers @@ -396,12 +299,12 @@ commands use the following default sockets: - `npipe:////./pipe/docker_engine` on Windows To achieve a similar effect without having to specify the `-H` flag for every -command, you could also [create a context](context_create.md), +command, you could also [create a context](https://docs.docker.com/reference/cli/docker/context/create/), or alternatively, use the [`DOCKER_HOST` environment variable](#environment-variables). For more information about the `-H` flag, see -[Daemon socket option](dockerd.md#daemon-socket-option). +[Daemon socket option](https://docs.docker.com/reference/cli/dockerd/#daemon-socket-option). #### Using TCP sockets diff --git a/docs/reference/commandline/commit.md b/docs/reference/commandline/commit.md index 281d96e488b5..02ae802b30c8 100644 --- a/docs/reference/commandline/commit.md +++ b/docs/reference/commandline/commit.md @@ -14,7 +14,7 @@ Create a new image from a container's changes | `-a`, `--author` | `string` | | Author (e.g., `John Hannibal Smith `) | | `-c`, `--change` | `list` | | Apply Dockerfile instruction to the created image | | `-m`, `--message` | `string` | | Commit message | -| `-p`, `--pause` | | | Pause container during commit | +| `-p`, `--pause` | `bool` | `true` | Pause container during commit | diff --git a/docs/reference/commandline/container_attach.md b/docs/reference/commandline/container_attach.md index a0810305d93e..beb6ab4c80f9 100644 --- a/docs/reference/commandline/container_attach.md +++ b/docs/reference/commandline/container_attach.md @@ -13,7 +13,7 @@ Attach local standard input, output, and error streams to a running container |:--------------------------------|:---------|:--------|:----------------------------------------------------| | [`--detach-keys`](#detach-keys) | `string` | | Override the key sequence for detaching a container | | `--no-stdin` | | | Do not attach STDIN | -| `--sig-proxy` | | | Proxy all received signals to the process | +| `--sig-proxy` | `bool` | `true` | Proxy all received signals to the process | @@ -164,4 +164,4 @@ the following: These `a`, `ctrl-a`, `X`, or `ctrl-\\` values are all examples of valid key sequences. To configure a different configuration default key sequence for all -containers, see [**Configuration file** section](cli.md#configuration-files). +containers, see [**Configuration file** section](https://docs.docker.com/engine/reference/commandline/cli/#configuration-files). diff --git a/docs/reference/commandline/container_commit.md b/docs/reference/commandline/container_commit.md index ff1c458e1a34..c7bad61ee98c 100644 --- a/docs/reference/commandline/container_commit.md +++ b/docs/reference/commandline/container_commit.md @@ -14,7 +14,7 @@ Create a new image from a container's changes | `-a`, `--author` | `string` | | Author (e.g., `John Hannibal Smith `) | | [`-c`](#change), [`--change`](#change) | `list` | | Apply Dockerfile instruction to the created image | | `-m`, `--message` | `string` | | Commit message | -| `-p`, `--pause` | | | Pause container during commit | +| `-p`, `--pause` | `bool` | `true` | Pause container during commit | diff --git a/docs/reference/commandline/container_cp.md b/docs/reference/commandline/container_cp.md index bf3741d8b212..d69683a390e9 100644 --- a/docs/reference/commandline/container_cp.md +++ b/docs/reference/commandline/container_cp.md @@ -112,7 +112,7 @@ $ docker cp CONTAINER:/var/logs/app.log - | tar x -O | grep "ERROR" ### Corner cases It isn't possible to copy certain system files such as resources under -`/proc`, `/sys`, `/dev`, [tmpfs](run.md#tmpfs), and mounts created by +`/proc`, `/sys`, `/dev`, [tmpfs](container_run.md#tmpfs), and mounts created by the user in the container. However, you can still copy such files by manually running `tar` in `docker exec`. Both of the following examples do the same thing in different ways (consider `SRC_PATH` and `DEST_PATH` are directories): diff --git a/docs/reference/commandline/container_create.md b/docs/reference/commandline/container_create.md index 6b598a839834..0ee6e4609b15 100644 --- a/docs/reference/commandline/container_create.md +++ b/docs/reference/commandline/container_create.md @@ -37,7 +37,7 @@ Create a new container | `--device-read-iops` | `list` | | Limit read rate (IO per second) from a device | | `--device-write-bps` | `list` | | Limit write rate (bytes per second) to a device | | `--device-write-iops` | `list` | | Limit write rate (IO per second) to a device | -| `--disable-content-trust` | | | Skip image verification | +| `--disable-content-trust` | `bool` | `true` | Skip image verification | | `--dns` | `list` | | Set custom DNS servers | | `--dns-option` | `list` | | Set DNS options | | `--dns-search` | `list` | | Set custom DNS search domains | @@ -131,8 +131,8 @@ so that it's ready to start when you need it. The initial status of the new container is `created`. The `docker create` command shares most of its options with the `docker run` -command (which performs a `docker create` before starting it). Refer to the -[`docker run` command](run.md) section and the [Docker run reference](../run.md) +command (which performs a `docker create` before starting it). +Refer to the [`docker run` CLI reference](container_run.md) for details on the available flags and options. ## Examples diff --git a/docs/reference/commandline/container_run.md b/docs/reference/commandline/container_run.md index de40a83f3354..a15ace244edd 100644 --- a/docs/reference/commandline/container_run.md +++ b/docs/reference/commandline/container_run.md @@ -39,7 +39,7 @@ Create and run a new container from an image | `--device-read-iops` | `list` | | Limit read rate (IO per second) from a device | | `--device-write-bps` | `list` | | Limit write rate (bytes per second) to a device | | `--device-write-iops` | `list` | | Limit write rate (IO per second) to a device | -| `--disable-content-trust` | | | Skip image verification | +| `--disable-content-trust` | `bool` | `true` | Skip image verification | | `--dns` | `list` | | Set custom DNS servers | | `--dns-option` | `list` | | Set DNS options | | `--dns-search` | `list` | | Set custom DNS search domains | @@ -99,7 +99,7 @@ Create and run a new container from an image | `--runtime` | `string` | | Runtime to use for this container | | [`--security-opt`](#security-opt) | `list` | | Security Options | | `--shm-size` | `bytes` | `0` | Size of /dev/shm | -| `--sig-proxy` | | | Proxy received signals to the process | +| `--sig-proxy` | `bool` | `true` | Proxy received signals to the process | | [`--stop-signal`](#stop-signal) | `string` | | Signal to stop the container | | [`--stop-timeout`](#stop-timeout) | `int` | `0` | Timeout (in seconds) to stop a container | | [`--storage-opt`](#storage-opt) | `list` | | Storage driver options for the container | @@ -787,7 +787,7 @@ the following: These `a`, `ctrl-a`, `X`, or `ctrl-\\` values are all examples of valid key sequences. To configure a different configuration default key sequence for all -containers, see [**Configuration file** section](cli.md#configuration-files). +containers, see [**Configuration file** section](https://docs.docker.com/engine/reference/commandline/cli/#configuration-files). ### Add host device to container (--device) @@ -858,6 +858,38 @@ PS C:\> docker run --device=class/86E0D1E0-8089-11D0-9CE4-08003E301F73 mcr.micro > The `--device` option is only supported on process-isolated Windows containers, > and produces an error if the container isolation is `hyperv`. +#### CDI devices + +> **Note** +> +> This is experimental feature and as such doesn't represent a stable API. + +Container Device Interface (CDI) is a +[standardized](https://github.com/cncf-tags/container-device-interface/blob/main/SPEC.md) +mechanism for container runtimes to create containers which are able to +interact with third party devices. + +With CDI, device configurations are defined using a JSON file. In addition to +enabling the container to interact with the device node, it also lets you +specify additional configuration for the device, such as kernel modules, host +libraries, and environment variables. + +You can reference a CDI device with the `--device` flag using the +fully-qualified name of the device, as shown in the following example: + +```console +$ docker run --device=vendor.com/class=device-name --rm -it ubuntu +``` + +This starts an `ubuntu` container with access to the specified CDI device, +`vendor.com/class=device-name`, assuming that: + +- A valid CDI specification (JSON file) for the requested device is available + on the system running the daemon, in one of the configured CDI specification + directories. +- The CDI feature has been enabled on the daemon side, see [Enable CDI + devices](https://docs.docker.com/reference/cli/dockerd/#enable-cdi-devices). + ### Attach to STDIN/STDOUT/STDERR (-a, --attach) The `--attach` (or `-a`) flag tells `docker run` to bind to the container's @@ -900,7 +932,7 @@ $ cat somefile | docker run -i -a stdin mybuilder dobuild > Linux: it ignores any signal with the default action. So, the process > doesn't terminate on `SIGINT` or `SIGTERM` unless it's coded to do so. -See also [the `docker cp` command](cp.md). +See also [the `docker cp` command](container_cp.md). ### Keep STDIN open (-i, --interactive) @@ -1016,6 +1048,11 @@ the required device when it is added. The `--gpus` flag allows you to access NVIDIA GPU resources. First you need to install the [nvidia-container-runtime](https://nvidia.github.io/nvidia-container-runtime/). +> **Note** +> +> You can also specify a GPU as a CDI device with the `--device` flag, see +> [CDI devices](#cdi-devices). + Read [Specify a container's resources](https://docs.docker.com/config/containers/resource_constraints/) for more information. @@ -1060,8 +1097,8 @@ This runs the `redis` container with a restart policy of **always**. If the container exits, Docker restarts it. When a restart policy is active on a container, it shows as either `Up` or -`Restarting` in [`docker ps`](ps.md). It can also be useful to use [`docker -events`](events.md) to see the restart policy in effect. +`Restarting` in [`docker ps`](container_ls.md). It can also be useful to use +[`docker events`](system_events.md) to see the restart policy in effect. An increasing delay (double the previous delay, starting at 100 milliseconds) is added before each restart to prevent flooding the server. This means the @@ -1092,8 +1129,8 @@ restart limit is only valid for the **on-failure** policy. #### Inspect container restarts The number of (attempted) restarts for a container can be obtained using the -[`docker inspect`](commandline/inspect.md) command. For example, to get the -number of restarts for container "my-container"; +[`docker inspect`](inspect.md) command. For example, to get the number of +restarts for container "my-container"; ```console $ docker inspect -f "{{ .RestartCount }}" my-container @@ -1269,7 +1306,7 @@ container to exit. This signal can be a signal name in the format `SIG`, for instance `SIGKILL`, or an unsigned number that matches a position in the kernel's syscall table, for instance `9`. -The default value is defined by [`STOPSIGNAL`](https://docs.docker.com/engine/reference/builder/#stopsignal) +The default value is defined by [`STOPSIGNAL`](https://docs.docker.com/reference/dockerfile/#stopsignal) in the image, or `SIGTERM` if the image has no `STOPSIGNAL` defined. ### Optional security options (--security-opt) diff --git a/docs/reference/commandline/create.md b/docs/reference/commandline/create.md index ce34f5b12c97..26f462a1c0f8 100644 --- a/docs/reference/commandline/create.md +++ b/docs/reference/commandline/create.md @@ -37,7 +37,7 @@ Create a new container | `--device-read-iops` | `list` | | Limit read rate (IO per second) from a device | | `--device-write-bps` | `list` | | Limit write rate (bytes per second) to a device | | `--device-write-iops` | `list` | | Limit write rate (IO per second) to a device | -| `--disable-content-trust` | | | Skip image verification | +| `--disable-content-trust` | `bool` | `true` | Skip image verification | | `--dns` | `list` | | Set custom DNS servers | | `--dns-option` | `list` | | Set DNS options | | `--dns-search` | `list` | | Set custom DNS search domains | diff --git a/docs/reference/commandline/docker.md b/docs/reference/commandline/docker.md new file mode 100644 index 000000000000..288afdf8abff --- /dev/null +++ b/docs/reference/commandline/docker.md @@ -0,0 +1,86 @@ +# docker + + +The base command for the Docker CLI. + +### Subcommands + +| Name | Description | +|:------------------------------|:------------------------------------------------------------------------------| +| [`attach`](attach.md) | Attach local standard input, output, and error streams to a running container | +| [`build`](build.md) | Build an image from a Dockerfile | +| [`builder`](builder.md) | Manage builds | +| [`checkpoint`](checkpoint.md) | Manage checkpoints | +| [`commit`](commit.md) | Create a new image from a container's changes | +| [`config`](config.md) | Manage Swarm configs | +| [`container`](container.md) | Manage containers | +| [`context`](context.md) | Manage contexts | +| [`cp`](cp.md) | Copy files/folders between a container and the local filesystem | +| [`create`](create.md) | Create a new container | +| [`diff`](diff.md) | Inspect changes to files or directories on a container's filesystem | +| [`events`](events.md) | Get real time events from the server | +| [`exec`](exec.md) | Execute a command in a running container | +| [`export`](export.md) | Export a container's filesystem as a tar archive | +| [`history`](history.md) | Show the history of an image | +| [`image`](image.md) | Manage images | +| [`images`](images.md) | List images | +| [`import`](import.md) | Import the contents from a tarball to create a filesystem image | +| [`info`](info.md) | Display system-wide information | +| [`inspect`](inspect.md) | Return low-level information on Docker objects | +| [`kill`](kill.md) | Kill one or more running containers | +| [`load`](load.md) | Load an image from a tar archive or STDIN | +| [`login`](login.md) | Log in to a registry | +| [`logout`](logout.md) | Log out from a registry | +| [`logs`](logs.md) | Fetch the logs of a container | +| [`manifest`](manifest.md) | Manage Docker image manifests and manifest lists | +| [`network`](network.md) | Manage networks | +| [`node`](node.md) | Manage Swarm nodes | +| [`pause`](pause.md) | Pause all processes within one or more containers | +| [`plugin`](plugin.md) | Manage plugins | +| [`port`](port.md) | List port mappings or a specific mapping for the container | +| [`ps`](ps.md) | List containers | +| [`pull`](pull.md) | Download an image from a registry | +| [`push`](push.md) | Upload an image to a registry | +| [`rename`](rename.md) | Rename a container | +| [`restart`](restart.md) | Restart one or more containers | +| [`rm`](rm.md) | Remove one or more containers | +| [`rmi`](rmi.md) | Remove one or more images | +| [`run`](run.md) | Create and run a new container from an image | +| [`save`](save.md) | Save one or more images to a tar archive (streamed to STDOUT by default) | +| [`search`](search.md) | Search Docker Hub for images | +| [`secret`](secret.md) | Manage Swarm secrets | +| [`service`](service.md) | Manage Swarm services | +| [`stack`](stack.md) | Manage Swarm stacks | +| [`start`](start.md) | Start one or more stopped containers | +| [`stats`](stats.md) | Display a live stream of container(s) resource usage statistics | +| [`stop`](stop.md) | Stop one or more running containers | +| [`swarm`](swarm.md) | Manage Swarm | +| [`system`](system.md) | Manage Docker | +| [`tag`](tag.md) | Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE | +| [`top`](top.md) | Display the running processes of a container | +| [`trust`](trust.md) | Manage trust on Docker images | +| [`unpause`](unpause.md) | Unpause all processes within one or more containers | +| [`update`](update.md) | Update configuration of one or more containers | +| [`version`](version.md) | Show the Docker version information | +| [`volume`](volume.md) | Manage volumes | +| [`wait`](wait.md) | Block until one or more containers stop, then print their exit codes | + + +### Options + +| Name | Type | Default | Description | +|:--------------------|:---------|:-------------------------|:--------------------------------------------------------------------------------------------------------------------------------------| +| `--config` | `string` | `/root/.docker` | Location of client config files | +| `-c`, `--context` | `string` | | Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with `docker context use`) | +| `-D`, `--debug` | | | Enable debug mode | +| `-H`, `--host` | `list` | | Daemon socket to connect to | +| `-l`, `--log-level` | `string` | `info` | Set the logging level (`debug`, `info`, `warn`, `error`, `fatal`) | +| `--tls` | | | Use TLS; implied by --tlsverify | +| `--tlscacert` | `string` | `/root/.docker/ca.pem` | Trust certs signed only by this CA | +| `--tlscert` | `string` | `/root/.docker/cert.pem` | Path to TLS certificate file | +| `--tlskey` | `string` | `/root/.docker/key.pem` | Path to TLS key file | +| `--tlsverify` | | | Use TLS and verify the remote | + + + + diff --git a/docs/reference/commandline/history.md b/docs/reference/commandline/history.md index 7ffc95033523..15a02e9092b5 100644 --- a/docs/reference/commandline/history.md +++ b/docs/reference/commandline/history.md @@ -12,7 +12,7 @@ Show the history of an image | Name | Type | Default | Description | |:----------------|:---------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `--format` | `string` | | Format output using a custom template:
'table': Print output in table format with column headers (default)
'table TEMPLATE': Print output in table format using the given Go template
'json': Print in JSON format
'TEMPLATE': Print output using the given Go template.
Refer to https://docs.docker.com/go/formatting/ for more information about formatting output with templates | -| `-H`, `--human` | | | Print sizes and dates in human readable format | +| `-H`, `--human` | `bool` | `true` | Print sizes and dates in human readable format | | `--no-trunc` | | | Don't truncate output | | `-q`, `--quiet` | | | Only show image IDs | diff --git a/docs/reference/commandline/image_build.md b/docs/reference/commandline/image_build.md index 61f7f384a948..af78159e6a4c 100644 --- a/docs/reference/commandline/image_build.md +++ b/docs/reference/commandline/image_build.md @@ -21,7 +21,7 @@ Build an image from a Dockerfile | `-c`, `--cpu-shares` | `int64` | `0` | CPU shares (relative weight) | | `--cpuset-cpus` | `string` | | CPUs in which to allow execution (0-3, 0,1) | | `--cpuset-mems` | `string` | | MEMs in which to allow execution (0-3, 0,1) | -| `--disable-content-trust` | | | Skip image verification | +| `--disable-content-trust` | `bool` | `true` | Skip image verification | | [`-f`](#file), [`--file`](#file) | `string` | | Name of the Dockerfile (Default is `PATH/Dockerfile`) | | `--force-rm` | | | Always remove intermediate containers | | `--iidfile` | `string` | | Write the image ID to the file | @@ -34,7 +34,7 @@ Build an image from a Dockerfile | `--platform` | `string` | | Set platform if server is multi-platform capable | | `--pull` | | | Always attempt to pull a newer version of the image | | `-q`, `--quiet` | | | Suppress the build output and print image ID on success | -| `--rm` | | | Remove intermediate containers after a successful build | +| `--rm` | `bool` | `true` | Remove intermediate containers after a successful build | | [`--security-opt`](#security-opt) | `stringSlice` | | Security options | | `--shm-size` | `bytes` | `0` | Size of `/dev/shm` | | [`--squash`](#squash) | | | Squash newly built layers into a single new layer | @@ -50,7 +50,7 @@ Build an image from a Dockerfile The `docker build` command builds Docker images from a Dockerfile and a "context". A build's context is the set of files located in the specified `PATH` or `URL`. The build process can refer to any of the files in the -context. For example, your build can use a [*COPY*](https://docs.docker.com/engine/reference/builder/#copy) +context. For example, your build can use a [*COPY*](https://docs.docker.com/reference/dockerfile/#copy) instruction to reference a file in the context. The `URL` parameter can refer to three kinds of resources: Git repositories, @@ -144,7 +144,7 @@ In most cases, it's best to put each Dockerfile in an empty directory. Then, add to that directory only the files needed for building the Dockerfile. To increase the build's performance, you can exclude files and directories by adding a `.dockerignore` file to that directory as well. For information on -creating one, see the [.dockerignore file](https://docs.docker.com/engine/reference/builder/#dockerignore-file). +creating one, see the [.dockerignore file](https://docs.docker.com/reference/dockerfile/#dockerignore-file). If the Docker client loses connection to the daemon, it cancels the build. This happens if you interrupt the Docker client with `CTRL-c` or if the Docker @@ -172,7 +172,7 @@ $ echo $? See also: -[*Dockerfile Reference*](https://docs.docker.com/engine/reference/builder/). +[*Dockerfile Reference*](https://docs.docker.com/reference/dockerfile/). ## Examples @@ -213,7 +213,7 @@ where to find the files for the "context" of the build on the Docker daemon. Remember that the daemon could be running on a remote machine and that no parsing of the Dockerfile happens at the client side (where you're running `docker build`). That means that all the files at `PATH` are sent, not just -the ones listed to [`ADD`](https://docs.docker.com/engine/reference/builder/#add) +the ones listed to [`ADD`](https://docs.docker.com/reference/dockerfile/#add) in the Dockerfile. The transfer of context from the local machine to the Docker daemon is what the @@ -302,7 +302,7 @@ Successfully built 99cc1ad10469 This example shows the use of the `.dockerignore` file to exclude the `.git` directory from the context. You can see its effect in the changed size of the uploaded context. The builder reference contains detailed information on -[creating a .dockerignore file](https://docs.docker.com/engine/reference/builder/#dockerignore-file). +[creating a .dockerignore file](https://docs.docker.com/reference/dockerfile/#dockerignore-file). When using the [BuildKit backend](https://docs.docker.com/build/buildkit/), `docker build` searches for a `.dockerignore` file relative to the Dockerfile @@ -321,7 +321,7 @@ $ docker build -t vieux/apache:2.0 . This examples builds in the same way as the previous example, but it then tags the resulting image. The repository name will be `vieux/apache` and the tag `2.0`. -[Read more about valid tags](tag.md). +[Read more about valid tags](image_tag.md). You can apply multiple tags to an image. For example, you can apply the `latest` tag to a newly built image and add another tag that references a specific @@ -384,12 +384,12 @@ the command line. ### Use a custom parent cgroup (--cgroup-parent) When you run `docker build` with the `--cgroup-parent` option, the daemon runs the containers -used in the build with the [corresponding `docker run` flag](../run.md#specify-custom-cgroups). +used in the build with the [corresponding `docker run` flag](container_run.md#cgroup-parent). ### Set ulimits in container (--ulimit) Using the `--ulimit` option with `docker build` causes the daemon to start each build step's -container using those [`--ulimit` flag values](run.md#ulimit). +container using those [`--ulimit` flag values](container_run.md#ulimit). ### Set build-time variables (--build-arg) @@ -415,7 +415,7 @@ Using this flag doesn't alter the output you see when the build process echoes t Dockerfile. For detailed information on using `ARG` and `ENV` instructions, see the -[Dockerfile reference](https://docs.docker.com/engine/reference/builder/). +[Dockerfile reference](https://docs.docker.com/reference/dockerfile/). You can also use the `--build-arg` flag without a value, in which case the daemon propagates the value from the local environment into the Docker container it's building: @@ -425,7 +425,7 @@ $ export HTTP_PROXY=http://10.20.30.2:1234 $ docker build --build-arg HTTP_PROXY . ``` -This example is similar to how `docker run -e` works. Refer to the [`docker run` documentation](run.md#env) +This example is similar to how `docker run -e` works. Refer to the [`docker run` documentation](container_run.md#env) for more information. ### Optional security options (--security-opt) @@ -553,7 +553,7 @@ $ docker build -o - . > out.tar The `--output` option exports all files from the target stage. A common pattern for exporting only specific files is to do multi-stage builds and to copy the -desired files to a new scratch stage with [`COPY --from`](https://docs.docker.com/engine/reference/builder/#copy). +desired files to a new scratch stage with [`COPY --from`](https://docs.docker.com/reference/dockerfile/#copy). The example, the `Dockerfile` below uses a separate stage to collect the build artifacts for exporting: @@ -642,7 +642,7 @@ Available options for the networking mode are: - `none`: Run with no network access. - `host`: Run in the host’s network environment. -Find more details in the [Dockerfile documentation](https://docs.docker.com/engine/reference/builder/#run---network). +Find more details in the [Dockerfile documentation](https://docs.docker.com/reference/dockerfile/#run---network). ### Squash an image's layers (--squash) (experimental) diff --git a/docs/reference/commandline/image_history.md b/docs/reference/commandline/image_history.md index a120d3e110d9..5b8ad00600e1 100644 --- a/docs/reference/commandline/image_history.md +++ b/docs/reference/commandline/image_history.md @@ -12,7 +12,7 @@ Show the history of an image | Name | Type | Default | Description | |:----------------------|:---------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | [`--format`](#format) | `string` | | Format output using a custom template:
'table': Print output in table format with column headers (default)
'table TEMPLATE': Print output in table format using the given Go template
'json': Print in JSON format
'TEMPLATE': Print output using the given Go template.
Refer to https://docs.docker.com/go/formatting/ for more information about formatting output with templates | -| `-H`, `--human` | | | Print sizes and dates in human readable format | +| `-H`, `--human` | `bool` | `true` | Print sizes and dates in human readable format | | `--no-trunc` | | | Don't truncate output | | `-q`, `--quiet` | | | Only show image IDs | diff --git a/docs/reference/commandline/image_pull.md b/docs/reference/commandline/image_pull.md index ada165558c2f..8333dd3e8196 100644 --- a/docs/reference/commandline/image_pull.md +++ b/docs/reference/commandline/image_pull.md @@ -12,7 +12,7 @@ Download an image from a registry | Name | Type | Default | Description | |:---------------------------------------------|:---------|:--------|:-------------------------------------------------| | [`-a`](#all-tags), [`--all-tags`](#all-tags) | | | Download all tagged images in the repository | -| `--disable-content-trust` | | | Skip image verification | +| `--disable-content-trust` | `bool` | `true` | Skip image verification | | `--platform` | `string` | | Set platform if server is multi-platform capable | | `-q`, `--quiet` | | | Suppress verbose output | @@ -34,7 +34,7 @@ use `docker pull`. If you are behind an HTTP proxy server, for example in corporate settings, before open a connect to registry, you may need to configure the Docker -daemon's proxy settings, refer to the [dockerd command-line reference](dockerd.md#proxy-configuration) +daemon's proxy settings, refer to the [dockerd command-line reference](https://docs.docker.com/reference/cli/dockerd/#proxy-configuration) for details. ### Concurrent downloads @@ -42,7 +42,7 @@ for details. By default the Docker daemon will pull three layers of an image at a time. If you are on a low bandwidth connection this may cause timeout issues and you may want to lower this via the `--max-concurrent-downloads` daemon option. See the -[daemon documentation](dockerd.md) for more details. +[daemon documentation](https://docs.docker.com/reference/cli/dockerd/) for more details. ## Examples @@ -81,7 +81,7 @@ Status: Downloaded newer image for debian:bookworm docker.io/library/debian:bookworm ``` -To see which images are present locally, use the [`docker images`](images.md) +To see which images are present locally, use the [`docker images`](image_ls.md) command: ```console @@ -184,7 +184,7 @@ Registry credentials are managed by [docker login](login.md). Docker uses the `https://` protocol to communicate with a registry, unless the registry is allowed to be accessed over an insecure connection. Refer to the -[insecure registries](dockerd.md#insecure-registries) section for more information. +[insecure registries](https://docs.docker.com/reference/cli/dockerd/#insecure-registries) section for more information. ### Pull a repository with multiple images (-a, --all-tags) diff --git a/docs/reference/commandline/image_push.md b/docs/reference/commandline/image_push.md index a2c83dbe1000..283694e73eff 100644 --- a/docs/reference/commandline/image_push.md +++ b/docs/reference/commandline/image_push.md @@ -9,11 +9,11 @@ Upload an image to a registry ### Options -| Name | Type | Default | Description | -|:---------------------------------------------|:-----|:--------|:--------------------------------------------| -| [`-a`](#all-tags), [`--all-tags`](#all-tags) | | | Push all tags of an image to the repository | -| `--disable-content-trust` | | | Skip image signing | -| `-q`, `--quiet` | | | Suppress verbose output | +| Name | Type | Default | Description | +|:---------------------------------------------|:-------|:--------|:--------------------------------------------| +| [`-a`](#all-tags), [`--all-tags`](#all-tags) | | | Push all tags of an image to the repository | +| `--disable-content-trust` | `bool` | `true` | Skip image signing | +| `-q`, `--quiet` | | | Suppress verbose output | @@ -23,8 +23,8 @@ Upload an image to a registry Use `docker image push` to share your images to the [Docker Hub](https://hub.docker.com) registry or to a self-hosted one. -Refer to the [`docker image tag`](tag.md) reference for more information about valid -image and tag names. +Refer to the [`docker image tag`](image_tag.md) reference for more information +about valid image and tag names. Killing the `docker image push` process, for example by pressing `CTRL-c` while it is running in a terminal, terminates the push operation. @@ -40,15 +40,15 @@ Registry credentials are managed by [docker login](login.md). By default the Docker daemon will push five layers of an image at a time. If you are on a low bandwidth connection this may cause timeout issues and you may want to lower this via the `--max-concurrent-uploads` daemon option. See the -[daemon documentation](dockerd.md) for more details. +[daemon documentation](https://docs.docker.com/reference/cli/dockerd/) for more details. ## Examples ### Push a new image to a registry -First save the new image by finding the container ID (using [`docker container ls`](ps.md)) -and then committing it to a new image name. Note that only `a-z0-9-_.` are -allowed when naming images: +First save the new image by finding the container ID (using [`docker container +ls`](container_ls.md)) and then committing it to a new image name. Note that +only `a-z0-9-_.` are allowed when naming images: ```console $ docker container commit c16378f943fe rhel-httpd:latest diff --git a/docs/reference/commandline/image_rm.md b/docs/reference/commandline/image_rm.md index 5fd35e993183..f3b303da0b69 100644 --- a/docs/reference/commandline/image_rm.md +++ b/docs/reference/commandline/image_rm.md @@ -26,7 +26,7 @@ removed. This does not remove images from a registry. You cannot remove an image of a running container unless you use the `-f` option. To see all images on a host -use the [`docker image ls`](images.md) command. +use the [`docker image ls`](image_ls.md) command. ## Examples diff --git a/docs/reference/commandline/image_tag.md b/docs/reference/commandline/image_tag.md index d9359f62ef9d..5e6c5626bc1e 100644 --- a/docs/reference/commandline/image_tag.md +++ b/docs/reference/commandline/image_tag.md @@ -43,8 +43,7 @@ underscores, periods, and hyphens. It can't start with a period or hyphen and must be no longer than 128 characters. If you don't specify a tag, the command uses `latest` by default. You can group your images together using names and tags, and then -[push](https://docs.docker.com/engine/reference/commandline/push) them to a -registry. +[push](image_push.md) them to a registry. ## Examples diff --git a/docs/reference/commandline/index.md b/docs/reference/commandline/index.md index 2be6c2e16027..7e20fd060802 100644 --- a/docs/reference/commandline/index.md +++ b/docs/reference/commandline/index.md @@ -10,11 +10,11 @@ identifier: "smn_cli_guide" This section contains reference information on using Docker's command line client. Each command has a reference page along with samples. If you are unfamiliar with the command line, you should start by reading about how to [Use -the Docker command line](cli.md). +the Docker command line](https://docs.docker.com/engine/reference/commandline/cli/). You start the Docker daemon with the command line. How you start the daemon affects your Docker containers. For that reason you should also make sure to -read the [`dockerd`](dockerd.md) reference page. +read the [`dockerd`](https://docs.docker.com/reference/cli/dockerd/) reference page. ## Commands by object @@ -22,7 +22,7 @@ read the [`dockerd`](dockerd.md) reference page. | Command | Description | | :-------------------------------- | :--------------------------------------------------- | -| [dockerd](dockerd.md) | Launch the Docker daemon | +| [dockerd](../dockerd.md) | Launch the Docker daemon | | [inspect](inspect.md) | Return low-level information on a container or image | | [system events](system_events.md) | Get real-time events from the server | | [system info](system_info.md) | Display system-wide information | diff --git a/docs/reference/commandline/node_ls.md b/docs/reference/commandline/node_ls.md index adb9a4ed5cb5..823e85994f33 100644 --- a/docs/reference/commandline/node_ls.md +++ b/docs/reference/commandline/node_ls.md @@ -78,7 +78,7 @@ ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS The `label` filter matches nodes based on engine labels and on the presence of a `label` alone or a `label` and a value. Engine labels are configured in -the [daemon configuration](dockerd.md#daemon-configuration-file). To filter on +the [daemon configuration](https://docs.docker.com/reference/cli/dockerd/#daemon-configuration-file). To filter on Swarm `node` labels, use [`node.label` instead](#nodelabel). The following filter matches nodes with the `foo` label regardless of its value. diff --git a/docs/reference/commandline/node_update.md b/docs/reference/commandline/node_update.md index 14d051fc380a..1138ddb5aa22 100644 --- a/docs/reference/commandline/node_update.md +++ b/docs/reference/commandline/node_update.md @@ -56,7 +56,7 @@ $ docker node update --label-add type=queue worker1 The labels you set for nodes using `docker node update` apply only to the node entity within the swarm. Do not confuse them with the docker daemon labels for -[dockerd](dockerd.md). +[dockerd](https://docs.docker.com/reference/cli/dockerd/). For more information about labels, refer to [apply custom metadata](https://docs.docker.com/engine/userguide/labels-custom-metadata/). diff --git a/docs/reference/commandline/plugin_create.md b/docs/reference/commandline/plugin_create.md index 7024fb1c55e8..ff1023406ea1 100644 --- a/docs/reference/commandline/plugin_create.md +++ b/docs/reference/commandline/plugin_create.md @@ -15,7 +15,7 @@ Create a plugin from a rootfs and configuration. Plugin data directory must cont ## Description Creates a plugin. Before creating the plugin, prepare the plugin's root -filesystem as well as the [config.json](../../extend/config.md). +filesystem as well as the [config.json](https://docs.docker.com/engine/extend/config/). ## Examples diff --git a/docs/reference/commandline/plugin_inspect.md b/docs/reference/commandline/plugin_inspect.md index 73906ed6388d..d3b10c8a1ea8 100644 --- a/docs/reference/commandline/plugin_inspect.md +++ b/docs/reference/commandline/plugin_inspect.md @@ -21,7 +21,7 @@ in a JSON array. ### Inspect a plugin -The following example example inspects the `tiborvass/sample-volume-plugin` plugin: +The following example inspects the `tiborvass/sample-volume-plugin` plugin: ```console $ docker plugin inspect tiborvass/sample-volume-plugin:latest diff --git a/docs/reference/commandline/plugin_install.md b/docs/reference/commandline/plugin_install.md index c52e444b0cfa..22c3bf2c7cb0 100644 --- a/docs/reference/commandline/plugin_install.md +++ b/docs/reference/commandline/plugin_install.md @@ -9,7 +9,7 @@ Install a plugin |:--------------------------|:---------|:--------|:--------------------------------------------------| | `--alias` | `string` | | Local name for plugin | | `--disable` | | | Do not enable the plugin on install | -| `--disable-content-trust` | | | Skip image verification | +| `--disable-content-trust` | `bool` | `true` | Skip image verification | | `--grant-all-permissions` | | | Grant all permissions necessary to run the plugin | diff --git a/docs/reference/commandline/plugin_push.md b/docs/reference/commandline/plugin_push.md index 4ad1dbf6c022..3fcfe47f6f2c 100644 --- a/docs/reference/commandline/plugin_push.md +++ b/docs/reference/commandline/plugin_push.md @@ -5,9 +5,9 @@ Push a plugin to a registry ### Options -| Name | Type | Default | Description | -|:--------------------------|:-----|:--------|:-------------------| -| `--disable-content-trust` | | | Skip image signing | +| Name | Type | Default | Description | +|:--------------------------|:-------|:--------|:-------------------| +| `--disable-content-trust` | `bool` | `true` | Skip image signing | diff --git a/docs/reference/commandline/plugin_upgrade.md b/docs/reference/commandline/plugin_upgrade.md index dfa8b22d46c0..c0147c86fdf4 100644 --- a/docs/reference/commandline/plugin_upgrade.md +++ b/docs/reference/commandline/plugin_upgrade.md @@ -5,11 +5,11 @@ Upgrade an existing plugin ### Options -| Name | Type | Default | Description | -|:--------------------------|:-----|:--------|:----------------------------------------------------------------------| -| `--disable-content-trust` | | | Skip image verification | -| `--grant-all-permissions` | | | Grant all permissions necessary to run the plugin | -| `--skip-remote-check` | | | Do not check if specified remote plugin matches existing plugin image | +| Name | Type | Default | Description | +|:--------------------------|:-------|:--------|:----------------------------------------------------------------------| +| `--disable-content-trust` | `bool` | `true` | Skip image verification | +| `--grant-all-permissions` | | | Grant all permissions necessary to run the plugin | +| `--skip-remote-check` | | | Do not check if specified remote plugin matches existing plugin image | diff --git a/docs/reference/commandline/pull.md b/docs/reference/commandline/pull.md index 9ea408dbff21..f100262fefba 100644 --- a/docs/reference/commandline/pull.md +++ b/docs/reference/commandline/pull.md @@ -12,7 +12,7 @@ Download an image from a registry | Name | Type | Default | Description | |:--------------------------|:---------|:--------|:-------------------------------------------------| | `-a`, `--all-tags` | | | Download all tagged images in the repository | -| `--disable-content-trust` | | | Skip image verification | +| `--disable-content-trust` | `bool` | `true` | Skip image verification | | `--platform` | `string` | | Set platform if server is multi-platform capable | | `-q`, `--quiet` | | | Suppress verbose output | diff --git a/docs/reference/commandline/push.md b/docs/reference/commandline/push.md index 16e9c1924629..dd93983d6018 100644 --- a/docs/reference/commandline/push.md +++ b/docs/reference/commandline/push.md @@ -9,11 +9,11 @@ Upload an image to a registry ### Options -| Name | Type | Default | Description | -|:--------------------------|:-----|:--------|:--------------------------------------------| -| `-a`, `--all-tags` | | | Push all tags of an image to the repository | -| `--disable-content-trust` | | | Skip image signing | -| `-q`, `--quiet` | | | Suppress verbose output | +| Name | Type | Default | Description | +|:--------------------------|:-------|:--------|:--------------------------------------------| +| `-a`, `--all-tags` | | | Push all tags of an image to the repository | +| `--disable-content-trust` | `bool` | `true` | Skip image signing | +| `-q`, `--quiet` | | | Suppress verbose output | diff --git a/docs/reference/commandline/run.md b/docs/reference/commandline/run.md index f4a72ba7bfee..b7a2d80dd73e 100644 --- a/docs/reference/commandline/run.md +++ b/docs/reference/commandline/run.md @@ -39,7 +39,7 @@ Create and run a new container from an image | `--device-read-iops` | `list` | | Limit read rate (IO per second) from a device | | `--device-write-bps` | `list` | | Limit write rate (bytes per second) to a device | | `--device-write-iops` | `list` | | Limit write rate (IO per second) to a device | -| `--disable-content-trust` | | | Skip image verification | +| `--disable-content-trust` | `bool` | `true` | Skip image verification | | `--dns` | `list` | | Set custom DNS servers | | `--dns-option` | `list` | | Set DNS options | | `--dns-search` | `list` | | Set custom DNS search domains | @@ -99,7 +99,7 @@ Create and run a new container from an image | `--runtime` | `string` | | Runtime to use for this container | | `--security-opt` | `list` | | Security Options | | `--shm-size` | `bytes` | `0` | Size of /dev/shm | -| `--sig-proxy` | | | Proxy received signals to the process | +| `--sig-proxy` | `bool` | `true` | Proxy received signals to the process | | `--stop-signal` | `string` | | Signal to stop the container | | `--stop-timeout` | `int` | `0` | Timeout (in seconds) to stop a container | | `--storage-opt` | `list` | | Storage driver options for the container | diff --git a/docs/reference/commandline/service_create.md b/docs/reference/commandline/service_create.md index 496957b9a9c7..32d274694e0e 100644 --- a/docs/reference/commandline/service_create.md +++ b/docs/reference/commandline/service_create.md @@ -349,7 +349,7 @@ volumes in a service:

The type of mount, can be either volume, bind, tmpfs, or npipe. Defaults to volume if no type is specified.

    -
  • volume: mounts a managed volume +
  • volume: mounts a managed volume into the container.
  • bind: bind-mounts a directory or file from the host into the container.
  • tmpfs: mount a tmpfs in the container
  • diff --git a/docs/reference/commandline/system_info.md b/docs/reference/commandline/system_info.md index 48fb3597d513..2d142ab16cb4 100644 --- a/docs/reference/commandline/system_info.md +++ b/docs/reference/commandline/system_info.md @@ -47,17 +47,17 @@ information about the `overlay2` storage driver is shown: ```console $ docker info -Client: Docker Engine - Community - Version: 24.0.0 +Client: + Version: 25.0.0 Context: default Debug Mode: false Plugins: buildx: Docker Buildx (Docker Inc.) - Version: v0.10.4 - Path: /usr/libexec/docker/cli-plugins/docker-buildx + Version: v0.12.1 + Path: /usr/local/libexec/docker/cli-plugins/docker-buildx compose: Docker Compose (Docker Inc.) - Version: v2.17.2 - Path: /usr/libexec/docker/cli-plugins/docker-compose + Version: v2.24.1 + Path: /usr/local/libexec/docker/cli-plugins/docker-compose Server: Containers: 14 @@ -65,15 +65,11 @@ Server: Paused: 1 Stopped: 10 Images: 52 - Server Version: 23.0.3 - Storage Driver: overlay2 - Backing Filesystem: extfs - Supports d_type: true - Using metacopy: false - Native Overlay Diff: true - userxattr: false + Server Version: 25.0.0 + Storage Driver: overlayfs + driver-type: io.containerd.snapshotter.v1 Logging Driver: json-file - Cgroup Driver: systemd + Cgroup Driver: cgroupfs Cgroup Version: 2 Plugins: Volume: local @@ -83,33 +79,31 @@ Server: /etc/cdi /var/run/cdi Swarm: inactive - Runtimes: io.containerd.runc.v2 runc + Runtimes: runc io.containerd.runc.v2 Default Runtime: runc Init Binary: docker-init - containerd version: 2806fc1057397dbaeefbea0e4e17bddfbd388f38 - runc version: v1.1.5-0-gf19387a + containerd version: 71909c1814c544ac47ab91d2e8b84718e517bb99 + runc version: v1.1.11-0-g4bccb38 init version: de40ad0 Security Options: - apparmor seccomp Profile: builtin cgroupns - Kernel Version: 5.15.0-25-generic - Operating System: Ubuntu 22.04 LTS + Kernel Version: 6.5.11-linuxkit + Operating System: Alpine Linux v3.19 OSType: linux - Architecture: x86_64 - CPUs: 1 - Total Memory: 991.7 MiB - Name: ip-172-30-0-91.ec2.internal - ID: 4cee4408-10d2-4e17-891c-a41736ac4536 + Architecture: aarch64 + CPUs: 10 + Total Memory: 7.663GiB + Name: 4a7ed206a70d + ID: c20f7230-59a2-4824-a2f4-fda71c982ee6 Docker Root Dir: /var/lib/docker Debug Mode: false - Username: gordontheturtle Experimental: false Insecure Registries: - myinsecurehost:5000 127.0.0.0/8 Live Restore Enabled: false + Product License: Community Engine ``` ### Format the output (--format) diff --git a/docs/reference/commandline/dockerd.md b/docs/reference/dockerd.md similarity index 93% rename from docs/reference/commandline/dockerd.md rename to docs/reference/dockerd.md index d4e59ac1f051..9496c093a28f 100644 --- a/docs/reference/commandline/dockerd.md +++ b/docs/reference/dockerd.md @@ -29,6 +29,7 @@ Options: --authorization-plugin list Authorization plugins to load --bip string Specify network bridge IP -b, --bridge string Attach containers to a network bridge + --cdi-spec-dir list CDI specification directories to use --cgroup-parent string Set parent cgroup for all containers --config-file string Daemon configuration file (default "/etc/docker/daemon.json") --containerd string containerd grpc address @@ -78,6 +79,7 @@ Options: --label list Set key=value labels to the daemon --live-restore Enable live restore of docker when containers are still running --log-driver string Default driver for container logs (default "json-file") + --log-format string Set the logging format ("text"|"json") (default "text") -l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info") --log-opt map Default log driver options for containers (default map[]) --max-concurrent-downloads int Set the max concurrent downloads (default 3) @@ -132,21 +134,21 @@ to [the `daemon.json` file](#daemon-configuration-file). The following list of environment variables are supported by the `dockerd` daemon. Some of these environment variables are supported both by the Docker Daemon and -the `docker` CLI. Refer to [Environment variables](cli.md#environment-variables) +the `docker` CLI. Refer to [Environment variables](https://docs.docker.com/engine/reference/commandline/cli/#environment-variables) in the CLI section to learn about environment variables supported by the `docker` CLI. -| Variable | Description | -|:--------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `DOCKER_CERT_PATH` | Location of your authentication keys. This variable is used both by the [`docker` CLI](cli.md) and the `dockerd` daemon. | -| `DOCKER_DRIVER` | The storage driver to use. | -| `DOCKER_RAMDISK` | If set this disables `pivot_root`. | -| `DOCKER_TLS_VERIFY` | When set Docker uses TLS and verifies the remote. This variable is used both by the [`docker` CLI](cli.md) and the `dockerd` daemon. | -| `DOCKER_TMPDIR` | Location for temporary files created by the daemon. | -| `HTTP_PROXY` | Proxy URL for HTTP requests unless overridden by NoProxy. See the [Go specification](https://pkg.go.dev/golang.org/x/net/http/httpproxy#Config) for details. | -| `HTTPS_PROXY` | Proxy URL for HTTPS requests unless overridden by NoProxy. See the [Go specification](https://pkg.go.dev/golang.org/x/net/http/httpproxy#Config) for details. | -| `MOBY_DISABLE_PIGZ` | Disables the use of [`unpigz`](https://linux.die.net/man/1/pigz) to decompress layers in parallel when pulling images, even if it is installed. | -| `NO_PROXY` | Comma-separated values specifying hosts that should be excluded from proxying. See the [Go specification](https://pkg.go.dev/golang.org/x/net/http/httpproxy#Config) for details. | +| Variable | Description | +| :------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `DOCKER_CERT_PATH` | Location of your authentication keys. This variable is used both by the [`docker` CLI](https://docs.docker.com/engine/reference/commandline/cli/) and the `dockerd` daemon. | +| `DOCKER_DRIVER` | The storage driver to use. | +| `DOCKER_RAMDISK` | If set this disables `pivot_root`. | +| `DOCKER_TLS_VERIFY` | When set Docker uses TLS and verifies the remote. This variable is used both by the [`docker` CLI](https://docs.docker.com/engine/reference/commandline/cli/) and the `dockerd` daemon. | +| `DOCKER_TMPDIR` | Location for temporary files created by the daemon. | +| `HTTP_PROXY` | Proxy URL for HTTP requests unless overridden by NoProxy. See the [Go specification](https://pkg.go.dev/golang.org/x/net/http/httpproxy#Config) for details. | +| `HTTPS_PROXY` | Proxy URL for HTTPS requests unless overridden by NoProxy. See the [Go specification](https://pkg.go.dev/golang.org/x/net/http/httpproxy#Config) for details. | +| `MOBY_DISABLE_PIGZ` | Disables the use of [`unpigz`](https://linux.die.net/man/1/pigz) to decompress layers in parallel when pulling images, even if it is installed. | +| `NO_PROXY` | Comma-separated values specifying hosts that should be excluded from proxying. See the [Go specification](https://pkg.go.dev/golang.org/x/net/http/httpproxy#Config) for details. | ## Examples @@ -794,7 +796,7 @@ Any `--ulimit` options passed to `docker run` override the daemon defaults. Be careful setting `nproc` with the `ulimit` flag, as `nproc` is designed by Linux to set the maximum number of processes available to a user, not to a container. -For details, see [`docker run` reference](run.md#ulimit). +For details, see [`docker run` reference](https://docs.docker.com/reference/cli/docker/container/run/#ulimit). ### Access authorization @@ -818,7 +820,7 @@ If you have multiple plugins installed, each plugin, in order, must allow the request for it to complete. For information about how to create an authorization plugin, refer to the -[authorization plugin](../../extend/plugins_authorization.md) section. +[authorization plugin](https://docs.docker.com/engine/extend/plugins_authorization/) section. ### Daemon user namespace options @@ -848,12 +850,79 @@ flag for the dockerd command line interface, or the `host-gateway-ip` key in the daemon configuration file. ```console -$ dockerd --host-gateway-ip 192.0.2.0 +$ cat > /etc/docker/daemon.json +{ "host-gateway-ip": "192.0.2.0" } +$ sudo systemctl restart docker $ docker run -it --add-host host.docker.internal:host-gateway \ busybox ping host.docker.internal PING host.docker.internal (192.0.2.0): 56 data bytes ``` +### Enable CDI devices + +> **Note** +> +> This is experimental feature and as such doesn't represent a stable API. +> +> This feature isn't enabled by default. To this feature, set `features.cdi` to +> `true` in the `daemon.json` configuration file. + +Container Device Interface (CDI) is a +[standardized](https://github.com/cncf-tags/container-device-interface/blob/main/SPEC.md) +mechanism for container runtimes to create containers which are able to +interact with third party devices. + +The Docker daemon supports running containers with CDI devices if the requested +device specifications are available on the filesystem of the daemon. + +The default specification directors are: + +- `/etc/cdi/` for static CDI Specs +- `/var/run/cdi` for generated CDI Specs + +Alternatively, you can set custom locations for CDI specifications using the +`cdi-spec-dirs` option in the `daemon.json` configuration file, or the +`--cdi-spec-dir` flag for the `dockerd` CLI. + +```json +{ + "features": { + "cdi": true + }, + "cdi-spec-dirs": ["/etc/cdi/", "/var/run/cdi"] +} +``` + +When CDI is enabled for a daemon, you can view the configured CDI specification +directories using the `docker info` command. + +#### Daemon logging format + +The `--log-format` option or "log-format" option in the [daemon configuration file](#daemon-configuration-file) +lets you set the format for logs produced by the daemon. The logging format should +only be configured either through the `--log-format` command line option or +through the "log-format" field in the configuration file; using both +the command-line option and the "log-format" field in the configuration +file produces an error. If this option is not set, the default is "text". + +The following example configures the daemon through the `--log-format` command +line option to use `json` formatted logs; + +```console +$ dockerd --log-format=json +# ... +{"level":"info","msg":"API listen on /var/run/docker.sock","time":"2024-09-16T11:06:08.558145428Z"} +``` + +The following example shows a `daemon.json` configuration file with the +"log-format" set; + +```json +{ + "log-format": "json" +} +``` + ### Miscellaneous options IP masquerading uses address translation to allow containers without a public @@ -1033,6 +1102,7 @@ The following is a full example of the allowed configuration options on Linux: "fixed-cidr": "", "fixed-cidr-v6": "", "group": "", + "host-gateway-ip": "", "hosts": [], "proxies": { "http-proxy": "http://proxy.example.com:80", @@ -1052,6 +1122,7 @@ The following is a full example of the allowed configuration options on Linux: "labels": [], "live-restore": true, "log-driver": "json-file", + "log-format": "text", "log-level": "", "log-opts": { "cache-disabled": "false", @@ -1142,10 +1213,12 @@ The following is a full example of the allowed configuration options on Windows: "features": {}, "fixed-cidr": "", "group": "", + "host-gateway-ip": "", "hosts": [], "insecure-registries": [], "labels": [], "log-driver": "", + "log-format": "text", "log-level": "", "max-concurrent-downloads": 3, "max-concurrent-uploads": 5, diff --git a/docs/reference/index.md b/docs/reference/index.md index 572e23c57cc5..5b872abca612 100644 --- a/docs/reference/index.md +++ b/docs/reference/index.md @@ -14,7 +14,7 @@ keywords: "Engine" # Engine reference -* [Dockerfile reference](https://docs.docker.com/engine/reference/builder/) +* [Dockerfile reference](https://docs.docker.com/reference/dockerfile/) * [Docker run reference](run.md) * [Command line reference](commandline/index.md) * [API Reference](https://docs.docker.com/engine/api/) diff --git a/docs/reference/run.md b/docs/reference/run.md index 41fd2c0dc2d8..bad35ccf422d 100644 --- a/docs/reference/run.md +++ b/docs/reference/run.md @@ -114,13 +114,13 @@ $ docker attach 0246aa4d1448 For more information about `docker run` flags related to foreground and background modes, see: -- [`docker run --detach`](commandline/container_run.md#detach): run container in background -- [`docker run --attach`](commandline/container_run.md#attach): attach to `stdin`, `stdout`, and `stderr` -- [`docker run --tty`](commandline/container_run.md#tty): allocate a pseudo-tty -- [`docker run --interactive`](commandline/container_run.md#interactive): keep `stdin` open even if not attached +- [`docker run --detach`](https://docs.docker.com/reference/cli/docker/container/run/#detach): run container in background +- [`docker run --attach`](https://docs.docker.com/reference/cli/docker/container/run/#attach): attach to `stdin`, `stdout`, and `stderr` +- [`docker run --tty`](https://docs.docker.com/reference/cli/docker/container/run/#tty): allocate a pseudo-tty +- [`docker run --interactive`](https://docs.docker.com/reference/cli/docker/container/run/#interactive): keep `stdin` open even if not attached For more information about re-attaching to a background container, see -[`docker attach`](commandline/container_attach.md). +[`docker attach`](https://docs.docker.com/reference/cli/docker/container/attach/). ## Container identification @@ -135,7 +135,7 @@ You can identify a container in three ways: The UUID identifier is a random ID assigned to the container by the daemon. The daemon generates a random string name for containers automatically. You can -also defined a custom name using [the `--name` flag](./commandline/container_run.md#name). +also defined a custom name using [the `--name` flag](https://docs.docker.com/reference/cli/docker/container/run/#name). Defining a `name` can be a handy way to add meaning to a container. If you specify a `name`, you can use it when referring to the container in a user-defined network. This works for both background and foreground Docker @@ -966,7 +966,7 @@ use of facilities allowed by the capabilities, so you should not have to adjust ## Overriding image defaults -When you build an image from a [Dockerfile](https://docs.docker.com/engine/reference/builder/), +When you build an image from a [Dockerfile](https://docs.docker.com/reference/dockerfile/), or when committing it, you can set a number of default parameters that take effect when the image starts up as a container. When you run an image, you can override those defaults using flags for the `docker run` command. diff --git a/e2e/cli-plugins/plugins/presocket/main.go b/e2e/cli-plugins/plugins/presocket/main.go new file mode 100644 index 000000000000..6cdf87a42402 --- /dev/null +++ b/e2e/cli-plugins/plugins/presocket/main.go @@ -0,0 +1,123 @@ +package main + +import ( + "fmt" + "os" + "os/signal" + "syscall" + "time" + + "github.com/docker/cli/cli-plugins/manager" + "github.com/docker/cli/cli-plugins/plugin" + "github.com/docker/cli/cli/command" + "github.com/spf13/cobra" +) + +func main() { + plugin.Run(RootCmd, manager.Metadata{ + SchemaVersion: "0.1.0", + Vendor: "Docker Inc.", + Version: "test", + }) +} + +func RootCmd(dockerCli command.Cli) *cobra.Command { + cmd := cobra.Command{ + Use: "presocket", + Short: "testing plugin that does not connect to the socket", + // override PersistentPreRunE so that the plugin default + // PersistentPreRunE doesn't run, simulating a plugin built + // with a pre-socket-communication version of the CLI + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + return nil + }, + } + + cmd.AddCommand(&cobra.Command{ + Use: "test-no-socket", + Short: "test command that runs until it receives a SIGINT", + RunE: func(cmd *cobra.Command, args []string) error { + go func() { + <-cmd.Context().Done() + fmt.Fprintln(dockerCli.Out(), "context cancelled") + os.Exit(2) + }() + signalCh := make(chan os.Signal, 10) + signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM) + go func() { + for range signalCh { + fmt.Fprintln(dockerCli.Out(), "received SIGINT") + } + }() + <-time.After(3 * time.Second) + fmt.Fprintln(dockerCli.Err(), "exit after 3 seconds") + return nil + }, + }) + + cmd.AddCommand(&cobra.Command{ + Use: "test-socket", + Short: "test command that runs until it receives a SIGINT", + PreRunE: func(cmd *cobra.Command, args []string) error { + return plugin.PersistentPreRunE(cmd, args) + }, + RunE: func(cmd *cobra.Command, args []string) error { + go func() { + <-cmd.Context().Done() + fmt.Fprintln(dockerCli.Out(), "context cancelled") + os.Exit(2) + }() + signalCh := make(chan os.Signal, 10) + signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM) + go func() { + for range signalCh { + fmt.Fprintln(dockerCli.Out(), "received SIGINT") + } + }() + <-time.After(3 * time.Second) + fmt.Fprintln(dockerCli.Err(), "exit after 3 seconds") + return nil + }, + }) + + cmd.AddCommand(&cobra.Command{ + Use: "test-socket-ignore-context", + Short: "test command that runs until it receives a SIGINT", + PreRunE: func(cmd *cobra.Command, args []string) error { + return plugin.PersistentPreRunE(cmd, args) + }, + RunE: func(cmd *cobra.Command, args []string) error { + signalCh := make(chan os.Signal, 10) + signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM) + go func() { + for range signalCh { + fmt.Fprintln(dockerCli.Out(), "received SIGINT") + } + }() + <-time.After(3 * time.Second) + fmt.Fprintln(dockerCli.Err(), "exit after 3 seconds") + return nil + }, + }) + + cmd.AddCommand(&cobra.Command{ + Use: "tty", + Short: "test command that attempts to read from the TTY", + RunE: func(cmd *cobra.Command, args []string) error { + done := make(chan struct{}) + go func() { + b := make([]byte, 1) + _, _ = dockerCli.In().Read(b) + done <- struct{}{} + }() + select { + case <-done: + case <-time.After(2 * time.Second): + fmt.Fprint(dockerCli.Err(), "timeout after 2 seconds") + } + return nil + }, + }) + + return &cmd +} diff --git a/e2e/cli-plugins/socket_test.go b/e2e/cli-plugins/socket_test.go new file mode 100644 index 000000000000..5e0b1cbb7c8f --- /dev/null +++ b/e2e/cli-plugins/socket_test.go @@ -0,0 +1,235 @@ +package cliplugins + +import ( + "bytes" + "io" + "os/exec" + "strings" + "syscall" + "testing" + "time" + + "github.com/creack/pty" + "gotest.tools/v3/assert" +) + +// TestPluginSocketBackwardsCompatible executes a plugin binary +// that does not connect to the CLI plugin socket, simulating +// a plugin compiled against an older version of the CLI, and +// ensures that backwards compatibility is maintained. +func TestPluginSocketBackwardsCompatible(t *testing.T) { + run, _, cleanup := prepare(t) + defer cleanup() + + t.Run("attached", func(t *testing.T) { + t.Run("the plugin gets signalled if attached to a TTY", func(t *testing.T) { + cmd := run("presocket", "test-no-socket") + command := exec.Command(cmd.Command[0], cmd.Command[1:]...) + + ptmx, err := pty.Start(command) + assert.NilError(t, err, "failed to launch command with fake TTY") + + // send a SIGINT to the process group after 1 second, since + // we're simulating an "attached TTY" scenario and a TTY would + // send a signal to the process group + go func() { + <-time.After(time.Second) + err := syscall.Kill(-command.Process.Pid, syscall.SIGINT) + assert.NilError(t, err, "failed to signal process group") + }() + bytes, err := io.ReadAll(ptmx) + if err != nil && !strings.Contains(err.Error(), "input/output error") { + t.Fatal("failed to get command output") + } + + // the plugin is attached to the TTY, so the parent process + // ignores the received signal, and the plugin receives a SIGINT + // as well + assert.Equal(t, string(bytes), "received SIGINT\r\nexit after 3 seconds\r\n") + }) + + // ensure that we don't break plugins that attempt to read from the TTY + // (see: https://github.com/moby/moby/issues/47073) + // (remove me if/when we decide to break compatibility here) + t.Run("the plugin can read from the TTY", func(t *testing.T) { + cmd := run("presocket", "tty") + command := exec.Command(cmd.Command[0], cmd.Command[1:]...) + + ptmx, err := pty.Start(command) + assert.NilError(t, err, "failed to launch command with fake TTY") + _, _ = ptmx.Write([]byte("hello!")) + + done := make(chan error) + go func() { + <-time.After(time.Second) + _, err := io.ReadAll(ptmx) + done <- err + }() + + select { + case cmdErr := <-done: + if cmdErr != nil && !strings.Contains(cmdErr.Error(), "input/output error") { + t.Fatal("failed to get command output") + } + case <-time.After(5 * time.Second): + t.Fatal("timed out! plugin process probably stuck") + } + }) + }) + + t.Run("detached", func(t *testing.T) { + t.Run("the plugin does not get signalled", func(t *testing.T) { + cmd := run("presocket", "test-no-socket") + command := exec.Command(cmd.Command[0], cmd.Command[1:]...) + t.Log(strings.Join(command.Args, " ")) + command.SysProcAttr = &syscall.SysProcAttr{ + Setpgid: true, + } + + go func() { + <-time.After(time.Second) + // we're signalling the parent process directly and not + // the process group, since we're testing the case where + // the process is detached and not simulating a CTRL-C + // from a TTY + err := syscall.Kill(command.Process.Pid, syscall.SIGINT) + assert.NilError(t, err, "failed to signal process group") + }() + bytes, err := command.CombinedOutput() + t.Log("command output: " + string(bytes)) + assert.NilError(t, err, "failed to run command") + + // the plugin process does not receive a SIGINT + // so it exits after 3 seconds and prints this message + assert.Equal(t, string(bytes), "exit after 3 seconds\n") + }) + + t.Run("the main CLI exits after 3 signals", func(t *testing.T) { + cmd := run("presocket", "test-no-socket") + command := exec.Command(cmd.Command[0], cmd.Command[1:]...) + t.Log(strings.Join(command.Args, " ")) + command.SysProcAttr = &syscall.SysProcAttr{ + Setpgid: true, + } + + go func() { + <-time.After(time.Second) + // we're signalling the parent process directly and not + // the process group, since we're testing the case where + // the process is detached and not simulating a CTRL-C + // from a TTY + err := syscall.Kill(command.Process.Pid, syscall.SIGINT) + assert.NilError(t, err, "failed to signal process group") + // TODO: look into CLI signal handling, it's currently necessary + // to add a short delay between each signal in order for the CLI + // process to consistently pick them all up. + time.Sleep(50 * time.Millisecond) + err = syscall.Kill(command.Process.Pid, syscall.SIGINT) + assert.NilError(t, err, "failed to signal process group") + time.Sleep(50 * time.Millisecond) + err = syscall.Kill(command.Process.Pid, syscall.SIGINT) + assert.NilError(t, err, "failed to signal process group") + }() + bytes, err := command.CombinedOutput() + assert.ErrorContains(t, err, "exit status 1") + + // the plugin process does not receive a SIGINT and does + // the CLI cannot cancel it over the socket, so it kills + // the plugin process and forcefully exits + assert.Equal(t, string(bytes), "got 3 SIGTERM/SIGINTs, forcefully exiting\n") + }) + }) +} + +func TestPluginSocketCommunication(t *testing.T) { + run, _, cleanup := prepare(t) + defer cleanup() + + t.Run("attached", func(t *testing.T) { + t.Run("the socket is not closed + the plugin receives a signal due to pgid", func(t *testing.T) { + cmd := run("presocket", "test-socket") + command := exec.Command(cmd.Command[0], cmd.Command[1:]...) + + ptmx, err := pty.Start(command) + assert.NilError(t, err, "failed to launch command with fake TTY") + + // send a SIGINT to the process group after 1 second, since + // we're simulating an "attached TTY" scenario and a TTY would + // send a signal to the process group + go func() { + <-time.After(time.Second) + err := syscall.Kill(-command.Process.Pid, syscall.SIGINT) + assert.NilError(t, err, "failed to signal process group") + }() + bytes, err := io.ReadAll(ptmx) + if err != nil && !strings.Contains(err.Error(), "input/output error") { + t.Fatal("failed to get command output") + } + + // the plugin is attached to the TTY, so the parent process + // ignores the received signal, and the plugin receives a SIGINT + // as well + assert.Equal(t, string(bytes), "received SIGINT\r\nexit after 3 seconds\r\n") + }) + }) + + t.Run("detached", func(t *testing.T) { + t.Run("the plugin does not get signalled", func(t *testing.T) { + cmd := run("presocket", "test-socket") + command := exec.Command(cmd.Command[0], cmd.Command[1:]...) + outB := bytes.Buffer{} + command.Stdout = &outB + command.Stderr = &outB + command.SysProcAttr = &syscall.SysProcAttr{ + Setpgid: true, + } + + // send a SIGINT to the process group after 1 second + go func() { + <-time.After(time.Second) + err := syscall.Kill(command.Process.Pid, syscall.SIGINT) + assert.NilError(t, err, "failed to signal CLI process") + }() + err := command.Run() + t.Log(outB.String()) + assert.ErrorContains(t, err, "exit status 2") + + // the plugin does not get signalled, but it does get it's + // context cancelled by the CLI through the socket + assert.Equal(t, outB.String(), "context cancelled\n") + }) + + t.Run("the main CLI exits after 3 signals", func(t *testing.T) { + cmd := run("presocket", "test-socket-ignore-context") + command := exec.Command(cmd.Command[0], cmd.Command[1:]...) + command.SysProcAttr = &syscall.SysProcAttr{ + Setpgid: true, + } + + go func() { + <-time.After(time.Second) + // we're signalling the parent process directly and not + // the process group, since we're testing the case where + // the process is detached and not simulating a CTRL-C + // from a TTY + err := syscall.Kill(command.Process.Pid, syscall.SIGINT) + assert.NilError(t, err, "failed to signal CLI process") + // TODO: same as above TODO, CLI signal handling is not consistent + // with multiple signals without intervals + time.Sleep(50 * time.Millisecond) + err = syscall.Kill(command.Process.Pid, syscall.SIGINT) + assert.NilError(t, err, "failed to signal CLI process") + time.Sleep(50 * time.Millisecond) + err = syscall.Kill(command.Process.Pid, syscall.SIGINT) + assert.NilError(t, err, "failed to signal CLI process§") + }() + bytes, err := command.CombinedOutput() + assert.ErrorContains(t, err, "exit status 1") + + // the plugin process does not receive a SIGINT and does + // not exit after having it's context cancelled, so the CLI + // kills the plugin process and forcefully exits + assert.Equal(t, string(bytes), "got 3 SIGTERM/SIGINTs, forcefully exiting\n") + }) + }) +} diff --git a/e2e/compose-env.connhelper-ssh.yaml b/e2e/compose-env.connhelper-ssh.yaml index 2a91ab48fe98..283e306fbc65 100644 --- a/e2e/compose-env.connhelper-ssh.yaml +++ b/e2e/compose-env.connhelper-ssh.yaml @@ -3,5 +3,7 @@ services: build: context: ./testdata dockerfile: Dockerfile.connhelper-ssh + args: + - ENGINE_VERSION environment: - TEST_CONNHELPER_SSH_ID_RSA_PUB diff --git a/e2e/compose-env.yaml b/e2e/compose-env.yaml index 9eade791b02a..2a30e1040ed4 100644 --- a/e2e/compose-env.yaml +++ b/e2e/compose-env.yaml @@ -1,9 +1,10 @@ services: + registry: image: 'registry:2' engine: - image: 'docker:${TEST_ENGINE_VERSION:-stable-dind}' + image: 'docker:${ENGINE_VERSION:-25.0}-dind' privileged: true command: ['--insecure-registry=registry:5000'] environment: @@ -16,6 +17,7 @@ services: ports: - 4443:4443 command: ['notary-server', '-config=/fixtures/notary-config.json'] + evil-notary-server: build: context: ./testdata diff --git a/e2e/container/run_test.go b/e2e/container/run_test.go index 3f110156ed70..bb79b0cf58da 100644 --- a/e2e/container/run_test.go +++ b/e2e/container/run_test.go @@ -146,6 +146,6 @@ func TestRunWithCgroupNamespace(t *testing.T) { environment.SkipIfCgroupNamespacesNotSupported(t) result := icmd.RunCommand("docker", "run", "--cgroupns=private", "--rm", fixtures.AlpineImage, - "/bin/grep", "-q", "':memory:/$'", "/proc/1/cgroup") + "cat", "/sys/fs/cgroup/cgroup.controllers") result.Assert(t, icmd.Success) } diff --git a/e2e/image/build_test.go b/e2e/image/build_test.go index d6a35b5b760f..fadd13922406 100644 --- a/e2e/image/build_test.go +++ b/e2e/image/build_test.go @@ -43,12 +43,19 @@ func TestBuildFromContextDirectoryWithTag(t *testing.T) { result.Assert(t, icmd.Expected{Err: buildkitDisabledWarning}) output.Assert(t, result.Stdout(), map[int]func(string) error{ - 0: output.Prefix("Sending build context to Docker daemon"), - 1: output.Suffix("Step 1/4 : FROM registry:5000/alpine:frozen"), - 3: output.Suffix("Step 2/4 : COPY run /usr/bin/run"), - 5: output.Suffix("Step 3/4 : RUN run"), - 7: output.Suffix("running"), - 8: output.Contains("Removing intermediate container"), + 0: output.Prefix("Sending build context to Docker daemon"), + 1: output.Suffix("Step 1/4 : FROM registry:5000/alpine:frozen"), + 3: output.Suffix("Step 2/4 : COPY run /usr/bin/run"), + 5: output.Suffix("Step 3/4 : RUN run"), + 7: output.Suffix("running"), + // TODO(krissetto): ugly, remove when no longer testing against moby 24. see https://github.com/moby/moby/pull/46270 + 8: func(s string) error { + err := output.Contains("Removed intermediate container")(s) // moby >= v25 + if err == nil { + return nil + } + return output.Contains("Removing intermediate container")(s) // moby < v25 + }, 10: output.Suffix("Step 4/4 : COPY data /data"), 12: output.Contains("Successfully built "), 13: output.Suffix("Successfully tagged myimage:latest"), diff --git a/e2e/image/testdata/pull-with-content-trust.golden b/e2e/image/testdata/pull-with-content-trust.golden index b21407e1172c..582a4e0cc9c8 100644 --- a/e2e/image/testdata/pull-with-content-trust.golden +++ b/e2e/image/testdata/pull-with-content-trust.golden @@ -1,5 +1,5 @@ Pull (1 of 1): registry:5000/trust-pull:latest@sha256:e2e16842c9b54d985bf1ef9242a313f36b856181f188de21313820e177002501 -sha256:e2e16842c9b54d985bf1ef9242a313f36b856181f188de21313820e177002501: Pulling from trust-pull +registry:5000/trust-pull@sha256:e2e16842c9b54d985bf1ef9242a313f36b856181f188de21313820e177002501: Pulling from trust-pull Digest: sha256:e2e16842c9b54d985bf1ef9242a313f36b856181f188de21313820e177002501 Status: Downloaded newer image for registry:5000/trust-pull@sha256:e2e16842c9b54d985bf1ef9242a313f36b856181f188de21313820e177002501 registry:5000/trust-pull:latest diff --git a/e2e/plugin/trust_test.go b/e2e/plugin/trust_test.go index 38bdcc5e4543..c6957d6f37db 100644 --- a/e2e/plugin/trust_test.go +++ b/e2e/plugin/trust_test.go @@ -11,6 +11,7 @@ import ( "github.com/docker/cli/e2e/internal/fixtures" "github.com/docker/cli/internal/test/environment" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/versions" "github.com/pkg/errors" "gotest.tools/v3/assert" "gotest.tools/v3/fs" @@ -21,6 +22,8 @@ import ( const registryPrefix = "registry:5000" func TestInstallWithContentTrust(t *testing.T) { + // TODO(krissetto): remove this skip once the fix (see https://github.com/moby/moby/pull/47299) is deployed to moby versions < 25 + skip.If(t, versions.LessThan(environment.DaemonAPIVersion(t), "1.44")) skip.If(t, environment.SkipPluginTests()) pluginName := fmt.Sprintf("%s/plugin-content-trust", registryPrefix) @@ -50,7 +53,7 @@ func TestInstallWithContentTrust(t *testing.T) { fixtures.WithNotary, ) result.Assert(t, icmd.Expected{ - Out: fmt.Sprintf("Status: Downloaded newer image for %s@sha", pluginName), + Out: fmt.Sprintf("Installed plugin %s", pluginName), }) } diff --git a/e2e/testdata/Dockerfile.connhelper-ssh b/e2e/testdata/Dockerfile.connhelper-ssh index 64306b518cc4..3771f3e62f14 100644 --- a/e2e/testdata/Dockerfile.connhelper-ssh +++ b/e2e/testdata/Dockerfile.connhelper-ssh @@ -1,5 +1,16 @@ -FROM docker:test-dind -RUN apk --no-cache add shadow openssh-server && \ +# syntax=docker/dockerfile:1 + +# ENGINE_VERSION is the version of the (docker-in-docker) Docker Engine to +# test against. +ARG ENGINE_VERSION=25.0 + +FROM docker:${ENGINE_VERSION}-dind + +# the openssh-client update is needed for security reasons when using docker:23.0-dind, currently maintained as an lts by mirantis +RUN apk --no-cache upgrade openssh-client && \ + apk --no-cache add shadow openssh-server && \ + # TODO(krissetto): `groupadd` can be removed once we only test against moby >= v24 + # see https://github.com/docker-library/docker/pull/470 groupadd -f docker && \ useradd --create-home --shell /bin/sh --password $(head -c32 /dev/urandom | base64) penguin && \ usermod -aG docker penguin && \ diff --git a/e2e/testdata/Dockerfile.evil-notary-server b/e2e/testdata/Dockerfile.evil-notary-server index d982d5a4eb07..97f234e849bf 100644 --- a/e2e/testdata/Dockerfile.evil-notary-server +++ b/e2e/testdata/Dockerfile.evil-notary-server @@ -1,4 +1,7 @@ +# syntax=docker/dockerfile:1 + ARG NOTARY_VERSION=0.6.1 + FROM notary:server-${NOTARY_VERSION} COPY ./notary-evil/ /fixtures/ diff --git a/e2e/testdata/Dockerfile.gencerts b/e2e/testdata/Dockerfile.gencerts index 30d1c9b6f719..a769c3b6194a 100644 --- a/e2e/testdata/Dockerfile.gencerts +++ b/e2e/testdata/Dockerfile.gencerts @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1 -ARG GO_VERSION=1.21.6 +ARG GO_VERSION=1.22.10 FROM golang:${GO_VERSION}-alpine AS generated ENV GOTOOLCHAIN=local diff --git a/e2e/testdata/Dockerfile.notary-server b/e2e/testdata/Dockerfile.notary-server index 4bc59d2d8832..846253e2fba6 100644 --- a/e2e/testdata/Dockerfile.notary-server +++ b/e2e/testdata/Dockerfile.notary-server @@ -1,4 +1,7 @@ +# syntax=docker/dockerfile:1 + ARG NOTARY_VERSION=0.6.1 + FROM notary:server-${NOTARY_VERSION} COPY ./notary/ /fixtures/ diff --git a/internal/test/environment/testenv.go b/internal/test/environment/testenv.go index 8b035fca1b8a..7fe6880244cd 100644 --- a/internal/test/environment/testenv.go +++ b/internal/test/environment/testenv.go @@ -108,3 +108,14 @@ func SkipIfNotPlatform(t *testing.T, platform string) { daemonPlatform := strings.TrimSpace(result.Stdout()) skip.If(t, daemonPlatform != platform, "running against a non %s daemon", platform) } + +// DaemonAPIVersion returns the negotiated daemon API version. +func DaemonAPIVersion(t *testing.T) string { + t.Helper() + // Use Client.APIVersion instead of Server.APIVersion. + // The latter is the maximum version that the server supports + // while the Client.APIVersion contains the negotiated version. + result := icmd.RunCmd(icmd.Command("docker", "version", "--format", "{{.Client.APIVersion}}")) + result.Assert(t, icmd.Expected{Err: icmd.None}) + return strings.TrimSpace(result.Stdout()) +} diff --git a/man/dockerd.8.md b/man/dockerd.8.md index f0b71b3eee6f..1dc668f00a56 100644 --- a/man/dockerd.8.md +++ b/man/dockerd.8.md @@ -52,6 +52,7 @@ dockerd - Enable daemon mode [**--label**[=*[]*]] [**--live-restore**[=**false**]] [**--log-driver**[=*json-file*]] +[**--log-format**="*text*|*json*"] [**--log-opt**[=*map[]*]] [**--mtu**[=*0*]] [**--max-concurrent-downloads**[=*3*]] @@ -324,6 +325,9 @@ unix://[/path/to/socket] to use. Default driver for container logs. Default is **json-file**. **Warning**: **docker logs** command works only for **json-file** logging driver. +**--log-format**="*text*|*json*" + Set the format for logs produced by the daemon. Default is "text". + **--log-opt**=[] Logging driver specific options. diff --git a/opts/throttledevice.go b/opts/throttledevice.go index bdf454eb27da..8bf128804794 100644 --- a/opts/throttledevice.go +++ b/opts/throttledevice.go @@ -94,7 +94,7 @@ func (opt *ThrottledeviceOpt) String() string { // GetList returns a slice of pointers to ThrottleDevices. func (opt *ThrottledeviceOpt) GetList() []*blkiodev.ThrottleDevice { - out := make([]*blkiodev.ThrottleDevice, 0, len(opt.values)) + out := make([]*blkiodev.ThrottleDevice, len(opt.values)) copy(out, opt.values) return out } diff --git a/scripts/build/plugins b/scripts/build/plugins index fa78b9536bd1..634d3f9db740 100755 --- a/scripts/build/plugins +++ b/scripts/build/plugins @@ -5,6 +5,12 @@ set -eu -o pipefail +# Disable CGO - we don't need it for these plugins. +# +# Important: this must be done before sourcing "./scripts/build/.variables", +# because some other variables are conditionally set whether CGO is enabled. +export CGO_ENABLED=0 + source ./scripts/build/.variables for p in cli-plugins/examples/* "$@" ; do @@ -15,5 +21,5 @@ for p in cli-plugins/examples/* "$@" ; do mkdir -p "$(dirname "${TARGET_PLUGIN}")" echo "Building $GO_LINKMODE $(basename "${TARGET_PLUGIN}")" - (set -x ; CGO_ENABLED=0 GO111MODULE=auto go build -o "${TARGET_PLUGIN}" -tags "${GO_BUILDTAGS}" -ldflags "${GO_LDFLAGS}" ${GO_BUILDMODE} "github.com/docker/cli/${p}") + (set -x ; GO111MODULE=auto go build -o "${TARGET_PLUGIN}" -tags "${GO_BUILDTAGS}" -ldflags "${GO_LDFLAGS}" ${GO_BUILDMODE} "github.com/docker/cli/${p}") done diff --git a/scripts/docs/generate-md.sh b/scripts/docs/generate-md.sh index 7b49c39341ec..4caa01eaed23 100755 --- a/scripts/docs/generate-md.sh +++ b/scripts/docs/generate-md.sh @@ -2,15 +2,12 @@ set -eu -: "${CLI_DOCS_TOOL_VERSION=v0.6.0}" +: "${CLI_DOCS_TOOL_VERSION=v0.7.0}" export GO111MODULE=auto function clean { rm -rf "$buildir" - if [ -f "$(pwd)/docs/reference/commandline/docker.md" ]; then - mv "$(pwd)/docs/reference/commandline/docker.md" "$(pwd)/docs/reference/commandline/cli.md" - fi } buildir=$(mktemp -d -t docker-cli-docsgen.XXXXXXXXXX) @@ -32,12 +29,6 @@ trap clean EXIT go build -mod=vendor -modfile=vendor.mod -tags docsgen -o /tmp/docsgen ./docs/generate/generate.go ) -# yaml generation on docs repo needs the cli.md file: https://github.com/docker/cli/pull/3924#discussion_r1059986605 -# but markdown generation docker.md atm. While waiting for a fix in cli-docs-tool -# we need to first move the cli.md file to docker.md, do the generation and -# then move it back in trap handler. -mv "$(pwd)/docs/reference/commandline/cli.md" "$(pwd)/docs/reference/commandline/docker.md" - ( set -x /tmp/docsgen --formats md --source "$(pwd)/docs/reference/commandline" --target "$(pwd)/docs/reference/commandline" diff --git a/scripts/docs/generate-yaml.sh b/scripts/docs/generate-yaml.sh index 4d0006e43e79..0d67c5e5bb09 100755 --- a/scripts/docs/generate-yaml.sh +++ b/scripts/docs/generate-yaml.sh @@ -2,7 +2,7 @@ set -eu -: "${CLI_DOCS_TOOL_VERSION=v0.5.1}" +: "${CLI_DOCS_TOOL_VERSION=v0.7.0}" export GO111MODULE=auto diff --git a/scripts/test/e2e/run b/scripts/test/e2e/run index 54e1d61e8a34..e2c651ea802c 100755 --- a/scripts/test/e2e/run +++ b/scripts/test/e2e/run @@ -2,6 +2,8 @@ # Run integration tests against the latest docker-ce dind set -eu -o pipefail +source ./scripts/build/.variables + container_ip() { local cid=$1 local network=$2 @@ -69,7 +71,7 @@ runtests() { GOPATH="$GOPATH" \ PATH="$PWD/build/:/usr/bin:/usr/local/bin:/usr/local/go/bin" \ HOME="$HOME" \ - DOCKER_CLI_E2E_PLUGINS_EXTRA_DIRS="$PWD/build/plugins-linux-amd64" \ + DOCKER_CLI_E2E_PLUGINS_EXTRA_DIRS="$PWD/build/plugins-linux-${GOARCH}" \ GO111MODULE=auto \ "$(command -v gotestsum)" -- ${TESTDIRS:-./e2e/...} ${TESTFLAGS-} } diff --git a/vendor.mod b/vendor.mod index 7d77c1ca4598..e311b2baace4 100644 --- a/vendor.mod +++ b/vendor.mod @@ -12,7 +12,7 @@ require ( github.com/creack/pty v1.1.21 github.com/distribution/reference v0.5.0 github.com/docker/distribution v2.8.3+incompatible - github.com/docker/docker v25.0.0-rc.3+incompatible + github.com/docker/docker v25.0.5-0.20240319141229-e63daec8672d+incompatible // 25.0 branch (v25.0.5-dev) github.com/docker/docker-credential-helpers v0.8.1 github.com/docker/go-connections v0.5.0 github.com/docker/go-units v0.5.0 @@ -38,8 +38,8 @@ require ( github.com/tonistiigi/go-rosetta v0.0.0-20200727161949-f79598599c5d github.com/xeipuuv/gojsonschema v1.2.0 golang.org/x/sync v0.6.0 - golang.org/x/sys v0.16.0 - golang.org/x/term v0.15.0 + golang.org/x/sys v0.18.0 + golang.org/x/term v0.18.0 golang.org/x/text v0.14.0 gopkg.in/yaml.v2 v2.4.0 gotest.tools/v3 v3.5.1 @@ -57,12 +57,13 @@ require ( github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect github.com/docker/go-metrics v0.0.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/klauspost/compress v1.17.4 // indirect + github.com/kr/pretty v0.3.1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect github.com/moby/sys/symlink v0.2.0 // indirect @@ -72,16 +73,19 @@ require ( github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect + github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect go.etcd.io/etcd/raft/v3 v3.5.6 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect - go.opentelemetry.io/otel v1.19.0 // indirect - go.opentelemetry.io/otel/metric v1.19.0 // indirect - go.opentelemetry.io/otel/trace v1.19.0 // indirect - golang.org/x/crypto v0.17.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect + go.opentelemetry.io/otel v1.21.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect + go.opentelemetry.io/otel/metric v1.21.0 // indirect + go.opentelemetry.io/otel/sdk v1.21.0 // indirect + go.opentelemetry.io/otel/trace v1.21.0 // indirect + golang.org/x/crypto v0.21.0 // indirect golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.19.0 // indirect + golang.org/x/net v0.23.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.16.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect diff --git a/vendor.sum b/vendor.sum index 7cf5e03e61d3..47a55b0a9bc1 100644 --- a/vendor.sum +++ b/vendor.sum @@ -54,8 +54,8 @@ github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5 github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v25.0.0-rc.3+incompatible h1:f2YaukI/rOEueLwmDGAVcES5E8Y+BT/e7pQWLu/WZSk= -github.com/docker/docker v25.0.0-rc.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v25.0.5-0.20240319141229-e63daec8672d+incompatible h1:/fHlcenWAlpspiwdoApWGdUJ9FuFsD/NeK8BuFyZZzY= +github.com/docker/docker v25.0.5-0.20240319141229-e63daec8672d+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.8.1 h1:j/eKUktUltBtMzKqmfLB0PAgqYyMHOp5vfsD1807oKo= github.com/docker/docker-credential-helpers v0.8.1/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= @@ -84,8 +84,8 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= @@ -143,8 +143,9 @@ github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -197,6 +198,7 @@ github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/ github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -227,6 +229,9 @@ github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJf github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -273,17 +278,19 @@ github.com/zmap/zlint/v3 v3.1.0 h1:WjVytZo79m/L1+/Mlphl09WBob6YTGljN5IGWZFpAv0= go.etcd.io/etcd/client/pkg/v3 v3.5.6/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ= go.etcd.io/etcd/raft/v3 v3.5.6 h1:tOmx6Ym6rn2GpZOrvTGJZciJHek6RnC3U/zNInzIN50= go.etcd.io/etcd/raft/v3 v3.5.6/go.mod h1:wL8kkRGx1Hp8FmZUuHfL3K2/OaGIDaXGr1N7i2G07J0= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q= -go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= -go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo= +go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg= -go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= -go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= -go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= -go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= -go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= +go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -295,8 +302,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= 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.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= @@ -308,8 +315,8 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -331,11 +338,11 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= diff --git a/vendor/github.com/docker/docker/api/swagger.yaml b/vendor/github.com/docker/docker/api/swagger.yaml index 567939580b48..201b54906441 100644 --- a/vendor/github.com/docker/docker/api/swagger.yaml +++ b/vendor/github.com/docker/docker/api/swagger.yaml @@ -391,7 +391,11 @@ definitions: ReadOnlyNonRecursive: description: | Make the mount non-recursively read-only, but still leave the mount recursive - (unless NonRecursive is set to true in conjunction). + (unless NonRecursive is set to `true` in conjunction). + + Addded in v1.44, before that version all read-only mounts were + non-recursive by default. To match the previous behaviour this + will default to `true` for clients on versions prior to v1.44. type: "boolean" default: false ReadOnlyForceRecursive: @@ -1743,8 +1747,12 @@ definitions: description: | Date and time at which the image was created, formatted in [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds. + + This information is only available if present in the image, + and omitted otherwise. type: "string" - x-nullable: false + format: "dateTime" + x-nullable: true example: "2022-02-04T21:20:12.497794809Z" Container: description: | @@ -8327,6 +8335,16 @@ paths: description: "BuildKit output configuration" type: "string" default: "" + - name: "version" + in: "query" + type: "string" + default: "1" + enum: ["1", "2"] + description: | + Version of the builder backend to use. + + - `1` is the first generation classic (deprecated) builder in the Docker daemon (default) + - `2` is [BuildKit](https://github.com/moby/buildkit) responses: 200: description: "no error" diff --git a/vendor/github.com/docker/docker/api/types/network/endpoint.go b/vendor/github.com/docker/docker/api/types/network/endpoint.go index 4b3c06a52b58..9edd1c38d919 100644 --- a/vendor/github.com/docker/docker/api/types/network/endpoint.go +++ b/vendor/github.com/docker/docker/api/types/network/endpoint.go @@ -14,6 +14,9 @@ type EndpointSettings struct { IPAMConfig *EndpointIPAMConfig Links []string Aliases []string // Aliases holds the list of extra, user-specified DNS names for this endpoint. + // MacAddress may be used to specify a MAC address when the container is created. + // Once the container is running, it becomes operational data (it may contain a + // generated address). MacAddress string // Operational data NetworkID string diff --git a/vendor/github.com/docker/docker/api/types/network/ipam.go b/vendor/github.com/docker/docker/api/types/network/ipam.go index 17f370ef7efe..f319e1402b08 100644 --- a/vendor/github.com/docker/docker/api/types/network/ipam.go +++ b/vendor/github.com/docker/docker/api/types/network/ipam.go @@ -30,30 +30,9 @@ const ( ip6 ipFamily = "IPv6" ) -// HasIPv6Subnets checks whether there's any IPv6 subnets in the ipam parameter. It ignores any invalid Subnet and nil -// ipam. -func HasIPv6Subnets(ipam *IPAM) bool { - if ipam == nil { - return false - } - - for _, cfg := range ipam.Config { - subnet, err := netip.ParsePrefix(cfg.Subnet) - if err != nil { - continue - } - - if subnet.Addr().Is6() { - return true - } - } - - return false -} - // ValidateIPAM checks whether the network's IPAM passed as argument is valid. It returns a joinError of the list of // errors found. -func ValidateIPAM(ipam *IPAM) error { +func ValidateIPAM(ipam *IPAM, enableIPv6 bool) error { if ipam == nil { return nil } @@ -70,6 +49,10 @@ func ValidateIPAM(ipam *IPAM) error { subnetFamily = ip6 } + if !enableIPv6 && subnetFamily == ip6 { + continue + } + if subnet != subnet.Masked() { errs = append(errs, fmt.Errorf("invalid subnet %s: it should be %s", subnet, subnet.Masked())) } diff --git a/vendor/github.com/docker/docker/api/types/types.go b/vendor/github.com/docker/docker/api/types/types.go index 5c56a0cafef1..56a8b77d45de 100644 --- a/vendor/github.com/docker/docker/api/types/types.go +++ b/vendor/github.com/docker/docker/api/types/types.go @@ -72,7 +72,10 @@ type ImageInspect struct { // Created is the date and time at which the image was created, formatted in // RFC 3339 nano-seconds (time.RFC3339Nano). - Created string + // + // This information is only available if present in the image, + // and omitted otherwise. + Created string `json:",omitempty"` // Container is the ID of the container that was used to create the image. // diff --git a/vendor/github.com/docker/docker/builder/remotecontext/urlutil/urlutil.go b/vendor/github.com/docker/docker/builder/remotecontext/urlutil/urlutil.go index e38988a30cd5..e8459cc820f2 100644 --- a/vendor/github.com/docker/docker/builder/remotecontext/urlutil/urlutil.go +++ b/vendor/github.com/docker/docker/builder/remotecontext/urlutil/urlutil.go @@ -12,7 +12,7 @@ import ( // urlPathWithFragmentSuffix matches fragments to use as Git reference and build // context from the Git repository. See IsGitURL for details. -var urlPathWithFragmentSuffix = regexp.MustCompile(".git(?:#.+)?$") +var urlPathWithFragmentSuffix = regexp.MustCompile(`\.git(?:#.+)?$`) // IsURL returns true if the provided str is an HTTP(S) URL by checking if it // has a http:// or https:// scheme. No validation is performed to verify if the diff --git a/vendor/github.com/docker/docker/client/client.go b/vendor/github.com/docker/docker/client/client.go index 0b496b0fa66f..f2eeb6c5702e 100644 --- a/vendor/github.com/docker/docker/client/client.go +++ b/vendor/github.com/docker/docker/client/client.go @@ -265,17 +265,22 @@ func (cli *Client) Close() error { // This allows for version-dependent code to use the same version as will // be negotiated when making the actual requests, and for which cases // we cannot do the negotiation lazily. -func (cli *Client) checkVersion(ctx context.Context) { - if cli.negotiateVersion && !cli.negotiated { - cli.NegotiateAPIVersion(ctx) +func (cli *Client) checkVersion(ctx context.Context) error { + if !cli.manualOverride && cli.negotiateVersion && !cli.negotiated { + ping, err := cli.Ping(ctx) + if err != nil { + return err + } + cli.negotiateAPIVersionPing(ping) } + return nil } // getAPIPath returns the versioned request path to call the API. // It appends the query parameters to the path if they are not empty. func (cli *Client) getAPIPath(ctx context.Context, p string, query url.Values) string { var apiPath string - cli.checkVersion(ctx) + _ = cli.checkVersion(ctx) if cli.version != "" { v := strings.TrimPrefix(cli.version, "v") apiPath = path.Join(cli.basePath, "/v"+v, p) @@ -307,7 +312,11 @@ func (cli *Client) ClientVersion() string { // added (1.24). func (cli *Client) NegotiateAPIVersion(ctx context.Context) { if !cli.manualOverride { - ping, _ := cli.Ping(ctx) + ping, err := cli.Ping(ctx) + if err != nil { + // FIXME(thaJeztah): Ping returns an error when failing to connect to the API; we should not swallow the error here, and instead returning it. + return + } cli.negotiateAPIVersionPing(ping) } } diff --git a/vendor/github.com/docker/docker/client/container_create.go b/vendor/github.com/docker/docker/client/container_create.go index 409f5b492a6e..5442d4267d09 100644 --- a/vendor/github.com/docker/docker/client/container_create.go +++ b/vendor/github.com/docker/docker/client/container_create.go @@ -28,7 +28,9 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config // // Normally, version-negotiation (if enabled) would not happen until // the API request is made. - cli.checkVersion(ctx) + if err := cli.checkVersion(ctx); err != nil { + return response, err + } if err := cli.NewVersionError(ctx, "1.25", "stop timeout"); config != nil && config.StopTimeout != nil && err != nil { return response, err diff --git a/vendor/github.com/docker/docker/client/container_exec.go b/vendor/github.com/docker/docker/client/container_exec.go index 3fff0c828897..526a3876a4a7 100644 --- a/vendor/github.com/docker/docker/client/container_exec.go +++ b/vendor/github.com/docker/docker/client/container_exec.go @@ -18,7 +18,9 @@ func (cli *Client) ContainerExecCreate(ctx context.Context, container string, co // // Normally, version-negotiation (if enabled) would not happen until // the API request is made. - cli.checkVersion(ctx) + if err := cli.checkVersion(ctx); err != nil { + return response, err + } if err := cli.NewVersionError(ctx, "1.25", "env"); len(config.Env) != 0 && err != nil { return response, err diff --git a/vendor/github.com/docker/docker/client/container_restart.go b/vendor/github.com/docker/docker/client/container_restart.go index 825d3e4e9d9b..02b5079bc463 100644 --- a/vendor/github.com/docker/docker/client/container_restart.go +++ b/vendor/github.com/docker/docker/client/container_restart.go @@ -23,7 +23,9 @@ func (cli *Client) ContainerRestart(ctx context.Context, containerID string, opt // // Normally, version-negotiation (if enabled) would not happen until // the API request is made. - cli.checkVersion(ctx) + if err := cli.checkVersion(ctx); err != nil { + return err + } if versions.GreaterThanOrEqualTo(cli.version, "1.42") { query.Set("signal", options.Signal) } diff --git a/vendor/github.com/docker/docker/client/container_stop.go b/vendor/github.com/docker/docker/client/container_stop.go index ac0cab69de94..7c98a354b42e 100644 --- a/vendor/github.com/docker/docker/client/container_stop.go +++ b/vendor/github.com/docker/docker/client/container_stop.go @@ -27,7 +27,9 @@ func (cli *Client) ContainerStop(ctx context.Context, containerID string, option // // Normally, version-negotiation (if enabled) would not happen until // the API request is made. - cli.checkVersion(ctx) + if err := cli.checkVersion(ctx); err != nil { + return err + } if versions.GreaterThanOrEqualTo(cli.version, "1.42") { query.Set("signal", options.Signal) } diff --git a/vendor/github.com/docker/docker/client/container_wait.go b/vendor/github.com/docker/docker/client/container_wait.go index b8d3bdef0db8..8bb6be0a18b2 100644 --- a/vendor/github.com/docker/docker/client/container_wait.go +++ b/vendor/github.com/docker/docker/client/container_wait.go @@ -30,19 +30,22 @@ const containerWaitErrorMsgLimit = 2 * 1024 /* Max: 2KiB */ // synchronize ContainerWait with other calls, such as specifying a // "next-exit" condition before issuing a ContainerStart request. func (cli *Client) ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error) { + resultC := make(chan container.WaitResponse) + errC := make(chan error, 1) + // Make sure we negotiated (if the client is configured to do so), // as code below contains API-version specific handling of options. // // Normally, version-negotiation (if enabled) would not happen until // the API request is made. - cli.checkVersion(ctx) + if err := cli.checkVersion(ctx); err != nil { + errC <- err + return resultC, errC + } if versions.LessThan(cli.ClientVersion(), "1.30") { return cli.legacyContainerWait(ctx, containerID) } - resultC := make(chan container.WaitResponse) - errC := make(chan error, 1) - query := url.Values{} if condition != "" { query.Set("condition", string(condition)) diff --git a/vendor/github.com/docker/docker/client/errors.go b/vendor/github.com/docker/docker/client/errors.go index 4b96b0208585..0d01e243fe0b 100644 --- a/vendor/github.com/docker/docker/client/errors.go +++ b/vendor/github.com/docker/docker/client/errors.go @@ -11,15 +11,16 @@ import ( // errConnectionFailed implements an error returned when connection failed. type errConnectionFailed struct { - host string + error } // Error returns a string representation of an errConnectionFailed -func (err errConnectionFailed) Error() string { - if err.host == "" { - return "Cannot connect to the Docker daemon. Is the docker daemon running on this host?" - } - return fmt.Sprintf("Cannot connect to the Docker daemon at %s. Is the docker daemon running?", err.host) +func (e errConnectionFailed) Error() string { + return e.error.Error() +} + +func (e errConnectionFailed) Unwrap() error { + return e.error } // IsErrConnectionFailed returns true if the error is caused by connection failed. @@ -29,7 +30,13 @@ func IsErrConnectionFailed(err error) bool { // ErrorConnectionFailed returns an error with host in the error message when connection to docker daemon failed. func ErrorConnectionFailed(host string) error { - return errConnectionFailed{host: host} + var err error + if host == "" { + err = fmt.Errorf("Cannot connect to the Docker daemon. Is the docker daemon running on this host?") + } else { + err = fmt.Errorf("Cannot connect to the Docker daemon at %s. Is the docker daemon running?", host) + } + return errConnectionFailed{error: err} } // IsErrNotFound returns true if the error is a NotFound error, which is returned @@ -60,7 +67,9 @@ func (cli *Client) NewVersionError(ctx context.Context, APIrequired, feature str // // Normally, version-negotiation (if enabled) would not happen until // the API request is made. - cli.checkVersion(ctx) + if err := cli.checkVersion(ctx); err != nil { + return err + } if cli.version != "" && versions.LessThan(cli.version, APIrequired) { return fmt.Errorf("%q requires API version %s, but the Docker daemon API version is %s", feature, APIrequired, cli.version) } diff --git a/vendor/github.com/docker/docker/client/image_list.go b/vendor/github.com/docker/docker/client/image_list.go index f3f2280e3249..fa6aecfc6ed0 100644 --- a/vendor/github.com/docker/docker/client/image_list.go +++ b/vendor/github.com/docker/docker/client/image_list.go @@ -13,14 +13,17 @@ import ( // ImageList returns a list of images in the docker host. func (cli *Client) ImageList(ctx context.Context, options types.ImageListOptions) ([]image.Summary, error) { + var images []image.Summary + // Make sure we negotiated (if the client is configured to do so), // as code below contains API-version specific handling of options. // // Normally, version-negotiation (if enabled) would not happen until // the API request is made. - cli.checkVersion(ctx) + if err := cli.checkVersion(ctx); err != nil { + return images, err + } - var images []image.Summary query := url.Values{} optionFilters := options.Filters diff --git a/vendor/github.com/docker/docker/client/network_create.go b/vendor/github.com/docker/docker/client/network_create.go index 668e87d653b2..d510feb3db9b 100644 --- a/vendor/github.com/docker/docker/client/network_create.go +++ b/vendor/github.com/docker/docker/client/network_create.go @@ -10,12 +10,16 @@ import ( // NetworkCreate creates a new network in the docker host. func (cli *Client) NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) { + var response types.NetworkCreateResponse + // Make sure we negotiated (if the client is configured to do so), // as code below contains API-version specific handling of options. // // Normally, version-negotiation (if enabled) would not happen until // the API request is made. - cli.checkVersion(ctx) + if err := cli.checkVersion(ctx); err != nil { + return response, err + } networkCreateRequest := types.NetworkCreateRequest{ NetworkCreate: options, @@ -25,7 +29,6 @@ func (cli *Client) NetworkCreate(ctx context.Context, name string, options types networkCreateRequest.CheckDuplicate = true //nolint:staticcheck // ignore SA1019: CheckDuplicate is deprecated since API v1.44. } - var response types.NetworkCreateResponse serverResp, err := cli.post(ctx, "/networks/create", nil, networkCreateRequest, nil) defer ensureReaderClosed(serverResp) if err != nil { diff --git a/vendor/github.com/docker/docker/client/ping.go b/vendor/github.com/docker/docker/client/ping.go index dfd1042fab26..bf3e9b1cd6d5 100644 --- a/vendor/github.com/docker/docker/client/ping.go +++ b/vendor/github.com/docker/docker/client/ping.go @@ -14,7 +14,10 @@ import ( // Ping pings the server and returns the value of the "Docker-Experimental", // "Builder-Version", "OS-Type" & "API-Version" headers. It attempts to use // a HEAD request on the endpoint, but falls back to GET if HEAD is not supported -// by the daemon. +// by the daemon. It ignores internal server errors returned by the API, which +// may be returned if the daemon is in an unhealthy state, but returns errors +// for other non-success status codes, failing to connect to the API, or failing +// to parse the API response. func (cli *Client) Ping(ctx context.Context) (types.Ping, error) { var ping types.Ping diff --git a/vendor/github.com/docker/docker/client/request.go b/vendor/github.com/docker/docker/client/request.go index efe07bb9ea59..50e213b50a08 100644 --- a/vendor/github.com/docker/docker/client/request.go +++ b/vendor/github.com/docker/docker/client/request.go @@ -134,17 +134,18 @@ func (cli *Client) sendRequest(ctx context.Context, method, path string, query u return resp, errdefs.FromStatusCode(err, resp.statusCode) } +// FIXME(thaJeztah): Should this actually return a serverResp when a connection error occurred? func (cli *Client) doRequest(req *http.Request) (serverResponse, error) { serverResp := serverResponse{statusCode: -1, reqURL: req.URL} resp, err := cli.client.Do(req) if err != nil { if cli.scheme != "https" && strings.Contains(err.Error(), "malformed HTTP response") { - return serverResp, fmt.Errorf("%v.\n* Are you trying to connect to a TLS-enabled daemon without TLS?", err) + return serverResp, errConnectionFailed{fmt.Errorf("%v.\n* Are you trying to connect to a TLS-enabled daemon without TLS?", err)} } if cli.scheme == "https" && strings.Contains(err.Error(), "bad certificate") { - return serverResp, errors.Wrap(err, "the server probably has client authentication (--tlsverify) enabled; check your TLS client certification settings") + return serverResp, errConnectionFailed{errors.Wrap(err, "the server probably has client authentication (--tlsverify) enabled; check your TLS client certification settings")} } // Don't decorate context sentinel errors; users may be comparing to @@ -156,12 +157,13 @@ func (cli *Client) doRequest(req *http.Request) (serverResponse, error) { if uErr, ok := err.(*url.Error); ok { if nErr, ok := uErr.Err.(*net.OpError); ok { if os.IsPermission(nErr.Err) { - return serverResp, errors.Wrapf(err, "permission denied while trying to connect to the Docker daemon socket at %v", cli.host) + return serverResp, errConnectionFailed{errors.Wrapf(err, "permission denied while trying to connect to the Docker daemon socket at %v", cli.host)} } } } if nErr, ok := err.(net.Error); ok { + // FIXME(thaJeztah): any net.Error should be considered a connection error (but we should include the original error)? if nErr.Timeout() { return serverResp, ErrorConnectionFailed(cli.host) } @@ -190,7 +192,7 @@ func (cli *Client) doRequest(req *http.Request) (serverResponse, error) { } } - return serverResp, errors.Wrap(err, "error during connect") + return serverResp, errConnectionFailed{errors.Wrap(err, "error during connect")} } if resp != nil { diff --git a/vendor/github.com/docker/docker/client/service_create.go b/vendor/github.com/docker/docker/client/service_create.go index 2ebb5ee3a580..b72cb420d49e 100644 --- a/vendor/github.com/docker/docker/client/service_create.go +++ b/vendor/github.com/docker/docker/client/service_create.go @@ -25,7 +25,9 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, // // Normally, version-negotiation (if enabled) would not happen until // the API request is made. - cli.checkVersion(ctx) + if err := cli.checkVersion(ctx); err != nil { + return response, err + } // Make sure containerSpec is not nil when no runtime is set or the runtime is set to container if service.TaskTemplate.ContainerSpec == nil && (service.TaskTemplate.Runtime == "" || service.TaskTemplate.Runtime == swarm.RuntimeContainer) { diff --git a/vendor/github.com/docker/docker/client/service_update.go b/vendor/github.com/docker/docker/client/service_update.go index e05eebf56657..d2f03f02f07c 100644 --- a/vendor/github.com/docker/docker/client/service_update.go +++ b/vendor/github.com/docker/docker/client/service_update.go @@ -16,18 +16,18 @@ import ( // It should be the value as set *before* the update. You can find this value in the Meta field // of swarm.Service, which can be found using ServiceInspectWithRaw. func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) { + response := swarm.ServiceUpdateResponse{} + // Make sure we negotiated (if the client is configured to do so), // as code below contains API-version specific handling of options. // // Normally, version-negotiation (if enabled) would not happen until // the API request is made. - cli.checkVersion(ctx) - - var ( - query = url.Values{} - response = swarm.ServiceUpdateResponse{} - ) + if err := cli.checkVersion(ctx); err != nil { + return response, err + } + query := url.Values{} if options.RegistryAuthFrom != "" { query.Set("registryAuthFrom", options.RegistryAuthFrom) } diff --git a/vendor/github.com/docker/docker/client/volume_remove.go b/vendor/github.com/docker/docker/client/volume_remove.go index 31e08cb97597..b8bdc5ae8585 100644 --- a/vendor/github.com/docker/docker/client/volume_remove.go +++ b/vendor/github.com/docker/docker/client/volume_remove.go @@ -16,7 +16,9 @@ func (cli *Client) VolumeRemove(ctx context.Context, volumeID string, force bool // // Normally, version-negotiation (if enabled) would not happen until // the API request is made. - cli.checkVersion(ctx) + if err := cli.checkVersion(ctx); err != nil { + return err + } if versions.GreaterThanOrEqualTo(cli.version, "1.25") { query.Set("force", "1") } diff --git a/vendor/github.com/docker/docker/pkg/ioutils/readers.go b/vendor/github.com/docker/docker/pkg/ioutils/readers.go index de00b95e3f64..e03d3fee7574 100644 --- a/vendor/github.com/docker/docker/pkg/ioutils/readers.go +++ b/vendor/github.com/docker/docker/pkg/ioutils/readers.go @@ -3,11 +3,15 @@ package ioutils // import "github.com/docker/docker/pkg/ioutils" import ( "context" "io" + "runtime/debug" + "sync/atomic" // make sure crypto.SHA256, crypto.sha512 and crypto.SHA384 are registered // TODO remove once https://github.com/opencontainers/go-digest/pull/64 is merged. _ "crypto/sha256" _ "crypto/sha512" + + "github.com/containerd/log" ) // ReadCloserWrapper wraps an io.Reader, and implements an io.ReadCloser @@ -16,10 +20,15 @@ import ( type ReadCloserWrapper struct { io.Reader closer func() error + closed atomic.Bool } // Close calls back the passed closer function func (r *ReadCloserWrapper) Close() error { + if !r.closed.CompareAndSwap(false, true) { + subsequentCloseWarn("ReadCloserWrapper") + return nil + } return r.closer() } @@ -87,6 +96,7 @@ type cancelReadCloser struct { cancel func() pR *io.PipeReader // Stream to read from pW *io.PipeWriter + closed atomic.Bool } // NewCancelReadCloser creates a wrapper that closes the ReadCloser when the @@ -146,6 +156,17 @@ func (p *cancelReadCloser) closeWithError(err error) { // Close closes the wrapper its underlying reader. It will cause // future calls to Read to return io.EOF. func (p *cancelReadCloser) Close() error { + if !p.closed.CompareAndSwap(false, true) { + subsequentCloseWarn("cancelReadCloser") + return nil + } p.closeWithError(io.EOF) return nil } + +func subsequentCloseWarn(name string) { + log.G(context.TODO()).Error("subsequent attempt to close " + name) + if log.GetLevel() >= log.DebugLevel { + log.G(context.TODO()).Errorf("stack trace: %s", string(debug.Stack())) + } +} diff --git a/vendor/github.com/docker/docker/pkg/ioutils/writers.go b/vendor/github.com/docker/docker/pkg/ioutils/writers.go index 61c679497dab..1f50602f28c8 100644 --- a/vendor/github.com/docker/docker/pkg/ioutils/writers.go +++ b/vendor/github.com/docker/docker/pkg/ioutils/writers.go @@ -1,6 +1,9 @@ package ioutils // import "github.com/docker/docker/pkg/ioutils" -import "io" +import ( + "io" + "sync/atomic" +) // NopWriter represents a type which write operation is nop. type NopWriter struct{} @@ -29,9 +32,14 @@ func (f *NopFlusher) Flush() {} type writeCloserWrapper struct { io.Writer closer func() error + closed atomic.Bool } func (r *writeCloserWrapper) Close() error { + if !r.closed.CompareAndSwap(false, true) { + subsequentCloseWarn("WriteCloserWrapper") + return nil + } return r.closer() } diff --git a/vendor/github.com/docker/docker/pkg/streamformatter/streamformatter.go b/vendor/github.com/docker/docker/pkg/streamformatter/streamformatter.go index b0456e580dc9..098df6b5236b 100644 --- a/vendor/github.com/docker/docker/pkg/streamformatter/streamformatter.go +++ b/vendor/github.com/docker/docker/pkg/streamformatter/streamformatter.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "io" + "sync" "github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/pkg/progress" @@ -109,6 +110,7 @@ type progressOutput struct { sf formatProgress out io.Writer newLines bool + mu sync.Mutex } // WriteProgress formats progress information from a ProgressReader. @@ -120,6 +122,9 @@ func (out *progressOutput) WriteProgress(prog progress.Progress) error { jsonProgress := jsonmessage.JSONProgress{Current: prog.Current, Total: prog.Total, HideCounts: prog.HideCounts, Units: prog.Units} formatted = out.sf.formatProgress(prog.ID, prog.Action, &jsonProgress, prog.Aux) } + + out.mu.Lock() + defer out.mu.Unlock() _, err := out.out.Write(formatted) if err != nil { return err diff --git a/vendor/github.com/docker/docker/pkg/system/xattrs.go b/vendor/github.com/docker/docker/pkg/system/xattrs.go new file mode 100644 index 000000000000..b3f4e8a21f50 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/system/xattrs.go @@ -0,0 +1,18 @@ +package system // import "github.com/docker/docker/pkg/system" + +type XattrError struct { + Op string + Attr string + Path string + Err error +} + +func (e *XattrError) Error() string { return e.Op + " " + e.Attr + " " + e.Path + ": " + e.Err.Error() } + +func (e *XattrError) Unwrap() error { return e.Err } + +// Timeout reports whether this error represents a timeout. +func (e *XattrError) Timeout() bool { + t, ok := e.Err.(interface{ Timeout() bool }) + return ok && t.Timeout() +} diff --git a/vendor/github.com/docker/docker/pkg/system/xattrs_linux.go b/vendor/github.com/docker/docker/pkg/system/xattrs_linux.go index 4196b281b364..facfbb3126f1 100644 --- a/vendor/github.com/docker/docker/pkg/system/xattrs_linux.go +++ b/vendor/github.com/docker/docker/pkg/system/xattrs_linux.go @@ -1,8 +1,6 @@ package system // import "github.com/docker/docker/pkg/system" import ( - "io/fs" - "golang.org/x/sys/unix" ) @@ -10,8 +8,8 @@ import ( // and associated with the given path in the file system. // It will returns a nil slice and nil error if the xattr is not set. func Lgetxattr(path string, attr string) ([]byte, error) { - pathErr := func(err error) ([]byte, error) { - return nil, &fs.PathError{Op: "lgetxattr", Path: path, Err: err} + sysErr := func(err error) ([]byte, error) { + return nil, &XattrError{Op: "lgetxattr", Attr: attr, Path: path, Err: err} } // Start with a 128 length byte array @@ -22,7 +20,7 @@ func Lgetxattr(path string, attr string) ([]byte, error) { // Buffer too small, use zero-sized buffer to get the actual size sz, errno = unix.Lgetxattr(path, attr, []byte{}) if errno != nil { - return pathErr(errno) + return sysErr(errno) } dest = make([]byte, sz) sz, errno = unix.Lgetxattr(path, attr, dest) @@ -32,7 +30,7 @@ func Lgetxattr(path string, attr string) ([]byte, error) { case errno == unix.ENODATA: return nil, nil case errno != nil: - return pathErr(errno) + return sysErr(errno) } return dest[:sz], nil @@ -43,7 +41,7 @@ func Lgetxattr(path string, attr string) ([]byte, error) { func Lsetxattr(path string, attr string, data []byte, flags int) error { err := unix.Lsetxattr(path, attr, data, flags) if err != nil { - return &fs.PathError{Op: "lsetxattr", Path: path, Err: err} + return &XattrError{Op: "lsetxattr", Attr: attr, Path: path, Err: err} } return nil } diff --git a/vendor/github.com/go-logr/logr/README.md b/vendor/github.com/go-logr/logr/README.md index ab5931181317..a8c29bfbd530 100644 --- a/vendor/github.com/go-logr/logr/README.md +++ b/vendor/github.com/go-logr/logr/README.md @@ -1,6 +1,7 @@ # A minimal logging API for Go [![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/logr.svg)](https://pkg.go.dev/github.com/go-logr/logr) +[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/go-logr/logr/badge)](https://securityscorecards.dev/viewer/?platform=github.com&org=go-logr&repo=logr) logr offers an(other) opinion on how Go programs and libraries can do logging without becoming coupled to a particular logging implementation. This is not @@ -73,6 +74,29 @@ received: If the Go standard library had defined an interface for logging, this project probably would not be needed. Alas, here we are. +When the Go developers started developing such an interface with +[slog](https://github.com/golang/go/issues/56345), they adopted some of the +logr design but also left out some parts and changed others: + +| Feature | logr | slog | +|---------|------|------| +| High-level API | `Logger` (passed by value) | `Logger` (passed by [pointer](https://github.com/golang/go/issues/59126)) | +| Low-level API | `LogSink` | `Handler` | +| Stack unwinding | done by `LogSink` | done by `Logger` | +| Skipping helper functions | `WithCallDepth`, `WithCallStackHelper` | [not supported by Logger](https://github.com/golang/go/issues/59145) | +| Generating a value for logging on demand | `Marshaler` | `LogValuer` | +| Log levels | >= 0, higher meaning "less important" | positive and negative, with 0 for "info" and higher meaning "more important" | +| Error log entries | always logged, don't have a verbosity level | normal log entries with level >= `LevelError` | +| Passing logger via context | `NewContext`, `FromContext` | no API | +| Adding a name to a logger | `WithName` | no API | +| Modify verbosity of log entries in a call chain | `V` | no API | +| Grouping of key/value pairs | not supported | `WithGroup`, `GroupValue` | + +The high-level slog API is explicitly meant to be one of many different APIs +that can be layered on top of a shared `slog.Handler`. logr is one such +alternative API, with [interoperability](#slog-interoperability) provided by the [`slogr`](slogr) +package. + ### Inspiration Before you consider this package, please read [this blog post by the @@ -118,6 +142,91 @@ There are implementations for the following logging libraries: - **github.com/go-kit/log**: [gokitlogr](https://github.com/tonglil/gokitlogr) (also compatible with github.com/go-kit/kit/log since v0.12.0) - **bytes.Buffer** (writing to a buffer): [bufrlogr](https://github.com/tonglil/buflogr) (useful for ensuring values were logged, like during testing) +## slog interoperability + +Interoperability goes both ways, using the `logr.Logger` API with a `slog.Handler` +and using the `slog.Logger` API with a `logr.LogSink`. [slogr](./slogr) provides `NewLogr` and +`NewSlogHandler` API calls to convert between a `logr.Logger` and a `slog.Handler`. +As usual, `slog.New` can be used to wrap such a `slog.Handler` in the high-level +slog API. `slogr` itself leaves that to the caller. + +## Using a `logr.Sink` as backend for slog + +Ideally, a logr sink implementation should support both logr and slog by +implementing both the normal logr interface(s) and `slogr.SlogSink`. Because +of a conflict in the parameters of the common `Enabled` method, it is [not +possible to implement both slog.Handler and logr.Sink in the same +type](https://github.com/golang/go/issues/59110). + +If both are supported, log calls can go from the high-level APIs to the backend +without the need to convert parameters. `NewLogr` and `NewSlogHandler` can +convert back and forth without adding additional wrappers, with one exception: +when `Logger.V` was used to adjust the verbosity for a `slog.Handler`, then +`NewSlogHandler` has to use a wrapper which adjusts the verbosity for future +log calls. + +Such an implementation should also support values that implement specific +interfaces from both packages for logging (`logr.Marshaler`, `slog.LogValuer`, +`slog.GroupValue`). logr does not convert those. + +Not supporting slog has several drawbacks: +- Recording source code locations works correctly if the handler gets called + through `slog.Logger`, but may be wrong in other cases. That's because a + `logr.Sink` does its own stack unwinding instead of using the program counter + provided by the high-level API. +- slog levels <= 0 can be mapped to logr levels by negating the level without a + loss of information. But all slog levels > 0 (e.g. `slog.LevelWarning` as + used by `slog.Logger.Warn`) must be mapped to 0 before calling the sink + because logr does not support "more important than info" levels. +- The slog group concept is supported by prefixing each key in a key/value + pair with the group names, separated by a dot. For structured output like + JSON it would be better to group the key/value pairs inside an object. +- Special slog values and interfaces don't work as expected. +- The overhead is likely to be higher. + +These drawbacks are severe enough that applications using a mixture of slog and +logr should switch to a different backend. + +## Using a `slog.Handler` as backend for logr + +Using a plain `slog.Handler` without support for logr works better than the +other direction: +- All logr verbosity levels can be mapped 1:1 to their corresponding slog level + by negating them. +- Stack unwinding is done by the `slogr.SlogSink` and the resulting program + counter is passed to the `slog.Handler`. +- Names added via `Logger.WithName` are gathered and recorded in an additional + attribute with `logger` as key and the names separated by slash as value. +- `Logger.Error` is turned into a log record with `slog.LevelError` as level + and an additional attribute with `err` as key, if an error was provided. + +The main drawback is that `logr.Marshaler` will not be supported. Types should +ideally support both `logr.Marshaler` and `slog.Valuer`. If compatibility +with logr implementations without slog support is not important, then +`slog.Valuer` is sufficient. + +## Context support for slog + +Storing a logger in a `context.Context` is not supported by +slog. `logr.NewContext` and `logr.FromContext` can be used with slog like this +to fill this gap: + + func HandlerFromContext(ctx context.Context) slog.Handler { + logger, err := logr.FromContext(ctx) + if err == nil { + return slogr.NewSlogHandler(logger) + } + return slog.Default().Handler() + } + + func ContextWithHandler(ctx context.Context, handler slog.Handler) context.Context { + return logr.NewContext(ctx, slogr.NewLogr(handler)) + } + +The downside is that storing and retrieving a `slog.Handler` needs more +allocations compared to using a `logr.Logger`. Therefore the recommendation is +to use the `logr.Logger` API in code which uses contextual logging. + ## FAQ ### Conceptual @@ -241,7 +350,9 @@ Otherwise, you can start out with `0` as "you always want to see this", Then gradually choose levels in between as you need them, working your way down from 10 (for debug and trace style logs) and up from 1 (for chattier -info-type logs.) +info-type logs). For reference, slog pre-defines -4 for debug logs +(corresponds to 4 in logr), which matches what is +[recommended for Kubernetes](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md#what-method-to-use). #### How do I choose my keys? diff --git a/vendor/github.com/go-logr/logr/SECURITY.md b/vendor/github.com/go-logr/logr/SECURITY.md new file mode 100644 index 000000000000..1ca756fc7b36 --- /dev/null +++ b/vendor/github.com/go-logr/logr/SECURITY.md @@ -0,0 +1,18 @@ +# Security Policy + +If you have discovered a security vulnerability in this project, please report it +privately. **Do not disclose it as a public issue.** This gives us time to work with you +to fix the issue before public exposure, reducing the chance that the exploit will be +used before a patch is released. + +You may submit the report in the following ways: + +- send an email to go-logr-security@googlegroups.com +- send us a [private vulnerability report](https://github.com/go-logr/logr/security/advisories/new) + +Please provide the following information in your report: + +- A description of the vulnerability and its impact +- How to reproduce the issue + +We ask that you give us 90 days to work on a fix before public exposure. diff --git a/vendor/github.com/go-logr/logr/funcr/funcr.go b/vendor/github.com/go-logr/logr/funcr/funcr.go index e52f0cd01e2e..12e5807cc5c3 100644 --- a/vendor/github.com/go-logr/logr/funcr/funcr.go +++ b/vendor/github.com/go-logr/logr/funcr/funcr.go @@ -116,17 +116,17 @@ type Options struct { // Equivalent hooks are offered for key-value pairs saved via // logr.Logger.WithValues or Formatter.AddValues (see RenderValuesHook) and // for user-provided pairs (see RenderArgsHook). - RenderBuiltinsHook func(kvList []interface{}) []interface{} + RenderBuiltinsHook func(kvList []any) []any // RenderValuesHook is the same as RenderBuiltinsHook, except that it is // only called for key-value pairs saved via logr.Logger.WithValues. See // RenderBuiltinsHook for more details. - RenderValuesHook func(kvList []interface{}) []interface{} + RenderValuesHook func(kvList []any) []any // RenderArgsHook is the same as RenderBuiltinsHook, except that it is only // called for key-value pairs passed directly to Info and Error. See // RenderBuiltinsHook for more details. - RenderArgsHook func(kvList []interface{}) []interface{} + RenderArgsHook func(kvList []any) []any // MaxLogDepth tells funcr how many levels of nested fields (e.g. a struct // that contains a struct, etc.) it may log. Every time it finds a struct, @@ -163,7 +163,7 @@ func (l fnlogger) WithName(name string) logr.LogSink { return &l } -func (l fnlogger) WithValues(kvList ...interface{}) logr.LogSink { +func (l fnlogger) WithValues(kvList ...any) logr.LogSink { l.Formatter.AddValues(kvList) return &l } @@ -173,12 +173,12 @@ func (l fnlogger) WithCallDepth(depth int) logr.LogSink { return &l } -func (l fnlogger) Info(level int, msg string, kvList ...interface{}) { +func (l fnlogger) Info(level int, msg string, kvList ...any) { prefix, args := l.FormatInfo(level, msg, kvList) l.write(prefix, args) } -func (l fnlogger) Error(err error, msg string, kvList ...interface{}) { +func (l fnlogger) Error(err error, msg string, kvList ...any) { prefix, args := l.FormatError(err, msg, kvList) l.write(prefix, args) } @@ -229,7 +229,7 @@ func newFormatter(opts Options, outfmt outputFormat) Formatter { type Formatter struct { outputFormat outputFormat prefix string - values []interface{} + values []any valuesStr string depth int opts *Options @@ -246,10 +246,10 @@ const ( ) // PseudoStruct is a list of key-value pairs that gets logged as a struct. -type PseudoStruct []interface{} +type PseudoStruct []any // render produces a log line, ready to use. -func (f Formatter) render(builtins, args []interface{}) string { +func (f Formatter) render(builtins, args []any) string { // Empirically bytes.Buffer is faster than strings.Builder for this. buf := bytes.NewBuffer(make([]byte, 0, 1024)) if f.outputFormat == outputJSON { @@ -292,7 +292,7 @@ func (f Formatter) render(builtins, args []interface{}) string { // This function returns a potentially modified version of kvList, which // ensures that there is a value for every key (adding a value if needed) and // that each key is a string (substituting a key if needed). -func (f Formatter) flatten(buf *bytes.Buffer, kvList []interface{}, continuing bool, escapeKeys bool) []interface{} { +func (f Formatter) flatten(buf *bytes.Buffer, kvList []any, continuing bool, escapeKeys bool) []any { // This logic overlaps with sanitize() but saves one type-cast per key, // which can be measurable. if len(kvList)%2 != 0 { @@ -334,7 +334,7 @@ func (f Formatter) flatten(buf *bytes.Buffer, kvList []interface{}, continuing b return kvList } -func (f Formatter) pretty(value interface{}) string { +func (f Formatter) pretty(value any) string { return f.prettyWithFlags(value, 0, 0) } @@ -343,7 +343,7 @@ const ( ) // TODO: This is not fast. Most of the overhead goes here. -func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) string { +func (f Formatter) prettyWithFlags(value any, flags uint32, depth int) string { if depth > f.opts.MaxLogDepth { return `""` } @@ -614,7 +614,7 @@ func isEmpty(v reflect.Value) bool { return false } -func invokeMarshaler(m logr.Marshaler) (ret interface{}) { +func invokeMarshaler(m logr.Marshaler) (ret any) { defer func() { if r := recover(); r != nil { ret = fmt.Sprintf("", r) @@ -675,12 +675,12 @@ func (f Formatter) caller() Caller { const noValue = "" -func (f Formatter) nonStringKey(v interface{}) string { +func (f Formatter) nonStringKey(v any) string { return fmt.Sprintf("", f.snippet(v)) } // snippet produces a short snippet string of an arbitrary value. -func (f Formatter) snippet(v interface{}) string { +func (f Formatter) snippet(v any) string { const snipLen = 16 snip := f.pretty(v) @@ -693,7 +693,7 @@ func (f Formatter) snippet(v interface{}) string { // sanitize ensures that a list of key-value pairs has a value for every key // (adding a value if needed) and that each key is a string (substituting a key // if needed). -func (f Formatter) sanitize(kvList []interface{}) []interface{} { +func (f Formatter) sanitize(kvList []any) []any { if len(kvList)%2 != 0 { kvList = append(kvList, noValue) } @@ -727,8 +727,8 @@ func (f Formatter) GetDepth() int { // FormatInfo renders an Info log message into strings. The prefix will be // empty when no names were set (via AddNames), or when the output is // configured for JSON. -func (f Formatter) FormatInfo(level int, msg string, kvList []interface{}) (prefix, argsStr string) { - args := make([]interface{}, 0, 64) // using a constant here impacts perf +func (f Formatter) FormatInfo(level int, msg string, kvList []any) (prefix, argsStr string) { + args := make([]any, 0, 64) // using a constant here impacts perf prefix = f.prefix if f.outputFormat == outputJSON { args = append(args, "logger", prefix) @@ -745,10 +745,10 @@ func (f Formatter) FormatInfo(level int, msg string, kvList []interface{}) (pref } // FormatError renders an Error log message into strings. The prefix will be -// empty when no names were set (via AddNames), or when the output is +// empty when no names were set (via AddNames), or when the output is // configured for JSON. -func (f Formatter) FormatError(err error, msg string, kvList []interface{}) (prefix, argsStr string) { - args := make([]interface{}, 0, 64) // using a constant here impacts perf +func (f Formatter) FormatError(err error, msg string, kvList []any) (prefix, argsStr string) { + args := make([]any, 0, 64) // using a constant here impacts perf prefix = f.prefix if f.outputFormat == outputJSON { args = append(args, "logger", prefix) @@ -761,12 +761,12 @@ func (f Formatter) FormatError(err error, msg string, kvList []interface{}) (pre args = append(args, "caller", f.caller()) } args = append(args, "msg", msg) - var loggableErr interface{} + var loggableErr any if err != nil { loggableErr = err.Error() } args = append(args, "error", loggableErr) - return f.prefix, f.render(args, kvList) + return prefix, f.render(args, kvList) } // AddName appends the specified name. funcr uses '/' characters to separate @@ -781,7 +781,7 @@ func (f *Formatter) AddName(name string) { // AddValues adds key-value pairs to the set of saved values to be logged with // each log line. -func (f *Formatter) AddValues(kvList []interface{}) { +func (f *Formatter) AddValues(kvList []any) { // Three slice args forces a copy. n := len(f.values) f.values = append(f.values[:n:n], kvList...) diff --git a/vendor/github.com/go-logr/logr/logr.go b/vendor/github.com/go-logr/logr/logr.go index e027aea3fd38..2a5075a180f4 100644 --- a/vendor/github.com/go-logr/logr/logr.go +++ b/vendor/github.com/go-logr/logr/logr.go @@ -127,9 +127,9 @@ limitations under the License. // such a value can call its methods without having to check whether the // instance is ready for use. // -// Calling methods with the null logger (Logger{}) as instance will crash -// because it has no LogSink. Therefore this null logger should never be passed -// around. For cases where passing a logger is optional, a pointer to Logger +// The zero logger (= Logger{}) is identical to Discard() and discards all log +// entries. Code that receives a Logger by value can simply call it, the methods +// will never crash. For cases where passing a logger is optional, a pointer to Logger // should be used. // // # Key Naming Conventions @@ -258,6 +258,12 @@ type Logger struct { // Enabled tests whether this Logger is enabled. For example, commandline // flags might be used to set the logging verbosity and disable some info logs. func (l Logger) Enabled() bool { + // Some implementations of LogSink look at the caller in Enabled (e.g. + // different verbosity levels per package or file), but we only pass one + // CallDepth in (via Init). This means that all calls from Logger to the + // LogSink's Enabled, Info, and Error methods must have the same number of + // frames. In other words, Logger methods can't call other Logger methods + // which call these LogSink methods unless we do it the same in all paths. return l.sink != nil && l.sink.Enabled(l.level) } @@ -267,11 +273,11 @@ func (l Logger) Enabled() bool { // line. The key/value pairs can then be used to add additional variable // information. The key/value pairs must alternate string keys and arbitrary // values. -func (l Logger) Info(msg string, keysAndValues ...interface{}) { +func (l Logger) Info(msg string, keysAndValues ...any) { if l.sink == nil { return } - if l.Enabled() { + if l.sink.Enabled(l.level) { // see comment in Enabled if withHelper, ok := l.sink.(CallStackHelperLogSink); ok { withHelper.GetCallStackHelper()() } @@ -289,7 +295,7 @@ func (l Logger) Info(msg string, keysAndValues ...interface{}) { // while the err argument should be used to attach the actual error that // triggered this log line, if present. The err parameter is optional // and nil may be passed instead of an error instance. -func (l Logger) Error(err error, msg string, keysAndValues ...interface{}) { +func (l Logger) Error(err error, msg string, keysAndValues ...any) { if l.sink == nil { return } @@ -314,9 +320,16 @@ func (l Logger) V(level int) Logger { return l } +// GetV returns the verbosity level of the logger. If the logger's LogSink is +// nil as in the Discard logger, this will always return 0. +func (l Logger) GetV() int { + // 0 if l.sink nil because of the if check in V above. + return l.level +} + // WithValues returns a new Logger instance with additional key/value pairs. // See Info for documentation on how key/value pairs work. -func (l Logger) WithValues(keysAndValues ...interface{}) Logger { +func (l Logger) WithValues(keysAndValues ...any) Logger { if l.sink == nil { return l } @@ -467,15 +480,15 @@ type LogSink interface { // The level argument is provided for optional logging. This method will // only be called when Enabled(level) is true. See Logger.Info for more // details. - Info(level int, msg string, keysAndValues ...interface{}) + Info(level int, msg string, keysAndValues ...any) // Error logs an error, with the given message and key/value pairs as // context. See Logger.Error for more details. - Error(err error, msg string, keysAndValues ...interface{}) + Error(err error, msg string, keysAndValues ...any) // WithValues returns a new LogSink with additional key/value pairs. See // Logger.WithValues for more details. - WithValues(keysAndValues ...interface{}) LogSink + WithValues(keysAndValues ...any) LogSink // WithName returns a new LogSink with the specified name appended. See // Logger.WithName for more details. @@ -546,5 +559,5 @@ type Marshaler interface { // with exported fields // // It may return any value of any type. - MarshalLog() interface{} + MarshalLog() any } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go index 303e5505e411..9509014e87c0 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go @@ -34,7 +34,7 @@ const ( RequestCount = "http.server.request_count" // Incoming request count total RequestContentLength = "http.server.request_content_length" // Incoming request bytes total ResponseContentLength = "http.server.response_content_length" // Incoming response bytes total - ServerLatency = "http.server.duration" // Incoming end to end duration, microseconds + ServerLatency = "http.server.duration" // Incoming end to end duration, milliseconds ) // Filter is a predicate used to determine whether a given http.request should @@ -42,5 +42,5 @@ const ( type Filter func(*http.Request) bool func newTracer(tp trace.TracerProvider) trace.Tracer { - return tp.Tracer(instrumentationName, trace.WithInstrumentationVersion(Version())) + return tp.Tracer(ScopeName, trace.WithInstrumentationVersion(Version())) } diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go index e4fa1b8d9d61..a1b5b5e5aa8e 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go @@ -25,9 +25,8 @@ import ( "go.opentelemetry.io/otel/trace" ) -const ( - instrumentationName = "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" -) +// ScopeName is the instrumentation scope name. +const ScopeName = "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" // config represents the configuration options available for the http.Handler // and http.Transport types. @@ -76,7 +75,7 @@ func newConfig(opts ...Option) *config { } c.Meter = c.MeterProvider.Meter( - instrumentationName, + ScopeName, metric.WithInstrumentationVersion(Version()), ) diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go index b2fbe07841ca..9a8260059d99 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go @@ -107,13 +107,25 @@ func (h *middleware) createMeasures() { h.counters = make(map[string]metric.Int64Counter) h.valueRecorders = make(map[string]metric.Float64Histogram) - requestBytesCounter, err := h.meter.Int64Counter(RequestContentLength) + requestBytesCounter, err := h.meter.Int64Counter( + RequestContentLength, + metric.WithUnit("By"), + metric.WithDescription("Measures the size of HTTP request content length (uncompressed)"), + ) handleErr(err) - responseBytesCounter, err := h.meter.Int64Counter(ResponseContentLength) + responseBytesCounter, err := h.meter.Int64Counter( + ResponseContentLength, + metric.WithUnit("By"), + metric.WithDescription("Measures the size of HTTP response content length (uncompressed)"), + ) handleErr(err) - serverLatencyMeasure, err := h.meter.Float64Histogram(ServerLatency) + serverLatencyMeasure, err := h.meter.Float64Histogram( + ServerLatency, + metric.WithUnit("ms"), + metric.WithDescription("Measures the duration of HTTP request handling"), + ) handleErr(err) h.counters[RequestContentLength] = requestBytesCounter diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go index 6eace875cfe4..bd41c1804210 100644 --- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go +++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go @@ -16,7 +16,7 @@ package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http // Version is the current release version of the otelhttp instrumentation. func Version() string { - return "0.45.0" + return "0.46.1" // This string is updated by the pre_release.sh script during release } diff --git a/vendor/go.opentelemetry.io/otel/.gitignore b/vendor/go.opentelemetry.io/otel/.gitignore index f3355c852be8..895c7664beb5 100644 --- a/vendor/go.opentelemetry.io/otel/.gitignore +++ b/vendor/go.opentelemetry.io/otel/.gitignore @@ -14,12 +14,9 @@ go.work.sum gen/ /example/dice/dice -/example/fib/fib -/example/fib/traces.txt -/example/jaeger/jaeger /example/namedtracer/namedtracer +/example/otel-collector/otel-collector /example/opencensus/opencensus /example/passthrough/passthrough /example/prometheus/prometheus /example/zipkin/zipkin -/example/otel-collector/otel-collector diff --git a/vendor/go.opentelemetry.io/otel/.golangci.yml b/vendor/go.opentelemetry.io/otel/.golangci.yml index 6e8eeec00faf..a62511f382e2 100644 --- a/vendor/go.opentelemetry.io/otel/.golangci.yml +++ b/vendor/go.opentelemetry.io/otel/.golangci.yml @@ -12,8 +12,9 @@ linters: - depguard - errcheck - godot - - gofmt + - gofumpt - goimports + - gosec - gosimple - govet - ineffassign @@ -53,6 +54,20 @@ issues: text: "calls to (.+) only in main[(][)] or init[(][)] functions" linters: - revive + # It's okay to not run gosec in a test. + - path: _test\.go + linters: + - gosec + # Igonoring gosec G404: Use of weak random number generator (math/rand instead of crypto/rand) + # as we commonly use it in tests and examples. + - text: "G404:" + linters: + - gosec + # Igonoring gosec G402: TLS MinVersion too low + # as the https://pkg.go.dev/crypto/tls#Config handles MinVersion default well. + - text: "G402: TLS MinVersion too low." + linters: + - gosec include: # revive exported should have comment or be unexported. - EXC0012 diff --git a/vendor/go.opentelemetry.io/otel/CHANGELOG.md b/vendor/go.opentelemetry.io/otel/CHANGELOG.md index 3e5c35b5dcc6..24874f856e35 100644 --- a/vendor/go.opentelemetry.io/otel/CHANGELOG.md +++ b/vendor/go.opentelemetry.io/otel/CHANGELOG.md @@ -8,6 +8,85 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +## [1.21.0/0.44.0] 2023-11-16 + +### Removed + +- Remove the deprecated `go.opentelemetry.io/otel/bridge/opencensus.NewTracer`. (#4706) +- Remove the deprecated `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` module. (#4707) +- Remove the deprecated `go.opentelemetry.io/otel/example/view` module. (#4708) +- Remove the deprecated `go.opentelemetry.io/otel/example/fib` module. (#4723) + +### Fixed + +- Do not parse non-protobuf responses in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4719) +- Do not parse non-protobuf responses in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#4719) + +## [1.20.0/0.43.0] 2023-11-10 + +This release brings a breaking change for custom trace API implementations. Some interfaces (`TracerProvider`, `Tracer`, `Span`) now embed the `go.opentelemetry.io/otel/trace/embedded` types. Implementors need to update their implementations based on what they want the default behavior to be. See the "API Implementations" section of the [trace API] package documentation for more information about how to accomplish this. + +### Added + +- Add `go.opentelemetry.io/otel/bridge/opencensus.InstallTraceBridge`, which installs the OpenCensus trace bridge, and replaces `opencensus.NewTracer`. (#4567) +- Add scope version to trace and metric bridges in `go.opentelemetry.io/otel/bridge/opencensus`. (#4584) +- Add the `go.opentelemetry.io/otel/trace/embedded` package to be embedded in the exported trace API interfaces. (#4620) +- Add the `go.opentelemetry.io/otel/trace/noop` package as a default no-op implementation of the trace API. (#4620) +- Add context propagation in `go.opentelemetry.io/otel/example/dice`. (#4644) +- Add view configuration to `go.opentelemetry.io/otel/example/prometheus`. (#4649) +- Add `go.opentelemetry.io/otel/metric.WithExplicitBucketBoundaries`, which allows defining default explicit bucket boundaries when creating histogram instruments. (#4603) +- Add `Version` function in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4660) +- Add `Version` function in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4660) +- Add Summary, SummaryDataPoint, and QuantileValue to `go.opentelemetry.io/sdk/metric/metricdata`. (#4622) +- `go.opentelemetry.io/otel/bridge/opencensus.NewMetricProducer` now supports exemplars from OpenCensus. (#4585) +- Add support for `WithExplicitBucketBoundaries` in `go.opentelemetry.io/otel/sdk/metric`. (#4605) +- Add support for Summary metrics in `go.opentelemetry.io/otel/bridge/opencensus`. (#4668) + +### Deprecated + +- Deprecate `go.opentelemetry.io/otel/bridge/opencensus.NewTracer` in favor of `opencensus.InstallTraceBridge`. (#4567) +- Deprecate `go.opentelemetry.io/otel/example/fib` package is in favor of `go.opentelemetry.io/otel/example/dice`. (#4618) +- Deprecate `go.opentelemetry.io/otel/trace.NewNoopTracerProvider`. + Use the added `NewTracerProvider` function in `go.opentelemetry.io/otel/trace/noop` instead. (#4620) +- Deprecate `go.opentelemetry.io/otel/example/view` package in favor of `go.opentelemetry.io/otel/example/prometheus`. (#4649) +- Deprecate `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#4693) + +### Changed + +- `go.opentelemetry.io/otel/bridge/opencensus.NewMetricProducer` returns a `*MetricProducer` struct instead of the metric.Producer interface. (#4583) +- The `TracerProvider` in `go.opentelemetry.io/otel/trace` now embeds the `go.opentelemetry.io/otel/trace/embedded.TracerProvider` type. + This extends the `TracerProvider` interface and is is a breaking change for any existing implementation. + Implementors need to update their implementations based on what they want the default behavior of the interface to be. + See the "API Implementations" section of the `go.opentelemetry.io/otel/trace` package documentation for more information about how to accomplish this. (#4620) +- The `Tracer` in `go.opentelemetry.io/otel/trace` now embeds the `go.opentelemetry.io/otel/trace/embedded.Tracer` type. + This extends the `Tracer` interface and is is a breaking change for any existing implementation. + Implementors need to update their implementations based on what they want the default behavior of the interface to be. + See the "API Implementations" section of the `go.opentelemetry.io/otel/trace` package documentation for more information about how to accomplish this. (#4620) +- The `Span` in `go.opentelemetry.io/otel/trace` now embeds the `go.opentelemetry.io/otel/trace/embedded.Span` type. + This extends the `Span` interface and is is a breaking change for any existing implementation. + Implementors need to update their implementations based on what they want the default behavior of the interface to be. + See the "API Implementations" section of the `go.opentelemetry.io/otel/trace` package documentation for more information about how to accomplish this. (#4620) +- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` does no longer depend on `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#4660) +- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` does no longer depend on `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#4660) +- Retry for `502 Bad Gateway` and `504 Gateway Timeout` HTTP statuses in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4670) +- Retry for `502 Bad Gateway` and `504 Gateway Timeout` HTTP statuses in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#4670) +- Retry for `RESOURCE_EXHAUSTED` only if RetryInfo is returned in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4669) +- Retry for `RESOURCE_EXHAUSTED` only if RetryInfo is returned in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`. (#4669) +- Retry temporary HTTP request failures in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4679) +- Retry temporary HTTP request failures in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#4679) + +### Fixed + +- Fix improper parsing of characters such us `+`, `/` by `Parse` in `go.opentelemetry.io/otel/baggage` as they were rendered as a whitespace. (#4667) +- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_RESOURCE_ATTRIBUTES` in `go.opentelemetry.io/otel/sdk/resource` as they were rendered as a whitespace. (#4699) +- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_EXPORTER_OTLP_HEADERS` and `OTEL_EXPORTER_OTLP_METRICS_HEADERS` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` as they were rendered as a whitespace. (#4699) +- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_EXPORTER_OTLP_HEADERS` and `OTEL_EXPORTER_OTLP_METRICS_HEADERS` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` as they were rendered as a whitespace. (#4699) +- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_EXPORTER_OTLP_HEADERS` and `OTEL_EXPORTER_OTLP_TRACES_HEADERS` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlptracegrpc` as they were rendered as a whitespace. (#4699) +- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_EXPORTER_OTLP_HEADERS` and `OTEL_EXPORTER_OTLP_TRACES_HEADERS` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlptracehttp` as they were rendered as a whitespace. (#4699) +- In `go.opentelemetry.op/otel/exporters/prometheus`, the exporter no longer `Collect`s metrics after `Shutdown` is invoked. (#4648) +- Fix documentation for `WithCompressor` in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`. (#4695) +- Fix documentation for `WithCompressor` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4695) + ## [1.19.0/0.42.0/0.0.7] 2023-09-28 This release contains the first stable release of the OpenTelemetry Go [metric SDK]. @@ -2656,7 +2735,9 @@ It contains api and sdk for trace and meter. - CircleCI build CI manifest files. - CODEOWNERS file to track owners of this project. -[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.19.0...HEAD +[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.21.0...HEAD +[1.21.0/0.44.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.21.0 +[1.20.0/0.43.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.20.0 [1.19.0/0.42.0/0.0.7]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.19.0 [1.19.0-rc.1/0.42.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.19.0-rc.1 [1.18.0/0.41.0/0.0.6]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.18.0 @@ -2731,7 +2812,7 @@ It contains api and sdk for trace and meter. [Go 1.20]: https://go.dev/doc/go1.20 [Go 1.19]: https://go.dev/doc/go1.19 [Go 1.18]: https://go.dev/doc/go1.18 -[Go 1.19]: https://go.dev/doc/go1.19 [metric API]:https://pkg.go.dev/go.opentelemetry.io/otel/metric [metric SDK]:https://pkg.go.dev/go.opentelemetry.io/otel/sdk/metric +[trace API]:https://pkg.go.dev/go.opentelemetry.io/otel/trace diff --git a/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md b/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md index a00dbca7b083..850606ae6924 100644 --- a/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md +++ b/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md @@ -90,6 +90,10 @@ git push Open a pull request against the main `opentelemetry-go` repo. Be sure to add the pull request ID to the entry you added to `CHANGELOG.md`. +Avoid rebasing and force-pushing to your branch to facilitate reviewing the pull request. +Rewriting Git history makes it difficult to keep track of iterations during code review. +All pull requests are squashed to a single commit upon merge to `main`. + ### How to Receive Comments * If the PR is not ready for review, please put `[WIP]` in the title, diff --git a/vendor/go.opentelemetry.io/otel/Makefile b/vendor/go.opentelemetry.io/otel/Makefile index 5c311706b0c3..35fc189961b6 100644 --- a/vendor/go.opentelemetry.io/otel/Makefile +++ b/vendor/go.opentelemetry.io/otel/Makefile @@ -77,6 +77,9 @@ $(GOTMPL): PACKAGE=go.opentelemetry.io/build-tools/gotmpl GORELEASE = $(TOOLS)/gorelease $(GORELEASE): PACKAGE=golang.org/x/exp/cmd/gorelease +GOVULNCHECK = $(TOOLS)/govulncheck +$(TOOLS)/govulncheck: PACKAGE=golang.org/x/vuln/cmd/govulncheck + .PHONY: tools tools: $(CROSSLINK) $(DBOTCONF) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(PORTO) $(GOJQ) $(SEMCONVGEN) $(MULTIMOD) $(SEMCONVKIT) $(GOTMPL) $(GORELEASE) @@ -189,6 +192,18 @@ test-coverage: | $(GOCOVMERGE) done; \ $(GOCOVMERGE) $$(find . -name coverage.out) > coverage.txt +# Adding a directory will include all benchmarks in that direcotry if a filter is not specified. +BENCHMARK_TARGETS := sdk/trace +.PHONY: benchmark +benchmark: $(BENCHMARK_TARGETS:%=benchmark/%) +BENCHMARK_FILTER = . +# You can override the filter for a particular directory by adding a rule here. +benchmark/sdk/trace: BENCHMARK_FILTER = SpanWithAttributes_8/AlwaysSample +benchmark/%: + @echo "$(GO) test -timeout $(TIMEOUT)s -run=xxxxxMatchNothingxxxxx -bench=$(BENCHMARK_FILTER) $*..." \ + && cd $* \ + $(foreach filter, $(BENCHMARK_FILTER), && $(GO) test -timeout $(TIMEOUT)s -run=xxxxxMatchNothingxxxxx -bench=$(filter)) + .PHONY: golangci-lint golangci-lint-fix golangci-lint-fix: ARGS=--fix golangci-lint-fix: golangci-lint @@ -216,7 +231,7 @@ go-mod-tidy/%: | crosslink lint-modules: go-mod-tidy .PHONY: lint -lint: misspell lint-modules golangci-lint +lint: misspell lint-modules golangci-lint govulncheck .PHONY: vanity-import-check vanity-import-check: | $(PORTO) @@ -226,6 +241,14 @@ vanity-import-check: | $(PORTO) misspell: | $(MISSPELL) @$(MISSPELL) -w $(ALL_DOCS) +.PHONY: govulncheck +govulncheck: $(OTEL_GO_MOD_DIRS:%=govulncheck/%) +govulncheck/%: DIR=$* +govulncheck/%: | $(GOVULNCHECK) + @echo "govulncheck ./... in $(DIR)" \ + && cd $(DIR) \ + && $(GOVULNCHECK) ./... + .PHONY: codespell codespell: | $(CODESPELL) @$(DOCKERPY) $(CODESPELL) @@ -289,3 +312,7 @@ COMMIT ?= "HEAD" add-tags: | $(MULTIMOD) @[ "${MODSET}" ] || ( echo ">> env var MODSET is not set"; exit 1 ) $(MULTIMOD) verify && $(MULTIMOD) tag -m ${MODSET} -c ${COMMIT} + +.PHONY: lint-markdown +lint-markdown: + docker run -v "$(CURDIR):$(WORKDIR)" docker://avtodev/markdown-lint:v1 -c $(WORKDIR)/.markdownlint.yaml $(WORKDIR)/**/*.md diff --git a/vendor/go.opentelemetry.io/otel/README.md b/vendor/go.opentelemetry.io/otel/README.md index 634326ef833f..2c5b0cc28ab1 100644 --- a/vendor/go.opentelemetry.io/otel/README.md +++ b/vendor/go.opentelemetry.io/otel/README.md @@ -11,16 +11,13 @@ It provides a set of APIs to directly measure performance and behavior of your s ## Project Status -| Signal | Status | Project | -|---------|------------|-----------------------| -| Traces | Stable | N/A | -| Metrics | Mixed [1] | [Go: Metric SDK (GA)] | -| Logs | Frozen [2] | N/A | +| Signal | Status | +|---------|------------| +| Traces | Stable | +| Metrics | Stable | +| Logs | Design [1] | -[Go: Metric SDK (GA)]: https://github.com/orgs/open-telemetry/projects/34 - -- [1]: [Metrics API](https://pkg.go.dev/go.opentelemetry.io/otel/metric) is Stable. [Metrics SDK](https://pkg.go.dev/go.opentelemetry.io/otel/sdk/metric) is Beta. -- [2]: The Logs signal development is halted for this project while we stabilize the Metrics SDK. +- [1]: Currently the logs signal development is in a design phase ([#4696](https://github.com/open-telemetry/opentelemetry-go/issues/4696)). No Logs Pull Requests are currently being accepted. Progress and status specific to this repository is tracked in our diff --git a/vendor/go.opentelemetry.io/otel/baggage/baggage.go b/vendor/go.opentelemetry.io/otel/baggage/baggage.go index 9e6b3b7b52af..84532cb1da34 100644 --- a/vendor/go.opentelemetry.io/otel/baggage/baggage.go +++ b/vendor/go.opentelemetry.io/otel/baggage/baggage.go @@ -254,7 +254,7 @@ func NewMember(key, value string, props ...Property) (Member, error) { if err := m.validate(); err != nil { return newInvalidMember(), err } - decodedValue, err := url.QueryUnescape(value) + decodedValue, err := url.PathUnescape(value) if err != nil { return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidValue, value) } @@ -301,7 +301,7 @@ func parseMember(member string) (Member, error) { // when converting the header into a data structure." key = strings.TrimSpace(k) var err error - value, err = url.QueryUnescape(strings.TrimSpace(v)) + value, err = url.PathUnescape(strings.TrimSpace(v)) if err != nil { return newInvalidMember(), fmt.Errorf("%w: %q", err, value) } diff --git a/vendor/go.opentelemetry.io/otel/internal/global/instruments.go b/vendor/go.opentelemetry.io/otel/internal/global/instruments.go index a33eded872a3..ebb13c20678e 100644 --- a/vendor/go.opentelemetry.io/otel/internal/global/instruments.go +++ b/vendor/go.opentelemetry.io/otel/internal/global/instruments.go @@ -34,11 +34,13 @@ type afCounter struct { name string opts []metric.Float64ObservableCounterOption - delegate atomic.Value //metric.Float64ObservableCounter + delegate atomic.Value // metric.Float64ObservableCounter } -var _ unwrapper = (*afCounter)(nil) -var _ metric.Float64ObservableCounter = (*afCounter)(nil) +var ( + _ unwrapper = (*afCounter)(nil) + _ metric.Float64ObservableCounter = (*afCounter)(nil) +) func (i *afCounter) setDelegate(m metric.Meter) { ctr, err := m.Float64ObservableCounter(i.name, i.opts...) @@ -63,11 +65,13 @@ type afUpDownCounter struct { name string opts []metric.Float64ObservableUpDownCounterOption - delegate atomic.Value //metric.Float64ObservableUpDownCounter + delegate atomic.Value // metric.Float64ObservableUpDownCounter } -var _ unwrapper = (*afUpDownCounter)(nil) -var _ metric.Float64ObservableUpDownCounter = (*afUpDownCounter)(nil) +var ( + _ unwrapper = (*afUpDownCounter)(nil) + _ metric.Float64ObservableUpDownCounter = (*afUpDownCounter)(nil) +) func (i *afUpDownCounter) setDelegate(m metric.Meter) { ctr, err := m.Float64ObservableUpDownCounter(i.name, i.opts...) @@ -92,11 +96,13 @@ type afGauge struct { name string opts []metric.Float64ObservableGaugeOption - delegate atomic.Value //metric.Float64ObservableGauge + delegate atomic.Value // metric.Float64ObservableGauge } -var _ unwrapper = (*afGauge)(nil) -var _ metric.Float64ObservableGauge = (*afGauge)(nil) +var ( + _ unwrapper = (*afGauge)(nil) + _ metric.Float64ObservableGauge = (*afGauge)(nil) +) func (i *afGauge) setDelegate(m metric.Meter) { ctr, err := m.Float64ObservableGauge(i.name, i.opts...) @@ -121,11 +127,13 @@ type aiCounter struct { name string opts []metric.Int64ObservableCounterOption - delegate atomic.Value //metric.Int64ObservableCounter + delegate atomic.Value // metric.Int64ObservableCounter } -var _ unwrapper = (*aiCounter)(nil) -var _ metric.Int64ObservableCounter = (*aiCounter)(nil) +var ( + _ unwrapper = (*aiCounter)(nil) + _ metric.Int64ObservableCounter = (*aiCounter)(nil) +) func (i *aiCounter) setDelegate(m metric.Meter) { ctr, err := m.Int64ObservableCounter(i.name, i.opts...) @@ -150,11 +158,13 @@ type aiUpDownCounter struct { name string opts []metric.Int64ObservableUpDownCounterOption - delegate atomic.Value //metric.Int64ObservableUpDownCounter + delegate atomic.Value // metric.Int64ObservableUpDownCounter } -var _ unwrapper = (*aiUpDownCounter)(nil) -var _ metric.Int64ObservableUpDownCounter = (*aiUpDownCounter)(nil) +var ( + _ unwrapper = (*aiUpDownCounter)(nil) + _ metric.Int64ObservableUpDownCounter = (*aiUpDownCounter)(nil) +) func (i *aiUpDownCounter) setDelegate(m metric.Meter) { ctr, err := m.Int64ObservableUpDownCounter(i.name, i.opts...) @@ -179,11 +189,13 @@ type aiGauge struct { name string opts []metric.Int64ObservableGaugeOption - delegate atomic.Value //metric.Int64ObservableGauge + delegate atomic.Value // metric.Int64ObservableGauge } -var _ unwrapper = (*aiGauge)(nil) -var _ metric.Int64ObservableGauge = (*aiGauge)(nil) +var ( + _ unwrapper = (*aiGauge)(nil) + _ metric.Int64ObservableGauge = (*aiGauge)(nil) +) func (i *aiGauge) setDelegate(m metric.Meter) { ctr, err := m.Int64ObservableGauge(i.name, i.opts...) @@ -208,7 +220,7 @@ type sfCounter struct { name string opts []metric.Float64CounterOption - delegate atomic.Value //metric.Float64Counter + delegate atomic.Value // metric.Float64Counter } var _ metric.Float64Counter = (*sfCounter)(nil) @@ -234,7 +246,7 @@ type sfUpDownCounter struct { name string opts []metric.Float64UpDownCounterOption - delegate atomic.Value //metric.Float64UpDownCounter + delegate atomic.Value // metric.Float64UpDownCounter } var _ metric.Float64UpDownCounter = (*sfUpDownCounter)(nil) @@ -260,7 +272,7 @@ type sfHistogram struct { name string opts []metric.Float64HistogramOption - delegate atomic.Value //metric.Float64Histogram + delegate atomic.Value // metric.Float64Histogram } var _ metric.Float64Histogram = (*sfHistogram)(nil) @@ -286,7 +298,7 @@ type siCounter struct { name string opts []metric.Int64CounterOption - delegate atomic.Value //metric.Int64Counter + delegate atomic.Value // metric.Int64Counter } var _ metric.Int64Counter = (*siCounter)(nil) @@ -312,7 +324,7 @@ type siUpDownCounter struct { name string opts []metric.Int64UpDownCounterOption - delegate atomic.Value //metric.Int64UpDownCounter + delegate atomic.Value // metric.Int64UpDownCounter } var _ metric.Int64UpDownCounter = (*siUpDownCounter)(nil) @@ -338,7 +350,7 @@ type siHistogram struct { name string opts []metric.Int64HistogramOption - delegate atomic.Value //metric.Int64Histogram + delegate atomic.Value // metric.Int64Histogram } var _ metric.Int64Histogram = (*siHistogram)(nil) diff --git a/vendor/go.opentelemetry.io/otel/internal/global/trace.go b/vendor/go.opentelemetry.io/otel/internal/global/trace.go index 5f008d0982be..3f61ec12a34f 100644 --- a/vendor/go.opentelemetry.io/otel/internal/global/trace.go +++ b/vendor/go.opentelemetry.io/otel/internal/global/trace.go @@ -39,6 +39,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/trace" + "go.opentelemetry.io/otel/trace/embedded" ) // tracerProvider is a placeholder for a configured SDK TracerProvider. @@ -46,6 +47,8 @@ import ( // All TracerProvider functionality is forwarded to a delegate once // configured. type tracerProvider struct { + embedded.TracerProvider + mtx sync.Mutex tracers map[il]*tracer delegate trace.TracerProvider @@ -119,6 +122,8 @@ type il struct { // All Tracer functionality is forwarded to a delegate once configured. // Otherwise, all functionality is forwarded to a NoopTracer. type tracer struct { + embedded.Tracer + name string opts []trace.TracerOption provider *tracerProvider @@ -156,6 +161,8 @@ func (t *tracer) Start(ctx context.Context, name string, opts ...trace.SpanStart // SpanContext. It performs no operations other than to return the wrapped // SpanContext. type nonRecordingSpan struct { + embedded.Span + sc trace.SpanContext tracer *tracer } diff --git a/vendor/go.opentelemetry.io/otel/metric/doc.go b/vendor/go.opentelemetry.io/otel/metric/doc.go index ae24e448d91d..54716e13b355 100644 --- a/vendor/go.opentelemetry.io/otel/metric/doc.go +++ b/vendor/go.opentelemetry.io/otel/metric/doc.go @@ -149,7 +149,7 @@ of [go.opentelemetry.io/otel/metric]. Finally, an author can embed another implementation in theirs. The embedded implementation will be used for methods not defined by the author. For example, -an author who want to default to silently dropping the call can use +an author who wants to default to silently dropping the call can use [go.opentelemetry.io/otel/metric/noop]: import "go.opentelemetry.io/otel/metric/noop" diff --git a/vendor/go.opentelemetry.io/otel/metric/instrument.go b/vendor/go.opentelemetry.io/otel/metric/instrument.go index cdca00058c68..be89cd533417 100644 --- a/vendor/go.opentelemetry.io/otel/metric/instrument.go +++ b/vendor/go.opentelemetry.io/otel/metric/instrument.go @@ -39,6 +39,12 @@ type InstrumentOption interface { Float64ObservableGaugeOption } +// HistogramOption applies options to histogram instruments. +type HistogramOption interface { + Int64HistogramOption + Float64HistogramOption +} + type descOpt string func (o descOpt) applyFloat64Counter(c Float64CounterConfig) Float64CounterConfig { @@ -171,6 +177,23 @@ func (o unitOpt) applyInt64ObservableGauge(c Int64ObservableGaugeConfig) Int64Ob // The unit u should be defined using the appropriate [UCUM](https://ucum.org) case-sensitive code. func WithUnit(u string) InstrumentOption { return unitOpt(u) } +// WithExplicitBucketBoundaries sets the instrument explicit bucket boundaries. +// +// This option is considered "advisory", and may be ignored by API implementations. +func WithExplicitBucketBoundaries(bounds ...float64) HistogramOption { return bucketOpt(bounds) } + +type bucketOpt []float64 + +func (o bucketOpt) applyFloat64Histogram(c Float64HistogramConfig) Float64HistogramConfig { + c.explicitBucketBoundaries = o + return c +} + +func (o bucketOpt) applyInt64Histogram(c Int64HistogramConfig) Int64HistogramConfig { + c.explicitBucketBoundaries = o + return c +} + // AddOption applies options to an addition measurement. See // [MeasurementOption] for other options that can be used as an AddOption. type AddOption interface { diff --git a/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go b/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go index f0b063721d81..0a4825ae6a79 100644 --- a/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go +++ b/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go @@ -147,8 +147,9 @@ type Float64Histogram interface { // Float64HistogramConfig contains options for synchronous counter instruments // that record int64 values. type Float64HistogramConfig struct { - description string - unit string + description string + unit string + explicitBucketBoundaries []float64 } // NewFloat64HistogramConfig returns a new [Float64HistogramConfig] with all @@ -171,6 +172,11 @@ func (c Float64HistogramConfig) Unit() string { return c.unit } +// ExplicitBucketBoundaries returns the configured explicit bucket boundaries. +func (c Float64HistogramConfig) ExplicitBucketBoundaries() []float64 { + return c.explicitBucketBoundaries +} + // Float64HistogramOption applies options to a [Float64HistogramConfig]. See // [InstrumentOption] for other options that can be used as a // Float64HistogramOption. diff --git a/vendor/go.opentelemetry.io/otel/metric/syncint64.go b/vendor/go.opentelemetry.io/otel/metric/syncint64.go index 6f508eb66d40..56667d32fc01 100644 --- a/vendor/go.opentelemetry.io/otel/metric/syncint64.go +++ b/vendor/go.opentelemetry.io/otel/metric/syncint64.go @@ -147,8 +147,9 @@ type Int64Histogram interface { // Int64HistogramConfig contains options for synchronous counter instruments // that record int64 values. type Int64HistogramConfig struct { - description string - unit string + description string + unit string + explicitBucketBoundaries []float64 } // NewInt64HistogramConfig returns a new [Int64HistogramConfig] with all opts @@ -171,6 +172,11 @@ func (c Int64HistogramConfig) Unit() string { return c.unit } +// ExplicitBucketBoundaries returns the configured explicit bucket boundaries. +func (c Int64HistogramConfig) ExplicitBucketBoundaries() []float64 { + return c.explicitBucketBoundaries +} + // Int64HistogramOption applies options to a [Int64HistogramConfig]. See // [InstrumentOption] for other options that can be used as an // Int64HistogramOption. diff --git a/vendor/go.opentelemetry.io/otel/propagation/trace_context.go b/vendor/go.opentelemetry.io/otel/propagation/trace_context.go index 902692da082e..75a8f3435a52 100644 --- a/vendor/go.opentelemetry.io/otel/propagation/trace_context.go +++ b/vendor/go.opentelemetry.io/otel/propagation/trace_context.go @@ -40,8 +40,10 @@ const ( // their proprietary information. type TraceContext struct{} -var _ TextMapPropagator = TraceContext{} -var traceCtxRegExp = regexp.MustCompile("^(?P[0-9a-f]{2})-(?P[a-f0-9]{32})-(?P[a-f0-9]{16})-(?P[a-f0-9]{2})(?:-.*)?$") +var ( + _ TextMapPropagator = TraceContext{} + traceCtxRegExp = regexp.MustCompile("^(?P[0-9a-f]{2})-(?P[a-f0-9]{32})-(?P[a-f0-9]{16})-(?P[a-f0-9]{2})(?:-.*)?$") +) // Inject set tracecontext from the Context into the carrier. func (tc TraceContext) Inject(ctx context.Context, carrier TextMapCarrier) { diff --git a/vendor/go.opentelemetry.io/otel/requirements.txt b/vendor/go.opentelemetry.io/otel/requirements.txt index ddff454685c8..e0a43e13840e 100644 --- a/vendor/go.opentelemetry.io/otel/requirements.txt +++ b/vendor/go.opentelemetry.io/otel/requirements.txt @@ -1 +1 @@ -codespell==2.2.5 +codespell==2.2.6 diff --git a/vendor/go.opentelemetry.io/otel/trace/config.go b/vendor/go.opentelemetry.io/otel/trace/config.go index cb3efbb9ad89..3aadc66cf7a7 100644 --- a/vendor/go.opentelemetry.io/otel/trace/config.go +++ b/vendor/go.opentelemetry.io/otel/trace/config.go @@ -268,6 +268,7 @@ func (o stackTraceOption) applyEvent(c EventConfig) EventConfig { c.stackTrace = bool(o) return c } + func (o stackTraceOption) applySpan(c SpanConfig) SpanConfig { c.stackTrace = bool(o) return c diff --git a/vendor/go.opentelemetry.io/otel/trace/doc.go b/vendor/go.opentelemetry.io/otel/trace/doc.go index ab0346f9664a..440f3d7565a1 100644 --- a/vendor/go.opentelemetry.io/otel/trace/doc.go +++ b/vendor/go.opentelemetry.io/otel/trace/doc.go @@ -62,5 +62,69 @@ a default. defer span.End() // ... } + +# API Implementations + +This package does not conform to the standard Go versioning policy; all of its +interfaces may have methods added to them without a package major version bump. +This non-standard API evolution could surprise an uninformed implementation +author. They could unknowingly build their implementation in a way that would +result in a runtime panic for their users that update to the new API. + +The API is designed to help inform an instrumentation author about this +non-standard API evolution. It requires them to choose a default behavior for +unimplemented interface methods. There are three behavior choices they can +make: + + - Compilation failure + - Panic + - Default to another implementation + +All interfaces in this API embed a corresponding interface from +[go.opentelemetry.io/otel/trace/embedded]. If an author wants the default +behavior of their implementations to be a compilation failure, signaling to +their users they need to update to the latest version of that implementation, +they need to embed the corresponding interface from +[go.opentelemetry.io/otel/trace/embedded] in their implementation. For +example, + + import "go.opentelemetry.io/otel/trace/embedded" + + type TracerProvider struct { + embedded.TracerProvider + // ... + } + +If an author wants the default behavior of their implementations to panic, they +can embed the API interface directly. + + import "go.opentelemetry.io/otel/trace" + + type TracerProvider struct { + trace.TracerProvider + // ... + } + +This option is not recommended. It will lead to publishing packages that +contain runtime panics when users update to newer versions of +[go.opentelemetry.io/otel/trace], which may be done with a trasitive +dependency. + +Finally, an author can embed another implementation in theirs. The embedded +implementation will be used for methods not defined by the author. For example, +an author who wants to default to silently dropping the call can use +[go.opentelemetry.io/otel/trace/noop]: + + import "go.opentelemetry.io/otel/trace/noop" + + type TracerProvider struct { + noop.TracerProvider + // ... + } + +It is strongly recommended that authors only embed +[go.opentelemetry.io/otel/trace/noop] if they choose this default behavior. +That implementation is the only one OpenTelemetry authors can guarantee will +fully implement all the API interfaces when a user updates their API. */ package trace // import "go.opentelemetry.io/otel/trace" diff --git a/vendor/go.opentelemetry.io/otel/trace/embedded/embedded.go b/vendor/go.opentelemetry.io/otel/trace/embedded/embedded.go new file mode 100644 index 000000000000..898db5a7546e --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/trace/embedded/embedded.go @@ -0,0 +1,56 @@ +// Copyright The OpenTelemetry 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 embedded provides interfaces embedded within the [OpenTelemetry +// trace API]. +// +// Implementers of the [OpenTelemetry trace API] can embed the relevant type +// from this package into their implementation directly. Doing so will result +// in a compilation error for users when the [OpenTelemetry trace API] is +// extended (which is something that can happen without a major version bump of +// the API package). +// +// [OpenTelemetry trace API]: https://pkg.go.dev/go.opentelemetry.io/otel/trace +package embedded // import "go.opentelemetry.io/otel/trace/embedded" + +// TracerProvider is embedded in +// [go.opentelemetry.io/otel/trace.TracerProvider]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/trace.TracerProvider] if you want users to +// experience a compilation error, signaling they need to update to your latest +// implementation, when the [go.opentelemetry.io/otel/trace.TracerProvider] +// interface is extended (which is something that can happen without a major +// version bump of the API package). +type TracerProvider interface{ tracerProvider() } + +// Tracer is embedded in [go.opentelemetry.io/otel/trace.Tracer]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/trace.Tracer] if you want users to experience a +// compilation error, signaling they need to update to your latest +// implementation, when the [go.opentelemetry.io/otel/trace.Tracer] interface +// is extended (which is something that can happen without a major version bump +// of the API package). +type Tracer interface{ tracer() } + +// Span is embedded in [go.opentelemetry.io/otel/trace.Span]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/trace.Span] if you want users to experience a +// compilation error, signaling they need to update to your latest +// implementation, when the [go.opentelemetry.io/otel/trace.Span] interface is +// extended (which is something that can happen without a major version bump of +// the API package). +type Span interface{ span() } diff --git a/vendor/go.opentelemetry.io/otel/trace/noop.go b/vendor/go.opentelemetry.io/otel/trace/noop.go index 7cf6c7f3ef9e..c125491caebf 100644 --- a/vendor/go.opentelemetry.io/otel/trace/noop.go +++ b/vendor/go.opentelemetry.io/otel/trace/noop.go @@ -19,16 +19,20 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/trace/embedded" ) // NewNoopTracerProvider returns an implementation of TracerProvider that // performs no operations. The Tracer and Spans created from the returned // TracerProvider also perform no operations. +// +// Deprecated: Use [go.opentelemetry.io/otel/trace/noop.NewTracerProvider] +// instead. func NewNoopTracerProvider() TracerProvider { return noopTracerProvider{} } -type noopTracerProvider struct{} +type noopTracerProvider struct{ embedded.TracerProvider } var _ TracerProvider = noopTracerProvider{} @@ -38,7 +42,7 @@ func (p noopTracerProvider) Tracer(string, ...TracerOption) Tracer { } // noopTracer is an implementation of Tracer that performs no operations. -type noopTracer struct{} +type noopTracer struct{ embedded.Tracer } var _ Tracer = noopTracer{} @@ -54,7 +58,7 @@ func (t noopTracer) Start(ctx context.Context, name string, _ ...SpanStartOption } // noopSpan is an implementation of Span that performs no operations. -type noopSpan struct{} +type noopSpan struct{ embedded.Span } var _ Span = noopSpan{} diff --git a/vendor/go.opentelemetry.io/otel/trace/trace.go b/vendor/go.opentelemetry.io/otel/trace/trace.go index 4aa94f79f46a..26a4b2260ec6 100644 --- a/vendor/go.opentelemetry.io/otel/trace/trace.go +++ b/vendor/go.opentelemetry.io/otel/trace/trace.go @@ -22,6 +22,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/trace/embedded" ) const ( @@ -48,8 +49,10 @@ func (e errorConst) Error() string { // nolint:revive // revive complains about stutter of `trace.TraceID`. type TraceID [16]byte -var nilTraceID TraceID -var _ json.Marshaler = nilTraceID +var ( + nilTraceID TraceID + _ json.Marshaler = nilTraceID +) // IsValid checks whether the trace TraceID is valid. A valid trace ID does // not consist of zeros only. @@ -71,8 +74,10 @@ func (t TraceID) String() string { // SpanID is a unique identity of a span in a trace. type SpanID [8]byte -var nilSpanID SpanID -var _ json.Marshaler = nilSpanID +var ( + nilSpanID SpanID + _ json.Marshaler = nilSpanID +) // IsValid checks whether the SpanID is valid. A valid SpanID does not consist // of zeros only. @@ -338,8 +343,15 @@ func (sc SpanContext) MarshalJSON() ([]byte, error) { // create a Span and it is then up to the operation the Span represents to // properly end the Span when the operation itself ends. // -// Warning: methods may be added to this interface in minor releases. +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. type Span interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Span + // End completes the Span. The Span is considered complete and ready to be // delivered through the rest of the telemetry pipeline after this method // is called. Therefore, updates to the Span are not allowed after this @@ -486,8 +498,15 @@ func (sk SpanKind) String() string { // Tracer is the creator of Spans. // -// Warning: methods may be added to this interface in minor releases. +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. type Tracer interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Tracer + // Start creates a span and a context.Context containing the newly-created span. // // If the context.Context provided in `ctx` contains a Span then the newly-created @@ -518,8 +537,15 @@ type Tracer interface { // at runtime from its users or it can simply use the globally registered one // (see https://pkg.go.dev/go.opentelemetry.io/otel#GetTracerProvider). // -// Warning: methods may be added to this interface in minor releases. +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. type TracerProvider interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.TracerProvider + // Tracer returns a unique Tracer scoped to be used by instrumentation code // to trace computational workflows. The scope and identity of that // instrumentation code is uniquely defined by the name and options passed. diff --git a/vendor/go.opentelemetry.io/otel/trace/tracestate.go b/vendor/go.opentelemetry.io/otel/trace/tracestate.go index ca68a82e5f73..d1e47ca2faac 100644 --- a/vendor/go.opentelemetry.io/otel/trace/tracestate.go +++ b/vendor/go.opentelemetry.io/otel/trace/tracestate.go @@ -28,9 +28,9 @@ const ( // based on the W3C Trace Context specification, see // https://www.w3.org/TR/trace-context-1/#tracestate-header - noTenantKeyFormat = `[a-z][_0-9a-z\-\*\/]{0,255}` - withTenantKeyFormat = `[a-z0-9][_0-9a-z\-\*\/]{0,240}@[a-z][_0-9a-z\-\*\/]{0,13}` - valueFormat = `[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]` + noTenantKeyFormat = `[a-z][_0-9a-z\-\*\/]*` + withTenantKeyFormat = `[a-z0-9][_0-9a-z\-\*\/]*@[a-z][_0-9a-z\-\*\/]*` + valueFormat = `[\x20-\x2b\x2d-\x3c\x3e-\x7e]*[\x21-\x2b\x2d-\x3c\x3e-\x7e]` errInvalidKey errorConst = "invalid tracestate key" errInvalidValue errorConst = "invalid tracestate value" @@ -40,9 +40,10 @@ const ( ) var ( - keyRe = regexp.MustCompile(`^((` + noTenantKeyFormat + `)|(` + withTenantKeyFormat + `))$`) - valueRe = regexp.MustCompile(`^(` + valueFormat + `)$`) - memberRe = regexp.MustCompile(`^\s*((` + noTenantKeyFormat + `)|(` + withTenantKeyFormat + `))=(` + valueFormat + `)\s*$`) + noTenantKeyRe = regexp.MustCompile(`^` + noTenantKeyFormat + `$`) + withTenantKeyRe = regexp.MustCompile(`^` + withTenantKeyFormat + `$`) + valueRe = regexp.MustCompile(`^` + valueFormat + `$`) + memberRe = regexp.MustCompile(`^\s*((?:` + noTenantKeyFormat + `)|(?:` + withTenantKeyFormat + `))=(` + valueFormat + `)\s*$`) ) type member struct { @@ -51,10 +52,19 @@ type member struct { } func newMember(key, value string) (member, error) { - if !keyRe.MatchString(key) { + if len(key) > 256 { return member{}, fmt.Errorf("%w: %s", errInvalidKey, key) } - if !valueRe.MatchString(value) { + if !noTenantKeyRe.MatchString(key) { + if !withTenantKeyRe.MatchString(key) { + return member{}, fmt.Errorf("%w: %s", errInvalidKey, key) + } + atIndex := strings.LastIndex(key, "@") + if atIndex > 241 || len(key)-1-atIndex > 14 { + return member{}, fmt.Errorf("%w: %s", errInvalidKey, key) + } + } + if len(value) > 256 || !valueRe.MatchString(value) { return member{}, fmt.Errorf("%w: %s", errInvalidValue, value) } return member{Key: key, Value: value}, nil @@ -62,14 +72,14 @@ func newMember(key, value string) (member, error) { func parseMember(m string) (member, error) { matches := memberRe.FindStringSubmatch(m) - if len(matches) != 5 { + if len(matches) != 3 { return member{}, fmt.Errorf("%w: %s", errInvalidMember, m) } - - return member{ - Key: matches[1], - Value: matches[4], - }, nil + result, e := newMember(matches[1], matches[2]) + if e != nil { + return member{}, fmt.Errorf("%w: %s", errInvalidMember, m) + } + return result, nil } // String encodes member into a string compliant with the W3C Trace Context diff --git a/vendor/go.opentelemetry.io/otel/version.go b/vendor/go.opentelemetry.io/otel/version.go index ad64e199672f..e2f743585d1d 100644 --- a/vendor/go.opentelemetry.io/otel/version.go +++ b/vendor/go.opentelemetry.io/otel/version.go @@ -16,5 +16,5 @@ package otel // import "go.opentelemetry.io/otel" // Version is the current release version of OpenTelemetry in use. func Version() string { - return "1.19.0" + return "1.21.0" } diff --git a/vendor/go.opentelemetry.io/otel/versions.yaml b/vendor/go.opentelemetry.io/otel/versions.yaml index 7d2127692403..3c153c9d6fc6 100644 --- a/vendor/go.opentelemetry.io/otel/versions.yaml +++ b/vendor/go.opentelemetry.io/otel/versions.yaml @@ -14,13 +14,12 @@ module-sets: stable-v1: - version: v1.19.0 + version: v1.21.0 modules: - go.opentelemetry.io/otel - go.opentelemetry.io/otel/bridge/opentracing - go.opentelemetry.io/otel/bridge/opentracing/test - go.opentelemetry.io/otel/example/dice - - go.opentelemetry.io/otel/example/fib - go.opentelemetry.io/otel/example/namedtracer - go.opentelemetry.io/otel/example/otel-collector - go.opentelemetry.io/otel/example/passthrough @@ -35,14 +34,12 @@ module-sets: - go.opentelemetry.io/otel/sdk/metric - go.opentelemetry.io/otel/trace experimental-metrics: - version: v0.42.0 + version: v0.44.0 modules: - go.opentelemetry.io/otel/bridge/opencensus - go.opentelemetry.io/otel/bridge/opencensus/test - go.opentelemetry.io/otel/example/opencensus - go.opentelemetry.io/otel/example/prometheus - - go.opentelemetry.io/otel/example/view - - go.opentelemetry.io/otel/exporters/otlp/otlpmetric - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp - go.opentelemetry.io/otel/exporters/prometheus diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go index c1f6b90dc32f..43557ab7e977 100644 --- a/vendor/golang.org/x/net/http2/frame.go +++ b/vendor/golang.org/x/net/http2/frame.go @@ -1510,13 +1510,12 @@ func (mh *MetaHeadersFrame) checkPseudos() error { } func (fr *Framer) maxHeaderStringLen() int { - v := fr.maxHeaderListSize() - if uint32(int(v)) == v { - return int(v) + v := int(fr.maxHeaderListSize()) + if v < 0 { + // If maxHeaderListSize overflows an int, use no limit (0). + return 0 } - // They had a crazy big number for MaxHeaderBytes anyway, - // so give them unlimited header lengths: - return 0 + return v } // readMetaFrame returns 0 or more CONTINUATION frames from fr and @@ -1565,6 +1564,7 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { if size > remainSize { hdec.SetEmitEnabled(false) mh.Truncated = true + remainSize = 0 return } remainSize -= size @@ -1577,6 +1577,36 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) { var hc headersOrContinuation = hf for { frag := hc.HeaderBlockFragment() + + // Avoid parsing large amounts of headers that we will then discard. + // If the sender exceeds the max header list size by too much, + // skip parsing the fragment and close the connection. + // + // "Too much" is either any CONTINUATION frame after we've already + // exceeded the max header list size (in which case remainSize is 0), + // or a frame whose encoded size is more than twice the remaining + // header list bytes we're willing to accept. + if int64(len(frag)) > int64(2*remainSize) { + if VerboseLogs { + log.Printf("http2: header list too large") + } + // It would be nice to send a RST_STREAM before sending the GOAWAY, + // but the structure of the server's frame writer makes this difficult. + return nil, ConnectionError(ErrCodeProtocol) + } + + // Also close the connection after any CONTINUATION frame following an + // invalid header, since we stop tracking the size of the headers after + // an invalid one. + if invalid != nil { + if VerboseLogs { + log.Printf("http2: invalid header: %v", invalid) + } + // It would be nice to send a RST_STREAM before sending the GOAWAY, + // but the structure of the server's frame writer makes this difficult. + return nil, ConnectionError(ErrCodeProtocol) + } + if _, err := hdec.Write(frag); err != nil { return nil, ConnectionError(ErrCodeCompression) } diff --git a/vendor/golang.org/x/net/http2/pipe.go b/vendor/golang.org/x/net/http2/pipe.go index 684d984fd96a..3b9f06b96244 100644 --- a/vendor/golang.org/x/net/http2/pipe.go +++ b/vendor/golang.org/x/net/http2/pipe.go @@ -77,7 +77,10 @@ func (p *pipe) Read(d []byte) (n int, err error) { } } -var errClosedPipeWrite = errors.New("write on closed buffer") +var ( + errClosedPipeWrite = errors.New("write on closed buffer") + errUninitializedPipeWrite = errors.New("write on uninitialized buffer") +) // Write copies bytes from p into the buffer and wakes a reader. // It is an error to write more data than the buffer can hold. @@ -91,6 +94,12 @@ func (p *pipe) Write(d []byte) (n int, err error) { if p.err != nil || p.breakErr != nil { return 0, errClosedPipeWrite } + // pipe.setBuffer is never invoked, leaving the buffer uninitialized. + // We shouldn't try to write to an uninitialized pipe, + // but returning an error is better than panicking. + if p.b == nil { + return 0, errUninitializedPipeWrite + } return p.b.Write(d) } diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index ae94c6408d5d..ce2e8b40eee6 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -124,6 +124,7 @@ type Server struct { // IdleTimeout specifies how long until idle clients should be // closed with a GOAWAY frame. PING frames are not considered // activity for the purposes of IdleTimeout. + // If zero or negative, there is no timeout. IdleTimeout time.Duration // MaxUploadBufferPerConnection is the size of the initial flow @@ -434,7 +435,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { // passes the connection off to us with the deadline already set. // Write deadlines are set per stream in serverConn.newStream. // Disarm the net.Conn write deadline here. - if sc.hs.WriteTimeout != 0 { + if sc.hs.WriteTimeout > 0 { sc.conn.SetWriteDeadline(time.Time{}) } @@ -924,7 +925,7 @@ func (sc *serverConn) serve() { sc.setConnState(http.StateActive) sc.setConnState(http.StateIdle) - if sc.srv.IdleTimeout != 0 { + if sc.srv.IdleTimeout > 0 { sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer) defer sc.idleTimer.Stop() } @@ -1637,7 +1638,7 @@ func (sc *serverConn) closeStream(st *stream, err error) { delete(sc.streams, st.id) if len(sc.streams) == 0 { sc.setConnState(http.StateIdle) - if sc.srv.IdleTimeout != 0 { + if sc.srv.IdleTimeout > 0 { sc.idleTimer.Reset(sc.srv.IdleTimeout) } if h1ServerKeepAlivesDisabled(sc.hs) { @@ -2017,7 +2018,7 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { // similar to how the http1 server works. Here it's // technically more like the http1 Server's ReadHeaderTimeout // (in Go 1.8), though. That's a more sane option anyway. - if sc.hs.ReadTimeout != 0 { + if sc.hs.ReadTimeout > 0 { sc.conn.SetReadDeadline(time.Time{}) st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout) } @@ -2038,7 +2039,7 @@ func (sc *serverConn) upgradeRequest(req *http.Request) { // Disable any read deadline set by the net/http package // prior to the upgrade. - if sc.hs.ReadTimeout != 0 { + if sc.hs.ReadTimeout > 0 { sc.conn.SetReadDeadline(time.Time{}) } @@ -2116,7 +2117,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream st.flow.conn = &sc.flow // link to conn-level counter st.flow.add(sc.initialStreamSendWindowSize) st.inflow.init(sc.srv.initialStreamRecvWindowSize()) - if sc.hs.WriteTimeout != 0 { + if sc.hs.WriteTimeout > 0 { st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout) } diff --git a/vendor/golang.org/x/net/http2/testsync.go b/vendor/golang.org/x/net/http2/testsync.go new file mode 100644 index 000000000000..61075bd16d31 --- /dev/null +++ b/vendor/golang.org/x/net/http2/testsync.go @@ -0,0 +1,331 @@ +// Copyright 2024 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. +package http2 + +import ( + "context" + "sync" + "time" +) + +// testSyncHooks coordinates goroutines in tests. +// +// For example, a call to ClientConn.RoundTrip involves several goroutines, including: +// - the goroutine running RoundTrip; +// - the clientStream.doRequest goroutine, which writes the request; and +// - the clientStream.readLoop goroutine, which reads the response. +// +// Using testSyncHooks, a test can start a RoundTrip and identify when all these goroutines +// are blocked waiting for some condition such as reading the Request.Body or waiting for +// flow control to become available. +// +// The testSyncHooks also manage timers and synthetic time in tests. +// This permits us to, for example, start a request and cause it to time out waiting for +// response headers without resorting to time.Sleep calls. +type testSyncHooks struct { + // active/inactive act as a mutex and condition variable. + // + // - neither chan contains a value: testSyncHooks is locked. + // - active contains a value: unlocked, and at least one goroutine is not blocked + // - inactive contains a value: unlocked, and all goroutines are blocked + active chan struct{} + inactive chan struct{} + + // goroutine counts + total int // total goroutines + condwait map[*sync.Cond]int // blocked in sync.Cond.Wait + blocked []*testBlockedGoroutine // otherwise blocked + + // fake time + now time.Time + timers []*fakeTimer + + // Transport testing: Report various events. + newclientconn func(*ClientConn) + newstream func(*clientStream) +} + +// testBlockedGoroutine is a blocked goroutine. +type testBlockedGoroutine struct { + f func() bool // blocked until f returns true + ch chan struct{} // closed when unblocked +} + +func newTestSyncHooks() *testSyncHooks { + h := &testSyncHooks{ + active: make(chan struct{}, 1), + inactive: make(chan struct{}, 1), + condwait: map[*sync.Cond]int{}, + } + h.inactive <- struct{}{} + h.now = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC) + return h +} + +// lock acquires the testSyncHooks mutex. +func (h *testSyncHooks) lock() { + select { + case <-h.active: + case <-h.inactive: + } +} + +// waitInactive waits for all goroutines to become inactive. +func (h *testSyncHooks) waitInactive() { + for { + <-h.inactive + if !h.unlock() { + break + } + } +} + +// unlock releases the testSyncHooks mutex. +// It reports whether any goroutines are active. +func (h *testSyncHooks) unlock() (active bool) { + // Look for a blocked goroutine which can be unblocked. + blocked := h.blocked[:0] + unblocked := false + for _, b := range h.blocked { + if !unblocked && b.f() { + unblocked = true + close(b.ch) + } else { + blocked = append(blocked, b) + } + } + h.blocked = blocked + + // Count goroutines blocked on condition variables. + condwait := 0 + for _, count := range h.condwait { + condwait += count + } + + if h.total > condwait+len(blocked) { + h.active <- struct{}{} + return true + } else { + h.inactive <- struct{}{} + return false + } +} + +// goRun starts a new goroutine. +func (h *testSyncHooks) goRun(f func()) { + h.lock() + h.total++ + h.unlock() + go func() { + defer func() { + h.lock() + h.total-- + h.unlock() + }() + f() + }() +} + +// blockUntil indicates that a goroutine is blocked waiting for some condition to become true. +// It waits until f returns true before proceeding. +// +// Example usage: +// +// h.blockUntil(func() bool { +// // Is the context done yet? +// select { +// case <-ctx.Done(): +// default: +// return false +// } +// return true +// }) +// // Wait for the context to become done. +// <-ctx.Done() +// +// The function f passed to blockUntil must be non-blocking and idempotent. +func (h *testSyncHooks) blockUntil(f func() bool) { + if f() { + return + } + ch := make(chan struct{}) + h.lock() + h.blocked = append(h.blocked, &testBlockedGoroutine{ + f: f, + ch: ch, + }) + h.unlock() + <-ch +} + +// broadcast is sync.Cond.Broadcast. +func (h *testSyncHooks) condBroadcast(cond *sync.Cond) { + h.lock() + delete(h.condwait, cond) + h.unlock() + cond.Broadcast() +} + +// broadcast is sync.Cond.Wait. +func (h *testSyncHooks) condWait(cond *sync.Cond) { + h.lock() + h.condwait[cond]++ + h.unlock() +} + +// newTimer creates a new fake timer. +func (h *testSyncHooks) newTimer(d time.Duration) timer { + h.lock() + defer h.unlock() + t := &fakeTimer{ + hooks: h, + when: h.now.Add(d), + c: make(chan time.Time), + } + h.timers = append(h.timers, t) + return t +} + +// afterFunc creates a new fake AfterFunc timer. +func (h *testSyncHooks) afterFunc(d time.Duration, f func()) timer { + h.lock() + defer h.unlock() + t := &fakeTimer{ + hooks: h, + when: h.now.Add(d), + f: f, + } + h.timers = append(h.timers, t) + return t +} + +func (h *testSyncHooks) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) { + ctx, cancel := context.WithCancel(ctx) + t := h.afterFunc(d, cancel) + return ctx, func() { + t.Stop() + cancel() + } +} + +func (h *testSyncHooks) timeUntilEvent() time.Duration { + h.lock() + defer h.unlock() + var next time.Time + for _, t := range h.timers { + if next.IsZero() || t.when.Before(next) { + next = t.when + } + } + if d := next.Sub(h.now); d > 0 { + return d + } + return 0 +} + +// advance advances time and causes synthetic timers to fire. +func (h *testSyncHooks) advance(d time.Duration) { + h.lock() + defer h.unlock() + h.now = h.now.Add(d) + timers := h.timers[:0] + for _, t := range h.timers { + t := t // remove after go.mod depends on go1.22 + t.mu.Lock() + switch { + case t.when.After(h.now): + timers = append(timers, t) + case t.when.IsZero(): + // stopped timer + default: + t.when = time.Time{} + if t.c != nil { + close(t.c) + } + if t.f != nil { + h.total++ + go func() { + defer func() { + h.lock() + h.total-- + h.unlock() + }() + t.f() + }() + } + } + t.mu.Unlock() + } + h.timers = timers +} + +// A timer wraps a time.Timer, or a synthetic equivalent in tests. +// Unlike time.Timer, timer is single-use: The timer channel is closed when the timer expires. +type timer interface { + C() <-chan time.Time + Stop() bool + Reset(d time.Duration) bool +} + +// timeTimer implements timer using real time. +type timeTimer struct { + t *time.Timer + c chan time.Time +} + +// newTimeTimer creates a new timer using real time. +func newTimeTimer(d time.Duration) timer { + ch := make(chan time.Time) + t := time.AfterFunc(d, func() { + close(ch) + }) + return &timeTimer{t, ch} +} + +// newTimeAfterFunc creates an AfterFunc timer using real time. +func newTimeAfterFunc(d time.Duration, f func()) timer { + return &timeTimer{ + t: time.AfterFunc(d, f), + } +} + +func (t timeTimer) C() <-chan time.Time { return t.c } +func (t timeTimer) Stop() bool { return t.t.Stop() } +func (t timeTimer) Reset(d time.Duration) bool { return t.t.Reset(d) } + +// fakeTimer implements timer using fake time. +type fakeTimer struct { + hooks *testSyncHooks + + mu sync.Mutex + when time.Time // when the timer will fire + c chan time.Time // closed when the timer fires; mutually exclusive with f + f func() // called when the timer fires; mutually exclusive with c +} + +func (t *fakeTimer) C() <-chan time.Time { return t.c } + +func (t *fakeTimer) Stop() bool { + t.mu.Lock() + defer t.mu.Unlock() + stopped := t.when.IsZero() + t.when = time.Time{} + return stopped +} + +func (t *fakeTimer) Reset(d time.Duration) bool { + if t.c != nil || t.f == nil { + panic("fakeTimer only supports Reset on AfterFunc timers") + } + t.mu.Lock() + defer t.mu.Unlock() + t.hooks.lock() + defer t.hooks.unlock() + active := !t.when.IsZero() + t.when = t.hooks.now.Add(d) + if !active { + t.hooks.timers = append(t.hooks.timers, t) + } + return active +} diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index df578b86c650..ce375c8c7535 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -147,6 +147,12 @@ type Transport struct { // waiting for their turn. StrictMaxConcurrentStreams bool + // IdleConnTimeout is the maximum amount of time an idle + // (keep-alive) connection will remain idle before closing + // itself. + // Zero means no limit. + IdleConnTimeout time.Duration + // ReadIdleTimeout is the timeout after which a health check using ping // frame will be carried out if no frame is received on the connection. // Note that a ping response will is considered a received frame, so if @@ -178,6 +184,8 @@ type Transport struct { connPoolOnce sync.Once connPoolOrDef ClientConnPool // non-nil version of ConnPool + + syncHooks *testSyncHooks } func (t *Transport) maxHeaderListSize() uint32 { @@ -302,7 +310,7 @@ type ClientConn struct { readerErr error // set before readerDone is closed idleTimeout time.Duration // or 0 for never - idleTimer *time.Timer + idleTimer timer mu sync.Mutex // guards following cond *sync.Cond // hold mu; broadcast on flow/closed changes @@ -344,6 +352,60 @@ type ClientConn struct { werr error // first write error that has occurred hbuf bytes.Buffer // HPACK encoder writes into this henc *hpack.Encoder + + syncHooks *testSyncHooks // can be nil +} + +// Hook points used for testing. +// Outside of tests, cc.syncHooks is nil and these all have minimal implementations. +// Inside tests, see the testSyncHooks function docs. + +// goRun starts a new goroutine. +func (cc *ClientConn) goRun(f func()) { + if cc.syncHooks != nil { + cc.syncHooks.goRun(f) + return + } + go f() +} + +// condBroadcast is cc.cond.Broadcast. +func (cc *ClientConn) condBroadcast() { + if cc.syncHooks != nil { + cc.syncHooks.condBroadcast(cc.cond) + } + cc.cond.Broadcast() +} + +// condWait is cc.cond.Wait. +func (cc *ClientConn) condWait() { + if cc.syncHooks != nil { + cc.syncHooks.condWait(cc.cond) + } + cc.cond.Wait() +} + +// newTimer creates a new time.Timer, or a synthetic timer in tests. +func (cc *ClientConn) newTimer(d time.Duration) timer { + if cc.syncHooks != nil { + return cc.syncHooks.newTimer(d) + } + return newTimeTimer(d) +} + +// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests. +func (cc *ClientConn) afterFunc(d time.Duration, f func()) timer { + if cc.syncHooks != nil { + return cc.syncHooks.afterFunc(d, f) + } + return newTimeAfterFunc(d, f) +} + +func (cc *ClientConn) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) { + if cc.syncHooks != nil { + return cc.syncHooks.contextWithTimeout(ctx, d) + } + return context.WithTimeout(ctx, d) } // clientStream is the state for a single HTTP/2 stream. One of these @@ -425,7 +487,7 @@ func (cs *clientStream) abortStreamLocked(err error) { // TODO(dneil): Clean up tests where cs.cc.cond is nil. if cs.cc.cond != nil { // Wake up writeRequestBody if it is waiting on flow control. - cs.cc.cond.Broadcast() + cs.cc.condBroadcast() } } @@ -435,7 +497,7 @@ func (cs *clientStream) abortRequestBodyWrite() { defer cc.mu.Unlock() if cs.reqBody != nil && cs.reqBodyClosed == nil { cs.closeReqBodyLocked() - cc.cond.Broadcast() + cc.condBroadcast() } } @@ -445,10 +507,10 @@ func (cs *clientStream) closeReqBodyLocked() { } cs.reqBodyClosed = make(chan struct{}) reqBodyClosed := cs.reqBodyClosed - go func() { + cs.cc.goRun(func() { cs.reqBody.Close() close(reqBodyClosed) - }() + }) } type stickyErrWriter struct { @@ -537,15 +599,6 @@ func authorityAddr(scheme string, authority string) (addr string) { return net.JoinHostPort(host, port) } -var retryBackoffHook func(time.Duration) *time.Timer - -func backoffNewTimer(d time.Duration) *time.Timer { - if retryBackoffHook != nil { - return retryBackoffHook(d) - } - return time.NewTimer(d) -} - // RoundTripOpt is like RoundTrip, but takes options. func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) { if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) { @@ -573,13 +626,27 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res backoff := float64(uint(1) << (uint(retry) - 1)) backoff += backoff * (0.1 * mathrand.Float64()) d := time.Second * time.Duration(backoff) - timer := backoffNewTimer(d) + var tm timer + if t.syncHooks != nil { + tm = t.syncHooks.newTimer(d) + t.syncHooks.blockUntil(func() bool { + select { + case <-tm.C(): + case <-req.Context().Done(): + default: + return false + } + return true + }) + } else { + tm = newTimeTimer(d) + } select { - case <-timer.C: + case <-tm.C(): t.vlogf("RoundTrip retrying after failure: %v", roundTripErr) continue case <-req.Context().Done(): - timer.Stop() + tm.Stop() err = req.Context().Err() } } @@ -658,6 +725,9 @@ func canRetryError(err error) bool { } func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse bool) (*ClientConn, error) { + if t.syncHooks != nil { + return t.newClientConn(nil, singleUse, t.syncHooks) + } host, _, err := net.SplitHostPort(addr) if err != nil { return nil, err @@ -666,7 +736,7 @@ func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse b if err != nil { return nil, err } - return t.newClientConn(tconn, singleUse) + return t.newClientConn(tconn, singleUse, nil) } func (t *Transport) newTLSConfig(host string) *tls.Config { @@ -732,10 +802,10 @@ func (t *Transport) maxEncoderHeaderTableSize() uint32 { } func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) { - return t.newClientConn(c, t.disableKeepAlives()) + return t.newClientConn(c, t.disableKeepAlives(), nil) } -func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) { +func (t *Transport) newClientConn(c net.Conn, singleUse bool, hooks *testSyncHooks) (*ClientConn, error) { cc := &ClientConn{ t: t, tconn: c, @@ -750,10 +820,15 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro wantSettingsAck: true, pings: make(map[[8]byte]chan struct{}), reqHeaderMu: make(chan struct{}, 1), + syncHooks: hooks, + } + if hooks != nil { + hooks.newclientconn(cc) + c = cc.tconn } if d := t.idleConnTimeout(); d != 0 { cc.idleTimeout = d - cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout) + cc.idleTimer = cc.afterFunc(d, cc.onIdleTimeout) } if VerboseLogs { t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr()) @@ -818,7 +893,7 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro return nil, cc.werr } - go cc.readLoop() + cc.goRun(cc.readLoop) return cc, nil } @@ -826,7 +901,7 @@ func (cc *ClientConn) healthCheck() { pingTimeout := cc.t.pingTimeout() // We don't need to periodically ping in the health check, because the readLoop of ClientConn will // trigger the healthCheck again if there is no frame received. - ctx, cancel := context.WithTimeout(context.Background(), pingTimeout) + ctx, cancel := cc.contextWithTimeout(context.Background(), pingTimeout) defer cancel() cc.vlogf("http2: Transport sending health check") err := cc.Ping(ctx) @@ -1056,7 +1131,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { // Wait for all in-flight streams to complete or connection to close done := make(chan struct{}) cancelled := false // guarded by cc.mu - go func() { + cc.goRun(func() { cc.mu.Lock() defer cc.mu.Unlock() for { @@ -1068,9 +1143,9 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { if cancelled { break } - cc.cond.Wait() + cc.condWait() } - }() + }) shutdownEnterWaitStateHook() select { case <-done: @@ -1080,7 +1155,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error { cc.mu.Lock() // Free the goroutine above cancelled = true - cc.cond.Broadcast() + cc.condBroadcast() cc.mu.Unlock() return ctx.Err() } @@ -1118,7 +1193,7 @@ func (cc *ClientConn) closeForError(err error) { for _, cs := range cc.streams { cs.abortStreamLocked(err) } - cc.cond.Broadcast() + cc.condBroadcast() cc.mu.Unlock() cc.closeConn() } @@ -1215,6 +1290,10 @@ func (cc *ClientConn) decrStreamReservationsLocked() { } func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { + return cc.roundTrip(req, nil) +} + +func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) (*http.Response, error) { ctx := req.Context() cs := &clientStream{ cc: cc, @@ -1229,9 +1308,23 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { respHeaderRecv: make(chan struct{}), donec: make(chan struct{}), } - go cs.doRequest(req) + cc.goRun(func() { + cs.doRequest(req) + }) waitDone := func() error { + if cc.syncHooks != nil { + cc.syncHooks.blockUntil(func() bool { + select { + case <-cs.donec: + case <-ctx.Done(): + case <-cs.reqCancel: + default: + return false + } + return true + }) + } select { case <-cs.donec: return nil @@ -1292,7 +1385,24 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { return err } + if streamf != nil { + streamf(cs) + } + for { + if cc.syncHooks != nil { + cc.syncHooks.blockUntil(func() bool { + select { + case <-cs.respHeaderRecv: + case <-cs.abort: + case <-ctx.Done(): + case <-cs.reqCancel: + default: + return false + } + return true + }) + } select { case <-cs.respHeaderRecv: return handleResponseHeaders() @@ -1348,6 +1458,21 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { if cc.reqHeaderMu == nil { panic("RoundTrip on uninitialized ClientConn") // for tests } + var newStreamHook func(*clientStream) + if cc.syncHooks != nil { + newStreamHook = cc.syncHooks.newstream + cc.syncHooks.blockUntil(func() bool { + select { + case cc.reqHeaderMu <- struct{}{}: + <-cc.reqHeaderMu + case <-cs.reqCancel: + case <-ctx.Done(): + default: + return false + } + return true + }) + } select { case cc.reqHeaderMu <- struct{}{}: case <-cs.reqCancel: @@ -1372,6 +1497,10 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { } cc.mu.Unlock() + if newStreamHook != nil { + newStreamHook(cs) + } + // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere? if !cc.t.disableCompression() && req.Header.Get("Accept-Encoding") == "" && @@ -1452,15 +1581,30 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { var respHeaderTimer <-chan time.Time var respHeaderRecv chan struct{} if d := cc.responseHeaderTimeout(); d != 0 { - timer := time.NewTimer(d) + timer := cc.newTimer(d) defer timer.Stop() - respHeaderTimer = timer.C + respHeaderTimer = timer.C() respHeaderRecv = cs.respHeaderRecv } // Wait until the peer half-closes its end of the stream, // or until the request is aborted (via context, error, or otherwise), // whichever comes first. for { + if cc.syncHooks != nil { + cc.syncHooks.blockUntil(func() bool { + select { + case <-cs.peerClosed: + case <-respHeaderTimer: + case <-respHeaderRecv: + case <-cs.abort: + case <-ctx.Done(): + case <-cs.reqCancel: + default: + return false + } + return true + }) + } select { case <-cs.peerClosed: return nil @@ -1609,7 +1753,7 @@ func (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error { return nil } cc.pendingRequests++ - cc.cond.Wait() + cc.condWait() cc.pendingRequests-- select { case <-cs.abort: @@ -1871,8 +2015,24 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) cs.flow.take(take) return take, nil } - cc.cond.Wait() + cc.condWait() + } +} + +func validateHeaders(hdrs http.Header) string { + for k, vv := range hdrs { + if !httpguts.ValidHeaderFieldName(k) { + return fmt.Sprintf("name %q", k) + } + for _, v := range vv { + if !httpguts.ValidHeaderFieldValue(v) { + // Don't include the value in the error, + // because it may be sensitive. + return fmt.Sprintf("value for header %q", k) + } + } } + return "" } var errNilRequestURL = errors.New("http2: Request.URI is nil") @@ -1912,19 +2072,14 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail } } - // Check for any invalid headers and return an error before we + // Check for any invalid headers+trailers and return an error before we // potentially pollute our hpack state. (We want to be able to // continue to reuse the hpack encoder for future requests) - for k, vv := range req.Header { - if !httpguts.ValidHeaderFieldName(k) { - return nil, fmt.Errorf("invalid HTTP header name %q", k) - } - for _, v := range vv { - if !httpguts.ValidHeaderFieldValue(v) { - // Don't include the value in the error, because it may be sensitive. - return nil, fmt.Errorf("invalid HTTP header value for header %q", k) - } - } + if err := validateHeaders(req.Header); err != "" { + return nil, fmt.Errorf("invalid HTTP header %s", err) + } + if err := validateHeaders(req.Trailer); err != "" { + return nil, fmt.Errorf("invalid HTTP trailer %s", err) } enumerateHeaders := func(f func(name, value string)) { @@ -2143,7 +2298,7 @@ func (cc *ClientConn) forgetStreamID(id uint32) { } // Wake up writeRequestBody via clientStream.awaitFlowControl and // wake up RoundTrip if there is a pending request. - cc.cond.Broadcast() + cc.condBroadcast() closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil if closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 { @@ -2231,7 +2386,7 @@ func (rl *clientConnReadLoop) cleanup() { cs.abortStreamLocked(err) } } - cc.cond.Broadcast() + cc.condBroadcast() cc.mu.Unlock() } @@ -2266,10 +2421,9 @@ func (rl *clientConnReadLoop) run() error { cc := rl.cc gotSettings := false readIdleTimeout := cc.t.ReadIdleTimeout - var t *time.Timer + var t timer if readIdleTimeout != 0 { - t = time.AfterFunc(readIdleTimeout, cc.healthCheck) - defer t.Stop() + t = cc.afterFunc(readIdleTimeout, cc.healthCheck) } for { f, err := cc.fr.ReadFrame() @@ -2684,7 +2838,7 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error { }) return nil } - if !cs.firstByte { + if !cs.pastHeaders { cc.logf("protocol error: received DATA before a HEADERS frame") rl.endStreamError(cs, StreamError{ StreamID: f.StreamID, @@ -2867,7 +3021,7 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { for _, cs := range cc.streams { cs.flow.add(delta) } - cc.cond.Broadcast() + cc.condBroadcast() cc.initialWindowSize = s.Val case SettingHeaderTableSize: @@ -2911,9 +3065,18 @@ func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error { fl = &cs.flow } if !fl.add(int32(f.Increment)) { + // For stream, the sender sends RST_STREAM with an error code of FLOW_CONTROL_ERROR + if cs != nil { + rl.endStreamError(cs, StreamError{ + StreamID: f.StreamID, + Code: ErrCodeFlowControl, + }) + return nil + } + return ConnectionError(ErrCodeFlowControl) } - cc.cond.Broadcast() + cc.condBroadcast() return nil } @@ -2955,24 +3118,38 @@ func (cc *ClientConn) Ping(ctx context.Context) error { } cc.mu.Unlock() } - errc := make(chan error, 1) - go func() { + var pingError error + errc := make(chan struct{}) + cc.goRun(func() { cc.wmu.Lock() defer cc.wmu.Unlock() - if err := cc.fr.WritePing(false, p); err != nil { - errc <- err + if pingError = cc.fr.WritePing(false, p); pingError != nil { + close(errc) return } - if err := cc.bw.Flush(); err != nil { - errc <- err + if pingError = cc.bw.Flush(); pingError != nil { + close(errc) return } - }() + }) + if cc.syncHooks != nil { + cc.syncHooks.blockUntil(func() bool { + select { + case <-c: + case <-errc: + case <-ctx.Done(): + case <-cc.readerDone: + default: + return false + } + return true + }) + } select { case <-c: return nil - case err := <-errc: - return err + case <-errc: + return pingError case <-ctx.Done(): return ctx.Err() case <-cc.readerDone: @@ -3141,9 +3318,17 @@ func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, err } func (t *Transport) idleConnTimeout() time.Duration { + // to keep things backwards compatible, we use non-zero values of + // IdleConnTimeout, followed by using the IdleConnTimeout on the underlying + // http1 transport, followed by 0 + if t.IdleConnTimeout != 0 { + return t.IdleConnTimeout + } + if t.t1 != nil { return t.t1.IdleConnTimeout } + return 0 } diff --git a/vendor/golang.org/x/sys/unix/aliases.go b/vendor/golang.org/x/sys/unix/aliases.go index e7d3df4bd360..b0e419857502 100644 --- a/vendor/golang.org/x/sys/unix/aliases.go +++ b/vendor/golang.org/x/sys/unix/aliases.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) && go1.9 +//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos package unix diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index c6492020ec79..fdcaa974d23b 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -584,7 +584,7 @@ ccflags="$@" $2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ || $2 ~ /^KEYCTL_/ || $2 ~ /^PERF_/ || - $2 ~ /^SECCOMP_MODE_/ || + $2 ~ /^SECCOMP_/ || $2 ~ /^SEEK_/ || $2 ~ /^SCHED_/ || $2 ~ /^SPLICE_/ || diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go b/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go index 16dc6993799f..2f0fa76e4f65 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build darwin && go1.12 +//go:build darwin package unix diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd.go b/vendor/golang.org/x/sys/unix/syscall_freebsd.go index 64d1bb4dba58..2b57e0f73bb8 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd.go @@ -13,6 +13,7 @@ package unix import ( + "errors" "sync" "unsafe" ) @@ -169,25 +170,26 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { func Uname(uname *Utsname) error { mib := []_C_int{CTL_KERN, KERN_OSTYPE} n := unsafe.Sizeof(uname.Sysname) - if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil { + // Suppress ENOMEM errors to be compatible with the C library __xuname() implementation. + if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } mib = []_C_int{CTL_KERN, KERN_HOSTNAME} n = unsafe.Sizeof(uname.Nodename) - if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } mib = []_C_int{CTL_KERN, KERN_OSRELEASE} n = unsafe.Sizeof(uname.Release) - if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } mib = []_C_int{CTL_KERN, KERN_VERSION} n = unsafe.Sizeof(uname.Version) - if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } @@ -205,7 +207,7 @@ func Uname(uname *Utsname) error { mib = []_C_int{CTL_HW, HW_MACHINE} n = unsafe.Sizeof(uname.Machine) - if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 0f85e29e621c..5682e2628ad0 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -1849,6 +1849,105 @@ func Dup2(oldfd, newfd int) error { //sys Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error) //sys Fsopen(fsName string, flags int) (fd int, err error) //sys Fspick(dirfd int, pathName string, flags int) (fd int, err error) + +//sys fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error) + +func fsconfigCommon(fd int, cmd uint, key string, value *byte, aux int) (err error) { + var keyp *byte + if keyp, err = BytePtrFromString(key); err != nil { + return + } + return fsconfig(fd, cmd, keyp, value, aux) +} + +// FsconfigSetFlag is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_FLAG. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +func FsconfigSetFlag(fd int, key string) (err error) { + return fsconfigCommon(fd, FSCONFIG_SET_FLAG, key, nil, 0) +} + +// FsconfigSetString is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_STRING. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// value is the parameter value to set. +func FsconfigSetString(fd int, key string, value string) (err error) { + var valuep *byte + if valuep, err = BytePtrFromString(value); err != nil { + return + } + return fsconfigCommon(fd, FSCONFIG_SET_STRING, key, valuep, 0) +} + +// FsconfigSetBinary is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_BINARY. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// value is the parameter value to set. +func FsconfigSetBinary(fd int, key string, value []byte) (err error) { + if len(value) == 0 { + return EINVAL + } + return fsconfigCommon(fd, FSCONFIG_SET_BINARY, key, &value[0], len(value)) +} + +// FsconfigSetPath is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_PATH. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// path is a non-empty path for specified key. +// atfd is a file descriptor at which to start lookup from or AT_FDCWD. +func FsconfigSetPath(fd int, key string, path string, atfd int) (err error) { + var valuep *byte + if valuep, err = BytePtrFromString(path); err != nil { + return + } + return fsconfigCommon(fd, FSCONFIG_SET_PATH, key, valuep, atfd) +} + +// FsconfigSetPathEmpty is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_PATH_EMPTY. The same as +// FconfigSetPath but with AT_PATH_EMPTY implied. +func FsconfigSetPathEmpty(fd int, key string, path string, atfd int) (err error) { + var valuep *byte + if valuep, err = BytePtrFromString(path); err != nil { + return + } + return fsconfigCommon(fd, FSCONFIG_SET_PATH_EMPTY, key, valuep, atfd) +} + +// FsconfigSetFd is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_FD. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// value is a file descriptor to be assigned to specified key. +func FsconfigSetFd(fd int, key string, value int) (err error) { + return fsconfigCommon(fd, FSCONFIG_SET_FD, key, nil, value) +} + +// FsconfigCreate is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_CMD_CREATE. +// +// fd is the filesystem context to act upon. +func FsconfigCreate(fd int) (err error) { + return fsconfig(fd, FSCONFIG_CMD_CREATE, nil, nil, 0) +} + +// FsconfigReconfigure is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_CMD_RECONFIGURE. +// +// fd is the filesystem context to act upon. +func FsconfigReconfigure(fd int) (err error) { + return fsconfig(fd, FSCONFIG_CMD_RECONFIGURE, nil, nil, 0) +} + //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 //sysnb Getpgid(pid int) (pgid int, err error) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index a5d3ff8df95e..36bf8399f4fa 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -1785,6 +1785,8 @@ const ( LANDLOCK_ACCESS_FS_REMOVE_FILE = 0x20 LANDLOCK_ACCESS_FS_TRUNCATE = 0x4000 LANDLOCK_ACCESS_FS_WRITE_FILE = 0x2 + LANDLOCK_ACCESS_NET_BIND_TCP = 0x1 + LANDLOCK_ACCESS_NET_CONNECT_TCP = 0x2 LANDLOCK_CREATE_RULESET_VERSION = 0x1 LINUX_REBOOT_CMD_CAD_OFF = 0x0 LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef @@ -2465,6 +2467,7 @@ const ( PR_MCE_KILL_GET = 0x22 PR_MCE_KILL_LATE = 0x0 PR_MCE_KILL_SET = 0x1 + PR_MDWE_NO_INHERIT = 0x2 PR_MDWE_REFUSE_EXEC_GAIN = 0x1 PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_ENABLE_MANAGEMENT = 0x2b @@ -2669,8 +2672,9 @@ const ( RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 - RTAX_FEATURE_MASK = 0xf + RTAX_FEATURE_MASK = 0x1f RTAX_FEATURE_SACK = 0x2 + RTAX_FEATURE_TCP_USEC_TS = 0x10 RTAX_FEATURE_TIMESTAMP = 0x4 RTAX_HOPLIMIT = 0xa RTAX_INITCWND = 0xb @@ -2913,9 +2917,38 @@ const ( SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x1d SC_LOG_FLUSH = 0x100000 + SECCOMP_ADDFD_FLAG_SEND = 0x2 + SECCOMP_ADDFD_FLAG_SETFD = 0x1 + SECCOMP_FILTER_FLAG_LOG = 0x2 + SECCOMP_FILTER_FLAG_NEW_LISTENER = 0x8 + SECCOMP_FILTER_FLAG_SPEC_ALLOW = 0x4 + SECCOMP_FILTER_FLAG_TSYNC = 0x1 + SECCOMP_FILTER_FLAG_TSYNC_ESRCH = 0x10 + SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV = 0x20 + SECCOMP_GET_ACTION_AVAIL = 0x2 + SECCOMP_GET_NOTIF_SIZES = 0x3 + SECCOMP_IOCTL_NOTIF_RECV = 0xc0502100 + SECCOMP_IOCTL_NOTIF_SEND = 0xc0182101 + SECCOMP_IOC_MAGIC = '!' SECCOMP_MODE_DISABLED = 0x0 SECCOMP_MODE_FILTER = 0x2 SECCOMP_MODE_STRICT = 0x1 + SECCOMP_RET_ACTION = 0x7fff0000 + SECCOMP_RET_ACTION_FULL = 0xffff0000 + SECCOMP_RET_ALLOW = 0x7fff0000 + SECCOMP_RET_DATA = 0xffff + SECCOMP_RET_ERRNO = 0x50000 + SECCOMP_RET_KILL = 0x0 + SECCOMP_RET_KILL_PROCESS = 0x80000000 + SECCOMP_RET_KILL_THREAD = 0x0 + SECCOMP_RET_LOG = 0x7ffc0000 + SECCOMP_RET_TRACE = 0x7ff00000 + SECCOMP_RET_TRAP = 0x30000 + SECCOMP_RET_USER_NOTIF = 0x7fc00000 + SECCOMP_SET_MODE_FILTER = 0x1 + SECCOMP_SET_MODE_STRICT = 0x0 + SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP = 0x1 + SECCOMP_USER_NOTIF_FLAG_CONTINUE = 0x1 SECRETMEM_MAGIC = 0x5345434d SECURITYFS_MAGIC = 0x73636673 SEEK_CUR = 0x1 @@ -3075,6 +3108,7 @@ const ( SOL_TIPC = 0x10f SOL_TLS = 0x11a SOL_UDP = 0x11 + SOL_VSOCK = 0x11f SOL_X25 = 0x106 SOL_XDP = 0x11b SOMAXCONN = 0x1000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index 4920821cf3b2..42ff8c3c1b06 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index a0c1e411275c..dca436004fa4 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -282,6 +282,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index c63985560f61..5cca668ac302 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -288,6 +288,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index 47cc62e25c14..d8cae6d15340 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -278,6 +278,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index 27ac4a09e22a..28e39afdcb4a 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -275,6 +275,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index 54694642a5de..cd66e92cb426 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x80 SIOCATMARK = 0x40047307 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index 3adb81d75822..c1595eba78e3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x80 SIOCATMARK = 0x40047307 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index 2dfe98f0d1b1..ee9456b0da74 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x80 SIOCATMARK = 0x40047307 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index f5398f84f041..8cfca81e1b56 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x80 SIOCATMARK = 0x40047307 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index c54f152d68fd..60b0deb3af77 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -336,6 +336,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 76057dc72fb5..f90aa7281bfb 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -340,6 +340,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index e0c3725e2b89..ba9e01503383 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -340,6 +340,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index 18f2813ed54b..07cdfd6e9fd3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -272,6 +272,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index 11619d4ec88f..2f1dd214a74e 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -344,6 +344,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index 396d994da79c..f40519d90180 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -335,6 +335,9 @@ const ( SCM_TIMESTAMPNS = 0x21 SCM_TXTIME = 0x3f SCM_WIFI_STATUS = 0x25 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x400000 SFD_NONBLOCK = 0x4000 SF_FP = 0x38 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go index 1488d27128cd..87d8612a1dc7 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -906,6 +906,16 @@ func Fspick(dirfd int, pathName string, flags int) (fd int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error) { + _, _, e1 := Syscall6(SYS_FSCONFIG, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(value)), uintptr(aux), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getdents(fd int, buf []byte) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go index fcf3ecbddee1..0cc3ce496e22 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go @@ -448,4 +448,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go index f56dc2504ae1..856d92d69ef9 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go @@ -371,4 +371,7 @@ const ( SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go index 974bf246767e..8d467094cf57 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go @@ -412,4 +412,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go index 39a2739e2310..edc173244d0d 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -315,4 +315,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go index cf9c9d77e10f..445eba206155 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go @@ -309,4 +309,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go index 10b7362ef442..adba01bca701 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go @@ -432,4 +432,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 4450 SYS_CACHESTAT = 4451 SYS_FCHMODAT2 = 4452 + SYS_MAP_SHADOW_STACK = 4453 + SYS_FUTEX_WAKE = 4454 + SYS_FUTEX_WAIT = 4455 + SYS_FUTEX_REQUEUE = 4456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go index cd4d8b4fd35e..014c4e9c7a75 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go @@ -362,4 +362,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 5450 SYS_CACHESTAT = 5451 SYS_FCHMODAT2 = 5452 + SYS_MAP_SHADOW_STACK = 5453 + SYS_FUTEX_WAKE = 5454 + SYS_FUTEX_WAIT = 5455 + SYS_FUTEX_REQUEUE = 5456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go index 2c0efca818b3..ccc97d74d05d 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go @@ -362,4 +362,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 5450 SYS_CACHESTAT = 5451 SYS_FCHMODAT2 = 5452 + SYS_MAP_SHADOW_STACK = 5453 + SYS_FUTEX_WAKE = 5454 + SYS_FUTEX_WAIT = 5455 + SYS_FUTEX_REQUEUE = 5456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go index a72e31d391d5..ec2b64a95d74 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go @@ -432,4 +432,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 4450 SYS_CACHESTAT = 4451 SYS_FCHMODAT2 = 4452 + SYS_MAP_SHADOW_STACK = 4453 + SYS_FUTEX_WAKE = 4454 + SYS_FUTEX_WAIT = 4455 + SYS_FUTEX_REQUEUE = 4456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go index c7d1e374713c..21a839e338b3 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go @@ -439,4 +439,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go index f4d4838c870d..c11121ec3b4d 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go @@ -411,4 +411,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go index b64f0e59114d..909b631fcb45 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go @@ -411,4 +411,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go index 95711195a064..e49bed16ea6b 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -316,4 +316,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go index f94e943bc4f5..66017d2d32b3 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go @@ -377,4 +377,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go index ba0c2bc5154a..47bab18dcedb 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go @@ -390,4 +390,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index bbf8399ff586..eff6bcdef814 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -174,7 +174,8 @@ type FscryptPolicyV2 struct { Contents_encryption_mode uint8 Filenames_encryption_mode uint8 Flags uint8 - _ [4]uint8 + Log2_data_unit_size uint8 + _ [3]uint8 Master_key_identifier [16]uint8 } @@ -455,60 +456,63 @@ type Ucred struct { } type TCPInfo struct { - State uint8 - Ca_state uint8 - Retransmits uint8 - Probes uint8 - Backoff uint8 - Options uint8 - Rto uint32 - Ato uint32 - Snd_mss uint32 - Rcv_mss uint32 - Unacked uint32 - Sacked uint32 - Lost uint32 - Retrans uint32 - Fackets uint32 - Last_data_sent uint32 - Last_ack_sent uint32 - Last_data_recv uint32 - Last_ack_recv uint32 - Pmtu uint32 - Rcv_ssthresh uint32 - Rtt uint32 - Rttvar uint32 - Snd_ssthresh uint32 - Snd_cwnd uint32 - Advmss uint32 - Reordering uint32 - Rcv_rtt uint32 - Rcv_space uint32 - Total_retrans uint32 - Pacing_rate uint64 - Max_pacing_rate uint64 - Bytes_acked uint64 - Bytes_received uint64 - Segs_out uint32 - Segs_in uint32 - Notsent_bytes uint32 - Min_rtt uint32 - Data_segs_in uint32 - Data_segs_out uint32 - Delivery_rate uint64 - Busy_time uint64 - Rwnd_limited uint64 - Sndbuf_limited uint64 - Delivered uint32 - Delivered_ce uint32 - Bytes_sent uint64 - Bytes_retrans uint64 - Dsack_dups uint32 - Reord_seen uint32 - Rcv_ooopack uint32 - Snd_wnd uint32 - Rcv_wnd uint32 - Rehash uint32 + State uint8 + Ca_state uint8 + Retransmits uint8 + Probes uint8 + Backoff uint8 + Options uint8 + Rto uint32 + Ato uint32 + Snd_mss uint32 + Rcv_mss uint32 + Unacked uint32 + Sacked uint32 + Lost uint32 + Retrans uint32 + Fackets uint32 + Last_data_sent uint32 + Last_ack_sent uint32 + Last_data_recv uint32 + Last_ack_recv uint32 + Pmtu uint32 + Rcv_ssthresh uint32 + Rtt uint32 + Rttvar uint32 + Snd_ssthresh uint32 + Snd_cwnd uint32 + Advmss uint32 + Reordering uint32 + Rcv_rtt uint32 + Rcv_space uint32 + Total_retrans uint32 + Pacing_rate uint64 + Max_pacing_rate uint64 + Bytes_acked uint64 + Bytes_received uint64 + Segs_out uint32 + Segs_in uint32 + Notsent_bytes uint32 + Min_rtt uint32 + Data_segs_in uint32 + Data_segs_out uint32 + Delivery_rate uint64 + Busy_time uint64 + Rwnd_limited uint64 + Sndbuf_limited uint64 + Delivered uint32 + Delivered_ce uint32 + Bytes_sent uint64 + Bytes_retrans uint64 + Dsack_dups uint32 + Reord_seen uint32 + Rcv_ooopack uint32 + Snd_wnd uint32 + Rcv_wnd uint32 + Rehash uint32 + Total_rto uint16 + Total_rto_recoveries uint16 + Total_rto_time uint32 } type CanFilter struct { @@ -551,7 +555,7 @@ const ( SizeofIPv6MTUInfo = 0x20 SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc - SizeofTCPInfo = 0xf0 + SizeofTCPInfo = 0xf8 SizeofCanFilter = 0x8 SizeofTCPRepairOpt = 0x8 ) @@ -832,6 +836,15 @@ const ( FSPICK_EMPTY_PATH = 0x8 FSMOUNT_CLOEXEC = 0x1 + + FSCONFIG_SET_FLAG = 0x0 + FSCONFIG_SET_STRING = 0x1 + FSCONFIG_SET_BINARY = 0x2 + FSCONFIG_SET_PATH = 0x3 + FSCONFIG_SET_PATH_EMPTY = 0x4 + FSCONFIG_SET_FD = 0x5 + FSCONFIG_CMD_CREATE = 0x6 + FSCONFIG_CMD_RECONFIGURE = 0x7 ) type OpenHow struct { @@ -1546,6 +1559,7 @@ const ( IFLA_DEVLINK_PORT = 0x3e IFLA_GSO_IPV4_MAX_SIZE = 0x3f IFLA_GRO_IPV4_MAX_SIZE = 0x40 + IFLA_DPLL_PIN = 0x41 IFLA_PROTO_DOWN_REASON_UNSPEC = 0x0 IFLA_PROTO_DOWN_REASON_MASK = 0x1 IFLA_PROTO_DOWN_REASON_VALUE = 0x2 @@ -1561,6 +1575,7 @@ const ( IFLA_INET6_ICMP6STATS = 0x6 IFLA_INET6_TOKEN = 0x7 IFLA_INET6_ADDR_GEN_MODE = 0x8 + IFLA_INET6_RA_MTU = 0x9 IFLA_BR_UNSPEC = 0x0 IFLA_BR_FORWARD_DELAY = 0x1 IFLA_BR_HELLO_TIME = 0x2 @@ -1608,6 +1623,9 @@ const ( IFLA_BR_MCAST_MLD_VERSION = 0x2c IFLA_BR_VLAN_STATS_PER_PORT = 0x2d IFLA_BR_MULTI_BOOLOPT = 0x2e + IFLA_BR_MCAST_QUERIER_STATE = 0x2f + IFLA_BR_FDB_N_LEARNED = 0x30 + IFLA_BR_FDB_MAX_LEARNED = 0x31 IFLA_BRPORT_UNSPEC = 0x0 IFLA_BRPORT_STATE = 0x1 IFLA_BRPORT_PRIORITY = 0x2 @@ -1645,6 +1663,14 @@ const ( IFLA_BRPORT_BACKUP_PORT = 0x22 IFLA_BRPORT_MRP_RING_OPEN = 0x23 IFLA_BRPORT_MRP_IN_OPEN = 0x24 + IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT = 0x25 + IFLA_BRPORT_MCAST_EHT_HOSTS_CNT = 0x26 + IFLA_BRPORT_LOCKED = 0x27 + IFLA_BRPORT_MAB = 0x28 + IFLA_BRPORT_MCAST_N_GROUPS = 0x29 + IFLA_BRPORT_MCAST_MAX_GROUPS = 0x2a + IFLA_BRPORT_NEIGH_VLAN_SUPPRESS = 0x2b + IFLA_BRPORT_BACKUP_NHID = 0x2c IFLA_INFO_UNSPEC = 0x0 IFLA_INFO_KIND = 0x1 IFLA_INFO_DATA = 0x2 @@ -1666,6 +1692,9 @@ const ( IFLA_MACVLAN_MACADDR = 0x4 IFLA_MACVLAN_MACADDR_DATA = 0x5 IFLA_MACVLAN_MACADDR_COUNT = 0x6 + IFLA_MACVLAN_BC_QUEUE_LEN = 0x7 + IFLA_MACVLAN_BC_QUEUE_LEN_USED = 0x8 + IFLA_MACVLAN_BC_CUTOFF = 0x9 IFLA_VRF_UNSPEC = 0x0 IFLA_VRF_TABLE = 0x1 IFLA_VRF_PORT_UNSPEC = 0x0 @@ -1689,9 +1718,22 @@ const ( IFLA_XFRM_UNSPEC = 0x0 IFLA_XFRM_LINK = 0x1 IFLA_XFRM_IF_ID = 0x2 + IFLA_XFRM_COLLECT_METADATA = 0x3 IFLA_IPVLAN_UNSPEC = 0x0 IFLA_IPVLAN_MODE = 0x1 IFLA_IPVLAN_FLAGS = 0x2 + NETKIT_NEXT = -0x1 + NETKIT_PASS = 0x0 + NETKIT_DROP = 0x2 + NETKIT_REDIRECT = 0x7 + NETKIT_L2 = 0x0 + NETKIT_L3 = 0x1 + IFLA_NETKIT_UNSPEC = 0x0 + IFLA_NETKIT_PEER_INFO = 0x1 + IFLA_NETKIT_PRIMARY = 0x2 + IFLA_NETKIT_POLICY = 0x3 + IFLA_NETKIT_PEER_POLICY = 0x4 + IFLA_NETKIT_MODE = 0x5 IFLA_VXLAN_UNSPEC = 0x0 IFLA_VXLAN_ID = 0x1 IFLA_VXLAN_GROUP = 0x2 @@ -1722,6 +1764,8 @@ const ( IFLA_VXLAN_GPE = 0x1b IFLA_VXLAN_TTL_INHERIT = 0x1c IFLA_VXLAN_DF = 0x1d + IFLA_VXLAN_VNIFILTER = 0x1e + IFLA_VXLAN_LOCALBYPASS = 0x1f IFLA_GENEVE_UNSPEC = 0x0 IFLA_GENEVE_ID = 0x1 IFLA_GENEVE_REMOTE = 0x2 @@ -1736,6 +1780,7 @@ const ( IFLA_GENEVE_LABEL = 0xb IFLA_GENEVE_TTL_INHERIT = 0xc IFLA_GENEVE_DF = 0xd + IFLA_GENEVE_INNER_PROTO_INHERIT = 0xe IFLA_BAREUDP_UNSPEC = 0x0 IFLA_BAREUDP_PORT = 0x1 IFLA_BAREUDP_ETHERTYPE = 0x2 @@ -1748,6 +1793,8 @@ const ( IFLA_GTP_FD1 = 0x2 IFLA_GTP_PDP_HASHSIZE = 0x3 IFLA_GTP_ROLE = 0x4 + IFLA_GTP_CREATE_SOCKETS = 0x5 + IFLA_GTP_RESTART_COUNT = 0x6 IFLA_BOND_UNSPEC = 0x0 IFLA_BOND_MODE = 0x1 IFLA_BOND_ACTIVE_SLAVE = 0x2 @@ -1777,6 +1824,9 @@ const ( IFLA_BOND_AD_ACTOR_SYSTEM = 0x1a IFLA_BOND_TLB_DYNAMIC_LB = 0x1b IFLA_BOND_PEER_NOTIF_DELAY = 0x1c + IFLA_BOND_AD_LACP_ACTIVE = 0x1d + IFLA_BOND_MISSED_MAX = 0x1e + IFLA_BOND_NS_IP6_TARGET = 0x1f IFLA_BOND_AD_INFO_UNSPEC = 0x0 IFLA_BOND_AD_INFO_AGGREGATOR = 0x1 IFLA_BOND_AD_INFO_NUM_PORTS = 0x2 @@ -1792,6 +1842,7 @@ const ( IFLA_BOND_SLAVE_AD_AGGREGATOR_ID = 0x6 IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE = 0x7 IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE = 0x8 + IFLA_BOND_SLAVE_PRIO = 0x9 IFLA_VF_INFO_UNSPEC = 0x0 IFLA_VF_INFO = 0x1 IFLA_VF_UNSPEC = 0x0 @@ -1850,8 +1901,16 @@ const ( IFLA_STATS_LINK_XSTATS_SLAVE = 0x3 IFLA_STATS_LINK_OFFLOAD_XSTATS = 0x4 IFLA_STATS_AF_SPEC = 0x5 + IFLA_STATS_GETSET_UNSPEC = 0x0 + IFLA_STATS_GET_FILTERS = 0x1 + IFLA_STATS_SET_OFFLOAD_XSTATS_L3_STATS = 0x2 IFLA_OFFLOAD_XSTATS_UNSPEC = 0x0 IFLA_OFFLOAD_XSTATS_CPU_HIT = 0x1 + IFLA_OFFLOAD_XSTATS_HW_S_INFO = 0x2 + IFLA_OFFLOAD_XSTATS_L3_STATS = 0x3 + IFLA_OFFLOAD_XSTATS_HW_S_INFO_UNSPEC = 0x0 + IFLA_OFFLOAD_XSTATS_HW_S_INFO_REQUEST = 0x1 + IFLA_OFFLOAD_XSTATS_HW_S_INFO_USED = 0x2 IFLA_XDP_UNSPEC = 0x0 IFLA_XDP_FD = 0x1 IFLA_XDP_ATTACHED = 0x2 @@ -1881,6 +1940,11 @@ const ( IFLA_RMNET_UNSPEC = 0x0 IFLA_RMNET_MUX_ID = 0x1 IFLA_RMNET_FLAGS = 0x2 + IFLA_MCTP_UNSPEC = 0x0 + IFLA_MCTP_NET = 0x1 + IFLA_DSA_UNSPEC = 0x0 + IFLA_DSA_CONDUIT = 0x1 + IFLA_DSA_MASTER = 0x1 ) const ( @@ -3399,7 +3463,7 @@ const ( DEVLINK_PORT_FN_ATTR_STATE = 0x2 DEVLINK_PORT_FN_ATTR_OPSTATE = 0x3 DEVLINK_PORT_FN_ATTR_CAPS = 0x4 - DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x4 + DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x5 ) type FsverityDigest struct { @@ -4183,7 +4247,8 @@ const ( ) type LandlockRulesetAttr struct { - Access_fs uint64 + Access_fs uint64 + Access_net uint64 } type LandlockPathBeneathAttr struct { @@ -5134,7 +5199,7 @@ const ( NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf - NL80211_FREQUENCY_ATTR_MAX = 0x1b + NL80211_FREQUENCY_ATTR_MAX = 0x1c NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6 NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11 NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc @@ -5547,7 +5612,7 @@ const ( NL80211_REGDOM_TYPE_CUSTOM_WORLD = 0x2 NL80211_REGDOM_TYPE_INTERSECTION = 0x3 NL80211_REGDOM_TYPE_WORLD = 0x1 - NL80211_REG_RULE_ATTR_MAX = 0x7 + NL80211_REG_RULE_ATTR_MAX = 0x8 NL80211_REKEY_DATA_AKM = 0x4 NL80211_REKEY_DATA_KCK = 0x2 NL80211_REKEY_DATA_KEK = 0x1 diff --git a/vendor/golang.org/x/sys/windows/env_windows.go b/vendor/golang.org/x/sys/windows/env_windows.go index b8ad19250689..d4577a423887 100644 --- a/vendor/golang.org/x/sys/windows/env_windows.go +++ b/vendor/golang.org/x/sys/windows/env_windows.go @@ -37,14 +37,17 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) { return nil, err } defer DestroyEnvironmentBlock(block) - blockp := unsafe.Pointer(block) - for { - entry := UTF16PtrToString((*uint16)(blockp)) - if len(entry) == 0 { - break + size := unsafe.Sizeof(*block) + for *block != 0 { + // find NUL terminator + end := unsafe.Pointer(block) + for *(*uint16)(end) != 0 { + end = unsafe.Add(end, size) } - env = append(env, entry) - blockp = unsafe.Add(blockp, 2*(len(entry)+1)) + + entry := unsafe.Slice(block, (uintptr(end)-uintptr(unsafe.Pointer(block)))/size) + env = append(env, UTF16ToString(entry)) + block = (*uint16)(unsafe.Add(end, size)) } return env, nil } diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index ffb8708ccf8a..6395a031d45d 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -125,8 +125,7 @@ func UTF16PtrToString(p *uint16) string { for ptr := unsafe.Pointer(p); *(*uint16)(ptr) != 0; n++ { ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p)) } - - return string(utf16.Decode(unsafe.Slice(p, n))) + return UTF16ToString(unsafe.Slice(p, n)) } func Getpagesize() int { return 4096 } diff --git a/vendor/modules.txt b/vendor/modules.txt index 7ef220b9842f..187464100ff6 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -53,7 +53,7 @@ github.com/docker/distribution/registry/client/transport github.com/docker/distribution/registry/storage/cache github.com/docker/distribution/registry/storage/cache/memory github.com/docker/distribution/uuid -# github.com/docker/docker v25.0.0-rc.3+incompatible +# github.com/docker/docker v25.0.5-0.20240319141229-e63daec8672d+incompatible ## explicit github.com/docker/docker/api github.com/docker/docker/api/types @@ -120,8 +120,8 @@ github.com/felixge/httpsnoop # github.com/fvbommel/sortorder v1.0.2 ## explicit; go 1.13 github.com/fvbommel/sortorder -# github.com/go-logr/logr v1.2.4 -## explicit; go 1.16 +# github.com/go-logr/logr v1.3.0 +## explicit; go 1.18 github.com/go-logr/logr github.com/go-logr/logr/funcr # github.com/go-logr/stdr v1.2.2 @@ -168,6 +168,8 @@ github.com/klauspost/compress/internal/cpuinfo github.com/klauspost/compress/internal/snapref github.com/klauspost/compress/zstd github.com/klauspost/compress/zstd/internal/xxhash +# github.com/kr/pretty v0.3.1 +## explicit; go 1.12 # github.com/mattn/go-runewidth v0.0.15 ## explicit; go 1.9 github.com/mattn/go-runewidth @@ -242,6 +244,8 @@ github.com/prometheus/procfs/internal/util # github.com/rivo/uniseg v0.2.0 ## explicit; go 1.12 github.com/rivo/uniseg +# github.com/rogpeppe/go-internal v1.10.0 +## explicit; go 1.19 # github.com/sirupsen/logrus v1.9.3 ## explicit; go 1.13 github.com/sirupsen/logrus @@ -282,11 +286,11 @@ github.com/xeipuuv/gojsonschema # go.etcd.io/etcd/raft/v3 v3.5.6 ## explicit; go 1.16 go.etcd.io/etcd/raft/v3/raftpb -# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 -## explicit; go 1.19 +# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 +## explicit; go 1.20 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil -# go.opentelemetry.io/otel v1.19.0 +# go.opentelemetry.io/otel v1.21.0 ## explicit; go 1.20 go.opentelemetry.io/otel go.opentelemetry.io/otel/attribute @@ -298,21 +302,26 @@ go.opentelemetry.io/otel/internal/baggage go.opentelemetry.io/otel/internal/global go.opentelemetry.io/otel/propagation go.opentelemetry.io/otel/semconv/v1.17.0 -# go.opentelemetry.io/otel/metric v1.19.0 +# go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 +## explicit; go 1.20 +# go.opentelemetry.io/otel/metric v1.21.0 ## explicit; go 1.20 go.opentelemetry.io/otel/metric go.opentelemetry.io/otel/metric/embedded -# go.opentelemetry.io/otel/trace v1.19.0 +# go.opentelemetry.io/otel/sdk v1.21.0 +## explicit; go 1.20 +# go.opentelemetry.io/otel/trace v1.21.0 ## explicit; go 1.20 go.opentelemetry.io/otel/trace -# golang.org/x/crypto v0.17.0 +go.opentelemetry.io/otel/trace/embedded +# golang.org/x/crypto v0.21.0 ## explicit; go 1.18 golang.org/x/crypto/ed25519 golang.org/x/crypto/pbkdf2 # golang.org/x/mod v0.14.0 ## explicit; go 1.18 golang.org/x/mod/semver -# golang.org/x/net v0.19.0 +# golang.org/x/net v0.23.0 ## explicit; go 1.18 golang.org/x/net/http/httpguts golang.org/x/net/http2 @@ -323,12 +332,12 @@ golang.org/x/net/trace # golang.org/x/sync v0.6.0 ## explicit; go 1.18 golang.org/x/sync/errgroup -# golang.org/x/sys v0.16.0 +# golang.org/x/sys v0.18.0 ## explicit; go 1.18 golang.org/x/sys/plan9 golang.org/x/sys/unix golang.org/x/sys/windows -# golang.org/x/term v0.15.0 +# golang.org/x/term v0.18.0 ## explicit; go 1.18 golang.org/x/term # golang.org/x/text v0.14.0