feat(region,climc): server set boot index (#15369)

This commit is contained in:
wanyaoqi
2022-11-16 23:20:54 +08:00
committed by GitHub
parent 3c90ef7532
commit 15ef8028da
8 changed files with 138 additions and 2 deletions

View File

@@ -112,6 +112,7 @@ func init() {
cmd.Perform("qga-set-password", &options.ServerQgaSetPassword{})
cmd.Perform("qga-command", &options.ServerQgaCommand{})
cmd.Perform("set-password", &options.ServerSetPasswordOptions{})
cmd.Perform("set-boot-index", &options.ServerSetBootIndexOptions{})
cmd.Get("vnc", new(options.ServerVncOptions))
cmd.Get("desc", new(options.ServerIdOptions))

View File

@@ -824,6 +824,13 @@ type GuestJsonDesc struct {
IsDaemon bool `json:"is_daemon"`
}
type ServerSetBootIndexInput struct {
// key index, value boot_index
Disks map[string]int8 `json:"disks"`
// key ordinal, value boot_index
Cdroms map[string]int8 `json:"cdroms"`
}
type ServerChangeDiskStorageInput struct {
DiskId string `json:"disk_id"`
TargetStorageId string `json:"target_storage_id"`

View File

@@ -62,6 +62,7 @@ import (
"yunion.io/x/onecloud/pkg/mcclient/modules/notify"
"yunion.io/x/onecloud/pkg/mcclient/modules/scheduler"
"yunion.io/x/onecloud/pkg/util/billing"
"yunion.io/x/onecloud/pkg/util/bitmap"
"yunion.io/x/onecloud/pkg/util/httputils"
"yunion.io/x/onecloud/pkg/util/logclient"
"yunion.io/x/onecloud/pkg/util/rand"
@@ -5457,6 +5458,91 @@ func (self *SGuest) startSwitchToClonedDisk(ctx context.Context, userCred mcclie
return nil
}
func (self *SGuest) PerformSetBootIndex(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.ServerSetBootIndexInput) (jsonutils.JSONObject, error) {
gds, err := self.GetGuestDisks()
if err != nil {
return nil, err
}
diskBootIndexes := map[int8]int8{}
for i := 0; i < len(gds); i++ {
diskBootIndexes[gds[i].Index] = gds[i].BootIndex
}
gcs, err := self.getCdroms()
if err != nil {
return nil, err
}
cdromBootIndexes := map[int]int8{}
for i := 0; i < len(gcs); i++ {
cdromBootIndexes[gcs[i].Ordinal] = gcs[i].BootIndex
}
for sDiskIndex, bootIndex := range input.Disks {
iDiskIndex, err := strconv.Atoi(sDiskIndex)
if err != nil {
return nil, httperrors.NewInputParameterError("failed parse disk index %s", sDiskIndex)
} else if iDiskIndex > 127 {
return nil, httperrors.NewInputParameterError("disk inex %s is exceed 127", sDiskIndex)
}
diskIndex := int8(iDiskIndex)
if _, ok := diskBootIndexes[diskIndex]; !ok {
return nil, httperrors.NewBadRequestError("disk has no index %d", diskIndex)
}
diskBootIndexes[diskIndex] = bootIndex
}
for sCdromOrdinal, bootIndex := range input.Cdroms {
cdromOrdinal, err := strconv.Atoi(sCdromOrdinal)
if err != nil {
return nil, httperrors.NewInputParameterError("failed parse cdrom ordinal %s", sCdromOrdinal)
}
if _, ok := cdromBootIndexes[cdromOrdinal]; !ok {
return nil, httperrors.NewBadRequestError("cdrom has no ordinal %d", cdromOrdinal)
}
cdromBootIndexes[cdromOrdinal] = bootIndex
}
bm := bitmap.NewBitMap(128)
for diskIndex, bootIndex := range diskBootIndexes {
if bootIndex < 0 {
continue
}
if bm.Has(int64(bootIndex)) {
return nil, httperrors.NewBadRequestError("disk index %d boot index %d is duplicated", diskIndex, bootIndex)
} else {
bm.Set(int64(bootIndex))
}
}
for cdromOrdinal, bootIndex := range cdromBootIndexes {
if bootIndex < 0 {
continue
}
if bm.Has(int64(bootIndex)) {
return nil, httperrors.NewBadRequestError("cdrom ordianl %d boot index %d is duplicated", cdromOrdinal, bootIndex)
} else {
bm.Set(int64(bootIndex))
}
}
for i := 0; i < len(gds); i++ {
if gds[i].BootIndex != diskBootIndexes[gds[i].Index] {
if err := gds[i].SetBootIndex(diskBootIndexes[gds[i].Index]); err != nil {
log.Errorf("gds[i].SetBootIndex: %s", err)
return nil, err
}
}
}
for i := 0; i < len(gcs); i++ {
if gcs[i].BootIndex != cdromBootIndexes[gcs[i].Ordinal] {
if err := gcs[i].SetBootIndex(cdromBootIndexes[gcs[i].Ordinal]); err != nil {
log.Errorf("gcs[i].SetBootIndex: %s", err)
return nil, err
}
}
}
return nil, nil
}
func (self *SGuest) PerformProbeIsolatedDevices(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
host, err := self.GetHost()
if err != nil {

View File

@@ -133,6 +133,14 @@ func (self *SGuestcdrom) GetDetails() string {
}
}
func (self *SGuestcdrom) SetBootIndex(bootIndex int8) error {
_, err := db.Update(self, func() error {
self.BootIndex = bootIndex
return nil
})
return err
}
func (self *SGuestcdrom) getJsonDesc() *api.GuestcdromJsonDesc {
if len(self.ImageId) > 0 && len(self.Path) > 0 {
return &api.GuestcdromJsonDesc{

View File

@@ -206,7 +206,8 @@ func (self *SGuestdisk) GetJsonDescAtHost(ctx context.Context, host *SHost) *api
}
desc.Format = disk.DiskFormat
desc.Index = self.Index
desc.BootIndex = &self.BootIndex
bootIndex := self.BootIndex
desc.BootIndex = &bootIndex
if len(disk.SnapshotId) > 0 {
needMerge := disk.GetMetadata(ctx, "merge_snapshot", nil)
@@ -263,6 +264,14 @@ func (self *SGuestdisk) ToDiskConfig() *api.DiskConfig {
return conf
}
func (self *SGuestdisk) SetBootIndex(bootIndex int8) error {
_, err := db.Update(self, func() error {
self.BootIndex = bootIndex
return nil
})
return err
}
func (manager *SGuestdiskManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,

View File

@@ -29,7 +29,7 @@ func init() {
"guestdisks",
[]string{"Guest_ID", "Guest",
"Disk_ID", "Disk", "Disk_size",
"Driver", "Cache_mode", "Index", "BootIndex", "Status", "Disk_type", "Storage_type"},
"Driver", "Cache_mode", "Index", "Boot_index", "Status", "Disk_type", "Storage_type"},
[]string{},
&Servers,
&Disks)

View File

@@ -139,6 +139,8 @@ func optionsStructRvToParams(rv reflect.Value) (*jsonutils.JSONDict, error) {
// TODO
msg := fmt.Sprintf("do not know what to do with non-anonymous struct field: %s", ft.Name)
panic(msg)
case reflect.Map:
p.Set(name, jsonutils.Marshal(f.Interface()))
case reflect.Slice, reflect.Array:
l := f.Len()
for i := 0; i < l; i++ {

View File

@@ -835,6 +835,29 @@ func (o *ServerSetPasswordOptions) Params() (jsonutils.JSONObject, error) {
return options.StructToParams(o)
}
type ServerSetBootIndexOptions struct {
ServerIdOptions
Disks map[string]int8 `help:"Disk index and boot index" json:"disks"`
Cdroms map[string]int8 `help:"Cdrom ordinal and boot index" json:"cdroms"`
}
func (o *ServerSetBootIndexOptions) Params() (jsonutils.JSONObject, error) {
for k, _ := range o.Disks {
if i, e := strconv.Atoi(k); e != nil {
return nil, e
} else if i > 127 {
return nil, fmt.Errorf("disk index grate than 127")
}
}
for k, _ := range o.Cdroms {
if _, e := strconv.Atoi(k); e != nil {
return nil, e
}
}
return options.StructToParams(o)
}
type ServerSaveImageOptions struct {
ServerIdOptions
IMAGE string `help:"Image name" json:"name"`