Skip to content

Commit

Permalink
fix(region,host): support traffic limit in change config (#18555)
Browse files Browse the repository at this point in the history
  • Loading branch information
wanyaoqi authored Nov 3, 2023
1 parent 3013a0d commit 3025b19
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 36 deletions.
3 changes: 3 additions & 0 deletions pkg/apis/compute/guests.go
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,9 @@ type ServerChangeConfigInput struct {
AutoStart bool `json:"auto_start"`

Disks []DiskConfig `json:"disks"`

SetTrafficLimits []ServerNicTrafficLimit
ResetTrafficLimits []ServerNicTrafficLimit
}

type ServerUpdateInput struct {
Expand Down
8 changes: 4 additions & 4 deletions pkg/compute/guestdrivers/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -533,22 +533,22 @@ func (drv *SBaseGuestDriver) FetchMonitorUrl(ctx context.Context, guest *models.
return influxdbUrl
}

func (drv *SBaseGuestDriver) RequestResetNicTrafficLimit(ctx context.Context, task taskman.ITask, host *models.SHost, guest *models.SGuest, input *api.ServerNicTrafficLimit) error {
func (drv *SBaseGuestDriver) RequestResetNicTrafficLimit(ctx context.Context, task taskman.ITask, host *models.SHost, guest *models.SGuest, input []api.ServerNicTrafficLimit) error {
return httperrors.ErrNotImplemented
}

func (drv *SBaseGuestDriver) RequestSetNicTrafficLimit(ctx context.Context, task taskman.ITask, host *models.SHost, guest *models.SGuest, input *api.ServerNicTrafficLimit) error {
func (drv *SBaseGuestDriver) RequestSetNicTrafficLimit(ctx context.Context, task taskman.ITask, host *models.SHost, guest *models.SGuest, input []api.ServerNicTrafficLimit) error {
return httperrors.ErrNotImplemented
}

func (drv *SBaseGuestDriver) SyncOsInfo(ctx context.Context, userCred mcclient.TokenCredential, g *models.SGuest, extVM cloudprovider.IOSInfo) error {
return nil
}

func (self *SBaseGuestDriver) RequestStartRescue(ctx context.Context, task taskman.ITask, body jsonutils.JSONObject, host *models.SHost, guest *models.SGuest) error {
func (drv *SBaseGuestDriver) RequestStartRescue(ctx context.Context, task taskman.ITask, body jsonutils.JSONObject, host *models.SHost, guest *models.SGuest) error {
return httperrors.ErrNotImplemented
}

func (self *SBaseGuestDriver) RequestStopRescue(ctx context.Context, task taskman.ITask, body jsonutils.JSONObject, host *models.SHost, guest *models.SGuest) error {
func (drv *SBaseGuestDriver) RequestStopRescue(ctx context.Context, task taskman.ITask, body jsonutils.JSONObject, host *models.SHost, guest *models.SGuest) error {
return httperrors.ErrNotImplemented
}
4 changes: 2 additions & 2 deletions pkg/compute/guestdrivers/kvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,7 @@ func (self *SKVMGuestDriver) FetchMonitorUrl(ctx context.Context, guest *models.
return self.SVirtualizedGuestDriver.FetchMonitorUrl(ctx, guest)
}

func (self *SKVMGuestDriver) RequestResetNicTrafficLimit(ctx context.Context, task taskman.ITask, host *models.SHost, guest *models.SGuest, input *api.ServerNicTrafficLimit) error {
func (self *SKVMGuestDriver) RequestResetNicTrafficLimit(ctx context.Context, task taskman.ITask, host *models.SHost, guest *models.SGuest, input []api.ServerNicTrafficLimit) error {
url := fmt.Sprintf("%s/servers/%s/reset-nic-traffic-limit", host.ManagerUri, guest.Id)
httpClient := httputils.GetDefaultClient()
header := task.GetTaskRequestHeader()
Expand All @@ -1162,7 +1162,7 @@ func (self *SKVMGuestDriver) RequestResetNicTrafficLimit(ctx context.Context, ta
return nil
}

func (self *SKVMGuestDriver) RequestSetNicTrafficLimit(ctx context.Context, task taskman.ITask, host *models.SHost, guest *models.SGuest, input *api.ServerNicTrafficLimit) error {
func (self *SKVMGuestDriver) RequestSetNicTrafficLimit(ctx context.Context, task taskman.ITask, host *models.SHost, guest *models.SGuest, input []api.ServerNicTrafficLimit) error {
url := fmt.Sprintf("%s/servers/%s/set-nic-traffic-limit", host.ManagerUri, guest.Id)
httpClient := httputils.GetDefaultClient()
header := task.GetTaskRequestHeader()
Expand Down
18 changes: 18 additions & 0 deletions pkg/compute/models/guest_actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -2759,6 +2759,24 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T
return nil, httperrors.NewInvalidStatusError("cannot change CPU/Memory spec in status %s", self.Status)
}

for i := range input.ResetTrafficLimits {
input.ResetTrafficLimits[i].Mac = strings.ToLower(input.ResetTrafficLimits[i].Mac)
_, err := self.GetGuestnetworkByMac(input.ResetTrafficLimits[i].Mac)
if err != nil {
return nil, errors.Wrap(err, "get guest network by mac")
}
}
confs.Set("reset_traffic_limits", jsonutils.Marshal(input.ResetTrafficLimits))

for i := range input.SetTrafficLimits {
input.SetTrafficLimits[i].Mac = strings.ToLower(input.SetTrafficLimits[i].Mac)
_, err := self.GetGuestnetworkByMac(input.SetTrafficLimits[i].Mac)
if err != nil {
return nil, errors.Wrap(err, "get guest network by mac")
}
}
confs.Set("set_traffic_limits", jsonutils.Marshal(input.SetTrafficLimits))

if addCpu < 0 {
addCpu = 0
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/compute/models/guestdrivers.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,8 @@ type IGuestDriver interface {
QgaRequestGetNetwork(ctx context.Context, userCred mcclient.TokenCredential, body jsonutils.JSONObject, host *SHost, guest *SGuest) (jsonutils.JSONObject, error)

FetchMonitorUrl(ctx context.Context, guest *SGuest) string
RequestResetNicTrafficLimit(ctx context.Context, task taskman.ITask, host *SHost, guest *SGuest, input *api.ServerNicTrafficLimit) error
RequestSetNicTrafficLimit(ctx context.Context, task taskman.ITask, host *SHost, guest *SGuest, input *api.ServerNicTrafficLimit) error
RequestResetNicTrafficLimit(ctx context.Context, task taskman.ITask, host *SHost, guest *SGuest, input []api.ServerNicTrafficLimit) error
RequestSetNicTrafficLimit(ctx context.Context, task taskman.ITask, host *SHost, guest *SGuest, input []api.ServerNicTrafficLimit) error

SyncOsInfo(ctx context.Context, userCred mcclient.TokenCredential, g *SGuest, extVM cloudprovider.IOSInfo) error

Expand Down
71 changes: 71 additions & 0 deletions pkg/compute/tasks/guest_change_config_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,69 @@ func (task *GuestChangeConfigTask) OnGuestChangeCpuMemSpecCompleteFailed(ctx con

func (task *GuestChangeConfigTask) OnGuestChangeCpuMemSpecFinish(ctx context.Context, guest *models.SGuest) {
models.HostManager.ClearSchedDescCache(guest.HostId)
if task.Params.Contains("reset_traffic_limits") {
host, _ := guest.GetHost()
resetTraffics := []api.ServerNicTrafficLimit{}
task.Params.Unmarshal(&resetTraffics, "reset_traffic_limits")
task.SetStage("OnGuestResetNicTraffics", nil)
err := guest.GetDriver().RequestResetNicTrafficLimit(ctx, task, host, guest, resetTraffics)
if err != nil {
task.markStageFailed(ctx, guest, jsonutils.NewString(err.Error()))
}
} else {
task.OnGuestResetNicTraffics(ctx, guest, nil)
}
}

func (task *GuestChangeConfigTask) OnGuestResetNicTraffics(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
if task.Params.Contains("reset_traffic_limits") {
resetTraffics := []api.ServerNicTrafficLimit{}
task.Params.Unmarshal(&resetTraffics, "reset_traffic_limits")
for i := range resetTraffics {
input := resetTraffics[i]
gn, _ := guest.GetGuestnetworkByMac(input.Mac)
err := gn.UpdateNicTrafficLimit(input.RxTrafficLimit, input.TxTrafficLimit)
if err != nil {
task.markStageFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("failed update guest nic traffic limit %s", err)))
return
}
err = gn.UpdateNicTrafficUsed(0, 0)
if err != nil {
task.markStageFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("failed update guest nic traffic used %s", err)))
return
}
}
}

if task.Params.Contains("set_traffic_limits") {
host, _ := guest.GetHost()
setTraffics := []api.ServerNicTrafficLimit{}
task.Params.Unmarshal(&setTraffics, "set_traffic_limits")
task.SetStage("OnGuestSetNicTraffics", nil)
err := guest.GetDriver().RequestSetNicTrafficLimit(ctx, task, host, guest, setTraffics)
if err != nil {
task.markStageFailed(ctx, guest, jsonutils.NewString(err.Error()))
}
} else {
task.OnGuestSetNicTraffics(ctx, guest, nil)
}
}

func (task *GuestChangeConfigTask) OnGuestSetNicTraffics(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
if task.Params.Contains("set_traffic_limits") {
setTraffics := []api.ServerNicTrafficLimit{}
task.Params.Unmarshal(&setTraffics, "set_traffic_limits")
for i := range setTraffics {
input := setTraffics[i]
gn, _ := guest.GetGuestnetworkByMac(input.Mac)
err := gn.UpdateNicTrafficLimit(input.RxTrafficLimit, input.TxTrafficLimit)
if err != nil {
task.markStageFailed(ctx, guest, jsonutils.NewString(fmt.Sprintf("failed update guest nic traffic limit %s", err)))
return
}
}
}

task.SetStage("OnSyncConfigComplete", nil)
err := guest.StartSyncTaskWithoutSyncstatus(ctx, task.UserCred, false, task.GetTaskId())
if err != nil {
Expand All @@ -343,6 +406,14 @@ func (task *GuestChangeConfigTask) OnGuestChangeCpuMemSpecFinish(ctx context.Con
}
}

func (task *GuestChangeConfigTask) OnGuestResetNicTrafficsFailed(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
task.markStageFailed(ctx, guest, data)
}

func (task *GuestChangeConfigTask) OnGuestSetNicTrafficsFailed(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
task.markStageFailed(ctx, guest, data)
}

func (task *GuestChangeConfigTask) OnSyncConfigComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
guest := obj.(*models.SGuest)

Expand Down
12 changes: 6 additions & 6 deletions pkg/compute/tasks/guest_sync_nic_traffics_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ func (self *GuestResetNicTrafficsTask) OnInit(ctx context.Context, obj db.IStand
self.taskFailed(ctx, guest, fmt.Sprintf("get host %s", err))
return
}
input := &compute.ServerNicTrafficLimit{}
self.GetParams().Unmarshal(input)
input := compute.ServerNicTrafficLimit{}
self.GetParams().Unmarshal(&input)
self.SetStage("OnResetNicTrafficLimit", nil)
err = guest.GetDriver().RequestResetNicTrafficLimit(ctx, self, host, guest, input)
err = guest.GetDriver().RequestResetNicTrafficLimit(ctx, self, host, guest, []compute.ServerNicTrafficLimit{input})
if err != nil {
self.taskFailed(ctx, guest, err.Error())
}
Expand Down Expand Up @@ -99,10 +99,10 @@ func (self *GuestSetNicTrafficsTask) OnInit(ctx context.Context, obj db.IStandal
self.taskFailed(ctx, guest, fmt.Sprintf("get host %s", err))
return
}
input := &compute.ServerNicTrafficLimit{}
self.GetParams().Unmarshal(input)
input := compute.ServerNicTrafficLimit{}
self.GetParams().Unmarshal(&input)
self.SetStage("OnSetNicTrafficLimit", nil)
err = guest.GetDriver().RequestSetNicTrafficLimit(ctx, self, host, guest, input)
err = guest.GetDriver().RequestSetNicTrafficLimit(ctx, self, host, guest, []compute.ServerNicTrafficLimit{input})
if err != nil {
self.taskFailed(ctx, guest, err.Error())
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/hostman/guestman/guesthandlers/guesthandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -835,8 +835,8 @@ func guestMemorySnapshotDelete(ctx context.Context, w http.ResponseWriter, r *ht
}

func guestResetNicTrafficLimit(ctx context.Context, userCred mcclient.TokenCredential, sid string, body jsonutils.JSONObject) (interface{}, error) {
input := new(computeapi.ServerNicTrafficLimit)
if err := body.Unmarshal(input); err != nil {
input := []computeapi.ServerNicTrafficLimit{}
if err := body.Unmarshal(&input); err != nil {
return nil, httperrors.NewInputParameterError("failed unmarshal input %s", err)
}

Expand All @@ -848,8 +848,8 @@ func guestResetNicTrafficLimit(ctx context.Context, userCred mcclient.TokenCrede
}

func guestSetNicTrafficLimit(ctx context.Context, userCred mcclient.TokenCredential, sid string, body jsonutils.JSONObject) (interface{}, error) {
input := new(computeapi.ServerNicTrafficLimit)
if err := body.Unmarshal(input); err != nil {
input := []computeapi.ServerNicTrafficLimit{}
if err := body.Unmarshal(&input); err != nil {
return nil, httperrors.NewInputParameterError("failed unmarshal input %s", err)
}

Expand Down
61 changes: 43 additions & 18 deletions pkg/hostman/guestman/guestman.go
Original file line number Diff line number Diff line change
Expand Up @@ -1485,11 +1485,27 @@ func (m *SGuestManager) RequestVerifyDirtyServer(s *SKVMGuestInstance) {
}
}

func (m *SGuestManager) ResetGuestNicTrafficLimit(guestId string, input *compute.ServerNicTrafficLimit) error {
func (m *SGuestManager) ResetGuestNicTrafficLimit(guestId string, input []compute.ServerNicTrafficLimit) error {
guest, ok := m.GetServer(guestId)
if !ok {
return httperrors.NewNotFoundError("guest %s not found", guestId)
}

m.TrafficLock.Lock()
defer m.TrafficLock.Unlock()
for i := range input {
if err := m.resetGuestNicTrafficLimit(guest, input[i]); err != nil {
return errors.Wrap(err, "reset guest nic traffic limit")
}
}

if err := guest.SaveLiveDesc(guest.Desc); err != nil {
return errors.Wrap(err, "guest save desc")
}
return nil
}

func (m *SGuestManager) resetGuestNicTrafficLimit(guest *SKVMGuestInstance, input compute.ServerNicTrafficLimit) error {
var nic *desc.SGuestNetwork
for i := range guest.Desc.Nics {
if guest.Desc.Nics[i].Mac == input.Mac {
Expand All @@ -1500,8 +1516,6 @@ func (m *SGuestManager) ResetGuestNicTrafficLimit(guestId string, input *compute
if nic == nil {
return httperrors.NewNotFoundError("guest nic %s not found", input.Mac)
}
m.TrafficLock.Lock()
defer m.TrafficLock.Unlock()

recordPath := guest.NicTrafficRecordPath()
if fileutils2.Exists(recordPath) {
Expand All @@ -1518,7 +1532,7 @@ func (m *SGuestManager) ResetGuestNicTrafficLimit(guestId string, input *compute
}
}
delete(record, strconv.Itoa(int(nic.Index)))
if err = m.SaveGuestTrafficRecord(guestId, record); err != nil {
if err = m.SaveGuestTrafficRecord(guest.Id, record); err != nil {
return errors.Wrap(err, "failed save guest traffic record")
}
}
Expand All @@ -1528,17 +1542,10 @@ func (m *SGuestManager) ResetGuestNicTrafficLimit(guestId string, input *compute
if input.TxTrafficLimit != nil {
nic.TxTrafficLimit = *input.TxTrafficLimit
}
if err := guest.SaveLiveDesc(guest.Desc); err != nil {
return errors.Wrap(err, "guest save desc")
}
return nil
}

func (m *SGuestManager) SetGuestNicTrafficLimit(guestId string, input *compute.ServerNicTrafficLimit) error {
guest, ok := m.GetServer(guestId)
if !ok {
return httperrors.NewNotFoundError("guest %s not found", guestId)
}
func (m *SGuestManager) setNicTrafficLimit(guest *SKVMGuestInstance, input compute.ServerNicTrafficLimit) error {
var nic *desc.SGuestNetwork
for i := range guest.Desc.Nics {
if guest.Desc.Nics[i].Mac == input.Mac {
Expand All @@ -1549,17 +1556,13 @@ func (m *SGuestManager) SetGuestNicTrafficLimit(guestId string, input *compute.S
if nic == nil {
return httperrors.NewNotFoundError("guest nic %s not found", input.Mac)
}
m.TrafficLock.Lock()
defer m.TrafficLock.Unlock()

if input.RxTrafficLimit != nil {
nic.RxTrafficLimit = *input.RxTrafficLimit
}
if input.TxTrafficLimit != nil {
nic.TxTrafficLimit = *input.TxTrafficLimit
}
if err := guest.SaveLiveDesc(guest.Desc); err != nil {
return errors.Wrap(err, "guest save desc")
}
recordPath := guest.NicTrafficRecordPath()
if fileutils2.Exists(recordPath) {
record, err := m.GetGuestTrafficRecord(guest.Id)
Expand All @@ -1574,8 +1577,30 @@ func (m *SGuestManager) SetGuestNicTrafficLimit(guestId string, input *compute.S
}
}
}
return m.SaveGuestTrafficRecord(guestId, record)
return m.SaveGuestTrafficRecord(guest.Id, record)
}
return nil
}

func (m *SGuestManager) SetGuestNicTrafficLimit(guestId string, input []compute.ServerNicTrafficLimit) error {
guest, ok := m.GetServer(guestId)
if !ok {
return httperrors.NewNotFoundError("guest %s not found", guestId)
}

m.TrafficLock.Lock()
defer m.TrafficLock.Unlock()

for i := range input {
if err := m.setNicTrafficLimit(guest, input[i]); err != nil {
return errors.Wrap(err, "set nic traffic limit")
}
}

if err := guest.SaveLiveDesc(guest.Desc); err != nil {
return errors.Wrap(err, "guest save desc")
}

return nil
}

Expand Down
Loading

0 comments on commit 3025b19

Please sign in to comment.