Merge pull request #3472 from rainzm/bugfix/guest_image

Bugfix: Guest Image
This commit is contained in:
yunion-ci-robot
2019-11-06 14:35:14 +08:00
committed by GitHub
9 changed files with 33 additions and 12 deletions
+2 -2
View File
@@ -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 {
+2
View File
@@ -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 (
+1 -1
View File
@@ -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
+6 -1
View File
@@ -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
+2 -2
View File
@@ -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)
}
}
+3 -5
View File
@@ -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)
+6
View File
@@ -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"`