remove internal/compatcontext and use context instead

This internal package was added in f6e44bc0e8
to preserve compatibility with go1.20 and older. At the time, our vendor.mod
still had go1.18 as minimum version requirement (see [1]), which got updated to go1.20
in 16063c7456, and go1.21 in f90b03ee5d

The version of BuildKit we use already started using context.WithoutCancel,
without a fallback, so we no longer can provide compatibility with older
versions of Go, which makes our compatiblity package redundant.

This patch removes the package, and updates our code to use stdlib's context
instead.

[1]: f6e44bc0e8/vendor.mod (L7)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2024-06-13 12:10:23 +02:00
parent 52333f3a34
commit 5343c7b451
24 changed files with 44 additions and 161 deletions

View File

@@ -11,7 +11,6 @@ import (
"github.com/containerd/log"
distref "github.com/distribution/reference"
"github.com/docker/docker/image"
"github.com/docker/docker/internal/compatcontext"
"github.com/docker/docker/layer"
"github.com/moby/buildkit/exporter"
"github.com/moby/buildkit/exporter/containerimage"
@@ -240,7 +239,7 @@ func (e *imageExporterInstance) newTempReference(ctx context.Context, config []b
}
unlease := func(ctx context.Context) error {
err := done(compatcontext.WithoutCancel(ctx))
err := done(context.WithoutCancel(ctx))
if err != nil {
log.G(ctx).WithError(err).Error("failed to delete descriptor reference lease")
}

View File

@@ -11,7 +11,6 @@ import (
"github.com/docker/docker/daemon/cluster/convert"
internalnetwork "github.com/docker/docker/daemon/network"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/internal/compatcontext"
"github.com/docker/docker/runconfig"
swarmapi "github.com/moby/swarmkit/v2/api"
"github.com/pkg/errors"
@@ -224,7 +223,7 @@ func (c *Cluster) AttachNetwork(target string, containerID string, addresses []s
log.G(ctx).Debugf("Successfully attached to network %s with task id %s", target, taskID)
release := func() {
ctx := compatcontext.WithoutCancel(ctx)
ctx := context.WithoutCancel(ctx)
ctx, cancel := context.WithTimeout(ctx, swarmRequestTimeout)
defer cancel()
if err := agent.ResourceAllocator().DetachNetwork(ctx, taskID); err != nil {

View File

@@ -21,7 +21,6 @@ import (
timetypes "github.com/docker/docker/api/types/time"
"github.com/docker/docker/daemon/cluster/convert"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/internal/compatcontext"
runconfigopts "github.com/docker/docker/runconfig/opts"
gogotypes "github.com/gogo/protobuf/types"
swarmapi "github.com/moby/swarmkit/v2/api"
@@ -266,7 +265,7 @@ func (c *Cluster) CreateService(s swarm.ServiceSpec, encodedAuth string, queryRe
// "ctx" could make it impossible to create a service
// if the registry is slow or unresponsive.
var cancel func()
ctx = compatcontext.WithoutCancel(ctx)
ctx = context.WithoutCancel(ctx)
ctx, cancel = context.WithTimeout(ctx, swarmRequestTimeout)
defer cancel()
}
@@ -382,7 +381,7 @@ func (c *Cluster) UpdateService(serviceIDOrName string, version uint64, spec swa
// "ctx" could make it impossible to update a service
// if the registry is slow or unresponsive.
var cancel func()
ctx = compatcontext.WithoutCancel(ctx)
ctx = context.WithoutCancel(ctx)
ctx, cancel = context.WithTimeout(ctx, swarmRequestTimeout)
defer cancel()
}

View File

@@ -27,7 +27,6 @@ import (
"github.com/docker/docker/builder"
"github.com/docker/docker/errdefs"
dimage "github.com/docker/docker/image"
"github.com/docker/docker/internal/compatcontext"
"github.com/docker/docker/layer"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/progress"
@@ -499,7 +498,7 @@ func (i *ImageService) createImageOCI(ctx context.Context, imgToCreate imagespec
return "", err
}
defer func() {
if err := release(compatcontext.WithoutCancel(ctx)); err != nil {
if err := release(context.WithoutCancel(ctx)); err != nil {
log.G(ctx).WithError(err).Warn("failed to release lease created for create")
}
}()

View File

@@ -20,7 +20,6 @@ import (
"github.com/containerd/log"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/image"
"github.com/docker/docker/internal/compatcontext"
"github.com/docker/docker/pkg/archive"
imagespec "github.com/moby/docker-image-spec/specs-go/v1"
"github.com/opencontainers/go-digest"
@@ -74,7 +73,7 @@ func (i *ImageService) CommitImage(ctx context.Context, cc backend.CommitConfig)
return "", fmt.Errorf("failed to create lease for commit: %w", err)
}
defer func() {
if err := release(compatcontext.WithoutCancel(ctx)); err != nil {
if err := release(context.WithoutCancel(ctx)); err != nil {
log.G(ctx).WithError(err).Warn("failed to release lease created for commit")
}
}()

View File

@@ -16,7 +16,6 @@ import (
"github.com/docker/docker/container"
dimages "github.com/docker/docker/daemon/images"
"github.com/docker/docker/image"
"github.com/docker/docker/internal/compatcontext"
"github.com/docker/docker/pkg/stringid"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@@ -216,7 +215,7 @@ func (i *ImageService) deleteAll(ctx context.Context, imgID image.ID, all []imag
}
defer func() {
if len(possiblyDeletedConfigs) > 0 {
if err := i.unleaseSnapshotsFromDeletedConfigs(compatcontext.WithoutCancel(ctx), possiblyDeletedConfigs); err != nil {
if err := i.unleaseSnapshotsFromDeletedConfigs(context.WithoutCancel(ctx), possiblyDeletedConfigs); err != nil {
log.G(ctx).WithError(err).Warn("failed to unlease snapshots")
}
}

View File

@@ -20,7 +20,6 @@ import (
"github.com/docker/docker/builder/dockerfile"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/image"
"github.com/docker/docker/internal/compatcontext"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/pools"
"github.com/google/uuid"
@@ -50,7 +49,7 @@ func (i *ImageService) ImportImage(ctx context.Context, ref reference.Named, pla
return "", errdefs.System(err)
}
defer func() {
if err := release(compatcontext.WithoutCancel(ctx)); err != nil {
if err := release(context.WithoutCancel(ctx)); err != nil {
logger.WithError(err).Warn("failed to release lease created for import")
}
}()

View File

@@ -11,7 +11,6 @@ import (
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/internal/compatcontext"
"github.com/hashicorp/go-multierror"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@@ -146,7 +145,7 @@ func (i *ImageService) pruneUnused(ctx context.Context, filterFunc imageFilterFu
// Workaround for https://github.com/moby/buildkit/issues/3797
defer func() {
if err := i.unleaseSnapshotsFromDeletedConfigs(compatcontext.WithoutCancel(ctx), possiblyDeletedConfigs); err != nil {
if err := i.unleaseSnapshotsFromDeletedConfigs(context.WithoutCancel(ctx), possiblyDeletedConfigs); err != nil {
errs = multierror.Append(errs, err)
}
}()

View File

@@ -21,7 +21,6 @@ import (
dimages "github.com/docker/docker/daemon/images"
"github.com/docker/docker/distribution"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/internal/compatcontext"
"github.com/docker/docker/pkg/progress"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/stringid"
@@ -195,7 +194,7 @@ func (i *ImageService) pullTag(ctx context.Context, ref reference.Named, platfor
logger.Info("image pulled")
// The pull succeeded, so try to remove any dangling image we have for this target
err = i.images.Delete(compatcontext.WithoutCancel(ctx), danglingImageName(img.Target().Digest))
err = i.images.Delete(context.WithoutCancel(ctx), danglingImageName(img.Target().Digest))
if err != nil && !cerrdefs.IsNotFound(err) {
// Image pull succeeded, but cleaning up the dangling image failed. Ignore the
// error to not mark the pull as failed.

View File

@@ -23,7 +23,6 @@ import (
"github.com/docker/docker/api/types/registry"
dimages "github.com/docker/docker/daemon/images"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/internal/compatcontext"
"github.com/docker/docker/pkg/progress"
"github.com/docker/docker/pkg/streamformatter"
"github.com/opencontainers/go-digest"
@@ -95,7 +94,7 @@ func (i *ImageService) pushRef(ctx context.Context, targetRef reference.Named, p
return err
}
defer func() {
if err := release(compatcontext.WithoutCancel(leasedCtx)); err != nil {
if err := release(context.WithoutCancel(leasedCtx)); err != nil {
log.G(ctx).WithField("image", targetRef).WithError(err).Warn("failed to release lease created for push")
}
}()

View File

@@ -11,7 +11,6 @@ import (
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/image"
"github.com/docker/docker/internal/compatcontext"
"github.com/pkg/errors"
)
@@ -53,7 +52,7 @@ func (i *ImageService) TagImage(ctx context.Context, imageID image.ID, newTag re
return errors.Wrapf(err, "failed to delete previous image %s", replacedImg.Name)
}
if _, err = i.images.Create(compatcontext.WithoutCancel(ctx), newImg); err != nil {
if _, err = i.images.Create(context.WithoutCancel(ctx), newImg); err != nil {
return errdefs.System(errors.Wrapf(err, "failed to create an image %s with target %s after deleting the existing one",
newImg.Name, imageID.String()))
}
@@ -68,7 +67,7 @@ func (i *ImageService) TagImage(ctx context.Context, imageID image.ID, newTag re
defer i.LogImageEvent(imageID.String(), reference.FamiliarString(newTag), events.ActionTag)
// Delete the source dangling image, as it's no longer dangling.
if err := i.images.Delete(compatcontext.WithoutCancel(ctx), danglingImageName(targetImage.Target.Digest)); err != nil {
if err := i.images.Delete(context.WithoutCancel(ctx), danglingImageName(targetImage.Target.Digest)); err != nil {
logger.WithError(err).Warn("unexpected error when deleting dangling image")
}

View File

@@ -14,7 +14,6 @@ import (
cerrdefs "github.com/containerd/errdefs"
"github.com/containerd/log"
"github.com/distribution/reference"
"github.com/docker/docker/internal/compatcontext"
"github.com/docker/docker/pkg/progress"
"github.com/docker/docker/pkg/stringid"
"github.com/opencontainers/go-digest"
@@ -56,7 +55,7 @@ func (j *jobs) showProgress(ctx context.Context, out progress.Output, updater pr
}
}
case <-ctx.Done():
ctx, cancel := context.WithTimeout(compatcontext.WithoutCancel(ctx), time.Millisecond*500)
ctx, cancel := context.WithTimeout(context.WithoutCancel(ctx), time.Millisecond*500)
defer cancel()
updater.UpdateProgress(ctx, j, out, start)
close(lastUpdate)

View File

@@ -6,7 +6,6 @@ import (
containerdimages "github.com/containerd/containerd/images"
cerrdefs "github.com/containerd/errdefs"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/internal/compatcontext"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
@@ -23,7 +22,7 @@ func (i *ImageService) softImageDelete(ctx context.Context, img containerdimages
// Create dangling image if this is the last image pointing to this target.
if len(imgs) == 1 {
err := i.ensureDanglingImage(compatcontext.WithoutCancel(ctx), img)
err := i.ensureDanglingImage(context.WithoutCancel(ctx), img)
// Error out in case we couldn't persist the old image.
if err != nil {
@@ -34,7 +33,7 @@ func (i *ImageService) softImageDelete(ctx context.Context, img containerdimages
// Free the target name.
// TODO: Add with target option
err := i.images.Delete(compatcontext.WithoutCancel(ctx), img.Name)
err := i.images.Delete(context.WithoutCancel(ctx), img.Name)
if err != nil {
if !cerrdefs.IsNotFound(err) {
return errdefs.System(errors.Wrapf(err, "failed to delete image %s which existed a moment before", img.Name))
@@ -58,7 +57,7 @@ func (i *ImageService) ensureDanglingImage(ctx context.Context, from containerdi
}
danglingImage.Name = danglingImageName(from.Target.Digest)
_, err := i.images.Create(compatcontext.WithoutCancel(ctx), danglingImage)
_, err := i.images.Create(context.WithoutCancel(ctx), danglingImage)
// If it already exists, then just continue.
if cerrdefs.IsAlreadyExists(err) {
return nil

View File

@@ -17,7 +17,6 @@ import (
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/container"
"github.com/docker/docker/internal/compatcontext"
"github.com/docker/docker/internal/mounttree"
"github.com/docker/docker/internal/unshare"
"github.com/docker/docker/pkg/fileutils"
@@ -71,7 +70,7 @@ func (daemon *Daemon) openContainerFS(ctr *container.Container) (_ *containerFSV
return nil, err
}
defer func() {
ctx := compatcontext.WithoutCancel(ctx)
ctx := context.WithoutCancel(ctx)
cleanup(ctx)
if err != nil {
_ = ctr.UnmountVolumes(ctx, daemon.LogVolumeEvent)

View File

@@ -13,7 +13,6 @@ import (
mounttypes "github.com/docker/docker/api/types/mount"
"github.com/docker/docker/container"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/internal/compatcontext"
"github.com/docker/docker/oci"
volumemounts "github.com/docker/docker/volume/mounts"
volumeopts "github.com/docker/docker/volume/service/opts"
@@ -117,8 +116,11 @@ func (daemon *Daemon) populateVolume(ctx context.Context, c *container.Container
log.G(ctx).WithError(err).Debugf("can't copy data from %s:%s, to %s", c.ID, mnt.Destination, volumePath)
return errors.Wrapf(err, "failed to populate volume")
}
defer mnt.Cleanup(compatcontext.WithoutCancel(ctx))
defer cleanup(compatcontext.WithoutCancel(ctx))
defer func() {
ctx := context.WithoutCancel(ctx)
_ = cleanup(ctx)
_ = mnt.Cleanup(ctx)
}()
log.G(ctx).Debugf("copying image data from %s:%s, to %s", c.ID, mnt.Destination, volumePath)
if err := c.CopyImagePathContent(volumePath, ctrDestPath); err != nil {

View File

@@ -58,7 +58,6 @@ import (
"github.com/docker/docker/dockerversion"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/image"
"github.com/docker/docker/internal/compatcontext"
"github.com/docker/docker/layer"
libcontainerdtypes "github.com/docker/docker/libcontainerd/types"
"github.com/docker/docker/libnetwork"
@@ -1282,7 +1281,7 @@ func (daemon *Daemon) waitForStartupDone() {
}
func (daemon *Daemon) shutdownContainer(c *container.Container) error {
ctx := compatcontext.WithoutCancel(context.TODO())
ctx := context.WithoutCancel(context.TODO())
// If container failed to exit in stopTimeout seconds of SIGTERM, then using the force
if err := daemon.containerStop(ctx, c, containertypes.StopOptions{}); err != nil {

View File

@@ -7,7 +7,6 @@ import (
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/container"
"github.com/docker/docker/internal/compatcontext"
)
// ContainerRestart stops and starts a container. It attempts to
@@ -35,7 +34,7 @@ func (daemon *Daemon) ContainerRestart(ctx context.Context, name string, options
func (daemon *Daemon) containerRestart(ctx context.Context, daemonCfg *configStore, container *container.Container, options containertypes.StopOptions) error {
// Restarting is expected to be an atomic operation, and cancelling
// the request should not cancel the stop -> start sequence.
ctx = compatcontext.WithoutCancel(ctx)
ctx = context.WithoutCancel(ctx)
// Determine isolation. If not specified in the hostconfig, use daemon default.
actualIsolation := container.HostConfig.Isolation

View File

@@ -9,7 +9,6 @@ import (
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/container"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/internal/compatcontext"
"github.com/docker/docker/libcontainerd"
"github.com/pkg/errors"
)
@@ -98,7 +97,7 @@ func (daemon *Daemon) containerStart(ctx context.Context, daemonCfg *configStore
}
container.Reset(false)
daemon.Cleanup(compatcontext.WithoutCancel(ctx), container)
daemon.Cleanup(context.WithoutCancel(ctx), container)
// if containers AutoRemove flag is set, remove it after clean up
if container.HostConfig.AutoRemove {
container.Unlock()
@@ -128,7 +127,7 @@ func (daemon *Daemon) containerStart(ctx context.Context, daemonCfg *configStore
return err
}
mnts = append(mnts, m...)
defer cleanup(compatcontext.WithoutCancel(ctx))
defer cleanup(context.WithoutCancel(ctx))
spec, err := daemon.createSpec(ctx, daemonCfg, container, mnts)
if err != nil {
@@ -172,7 +171,7 @@ func (daemon *Daemon) containerStart(ctx context.Context, daemonCfg *configStore
}
defer func() {
if retErr != nil {
if err := ctr.Delete(compatcontext.WithoutCancel(ctx)); err != nil {
if err := ctr.Delete(context.WithoutCancel(ctx)); err != nil {
log.G(ctx).WithError(err).WithField("container", container.ID).
Error("failed to delete failed start container")
}
@@ -189,7 +188,7 @@ func (daemon *Daemon) containerStart(ctx context.Context, daemonCfg *configStore
}
defer func() {
if retErr != nil {
if err := tsk.ForceDelete(compatcontext.WithoutCancel(ctx)); err != nil {
if err := tsk.ForceDelete(context.WithoutCancel(ctx)); err != nil {
log.G(ctx).WithError(err).WithField("container", container.ID).
Error("failed to delete task after fail start")
}

View File

@@ -9,7 +9,6 @@ import (
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/container"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/internal/compatcontext"
"github.com/moby/sys/signal"
"github.com/pkg/errors"
)
@@ -47,7 +46,7 @@ func (daemon *Daemon) ContainerStop(ctx context.Context, name string, options co
// the request to stop the container.
func (daemon *Daemon) containerStop(ctx context.Context, ctr *container.Container, options containertypes.StopOptions) (retErr error) {
// Cancelling the request should not cancel the stop.
ctx = compatcontext.WithoutCancel(ctx)
ctx = context.WithoutCancel(ctx)
if !ctr.IsRunning() {
return nil

View File

@@ -15,7 +15,6 @@ import (
mounttypes "github.com/docker/docker/api/types/mount"
"github.com/docker/docker/container"
"github.com/docker/docker/internal/cleanups"
"github.com/docker/docker/internal/compatcontext"
volumemounts "github.com/docker/docker/volume/mounts"
"github.com/pkg/errors"
)
@@ -40,7 +39,7 @@ func (daemon *Daemon) setupMounts(ctx context.Context, c *container.Container) (
cleanups := cleanups.Composite{}
defer func() {
if err := cleanups.Call(compatcontext.WithoutCancel(ctx)); err != nil {
if err := cleanups.Call(context.WithoutCancel(ctx)); err != nil {
log.G(ctx).WithError(err).Warn("failed to cleanup temporary mounts created by MountPoint.Setup")
}
}()

View File

@@ -8,7 +8,6 @@ import (
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/container"
"github.com/docker/docker/internal/cleanups"
"github.com/docker/docker/internal/compatcontext"
"github.com/docker/docker/pkg/idtools"
volumemounts "github.com/docker/docker/volume/mounts"
)
@@ -25,33 +24,33 @@ import (
// an array of runtime spec mounts, not container mounts. Then no need to
// do multiple transitions.
func (daemon *Daemon) setupMounts(ctx context.Context, c *container.Container) ([]container.Mount, func(context.Context) error, error) {
cleanups := cleanups.Composite{}
mntCleanups := cleanups.Composite{}
defer func() {
if err := cleanups.Call(compatcontext.WithoutCancel(ctx)); err != nil {
if err := mntCleanups.Call(context.WithoutCancel(ctx)); err != nil {
log.G(ctx).WithError(err).Warn("failed to cleanup temporary mounts created by MountPoint.Setup")
}
}()
var mnts []container.Mount
for _, mount := range c.MountPoints { // type is volumemounts.MountPoint
if err := daemon.lazyInitializeVolume(c.ID, mount); err != nil {
for _, mp := range c.MountPoints { // type is volumemounts.MountPoint
if err := daemon.lazyInitializeVolume(c.ID, mp); err != nil {
return nil, nil, err
}
s, c, err := mount.Setup(ctx, c.MountLabel, idtools.Identity{}, nil)
s, c, err := mp.Setup(ctx, c.MountLabel, idtools.Identity{}, nil)
if err != nil {
return nil, nil, err
}
cleanups.Add(c)
mntCleanups.Add(c)
mnts = append(mnts, container.Mount{
Source: s,
Destination: mount.Destination,
Writable: mount.RW,
Destination: mp.Destination,
Writable: mp.RW,
})
}
sort.Sort(mounts(mnts))
return mnts, cleanups.Release(), nil
return mnts, mntCleanups.Release(), nil
}
// setBindModeIfNull is platform specific processing which is a no-op on

View File

@@ -1,89 +0,0 @@
//go:build !go1.21
// Copyright (c) 2009 The Go Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// - Redistributions of source code must retain the above copyright
//
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above
//
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Google Inc. nor the names of its
//
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Source: https://cs.opensource.google/go/go/+/refs/tags/go1.21.1:src/context/context.go
// The only modifications to the original source were:
// - replacing the usage of internal reflectlite with reflect
// - replacing the usage of private value function with Value method call
package compatcontext // import "github.com/docker/docker/internal/compatcontext"
import (
"context"
"reflect"
"time"
)
// WithoutCancel returns a copy of parent that is not canceled when parent is canceled.
// The returned context returns no Deadline or Err, and its Done channel is nil.
// Calling [Cause] on the returned context returns nil.
func WithoutCancel(parent context.Context) context.Context {
if parent == nil {
panic("cannot create context from nil parent")
}
return withoutCancelCtx{parent}
}
type withoutCancelCtx struct {
c context.Context
}
func (withoutCancelCtx) Deadline() (deadline time.Time, ok bool) {
return
}
func (withoutCancelCtx) Done() <-chan struct{} {
return nil
}
func (withoutCancelCtx) Err() error {
return nil
}
func (c withoutCancelCtx) Value(key any) any {
return c.c.Value(key)
}
func (c withoutCancelCtx) String() string {
return contextName(c.c) + ".WithoutCancel"
}
type stringer interface {
String() string
}
func contextName(c context.Context) string {
if s, ok := c.(stringer); ok {
return s.String()
}
return reflect.TypeOf(c).String()
}

View File

@@ -1,9 +0,0 @@
//go:build go1.21
package compatcontext // import "github.com/docker/docker/internal/compatcontext"
import "context"
func WithoutCancel(ctx context.Context) context.Context {
return context.WithoutCancel(ctx)
}

View File

@@ -8,7 +8,6 @@ import (
"github.com/containerd/log"
"github.com/docker/docker/internal/cleanups"
"github.com/docker/docker/internal/compatcontext"
"github.com/pkg/errors"
"golang.org/x/sys/windows"
)
@@ -27,9 +26,9 @@ func Join(ctx context.Context, path, subpath string) (*SafePath, error) {
}
parts := strings.Split(subpart, string(os.PathSeparator))
cleanups := cleanups.Composite{}
cleanupJobs := cleanups.Composite{}
defer func() {
if cErr := cleanups.Call(compatcontext.WithoutCancel(ctx)); cErr != nil {
if cErr := cleanupJobs.Call(context.WithoutCancel(ctx)); cErr != nil {
log.G(ctx).WithError(cErr).Warn("failed to close handles after error")
}
}()
@@ -45,7 +44,7 @@ func Join(ctx context.Context, path, subpath string) (*SafePath, error) {
}
return nil, errors.Wrapf(err, "failed to lock file %s", fullPath)
}
cleanups.Add(func(context.Context) error {
cleanupJobs.Add(func(context.Context) error {
if err := windows.CloseHandle(handle); err != nil {
return &os.PathError{Op: "CloseHandle", Path: fullPath, Err: err}
}
@@ -75,7 +74,7 @@ func Join(ctx context.Context, path, subpath string) (*SafePath, error) {
path: fullPath,
sourceBase: base,
sourceSubpath: subpart,
cleanup: cleanups.Release(),
cleanup: cleanupJobs.Release(),
}, nil
}