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