| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- // Copyright 2019 Yunion
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package disk
- import (
- "context"
- "fmt"
- "yunion.io/x/jsonutils"
- "yunion.io/x/log"
- "yunion.io/x/pkg/errors"
- "yunion.io/x/pkg/util/stringutils"
- api "yunion.io/x/onecloud/pkg/apis/compute"
- "yunion.io/x/onecloud/pkg/cloudcommon/db"
- "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
- "yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
- "yunion.io/x/onecloud/pkg/compute/models"
- "yunion.io/x/onecloud/pkg/util/logclient"
- )
- type DiskCreateTask struct {
- SDiskBaseTask
- }
- func (self *DiskCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
- disk := obj.(*models.SDisk)
- storage, _ := disk.GetStorage()
- storagecache := storage.GetStoragecache()
- imageId := disk.GetTemplateId()
- // use image only if disk not created from snapshot or backup
- if len(imageId) > 0 && len(disk.SnapshotId) == 0 && len(disk.BackupId) == 0 {
- self.SetStage("OnStorageCacheImageComplete", nil)
- cacheImageFmt, err := disk.GetCacheImageFormat(ctx)
- if err != nil {
- self.OnStartAllocateFailed(ctx, disk, jsonutils.NewString(err.Error()))
- return
- }
- input := api.CacheImageInput{
- ImageId: imageId,
- Format: cacheImageFmt,
- ParentTaskId: self.GetTaskId(),
- }
- guest := disk.GetGuest()
- if guest != nil {
- input.ServerId = guest.Id
- }
- storagecache.StartImageCacheTask(ctx, self.UserCred, input)
- } else {
- self.OnStorageCacheImageComplete(ctx, disk, nil)
- }
- }
- func (self *DiskCreateTask) OnStorageCacheImageComplete(ctx context.Context, disk *models.SDisk, data jsonutils.JSONObject) {
- rebuild, _ := self.GetParams().Bool("rebuild")
- snapshot, _ := self.GetParams().GetString("snapshot")
- if rebuild {
- db.OpsLog.LogEvent(disk, db.ACT_DELOCATE, disk.GetShortDesc(ctx), self.GetUserCred())
- } else {
- guest := disk.GetGuest()
- if guest != nil {
- guest.SetStatus(ctx, self.GetUserCred(), api.VM_CREATE_DISK, "OnStorageCacheImageComplete")
- }
- }
- storage, err := disk.GetStorage()
- if err != nil {
- self.OnStartAllocateFailed(ctx, disk, jsonutils.NewString(errors.Wrapf(err, "disk.GetStorage").Error()))
- return
- }
- host, err := disk.GetMasterHost(storage)
- if err != nil {
- self.OnStartAllocateFailed(ctx, disk, jsonutils.NewString(errors.Wrapf(err, "GetMasterHost").Error()))
- return
- }
- db.OpsLog.LogEvent(disk, db.ACT_ALLOCATING, disk.GetShortDesc(ctx), self.GetUserCred())
- disk.SetStatus(ctx, self.GetUserCred(), api.DISK_STARTALLOC, fmt.Sprintf("Disk start alloc use host %s(%s)", host.Name, host.Id))
- if rebuild && storage.StorageType == api.STORAGE_RBD {
- if count, _ := disk.GetSnapshotCount(); count > 0 {
- backingDiskId := stringutils.UUID4()
- self.Params.Set("backing_disk_id", jsonutils.NewString(backingDiskId))
- }
- }
- self.SetStage("OnDiskReady", nil)
- if err := disk.StartAllocate(ctx, host, storage, self.GetTaskId(), self.GetUserCred(), rebuild, snapshot, self); err != nil {
- self.OnStartAllocateFailed(ctx, disk, jsonutils.NewString(err.Error()))
- }
- }
- func (self *DiskCreateTask) OnStartAllocateFailed(ctx context.Context, disk *models.SDisk, data jsonutils.JSONObject) {
- disk.SetStatus(ctx, self.UserCred, api.DISK_ALLOC_FAILED, data.String())
- logclient.AddActionLogWithStartable(self, disk, logclient.ACT_ALLOCATE, data, self.UserCred, false)
- self.SetStageFailed(ctx, data)
- }
- func (self *DiskCreateTask) OnDiskReady(ctx context.Context, disk *models.SDisk, data jsonutils.JSONObject) {
- diskSize, _ := data.Int("disk_size")
- if _, err := db.Update(disk, func() error {
- disk.DiskSize = int(diskSize)
- diskFromat, _ := data.GetString("disk_format")
- if len(diskFromat) > 0 {
- disk.DiskFormat = diskFromat
- }
- disk.AccessPath, _ = data.GetString("disk_path")
- return nil
- }); err != nil {
- log.Errorf("update disk info error: %v", err)
- }
- if jsonutils.QueryBoolean(self.Params, "rebuild", false) {
- backingDiskId, _ := self.Params.GetString("backing_disk_id")
- if len(backingDiskId) > 0 {
- err := disk.UpdataSnapshotsBackingDisk(backingDiskId)
- if err != nil {
- log.Errorf("update disk snapshots backing disk fiailed %s", err)
- }
- }
- }
- disk.SetStatus(ctx, self.UserCred, api.DISK_READY, "")
- self.CleanHostSchedCache(disk)
- db.OpsLog.LogEvent(disk, db.ACT_ALLOCATE, disk.GetShortDesc(ctx), self.UserCred)
- notifyclient.EventNotify(ctx, self.UserCred, notifyclient.SEventNotifyParam{
- Obj: disk,
- Action: notifyclient.ActionCreate,
- })
- if !self.IsSubtask() {
- guest := disk.GetGuest()
- if guest != nil {
- // just sync guest status
- self.SetStage("OnGuestSyncstatusComplete", nil)
- guest.StartSyncstatus(ctx, self.GetUserCred(), self.GetTaskId())
- return
- }
- }
- self.SetStageComplete(ctx, nil)
- }
- func (self *DiskCreateTask) OnDiskReadyFailed(ctx context.Context, disk *models.SDisk, data jsonutils.JSONObject) {
- rebuild, _ := self.GetParams().Bool("rebuild")
- status := api.DISK_ALLOC_FAILED
- if rebuild {
- status = api.DISK_REBUILD_FAILED
- }
- disk.SetStatus(ctx, self.UserCred, status, data.String())
- logclient.AddActionLogWithStartable(self, disk, logclient.ACT_ALLOCATE, data, self.UserCred, false)
- self.SetStageFailed(ctx, data)
- }
- func (self *DiskCreateTask) OnGuestSyncstatusComplete(ctx context.Context, disk *models.SDisk, data jsonutils.JSONObject) {
- self.SetStageComplete(ctx, nil)
- }
- func (self *DiskCreateTask) OnGuestSyncstatusCompleteFailed(ctx context.Context, disk *models.SDisk, err jsonutils.JSONObject) {
- // ??? why
- log.Errorf("OnGuestSyncstatusCompleteFailed: %s", err.String())
- self.SetStageFailed(ctx, err)
- }
- func init() {
- taskman.RegisterTask(DiskCreateTask{})
- }
|