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  }