mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-10-28 03:23:25 +08:00
Feature/floppy (#15008)
* feat(region,host): add floppy,mult cdrom * fix floppy-device Co-authored-by: huangzekeng <huangzekeng@grgbanking.com>
This commit is contained in:
co-authored by
huangzekeng
parent
3a9f2de4ee
commit
bbaaf2da7e
@@ -325,7 +325,7 @@ func (self *SBaremetalGuestDriver) RequestGuestHotRemoveIso(ctx context.Context,
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) RequestGuestCreateInsertIso(ctx context.Context, imageId string, guest *models.SGuest, task taskman.ITask) error {
|
||||
return guest.StartInsertIsoTask(ctx, imageId, true, guest.HostId, task.GetUserCred(), task.GetTaskId())
|
||||
return guest.StartInsertIsoTask(ctx, 0, imageId, true, guest.HostId, task.GetUserCred(), task.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) RequestStartOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, userCred mcclient.TokenCredential, task taskman.ITask) error {
|
||||
@@ -611,3 +611,7 @@ func (self *SBaremetalGuestDriver) IsSupportCdrom(guest *models.SGuest) (bool, e
|
||||
}
|
||||
return ipmiInfo.CdromBoot, nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) IsSupportFloppy(guest *models.SGuest) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
@@ -248,6 +248,18 @@ func (self *SBaseGuestDriver) RequestRebuildRootDisk(ctx context.Context, guest
|
||||
return fmt.Errorf("Not Implement")
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) NeedRequestGuestHotAddVfd(ctx context.Context, guest *models.SGuest) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) RequestGuestHotAddVfd(ctx context.Context, guest *models.SGuest, path string, boot bool, task taskman.ITask) error {
|
||||
return fmt.Errorf("Not Implement")
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) RequestGuestHotRemoveVfd(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
|
||||
return fmt.Errorf("Not Implement")
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) RequestDiskSnapshot(ctx context.Context, guest *models.SGuest, task taskman.ITask, snapshotId, diskId string) error {
|
||||
return fmt.Errorf("Not Implement")
|
||||
}
|
||||
|
||||
@@ -80,6 +80,10 @@ func (self *SCloudpodsGuestDriver) IsSupportCdrom(guest *models.SGuest) (bool, e
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (self *SCloudpodsGuestDriver) IsSupportFloppy(guest *models.SGuest) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (self *SCloudpodsGuestDriver) IsSupportMigrate() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -220,3 +220,7 @@ func (self *SContainerDriver) IsSupportGuestClone() bool {
|
||||
func (self *SContainerDriver) IsSupportCdrom(guest *models.SGuest) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (self *SContainerDriver) IsSupportFloppy(guest *models.SGuest) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
@@ -651,6 +651,18 @@ func (self *SKVMGuestDriver) RequestGuestHotRemoveIso(ctx context.Context, guest
|
||||
return guest.StartSyncTask(ctx, task.GetUserCred(), false, task.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) NeedRequestGuestHotAddVfd(ctx context.Context, guest *models.SGuest) bool {
|
||||
return guest.Status == api.VM_RUNNING
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestGuestHotAddVfd(ctx context.Context, guest *models.SGuest, path string, boot bool, task taskman.ITask) error {
|
||||
return guest.StartSyncTask(ctx, task.GetUserCred(), false, task.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestGuestHotRemoveVfd(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
|
||||
return guest.StartSyncTask(ctx, task.GetUserCred(), false, task.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestRebuildRootDisk(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
|
||||
subtask, err := taskman.TaskManager.NewTask(ctx, "KVMGuestRebuildRootTask", guest, task.GetUserCred(), task.GetParams(), task.GetTaskId(), "", nil)
|
||||
if err != nil {
|
||||
@@ -714,6 +726,10 @@ func (self *SKVMGuestDriver) IsSupportCdrom(guest *models.SGuest) (bool, error)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) IsSupportFloppy(guest *models.SGuest) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) IsSupportMigrate() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1189,6 +1189,10 @@ func (self *SManagedVirtualizedGuestDriver) IsSupportCdrom(guest *models.SGuest)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (self *SManagedVirtualizedGuestDriver) IsSupportFloppy(guest *models.SGuest) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func GetCloudVMStatus(vm cloudprovider.ICloudVM) string {
|
||||
status := vm.GetStatus()
|
||||
switch status {
|
||||
|
||||
@@ -220,7 +220,7 @@ func (self *SVirtualizedGuestDriver) ChooseHostStorage(host *models.SHost, guest
|
||||
}
|
||||
|
||||
func (self *SVirtualizedGuestDriver) RequestGuestCreateInsertIso(ctx context.Context, imageId string, guest *models.SGuest, task taskman.ITask) error {
|
||||
return guest.StartInsertIsoTask(ctx, imageId, true, guest.HostId, task.GetUserCred(), task.GetTaskId())
|
||||
return guest.StartInsertIsoTask(ctx, 0, imageId, true, guest.HostId, task.GetUserCred(), task.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *SVirtualizedGuestDriver) StartGuestStopTask(guest *models.SGuest, ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error {
|
||||
|
||||
@@ -1139,18 +1139,18 @@ func (self *SGuest) StartGuestStopTask(ctx context.Context, userCred mcclient.To
|
||||
return self.GetDriver().StartGuestStopTask(self, ctx, userCred, params, parentTaskId)
|
||||
}
|
||||
|
||||
func (self *SGuest) insertIso(imageId string) bool {
|
||||
cdrom := self.getCdrom(true)
|
||||
func (self *SGuest) insertIso(imageId string, cdromOrdinal int64) bool {
|
||||
cdrom := self.getCdrom(true, cdromOrdinal)
|
||||
return cdrom.insertIso(imageId)
|
||||
}
|
||||
|
||||
func (self *SGuest) InsertIsoSucc(imageId string, path string, size int64, name string) bool {
|
||||
cdrom := self.getCdrom(false)
|
||||
func (self *SGuest) InsertIsoSucc(cdromOrdinal int64, imageId string, path string, size int64, name string) bool {
|
||||
cdrom := self.getCdrom(false, cdromOrdinal)
|
||||
return cdrom.insertIsoSucc(imageId, path, size, name)
|
||||
}
|
||||
|
||||
func (self *SGuest) GetDetailsIso(userCred mcclient.TokenCredential) jsonutils.JSONObject {
|
||||
cdrom := self.getCdrom(false)
|
||||
func (self *SGuest) GetDetailsIso(cdromOrdinal int64, userCred mcclient.TokenCredential) jsonutils.JSONObject {
|
||||
cdrom := self.getCdrom(false, cdromOrdinal)
|
||||
desc := jsonutils.NewDict()
|
||||
if len(cdrom.ImageId) > 0 {
|
||||
desc.Set("image_id", jsonutils.NewString(cdrom.ImageId))
|
||||
@@ -1168,7 +1168,11 @@ func (self *SGuest) PerformInsertiso(ctx context.Context, userCred mcclient.Toke
|
||||
if !utils.IsInStringArray(self.Hypervisor, []string{api.HYPERVISOR_KVM, api.HYPERVISOR_BAREMETAL}) {
|
||||
return nil, httperrors.NewNotAcceptableError("Not allow for hypervisor %s", self.Hypervisor)
|
||||
}
|
||||
cdrom := self.getCdrom(false)
|
||||
cdromOrdinal, _ := data.Int("cdrom_ordinal")
|
||||
if cdromOrdinal < 0 {
|
||||
return nil, httperrors.NewServerStatusError("invalid cdrom_ordinal: %d", cdromOrdinal)
|
||||
}
|
||||
cdrom := self.getCdrom(false, cdromOrdinal)
|
||||
if cdrom != nil && len(cdrom.ImageId) > 0 {
|
||||
return nil, httperrors.NewBadRequestError("CD-ROM not empty, please eject first")
|
||||
}
|
||||
@@ -1180,7 +1184,7 @@ func (self *SGuest) PerformInsertiso(ctx context.Context, userCred mcclient.Toke
|
||||
}
|
||||
|
||||
if utils.IsInStringArray(self.Status, []string{api.VM_RUNNING, api.VM_READY}) {
|
||||
err = self.StartInsertIsoTask(ctx, image.Id, false, self.HostId, userCred, "")
|
||||
err = self.StartInsertIsoTask(ctx, cdromOrdinal, image.Id, false, self.HostId, userCred, "")
|
||||
return nil, err
|
||||
} else {
|
||||
return nil, httperrors.NewServerStatusError("Insert ISO not allowed in status %s", self.Status)
|
||||
@@ -1191,20 +1195,26 @@ func (self *SGuest) PerformEjectiso(ctx context.Context, userCred mcclient.Token
|
||||
if !utils.IsInStringArray(self.Hypervisor, []string{api.HYPERVISOR_KVM, api.HYPERVISOR_BAREMETAL}) {
|
||||
return nil, httperrors.NewNotAcceptableError("Not allow for hypervisor %s", self.Hypervisor)
|
||||
}
|
||||
cdrom := self.getCdrom(false)
|
||||
cdromOrdinal, _ := data.Int("cdrom_ordinal")
|
||||
if cdromOrdinal < 0 {
|
||||
return nil, httperrors.NewServerStatusError("invalid cdrom_ordinal: %d", cdromOrdinal)
|
||||
}
|
||||
cdrom := self.getCdrom(false, cdromOrdinal)
|
||||
if cdrom == nil || len(cdrom.ImageId) == 0 {
|
||||
return nil, httperrors.NewBadRequestError("No ISO to eject")
|
||||
}
|
||||
if utils.IsInStringArray(self.Status, []string{api.VM_RUNNING, api.VM_READY}) {
|
||||
err := self.StartEjectisoTask(ctx, userCred, "")
|
||||
err := self.StartEjectisoTask(ctx, cdromOrdinal, userCred, "")
|
||||
return nil, err
|
||||
} else {
|
||||
return nil, httperrors.NewServerStatusError("Eject ISO not allowed in status %s", self.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SGuest) StartEjectisoTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "GuestEjectISOTask", self, userCred, nil, parentTaskId, "", nil)
|
||||
func (self *SGuest) StartEjectisoTask(ctx context.Context, cdromOrdinal int64, userCred mcclient.TokenCredential, parentTaskId string) error {
|
||||
data := jsonutils.NewDict()
|
||||
data.Add(jsonutils.NewInt(cdromOrdinal), "cdrom_ordinal")
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "GuestEjectISOTask", self, userCred, data, parentTaskId, "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1212,11 +1222,12 @@ func (self *SGuest) StartEjectisoTask(ctx context.Context, userCred mcclient.Tok
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SGuest) StartInsertIsoTask(ctx context.Context, imageId string, boot bool, hostId string, userCred mcclient.TokenCredential, parentTaskId string) error {
|
||||
self.insertIso(imageId)
|
||||
func (self *SGuest) StartInsertIsoTask(ctx context.Context, cdromOrdinal int64, imageId string, boot bool, hostId string, userCred mcclient.TokenCredential, parentTaskId string) error {
|
||||
self.insertIso(imageId, cdromOrdinal)
|
||||
|
||||
data := jsonutils.NewDict()
|
||||
data.Add(jsonutils.NewString(imageId), "image_id")
|
||||
data.Add(jsonutils.NewInt(cdromOrdinal), "cdrom_ordinal")
|
||||
data.Add(jsonutils.NewString(hostId), "host_id")
|
||||
if boot {
|
||||
data.Add(jsonutils.JSONTrue, "boot")
|
||||
@@ -1233,6 +1244,105 @@ func (self *SGuest) StartInsertIsoTask(ctx context.Context, imageId string, boot
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SGuest) insertVfd(imageId string, floppyOrdinal int64) bool {
|
||||
floppy := self.getFloppy(true, floppyOrdinal)
|
||||
return floppy.insertVfd(imageId)
|
||||
}
|
||||
|
||||
func (self *SGuest) InsertVfdSucc(floppyOrdinal int64, imageId string, path string, size int64, name string) bool {
|
||||
floppy := self.getFloppy(true, floppyOrdinal)
|
||||
return floppy.insertVfdSucc(imageId, path, size, name)
|
||||
}
|
||||
|
||||
func (self *SGuest) GetDetailsVfd(floppyOrdinal int64, userCred mcclient.TokenCredential) jsonutils.JSONObject {
|
||||
floppy := self.getFloppy(false, floppyOrdinal)
|
||||
desc := jsonutils.NewDict()
|
||||
if len(floppy.ImageId) > 0 {
|
||||
desc.Set("image_id", jsonutils.NewString(floppy.ImageId))
|
||||
desc.Set("status", jsonutils.NewString("inserting"))
|
||||
}
|
||||
if len(floppy.Path) > 0 {
|
||||
desc.Set("name", jsonutils.NewString(floppy.Name))
|
||||
desc.Set("size", jsonutils.NewInt(int64(floppy.Size)))
|
||||
desc.Set("status", jsonutils.NewString("ready"))
|
||||
}
|
||||
return desc
|
||||
}
|
||||
|
||||
func (self *SGuest) PerformInsertvfd(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data api.ServerInsertVfdInput) (jsonutils.JSONObject, error) {
|
||||
if !utils.IsInStringArray(self.Hypervisor, []string{api.HYPERVISOR_KVM, api.HYPERVISOR_BAREMETAL}) {
|
||||
return nil, httperrors.NewNotAcceptableError("Not allow for hypervisor %s", self.Hypervisor)
|
||||
}
|
||||
if data.FloppyOrdinal < 0 {
|
||||
return nil, httperrors.NewServerStatusError("invalid floppy_ordinal: %d", data.FloppyOrdinal)
|
||||
}
|
||||
floppy := self.getFloppy(false, data.FloppyOrdinal)
|
||||
if floppy != nil && len(floppy.ImageId) > 0 {
|
||||
return nil, httperrors.NewBadRequestError("Floppy not empty, please eject first")
|
||||
}
|
||||
image, err := parseIsoInfo(ctx, userCred, data.ImageId)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if utils.IsInStringArray(self.Status, []string{api.VM_RUNNING, api.VM_READY}) {
|
||||
err = self.StartInsertVfdTask(ctx, data.FloppyOrdinal, image.Id, false, self.HostId, userCred, "")
|
||||
return nil, err
|
||||
} else {
|
||||
return nil, httperrors.NewServerStatusError("Insert ISO not allowed in status %s", self.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SGuest) PerformEjectvfd(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data api.ServerEjectVfdInput) (jsonutils.JSONObject, error) {
|
||||
if !utils.IsInStringArray(self.Hypervisor, []string{api.HYPERVISOR_KVM, api.HYPERVISOR_BAREMETAL}) {
|
||||
return nil, httperrors.NewNotAcceptableError("Not allow for hypervisor %s", self.Hypervisor)
|
||||
}
|
||||
if data.FloppyOrdinal < 0 {
|
||||
return nil, httperrors.NewServerStatusError("invalid floppy_ordinal: %d", data.FloppyOrdinal)
|
||||
}
|
||||
floppy := self.getFloppy(false, data.FloppyOrdinal)
|
||||
if floppy == nil || len(floppy.ImageId) == 0 {
|
||||
return nil, httperrors.NewBadRequestError("No VFD to eject")
|
||||
}
|
||||
if utils.IsInStringArray(self.Status, []string{api.VM_RUNNING, api.VM_READY}) {
|
||||
err := self.StartEjectvfdTask(ctx, userCred, "")
|
||||
return nil, err
|
||||
} else {
|
||||
return nil, httperrors.NewServerStatusError("Eject ISO not allowed in status %s", self.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SGuest) StartEjectvfdTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "GuestEjectVFDTask", self, userCred, nil, parentTaskId, "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SGuest) StartInsertVfdTask(ctx context.Context, floppyOrdinal int64, imageId string, boot bool, hostId string, userCred mcclient.TokenCredential, parentTaskId string) error {
|
||||
self.insertVfd(imageId, floppyOrdinal)
|
||||
|
||||
data := jsonutils.NewDict()
|
||||
data.Add(jsonutils.NewString(imageId), "image_id")
|
||||
data.Add(jsonutils.NewString(hostId), "host_id")
|
||||
if boot {
|
||||
data.Add(jsonutils.JSONTrue, "boot")
|
||||
}
|
||||
taskName := "GuestInsertVfdTask"
|
||||
if self.BackupHostId != "" {
|
||||
taskName = "HaGuestInsertVfdTask"
|
||||
}
|
||||
task, err := taskman.TaskManager.NewTask(ctx, taskName, self, userCred, data, parentTaskId, "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SGuest) StartGueststartTask(
|
||||
ctx context.Context, userCred mcclient.TokenCredential,
|
||||
data *jsonutils.JSONDict, parentTaskId string,
|
||||
@@ -2126,7 +2236,6 @@ func (self *SGuest) attachIsolatedDevice(ctx context.Context, userCred mcclient.
|
||||
return fmt.Errorf("Isolated device already attached to another guest: %s", dev.GuestId)
|
||||
}
|
||||
if dev.HostId !=
|
||||
|
||||
self.HostId {
|
||||
return fmt.Errorf("Isolated device and guest are not located in the same host")
|
||||
}
|
||||
@@ -4631,9 +4740,17 @@ func (self *SGuest) validateForBatchMigrate(ctx context.Context, rescueMode bool
|
||||
return guest, httperrors.NewBadRequestError("guest %s status %s can't migrate", guest.Name, guest.Status)
|
||||
}
|
||||
if guest.Status == api.VM_RUNNING {
|
||||
cdrom := guest.getCdrom(false)
|
||||
if cdrom != nil && len(cdrom.ImageId) > 0 {
|
||||
return guest, httperrors.NewBadRequestError("cannot migrate with cdrom")
|
||||
cdroms, _ := guest.getCdroms()
|
||||
for _, cdrom := range cdroms {
|
||||
if len(cdrom.ImageId) > 0 {
|
||||
return guest, httperrors.NewBadRequestError("cannot migrate with cdrom")
|
||||
}
|
||||
}
|
||||
floppys, _ := guest.getFloppys()
|
||||
for _, floppy := range floppys {
|
||||
if len(floppy.ImageId) > 0 {
|
||||
return guest, httperrors.NewBadRequestError("cannot migrate with floppy")
|
||||
}
|
||||
}
|
||||
} else if guest.Status == api.VM_UNKNOWN {
|
||||
if guest.getDefaultStorageType() == api.STORAGE_LOCAL {
|
||||
|
||||
@@ -222,12 +222,25 @@ func (manager *SGuestManager) FetchCustomizeColumns(
|
||||
gcds := fetchGuestCdroms(guestIds)
|
||||
if gcds != nil {
|
||||
for i := range rows {
|
||||
if gcd, ok := gcds[guestIds[i]]; ok {
|
||||
rows[i].Cdrom = gcd.GetDetails()
|
||||
for _, gcd := range gcds[guestIds[i]] {
|
||||
t := api.Cdrom{Ordinal: gcd.Ordinal, Detail: gcd.GetDetails()}
|
||||
rows[i].Cdrom = append(rows[i].Cdrom, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(fields) == 0 || fields.Contains("floppy") {
|
||||
gfloppys := fetchGuestFloppys(guestIds)
|
||||
if gfloppys != nil {
|
||||
for i := range rows {
|
||||
for _, gfl := range gfloppys[guestIds[i]] {
|
||||
t := api.Floppy{Ordinal: gfl.Ordinal, Detail: gfl.GetDetails()}
|
||||
rows[i].Floppy = append(rows[i].Floppy, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(fields) == 0 || fields.Contains("scaling_group") {
|
||||
sggs := fetchScalingGroupGuest(guestIds...)
|
||||
if sggs != nil && len(sggs) != 0 {
|
||||
@@ -691,16 +704,30 @@ func fetchGuestIsolatedDevices(guestIds []string) map[string][]api.SIsolatedDevi
|
||||
return ret
|
||||
}
|
||||
|
||||
func fetchGuestCdroms(guestIds []string) map[string]SGuestcdrom {
|
||||
func fetchGuestCdroms(guestIds []string) map[string][]SGuestcdrom {
|
||||
q := GuestcdromManager.Query().In("id", guestIds)
|
||||
gcds := make([]SGuestcdrom, 0)
|
||||
err := q.All(&gcds)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
ret := make(map[string]SGuestcdrom)
|
||||
ret := make(map[string][]SGuestcdrom)
|
||||
for i := range gcds {
|
||||
ret[gcds[i].Id] = gcds[i]
|
||||
ret[gcds[i].Id] = append(ret[gcds[i].Id], gcds[i])
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func fetchGuestFloppys(guestIds []string) map[string][]SGuestfloppy {
|
||||
q := GuestFloppyManager.Query().In("id", guestIds)
|
||||
gfls := make([]SGuestfloppy, 0)
|
||||
err := q.All(&gfls)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
ret := make(map[string][]SGuestfloppy)
|
||||
for i := range gfls {
|
||||
ret[gfls[i].Id] = append(ret[gfls[i].Id], gfls[i])
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -47,7 +47,9 @@ func init() {
|
||||
type SGuestcdrom struct {
|
||||
db.SModelBase
|
||||
|
||||
Id string `width:"36" charset:"ascii" primary:"true"` // = Column(VARCHAR(36, charset='ascii'), primary_key=True)
|
||||
RowId int64 `primary:"true" auto_increment:"true" list:"user"`
|
||||
Ordinal int `nullable:"false" default:"0"` // = Column(Integer, nullable=False, default=0)
|
||||
Id string `width:"36" charset:"ascii"` // = Column(VARCHAR(36, charset='ascii'), primary_key=True)
|
||||
ImageId string `width:"36" charset:"ascii" nullable:"true"` // Column(VARCHAR(36, charset='ascii'), nullable=True)
|
||||
Name string `width:"64" charset:"ascii" nullable:"true"` // Column(VARCHAR(64, charset='ascii'), nullable=True)
|
||||
Path string `width:"256" charset:"ascii" nullable:"true"` // Column(VARCHAR(256, charset='ascii'), nullable=True)
|
||||
@@ -127,6 +129,7 @@ func (self *SGuestcdrom) GetDetails() string {
|
||||
func (self *SGuestcdrom) getJsonDesc() *api.GuestcdromJsonDesc {
|
||||
if len(self.ImageId) > 0 && len(self.Path) > 0 {
|
||||
return &api.GuestcdromJsonDesc{
|
||||
Ordinal: self.Ordinal,
|
||||
ImageId: self.ImageId,
|
||||
Path: self.Path,
|
||||
Name: self.Name,
|
||||
|
||||
@@ -169,6 +169,10 @@ type IGuestDriver interface {
|
||||
RequestGuestHotRemoveIso(ctx context.Context, guest *SGuest, task taskman.ITask) error
|
||||
RequestRebuildRootDisk(ctx context.Context, guest *SGuest, task taskman.ITask) error
|
||||
|
||||
NeedRequestGuestHotAddVfd(ctx context.Context, guest *SGuest) bool
|
||||
RequestGuestHotAddVfd(ctx context.Context, guest *SGuest, path string, boot bool, task taskman.ITask) error
|
||||
RequestGuestHotRemoveVfd(ctx context.Context, guest *SGuest, task taskman.ITask) error
|
||||
|
||||
RequestDiskSnapshot(ctx context.Context, guest *SGuest, task taskman.ITask, snapshotId, diskId string) error
|
||||
RequestDeleteSnapshot(ctx context.Context, guest *SGuest, task taskman.ITask, params *jsonutils.JSONDict) error
|
||||
RequestReloadDiskSnapshot(ctx context.Context, guest *SGuest, task taskman.ITask, params *jsonutils.JSONDict) error
|
||||
@@ -193,6 +197,7 @@ type IGuestDriver interface {
|
||||
CancelExpireTime(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest) error
|
||||
|
||||
IsSupportCdrom(guest *SGuest) (bool, error)
|
||||
IsSupportFloppy(guest *SGuest) (bool, error)
|
||||
IsSupportPublicipToEip() bool
|
||||
RequestConvertPublicipToEip(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, task taskman.ITask) error
|
||||
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
// 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 models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/log"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
)
|
||||
|
||||
// +onecloud:swagger-gen-ignore
|
||||
type SGuestFloppyManager struct {
|
||||
db.SModelBaseManager
|
||||
}
|
||||
|
||||
var GuestFloppyManager *SGuestFloppyManager
|
||||
|
||||
func init() {
|
||||
GuestFloppyManager = &SGuestFloppyManager{
|
||||
SModelBaseManager: db.NewModelBaseManager(
|
||||
SGuestfloppy{},
|
||||
"guestfloppy_tbl",
|
||||
"guestfloppy",
|
||||
"guestfloppys",
|
||||
),
|
||||
}
|
||||
GuestFloppyManager.SetVirtualObject(GuestFloppyManager)
|
||||
}
|
||||
|
||||
// +onecloud:swagger-gen-ignore
|
||||
type SGuestfloppy struct {
|
||||
db.SModelBase
|
||||
|
||||
RowId int64 `primary:"true" auto_increment:"true" list:"user"`
|
||||
Id string `width:"36" charset:"ascii" ` // = Column(VARCHAR(36, charset='ascii'), primary_key=True)
|
||||
Ordinal int `nullable:"false" default:"0"` // = Column(Integer, nullable=False, default=0)
|
||||
ImageId string `width:"36" charset:"ascii" nullable:"true"` // Column(VARCHAR(36, charset='ascii'), nullable=True)
|
||||
Name string `width:"64" charset:"ascii" nullable:"true"` // Column(VARCHAR(64, charset='ascii'), nullable=True)
|
||||
Path string `width:"256" charset:"ascii" nullable:"true"` // Column(VARCHAR(256, charset='ascii'), nullable=True)
|
||||
Size int64 `nullable:"false" default:"0"` // = Column(Integer, nullable=False, default=0)
|
||||
UpdatedAt time.Time `nullable:"false" updated_at:"true" nullable:"false"`
|
||||
UpdateVersion int `default:"0" nullable:"false" auto_version:"true"`
|
||||
}
|
||||
|
||||
func (self *SGuestfloppy) insertVfd(imageId string) bool {
|
||||
if len(self.ImageId) == 0 {
|
||||
_, err := db.Update(self, func() error {
|
||||
self.ImageId = imageId
|
||||
self.Name = ""
|
||||
self.Path = ""
|
||||
self.Size = 0
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("insertVfd saveupdate fail: %s", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SGuestfloppy) insertVfdSucc(imageId string, path string, size int64, name string) bool {
|
||||
if self.ImageId == imageId {
|
||||
_, err := db.Update(self, func() error {
|
||||
self.Name = name
|
||||
self.Path = path
|
||||
self.Size = size
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("insertIsoSucc saveUpdate fail %s", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SGuestfloppy) ejectVfd() bool {
|
||||
if len(self.ImageId) > 0 {
|
||||
_, err := db.Update(self, func() error {
|
||||
self.ImageId = ""
|
||||
self.Name = ""
|
||||
self.Path = ""
|
||||
self.Size = 0
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("ejectVfd saveUpdate fail %s", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SGuestfloppy) GetDetails() string {
|
||||
if len(self.ImageId) > 0 {
|
||||
if self.Size > 0 {
|
||||
return fmt.Sprintf("%s(%s/%dMB)", self.Name, self.ImageId, self.Size)
|
||||
} else {
|
||||
return fmt.Sprintf("%s(inserting)", self.ImageId)
|
||||
}
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SGuestfloppy) getJsonDesc() *api.GuestfloppyJsonDesc {
|
||||
if len(self.ImageId) > 0 && len(self.Path) > 0 {
|
||||
return &api.GuestfloppyJsonDesc{
|
||||
Ordinal: self.Ordinal,
|
||||
ImageId: self.ImageId,
|
||||
Path: self.Path,
|
||||
Name: self.Name,
|
||||
Size: self.Size,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+109
-10
@@ -2227,6 +2227,7 @@ func (self *SGuest) moreExtraInfo(
|
||||
}
|
||||
|
||||
out.CdromSupport, _ = self.GetDriver().IsSupportCdrom(self)
|
||||
out.FloppySupport, _ = self.GetDriver().IsSupportFloppy(self)
|
||||
|
||||
return out
|
||||
}
|
||||
@@ -2336,18 +2337,19 @@ func (self *SGuest) getNetworksDetails() string {
|
||||
}
|
||||
|
||||
func (self *SGuest) GetCdrom() *SGuestcdrom {
|
||||
return self.getCdrom(false)
|
||||
return self.getCdrom(false, 0)
|
||||
}
|
||||
|
||||
func (self *SGuest) getCdrom(create bool) *SGuestcdrom {
|
||||
func (self *SGuest) getCdrom(create bool, ordinal int64) *SGuestcdrom {
|
||||
cdrom := SGuestcdrom{}
|
||||
cdrom.SetModelManager(GuestcdromManager, &cdrom)
|
||||
|
||||
err := GuestcdromManager.Query().Equals("id", self.Id).First(&cdrom)
|
||||
err := GuestcdromManager.Query().Equals("id", self.Id).Equals("ordinal", ordinal).First(&cdrom)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
if create {
|
||||
cdrom.Id = self.Id
|
||||
cdrom.Ordinal = int(ordinal)
|
||||
err = GuestcdromManager.TableSpec().Insert(context.TODO(), &cdrom)
|
||||
if err != nil {
|
||||
log.Errorf("insert cdrom fail %s", err)
|
||||
@@ -2366,6 +2368,54 @@ func (self *SGuest) getCdrom(create bool) *SGuestcdrom {
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SGuest) getCdroms() ([]SGuestcdrom, error) {
|
||||
cdroms := make([]SGuestcdrom, 0)
|
||||
q := GuestcdromManager.Query().Equals("id", self.Id)
|
||||
err := db.FetchModelObjects(GuestcdromManager, q, &cdroms)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "db.FetchModelObjects")
|
||||
}
|
||||
return cdroms, nil
|
||||
}
|
||||
|
||||
func (self *SGuest) getFloppys() ([]SGuestfloppy, error) {
|
||||
floppys := make([]SGuestfloppy, 0)
|
||||
q := GuestFloppyManager.Query().Equals("id", self.Id)
|
||||
err := db.FetchModelObjects(GuestFloppyManager, q, &floppys)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "db.FetchModelObjects")
|
||||
}
|
||||
return floppys, nil
|
||||
}
|
||||
|
||||
func (self *SGuest) getFloppy(create bool, ordinal int64) *SGuestfloppy {
|
||||
floppy := SGuestfloppy{}
|
||||
floppy.SetModelManager(GuestFloppyManager, &floppy)
|
||||
|
||||
err := GuestFloppyManager.Query().Equals("id", self.Id).Equals("ordinal", ordinal).First(&floppy)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
if create {
|
||||
floppy.Id = self.Id
|
||||
floppy.Ordinal = int(ordinal)
|
||||
err = GuestFloppyManager.TableSpec().Insert(context.TODO(), &floppy)
|
||||
if err != nil {
|
||||
log.Errorf("insert cdrom fail %s", err)
|
||||
return nil
|
||||
}
|
||||
return &floppy
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
log.Errorf("getFloppy query fail %s", err)
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
return &floppy
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SGuest) getKeypair() *SKeypair {
|
||||
if len(self.KeypairId) > 0 {
|
||||
keypair, _ := KeypairManager.FetchById(self.KeypairId)
|
||||
@@ -4088,8 +4138,8 @@ func (self *SGuest) DetachAllNetworks(ctx context.Context, userCred mcclient.Tok
|
||||
return GuestnetworkManager.DeleteGuestNics(ctx, userCred, gns, false)
|
||||
}
|
||||
|
||||
func (self *SGuest) EjectIso(userCred mcclient.TokenCredential) bool {
|
||||
cdrom := self.getCdrom(false)
|
||||
func (self *SGuest) EjectIso(cdromOrdinal int64, userCred mcclient.TokenCredential) bool {
|
||||
cdrom := self.getCdrom(false, cdromOrdinal)
|
||||
if cdrom != nil && len(cdrom.ImageId) > 0 {
|
||||
imageId := cdrom.ImageId
|
||||
if cdrom.ejectIso() {
|
||||
@@ -4100,6 +4150,48 @@ func (self *SGuest) EjectIso(userCred mcclient.TokenCredential) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SGuest) EjectAllIso(userCred mcclient.TokenCredential) bool {
|
||||
cdroms, _ := self.getCdroms()
|
||||
for _, cdrom := range cdroms {
|
||||
if len(cdrom.ImageId) > 0 {
|
||||
imageId := cdrom.ImageId
|
||||
if cdrom.ejectIso() {
|
||||
db.OpsLog.LogEvent(self, db.ACT_ISO_DETACH, imageId, userCred)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SGuest) EjectVfd(floppyOrdinal int64, userCred mcclient.TokenCredential) bool {
|
||||
floppy := self.getFloppy(false, floppyOrdinal)
|
||||
if floppy != nil && len(floppy.ImageId) > 0 {
|
||||
imageId := floppy.ImageId
|
||||
if floppy.ejectVfd() {
|
||||
db.OpsLog.LogEvent(self, db.ACT_VFD_DETACH, imageId, userCred)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SGuest) EjectAllVfd(userCred mcclient.TokenCredential) bool {
|
||||
floppys, _ := self.getFloppys()
|
||||
for _, floppy := range floppys {
|
||||
if len(floppy.ImageId) > 0 {
|
||||
imageId := floppy.ImageId
|
||||
if floppy.ejectVfd() {
|
||||
db.OpsLog.LogEvent(self, db.ACT_ISO_DETACH, imageId, userCred)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SGuest) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
// self.SVirtualResourceBase.Delete(ctx, userCred)
|
||||
// override
|
||||
@@ -4421,10 +4513,17 @@ func (self *SGuest) GetJsonDescAtHypervisor(ctx context.Context, host *SHost) *a
|
||||
desc.Disks = append(desc.Disks, diskDesc)
|
||||
}
|
||||
|
||||
// cdrom
|
||||
cdrom := self.getCdrom(false)
|
||||
if cdrom != nil {
|
||||
desc.Cdrom = cdrom.getJsonDesc()
|
||||
cdroms, _ := self.getCdroms()
|
||||
for _, cdrom := range cdroms {
|
||||
cdromDesc := cdrom.getJsonDesc()
|
||||
desc.Cdroms = append(desc.Cdroms, cdromDesc)
|
||||
}
|
||||
|
||||
//floppy
|
||||
floppys, _ := self.getFloppys()
|
||||
for _, floppy := range floppys {
|
||||
floppyDesc := floppy.getJsonDesc()
|
||||
desc.Floppys = append(desc.Floppys, floppyDesc)
|
||||
}
|
||||
|
||||
// tenant
|
||||
@@ -5631,7 +5730,7 @@ func (self *SGuest) toCreateInput() *api.ServerCreateInput {
|
||||
r := new(api.ServerCreateInput)
|
||||
r.VmemSize = self.VmemSize
|
||||
r.VcpuCount = int(self.VcpuCount)
|
||||
if guestCdrom := self.getCdrom(false); guestCdrom != nil {
|
||||
if guestCdrom := self.getCdrom(false, 0); guestCdrom != nil {
|
||||
r.Cdrom = guestCdrom.ImageId
|
||||
}
|
||||
r.Vga = self.Vga
|
||||
|
||||
@@ -127,7 +127,8 @@ func (guest *SGuest) purge(ctx context.Context, userCred mcclient.TokenCredentia
|
||||
guest.RevokeAllSecgroups(ctx, userCred)
|
||||
guest.LeaveAllGroups(ctx, userCred)
|
||||
guest.DetachAllNetworks(ctx, userCred)
|
||||
guest.EjectIso(userCred)
|
||||
guest.EjectAllIso(userCred)
|
||||
guest.EjectAllVfd(userCred)
|
||||
guest.DeleteEip(ctx, userCred)
|
||||
guest.purgeInstanceSnapshots(ctx, userCred)
|
||||
guest.DeleteAllDisksInDB(ctx, userCred)
|
||||
|
||||
@@ -63,6 +63,7 @@ func InitHandlers(app *appsrv.Application) {
|
||||
db.SharedResourceManager,
|
||||
db.I18nManager,
|
||||
models.GuestcdromManager,
|
||||
models.GuestFloppyManager,
|
||||
models.NetInterfaceManager,
|
||||
|
||||
models.QuotaManager,
|
||||
|
||||
@@ -359,7 +359,7 @@ func (self *GuestCreateBackupTask) StartCreateBackupDisks(ctx context.Context, g
|
||||
|
||||
func (self *GuestCreateBackupTask) StartInsertIso(ctx context.Context, guest *models.SGuest, imageId string) {
|
||||
self.SetStage("OnInsertIso", nil)
|
||||
guest.StartInsertIsoTask(ctx, imageId, false, guest.BackupHostId, self.UserCred, self.GetTaskId())
|
||||
guest.StartInsertIsoTask(ctx, 0, imageId, false, guest.BackupHostId, self.UserCred, self.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *GuestCreateBackupTask) OnInsertIso(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
|
||||
|
||||
@@ -332,7 +332,8 @@ func (self *GuestDeleteTask) OnGuestDeleteCompleteFailed(ctx context.Context, ob
|
||||
func (self *GuestDeleteTask) OnGuestDeleteComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
guest := obj.(*models.SGuest)
|
||||
guest.DetachAllNetworks(ctx, self.UserCred)
|
||||
guest.EjectIso(self.UserCred)
|
||||
guest.EjectAllIso(self.UserCred)
|
||||
guest.EjectAllVfd(self.UserCred)
|
||||
guest.DeleteEip(ctx, self.UserCred)
|
||||
guest.GetDriver().OnDeleteGuestFinalCleanup(ctx, guest, self.UserCred)
|
||||
// sync capacity used for storage
|
||||
|
||||
@@ -39,7 +39,8 @@ func (self *GuestEjectISOTask) OnInit(ctx context.Context, obj db.IStandaloneMod
|
||||
|
||||
func (self *GuestEjectISOTask) startEjectIso(ctx context.Context, obj db.IStandaloneModel) {
|
||||
guest := obj.(*models.SGuest)
|
||||
if guest.EjectIso(self.UserCred) && guest.Status == api.VM_RUNNING {
|
||||
cdromOrdinal, _ := self.Params.Int("cdrom_ordinal")
|
||||
if guest.EjectIso(cdromOrdinal, self.UserCred) && guest.Status == api.VM_RUNNING {
|
||||
self.SetStage("OnConfigSyncComplete", nil)
|
||||
guest.GetDriver().RequestGuestHotRemoveIso(ctx, guest, self)
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
// 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 tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
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/compute/models"
|
||||
)
|
||||
|
||||
type GuestEjectVFDTask struct {
|
||||
SGuestBaseTask
|
||||
}
|
||||
|
||||
func init() {
|
||||
taskman.RegisterTask(GuestEjectVFDTask{})
|
||||
}
|
||||
|
||||
func (self *GuestEjectVFDTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
self.startEjectVfd(ctx, obj)
|
||||
}
|
||||
|
||||
func (self *GuestEjectVFDTask) startEjectVfd(ctx context.Context, obj db.IStandaloneModel) {
|
||||
guest := obj.(*models.SGuest)
|
||||
floppyOrdinal, _ := self.Params.Int("floppy_ordinal")
|
||||
if guest.EjectVfd(floppyOrdinal, self.UserCred) && guest.Status == api.VM_RUNNING {
|
||||
self.SetStage("OnConfigSyncComplete", nil)
|
||||
guest.GetDriver().RequestGuestHotRemoveVfd(ctx, guest, self)
|
||||
} else {
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *GuestEjectVFDTask) OnConfigSyncComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
@@ -41,6 +41,7 @@ func (self *GuestInsertIsoTask) OnInit(ctx context.Context, obj db.IStandaloneMo
|
||||
func (self *GuestInsertIsoTask) prepareIsoImage(ctx context.Context, obj db.IStandaloneModel) {
|
||||
guest := obj.(*models.SGuest)
|
||||
imageId, _ := self.Params.GetString("image_id")
|
||||
cdromOrdinal, _ := self.Params.Int("cdrom_ordinal")
|
||||
db.OpsLog.LogEvent(obj, db.ACT_ISO_PREPARING, imageId, self.UserCred)
|
||||
|
||||
disks, _ := guest.GetGuestDisks()
|
||||
@@ -57,7 +58,7 @@ func (self *GuestInsertIsoTask) prepareIsoImage(ctx context.Context, obj db.ISta
|
||||
}
|
||||
storageCache.StartImageCacheTask(ctx, self.UserCred, input)
|
||||
} else {
|
||||
guest.EjectIso(self.UserCred)
|
||||
guest.EjectIso(cdromOrdinal, self.UserCred)
|
||||
db.OpsLog.LogEvent(obj, db.ACT_ISO_PREPARE_FAIL, imageId, self.UserCred)
|
||||
self.SetStageFailed(ctx, jsonutils.NewString("host no local storage cache"))
|
||||
}
|
||||
@@ -65,14 +66,16 @@ func (self *GuestInsertIsoTask) prepareIsoImage(ctx context.Context, obj db.ISta
|
||||
|
||||
func (self *GuestInsertIsoTask) OnIsoPrepareCompleteFailed(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
imageId, _ := self.Params.GetString("image_id")
|
||||
cdromOrdinal, _ := self.Params.Int("cdrom_ordinal")
|
||||
db.OpsLog.LogEvent(obj, db.ACT_ISO_PREPARE_FAIL, imageId, self.UserCred)
|
||||
guest := obj.(*models.SGuest)
|
||||
guest.EjectIso(self.UserCred)
|
||||
guest.EjectIso(cdromOrdinal, self.UserCred)
|
||||
self.SetStageFailed(ctx, data)
|
||||
}
|
||||
|
||||
func (self *GuestInsertIsoTask) OnIsoPrepareComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
imageId, _ := data.GetString("image_id")
|
||||
cdromOrdinal, _ := self.Params.Int("cdrom_ordinal")
|
||||
size, err := data.Int("size")
|
||||
if err != nil {
|
||||
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
|
||||
@@ -81,8 +84,8 @@ func (self *GuestInsertIsoTask) OnIsoPrepareComplete(ctx context.Context, obj db
|
||||
name, _ := data.GetString("name")
|
||||
path, _ := data.GetString("path")
|
||||
guest := obj.(*models.SGuest)
|
||||
if guest.InsertIsoSucc(imageId, path, size, name) {
|
||||
db.OpsLog.LogEvent(guest, db.ACT_ISO_ATTACH, guest.GetDetailsIso(self.UserCred), self.UserCred)
|
||||
if guest.InsertIsoSucc(cdromOrdinal, imageId, path, size, name) {
|
||||
db.OpsLog.LogEvent(guest, db.ACT_ISO_ATTACH, guest.GetDetailsIso(cdromOrdinal, self.UserCred), self.UserCred)
|
||||
if guest.GetDriver().NeedRequestGuestHotAddIso(ctx, guest) {
|
||||
self.SetStage("OnConfigSyncComplete", nil)
|
||||
boot := jsonutils.QueryBoolean(self.Params, "boot", false)
|
||||
@@ -110,6 +113,7 @@ func (self *HaGuestInsertIsoTask) OnInit(ctx context.Context, obj db.IStandalone
|
||||
func (self *HaGuestInsertIsoTask) prepareIsoImage(ctx context.Context, obj db.IStandaloneModel) {
|
||||
guest := obj.(*models.SGuest)
|
||||
imageId, _ := self.Params.GetString("image_id")
|
||||
cdromOrdinal, _ := self.Params.Int("cdrom_ordinal")
|
||||
db.OpsLog.LogEvent(obj, db.ACT_ISO_PREPARING, imageId, self.UserCred)
|
||||
disks, _ := guest.GetGuestDisks()
|
||||
disk := disks[0].GetDisk()
|
||||
@@ -124,7 +128,7 @@ func (self *HaGuestInsertIsoTask) prepareIsoImage(ctx context.Context, obj db.IS
|
||||
}
|
||||
storageCache.StartImageCacheTask(ctx, self.UserCred, input)
|
||||
} else {
|
||||
guest.EjectIso(self.UserCred)
|
||||
guest.EjectIso(cdromOrdinal, self.UserCred)
|
||||
db.OpsLog.LogEvent(obj, db.ACT_ISO_PREPARE_FAIL, imageId, self.UserCred)
|
||||
self.SetStageFailed(ctx, jsonutils.NewString("host no local storage cache"))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
// 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 tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
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/compute/models"
|
||||
)
|
||||
|
||||
type GuestInsertVfdTask struct {
|
||||
SGuestBaseTask
|
||||
}
|
||||
|
||||
func init() {
|
||||
taskman.RegisterTask(GuestInsertVfdTask{})
|
||||
taskman.RegisterTask(HaGuestInsertVfdTask{})
|
||||
}
|
||||
|
||||
func (self *GuestInsertVfdTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
self.prepareVfdImage(ctx, obj)
|
||||
}
|
||||
|
||||
func (self *GuestInsertVfdTask) prepareVfdImage(ctx context.Context, obj db.IStandaloneModel) {
|
||||
guest := obj.(*models.SGuest)
|
||||
imageId, _ := self.Params.GetString("image_id")
|
||||
floppyOrdinal, _ := self.Params.Int("floppy_ordinal")
|
||||
db.OpsLog.LogEvent(obj, db.ACT_VFD_PREPARING, imageId, self.UserCred)
|
||||
|
||||
disks, _ := guest.GetGuestDisks()
|
||||
disk := disks[0].GetDisk()
|
||||
storage, _ := disk.GetStorage()
|
||||
storageCache := storage.GetStoragecache()
|
||||
|
||||
if storageCache != nil {
|
||||
self.SetStage("OnVfdPrepareComplete", nil)
|
||||
input := api.CacheImageInput{
|
||||
ImageId: imageId,
|
||||
Format: "raw",
|
||||
ParentTaskId: self.GetTaskId(),
|
||||
}
|
||||
storageCache.StartImageCacheTask(ctx, self.UserCred, input)
|
||||
} else {
|
||||
guest.EjectVfd(floppyOrdinal, self.UserCred)
|
||||
db.OpsLog.LogEvent(obj, db.ACT_VFD_PREPARE_FAIL, imageId, self.UserCred)
|
||||
self.SetStageFailed(ctx, jsonutils.NewString("host no local storage cache"))
|
||||
}
|
||||
}
|
||||
|
||||
func (self *GuestInsertVfdTask) OnVfdPrepareCompleteFailed(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
imageId, _ := self.Params.GetString("image_id")
|
||||
floppyOrdinal, _ := self.Params.Int("floppy_ordinal")
|
||||
db.OpsLog.LogEvent(obj, db.ACT_VFD_PREPARE_FAIL, imageId, self.UserCred)
|
||||
guest := obj.(*models.SGuest)
|
||||
guest.EjectVfd(floppyOrdinal, self.UserCred)
|
||||
self.SetStageFailed(ctx, data)
|
||||
}
|
||||
|
||||
func (self *GuestInsertVfdTask) OnVfdPrepareComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
floppyOrdinal, _ := self.Params.Int("floppy_ordinal")
|
||||
imageId, _ := data.GetString("image_id")
|
||||
size, err := data.Int("size")
|
||||
if err != nil {
|
||||
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
|
||||
return
|
||||
}
|
||||
name, _ := data.GetString("name")
|
||||
path, _ := data.GetString("path")
|
||||
guest := obj.(*models.SGuest)
|
||||
if guest.InsertVfdSucc(floppyOrdinal, imageId, path, size, name) {
|
||||
db.OpsLog.LogEvent(guest, db.ACT_VFD_ATTACH, guest.GetDetailsVfd(floppyOrdinal, self.UserCred), self.UserCred)
|
||||
if guest.GetDriver().NeedRequestGuestHotAddVfd(ctx, guest) {
|
||||
self.SetStage("OnConfigSyncComplete", nil)
|
||||
boot := jsonutils.QueryBoolean(self.Params, "boot", false)
|
||||
guest.GetDriver().RequestGuestHotAddVfd(ctx, guest, path, boot, self)
|
||||
} else {
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
} else {
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *GuestInsertVfdTask) OnConfigSyncComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
type HaGuestInsertVfdTask struct {
|
||||
GuestInsertVfdTask
|
||||
}
|
||||
|
||||
func (self *HaGuestInsertVfdTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
self.prepareVfdImage(ctx, obj)
|
||||
}
|
||||
|
||||
func (self *HaGuestInsertVfdTask) prepareVfdImage(ctx context.Context, obj db.IStandaloneModel) {
|
||||
guest := obj.(*models.SGuest)
|
||||
imageId, _ := self.Params.GetString("image_id")
|
||||
floppyOrdinal, _ := self.Params.Int("floppy_ordinal")
|
||||
db.OpsLog.LogEvent(obj, db.ACT_VFD_PREPARING, imageId, self.UserCred)
|
||||
disks, _ := guest.GetGuestDisks()
|
||||
disk := disks[0].GetDisk()
|
||||
storage := disk.GetBackupStorage()
|
||||
storageCache := storage.GetStoragecache()
|
||||
if storageCache != nil {
|
||||
self.SetStage("OnBackupVfdPrepareComplete", nil)
|
||||
input := api.CacheImageInput{
|
||||
ImageId: imageId,
|
||||
Format: "raw",
|
||||
ParentTaskId: self.GetTaskId(),
|
||||
}
|
||||
storageCache.StartImageCacheTask(ctx, self.UserCred, input)
|
||||
} else {
|
||||
guest.EjectVfd(floppyOrdinal, self.UserCred)
|
||||
db.OpsLog.LogEvent(obj, db.ACT_VFD_PREPARE_FAIL, imageId, self.UserCred)
|
||||
self.SetStageFailed(ctx, jsonutils.NewString("host no local storage cache"))
|
||||
}
|
||||
}
|
||||
|
||||
func (self *HaGuestInsertVfdTask) OnBackupVfdPrepareComplete(
|
||||
ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject,
|
||||
) {
|
||||
self.GuestInsertVfdTask.prepareVfdImage(ctx, guest)
|
||||
}
|
||||
|
||||
func (self *HaGuestInsertVfdTask) OnBackupVfdPrepareCompleteFailed(
|
||||
ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject,
|
||||
) {
|
||||
self.OnVfdPrepareCompleteFailed(ctx, guest, data)
|
||||
}
|
||||
Reference in New Issue
Block a user