diff --git a/pkg/compute/models/disks.go b/pkg/compute/models/disks.go index a2d996d10c..a4e7cf9c4b 100644 --- a/pkg/compute/models/disks.go +++ b/pkg/compute/models/disks.go @@ -984,6 +984,13 @@ func (self *SDisk) ValidatePurgeCondition(ctx context.Context) error { } func (self *SDisk) validateDeleteCondition(ctx context.Context, isPurge bool) error { + if !isPurge { + storage := self.GetStorage() + host := storage.GetMasterHost() + if host == nil { + return httperrors.NewBadRequestError("storage of disk no valid host") + } + } cnt, err := self.GetGuestDiskCount() if err != nil { return httperrors.NewInternalServerError("GetGuestDiskCount fail %s", err) diff --git a/pkg/compute/models/guest_actions.go b/pkg/compute/models/guest_actions.go index 979659079b..041f3cc7d3 100644 --- a/pkg/compute/models/guest_actions.go +++ b/pkg/compute/models/guest_actions.go @@ -2030,12 +2030,16 @@ func (self *SGuest) AllowPerformDetachnetwork(ctx context.Context, userCred mccl } func (self *SGuest) PerformDetachnetwork(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { - if self.Status != api.VM_READY { + if !utils.IsInStringArray(self.Status, []string{api.VM_READY, api.VM_RUNNING}) { return nil, httperrors.NewInvalidStatusError("Cannot detach network in status %s", self.Status) } - reserve := jsonutils.QueryBoolean(data, "reserve", false) + var ( + reserve = jsonutils.QueryBoolean(data, "reserve", false) + netStr, _ = data.GetString("net_id") + gns []SGuestnetwork + err error + ) - netStr, _ := data.GetString("net_id") if len(netStr) > 0 { netObj, err := NetworkManager.FetchByIdOrName(userCred, netStr) if err != nil { @@ -2044,12 +2048,10 @@ func (self *SGuest) PerformDetachnetwork(ctx context.Context, userCred mcclient. } return nil, httperrors.NewGeneralError(err) } - gns, err := self.GetNetworks(netObj.GetId()) + gns, err = self.GetNetworks(netObj.GetId()) if err != nil { return nil, httperrors.NewGeneralError(err) } - err = self.detachNetworks(ctx, userCred, gns, reserve, true) - return nil, err } ipStr, _ := data.GetString("ip_addr") if len(ipStr) > 0 { @@ -2060,8 +2062,7 @@ func (self *SGuest) PerformDetachnetwork(ctx context.Context, userCred mcclient. } return nil, httperrors.NewGeneralError(err) } - err = self.detachNetworks(ctx, userCred, []SGuestnetwork{*gn}, reserve, true) - return nil, err + gns = []SGuestnetwork{*gn} } macStr, _ := data.GetString("mac") if len(macStr) > 0 { @@ -2072,10 +2073,18 @@ func (self *SGuest) PerformDetachnetwork(ctx context.Context, userCred mcclient. } return nil, httperrors.NewGeneralError(err) } - err = self.detachNetworks(ctx, userCred, []SGuestnetwork{*gn}, reserve, true) + gns = []SGuestnetwork{*gn} + } + if self.Status == api.VM_READY { + err = self.detachNetworks(ctx, userCred, gns, reserve, true) return nil, err + } else { + err = self.detachNetworks(ctx, userCred, gns, reserve, false) + if err != nil { + return nil, err + } + return nil, self.StartSyncTask(ctx, userCred, false, "") } - return nil, httperrors.NewInputParameterError("no either ip_addr, mac or network specified") } func (self *SGuest) AllowPerformAttachnetwork(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { diff --git a/pkg/compute/models/instance_snapshots.go b/pkg/compute/models/instance_snapshots.go index 02c028061f..3bffb504a3 100644 --- a/pkg/compute/models/instance_snapshots.go +++ b/pkg/compute/models/instance_snapshots.go @@ -277,7 +277,7 @@ func (self *SInstanceSnapshot) ToInstanceCreateInput( } sourceInput.OsType = self.OsType sourceInput.InstanceType = self.InstanceType - // sourceInput.Networks = serverConfig.Networks + sourceInput.Networks = serverConfig.Networks return sourceInput, nil } diff --git a/pkg/hostman/guestman/guestman.go b/pkg/hostman/guestman/guestman.go index c22c9fecba..b9ddefab60 100644 --- a/pkg/hostman/guestman/guestman.go +++ b/pkg/hostman/guestman/guestman.go @@ -452,7 +452,7 @@ func (m *SGuestManager) GetStatus(sid string) string { } } if guest.IsRunning() { - if guest.BlockJobsCount() > 0 { + if guest.Monitor != nil && guest.BlockJobsCount() > 0 { return GUEST_BLOCK_STREAM } return GUEST_RUNNING diff --git a/pkg/hostman/guestman/qemu-kvmhelper.go b/pkg/hostman/guestman/qemu-kvmhelper.go index 7604b5251c..22854c9137 100644 --- a/pkg/hostman/guestman/qemu-kvmhelper.go +++ b/pkg/hostman/guestman/qemu-kvmhelper.go @@ -466,6 +466,10 @@ func (s *SKVMGuestInstance) _generateStartScript(data *jsonutils.JSONDict) (stri bootOrder, _ := s.Desc.GetString("boot_order") cmd += fmt.Sprintf(" -boot order=%s", bootOrder) + cdrom, _ := s.Desc.Get("cdrom") + if cdrom != nil && cdrom.Contains("path") { + cmd += ",menu=on" + } if s.getBios() == "UEFI" { cmd += fmt.Sprintf(" -bios %s", options.HostOptions.OvmfPath) @@ -560,7 +564,6 @@ func (s *SKVMGuestInstance) _generateStartScript(data *jsonutils.JSONDict) (stri cmd += " -drive id=ide0-cd0,media=cdrom,if=none" } - cdrom, _ := s.Desc.Get("cdrom") if cdrom != nil && cdrom.Contains("path") { cdromPath, _ := cdrom.GetString("path") if len(cdromPath) > 0 {