mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
Merge pull request #8054 from rainzm/esxi/cluster
Sync cluster for ESXi Host
This commit is contained in:
@@ -248,6 +248,8 @@ type ICloudHost interface {
|
||||
|
||||
CreateVM(desc *SManagedVMCreateConfig) (ICloudVM, error)
|
||||
GetIHostNics() ([]ICloudHostNetInterface, error)
|
||||
|
||||
GetSchedtags() ([]string, error)
|
||||
}
|
||||
|
||||
type ICloudVM interface {
|
||||
|
||||
@@ -33,6 +33,7 @@ import (
|
||||
"yunion.io/x/pkg/util/fileutils"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
"yunion.io/x/pkg/util/regutils"
|
||||
"yunion.io/x/pkg/util/sets"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
@@ -1735,6 +1736,11 @@ func (self *SHost) syncWithCloudHost(ctx context.Context, userCred mcclient.Toke
|
||||
self.SyncShareState(ctx, userCred, provider.getAccountShareInfo())
|
||||
}
|
||||
|
||||
if err := self.syncSchedtags(ctx, userCred, extHost); err != nil {
|
||||
log.Errorf("syncSchedtags fail: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := HostManager.ClearSchedDescCache(self.Id); err != nil {
|
||||
log.Errorf("ClearSchedDescCache for host %s error %v", self.Name, err)
|
||||
}
|
||||
@@ -1766,6 +1772,102 @@ func (self *SHost) syncWithCloudPrepaidVM(extVM cloudprovider.ICloudVM, host *SH
|
||||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
METADATA_EXT_SCHEDTAG_KEY = "ext:schedtag"
|
||||
METADATA_EXT_SCHEDTAG_VALUE = "yes"
|
||||
)
|
||||
|
||||
func (s *SHost) syncSchedtags(ctx context.Context, userCred mcclient.TokenCredential, extHost cloudprovider.ICloudHost) error {
|
||||
stq := SchedtagManager.Query()
|
||||
subq := HostschedtagManager.Query("schedtag_id").Equals("host_id", s.Id).SubQuery()
|
||||
stq = stq.Join(subq, sqlchemy.Equals(stq.Field("id"), subq.Field("schedtag_id")))
|
||||
schedtags := make([]SSchedtag, 0)
|
||||
err := db.FetchModelObjects(SchedtagManager, stq, &schedtags)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "db.FetchModelObjects")
|
||||
}
|
||||
extSchedtagStrs, err := extHost.GetSchedtags()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "extHost.GetSchedtags")
|
||||
}
|
||||
extStStrSet := sets.NewString(extSchedtagStrs...)
|
||||
removed := make([]*SSchedtag, 0)
|
||||
removedIds := make([]string, 0)
|
||||
for i := range schedtags {
|
||||
stag := &schedtags[i]
|
||||
if v := stag.GetMetadata(METADATA_EXT_SCHEDTAG_KEY, userCred); v != METADATA_EXT_SCHEDTAG_VALUE {
|
||||
continue
|
||||
}
|
||||
if !extStStrSet.Has(stag.GetName()) {
|
||||
removed = append(removed, stag)
|
||||
removedIds = append(removedIds, stag.GetId())
|
||||
} else {
|
||||
extStStrSet.Delete(stag.GetName())
|
||||
}
|
||||
}
|
||||
added := extStStrSet.UnsortedList()
|
||||
|
||||
for _, stStr := range added {
|
||||
st := &SSchedtag{
|
||||
ResourceType: HostManager.KeywordPlural(),
|
||||
}
|
||||
st.DomainId = s.DomainId
|
||||
st.Name = stStr
|
||||
st.Description = "Sync from cloud"
|
||||
err := SchedtagManager.TableSpec().Insert(ctx, st)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to create schedtag %q", stStr)
|
||||
}
|
||||
st.SetModelManager(SchedtagManager, st)
|
||||
st.SetMetadata(ctx, METADATA_EXT_SCHEDTAG_KEY, METADATA_EXT_SCHEDTAG_VALUE, userCred)
|
||||
// attach
|
||||
hostschedtag := &SHostschedtag{
|
||||
HostId: s.GetId(),
|
||||
}
|
||||
hostschedtag.SchedtagId = st.GetId()
|
||||
err = HostschedtagManager.TableSpec().Insert(ctx, hostschedtag)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to create hostschedtag for tag %q host %q", stStr, s.GetId())
|
||||
}
|
||||
}
|
||||
|
||||
if len(removedIds) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
q := HostschedtagManager.Query().Equals("host_id", s.GetId()).In("schedtag_id", removedIds)
|
||||
hostschedtags := make([]SHostschedtag, 0, len(removedIds))
|
||||
err = db.FetchModelObjects(HostschedtagManager, q, &hostschedtags)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "db.FetchModelObject")
|
||||
}
|
||||
for i := range hostschedtags {
|
||||
err = hostschedtags[i].Detach(ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to detach host %q and schedtag %q", hostschedtags[i].HostId, hostschedtags[i].SchedtagId)
|
||||
}
|
||||
}
|
||||
|
||||
// try to clean
|
||||
for _, tag := range removed {
|
||||
cnt, err := tag.GetObjectCount()
|
||||
if err != nil {
|
||||
log.Errorf("unable to GetObjectCount for schedtag %q: %v", tag.GetName(), err)
|
||||
continue
|
||||
}
|
||||
if cnt > 0 {
|
||||
continue
|
||||
}
|
||||
err = tag.Delete(ctx, userCred)
|
||||
if err != nil {
|
||||
log.Errorf("unable to delete schedtag %q: %v", tag.GetName(), err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SHostManager) newFromCloudHost(ctx context.Context, userCred mcclient.TokenCredential, extHost cloudprovider.ICloudHost, provider *SCloudprovider, izone *SZone) (*SHost, error) {
|
||||
host := SHost{}
|
||||
host.SetModelManager(manager, &host)
|
||||
@@ -1844,6 +1946,11 @@ func (manager *SHostManager) newFromCloudHost(ctx context.Context, userCred mccl
|
||||
|
||||
SyncCloudDomain(userCred, &host, provider.GetOwnerId())
|
||||
|
||||
if err := host.syncSchedtags(ctx, userCred, extHost); err != nil {
|
||||
log.Errorf("newFromCloudHost fail in syncSchedtags %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if provider != nil {
|
||||
host.SyncShareState(ctx, userCred, provider.getAccountShareInfo())
|
||||
}
|
||||
|
||||
@@ -104,3 +104,7 @@ func (cluster *SCluster) SyncResourcePool(name string) (*mo.ResourcePool, error)
|
||||
}
|
||||
return cluster.CreateResourcePool(name)
|
||||
}
|
||||
|
||||
func (cluster *SCluster) getoCluster() *mo.ClusterComputeResource {
|
||||
return cluster.object.(*mo.ClusterComputeResource)
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ type SDatacenter struct {
|
||||
istorages []cloudprovider.ICloudStorage
|
||||
inetworks []IVMNetwork
|
||||
iresoucePool []cloudprovider.ICloudProject
|
||||
clusters []*SCluster
|
||||
|
||||
Name string
|
||||
}
|
||||
@@ -148,6 +149,9 @@ func (dc *SDatacenter) GetCluster(cluster string) (*SCluster, error) {
|
||||
}
|
||||
|
||||
func (dc *SDatacenter) listClusters() ([]*SCluster, error) {
|
||||
if dc.clusters != nil {
|
||||
return dc.clusters, nil
|
||||
}
|
||||
clusters := []mo.ClusterComputeResource{}
|
||||
err := dc.manager.scanMObjects(dc.object.Entity().Self, RESOURCEPOOL_PROPS, &clusters)
|
||||
if err != nil {
|
||||
|
||||
@@ -128,6 +128,29 @@ func (self *SHost) GetMetadata() *jsonutils.JSONDict {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SHost) GetSchedtags() ([]string, error) {
|
||||
clusters, err := self.datacenter.listClusters()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reference := self.GetoHostSystem().Reference()
|
||||
tags := make([]string, 0, 1)
|
||||
Loop:
|
||||
for i := range clusters {
|
||||
oc := clusters[i].getoCluster()
|
||||
if len(oc.Host) == 0 {
|
||||
continue
|
||||
}
|
||||
for _, h := range oc.Host {
|
||||
if h == reference {
|
||||
tags = append(tags, fmt.Sprintf("cluster:%s", oc.Name))
|
||||
continue Loop
|
||||
}
|
||||
}
|
||||
}
|
||||
return tags, nil
|
||||
}
|
||||
|
||||
func (self *SHost) getHostSystem() *mo.HostSystem {
|
||||
return self.object.(*mo.HostSystem)
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/multicloud"
|
||||
)
|
||||
|
||||
var RESOURCEPOOL_PROPS = []string{"name", "parent"}
|
||||
var RESOURCEPOOL_PROPS = []string{"name", "parent", "host"}
|
||||
|
||||
type SResourcePool struct {
|
||||
multicloud.SResourceBase
|
||||
|
||||
@@ -29,3 +29,7 @@ func (self *SHostBase) GetMemCmtbound() float32 {
|
||||
func (self *SHostBase) GetReservedMemoryMb() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SHostBase) GetSchedtags() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user