diff --git a/cmd/climc/shell/compute/disks.go b/cmd/climc/shell/compute/disks.go index 500eb6ca47..39a72b2d0e 100644 --- a/cmd/climc/shell/compute/disks.go +++ b/cmd/climc/shell/compute/disks.go @@ -42,6 +42,7 @@ import ( func init() { cmd := shell.NewResourceCmd(&modules.Disks) cmd.Perform("set-class-metadata", &options.ResourceMetadataOptions{}) + cmd.Perform("rebuild", &options.ResourceIdOptions{}) type DiskListOptions struct { options.BaseListOptions diff --git a/pkg/apis/compute/disk.go b/pkg/apis/compute/disk.go index 8a88c86021..6f04ec81fd 100644 --- a/pkg/apis/compute/disk.go +++ b/pkg/apis/compute/disk.go @@ -327,3 +327,5 @@ type DiskResetInput struct { type DiskSnapshotpolicyInput struct { SnapshotpolicyId string `json:"snapshotpolicy_id"` } + +type DiskRebuildInput struct{} diff --git a/pkg/compute/models/disks.go b/pkg/compute/models/disks.go index dbf7d518df..e6a6f0a6d1 100644 --- a/pkg/compute/models/disks.go +++ b/pkg/compute/models/disks.go @@ -2985,3 +2985,18 @@ func (manager *SDiskManager) ListItemExportKeys(ctx context.Context, } return q, nil } + +func (disk *SDisk) PerformRebuild( + ctx context.Context, + userCred mcclient.TokenCredential, + query jsonutils.JSONObject, + input *api.DiskRebuildInput, +) (jsonutils.JSONObject, error) { + guests := disk.GetGuests() + for _, guest := range guests { + if guest.GetStatus() != api.VM_READY { + return nil, httperrors.NewInvalidStatusError("Guest %s status is %s", guest.GetId(), guest.GetStatus()) + } + } + return nil, disk.StartDiskCreateTask(ctx, userCred, true, disk.SnapshotId, "") +} diff --git a/pkg/compute/tasks/disk_create_task.go b/pkg/compute/tasks/disk_create_task.go index 8ba5defd3e..fc4338f693 100644 --- a/pkg/compute/tasks/disk_create_task.go +++ b/pkg/compute/tasks/disk_create_task.go @@ -130,6 +130,13 @@ func (self *DiskCreateTask) OnDiskReady(ctx context.Context, disk *models.SDisk, Obj: disk, Action: notifyclient.ActionCreate, }) + if !self.IsSubtask() { + guest := disk.GetGuest() + if guest != nil { + // just sync guest status + guest.StartSyncstatus(ctx, self.GetUserCred(), "") + } + } self.SetStageComplete(ctx, nil) } diff --git a/pkg/mcclient/options/metadata.go b/pkg/mcclient/options/metadata.go index 96ef9ae2d6..df6d51e17e 100644 --- a/pkg/mcclient/options/metadata.go +++ b/pkg/mcclient/options/metadata.go @@ -129,6 +129,18 @@ func (opts *DomainTagValueTreeOptions) Property() string { return "domain-tag-value-tree" } +type ResourceIdOptions struct { + ID string `help:"ID or name of the resource" json:"-"` +} + +func (o *ResourceIdOptions) GetId() string { + return o.ID +} + +func (o *ResourceIdOptions) Params() (jsonutils.JSONObject, error) { + return nil, nil +} + type ResourceMetadataOptions struct { ID string `help:"ID or name of resources" json:"-"` TAGS []string `help:"Tags info, eg: hypervisor=aliyun、os_type=Linux、os_version"`