github.com/kinvolk/docker@v1.13.1/daemon/update.go (about)

     1  package daemon
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/docker/docker/api/types/container"
     7  )
     8  
     9  // ContainerUpdate updates configuration of the container
    10  func (daemon *Daemon) ContainerUpdate(name string, hostConfig *container.HostConfig) (container.ContainerUpdateOKBody, error) {
    11  	var warnings []string
    12  
    13  	warnings, err := daemon.verifyContainerSettings(hostConfig, nil, true)
    14  	if err != nil {
    15  		return container.ContainerUpdateOKBody{Warnings: warnings}, err
    16  	}
    17  
    18  	if err := daemon.update(name, hostConfig); err != nil {
    19  		return container.ContainerUpdateOKBody{Warnings: warnings}, err
    20  	}
    21  
    22  	return container.ContainerUpdateOKBody{Warnings: 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 err := container.UpdateContainer(hostConfig); err != nil {
    65  		restoreConfig = true
    66  		return errCannotUpdate(container.ID, err)
    67  	}
    68  
    69  	// if Restart Policy changed, we need to update container monitor
    70  	if hostConfig.RestartPolicy.Name != "" {
    71  		container.UpdateMonitor(hostConfig.RestartPolicy)
    72  	}
    73  
    74  	// If container is not running, update hostConfig struct is enough,
    75  	// resources will be updated when the container is started again.
    76  	// If container is running (including paused), we need to update configs
    77  	// to the real world.
    78  	if container.IsRunning() && !container.IsRestarting() {
    79  		if err := daemon.containerd.UpdateResources(container.ID, toContainerdResources(hostConfig.Resources)); err != nil {
    80  			restoreConfig = true
    81  			return errCannotUpdate(container.ID, err)
    82  		}
    83  	}
    84  
    85  	daemon.LogContainerEvent(container, "update")
    86  
    87  	return nil
    88  }
    89  
    90  func errCannotUpdate(containerID string, err error) error {
    91  	return fmt.Errorf("Cannot update container %s: %v", containerID, err)
    92  }