Skip to content

Commit

Permalink
guestdrivers: kvm: eip associate
Browse files Browse the repository at this point in the history
  • Loading branch information
yousong committed May 28, 2020
1 parent ff6e3e2 commit 8b82d67
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
53 changes: 53 additions & 0 deletions pkg/compute/guestdrivers/kvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@ import (

"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/utils"
"yunion.io/x/sqlchemy"

api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
Expand Down Expand Up @@ -302,6 +305,56 @@ func (self *SKVMGuestDriver) OnDeleteGuestFinalCleanup(ctx context.Context, gues
return nil
}

func (self *SKVMGuestDriver) IsSupportEip() bool {
return true
}

func (self *SKVMGuestDriver) RequestAssociateEip(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, eip *models.SElasticip, task taskman.ITask) error {
defer task.ScheduleRun(nil)

lockman.LockObject(ctx, guest)
defer lockman.ReleaseObject(ctx, guest)

var guestnics []models.SGuestnetwork
{
netq := models.NetworkManager.Query().SubQuery()
wirq := models.WireManager.Query().SubQuery()
vpcq := models.VpcManager.Query().SubQuery()
gneq := models.GuestnetworkManager.Query()
q := gneq.Equals("guest_id", guest.Id).
IsNullOrEmpty("eip_id")
q = q.Join(netq, sqlchemy.Equals(netq.Field("id"), gneq.Field("network_id")))
q = q.Join(wirq, sqlchemy.Equals(wirq.Field("id"), netq.Field("wire_id")))
q = q.Join(vpcq, sqlchemy.Equals(vpcq.Field("id"), wirq.Field("vpc_id")))
q = q.Filter(sqlchemy.NotEquals(vpcq.Field("id"), api.DEFAULT_VPC_ID))
if err := db.FetchModelObjects(models.GuestnetworkManager, q, &guestnics); err != nil {
return err
}
if len(guestnics) == 0 {
return errors.Errorf("guest has no nics to associate eip")
}
}

guestnic := &guestnics[0]
lockman.LockObject(ctx, guestnic)
defer lockman.ReleaseObject(ctx, guestnic)
if _, err := db.Update(guestnic, func() error {
guestnic.EipId = eip.Id
return nil
}); err != nil {
return errors.Wrapf(err, "set associated eip for guestnic %s (guest:%s, network:%s)",
guestnic.Ifname, guestnic.GuestId, guestnic.NetworkId)
}

if err := eip.AssociateVM(ctx, userCred, guest); err != nil {
return errors.Wrapf(err, "associate eip %s(%s) to vm %s(%s)", eip.Name, eip.Id, guest.Name, guest.Id)
}
if err := eip.SetStatus(userCred, api.EIP_STATUS_READY, api.EIP_STATUS_ASSOCIATE); err != nil {
return errors.Wrapf(err, "set eip status to %s", api.EIP_STATUS_ALLOCATE)
}
return nil
}

func (self *SKVMGuestDriver) NeedStopForChangeSpec(guest *models.SGuest, cpuChanged, memChanged bool) bool {
return guest.GetMetadata("hotplug_cpu_mem", nil) != "enable" ||
(memChanged && guest.GetMetadata("__hugepage", nil) == "native")
Expand Down
2 changes: 2 additions & 0 deletions pkg/compute/models/elasticips.go
Original file line number Diff line number Diff line change
Expand Up @@ -967,6 +967,8 @@ func (self *SElasticip) PerformAssociate(ctx context.Context, userCred mcclient.
return nil, httperrors.NewInvalidStatusError("cannot associate pending delete server")
}

// IMPORTANT: this serves as a guard against a guest to have multiple
// associated elastic_ips
seip, _ := server.GetEip()
if seip != nil {
return nil, httperrors.NewInvalidStatusError("instance is already associated with eip")
Expand Down

0 comments on commit 8b82d67

Please sign in to comment.