fix: host inherit class metadata from wire (#13896)

* fix: host inherit class metadata from wire

* deal with host delete exit

Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
This commit is contained in:
Jian Qiu
2022-04-05 11:14:28 +08:00
committed by GitHub
parent 2215f3d760
commit 87a7d4efe0
16 changed files with 77 additions and 23 deletions

View File

@@ -33,4 +33,5 @@ func init() {
cmd.PerformWithKeyword("merge", "merge-from", new(options.WireMergeOptions))
cmd.Perform("merge-network", new(options.WireOptions))
cmd.Get("topology", &options.WireOptions{})
cmd.Perform("set-class-metadata", &options.ResourceMetadataOptions{})
}

View File

@@ -299,24 +299,45 @@ func (model *SStandaloneAnonResourceBase) SetClassMetadataAll(ctx context.Contex
return nil
}
func (model *SStandaloneAnonResourceBase) Inherit(ctx context.Context, sonModel *SStandaloneAnonResourceBase) error {
return Inherit(ctx, model, sonModel)
func (model *SStandaloneAnonResourceBase) InheritTo(ctx context.Context, dest IClassMetadataSetter) error {
return InheritFromTo(ctx, model, dest)
}
type IClassMetadataSetter interface {
// a setter should first be a owner
IClassMetadataOwner
SetClassMetadataAll(context.Context, map[string]string, mcclient.TokenCredential) error
}
func Inherit(ctx context.Context, parent IClassMetadataOwner, son IClassMetadataSetter) error {
metadata, err := parent.GetAllClassMetadata()
func InheritFromTo(ctx context.Context, src IClassMetadataOwner, dest IClassMetadataSetter) error {
metadata, err := src.GetAllClassMetadata()
if err != nil {
return errors.Wrap(err, "GetAllClassMetadata")
}
if len(metadata) == 0 {
return nil
}
curMeta, err := dest.GetAllClassMetadata()
if err != nil {
return errors.Wrap(err, "GetAllClassMetadata dest")
}
if len(curMeta) > 0 {
// check conflict
for k, v := range curMeta {
if sv, ok := metadata[k]; ok {
if sv != v {
// duplicate value for identical key
return errors.Wrapf(httperrors.ErrConflict, "destination has another value for class key %s", k)
}
} else {
// no such class key
return errors.Wrapf(httperrors.ErrConflict, "destination has extra class key %s", k)
}
}
}
userCred := auth.AdminCredential()
return son.SetClassMetadataAll(ctx, metadata, userCred)
return dest.SetClassMetadataAll(ctx, metadata, userCred)
}
type IClassMetadataOwner interface {

View File

@@ -288,7 +288,7 @@ func (model *SVirtualResourceBase) PostCreate(ctx context.Context, userCred mccl
log.Errorf("unable to GetTenantCache: %s", err.Error())
return
}
err = Inherit(ctx, project, model)
err = InheritFromTo(ctx, project, model)
if err != nil {
log.Errorf("unable to inherit class metadata from poject %s: %s", project.GetId(), err.Error())
}

View File

@@ -280,7 +280,7 @@ func (db *SDiskBackup) PostCreate(ctx context.Context, userCred mcclient.TokenCr
if err != nil {
log.Errorf("unable to GetDisk: %s", err.Error())
}
err = disk.Inherit(ctx, &db.SStandaloneAnonResourceBase)
err = disk.InheritTo(ctx, db)
if err != nil {
log.Errorf("unable to inherit from disk %s to backup %s: %s", disk.GetId(), db.GetId(), err.Error())
}

View File

@@ -4733,7 +4733,7 @@ func (self *SGuest) PerformInstanceSnapshot(
ctx, userCred, pendingUsage, pendingUsage, false)
return nil, httperrors.NewInternalServerError("create instance snapshot failed: %s", err)
}
err = self.Inherit(ctx, &instanceSnapshot.SStandaloneAnonResourceBase)
err = self.InheritTo(ctx, instanceSnapshot)
if err != nil {
return nil, errors.Wrapf(err, "unable to inherit from guest %s to instance snapshot %s", self.GetId(), instanceSnapshot.GetId())
}
@@ -4776,7 +4776,7 @@ func (self *SGuest) PerformInstanceBackup(ctx context.Context, userCred mcclient
if err != nil {
return nil, httperrors.NewInternalServerError("create instance backup failed: %s", err)
}
err = self.Inherit(ctx, &instanceBackup.SStandaloneAnonResourceBase)
err = self.InheritTo(ctx, instanceBackup)
if err != nil {
return nil, errors.Wrapf(err, "unable to inherit from guest %s to instance backup %s", self.GetId(), instanceBackup.GetId())
}

View File

@@ -3856,7 +3856,7 @@ func (self *SGuest) createDiskOnHost(
if autoAttach {
err = self.attach2Disk(ctx, disk, userCred, diskConfig.Driver, diskConfig.Cache, diskConfig.Mountpoint)
}
err = self.Inherit(ctx, &disk.SStandaloneAnonResourceBase)
err = self.InheritTo(ctx, disk)
if err != nil {
return nil, errors.Wrapf(err, "unable to inherit from guest %s to disk %s", self.GetId(), disk.GetId())
}

View File

@@ -4276,7 +4276,7 @@ func (self *SHost) addNetif(ctx context.Context, userCred mcclient.TokenCredenti
}
// inherit wire's class metadata
if sw != nil {
err := db.Inherit(ctx, sw, self)
err := db.InheritFromTo(ctx, sw, self)
if err != nil {
return errors.Wrapf(err, "unable to inherit class metadata from sw %s", sw.GetName())
}

View File

@@ -290,3 +290,19 @@ func (manager *SHostwireManager) ListItemExportKeys(ctx context.Context,
return q, nil
}
func (hw *SHostwire) PostCreate(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
query jsonutils.JSONObject,
data jsonutils.JSONObject,
) {
hw.SHostJointsBase.PostCreate(ctx, userCred, ownerId, query, data)
host := hw.GetHost()
wire := hw.GetWire()
err := db.InheritFromTo(ctx, wire, host)
if err != nil {
log.Errorf("Inherit class metadata from host to wire fail: %s", err)
}
}

View File

@@ -393,7 +393,7 @@ func (manager *SInstanceSnapshotManager) CreateInstanceSnapshot(ctx context.Cont
if err != nil {
return nil, errors.Wrap(err, "Insert")
}
err = db.Inherit(ctx, guest, instanceSnapshot)
err = db.InheritFromTo(ctx, guest, instanceSnapshot)
if err != nil {
return nil, errors.Wrap(err, "Inherit ClassMetadata")
}

View File

@@ -2792,7 +2792,7 @@ func (manager *SNetworkManager) PerformTryCreateNetwork(ctx context.Context, use
if err != nil {
return nil, errors.Wrap(err, "unable to get wire")
}
err = db.Inherit(ctx, wire, newNetwork)
err = db.InheritFromTo(ctx, wire, newNetwork)
if err != nil {
return nil, errors.Wrap(err, "unable to inherit wire")
}

View File

@@ -411,7 +411,7 @@ func (snapshot *SSnapshot) PostCreate(ctx context.Context, userCred mcclient.Tok
if err != nil {
log.Errorf("unable to GetDisk: %s", err.Error())
}
err = disk.Inherit(ctx, &snapshot.SStandaloneAnonResourceBase)
err = disk.InheritTo(ctx, snapshot)
if err != nil {
log.Errorf("unable to inherit from disk %s to snapshot %s: %s", disk.GetId(), snapshot.GetId(), err.Error())
}

View File

@@ -1471,7 +1471,7 @@ func (model *SWire) PostCreate(ctx context.Context, userCred mcclient.TokenCrede
if err != nil {
log.Errorf("unable to getvpc of wire %s: %s", model.GetId(), vpc.GetId())
}
err = db.Inherit(ctx, vpc, model)
err = db.InheritFromTo(ctx, vpc, model)
if err != nil {
log.Errorf("unable to inhert vpc to model %s: %s", model.GetId(), err.Error())
}

View File

@@ -1178,7 +1178,7 @@ func (self *SKVMRegionDriver) RequestCreateInstanceSnapshot(ctx context.Context,
return err
}
err = isp.Inherit(ctx, &snapshot.SStandaloneAnonResourceBase)
err = isp.InheritTo(ctx, snapshot)
if err != nil {
return errors.Wrapf(err, "unable to inherit from instance snapshot %s to snapshot %s", isp.GetId(), snapshot.GetId())
}
@@ -1333,7 +1333,7 @@ func (self *SKVMRegionDriver) RequestCreateInstanceBackup(ctx context.Context, g
if err != nil {
return err
}
err = ib.Inherit(ctx, &backup.SStandaloneAnonResourceBase)
err = ib.InheritTo(ctx, backup)
if err != nil {
return errors.Wrapf(err, "unable to inherit from instance backup %s to backup %s", ib.GetId(), backup.GetId())
}

View File

@@ -27,11 +27,11 @@ import (
"strings"
"time"
"github.com/pkg/errors"
"github.com/vishvananda/netlink"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/version"
"yunion.io/x/pkg/utils"
@@ -52,6 +52,7 @@ import (
"yunion.io/x/onecloud/pkg/hostman/options"
"yunion.io/x/onecloud/pkg/hostman/storageman"
"yunion.io/x/onecloud/pkg/hostman/system_service"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
"yunion.io/x/onecloud/pkg/util/cgrouputils"
@@ -426,10 +427,10 @@ func (h *SHostInfo) prepareEnv() error {
}
szlist := hp.PageSizes()
if len(szlist) == 0 {
return errors.New("invalid hugepages total size")
return errors.Error("invalid hugepages total size")
}
if len(szlist) > 1 {
return errors.New("cannot support more than 1 type of hugepage size")
return errors.Error("cannot support more than 1 type of hugepage size")
}
h.sysinfo.HugepageSizeKb = szlist[0]
case "transparent":
@@ -591,7 +592,7 @@ func (h *SHostInfo) EnableNativeHugepages(reservedMb int) error {
return nil
}
} else {
return errors.New("cannot support more than 1 type of hugepage sizes")
return errors.Error("cannot support more than 1 type of hugepage sizes")
}
mem := h.GetMemory()
if reservedMb > 0 {
@@ -1794,6 +1795,10 @@ func (h *SHostInfo) unregister() {
_, err := modules.Hosts.PerformAction(
h.GetSession(), h.HostId, "offline", jsonutils.Marshal(map[string]string{"reason": "host stop"}))
if err != nil {
if errors.Cause(err) == httperrors.ErrResourceNotFound {
log.Errorf("host not found on region, may be removed, exit cleanly")
break
}
if !isLog {
logclient.AddSimpleActionLog(h, logclient.ACT_OFFLINE, err, hostutils.GetComputeSession(context.Background()).GetToken(), false)
isLog = true

View File

@@ -19,8 +19,10 @@ import (
"time"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/hostman/hostutils"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
)
@@ -84,7 +86,12 @@ func (p *SHostPingTask) ping(div int, hostId string) error {
res, err := modules.Hosts.PerformAction(hostutils.GetComputeSession(context.Background()),
hostId, "ping", nil)
if err != nil {
return err
if errors.Cause(err) == httperrors.ErrResourceNotFound {
log.Errorf("host seemd removed from region ...")
return nil
} else {
return errors.Wrap(err, "ping")
}
} else {
name, err := res.GetString("name")
if err != nil {

View File

@@ -141,7 +141,11 @@ func (opts *ResourceMetadataOptions) GetId() string {
func (opts *ResourceMetadataOptions) Params() (jsonutils.JSONObject, error) {
params := jsonutils.NewDict()
for _, tag := range opts.TAGS {
info := strings.Split(tag, "=")
sep := "="
if strings.Index(tag, sep) < 0 {
sep = ":"
}
info := strings.Split(tag, sep)
if len(info) == 2 {
if len(info[0]) == 0 {
return nil, fmt.Errorf("invalidate tag info %s", tag)