This commit is contained in:
wanyaoqi
2019-01-22 16:56:48 +08:00
committed by Zexi Li
parent 849d76f050
commit c792eba33d
32 changed files with 352 additions and 177 deletions
+2 -2
View File
@@ -1,8 +1,8 @@
package main
import "yunion.io/x/onecloud/pkg/hostman/service"
import "yunion.io/x/onecloud/pkg/hostman"
func main() {
var srv = service.SHostService{}
var srv = hostman.SHostService{}
srv.StartService()
}
+1 -1
View File
@@ -332,7 +332,7 @@ func (app *Application) ListenAndServe(addr string) {
app.server = app.initServer(addr)
err := app.server.ListenAndServe()
if err != nil {
log.Fatalf("ListAndServer fail: %s", err)
log.Infof("ListAndServer: %s", err)
}
}
+1
View File
@@ -51,4 +51,5 @@ func ServeForever(app *appsrv.Application, options *CommonOptions) {
} else {
app.ListenAndServe(addr)
}
select {} // for quit handler
}
+7 -20
View File
@@ -9,29 +9,16 @@ import (
"yunion.io/x/pkg/utils"
)
type IServiceBase interface {
StartService()
ExitService()
TrapSignals(signalutils.Trap)
}
type SServiceBase struct{}
type SServiceBase struct {
}
func (s *SServiceBase) TrapSignals(quitHandler signalutils.Trap) {
func (s *SServiceBase) RegisterSignals(quitHandler signalutils.Trap) {
quitSignals := []os.Signal{syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM}
signalutils.RegisterSignal(quitHandler, quitSignals...)
dumpStack := func() {
// dump goroutine stack
signalutils.RegisterSignal(func() {
utils.DumpAllGoroutineStack(log.Logger().Out)
}
signalutils.RegisterSignal(dumpStack, syscall.SIGUSR1)
}, syscall.SIGUSR1)
signalutils.StartTrap()
}
func (s *SServiceBase) StartService() {
log.Infof("Base Start Service ...")
}
func (s *SServiceBase) ExitService() {
log.Infof("Base Exit Service ...")
}
+2 -2
View File
@@ -57,10 +57,10 @@ func (w *SWorkManager) DelayTask(ctx context.Context, task DelayTaskFunc, params
res, err := task(ctx, params)
if err != nil {
log.Debugf("DelayTask failed: %s", err)
log.Infof("DelayTask failed: %s", err)
w.onFailed(ctx, err.Error())
} else {
log.Debugf("DelayTask complete: %v", res)
log.Infof("DelayTask complete: %v", res)
w.onCompleted(ctx, res)
}
}()
+4 -1
View File
@@ -7,6 +7,7 @@ import (
"path"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/hostman/hostutils"
"yunion.io/x/onecloud/pkg/hostman/storageman"
@@ -47,8 +48,9 @@ func guestActions(ctx context.Context, w http.ResponseWriter, r *http.Request) {
var sid = params["<sid>"]
var action = params["<action>"]
if f, ok := actionFuncs[action]; !ok {
hostutils.Response(ctx, w, httperrors.NewNotFoundError("Not found"))
hostutils.Response(ctx, w, httperrors.NewNotFoundError("%s Not found", action))
} else {
log.Infof("Guest %s Do %s", sid, action)
res, err := f(ctx, sid, body)
if err != nil {
hostutils.Response(ctx, w, err)
@@ -130,6 +132,7 @@ func guestMonitor(ctx context.Context, sid string, body jsonutils.JSONObject) (i
return nil, err
} else {
var res = <-c
log.Errorln(res)
return strDict{"results": path.Join("\n", res)}, nil
}
} else {
+3 -3
View File
@@ -124,8 +124,8 @@ func (m *SGuestManager) OnVerifyExistingGuestsSucc(servers []jsonutils.JSONObjec
}
func (m *SGuestManager) RemoveCandidateServer(server *SKVMGuestInstance) {
if _, ok := m.CandidateServers[server.GetId()]; ok {
delete(m.CandidateServers, server.GetId())
if _, ok := m.CandidateServers[server.Id]; ok {
delete(m.CandidateServers, server.Id)
if len(m.CandidateServers) == 0 {
m.OnLoadExistingGuestsComplete()
}
@@ -347,7 +347,7 @@ func (m *SGuestManager) GuestStart(ctx context.Context, sid string, body jsonuti
}
func (m *SGuestManager) GuestStop(ctx context.Context, sid string, timeout int64) error {
if guest, ok := m.Servers[sid]; !ok {
if guest, ok := m.Servers[sid]; ok {
hostutils.DelayTaskWithoutReqctx(ctx, guest.ExecStopTask, timeout)
return nil
} else {
+6 -6
View File
@@ -227,7 +227,7 @@ func (d *SGuestDiskSyncTask) addDisk(disk jsonutils.JSONObject) {
var params = map[string]string{
"file": iDisk.GetPath(),
"if": "none",
"id": fmt.Sprintf("drive_%s", diskIndex),
"id": fmt.Sprintf("drive_%d", diskIndex),
"cache": cacheMode,
"aio": aio,
}
@@ -254,8 +254,8 @@ func (d *SGuestDiskSyncTask) onAddDiskSucc(disk jsonutils.JSONObject, results st
)
var params = map[string]interface{}{
"drive": fmt.Sprintf("drive_%s", diskIndex),
"id": fmt.Sprintf("drive_%s", diskIndex),
"drive": fmt.Sprintf("drive_%d", diskIndex),
"id": fmt.Sprintf("drive_%d", diskIndex),
}
if diskDirver == DISK_DRIVER_VIRTIO {
@@ -415,9 +415,9 @@ func (s *SGuestResumeTask) onConfirmRunning(status string) {
}
func (s *SGuestResumeTask) taskFailed(reason string) {
log.Infof("Start guest %s failed: %s", s.GetId(), reason)
log.Infof("Start guest %s failed: %s", s.Id, reason)
s.ForceStop()
if len(appctx.AppContextTaskId(s.ctx)) > 0 {
if s.ctx != nil && len(appctx.AppContextTaskId(s.ctx)) > 0 {
hostutils.TaskFailed(s.ctx, reason)
} else {
s.SyncStatus()
@@ -443,7 +443,7 @@ func (s *SGuestResumeTask) onResumeSucc(res string) {
func (s *SGuestResumeTask) onStartRunning() {
s.removeStatefile()
if len(appctx.AppContextTaskId(s.ctx)) > 0 {
if s.ctx != nil && len(appctx.AppContextTaskId(s.ctx)) > 0 {
hostutils.TaskComplete(s.ctx, nil)
}
if options.HostOptions.SetVncPassword {
+31 -26
View File
@@ -98,19 +98,20 @@ func (s *SKVMGuestInstance) GetVncFilePath() string {
}
func (s *SKVMGuestInstance) GetPid() int {
pidFile := s.GetPidFilePath()
fi, err := os.Stat(pidFile)
return s.getPid(s.GetPidFilePath(), s.Id)
}
func (s *SKVMGuestInstance) getPid(pidFile, uuid string) int {
_, err := os.Stat(pidFile)
if os.IsNotExist(err) {
return -1
}
if fi.Mode().IsRegular() {
return -1
}
content, err := ioutil.ReadFile(pidFile)
pidStr, err := fileutils2.FileGetContents(pidFile)
if err != nil {
log.Errorln(err)
return -2
}
pid := s.findPid(strings.Split(string(content), "\n"))
pid := s.findPid(strings.Split(pidStr, "\n"), uuid)
if len(pid) > 0 && regutils.MatchInteger(pid) {
v, _ := strconv.ParseInt(pid, 10, 0)
return int(v)
@@ -118,20 +119,20 @@ func (s *SKVMGuestInstance) GetPid() int {
return -2
}
func (s *SKVMGuestInstance) findPid(pids []string) string {
func (s *SKVMGuestInstance) findPid(pids []string, uuid string) string {
if len(pids) == 0 {
return ""
}
for _, pid := range pids {
pid := strings.TrimSpace(pid)
if s.isSelfQemuPid(pid) {
if s.isSelfQemuPid(pid, uuid) {
return pid
}
}
return ""
}
func (s *SKVMGuestInstance) isSelfQemuPid(pid string) bool {
func (s *SKVMGuestInstance) isSelfQemuPid(pid, uuid string) bool {
if len(pid) == 0 {
return false
}
@@ -150,7 +151,7 @@ func (s *SKVMGuestInstance) isSelfQemuPid(pid string) bool {
return false
}
return bytes.Index(cmdline, []byte("qemu-system")) >= 0 &&
bytes.Index(cmdline, []byte(s.Id)) >= 0
bytes.Index(cmdline, []byte(uuid)) >= 0
}
func (s *SKVMGuestInstance) GetDescFilePath() string {
@@ -248,10 +249,16 @@ func (s *SKVMGuestInstance) saveScripts(data *jsonutils.JSONDict) error {
if err != nil {
return err
}
if fileutils2.Exists(s.GetStartScriptPath()) {
os.Remove(s.GetStartScriptPath())
}
if err = fileutils2.FilePutContents(s.GetStartScriptPath(), startScript, false); err != nil {
return err
}
stopScript := s.generateStopScript(data)
if fileutils2.Exists(s.GetStartScriptPath()) {
os.Remove(s.GetStopScriptPath())
}
return fileutils2.FilePutContents(s.GetStopScriptPath(), stopScript, false)
}
@@ -264,8 +271,8 @@ func (s *SKVMGuestInstance) GetStopScriptPath() string {
}
func (s *SKVMGuestInstance) ImportServer(pendingDelete bool) {
s.manager.Servers[s.GetId()] = s
delete(s.manager.CandidateServers, s.GetId())
s.manager.Servers[s.Id] = s
s.manager.RemoveCandidateServer(s)
if s.IsDirtyShotdown() && !pendingDelete {
log.Infof("Server dirty shotdown %s", s.GetName())
@@ -273,12 +280,12 @@ func (s *SKVMGuestInstance) ImportServer(pendingDelete bool) {
jsonutils.QueryBoolean(s.Desc, "is_slave", false) {
s.DirtyServerRequestStart()
} else {
s.StartGuest(nil, nil)
s.StartGuest(context.Background(), jsonutils.NewDict())
}
return
}
if s.IsRunning() {
log.Infof("%s is running, pending_delete=%s", s.GetName(), pendingDelete)
log.Infof("%s is running, pending_delete=%t", s.GetName(), pendingDelete)
if !pendingDelete {
s.StartMonitor(nil)
}
@@ -287,7 +294,7 @@ func (s *SKVMGuestInstance) ImportServer(pendingDelete bool) {
if s.IsSuspend() {
action = "suspend"
}
log.Infof("%s is %s, pending_delete=%s", s.GetName(), action, pendingDelete)
log.Infof("%s is %s, pending_delete=%t", s.GetName(), action, pendingDelete)
s.SyncStatus()
}
}
@@ -330,10 +337,6 @@ func (s *SKVMGuestInstance) StartMonitor(ctx context.Context) {
}
func (s *SKVMGuestInstance) delayStartMonitor(ctx context.Context) {
if s.GetQmpMonitorPort(-1) > 0 {
// TODO enable hmp?
}
if options.HostOptions.EnableQmpMonitor && s.GetQmpMonitorPort(-1) > 0 {
s.Monitor = monitor.NewQmpMonitor(
s.onMonitorDisConnect,
@@ -341,6 +344,8 @@ func (s *SKVMGuestInstance) delayStartMonitor(ctx context.Context) {
func() { s.onMonitorConnected(ctx) },
)
s.Monitor.Connect("127.0.0.1", s.GetQmpMonitorPort(-1))
} else {
// TODO HMP Monitor
}
}
@@ -391,7 +396,7 @@ func (s *SKVMGuestInstance) CleanStartupTask() {
}
func (s *SKVMGuestInstance) onMonitorTimeout(ctx context.Context, err error) {
log.Errorf("Monitor connect timeout, VM %s frozen!! force restart!!!!", s.GetId())
log.Errorf("Monitor connect timeout, VM %s frozen!! force restart!!!!", s.Id)
s.ForceStop()
timeutils2.AddTimeout(time.Second*3,
func() { s.asyncScriptStart(ctx, jsonutils.NewDict()) })
@@ -455,7 +460,7 @@ func (s *SKVMGuestInstance) SyncStatus() {
status = "suspend"
}
hostutils.UpdateServerStatus(context.Background(), s.GetId(), status)
hostutils.UpdateServerStatus(context.Background(), s.Id, status)
}
func (s *SKVMGuestInstance) CheckBlockOrRunning(jobs int) {
@@ -463,7 +468,7 @@ func (s *SKVMGuestInstance) CheckBlockOrRunning(jobs int) {
if jobs > 0 {
status = "block_stream"
}
_, err := hostutils.UpdateServerStatus(context.Background(), s.GetId(), status)
_, err := hostutils.UpdateServerStatus(context.Background(), s.Id, status)
if err != nil {
log.Errorln(err)
}
@@ -923,7 +928,7 @@ func (s *SKVMGuestInstance) streamDisksComplete(ctx context.Context) {
}
s.SaveDesc(s.Desc)
_, err := modules.Servers.PerformAction(hostutils.GetComputeSession(ctx),
s.GetId(), "stream-disks-complete", nil)
s.Id, "stream-disks-complete", nil)
if err != nil {
log.Infof("stream disks complete sync error %s", err)
}
@@ -935,7 +940,7 @@ func (s *SKVMGuestInstance) GetQemuVersionStr() string {
func (s *SKVMGuestInstance) SyncMetadata(meta *jsonutils.JSONDict) {
_, err := modules.Servers.SetMetadata(hostutils.GetComputeSession(context.Background()),
s.GetId(), meta)
s.Id, meta)
if err != nil {
log.Errorln(err)
}
@@ -946,7 +951,7 @@ func (s *SKVMGuestInstance) SetVncPassword() {
s.VncPassword = password
var callback = func(res string) {
if len(res) > 0 {
log.Errorln("Set vnc password failed: %s", res)
log.Errorf("Set vnc password failed: %s", res)
}
}
timeutils2.AddTimeout(time.Second*3,
+11
View File
@@ -0,0 +1,11 @@
package guestman
import (
"testing"
)
func TestSKVMGuestInstance_getPid(t *testing.T) {
manager := NewGuestManager(nil, "/opt/cloud/workspace/servers")
s := NewKVMGuestInstance("05b787e9-b78e-4ebc-8128-04f55d37306f", manager)
t.Logf("Guest is ->> %d", s.GetPid())
}
+27 -4
View File
@@ -337,6 +337,20 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) (strin
cmd += "function nic_speed() {\n"
cmd += " $QEMU_CMD "
if s.IsKvmSupport() {
cmd += "-enable-kvm"
} else {
cmd += "-no-kvm"
}
cmd += " -device virtio-net-pci,? 2>&1 | grep .speed= > /dev/null\n"
cmd += " if [ \"$?\" -eq \"0\" ]; then\n"
cmd += " echo \",speed=$1\"\n"
cmd += " fi\n"
cmd += "}\n"
// Generate Start VM script
cmd += `CMD="$QEMU_CMD`
var accel, cpuType string
if s.IsKvmSupport() {
cmd += " -enable-kvm"
@@ -364,7 +378,7 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) (strin
cmd += fmt.Sprintf(" -cpu %s", cpuType)
// TODO hmp - -
cmd += s.getMonitorDesc("hmqmon", s.GetQmpMonitorPort(int(vncPort)), MODE_READLINE)
cmd += s.getMonitorDesc("hmqmon", s.GetHmpMonitorPort(int(vncPort)), MODE_READLINE)
if options.HostOptions.EnableQmpMonitor {
cmd += s.getMonitorDesc("qmqmon", s.GetQmpMonitorPort(int(vncPort)), MODE_CONTROL)
}
@@ -444,9 +458,10 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) (strin
// cmd += isolated_devs_params['vga']
// else:
// cmd += ' -vga %s' % self.desc.get('vga', 'std')
// cmd += ' -vnc :%d' % (vnc_port)
// if options.set_vnc_password:
// cmd += ',password'
cmd += fmt.Sprintf(" -vnc :%d", vncPort)
if options.HostOptions.SetVncPassword {
cmd += ",password"
}
}
var diskDrivers = []string{}
@@ -530,6 +545,7 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) (strin
} else if jsonutils.QueryBoolean(s.Desc, "is_master", false) {
cmd += " -S"
}
cmd += fmt.Sprintf(" -D %s", path.Join(s.HomeDir(), "log"))
cmd += "\"\n"
cmd += "if [ ! -z \"$STATE_FILE\" ] && [ -d \"$STATE_FILE\" ] && [ -f \"$STATE_FILE/content\" ]; then\n"
@@ -540,6 +556,13 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) (strin
cmd += " $CMD\n"
cmd += "fi\n"
/*
# cmd += 'sleep 1\n'
# cmd += 'PID_NUM=$(cat $PID_FILE)\n'
# cmd += 'echo -17 > /proc/$PID_NUM/oom_adj\n'
# cmd += 'echo "qemu started"\n'
*/
return cmd, nil
}
@@ -1,4 +1,4 @@
package service
package hostman
import (
"context"
@@ -19,8 +19,7 @@ import (
type SHostService struct {
service.SServiceBase
guestmanager *guestman.SGuestManager
hostinstance *hostinfo.SHostInfo
isExiting bool
}
func (host *SHostService) StartService() {
@@ -30,48 +29,52 @@ func (host *SHostService) StartService() {
options.HostOptions.EnableRbac = false
app := cloudcommon.InitApp(&options.HostOptions.CommonOptions, false)
host.TrapSignals(func() { host.quitSignalHandler(app) })
hostInstance := hostinfo.Instance()
if err := hostInstance.Init(); err != nil {
log.Fatalf(err.Error())
}
// register quit handler
host.RegisterSignals(func() {
if host.isExiting {
return
} else {
host.isExiting = true
}
if app.IsInServe() {
err := app.ShowDown(context.Background())
if err != nil {
log.Errorln(err.Error())
}
}
hostinfo.Stop()
storageman.Stop()
guestman.Stop()
hostutils.GetWorkManager().Stop()
os.Exit(0)
})
if err := storageman.Init(hostInstance); err != nil {
log.Fatalf(err.Error())
}
guestman.Init(hostInstance, options.HostOptions.ServersPath)
var c = make(chan struct{})
cloudcommon.InitAuth(&options.HostOptions.CommonOptions, func() {
log.Infof("Auth complete!!")
hostInstance.StartRegister(5, guestman.GetGuestManager().Bootstrap)
<-hostinfo.Instance().IsRegistered
close(c)
})
host.initHandlers(app)
<-c // wait host and guest init
<-hostinfo.Instance().IsRegistered // wait host and guest init
cloudcommon.ServeForever(app, &options.HostOptions.CommonOptions)
}
func (host *SHostService) quitSignalHandler(app *appsrv.Application) {
if app.IsInServe() {
err := app.ShowDown(context.Background())
if err != nil {
log.Errorln(err.Error())
}
}
hostutils.GetWorkManager().Stop()
os.Exit(0)
}
func (host *SHostService) initHandlers(app *appsrv.Application) {
guestman.AddGuestTaskHandler("", app)
storageman.AddStorageHandler("", app)
@@ -30,6 +30,7 @@ type IBridgeDriver interface {
GenerateIfdownScripts(scriptPath string, nic jsonutils.JSONObject) error
RegisterHostlocalServer(mac, ip string) error
WarmupConfig() error
CleanupConfig()
}
type SBaseBridgeDriver struct {
@@ -189,6 +190,11 @@ type SOVSBridgeDriver struct {
SBaseBridgeDriver
}
func (o *SOVSBridgeDriver) CleanupConfig() {
ovsutils.CleanAllHiddenPorts()
// if enableopenflowcontroller ...
}
func (o *SOVSBridgeDriver) Exists() bool {
data, err := procutils.NewCommand("ovs-vsctl", "list-br").Run()
if err != nil {
+1 -1
View File
@@ -54,7 +54,7 @@ func NewDHCPRelay(addrs []string) *SDHCPRelay {
func (r *SDHCPRelay) Start() {
log.Infof("DHCPRelay starting ...")
go r.server.ListenAndServe(r)
r.server.ListenAndServe(r)
}
func (r *SDHCPRelay) Setup(addr string) {
+53 -18
View File
@@ -49,8 +49,10 @@ type SHostInfo struct {
isRegistered bool
IsRegistered chan struct{}
registerCallback func()
saved bool
pinger *SHostPingTask
stopped bool
saved bool
pinger *SHostPingTask
kvmModuleSupport string
nestStatus string
@@ -58,7 +60,7 @@ type SHostInfo struct {
Cpu *SCPUInfo
Mem *SMemory
sysinfo *SSysInfo
// storageManager *storageman.SStorageManager
IsolatedDeviceMan *isolated_device.IsolatedDeviceManager
MasterNic *netutils2.SNetInterface
@@ -278,18 +280,18 @@ func (h *SHostInfo) detectHostInfo() error {
h.detectiveStorageSystem()
// TODO
// if options.HostOptions.CheckSystemServices {
// if err := h.checkSystemServices(); err != nil {
// return err
// }
// }
if options.HostOptions.CheckSystemServices {
if err := h.checkSystemServices(); err != nil {
return err
}
}
return nil
}
func (h *SHostInfo) checkSystemServices() error {
// TOOD
return fmt.Errorf("not implement so far")
for _, srv := range []string{"ntpd", "telegraf"} {
srvinst := system_service.GetService(srv)
}
}
func (h *SHostInfo) detectiveStorageSystem() {
@@ -853,7 +855,7 @@ func (h *SHostInfo) onUpdateHostInfoSucc(body jsonutils.JSONObject) {
if memReserved, _ := hostbody.Int("mem_reserved"); memReserved == 0 {
h.updateHostReservedMem()
} else {
h.putHostOffline()
h.PutHostOffline()
}
}
@@ -878,7 +880,7 @@ func (h *SHostInfo) getReservedMem() int64 {
return int64(reserved)
}
func (h *SHostInfo) putHostOffline() {
func (h *SHostInfo) PutHostOffline() {
_, err := modules.Hosts.PerformAction(
h.GetSession(), h.HostId, "offline", nil)
if err != nil {
@@ -1081,6 +1083,8 @@ func (h *SHostInfo) onGetStorageInfoSucc(hoststorages []jsonutils.JSONObject) {
storageName, _ := hs.GetString("storage")
storageConf, _ := hs.Get("storage_conf")
log.Infof("Storage %s(%s) mountpoint %s", storageName, storagetype, mountPoint)
if !utils.IsInStringArray(storagetype, storagetypes.Local) {
storage := storageManager.NewSharedStorageInstance(mountPoint, storagetype)
if storage != nil {
@@ -1124,7 +1128,7 @@ func (h *SHostInfo) uploadStorageInfo() {
}
func (h *SHostInfo) onSyncStorageInfoSucc(storage storageman.IStorage, storageInfo jsonutils.JSONObject) {
if len(storage.GetId()) > 0 {
if len(storage.GetId()) == 0 {
id, _ := storageInfo.GetString("id")
name, _ := storageInfo.GetString("name")
storageConf, _ := storageInfo.Get("storage_conf")
@@ -1191,10 +1195,8 @@ func (h *SHostInfo) uploadIsolatedDevices() {
}
func (h *SHostInfo) onSucc() {
if !h.isRegistered {
if !h.stopped && !h.isRegistered {
log.Infof("Host registration process success....")
h.isRegistered = true
if err := h.save(); err != nil {
panic(err.Error())
}
@@ -1206,6 +1208,7 @@ func (h *SHostInfo) onSucc() {
h.registerCallback()
}
h.isRegistered = true
// To notify caller, host register is success
close(h.IsRegistered)
}
@@ -1213,7 +1216,9 @@ func (h *SHostInfo) onSucc() {
func (h *SHostInfo) StartPinger() {
h.pinger = NewHostPingTask(options.HostOptions.PingRegionInterval)
go h.pinger.Start()
if h.pinger != nil {
go h.pinger.Start()
}
}
func (h *SHostInfo) save() error {
@@ -1263,6 +1268,32 @@ func (h *SHostInfo) registerHostlocalServer() error {
return nil
}
func (h *SHostInfo) stop() {
log.Infof("Host Info stop ...")
h.unregister()
if h.pinger != nil {
h.pinger.Stop()
}
for _, nic := range h.Nics {
nic.ExitCleanup()
}
}
func (h *SHostInfo) unregister() {
h.stopped = true
_, err := modules.Hosts.PerformAction(
h.GetSession(), h.HostId, "offline", nil)
if err != nil {
log.Errorln(err)
}
}
func (h *SHostInfo) OnCatalogChanged(catalog map[string]interface{}) {
if options.HostOptions.ManageNtpConfiguration {
}
}
func NewHostInfo() (*SHostInfo, error) {
var res = new(SHostInfo)
res.sysinfo = &SSysInfo{}
@@ -1297,3 +1328,7 @@ func Instance() *SHostInfo {
}
return hostInfo
}
func Stop() {
hostInfo.stop()
}
+6
View File
@@ -201,6 +201,12 @@ func (n *SNIC) SetWireId(wire, wireId string, bandwidth int64) {
n.Bandwidth = int(bandwidth)
}
func (n *SNIC) ExitCleanup() {
n.BridgeDev.CleanupConfig()
log.Infof("Stop DHCP Server")
// TODO stop dhcp server
}
func NewNIC(desc string) (*SNIC, error) {
nic := new(SNIC)
data := strings.Split(desc, "/")
+51 -3
View File
@@ -1,13 +1,61 @@
package hostinfo
import (
"context"
"time"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/hostman/hostutils"
"yunion.io/x/onecloud/pkg/mcclient/modules"
)
type SHostPingTask struct {
interval int
interval int // second
running bool
}
func NewHostPingTask(interval int) *SHostPingTask {
return &SHostPingTask{interval}
if interval <= 0 {
return nil
}
return &SHostPingTask{interval, true}
}
func (p *SHostPingTask) Start() {
//TODO
var (
div = 1
hostId = Instance().GetHostId()
)
for {
time.Sleep(time.Duration(p.interval/div) * time.Second)
if !p.running {
return
}
res, err := modules.Hosts.PerformAction(hostutils.GetComputeSession(context.Background()),
hostId, "ping", nil)
if err != nil {
div = 3
} else {
name, err := res.GetString("name")
if err != nil {
Instance().setHostname(name)
}
catalog, err := res.Get("catalog")
if err != nil {
var cl = make(map[string]interface{}, 0)
err = catalog.Unmarshal(&cl)
if err != nil {
log.Errorln(err)
continue
}
Instance().OnCatalogChanged(cl)
}
}
}
}
func (p *SHostPingTask) Stop() {
if p.running {
p.running = false
}
}
+1 -1
View File
@@ -20,7 +20,7 @@ type HmpMonitor struct {
callbackQueue []StringCallback
}
func NewHmpMonitor(OnMonitorConnected MonitorSuccFunc, OnMonitorDisConnect, OnMonitorTimeout MonitorErrorFunc) *HmpMonitor {
func NewHmpMonitor(OnMonitorDisConnect, OnMonitorTimeout MonitorErrorFunc, OnMonitorConnected MonitorSuccFunc) *HmpMonitor {
return &HmpMonitor{
SBaseMonitor: *NewBaseMonitor(OnMonitorConnected, OnMonitorDisConnect, OnMonitorTimeout),
commandQueue: make([]string, 0),
+2 -1
View File
@@ -11,7 +11,7 @@ func TestHmpMonitor_Connect(t *testing.T) {
onConnected := func() { log.Infof("Monitor Connected") }
onDisConnect := func(error) { log.Infof("Monitor DisConnect") }
onTimeout := func(error) { log.Infof("Monitor Timeout") }
m := NewHmpMonitor(onConnected, onDisConnect, onTimeout)
m := NewHmpMonitor(onDisConnect, onTimeout, onConnected)
var host = "127.0.0.1"
var port = 55901
m.Connect(host, port)
@@ -21,5 +21,6 @@ func TestHmpMonitor_Connect(t *testing.T) {
statusCallBack := func(res string) { log.Infof("OnStatusCallback %s", res) }
m.QueryStatus(statusCallBack)
m.Disconnect()
time.Sleep(3 * time.Second)
}
+2
View File
@@ -54,6 +54,7 @@ type SBaseMonitor struct {
QemuVersion string
connected bool
timeout bool
rwc net.Conn
mutex *sync.Mutex
@@ -66,6 +67,7 @@ func NewBaseMonitor(OnMonitorConnected MonitorSuccFunc, OnMonitorDisConnect, OnM
OnMonitorConnected: OnMonitorConnected,
OnMonitorDisConnect: OnMonitorDisConnect,
OnMonitorTimeout: OnMonitorTimeout,
timeout: true,
mutex: &sync.Mutex{},
}
}
+29 -13
View File
@@ -95,14 +95,16 @@ func NewQmpMonitor(OnMonitorDisConnect, OnMonitorTimeout MonitorErrorFunc,
callbackQueue: make([]qmpMonitorCallBack, 0),
}
// qmp init must set capabilities
// On qmp init must set capabilities
m.commandQueue = append(m.commandQueue, &Command{Execute: "qmp_capabilities"})
m.callbackQueue = append(m.callbackQueue, nil)
return m
}
func (m *QmpMonitor) actionResult(res *Response) string {
if res.ErrorVal != nil {
log.Infof("Qmp Monitor action result %s", res.ErrorVal.Error())
return res.ErrorVal.Error()
} else {
return ""
@@ -150,31 +152,44 @@ func (m *QmpMonitor) read(r io.Reader) {
}
m.callBack(res)
} else if val, ok := objmap["event"]; ok {
var event = &Event{}
event.Event = string(*val)
json.Unmarshal(*objmap["data"], &event.Data)
json.Unmarshal(*objmap["timestamp"], event.Timestamp)
var event = &Event{
Event: string(*val),
Data: make(map[string]interface{}, 0),
Timestamp: new(Timestamp),
}
if data, ok := objmap["data"]; ok {
json.Unmarshal(*data, &event.Data)
}
if timestamp, ok := objmap["timestamp"]; ok {
json.Unmarshal(*timestamp, event.Timestamp)
}
m.watchEvent(event)
} else if val, ok := objmap["QMP"]; ok {
var version Version
json.Unmarshal(*val, &version)
m.QemuVersion = version.String()
m.connected = true
json.Unmarshal(*val, &objmap)
if val, ok = objmap["version"]; ok {
var version Version
json.Unmarshal(*val, &version)
m.QemuVersion = version.String()
}
// remove reader timeout
m.rwc.SetReadDeadline(time.Time{})
log.Infof("Qmp Connected")
m.connected = true
m.timeout = false
go m.query()
go m.OnMonitorConnected()
}
}
log.Errorln("Scan over ...")
log.Infof("Scan over ...")
if err := scanner.Err(); err != nil {
log.Errorln(err)
if m.connected {
if m.timeout {
m.OnMonitorTimeout(err)
} else if m.connected {
m.connected = false
m.OnMonitorDisConnect(err)
} else {
m.OnMonitorTimeout(err)
}
}
m.reading = false
@@ -185,6 +200,7 @@ func (m QmpMonitor) watchEvent(event *Event) {
}
func (m *QmpMonitor) write(cmd []byte) error {
log.Infof("QMP Write: %s", string(cmd))
length, index := len(cmd), 0
for index < length {
i, err := m.rwc.Write(cmd)
+2 -1
View File
@@ -11,7 +11,7 @@ func TestQmpMonitor_Connect(t *testing.T) {
onConnected := func() { log.Infof("Monitor Connected") }
onDisConnect := func(error) { log.Infof("Monitor DisConnect") }
onTimeout := func(error) { log.Infof("Monitor Timeout") }
m := NewQmpMonitor(onConnected, onDisConnect, onTimeout)
m := NewQmpMonitor(onDisConnect, onTimeout, onConnected)
var host = "127.0.0.1"
var port = 56101
m.Connect(host, port)
@@ -26,5 +26,6 @@ func TestQmpMonitor_Connect(t *testing.T) {
statusCallBack := func(res string) { log.Infof("OnStatusCallback %s", res) }
m.QueryStatus(statusCallBack)
m.Disconnect()
time.Sleep(3 * time.Second)
}
+2 -1
View File
@@ -74,7 +74,8 @@ type SHostOptions struct {
EnableOpenflowController bool `default:"false"`
K8sClusterCidr string `default:"10.43.0.0/16" help:"Kubernetes cluster IP range"`
PingRegionInterval int `default:"60" help:"interval to ping region, deefault is 1 minute"`
PingRegionInterval int `default:"60" help:"interval to ping region, deefault is 1 minute"`
ManageNtpConfiguration bool `default:"true"`
}
var HostOptions SHostOptions
-1
View File
@@ -1 +0,0 @@
package service // import "yunion.io/x/onecloud/pkg/hostman/service"
+4
View File
@@ -275,3 +275,7 @@ func Init(host hostutils.IHost) error {
storageManager, err = NewStorageManager(host)
return err
}
func Stop() {
// pass do nothing
}
+15 -23
View File
@@ -16,13 +16,12 @@ import (
)
type SImageDesc struct {
Name string
Format string
Id string
Chksum string
Path string
ParentId string
Size int64
Name string
Format string
Id string
Chksum string
Path string
Size int64
}
type SRemoteFile struct {
@@ -36,10 +35,9 @@ type SRemoteFile struct {
timeout time.Duration
extraHeaders map[string]string
chksum string
format string
parentId string
name string
chksum string
format string
name string
}
func NewRemoteFile(
@@ -89,12 +87,11 @@ func (r *SRemoteFile) GetInfo() *SImageDesc {
}
return &SImageDesc{
Name: r.name,
Format: r.format,
Chksum: r.chksum,
Path: r.localPath,
ParentId: r.parentId,
Size: fi.Size(),
Name: r.name,
Format: r.format,
Chksum: r.chksum,
Path: r.localPath,
Size: fi.Size(),
}
}
@@ -226,10 +223,5 @@ func (r *SRemoteFile) download(getData bool, preChksum string) bool {
func (r *SRemoteFile) setProperties(header http.Header) {
r.chksum = header.Get("X-Image-Meta-Checksum")
r.format = header.Get("X-Image-Meta-Disk_format")
r.parentId = header.Get("X-Image-Meta-Parent_id")
if len(r.parentId) == 0 {
r.name = ""
} else {
r.name = header.Get("X-Image-Meta-Name")
}
r.name = header.Get("X-Image-Meta-Name")
}
+2
View File
@@ -70,6 +70,8 @@ func (s *SLocalStorage) SyncStorageInfo() (jsonutils.JSONObject, error) {
res jsonutils.JSONObject
)
log.Infof("Sync storage info %s", s.StorageId)
if len(s.StorageId) > 0 {
res, err = modules.Storages.Put(
hostutils.GetComputeSession(context.Background()),
+1
View File
@@ -0,0 +1 @@
package system_service // import "yunion.io/x/onecloud/pkg/hostman/system_service"
@@ -0,0 +1,18 @@
package system_service
type ISystemService interface {
IsInstalled() bool
Start() error
IsActive() bool
GetConf(map[string]interface{}) []string
SetConf([]string)
BgReload(servers []string)
Enable() error
Disable() error
GetStatus() string
Reload()
}
func GetService(name string) ISystemService {
return nil
}
+33 -24
View File
@@ -50,8 +50,8 @@ type CGroupTask struct {
hand ICGroupTask
}
func NewCGroupTask(pid string, coreNum int) *CGroupTask {
return &CGroupTask{
func NewCGroupTask(pid string, coreNum int) CGroupTask {
return CGroupTask{
pid: pid,
weight: float64(coreNum) / normalizeBase,
}
@@ -111,10 +111,15 @@ func SetRootParam(module, name, value, pid string) bool {
if param := GetRootParam(module, name, pid); param != value {
fi, err := os.Open(GetTaskParamPath(module, name, pid))
if err == nil {
fi.Write([]byte(value))
err = fi.Sync()
_, err = fi.Write([]byte(value))
if err != nil {
err = fi.Close()
} else {
log.Errorln(err)
}
} else {
log.Errorln(err)
}
defer fi.Close()
if err != nil {
if len(pid) == 0 {
@@ -356,7 +361,7 @@ func (c *CGroupTask) init() bool {
*/
type CGroupCPUTask struct {
*CGroupTask
CGroupTask
}
const (
@@ -378,9 +383,9 @@ func (c *CGroupCPUTask) init() bool {
fmt.Sprintf("%d", CgroupsSharesWeight), "")
}
func NewCGroupCPUTask(pid string, coreNum int) *CGroupCPUTask {
cgroup := &CGroupCPUTask{NewCGroupTask(pid, coreNum)}
cgroup.hand = cgroup
func NewCGroupCPUTask(pid string, coreNum int) CGroupCPUTask {
cgroup := CGroupCPUTask{NewCGroupTask(pid, coreNum)}
cgroup.hand = &cgroup
return cgroup
}
@@ -389,7 +394,7 @@ func NewCGroupCPUTask(pid string, coreNum int) *CGroupCPUTask {
*/
type CGroupIOTask struct {
*CGroupTask
CGroupTask
}
const (
@@ -417,8 +422,8 @@ func (c *CGroupIOTask) init() bool {
return SetRootParam(c.Module(), BLOCK_IO_WEIGHT, fmt.Sprintf("%d", IoWeightMax), "")
}
func NewCGroupIOTask(pid string, coreNum int) *CGroupIOTask {
return &CGroupIOTask{NewCGroupTask(pid, coreNum)}
func NewCGroupIOTask(pid string, coreNum int) CGroupIOTask {
return CGroupIOTask{NewCGroupTask(pid, coreNum)}
}
/**
@@ -426,7 +431,7 @@ func NewCGroupIOTask(pid string, coreNum int) *CGroupIOTask {
*/
type CGroupIOHardlimitTask struct {
*CGroupIOTask
CGroupIOTask
cpuNum int
params map[string]int
@@ -443,8 +448,8 @@ func (c *CGroupIOHardlimitTask) GetConfig() map[string]string {
return config
}
func NewCGroupIOHardlimitTask(pid string, mem int, params map[string]int, devId string) *CGroupIOHardlimitTask {
return &CGroupIOHardlimitTask{
func NewCGroupIOHardlimitTask(pid string, mem int, params map[string]int, devId string) CGroupIOHardlimitTask {
return CGroupIOHardlimitTask{
CGroupIOTask: NewCGroupIOTask(pid, 0),
cpuNum: mem,
params: params,
@@ -457,7 +462,7 @@ func NewCGroupIOHardlimitTask(pid string, mem int, params map[string]int, devId
*/
type CGroupMemoryTask struct {
*CGroupTask
CGroupTask
}
const (
@@ -474,8 +479,8 @@ func (c *CGroupMemoryTask) GetConfig() map[string]string {
return map[string]string{MEMORY_SWAPPINESS: fmt.Sprintf("%d", vm_swappiness)}
}
func NewCGroupMemoryTask(pid string, coreNum int) *CGroupMemoryTask {
return &CGroupMemoryTask{
func NewCGroupMemoryTask(pid string, coreNum int) CGroupMemoryTask {
return CGroupMemoryTask{
CGroupTask: NewCGroupTask(pid, coreNum),
}
}
@@ -485,7 +490,7 @@ func NewCGroupMemoryTask(pid string, coreNum int) *CGroupMemoryTask {
*/
type CGroupCPUSetTask struct {
*CGroupTask
CGroupTask
cpuset string
}
@@ -507,8 +512,8 @@ func (c *CGroupCPUSetTask) GetConfig() map[string]string {
return map[string]string{CPUSET_CPUS: c.cpuset}
}
func NewCGroupCPUSetTask(pid string, coreNum int, cpuset string) *CGroupCPUSetTask {
return &CGroupCPUSetTask{
func NewCGroupCPUSetTask(pid string, coreNum int, cpuset string) CGroupCPUSetTask {
return CGroupCPUSetTask{
CGroupTask: NewCGroupTask(pid, coreNum),
cpuset: cpuset,
}
@@ -524,7 +529,8 @@ func Init() bool {
}
func CgroupSet(pid string, coreNum int) bool {
for _, hand := range []ICGroupTask{&CGroupCPUTask{}, &CGroupIOTask{}, &CGroupMemoryTask{}} {
tasks := []ICGroupTask{&CGroupCPUTask{}, &CGroupIOTask{}, &CGroupMemoryTask{}}
for _, hand := range tasks {
hand.SetHand(hand)
hand.SetPid(pid)
hand.SetWeight(coreNum)
@@ -544,7 +550,9 @@ func CgroupIoHardlimitSet(
}
func CgroupDestroy(pid string) bool {
for _, hand := range []ICGroupTask{&CGroupCPUTask{}, &CGroupIOTask{}, &CGroupMemoryTask{}, &CGroupCPUSetTask{}, &CGroupIOHardlimitTask{}} {
tasks := []ICGroupTask{&CGroupCPUTask{}, &CGroupIOTask{}, &CGroupMemoryTask{},
&CGroupCPUSetTask{}, &CGroupIOHardlimitTask{}}
for _, hand := range tasks {
hand.SetHand(hand)
hand.SetPid(pid)
if !hand.RemoveTask() {
@@ -555,7 +563,8 @@ func CgroupDestroy(pid string) bool {
}
func CgroupCleanAll() {
for _, hand := range []ICGroupTask{&CGroupCPUTask{}, &CGroupIOTask{}, &CGroupMemoryTask{}, &CGroupCPUSetTask{}, &CGroupIOHardlimitTask{}} {
tasks := []ICGroupTask{&CGroupCPUTask{}, &CGroupIOTask{}, &CGroupMemoryTask{}, &CGroupCPUSetTask{}, &CGroupIOHardlimitTask{}}
for _, hand := range tasks {
hand.SetHand(hand)
CleanupNonexistPids(hand.Module())
}
+2 -2
View File
@@ -30,12 +30,12 @@ var PRIVATE_PREFIXES = []string{
}
func IsTcpPortUsed(addr string, port int) bool {
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", addr, port))
conn, _ := net.Dial("tcp", fmt.Sprintf("%s:%d", addr, port))
if conn != nil {
conn.Close()
log.Infof("Tcp port in use: %s %d", addr, port)
return true
} else {
log.Infof("IsTcpPortUsed: %s %d %s", addr, port, err)
return false
}
}
+1
View File
@@ -44,6 +44,7 @@ func Run(name string, args ...string) ([]string, error) {
// Doesn't have timeout
func (c *Command) Run() ([]byte, error) {
log.Infof("Exec command: %s %v", c.Path, c.Args)
output, err := RunCommandWithoutTimeout(c.Path, c.Args...)
if err != nil {
log.Errorf("Execute command %q , error: %v , output: %s", c, err, string(output))