Merge pull request #25518 from Luap99/docker-v28

update docker to v28 and c/{common,image,storage} to main
This commit is contained in:
openshift-merge-bot[bot] 2025-03-11 17:44:26 +00:00 committed by GitHub
commit 5eeaa43728
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
315 changed files with 11579 additions and 4164 deletions

View File

@ -21,7 +21,7 @@ import (
"github.com/containers/podman/v5/pkg/specgen" "github.com/containers/podman/v5/pkg/specgen"
"github.com/containers/podman/v5/pkg/specgenutil" "github.com/containers/podman/v5/pkg/specgenutil"
"github.com/containers/podman/v5/pkg/util" "github.com/containers/podman/v5/pkg/util"
"github.com/docker/docker/pkg/parsers" "github.com/containers/storage/pkg/parsers"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

32
go.mod
View File

@ -14,10 +14,10 @@ require (
github.com/checkpoint-restore/go-criu/v7 v7.2.0 github.com/checkpoint-restore/go-criu/v7 v7.2.0
github.com/containernetworking/plugins v1.5.1 github.com/containernetworking/plugins v1.5.1
github.com/containers/buildah v1.39.2 github.com/containers/buildah v1.39.2
github.com/containers/common v0.62.1 github.com/containers/common v0.62.2-0.20250306142925-6e82793fd29d
github.com/containers/conmon v2.0.20+incompatible github.com/containers/conmon v2.0.20+incompatible
github.com/containers/gvisor-tap-vsock v0.8.4 github.com/containers/gvisor-tap-vsock v0.8.4
github.com/containers/image/v5 v5.34.1 github.com/containers/image/v5 v5.34.2-0.20250306154130-12497efe55ac
github.com/containers/libhvee v0.10.0 github.com/containers/libhvee v0.10.0
github.com/containers/ocicrypt v1.2.1 github.com/containers/ocicrypt v1.2.1
github.com/containers/psgo v1.9.0 github.com/containers/psgo v1.9.0
@ -29,7 +29,7 @@ require (
github.com/cyphar/filepath-securejoin v0.4.1 github.com/cyphar/filepath-securejoin v0.4.1
github.com/digitalocean/go-qemu v0.0.0-20250212194115-ee9b0668d242 github.com/digitalocean/go-qemu v0.0.0-20250212194115-ee9b0668d242
github.com/docker/distribution v2.8.3+incompatible github.com/docker/distribution v2.8.3+incompatible
github.com/docker/docker v27.5.1+incompatible github.com/docker/docker v28.0.1+incompatible
github.com/docker/go-connections v0.5.0 github.com/docker/go-connections v0.5.0
github.com/docker/go-plugins-helpers v0.0.0-20240701071450-45e2431495c8 github.com/docker/go-plugins-helpers v0.0.0-20240701071450-45e2431495c8
github.com/docker/go-units v0.5.0 github.com/docker/go-units v0.5.0
@ -98,7 +98,7 @@ require (
github.com/chzyer/readline v1.5.1 // indirect github.com/chzyer/readline v1.5.1 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect github.com/cloudwego/iasm v0.2.0 // indirect
github.com/containerd/cgroups/v3 v3.0.3 // indirect github.com/containerd/cgroups/v3 v3.0.5 // indirect
github.com/containerd/errdefs v1.0.0 // indirect github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect
github.com/containerd/log v0.1.0 // indirect github.com/containerd/log v0.1.0 // indirect
@ -110,12 +110,12 @@ require (
github.com/containers/luksy v0.0.0-20250106202729-a3a812db5b72 // indirect github.com/containers/luksy v0.0.0-20250106202729-a3a812db5b72 // indirect
github.com/coreos/go-oidc/v3 v3.12.0 // indirect github.com/coreos/go-oidc/v3 v3.12.0 // indirect
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect
github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f // indirect github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/digitalocean/go-libvirt v0.0.0-20220804181439-8648fbde413e // indirect github.com/digitalocean/go-libvirt v0.0.0-20220804181439-8648fbde413e // indirect
github.com/disiqueira/gotree/v3 v3.0.2 // indirect github.com/disiqueira/gotree/v3 v3.0.2 // indirect
github.com/distribution/reference v0.6.0 // indirect github.com/distribution/reference v0.6.0 // indirect
github.com/docker/docker-credential-helpers v0.8.2 // indirect github.com/docker/docker-credential-helpers v0.9.2 // indirect
github.com/ebitengine/purego v0.8.2 // indirect github.com/ebitengine/purego v0.8.2 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/fsnotify/fsnotify v1.8.0 // indirect
@ -195,9 +195,10 @@ require (
github.com/secure-systems-lab/go-securesystemslib v0.9.0 // indirect github.com/secure-systems-lab/go-securesystemslib v0.9.0 // indirect
github.com/segmentio/ksuid v1.0.4 // indirect github.com/segmentio/ksuid v1.0.4 // indirect
github.com/sigstore/fulcio v1.6.4 // indirect github.com/sigstore/fulcio v1.6.4 // indirect
github.com/sigstore/rekor v1.3.8 // indirect github.com/sigstore/protobuf-specs v0.4.0 // indirect
github.com/sigstore/sigstore v1.8.12 // indirect github.com/sigstore/rekor v1.3.9 // indirect
github.com/skeema/knownhosts v1.3.0 // indirect github.com/sigstore/sigstore v1.8.15 // indirect
github.com/skeema/knownhosts v1.3.1 // indirect
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
github.com/smallstep/pkcs7 v0.1.1 // indirect github.com/smallstep/pkcs7 v0.1.1 // indirect
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 // indirect github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 // indirect
@ -217,16 +218,17 @@ require (
go.mongodb.org/mongo-driver v1.14.0 // indirect go.mongodb.org/mongo-driver v1.14.0 // indirect
go.opencensus.io v0.24.0 // indirect go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect
go.opentelemetry.io/otel v1.31.0 // indirect go.opentelemetry.io/otel v1.32.0 // indirect
go.opentelemetry.io/otel/metric v1.31.0 // indirect go.opentelemetry.io/otel/metric v1.32.0 // indirect
go.opentelemetry.io/otel/trace v1.31.0 // indirect go.opentelemetry.io/otel/trace v1.32.0 // indirect
golang.org/x/arch v0.8.0 // indirect golang.org/x/arch v0.8.0 // indirect
golang.org/x/mod v0.22.0 // indirect golang.org/x/mod v0.22.0 // indirect
golang.org/x/oauth2 v0.25.0 // indirect golang.org/x/oauth2 v0.26.0 // indirect
golang.org/x/time v0.9.0 // indirect golang.org/x/time v0.9.0 // indirect
golang.org/x/tools v0.29.0 // indirect golang.org/x/tools v0.29.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect
google.golang.org/grpc v1.69.4 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
google.golang.org/grpc v1.70.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
tags.cncf.io/container-device-interface/specs-go v0.8.0 // indirect tags.cncf.io/container-device-interface/specs-go v0.8.0 // indirect

83
go.sum
View File

@ -58,8 +58,8 @@ github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJ
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0= github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo=
github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0= github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
@ -78,14 +78,14 @@ github.com/containernetworking/plugins v1.5.1 h1:T5ji+LPYjjgW0QM+KyrigZbLsZ8jaX+
github.com/containernetworking/plugins v1.5.1/go.mod h1:MIQfgMayGuHYs0XdNudf31cLLAC+i242hNm6KuDGqCM= github.com/containernetworking/plugins v1.5.1/go.mod h1:MIQfgMayGuHYs0XdNudf31cLLAC+i242hNm6KuDGqCM=
github.com/containers/buildah v1.39.2 h1:YaFMNnuTr7wKYKQDHkm7yyP9HhWVrNB4DA+DjYUS9k4= github.com/containers/buildah v1.39.2 h1:YaFMNnuTr7wKYKQDHkm7yyP9HhWVrNB4DA+DjYUS9k4=
github.com/containers/buildah v1.39.2/go.mod h1:Vb4sDbEq06qQqk29mcGw/1qit8dyukpfL4hwNQ5t+z8= github.com/containers/buildah v1.39.2/go.mod h1:Vb4sDbEq06qQqk29mcGw/1qit8dyukpfL4hwNQ5t+z8=
github.com/containers/common v0.62.1 h1:durvu7Kelb8PYgX7bwuAg/d5LKj2hs3cAaqcU7Vnqus= github.com/containers/common v0.62.2-0.20250306142925-6e82793fd29d h1:FTsiNAhuriMBXf6x5e9pFoc4W2mJxsnI0HUOBpPGB94=
github.com/containers/common v0.62.1/go.mod h1:n9cEboBmY3AnTk1alkq4t7sLM4plwkDCiaWbsf67YxE= github.com/containers/common v0.62.2-0.20250306142925-6e82793fd29d/go.mod h1:Dta+lCx83XAeGHtWwTPz+UwpWMiC0nMZQu4LWm1mTEg=
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg= github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I= github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/gvisor-tap-vsock v0.8.4 h1:z7MqcldnXYGaU6uTaKVl7RFxTmbhNsd2UL0CyM3fdBs= github.com/containers/gvisor-tap-vsock v0.8.4 h1:z7MqcldnXYGaU6uTaKVl7RFxTmbhNsd2UL0CyM3fdBs=
github.com/containers/gvisor-tap-vsock v0.8.4/go.mod h1:Guh8d/SiuJ9jlnuIyUjcKkFKQ2qpLhNKPGD1jMoIt2Q= github.com/containers/gvisor-tap-vsock v0.8.4/go.mod h1:Guh8d/SiuJ9jlnuIyUjcKkFKQ2qpLhNKPGD1jMoIt2Q=
github.com/containers/image/v5 v5.34.1 h1:/m2bkFnuedTyNkzma8s7cFLjeefPIb4trjyafWhIlwM= github.com/containers/image/v5 v5.34.2-0.20250306154130-12497efe55ac h1:6MRfoW2H0PBNfL5vsGeD2yCz/y7BoObc8a/drJLTRXE=
github.com/containers/image/v5 v5.34.1/go.mod h1:/WnvUSEfdqC/ahMRd4YJDBLrpYWkGl018rB77iB3FDo= github.com/containers/image/v5 v5.34.2-0.20250306154130-12497efe55ac/go.mod h1:Q0vC30+RLFCPdM9Nvm4eaFH5MvWZPkGFPEL1+EzzOHo=
github.com/containers/libhvee v0.10.0 h1:7VLv8keWZpHuGmWvyY4c1mVH5V1JYb1G78VC+8AlrM0= github.com/containers/libhvee v0.10.0 h1:7VLv8keWZpHuGmWvyY4c1mVH5V1JYb1G78VC+8AlrM0=
github.com/containers/libhvee v0.10.0/go.mod h1:at0h8lRcK5jCKfQgU/e6Io0Mw12F36zRLjXVOXRoDTM= github.com/containers/libhvee v0.10.0/go.mod h1:at0h8lRcK5jCKfQgU/e6Io0Mw12F36zRLjXVOXRoDTM=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
@ -113,8 +113,8 @@ github.com/crc-org/vfkit v0.6.0 h1:gUasCX2QqY9pUPebFhYsuINB8XSS/iz0qy4v18CUyB4=
github.com/crc-org/vfkit v0.6.0/go.mod h1:i+fGyDMg5MpuUYCFXc2VXw+5R7MBD6A/8xU9UxWv/9s= github.com/crc-org/vfkit v0.6.0/go.mod h1:i+fGyDMg5MpuUYCFXc2VXw+5R7MBD6A/8xU9UxWv/9s=
github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f h1:eHnXnuK47UlSTOQexbzxAZfekVz6i+LKRdj1CU5DPaM= github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 h1:uX1JmpONuD549D73r6cgnxyUu18Zb7yHAy5AYU0Pm4Q=
github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw=
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -129,14 +129,14 @@ github.com/disiqueira/gotree/v3 v3.0.2 h1:ik5iuLQQoufZBNPY518dXhiO5056hyNBIK9lWh
github.com/disiqueira/gotree/v3 v3.0.2/go.mod h1:ZuyjE4+mUQZlbpkI24AmruZKhg3VHEgPLDY8Qk+uUu8= github.com/disiqueira/gotree/v3 v3.0.2/go.mod h1:ZuyjE4+mUQZlbpkI24AmruZKhg3VHEgPLDY8Qk+uUu8=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/cli v27.5.1+incompatible h1:JB9cieUT9YNiMITtIsguaN55PLOHhBSz3LKVc6cqWaY= github.com/docker/cli v28.0.1+incompatible h1:g0h5NQNda3/CxIsaZfH4Tyf6vpxFth7PYl3hgCPOKzs=
github.com/docker/cli v27.5.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v28.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v27.5.1+incompatible h1:4PYU5dnBYqRQi0294d1FBECqT9ECWeQAIfE8q4YnPY8= github.com/docker/docker v28.0.1+incompatible h1:FCHjSRdXhNRFjlHMTv4jUNlIBbTeRjrWfeFuJp7jpo0=
github.com/docker/docker v27.5.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v28.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= github.com/docker/docker-credential-helpers v0.9.2 h1:50JF7ADQiHdAVBRtg/vy883Y4U5+5GmPOBNtUU+X+6A=
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/docker-credential-helpers v0.9.2/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
@ -439,8 +439,8 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/rootless-containers/rootlesskit/v2 v2.3.2 h1:QZk7sKU3+B8UHretEeIg6NSTTpj0o4iHGNhNbJBnHOU= github.com/rootless-containers/rootlesskit/v2 v2.3.2 h1:QZk7sKU3+B8UHretEeIg6NSTTpj0o4iHGNhNbJBnHOU=
github.com/rootless-containers/rootlesskit/v2 v2.3.2/go.mod h1:RL7YzL02nA2d8HAzt5d1nZnuiAeudQ4oym+HF/7sk7U= github.com/rootless-containers/rootlesskit/v2 v2.3.2/go.mod h1:RL7YzL02nA2d8HAzt5d1nZnuiAeudQ4oym+HF/7sk7U=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@ -458,14 +458,16 @@ github.com/shirou/gopsutil/v4 v4.25.2 h1:NMscG3l2CqtWFS86kj3vP7soOczqrQYIEhO/pMv
github.com/shirou/gopsutil/v4 v4.25.2/go.mod h1:34gBYJzyqCDT11b6bMHP0XCvWeU3J61XRT7a2EmCRTA= github.com/shirou/gopsutil/v4 v4.25.2/go.mod h1:34gBYJzyqCDT11b6bMHP0XCvWeU3J61XRT7a2EmCRTA=
github.com/sigstore/fulcio v1.6.4 h1:d86obfxUAG3Y6CYwOx1pdwCZwKmROB6w6927pKOVIRY= github.com/sigstore/fulcio v1.6.4 h1:d86obfxUAG3Y6CYwOx1pdwCZwKmROB6w6927pKOVIRY=
github.com/sigstore/fulcio v1.6.4/go.mod h1:Y6bn3i3KGhXpaHsAtYP3Z4Np0+VzCo1fLv8Ci6mbPDs= github.com/sigstore/fulcio v1.6.4/go.mod h1:Y6bn3i3KGhXpaHsAtYP3Z4Np0+VzCo1fLv8Ci6mbPDs=
github.com/sigstore/rekor v1.3.8 h1:B8kJI8mpSIXova4Jxa6vXdJyysRxFGsEsLKBDl0rRjA= github.com/sigstore/protobuf-specs v0.4.0 h1:yoZbdh0kZYKOSiVbYyA8J3f2wLh5aUk2SQB7LgAfIdU=
github.com/sigstore/rekor v1.3.8/go.mod h1:/dHFYKSuxEygfDRnEwyJ+ZD6qoVYNXQdi1mJrKvKWsI= github.com/sigstore/protobuf-specs v0.4.0/go.mod h1:FKW5NYhnnFQ/Vb9RKtQk91iYd0MKJ9AxyqInEwU6+OI=
github.com/sigstore/sigstore v1.8.12 h1:S8xMVZbE2z9ZBuQUEG737pxdLjnbOIcFi5v9UFfkJFc= github.com/sigstore/rekor v1.3.9 h1:sUjRpKVh/hhgqGMs0t+TubgYsksArZ6poLEC3MsGAzU=
github.com/sigstore/sigstore v1.8.12/go.mod h1:+PYQAa8rfw0QdPpBcT+Gl3egKD9c+TUgAlF12H3Nmjo= github.com/sigstore/rekor v1.3.9/go.mod h1:xThNUhm6eNEmkJ/SiU/FVU7pLY2f380fSDZFsdDWlcM=
github.com/sigstore/sigstore v1.8.15 h1:9HHnZmxjPQSTPXTCZc25HDxxSTWwsGMh/ZhWZZ39maU=
github.com/sigstore/sigstore v1.8.15/go.mod h1:+Wa5mrG6A+Gss516YC9owy10q3IazqIRe0y1EoQRHHM=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA=
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
github.com/smallstep/pkcs7 v0.1.1 h1:x+rPdt2W088V9Vkjho4KtoggyktZJlMduZAtRHm68LU= github.com/smallstep/pkcs7 v0.1.1 h1:x+rPdt2W088V9Vkjho4KtoggyktZJlMduZAtRHm68LU=
@ -552,20 +554,20 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM=
go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U=
go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 h1:lUsI2TYsQw2r1IASwoROaCnjdj2cvC2+Jbxvk6nHnWU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 h1:lUsI2TYsQw2r1IASwoROaCnjdj2cvC2+Jbxvk6nHnWU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0/go.mod h1:2HpZxxQurfGxJlJDblybejHB6RX6pmExPNe517hREw4= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0/go.mod h1:2HpZxxQurfGxJlJDblybejHB6RX6pmExPNe517hREw4=
go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M=
go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4=
go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU=
go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM=
go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8=
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
@ -620,8 +622,8 @@ golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE=
golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -718,18 +720,17 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk=
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q= google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q=
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08= google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw= google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4= google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A= google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -755,8 +756,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=

View File

@ -24,10 +24,10 @@ import (
"github.com/containers/podman/v5/pkg/ps" "github.com/containers/podman/v5/pkg/ps"
"github.com/containers/podman/v5/pkg/signal" "github.com/containers/podman/v5/pkg/signal"
"github.com/containers/podman/v5/pkg/util" "github.com/containers/podman/v5/pkg/util"
"github.com/docker/docker/api/types"
dockerBackend "github.com/docker/docker/api/types/backend" dockerBackend "github.com/docker/docker/api/types/backend"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/storage"
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
"github.com/docker/go-units" "github.com/docker/go-units"
spec "github.com/opencontainers/runtime-spec/specs-go" spec "github.com/opencontainers/runtime-spec/specs-go"
@ -347,9 +347,9 @@ func LibpodToContainer(l *libpod.Container, sz bool) (*handlers.Container, error
return nil, err return nil, err
} }
ports := make([]types.Port, len(portMappings)) ports := make([]container.Port, len(portMappings))
for idx, portMapping := range portMappings { for idx, portMapping := range portMappings {
ports[idx] = types.Port{ ports[idx] = container.Port{
IP: portMapping.HostIP, IP: portMapping.HostIP,
PrivatePort: portMapping.ContainerPort, PrivatePort: portMapping.ContainerPort,
PublicPort: portMapping.HostPort, PublicPort: portMapping.HostPort,
@ -365,7 +365,7 @@ func LibpodToContainer(l *libpod.Container, sz bool) (*handlers.Container, error
if err != nil { if err != nil {
return nil, err return nil, err
} }
networkSettings := types.SummaryNetworkSettings{} networkSettings := container.NetworkSettingsSummary{}
if err := json.Unmarshal(n, &networkSettings); err != nil { if err := json.Unmarshal(n, &networkSettings); err != nil {
return nil, err return nil, err
} }
@ -374,13 +374,13 @@ func LibpodToContainer(l *libpod.Container, sz bool) (*handlers.Container, error
if err != nil { if err != nil {
return nil, err return nil, err
} }
mounts := []types.MountPoint{} mounts := []container.MountPoint{}
if err := json.Unmarshal(m, &mounts); err != nil { if err := json.Unmarshal(m, &mounts); err != nil {
return nil, err return nil, err
} }
return &handlers.Container{ return &handlers.Container{
Container: types.Container{ Container: container.Summary{
ID: l.ID(), ID: l.ID(),
Names: []string{fmt.Sprintf("/%s", l.Name())}, Names: []string{fmt.Sprintf("/%s", l.Name())},
Image: imageName, Image: imageName,
@ -408,7 +408,7 @@ func LibpodToContainer(l *libpod.Container, sz bool) (*handlers.Container, error
}, nil }, nil
} }
func convertSecondaryIPPrefixLen(input *define.InspectNetworkSettings, output *types.NetworkSettings) { func convertSecondaryIPPrefixLen(input *define.InspectNetworkSettings, output *container.NetworkSettings) {
for index, ip := range input.SecondaryIPAddresses { for index, ip := range input.SecondaryIPAddresses {
output.SecondaryIPAddresses[index].PrefixLen = ip.PrefixLength output.SecondaryIPAddresses[index].PrefixLen = ip.PrefixLength
} }
@ -417,7 +417,7 @@ func convertSecondaryIPPrefixLen(input *define.InspectNetworkSettings, output *t
} }
} }
func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON, error) { func LibpodToContainerJSON(l *libpod.Container, sz bool) (*container.InspectResponse, error) {
imageID, imageName := l.Image() imageID, imageName := l.Image()
inspect, err := l.Inspect(sz) inspect, err := l.Inspect(sz)
if err != nil { if err != nil {
@ -432,7 +432,7 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON,
if err != nil { if err != nil {
return nil, err return nil, err
} }
state := types.ContainerState{} state := container.State{}
if err := json.Unmarshal(i, &state); err != nil { if err := json.Unmarshal(i, &state); err != nil {
return nil, err return nil, err
} }
@ -448,14 +448,14 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON,
} }
if l.HasHealthCheck() && state.Status != "created" { if l.HasHealthCheck() && state.Status != "created" {
state.Health = &types.Health{} state.Health = &container.Health{}
if inspect.State.Health != nil { if inspect.State.Health != nil {
state.Health.Status = inspect.State.Health.Status state.Health.Status = inspect.State.Health.Status
state.Health.FailingStreak = inspect.State.Health.FailingStreak state.Health.FailingStreak = inspect.State.Health.FailingStreak
log := inspect.State.Health.Log log := inspect.State.Health.Log
for _, item := range log { for _, item := range log {
res := &types.HealthcheckResult{} res := &container.HealthcheckResult{}
s, err := time.Parse(time.RFC3339Nano, item.Start) s, err := time.Parse(time.RFC3339Nano, item.Start)
if err != nil { if err != nil {
return nil, err return nil, err
@ -490,16 +490,13 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON,
if hc.LogConfig.Type == define.KubernetesLogging { if hc.LogConfig.Type == define.KubernetesLogging {
hc.LogConfig.Type = define.JSONLogging hc.LogConfig.Type = define.JSONLogging
} }
g, err := json.Marshal(inspect.GraphDriver)
if err != nil { graphDriver := storage.DriverData{
return nil, err Name: inspect.GraphDriver.Name,
} Data: inspect.GraphDriver.Data,
graphDriver := types.GraphDriverData{}
if err := json.Unmarshal(g, &graphDriver); err != nil {
return nil, err
} }
cb := types.ContainerJSONBase{ cb := container.ContainerJSONBase{
ID: l.ID(), ID: l.ID(),
Created: l.CreatedTime().UTC().Format(time.RFC3339Nano), // Docker uses UTC Created: l.CreatedTime().UTC().Format(time.RFC3339Nano), // Docker uses UTC
Path: inspect.Path, Path: inspect.Path,
@ -510,7 +507,6 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON,
HostnamePath: inspect.HostnamePath, HostnamePath: inspect.HostnamePath,
HostsPath: inspect.HostsPath, HostsPath: inspect.HostsPath,
LogPath: l.LogPath(), LogPath: l.LogPath(),
Node: nil,
Name: fmt.Sprintf("/%s", l.Name()), Name: fmt.Sprintf("/%s", l.Name()),
RestartCount: int(inspect.RestartCount), RestartCount: int(inspect.RestartCount),
Driver: inspect.Driver, Driver: inspect.Driver,
@ -588,7 +584,7 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON,
if err != nil { if err != nil {
return nil, err return nil, err
} }
mounts := []types.MountPoint{} mounts := []container.MountPoint{}
if err := json.Unmarshal(m, &mounts); err != nil { if err := json.Unmarshal(m, &mounts); err != nil {
return nil, err return nil, err
} }
@ -607,7 +603,7 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON,
return nil, err return nil, err
} }
networkSettings := types.NetworkSettings{} networkSettings := container.NetworkSettings{}
if err := json.Unmarshal(n, &networkSettings); err != nil { if err := json.Unmarshal(n, &networkSettings); err != nil {
return nil, err return nil, err
} }
@ -619,7 +615,7 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON,
networkSettings.Networks = map[string]*network.EndpointSettings{} networkSettings.Networks = map[string]*network.EndpointSettings{}
} }
c := types.ContainerJSON{ c := container.InspectResponse{
ContainerJSONBase: &cb, ContainerJSONBase: &cb,
Mounts: mounts, Mounts: mounts,
Config: &config, Config: &config,
@ -791,6 +787,6 @@ func UpdateContainer(w http.ResponseWriter, r *http.Request) {
return return
} }
responseStruct := container.ContainerUpdateOKBody{} responseStruct := container.UpdateResponse{}
utils.WriteResponse(w, http.StatusOK, responseStruct) utils.WriteResponse(w, http.StatusOK, responseStruct)
} }

View File

@ -25,9 +25,9 @@ import (
"github.com/containers/podman/v5/pkg/domain/infra/abi" "github.com/containers/podman/v5/pkg/domain/infra/abi"
"github.com/containers/podman/v5/pkg/util" "github.com/containers/podman/v5/pkg/util"
"github.com/containers/storage" "github.com/containers/storage"
docker "github.com/docker/docker/api/types"
dockerContainer "github.com/docker/docker/api/types/container" dockerContainer "github.com/docker/docker/api/types/container"
dockerImage "github.com/docker/docker/api/types/image" dockerImage "github.com/docker/docker/api/types/image"
dockerStorage "github.com/docker/docker/api/types/storage"
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
"github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -371,7 +371,7 @@ func imageDataToImageInspect(ctx context.Context, l *libimage.Image) (*handlers.
StopSignal: info.Config.StopSignal, StopSignal: info.Config.StopSignal,
} }
rootfs := docker.RootFS{} rootfs := dockerImage.RootFS{}
if info.RootFS != nil { if info.RootFS != nil {
rootfs.Type = info.RootFS.Type rootfs.Type = info.RootFS.Type
rootfs.Layers = make([]string, 0, len(info.RootFS.Layers)) rootfs.Layers = make([]string, 0, len(info.RootFS.Layers))
@ -380,7 +380,7 @@ func imageDataToImageInspect(ctx context.Context, l *libimage.Image) (*handlers.
} }
} }
graphDriver := docker.GraphDriverData{ graphDriver := dockerStorage.DriverData{
Name: info.GraphDriver.Name, Name: info.GraphDriver.Name,
Data: info.GraphDriver.Data, Data: info.GraphDriver.Data,
} }
@ -389,7 +389,7 @@ func imageDataToImageInspect(ctx context.Context, l *libimage.Image) (*handlers.
cc.Hostname = info.ID[0:11] // short ID is the hostname cc.Hostname = info.ID[0:11] // short ID is the hostname
cc.Volumes = info.Config.Volumes cc.Volumes = info.Config.Volumes
dockerImageInspect := docker.ImageInspect{ dockerImageInspect := dockerImage.InspectResponse{
Architecture: info.Architecture, Architecture: info.Architecture,
Author: info.Author, Author: info.Author,
Comment: info.Comment, Comment: info.Comment,
@ -410,7 +410,7 @@ func imageDataToImageInspect(ctx context.Context, l *libimage.Image) (*handlers.
Variant: "", Variant: "",
VirtualSize: info.VirtualSize, VirtualSize: info.VirtualSize,
} }
return &handlers.ImageInspect{ImageInspect: dockerImageInspect}, nil return &handlers.ImageInspect{InspectResponse: dockerImageInspect}, nil
} }
// portsToPortSet converts libpod's exposed ports to docker's structs // portsToPortSet converts libpod's exposed ports to docker's structs

View File

@ -66,7 +66,7 @@ func PruneImages(w http.ResponseWriter, r *http.Request) {
} }
payload := handlers.ImagesPruneReport{ payload := handlers.ImagesPruneReport{
ImagesPruneReport: dockerImage.PruneReport{ PruneReport: dockerImage.PruneReport{
ImagesDeleted: idr, ImagesDeleted: idr,
SpaceReclaimed: reclaimedSpace, SpaceReclaimed: reclaimedSpace,
}, },

View File

@ -165,6 +165,7 @@ loop: // break out of for/select infinite loop
Current: int64(e.Offset), Current: int64(e.Offset),
Total: e.Artifact.Size, Total: e.Artifact.Size,
} }
//nolint:staticcheck // Deprecated field, but because consumers might still read it keep it.
report.ProgressMessage = report.Progress.String() report.ProgressMessage = report.Progress.String()
case types.ProgressEventSkipped: case types.ProgressEventSkipped:
report.Status = "Layer already exists" report.Status = "Layer already exists"
@ -190,6 +191,7 @@ loop: // break out of for/select infinite loop
report.Error = &jsonmessage.JSONError{ report.Error = &jsonmessage.JSONError{
Message: msg, Message: msg,
} }
//nolint:staticcheck // Deprecated field, but because consumers might still read it keep it.
report.ErrorMessage = msg report.ErrorMessage = msg
if err := enc.Encode(report); err != nil { if err := enc.Encode(report); err != nil {
logrus.Warnf("Failed to json encode error %q", err.Error()) logrus.Warnf("Failed to json encode error %q", err.Error())

View File

@ -13,6 +13,7 @@ import (
"github.com/containers/podman/v5/pkg/domain/entities" "github.com/containers/podman/v5/pkg/domain/entities"
"github.com/containers/podman/v5/pkg/domain/infra/abi" "github.com/containers/podman/v5/pkg/domain/infra/abi"
docker "github.com/docker/docker/api/types" docker "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
dockerImage "github.com/docker/docker/api/types/image" dockerImage "github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/volume" "github.com/docker/docker/api/types/volume"
) )
@ -44,9 +45,9 @@ func GetDiskUsage(w http.ResponseWriter, r *http.Request) {
imgs[i] = &t imgs[i] = &t
} }
ctnrs := make([]*docker.Container, len(df.Containers)) ctnrs := make([]*container.Summary, len(df.Containers))
for i, o := range df.Containers { for i, o := range df.Containers {
t := docker.Container{ t := container.Summary{
ID: o.ContainerID, ID: o.ContainerID,
Names: []string{o.Names}, Names: []string{o.Names},
Image: o.Image, Image: o.Image,

View File

@ -311,7 +311,7 @@ func PruneVolumes(w http.ResponseWriter, r *http.Request) {
} }
payload := handlers.VolumesPruneReport{ payload := handlers.VolumesPruneReport{
VolumesPruneReport: volume.PruneReport{ PruneReport: volume.PruneReport{
VolumesDeleted: prunedIds, VolumesDeleted: prunedIds,
SpaceReclaimed: reclaimedSpace, SpaceReclaimed: reclaimedSpace,
}, },

View File

@ -11,7 +11,7 @@ import (
"github.com/containers/podman/v5/pkg/domain/entities" "github.com/containers/podman/v5/pkg/domain/entities"
"github.com/containers/podman/v5/pkg/domain/entities/reports" "github.com/containers/podman/v5/pkg/domain/entities/reports"
"github.com/containers/podman/v5/pkg/inspect" "github.com/containers/podman/v5/pkg/inspect"
dockerAPI "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container"
dockerImage "github.com/docker/docker/api/types/image" dockerImage "github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/volume" "github.com/docker/docker/api/types/volume"
@ -125,7 +125,7 @@ type inspectImageResponseLibpod struct {
// swagger:response // swagger:response
type containerInspectResponse struct { type containerInspectResponse struct {
// in:body // in:body
Body dockerAPI.ContainerJSON Body container.InspectResponse
} }
// List processes in container // List processes in container

View File

@ -6,9 +6,11 @@ import (
docker "github.com/docker/docker/api/types" docker "github.com/docker/docker/api/types"
dockerBackend "github.com/docker/docker/api/types/backend" dockerBackend "github.com/docker/docker/api/types/backend"
dockerContainer "github.com/docker/docker/api/types/container" dockerContainer "github.com/docker/docker/api/types/container"
dockerImage "github.com/docker/docker/api/types/image"
dockerNetwork "github.com/docker/docker/api/types/network" dockerNetwork "github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/system" "github.com/docker/docker/api/types/system"
"github.com/docker/docker/api/types/volume"
"github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-spec/specs-go"
) )
@ -17,7 +19,7 @@ type AuthConfig struct {
} }
type ImageInspect struct { type ImageInspect struct {
docker.ImageInspect dockerImage.InspectResponse
// Container is for backwards compat but is basically unused // Container is for backwards compat but is basically unused
Container string Container string
} }
@ -45,7 +47,7 @@ type LibpodImagesResolveReport struct {
} }
type ContainersPruneReport struct { type ContainersPruneReport struct {
docker.ContainersPruneReport dockerContainer.PruneReport
} }
type ContainersPruneReportLibpod struct { type ContainersPruneReportLibpod struct {
@ -101,11 +103,11 @@ type DiskUsage struct {
} }
type VolumesPruneReport struct { type VolumesPruneReport struct {
docker.VolumesPruneReport volume.PruneReport
} }
type ImagesPruneReport struct { type ImagesPruneReport struct {
docker.ImagesPruneReport dockerImage.PruneReport
} }
type BuildCachePruneReport struct { type BuildCachePruneReport struct {
@ -113,7 +115,7 @@ type BuildCachePruneReport struct {
} }
type NetworkPruneReport struct { type NetworkPruneReport struct {
docker.NetworksPruneReport dockerNetwork.PruneReport
} }
type ConfigCreateResponse struct { type ConfigCreateResponse struct {
@ -166,7 +168,7 @@ type HistoryResponse struct {
} }
type ExecCreateConfig struct { type ExecCreateConfig struct {
docker.ExecConfig dockerContainer.ExecOptions
} }
type ExecStartConfig struct { type ExecStartConfig struct {

View File

@ -169,6 +169,7 @@ loop: // break out of for/select infinite loop
report.Status = "Downloading" report.Status = "Downloading"
report.Progress.Current = int64(e.Offset) report.Progress.Current = int64(e.Offset)
report.Progress.Total = e.Artifact.Size report.Progress.Total = e.Artifact.Size
//nolint:staticcheck // Deprecated field, but because consumers might still read it keep it.
report.ProgressMessage = report.Progress.String() report.ProgressMessage = report.Progress.String()
case types.ProgressEventSkipped: case types.ProgressEventSkipped:
report.Status = "Already exists" report.Status = "Already exists"
@ -193,6 +194,7 @@ loop: // break out of for/select infinite loop
report.Error = &jsonmessage.JSONError{ report.Error = &jsonmessage.JSONError{
Message: msg, Message: msg,
} }
//nolint:staticcheck // Deprecated field, but because consumers might still read it keep it.
report.ErrorMessage = msg report.ErrorMessage = msg
} else { } else {
pulledImages := pullRes.images pulledImages := pullRes.images
@ -205,6 +207,7 @@ loop: // break out of for/select infinite loop
report.Error = &jsonmessage.JSONError{ report.Error = &jsonmessage.JSONError{
Message: msg, Message: msg,
} }
//nolint:staticcheck // Deprecated field, but because consumers might still read it keep it.
report.ErrorMessage = msg report.ErrorMessage = msg
writeStatusCode(http.StatusInternalServerError) writeStatusCode(http.StatusInternalServerError)
} }

View File

@ -11,26 +11,26 @@ import (
"github.com/containers/podman/v5/pkg/bindings" "github.com/containers/podman/v5/pkg/bindings"
"github.com/containers/podman/v5/pkg/bindings/images" "github.com/containers/podman/v5/pkg/bindings/images"
"github.com/containers/podman/v5/pkg/domain/entities/types"
"github.com/containers/storage/pkg/regexp" "github.com/containers/storage/pkg/regexp"
dockerAPI "github.com/docker/docker/api/types"
) )
var iidRegex = regexp.Delayed(`^[0-9a-f]{12}`) var iidRegex = regexp.Delayed(`^[0-9a-f]{12}`)
// Commit creates a container image from a container. The container is defined by nameOrID. Use // Commit creates a container image from a container. The container is defined by nameOrID. Use
// the CommitOptions for finer grain control on characteristics of the resulting image. // the CommitOptions for finer grain control on characteristics of the resulting image.
func Commit(ctx context.Context, nameOrID string, options *CommitOptions) (dockerAPI.IDResponse, error) { func Commit(ctx context.Context, nameOrID string, options *CommitOptions) (types.IDResponse, error) {
if options == nil { if options == nil {
options = new(CommitOptions) options = new(CommitOptions)
} }
id := dockerAPI.IDResponse{} id := types.IDResponse{}
conn, err := bindings.GetClient(ctx) conn, err := bindings.GetClient(ctx)
if err != nil { if err != nil {
return id, err return id, err
} }
params, err := options.ToParams() params, err := options.ToParams()
if err != nil { if err != nil {
return dockerAPI.IDResponse{}, err return types.IDResponse{}, err
} }
params.Set("container", nameOrID) params.Set("container", nameOrID)
var requestBody io.Reader var requestBody io.Reader

View File

@ -11,7 +11,7 @@ import (
"github.com/containers/podman/v5/libpod/define" "github.com/containers/podman/v5/libpod/define"
"github.com/containers/podman/v5/pkg/api/handlers" "github.com/containers/podman/v5/pkg/api/handlers"
"github.com/containers/podman/v5/pkg/bindings" "github.com/containers/podman/v5/pkg/bindings"
dockerAPI "github.com/docker/docker/api/types" "github.com/containers/podman/v5/pkg/domain/entities/types"
jsoniter "github.com/json-iterator/go" jsoniter "github.com/json-iterator/go"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -43,7 +43,7 @@ func ExecCreate(ctx context.Context, nameOrID string, config *handlers.ExecCreat
} }
defer resp.Body.Close() defer resp.Body.Close()
respStruct := new(dockerAPI.IDResponse) respStruct := new(types.IDResponse)
if err := resp.Process(respStruct); err != nil { if err := resp.Process(respStruct); err != nil {
return "", err return "", err
} }

View File

@ -24,7 +24,6 @@ import (
"github.com/containers/podman/v5/pkg/bindings/images" "github.com/containers/podman/v5/pkg/bindings/images"
entitiesTypes "github.com/containers/podman/v5/pkg/domain/entities/types" entitiesTypes "github.com/containers/podman/v5/pkg/domain/entities/types"
"github.com/containers/podman/v5/pkg/errorhandling" "github.com/containers/podman/v5/pkg/errorhandling"
dockerAPI "github.com/docker/docker/api/types"
jsoniter "github.com/json-iterator/go" jsoniter "github.com/json-iterator/go"
) )
@ -33,7 +32,7 @@ import (
// of a list if the name provided is a manifest list. The ID of the new manifest list // of a list if the name provided is a manifest list. The ID of the new manifest list
// is returned as a string. // is returned as a string.
func Create(ctx context.Context, name string, images []string, options *CreateOptions) (string, error) { func Create(ctx context.Context, name string, images []string, options *CreateOptions) (string, error) {
var idr dockerAPI.IDResponse var idr entitiesTypes.IDResponse
if options == nil { if options == nil {
options = new(CreateOptions) options = new(CreateOptions)
} }

View File

@ -9,7 +9,6 @@ import (
entitiesTypes "github.com/containers/podman/v5/pkg/domain/entities/types" entitiesTypes "github.com/containers/podman/v5/pkg/domain/entities/types"
"github.com/containers/podman/v5/pkg/specgen" "github.com/containers/podman/v5/pkg/specgen"
"github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/archive"
dockerAPI "github.com/docker/docker/api/types"
) )
type Container struct { type Container struct {
@ -117,5 +116,4 @@ type IDOrNameResponse struct {
IDOrName string IDOrName string
} }
// swagger:model type IDResponse = entitiesTypes.IDResponse
type IDResponse dockerAPI.IDResponse

View File

@ -77,3 +77,11 @@ type BuildReport struct {
// Format to save the image in // Format to save the image in
SaveFormat string SaveFormat string
} }
// swagger:model
type IDResponse struct {
// The id of the newly created object.
// Required: true
ID string `json:"Id"`
}

View File

@ -1,10 +1,10 @@
package internal package internal
import ( import (
"maps"
"slices" "slices"
v1 "github.com/opencontainers/image-spec/specs-go/v1" v1 "github.com/opencontainers/image-spec/specs-go/v1"
"golang.org/x/exp/maps"
) )
// DeepCopyDescriptor copies a Descriptor, deeply copying its contents // DeepCopyDescriptor copies a Descriptor, deeply copying its contents

View File

@ -14,6 +14,7 @@ import (
"github.com/containerd/platforms" "github.com/containerd/platforms"
"github.com/containers/common/libimage/platform" "github.com/containers/common/libimage/platform"
"github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/image"
"github.com/containers/image/v5/manifest" "github.com/containers/image/v5/manifest"
storageTransport "github.com/containers/image/v5/storage" storageTransport "github.com/containers/image/v5/storage"
"github.com/containers/image/v5/types" "github.com/containers/image/v5/types"
@ -1002,7 +1003,7 @@ func (i *Image) Manifest(ctx context.Context) (rawManifest []byte, mimeType stri
if err != nil { if err != nil {
return nil, "", err return nil, "", err
} }
return src.GetManifest(ctx, nil) return image.UnparsedInstance(src, nil).Manifest(ctx)
} }
// getImageID creates an image object and uses the hex value of the config // getImageID creates an image object and uses the hex value of the config

View File

@ -6,6 +6,7 @@ import (
"context" "context"
"time" "time"
"github.com/containers/image/v5/image"
"github.com/containers/image/v5/manifest" "github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/types" "github.com/containers/image/v5/types"
"github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
@ -159,7 +160,7 @@ func (i *Image) Inspect(ctx context.Context, options *InspectOptions) (*ImageDat
if err != nil { if err != nil {
return nil, err return nil, err
} }
manifestRaw, manifestType, err := src.GetManifest(ctx, nil) manifestRaw, manifestType, err := image.UnparsedInstance(src, nil).Manifest(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -18,6 +18,7 @@ import (
"github.com/containers/common/pkg/supplemented" "github.com/containers/common/pkg/supplemented"
imageCopy "github.com/containers/image/v5/copy" imageCopy "github.com/containers/image/v5/copy"
"github.com/containers/image/v5/docker" "github.com/containers/image/v5/docker"
"github.com/containers/image/v5/image"
"github.com/containers/image/v5/manifest" "github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/oci/layout" "github.com/containers/image/v5/oci/layout"
"github.com/containers/image/v5/signature" "github.com/containers/image/v5/signature"
@ -370,11 +371,12 @@ func (i *Image) IsManifestList(ctx context.Context) (bool, error) {
if err != nil { if err != nil {
return false, err return false, err
} }
imgRef, err := ref.NewImageSource(ctx, i.runtime.systemContextCopy()) imgSrc, err := ref.NewImageSource(ctx, i.runtime.systemContextCopy())
if err != nil { if err != nil {
return false, err return false, err
} }
_, manifestType, err := imgRef.GetManifest(ctx, nil) defer imgSrc.Close()
_, manifestType, err := image.UnparsedInstance(imgSrc, nil).Manifest(ctx)
if err != nil { if err != nil {
return false, err return false, err
} }
@ -717,7 +719,7 @@ func (m *ManifestList) AnnotateInstance(d digest.Digest, options *ManifestListAn
return err return err
} }
defer src.Close() defer src.Close()
subjectManifestBytes, subjectManifestType, err := src.GetManifest(ctx, nil) subjectManifestBytes, subjectManifestType, err := image.UnparsedInstance(src, nil).Manifest(ctx)
if err != nil { if err != nil {
return err return err
} }

View File

@ -526,7 +526,7 @@ func (l *list) Add(ctx context.Context, sys *types.SystemContext, ref types.Imag
var instanceInfos []instanceInfo var instanceInfos []instanceInfo
var manifestDigest digest.Digest var manifestDigest digest.Digest
primaryManifestBytes, primaryManifestType, err := src.GetManifest(ctx, nil) primaryManifestBytes, primaryManifestType, err := image.UnparsedInstance(src, nil).Manifest(ctx)
if err != nil { if err != nil {
return "", fmt.Errorf("reading manifest from %q: %w", transports.ImageName(ref), err) return "", fmt.Errorf("reading manifest from %q: %w", transports.ImageName(ref), err)
} }
@ -613,7 +613,8 @@ func (l *list) Add(ctx context.Context, sys *types.SystemContext, ref types.Imag
knownConfigTypes := []string{manifest.DockerV2Schema2ConfigMediaType, v1.MediaTypeImageConfig} knownConfigTypes := []string{manifest.DockerV2Schema2ConfigMediaType, v1.MediaTypeImageConfig}
for _, instanceInfo := range instanceInfos { for _, instanceInfo := range instanceInfos {
manifestBytes, manifestType, err := src.GetManifest(ctx, instanceInfo.instanceDigest) unparsedInstance := image.UnparsedInstance(src, instanceInfo.instanceDigest)
manifestBytes, manifestType, err := unparsedInstance.Manifest(ctx)
if err != nil { if err != nil {
return "", fmt.Errorf("reading manifest from %q, instance %q: %w", transports.ImageName(ref), instanceInfo.instanceDigest, err) return "", fmt.Errorf("reading manifest from %q, instance %q: %w", transports.ImageName(ref), instanceInfo.instanceDigest, err)
} }
@ -625,7 +626,7 @@ func (l *list) Add(ctx context.Context, sys *types.SystemContext, ref types.Imag
hasPlatformConfig := instanceInfo.ArtifactType == "" && slices.Contains(knownConfigTypes, instanceInfo.ConfigInfo.MediaType) hasPlatformConfig := instanceInfo.ArtifactType == "" && slices.Contains(knownConfigTypes, instanceInfo.ConfigInfo.MediaType)
needToParsePlatformConfig := (instanceInfo.OS == "" || instanceInfo.Architecture == "") needToParsePlatformConfig := (instanceInfo.OS == "" || instanceInfo.Architecture == "")
if hasPlatformConfig && needToParsePlatformConfig { if hasPlatformConfig && needToParsePlatformConfig {
img, err := image.FromUnparsedImage(ctx, sys, image.UnparsedInstance(src, instanceInfo.instanceDigest)) img, err := image.FromUnparsedImage(ctx, sys, unparsedInstance)
if err != nil { if err != nil {
return "", fmt.Errorf("reading configuration blob from %q: %w", transports.ImageName(ref), err) return "", fmt.Errorf("reading configuration blob from %q: %w", transports.ImageName(ref), err)
} }
@ -712,12 +713,12 @@ func (l *list) AddArtifact(ctx context.Context, sys *types.SystemContext, option
// reason. // reason.
var subject *v1.Descriptor var subject *v1.Descriptor
if options.SubjectReference != nil { if options.SubjectReference != nil {
subjectReference, err := options.SubjectReference.NewImageSource(ctx, sys) subjectSource, err := options.SubjectReference.NewImageSource(ctx, sys)
if err != nil { if err != nil {
return "", fmt.Errorf("setting up to read manifest and configuration from subject %q: %w", transports.ImageName(options.SubjectReference), err) return "", fmt.Errorf("setting up to read manifest and configuration from subject %q: %w", transports.ImageName(options.SubjectReference), err)
} }
defer subjectReference.Close() defer subjectSource.Close()
subjectManifestBytes, subjectManifestType, err := subjectReference.GetManifest(ctx, nil) subjectManifestBytes, subjectManifestType, err := image.UnparsedInstance(subjectSource, nil).Manifest(ctx)
if err != nil { if err != nil {
return "", fmt.Errorf("reading manifest from subject %q: %w", transports.ImageName(options.SubjectReference), err) return "", fmt.Errorf("reading manifest from subject %q: %w", transports.ImageName(options.SubjectReference), err)
} }

View File

@ -26,7 +26,7 @@ func (n *netavarkNetwork) execUpdate(networkName string, networkDNSServers []str
// Setup will setup the container network namespace. It returns // Setup will setup the container network namespace. It returns
// a map of StatusBlocks, the key is the network name. // a map of StatusBlocks, the key is the network name.
func (n *netavarkNetwork) Setup(namespacePath string, options types.SetupOptions) (map[string]types.StatusBlock, error) { func (n *netavarkNetwork) Setup(namespacePath string, options types.SetupOptions) (_ map[string]types.StatusBlock, retErr error) {
n.lock.Lock() n.lock.Lock()
defer n.lock.Unlock() defer n.lock.Unlock()
err := n.loadNetworks() err := n.loadNetworks()
@ -44,6 +44,15 @@ func (n *netavarkNetwork) Setup(namespacePath string, options types.SetupOptions
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer func() {
// In case the setup failed for whatever reason podman will not start the
// container so we must free the allocated ips again to not leak them.
if retErr != nil {
if err := n.deallocIPs(&options.NetworkOptions); err != nil {
logrus.Error(err)
}
}
}()
netavarkOpts, needPlugin, err := n.convertNetOpts(options.NetworkOptions) netavarkOpts, needPlugin, err := n.convertNetOpts(options.NetworkOptions)
if err != nil { if err != nil {
@ -72,15 +81,7 @@ func (n *netavarkNetwork) Setup(namespacePath string, options types.SetupOptions
result := map[string]types.StatusBlock{} result := map[string]types.StatusBlock{}
setup := func() error { setup := func() error {
err := n.execNetavark([]string{"setup", namespacePath}, needPlugin, netavarkOpts, &result) return n.execNetavark([]string{"setup", namespacePath}, needPlugin, netavarkOpts, &result)
if err != nil {
// lets dealloc ips to prevent leaking
if err := n.deallocIPs(&options.NetworkOptions); err != nil {
logrus.Error(err)
}
return err
}
return nil
} }
if n.rootlessNetns != nil { if n.rootlessNetns != nil {

View File

@ -685,6 +685,10 @@ func openSlirp4netnsPort(apiSocket, proto, hostip string, hostport, guestport ui
if _, err := conn.Write([]byte(fmt.Sprintf("%s\n", data))); err != nil { if _, err := conn.Write([]byte(fmt.Sprintf("%s\n", data))); err != nil {
return fmt.Errorf("cannot write to control socket %s: %w", apiSocket, err) return fmt.Errorf("cannot write to control socket %s: %w", apiSocket, err)
} }
//nolint:errcheck // This cast should never fail, if it does we get a interface
// conversion panic and a stack trace on how we ended up here which is more
// valuable than returning a human friendly error test as we don't know how it
// happened.
if err := conn.(*net.UnixConn).CloseWrite(); err != nil { if err := conn.(*net.UnixConn).CloseWrite(); err != nil {
return fmt.Errorf("cannot shutdown the socket %s: %w", apiSocket, err) return fmt.Errorf("cannot shutdown the socket %s: %w", apiSocket, err)
} }

View File

@ -24,7 +24,7 @@ profile {{.Name}} flags=(attach_disconnected,mediate_deleted) {
# Allow certain signals from OCI runtimes (podman, runc and crun) # Allow certain signals from OCI runtimes (podman, runc and crun)
signal (receive) peer={/usr/bin/,/usr/sbin/,}runc, signal (receive) peer={/usr/bin/,/usr/sbin/,}runc,
signal (receive) peer={/usr/bin/,/usr/sbin/,}crun*, signal (receive) peer={/usr/bin/,/usr/sbin/,}crun*,
signal (receive) set=(int, quit, kill, term) peer={/usr/bin/,/usr/sbin/,}podman, signal (receive) peer={/usr/bin/,/usr/sbin/,}podman,
{{end}} {{end}}
deny @{PROC}/* w, # deny write for all files directly in /proc (not in a subdir) deny @{PROC}/* w, # deny write for all files directly in /proc (not in a subdir)

View File

@ -843,11 +843,16 @@ func UserOwnsCurrentSystemdCgroup() (bool, error) {
if err != nil { if err != nil {
return false, err return false, err
} }
s := st.Sys() s := st.Sys()
if s == nil { if s == nil {
return false, fmt.Errorf("stat cgroup path %s", cgroupPath) return false, fmt.Errorf("stat cgroup path is nil %s", cgroupPath)
} }
//nolint:errcheck // This cast should never fail, if it does we get a interface
// conversion panic and a stack trace on how we ended up here which is more
// valuable than returning a human friendly error test as we don't know how it
// happened.
if int(s.(*syscall.Stat_t).Uid) != uid { if int(s.(*syscall.Stat_t).Uid) != uid {
return false, nil return false, nil
} }

View File

@ -29,9 +29,11 @@ func ChangeHostPathOwnership(path string, recursive bool, uid, gid int) error {
return err return err
} }
//nolint:errcheck
stat := f.Sys().(*syscall.Stat_t)
// Get current ownership // Get current ownership
currentUID := int(f.Sys().(*syscall.Stat_t).Uid) currentUID := int(stat.Uid)
currentGID := int(f.Sys().(*syscall.Stat_t).Gid) currentGID := int(stat.Gid)
if uid != currentUID || gid != currentGID { if uid != currentUID || gid != currentGID {
return os.Lchown(filePath, uid, gid) return os.Lchown(filePath, uid, gid)
@ -49,9 +51,11 @@ func ChangeHostPathOwnership(path string, recursive bool, uid, gid int) error {
return fmt.Errorf("failed to get host path information: %w", err) return fmt.Errorf("failed to get host path information: %w", err)
} }
//nolint:errcheck
stat := f.Sys().(*syscall.Stat_t)
// Get current ownership // Get current ownership
currentUID := int(f.Sys().(*syscall.Stat_t).Uid) currentUID := int(stat.Uid)
currentGID := int(f.Sys().(*syscall.Stat_t).Gid) currentGID := int(stat.Gid)
if uid != currentUID || gid != currentGID { if uid != currentUID || gid != currentGID {
if err := os.Lchown(path, uid, gid); err != nil { if err := os.Lchown(path, uid, gid); err != nil {

View File

@ -12,7 +12,6 @@ import (
"github.com/containers/common/internal/attributedstring" "github.com/containers/common/internal/attributedstring"
"github.com/containers/common/libnetwork/types" "github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/capabilities"
"github.com/containers/storage/pkg/fileutils" "github.com/containers/storage/pkg/fileutils"
"github.com/containers/storage/pkg/homedir" "github.com/containers/storage/pkg/homedir"
"github.com/containers/storage/pkg/unshare" "github.com/containers/storage/pkg/unshare"
@ -979,24 +978,6 @@ func (c *Config) GetDefaultEnvEx(envHost, httpProxy bool) []string {
return append(env, c.Containers.Env.Get()...) return append(env, c.Containers.Env.Get()...)
} }
// Capabilities returns the capabilities parses the Add and Drop capability
// list from the default capabilities for the container
func (c *Config) Capabilities(user string, addCapabilities, dropCapabilities []string) ([]string, error) {
userNotRoot := func(user string) bool {
if user == "" || user == "root" || user == "0" {
return false
}
return true
}
defaultCapabilities := c.Containers.DefaultCapabilities.Get()
if userNotRoot(user) {
defaultCapabilities = []string{}
}
return capabilities.MergeCapabilities(defaultCapabilities, addCapabilities, dropCapabilities)
}
// Device parses device mapping string to a src, dest & permissions string // Device parses device mapping string to a src, dest & permissions string
// Valid values for device looklike: // Valid values for device looklike:
// //

View File

@ -1,6 +1,7 @@
package config package config
import ( import (
"github.com/containers/common/pkg/capabilities"
selinux "github.com/opencontainers/selinux/go-selinux" selinux "github.com/opencontainers/selinux/go-selinux"
) )
@ -26,3 +27,21 @@ var defaultHelperBinariesDir = []string{
"/usr/libexec/podman", "/usr/libexec/podman",
"/usr/lib/podman", "/usr/lib/podman",
} }
// Capabilities returns the capabilities parses the Add and Drop capability
// list from the default capabilities for the container
func (c *Config) Capabilities(user string, addCapabilities, dropCapabilities []string) ([]string, error) {
userNotRoot := func(user string) bool {
if user == "" || user == "root" || user == "0" {
return false
}
return true
}
defaultCapabilities := c.Containers.DefaultCapabilities.Get()
if userNotRoot(user) {
defaultCapabilities = []string{}
}
return capabilities.MergeCapabilities(defaultCapabilities, addCapabilities, dropCapabilities)
}

View File

@ -6,7 +6,7 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"regexp" "strconv"
"strings" "strings"
"github.com/containers/storage/pkg/fileutils" "github.com/containers/storage/pkg/fileutils"
@ -97,8 +97,9 @@ func (c *ContainersConfig) validateTZ() error {
} }
func (c *ContainersConfig) validateUmask() error { func (c *ContainersConfig) validateUmask() error {
validUmask := regexp.MustCompile(`^[0-7]{1,4}$`) // Valid values are 0 to 7777 octal.
if !validUmask.MatchString(c.Umask) { _, err := strconv.ParseUint(c.Umask, 8, 12)
if err != nil {
return fmt.Errorf("not a valid umask %s", c.Umask) return fmt.Errorf("not a valid umask %s", c.Umask)
} }
return nil return nil

View File

@ -5,3 +5,9 @@ package config
func selinuxEnabled() bool { func selinuxEnabled() bool {
return false return false
} }
// Capabilities returns the capabilities parses the Add and Drop capability
// list from the default capabilities for the container
func (c *Config) Capabilities(user string, addCapabilities, dropCapabilities []string) ([]string, error) {
return nil, nil
}

View File

@ -539,7 +539,7 @@ func (c *Config) NetNS() string {
return c.Containers.NetNS return c.Containers.NetNS
} }
func (c EngineConfig) EventsLogMaxSize() uint64 { func (c *EngineConfig) EventsLogMaxSize() uint64 {
return uint64(c.EventsLogFileMaxSize) return uint64(c.EventsLogFileMaxSize)
} }

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"time" "time"
"github.com/containers/common/pkg/secrets/define" "github.com/containers/common/pkg/secrets/define"
@ -12,7 +13,6 @@ import (
"github.com/containers/common/pkg/secrets/passdriver" "github.com/containers/common/pkg/secrets/passdriver"
"github.com/containers/common/pkg/secrets/shelldriver" "github.com/containers/common/pkg/secrets/shelldriver"
"github.com/containers/storage/pkg/lockfile" "github.com/containers/storage/pkg/lockfile"
"github.com/containers/storage/pkg/regexp"
"github.com/containers/storage/pkg/stringid" "github.com/containers/storage/pkg/stringid"
"golang.org/x/exp/maps" "golang.org/x/exp/maps"
) )
@ -50,10 +50,6 @@ var errDataSize = errors.New("secret data must be larger than 0 and less than 51
// secretsFile is the name of the file that the secrets database will be stored in // secretsFile is the name of the file that the secrets database will be stored in
var secretsFile = "secrets.json" var secretsFile = "secrets.json"
// secretNameRegexp matches valid secret names
// Allowed: 253 characters, excluding ,/=\0
var secretNameRegexp = regexp.Delayed("^[^,/=\000]+$")
// SecretsManager holds information on handling secrets // SecretsManager holds information on handling secrets
// //
// revive does not like the name because the package is already called secrets // revive does not like the name because the package is already called secrets
@ -320,9 +316,7 @@ func (s *SecretsManager) LookupSecretData(nameOrID string) (*Secret, []byte, err
// validateSecretName checks if the secret name is valid. // validateSecretName checks if the secret name is valid.
func validateSecretName(name string) error { func validateSecretName(name string) error {
if len(name) == 0 || if len(name) == 0 || len(name) > 253 || strings.ContainsAny(name, ",/=\000") {
len(name) > 253 ||
!secretNameRegexp.MatchString(name) {
return fmt.Errorf("secret name %q can not include '=', '/', ',', or the '\\0' (NULL) and be between 1 and 253 characters: %w", name, errInvalidSecretName) return fmt.Errorf("secret name %q can not include '=', '/', ',', or the '\\0' (NULL) and be between 1 and 253 characters: %w", name, errInvalidSecretName)
} }
return nil return nil

View File

@ -205,7 +205,7 @@ func (s *supplementedImageReference) NewImageSource(ctx context.Context, sys *ty
} }
// Read the default manifest for the image. // Read the default manifest for the image.
manifestBytes, manifestType, err := src.GetManifest(ctx, nil) manifestBytes, manifestType, err := image.UnparsedInstance(src, nil).Manifest(ctx)
if err != nil { if err != nil {
return nil, fmt.Errorf("reading default manifest from image %q: %w", transports.ImageName(ref), err) return nil, fmt.Errorf("reading default manifest from image %q: %w", transports.ImageName(ref), err)
} }
@ -261,7 +261,7 @@ func (s *supplementedImageReference) NewImageSource(ctx context.Context, sys *ty
} }
// Read the instance's manifest. // Read the instance's manifest.
manifestBytes, manifestType, err := manifestToRead.src.GetManifest(ctx, manifestToRead.instance) manifestBytes, manifestType, err := image.UnparsedInstance(manifestToRead.src, manifestToRead.instance).Manifest(ctx)
if err != nil { if err != nil {
// if errors.Is(err, storage.ErrImageUnknown) || errors.Is(err, os.ErrNotExist) { // if errors.Is(err, storage.ErrImageUnknown) || errors.Is(err, os.ErrNotExist) {
// Trust that we either don't need it, or that it's in another reference. // Trust that we either don't need it, or that it's in another reference.

View File

@ -1,6 +1,6 @@
package sysinfo package sysinfo
import "github.com/docker/docker/pkg/parsers" import "github.com/containers/storage/pkg/parsers"
// SysInfo stores information about which features a kernel supports. // SysInfo stores information about which features a kernel supports.
// TODO Windows: Factor out platform specific capabilities. // TODO Windows: Factor out platform specific capabilities.

View File

@ -1,4 +1,4 @@
package version package version
// Version is the version of the build. // Version is the version of the build.
const Version = "0.62.1" const Version = "0.63.0-dev"

View File

@ -148,6 +148,13 @@ type Options struct {
// so that storage.ResolveReference returns exactly the created image. // so that storage.ResolveReference returns exactly the created image.
// WARNING: It is unspecified whether the reference also contains a reference.Named element. // WARNING: It is unspecified whether the reference also contains a reference.Named element.
ReportResolvedReference *types.ImageReference ReportResolvedReference *types.ImageReference
// DestinationTimestamp, if set, will force timestamps of content created in the destination to this value.
// Most transports don't support this.
//
// In oci-archive: destinations, this will set the create/mod/access timestamps in each tar entry
// (but not a timestamp of the created archive file).
DestinationTimestamp *time.Time
} }
// OptionCompressionVariant allows to supply information about // OptionCompressionVariant allows to supply information about
@ -354,6 +361,7 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef,
if err := c.dest.CommitWithOptions(ctx, private.CommitOptions{ if err := c.dest.CommitWithOptions(ctx, private.CommitOptions{
UnparsedToplevel: c.unparsedToplevel, UnparsedToplevel: c.unparsedToplevel,
ReportResolvedReference: options.ReportResolvedReference, ReportResolvedReference: options.ReportResolvedReference,
Timestamp: options.DestinationTimestamp,
}); err != nil { }); err != nil {
return nil, fmt.Errorf("committing the finished image: %w", err) return nil, fmt.Errorf("committing the finished image: %w", err)
} }

View File

@ -328,19 +328,16 @@ func prepareImageConfigForDest(ctx context.Context, sys *types.SystemContext, sr
} }
wantedPlatforms := platform.WantedPlatforms(sys) wantedPlatforms := platform.WantedPlatforms(sys)
options := newOrderedSet() if !slices.ContainsFunc(wantedPlatforms, func(wantedPlatform imgspecv1.Platform) bool {
match := false
for _, wantedPlatform := range wantedPlatforms {
// For a transitional period, this might trigger warnings because the Variant // For a transitional period, this might trigger warnings because the Variant
// field was added to OCI config only recently. If this turns out to be too noisy, // field was added to OCI config only recently. If this turns out to be too noisy,
// revert this check to only look for (OS, Architecture). // revert this check to only look for (OS, Architecture).
if platform.MatchesPlatform(ociConfig.Platform, wantedPlatform) { return platform.MatchesPlatform(ociConfig.Platform, wantedPlatform)
match = true }) {
break options := newOrderedSet()
for _, p := range wantedPlatforms {
options.append(fmt.Sprintf("%s+%s+%q", p.OS, p.Architecture, p.Variant))
} }
options.append(fmt.Sprintf("%s+%s+%q", wantedPlatform.OS, wantedPlatform.Architecture, wantedPlatform.Variant))
}
if !match {
logrus.Infof("Image operating system mismatch: image uses OS %q+architecture %q+%q, expecting one of %q", logrus.Infof("Image operating system mismatch: image uses OS %q+architecture %q+%q, expecting one of %q",
ociConfig.OS, ociConfig.Architecture, ociConfig.Variant, strings.Join(options.list, ", ")) ociConfig.OS, ociConfig.Architecture, ociConfig.Variant, strings.Join(options.list, ", "))
} }

View File

@ -92,7 +92,7 @@ func imageLoadGoroutine(ctx context.Context, c *client.Client, reader *io.PipeRe
// imageLoad accepts tar stream on reader and sends it to c // imageLoad accepts tar stream on reader and sends it to c
func imageLoad(ctx context.Context, c *client.Client, reader *io.PipeReader) error { func imageLoad(ctx context.Context, c *client.Client, reader *io.PipeReader) error {
resp, err := c.ImageLoad(ctx, reader, true) resp, err := c.ImageLoad(ctx, reader, client.ImageLoadWithQuiet(true))
if err != nil { if err != nil {
return fmt.Errorf("starting a load operation in docker engine: %w", err) return fmt.Errorf("starting a load operation in docker engine: %w", err)
} }

View File

@ -475,7 +475,7 @@ func (c *dockerClient) resolveRequestURL(path string) (*url.URL, error) {
} }
// Checks if the auth headers in the response contain an indication of a failed // Checks if the auth headers in the response contain an indication of a failed
// authorizdation because of an "insufficient_scope" error. If that's the case, // authorization because of an "insufficient_scope" error. If that's the case,
// returns the required scope to be used for fetching a new token. // returns the required scope to be used for fetching a new token.
func needsRetryWithUpdatedScope(res *http.Response) (bool, *authScope) { func needsRetryWithUpdatedScope(res *http.Response) (bool, *authScope) {
if res.StatusCode == http.StatusUnauthorized { if res.StatusCode == http.StatusUnauthorized {

View File

@ -3,6 +3,7 @@ package private
import ( import (
"context" "context"
"io" "io"
"time"
"github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/internal/blobinfocache" "github.com/containers/image/v5/internal/blobinfocache"
@ -170,6 +171,12 @@ type CommitOptions struct {
// What “resolved” means is transport-specific. // What “resolved” means is transport-specific.
// Transports which dont support reporting resolved references can ignore the field; the generic copy code writes "nil" into the value. // Transports which dont support reporting resolved references can ignore the field; the generic copy code writes "nil" into the value.
ReportResolvedReference *types.ImageReference ReportResolvedReference *types.ImageReference
// Timestamp, if set, will force timestamps of content created in the destination to this value.
// Most transports don't support this.
//
// In oci-archive: destinations, this will set the create/mod/access timestamps in each tar entry
// (but not a timestamp of the created archive file).
Timestamp *time.Time
} }
// ImageSourceChunk is a portion of a blob. // ImageSourceChunk is a portion of a blob.

View File

@ -1,22 +0,0 @@
//go:build linux
package reflink
import (
"io"
"os"
"golang.org/x/sys/unix"
)
// LinkOrCopy attempts to reflink the source to the destination fd.
// If reflinking fails or is unsupported, it falls back to io.Copy().
func LinkOrCopy(src, dst *os.File) error {
_, _, errno := unix.Syscall(unix.SYS_IOCTL, dst.Fd(), unix.FICLONE, src.Fd())
if errno == 0 {
return nil
}
_, err := io.Copy(dst, src)
return err
}

View File

@ -1,15 +0,0 @@
//go:build !linux
package reflink
import (
"io"
"os"
)
// LinkOrCopy attempts to reflink the source to the destination fd.
// If reflinking fails or is unsupported, it falls back to io.Copy().
func LinkOrCopy(src, dst *os.File) error {
_, err := io.Copy(dst, src)
return err
}

View File

@ -166,10 +166,11 @@ func (m *OCI1) UpdateLayerInfos(layerInfos []types.BlobInfo) error {
// getEncryptedMediaType will return the mediatype to its encrypted counterpart and return // getEncryptedMediaType will return the mediatype to its encrypted counterpart and return
// an error if the mediatype does not support encryption // an error if the mediatype does not support encryption
func getEncryptedMediaType(mediatype string) (string, error) { func getEncryptedMediaType(mediatype string) (string, error) {
if slices.Contains(strings.Split(mediatype, "+")[1:], "encrypted") { parts := strings.Split(mediatype, "+")
if slices.Contains(parts[1:], "encrypted") {
return "", fmt.Errorf("unsupported mediaType: %q already encrypted", mediatype) return "", fmt.Errorf("unsupported mediaType: %q already encrypted", mediatype)
} }
unsuffixedMediatype := strings.Split(mediatype, "+")[0] unsuffixedMediatype := parts[0]
switch unsuffixedMediatype { switch unsuffixedMediatype {
case DockerV2Schema2LayerMediaType, imgspecv1.MediaTypeImageLayer, case DockerV2Schema2LayerMediaType, imgspecv1.MediaTypeImageLayer,
imgspecv1.MediaTypeImageLayerNonDistributable: //nolint:staticcheck // NonDistributable layers are deprecated, but we want to continue to support manipulating pre-existing images. imgspecv1.MediaTypeImageLayerNonDistributable: //nolint:staticcheck // NonDistributable layers are deprecated, but we want to continue to support manipulating pre-existing images.

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"time"
"github.com/containers/image/v5/internal/imagedestination" "github.com/containers/image/v5/internal/imagedestination"
"github.com/containers/image/v5/internal/imagedestination/impl" "github.com/containers/image/v5/internal/imagedestination/impl"
@ -172,16 +173,19 @@ func (d *ociArchiveImageDestination) CommitWithOptions(ctx context.Context, opti
src := d.tempDirRef.tempDirectory src := d.tempDirRef.tempDirectory
// path to save tarred up file // path to save tarred up file
dst := d.ref.resolvedFile dst := d.ref.resolvedFile
return tarDirectory(src, dst) return tarDirectory(src, dst, options.Timestamp)
} }
// tar converts the directory at src and saves it to dst // tar converts the directory at src and saves it to dst
func tarDirectory(src, dst string) error { // if contentModTimes is non-nil, tar header entries times are set to this
func tarDirectory(src, dst string, contentModTimes *time.Time) (retErr error) {
// input is a stream of bytes from the archive of the directory at path // input is a stream of bytes from the archive of the directory at path
input, err := archive.TarWithOptions(src, &archive.TarOptions{ input, err := archive.TarWithOptions(src, &archive.TarOptions{
Compression: archive.Uncompressed, Compression: archive.Uncompressed,
// Dont include the data about the user account this code is running under. // Dont include the data about the user account this code is running under.
ChownOpts: &idtools.IDPair{UID: 0, GID: 0}, ChownOpts: &idtools.IDPair{UID: 0, GID: 0},
// override tar header timestamps
Timestamp: contentModTimes,
}) })
if err != nil { if err != nil {
return fmt.Errorf("retrieving stream of bytes from %q: %w", src, err) return fmt.Errorf("retrieving stream of bytes from %q: %w", src, err)
@ -193,7 +197,14 @@ func tarDirectory(src, dst string) error {
if err != nil { if err != nil {
return fmt.Errorf("creating tar file %q: %w", dst, err) return fmt.Errorf("creating tar file %q: %w", dst, err)
} }
defer outFile.Close()
// since we are writing to this file, make sure we handle errors
defer func() {
closeErr := outFile.Close()
if retErr == nil {
retErr = closeErr
}
}()
// copies the contents of the directory to the tar file // copies the contents of the directory to the tar file
// TODO: This can take quite some time, and should ideally be cancellable using a context.Context. // TODO: This can take quite some time, and should ideally be cancellable using a context.Context.

View File

@ -159,7 +159,7 @@ func (ref ociReference) deleteReferenceFromIndex(referenceIndex int) error {
return saveJSON(ref.indexPath(), index) return saveJSON(ref.indexPath(), index)
} }
func saveJSON(path string, content any) error { func saveJSON(path string, content any) (retErr error) {
// If the file already exists, get its mode to preserve it // If the file already exists, get its mode to preserve it
var mode fs.FileMode var mode fs.FileMode
existingfi, err := os.Stat(path) existingfi, err := os.Stat(path)
@ -177,7 +177,13 @@ func saveJSON(path string, content any) error {
if err != nil { if err != nil {
return err return err
} }
defer file.Close() // since we are writing to this file, make sure we handle errors
defer func() {
closeErr := file.Close()
if retErr == nil {
retErr = closeErr
}
}()
return json.NewEncoder(file).Encode(content) return json.NewEncoder(file).Encode(content)
} }

View File

@ -17,7 +17,6 @@ import (
"github.com/containers/image/v5/internal/manifest" "github.com/containers/image/v5/internal/manifest"
"github.com/containers/image/v5/internal/private" "github.com/containers/image/v5/internal/private"
"github.com/containers/image/v5/internal/putblobdigest" "github.com/containers/image/v5/internal/putblobdigest"
"github.com/containers/image/v5/internal/reflink"
"github.com/containers/image/v5/types" "github.com/containers/image/v5/types"
"github.com/containers/storage/pkg/fileutils" "github.com/containers/storage/pkg/fileutils"
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
@ -116,7 +115,7 @@ func (d *ociImageDestination) Close() error {
// WARNING: The contents of stream are being verified on the fly. Until stream.Read() returns io.EOF, the contents of the data SHOULD NOT be available // WARNING: The contents of stream are being verified on the fly. Until stream.Read() returns io.EOF, the contents of the data SHOULD NOT be available
// to any other readers for download using the supplied digest. // to any other readers for download using the supplied digest.
// If stream.Read() at any time, ESPECIALLY at end of input, returns an error, PutBlobWithOptions MUST 1) fail, and 2) delete any data stored so far. // If stream.Read() at any time, ESPECIALLY at end of input, returns an error, PutBlobWithOptions MUST 1) fail, and 2) delete any data stored so far.
func (d *ociImageDestination) PutBlobWithOptions(ctx context.Context, stream io.Reader, inputInfo types.BlobInfo, options private.PutBlobOptions) (private.UploadedBlob, error) { func (d *ociImageDestination) PutBlobWithOptions(ctx context.Context, stream io.Reader, inputInfo types.BlobInfo, options private.PutBlobOptions) (_ private.UploadedBlob, retErr error) {
blobFile, err := os.CreateTemp(d.ref.dir, "oci-put-blob") blobFile, err := os.CreateTemp(d.ref.dir, "oci-put-blob")
if err != nil { if err != nil {
return private.UploadedBlob{}, err return private.UploadedBlob{}, err
@ -125,7 +124,10 @@ func (d *ociImageDestination) PutBlobWithOptions(ctx context.Context, stream io.
explicitClosed := false explicitClosed := false
defer func() { defer func() {
if !explicitClosed { if !explicitClosed {
blobFile.Close() closeErr := blobFile.Close()
if retErr == nil {
retErr = closeErr
}
} }
if !succeeded { if !succeeded {
os.Remove(blobFile.Name()) os.Remove(blobFile.Name())
@ -177,7 +179,10 @@ func (d *ociImageDestination) blobFileSyncAndRename(blobFile *os.File, blobDiges
} }
// need to explicitly close the file, since a rename won't otherwise work on Windows // need to explicitly close the file, since a rename won't otherwise work on Windows
blobFile.Close() err = blobFile.Close()
if err != nil {
return err
}
*closed = true *closed = true
if err := os.Rename(blobFile.Name(), blobPath); err != nil { if err := os.Rename(blobFile.Name(), blobPath); err != nil {
@ -324,10 +329,10 @@ type PutBlobFromLocalFileOption struct{}
// It computes, and returns, the digest and size of the used file. // It computes, and returns, the digest and size of the used file.
// //
// This function can be used instead of dest.PutBlob() where the ImageDestination requires PutBlob() to be called. // This function can be used instead of dest.PutBlob() where the ImageDestination requires PutBlob() to be called.
func PutBlobFromLocalFile(ctx context.Context, dest types.ImageDestination, file string, options ...PutBlobFromLocalFileOption) (digest.Digest, int64, error) { func PutBlobFromLocalFile(ctx context.Context, dest types.ImageDestination, file string, options ...PutBlobFromLocalFileOption) (_ digest.Digest, _ int64, retErr error) {
d, ok := dest.(*ociImageDestination) d, ok := dest.(*ociImageDestination)
if !ok { if !ok {
return "", -1, errors.New("internal error: PutBlobFromLocalFile called with a non-oci: destination") return "", -1, errors.New("caller error: PutBlobFromLocalFile called with a non-oci: destination")
} }
succeeded := false succeeded := false
@ -338,7 +343,10 @@ func PutBlobFromLocalFile(ctx context.Context, dest types.ImageDestination, file
} }
defer func() { defer func() {
if !blobFileClosed { if !blobFileClosed {
blobFile.Close() closeErr := blobFile.Close()
if retErr == nil {
retErr = closeErr
}
} }
if !succeeded { if !succeeded {
os.Remove(blobFile.Name()) os.Remove(blobFile.Name())
@ -351,7 +359,7 @@ func PutBlobFromLocalFile(ctx context.Context, dest types.ImageDestination, file
} }
defer srcFile.Close() defer srcFile.Close()
err = reflink.LinkOrCopy(srcFile, blobFile) err = fileutils.ReflinkOrCopy(srcFile, blobFile)
if err != nil { if err != nil {
return "", -1, err return "", -1, err
} }

View File

@ -16,6 +16,7 @@ import (
"github.com/containers/image/v5/internal/private" "github.com/containers/image/v5/internal/private"
"github.com/containers/image/v5/pkg/tlsclientconfig" "github.com/containers/image/v5/pkg/tlsclientconfig"
"github.com/containers/image/v5/types" "github.com/containers/image/v5/types"
"github.com/containers/storage/pkg/fileutils"
"github.com/docker/go-connections/tlsconfig" "github.com/docker/go-connections/tlsconfig"
"github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
@ -214,3 +215,26 @@ func getBlobSize(resp *http.Response) int64 {
} }
return size return size
} }
// GetLocalBlobPath returns the local path to the blob file with the given digest.
// The returned path is checked for existence so when a non existing digest is
// given an error will be returned.
//
// Important: The returned path must be treated as read only, writing the file will
// corrupt the oci layout as the digest no longer matches.
func GetLocalBlobPath(ctx context.Context, src types.ImageSource, digest digest.Digest) (string, error) {
s, ok := src.(*ociImageSource)
if !ok {
return "", errors.New("caller error: GetLocalBlobPath called with a non-oci: source")
}
path, err := s.ref.blobPath(digest, s.sharedBlobDir)
if err != nil {
return "", err
}
if err := fileutils.Exists(path); err != nil {
return "", err
}
return path, nil
}

View File

@ -12,6 +12,7 @@ import (
"github.com/containers/image/v5/directory/explicitfilepath" "github.com/containers/image/v5/directory/explicitfilepath"
"github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/internal/image" "github.com/containers/image/v5/internal/image"
"github.com/containers/image/v5/internal/manifest"
"github.com/containers/image/v5/oci/internal" "github.com/containers/image/v5/oci/internal"
"github.com/containers/image/v5/transports" "github.com/containers/image/v5/transports"
"github.com/containers/image/v5/types" "github.com/containers/image/v5/types"
@ -234,7 +235,7 @@ func (ref ociReference) getManifestDescriptor() (imgspecv1.Descriptor, int, erro
var unsupportedMIMETypes []string var unsupportedMIMETypes []string
for i, md := range index.Manifests { for i, md := range index.Manifests {
if refName, ok := md.Annotations[imgspecv1.AnnotationRefName]; ok && refName == ref.image { if refName, ok := md.Annotations[imgspecv1.AnnotationRefName]; ok && refName == ref.image {
if md.MediaType == imgspecv1.MediaTypeImageManifest || md.MediaType == imgspecv1.MediaTypeImageIndex { if md.MediaType == imgspecv1.MediaTypeImageManifest || md.MediaType == imgspecv1.MediaTypeImageIndex || md.MediaType == manifest.DockerV2Schema2MediaType || md.MediaType == manifest.DockerV2ListMediaType {
return md, i, nil return md, i, nil
} }
unsupportedMIMETypes = append(unsupportedMIMETypes, md.MediaType) unsupportedMIMETypes = append(unsupportedMIMETypes, md.MediaType)

View File

@ -143,16 +143,24 @@ func (d *ostreeImageDestination) PutBlobWithOptions(ctx context.Context, stream
return private.UploadedBlob{}, err return private.UploadedBlob{}, err
} }
digester, stream := putblobdigest.DigestIfCanonicalUnknown(stream, inputInfo)
blobPath := filepath.Join(tmpDir, "content") blobPath := filepath.Join(tmpDir, "content")
blobFile, err := os.Create(blobPath) blobFile, err := os.Create(blobPath)
if err != nil { if err != nil {
return private.UploadedBlob{}, err return private.UploadedBlob{}, err
} }
defer blobFile.Close() size, err := func() (_ int64, retErr error) { // A scope for defer
// since we are writing to this file, make sure we handle errors
digester, stream := putblobdigest.DigestIfCanonicalUnknown(stream, inputInfo) defer func() {
// TODO: This can take quite some time, and should ideally be cancellable using ctx.Done(). closeErr := blobFile.Close()
size, err := io.Copy(blobFile, stream) if retErr == nil {
retErr = closeErr
}
}()
// TODO: This can take quite some time, and should ideally be cancellable using ctx.Done().
return io.Copy(blobFile, stream)
}()
if err != nil { if err != nil {
return private.UploadedBlob{}, err return private.UploadedBlob{}, err
} }
@ -247,9 +255,15 @@ func (d *ostreeImageDestination) ostreeCommit(repo *otbuiltin.Repo, branch strin
return err return err
} }
func generateTarSplitMetadata(output *bytes.Buffer, file string) (digest.Digest, int64, error) { func generateTarSplitMetadata(output *bytes.Buffer, file string) (_ digest.Digest, _ int64, retErr error) {
mfz := pgzip.NewWriter(output) mfz := pgzip.NewWriter(output)
defer mfz.Close() // since we are writing to this, make sure we handle errors
defer func() {
closeErr := mfz.Close()
if retErr == nil {
retErr = closeErr
}
}()
metaPacker := storage.NewJSONPacker(mfz) metaPacker := storage.NewJSONPacker(mfz)
stream, err := os.OpenFile(file, os.O_RDONLY, 0) stream, err := os.OpenFile(file, os.O_RDONLY, 0)

View File

@ -250,9 +250,7 @@ func newOSTreePathFileGetter(repo *C.struct_OstreeRepo, commit string) (*ostreeP
func (o ostreePathFileGetter) Get(filename string) (io.ReadCloser, error) { func (o ostreePathFileGetter) Get(filename string) (io.ReadCloser, error) {
var file *C.GFile var file *C.GFile
if strings.HasPrefix(filename, "./") { filename, _ = strings.CutPrefix(filename, "./")
filename = filename[2:]
}
cfilename := C.CString(filename) cfilename := C.CString(filename)
defer C.free(unsafe.Pointer(cfilename)) defer C.free(unsafe.Pointer(cfilename))

View File

@ -87,14 +87,20 @@ func new2(path string) (*cache, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("initializing blob info cache at %q: %w", path, err) return nil, fmt.Errorf("initializing blob info cache at %q: %w", path, err)
} }
defer db.Close() err = func() (retErr error) { // A scope for defer
defer func() {
// We dont check the schema before every operation, because that would be costly closeErr := db.Close()
// and because we assume schema changes will be handled by using a different path. if retErr == nil {
if err := ensureDBHasCurrentSchema(db); err != nil { retErr = closeErr
}
}()
// We dont check the schema before every operation, because that would be costly
// and because we assume schema changes will be handled by using a different path.
return ensureDBHasCurrentSchema(db)
}()
if err != nil {
return nil, err return nil, err
} }
return &cache{ return &cache{
path: path, path: path,
refCount: 0, refCount: 0,
@ -147,25 +153,30 @@ func (sqc *cache) Close() {
type void struct{} // So that we dont have to write struct{}{} all over the place type void struct{} // So that we dont have to write struct{}{} all over the place
// transaction calls fn within a read-write transaction in sqc. // transaction calls fn within a read-write transaction in sqc.
func transaction[T any](sqc *cache, fn func(tx *sql.Tx) (T, error)) (T, error) { func transaction[T any](sqc *cache, fn func(tx *sql.Tx) (T, error)) (_ T, retErr error) {
db, closeDB, err := func() (*sql.DB, func(), error) { // A scope for defer db, closeDB, err := func() (*sql.DB, func() error, error) { // A scope for defer
sqc.lock.Lock() sqc.lock.Lock()
defer sqc.lock.Unlock() defer sqc.lock.Unlock()
if sqc.db != nil { if sqc.db != nil {
return sqc.db, func() {}, nil return sqc.db, func() error { return nil }, nil
} }
db, err := rawOpen(sqc.path) db, err := rawOpen(sqc.path)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("opening blob info cache at %q: %w", sqc.path, err) return nil, nil, fmt.Errorf("opening blob info cache at %q: %w", sqc.path, err)
} }
return db, func() { db.Close() }, nil return db, db.Close, nil
}() }()
if err != nil { if err != nil {
var zeroRes T // A zero value of T var zeroRes T // A zero value of T
return zeroRes, err return zeroRes, err
} }
defer closeDB() defer func() {
closeErr := closeDB()
if retErr == nil {
retErr = closeErr
}
}()
return dbTransaction(db, fn) return dbTransaction(db, fn)
} }

View File

@ -134,7 +134,7 @@ func ResolveShortNameAlias(ctx *types.SystemContext, name string) (reference.Nam
// editShortNameAlias loads the aliases.conf file and changes it. If value is // editShortNameAlias loads the aliases.conf file and changes it. If value is
// set, it adds the name-value pair as a new alias. Otherwise, it will remove // set, it adds the name-value pair as a new alias. Otherwise, it will remove
// name from the config. // name from the config.
func editShortNameAlias(ctx *types.SystemContext, name string, value *string) error { func editShortNameAlias(ctx *types.SystemContext, name string, value *string) (retErr error) {
if err := validateShortName(name); err != nil { if err := validateShortName(name); err != nil {
return err return err
} }
@ -178,7 +178,13 @@ func editShortNameAlias(ctx *types.SystemContext, name string, value *string) er
if err != nil { if err != nil {
return err return err
} }
defer f.Close() // since we are writing to this file, make sure we handle err on Close()
defer func() {
closeErr := f.Close()
if retErr == nil {
retErr = closeErr
}
}()
encoder := toml.NewEncoder(f) encoder := toml.NewEncoder(f)
return encoder.Encode(conf) return encoder.Encode(conf)

View File

@ -430,7 +430,8 @@ func (config *V2RegistriesConf) postProcessRegistries() error {
return fmt.Errorf("pull-from-mirror must not be set for a non-mirror registry %q", reg.Prefix) return fmt.Errorf("pull-from-mirror must not be set for a non-mirror registry %q", reg.Prefix)
} }
// make sure mirrors are valid // make sure mirrors are valid
for _, mir := range reg.Mirrors { for j := range reg.Mirrors {
mir := &reg.Mirrors[j]
mir.Location, err = parseLocation(mir.Location) mir.Location, err = parseLocation(mir.Location)
if err != nil { if err != nil {
return err return err

View File

@ -186,12 +186,18 @@ func convertSIFToElements(ctx context.Context, sifImage *sif.FileImage, tempDir
// has an -o option that allows extracting a squashfs from the SIF file directly, // has an -o option that allows extracting a squashfs from the SIF file directly,
// but that version is not currently available in RHEL 8. // but that version is not currently available in RHEL 8.
logrus.Debugf("Creating a temporary squashfs image %s ...", squashFSPath) logrus.Debugf("Creating a temporary squashfs image %s ...", squashFSPath)
if err := func() error { // A scope for defer if err := func() (retErr error) { // A scope for defer
f, err := os.Create(squashFSPath) f, err := os.Create(squashFSPath)
if err != nil { if err != nil {
return err return err
} }
defer f.Close() // since we are writing to this file, make sure we handle err on Close()
defer func() {
closeErr := f.Close()
if retErr == nil {
retErr = closeErr
}
}()
// TODO: This can take quite some time, and should ideally be cancellable using ctx.Done(). // TODO: This can take quite some time, and should ideally be cancellable using ctx.Done().
if _, err := io.CopyN(f, rootFS.GetReader(), rootFS.Size()); err != nil { if _, err := io.CopyN(f, rootFS.GetReader(), rootFS.Size()); err != nil {
return err return err

View File

@ -180,18 +180,18 @@ type PRSigstoreSignedPKI interface {
// prSigstoreSignedPKI contains non-fulcio certificate PKI configuration options for prSigstoreSigned // prSigstoreSignedPKI contains non-fulcio certificate PKI configuration options for prSigstoreSigned
type prSigstoreSignedPKI struct { type prSigstoreSignedPKI struct {
// CARootsPath a path to a file containing accepted CA root certificates, in PEM format. Exactly one of CARootsPath and CARootsData must be specified. // CARootsPath a path to a file containing accepted CA root certificates, in PEM format. Exactly one of CARootsPath and CARootsData must be specified.
CARootsPath string `json:"caRootsPath"` CARootsPath string `json:"caRootsPath,omitempty"`
// CARootsData contains accepted CA root certificates in PEM format, all of that base64-encoded. Exactly one of CARootsPath and CARootsData must be specified. // CARootsData contains accepted CA root certificates in PEM format, all of that base64-encoded. Exactly one of CARootsPath and CARootsData must be specified.
CARootsData []byte `json:"caRootsData"` CARootsData []byte `json:"caRootsData,omitempty"`
// CAIntermediatesPath a path to a file containing accepted CA intermediate certificates, in PEM format. Only one of CAIntermediatesPath or CAIntermediatesData can be specified, not both. // CAIntermediatesPath a path to a file containing accepted CA intermediate certificates, in PEM format. Only one of CAIntermediatesPath or CAIntermediatesData can be specified, not both.
CAIntermediatesPath string `json:"caIntermediatesPath"` CAIntermediatesPath string `json:"caIntermediatesPath,omitempty"`
// CAIntermediatesData contains accepted CA intermediate certificates in PEM format, all of that base64-encoded. Only one of CAIntermediatesPath or CAIntermediatesData can be specified, not both. // CAIntermediatesData contains accepted CA intermediate certificates in PEM format, all of that base64-encoded. Only one of CAIntermediatesPath or CAIntermediatesData can be specified, not both.
CAIntermediatesData []byte `json:"caIntermediatesData"` CAIntermediatesData []byte `json:"caIntermediatesData,omitempty"`
// SubjectEmail specifies the expected email address imposed on the subject to which the certificate was issued. At least one of SubjectEmail and SubjectHostname must be specified. // SubjectEmail specifies the expected email address imposed on the subject to which the certificate was issued. At least one of SubjectEmail and SubjectHostname must be specified.
SubjectEmail string `json:"subjectEmail"` SubjectEmail string `json:"subjectEmail,omitempty"`
// SubjectHostname specifies the expected hostname imposed on the subject to which the certificate was issued. At least one of SubjectEmail and SubjectHostname must be specified. // SubjectHostname specifies the expected hostname imposed on the subject to which the certificate was issued. At least one of SubjectEmail and SubjectHostname must be specified.
SubjectHostname string `json:"subjectHostname"` SubjectHostname string `json:"subjectHostname,omitempty"`
} }
// PolicyReferenceMatch specifies a set of image identities accepted in PolicyRequirement. // PolicyReferenceMatch specifies a set of image identities accepted in PolicyRequirement.

View File

@ -272,43 +272,56 @@ func (s *storageImageDestination) putBlobToPendingFile(stream io.Reader, blobinf
if err != nil { if err != nil {
return private.UploadedBlob{}, fmt.Errorf("creating temporary file %q: %w", filename, err) return private.UploadedBlob{}, fmt.Errorf("creating temporary file %q: %w", filename, err)
} }
defer file.Close() blobDigest, diffID, count, err := func() (_, _ digest.Digest, _ int64, retErr error) { // A scope for defer
counter := ioutils.NewWriteCounter(file) // since we are writing to this file, make sure we handle err on Close()
stream = io.TeeReader(stream, counter) defer func() {
digester, stream := putblobdigest.DigestIfUnknown(stream, blobinfo) closeErr := file.Close()
decompressed, err := archive.DecompressStream(stream) if retErr == nil {
if err != nil { retErr = closeErr
return private.UploadedBlob{}, fmt.Errorf("setting up to decompress blob: %w", err) }
} }()
counter := ioutils.NewWriteCounter(file)
stream = io.TeeReader(stream, counter)
digester, stream := putblobdigest.DigestIfUnknown(stream, blobinfo)
decompressed, err := archive.DecompressStream(stream)
if err != nil {
return "", "", 0, fmt.Errorf("setting up to decompress blob: %w", err)
diffID := digest.Canonical.Digester() }
// Copy the data to the file. defer decompressed.Close()
// TODO: This can take quite some time, and should ideally be cancellable using context.Context.
_, err = io.Copy(diffID.Hash(), decompressed) diffID := digest.Canonical.Digester()
decompressed.Close() // Copy the data to the file.
// TODO: This can take quite some time, and should ideally be cancellable using context.Context.
_, err = io.Copy(diffID.Hash(), decompressed)
if err != nil {
return "", "", 0, fmt.Errorf("storing blob to file %q: %w", filename, err)
}
return digester.Digest(), diffID.Digest(), counter.Count, nil
}()
if err != nil { if err != nil {
return private.UploadedBlob{}, fmt.Errorf("storing blob to file %q: %w", filename, err) return private.UploadedBlob{}, err
} }
// Determine blob properties, and fail if information that we were given about the blob // Determine blob properties, and fail if information that we were given about the blob
// is known to be incorrect. // is known to be incorrect.
blobDigest := digester.Digest()
blobSize := blobinfo.Size blobSize := blobinfo.Size
if blobSize < 0 { if blobSize < 0 {
blobSize = counter.Count blobSize = count
} else if blobinfo.Size != counter.Count { } else if blobinfo.Size != count {
return private.UploadedBlob{}, ErrBlobSizeMismatch return private.UploadedBlob{}, ErrBlobSizeMismatch
} }
// Record information about the blob. // Record information about the blob.
s.lock.Lock() s.lock.Lock()
s.lockProtected.blobDiffIDs[blobDigest] = diffID.Digest() s.lockProtected.blobDiffIDs[blobDigest] = diffID
s.lockProtected.fileSizes[blobDigest] = counter.Count s.lockProtected.fileSizes[blobDigest] = count
s.lockProtected.filenames[blobDigest] = filename s.lockProtected.filenames[blobDigest] = filename
s.lock.Unlock() s.lock.Unlock()
// This is safe because we have just computed diffID, and blobDigest was either computed // This is safe because we have just computed diffID, and blobDigest was either computed
// by us, or validated by the caller (usually copy.digestingReader). // by us, or validated by the caller (usually copy.digestingReader).
options.Cache.RecordDigestUncompressedPair(blobDigest, diffID.Digest()) options.Cache.RecordDigestUncompressedPair(blobDigest, diffID)
return private.UploadedBlob{ return private.UploadedBlob{
Digest: blobDigest, Digest: blobDigest,
Size: blobSize, Size: blobSize,

View File

@ -362,15 +362,14 @@ func (s storageTransport) ValidatePolicyConfigurationScope(scope string) error {
} }
storeSpec := scope[1:closeIndex] storeSpec := scope[1:closeIndex]
scope = scope[closeIndex+1:] scope = scope[closeIndex+1:]
storeInfo := strings.SplitN(storeSpec, "@", 2) if a, b, ok := strings.Cut(storeSpec, "@"); ok && a != "" && b != "" {
if len(storeInfo) == 1 && storeInfo[0] != "" { // Two components: the driver type and the graph root.
// One component: the graph root. if !filepath.IsAbs(b) {
if !filepath.IsAbs(storeInfo[0]) {
return ErrPathNotAbsolute return ErrPathNotAbsolute
} }
} else if len(storeInfo) == 2 && storeInfo[0] != "" && storeInfo[1] != "" { } else if !ok && a != "" {
// Two components: the driver type and the graph root. // One component: the graph root.
if !filepath.IsAbs(storeInfo[1]) { if !filepath.IsAbs(storeSpec) {
return ErrPathNotAbsolute return ErrPathNotAbsolute
} }
} else { } else {

View File

@ -6,12 +6,12 @@ const (
// VersionMajor is for an API incompatible changes // VersionMajor is for an API incompatible changes
VersionMajor = 5 VersionMajor = 5
// VersionMinor is for functionality in a backwards-compatible manner // VersionMinor is for functionality in a backwards-compatible manner
VersionMinor = 34 VersionMinor = 35
// VersionPatch is for backwards-compatible bug fixes // VersionPatch is for backwards-compatible bug fixes
VersionPatch = 1 VersionPatch = 0
// VersionDev indicates development branch. Releases will be empty string. // VersionDev indicates development branch. Releases will be empty string.
VersionDev = "" VersionDev = "-dev"
) )
// Version is the specification version that the package types support. // Version is the specification version that the package types support.

View File

@ -15,27 +15,30 @@ type Program interface {
// ProgramFunc is a type of function that initializes programs based on arguments. // ProgramFunc is a type of function that initializes programs based on arguments.
type ProgramFunc func(args ...string) Program type ProgramFunc func(args ...string) Program
// NewShellProgramFunc creates programs that are executed in a Shell. // NewShellProgramFunc creates a [ProgramFunc] to run command in a [Shell].
func NewShellProgramFunc(name string) ProgramFunc { func NewShellProgramFunc(command string) ProgramFunc {
return NewShellProgramFuncWithEnv(name, nil)
}
// NewShellProgramFuncWithEnv creates programs that are executed in a Shell with environment variables
func NewShellProgramFuncWithEnv(name string, env *map[string]string) ProgramFunc {
return func(args ...string) Program { return func(args ...string) Program {
return &Shell{cmd: createProgramCmdRedirectErr(name, args, env)} return createProgramCmdRedirectErr(command, args, nil)
} }
} }
func createProgramCmdRedirectErr(commandName string, args []string, env *map[string]string) *exec.Cmd { // NewShellProgramFuncWithEnv creates a [ProgramFunc] tu run command
programCmd := exec.Command(commandName, args...) // in a [Shell] with the given environment variables.
func NewShellProgramFuncWithEnv(command string, env *map[string]string) ProgramFunc {
return func(args ...string) Program {
return createProgramCmdRedirectErr(command, args, env)
}
}
func createProgramCmdRedirectErr(command string, args []string, env *map[string]string) *Shell {
ec := exec.Command(command, args...)
if env != nil { if env != nil {
for k, v := range *env { for k, v := range *env {
programCmd.Env = append(programCmd.Environ(), k+"="+v) ec.Env = append(ec.Environ(), k+"="+v)
} }
} }
programCmd.Stderr = os.Stderr ec.Stderr = os.Stderr
return programCmd return &Shell{cmd: ec}
} }
// Shell invokes shell commands to talk with a remote credentials-helper. // Shell invokes shell commands to talk with a remote credentials-helper.

View File

@ -2,7 +2,9 @@
# This file lists all contributors to the repository. # This file lists all contributors to the repository.
# See hack/generate-authors.sh to make modifications. # See hack/generate-authors.sh to make modifications.
7sunarni <710720732@qq.com>
Aanand Prasad <aanand.prasad@gmail.com> Aanand Prasad <aanand.prasad@gmail.com>
Aarni Koskela <akx@iki.fi>
Aaron Davidson <aaron@databricks.com> Aaron Davidson <aaron@databricks.com>
Aaron Feng <aaron.feng@gmail.com> Aaron Feng <aaron.feng@gmail.com>
Aaron Hnatiw <aaron@griddio.com> Aaron Hnatiw <aaron@griddio.com>
@ -11,6 +13,7 @@ Aaron L. Xu <liker.xu@foxmail.com>
Aaron Lehmann <alehmann@netflix.com> Aaron Lehmann <alehmann@netflix.com>
Aaron Welch <welch@packet.net> Aaron Welch <welch@packet.net>
Aaron Yoshitake <airandfingers@gmail.com> Aaron Yoshitake <airandfingers@gmail.com>
Abdur Rehman <abdur_rehman@mentor.com>
Abel Muiño <amuino@gmail.com> Abel Muiño <amuino@gmail.com>
Abhijeet Kasurde <akasurde@redhat.com> Abhijeet Kasurde <akasurde@redhat.com>
Abhinandan Prativadi <aprativadi@gmail.com> Abhinandan Prativadi <aprativadi@gmail.com>
@ -24,9 +27,11 @@ Adam Avilla <aavilla@yp.com>
Adam Dobrawy <naczelnik@jawnosc.tk> Adam Dobrawy <naczelnik@jawnosc.tk>
Adam Eijdenberg <adam.eijdenberg@gmail.com> Adam Eijdenberg <adam.eijdenberg@gmail.com>
Adam Kunk <adam.kunk@tiaa-cref.org> Adam Kunk <adam.kunk@tiaa-cref.org>
Adam Lamers <adam.lamers@wmsdev.pl>
Adam Miller <admiller@redhat.com> Adam Miller <admiller@redhat.com>
Adam Mills <adam@armills.info> Adam Mills <adam@armills.info>
Adam Pointer <adam.pointer@skybettingandgaming.com> Adam Pointer <adam.pointer@skybettingandgaming.com>
Adam Simon <adamsimon85100@gmail.com>
Adam Singer <financeCoding@gmail.com> Adam Singer <financeCoding@gmail.com>
Adam Thornton <adam.thornton@maryville.com> Adam Thornton <adam.thornton@maryville.com>
Adam Walz <adam@adamwalz.net> Adam Walz <adam@adamwalz.net>
@ -119,6 +124,7 @@ amangoel <amangoel@gmail.com>
Amen Belayneh <amenbelayneh@gmail.com> Amen Belayneh <amenbelayneh@gmail.com>
Ameya Gawde <agawde@mirantis.com> Ameya Gawde <agawde@mirantis.com>
Amir Goldstein <amir73il@aquasec.com> Amir Goldstein <amir73il@aquasec.com>
AmirBuddy <badinlu.amirhossein@gmail.com>
Amit Bakshi <ambakshi@gmail.com> Amit Bakshi <ambakshi@gmail.com>
Amit Krishnan <amit.krishnan@oracle.com> Amit Krishnan <amit.krishnan@oracle.com>
Amit Shukla <amit.shukla@docker.com> Amit Shukla <amit.shukla@docker.com>
@ -168,6 +174,7 @@ Andrey Kolomentsev <andrey.kolomentsev@docker.com>
Andrey Petrov <andrey.petrov@shazow.net> Andrey Petrov <andrey.petrov@shazow.net>
Andrey Stolbovsky <andrey.stolbovsky@gmail.com> Andrey Stolbovsky <andrey.stolbovsky@gmail.com>
André Martins <aanm90@gmail.com> André Martins <aanm90@gmail.com>
Andrés Maldonado <maldonado@codelutin.com>
Andy Chambers <anchambers@paypal.com> Andy Chambers <anchambers@paypal.com>
andy diller <dillera@gmail.com> andy diller <dillera@gmail.com>
Andy Goldstein <agoldste@redhat.com> Andy Goldstein <agoldste@redhat.com>
@ -219,6 +226,7 @@ Artur Meyster <arthurfbi@yahoo.com>
Arun Gupta <arun.gupta@gmail.com> Arun Gupta <arun.gupta@gmail.com>
Asad Saeeduddin <masaeedu@gmail.com> Asad Saeeduddin <masaeedu@gmail.com>
Asbjørn Enge <asbjorn@hanafjedle.net> Asbjørn Enge <asbjorn@hanafjedle.net>
Ashly Mathew <ashly.mathew@sap.com>
Austin Vazquez <macedonv@amazon.com> Austin Vazquez <macedonv@amazon.com>
averagehuman <averagehuman@users.noreply.github.com> averagehuman <averagehuman@users.noreply.github.com>
Avi Das <andas222@gmail.com> Avi Das <andas222@gmail.com>
@ -345,6 +353,7 @@ Chance Zibolski <chance.zibolski@gmail.com>
Chander Govindarajan <chandergovind@gmail.com> Chander Govindarajan <chandergovind@gmail.com>
Chanhun Jeong <keyolk@gmail.com> Chanhun Jeong <keyolk@gmail.com>
Chao Wang <wangchao.fnst@cn.fujitsu.com> Chao Wang <wangchao.fnst@cn.fujitsu.com>
Charity Kathure <ckathure@microsoft.com>
Charles Chan <charleswhchan@users.noreply.github.com> Charles Chan <charleswhchan@users.noreply.github.com>
Charles Hooper <charles.hooper@dotcloud.com> Charles Hooper <charles.hooper@dotcloud.com>
Charles Law <claw@conduce.com> Charles Law <claw@conduce.com>
@ -480,6 +489,7 @@ Daniel Farrell <dfarrell@redhat.com>
Daniel Garcia <daniel@danielgarcia.info> Daniel Garcia <daniel@danielgarcia.info>
Daniel Gasienica <daniel@gasienica.ch> Daniel Gasienica <daniel@gasienica.ch>
Daniel Grunwell <mwgrunny@gmail.com> Daniel Grunwell <mwgrunny@gmail.com>
Daniel Guns <danbguns@gmail.com>
Daniel Helfand <helfand.4@gmail.com> Daniel Helfand <helfand.4@gmail.com>
Daniel Hiltgen <daniel.hiltgen@docker.com> Daniel Hiltgen <daniel.hiltgen@docker.com>
Daniel J Walsh <dwalsh@redhat.com> Daniel J Walsh <dwalsh@redhat.com>
@ -763,6 +773,7 @@ Frank Macreery <frank@macreery.com>
Frank Rosquin <frank.rosquin+github@gmail.com> Frank Rosquin <frank.rosquin+github@gmail.com>
Frank Villaro-Dixon <frank.villarodixon@merkle.com> Frank Villaro-Dixon <frank.villarodixon@merkle.com>
Frank Yang <yyb196@gmail.com> Frank Yang <yyb196@gmail.com>
François Scala <github@arcenik.net>
Fred Lifton <fred.lifton@docker.com> Fred Lifton <fred.lifton@docker.com>
Frederick F. Kautz IV <fkautz@redhat.com> Frederick F. Kautz IV <fkautz@redhat.com>
Frederico F. de Oliveira <FreddieOliveira@users.noreply.github.com> Frederico F. de Oliveira <FreddieOliveira@users.noreply.github.com>
@ -798,6 +809,7 @@ GennadySpb <lipenkov@gmail.com>
Geoff Levand <geoff@infradead.org> Geoff Levand <geoff@infradead.org>
Geoffrey Bachelet <grosfrais@gmail.com> Geoffrey Bachelet <grosfrais@gmail.com>
Geon Kim <geon0250@gmail.com> Geon Kim <geon0250@gmail.com>
George Adams <georgeadams1995@gmail.com>
George Kontridze <george@bugsnag.com> George Kontridze <george@bugsnag.com>
George Ma <mayangang@outlook.com> George Ma <mayangang@outlook.com>
George MacRorie <gmacr31@gmail.com> George MacRorie <gmacr31@gmail.com>
@ -826,6 +838,7 @@ Gopikannan Venugopalsamy <gopikannan.venugopalsamy@gmail.com>
Gosuke Miyashita <gosukenator@gmail.com> Gosuke Miyashita <gosukenator@gmail.com>
Gou Rao <gou@portworx.com> Gou Rao <gou@portworx.com>
Govinda Fichtner <govinda.fichtner@googlemail.com> Govinda Fichtner <govinda.fichtner@googlemail.com>
Grace Choi <grace.54109@gmail.com>
Grant Millar <rid@cylo.io> Grant Millar <rid@cylo.io>
Grant Reaber <grant.reaber@gmail.com> Grant Reaber <grant.reaber@gmail.com>
Graydon Hoare <graydon@pobox.com> Graydon Hoare <graydon@pobox.com>
@ -966,6 +979,7 @@ James Nugent <james@jen20.com>
James Sanders <james3sanders@gmail.com> James Sanders <james3sanders@gmail.com>
James Turnbull <james@lovedthanlost.net> James Turnbull <james@lovedthanlost.net>
James Watkins-Harvey <jwatkins@progi-media.com> James Watkins-Harvey <jwatkins@progi-media.com>
Jameson Hyde <jameson.hyde@docker.com>
Jamie Hannaford <jamie@limetree.org> Jamie Hannaford <jamie@limetree.org>
Jamshid Afshar <jafshar@yahoo.com> Jamshid Afshar <jafshar@yahoo.com>
Jan Breig <git@pygos.space> Jan Breig <git@pygos.space>
@ -1064,13 +1078,16 @@ Jim Perrin <jperrin@centos.org>
Jimmy Cuadra <jimmy@jimmycuadra.com> Jimmy Cuadra <jimmy@jimmycuadra.com>
Jimmy Puckett <jimmy.puckett@spinen.com> Jimmy Puckett <jimmy.puckett@spinen.com>
Jimmy Song <rootsongjc@gmail.com> Jimmy Song <rootsongjc@gmail.com>
jinjiadu <jinjiadu@aliyun.com>
Jinsoo Park <cellpjs@gmail.com> Jinsoo Park <cellpjs@gmail.com>
Jintao Zhang <zhangjintao9020@gmail.com> Jintao Zhang <zhangjintao9020@gmail.com>
Jiri Appl <jiria@microsoft.com> Jiri Appl <jiria@microsoft.com>
Jiri Popelka <jpopelka@redhat.com> Jiri Popelka <jpopelka@redhat.com>
Jiuyue Ma <majiuyue@huawei.com> Jiuyue Ma <majiuyue@huawei.com>
Jiří Župka <jzupka@redhat.com> Jiří Župka <jzupka@redhat.com>
jjimbo137 <115816493+jjimbo137@users.noreply.github.com>
Joakim Roubert <joakim.roubert@axis.com> Joakim Roubert <joakim.roubert@axis.com>
Joan Grau <grautxo.dev@proton.me>
Joao Fernandes <joao.fernandes@docker.com> Joao Fernandes <joao.fernandes@docker.com>
Joao Trindade <trindade.joao@gmail.com> Joao Trindade <trindade.joao@gmail.com>
Joe Beda <joe.github@bedafamily.com> Joe Beda <joe.github@bedafamily.com>
@ -1155,6 +1172,7 @@ Josiah Kiehl <jkiehl@riotgames.com>
José Tomás Albornoz <jojo@eljojo.net> José Tomás Albornoz <jojo@eljojo.net>
Joyce Jang <mail@joycejang.com> Joyce Jang <mail@joycejang.com>
JP <jpellerin@leapfrogonline.com> JP <jpellerin@leapfrogonline.com>
JSchltggr <jschltggr@gmail.com>
Julian Taylor <jtaylor.debian@googlemail.com> Julian Taylor <jtaylor.debian@googlemail.com>
Julien Barbier <write0@gmail.com> Julien Barbier <write0@gmail.com>
Julien Bisconti <veggiemonk@users.noreply.github.com> Julien Bisconti <veggiemonk@users.noreply.github.com>
@ -1289,6 +1307,7 @@ Laura Brehm <laurabrehm@hey.com>
Laura Frank <ljfrank@gmail.com> Laura Frank <ljfrank@gmail.com>
Laurent Bernaille <laurent.bernaille@datadoghq.com> Laurent Bernaille <laurent.bernaille@datadoghq.com>
Laurent Erignoux <lerignoux@gmail.com> Laurent Erignoux <lerignoux@gmail.com>
Laurent Goderre <laurent.goderre@docker.com>
Laurie Voss <github@seldo.com> Laurie Voss <github@seldo.com>
Leandro Motta Barros <lmb@stackedboxes.org> Leandro Motta Barros <lmb@stackedboxes.org>
Leandro Siqueira <leandro.siqueira@gmail.com> Leandro Siqueira <leandro.siqueira@gmail.com>
@ -1369,6 +1388,7 @@ Madhan Raj Mookkandy <MadhanRaj.Mookkandy@microsoft.com>
Madhav Puri <madhav.puri@gmail.com> Madhav Puri <madhav.puri@gmail.com>
Madhu Venugopal <mavenugo@gmail.com> Madhu Venugopal <mavenugo@gmail.com>
Mageee <fangpuyi@foxmail.com> Mageee <fangpuyi@foxmail.com>
maggie44 <64841595+maggie44@users.noreply.github.com>
Mahesh Tiyyagura <tmahesh@gmail.com> Mahesh Tiyyagura <tmahesh@gmail.com>
malnick <malnick@gmail..com> malnick <malnick@gmail..com>
Malte Janduda <mail@janduda.net> Malte Janduda <mail@janduda.net>
@ -1579,6 +1599,7 @@ Muayyad Alsadi <alsadi@gmail.com>
Muhammad Zohaib Aslam <zohaibse011@gmail.com> Muhammad Zohaib Aslam <zohaibse011@gmail.com>
Mustafa Akın <mustafa91@gmail.com> Mustafa Akın <mustafa91@gmail.com>
Muthukumar R <muthur@gmail.com> Muthukumar R <muthur@gmail.com>
Myeongjoon Kim <kimmj8409@gmail.com>
Máximo Cuadros <mcuadros@gmail.com> Máximo Cuadros <mcuadros@gmail.com>
Médi-Rémi Hashim <medimatrix@users.noreply.github.com> Médi-Rémi Hashim <medimatrix@users.noreply.github.com>
Nace Oroz <orkica@gmail.com> Nace Oroz <orkica@gmail.com>
@ -1593,6 +1614,7 @@ Natasha Jarus <linuxmercedes@gmail.com>
Nate Brennand <nate.brennand@clever.com> Nate Brennand <nate.brennand@clever.com>
Nate Eagleson <nate@nateeag.com> Nate Eagleson <nate@nateeag.com>
Nate Jones <nate@endot.org> Nate Jones <nate@endot.org>
Nathan Baulch <nathan.baulch@gmail.com>
Nathan Carlson <carl4403@umn.edu> Nathan Carlson <carl4403@umn.edu>
Nathan Herald <me@nathanherald.com> Nathan Herald <me@nathanherald.com>
Nathan Hsieh <hsieh.nathan@gmail.com> Nathan Hsieh <hsieh.nathan@gmail.com>
@ -1655,6 +1677,7 @@ Nuutti Kotivuori <naked@iki.fi>
nzwsch <hi@nzwsch.com> nzwsch <hi@nzwsch.com>
O.S. Tezer <ostezer@gmail.com> O.S. Tezer <ostezer@gmail.com>
objectified <objectified@gmail.com> objectified <objectified@gmail.com>
Octol1ttle <l1ttleofficial@outlook.com>
Odin Ugedal <odin@ugedal.com> Odin Ugedal <odin@ugedal.com>
Oguz Bilgic <fisyonet@gmail.com> Oguz Bilgic <fisyonet@gmail.com>
Oh Jinkyun <tintypemolly@gmail.com> Oh Jinkyun <tintypemolly@gmail.com>
@ -1763,6 +1786,7 @@ Pierre Carrier <pierre@meteor.com>
Pierre Dal-Pra <dalpra.pierre@gmail.com> Pierre Dal-Pra <dalpra.pierre@gmail.com>
Pierre Wacrenier <pierre.wacrenier@gmail.com> Pierre Wacrenier <pierre.wacrenier@gmail.com>
Pierre-Alain RIVIERE <pariviere@ippon.fr> Pierre-Alain RIVIERE <pariviere@ippon.fr>
pinglanlu <pinglanlu@outlook.com>
Piotr Bogdan <ppbogdan@gmail.com> Piotr Bogdan <ppbogdan@gmail.com>
Piotr Karbowski <piotr.karbowski@protonmail.ch> Piotr Karbowski <piotr.karbowski@protonmail.ch>
Porjo <porjo38@yahoo.com.au> Porjo <porjo38@yahoo.com.au>
@ -1790,6 +1814,7 @@ Quentin Tayssier <qtayssier@gmail.com>
r0n22 <cameron.regan@gmail.com> r0n22 <cameron.regan@gmail.com>
Rachit Sharma <rachitsharma613@gmail.com> Rachit Sharma <rachitsharma613@gmail.com>
Radostin Stoyanov <rstoyanov1@gmail.com> Radostin Stoyanov <rstoyanov1@gmail.com>
Rafael Fernández López <ereslibre@ereslibre.es>
Rafal Jeczalik <rjeczalik@gmail.com> Rafal Jeczalik <rjeczalik@gmail.com>
Rafe Colton <rafael.colton@gmail.com> Rafe Colton <rafael.colton@gmail.com>
Raghavendra K T <raghavendra.kt@linux.vnet.ibm.com> Raghavendra K T <raghavendra.kt@linux.vnet.ibm.com>
@ -1856,7 +1881,7 @@ Robin Speekenbrink <robin@kingsquare.nl>
Robin Thoni <robin@rthoni.com> Robin Thoni <robin@rthoni.com>
robpc <rpcann@gmail.com> robpc <rpcann@gmail.com>
Rodolfo Carvalho <rhcarvalho@gmail.com> Rodolfo Carvalho <rhcarvalho@gmail.com>
Rodrigo Campos <rodrigo@kinvolk.io> Rodrigo Campos <rodrigoca@microsoft.com>
Rodrigo Vaz <rodrigo.vaz@gmail.com> Rodrigo Vaz <rodrigo.vaz@gmail.com>
Roel Van Nyen <roel.vannyen@gmail.com> Roel Van Nyen <roel.vannyen@gmail.com>
Roger Peppe <rogpeppe@gmail.com> Roger Peppe <rogpeppe@gmail.com>
@ -1995,6 +2020,7 @@ Sevki Hasirci <s@sevki.org>
Shane Canon <scanon@lbl.gov> Shane Canon <scanon@lbl.gov>
Shane da Silva <shane@dasilva.io> Shane da Silva <shane@dasilva.io>
Shaun Kaasten <shaunk@gmail.com> Shaun Kaasten <shaunk@gmail.com>
Shaun Thompson <shaun.thompson@docker.com>
shaunol <shaunol@gmail.com> shaunol <shaunol@gmail.com>
Shawn Landden <shawn@churchofgit.com> Shawn Landden <shawn@churchofgit.com>
Shawn Siefkas <shawn.siefkas@meredith.com> Shawn Siefkas <shawn.siefkas@meredith.com>
@ -2013,6 +2039,7 @@ Shijun Qin <qinshijun16@mails.ucas.ac.cn>
Shishir Mahajan <shishir.mahajan@redhat.com> Shishir Mahajan <shishir.mahajan@redhat.com>
Shoubhik Bose <sbose78@gmail.com> Shoubhik Bose <sbose78@gmail.com>
Shourya Sarcar <shourya.sarcar@gmail.com> Shourya Sarcar <shourya.sarcar@gmail.com>
Shreenidhi Shedi <shreenidhi.shedi@broadcom.com>
Shu-Wai Chow <shu-wai.chow@seattlechildrens.org> Shu-Wai Chow <shu-wai.chow@seattlechildrens.org>
shuai-z <zs.broccoli@gmail.com> shuai-z <zs.broccoli@gmail.com>
Shukui Yang <yangshukui@huawei.com> Shukui Yang <yangshukui@huawei.com>
@ -2100,6 +2127,7 @@ Sébastien Stormacq <sebsto@users.noreply.github.com>
Sören Tempel <soeren+git@soeren-tempel.net> Sören Tempel <soeren+git@soeren-tempel.net>
Tabakhase <mail@tabakhase.com> Tabakhase <mail@tabakhase.com>
Tadej Janež <tadej.j@nez.si> Tadej Janež <tadej.j@nez.si>
Tadeusz Dudkiewicz <tadeusz.dudkiewicz@rtbhouse.com>
Takuto Sato <tockn.jp@gmail.com> Takuto Sato <tockn.jp@gmail.com>
tang0th <tang0th@gmx.com> tang0th <tang0th@gmx.com>
Tangi Colin <tangicolin@gmail.com> Tangi Colin <tangicolin@gmail.com>
@ -2107,6 +2135,7 @@ Tatsuki Sugiura <sugi@nemui.org>
Tatsushi Inagaki <e29253@jp.ibm.com> Tatsushi Inagaki <e29253@jp.ibm.com>
Taylan Isikdemir <taylani@google.com> Taylan Isikdemir <taylani@google.com>
Taylor Jones <monitorjbl@gmail.com> Taylor Jones <monitorjbl@gmail.com>
tcpdumppy <847462026@qq.com>
Ted M. Young <tedyoung@gmail.com> Ted M. Young <tedyoung@gmail.com>
Tehmasp Chaudhri <tehmasp@gmail.com> Tehmasp Chaudhri <tehmasp@gmail.com>
Tejaswini Duggaraju <naduggar@microsoft.com> Tejaswini Duggaraju <naduggar@microsoft.com>
@ -2391,6 +2420,7 @@ You-Sheng Yang (楊有勝) <vicamo@gmail.com>
youcai <omegacoleman@gmail.com> youcai <omegacoleman@gmail.com>
Youcef YEKHLEF <yyekhlef@gmail.com> Youcef YEKHLEF <yyekhlef@gmail.com>
Youfu Zhang <zhangyoufu@gmail.com> Youfu Zhang <zhangyoufu@gmail.com>
YR Chen <stevapple@icloud.com>
Yu Changchun <yuchangchun1@huawei.com> Yu Changchun <yuchangchun1@huawei.com>
Yu Chengxia <yuchengxia@huawei.com> Yu Chengxia <yuchengxia@huawei.com>
Yu Peng <yu.peng36@zte.com.cn> Yu Peng <yu.peng36@zte.com.cn>

View File

@ -3,7 +3,7 @@ package api // import "github.com/docker/docker/api"
// Common constants for daemon and client. // Common constants for daemon and client.
const ( const (
// DefaultVersion of the current REST API. // DefaultVersion of the current REST API.
DefaultVersion = "1.47" DefaultVersion = "1.48"
// MinSupportedAPIVersion is the minimum API version that can be supported // MinSupportedAPIVersion is the minimum API version that can be supported
// by the API server, specified as "major.minor". Note that the daemon // by the API server, specified as "major.minor". Note that the daemon

File diff suppressed because it is too large Load Diff

View File

@ -92,6 +92,13 @@ type ContainerStatsConfig struct {
OutStream func() io.Writer OutStream func() io.Writer
} }
// ContainerInspectOptions defines options for the backend.ContainerInspect
// call.
type ContainerInspectOptions struct {
// Size controls whether to propagate the container's size fields.
Size bool
}
// ExecStartConfig holds the options to start container's exec. // ExecStartConfig holds the options to start container's exec.
type ExecStartConfig struct { type ExecStartConfig struct {
Stdin io.Reader Stdin io.Reader
@ -141,7 +148,11 @@ type CreateImageConfig struct {
// from the backend. // from the backend.
type GetImageOpts struct { type GetImageOpts struct {
Platform *ocispec.Platform Platform *ocispec.Platform
Details bool }
// ImageInspectOpts holds parameters to inspect an image.
type ImageInspectOpts struct {
Manifests bool
} }
// CommitConfig is the configuration for creating an image as part of a build. // CommitConfig is the configuration for creating an image as part of a build.

View File

@ -11,7 +11,7 @@ import (
"github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/registry"
) )
// NewHijackedResponse intializes a HijackedResponse type // NewHijackedResponse initializes a [HijackedResponse] type.
func NewHijackedResponse(conn net.Conn, mediaType string) HijackedResponse { func NewHijackedResponse(conn net.Conn, mediaType string) HijackedResponse {
return HijackedResponse{Conn: conn, Reader: bufio.NewReader(conn), mediaType: mediaType} return HijackedResponse{Conn: conn, Reader: bufio.NewReader(conn), mediaType: mediaType}
} }
@ -129,14 +129,6 @@ type ImageBuildResponse struct {
OSType string OSType string
} }
// RequestPrivilegeFunc is a function interface that
// clients can supply to retry operations after
// getting an authorization error.
// This function returns the registry authentication
// header value in base 64 format, or an error
// if the privilege request fails.
type RequestPrivilegeFunc func(context.Context) (string, error)
// NodeListOptions holds parameters to list nodes with. // NodeListOptions holds parameters to list nodes with.
type NodeListOptions struct { type NodeListOptions struct {
Filters filters.Args Filters filters.Args
@ -235,11 +227,18 @@ type PluginDisableOptions struct {
// PluginInstallOptions holds parameters to install a plugin. // PluginInstallOptions holds parameters to install a plugin.
type PluginInstallOptions struct { type PluginInstallOptions struct {
Disabled bool Disabled bool
AcceptAllPermissions bool AcceptAllPermissions bool
RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry
RemoteRef string // RemoteRef is the plugin name on the registry RemoteRef string // RemoteRef is the plugin name on the registry
PrivilegeFunc RequestPrivilegeFunc
// PrivilegeFunc is a function that clients can supply to retry operations
// after getting an authorization error. This function returns the registry
// authentication header value in base64 encoded format, or an error if the
// privilege request fails.
//
// For details, refer to [github.com/docker/docker/api/types/registry.RequestAuthConfig].
PrivilegeFunc func(context.Context) (string, error)
AcceptPermissionsFunc func(context.Context, PluginPrivileges) (bool, error) AcceptPermissionsFunc func(context.Context, PluginPrivileges) (bool, error)
Args []string Args []string
} }

View File

@ -1,10 +1,10 @@
package types package common
// This file was generated by the swagger tool. // This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command // Editing this file might prove futile when you re-run the swagger generate command
// IDResponse Response to an API call that returns just an Id // IDResponse Response to an API call that returns just an Id
// swagger:model IdResponse // swagger:model IDResponse
type IDResponse struct { type IDResponse struct {
// The id of the newly created object. // The id of the newly created object.

View File

@ -0,0 +1,7 @@
package container
import "github.com/docker/docker/api/types/common"
// CommitResponse response for the commit API call, containing the ID of the
// image that was produced.
type CommitResponse = common.IDResponse

View File

@ -4,8 +4,22 @@ import (
"io" "io"
"os" "os"
"time" "time"
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/storage"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
) )
// ContainerUpdateOKBody OK response to ContainerUpdate operation
//
// Deprecated: use [UpdateResponse]. This alias will be removed in the next release.
type ContainerUpdateOKBody = UpdateResponse
// ContainerTopOKBody OK response to ContainerTop operation
//
// Deprecated: use [TopResponse]. This alias will be removed in the next release.
type ContainerTopOKBody = TopResponse
// PruneReport contains the response for Engine API: // PruneReport contains the response for Engine API:
// POST "/containers/prune" // POST "/containers/prune"
type PruneReport struct { type PruneReport struct {
@ -42,3 +56,133 @@ type StatsResponseReader struct {
Body io.ReadCloser `json:"body"` Body io.ReadCloser `json:"body"`
OSType string `json:"ostype"` OSType string `json:"ostype"`
} }
// MountPoint represents a mount point configuration inside the container.
// This is used for reporting the mountpoints in use by a container.
type MountPoint struct {
// Type is the type of mount, see `Type<foo>` definitions in
// github.com/docker/docker/api/types/mount.Type
Type mount.Type `json:",omitempty"`
// Name is the name reference to the underlying data defined by `Source`
// e.g., the volume name.
Name string `json:",omitempty"`
// Source is the source location of the mount.
//
// For volumes, this contains the storage location of the volume (within
// `/var/lib/docker/volumes/`). For bind-mounts, and `npipe`, this contains
// the source (host) part of the bind-mount. For `tmpfs` mount points, this
// field is empty.
Source string
// Destination is the path relative to the container root (`/`) where the
// Source is mounted inside the container.
Destination string
// Driver is the volume driver used to create the volume (if it is a volume).
Driver string `json:",omitempty"`
// Mode is a comma separated list of options supplied by the user when
// creating the bind/volume mount.
//
// The default is platform-specific (`"z"` on Linux, empty on Windows).
Mode string
// RW indicates whether the mount is mounted writable (read-write).
RW bool
// Propagation describes how mounts are propagated from the host into the
// mount point, and vice-versa. Refer to the Linux kernel documentation
// for details:
// https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt
//
// This field is not used on Windows.
Propagation mount.Propagation
}
// State stores container's running state
// it's part of ContainerJSONBase and returned by "inspect" command
type State struct {
Status string // String representation of the container state. Can be one of "created", "running", "paused", "restarting", "removing", "exited", or "dead"
Running bool
Paused bool
Restarting bool
OOMKilled bool
Dead bool
Pid int
ExitCode int
Error string
StartedAt string
FinishedAt string
Health *Health `json:",omitempty"`
}
// Summary contains response of Engine API:
// GET "/containers/json"
type Summary struct {
ID string `json:"Id"`
Names []string
Image string
ImageID string
ImageManifestDescriptor *ocispec.Descriptor `json:"ImageManifestDescriptor,omitempty"`
Command string
Created int64
Ports []Port
SizeRw int64 `json:",omitempty"`
SizeRootFs int64 `json:",omitempty"`
Labels map[string]string
State string
Status string
HostConfig struct {
NetworkMode string `json:",omitempty"`
Annotations map[string]string `json:",omitempty"`
}
NetworkSettings *NetworkSettingsSummary
Mounts []MountPoint
}
// ContainerJSONBase contains response of Engine API GET "/containers/{name:.*}/json"
// for API version 1.18 and older.
//
// TODO(thaJeztah): combine ContainerJSONBase and InspectResponse into a single struct.
// The split between ContainerJSONBase (ContainerJSONBase) and InspectResponse (InspectResponse)
// was done in commit 6deaa58ba5f051039643cedceee97c8695e2af74 (https://github.com/moby/moby/pull/13675).
// ContainerJSONBase contained all fields for API < 1.19, and InspectResponse
// held fields that were added in API 1.19 and up. Given that the minimum
// supported API version is now 1.24, we no longer use the separate type.
type ContainerJSONBase struct {
ID string `json:"Id"`
Created string
Path string
Args []string
State *State
Image string
ResolvConfPath string
HostnamePath string
HostsPath string
LogPath string
Name string
RestartCount int
Driver string
Platform string
MountLabel string
ProcessLabel string
AppArmorProfile string
ExecIDs []string
HostConfig *HostConfig
GraphDriver storage.DriverData
SizeRw *int64 `json:",omitempty"`
SizeRootFs *int64 `json:",omitempty"`
}
// InspectResponse is the response for the GET "/containers/{name:.*}/json"
// endpoint.
type InspectResponse struct {
*ContainerJSONBase
Mounts []MountPoint
Config *Config
NetworkSettings *NetworkSettings
// ImageManifestDescriptor is the descriptor of a platform-specific manifest of the image used to create the container.
ImageManifestDescriptor *ocispec.Descriptor `json:"ImageManifestDescriptor,omitempty"`
}

View File

@ -1,22 +0,0 @@
package container // import "github.com/docker/docker/api/types/container"
// ----------------------------------------------------------------------------
// Code generated by `swagger generate operation`. DO NOT EDIT.
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------
// ContainerTopOKBody OK response to ContainerTop operation
// swagger:model ContainerTopOKBody
type ContainerTopOKBody struct {
// Each process running in the container, where each is process
// is an array of values corresponding to the titles.
//
// Required: true
Processes [][]string `json:"Processes"`
// The ps column titles
// Required: true
Titles []string `json:"Titles"`
}

View File

@ -1,16 +0,0 @@
package container // import "github.com/docker/docker/api/types/container"
// ----------------------------------------------------------------------------
// Code generated by `swagger generate operation`. DO NOT EDIT.
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------
// ContainerUpdateOKBody OK response to ContainerUpdate operation
// swagger:model ContainerUpdateOKBody
type ContainerUpdateOKBody struct {
// warnings
// Required: true
Warnings []string `json:"Warnings"`
}

View File

@ -1,5 +1,13 @@
package container package container
import "github.com/docker/docker/api/types/common"
// ExecCreateResponse is the response for a successful exec-create request.
// It holds the ID of the exec that was created.
//
// TODO(thaJeztah): make this a distinct type.
type ExecCreateResponse = common.IDResponse
// ExecOptions is a small subset of the Config struct that holds the configuration // ExecOptions is a small subset of the Config struct that holds the configuration
// for the exec feature of docker. // for the exec feature of docker.
type ExecOptions struct { type ExecOptions struct {

View File

@ -0,0 +1,26 @@
package container
import "time"
// Health states
const (
NoHealthcheck = "none" // Indicates there is no healthcheck
Starting = "starting" // Starting indicates that the container is not yet ready
Healthy = "healthy" // Healthy indicates that the container is running correctly
Unhealthy = "unhealthy" // Unhealthy indicates that the container has a problem
)
// Health stores information about the container's healthcheck results
type Health struct {
Status string // Status is one of [Starting], [Healthy] or [Unhealthy].
FailingStreak int // FailingStreak is the number of consecutive failures
Log []*HealthcheckResult // Log contains the last few results (oldest first)
}
// HealthcheckResult stores information about a single run of a healthcheck probe
type HealthcheckResult struct {
Start time.Time // Start is the time this check started
End time.Time // End is the time this check ended
ExitCode int // ExitCode meanings: 0=healthy, 1=unhealthy, 2=reserved (considered unhealthy), else=error running probe
Output string // Output from last check
}

View File

@ -0,0 +1,56 @@
package container
import (
"github.com/docker/docker/api/types/network"
"github.com/docker/go-connections/nat"
)
// NetworkSettings exposes the network settings in the api
type NetworkSettings struct {
NetworkSettingsBase
DefaultNetworkSettings
Networks map[string]*network.EndpointSettings
}
// NetworkSettingsBase holds networking state for a container when inspecting it.
type NetworkSettingsBase struct {
Bridge string // Bridge contains the name of the default bridge interface iff it was set through the daemon --bridge flag.
SandboxID string // SandboxID uniquely represents a container's network stack
SandboxKey string // SandboxKey identifies the sandbox
Ports nat.PortMap // Ports is a collection of PortBinding indexed by Port
// HairpinMode specifies if hairpin NAT should be enabled on the virtual interface
//
// Deprecated: This field is never set and will be removed in a future release.
HairpinMode bool
// LinkLocalIPv6Address is an IPv6 unicast address using the link-local prefix
//
// Deprecated: This field is never set and will be removed in a future release.
LinkLocalIPv6Address string
// LinkLocalIPv6PrefixLen is the prefix length of an IPv6 unicast address
//
// Deprecated: This field is never set and will be removed in a future release.
LinkLocalIPv6PrefixLen int
SecondaryIPAddresses []network.Address // Deprecated: This field is never set and will be removed in a future release.
SecondaryIPv6Addresses []network.Address // Deprecated: This field is never set and will be removed in a future release.
}
// DefaultNetworkSettings holds network information
// during the 2 release deprecation period.
// It will be removed in Docker 1.11.
type DefaultNetworkSettings struct {
EndpointID string // EndpointID uniquely represents a service endpoint in a Sandbox
Gateway string // Gateway holds the gateway address for the network
GlobalIPv6Address string // GlobalIPv6Address holds network's global IPv6 address
GlobalIPv6PrefixLen int // GlobalIPv6PrefixLen represents mask length of network's global IPv6 address
IPAddress string // IPAddress holds the IPv4 address for the network
IPPrefixLen int // IPPrefixLen represents mask length of network's IPv4 address
IPv6Gateway string // IPv6Gateway holds gateway address specific for IPv6
MacAddress string // MacAddress holds the MAC address for the network
}
// NetworkSettingsSummary provides a summary of container's networks
// in /containers/json
type NetworkSettingsSummary struct {
Networks map[string]*network.EndpointSettings
}

View File

@ -1,4 +1,4 @@
package types package container
// This file was generated by the swagger tool. // This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command // Editing this file might prove futile when you re-run the swagger generate command

View File

@ -148,7 +148,15 @@ type PidsStats struct {
} }
// Stats is Ultimate struct aggregating all types of stats of one container // Stats is Ultimate struct aggregating all types of stats of one container
type Stats struct { //
// Deprecated: use [StatsResponse] instead. This type will be removed in the next release.
type Stats = StatsResponse
// StatsResponse aggregates all types of stats of one container.
type StatsResponse struct {
Name string `json:"name,omitempty"`
ID string `json:"id,omitempty"`
// Common stats // Common stats
Read time.Time `json:"read"` Read time.Time `json:"read"`
PreRead time.Time `json:"preread"` PreRead time.Time `json:"preread"`
@ -162,20 +170,8 @@ type Stats struct {
StorageStats StorageStats `json:"storage_stats,omitempty"` StorageStats StorageStats `json:"storage_stats,omitempty"`
// Shared stats // Shared stats
CPUStats CPUStats `json:"cpu_stats,omitempty"` CPUStats CPUStats `json:"cpu_stats,omitempty"`
PreCPUStats CPUStats `json:"precpu_stats,omitempty"` // "Pre"="Previous" PreCPUStats CPUStats `json:"precpu_stats,omitempty"` // "Pre"="Previous"
MemoryStats MemoryStats `json:"memory_stats,omitempty"` MemoryStats MemoryStats `json:"memory_stats,omitempty"`
} Networks map[string]NetworkStats `json:"networks,omitempty"`
// StatsResponse is newly used Networks.
//
// TODO(thaJeztah): unify with [Stats]. This wrapper was to account for pre-api v1.21 changes, see https://github.com/moby/moby/commit/d3379946ec96fb6163cb8c4517d7d5a067045801
type StatsResponse struct {
Stats
Name string `json:"name,omitempty"`
ID string `json:"id,omitempty"`
// Networks request version >=1.21
Networks map[string]NetworkStats `json:"networks,omitempty"`
} }

View File

@ -0,0 +1,18 @@
package container
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
// TopResponse ContainerTopResponse
//
// Container "top" response.
// swagger:model TopResponse
type TopResponse struct {
// Each process running in the container, where each process
// is an array of values corresponding to the titles.
Processes [][]string `json:"Processes"`
// The ps column titles
Titles []string `json:"Titles"`
}

View File

@ -0,0 +1,14 @@
package container
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
// UpdateResponse ContainerUpdateResponse
//
// Response for a successful container-update.
// swagger:model UpdateResponse
type UpdateResponse struct {
// Warnings encountered when updating the container.
Warnings []string `json:"Warnings"`
}

View File

@ -22,16 +22,3 @@ func (e invalidFilter) Error() string {
// InvalidParameter marks this error as ErrInvalidParameter // InvalidParameter marks this error as ErrInvalidParameter
func (e invalidFilter) InvalidParameter() {} func (e invalidFilter) InvalidParameter() {}
// unreachableCode is an error indicating that the code path was not expected to be reached.
type unreachableCode struct {
Filter string
Value []string
}
// System marks this error as ErrSystem
func (e unreachableCode) System() {}
func (e unreachableCode) Error() string {
return fmt.Sprintf("unreachable code reached for filter: %q with values: %s", e.Filter, e.Value)
}

View File

@ -200,7 +200,6 @@ func (args Args) Match(field, source string) bool {
// Error is not nil only if the filter values are not valid boolean or are conflicting. // Error is not nil only if the filter values are not valid boolean or are conflicting.
func (args Args) GetBoolOrDefault(key string, defaultValue bool) (bool, error) { func (args Args) GetBoolOrDefault(key string, defaultValue bool) (bool, error) {
fieldValues, ok := args.fields[key] fieldValues, ok := args.fields[key]
if !ok { if !ok {
return defaultValue, nil return defaultValue, nil
} }
@ -211,20 +210,11 @@ func (args Args) GetBoolOrDefault(key string, defaultValue bool) (bool, error) {
isFalse := fieldValues["0"] || fieldValues["false"] isFalse := fieldValues["0"] || fieldValues["false"]
isTrue := fieldValues["1"] || fieldValues["true"] isTrue := fieldValues["1"] || fieldValues["true"]
if isFalse == isTrue {
conflicting := isFalse && isTrue // Either no or conflicting truthy/falsy value were provided
invalid := !isFalse && !isTrue
if conflicting || invalid {
return defaultValue, &invalidFilter{key, args.Get(key)} return defaultValue, &invalidFilter{key, args.Get(key)}
} else if isFalse {
return false, nil
} else if isTrue {
return true, nil
} }
return isTrue, nil
// This code shouldn't be reached.
return defaultValue, &unreachableCode{Filter: key, Value: args.Get(key)}
} }
// ExactMatch returns true if the source matches exactly one of the values. // ExactMatch returns true if the source matches exactly one of the values.

View File

@ -0,0 +1,140 @@
package image
import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/storage"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// RootFS returns Image's RootFS description including the layer IDs.
type RootFS struct {
Type string `json:",omitempty"`
Layers []string `json:",omitempty"`
}
// InspectResponse contains response of Engine API:
// GET "/images/{name:.*}/json"
type InspectResponse struct {
// ID is the content-addressable ID of an image.
//
// This identifier is a content-addressable digest calculated from the
// image's configuration (which includes the digests of layers used by
// the image).
//
// Note that this digest differs from the `RepoDigests` below, which
// holds digests of image manifests that reference the image.
ID string `json:"Id"`
// RepoTags is a list of image names/tags in the local image cache that
// reference this image.
//
// Multiple image tags can refer to the same image, and this list may be
// empty if no tags reference the image, in which case the image is
// "untagged", in which case it can still be referenced by its ID.
RepoTags []string
// RepoDigests is a list of content-addressable digests of locally available
// image manifests that the image is referenced from. Multiple manifests can
// refer to the same image.
//
// These digests are usually only available if the image was either pulled
// from a registry, or if the image was pushed to a registry, which is when
// the manifest is generated and its digest calculated.
RepoDigests []string
// Parent is the ID of the parent image.
//
// Depending on how the image was created, this field may be empty and
// is only set for images that were built/created locally. This field
// is empty if the image was pulled from an image registry.
Parent string
// Comment is an optional message that can be set when committing or
// importing the image.
Comment string
// Created is the date and time at which the image was created, formatted in
// RFC 3339 nano-seconds (time.RFC3339Nano).
//
// This information is only available if present in the image,
// and omitted otherwise.
Created string `json:",omitempty"`
// Container is the ID of the container that was used to create the image.
//
// Depending on how the image was created, this field may be empty.
//
// Deprecated: this field is omitted in API v1.45, but kept for backward compatibility.
Container string `json:",omitempty"`
// ContainerConfig is an optional field containing the configuration of the
// container that was last committed when creating the image.
//
// Previous versions of Docker builder used this field to store build cache,
// and it is not in active use anymore.
//
// Deprecated: this field is omitted in API v1.45, but kept for backward compatibility.
ContainerConfig *container.Config `json:",omitempty"`
// DockerVersion is the version of Docker that was used to build the image.
//
// Depending on how the image was created, this field may be empty.
DockerVersion string
// Author is the name of the author that was specified when committing the
// image, or as specified through MAINTAINER (deprecated) in the Dockerfile.
Author string
Config *container.Config
// Architecture is the hardware CPU architecture that the image runs on.
Architecture string
// Variant is the CPU architecture variant (presently ARM-only).
Variant string `json:",omitempty"`
// OS is the Operating System the image is built to run on.
Os string
// OsVersion is the version of the Operating System the image is built to
// run on (especially for Windows).
OsVersion string `json:",omitempty"`
// Size is the total size of the image including all layers it is composed of.
Size int64
// VirtualSize is the total size of the image including all layers it is
// composed of.
//
// Deprecated: this field is omitted in API v1.44, but kept for backward compatibility. Use Size instead.
VirtualSize int64 `json:"VirtualSize,omitempty"`
// GraphDriver holds information about the storage driver used to store the
// container's and image's filesystem.
GraphDriver storage.DriverData
// RootFS contains information about the image's RootFS, including the
// layer IDs.
RootFS RootFS
// Metadata of the image in the local cache.
//
// This information is local to the daemon, and not part of the image itself.
Metadata Metadata
// Descriptor is the OCI descriptor of the image target.
// It's only set if the daemon provides a multi-platform image store.
//
// WARNING: This is experimental and may change at any time without any backward
// compatibility.
Descriptor *ocispec.Descriptor `json:"Descriptor,omitempty"`
// Manifests is a list of image manifests available in this image. It
// provides a more detailed view of the platform-specific image manifests or
// other image-attached data like build attestations.
//
// Only available if the daemon provides a multi-platform image store.
//
// WARNING: This is experimental and may change at any time without any backward
// compatibility.
Manifests []ManifestSummary `json:"Manifests,omitempty"`
}

View File

@ -38,7 +38,7 @@ type PullOptions struct {
// authentication header value in base64 encoded format, or an error if the // authentication header value in base64 encoded format, or an error if the
// privilege request fails. // privilege request fails.
// //
// Also see [github.com/docker/docker/api/types.RequestPrivilegeFunc]. // For details, refer to [github.com/docker/docker/api/types/registry.RequestAuthConfig].
PrivilegeFunc func(context.Context) (string, error) PrivilegeFunc func(context.Context) (string, error)
Platform string Platform string
} }
@ -53,7 +53,7 @@ type PushOptions struct {
// authentication header value in base64 encoded format, or an error if the // authentication header value in base64 encoded format, or an error if the
// privilege request fails. // privilege request fails.
// //
// Also see [github.com/docker/docker/api/types.RequestPrivilegeFunc]. // For details, refer to [github.com/docker/docker/api/types/registry.RequestAuthConfig].
PrivilegeFunc func(context.Context) (string, error) PrivilegeFunc func(context.Context) (string, error)
// Platform is an optional field that selects a specific platform to push // Platform is an optional field that selects a specific platform to push
@ -86,3 +86,31 @@ type RemoveOptions struct {
Force bool Force bool
PruneChildren bool PruneChildren bool
} }
// HistoryOptions holds parameters to get image history.
type HistoryOptions struct {
// Platform from the manifest list to use for history.
Platform *ocispec.Platform
}
// LoadOptions holds parameters to load images.
type LoadOptions struct {
// Quiet suppresses progress output
Quiet bool
// Platforms selects the platforms to load if the image is a
// multi-platform image and has multiple variants.
Platforms []ocispec.Platform
}
type InspectOptions struct {
// Manifests returns the image manifests.
Manifests bool
}
// SaveOptions holds parameters to save images.
type SaveOptions struct {
// Platforms selects the platforms to save if the image is a
// multi-platform image and has multiple variants.
Platforms []ocispec.Platform
}

View File

@ -1,5 +1,7 @@
package image package image
import ocispec "github.com/opencontainers/image-spec/specs-go/v1"
type Summary struct { type Summary struct {
// Number of containers using this image. Includes both stopped and running // Number of containers using this image. Includes both stopped and running
@ -42,6 +44,13 @@ type Summary struct {
// Required: true // Required: true
ParentID string `json:"ParentId"` ParentID string `json:"ParentId"`
// Descriptor is the OCI descriptor of the image target.
// It's only set if the daemon provides a multi-platform image store.
//
// WARNING: This is experimental and may change at any time without any backward
// compatibility.
Descriptor *ocispec.Descriptor `json:"Descriptor,omitempty"`
// Manifests is a list of image manifests available in this image. It // Manifests is a list of image manifests available in this image. It
// provides a more detailed view of the platform-specific image manifests or // provides a more detailed view of the platform-specific image manifests or
// other image-attached data like build attestations. // other image-attached data like build attestations.

View File

@ -19,6 +19,8 @@ const (
TypeNamedPipe Type = "npipe" TypeNamedPipe Type = "npipe"
// TypeCluster is the type for Swarm Cluster Volumes. // TypeCluster is the type for Swarm Cluster Volumes.
TypeCluster Type = "cluster" TypeCluster Type = "cluster"
// TypeImage is the type for mounting another image's filesystem
TypeImage Type = "image"
) )
// Mount represents a mount (volume). // Mount represents a mount (volume).
@ -34,6 +36,7 @@ type Mount struct {
BindOptions *BindOptions `json:",omitempty"` BindOptions *BindOptions `json:",omitempty"`
VolumeOptions *VolumeOptions `json:",omitempty"` VolumeOptions *VolumeOptions `json:",omitempty"`
ImageOptions *ImageOptions `json:",omitempty"`
TmpfsOptions *TmpfsOptions `json:",omitempty"` TmpfsOptions *TmpfsOptions `json:",omitempty"`
ClusterOptions *ClusterOptions `json:",omitempty"` ClusterOptions *ClusterOptions `json:",omitempty"`
} }
@ -100,6 +103,10 @@ type VolumeOptions struct {
DriverConfig *Driver `json:",omitempty"` DriverConfig *Driver `json:",omitempty"`
} }
type ImageOptions struct {
Subpath string `json:",omitempty"`
}
// Driver represents a volume driver. // Driver represents a volume driver.
type Driver struct { type Driver struct {
Name string `json:",omitempty"` Name string `json:",omitempty"`

View File

@ -19,6 +19,12 @@ type EndpointSettings struct {
// generated address). // generated address).
MacAddress string MacAddress string
DriverOpts map[string]string DriverOpts map[string]string
// GwPriority determines which endpoint will provide the default gateway
// for the container. The endpoint with the highest priority will be used.
// If multiple endpoints have the same priority, they are lexicographically
// sorted based on their network name, and the one that sorts first is picked.
GwPriority int
// Operational data // Operational data
NetworkID string NetworkID string
EndpointID string EndpointID string

View File

@ -33,6 +33,7 @@ type CreateRequest struct {
type CreateOptions struct { type CreateOptions struct {
Driver string // Driver is the driver-name used to create the network (e.g. `bridge`, `overlay`) Driver string // Driver is the driver-name used to create the network (e.g. `bridge`, `overlay`)
Scope string // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level). Scope string // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level).
EnableIPv4 *bool `json:",omitempty"` // EnableIPv4 represents whether to enable IPv4.
EnableIPv6 *bool `json:",omitempty"` // EnableIPv6 represents whether to enable IPv6. EnableIPv6 *bool `json:",omitempty"` // EnableIPv6 represents whether to enable IPv6.
IPAM *IPAM // IPAM is the network's IP Address Management. IPAM *IPAM // IPAM is the network's IP Address Management.
Internal bool // Internal represents if the network is used internal only. Internal bool // Internal represents if the network is used internal only.
@ -76,7 +77,8 @@ type Inspect struct {
Created time.Time // Created is the time the network created Created time.Time // Created is the time the network created
Scope string // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level) Scope string // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level)
Driver string // Driver is the Driver name used to create the network (e.g. `bridge`, `overlay`) Driver string // Driver is the Driver name used to create the network (e.g. `bridge`, `overlay`)
EnableIPv6 bool // EnableIPv6 represents whether to enable IPv6 EnableIPv4 bool // EnableIPv4 represents whether IPv4 is enabled
EnableIPv6 bool // EnableIPv6 represents whether IPv6 is enabled
IPAM IPAM // IPAM is the network's IP Address Management IPAM IPAM // IPAM is the network's IP Address Management
Internal bool // Internal represents if the network is used internal only Internal bool // Internal represents if the network is used internal only
Attachable bool // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode. Attachable bool // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode.

View File

@ -1,17 +1,29 @@
package registry // import "github.com/docker/docker/api/types/registry" package registry // import "github.com/docker/docker/api/types/registry"
import ( import (
"context"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"fmt"
"io" "io"
"strings" "strings"
"github.com/pkg/errors"
) )
// AuthHeader is the name of the header used to send encoded registry // AuthHeader is the name of the header used to send encoded registry
// authorization credentials for registry operations (push/pull). // authorization credentials for registry operations (push/pull).
const AuthHeader = "X-Registry-Auth" const AuthHeader = "X-Registry-Auth"
// RequestAuthConfig is a function interface that clients can supply
// to retry operations after getting an authorization error.
//
// The function must return the [AuthHeader] value ([AuthConfig]), encoded
// in base64url format ([RFC4648, section 5]), which can be decoded by
// [DecodeAuthConfig].
//
// It must return an error if the privilege request fails.
//
// [RFC4648, section 5]: https://tools.ietf.org/html/rfc4648#section-5
type RequestAuthConfig func(context.Context) (string, error)
// AuthConfig contains authorization information for connecting to a Registry. // AuthConfig contains authorization information for connecting to a Registry.
type AuthConfig struct { type AuthConfig struct {
Username string `json:"username,omitempty"` Username string `json:"username,omitempty"`
@ -85,7 +97,7 @@ func decodeAuthConfigFromReader(rdr io.Reader) (*AuthConfig, error) {
} }
func invalid(err error) error { func invalid(err error) error {
return errInvalidParameter{errors.Wrap(err, "invalid X-Registry-Auth header")} return errInvalidParameter{fmt.Errorf("invalid X-Registry-Auth header: %w", err)}
} }
type errInvalidParameter struct{ error } type errInvalidParameter struct{ error }

View File

@ -9,11 +9,29 @@ import (
// ServiceConfig stores daemon registry services configuration. // ServiceConfig stores daemon registry services configuration.
type ServiceConfig struct { type ServiceConfig struct {
AllowNondistributableArtifactsCIDRs []*NetIPNet AllowNondistributableArtifactsCIDRs []*NetIPNet `json:"AllowNondistributableArtifactsCIDRs,omitempty"` // Deprecated: non-distributable artifacts are deprecated and enabled by default. This field will be removed in the next release.
AllowNondistributableArtifactsHostnames []string AllowNondistributableArtifactsHostnames []string `json:"AllowNondistributableArtifactsHostnames,omitempty"` // Deprecated: non-distributable artifacts are deprecated and enabled by default. This field will be removed in the next release.
InsecureRegistryCIDRs []*NetIPNet `json:"InsecureRegistryCIDRs"`
IndexConfigs map[string]*IndexInfo `json:"IndexConfigs"` InsecureRegistryCIDRs []*NetIPNet `json:"InsecureRegistryCIDRs"`
Mirrors []string IndexConfigs map[string]*IndexInfo `json:"IndexConfigs"`
Mirrors []string
}
// MarshalJSON implements a custom marshaler to include legacy fields
// in API responses.
func (sc ServiceConfig) MarshalJSON() ([]byte, error) {
tmp := map[string]interface{}{
"InsecureRegistryCIDRs": sc.InsecureRegistryCIDRs,
"IndexConfigs": sc.IndexConfigs,
"Mirrors": sc.Mirrors,
}
if sc.AllowNondistributableArtifactsCIDRs != nil {
tmp["AllowNondistributableArtifactsCIDRs"] = nil
}
if sc.AllowNondistributableArtifactsHostnames != nil {
tmp["AllowNondistributableArtifactsHostnames"] = nil
}
return json.Marshal(tmp)
} }
// NetIPNet is the net.IPNet type, which can be marshalled and // NetIPNet is the net.IPNet type, which can be marshalled and

View File

@ -10,11 +10,12 @@ import (
type SearchOptions struct { type SearchOptions struct {
RegistryAuth string RegistryAuth string
// PrivilegeFunc is a [types.RequestPrivilegeFunc] the client can // PrivilegeFunc is a function that clients can supply to retry operations
// supply to retry operations after getting an authorization error. // after getting an authorization error. This function returns the registry
// authentication header value in base64 encoded format, or an error if the
// privilege request fails.
// //
// It must return the registry authentication header value in base64 // For details, refer to [github.com/docker/docker/api/types/registry.RequestAuthConfig].
// format, or an error if the privilege request fails.
PrivilegeFunc func(context.Context) (string, error) PrivilegeFunc func(context.Context) (string, error)
Filters filters.Args Filters filters.Args
Limit int Limit int

View File

@ -1,13 +1,13 @@
package types package storage
// This file was generated by the swagger tool. // This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command // Editing this file might prove futile when you re-run the swagger generate command
// GraphDriverData Information about the storage driver used to store the container's and // DriverData Information about the storage driver used to store the container's and
// image's filesystem. // image's filesystem.
// //
// swagger:model GraphDriverData // swagger:model DriverData
type GraphDriverData struct { type DriverData struct {
// Low-level storage metadata, provided as key/value pairs. // Low-level storage metadata, provided as key/value pairs.
// //

View File

@ -29,8 +29,8 @@ type Info struct {
CPUSet bool CPUSet bool
PidsLimit bool PidsLimit bool
IPv4Forwarding bool IPv4Forwarding bool
BridgeNfIptables bool BridgeNfIptables bool `json:"BridgeNfIptables"` // Deprecated: netfilter module is now loaded on-demand and no longer during daemon startup, making this field obsolete. This field is always false and will be removed in the next release.
BridgeNfIP6tables bool `json:"BridgeNfIp6tables"` BridgeNfIP6tables bool `json:"BridgeNfIp6tables"` // Deprecated: netfilter module is now loaded on-demand and no longer during daemon startup, making this field obsolete. This field is always false and will be removed in the next release.
Debug bool Debug bool
NFd int NFd int
OomKillDisable bool OomKillDisable bool
@ -137,8 +137,13 @@ type PluginsInfo struct {
// Commit holds the Git-commit (SHA1) that a binary was built from, as reported // Commit holds the Git-commit (SHA1) that a binary was built from, as reported
// in the version-string of external tools, such as containerd, or runC. // in the version-string of external tools, such as containerd, or runC.
type Commit struct { type Commit struct {
ID string // ID is the actual commit ID of external tool. // ID is the actual commit ID or version of external tool.
Expected string // Expected is the commit ID of external tool expected by dockerd as set at build time. ID string
// Expected is the commit ID of external tool expected by dockerd as set at build time.
//
// Deprecated: this field is no longer used in API v1.49, but kept for backward-compatibility with older API versions.
Expected string
} }
// NetworkAddressPool is a temp struct used by [Info] struct. // NetworkAddressPool is a temp struct used by [Info] struct.

View File

@ -6,11 +6,8 @@ import (
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/volume" "github.com/docker/docker/api/types/volume"
"github.com/docker/go-connections/nat"
) )
const ( const (
@ -21,145 +18,6 @@ const (
MediaTypeMultiplexedStream = "application/vnd.docker.multiplexed-stream" MediaTypeMultiplexedStream = "application/vnd.docker.multiplexed-stream"
) )
// RootFS returns Image's RootFS description including the layer IDs.
type RootFS struct {
Type string `json:",omitempty"`
Layers []string `json:",omitempty"`
}
// ImageInspect contains response of Engine API:
// GET "/images/{name:.*}/json"
type ImageInspect struct {
// ID is the content-addressable ID of an image.
//
// This identifier is a content-addressable digest calculated from the
// image's configuration (which includes the digests of layers used by
// the image).
//
// Note that this digest differs from the `RepoDigests` below, which
// holds digests of image manifests that reference the image.
ID string `json:"Id"`
// RepoTags is a list of image names/tags in the local image cache that
// reference this image.
//
// Multiple image tags can refer to the same image, and this list may be
// empty if no tags reference the image, in which case the image is
// "untagged", in which case it can still be referenced by its ID.
RepoTags []string
// RepoDigests is a list of content-addressable digests of locally available
// image manifests that the image is referenced from. Multiple manifests can
// refer to the same image.
//
// These digests are usually only available if the image was either pulled
// from a registry, or if the image was pushed to a registry, which is when
// the manifest is generated and its digest calculated.
RepoDigests []string
// Parent is the ID of the parent image.
//
// Depending on how the image was created, this field may be empty and
// is only set for images that were built/created locally. This field
// is empty if the image was pulled from an image registry.
Parent string
// Comment is an optional message that can be set when committing or
// importing the image.
Comment string
// Created is the date and time at which the image was created, formatted in
// RFC 3339 nano-seconds (time.RFC3339Nano).
//
// This information is only available if present in the image,
// and omitted otherwise.
Created string `json:",omitempty"`
// Container is the ID of the container that was used to create the image.
//
// Depending on how the image was created, this field may be empty.
//
// Deprecated: this field is omitted in API v1.45, but kept for backward compatibility.
Container string `json:",omitempty"`
// ContainerConfig is an optional field containing the configuration of the
// container that was last committed when creating the image.
//
// Previous versions of Docker builder used this field to store build cache,
// and it is not in active use anymore.
//
// Deprecated: this field is omitted in API v1.45, but kept for backward compatibility.
ContainerConfig *container.Config `json:",omitempty"`
// DockerVersion is the version of Docker that was used to build the image.
//
// Depending on how the image was created, this field may be empty.
DockerVersion string
// Author is the name of the author that was specified when committing the
// image, or as specified through MAINTAINER (deprecated) in the Dockerfile.
Author string
Config *container.Config
// Architecture is the hardware CPU architecture that the image runs on.
Architecture string
// Variant is the CPU architecture variant (presently ARM-only).
Variant string `json:",omitempty"`
// OS is the Operating System the image is built to run on.
Os string
// OsVersion is the version of the Operating System the image is built to
// run on (especially for Windows).
OsVersion string `json:",omitempty"`
// Size is the total size of the image including all layers it is composed of.
Size int64
// VirtualSize is the total size of the image including all layers it is
// composed of.
//
// Deprecated: this field is omitted in API v1.44, but kept for backward compatibility. Use Size instead.
VirtualSize int64 `json:"VirtualSize,omitempty"`
// GraphDriver holds information about the storage driver used to store the
// container's and image's filesystem.
GraphDriver GraphDriverData
// RootFS contains information about the image's RootFS, including the
// layer IDs.
RootFS RootFS
// Metadata of the image in the local cache.
//
// This information is local to the daemon, and not part of the image itself.
Metadata image.Metadata
}
// Container contains response of Engine API:
// GET "/containers/json"
type Container struct {
ID string `json:"Id"`
Names []string
Image string
ImageID string
Command string
Created int64
Ports []Port
SizeRw int64 `json:",omitempty"`
SizeRootFs int64 `json:",omitempty"`
Labels map[string]string
State string
Status string
HostConfig struct {
NetworkMode string `json:",omitempty"`
Annotations map[string]string `json:",omitempty"`
}
NetworkSettings *SummaryNetworkSettings
Mounts []MountPoint
}
// Ping contains response of Engine API: // Ping contains response of Engine API:
// GET "/_ping" // GET "/_ping"
type Ping struct { type Ping struct {
@ -205,176 +63,6 @@ type Version struct {
BuildTime string `json:",omitempty"` BuildTime string `json:",omitempty"`
} }
// HealthcheckResult stores information about a single run of a healthcheck probe
type HealthcheckResult struct {
Start time.Time // Start is the time this check started
End time.Time // End is the time this check ended
ExitCode int // ExitCode meanings: 0=healthy, 1=unhealthy, 2=reserved (considered unhealthy), else=error running probe
Output string // Output from last check
}
// Health states
const (
NoHealthcheck = "none" // Indicates there is no healthcheck
Starting = "starting" // Starting indicates that the container is not yet ready
Healthy = "healthy" // Healthy indicates that the container is running correctly
Unhealthy = "unhealthy" // Unhealthy indicates that the container has a problem
)
// Health stores information about the container's healthcheck results
type Health struct {
Status string // Status is one of Starting, Healthy or Unhealthy
FailingStreak int // FailingStreak is the number of consecutive failures
Log []*HealthcheckResult // Log contains the last few results (oldest first)
}
// ContainerState stores container's running state
// it's part of ContainerJSONBase and will return by "inspect" command
type ContainerState struct {
Status string // String representation of the container state. Can be one of "created", "running", "paused", "restarting", "removing", "exited", or "dead"
Running bool
Paused bool
Restarting bool
OOMKilled bool
Dead bool
Pid int
ExitCode int
Error string
StartedAt string
FinishedAt string
Health *Health `json:",omitempty"`
}
// ContainerJSONBase contains response of Engine API:
// GET "/containers/{name:.*}/json"
type ContainerJSONBase struct {
ID string `json:"Id"`
Created string
Path string
Args []string
State *ContainerState
Image string
ResolvConfPath string
HostnamePath string
HostsPath string
LogPath string
Node *ContainerNode `json:",omitempty"` // Deprecated: Node was only propagated by Docker Swarm standalone API. It sill be removed in the next release.
Name string
RestartCount int
Driver string
Platform string
MountLabel string
ProcessLabel string
AppArmorProfile string
ExecIDs []string
HostConfig *container.HostConfig
GraphDriver GraphDriverData
SizeRw *int64 `json:",omitempty"`
SizeRootFs *int64 `json:",omitempty"`
}
// ContainerJSON is newly used struct along with MountPoint
type ContainerJSON struct {
*ContainerJSONBase
Mounts []MountPoint
Config *container.Config
NetworkSettings *NetworkSettings
}
// NetworkSettings exposes the network settings in the api
type NetworkSettings struct {
NetworkSettingsBase
DefaultNetworkSettings
Networks map[string]*network.EndpointSettings
}
// SummaryNetworkSettings provides a summary of container's networks
// in /containers/json
type SummaryNetworkSettings struct {
Networks map[string]*network.EndpointSettings
}
// NetworkSettingsBase holds networking state for a container when inspecting it.
type NetworkSettingsBase struct {
Bridge string // Bridge contains the name of the default bridge interface iff it was set through the daemon --bridge flag.
SandboxID string // SandboxID uniquely represents a container's network stack
SandboxKey string // SandboxKey identifies the sandbox
Ports nat.PortMap // Ports is a collection of PortBinding indexed by Port
// HairpinMode specifies if hairpin NAT should be enabled on the virtual interface
//
// Deprecated: This field is never set and will be removed in a future release.
HairpinMode bool
// LinkLocalIPv6Address is an IPv6 unicast address using the link-local prefix
//
// Deprecated: This field is never set and will be removed in a future release.
LinkLocalIPv6Address string
// LinkLocalIPv6PrefixLen is the prefix length of an IPv6 unicast address
//
// Deprecated: This field is never set and will be removed in a future release.
LinkLocalIPv6PrefixLen int
SecondaryIPAddresses []network.Address // Deprecated: This field is never set and will be removed in a future release.
SecondaryIPv6Addresses []network.Address // Deprecated: This field is never set and will be removed in a future release.
}
// DefaultNetworkSettings holds network information
// during the 2 release deprecation period.
// It will be removed in Docker 1.11.
type DefaultNetworkSettings struct {
EndpointID string // EndpointID uniquely represents a service endpoint in a Sandbox
Gateway string // Gateway holds the gateway address for the network
GlobalIPv6Address string // GlobalIPv6Address holds network's global IPv6 address
GlobalIPv6PrefixLen int // GlobalIPv6PrefixLen represents mask length of network's global IPv6 address
IPAddress string // IPAddress holds the IPv4 address for the network
IPPrefixLen int // IPPrefixLen represents mask length of network's IPv4 address
IPv6Gateway string // IPv6Gateway holds gateway address specific for IPv6
MacAddress string // MacAddress holds the MAC address for the network
}
// MountPoint represents a mount point configuration inside the container.
// This is used for reporting the mountpoints in use by a container.
type MountPoint struct {
// Type is the type of mount, see `Type<foo>` definitions in
// github.com/docker/docker/api/types/mount.Type
Type mount.Type `json:",omitempty"`
// Name is the name reference to the underlying data defined by `Source`
// e.g., the volume name.
Name string `json:",omitempty"`
// Source is the source location of the mount.
//
// For volumes, this contains the storage location of the volume (within
// `/var/lib/docker/volumes/`). For bind-mounts, and `npipe`, this contains
// the source (host) part of the bind-mount. For `tmpfs` mount points, this
// field is empty.
Source string
// Destination is the path relative to the container root (`/`) where the
// Source is mounted inside the container.
Destination string
// Driver is the volume driver used to create the volume (if it is a volume).
Driver string `json:",omitempty"`
// Mode is a comma separated list of options supplied by the user when
// creating the bind/volume mount.
//
// The default is platform-specific (`"z"` on Linux, empty on Windows).
Mode string
// RW indicates whether the mount is mounted writable (read-write).
RW bool
// Propagation describes how mounts are propagated from the host into the
// mount point, and vice-versa. Refer to the Linux kernel documentation
// for details:
// https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt
//
// This field is not used on Windows.
Propagation mount.Propagation
}
// DiskUsageObject represents an object type used for disk usage query filtering. // DiskUsageObject represents an object type used for disk usage query filtering.
type DiskUsageObject string type DiskUsageObject string
@ -401,7 +89,7 @@ type DiskUsageOptions struct {
type DiskUsage struct { type DiskUsage struct {
LayersSize int64 LayersSize int64
Images []*image.Summary Images []*image.Summary
Containers []*Container Containers []*container.Summary
Volumes []*volume.Volume Volumes []*volume.Volume
BuildCache []*BuildCache BuildCache []*BuildCache
BuilderSize int64 `json:",omitempty"` // Deprecated: deprecated in API 1.38, and no longer used since API 1.40. BuilderSize int64 `json:",omitempty"` // Deprecated: deprecated in API 1.38, and no longer used since API 1.40.
@ -481,9 +169,11 @@ type BuildCache struct {
// BuildCachePruneOptions hold parameters to prune the build cache // BuildCachePruneOptions hold parameters to prune the build cache
type BuildCachePruneOptions struct { type BuildCachePruneOptions struct {
All bool All bool
KeepStorage int64 ReservedSpace int64
Filters filters.Args MaxUsedSpace int64
MinFreeSpace int64
Filters filters.Args
// FIXME(thaJeztah): add new options; see https://github.com/moby/moby/issues/48639 KeepStorage int64 // Deprecated: deprecated in API 1.48.
} }

View File

@ -1,210 +1,115 @@
package types package types
import ( import (
"context"
"github.com/docker/docker/api/types/common"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/storage"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/volume"
) )
// ImagesPruneReport contains the response for Engine API: // IDResponse Response to an API call that returns just an Id.
// POST "/images/prune"
// //
// Deprecated: use [image.PruneReport]. // Deprecated: use either [container.CommitResponse] or [container.ExecCreateResponse]. It will be removed in the next release.
type ImagesPruneReport = image.PruneReport type IDResponse = common.IDResponse
// VolumesPruneReport contains the response for Engine API: // ContainerJSONBase contains response of Engine API GET "/containers/{name:.*}/json"
// POST "/volumes/prune". // for API version 1.18 and older.
// //
// Deprecated: use [volume.PruneReport]. // Deprecated: use [container.InspectResponse] or [container.ContainerJSONBase]. It will be removed in the next release.
type VolumesPruneReport = volume.PruneReport type ContainerJSONBase = container.ContainerJSONBase
// NetworkCreateRequest is the request message sent to the server for network create call. // ContainerJSON is the response for the GET "/containers/{name:.*}/json"
// endpoint.
// //
// Deprecated: use [network.CreateRequest]. // Deprecated: use [container.InspectResponse]. It will be removed in the next release.
type NetworkCreateRequest = network.CreateRequest type ContainerJSON = container.InspectResponse
// NetworkCreate is the expected body of the "create network" http request message // Container contains response of Engine API:
// GET "/containers/json"
// //
// Deprecated: use [network.CreateOptions]. // Deprecated: use [container.Summary].
type NetworkCreate = network.CreateOptions type Container = container.Summary
// NetworkListOptions holds parameters to filter the list of networks with. // ContainerState stores container's running state
// //
// Deprecated: use [network.ListOptions]. // Deprecated: use [container.State].
type NetworkListOptions = network.ListOptions type ContainerState = container.State
// NetworkCreateResponse is the response message sent by the server for network create call. // NetworkSettings exposes the network settings in the api.
// //
// Deprecated: use [network.CreateResponse]. // Deprecated: use [container.NetworkSettings].
type NetworkCreateResponse = network.CreateResponse type NetworkSettings = container.NetworkSettings
// NetworkInspectOptions holds parameters to inspect network. // NetworkSettingsBase holds networking state for a container when inspecting it.
// //
// Deprecated: use [network.InspectOptions]. // Deprecated: use [container.NetworkSettingsBase].
type NetworkInspectOptions = network.InspectOptions type NetworkSettingsBase = container.NetworkSettingsBase
// NetworkConnect represents the data to be used to connect a container to the network // DefaultNetworkSettings holds network information
// during the 2 release deprecation period.
// It will be removed in Docker 1.11.
// //
// Deprecated: use [network.ConnectOptions]. // Deprecated: use [container.DefaultNetworkSettings].
type NetworkConnect = network.ConnectOptions type DefaultNetworkSettings = container.DefaultNetworkSettings
// NetworkDisconnect represents the data to be used to disconnect a container from the network // SummaryNetworkSettings provides a summary of container's networks
// in /containers/json.
// //
// Deprecated: use [network.DisconnectOptions]. // Deprecated: use [container.NetworkSettingsSummary].
type NetworkDisconnect = network.DisconnectOptions type SummaryNetworkSettings = container.NetworkSettingsSummary
// EndpointResource contains network resources allocated and used for a container in a network. // Health states
// const (
// Deprecated: use [network.EndpointResource]. NoHealthcheck = container.NoHealthcheck // Deprecated: use [container.NoHealthcheck].
type EndpointResource = network.EndpointResource Starting = container.Starting // Deprecated: use [container.Starting].
Healthy = container.Healthy // Deprecated: use [container.Healthy].
Unhealthy = container.Unhealthy // Deprecated: use [container.Unhealthy].
)
// NetworkResource is the body of the "get network" http response message/ // Health stores information about the container's healthcheck results.
// //
// Deprecated: use [network.Inspect] or [network.Summary] (for list operations). // Deprecated: use [container.Health].
type NetworkResource = network.Inspect type Health = container.Health
// NetworksPruneReport contains the response for Engine API: // HealthcheckResult stores information about a single run of a healthcheck probe.
// POST "/networks/prune"
// //
// Deprecated: use [network.PruneReport]. // Deprecated: use [container.HealthcheckResult].
type NetworksPruneReport = network.PruneReport type HealthcheckResult = container.HealthcheckResult
// ExecConfig is a small subset of the Config struct that holds the configuration // MountPoint represents a mount point configuration inside the container.
// for the exec feature of docker. // This is used for reporting the mountpoints in use by a container.
// //
// Deprecated: use [container.ExecOptions]. // Deprecated: use [container.MountPoint].
type ExecConfig = container.ExecOptions type MountPoint = container.MountPoint
// ExecStartCheck is a temp struct used by execStart // Port An open port on a container
// Config fields is part of ExecConfig in runconfig package
// //
// Deprecated: use [container.ExecStartOptions] or [container.ExecAttachOptions]. // Deprecated: use [container.Port].
type ExecStartCheck = container.ExecStartOptions type Port = container.Port
// ContainerExecInspect holds information returned by exec inspect. // GraphDriverData Information about the storage driver used to store the container's and
// image's filesystem.
// //
// Deprecated: use [container.ExecInspect]. // Deprecated: use [storage.DriverData].
type ContainerExecInspect = container.ExecInspect type GraphDriverData = storage.DriverData
// ContainersPruneReport contains the response for Engine API: // RootFS returns Image's RootFS description including the layer IDs.
// POST "/containers/prune"
// //
// Deprecated: use [container.PruneReport]. // Deprecated: use [image.RootFS].
type ContainersPruneReport = container.PruneReport type RootFS = image.RootFS
// ContainerPathStat is used to encode the header from // ImageInspect contains response of Engine API:
// GET "/containers/{name:.*}/archive" // GET "/images/{name:.*}/json"
// "Name" is the file or directory name.
// //
// Deprecated: use [container.PathStat]. // Deprecated: use [image.InspectResponse].
type ContainerPathStat = container.PathStat type ImageInspect = image.InspectResponse
// CopyToContainerOptions holds information // RequestPrivilegeFunc is a function interface that clients can supply to
// about files to copy into a container. // retry operations after getting an authorization error.
// This function returns the registry authentication header value in base64
// format, or an error if the privilege request fails.
// //
// Deprecated: use [container.CopyToContainerOptions], // Deprecated: moved to [github.com/docker/docker/api/types/registry.RequestAuthConfig].
type CopyToContainerOptions = container.CopyToContainerOptions type RequestPrivilegeFunc func(context.Context) (string, error)
// ContainerStats contains response of Engine API:
// GET "/stats"
//
// Deprecated: use [container.StatsResponseReader].
type ContainerStats = container.StatsResponseReader
// ThrottlingData stores CPU throttling stats of one running container.
// Not used on Windows.
//
// Deprecated: use [container.ThrottlingData].
type ThrottlingData = container.ThrottlingData
// CPUUsage stores All CPU stats aggregated since container inception.
//
// Deprecated: use [container.CPUUsage].
type CPUUsage = container.CPUUsage
// CPUStats aggregates and wraps all CPU related info of container
//
// Deprecated: use [container.CPUStats].
type CPUStats = container.CPUStats
// MemoryStats aggregates all memory stats since container inception on Linux.
// Windows returns stats for commit and private working set only.
//
// Deprecated: use [container.MemoryStats].
type MemoryStats = container.MemoryStats
// BlkioStatEntry is one small entity to store a piece of Blkio stats
// Not used on Windows.
//
// Deprecated: use [container.BlkioStatEntry].
type BlkioStatEntry = container.BlkioStatEntry
// BlkioStats stores All IO service stats for data read and write.
// This is a Linux specific structure as the differences between expressing
// block I/O on Windows and Linux are sufficiently significant to make
// little sense attempting to morph into a combined structure.
//
// Deprecated: use [container.BlkioStats].
type BlkioStats = container.BlkioStats
// StorageStats is the disk I/O stats for read/write on Windows.
//
// Deprecated: use [container.StorageStats].
type StorageStats = container.StorageStats
// NetworkStats aggregates the network stats of one container
//
// Deprecated: use [container.NetworkStats].
type NetworkStats = container.NetworkStats
// PidsStats contains the stats of a container's pids
//
// Deprecated: use [container.PidsStats].
type PidsStats = container.PidsStats
// Stats is Ultimate struct aggregating all types of stats of one container
//
// Deprecated: use [container.Stats].
type Stats = container.Stats
// StatsJSON is newly used Networks
//
// Deprecated: use [container.StatsResponse].
type StatsJSON = container.StatsResponse
// EventsOptions holds parameters to filter events with.
//
// Deprecated: use [events.ListOptions].
type EventsOptions = events.ListOptions
// ImageSearchOptions holds parameters to search images with.
//
// Deprecated: use [registry.SearchOptions].
type ImageSearchOptions = registry.SearchOptions
// ImageImportSource holds source information for ImageImport
//
// Deprecated: use [image.ImportSource].
type ImageImportSource image.ImportSource
// ImageLoadResponse returns information to the client about a load process.
//
// Deprecated: use [image.LoadResponse].
type ImageLoadResponse = image.LoadResponse
// ContainerNode stores information about the node that a container
// is running on. It's only used by the Docker Swarm standalone API.
//
// Deprecated: ContainerNode was used for the classic Docker Swarm standalone API. It will be removed in the next release.
type ContainerNode struct {
ID string
IPAddress string `json:"IP"`
Addr string
Name string
Cpus int
Memory int64
Labels map[string]string
}

View File

@ -10,7 +10,7 @@ func (cli *Client) BuildCancel(ctx context.Context, id string) error {
query := url.Values{} query := url.Values{}
query.Set("id", id) query.Set("id", id)
serverResp, err := cli.post(ctx, "/build/cancel", query, nil, nil) resp, err := cli.post(ctx, "/build/cancel", query, nil, nil)
ensureReaderClosed(serverResp) ensureReaderClosed(resp)
return err return err
} }

View File

@ -17,27 +17,38 @@ func (cli *Client) BuildCachePrune(ctx context.Context, opts types.BuildCachePru
return nil, err return nil, err
} }
report := types.BuildCachePruneReport{}
query := url.Values{} query := url.Values{}
if opts.All { if opts.All {
query.Set("all", "1") query.Set("all", "1")
} }
query.Set("keep-storage", strconv.Itoa(int(opts.KeepStorage)))
if opts.KeepStorage != 0 {
query.Set("keep-storage", strconv.Itoa(int(opts.KeepStorage)))
}
if opts.ReservedSpace != 0 {
query.Set("reserved-space", strconv.Itoa(int(opts.ReservedSpace)))
}
if opts.MaxUsedSpace != 0 {
query.Set("max-used-space", strconv.Itoa(int(opts.MaxUsedSpace)))
}
if opts.MinFreeSpace != 0 {
query.Set("min-free-space", strconv.Itoa(int(opts.MinFreeSpace)))
}
f, err := filters.ToJSON(opts.Filters) f, err := filters.ToJSON(opts.Filters)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "prune could not marshal filters option") return nil, errors.Wrap(err, "prune could not marshal filters option")
} }
query.Set("filters", f) query.Set("filters", f)
serverResp, err := cli.post(ctx, "/build/prune", query, nil, nil) resp, err := cli.post(ctx, "/build/prune", query, nil, nil)
defer ensureReaderClosed(serverResp) defer ensureReaderClosed(resp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err := json.NewDecoder(serverResp.body).Decode(&report); err != nil { report := types.BuildCachePruneReport{}
if err := json.NewDecoder(resp.Body).Decode(&report); err != nil {
return nil, errors.Wrap(err, "error retrieving disk usage") return nil, errors.Wrap(err, "error retrieving disk usage")
} }

View File

@ -6,11 +6,11 @@ import (
"github.com/docker/docker/api/types/checkpoint" "github.com/docker/docker/api/types/checkpoint"
) )
type apiClientExperimental interface { // CheckpointAPIClient defines API client methods for the checkpoints.
CheckpointAPIClient //
} // Experimental: checkpoint and restore is still an experimental feature,
// and only available if the daemon is running with experimental features
// CheckpointAPIClient defines API client methods for the checkpoints // enabled.
type CheckpointAPIClient interface { type CheckpointAPIClient interface {
CheckpointCreate(ctx context.Context, container string, options checkpoint.CreateOptions) error CheckpointCreate(ctx context.Context, container string, options checkpoint.CreateOptions) error
CheckpointDelete(ctx context.Context, container string, options checkpoint.DeleteOptions) error CheckpointDelete(ctx context.Context, container string, options checkpoint.DeleteOptions) error

View File

@ -7,8 +7,13 @@ import (
) )
// CheckpointCreate creates a checkpoint from the given container with the given name // CheckpointCreate creates a checkpoint from the given container with the given name
func (cli *Client) CheckpointCreate(ctx context.Context, container string, options checkpoint.CreateOptions) error { func (cli *Client) CheckpointCreate(ctx context.Context, containerID string, options checkpoint.CreateOptions) error {
resp, err := cli.post(ctx, "/containers/"+container+"/checkpoints", nil, options, nil) containerID, err := trimID("container", containerID)
if err != nil {
return err
}
resp, err := cli.post(ctx, "/containers/"+containerID+"/checkpoints", nil, options, nil)
ensureReaderClosed(resp) ensureReaderClosed(resp)
return err return err
} }

View File

@ -9,6 +9,11 @@ import (
// CheckpointDelete deletes the checkpoint with the given name from the given container // CheckpointDelete deletes the checkpoint with the given name from the given container
func (cli *Client) CheckpointDelete(ctx context.Context, containerID string, options checkpoint.DeleteOptions) error { func (cli *Client) CheckpointDelete(ctx context.Context, containerID string, options checkpoint.DeleteOptions) error {
containerID, err := trimID("container", containerID)
if err != nil {
return err
}
query := url.Values{} query := url.Values{}
if options.CheckpointDir != "" { if options.CheckpointDir != "" {
query.Set("dir", options.CheckpointDir) query.Set("dir", options.CheckpointDir)

View File

@ -23,6 +23,6 @@ func (cli *Client) CheckpointList(ctx context.Context, container string, options
return checkpoints, err return checkpoints, err
} }
err = json.NewDecoder(resp.body).Decode(&checkpoints) err = json.NewDecoder(resp.Body).Decode(&checkpoints)
return checkpoints, err return checkpoints, err
} }

View File

@ -59,7 +59,6 @@ import (
"github.com/docker/go-connections/sockets" "github.com/docker/go-connections/sockets"
"github.com/pkg/errors" "github.com/pkg/errors"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.opentelemetry.io/otel/trace"
) )
// DummyHost is a hostname used for local communication. // DummyHost is a hostname used for local communication.
@ -99,6 +98,9 @@ const DummyHost = "api.moby.localhost"
// recent version before negotiation was introduced. // recent version before negotiation was introduced.
const fallbackAPIVersion = "1.24" const fallbackAPIVersion = "1.24"
// Ensure that Client always implements APIClient.
var _ APIClient = &Client{}
// Client is the API client that performs all operations // Client is the API client that performs all operations
// against a docker server. // against a docker server.
type Client struct { type Client struct {
@ -138,7 +140,7 @@ type Client struct {
// negotiateLock is used to single-flight the version negotiation process // negotiateLock is used to single-flight the version negotiation process
negotiateLock sync.Mutex negotiateLock sync.Mutex
tp trace.TracerProvider traceOpts []otelhttp.Option
// When the client transport is an *http.Transport (default) we need to do some extra things (like closing idle connections). // When the client transport is an *http.Transport (default) we need to do some extra things (like closing idle connections).
// Store the original transport as the http.Client transport will be wrapped with tracing libs. // Store the original transport as the http.Client transport will be wrapped with tracing libs.
@ -200,6 +202,12 @@ func NewClientWithOpts(ops ...Opt) (*Client, error) {
client: client, client: client,
proto: hostURL.Scheme, proto: hostURL.Scheme,
addr: hostURL.Host, addr: hostURL.Host,
traceOpts: []otelhttp.Option{
otelhttp.WithSpanNameFormatter(func(_ string, req *http.Request) string {
return req.Method + " " + req.URL.Path
}),
},
} }
for _, op := range ops { for _, op := range ops {
@ -227,13 +235,7 @@ func NewClientWithOpts(ops ...Opt) (*Client, error) {
} }
} }
c.client.Transport = otelhttp.NewTransport( c.client.Transport = otelhttp.NewTransport(c.client.Transport, c.traceOpts...)
c.client.Transport,
otelhttp.WithTracerProvider(c.tp),
otelhttp.WithSpanNameFormatter(func(_ string, req *http.Request) string {
return req.Method + " " + req.URL.Path
}),
)
return c, nil return c, nil
} }
@ -304,8 +306,7 @@ func (cli *Client) getAPIPath(ctx context.Context, p string, query url.Values) s
var apiPath string var apiPath string
_ = cli.checkVersion(ctx) _ = cli.checkVersion(ctx)
if cli.version != "" { if cli.version != "" {
v := strings.TrimPrefix(cli.version, "v") apiPath = path.Join(cli.basePath, "/v"+strings.TrimPrefix(cli.version, "v"), p)
apiPath = path.Join(cli.basePath, "/v"+v, p)
} else { } else {
apiPath = path.Join(cli.basePath, p) apiPath = path.Join(cli.basePath, p)
} }
@ -450,6 +451,10 @@ func (cli *Client) dialerFromTransport() func(context.Context, string, string) (
// //
// ["docker dial-stdio"]: https://github.com/docker/cli/pull/1014 // ["docker dial-stdio"]: https://github.com/docker/cli/pull/1014
func (cli *Client) Dialer() func(context.Context) (net.Conn, error) { func (cli *Client) Dialer() func(context.Context) (net.Conn, error) {
return cli.dialer()
}
func (cli *Client) dialer() func(context.Context) (net.Conn, error) {
return func(ctx context.Context) (net.Conn, error) { return func(ctx context.Context) (net.Conn, error) {
if dialFn := cli.dialerFromTransport(); dialFn != nil { if dialFn := cli.dialerFromTransport(); dialFn != nil {
return dialFn(ctx, cli.proto, cli.addr) return dialFn(ctx, cli.proto, cli.addr)

View File

@ -20,17 +20,23 @@ import (
) )
// CommonAPIClient is the common methods between stable and experimental versions of APIClient. // CommonAPIClient is the common methods between stable and experimental versions of APIClient.
type CommonAPIClient interface { //
// Deprecated: use [APIClient] instead. This type will be an alias for [APIClient] in the next release, and removed after.
type CommonAPIClient = stableAPIClient
// APIClient is an interface that clients that talk with a docker server must implement.
type APIClient interface {
stableAPIClient
CheckpointAPIClient // CheckpointAPIClient is still experimental.
}
type stableAPIClient interface {
ConfigAPIClient ConfigAPIClient
ContainerAPIClient ContainerAPIClient
DistributionAPIClient DistributionAPIClient
ImageAPIClient ImageAPIClient
NodeAPIClient
NetworkAPIClient NetworkAPIClient
PluginAPIClient PluginAPIClient
ServiceAPIClient
SwarmAPIClient
SecretAPIClient
SystemAPIClient SystemAPIClient
VolumeAPIClient VolumeAPIClient
ClientVersion() string ClientVersion() string
@ -39,27 +45,43 @@ type CommonAPIClient interface {
ServerVersion(ctx context.Context) (types.Version, error) ServerVersion(ctx context.Context) (types.Version, error)
NegotiateAPIVersion(ctx context.Context) NegotiateAPIVersion(ctx context.Context)
NegotiateAPIVersionPing(types.Ping) NegotiateAPIVersionPing(types.Ping)
DialHijack(ctx context.Context, url, proto string, meta map[string][]string) (net.Conn, error) HijackDialer
Dialer() func(context.Context) (net.Conn, error) Dialer() func(context.Context) (net.Conn, error)
Close() error Close() error
SwarmManagementAPIClient
}
// SwarmManagementAPIClient defines all methods for managing Swarm-specific
// objects.
type SwarmManagementAPIClient interface {
SwarmAPIClient
NodeAPIClient
ServiceAPIClient
SecretAPIClient
ConfigAPIClient
}
// HijackDialer defines methods for a hijack dialer.
type HijackDialer interface {
DialHijack(ctx context.Context, url, proto string, meta map[string][]string) (net.Conn, error)
} }
// ContainerAPIClient defines API client methods for the containers // ContainerAPIClient defines API client methods for the containers
type ContainerAPIClient interface { type ContainerAPIClient interface {
ContainerAttach(ctx context.Context, container string, options container.AttachOptions) (types.HijackedResponse, error) ContainerAttach(ctx context.Context, container string, options container.AttachOptions) (types.HijackedResponse, error)
ContainerCommit(ctx context.Context, container string, options container.CommitOptions) (types.IDResponse, error) ContainerCommit(ctx context.Context, container string, options container.CommitOptions) (container.CommitResponse, error)
ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error)
ContainerDiff(ctx context.Context, container string) ([]container.FilesystemChange, error) ContainerDiff(ctx context.Context, container string) ([]container.FilesystemChange, error)
ContainerExecAttach(ctx context.Context, execID string, options container.ExecAttachOptions) (types.HijackedResponse, error) ContainerExecAttach(ctx context.Context, execID string, options container.ExecAttachOptions) (types.HijackedResponse, error)
ContainerExecCreate(ctx context.Context, container string, options container.ExecOptions) (types.IDResponse, error) ContainerExecCreate(ctx context.Context, container string, options container.ExecOptions) (container.ExecCreateResponse, error)
ContainerExecInspect(ctx context.Context, execID string) (container.ExecInspect, error) ContainerExecInspect(ctx context.Context, execID string) (container.ExecInspect, error)
ContainerExecResize(ctx context.Context, execID string, options container.ResizeOptions) error ContainerExecResize(ctx context.Context, execID string, options container.ResizeOptions) error
ContainerExecStart(ctx context.Context, execID string, options container.ExecStartOptions) error ContainerExecStart(ctx context.Context, execID string, options container.ExecStartOptions) error
ContainerExport(ctx context.Context, container string) (io.ReadCloser, error) ContainerExport(ctx context.Context, container string) (io.ReadCloser, error)
ContainerInspect(ctx context.Context, container string) (types.ContainerJSON, error) ContainerInspect(ctx context.Context, container string) (container.InspectResponse, error)
ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (types.ContainerJSON, []byte, error) ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (container.InspectResponse, []byte, error)
ContainerKill(ctx context.Context, container, signal string) error ContainerKill(ctx context.Context, container, signal string) error
ContainerList(ctx context.Context, options container.ListOptions) ([]types.Container, error) ContainerList(ctx context.Context, options container.ListOptions) ([]container.Summary, error)
ContainerLogs(ctx context.Context, container string, options container.LogsOptions) (io.ReadCloser, error) ContainerLogs(ctx context.Context, container string, options container.LogsOptions) (io.ReadCloser, error)
ContainerPause(ctx context.Context, container string) error ContainerPause(ctx context.Context, container string) error
ContainerRemove(ctx context.Context, container string, options container.RemoveOptions) error ContainerRemove(ctx context.Context, container string, options container.RemoveOptions) error
@ -71,9 +93,9 @@ type ContainerAPIClient interface {
ContainerStatsOneShot(ctx context.Context, container string) (container.StatsResponseReader, error) ContainerStatsOneShot(ctx context.Context, container string) (container.StatsResponseReader, error)
ContainerStart(ctx context.Context, container string, options container.StartOptions) error ContainerStart(ctx context.Context, container string, options container.StartOptions) error
ContainerStop(ctx context.Context, container string, options container.StopOptions) error ContainerStop(ctx context.Context, container string, options container.StopOptions) error
ContainerTop(ctx context.Context, container string, arguments []string) (container.ContainerTopOKBody, error) ContainerTop(ctx context.Context, container string, arguments []string) (container.TopResponse, error)
ContainerUnpause(ctx context.Context, container string) error ContainerUnpause(ctx context.Context, container string) error
ContainerUpdate(ctx context.Context, container string, updateConfig container.UpdateConfig) (container.ContainerUpdateOKBody, error) ContainerUpdate(ctx context.Context, container string, updateConfig container.UpdateConfig) (container.UpdateResponse, error)
ContainerWait(ctx context.Context, container string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error) ContainerWait(ctx context.Context, container string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error)
CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, container.PathStat, error) CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, container.PathStat, error)
CopyToContainer(ctx context.Context, container, path string, content io.Reader, options container.CopyToContainerOptions) error CopyToContainer(ctx context.Context, container, path string, content io.Reader, options container.CopyToContainerOptions) error
@ -91,18 +113,30 @@ type ImageAPIClient interface {
BuildCachePrune(ctx context.Context, opts types.BuildCachePruneOptions) (*types.BuildCachePruneReport, error) BuildCachePrune(ctx context.Context, opts types.BuildCachePruneOptions) (*types.BuildCachePruneReport, error)
BuildCancel(ctx context.Context, id string) error BuildCancel(ctx context.Context, id string) error
ImageCreate(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, error) ImageCreate(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, error)
ImageHistory(ctx context.Context, image string) ([]image.HistoryResponseItem, error)
ImageImport(ctx context.Context, source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) ImageImport(ctx context.Context, source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error)
ImageInspectWithRaw(ctx context.Context, image string) (types.ImageInspect, []byte, error)
ImageList(ctx context.Context, options image.ListOptions) ([]image.Summary, error) ImageList(ctx context.Context, options image.ListOptions) ([]image.Summary, error)
ImageLoad(ctx context.Context, input io.Reader, quiet bool) (image.LoadResponse, error)
ImagePull(ctx context.Context, ref string, options image.PullOptions) (io.ReadCloser, error) ImagePull(ctx context.Context, ref string, options image.PullOptions) (io.ReadCloser, error)
ImagePush(ctx context.Context, ref string, options image.PushOptions) (io.ReadCloser, error) ImagePush(ctx context.Context, ref string, options image.PushOptions) (io.ReadCloser, error)
ImageRemove(ctx context.Context, image string, options image.RemoveOptions) ([]image.DeleteResponse, error) ImageRemove(ctx context.Context, image string, options image.RemoveOptions) ([]image.DeleteResponse, error)
ImageSearch(ctx context.Context, term string, options registry.SearchOptions) ([]registry.SearchResult, error) ImageSearch(ctx context.Context, term string, options registry.SearchOptions) ([]registry.SearchResult, error)
ImageSave(ctx context.Context, images []string) (io.ReadCloser, error)
ImageTag(ctx context.Context, image, ref string) error ImageTag(ctx context.Context, image, ref string) error
ImagesPrune(ctx context.Context, pruneFilter filters.Args) (image.PruneReport, error) ImagesPrune(ctx context.Context, pruneFilter filters.Args) (image.PruneReport, error)
ImageInspect(ctx context.Context, image string, _ ...ImageInspectOption) (image.InspectResponse, error)
ImageHistory(ctx context.Context, image string, _ ...ImageHistoryOption) ([]image.HistoryResponseItem, error)
ImageLoad(ctx context.Context, input io.Reader, _ ...ImageLoadOption) (image.LoadResponse, error)
ImageSave(ctx context.Context, images []string, _ ...ImageSaveOption) (io.ReadCloser, error)
ImageAPIClientDeprecated
}
// ImageAPIClientDeprecated defines deprecated methods of the ImageAPIClient.
type ImageAPIClientDeprecated interface {
// ImageInspectWithRaw returns the image information and its raw representation.
//
// Deprecated: Use [Client.ImageInspect] instead. Raw response can be obtained using the [ImageInspectWithRawResponse] option.
ImageInspectWithRaw(ctx context.Context, image string) (image.InspectResponse, []byte, error)
} }
// NetworkAPIClient defines API client methods for the networks // NetworkAPIClient defines API client methods for the networks

Some files were not shown because too many files have changed in this diff Show More