mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-21 06:09:39 +08:00
Before this patch, host guests will not migrate on host manual shutdown. This patch from k8s node status check host still on line, if node status not ready, region will migrate guests on host. Signed-off-by: wanyaoqi <d3lx.yq@gmail.com>
157 lines
3.6 KiB
Go
157 lines
3.6 KiB
Go
// Copyright 2019 Yunion
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package hostinfo
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/shirou/gopsutil/mem"
|
|
|
|
"yunion.io/x/jsonutils"
|
|
"yunion.io/x/log"
|
|
"yunion.io/x/pkg/errors"
|
|
|
|
api "yunion.io/x/onecloud/pkg/apis/compute"
|
|
"yunion.io/x/onecloud/pkg/hostman/hostutils"
|
|
"yunion.io/x/onecloud/pkg/hostman/options"
|
|
"yunion.io/x/onecloud/pkg/hostman/storageman"
|
|
"yunion.io/x/onecloud/pkg/httperrors"
|
|
"yunion.io/x/onecloud/pkg/mcclient"
|
|
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
|
)
|
|
|
|
type SHostPingTask struct {
|
|
interval int // second
|
|
running bool
|
|
|
|
lastStatAt time.Time
|
|
}
|
|
|
|
type SEndpoint struct {
|
|
Id string `json:"id"`
|
|
Interface string `json:"interface"`
|
|
Region string `json:"region"`
|
|
Region_id string `json:"region_id"`
|
|
Url string `json:"url"`
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
type SCatalog struct {
|
|
Id string `json:"id"`
|
|
Name string `json:"name"`
|
|
Type string `json:"type"`
|
|
Endpoints []SEndpoint `json:"endpoint"`
|
|
}
|
|
|
|
func NewCatalog() *SCatalog {
|
|
return &SCatalog{
|
|
Endpoints: make([]SEndpoint, 0),
|
|
}
|
|
}
|
|
|
|
func NewHostPingTask(interval int) *SHostPingTask {
|
|
if interval <= 0 {
|
|
return nil
|
|
}
|
|
return &SHostPingTask{
|
|
interval: interval,
|
|
running: true,
|
|
}
|
|
}
|
|
|
|
func (p *SHostPingTask) Start() {
|
|
log.Infof("Start host pinger ...")
|
|
var (
|
|
div = 1
|
|
hostId = Instance().GetHostId()
|
|
err error
|
|
)
|
|
for {
|
|
if !p.running {
|
|
return
|
|
}
|
|
if err = p.ping(div, hostId); err != nil {
|
|
log.Errorf("host ping failed %s", err)
|
|
div = 3
|
|
} else {
|
|
div = 1
|
|
}
|
|
|
|
time.Sleep(time.Duration(p.interval/div) * time.Second)
|
|
}
|
|
}
|
|
|
|
func (p *SHostPingTask) payload() api.SHostPingInput {
|
|
data := api.SHostPingInput{}
|
|
|
|
now := time.Now()
|
|
if !p.lastStatAt.IsZero() && now.Before(p.lastStatAt.Add(time.Duration(options.HostOptions.SyncStorageInfoDurationSecond)*time.Second)) {
|
|
return data
|
|
}
|
|
|
|
p.lastStatAt = now
|
|
data = storageman.GatherHostStorageStats()
|
|
data.WithData = true
|
|
info, err := mem.VirtualMemory()
|
|
if err != nil {
|
|
return data
|
|
}
|
|
memTotal := int(info.Total / 1024 / 1024)
|
|
memFree := int(info.Available / 1024 / 1024)
|
|
memUsed := memTotal - memFree
|
|
data.MemoryUsedMb = memUsed
|
|
return data
|
|
}
|
|
|
|
func (p *SHostPingTask) ping(div int, hostId string) error {
|
|
log.Debugf("ping region at %d...", div)
|
|
res, err := modules.Hosts.PerformAction(hostutils.GetComputeSession(context.Background()),
|
|
hostId, "ping", jsonutils.Marshal(p.payload()))
|
|
if err != nil {
|
|
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 {
|
|
// Instance().setHostname(name)
|
|
// }
|
|
catalog, err := res.Get("catalog")
|
|
if err == nil {
|
|
cl := make(mcclient.KeystoneServiceCatalogV3, 0)
|
|
err = catalog.Unmarshal(&cl)
|
|
if err != nil {
|
|
log.Errorln(err)
|
|
return nil
|
|
}
|
|
|
|
Instance().OnCatalogChanged(cl)
|
|
} else {
|
|
log.Errorln(err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (p *SHostPingTask) Stop() {
|
|
if p.running {
|
|
p.running = false
|
|
}
|
|
}
|