container_create_task.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package container
  15. import (
  16. "context"
  17. "yunion.io/x/jsonutils"
  18. "yunion.io/x/pkg/errors"
  19. "yunion.io/x/onecloud/pkg/apis"
  20. api "yunion.io/x/onecloud/pkg/apis/compute"
  21. imageapi "yunion.io/x/onecloud/pkg/apis/image"
  22. "yunion.io/x/onecloud/pkg/cloudcommon/db"
  23. "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
  24. "yunion.io/x/onecloud/pkg/compute/models"
  25. )
  26. type ContainerBaseTask struct {
  27. taskman.STask
  28. }
  29. func (t *ContainerBaseTask) GetContainer() *models.SContainer {
  30. return t.GetObject().(*models.SContainer)
  31. }
  32. func (t *ContainerBaseTask) GetPod() *models.SGuest {
  33. return t.GetContainer().GetPod()
  34. }
  35. func (t *ContainerBaseTask) GetPodDriver() models.IPodDriver {
  36. drv, err := t.GetPod().GetDriver()
  37. if err != nil {
  38. return nil
  39. }
  40. return drv.(models.IPodDriver)
  41. }
  42. func (t *ContainerBaseTask) GetContainerCacheImagesInput(ctr *models.SContainer) (*api.ContainerCacheImagesInput, error) {
  43. input := &api.ContainerCacheImagesInput{}
  44. for i := range ctr.Spec.VolumeMounts {
  45. vol := ctr.Spec.VolumeMounts[i]
  46. if vol.Type != apis.CONTAINER_VOLUME_MOUNT_TYPE_DISK {
  47. continue
  48. }
  49. disk := vol.Disk
  50. for j := range disk.PostOverlay {
  51. pov := vol.Disk.PostOverlay[j]
  52. if pov.GetType() != apis.CONTAINER_VOLUME_MOUNT_DISK_POST_OVERLAY_IMAGE {
  53. continue
  54. }
  55. if err := input.Add(disk.Id, pov.Image.Id, imageapi.IMAGE_DISK_FORMAT_TGZ); err != nil {
  56. return nil, errors.Wrapf(err, "add disk %q, image %q", disk.Id, pov.Image.Id)
  57. }
  58. }
  59. }
  60. return input, nil
  61. }
  62. type ContainerCreateTask struct {
  63. ContainerBaseTask
  64. }
  65. func init() {
  66. taskman.RegisterTask(ContainerCreateTask{})
  67. }
  68. func (t *ContainerCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
  69. t.startPullImage(ctx, obj.(*models.SContainer))
  70. }
  71. func (t *ContainerCreateTask) startPullImage(ctx context.Context, container *models.SContainer) {
  72. t.SetStage("OnImagePulled", nil)
  73. input, err := container.GetHostPullImageInput(ctx, t.GetUserCred())
  74. if err != nil {
  75. t.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
  76. return
  77. }
  78. if err := container.StartPullImageTask(ctx, t.GetUserCred(), input, t.GetTaskId()); err != nil {
  79. t.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
  80. return
  81. }
  82. }
  83. func (t *ContainerCreateTask) OnImagePulled(ctx context.Context, container *models.SContainer, data jsonutils.JSONObject) {
  84. if jsonutils.QueryBoolean(t.GetParams(), "auto_start", false) {
  85. t.requestCreate(ctx, container)
  86. } else {
  87. container.SetStatus(ctx, t.GetUserCred(), api.CONTAINER_STATUS_EXITED, "")
  88. t.OnStarted(ctx, container, nil)
  89. }
  90. }
  91. func (t *ContainerCreateTask) OnImagePulledFailed(ctx context.Context, container *models.SContainer, reason jsonutils.JSONObject) {
  92. t.SetStageFailed(ctx, reason)
  93. }
  94. func (t *ContainerCreateTask) requestCreate(ctx context.Context, container *models.SContainer) {
  95. container.SetStatus(ctx, t.GetUserCred(), api.CONTAINER_STATUS_CREATING, "")
  96. t.SetStage("OnCreated", nil)
  97. if err := t.GetPodDriver().RequestCreateContainer(ctx, t.GetUserCred(), t); err != nil {
  98. t.OnCreatedFailed(ctx, container, jsonutils.NewString(err.Error()))
  99. return
  100. }
  101. }
  102. func (t *ContainerCreateTask) OnCreated(ctx context.Context, container *models.SContainer, data jsonutils.JSONObject) {
  103. t.SetStage("OnStarted", nil)
  104. if err := container.StartStartTask(ctx, t.GetUserCred(), t.GetTaskId()); err != nil {
  105. t.OnCreatedFailed(ctx, container, jsonutils.NewString(errors.Wrap(err, "StartStartTask").Error()))
  106. }
  107. }
  108. func (t *ContainerCreateTask) OnCreatedFailed(ctx context.Context, container *models.SContainer, reason jsonutils.JSONObject) {
  109. container.SetStatus(ctx, t.GetUserCred(), api.CONTAINER_STATUS_CREATE_FAILED, reason.String())
  110. t.SetStageFailed(ctx, reason)
  111. }
  112. func (t *ContainerCreateTask) OnStarted(ctx context.Context, container *models.SContainer, data jsonutils.JSONObject) {
  113. t.SetStageComplete(ctx, nil)
  114. }
  115. func (t *ContainerCreateTask) OnStartedFailed(ctx context.Context, container *models.SContainer, reason jsonutils.JSONObject) {
  116. t.SetStageFailed(ctx, reason)
  117. }