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  }