diff --git a/daemon/container.go b/daemon/container.go index e03f585ca6..d43e95489d 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -103,7 +103,14 @@ func (daemon *Daemon) load(id string) (*container.Container, error) { } // Register makes a container object usable by the daemon as +// +// Deprecated: this function is unused and will be removed in the next release. func (daemon *Daemon) Register(c *container.Container) error { + return daemon.register(context.TODO(), c) +} + +// register makes a container object usable by the daemon as [container.Container.ID]. +func (daemon *Daemon) register(ctx context.Context, c *container.Container) error { // Attach to stdout and stderr if c.Config.OpenStdin { c.StreamConfig.NewInputPipes() @@ -116,8 +123,18 @@ func (daemon *Daemon) Register(c *container.Container) error { c.Lock() defer c.Unlock() + // FIXME(thaJeztah): this logic may not be atomic: + // + // - daemon.containers.Add does not promise to "add", allows overwriting a container with the given ID. + // - c.CheckpointTo may fail, in which case we registered a container, but failed to write to disk + // + // We should consider: + // + // - changing the signature of containers.Add to return an error if the + // given ID exists (potentially adding an alternative to "set" / "update") + // - adding a defer to rollback the "Add" when failing to CheckPoint. daemon.containers.Add(c.ID, c) - return c.CheckpointTo(context.TODO(), daemon.containersReplica) + return c.CheckpointTo(ctx, daemon.containersReplica) } func (daemon *Daemon) newContainer(name string, operatingSystem string, config *containertypes.Config, hostConfig *containertypes.HostConfig, imgID image.ID, managed bool) (*container.Container, error) { diff --git a/daemon/create.go b/daemon/create.go index e89ea83575..3e2227f743 100644 --- a/daemon/create.go +++ b/daemon/create.go @@ -236,7 +236,7 @@ func (daemon *Daemon) create(ctx context.Context, daemonCfg *config.Config, opts } daemon.updateContainerNetworkSettings(ctr, endpointsConfigs) - if err := daemon.Register(ctr); err != nil { + if err := daemon.register(ctx, ctr); err != nil { return nil, err } stateCtr.set(ctr.ID, "stopped") diff --git a/daemon/daemon.go b/daemon/daemon.go index 7c5d3fd1ac..3cbcec2ccd 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -335,7 +335,7 @@ func (daemon *Daemon) restore(cfg *configStore) error { mapLock.Unlock() return } - if err := daemon.Register(c); err != nil { + if err := daemon.register(context.TODO(), c); err != nil { logger.WithError(err).Error("failed to register container") mapLock.Lock() delete(containers, c.ID)