summaryrefslogtreecommitdiff
path: root/vendor
diff options
context:
space:
mode:
Diffstat (limited to 'vendor')
-rw-r--r--vendor/github.com/docker/docker/errdefs/defs.go69
-rw-r--r--vendor/github.com/docker/docker/errdefs/doc.go8
-rw-r--r--vendor/github.com/docker/docker/errdefs/helpers.go309
-rw-r--r--vendor/github.com/docker/docker/errdefs/http_helpers.go49
-rw-r--r--vendor/github.com/docker/docker/errdefs/is.go78
-rw-r--r--vendor/github.com/docker/docker/pkg/archive/archive_deprecated.go259
-rw-r--r--vendor/github.com/docker/docker/pkg/archive/changes_deprecated.go56
-rw-r--r--vendor/github.com/docker/docker/pkg/archive/copy_deprecated.go130
-rw-r--r--vendor/github.com/docker/docker/pkg/archive/diff_deprecated.go37
-rw-r--r--vendor/github.com/docker/docker/pkg/archive/path_deprecated.go10
-rw-r--r--vendor/github.com/docker/docker/pkg/archive/utils.go42
-rw-r--r--vendor/github.com/docker/docker/pkg/archive/whiteouts_deprecated.go10
-rw-r--r--vendor/github.com/docker/docker/pkg/archive/wrap_deprecated.go14
-rw-r--r--vendor/github.com/docker/docker/pkg/idtools/idtools.go223
-rw-r--r--vendor/github.com/docker/docker/pkg/idtools/idtools_windows.go12
-rw-r--r--vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md2
-rw-r--r--vendor/github.com/golang-jwt/jwt/v5/ecdsa.go4
-rw-r--r--vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go4
-rw-r--r--vendor/github.com/golang-jwt/jwt/v5/ed25519.go4
-rw-r--r--vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go4
-rw-r--r--vendor/github.com/golang-jwt/jwt/v5/hmac.go4
-rw-r--r--vendor/github.com/golang-jwt/jwt/v5/map_claims.go8
-rw-r--r--vendor/github.com/golang-jwt/jwt/v5/none.go4
-rw-r--r--vendor/github.com/golang-jwt/jwt/v5/parser_option.go25
-rw-r--r--vendor/github.com/golang-jwt/jwt/v5/rsa.go4
-rw-r--r--vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go4
-rw-r--r--vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go6
-rw-r--r--vendor/github.com/golang-jwt/jwt/v5/signing_method.go6
-rw-r--r--vendor/github.com/golang-jwt/jwt/v5/token.go20
-rw-r--r--vendor/github.com/golang-jwt/jwt/v5/types.go4
-rw-r--r--vendor/github.com/golang-jwt/jwt/v5/validator.go50
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/CONTRIBUTING.md2
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/Pipfile2
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/Pipfile.lock60
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/RELEASING.md18
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/container.go27
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/docker.go139
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/exec/processor.go1
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/generic.go5
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/internal/config/config.go2
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/internal/core/labels.go5
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/internal/version.go2
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/lifecycle.go79
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/mkdocs.yml29
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/options.go112
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/parallel.go7
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/port_forwarding.go11
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/reaper.go4
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/requirements.txt2
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/testing.go12
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/wait/file.go2
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/wait/host_port.go94
-rw-r--r--vendor/github.com/testcontainers/testcontainers-go/wait/walk.go3
-rw-r--r--vendor/github.com/xlgmokha/minit/LICENSE21
-rw-r--r--vendor/github.com/xlgmokha/minit/README.md71
-rw-r--r--vendor/github.com/xlgmokha/minit/main.go65
-rw-r--r--vendor/modules.txt14
57 files changed, 604 insertions, 1644 deletions
diff --git a/vendor/github.com/docker/docker/errdefs/defs.go b/vendor/github.com/docker/docker/errdefs/defs.go
deleted file mode 100644
index a5523c3..0000000
--- a/vendor/github.com/docker/docker/errdefs/defs.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package errdefs
-
-// ErrNotFound signals that the requested object doesn't exist
-type ErrNotFound interface {
- NotFound()
-}
-
-// ErrInvalidParameter signals that the user input is invalid
-type ErrInvalidParameter interface {
- InvalidParameter()
-}
-
-// ErrConflict signals that some internal state conflicts with the requested action and can't be performed.
-// A change in state should be able to clear this error.
-type ErrConflict interface {
- Conflict()
-}
-
-// ErrUnauthorized is used to signify that the user is not authorized to perform a specific action
-type ErrUnauthorized interface {
- Unauthorized()
-}
-
-// ErrUnavailable signals that the requested action/subsystem is not available.
-type ErrUnavailable interface {
- Unavailable()
-}
-
-// ErrForbidden signals that the requested action cannot be performed under any circumstances.
-// When a ErrForbidden is returned, the caller should never retry the action.
-type ErrForbidden interface {
- Forbidden()
-}
-
-// ErrSystem signals that some internal error occurred.
-// An example of this would be a failed mount request.
-type ErrSystem interface {
- System()
-}
-
-// ErrNotModified signals that an action can't be performed because it's already in the desired state
-type ErrNotModified interface {
- NotModified()
-}
-
-// ErrNotImplemented signals that the requested action/feature is not implemented on the system as configured.
-type ErrNotImplemented interface {
- NotImplemented()
-}
-
-// ErrUnknown signals that the kind of error that occurred is not known.
-type ErrUnknown interface {
- Unknown()
-}
-
-// ErrCancelled signals that the action was cancelled.
-type ErrCancelled interface {
- Cancelled()
-}
-
-// ErrDeadline signals that the deadline was reached before the action completed.
-type ErrDeadline interface {
- DeadlineExceeded()
-}
-
-// ErrDataLoss indicates that data was lost or there is data corruption.
-type ErrDataLoss interface {
- DataLoss()
-}
diff --git a/vendor/github.com/docker/docker/errdefs/doc.go b/vendor/github.com/docker/docker/errdefs/doc.go
deleted file mode 100644
index efbe8ba..0000000
--- a/vendor/github.com/docker/docker/errdefs/doc.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Package errdefs defines a set of error interfaces that packages should use for communicating classes of errors.
-// Errors that cross the package boundary should implement one (and only one) of these interfaces.
-//
-// Packages should not reference these interfaces directly, only implement them.
-// To check if a particular error implements one of these interfaces, there are helper
-// functions provided (e.g. `Is<SomeError>`) which can be used rather than asserting the interfaces directly.
-// If you must assert on these interfaces, be sure to check the causal chain (`err.Unwrap()`).
-package errdefs
diff --git a/vendor/github.com/docker/docker/errdefs/helpers.go b/vendor/github.com/docker/docker/errdefs/helpers.go
deleted file mode 100644
index 2a9f7ff..0000000
--- a/vendor/github.com/docker/docker/errdefs/helpers.go
+++ /dev/null
@@ -1,309 +0,0 @@
-package errdefs
-
-import (
- "context"
-
- cerrdefs "github.com/containerd/errdefs"
-)
-
-type errNotFound struct{ error }
-
-func (errNotFound) NotFound() {}
-
-func (e errNotFound) Cause() error {
- return e.error
-}
-
-func (e errNotFound) Unwrap() error {
- return e.error
-}
-
-// NotFound creates an [ErrNotFound] error from the given error.
-// It returns the error as-is if it is either nil (no error) or already implements
-// [ErrNotFound],
-func NotFound(err error) error {
- if err == nil || cerrdefs.IsNotFound(err) {
- return err
- }
- return errNotFound{err}
-}
-
-type errInvalidParameter struct{ error }
-
-func (errInvalidParameter) InvalidParameter() {}
-
-func (e errInvalidParameter) Cause() error {
- return e.error
-}
-
-func (e errInvalidParameter) Unwrap() error {
- return e.error
-}
-
-// InvalidParameter creates an [ErrInvalidParameter] error from the given error.
-// It returns the error as-is if it is either nil (no error) or already implements
-// [ErrInvalidParameter],
-func InvalidParameter(err error) error {
- if err == nil || cerrdefs.IsInvalidArgument(err) {
- return err
- }
- return errInvalidParameter{err}
-}
-
-type errConflict struct{ error }
-
-func (errConflict) Conflict() {}
-
-func (e errConflict) Cause() error {
- return e.error
-}
-
-func (e errConflict) Unwrap() error {
- return e.error
-}
-
-// Conflict creates an [ErrConflict] error from the given error.
-// It returns the error as-is if it is either nil (no error) or already implements
-// [ErrConflict],
-func Conflict(err error) error {
- if err == nil || cerrdefs.IsConflict(err) {
- return err
- }
- return errConflict{err}
-}
-
-type errUnauthorized struct{ error }
-
-func (errUnauthorized) Unauthorized() {}
-
-func (e errUnauthorized) Cause() error {
- return e.error
-}
-
-func (e errUnauthorized) Unwrap() error {
- return e.error
-}
-
-// Unauthorized creates an [ErrUnauthorized] error from the given error.
-// It returns the error as-is if it is either nil (no error) or already implements
-// [ErrUnauthorized],
-func Unauthorized(err error) error {
- if err == nil || cerrdefs.IsUnauthorized(err) {
- return err
- }
- return errUnauthorized{err}
-}
-
-type errUnavailable struct{ error }
-
-func (errUnavailable) Unavailable() {}
-
-func (e errUnavailable) Cause() error {
- return e.error
-}
-
-func (e errUnavailable) Unwrap() error {
- return e.error
-}
-
-// Unavailable creates an [ErrUnavailable] error from the given error.
-// It returns the error as-is if it is either nil (no error) or already implements
-// [ErrUnavailable],
-func Unavailable(err error) error {
- if err == nil || cerrdefs.IsUnavailable(err) {
- return err
- }
- return errUnavailable{err}
-}
-
-type errForbidden struct{ error }
-
-func (errForbidden) Forbidden() {}
-
-func (e errForbidden) Cause() error {
- return e.error
-}
-
-func (e errForbidden) Unwrap() error {
- return e.error
-}
-
-// Forbidden creates an [ErrForbidden] error from the given error.
-// It returns the error as-is if it is either nil (no error) or already implements
-// [ErrForbidden],
-func Forbidden(err error) error {
- if err == nil || cerrdefs.IsPermissionDenied(err) {
- return err
- }
- return errForbidden{err}
-}
-
-type errSystem struct{ error }
-
-func (errSystem) System() {}
-
-func (e errSystem) Cause() error {
- return e.error
-}
-
-func (e errSystem) Unwrap() error {
- return e.error
-}
-
-// System creates an [ErrSystem] error from the given error.
-// It returns the error as-is if it is either nil (no error) or already implements
-// [ErrSystem],
-func System(err error) error {
- if err == nil || cerrdefs.IsInternal(err) {
- return err
- }
- return errSystem{err}
-}
-
-type errNotModified struct{ error }
-
-func (errNotModified) NotModified() {}
-
-func (e errNotModified) Cause() error {
- return e.error
-}
-
-func (e errNotModified) Unwrap() error {
- return e.error
-}
-
-// NotModified creates an [ErrNotModified] error from the given error.
-// It returns the error as-is if it is either nil (no error) or already implements
-// [NotModified],
-func NotModified(err error) error {
- if err == nil || cerrdefs.IsNotModified(err) {
- return err
- }
- return errNotModified{err}
-}
-
-type errNotImplemented struct{ error }
-
-func (errNotImplemented) NotImplemented() {}
-
-func (e errNotImplemented) Cause() error {
- return e.error
-}
-
-func (e errNotImplemented) Unwrap() error {
- return e.error
-}
-
-// NotImplemented creates an [ErrNotImplemented] error from the given error.
-// It returns the error as-is if it is either nil (no error) or already implements
-// [ErrNotImplemented],
-func NotImplemented(err error) error {
- if err == nil || cerrdefs.IsNotImplemented(err) {
- return err
- }
- return errNotImplemented{err}
-}
-
-type errUnknown struct{ error }
-
-func (errUnknown) Unknown() {}
-
-func (e errUnknown) Cause() error {
- return e.error
-}
-
-func (e errUnknown) Unwrap() error {
- return e.error
-}
-
-// Unknown creates an [ErrUnknown] error from the given error.
-// It returns the error as-is if it is either nil (no error) or already implements
-// [ErrUnknown],
-func Unknown(err error) error {
- if err == nil || cerrdefs.IsUnknown(err) {
- return err
- }
- return errUnknown{err}
-}
-
-type errCancelled struct{ error }
-
-func (errCancelled) Cancelled() {}
-
-func (e errCancelled) Cause() error {
- return e.error
-}
-
-func (e errCancelled) Unwrap() error {
- return e.error
-}
-
-// Cancelled creates an [ErrCancelled] error from the given error.
-// It returns the error as-is if it is either nil (no error) or already implements
-// [ErrCancelled],
-func Cancelled(err error) error {
- if err == nil || cerrdefs.IsCanceled(err) {
- return err
- }
- return errCancelled{err}
-}
-
-type errDeadline struct{ error }
-
-func (errDeadline) DeadlineExceeded() {}
-
-func (e errDeadline) Cause() error {
- return e.error
-}
-
-func (e errDeadline) Unwrap() error {
- return e.error
-}
-
-// Deadline creates an [ErrDeadline] error from the given error.
-// It returns the error as-is if it is either nil (no error) or already implements
-// [ErrDeadline],
-func Deadline(err error) error {
- if err == nil || cerrdefs.IsDeadlineExceeded(err) {
- return err
- }
- return errDeadline{err}
-}
-
-type errDataLoss struct{ error }
-
-func (errDataLoss) DataLoss() {}
-
-func (e errDataLoss) Cause() error {
- return e.error
-}
-
-func (e errDataLoss) Unwrap() error {
- return e.error
-}
-
-// DataLoss creates an [ErrDataLoss] error from the given error.
-// It returns the error as-is if it is either nil (no error) or already implements
-// [ErrDataLoss],
-func DataLoss(err error) error {
- if err == nil || cerrdefs.IsDataLoss(err) {
- return err
- }
- return errDataLoss{err}
-}
-
-// FromContext returns the error class from the passed in context
-func FromContext(ctx context.Context) error {
- e := ctx.Err()
- if e == nil {
- return nil
- }
-
- if e == context.Canceled {
- return Cancelled(e)
- }
- if e == context.DeadlineExceeded {
- return Deadline(e)
- }
- return Unknown(e)
-}
diff --git a/vendor/github.com/docker/docker/errdefs/http_helpers.go b/vendor/github.com/docker/docker/errdefs/http_helpers.go
deleted file mode 100644
index 823ff2d..0000000
--- a/vendor/github.com/docker/docker/errdefs/http_helpers.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package errdefs
-
-import (
- "net/http"
-)
-
-// FromStatusCode creates an errdef error, based on the provided HTTP status-code
-//
-// Deprecated: Use [cerrdefs.ToNative] instead
-func FromStatusCode(err error, statusCode int) error {
- if err == nil {
- return nil
- }
- switch statusCode {
- case http.StatusNotFound:
- return NotFound(err)
- case http.StatusBadRequest:
- return InvalidParameter(err)
- case http.StatusConflict:
- return Conflict(err)
- case http.StatusUnauthorized:
- return Unauthorized(err)
- case http.StatusServiceUnavailable:
- return Unavailable(err)
- case http.StatusForbidden:
- return Forbidden(err)
- case http.StatusNotModified:
- return NotModified(err)
- case http.StatusNotImplemented:
- return NotImplemented(err)
- case http.StatusInternalServerError:
- if IsCancelled(err) || IsSystem(err) || IsUnknown(err) || IsDataLoss(err) || IsDeadline(err) {
- return err
- }
- return System(err)
- default:
- switch {
- case statusCode >= http.StatusOK && statusCode < http.StatusBadRequest:
- // it's a client error
- return err
- case statusCode >= http.StatusBadRequest && statusCode < http.StatusInternalServerError:
- return InvalidParameter(err)
- case statusCode >= http.StatusInternalServerError && statusCode < 600:
- return System(err)
- default:
- return Unknown(err)
- }
- }
-}
diff --git a/vendor/github.com/docker/docker/errdefs/is.go b/vendor/github.com/docker/docker/errdefs/is.go
deleted file mode 100644
index ceb754a..0000000
--- a/vendor/github.com/docker/docker/errdefs/is.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package errdefs
-
-import (
- "context"
- "errors"
-
- cerrdefs "github.com/containerd/errdefs"
-)
-
-// IsNotFound returns if the passed in error is an [ErrNotFound],
-//
-// Deprecated: use containerd [cerrdefs.IsNotFound]
-var IsNotFound = cerrdefs.IsNotFound
-
-// IsInvalidParameter returns if the passed in error is an [ErrInvalidParameter].
-//
-// Deprecated: use containerd [cerrdefs.IsInvalidArgument]
-var IsInvalidParameter = cerrdefs.IsInvalidArgument
-
-// IsConflict returns if the passed in error is an [ErrConflict].
-//
-// Deprecated: use containerd [cerrdefs.IsConflict]
-var IsConflict = cerrdefs.IsConflict
-
-// IsUnauthorized returns if the passed in error is an [ErrUnauthorized].
-//
-// Deprecated: use containerd [cerrdefs.IsUnauthorized]
-var IsUnauthorized = cerrdefs.IsUnauthorized
-
-// IsUnavailable returns if the passed in error is an [ErrUnavailable].
-//
-// Deprecated: use containerd [cerrdefs.IsUnavailable]
-var IsUnavailable = cerrdefs.IsUnavailable
-
-// IsForbidden returns if the passed in error is an [ErrForbidden].
-//
-// Deprecated: use containerd [cerrdefs.IsPermissionDenied]
-var IsForbidden = cerrdefs.IsPermissionDenied
-
-// IsSystem returns if the passed in error is an [ErrSystem].
-//
-// Deprecated: use containerd [cerrdefs.IsInternal]
-var IsSystem = cerrdefs.IsInternal
-
-// IsNotModified returns if the passed in error is an [ErrNotModified].
-//
-// Deprecated: use containerd [cerrdefs.IsNotModified]
-var IsNotModified = cerrdefs.IsNotModified
-
-// IsNotImplemented returns if the passed in error is an [ErrNotImplemented].
-//
-// Deprecated: use containerd [cerrdefs.IsNotImplemented]
-var IsNotImplemented = cerrdefs.IsNotImplemented
-
-// IsUnknown returns if the passed in error is an [ErrUnknown].
-//
-// Deprecated: use containerd [cerrdefs.IsUnknown]
-var IsUnknown = cerrdefs.IsUnknown
-
-// IsCancelled returns if the passed in error is an [ErrCancelled].
-//
-// Deprecated: use containerd [cerrdefs.IsCanceled]
-var IsCancelled = cerrdefs.IsCanceled
-
-// IsDeadline returns if the passed in error is an [ErrDeadline].
-//
-// Deprecated: use containerd [cerrdefs.IsDeadlineExceeded]
-var IsDeadline = cerrdefs.IsDeadlineExceeded
-
-// IsDataLoss returns if the passed in error is an [ErrDataLoss].
-//
-// Deprecated: use containerd [cerrdefs.IsDataLoss]
-var IsDataLoss = cerrdefs.IsDataLoss
-
-// IsContext returns if the passed in error is due to context cancellation or deadline exceeded.
-func IsContext(err error) bool {
- return errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded)
-}
diff --git a/vendor/github.com/docker/docker/pkg/archive/archive_deprecated.go b/vendor/github.com/docker/docker/pkg/archive/archive_deprecated.go
deleted file mode 100644
index 5bdbdef..0000000
--- a/vendor/github.com/docker/docker/pkg/archive/archive_deprecated.go
+++ /dev/null
@@ -1,259 +0,0 @@
-// Package archive provides helper functions for dealing with archive files.
-package archive
-
-import (
- "archive/tar"
- "io"
- "os"
-
- "github.com/docker/docker/pkg/idtools"
- "github.com/moby/go-archive"
- "github.com/moby/go-archive/compression"
- "github.com/moby/go-archive/tarheader"
-)
-
-// ImpliedDirectoryMode represents the mode (Unix permissions) applied to directories that are implied by files in a
-// tar, but that do not have their own header entry.
-//
-// Deprecated: use [archive.ImpliedDirectoryMode] instead.
-const ImpliedDirectoryMode = archive.ImpliedDirectoryMode
-
-type (
- // Compression is the state represents if compressed or not.
- //
- // Deprecated: use [compression.Compression] instead.
- Compression = compression.Compression
- // WhiteoutFormat is the format of whiteouts unpacked
- //
- // Deprecated: use [archive.WhiteoutFormat] instead.
- WhiteoutFormat = archive.WhiteoutFormat
-
- // TarOptions wraps the tar options.
- //
- // Deprecated: use [archive.TarOptions] instead.
- TarOptions struct {
- IncludeFiles []string
- ExcludePatterns []string
- Compression compression.Compression
- NoLchown bool
- IDMap idtools.IdentityMapping
- ChownOpts *idtools.Identity
- IncludeSourceDir bool
- // WhiteoutFormat is the expected on disk format for whiteout files.
- // This format will be converted to the standard format on pack
- // and from the standard format on unpack.
- WhiteoutFormat archive.WhiteoutFormat
- // When unpacking, specifies whether overwriting a directory with a
- // non-directory is allowed and vice versa.
- NoOverwriteDirNonDir bool
- // For each include when creating an archive, the included name will be
- // replaced with the matching name from this map.
- RebaseNames map[string]string
- InUserNS bool
- // Allow unpacking to succeed in spite of failures to set extended
- // attributes on the unpacked files due to the destination filesystem
- // not supporting them or a lack of permissions. Extended attributes
- // were probably in the archive for a reason, so set this option at
- // your own peril.
- BestEffortXattrs bool
- }
-)
-
-// Archiver implements the Archiver interface and allows the reuse of most utility functions of
-// this package with a pluggable Untar function. Also, to facilitate the passing of specific id
-// mappings for untar, an Archiver can be created with maps which will then be passed to Untar operations.
-//
-// Deprecated: use [archive.Archiver] instead.
-type Archiver struct {
- Untar func(io.Reader, string, *TarOptions) error
- IDMapping idtools.IdentityMapping
-}
-
-// NewDefaultArchiver returns a new Archiver without any IdentityMapping
-//
-// Deprecated: use [archive.NewDefaultArchiver] instead.
-func NewDefaultArchiver() *Archiver {
- return &Archiver{Untar: Untar}
-}
-
-const (
- Uncompressed = compression.None // Deprecated: use [compression.None] instead.
- Bzip2 = compression.Bzip2 // Deprecated: use [compression.Bzip2] instead.
- Gzip = compression.Gzip // Deprecated: use [compression.Gzip] instead.
- Xz = compression.Xz // Deprecated: use [compression.Xz] instead.
- Zstd = compression.Zstd // Deprecated: use [compression.Zstd] instead.
-)
-
-const (
- AUFSWhiteoutFormat = archive.AUFSWhiteoutFormat // Deprecated: use [archive.AUFSWhiteoutFormat] instead.
- OverlayWhiteoutFormat = archive.OverlayWhiteoutFormat // Deprecated: use [archive.OverlayWhiteoutFormat] instead.
-)
-
-// IsArchivePath checks if the (possibly compressed) file at the given path
-// starts with a tar file header.
-//
-// Deprecated: use [archive.IsArchivePath] instead.
-func IsArchivePath(path string) bool {
- return archive.IsArchivePath(path)
-}
-
-// DetectCompression detects the compression algorithm of the source.
-//
-// Deprecated: use [compression.Detect] instead.
-func DetectCompression(source []byte) archive.Compression {
- return compression.Detect(source)
-}
-
-// DecompressStream decompresses the archive and returns a ReaderCloser with the decompressed archive.
-//
-// Deprecated: use [compression.DecompressStream] instead.
-func DecompressStream(arch io.Reader) (io.ReadCloser, error) {
- return compression.DecompressStream(arch)
-}
-
-// CompressStream compresses the dest with specified compression algorithm.
-//
-// Deprecated: use [compression.CompressStream] instead.
-func CompressStream(dest io.Writer, comp compression.Compression) (io.WriteCloser, error) {
- return compression.CompressStream(dest, comp)
-}
-
-// TarModifierFunc is a function that can be passed to ReplaceFileTarWrapper.
-//
-// Deprecated: use [archive.TarModifierFunc] instead.
-type TarModifierFunc = archive.TarModifierFunc
-
-// ReplaceFileTarWrapper converts inputTarStream to a new tar stream.
-//
-// Deprecated: use [archive.ReplaceFileTarWrapper] instead.
-func ReplaceFileTarWrapper(inputTarStream io.ReadCloser, mods map[string]archive.TarModifierFunc) io.ReadCloser {
- return archive.ReplaceFileTarWrapper(inputTarStream, mods)
-}
-
-// FileInfoHeaderNoLookups creates a partially-populated tar.Header from fi.
-//
-// Deprecated: use [tarheader.FileInfoHeaderNoLookups] instead.
-func FileInfoHeaderNoLookups(fi os.FileInfo, link string) (*tar.Header, error) {
- return tarheader.FileInfoHeaderNoLookups(fi, link)
-}
-
-// FileInfoHeader creates a populated Header from fi.
-//
-// Deprecated: use [archive.FileInfoHeader] instead.
-func FileInfoHeader(name string, fi os.FileInfo, link string) (*tar.Header, error) {
- return archive.FileInfoHeader(name, fi, link)
-}
-
-// ReadSecurityXattrToTarHeader reads security.capability xattr from filesystem
-// to a tar header
-//
-// Deprecated: use [archive.ReadSecurityXattrToTarHeader] instead.
-func ReadSecurityXattrToTarHeader(path string, hdr *tar.Header) error {
- return archive.ReadSecurityXattrToTarHeader(path, hdr)
-}
-
-// Tar creates an archive from the directory at `path`, and returns it as a
-// stream of bytes.
-//
-// Deprecated: use [archive.Tar] instead.
-func Tar(path string, compression archive.Compression) (io.ReadCloser, error) {
- return archive.TarWithOptions(path, &archive.TarOptions{Compression: compression})
-}
-
-// TarWithOptions creates an archive with the given options.
-//
-// Deprecated: use [archive.TarWithOptions] instead.
-func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) {
- return archive.TarWithOptions(srcPath, toArchiveOpt(options))
-}
-
-// Tarballer is a lower-level interface to TarWithOptions.
-//
-// Deprecated: use [archive.Tarballer] instead.
-type Tarballer = archive.Tarballer
-
-// NewTarballer constructs a new tarballer using TarWithOptions.
-//
-// Deprecated: use [archive.Tarballer] instead.
-func NewTarballer(srcPath string, options *TarOptions) (*archive.Tarballer, error) {
- return archive.NewTarballer(srcPath, toArchiveOpt(options))
-}
-
-// Unpack unpacks the decompressedArchive to dest with options.
-//
-// Deprecated: use [archive.Unpack] instead.
-func Unpack(decompressedArchive io.Reader, dest string, options *TarOptions) error {
- return archive.Unpack(decompressedArchive, dest, toArchiveOpt(options))
-}
-
-// Untar reads a stream of bytes from `archive`, parses it as a tar archive,
-// and unpacks it into the directory at `dest`.
-//
-// Deprecated: use [archive.Untar] instead.
-func Untar(tarArchive io.Reader, dest string, options *TarOptions) error {
- return archive.Untar(tarArchive, dest, toArchiveOpt(options))
-}
-
-// UntarUncompressed reads a stream of bytes from `tarArchive`, parses it as a tar archive,
-// and unpacks it into the directory at `dest`.
-// The archive must be an uncompressed stream.
-//
-// Deprecated: use [archive.UntarUncompressed] instead.
-func UntarUncompressed(tarArchive io.Reader, dest string, options *TarOptions) error {
- return archive.UntarUncompressed(tarArchive, dest, toArchiveOpt(options))
-}
-
-// TarUntar is a convenience function which calls Tar and Untar, with the output of one piped into the other.
-// If either Tar or Untar fails, TarUntar aborts and returns the error.
-func (archiver *Archiver) TarUntar(src, dst string) error {
- return (&archive.Archiver{
- Untar: func(reader io.Reader, s string, options *archive.TarOptions) error {
- return archiver.Untar(reader, s, &TarOptions{
- IDMap: archiver.IDMapping,
- })
- },
- IDMapping: idtools.ToUserIdentityMapping(archiver.IDMapping),
- }).TarUntar(src, dst)
-}
-
-// UntarPath untar a file from path to a destination, src is the source tar file path.
-func (archiver *Archiver) UntarPath(src, dst string) error {
- return (&archive.Archiver{
- Untar: func(reader io.Reader, s string, options *archive.TarOptions) error {
- return archiver.Untar(reader, s, &TarOptions{
- IDMap: archiver.IDMapping,
- })
- },
- IDMapping: idtools.ToUserIdentityMapping(archiver.IDMapping),
- }).UntarPath(src, dst)
-}
-
-// CopyWithTar creates a tar archive of filesystem path `src`, and
-// unpacks it at filesystem path `dst`.
-// The archive is streamed directly with fixed buffering and no
-// intermediary disk IO.
-func (archiver *Archiver) CopyWithTar(src, dst string) error {
- return (&archive.Archiver{
- Untar: func(reader io.Reader, s string, options *archive.TarOptions) error {
- return archiver.Untar(reader, s, nil)
- },
- IDMapping: idtools.ToUserIdentityMapping(archiver.IDMapping),
- }).CopyWithTar(src, dst)
-}
-
-// CopyFileWithTar emulates the behavior of the 'cp' command-line
-// for a single file. It copies a regular file from path `src` to
-// path `dst`, and preserves all its metadata.
-func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
- return (&archive.Archiver{
- Untar: func(reader io.Reader, s string, options *archive.TarOptions) error {
- return archiver.Untar(reader, s, nil)
- },
- IDMapping: idtools.ToUserIdentityMapping(archiver.IDMapping),
- }).CopyFileWithTar(src, dst)
-}
-
-// IdentityMapping returns the IdentityMapping of the archiver.
-func (archiver *Archiver) IdentityMapping() idtools.IdentityMapping {
- return archiver.IDMapping
-}
diff --git a/vendor/github.com/docker/docker/pkg/archive/changes_deprecated.go b/vendor/github.com/docker/docker/pkg/archive/changes_deprecated.go
deleted file mode 100644
index 48c7523..0000000
--- a/vendor/github.com/docker/docker/pkg/archive/changes_deprecated.go
+++ /dev/null
@@ -1,56 +0,0 @@
-package archive
-
-import (
- "io"
-
- "github.com/docker/docker/pkg/idtools"
- "github.com/moby/go-archive"
-)
-
-// ChangeType represents the change
-//
-// Deprecated: use [archive.ChangeType] instead.
-type ChangeType = archive.ChangeType
-
-const (
- ChangeModify = archive.ChangeModify // Deprecated: use [archive.ChangeModify] instead.
- ChangeAdd = archive.ChangeAdd // Deprecated: use [archive.ChangeAdd] instead.
- ChangeDelete = archive.ChangeDelete // Deprecated: use [archive.ChangeDelete] instead.
-)
-
-// Change represents a change.
-//
-// Deprecated: use [archive.Change] instead.
-type Change = archive.Change
-
-// Changes walks the path rw and determines changes for the files in the path,
-// with respect to the parent layers
-//
-// Deprecated: use [archive.Changes] instead.
-func Changes(layers []string, rw string) ([]archive.Change, error) {
- return archive.Changes(layers, rw)
-}
-
-// FileInfo describes the information of a file.
-//
-// Deprecated: use [archive.FileInfo] instead.
-type FileInfo = archive.FileInfo
-
-// ChangesDirs compares two directories and generates an array of Change objects describing the changes.
-//
-// Deprecated: use [archive.ChangesDirs] instead.
-func ChangesDirs(newDir, oldDir string) ([]archive.Change, error) {
- return archive.ChangesDirs(newDir, oldDir)
-}
-
-// ChangesSize calculates the size in bytes of the provided changes, based on newDir.
-//
-// Deprecated: use [archive.ChangesSize] instead.
-func ChangesSize(newDir string, changes []archive.Change) int64 {
- return archive.ChangesSize(newDir, changes)
-}
-
-// ExportChanges produces an Archive from the provided changes, relative to dir.
-func ExportChanges(dir string, changes []archive.Change, idMap idtools.IdentityMapping) (io.ReadCloser, error) {
- return archive.ExportChanges(dir, changes, idtools.ToUserIdentityMapping(idMap))
-}
diff --git a/vendor/github.com/docker/docker/pkg/archive/copy_deprecated.go b/vendor/github.com/docker/docker/pkg/archive/copy_deprecated.go
deleted file mode 100644
index 1901e55..0000000
--- a/vendor/github.com/docker/docker/pkg/archive/copy_deprecated.go
+++ /dev/null
@@ -1,130 +0,0 @@
-package archive
-
-import (
- "io"
-
- "github.com/moby/go-archive"
- "github.com/moby/go-archive/compression"
-)
-
-var (
- ErrNotDirectory = archive.ErrNotDirectory // Deprecated: use [archive.ErrNotDirectory] instead.
- ErrDirNotExists = archive.ErrDirNotExists // Deprecated: use [archive.ErrDirNotExists] instead.
- ErrCannotCopyDir = archive.ErrCannotCopyDir // Deprecated: use [archive.ErrCannotCopyDir] instead.
- ErrInvalidCopySource = archive.ErrInvalidCopySource // Deprecated: use [archive.ErrInvalidCopySource] instead.
-)
-
-// PreserveTrailingDotOrSeparator returns the given cleaned path.
-//
-// Deprecated: use [archive.PreserveTrailingDotOrSeparator] instead.
-func PreserveTrailingDotOrSeparator(cleanedPath string, originalPath string) string {
- return archive.PreserveTrailingDotOrSeparator(cleanedPath, originalPath)
-}
-
-// SplitPathDirEntry splits the given path between its directory name and its
-// basename.
-//
-// Deprecated: use [archive.SplitPathDirEntry] instead.
-func SplitPathDirEntry(path string) (dir, base string) {
- return archive.SplitPathDirEntry(path)
-}
-
-// TarResource archives the resource described by the given CopyInfo to a Tar
-// archive.
-//
-// Deprecated: use [archive.TarResource] instead.
-func TarResource(sourceInfo archive.CopyInfo) (content io.ReadCloser, err error) {
- return archive.TarResource(sourceInfo)
-}
-
-// TarResourceRebase is like TarResource but renames the first path element of
-// items in the resulting tar archive to match the given rebaseName if not "".
-//
-// Deprecated: use [archive.TarResourceRebase] instead.
-func TarResourceRebase(sourcePath, rebaseName string) (content io.ReadCloser, _ error) {
- return archive.TarResourceRebase(sourcePath, rebaseName)
-}
-
-// TarResourceRebaseOpts does not preform the Tar, but instead just creates the rebase
-// parameters to be sent to TarWithOptions.
-//
-// Deprecated: use [archive.TarResourceRebaseOpts] instead.
-func TarResourceRebaseOpts(sourceBase string, rebaseName string) *TarOptions {
- filter := []string{sourceBase}
- return &TarOptions{
- Compression: compression.None,
- IncludeFiles: filter,
- IncludeSourceDir: true,
- RebaseNames: map[string]string{
- sourceBase: rebaseName,
- },
- }
-}
-
-// CopyInfo holds basic info about the source or destination path of a copy operation.
-//
-// Deprecated: use [archive.CopyInfo] instead.
-type CopyInfo = archive.CopyInfo
-
-// CopyInfoSourcePath stats the given path to create a CopyInfo struct.
-// struct representing that resource for the source of an archive copy
-// operation.
-//
-// Deprecated: use [archive.CopyInfoSourcePath] instead.
-func CopyInfoSourcePath(path string, followLink bool) (archive.CopyInfo, error) {
- return archive.CopyInfoSourcePath(path, followLink)
-}
-
-// CopyInfoDestinationPath stats the given path to create a CopyInfo
-// struct representing that resource for the destination of an archive copy
-// operation.
-//
-// Deprecated: use [archive.CopyInfoDestinationPath] instead.
-func CopyInfoDestinationPath(path string) (info archive.CopyInfo, err error) {
- return archive.CopyInfoDestinationPath(path)
-}
-
-// PrepareArchiveCopy prepares the given srcContent archive.
-//
-// Deprecated: use [archive.PrepareArchiveCopy] instead.
-func PrepareArchiveCopy(srcContent io.Reader, srcInfo, dstInfo archive.CopyInfo) (dstDir string, content io.ReadCloser, err error) {
- return archive.PrepareArchiveCopy(srcContent, srcInfo, dstInfo)
-}
-
-// RebaseArchiveEntries rewrites the given srcContent archive replacing
-// an occurrence of oldBase with newBase at the beginning of entry names.
-//
-// Deprecated: use [archive.RebaseArchiveEntries] instead.
-func RebaseArchiveEntries(srcContent io.Reader, oldBase, newBase string) io.ReadCloser {
- return archive.RebaseArchiveEntries(srcContent, oldBase, newBase)
-}
-
-// CopyResource performs an archive copy from the given source path to the
-// given destination path.
-//
-// Deprecated: use [archive.CopyResource] instead.
-func CopyResource(srcPath, dstPath string, followLink bool) error {
- return archive.CopyResource(srcPath, dstPath, followLink)
-}
-
-// CopyTo handles extracting the given content whose
-// entries should be sourced from srcInfo to dstPath.
-//
-// Deprecated: use [archive.CopyTo] instead.
-func CopyTo(content io.Reader, srcInfo archive.CopyInfo, dstPath string) error {
- return archive.CopyTo(content, srcInfo, dstPath)
-}
-
-// ResolveHostSourcePath decides real path need to be copied.
-//
-// Deprecated: use [archive.ResolveHostSourcePath] instead.
-func ResolveHostSourcePath(path string, followLink bool) (resolvedPath, rebaseName string, _ error) {
- return archive.ResolveHostSourcePath(path, followLink)
-}
-
-// GetRebaseName normalizes and compares path and resolvedPath.
-//
-// Deprecated: use [archive.GetRebaseName] instead.
-func GetRebaseName(path, resolvedPath string) (string, string) {
- return archive.GetRebaseName(path, resolvedPath)
-}
diff --git a/vendor/github.com/docker/docker/pkg/archive/diff_deprecated.go b/vendor/github.com/docker/docker/pkg/archive/diff_deprecated.go
deleted file mode 100644
index dd5e0d5..0000000
--- a/vendor/github.com/docker/docker/pkg/archive/diff_deprecated.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package archive
-
-import (
- "io"
-
- "github.com/moby/go-archive"
-)
-
-// UnpackLayer unpack `layer` to a `dest`.
-//
-// Deprecated: use [archive.UnpackLayer] instead.
-func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64, err error) {
- return archive.UnpackLayer(dest, layer, toArchiveOpt(options))
-}
-
-// ApplyLayer parses a diff in the standard layer format from `layer`,
-// and applies it to the directory `dest`.
-//
-// Deprecated: use [archive.ApplyLayer] instead.
-func ApplyLayer(dest string, layer io.Reader) (int64, error) {
- return archive.ApplyLayer(dest, layer)
-}
-
-// ApplyUncompressedLayer parses a diff in the standard layer format from
-// `layer`, and applies it to the directory `dest`.
-//
-// Deprecated: use [archive.ApplyUncompressedLayer] instead.
-func ApplyUncompressedLayer(dest string, layer io.Reader, options *TarOptions) (int64, error) {
- return archive.ApplyUncompressedLayer(dest, layer, toArchiveOpt(options))
-}
-
-// IsEmpty checks if the tar archive is empty (doesn't contain any entries).
-//
-// Deprecated: use [archive.IsEmpty] instead.
-func IsEmpty(rd io.Reader) (bool, error) {
- return archive.IsEmpty(rd)
-}
diff --git a/vendor/github.com/docker/docker/pkg/archive/path_deprecated.go b/vendor/github.com/docker/docker/pkg/archive/path_deprecated.go
deleted file mode 100644
index 0fa74de..0000000
--- a/vendor/github.com/docker/docker/pkg/archive/path_deprecated.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package archive
-
-import "github.com/moby/go-archive"
-
-// CheckSystemDriveAndRemoveDriveLetter verifies that a path is the system drive.
-//
-// Deprecated: use [archive.CheckSystemDriveAndRemoveDriveLetter] instead.
-func CheckSystemDriveAndRemoveDriveLetter(path string) (string, error) {
- return archive.CheckSystemDriveAndRemoveDriveLetter(path)
-}
diff --git a/vendor/github.com/docker/docker/pkg/archive/utils.go b/vendor/github.com/docker/docker/pkg/archive/utils.go
deleted file mode 100644
index 692cf16..0000000
--- a/vendor/github.com/docker/docker/pkg/archive/utils.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package archive
-
-import (
- "github.com/docker/docker/pkg/idtools"
- "github.com/moby/go-archive"
-)
-
-// ToArchiveOpt converts an [TarOptions] to a [archive.TarOptions].
-//
-// Deprecated: use [archive.TarOptions] instead, this utility is for internal use to transition to the [github.com/moby/go-archive] module.
-func ToArchiveOpt(options *TarOptions) *archive.TarOptions {
- return toArchiveOpt(options)
-}
-
-func toArchiveOpt(options *TarOptions) *archive.TarOptions {
- if options == nil {
- return nil
- }
-
- var chownOpts *archive.ChownOpts
- if options.ChownOpts != nil {
- chownOpts = &archive.ChownOpts{
- UID: options.ChownOpts.UID,
- GID: options.ChownOpts.GID,
- }
- }
-
- return &archive.TarOptions{
- IncludeFiles: options.IncludeFiles,
- ExcludePatterns: options.ExcludePatterns,
- Compression: options.Compression,
- NoLchown: options.NoLchown,
- IDMap: idtools.ToUserIdentityMapping(options.IDMap),
- ChownOpts: chownOpts,
- IncludeSourceDir: options.IncludeSourceDir,
- WhiteoutFormat: options.WhiteoutFormat,
- NoOverwriteDirNonDir: options.NoOverwriteDirNonDir,
- RebaseNames: options.RebaseNames,
- InUserNS: options.InUserNS,
- BestEffortXattrs: options.BestEffortXattrs,
- }
-}
diff --git a/vendor/github.com/docker/docker/pkg/archive/whiteouts_deprecated.go b/vendor/github.com/docker/docker/pkg/archive/whiteouts_deprecated.go
deleted file mode 100644
index 0ab8590..0000000
--- a/vendor/github.com/docker/docker/pkg/archive/whiteouts_deprecated.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package archive
-
-import "github.com/moby/go-archive"
-
-const (
- WhiteoutPrefix = archive.WhiteoutPrefix // Deprecated: use [archive.WhiteoutPrefix] instead.
- WhiteoutMetaPrefix = archive.WhiteoutMetaPrefix // Deprecated: use [archive.WhiteoutMetaPrefix] instead.
- WhiteoutLinkDir = archive.WhiteoutLinkDir // Deprecated: use [archive.WhiteoutLinkDir] instead.
- WhiteoutOpaqueDir = archive.WhiteoutOpaqueDir // Deprecated: use [archive.WhiteoutOpaqueDir] instead.
-)
diff --git a/vendor/github.com/docker/docker/pkg/archive/wrap_deprecated.go b/vendor/github.com/docker/docker/pkg/archive/wrap_deprecated.go
deleted file mode 100644
index e5d3fa9..0000000
--- a/vendor/github.com/docker/docker/pkg/archive/wrap_deprecated.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package archive
-
-import (
- "io"
-
- "github.com/moby/go-archive"
-)
-
-// Generate generates a new archive from the content provided as input.
-//
-// Deprecated: use [archive.Generate] instead.
-func Generate(input ...string) (io.Reader, error) {
- return archive.Generate(input...)
-}
diff --git a/vendor/github.com/docker/docker/pkg/idtools/idtools.go b/vendor/github.com/docker/docker/pkg/idtools/idtools.go
deleted file mode 100644
index 982f81d..0000000
--- a/vendor/github.com/docker/docker/pkg/idtools/idtools.go
+++ /dev/null
@@ -1,223 +0,0 @@
-package idtools
-
-import (
- "fmt"
- "os"
-
- "github.com/moby/sys/user"
-)
-
-// IDMap contains a single entry for user namespace range remapping. An array
-// of IDMap entries represents the structure that will be provided to the Linux
-// kernel for creating a user namespace.
-//
-// Deprecated: use [user.IDMap] instead.
-type IDMap struct {
- ContainerID int `json:"container_id"`
- HostID int `json:"host_id"`
- Size int `json:"size"`
-}
-
-// MkdirAllAndChown creates a directory (include any along the path) and then modifies
-// ownership to the requested uid/gid. If the directory already exists, this
-// function will still change ownership and permissions.
-//
-// Deprecated: use [user.MkdirAllAndChown] instead.
-func MkdirAllAndChown(path string, mode os.FileMode, owner Identity) error {
- return user.MkdirAllAndChown(path, mode, owner.UID, owner.GID)
-}
-
-// MkdirAndChown creates a directory and then modifies ownership to the requested uid/gid.
-// If the directory already exists, this function still changes ownership and permissions.
-// Note that unlike os.Mkdir(), this function does not return IsExist error
-// in case path already exists.
-//
-// Deprecated: use [user.MkdirAndChown] instead.
-func MkdirAndChown(path string, mode os.FileMode, owner Identity) error {
- return user.MkdirAndChown(path, mode, owner.UID, owner.GID)
-}
-
-// MkdirAllAndChownNew creates a directory (include any along the path) and then modifies
-// ownership ONLY of newly created directories to the requested uid/gid. If the
-// directories along the path exist, no change of ownership or permissions will be performed
-//
-// Deprecated: use [user.MkdirAllAndChown] with the [user.WithOnlyNew] option instead.
-func MkdirAllAndChownNew(path string, mode os.FileMode, owner Identity) error {
- return user.MkdirAllAndChown(path, mode, owner.UID, owner.GID, user.WithOnlyNew)
-}
-
-// GetRootUIDGID retrieves the remapped root uid/gid pair from the set of maps.
-// If the maps are empty, then the root uid/gid will default to "real" 0/0
-//
-// Deprecated: use [(user.IdentityMapping).RootPair] instead.
-func GetRootUIDGID(uidMap, gidMap []IDMap) (int, int, error) {
- return getRootUIDGID(uidMap, gidMap)
-}
-
-// getRootUIDGID retrieves the remapped root uid/gid pair from the set of maps.
-// If the maps are empty, then the root uid/gid will default to "real" 0/0
-func getRootUIDGID(uidMap, gidMap []IDMap) (int, int, error) {
- uid, err := toHost(0, uidMap)
- if err != nil {
- return -1, -1, err
- }
- gid, err := toHost(0, gidMap)
- if err != nil {
- return -1, -1, err
- }
- return uid, gid, nil
-}
-
-// toContainer takes an id mapping, and uses it to translate a
-// host ID to the remapped ID. If no map is provided, then the translation
-// assumes a 1-to-1 mapping and returns the passed in id
-func toContainer(hostID int, idMap []IDMap) (int, error) {
- if idMap == nil {
- return hostID, nil
- }
- for _, m := range idMap {
- if (hostID >= m.HostID) && (hostID <= (m.HostID + m.Size - 1)) {
- contID := m.ContainerID + (hostID - m.HostID)
- return contID, nil
- }
- }
- return -1, fmt.Errorf("Host ID %d cannot be mapped to a container ID", hostID)
-}
-
-// toHost takes an id mapping and a remapped ID, and translates the
-// ID to the mapped host ID. If no map is provided, then the translation
-// assumes a 1-to-1 mapping and returns the passed in id #
-func toHost(contID int, idMap []IDMap) (int, error) {
- if idMap == nil {
- return contID, nil
- }
- for _, m := range idMap {
- if (contID >= m.ContainerID) && (contID <= (m.ContainerID + m.Size - 1)) {
- hostID := m.HostID + (contID - m.ContainerID)
- return hostID, nil
- }
- }
- return -1, fmt.Errorf("Container ID %d cannot be mapped to a host ID", contID)
-}
-
-// Identity is either a UID and GID pair or a SID (but not both)
-type Identity struct {
- UID int
- GID int
- SID string
-}
-
-// Chown changes the numeric uid and gid of the named file to id.UID and id.GID.
-//
-// Deprecated: this method is deprecated and will be removed in the next release.
-func (id Identity) Chown(name string) error {
- return os.Chown(name, id.UID, id.GID)
-}
-
-// IdentityMapping contains a mappings of UIDs and GIDs.
-// The zero value represents an empty mapping.
-//
-// Deprecated: this type is deprecated and will be removed in the next release.
-type IdentityMapping struct {
- UIDMaps []IDMap `json:"UIDMaps"`
- GIDMaps []IDMap `json:"GIDMaps"`
-}
-
-// FromUserIdentityMapping converts a [user.IdentityMapping] to an [idtools.IdentityMapping].
-//
-// Deprecated: use [user.IdentityMapping] directly, this is transitioning to user package.
-func FromUserIdentityMapping(u user.IdentityMapping) IdentityMapping {
- return IdentityMapping{
- UIDMaps: fromUserIDMap(u.UIDMaps),
- GIDMaps: fromUserIDMap(u.GIDMaps),
- }
-}
-
-func fromUserIDMap(u []user.IDMap) []IDMap {
- if u == nil {
- return nil
- }
- m := make([]IDMap, len(u))
- for i := range u {
- m[i] = IDMap{
- ContainerID: int(u[i].ID),
- HostID: int(u[i].ParentID),
- Size: int(u[i].Count),
- }
- }
- return m
-}
-
-// ToUserIdentityMapping converts an [idtools.IdentityMapping] to a [user.IdentityMapping].
-//
-// Deprecated: use [user.IdentityMapping] directly, this is transitioning to user package.
-func ToUserIdentityMapping(u IdentityMapping) user.IdentityMapping {
- return user.IdentityMapping{
- UIDMaps: toUserIDMap(u.UIDMaps),
- GIDMaps: toUserIDMap(u.GIDMaps),
- }
-}
-
-func toUserIDMap(u []IDMap) []user.IDMap {
- if u == nil {
- return nil
- }
- m := make([]user.IDMap, len(u))
- for i := range u {
- m[i] = user.IDMap{
- ID: int64(u[i].ContainerID),
- ParentID: int64(u[i].HostID),
- Count: int64(u[i].Size),
- }
- }
- return m
-}
-
-// RootPair returns a uid and gid pair for the root user. The error is ignored
-// because a root user always exists, and the defaults are correct when the uid
-// and gid maps are empty.
-func (i IdentityMapping) RootPair() Identity {
- uid, gid, _ := getRootUIDGID(i.UIDMaps, i.GIDMaps)
- return Identity{UID: uid, GID: gid}
-}
-
-// ToHost returns the host UID and GID for the container uid, gid.
-// Remapping is only performed if the ids aren't already the remapped root ids
-func (i IdentityMapping) ToHost(pair Identity) (Identity, error) {
- var err error
- target := i.RootPair()
-
- if pair.UID != target.UID {
- target.UID, err = toHost(pair.UID, i.UIDMaps)
- if err != nil {
- return target, err
- }
- }
-
- if pair.GID != target.GID {
- target.GID, err = toHost(pair.GID, i.GIDMaps)
- }
- return target, err
-}
-
-// ToContainer returns the container UID and GID for the host uid and gid
-func (i IdentityMapping) ToContainer(pair Identity) (int, int, error) {
- uid, err := toContainer(pair.UID, i.UIDMaps)
- if err != nil {
- return -1, -1, err
- }
- gid, err := toContainer(pair.GID, i.GIDMaps)
- return uid, gid, err
-}
-
-// Empty returns true if there are no id mappings
-func (i IdentityMapping) Empty() bool {
- return len(i.UIDMaps) == 0 && len(i.GIDMaps) == 0
-}
-
-// CurrentIdentity returns the identity of the current process
-//
-// Deprecated: use [os.Getuid] and [os.Getegid] instead.
-func CurrentIdentity() Identity {
- return Identity{UID: os.Getuid(), GID: os.Getegid()}
-}
diff --git a/vendor/github.com/docker/docker/pkg/idtools/idtools_windows.go b/vendor/github.com/docker/docker/pkg/idtools/idtools_windows.go
deleted file mode 100644
index f83f59f..0000000
--- a/vendor/github.com/docker/docker/pkg/idtools/idtools_windows.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package idtools
-
-const (
- SeTakeOwnershipPrivilege = "SeTakeOwnershipPrivilege"
-)
-
-// TODO(thaJeztah): these magic consts need a source of reference, and should be defined in a canonical location
-const (
- ContainerAdministratorSidString = "S-1-5-93-2-1"
-
- ContainerUserSidString = "S-1-5-93-2-2"
-)
diff --git a/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md b/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md
index ff9c57e..b3178e7 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md
+++ b/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md
@@ -155,7 +155,7 @@ stored in base64 encoded form, which was redundant with the information in the
type Token struct {
Raw string // Raw contains the raw token
Method SigningMethod // Method is the signing method used or to be used
- Header map[string]interface{} // Header is the first segment of the token in decoded form
+ Header map[string]any // Header is the first segment of the token in decoded form
Claims Claims // Claims is the second segment of the token in decoded form
Signature []byte // Signature is the third segment of the token in decoded form
Valid bool // Valid specifies if the token is valid
diff --git a/vendor/github.com/golang-jwt/jwt/v5/ecdsa.go b/vendor/github.com/golang-jwt/jwt/v5/ecdsa.go
index c929e4a..06cd94d 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/ecdsa.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/ecdsa.go
@@ -55,7 +55,7 @@ func (m *SigningMethodECDSA) Alg() string {
// Verify implements token verification for the SigningMethod.
// For this verify method, key must be an ecdsa.PublicKey struct
-func (m *SigningMethodECDSA) Verify(signingString string, sig []byte, key interface{}) error {
+func (m *SigningMethodECDSA) Verify(signingString string, sig []byte, key any) error {
// Get the key
var ecdsaKey *ecdsa.PublicKey
switch k := key.(type) {
@@ -89,7 +89,7 @@ func (m *SigningMethodECDSA) Verify(signingString string, sig []byte, key interf
// Sign implements token signing for the SigningMethod.
// For this signing method, key must be an ecdsa.PrivateKey struct
-func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) ([]byte, error) {
+func (m *SigningMethodECDSA) Sign(signingString string, key any) ([]byte, error) {
// Get the key
var ecdsaKey *ecdsa.PrivateKey
switch k := key.(type) {
diff --git a/vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go b/vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go
index 5700636..44a3b7a 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go
@@ -23,7 +23,7 @@ func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) {
}
// Parse the key
- var parsedKey interface{}
+ var parsedKey any
if parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil {
if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
return nil, err
@@ -50,7 +50,7 @@ func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) {
}
// Parse the key
- var parsedKey interface{}
+ var parsedKey any
if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
parsedKey = cert.PublicKey
diff --git a/vendor/github.com/golang-jwt/jwt/v5/ed25519.go b/vendor/github.com/golang-jwt/jwt/v5/ed25519.go
index c213811..4159e57 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/ed25519.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/ed25519.go
@@ -33,7 +33,7 @@ func (m *SigningMethodEd25519) Alg() string {
// Verify implements token verification for the SigningMethod.
// For this verify method, key must be an ed25519.PublicKey
-func (m *SigningMethodEd25519) Verify(signingString string, sig []byte, key interface{}) error {
+func (m *SigningMethodEd25519) Verify(signingString string, sig []byte, key any) error {
var ed25519Key ed25519.PublicKey
var ok bool
@@ -55,7 +55,7 @@ func (m *SigningMethodEd25519) Verify(signingString string, sig []byte, key inte
// Sign implements token signing for the SigningMethod.
// For this signing method, key must be an ed25519.PrivateKey
-func (m *SigningMethodEd25519) Sign(signingString string, key interface{}) ([]byte, error) {
+func (m *SigningMethodEd25519) Sign(signingString string, key any) ([]byte, error) {
var ed25519Key crypto.Signer
var ok bool
diff --git a/vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go b/vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go
index cdb5e68..6f46e88 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go
@@ -24,7 +24,7 @@ func ParseEdPrivateKeyFromPEM(key []byte) (crypto.PrivateKey, error) {
}
// Parse the key
- var parsedKey interface{}
+ var parsedKey any
if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
return nil, err
}
@@ -49,7 +49,7 @@ func ParseEdPublicKeyFromPEM(key []byte) (crypto.PublicKey, error) {
}
// Parse the key
- var parsedKey interface{}
+ var parsedKey any
if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
return nil, err
}
diff --git a/vendor/github.com/golang-jwt/jwt/v5/hmac.go b/vendor/github.com/golang-jwt/jwt/v5/hmac.go
index aca600c..1bef138 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/hmac.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/hmac.go
@@ -55,7 +55,7 @@ func (m *SigningMethodHMAC) Alg() string {
// about this, and why we intentionally are not supporting string as a key can
// be found on our usage guide
// https://golang-jwt.github.io/jwt/usage/signing_methods/#signing-methods-and-key-types.
-func (m *SigningMethodHMAC) Verify(signingString string, sig []byte, key interface{}) error {
+func (m *SigningMethodHMAC) Verify(signingString string, sig []byte, key any) error {
// Verify the key is the right type
keyBytes, ok := key.([]byte)
if !ok {
@@ -88,7 +88,7 @@ func (m *SigningMethodHMAC) Verify(signingString string, sig []byte, key interfa
// cryptographically random source, e.g. crypto/rand. Additional information
// about this, and why we intentionally are not supporting string as a key can
// be found on our usage guide https://golang-jwt.github.io/jwt/usage/signing_methods/.
-func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) ([]byte, error) {
+func (m *SigningMethodHMAC) Sign(signingString string, key any) ([]byte, error) {
if keyBytes, ok := key.([]byte); ok {
if !m.Hash.Available() {
return nil, ErrHashUnavailable
diff --git a/vendor/github.com/golang-jwt/jwt/v5/map_claims.go b/vendor/github.com/golang-jwt/jwt/v5/map_claims.go
index b2b51a1..3b92052 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/map_claims.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/map_claims.go
@@ -5,9 +5,9 @@ import (
"fmt"
)
-// MapClaims is a claims type that uses the map[string]interface{} for JSON
+// MapClaims is a claims type that uses the map[string]any for JSON
// decoding. This is the default claims type if you don't supply one
-type MapClaims map[string]interface{}
+type MapClaims map[string]any
// GetExpirationTime implements the Claims interface.
func (m MapClaims) GetExpirationTime() (*NumericDate, error) {
@@ -73,7 +73,7 @@ func (m MapClaims) parseClaimsString(key string) (ClaimStrings, error) {
cs = append(cs, v)
case []string:
cs = v
- case []interface{}:
+ case []any:
for _, a := range v {
vs, ok := a.(string)
if !ok {
@@ -92,7 +92,7 @@ func (m MapClaims) parseClaimsString(key string) (ClaimStrings, error) {
func (m MapClaims) parseString(key string) (string, error) {
var (
ok bool
- raw interface{}
+ raw any
iss string
)
raw, ok = m[key]
diff --git a/vendor/github.com/golang-jwt/jwt/v5/none.go b/vendor/github.com/golang-jwt/jwt/v5/none.go
index 685c2ea..624ad55 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/none.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/none.go
@@ -25,7 +25,7 @@ func (m *signingMethodNone) Alg() string {
}
// Only allow 'none' alg type if UnsafeAllowNoneSignatureType is specified as the key
-func (m *signingMethodNone) Verify(signingString string, sig []byte, key interface{}) (err error) {
+func (m *signingMethodNone) Verify(signingString string, sig []byte, key any) (err error) {
// Key must be UnsafeAllowNoneSignatureType to prevent accidentally
// accepting 'none' signing method
if _, ok := key.(unsafeNoneMagicConstant); !ok {
@@ -41,7 +41,7 @@ func (m *signingMethodNone) Verify(signingString string, sig []byte, key interfa
}
// Only allow 'none' signing if UnsafeAllowNoneSignatureType is specified as the key
-func (m *signingMethodNone) Sign(signingString string, key interface{}) ([]byte, error) {
+func (m *signingMethodNone) Sign(signingString string, key any) ([]byte, error) {
if _, ok := key.(unsafeNoneMagicConstant); ok {
return []byte{}, nil
}
diff --git a/vendor/github.com/golang-jwt/jwt/v5/parser_option.go b/vendor/github.com/golang-jwt/jwt/v5/parser_option.go
index 88a780f..4315735 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/parser_option.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/parser_option.go
@@ -66,20 +66,37 @@ func WithExpirationRequired() ParserOption {
}
}
-// WithAudience configures the validator to require the specified audience in
-// the `aud` claim. Validation will fail if the audience is not listed in the
-// token or the `aud` claim is missing.
+// WithAudience configures the validator to require any of the specified
+// audiences in the `aud` claim. Validation will fail if the audience is not
+// listed in the token or the `aud` claim is missing.
//
// NOTE: While the `aud` claim is OPTIONAL in a JWT, the handling of it is
// application-specific. Since this validation API is helping developers in
// writing secure application, we decided to REQUIRE the existence of the claim,
// if an audience is expected.
-func WithAudience(aud string) ParserOption {
+func WithAudience(aud ...string) ParserOption {
return func(p *Parser) {
p.validator.expectedAud = aud
}
}
+// WithAllAudiences configures the validator to require all the specified
+// audiences in the `aud` claim. Validation will fail if the specified audiences
+// are not listed in the token or the `aud` claim is missing. Duplicates within
+// the list are de-duplicated since internally, we use a map to look up the
+// audiences.
+//
+// NOTE: While the `aud` claim is OPTIONAL in a JWT, the handling of it is
+// application-specific. Since this validation API is helping developers in
+// writing secure application, we decided to REQUIRE the existence of the claim,
+// if an audience is expected.
+func WithAllAudiences(aud ...string) ParserOption {
+ return func(p *Parser) {
+ p.validator.expectedAud = aud
+ p.validator.expectAllAud = true
+ }
+}
+
// WithIssuer configures the validator to require the specified issuer in the
// `iss` claim. Validation will fail if a different issuer is specified in the
// token or the `iss` claim is missing.
diff --git a/vendor/github.com/golang-jwt/jwt/v5/rsa.go b/vendor/github.com/golang-jwt/jwt/v5/rsa.go
index 83cbee6..98b960a 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/rsa.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/rsa.go
@@ -46,7 +46,7 @@ func (m *SigningMethodRSA) Alg() string {
// Verify implements token verification for the SigningMethod
// For this signing method, must be an *rsa.PublicKey structure.
-func (m *SigningMethodRSA) Verify(signingString string, sig []byte, key interface{}) error {
+func (m *SigningMethodRSA) Verify(signingString string, sig []byte, key any) error {
var rsaKey *rsa.PublicKey
var ok bool
@@ -67,7 +67,7 @@ func (m *SigningMethodRSA) Verify(signingString string, sig []byte, key interfac
// Sign implements token signing for the SigningMethod
// For this signing method, must be an *rsa.PrivateKey structure.
-func (m *SigningMethodRSA) Sign(signingString string, key interface{}) ([]byte, error) {
+func (m *SigningMethodRSA) Sign(signingString string, key any) ([]byte, error) {
var rsaKey *rsa.PrivateKey
var ok bool
diff --git a/vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go b/vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go
index 28c386e..7c216ae 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go
@@ -82,7 +82,7 @@ func init() {
// Verify implements token verification for the SigningMethod.
// For this verify method, key must be an rsa.PublicKey struct
-func (m *SigningMethodRSAPSS) Verify(signingString string, sig []byte, key interface{}) error {
+func (m *SigningMethodRSAPSS) Verify(signingString string, sig []byte, key any) error {
var rsaKey *rsa.PublicKey
switch k := key.(type) {
case *rsa.PublicKey:
@@ -108,7 +108,7 @@ func (m *SigningMethodRSAPSS) Verify(signingString string, sig []byte, key inter
// Sign implements token signing for the SigningMethod.
// For this signing method, key must be an rsa.PrivateKey struct
-func (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) ([]byte, error) {
+func (m *SigningMethodRSAPSS) Sign(signingString string, key any) ([]byte, error) {
var rsaKey *rsa.PrivateKey
switch k := key.(type) {
diff --git a/vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go b/vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go
index b3aeebb..f22c3d0 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go
@@ -23,7 +23,7 @@ func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) {
return nil, ErrKeyMustBePEMEncoded
}
- var parsedKey interface{}
+ var parsedKey any
if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {
if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
return nil, err
@@ -53,7 +53,7 @@ func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.Pr
return nil, ErrKeyMustBePEMEncoded
}
- var parsedKey interface{}
+ var parsedKey any
var blockDecrypted []byte
if blockDecrypted, err = x509.DecryptPEMBlock(block, []byte(password)); err != nil {
@@ -86,7 +86,7 @@ func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) {
}
// Parse the key
- var parsedKey interface{}
+ var parsedKey any
if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
parsedKey = cert.PublicKey
diff --git a/vendor/github.com/golang-jwt/jwt/v5/signing_method.go b/vendor/github.com/golang-jwt/jwt/v5/signing_method.go
index 0d73631..096d0ed 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/signing_method.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/signing_method.go
@@ -12,9 +12,9 @@ var signingMethodLock = new(sync.RWMutex)
// signature in Sign. The signature is then usually base64 encoded as part of a
// JWT.
type SigningMethod interface {
- Verify(signingString string, sig []byte, key interface{}) error // Returns nil if signature is valid
- Sign(signingString string, key interface{}) ([]byte, error) // Returns signature or error
- Alg() string // returns the alg identifier for this method (example: 'HS256')
+ Verify(signingString string, sig []byte, key any) error // Returns nil if signature is valid
+ Sign(signingString string, key any) ([]byte, error) // Returns signature or error
+ Alg() string // returns the alg identifier for this method (example: 'HS256')
}
// RegisterSigningMethod registers the "alg" name and a factory function for signing method.
diff --git a/vendor/github.com/golang-jwt/jwt/v5/token.go b/vendor/github.com/golang-jwt/jwt/v5/token.go
index 9c7f4ab..3f71558 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/token.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/token.go
@@ -11,9 +11,9 @@ import (
// Token. This allows you to use properties in the Header of the token (such as
// `kid`) to identify which key to use.
//
-// The returned interface{} may be a single key or a VerificationKeySet containing
+// The returned any may be a single key or a VerificationKeySet containing
// multiple keys.
-type Keyfunc func(*Token) (interface{}, error)
+type Keyfunc func(*Token) (any, error)
// VerificationKey represents a public or secret key for verifying a token's signature.
type VerificationKey interface {
@@ -28,12 +28,12 @@ type VerificationKeySet struct {
// Token represents a JWT Token. Different fields will be used depending on
// whether you're creating or parsing/verifying a token.
type Token struct {
- Raw string // Raw contains the raw token. Populated when you [Parse] a token
- Method SigningMethod // Method is the signing method used or to be used
- Header map[string]interface{} // Header is the first segment of the token in decoded form
- Claims Claims // Claims is the second segment of the token in decoded form
- Signature []byte // Signature is the third segment of the token in decoded form. Populated when you Parse a token
- Valid bool // Valid specifies if the token is valid. Populated when you Parse/Verify a token
+ Raw string // Raw contains the raw token. Populated when you [Parse] a token
+ Method SigningMethod // Method is the signing method used or to be used
+ Header map[string]any // Header is the first segment of the token in decoded form
+ Claims Claims // Claims is the second segment of the token in decoded form
+ Signature []byte // Signature is the third segment of the token in decoded form. Populated when you Parse a token
+ Valid bool // Valid specifies if the token is valid. Populated when you Parse/Verify a token
}
// New creates a new [Token] with the specified signing method and an empty map
@@ -46,7 +46,7 @@ func New(method SigningMethod, opts ...TokenOption) *Token {
// claims. Additional options can be specified, but are currently unused.
func NewWithClaims(method SigningMethod, claims Claims, opts ...TokenOption) *Token {
return &Token{
- Header: map[string]interface{}{
+ Header: map[string]any{
"typ": "JWT",
"alg": method.Alg(),
},
@@ -60,7 +60,7 @@ func NewWithClaims(method SigningMethod, claims Claims, opts ...TokenOption) *To
// https://golang-jwt.github.io/jwt/usage/signing_methods/#signing-methods-and-key-types
// for an overview of the different signing methods and their respective key
// types.
-func (t *Token) SignedString(key interface{}) (string, error) {
+func (t *Token) SignedString(key any) (string, error) {
sstr, err := t.SigningString()
if err != nil {
return "", err
diff --git a/vendor/github.com/golang-jwt/jwt/v5/types.go b/vendor/github.com/golang-jwt/jwt/v5/types.go
index b2655a9..a3e0ef1 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/types.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/types.go
@@ -103,7 +103,7 @@ func (date *NumericDate) UnmarshalJSON(b []byte) (err error) {
type ClaimStrings []string
func (s *ClaimStrings) UnmarshalJSON(data []byte) (err error) {
- var value interface{}
+ var value any
if err = json.Unmarshal(data, &value); err != nil {
return err
@@ -116,7 +116,7 @@ func (s *ClaimStrings) UnmarshalJSON(data []byte) (err error) {
aud = append(aud, v)
case []string:
aud = ClaimStrings(v)
- case []interface{}:
+ case []any:
for _, vv := range v {
vs, ok := vv.(string)
if !ok {
diff --git a/vendor/github.com/golang-jwt/jwt/v5/validator.go b/vendor/github.com/golang-jwt/jwt/v5/validator.go
index 008ecd8..92b5c05 100644
--- a/vendor/github.com/golang-jwt/jwt/v5/validator.go
+++ b/vendor/github.com/golang-jwt/jwt/v5/validator.go
@@ -1,8 +1,8 @@
package jwt
import (
- "crypto/subtle"
"fmt"
+ "slices"
"time"
)
@@ -52,8 +52,12 @@ type Validator struct {
verifyIat bool
// expectedAud contains the audience this token expects. Supplying an empty
- // string will disable aud checking.
- expectedAud string
+ // slice will disable aud checking.
+ expectedAud []string
+
+ // expectAllAud specifies whether all expected audiences must be present in
+ // the token. If false, only one of the expected audiences must be present.
+ expectAllAud bool
// expectedIss contains the issuer this token expects. Supplying an empty
// string will disable iss checking.
@@ -88,7 +92,7 @@ func NewValidator(opts ...ParserOption) *Validator {
func (v *Validator) Validate(claims Claims) error {
var (
now time.Time
- errs []error = make([]error, 0, 6)
+ errs = make([]error, 0, 6)
err error
)
@@ -120,8 +124,8 @@ func (v *Validator) Validate(claims Claims) error {
}
// If we have an expected audience, we also require the audience claim
- if v.expectedAud != "" {
- if err = v.verifyAudience(claims, v.expectedAud, true); err != nil {
+ if len(v.expectedAud) > 0 {
+ if err = v.verifyAudience(claims, v.expectedAud, v.expectAllAud); err != nil {
errs = append(errs, err)
}
}
@@ -226,33 +230,39 @@ func (v *Validator) verifyNotBefore(claims Claims, cmp time.Time, required bool)
//
// Additionally, if any error occurs while retrieving the claim, e.g., when its
// the wrong type, an ErrTokenUnverifiable error will be returned.
-func (v *Validator) verifyAudience(claims Claims, cmp string, required bool) error {
+func (v *Validator) verifyAudience(claims Claims, cmp []string, expectAllAud bool) error {
aud, err := claims.GetAudience()
if err != nil {
return err
}
- if len(aud) == 0 {
+ // Check that aud exists and is not empty. We only require the aud claim
+ // if we expect at least one audience to be present.
+ if len(aud) == 0 || len(aud) == 1 && aud[0] == "" {
+ required := len(v.expectedAud) > 0
return errorIfRequired(required, "aud")
}
- // use a var here to keep constant time compare when looping over a number of claims
- result := false
-
- var stringClaims string
- for _, a := range aud {
- if subtle.ConstantTimeCompare([]byte(a), []byte(cmp)) != 0 {
- result = true
+ if !expectAllAud {
+ for _, a := range aud {
+ // If we only expect one match, we can stop early if we find a match
+ if slices.Contains(cmp, a) {
+ return nil
+ }
}
- stringClaims = stringClaims + a
+
+ return ErrTokenInvalidAudience
}
- // case where "" is sent in one or many aud claims
- if stringClaims == "" {
- return errorIfRequired(required, "aud")
+ // Note that we are looping cmp here to ensure that all expected audiences
+ // are present in the aud claim.
+ for _, a := range cmp {
+ if !slices.Contains(aud, a) {
+ return ErrTokenInvalidAudience
+ }
}
- return errorIfFalse(result, ErrTokenInvalidAudience)
+ return nil
}
// verifyIssuer compares the iss claim in claims against cmp.
diff --git a/vendor/github.com/testcontainers/testcontainers-go/CONTRIBUTING.md b/vendor/github.com/testcontainers/testcontainers-go/CONTRIBUTING.md
index c8194c2..4736297 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/CONTRIBUTING.md
+++ b/vendor/github.com/testcontainers/testcontainers-go/CONTRIBUTING.md
@@ -2,7 +2,7 @@
Please see the [main contributing guidelines](./docs/contributing.md).
-There are additional docs describing [contributing documentation changes](./docs/contributing_docs.md).
+There are additional docs describing [contributing documentation changes](./docs/contributing.md).
### GitHub Sponsorship
diff --git a/vendor/github.com/testcontainers/testcontainers-go/Pipfile b/vendor/github.com/testcontainers/testcontainers-go/Pipfile
index f35e8eb..58e8ace 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/Pipfile
+++ b/vendor/github.com/testcontainers/testcontainers-go/Pipfile
@@ -8,7 +8,7 @@ verify_ssl = true
[packages]
mkdocs = "==1.5.3"
mkdocs-codeinclude-plugin = "==0.2.1"
-mkdocs-include-markdown-plugin = "==7.1.5"
+mkdocs-include-markdown-plugin = "==7.1.6"
mkdocs-material = "==9.5.18"
mkdocs-markdownextradata-plugin = "==0.2.6"
diff --git a/vendor/github.com/testcontainers/testcontainers-go/Pipfile.lock b/vendor/github.com/testcontainers/testcontainers-go/Pipfile.lock
index e3b2e97..a8a6ab2 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/Pipfile.lock
+++ b/vendor/github.com/testcontainers/testcontainers-go/Pipfile.lock
@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
- "sha256": "4a9599a9c2db79998493adaaa691752f995ed409e15840df5aae155c83963d51"
+ "sha256": "160280c0c2d9beaa296833b5f5e754123020e5a15854a5ee6201df9cf5761554"
},
"pipfile-spec": 6,
"requires": {
@@ -26,11 +26,11 @@
},
"bracex": {
"hashes": [
- "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6",
- "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"
+ "sha256:0b0049264e7340b3ec782b5cb99beb325f36c3782a32e36e876452fd49a09952",
+ "sha256:98f1347cd77e22ee8d967a30ad4e310b233f7754dbf31ff3fceb76145ba47dc7"
],
- "markers": "python_version >= '3.8'",
- "version": "==2.5.post1"
+ "markers": "python_version >= '3.9'",
+ "version": "==2.6"
},
"certifi": {
"hashes": [
@@ -139,11 +139,11 @@
},
"click": {
"hashes": [
- "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2",
- "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"
+ "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202",
+ "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b"
],
- "markers": "python_version >= '3.7'",
- "version": "==8.1.8"
+ "markers": "python_version >= '3.10'",
+ "version": "==8.2.1"
},
"colorama": {
"hashes": [
@@ -186,11 +186,11 @@
},
"markdown": {
"hashes": [
- "sha256:794a929b79c5af141ef5ab0f2f642d0f7b1872981250230e72682346f7cc90dc",
- "sha256:7df81e63f0df5c4b24b7d156eb81e4690595239b7d70937d0409f1b0de319c6f"
+ "sha256:247b9a70dd12e27f67431ce62523e675b866d254f900c4fe75ce3dda62237c45",
+ "sha256:5c83764dbd4e00bdd94d85a19b8d55ccca20fe35b2e678a1422b380324dd5f24"
],
"markers": "python_version >= '3.9'",
- "version": "==3.8"
+ "version": "==3.8.2"
},
"markupsafe": {
"hashes": [
@@ -287,12 +287,12 @@
},
"mkdocs-include-markdown-plugin": {
"hashes": [
- "sha256:a986967594da6789226798e3c41c70bc17130fadb92b4313f42bd3defdac0adc",
- "sha256:d0b96edee45e7fda5eb189e63331cfaf1bf1fbdbebbd08371f1daa77045d3ae9"
+ "sha256:7975a593514887c18ecb68e11e35c074c5499cfa3e51b18cd16323862e1f7345",
+ "sha256:a0753cb82704c10a287f1e789fc9848f82b6beb8749814b24b03dd9f67816677"
],
"index": "pypi",
"markers": "python_version >= '3.9'",
- "version": "==7.1.5"
+ "version": "==7.1.6"
},
"mkdocs-markdownextradata-plugin": {
"hashes": [
@@ -344,11 +344,11 @@
},
"platformdirs": {
"hashes": [
- "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94",
- "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351"
+ "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc",
+ "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4"
],
"markers": "python_version >= '3.9'",
- "version": "==4.3.7"
+ "version": "==4.3.8"
},
"pygments": {
"hashes": [
@@ -443,11 +443,11 @@
},
"pyyaml-env-tag": {
"hashes": [
- "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb",
- "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"
+ "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04",
+ "sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff"
],
- "markers": "python_version >= '3.6'",
- "version": "==0.1"
+ "markers": "python_version >= '3.9'",
+ "version": "==1.1"
},
"regex": {
"hashes": [
@@ -553,12 +553,12 @@
},
"urllib3": {
"hashes": [
- "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472",
- "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"
+ "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760",
+ "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"
],
"index": "pypi",
- "markers": "python_version >= '3.8'",
- "version": "==2.2.2"
+ "markers": "python_version >= '3.9'",
+ "version": "==2.5.0"
},
"watchdog": {
"hashes": [
@@ -598,11 +598,11 @@
},
"wcmatch": {
"hashes": [
- "sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a",
- "sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a"
+ "sha256:5848ace7dbb0476e5e55ab63c6bbd529745089343427caa5537f230cc01beb8a",
+ "sha256:f11f94208c8c8484a16f4f48638a85d771d9513f4ab3f37595978801cb9465af"
],
- "markers": "python_version >= '3.8'",
- "version": "==10.0"
+ "markers": "python_version >= '3.9'",
+ "version": "==10.1"
},
"zipp": {
"hashes": [
diff --git a/vendor/github.com/testcontainers/testcontainers-go/RELEASING.md b/vendor/github.com/testcontainers/testcontainers-go/RELEASING.md
index 31a9954..a35e243 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/RELEASING.md
+++ b/vendor/github.com/testcontainers/testcontainers-go/RELEASING.md
@@ -93,23 +93,23 @@ go mod tidy
go mod tidy
go mod tidy
go mod tidy
-sed "s/Not available until the next release of testcontainers-go <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\"><span class=\"tc-version\">:material-tag: main<\/span><\/a>/Since testcontainers-go <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\/releases\/tag\/v0.20.1\"><span class=\"tc-version\">:material-tag: v0.20.1<\/span><\/a>/g" couchbase.md > couchbase.md.tmp
+sed "s/Not available until the next release <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\"><span class=\"tc-version\">:material-tag: main<\/span><\/a>/Since <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\/releases\/tag\/v0.20.1\"><span class=\"tc-version\">:material-tag: v0.20.1<\/span><\/a>/g" couchbase.md > couchbase.md.tmp
mv couchbase.md.tmp couchbase.md
-sed "s/Not available until the next release of testcontainers-go <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\"><span class=\"tc-version\">:material-tag: main<\/span><\/a>/Since testcontainers-go <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\/releases\/tag\/v0.20.1\"><span class=\"tc-version\">:material-tag: v0.20.1<\/span><\/a>/g" localstack.md > localstack.md.tmp
+sed "s/Not available until the next release <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\"><span class=\"tc-version\">:material-tag: main<\/span><\/a>/Since <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\/releases\/tag\/v0.20.1\"><span class=\"tc-version\">:material-tag: v0.20.1<\/span><\/a>/g" localstack.md > localstack.md.tmp
mv localstack.md.tmp localstack.md
-sed "s/Not available until the next release of testcontainers-go <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\"><span class=\"tc-version\">:material-tag: main<\/span><\/a>/Since testcontainers-go <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\/releases\/tag\/v0.20.1\"><span class=\"tc-version\">:material-tag: v0.20.1<\/span><\/a>/g" mysql.md > mysql.md.tmp
+sed "s/Not available until the next release <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\"><span class=\"tc-version\">:material-tag: main<\/span><\/a>/Since <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\/releases\/tag\/v0.20.1\"><span class=\"tc-version\">:material-tag: v0.20.1<\/span><\/a>/g" mysql.md > mysql.md.tmp
mv mysql.md.tmp mysql.md
-sed "s/Not available until the next release of testcontainers-go <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\"><span class=\"tc-version\">:material-tag: main<\/span><\/a>/Since testcontainers-go <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\/releases\/tag\/v0.20.1\"><span class=\"tc-version\">:material-tag: v0.20.1<\/span><\/a>/g" neo4j.md > neo4j.md.tmp
+sed "s/Not available until the next release <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\"><span class=\"tc-version\">:material-tag: main<\/span><\/a>/Since <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\/releases\/tag\/v0.20.1\"><span class=\"tc-version\">:material-tag: v0.20.1<\/span><\/a>/g" neo4j.md > neo4j.md.tmp
mv neo4j.md.tmp neo4j.md
-sed "s/Not available until the next release of testcontainers-go <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\"><span class=\"tc-version\">:material-tag: main<\/span><\/a>/Since testcontainers-go <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\/releases\/tag\/v0.20.1\"><span class=\"tc-version\">:material-tag: v0.20.1<\/span><\/a>/g" postgres.md > postgres.md.tmp
+sed "s/Not available until the next release <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\"><span class=\"tc-version\">:material-tag: main<\/span><\/a>/Since <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\/releases\/tag\/v0.20.1\"><span class=\"tc-version\">:material-tag: v0.20.1<\/span><\/a>/g" postgres.md > postgres.md.tmp
mv postgres.md.tmp postgres.md
-sed "s/Not available until the next release of testcontainers-go <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\"><span class=\"tc-version\">:material-tag: main<\/span><\/a>/Since testcontainers-go <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\/releases\/tag\/v0.20.1\"><span class=\"tc-version\">:material-tag: v0.20.1<\/span><\/a>/g" pulsar.md > pulsar.md.tmp
+sed "s/Not available until the next release <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\"><span class=\"tc-version\">:material-tag: main<\/span><\/a>/Since <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\/releases\/tag\/v0.20.1\"><span class=\"tc-version\">:material-tag: v0.20.1<\/span><\/a>/g" pulsar.md > pulsar.md.tmp
mv pulsar.md.tmp pulsar.md
-sed "s/Not available until the next release of testcontainers-go <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\"><span class=\"tc-version\">:material-tag: main<\/span><\/a>/Since testcontainers-go <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\/releases\/tag\/v0.20.1\"><span class=\"tc-version\">:material-tag: v0.20.1<\/span><\/a>/g" redis.md > redis.md.tmp
+sed "s/Not available until the next release <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\"><span class=\"tc-version\">:material-tag: main<\/span><\/a>/Since <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\/releases\/tag\/v0.20.1\"><span class=\"tc-version\">:material-tag: v0.20.1<\/span><\/a>/g" redis.md > redis.md.tmp
mv redis.md.tmp redis.md
-sed "s/Not available until the next release of testcontainers-go <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\"><span class=\"tc-version\">:material-tag: main<\/span><\/a>/Since testcontainers-go <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\/releases\/tag\/v0.20.1\"><span class=\"tc-version\">:material-tag: v0.20.1<\/span><\/a>/g" redpanda.md > redpanda.md.tmp
+sed "s/Not available until the next release <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\"><span class=\"tc-version\">:material-tag: main<\/span><\/a>/Since <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\/releases\/tag\/v0.20.1\"><span class=\"tc-version\">:material-tag: v0.20.1<\/span><\/a>/g" redpanda.md > redpanda.md.tmp
mv redpanda.md.tmp redpanda.md
-sed "s/Not available until the next release of testcontainers-go <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\"><span class=\"tc-version\">:material-tag: main<\/span><\/a>/Since testcontainers-go <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\/releases\/tag\/v0.20.1\"><span class=\"tc-version\">:material-tag: v0.20.1<\/span><\/a>/g" vault.md > vault.md.tmp
+sed "s/Not available until the next release <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\"><span class=\"tc-version\">:material-tag: main<\/span><\/a>/Since <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-go\/releases\/tag\/v0.20.1\"><span class=\"tc-version\">:material-tag: v0.20.1<\/span><\/a>/g" vault.md > vault.md.tmp
mv vault.md.tmp vault.md
```
diff --git a/vendor/github.com/testcontainers/testcontainers-go/container.go b/vendor/github.com/testcontainers/testcontainers-go/container.go
index 1977632..b0f2273 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/container.go
+++ b/vendor/github.com/testcontainers/testcontainers-go/container.go
@@ -6,19 +6,20 @@ import (
"errors"
"fmt"
"io"
+ "maps"
"os"
"path/filepath"
"strings"
"time"
"github.com/cpuguy83/dockercfg"
- "github.com/docker/docker/api/types"
+ "github.com/docker/docker/api/types/build"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/registry"
- "github.com/docker/docker/pkg/archive"
"github.com/docker/go-connections/nat"
"github.com/google/uuid"
+ "github.com/moby/go-archive"
"github.com/moby/patternmatcher/ignorefile"
tcexec "github.com/testcontainers/testcontainers-go/exec"
@@ -73,7 +74,7 @@ type Container interface {
// ImageBuildInfo defines what is needed to build an image
type ImageBuildInfo interface {
- BuildOptions() (types.ImageBuildOptions, error) // converts the ImageBuildInfo to a types.ImageBuildOptions
+ BuildOptions() (build.ImageBuildOptions, error) // converts the ImageBuildInfo to a build.ImageBuildOptions
GetContext() (io.Reader, error) // the path to the build context
GetDockerfile() string // the relative path to the Dockerfile, including the file itself
GetRepo() string // get repo label for image
@@ -103,7 +104,7 @@ type FromDockerfile struct {
// BuildOptionsModifier Modifier for the build options before image build. Use it for
// advanced configurations while building the image. Please consider that the modifier
// is called after the default build options are set.
- BuildOptionsModifier func(*types.ImageBuildOptions)
+ BuildOptionsModifier func(*build.ImageBuildOptions)
}
type ContainerFile struct {
@@ -433,8 +434,8 @@ func (c *ContainerRequest) BuildLogWriter() io.Writer {
// BuildOptions returns the image build options when building a Docker image from a Dockerfile.
// It will apply some defaults and finally call the BuildOptionsModifier from the FromDockerfile struct,
// if set.
-func (c *ContainerRequest) BuildOptions() (types.ImageBuildOptions, error) {
- buildOptions := types.ImageBuildOptions{
+func (c *ContainerRequest) BuildOptions() (build.ImageBuildOptions, error) {
+ buildOptions := build.ImageBuildOptions{
Remove: true,
ForceRemove: true,
}
@@ -450,16 +451,14 @@ func (c *ContainerRequest) BuildOptions() (types.ImageBuildOptions, error) {
// Make sure the auth configs from the Dockerfile are set right after the user-defined build options.
authsFromDockerfile, err := getAuthConfigsFromDockerfile(c)
if err != nil {
- return types.ImageBuildOptions{}, fmt.Errorf("auth configs from Dockerfile: %w", err)
+ return build.ImageBuildOptions{}, fmt.Errorf("auth configs from Dockerfile: %w", err)
}
if buildOptions.AuthConfigs == nil {
buildOptions.AuthConfigs = map[string]registry.AuthConfig{}
}
- for registry, authConfig := range authsFromDockerfile {
- buildOptions.AuthConfigs[registry] = authConfig
- }
+ maps.Copy(buildOptions.AuthConfigs, authsFromDockerfile)
// make sure the first tag is the one defined in the ContainerRequest
tag := fmt.Sprintf("%s:%s", c.GetRepo(), c.GetTag())
@@ -468,7 +467,7 @@ func (c *ContainerRequest) BuildOptions() (types.ImageBuildOptions, error) {
for _, is := range c.ImageSubstitutors {
modifiedTag, err := is.Substitute(tag)
if err != nil {
- return types.ImageBuildOptions{}, fmt.Errorf("failed to substitute image %s with %s: %w", tag, is.Description(), err)
+ return build.ImageBuildOptions{}, fmt.Errorf("failed to substitute image %s with %s: %w", tag, is.Description(), err)
}
if modifiedTag != tag {
@@ -487,10 +486,10 @@ func (c *ContainerRequest) BuildOptions() (types.ImageBuildOptions, error) {
if !c.ShouldKeepBuiltImage() {
dst := GenericLabels()
if err = core.MergeCustomLabels(dst, c.Labels); err != nil {
- return types.ImageBuildOptions{}, err
+ return build.ImageBuildOptions{}, err
}
if err = core.MergeCustomLabels(dst, buildOptions.Labels); err != nil {
- return types.ImageBuildOptions{}, err
+ return build.ImageBuildOptions{}, err
}
buildOptions.Labels = dst
}
@@ -498,7 +497,7 @@ func (c *ContainerRequest) BuildOptions() (types.ImageBuildOptions, error) {
// Do this as late as possible to ensure we don't leak the context on error/panic.
buildContext, err := c.GetContext()
if err != nil {
- return types.ImageBuildOptions{}, err
+ return build.ImageBuildOptions{}, err
}
buildOptions.Context = buildContext
diff --git a/vendor/github.com/testcontainers/testcontainers-go/docker.go b/vendor/github.com/testcontainers/testcontainers-go/docker.go
index c578796..e20026c 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/docker.go
+++ b/vendor/github.com/testcontainers/testcontainers-go/docker.go
@@ -5,6 +5,7 @@ import (
"bufio"
"context"
"encoding/base64"
+ "encoding/binary"
"encoding/json"
"errors"
"fmt"
@@ -15,18 +16,19 @@ import (
"os"
"path/filepath"
"regexp"
+ "slices"
"sync"
"time"
"github.com/cenkalti/backoff/v4"
+ "github.com/containerd/errdefs"
"github.com/containerd/platforms"
- "github.com/docker/docker/api/types"
+ "github.com/docker/docker/api/types/build"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/client"
- "github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/jsonmessage"
"github.com/docker/docker/pkg/stdcopy"
"github.com/docker/go-connections/nat"
@@ -79,6 +81,7 @@ type DockerContainer struct {
provider *DockerProvider
sessionID string
terminationSignal chan bool
+ consumersMtx sync.Mutex // protects consumers
consumers []LogConsumer
// TODO: Remove locking and wait group once the deprecated StartLogProducer and
@@ -139,7 +142,8 @@ func (c *DockerContainer) Endpoint(ctx context.Context, proto string) (string, e
}
// PortEndpoint gets proto://host:port string for the given exposed port
-// Will returns just host:port if proto is ""
+// It returns proto://host:port or proto://[IPv6host]:port string for the given exposed port.
+// It returns just host:port or [IPv6host]:port if proto is blank.
func (c *DockerContainer) PortEndpoint(ctx context.Context, port nat.Port, proto string) (string, error) {
host, err := c.Host(ctx)
if err != nil {
@@ -151,12 +155,12 @@ func (c *DockerContainer) PortEndpoint(ctx context.Context, port nat.Port, proto
return "", err
}
- protoFull := ""
- if proto != "" {
- protoFull = proto + "://"
+ hostPort := net.JoinHostPort(host, outerPort.Port())
+ if proto == "" {
+ return hostPort, nil
}
- return fmt.Sprintf("%s%s:%s", protoFull, host, outerPort.Port()), nil
+ return proto + "://" + hostPort, nil
}
// Host gets host (ip or name) of the docker daemon where the container port is exposed
@@ -205,7 +209,7 @@ func (c *DockerContainer) MappedPort(ctx context.Context, port nat.Port) (nat.Po
return nat.NewPort(k.Proto(), p[0].HostPort)
}
- return "", errdefs.NotFound(fmt.Errorf("port %q not found", port))
+ return "", errdefs.ErrNotFound.WithMessage(fmt.Sprintf("port %q not found", port))
}
// Deprecated: use c.Inspect(ctx).NetworkSettings.Ports instead.
@@ -364,8 +368,6 @@ func (c *DockerContainer) inspectRawContainer(ctx context.Context) (*container.I
// Logs will fetch both STDOUT and STDERR from the current container. Returns a
// ReadCloser and leaves it up to the caller to extract what it wants.
func (c *DockerContainer) Logs(ctx context.Context) (io.ReadCloser, error) {
- const streamHeaderSize = 8
-
options := container.LogsOptions{
ShowStdout: true,
ShowStderr: true,
@@ -377,42 +379,43 @@ func (c *DockerContainer) Logs(ctx context.Context) (io.ReadCloser, error) {
}
defer c.provider.Close()
+ resp, err := c.Inspect(ctx)
+ if err != nil {
+ return nil, err
+ }
+
+ if resp.Config.Tty {
+ return rc, nil
+ }
+
+ return c.parseMultiplexedLogs(rc), nil
+}
+
+// parseMultiplexedLogs handles the multiplexed log format used when TTY is disabled
+func (c *DockerContainer) parseMultiplexedLogs(rc io.ReadCloser) io.ReadCloser {
+ const streamHeaderSize = 8
+
pr, pw := io.Pipe()
r := bufio.NewReader(rc)
go func() {
- lineStarted := true
- for err == nil {
- line, isPrefix, err := r.ReadLine()
-
- if lineStarted && len(line) >= streamHeaderSize {
- line = line[streamHeaderSize:] // trim stream header
- lineStarted = false
- }
- if !isPrefix {
- lineStarted = true
- }
-
- _, errW := pw.Write(line)
- if errW != nil {
+ header := make([]byte, streamHeaderSize)
+ for {
+ _, errH := io.ReadFull(r, header)
+ if errH != nil {
+ _ = pw.CloseWithError(errH)
return
}
- if !isPrefix {
- _, errW := pw.Write([]byte("\n"))
- if errW != nil {
- return
- }
- }
-
- if err != nil {
- _ = pw.CloseWithError(err)
+ frameSize := binary.BigEndian.Uint32(header[4:])
+ if _, err := io.CopyN(pw, r, int64(frameSize)); err != nil {
+ pw.CloseWithError(err)
return
}
}
}()
- return pr, nil
+ return pr
}
// Deprecated: use the ContainerRequest.LogConsumerConfig field instead.
@@ -423,9 +426,29 @@ func (c *DockerContainer) FollowOutput(consumer LogConsumer) {
// followOutput adds a LogConsumer to be sent logs from the container's
// STDOUT and STDERR
func (c *DockerContainer) followOutput(consumer LogConsumer) {
+ c.consumersMtx.Lock()
+ defer c.consumersMtx.Unlock()
+
c.consumers = append(c.consumers, consumer)
}
+// consumersCopy returns a copy of the current consumers.
+func (c *DockerContainer) consumersCopy() []LogConsumer {
+ c.consumersMtx.Lock()
+ defer c.consumersMtx.Unlock()
+
+ return slices.Clone(c.consumers)
+}
+
+// resetConsumers resets the current consumers to the provided ones.
+func (c *DockerContainer) resetConsumers(consumers []LogConsumer) {
+ c.consumersMtx.Lock()
+ defer c.consumersMtx.Unlock()
+
+ c.consumers = c.consumers[:0]
+ c.consumers = append(c.consumers, consumers...)
+}
+
// Deprecated: use c.Inspect(ctx).Name instead.
// Name gets the name of the container.
func (c *DockerContainer) Name(ctx context.Context) (string, error) {
@@ -760,8 +783,10 @@ func (c *DockerContainer) startLogProduction(ctx context.Context, opts ...LogPro
}
// Setup the log writers.
- stdout := newLogConsumerWriter(StdoutLog, c.consumers)
- stderr := newLogConsumerWriter(StderrLog, c.consumers)
+
+ consumers := c.consumersCopy()
+ stdout := newLogConsumerWriter(StdoutLog, consumers)
+ stderr := newLogConsumerWriter(StderrLog, consumers)
// Setup the log production context which will be used to stop the log production.
c.logProductionCtx, c.logProductionCancel = context.WithCancelCause(ctx)
@@ -977,22 +1002,22 @@ var _ ContainerProvider = (*DockerProvider)(nil)
// BuildImage will build and image from context and Dockerfile, then return the tag
func (p *DockerProvider) BuildImage(ctx context.Context, img ImageBuildInfo) (string, error) {
- var buildOptions types.ImageBuildOptions
+ var buildOptions build.ImageBuildOptions
resp, err := backoff.RetryNotifyWithData(
- func() (types.ImageBuildResponse, error) {
+ func() (build.ImageBuildResponse, error) {
var err error
buildOptions, err = img.BuildOptions()
if err != nil {
- return types.ImageBuildResponse{}, backoff.Permanent(fmt.Errorf("build options: %w", err))
+ return build.ImageBuildResponse{}, backoff.Permanent(fmt.Errorf("build options: %w", err))
}
defer tryClose(buildOptions.Context) // release resources in any case
resp, err := p.client.ImageBuild(ctx, buildOptions.Context, buildOptions)
if err != nil {
if isPermanentClientError(err) {
- return types.ImageBuildResponse{}, backoff.Permanent(fmt.Errorf("build image: %w", err))
+ return build.ImageBuildResponse{}, backoff.Permanent(fmt.Errorf("build image: %w", err))
}
- return types.ImageBuildResponse{}, err
+ return build.ImageBuildResponse{}, err
}
defer p.Close()
@@ -1037,13 +1062,7 @@ func (p *DockerProvider) CreateContainer(ctx context.Context, req ContainerReque
// as container won't be attached to it automatically
// in case of Podman the bridge network is called 'podman' as 'bridge' would conflict
if defaultNetwork != p.defaultBridgeNetworkName {
- isAttached := false
- for _, net := range req.Networks {
- if net == defaultNetwork {
- isAttached = true
- break
- }
- }
+ isAttached := slices.Contains(req.Networks, defaultNetwork)
if !isAttached {
req.Networks = append(req.Networks, defaultNetwork)
@@ -1121,7 +1140,7 @@ func (p *DockerProvider) CreateContainer(ctx context.Context, req ContainerReque
} else {
img, err := p.client.ImageInspect(ctx, imageName)
if err != nil {
- if !client.IsErrNotFound(err) {
+ if !errdefs.IsNotFound(err) {
return nil, err
}
shouldPullImage = true
@@ -1290,7 +1309,7 @@ func (p *DockerProvider) waitContainerCreation(ctx context.Context, name string)
}
if c == nil {
- return nil, errdefs.NotFound(fmt.Errorf("container %s not found", name))
+ return nil, errdefs.ErrNotFound.WithMessage(fmt.Sprintf("container %s not found", name))
}
return c, nil
},
@@ -1364,11 +1383,19 @@ func (p *DockerProvider) ReuseOrCreateContainer(ctx context.Context, req Contain
lifecycleHooks: []ContainerLifecycleHooks{combineContainerHooks(defaultHooks, req.LifecycleHooks)},
}
+ // Workaround for https://github.com/moby/moby/issues/50133.
+ // /containers/{id}/json API endpoint of Docker Engine takes data about container from master (not replica) database
+ // which is synchronized with container state after call of /containers/{id}/stop API endpoint.
+ dcState, err := dc.State(ctx)
+ if err != nil {
+ return nil, fmt.Errorf("docker container state: %w", err)
+ }
+
// If a container was stopped programmatically, we want to ensure the container
// is running again, but only if it is not paused, as it's not possible to start
// a paused container. The Docker Engine returns the "cannot start a paused container,
// try unpause instead" error.
- switch c.State {
+ switch dcState.Status {
case "running":
// cannot re-start a running container, but we still need
// to call the startup hooks.
@@ -1401,7 +1428,7 @@ func (p *DockerProvider) ReuseOrCreateContainer(ctx context.Context, req Contain
func (p *DockerProvider) attemptToPullImage(ctx context.Context, tag string, pullOpt image.PullOptions) error {
registry, imageAuth, err := DockerImageAuth(ctx, tag)
if err != nil {
- p.Logger.Printf("Failed to get image auth for %s. Setting empty credentials for the image: %s. Error is: %s", registry, tag, err)
+ p.Logger.Printf("No image auth found for %s. Setting empty credentials for the image: %s. This is expected for public images. Details: %s", registry, tag, err)
} else {
// see https://github.com/docker/docs/blob/e8e1204f914767128814dca0ea008644709c117f/engine/api/sdk/examples.md?plain=1#L649-L657
encodedJSON, err := json.Marshal(imageAuth)
@@ -1437,7 +1464,7 @@ func (p *DockerProvider) attemptToPullImage(ctx context.Context, tag string, pul
defer pull.Close()
// download of docker image finishes at EOF of the pull request
- _, err = io.ReadAll(pull)
+ _, err = io.Copy(io.Discard, pull)
return err
}
@@ -1791,11 +1818,11 @@ func (p *DockerProvider) PullImage(ctx context.Context, img string) error {
var permanentClientErrors = []func(error) bool{
errdefs.IsNotFound,
- errdefs.IsInvalidParameter,
+ errdefs.IsInvalidArgument,
errdefs.IsUnauthorized,
- errdefs.IsForbidden,
+ errdefs.IsPermissionDenied,
errdefs.IsNotImplemented,
- errdefs.IsSystem,
+ errdefs.IsInternal,
}
func isPermanentClientError(err error) bool {
diff --git a/vendor/github.com/testcontainers/testcontainers-go/exec/processor.go b/vendor/github.com/testcontainers/testcontainers-go/exec/processor.go
index 9c852fb..36f1db1 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/exec/processor.go
+++ b/vendor/github.com/testcontainers/testcontainers-go/exec/processor.go
@@ -25,7 +25,6 @@ func NewProcessOptions(cmd []string) *ProcessOptions {
return &ProcessOptions{
ExecConfig: container.ExecOptions{
Cmd: cmd,
- Detach: false,
AttachStdout: true,
AttachStderr: true,
},
diff --git a/vendor/github.com/testcontainers/testcontainers-go/generic.go b/vendor/github.com/testcontainers/testcontainers-go/generic.go
index 9663b03..dc5ee1c 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/generic.go
+++ b/vendor/github.com/testcontainers/testcontainers-go/generic.go
@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
+ "maps"
"strings"
"sync"
@@ -113,9 +114,7 @@ func GenericLabels() map[string]string {
// AddGenericLabels adds the generic labels to target.
func AddGenericLabels(target map[string]string) {
- for k, v := range GenericLabels() {
- target[k] = v
- }
+ maps.Copy(target, GenericLabels())
}
// Run is a convenience function that creates a new container and starts it.
diff --git a/vendor/github.com/testcontainers/testcontainers-go/internal/config/config.go b/vendor/github.com/testcontainers/testcontainers-go/internal/config/config.go
index 64f2f7f..dda7e28 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/internal/config/config.go
+++ b/vendor/github.com/testcontainers/testcontainers-go/internal/config/config.go
@@ -11,7 +11,7 @@ import (
"github.com/magiconair/properties"
)
-const ReaperDefaultImage = "testcontainers/ryuk:0.11.0"
+const ReaperDefaultImage = "testcontainers/ryuk:0.12.0"
var (
tcConfig Config
diff --git a/vendor/github.com/testcontainers/testcontainers-go/internal/core/labels.go b/vendor/github.com/testcontainers/testcontainers-go/internal/core/labels.go
index 0814924..198fdae 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/internal/core/labels.go
+++ b/vendor/github.com/testcontainers/testcontainers-go/internal/core/labels.go
@@ -3,6 +3,7 @@ package core
import (
"errors"
"fmt"
+ "maps"
"strings"
"github.com/testcontainers/testcontainers-go/internal"
@@ -51,9 +52,7 @@ func DefaultLabels(sessionID string) map[string]string {
// AddDefaultLabels adds the default labels for sessionID to target.
func AddDefaultLabels(sessionID string, target map[string]string) {
- for k, v := range DefaultLabels(sessionID) {
- target[k] = v
- }
+ maps.Copy(target, DefaultLabels(sessionID))
}
// MergeCustomLabels sets labels from src to dst.
diff --git a/vendor/github.com/testcontainers/testcontainers-go/internal/version.go b/vendor/github.com/testcontainers/testcontainers-go/internal/version.go
index 6dba727..bc31ad9 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/internal/version.go
+++ b/vendor/github.com/testcontainers/testcontainers-go/internal/version.go
@@ -1,4 +1,4 @@
package internal
// Version is the next development version of the application
-const Version = "0.37.0"
+const Version = "0.38.0"
diff --git a/vendor/github.com/testcontainers/testcontainers-go/lifecycle.go b/vendor/github.com/testcontainers/testcontainers-go/lifecycle.go
index 72363cc..7887ebe 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/lifecycle.go
+++ b/vendor/github.com/testcontainers/testcontainers-go/lifecycle.go
@@ -9,7 +9,6 @@ import (
"strings"
"time"
- "github.com/cenkalti/backoff/v4"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/go-connections/nat"
@@ -190,10 +189,7 @@ var defaultLogConsumersHook = func(cfg *LogConsumerConfig) ContainerLifecycleHoo
}
dockerContainer := c.(*DockerContainer)
- dockerContainer.consumers = dockerContainer.consumers[:0]
- for _, consumer := range cfg.Consumers {
- dockerContainer.followOutput(consumer)
- }
+ dockerContainer.resetConsumers(cfg.Consumers)
return dockerContainer.startLogProduction(ctx, cfg.Opts...)
},
@@ -213,71 +209,10 @@ var defaultLogConsumersHook = func(cfg *LogConsumerConfig) ContainerLifecycleHoo
}
}
-func checkPortsMapped(exposedAndMappedPorts nat.PortMap, exposedPorts []string) error {
- portMap, _, err := nat.ParsePortSpecs(exposedPorts)
- if err != nil {
- return fmt.Errorf("parse exposed ports: %w", err)
- }
-
- for exposedPort := range portMap {
- // having entries in exposedAndMappedPorts, where the key is the exposed port,
- // and the value is the mapped port, means that the port has been already mapped.
- if _, ok := exposedAndMappedPorts[exposedPort]; ok {
- continue
- }
-
- // check if the port is mapped with the protocol (default is TCP)
- if strings.Contains(string(exposedPort), "/") {
- return fmt.Errorf("port %s is not mapped yet", exposedPort)
- }
-
- // Port didn't have a type, default to tcp and retry.
- exposedPort += "/tcp"
- if _, ok := exposedAndMappedPorts[exposedPort]; !ok {
- return fmt.Errorf("port %s is not mapped yet", exposedPort)
- }
- }
-
- return nil
-}
-
// defaultReadinessHook is a hook that will wait for the container to be ready
var defaultReadinessHook = func() ContainerLifecycleHooks {
return ContainerLifecycleHooks{
PostStarts: []ContainerHook{
- func(ctx context.Context, c Container) error {
- // wait until all the exposed ports are mapped:
- // it will be ready when all the exposed ports are mapped,
- // checking every 50ms, up to 1s, and failing if all the
- // exposed ports are not mapped in 5s.
- dockerContainer := c.(*DockerContainer)
-
- b := backoff.NewExponentialBackOff()
-
- b.InitialInterval = 50 * time.Millisecond
- b.MaxElapsedTime = 5 * time.Second
- b.MaxInterval = time.Duration(float64(time.Second) * backoff.DefaultRandomizationFactor)
-
- err := backoff.RetryNotify(
- func() error {
- jsonRaw, err := dockerContainer.inspectRawContainer(ctx)
- if err != nil {
- return err
- }
-
- return checkPortsMapped(jsonRaw.NetworkSettings.Ports, dockerContainer.exposedPorts)
- },
- b,
- func(err error, _ time.Duration) {
- dockerContainer.logger.Printf("All requested ports were not exposed: %v", err)
- },
- )
- if err != nil {
- return fmt.Errorf("all exposed ports, %s, were not mapped in 5s: %w", dockerContainer.exposedPorts, err)
- }
-
- return nil
- },
// wait for the container to be ready
func(ctx context.Context, c Container) error {
dockerContainer := c.(*DockerContainer)
@@ -373,7 +308,11 @@ func (c *DockerContainer) printLogs(ctx context.Context, cause error) {
b, err := io.ReadAll(reader)
if err != nil {
- c.logger.Printf("failed reading container logs: %v\n", err)
+ if len(b) > 0 {
+ c.logger.Printf("failed reading container logs: %v\npartial container logs (%s):\n%s", err, cause, b)
+ } else {
+ c.logger.Printf("failed reading container logs: %v\n", err)
+ }
return
}
@@ -620,7 +559,7 @@ func combineContainerHooks(defaultHooks, userDefinedHooks []ContainerLifecycleHo
hooksType := reflect.TypeOf(hooks)
for _, defaultHook := range defaultHooks {
defaultVal := reflect.ValueOf(defaultHook)
- for i := 0; i < hooksType.NumField(); i++ {
+ for i := range hooksType.NumField() {
if strings.HasPrefix(hooksType.Field(i).Name, "Pre") {
field := hooksVal.Field(i)
field.Set(reflect.AppendSlice(field, defaultVal.Field(i)))
@@ -633,7 +572,7 @@ func combineContainerHooks(defaultHooks, userDefinedHooks []ContainerLifecycleHo
// post-hooks will be the first ones to be executed.
for _, userDefinedHook := range userDefinedHooks {
userVal := reflect.ValueOf(userDefinedHook)
- for i := 0; i < hooksType.NumField(); i++ {
+ for i := range hooksType.NumField() {
field := hooksVal.Field(i)
field.Set(reflect.AppendSlice(field, userVal.Field(i)))
}
@@ -642,7 +581,7 @@ func combineContainerHooks(defaultHooks, userDefinedHooks []ContainerLifecycleHo
// Finally, append the default post-hooks.
for _, defaultHook := range defaultHooks {
defaultVal := reflect.ValueOf(defaultHook)
- for i := 0; i < hooksType.NumField(); i++ {
+ for i := range hooksType.NumField() {
if strings.HasPrefix(hooksType.Field(i).Name, "Post") {
field := hooksVal.Field(i)
field.Set(reflect.AppendSlice(field, defaultVal.Field(i)))
diff --git a/vendor/github.com/testcontainers/testcontainers-go/mkdocs.yml b/vendor/github.com/testcontainers/testcontainers-go/mkdocs.yml
index 99e8f4a..60fa87c 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/mkdocs.yml
+++ b/vendor/github.com/testcontainers/testcontainers-go/mkdocs.yml
@@ -40,19 +40,6 @@ nav:
- Quickstart: quickstart.md
- Features:
- features/creating_container.md
- - features/configuration.md
- - features/image_name_substitution.md
- - features/files_and_mounts.md
- - features/creating_networks.md
- - features/networking.md
- - features/tls.md
- - features/test_session_semantics.md
- - features/garbage_collector.md
- - features/build_from_dockerfile.md
- - features/docker_auth.md
- - features/docker_compose.md
- - features/follow_logs.md
- - features/override_container_command.md
- Wait Strategies:
- Introduction: features/wait/introduction.md
- Exec: features/wait/exec.md
@@ -66,6 +53,18 @@ nav:
- SQL: features/wait/sql.md
- TLS: features/wait/tls.md
- Walk: features/wait/walk.md
+ - features/files_and_mounts.md
+ - features/follow_logs.md
+ - features/garbage_collector.md
+ - features/build_from_dockerfile.md
+ - features/override_container_command.md
+ - features/networking.md
+ - features/configuration.md
+ - features/image_name_substitution.md
+ - features/test_session_semantics.md
+ - features/docker_auth.md
+ - features/docker_compose.md
+ - features/tls.md
- Modules:
- modules/index.md
- modules/aerospike.md
@@ -86,7 +85,6 @@ nav:
- modules/dynamodb.md
- modules/elasticsearch.md
- modules/etcd.md
- - modules/firebase.md
- modules/gcloud.md
- modules/grafana-lgtm.md
- modules/inbucket.md
@@ -97,6 +95,7 @@ nav:
- modules/localstack.md
- modules/mariadb.md
- modules/meilisearch.md
+ - modules/memcached.md
- modules/milvus.md
- modules/minio.md
- modules/mockserver.md
@@ -150,4 +149,4 @@ nav:
- Getting help: getting_help.md
edit_uri: edit/main/docs/
extra:
- latest_version: v0.37.0
+ latest_version: v0.38.0
diff --git a/vendor/github.com/testcontainers/testcontainers-go/options.go b/vendor/github.com/testcontainers/testcontainers-go/options.go
index 9afbcd7..f7775f8 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/options.go
+++ b/vendor/github.com/testcontainers/testcontainers-go/options.go
@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
+ "maps"
"net/url"
"time"
@@ -77,9 +78,7 @@ func WithEnv(envs map[string]string) CustomizeRequestOption {
req.Env = map[string]string{}
}
- for key, val := range envs {
- req.Env[key] = val
- }
+ maps.Copy(req.Env, envs)
return nil
}
@@ -106,14 +105,33 @@ func WithHostPortAccess(ports ...int) CustomizeRequestOption {
}
}
+// WithName will set the name of the container.
+func WithName(containerName string) CustomizeRequestOption {
+ return func(req *GenericContainerRequest) error {
+ if containerName == "" {
+ return errors.New("container name must be provided")
+ }
+ req.Name = containerName
+ return nil
+ }
+}
+
+// WithNoStart will prevent the container from being started after creation.
+func WithNoStart() CustomizeRequestOption {
+ return func(req *GenericContainerRequest) error {
+ req.Started = false
+ return nil
+ }
+}
+
// WithReuseByName will mark a container to be reused if it exists or create a new one if it doesn't.
// A container name must be provided to identify the container to be reused.
func WithReuseByName(containerName string) CustomizeRequestOption {
return func(req *GenericContainerRequest) error {
- if containerName == "" {
- return errors.New("container name must be provided for reuse")
+ if err := WithName(containerName)(req); err != nil {
+ return err
}
- req.Name = containerName
+
req.Reuse = true
return nil
}
@@ -255,6 +273,17 @@ func WithLogConsumers(consumer ...LogConsumer) CustomizeRequestOption {
}
}
+// WithLogConsumerConfig sets the log consumer config for a container.
+// Beware that this option completely replaces the existing log consumer config,
+// including the log consumers and the log production options,
+// so it should be used with care.
+func WithLogConsumerConfig(config *LogConsumerConfig) CustomizeRequestOption {
+ return func(req *GenericContainerRequest) error {
+ req.LogConsumerCfg = config
+ return nil
+ }
+}
+
// Executable represents an executable command to be sent to a container, including options,
// as part of the different lifecycle hooks.
type Executable interface {
@@ -281,11 +310,11 @@ type RawCommand struct {
cmds []string
}
-func NewRawCommand(cmds []string) RawCommand {
+func NewRawCommand(cmds []string, opts ...tcexec.ProcessOption) RawCommand {
return RawCommand{
cmds: cmds,
ExecOptions: ExecOptions{
- opts: []tcexec.ProcessOption{},
+ opts: opts,
},
}
}
@@ -343,12 +372,17 @@ func WithAfterReadyCommand(execs ...Executable) CustomizeRequestOption {
}
}
-// WithWaitStrategy sets the wait strategy for a container, using 60 seconds as deadline
+// WithWaitStrategy replaces the wait strategy for a container, using 60 seconds as deadline
func WithWaitStrategy(strategies ...wait.Strategy) CustomizeRequestOption {
return WithWaitStrategyAndDeadline(60*time.Second, strategies...)
}
-// WithWaitStrategyAndDeadline sets the wait strategy for a container, including deadline
+// WithAdditionalWaitStrategy appends the wait strategy for a container, using 60 seconds as deadline
+func WithAdditionalWaitStrategy(strategies ...wait.Strategy) CustomizeRequestOption {
+ return WithAdditionalWaitStrategyAndDeadline(60*time.Second, strategies...)
+}
+
+// WithWaitStrategyAndDeadline replaces the wait strategy for a container, including deadline
func WithWaitStrategyAndDeadline(deadline time.Duration, strategies ...wait.Strategy) CustomizeRequestOption {
return func(req *GenericContainerRequest) error {
req.WaitingFor = wait.ForAll(strategies...).WithDeadline(deadline)
@@ -357,6 +391,24 @@ func WithWaitStrategyAndDeadline(deadline time.Duration, strategies ...wait.Stra
}
}
+// WithAdditionalWaitStrategyAndDeadline appends the wait strategy for a container, including deadline
+func WithAdditionalWaitStrategyAndDeadline(deadline time.Duration, strategies ...wait.Strategy) CustomizeRequestOption {
+ return func(req *GenericContainerRequest) error {
+ if req.WaitingFor == nil {
+ req.WaitingFor = wait.ForAll(strategies...).WithDeadline(deadline)
+ return nil
+ }
+
+ wss := make([]wait.Strategy, 0, len(strategies)+1)
+ wss = append(wss, req.WaitingFor)
+ wss = append(wss, strategies...)
+
+ req.WaitingFor = wait.ForAll(wss...).WithDeadline(deadline)
+
+ return nil
+ }
+}
+
// WithImageMount mounts an image to a container, passing the source image name,
// the relative subpath to mount in that image, and the mount point in the target container.
// This option validates that the subpath is a relative path, raising an error otherwise.
@@ -376,6 +428,22 @@ func WithImageMount(source string, subpath string, target ContainerMountTarget)
}
}
+// WithAlwaysPull will pull the image before starting the container
+func WithAlwaysPull() CustomizeRequestOption {
+ return func(req *GenericContainerRequest) error {
+ req.AlwaysPullImage = true
+ return nil
+ }
+}
+
+// WithImagePlatform sets the platform for a container
+func WithImagePlatform(platform string) CustomizeRequestOption {
+ return func(req *GenericContainerRequest) error {
+ req.ImagePlatform = platform
+ return nil
+ }
+}
+
// WithEntrypoint completely replaces the entrypoint of a container
func WithEntrypoint(entrypoint ...string) CustomizeRequestOption {
return func(req *GenericContainerRequest) error {
@@ -422,9 +490,23 @@ func WithLabels(labels map[string]string) CustomizeRequestOption {
if req.Labels == nil {
req.Labels = make(map[string]string)
}
- for k, v := range labels {
- req.Labels[k] = v
- }
+ maps.Copy(req.Labels, labels)
+ return nil
+ }
+}
+
+// WithLifecycleHooks completely replaces the lifecycle hooks for a container
+func WithLifecycleHooks(hooks ...ContainerLifecycleHooks) CustomizeRequestOption {
+ return func(req *GenericContainerRequest) error {
+ req.LifecycleHooks = hooks
+ return nil
+ }
+}
+
+// WithAdditionalLifecycleHooks appends lifecycle hooks to the existing ones for a container
+func WithAdditionalLifecycleHooks(hooks ...ContainerLifecycleHooks) CustomizeRequestOption {
+ return func(req *GenericContainerRequest) error {
+ req.LifecycleHooks = append(req.LifecycleHooks, hooks...)
return nil
}
}
@@ -443,9 +525,7 @@ func WithTmpfs(tmpfs map[string]string) CustomizeRequestOption {
if req.Tmpfs == nil {
req.Tmpfs = make(map[string]string)
}
- for k, v := range tmpfs {
- req.Tmpfs[k] = v
- }
+ maps.Copy(req.Tmpfs, tmpfs)
return nil
}
}
diff --git a/vendor/github.com/testcontainers/testcontainers-go/parallel.go b/vendor/github.com/testcontainers/testcontainers-go/parallel.go
index 0349023..a75d011 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/parallel.go
+++ b/vendor/github.com/testcontainers/testcontainers-go/parallel.go
@@ -61,10 +61,7 @@ func ParallelContainers(ctx context.Context, reqs ParallelContainerRequest, opt
opt.WorkersCount = defaultWorkersCount
}
- tasksChanSize := opt.WorkersCount
- if tasksChanSize > len(reqs) {
- tasksChanSize = len(reqs)
- }
+ tasksChanSize := min(opt.WorkersCount, len(reqs))
tasksChan := make(chan GenericContainerRequest, tasksChanSize)
resultsChan := make(chan parallelContainersResult, tasksChanSize)
@@ -74,7 +71,7 @@ func ParallelContainers(ctx context.Context, reqs ParallelContainerRequest, opt
wg.Add(tasksChanSize)
// run workers
- for i := 0; i < tasksChanSize; i++ {
+ for range tasksChanSize {
go parallelContainersRunner(ctx, tasksChan, resultsChan, &wg)
}
diff --git a/vendor/github.com/testcontainers/testcontainers-go/port_forwarding.go b/vendor/github.com/testcontainers/testcontainers-go/port_forwarding.go
index cd82361..107bd42 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/port_forwarding.go
+++ b/vendor/github.com/testcontainers/testcontainers-go/port_forwarding.go
@@ -6,6 +6,7 @@ import (
"fmt"
"io"
"net"
+ "slices"
"sync"
"time"
@@ -19,7 +20,7 @@ import (
const (
// hubSshdImage {
- sshdImage string = "testcontainers/sshd:1.2.0"
+ sshdImage string = "testcontainers/sshd:1.3.0"
// }
// HostInternal is the internal hostname used to reach the host from the container,
@@ -135,13 +136,7 @@ func exposeHostPorts(ctx context.Context, req *ContainerRequest, ports ...int) (
modes := []container.NetworkMode{container.NetworkMode(sshdFirstNetwork), "none", "host"}
// if the container is not in one of the modes, attach it to the first network of the SSHD container
- found := false
- for _, mode := range modes {
- if hostConfig.NetworkMode == mode {
- found = true
- break
- }
- }
+ found := slices.Contains(modes, hostConfig.NetworkMode)
if !found {
req.Networks = append(req.Networks, sshdFirstNetwork)
}
diff --git a/vendor/github.com/testcontainers/testcontainers-go/reaper.go b/vendor/github.com/testcontainers/testcontainers-go/reaper.go
index 26cac14..4e46f0e 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/reaper.go
+++ b/vendor/github.com/testcontainers/testcontainers-go/reaper.go
@@ -14,10 +14,10 @@ import (
"time"
"github.com/cenkalti/backoff/v4"
+ "github.com/containerd/errdefs"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
- "github.com/docker/docker/errdefs"
"github.com/docker/go-connections/nat"
"github.com/testcontainers/testcontainers-go/internal/config"
@@ -224,7 +224,7 @@ func (r *reaperSpawner) isRunning(ctx context.Context, ctr Container) error {
if !state.Running {
// Use NotFound error to indicate the container is not running
// and should be recreated.
- return errdefs.NotFound(fmt.Errorf("container state: %s", state.Status))
+ return errdefs.ErrNotFound.WithMessage("container state: " + state.Status)
}
return nil
diff --git a/vendor/github.com/testcontainers/testcontainers-go/requirements.txt b/vendor/github.com/testcontainers/testcontainers-go/requirements.txt
index e4db882..8027e7d 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/requirements.txt
+++ b/vendor/github.com/testcontainers/testcontainers-go/requirements.txt
@@ -1,5 +1,5 @@
mkdocs==1.5.3
mkdocs-codeinclude-plugin==0.2.1
-mkdocs-include-markdown-plugin==6.2.2
+mkdocs-include-markdown-plugin==7.1.5
mkdocs-material==9.5.18
mkdocs-markdownextradata-plugin==0.2.6
diff --git a/vendor/github.com/testcontainers/testcontainers-go/testing.go b/vendor/github.com/testcontainers/testcontainers-go/testing.go
index 1f41913..704af99 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/testing.go
+++ b/vendor/github.com/testcontainers/testcontainers-go/testing.go
@@ -7,7 +7,7 @@ import (
"regexp"
"testing"
- "github.com/docker/docker/errdefs"
+ "github.com/containerd/errdefs"
"github.com/stretchr/testify/require"
)
@@ -147,15 +147,19 @@ func isCleanupSafe(err error) bool {
return true
}
- switch x := err.(type) { //nolint:errorlint // We need to check for interfaces.
- case errdefs.ErrNotFound:
+ // First try with containerd's errdefs
+ switch {
+ case errdefs.IsNotFound(err):
return true
- case errdefs.ErrConflict:
+ case errdefs.IsConflict(err):
// Terminating a container that is already terminating.
if errAlreadyInProgress.MatchString(err.Error()) {
return true
}
return false
+ }
+
+ switch x := err.(type) { //nolint:errorlint // We need to check for interfaces.
case causer:
return isCleanupSafe(x.Cause())
case wrapErr:
diff --git a/vendor/github.com/testcontainers/testcontainers-go/wait/file.go b/vendor/github.com/testcontainers/testcontainers-go/wait/file.go
index d9cab7a..4f6d38c 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/wait/file.go
+++ b/vendor/github.com/testcontainers/testcontainers-go/wait/file.go
@@ -6,7 +6,7 @@ import (
"io"
"time"
- "github.com/docker/docker/errdefs"
+ "github.com/containerd/errdefs"
)
var (
diff --git a/vendor/github.com/testcontainers/testcontainers-go/wait/host_port.go b/vendor/github.com/testcontainers/testcontainers-go/wait/host_port.go
index 2070bf1..8d97ccb 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/wait/host_port.go
+++ b/vendor/github.com/testcontainers/testcontainers-go/wait/host_port.go
@@ -6,7 +6,6 @@ import (
"fmt"
"net"
"os"
- "strconv"
"time"
"github.com/docker/go-connections/nat"
@@ -42,6 +41,11 @@ type HostPortStrategy struct {
// a shell is not available in the container or when the container doesn't bind
// the port internally until additional conditions are met.
skipInternalCheck bool
+
+ // skipExternalCheck is a flag to skip the external check, which, if used with
+ // skipInternalCheck, makes strategy waiting only for port mapping completion
+ // without accessing port.
+ skipExternalCheck bool
}
// NewHostPortStrategy constructs a default host port strategy that waits for the given
@@ -70,6 +74,12 @@ func ForExposedPort() *HostPortStrategy {
return NewHostPortStrategy("")
}
+// ForMappedPort returns a host port strategy that waits for the given port
+// to be mapped without accessing the port itself.
+func ForMappedPort(port nat.Port) *HostPortStrategy {
+ return NewHostPortStrategy(port).SkipInternalCheck().SkipExternalCheck()
+}
+
// SkipInternalCheck changes the host port strategy to skip the internal check,
// which is useful when a shell is not available in the container or when the
// container doesn't bind the port internally until additional conditions are met.
@@ -79,6 +89,15 @@ func (hp *HostPortStrategy) SkipInternalCheck() *HostPortStrategy {
return hp
}
+// SkipExternalCheck changes the host port strategy to skip the external check,
+// which, if used with SkipInternalCheck, makes strategy waiting only for port
+// mapping completion without accessing port.
+func (hp *HostPortStrategy) SkipExternalCheck() *HostPortStrategy {
+ hp.skipExternalCheck = true
+
+ return hp
+}
+
// WithStartupTimeout can be used to change the default startup timeout
func (hp *HostPortStrategy) WithStartupTimeout(startupTimeout time.Duration) *HostPortStrategy {
hp.timeout = &startupTimeout
@@ -95,6 +114,25 @@ func (hp *HostPortStrategy) Timeout() *time.Duration {
return hp.timeout
}
+// detectInternalPort returns the lowest internal port that is currently bound.
+// If no internal port is found, it returns the zero nat.Port value which
+// can be checked against an empty string.
+func (hp *HostPortStrategy) detectInternalPort(ctx context.Context, target StrategyTarget) (nat.Port, error) {
+ var internalPort nat.Port
+ inspect, err := target.Inspect(ctx)
+ if err != nil {
+ return internalPort, fmt.Errorf("inspect: %w", err)
+ }
+
+ for port := range inspect.NetworkSettings.Ports {
+ if internalPort == "" || port.Int() < internalPort.Int() {
+ internalPort = port
+ }
+ }
+
+ return internalPort, nil
+}
+
// WaitUntilReady implements Strategy.WaitUntilReady
func (hp *HostPortStrategy) WaitUntilReady(ctx context.Context, target StrategyTarget) error {
timeout := defaultStartupTimeout()
@@ -105,34 +143,37 @@ func (hp *HostPortStrategy) WaitUntilReady(ctx context.Context, target StrategyT
ctx, cancel := context.WithTimeout(ctx, timeout)
defer cancel()
- ipAddress, err := target.Host(ctx)
- if err != nil {
- return err
- }
-
waitInterval := hp.PollInterval
internalPort := hp.Port
+ i := 0
if internalPort == "" {
- inspect, err := target.Inspect(ctx)
+ var err error
+ // Port is not specified, so we need to detect it.
+ internalPort, err = hp.detectInternalPort(ctx, target)
if err != nil {
- return err
+ return fmt.Errorf("detect internal port: %w", err)
}
- for port := range inspect.NetworkSettings.Ports {
- if internalPort == "" || port.Int() < internalPort.Int() {
- internalPort = port
+ for internalPort == "" {
+ select {
+ case <-ctx.Done():
+ return fmt.Errorf("detect internal port: retries: %d, last err: %w, ctx err: %w", i, err, ctx.Err())
+ case <-time.After(waitInterval):
+ if err := checkTarget(ctx, target); err != nil {
+ return fmt.Errorf("detect internal port: check target: retries: %d, last err: %w", i, err)
+ }
+
+ internalPort, err = hp.detectInternalPort(ctx, target)
+ if err != nil {
+ return fmt.Errorf("detect internal port: %w", err)
+ }
}
}
}
- if internalPort == "" {
- return errors.New("no port to wait for")
- }
-
- var port nat.Port
- port, err = target.MappedPort(ctx, internalPort)
- i := 0
+ port, err := target.MappedPort(ctx, internalPort)
+ i = 0
for port == "" {
i++
@@ -142,7 +183,7 @@ func (hp *HostPortStrategy) WaitUntilReady(ctx context.Context, target StrategyT
return fmt.Errorf("mapped port: retries: %d, port: %q, last err: %w, ctx err: %w", i, port, err, ctx.Err())
case <-time.After(waitInterval):
if err := checkTarget(ctx, target); err != nil {
- return fmt.Errorf("check target: retries: %d, port: %q, last err: %w", i, port, err)
+ return fmt.Errorf("mapped port: check target: retries: %d, port: %q, last err: %w", i, port, err)
}
port, err = target.MappedPort(ctx, internalPort)
if err != nil {
@@ -151,8 +192,15 @@ func (hp *HostPortStrategy) WaitUntilReady(ctx context.Context, target StrategyT
}
}
- if err := externalCheck(ctx, ipAddress, port, target, waitInterval); err != nil {
- return fmt.Errorf("external check: %w", err)
+ if !hp.skipExternalCheck {
+ ipAddress, err := target.Host(ctx)
+ if err != nil {
+ return fmt.Errorf("host: %w", err)
+ }
+
+ if err := externalCheck(ctx, ipAddress, port, target, waitInterval); err != nil {
+ return fmt.Errorf("external check: %w", err)
+ }
}
if hp.skipInternalCheck {
@@ -177,11 +225,9 @@ func (hp *HostPortStrategy) WaitUntilReady(ctx context.Context, target StrategyT
func externalCheck(ctx context.Context, ipAddress string, port nat.Port, target StrategyTarget, waitInterval time.Duration) error {
proto := port.Proto()
- portNumber := port.Int()
- portString := strconv.Itoa(portNumber)
dialer := net.Dialer{}
- address := net.JoinHostPort(ipAddress, portString)
+ address := net.JoinHostPort(ipAddress, port.Port())
for i := 0; ; i++ {
if err := checkTarget(ctx, target); err != nil {
return fmt.Errorf("check target: retries: %d address: %s: %w", i, address, err)
diff --git a/vendor/github.com/testcontainers/testcontainers-go/wait/walk.go b/vendor/github.com/testcontainers/testcontainers-go/wait/walk.go
index 009e563..98f5755 100644
--- a/vendor/github.com/testcontainers/testcontainers-go/wait/walk.go
+++ b/vendor/github.com/testcontainers/testcontainers-go/wait/walk.go
@@ -2,6 +2,7 @@ package wait
import (
"errors"
+ "slices"
)
var (
@@ -63,7 +64,7 @@ func walk(root *Strategy, visit VisitFunc) error {
for range s.Strategies {
if err := walk(&s.Strategies[i], visit); err != nil {
if errors.Is(err, ErrVisitRemove) {
- s.Strategies = append(s.Strategies[:i], s.Strategies[i+1:]...)
+ s.Strategies = slices.Delete(s.Strategies, i, i+1)
if errors.Is(err, VisitStop) {
return VisitStop
}
diff --git a/vendor/github.com/xlgmokha/minit/LICENSE b/vendor/github.com/xlgmokha/minit/LICENSE
new file mode 100644
index 0000000..a9ea45c
--- /dev/null
+++ b/vendor/github.com/xlgmokha/minit/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 mo khan
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/xlgmokha/minit/README.md b/vendor/github.com/xlgmokha/minit/README.md
new file mode 100644
index 0000000..6fcc536
--- /dev/null
+++ b/vendor/github.com/xlgmokha/minit/README.md
@@ -0,0 +1,71 @@
+# minit
+
+A minimal Procfile-based process supervisor for Docker containers.
+
+## Features
+
+- **Zero dependencies**: Works in scratch containers without shells or external tools
+- **Procfile support**: Run multiple processes from a single configuration file
+- **Signal forwarding**: Graceful shutdown with SIGTERM propagation
+- **Process groups**: Uses `setpgid` for proper signal handling
+- **Clean logs**: Direct stdout/stderr streaming without buffering
+
+## Usage
+
+```bash
+# Run (reads Procfile from current directory)
+./minit
+```
+
+## Procfile Format
+
+```
+web: ./server -port 8080
+worker: ./worker -queue tasks
+redis: redis-server --port 6379
+scheduler: ./scheduler -interval 60s
+```
+
+## Installation
+
+```dockerfile
+FROM golang:alpine AS minit-builder
+RUN go install github.com/xlgmokha/minit@latest
+```
+
+## Docker Example
+Combine minit with [dumb-init](https://github.com/Yelp/dumb-init) for proper PID 1 signal handling:
+
+```dockerfile
+# syntax=docker/dockerfile:1
+
+# Build stage for minit
+FROM golang:alpine AS minit-builder
+RUN go install github.com/xlgmokha/minit@latest
+
+# Build stage for dumb-init
+FROM debian:bookworm-slim AS dumb-init-builder
+RUN apt-get update && apt-get install -y wget && \
+ wget -O /usr/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.5/dumb-init_1.2.5_x86_64 && \
+ chmod +x /usr/bin/dumb-init
+
+# Final stage
+FROM gcr.io/distroless/base-debian12:nonroot
+COPY --from=minit-builder /go/bin/minit /bin/minit
+COPY --from=dumb-init-builder /usr/bin/dumb-init /usr/bin/dumb-init
+COPY Procfile /Procfile
+COPY your-app /your-app
+
+ENTRYPOINT ["/usr/bin/dumb-init", "--"]
+CMD ["/bin/minit"]
+```
+
+### Why use dumb-init?
+- **PID 1 responsibilities**: Zombie reaping, proper signal handling
+- **Graceful shutdown**: Ensures all processes terminate cleanly
+- **Container compatibility**: Works with all container runtimes
+- **Security**: Runs as non-root user with distroless base
+
+## License
+
+MIT
diff --git a/vendor/github.com/xlgmokha/minit/main.go b/vendor/github.com/xlgmokha/minit/main.go
new file mode 100644
index 0000000..f155bc4
--- /dev/null
+++ b/vendor/github.com/xlgmokha/minit/main.go
@@ -0,0 +1,65 @@
+package main
+
+import (
+ "bufio"
+ "os"
+ "os/exec"
+ "os/signal"
+ "strings"
+ "sync"
+ "syscall"
+)
+
+func main() {
+ file, _ := os.Open("Procfile")
+ defer file.Close()
+
+ var cmds []*exec.Cmd
+ var wg sync.WaitGroup
+
+ scanner := bufio.NewScanner(file)
+ for scanner.Scan() {
+ line := strings.TrimSpace(scanner.Text())
+ if line == "" || strings.HasPrefix(line, "#") {
+ continue
+ }
+
+ parts := strings.SplitN(line, ":", 2)
+ if len(parts) != 2 {
+ continue
+ }
+
+ args := strings.Fields(strings.TrimSpace(parts[1]))
+ if len(args) == 0 {
+ continue
+ }
+
+ cmd := exec.Command(args[0], args[1:]...)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
+
+ cmds = append(cmds, cmd)
+
+ wg.Add(1)
+ go func(c *exec.Cmd) {
+ defer wg.Done()
+ c.Start()
+ c.Wait()
+ }(cmd)
+ }
+
+ sigChan := make(chan os.Signal, 1)
+ signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
+
+ go func() {
+ <-sigChan
+ for _, cmd := range cmds {
+ if cmd.Process != nil {
+ syscall.Kill(-cmd.Process.Pid, syscall.SIGTERM)
+ }
+ }
+ }()
+
+ wg.Wait()
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index c383d9c..ab36b4e 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -107,11 +107,8 @@ github.com/docker/docker/api/types/time
github.com/docker/docker/api/types/versions
github.com/docker/docker/api/types/volume
github.com/docker/docker/client
-github.com/docker/docker/errdefs
github.com/docker/docker/internal/lazyregexp
github.com/docker/docker/internal/multierror
-github.com/docker/docker/pkg/archive
-github.com/docker/docker/pkg/idtools
github.com/docker/docker/pkg/jsonmessage
github.com/docker/docker/pkg/stdcopy
# github.com/docker/go-connections v0.5.0
@@ -206,7 +203,7 @@ github.com/go-stack/stack
# github.com/gogo/protobuf v1.3.2
## explicit; go 1.15
github.com/gogo/protobuf/proto
-# github.com/golang-jwt/jwt/v5 v5.2.2
+# github.com/golang-jwt/jwt/v5 v5.2.3
## explicit; go 1.18
github.com/golang-jwt/jwt/v5
# github.com/golang/protobuf v1.5.4
@@ -299,8 +296,6 @@ github.com/moby/go-archive/tarheader
## explicit; go 1.19
github.com/moby/patternmatcher
github.com/moby/patternmatcher/ignorefile
-# github.com/moby/sys/atomicwriter v0.1.0
-## explicit; go 1.18
# github.com/moby/sys/sequential v0.6.0
## explicit; go 1.17
github.com/moby/sys/sequential
@@ -387,7 +382,7 @@ github.com/spiffe/go-spiffe/v2/spiffeid
github.com/stretchr/testify/assert
github.com/stretchr/testify/assert/yaml
github.com/stretchr/testify/require
-# github.com/testcontainers/testcontainers-go v0.37.0
+# github.com/testcontainers/testcontainers-go v0.38.0
## explicit; go 1.23.0
github.com/testcontainers/testcontainers-go
github.com/testcontainers/testcontainers-go/exec
@@ -408,6 +403,9 @@ github.com/tklauser/numcpus
github.com/twitchtv/twirp
github.com/twitchtv/twirp/ctxsetters
github.com/twitchtv/twirp/internal/contextkeys
+# github.com/xlgmokha/minit v0.0.0-20250704170309-a54b2e2e06f1
+## explicit; go 1.24
+github.com/xlgmokha/minit
# github.com/xlgmokha/x v0.0.0-20250523153843-ded39aa54bc5
## explicit; go 1.24
github.com/xlgmokha/x/pkg/context
@@ -522,7 +520,7 @@ golang.org/x/text/unicode/norm
google.golang.org/genproto/googleapis/api
google.golang.org/genproto/googleapis/api/annotations
google.golang.org/genproto/googleapis/api/expr/v1alpha1
-# google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7
+# google.golang.org/genproto/googleapis/rpc v0.0.0-20250721164621-a45f3dfb1074
## explicit; go 1.23.0
google.golang.org/genproto/googleapis/rpc/status
# google.golang.org/grpc v1.73.0