github.com/portworx/docker@v1.12.1/daemon/update.go (about) 1 package daemon 2 3 import ( 4 "fmt" 5 6 "github.com/docker/engine-api/types/container" 7 ) 8 9 // ContainerUpdate updates configuration of the container 10 func (daemon *Daemon) ContainerUpdate(name string, hostConfig *container.HostConfig, validateHostname bool) ([]string, error) { 11 var warnings []string 12 13 warnings, err := daemon.verifyContainerSettings(hostConfig, nil, true, validateHostname) 14 if err != nil { 15 return warnings, err 16 } 17 18 if err := daemon.update(name, hostConfig); err != nil { 19 return warnings, err 20 } 21 22 return warnings, nil 23 } 24 25 // ContainerUpdateCmdOnBuild updates Path and Args for the container with ID cID. 26 func (daemon *Daemon) ContainerUpdateCmdOnBuild(cID string, cmd []string) error { 27 if len(cmd) == 0 { 28 return nil 29 } 30 c, err := daemon.GetContainer(cID) 31 if err != nil { 32 return err 33 } 34 c.Path = cmd[0] 35 c.Args = cmd[1:] 36 return nil 37 } 38 39 func (daemon *Daemon) update(name string, hostConfig *container.HostConfig) error { 40 if hostConfig == nil { 41 return nil 42 } 43 44 container, err := daemon.GetContainer(name) 45 if err != nil { 46 return err 47 } 48 49 restoreConfig := false 50 backupHostConfig := *container.HostConfig 51 defer func() { 52 if restoreConfig { 53 container.Lock() 54 container.HostConfig = &backupHostConfig 55 container.ToDisk() 56 container.Unlock() 57 } 58 }() 59 60 if container.RemovalInProgress || container.Dead { 61 return errCannotUpdate(container.ID, fmt.Errorf("Container is marked for removal and cannot be \"update\".")) 62 } 63 64 if container.IsRunning() && hostConfig.KernelMemory != 0 { 65 return errCannotUpdate(container.ID, fmt.Errorf("Can not update kernel memory to a running container, please stop it first.")) 66 } 67 68 if err := container.UpdateContainer(hostConfig); err != nil { 69 restoreConfig = true 70 return errCannotUpdate(container.ID, err) 71 } 72 73 // if Restart Policy changed, we need to update container monitor 74 container.UpdateMonitor(hostConfig.RestartPolicy) 75 76 // If container is not running, update hostConfig struct is enough, 77 // resources will be updated when the container is started again. 78 // If container is running (including paused), we need to update configs 79 // to the real world. 80 if container.IsRunning() && !container.IsRestarting() { 81 if err := daemon.containerd.UpdateResources(container.ID, toContainerdResources(hostConfig.Resources)); err != nil { 82 restoreConfig = true 83 return errCannotUpdate(container.ID, err) 84 } 85 } 86 87 daemon.LogContainerEvent(container, "update") 88 89 return nil 90 } 91 92 func errCannotUpdate(containerID string, err error) error { 93 return fmt.Errorf("Cannot update container %s: %v", containerID, err) 94 }