update.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package daemon
  2. import (
  3. "fmt"
  4. "github.com/docker/engine-api/types/container"
  5. )
  6. // ContainerUpdate updates configuration of the container
  7. func (daemon *Daemon) ContainerUpdate(name string, hostConfig *container.HostConfig, validateHostname bool) ([]string, error) {
  8. var warnings []string
  9. warnings, err := daemon.verifyContainerSettings(hostConfig, nil, true, validateHostname)
  10. if err != nil {
  11. return warnings, err
  12. }
  13. if err := daemon.update(name, hostConfig); err != nil {
  14. return warnings, err
  15. }
  16. return warnings, nil
  17. }
  18. // ContainerUpdateCmdOnBuild updates Path and Args for the container with ID cID.
  19. func (daemon *Daemon) ContainerUpdateCmdOnBuild(cID string, cmd []string) error {
  20. if len(cmd) == 0 {
  21. return nil
  22. }
  23. c, err := daemon.GetContainer(cID)
  24. if err != nil {
  25. return err
  26. }
  27. c.Path = cmd[0]
  28. c.Args = cmd[1:]
  29. return nil
  30. }
  31. func (daemon *Daemon) update(name string, hostConfig *container.HostConfig) error {
  32. if hostConfig == nil {
  33. return nil
  34. }
  35. container, err := daemon.GetContainer(name)
  36. if err != nil {
  37. return err
  38. }
  39. restoreConfig := false
  40. backupHostConfig := *container.HostConfig
  41. defer func() {
  42. if restoreConfig {
  43. container.Lock()
  44. container.HostConfig = &backupHostConfig
  45. container.ToDisk()
  46. container.Unlock()
  47. }
  48. }()
  49. if container.RemovalInProgress || container.Dead {
  50. return errCannotUpdate(container.ID, fmt.Errorf("Container is marked for removal and cannot be \"update\"."))
  51. }
  52. if err := container.UpdateContainer(hostConfig); err != nil {
  53. restoreConfig = true
  54. return errCannotUpdate(container.ID, err)
  55. }
  56. // if Restart Policy changed, we need to update container monitor
  57. container.UpdateMonitor(hostConfig.RestartPolicy)
  58. // If container is not running, update hostConfig struct is enough,
  59. // resources will be updated when the container is started again.
  60. // If container is running (including paused), we need to update configs
  61. // to the real world.
  62. if container.IsRunning() && !container.IsRestarting() {
  63. if err := daemon.containerd.UpdateResources(container.ID, toContainerdResources(hostConfig.Resources)); err != nil {
  64. restoreConfig = true
  65. return errCannotUpdate(container.ID, err)
  66. }
  67. }
  68. daemon.LogContainerEvent(container, "update")
  69. return nil
  70. }
  71. func errCannotUpdate(containerID string, err error) error {
  72. return fmt.Errorf("Cannot update container %s: %v", containerID, err)
  73. }