github.com/rumpl/bof@v23.0.0-rc.2+incompatible/daemon/update.go (about) 1 package daemon // import "github.com/docker/docker/daemon" 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/docker/docker/api/types/container" 8 "github.com/docker/docker/errdefs" 9 "github.com/pkg/errors" 10 ) 11 12 // ContainerUpdate updates configuration of the container 13 func (daemon *Daemon) ContainerUpdate(name string, hostConfig *container.HostConfig) (container.ContainerUpdateOKBody, error) { 14 var warnings []string 15 16 warnings, err := daemon.verifyContainerSettings(hostConfig, nil, true) 17 if err != nil { 18 return container.ContainerUpdateOKBody{Warnings: warnings}, errdefs.InvalidParameter(err) 19 } 20 21 if err := daemon.update(name, hostConfig); err != nil { 22 return container.ContainerUpdateOKBody{Warnings: warnings}, err 23 } 24 25 return container.ContainerUpdateOKBody{Warnings: warnings}, nil 26 } 27 28 func (daemon *Daemon) update(name string, hostConfig *container.HostConfig) error { 29 if hostConfig == nil { 30 return nil 31 } 32 33 ctr, err := daemon.GetContainer(name) 34 if err != nil { 35 return err 36 } 37 38 restoreConfig := false 39 backupHostConfig := *ctr.HostConfig 40 41 defer func() { 42 if restoreConfig { 43 ctr.Lock() 44 if !ctr.RemovalInProgress && !ctr.Dead { 45 ctr.HostConfig = &backupHostConfig 46 ctr.CheckpointTo(daemon.containersReplica) 47 } 48 ctr.Unlock() 49 } 50 }() 51 52 ctr.Lock() 53 54 if ctr.RemovalInProgress || ctr.Dead { 55 ctr.Unlock() 56 return errCannotUpdate(ctr.ID, fmt.Errorf("container is marked for removal and cannot be \"update\"")) 57 } 58 59 if err := ctr.UpdateContainer(hostConfig); err != nil { 60 restoreConfig = true 61 ctr.Unlock() 62 return errCannotUpdate(ctr.ID, err) 63 } 64 if err := ctr.CheckpointTo(daemon.containersReplica); err != nil { 65 restoreConfig = true 66 ctr.Unlock() 67 return errCannotUpdate(ctr.ID, err) 68 } 69 70 ctr.Unlock() 71 72 // if Restart Policy changed, we need to update container monitor 73 if hostConfig.RestartPolicy.Name != "" { 74 ctr.UpdateMonitor(hostConfig.RestartPolicy) 75 } 76 77 // If container is not running, update hostConfig struct is enough, 78 // resources will be updated when the container is started again. 79 // If container is running (including paused), we need to update configs 80 // to the real world. 81 if ctr.IsRunning() && !ctr.IsRestarting() { 82 if err := daemon.containerd.UpdateResources(context.Background(), ctr.ID, toContainerdResources(hostConfig.Resources)); err != nil { 83 restoreConfig = true 84 // TODO: it would be nice if containerd responded with better errors here so we can classify this better. 85 return errCannotUpdate(ctr.ID, errdefs.System(err)) 86 } 87 } 88 89 daemon.LogContainerEvent(ctr, "update") 90 91 return nil 92 } 93 94 func errCannotUpdate(containerID string, err error) error { 95 return errors.Wrap(err, "Cannot update container "+containerID) 96 }