Signed-off-by: Derek McGowan <derek@mcg.dev>
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,14 @@ |
| 0 |
+package libcontainerd |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "context" |
|
| 4 |
+ |
|
| 5 |
+ containerd "github.com/containerd/containerd/v2/client" |
|
| 6 |
+ "github.com/docker/docker/daemon/internal/libcontainerd/remote" |
|
| 7 |
+ libcontainerdtypes "github.com/docker/docker/daemon/internal/libcontainerd/types" |
|
| 8 |
+) |
|
| 9 |
+ |
|
| 10 |
+// NewClient creates a new libcontainerd client from a containerd client |
|
| 11 |
+func NewClient(ctx context.Context, cli *containerd.Client, stateDir, ns string, b libcontainerdtypes.Backend) (libcontainerdtypes.Client, error) {
|
|
| 12 |
+ return remote.NewClient(ctx, cli, stateDir, ns, b) |
|
| 13 |
+} |
| 0 | 14 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,19 @@ |
| 0 |
+package libcontainerd |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "context" |
|
| 4 |
+ |
|
| 5 |
+ containerd "github.com/containerd/containerd/v2/client" |
|
| 6 |
+ "github.com/docker/docker/daemon/internal/libcontainerd/local" |
|
| 7 |
+ "github.com/docker/docker/daemon/internal/libcontainerd/remote" |
|
| 8 |
+ libcontainerdtypes "github.com/docker/docker/daemon/internal/libcontainerd/types" |
|
| 9 |
+ "github.com/docker/docker/pkg/system" |
|
| 10 |
+) |
|
| 11 |
+ |
|
| 12 |
+// NewClient creates a new libcontainerd client from a containerd client |
|
| 13 |
+func NewClient(ctx context.Context, cli *containerd.Client, stateDir, ns string, b libcontainerdtypes.Backend) (libcontainerdtypes.Client, error) {
|
|
| 14 |
+ if !system.ContainerdRuntimeSupported() {
|
|
| 15 |
+ return local.NewClient(ctx, b) |
|
| 16 |
+ } |
|
| 17 |
+ return remote.NewClient(ctx, cli, stateDir, ns, b) |
|
| 18 |
+} |
| 0 | 19 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,61 @@ |
| 0 |
+package libcontainerd |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "context" |
|
| 4 |
+ |
|
| 5 |
+ containerd "github.com/containerd/containerd/v2/client" |
|
| 6 |
+ cerrdefs "github.com/containerd/errdefs" |
|
| 7 |
+ "github.com/containerd/log" |
|
| 8 |
+ "github.com/opencontainers/runtime-spec/specs-go" |
|
| 9 |
+ "github.com/pkg/errors" |
|
| 10 |
+ |
|
| 11 |
+ "github.com/docker/docker/daemon/internal/libcontainerd/types" |
|
| 12 |
+) |
|
| 13 |
+ |
|
| 14 |
+// ReplaceContainer creates a new container, replacing any existing container |
|
| 15 |
+// with the same id if necessary. |
|
| 16 |
+func ReplaceContainer(ctx context.Context, client types.Client, id string, spec *specs.Spec, shim string, runtimeOptions interface{}, opts ...containerd.NewContainerOpts) (types.Container, error) {
|
|
| 17 |
+ newContainer := func() (types.Container, error) {
|
|
| 18 |
+ return client.NewContainer(ctx, id, spec, shim, runtimeOptions, opts...) |
|
| 19 |
+ } |
|
| 20 |
+ ctr, err := newContainer() |
|
| 21 |
+ if err == nil || !cerrdefs.IsConflict(err) {
|
|
| 22 |
+ return ctr, err |
|
| 23 |
+ } |
|
| 24 |
+ |
|
| 25 |
+ log.G(ctx).WithContext(ctx).WithField("container", id).Debug("A container already exists with the same ID. Attempting to clean up the old container.")
|
|
| 26 |
+ ctr, err = client.LoadContainer(ctx, id) |
|
| 27 |
+ if err != nil {
|
|
| 28 |
+ if cerrdefs.IsNotFound(err) {
|
|
| 29 |
+ // Task failed successfully: the container no longer exists, |
|
| 30 |
+ // despite us not doing anything. May as well try to create |
|
| 31 |
+ // the container again. It might succeed. |
|
| 32 |
+ return newContainer() |
|
| 33 |
+ } |
|
| 34 |
+ return nil, errors.Wrap(err, "could not load stale containerd container object") |
|
| 35 |
+ } |
|
| 36 |
+ tsk, err := ctr.Task(ctx) |
|
| 37 |
+ if err != nil {
|
|
| 38 |
+ if cerrdefs.IsNotFound(err) {
|
|
| 39 |
+ goto deleteContainer |
|
| 40 |
+ } |
|
| 41 |
+ // There is no point in trying to delete the container if we |
|
| 42 |
+ // cannot determine whether or not it has a task. The containerd |
|
| 43 |
+ // client would just try to load the task itself, get the same |
|
| 44 |
+ // error, and give up. |
|
| 45 |
+ return nil, errors.Wrap(err, "could not load stale containerd task object") |
|
| 46 |
+ } |
|
| 47 |
+ if err := tsk.ForceDelete(ctx); err != nil {
|
|
| 48 |
+ if !cerrdefs.IsNotFound(err) {
|
|
| 49 |
+ return nil, errors.Wrap(err, "could not delete stale containerd task object") |
|
| 50 |
+ } |
|
| 51 |
+ // The task might have exited on its own. Proceed with |
|
| 52 |
+ // attempting to delete the container. |
|
| 53 |
+ } |
|
| 54 |
+deleteContainer: |
|
| 55 |
+ if err := ctr.Delete(ctx); err != nil && !cerrdefs.IsNotFound(err) {
|
|
| 56 |
+ return nil, errors.Wrap(err, "could not delete stale containerd container object") |
|
| 57 |
+ } |
|
| 58 |
+ |
|
| 59 |
+ return newContainer() |
|
| 60 |
+} |
| ... | ... |
@@ -11,9 +11,9 @@ import ( |
| 11 | 11 |
"github.com/containerd/containerd/v2/pkg/cio" |
| 12 | 12 |
cerrdefs "github.com/containerd/errdefs" |
| 13 | 13 |
"github.com/containerd/log" |
| 14 |
+ "github.com/docker/docker/daemon/internal/libcontainerd" |
|
| 14 | 15 |
libcontainerdtypes "github.com/docker/docker/daemon/internal/libcontainerd/types" |
| 15 | 16 |
"github.com/docker/docker/errdefs" |
| 16 |
- "github.com/docker/docker/libcontainerd" |
|
| 17 | 17 |
"github.com/opencontainers/runtime-spec/specs-go" |
| 18 | 18 |
"github.com/pkg/errors" |
| 19 | 19 |
) |
| ... | ... |
@@ -11,10 +11,10 @@ import ( |
| 11 | 11 |
"github.com/docker/docker/api/types/events" |
| 12 | 12 |
"github.com/docker/docker/daemon/container" |
| 13 | 13 |
mobyc8dstore "github.com/docker/docker/daemon/containerd" |
| 14 |
+ "github.com/docker/docker/daemon/internal/libcontainerd" |
|
| 14 | 15 |
"github.com/docker/docker/daemon/internal/metrics" |
| 15 | 16 |
"github.com/docker/docker/errdefs" |
| 16 | 17 |
"github.com/docker/docker/internal/otelutil" |
| 17 |
- "github.com/docker/docker/libcontainerd" |
|
| 18 | 18 |
"github.com/pkg/errors" |
| 19 | 19 |
"go.opentelemetry.io/otel" |
| 20 | 20 |
"go.opentelemetry.io/otel/attribute" |
| 21 | 21 |
deleted file mode 100644 |
| ... | ... |
@@ -1,14 +0,0 @@ |
| 1 |
-package libcontainerd |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "context" |
|
| 5 |
- |
|
| 6 |
- containerd "github.com/containerd/containerd/v2/client" |
|
| 7 |
- "github.com/docker/docker/daemon/internal/libcontainerd/remote" |
|
| 8 |
- libcontainerdtypes "github.com/docker/docker/daemon/internal/libcontainerd/types" |
|
| 9 |
-) |
|
| 10 |
- |
|
| 11 |
-// NewClient creates a new libcontainerd client from a containerd client |
|
| 12 |
-func NewClient(ctx context.Context, cli *containerd.Client, stateDir, ns string, b libcontainerdtypes.Backend) (libcontainerdtypes.Client, error) {
|
|
| 13 |
- return remote.NewClient(ctx, cli, stateDir, ns, b) |
|
| 14 |
-} |
| 15 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,19 +0,0 @@ |
| 1 |
-package libcontainerd |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "context" |
|
| 5 |
- |
|
| 6 |
- containerd "github.com/containerd/containerd/v2/client" |
|
| 7 |
- "github.com/docker/docker/daemon/internal/libcontainerd/local" |
|
| 8 |
- "github.com/docker/docker/daemon/internal/libcontainerd/remote" |
|
| 9 |
- libcontainerdtypes "github.com/docker/docker/daemon/internal/libcontainerd/types" |
|
| 10 |
- "github.com/docker/docker/pkg/system" |
|
| 11 |
-) |
|
| 12 |
- |
|
| 13 |
-// NewClient creates a new libcontainerd client from a containerd client |
|
| 14 |
-func NewClient(ctx context.Context, cli *containerd.Client, stateDir, ns string, b libcontainerdtypes.Backend) (libcontainerdtypes.Client, error) {
|
|
| 15 |
- if !system.ContainerdRuntimeSupported() {
|
|
| 16 |
- return local.NewClient(ctx, b) |
|
| 17 |
- } |
|
| 18 |
- return remote.NewClient(ctx, cli, stateDir, ns, b) |
|
| 19 |
-} |
| 20 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,61 +0,0 @@ |
| 1 |
-package libcontainerd |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "context" |
|
| 5 |
- |
|
| 6 |
- containerd "github.com/containerd/containerd/v2/client" |
|
| 7 |
- cerrdefs "github.com/containerd/errdefs" |
|
| 8 |
- "github.com/containerd/log" |
|
| 9 |
- "github.com/opencontainers/runtime-spec/specs-go" |
|
| 10 |
- "github.com/pkg/errors" |
|
| 11 |
- |
|
| 12 |
- "github.com/docker/docker/daemon/internal/libcontainerd/types" |
|
| 13 |
-) |
|
| 14 |
- |
|
| 15 |
-// ReplaceContainer creates a new container, replacing any existing container |
|
| 16 |
-// with the same id if necessary. |
|
| 17 |
-func ReplaceContainer(ctx context.Context, client types.Client, id string, spec *specs.Spec, shim string, runtimeOptions interface{}, opts ...containerd.NewContainerOpts) (types.Container, error) {
|
|
| 18 |
- newContainer := func() (types.Container, error) {
|
|
| 19 |
- return client.NewContainer(ctx, id, spec, shim, runtimeOptions, opts...) |
|
| 20 |
- } |
|
| 21 |
- ctr, err := newContainer() |
|
| 22 |
- if err == nil || !cerrdefs.IsConflict(err) {
|
|
| 23 |
- return ctr, err |
|
| 24 |
- } |
|
| 25 |
- |
|
| 26 |
- log.G(ctx).WithContext(ctx).WithField("container", id).Debug("A container already exists with the same ID. Attempting to clean up the old container.")
|
|
| 27 |
- ctr, err = client.LoadContainer(ctx, id) |
|
| 28 |
- if err != nil {
|
|
| 29 |
- if cerrdefs.IsNotFound(err) {
|
|
| 30 |
- // Task failed successfully: the container no longer exists, |
|
| 31 |
- // despite us not doing anything. May as well try to create |
|
| 32 |
- // the container again. It might succeed. |
|
| 33 |
- return newContainer() |
|
| 34 |
- } |
|
| 35 |
- return nil, errors.Wrap(err, "could not load stale containerd container object") |
|
| 36 |
- } |
|
| 37 |
- tsk, err := ctr.Task(ctx) |
|
| 38 |
- if err != nil {
|
|
| 39 |
- if cerrdefs.IsNotFound(err) {
|
|
| 40 |
- goto deleteContainer |
|
| 41 |
- } |
|
| 42 |
- // There is no point in trying to delete the container if we |
|
| 43 |
- // cannot determine whether or not it has a task. The containerd |
|
| 44 |
- // client would just try to load the task itself, get the same |
|
| 45 |
- // error, and give up. |
|
| 46 |
- return nil, errors.Wrap(err, "could not load stale containerd task object") |
|
| 47 |
- } |
|
| 48 |
- if err := tsk.ForceDelete(ctx); err != nil {
|
|
| 49 |
- if !cerrdefs.IsNotFound(err) {
|
|
| 50 |
- return nil, errors.Wrap(err, "could not delete stale containerd task object") |
|
| 51 |
- } |
|
| 52 |
- // The task might have exited on its own. Proceed with |
|
| 53 |
- // attempting to delete the container. |
|
| 54 |
- } |
|
| 55 |
-deleteContainer: |
|
| 56 |
- if err := ctr.Delete(ctx); err != nil && !cerrdefs.IsNotFound(err) {
|
|
| 57 |
- return nil, errors.Wrap(err, "could not delete stale containerd container object") |
|
| 58 |
- } |
|
| 59 |
- |
|
| 60 |
- return newContainer() |
|
| 61 |
-} |