update.go 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package daemon
  2. import (
  3. "fmt"
  4. "github.com/docker/docker/api/types/container"
  5. )
  6. // ContainerUpdate updates configuration of the container
  7. func (daemon *Daemon) ContainerUpdate(name string, hostConfig *container.HostConfig) (container.ContainerUpdateOKBody, error) {
  8. var warnings []string
  9. warnings, err := daemon.verifyContainerSettings(hostConfig, nil, true)
  10. if err != nil {
  11. return container.ContainerUpdateOKBody{Warnings: warnings}, err
  12. }
  13. if err := daemon.update(name, hostConfig); err != nil {
  14. return container.ContainerUpdateOKBody{Warnings: warnings}, err
  15. }
  16. return container.ContainerUpdateOKBody{Warnings: 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. if hostConfig.RestartPolicy.Name != "" {
  58. container.UpdateMonitor(hostConfig.RestartPolicy)
  59. }
  60. // If container is not running, update hostConfig struct is enough,
  61. // resources will be updated when the container is started again.
  62. // If container is running (including paused), we need to update configs
  63. // to the real world.
  64. if container.IsRunning() && !container.IsRestarting() {
  65. if err := daemon.containerd.UpdateResources(container.ID, toContainerdResources(hostConfig.Resources)); err != nil {
  66. restoreConfig = true
  67. return errCannotUpdate(container.ID, err)
  68. }
  69. }
  70. daemon.LogContainerEvent(container, "update")
  71. return nil
  72. }
  73. func errCannotUpdate(containerID string, err error) error {
  74. return fmt.Errorf("Cannot update container %s: %v", containerID, err)
  75. }