8799c4fc |
package daemon
import (
"fmt"
|
91e197d6 |
"github.com/docker/docker/api/types/container" |
ebcb7d6b |
"github.com/pkg/errors" |
8799c4fc |
)
|
ff3ea4c9 |
// ContainerUpdate updates configuration of the container |
ef39256d |
func (daemon *Daemon) ContainerUpdate(name string, hostConfig *container.HostConfig) (container.ContainerUpdateOKBody, error) { |
8799c4fc |
var warnings []string
|
9fa44906 |
c, err := daemon.GetContainer(name)
if err != nil {
return container.ContainerUpdateOKBody{Warnings: warnings}, err
}
|
0380fbff |
warnings, err = daemon.verifyContainerSettings(c.OS, hostConfig, nil, true) |
8799c4fc |
if err != nil { |
ebcb7d6b |
return container.ContainerUpdateOKBody{Warnings: warnings}, validationError{err} |
8799c4fc |
}
if err := daemon.update(name, hostConfig); err != nil { |
f196cf6a |
return container.ContainerUpdateOKBody{Warnings: warnings}, err |
8799c4fc |
}
|
f196cf6a |
return container.ContainerUpdateOKBody{Warnings: warnings}, nil |
8799c4fc |
}
func (daemon *Daemon) update(name string, hostConfig *container.HostConfig) error {
if hostConfig == nil {
return nil
}
container, err := daemon.GetContainer(name)
if err != nil {
return err
}
|
fa3b1971 |
restoreConfig := false
backupHostConfig := *container.HostConfig
defer func() {
if restoreConfig {
container.Lock()
container.HostConfig = &backupHostConfig |
edad5270 |
container.CheckpointTo(daemon.containersReplica) |
fa3b1971 |
container.Unlock()
}
}()
|
8799c4fc |
if container.RemovalInProgress || container.Dead { |
9b47b7b1 |
return errCannotUpdate(container.ID, fmt.Errorf("container is marked for removal and cannot be \"update\"")) |
8799c4fc |
}
|
eed4c7b7 |
container.Lock() |
8799c4fc |
if err := container.UpdateContainer(hostConfig); err != nil { |
fa3b1971 |
restoreConfig = true |
eed4c7b7 |
container.Unlock() |
a793564b |
return errCannotUpdate(container.ID, err) |
8799c4fc |
} |
aacddda8 |
if err := container.CheckpointTo(daemon.containersReplica); err != nil { |
eed4c7b7 |
restoreConfig = true
container.Unlock()
return errCannotUpdate(container.ID, err)
}
container.Unlock() |
8799c4fc |
|
ff3ea4c9 |
// if Restart Policy changed, we need to update container monitor |
737b5b17 |
if hostConfig.RestartPolicy.Name != "" {
container.UpdateMonitor(hostConfig.RestartPolicy)
} |
ff3ea4c9 |
|
8799c4fc |
// If container is not running, update hostConfig struct is enough,
// resources will be updated when the container is started again.
// If container is running (including paused), we need to update configs
// to the real world. |
ff3ea4c9 |
if container.IsRunning() && !container.IsRestarting() { |
9c4570a9 |
if err := daemon.containerd.UpdateResources(container.ID, toContainerdResources(hostConfig.Resources)); err != nil { |
fa3b1971 |
restoreConfig = true |
ebcb7d6b |
// TODO: it would be nice if containerd responded with better errors here so we can classify this better.
return errCannotUpdate(container.ID, systemError{err}) |
8799c4fc |
}
}
|
72f1881d |
daemon.LogContainerEvent(container, "update")
|
8799c4fc |
return nil
} |
a793564b |
func errCannotUpdate(containerID string, err error) error { |
ebcb7d6b |
return errors.Wrap(err, "Cannot update container "+containerID) |
a793564b |
} |