fix: qemu extra options support multiple values

This commit is contained in:
Qiu Jian
2021-11-08 11:58:45 +08:00
parent 83da0272e7
commit 2004e00a42
4 changed files with 77 additions and 19 deletions

View File

@@ -19,9 +19,11 @@ import (
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/apis"
"yunion.io/x/onecloud/pkg/apis/billing"
"yunion.io/x/onecloud/pkg/httperrors"
)
type ServerListInput struct {
@@ -700,3 +702,30 @@ type ServerChangeDiskStorageInternalInput struct {
StorageId string `json:"storage_id"`
TargetDiskId string `json:"target_disk_id"`
}
type ServerSetExtraOptionInput struct {
Key string `json:"key"`
Value string `json:"value"`
}
func (o ServerSetExtraOptionInput) Validate() error {
if len(o.Key) == 0 {
return errors.Wrap(httperrors.ErrBadRequest, "empty key")
}
if len(o.Value) == 0 {
return errors.Wrap(httperrors.ErrBadRequest, "empty value")
}
return nil
}
type ServerDelExtraOptionInput struct {
Key string `json:"key"`
Value string `json:"value"`
}
func (o ServerDelExtraOptionInput) Validate() error {
if len(o.Key) == 0 {
return errors.Wrap(httperrors.ErrBadRequest, "empty key")
}
return nil
}

View File

@@ -3662,18 +3662,22 @@ func (self *SGuest) StartReconcileBackup(ctx context.Context, userCred mcclient.
return nil
}
func (self *SGuest) AllowPerformSetExtraOption(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
func (self *SGuest) AllowPerformSetExtraOption(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.ServerSetExtraOptionInput) bool {
return db.IsAdminAllowPerform(userCred, self, "set-extra-option")
}
func (self *SGuest) PerformSetExtraOption(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
key, err := data.GetString("key")
func (self *SGuest) PerformSetExtraOption(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.ServerSetExtraOptionInput) (jsonutils.JSONObject, error) {
err := input.Validate()
if err != nil {
return nil, httperrors.NewMissingParameterError("key")
return nil, errors.Wrap(err, "input.Validate")
}
value, _ := data.GetString("value")
extraOptions := self.GetExtraOptions(userCred)
extraOptions.Set(key, jsonutils.NewString(value))
optVal := make([]string, 0)
extraOptions.Unmarshal(&optVal, input.Key)
if !utils.IsInStringArray(input.Value, optVal) {
optVal = append(optVal, input.Value)
}
extraOptions.Set(input.Key, jsonutils.Marshal(optVal))
return nil, self.SetExtraOptions(ctx, userCred, extraOptions)
}
@@ -3690,17 +3694,31 @@ func (self *SGuest) SetExtraOptions(ctx context.Context, userCred mcclient.Token
return self.SetMetadata(ctx, "extra_options", extraOptions, userCred)
}
func (self *SGuest) AllowPerformDelExtraOption(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
func (self *SGuest) AllowPerformDelExtraOption(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.ServerDelExtraOptionInput) bool {
return db.IsAdminAllowPerform(userCred, self, "del-extra-option")
}
func (self *SGuest) PerformDelExtraOption(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
key, err := data.GetString("key")
func (self *SGuest) PerformDelExtraOption(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.ServerDelExtraOptionInput) (jsonutils.JSONObject, error) {
err := input.Validate()
if err != nil {
return nil, httperrors.NewMissingParameterError("key")
return nil, errors.Wrap(err, "input.Validate")
}
extraOptions := self.GetExtraOptions(userCred)
extraOptions.Remove(key)
var newOpt []string
if len(input.Value) > 0 {
optVal := make([]string, 0)
extraOptions.Unmarshal(&optVal, input.Key)
for _, v := range optVal {
if v != input.Value {
newOpt = append(newOpt, v)
}
}
}
if len(newOpt) > 0 {
extraOptions.Set(input.Key, jsonutils.Marshal(newOpt))
} else if extraOptions.Contains(input.Key) {
extraOptions.Remove(input.Key)
}
return nil, self.SetExtraOptions(ctx, userCred, extraOptions)
}

View File

@@ -303,10 +303,7 @@ function nic_mtu() {
}
cmd += fmt.Sprintf(" -pidfile %s", s.GetPidFilePath())
extraOptions, _ := s.Desc.GetMap("extra_options")
for k, v := range extraOptions {
cmd += fmt.Sprintf(" -%s %s", k, v.String())
}
cmd += s.extraOptions()
// cmd += s.getQgaDesc()
if fileutils2.Exists("/dev/random") {

View File

@@ -361,6 +361,23 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) (strin
}
}
func (s *SKVMGuestInstance) extraOptions() string {
cmd := " "
extraOptions, _ := s.Desc.GetMap("extra_options")
for k, v := range extraOptions {
switch jsonV := v.(type) {
case *jsonutils.JSONArray:
for i := 0; i < jsonV.Size(); i++ {
vAtI, _ := jsonV.GetAt(i)
cmd += fmt.Sprintf(" -%s %s", k, vAtI.String())
}
default:
cmd += fmt.Sprintf(" -%s %s", k, v.String())
}
}
return cmd
}
func (s *SKVMGuestInstance) _generateStartScript(data *jsonutils.JSONDict) (string, error) {
var (
uuid, _ = s.Desc.GetString("uuid")
@@ -671,10 +688,7 @@ function nic_mtu() {
}
cmd += fmt.Sprintf(" -pidfile %s", s.GetPidFilePath())
extraOptions, _ := s.Desc.GetMap("extra_options")
for k, v := range extraOptions {
cmd += fmt.Sprintf(" -%s %s", k, v.String())
}
cmd += s.extraOptions()
cmd += s.getQgaDesc()
if fileutils2.Exists("/dev/random") {