mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-08-31 01:35:56 +08:00
Merge pull request #3472 from rainzm/bugfix/guest_image
Bugfix: Guest Image
This commit is contained in:
@@ -556,9 +556,9 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&options.ServerSaveImageOptions{}, "server-save-guest-image",
|
||||
R(&options.ServerSaveGuestImageOptions{}, "server-save-guest-image",
|
||||
"save root disk and data disks to new images and upload to glance.", func(s *mcclient.ClientSession,
|
||||
opts *options.ServerSaveImageOptions) error {
|
||||
opts *options.ServerSaveGuestImageOptions) error {
|
||||
|
||||
params, err := options.StructToParams(opts)
|
||||
if err != nil {
|
||||
|
||||
@@ -47,6 +47,8 @@ const (
|
||||
IMAGE_IS_READONLY = "is_readonly"
|
||||
IMAGE_PARTITION_TYPE = "partition_type"
|
||||
IMAGE_INSTALLED_CLOUDINIT = "installed_cloud_init"
|
||||
|
||||
IMAGE_STATUS_UPDATING = "updating"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
@@ -300,7 +300,7 @@ func (self *SVirtualizedGuestDriver) StartGuestSaveImage(ctx context.Context, us
|
||||
|
||||
func (self *SVirtualizedGuestDriver) StartGuestSaveGuestImage(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
guest *models.SGuest, params *jsonutils.JSONDict, parentTaskId string) error {
|
||||
|
||||
guest.SetStatus(userCred, api.VM_START_SAVE_DISK, "")
|
||||
if task, err := taskman.TaskManager.NewTask(ctx, "GuestSaveGuestImageTask", guest, userCred, params, parentTaskId,
|
||||
"", nil); err != nil {
|
||||
return err
|
||||
|
||||
@@ -1511,7 +1511,12 @@ func parseIsoInfo(ctx context.Context, userCred mcclient.TokenCredential, imageI
|
||||
func (self *SDisk) fetchDiskInfo(diskConfig *api.DiskConfig) {
|
||||
if len(diskConfig.ImageId) > 0 {
|
||||
self.TemplateId = diskConfig.ImageId
|
||||
self.DiskType = api.DISK_TYPE_SYS
|
||||
// support for create vm from guest image
|
||||
if len(diskConfig.DiskType) == 0 {
|
||||
self.DiskType = api.DISK_TYPE_SYS
|
||||
} else {
|
||||
self.DiskType = diskConfig.DiskType
|
||||
}
|
||||
} else if len(diskConfig.SnapshotId) > 0 {
|
||||
self.SnapshotId = diskConfig.SnapshotId
|
||||
self.DiskType = diskConfig.DiskType
|
||||
|
||||
@@ -199,7 +199,7 @@ func (self *SGuest) PerformSaveGuestImage(ctx context.Context, userCred mcclient
|
||||
if !utils.IsInStringArray(self.Status, []string{api.VM_READY}) {
|
||||
return nil, httperrors.NewBadRequestError("Cannot save image in status %s", self.Status)
|
||||
}
|
||||
if !data.Contains("name") {
|
||||
if !data.Contains("name") && !data.Contains("generate_name") {
|
||||
return nil, httperrors.NewMissingParameterError("Image name is required")
|
||||
}
|
||||
if self.Hypervisor != api.HYPERVISOR_KVM {
|
||||
@@ -238,7 +238,7 @@ func (self *SGuest) PerformSaveGuestImage(ctx context.Context, userCred mcclient
|
||||
|
||||
kwargs.Add(images, "images")
|
||||
|
||||
s := auth.GetAdminSession(ctx, options.Options.Region, "")
|
||||
s := auth.GetSession(ctx, userCred, options.Options.Region, "")
|
||||
ret, err := modules.GuestImages.Create(s, kwargs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -66,10 +66,11 @@ func (self *GuestSaveGuestImageTask) OnSaveRootImageComplete(ctx context.Context
|
||||
self.taskFailed(ctx, guest, "subtask failed")
|
||||
}
|
||||
|
||||
if restart, _ := self.GetParams().Bool("restart"); restart {
|
||||
if restart, _ := self.GetParams().Bool("auto_start"); restart {
|
||||
self.SetStage("on_start_server_complete", nil)
|
||||
guest.StartGueststartTask(ctx, self.GetUserCred(), nil, self.GetTaskId())
|
||||
} else {
|
||||
guest.SetStatus(self.UserCred, api.VM_READY, "")
|
||||
self.taskSuc(ctx, guest)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,7 +554,7 @@ func (self *SImage) ImageProbeAndCustomization(
|
||||
|
||||
func (self *SImage) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
if self.Status != api.IMAGE_STATUS_QUEUED {
|
||||
if self.IsGuestImage.IsTrue() && !self.CanUpdate(data) {
|
||||
if !self.CanUpdate(data) {
|
||||
return nil, httperrors.NewForbiddenError("image is the part of guest imgae")
|
||||
}
|
||||
appParams := appsrv.AppContextGetParams(ctx)
|
||||
@@ -1263,8 +1263,6 @@ func (self *SImage) PerformUpdateTorrentStatus(ctx context.Context, userCred mcc
|
||||
|
||||
func (self *SImage) CanUpdate(data jsonutils.JSONObject) bool {
|
||||
dict := data.(*jsonutils.JSONDict)
|
||||
if dict.Length() == 1 && !dict.Contains("description") {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
// Only allow update description for now when Image is part of guest image
|
||||
return self.IsGuestImage.IsFalse() || (dict.Length() == 1 && dict.Contains("description"))
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/image"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/image/models"
|
||||
@@ -37,6 +38,10 @@ func init() {
|
||||
|
||||
func (self *GuestImageUpdateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
guestImage := obj.(*models.SGuestImage)
|
||||
|
||||
self.Params.Add(jsonutils.NewString(guestImage.Status), "old_status")
|
||||
guestImage.SetStatus(self.UserCred, image.IMAGE_STATUS_UPDATING, "")
|
||||
|
||||
subImages, err := models.GuestImageJointManager.GetImagesByFilter(guestImage.GetId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Asc("name")
|
||||
})
|
||||
@@ -75,10 +80,14 @@ func (self *GuestImageUpdateTask) OnInit(ctx context.Context, obj db.IStandalone
|
||||
return
|
||||
}
|
||||
}
|
||||
oldStatus, _ := self.Params.GetString("old_status")
|
||||
guestImage.SetStatus(self.UserCred, oldStatus, "")
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
func (self *GuestImageUpdateTask) taskFailed(ctx context.Context, guestImage *models.SGuestImage, reason string) {
|
||||
oldStatus, _ := self.Params.GetString("old_status")
|
||||
guestImage.SetStatus(self.UserCred, oldStatus, "")
|
||||
db.OpsLog.LogEvent(guestImage, db.ACT_SUBIMAGE_UPDATE_FAIL, reason, self.UserCred)
|
||||
logclient.AddActionLogWithContext(ctx, guestImage, logclient.ACT_SUBIMAGE_UPDATE, reason, self.UserCred, false)
|
||||
self.SetStageFailed(ctx, reason)
|
||||
|
||||
@@ -539,6 +539,12 @@ type ServerSaveImageOptions struct {
|
||||
AutoStart *bool `help:"Auto start server after image saved"`
|
||||
}
|
||||
|
||||
type ServerSaveGuestImageOptions struct {
|
||||
ID string `help:"ID or name of server" json:"-"`
|
||||
IMAGE string `help:"Image name" json:"name"`
|
||||
AutoStart *bool `help:"Auto start server after image saved"`
|
||||
}
|
||||
|
||||
type ServerRebuildRootOptions struct {
|
||||
ID string `help:"Server to rebuild root" json:"-"`
|
||||
ImageId string `help:"New root Image template ID" json:"image_id" token:"image"`
|
||||
|
||||
Reference in New Issue
Block a user