host complie success

This commit is contained in:
wanyaoqi
2019-01-16 12:09:06 +08:00
parent 1867584335
commit be7f8f1e95
28 changed files with 1088 additions and 258 deletions
+23 -23
View File
@@ -141,7 +141,7 @@ func guestSync(ctx context.Context, sid string, body jsonutils.JSONObject) (inte
if !guestManger.IsGuestExist(sid) {
return nil, httperrors.NewNotFoundError("Guest %s not found", sid)
}
hostutils.DelayTask(ctx, guestManger.GuestSync, &SGuestSync{sid, body})
hostutils.DelayTask(ctx, guestManger.GuestSync, &SBaseParms{sid, body})
return nil, nil
}
@@ -262,13 +262,13 @@ func guestResume(ctx context.Context, sid string, body jsonutils.JSONObject) (in
return nil, nil
}
func guestStartNbdServer(ctx context.Context, sid string, body jsonutils.JSONObject) (interface{}, error) {
if !guestManger.IsGuestExist(sid) {
return nil, httperrors.NewNotFoundError("Guest %s not found", sid)
}
hostutils.DelayTask(ctx, guestManger.StartNbdServer, sid)
return nil, nil
}
// func guestStartNbdServer(ctx context.Context, sid string, body jsonutils.JSONObject) (interface{}, error) {
// if !guestManger.IsGuestExist(sid) {
// return nil, httperrors.NewNotFoundError("Guest %s not found", sid)
// }
// hostutils.DelayTask(ctx, guestManger.StartNbdServer, sid)
// return nil, nil
// }
func guestDriveMirror(ctx context.Context, sid string, body jsonutils.JSONObject) (interface{}, error) {
if !guestManger.IsGuestExist(sid) {
@@ -278,7 +278,7 @@ func guestDriveMirror(ctx context.Context, sid string, body jsonutils.JSONObject
if err != nil {
return nil, httperrors.NewMissingParameterError("backup_ndb_server_uri")
}
hostutils.DelayTask(ctx, guestManger.StartDriveMirror,
hostutils.DelayTaskWithoutReqctx(ctx, guestManger.StartDriveMirror,
&SDriverMirror{sid, backupNbdServerUri})
return nil, nil
}
@@ -295,11 +295,11 @@ func guestReloadDiskSnapshot(ctx context.Context, sid string, body jsonutils.JSO
var disk storageman.IDisk
guest := guestManger.Servers[sid]
disks, _ := guest.Desc.GetArray("disks")
for _, disk := range disks {
id, _ := disk.GetString("disk_id")
for _, d := range disks {
id, _ := d.GetString("disk_id")
if diskId == id {
diskPath, _ := disk.GetString("path")
disk := storageman.GetManager().GetDiskByPath(diskPath)
diskPath, _ := d.GetString("path")
disk = storageman.GetManager().GetDiskByPath(diskPath)
break
}
}
@@ -327,11 +327,11 @@ func guestSnapshot(ctx context.Context, sid string, body jsonutils.JSONObject) (
var disk storageman.IDisk
guest := guestManger.Servers[sid]
disks, _ := guest.Desc.GetArray("disks")
for _, disk := range disks {
id, _ := disk.GetString("disk_id")
for _, d := range disks {
id, _ := d.GetString("disk_id")
if diskId == id {
diskPath, _ := disk.GetString("path")
disk := storageman.GetManager().GetDiskByPath(diskPath)
diskPath, _ := d.GetString("path")
disk = storageman.GetManager().GetDiskByPath(diskPath)
break
}
}
@@ -356,11 +356,11 @@ func guestDeleteSnapshot(ctx context.Context, sid string, body jsonutils.JSONObj
var disk storageman.IDisk
guest := guestManger.Servers[sid]
disks, _ := guest.Desc.GetArray("disks")
for _, disk := range disks {
id, _ := disk.GetString("disk_id")
for _, d := range disks {
id, _ := d.GetString("disk_id")
if diskId == id {
diskPath, _ := disk.GetString("path")
disk := storageman.GetManager().GetDiskByPath(diskPath)
diskPath, _ := d.GetString("path")
disk = storageman.GetManager().GetDiskByPath(diskPath)
break
}
}
@@ -409,6 +409,6 @@ var actionFuncs = map[string]actionFunc{
"dest-prepare-migrate": guestDestPrepareMigrate,
"live-migrate": guestLiveMigrate,
"resume": guestResume,
"start-nbd-server": guestStartNbdServer,
"drive-mirror": guestDriveMirror,
// "start-nbd-server": guestStartNbdServer,
"drive-mirror": guestDriveMirror,
}
+2 -1
View File
@@ -11,7 +11,8 @@ type SBaseParms struct {
}
type SGuestDeploy struct {
SGuestBaseParms
Sid string
Body jsonutils.JSONObject
IsInit bool
}
+63 -23
View File
@@ -29,7 +29,9 @@ import (
"yunion.io/x/onecloud/pkg/util/timeutils2"
)
const VNC_PORT_BASE = 5900
const (
VNC_PORT_BASE = 5900
)
type SGuestManager struct {
host hostutils.IHost
@@ -273,8 +275,7 @@ func (m *SGuestManager) GuestDeploy(ctx context.Context, params interface{}) (js
password = seclib.RandomPassword(12)
}
guestInfo, err := guest.DeployFs(&guestfs.SDeployInfo{
publicKey, deploys, password, deployParams.IsInit})
guestInfo, err := guest.DeployFs(guestfs.NewDeployInfo(publicKey, deploys, password, deployParams.IsInit, false))
if err != nil {
log.Errorf("Deploy guest fs error: %s", err)
return nil, err
@@ -282,13 +283,14 @@ func (m *SGuestManager) GuestDeploy(ctx context.Context, params interface{}) (js
return guestInfo, nil
}
} else {
return nil, fmt.Errorf("Guest %s not found", sid)
return nil, fmt.Errorf("Guest %s not found", deployParams.Sid)
}
}
// delay cpuset balance
func (m *SGuestManager) CpusetBalance(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
// TODO
return nil, fmt.Errorf("not implement")
}
func (m *SGuestManager) Status(sid string) string {
@@ -326,11 +328,8 @@ func (m *SGuestManager) GuestStart(ctx context.Context, sid string, body jsonuti
}
if guest.IsStopped() {
params, _ := body.Get("params")
if err := guest.StartGuest(ctx, params); err != nil {
return nil, httperrors.NewBadRequestError("Failed to start server")
} else {
return jsonutils.NewDict(jsonutils.NewPair("vnc_port", jsonutils.NewInt(0))), nil
}
guest.StartGuest(ctx, params)
return jsonutils.NewDict(jsonutils.NewPair("vnc_port", jsonutils.NewInt(0))), nil
} else {
vncPort := guest.GetVncPort()
if vncPort > 0 {
@@ -386,9 +385,14 @@ func (m *SGuestManager) SrcPrepareMigrate(ctx context.Context, params interface{
return nil, hostutils.ParamsError
}
guest := m.Servers[migParams.Sid]
disksPrepare := guest.PrepareMigrate(migParams.LiveMigrate)
if len(disksPrepare) > 0 {
return map[string]interface{}{"disks_back": disksPrepare}, nil
disksPrepare, err := guest.PrepareMigrate(migParams.LiveMigrate)
if err != nil {
return nil, err
}
if disksPrepare.Length() > 0 {
ret := jsonutils.NewDict()
ret.Set("disks_back", disksPrepare)
return ret, nil
}
return nil, nil
}
@@ -400,7 +404,7 @@ func (m *SGuestManager) DestPrepareMigrate(ctx context.Context, params interface
}
guest := m.Servers[migParams.Sid]
if err := guest.CreateFromDesc(desc); err != nil {
if err := guest.CreateFromDesc(migParams.Desc); err != nil {
return nil, err
}
@@ -437,9 +441,10 @@ func (m *SGuestManager) DestPrepareMigrate(ctx context.Context, params interface
// create snapshots form remote url
diskStorageId, _ := diskinfo.GetString("storage_id")
for _, snapshotId := range snapshots {
snapshotUrl := path.Join(migParams.SnapshotsUri, diskStorageId, diskId, snapshotId)
snapshotPath := path.Join(disk.GetSnapshotDir(), snapshotId)
log.Infof("Disk %s snapshot %s url: %s", diskId, snapshotId, snapshotUrl)
snapId, _ := snapshotId.GetString()
snapshotUrl := path.Join(migParams.SnapshotsUri, diskStorageId, diskId, snapId)
snapshotPath := path.Join(disk.GetSnapshotDir(), snapId)
log.Infof("Disk %s snapshot %s url: %s", diskId, snapId, snapshotUrl)
iStorage.CreateSnapshotFormUrl(ctx, snapshotUrl, diskId, snapshotPath)
}
@@ -447,7 +452,7 @@ func (m *SGuestManager) DestPrepareMigrate(ctx context.Context, params interface
// create local disk
backingFile, _ := migParams.DisksBackingFile.GetString(diskId)
size, _ := diskinfo.Int("size")
_, err := disk.CreateRaw(ctx, size, "qcow2", "", false, "", backingFile)
_, err := disk.CreateRaw(ctx, int(size), "qcow2", "", false, "", backingFile)
if err != nil {
log.Errorln(err)
return nil, err
@@ -455,7 +460,7 @@ func (m *SGuestManager) DestPrepareMigrate(ctx context.Context, params interface
} else {
// download disk form remote url
diskUrl := path.Join(migParams.DisksUri, diskStorageId, diskId)
if err := disk.CreateFromUrl(); err != nil {
if err := disk.CreateFromUrl(ctx, diskUrl); err != nil {
log.Errorln(err)
return nil, err
}
@@ -473,7 +478,7 @@ func (m *SGuestManager) DestPrepareMigrate(ctx context.Context, params interface
startParams := jsonutils.NewDict()
startParams.Set("qemu_version", jsonutils.NewString(migParams.QemuVersion))
startParams.Set("need_migrate", jsonutils.JSONTrue)
guest.StartGuest(ctx, params)
guest.StartGuest(ctx, startParams)
}
return nil, nil
@@ -505,7 +510,7 @@ func (m *SGuestManager) CanMigrate(sid string) bool {
return true
}
func (m *SGuestManager) GetFreePortByBase(basePort int64) int64 {
func (m *SGuestManager) GetFreePortByBase(basePort int) int {
var port = 1
for {
if netutils2.IsTcpPortUsed("0.0.0.0", basePort+port) ||
@@ -517,7 +522,7 @@ func (m *SGuestManager) GetFreePortByBase(basePort int64) int64 {
}
}
func (m *SGuestManager) GetFreeVncPort() int64 {
func (m *SGuestManager) GetFreeVncPort() int {
vncPorts := make(map[int]struct{}, 0)
for _, guest := range m.Servers {
inUsePort := guest.GetVncPort()
@@ -569,22 +574,57 @@ func (m *SGuestManager) DeleteSnapshot(ctx context.Context, params interface{})
delParams.ConvertSnapshot, delParams.PendingDelete)
} else {
return jsonutils.NewDict(jsonutils.NewPair("deleted", jsonutils.JSONTrue)),
delParams.Disk.DeleteSnapshot(delParams.DeleteSnapshot)
delParams.Disk.DeleteSnapshot(delParams.DeleteSnapshot, "", false)
}
}
func (m *SGuestManager) Resume(ctx context.Context, sid string, isLiveMigrate bool) (jsonutils.JSONObject, error) {
guest := guestManger.Servers[sid]
resumeTask := NewGuestResumeTask(ctx, guest)
if isLiveMigrate {
guest.StartPresendArp()
}
resumeTask.Start()
return nil, nil
}
// func (m *SGuestManager) StartNbdServer(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
// sid, ok := params.(string)
// if !ok {
// return nil, hostutils.ParamsError
// }
// guest := guestManger.Servers[sid]
// port := m.GetFreePortByBase(BUILT_IN_NBD_SERVER_PORT_BASE)
// }
func (m *SGuestManager) StartDriveMirror(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
mirrorParams, ok := params.(*SDriverMirror)
if !ok {
return nil, hostutils.ParamsError
}
guest := guestManger.Servers[mirrorParams.Sid]
task := NewDriveMirrorTask(ctx, guest, mirrorParams.NbdServerUri, "top", nil)
task.Start()
return nil, nil
}
func (m *SGuestManager) ExitGuestCleanup() {
for _, guest := range m.Servers {
guest.ExitCleanup(false)
}
// TODO
m.StopCpusetBalancer()
// m.StopCpusetBalancer()
cgrouputils.CgroupCleanAll()
// TODO
// hostmetrics?
}
func (m *SGuestManager) GetHost() hostutils.IHost {
return m.host
}
var guestManger *SGuestManager
func Stop() {
+107 -51
View File
@@ -34,7 +34,7 @@ type SGuestStopTask struct {
*SKVMGuestInstance
ctx context.Context
timeout int64
startPowerdown *time.Time
startPowerdown time.Time
}
func NewGuestStopTask(guest *SKVMGuestInstance, ctx context.Context, timeout int64) *SGuestStopTask {
@@ -42,7 +42,7 @@ func NewGuestStopTask(guest *SKVMGuestInstance, ctx context.Context, timeout int
SKVMGuestInstance: guest,
ctx: ctx,
timeout: timeout,
startPowerdown: nil,
startPowerdown: time.Time{},
}
}
@@ -57,12 +57,13 @@ func (s *SGuestStopTask) Start() {
func (s *SGuestStopTask) onPowerdownGuest(results string) {
s.ExitCleanup(true)
s.startPowerdown = &time.Now()
s.startPowerdown = time.Now()
s.checkGuestRunning()
}
func (s *SGuestStopTask) checkGuestRunning() {
if !s.IsRunning() || time.Now().Sub(*s.startPowerdown) > (s.timeout*time.Second) {
if !s.IsRunning() ||
time.Now().Sub(s.startPowerdown) > time.Duration(s.timeout)*time.Second {
s.Stop() // force stop
hostutils.TaskComplete(s.ctx, nil)
} else {
@@ -82,13 +83,13 @@ func (s *SGuestStopTask) CheckGuestRunningLater() {
type SGuestSyncConfigTaskExecutor struct {
ctx context.Context
guest *SKVMGuestInstance
tasks IGuestTasks
tasks []IGuestTasks
errors []error
callback func([]error)
}
func NewGuestSyncConfigTaskExecutor(ctx context.Context, guest *SKVMGuestInstance, tasks []IGuestTasks, callback func(error)) *SGuestSyncConfigTaskExecutor {
func NewGuestSyncConfigTaskExecutor(ctx context.Context, guest *SKVMGuestInstance, tasks []IGuestTasks, callback func([]error)) *SGuestSyncConfigTaskExecutor {
return &SGuestSyncConfigTaskExecutor{ctx, guest, tasks, make([]error, 0), callback}
}
@@ -98,7 +99,7 @@ func (t *SGuestSyncConfigTaskExecutor) Start(delay int) {
func (t *SGuestSyncConfigTaskExecutor) runNextTask() {
if len(t.tasks) > 0 {
task := t.tasks[len(t.tasks-1)]
task := t.tasks[len(t.tasks)-1]
t.tasks = t.tasks[:len(t.tasks)-1]
task.Start(t.runNextTaskCallback)
} else {
@@ -130,27 +131,27 @@ type SGuestDiskSyncTask struct {
addDisks []jsonutils.JSONObject
cdrom *string
callback func(error)
callback func(...error)
}
func NewGuestDiskSyncTask(guest *SKVMGuestInstance, delDisks, addDisks []jsonutils.JSONObject, cdrom *string) *SGuestDiskSyncTask {
return &SGuestDiskSyncTask{guest, delDisks, addDisks, cdrom}
return &SGuestDiskSyncTask{guest, delDisks, addDisks, cdrom, nil}
}
func (d *SGuestDiskSyncTask) Start(callback func(error)) {
func (d *SGuestDiskSyncTask) Start(callback func(...error)) {
d.callback = callback
d.syncDisksConf()
}
func (d *SGuestDiskSyncTask) syncDisksConf() {
if len(d.delDisks) > 0 {
disk = d.delDisks[len(d.delDisks)-1]
disk := d.delDisks[len(d.delDisks)-1]
d.delDisks = d.delDisks[:len(d.delDisks)-1]
d.removeDisk(disk)
return
}
if len(d.addDisks) > 0 {
disk = d.addDisks[len(d.addDisks)-1]
disk := d.addDisks[len(d.addDisks)-1]
d.addDisks = d.addDisks[:len(d.addDisks)-1]
d.addDisk(disk)
return
@@ -159,7 +160,7 @@ func (d *SGuestDiskSyncTask) syncDisksConf() {
d.changeCdrom()
return
}
d.callback(nil)
d.callback()
}
func (d *SGuestDiskSyncTask) changeCdrom() {
@@ -170,7 +171,7 @@ func (d *SGuestDiskSyncTask) onGetBlockInfo(results *jsonutils.JSONArray) {
var cdName string
for _, r := range results.Value() {
device, _ := r.GetString("device")
if regexp.MustCompile(`^ide\d+-cd\d+$`, device) {
if regexp.MustCompile(`^ide\d+-cd\d+$`).MatchString(device) {
cdName = device
break
}
@@ -195,7 +196,7 @@ func (d *SGuestDiskSyncTask) OnChangeCdromContentSucc(results string) {
func (d *SGuestDiskSyncTask) removeDisk(disk jsonutils.JSONObject) {
index, _ := disk.Int("index")
devId = fmt.Sprintf("drive_%s", index)
devId := fmt.Sprintf("drive_%d", index)
d.guest.Monitor.DriveDel(devId,
func(results string) { d.onRemoveDriveSucc(devId, results) })
}
@@ -258,7 +259,7 @@ func (d *SGuestDiskSyncTask) onAddDiskSucc(disk jsonutils.JSONObject, results st
}
if diskDirver == DISK_DRIVER_VIRTIO {
params["addr"] = fmt.Sprintf("0x%x", d.guest.GetDiskAddr(diskIndex))
params["addr"] = fmt.Sprintf("0x%x", d.guest.GetDiskAddr(int(diskIndex)))
} else if DISK_DRIVER_IDE == diskDirver {
params["unit"] = diskIndex % 2
}
@@ -289,12 +290,12 @@ func (n *SGuestNetworkSyncTask) Start(callback func(...error)) {
func (n *SGuestNetworkSyncTask) syncNetworkConf() {
if len(n.delNics) > 0 {
nic = n.delNics[len(n.delNics)-1]
nic := n.delNics[len(n.delNics)-1]
n.delNics = n.delNics[:len(n.delNics)-1]
n.removeNic(nic)
return
} else if len(n.addNics) > 0 {
nic = n.addNics[len(n.addNics)-1]
nic := n.addNics[len(n.addNics)-1]
n.addNics = n.addNics[:len(n.addNics)-1]
n.addNic(nic)
return
@@ -311,8 +312,8 @@ func (n *SGuestNetworkSyncTask) addNic(nic jsonutils.JSONObject) {
// pass not implement
}
func NewGuestNetworkSyncTask(guest *SKVMGuestInstance, delNics, addNics jsonutils.JSONObject) *SGuestNetworkSyncTask {
return &SGuestNetworkSyncTask{guest, delNics, addNics, make(error, 0)}
func NewGuestNetworkSyncTask(guest *SKVMGuestInstance, delNics, addNics []jsonutils.JSONObject) *SGuestNetworkSyncTask {
return &SGuestNetworkSyncTask{guest, delNics, addNics, make([]error, 0), nil}
}
/**
@@ -351,10 +352,10 @@ func (s *SGuestLiveMigrateTask) startMigrateStatusCheck(string) {
s.c = make(chan struct{})
for {
select {
case <-c: // on c close
case <-s.c: // on c close
break
case <-time.After(time.Second * 1):
s.Monitor.getMigrateStatus(s.onGetMigrateStatus)
s.Monitor.GetMigrateStatus(s.onGetMigrateStatus)
}
}
}
@@ -362,10 +363,10 @@ func (s *SGuestLiveMigrateTask) startMigrateStatusCheck(string) {
func (s *SGuestLiveMigrateTask) onGetMigrateStatus(status string) {
if status == "completed" {
close(s.c)
hostutils.TaskComplete(ctx, nil)
hostutils.TaskComplete(s.ctx, nil)
} else if status == "failed" {
close(c)
hostutils.TaskFailed(ctx, fmt.Sprintf("Query migrate got status: %s", status))
close(s.c)
hostutils.TaskFailed(s.ctx, fmt.Sprintf("Query migrate got status: %s", status))
}
}
@@ -380,6 +381,13 @@ type SGuestResumeTask struct {
startTime time.Time
}
func NewGuestResumeTask(ctx context.Context, s *SKVMGuestInstance) *SGuestResumeTask {
return &SGuestResumeTask{
SKVMGuestInstance: s,
ctx: ctx,
}
}
func (s *SGuestResumeTask) Start() {
s.startTime = time.Now()
s.confirmRunning()
@@ -409,8 +417,8 @@ func (s *SGuestResumeTask) onConfirmRunning(status string) {
func (s *SGuestResumeTask) taskFailed(reason string) {
log.Infof("Start guest %s failed: %s", s.GetId(), reason)
s.ForceStop()
if len(appctx.AppContextTaskId(ctx)) > 0 {
hostutils.TaskFailed(ctx, reason)
if len(appctx.AppContextTaskId(s.ctx)) > 0 {
hostutils.TaskFailed(s.ctx, reason)
} else {
s.SyncStatus()
}
@@ -426,7 +434,7 @@ func (s *SGuestResumeTask) onGetBlockInfo(results *jsonutils.JSONArray) {
func (s *SGuestResumeTask) resumeGuest() {
s.startTime = time.Now()
s.Monitor.Cont(s.onResumeSucc)
s.Monitor.SimpleCommand("cont", s.onResumeSucc)
}
func (s *SGuestResumeTask) onResumeSucc(res string) {
@@ -435,8 +443,8 @@ func (s *SGuestResumeTask) onResumeSucc(res string) {
func (s *SGuestResumeTask) onStartRunning() {
s.removeStatefile()
if len(appctx.AppContextTaskId(ctx)) > 0 {
hostutils.TaskComplete(ctx, nil)
if len(appctx.AppContextTaskId(s.ctx)) > 0 {
hostutils.TaskComplete(s.ctx, nil)
}
if options.HostOptions.SetVncPassword {
s.SetVncPassword()
@@ -448,13 +456,14 @@ func (s *SGuestResumeTask) onStartRunning() {
if len(disksIdx) > 0 {
timeutils2.AddTimeout(time.Second*5, func() { s.startStreamDisks(disksIdx) })
} else if options.HostOptions.AutoMergeBackingTemplate {
timeutils2.AddTimeout(time.Second*options.HostOptions.AutoMergeDelaySeconds,
timeutils2.AddTimeout(
time.Second*time.Duration(options.HostOptions.AutoMergeDelaySeconds),
func() { s.startStreamDisks(nil) })
}
}
func (s *SGuestResumeTask) startStreamDisks(disksIdx []int) {
s.startTime = nil
s.startTime = time.Time{}
s.CleanStartupTask()
if s.IsMonitorAlive() {
s.StreamDisks(s.ctx, func() { s.onStreamComplete(disksIdx) }, disksIdx)
@@ -500,7 +509,7 @@ type SGuestStreamDisksTask struct {
streamDevs []string
}
func NewGuestStreamDisksTask(ctx context.Context, guest *SKVMGuestInstance, callback func(), disksIdx []int) {
func NewGuestStreamDisksTask(ctx context.Context, guest *SKVMGuestInstance, callback func(), disksIdx []int) *SGuestStreamDisksTask {
return &SGuestStreamDisksTask{
SKVMGuestInstance: guest,
ctx: ctx,
@@ -516,7 +525,7 @@ func (s *SGuestStreamDisksTask) Start() {
func (s *SGuestStreamDisksTask) onInitCheckStreamJobs(jobs int) {
if jobs > 0 {
log.Warningf("GuestStreamDisksTask: duplicate block streaming???")
s.startWaitBlockStream()
s.startWaitBlockStream("")
} else if jobs == 0 {
s.startBlockStreaming()
}
@@ -565,13 +574,13 @@ func (s *SGuestStreamDisksTask) onBlockDrivesSucc(res *jsonutils.JSONArray) {
func (s *SGuestStreamDisksTask) startDoBlockStream() {
if len(s.streamDevs) > 0 {
dev = s.streamDevs[0]
dev := s.streamDevs[0]
s.streamDevs = s.streamDevs[1:]
s.Monitor.BlockStream(dev, s.startWaitBlockStream)
}
}
func (s *SGuestStreamDisksTask) startWaitBlockStream() {
func (s *SGuestStreamDisksTask) startWaitBlockStream(res string) {
if s.c == nil {
s.c = make(chan struct{})
for {
@@ -636,7 +645,7 @@ type SGuestReloadDiskTask struct {
}
func NewGuestReloadDiskTask(
ctx context.Context, s *SKVMGuestInstance, disk *storageman.IDisk,
ctx context.Context, s *SKVMGuestInstance, disk storageman.IDisk,
) *SGuestReloadDiskTask {
return &SGuestReloadDiskTask{
SKVMGuestInstance: s,
@@ -704,14 +713,12 @@ func (s *SGuestReloadDiskTask) onReloadSucc(err string) {
if len(err) > 0 {
log.Errorf("monitor new snapshot blkdev error: %s", err)
}
s.Monitor.SimpleCommand(cont, s.onResumeSucc)
s.Monitor.SimpleCommand("cont", s.onResumeSucc)
}
func (s *SGuestReloadDiskTask) onResumeSucc(results string) {
log.Infof("guest reload disk task resume succ %s", results)
if _, err := hostutils.TaskComplete(ctx, nil); err != nil {
log.Errorln(err)
}
hostutils.TaskComplete(s.ctx, nil)
}
func (s *SGuestReloadDiskTask) taskFailed(reason string) {
@@ -730,7 +737,7 @@ type SGuestDiskSnapshotTask struct {
}
func NewGuestDiskSnapshotTask(
ctx context.Context, s *SKVMGuestInstance, disk *storageman.IDisk, snapshotId string,
ctx context.Context, s *SKVMGuestInstance, disk storageman.IDisk, snapshotId string,
) *SGuestDiskSnapshotTask {
return &SGuestDiskSnapshotTask{
SGuestReloadDiskTask: NewGuestReloadDiskTask(ctx, s, disk),
@@ -769,11 +776,9 @@ func (s *SGuestDiskSnapshotTask) onResumeSucc(res string) {
log.Infof("guest disk snapshot task resume succ %s", res)
snapshotDir := s.disk.GetSnapshotDir()
snapshotLocation := path.Join(snapshotDir, s.snapshotId)
_, err := hostutils.TaskComplete(s.ctx, jsonutils.NewDict(
hostutils.TaskComplete(s.ctx, jsonutils.NewDict(
jsonutils.NewPair("localtion", jsonutils.NewString(snapshotLocation))))
if err != nil {
log.Errorln(err)
}
}
/**
@@ -790,8 +795,8 @@ type SGuestSnapshotDeleteTask struct {
}
func NewGuestSnapshotDeleteTask(
ctx context.Context, s *SKVMGuestInstance, disk *storageman.IDisk,
deleteSnapshot, convertSnapshot string, pendingDelete string,
ctx context.Context, s *SKVMGuestInstance, disk storageman.IDisk,
deleteSnapshot, convertSnapshot string, pendingDelete bool,
) *SGuestSnapshotDeleteTask {
return &SGuestSnapshotDeleteTask{
SGuestReloadDiskTask: NewGuestReloadDiskTask(ctx, s, disk),
@@ -876,9 +881,60 @@ func (s *SGuestSnapshotDeleteTask) onResumeSucc(res string) {
snapshotDir := s.disk.GetSnapshotDir()
exec.Command("rm", "-f", path.Join(snapshotDir, s.deleteSnapshot))
}
_, err := hostutils.TaskComplete(s.ctx,
hostutils.TaskComplete(s.ctx,
jsonutils.NewDict(jsonutils.NewPair("deleted", jsonutils.JSONTrue)))
if err != nil {
log.Errorln(err)
}
/**
* GuestDriveMirrorTask
**/
type SDriveMirrorTask struct {
*SKVMGuestInstance
ctx context.Context
nbdUri string
onSucc func()
syncMode string
index int
}
func NewDriveMirrorTask(
ctx context.Context, s *SKVMGuestInstance, nbdUri, syncMode string, onSucc func(),
) *SDriveMirrorTask {
return &SDriveMirrorTask{
SKVMGuestInstance: s,
ctx: ctx,
nbdUri: nbdUri,
syncMode: syncMode,
onSucc: onSucc,
}
}
func (s *SDriveMirrorTask) Start() {
s.startMirror("")
}
func (s *SDriveMirrorTask) startMirror(res string) {
log.Infof("drive mirror results:%s", res)
if len(res) > 0 {
hostutils.TaskFailed(s.ctx, res)
return
}
disks, _ := s.Desc.GetArray("disks")
if s.index < len(disks) {
if s.index >= 1 { // data disk
s.syncMode = "none"
}
target := fmt.Sprintf("%s:exportname=drive_%d", s.nbdUri, s.index)
s.Monitor.DriveMirror(s.startMirror, fmt.Sprintf("drive_%d", s.index),
target, s.syncMode, true)
s.index += 1
} else {
if s.onSucc != nil {
s.onSucc()
} else {
hostutils.TaskComplete(s.ctx, nil)
}
}
}
+129 -56
View File
@@ -28,6 +28,7 @@ import (
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/util/cgrouputils"
"yunion.io/x/onecloud/pkg/util/fileutils2"
"yunion.io/x/onecloud/pkg/util/netutils2"
"yunion.io/x/onecloud/pkg/util/timeutils2"
"yunion.io/x/onecloud/pkg/util/version"
)
@@ -71,6 +72,14 @@ func (s *SKVMGuestInstance) GetName() string {
return fmt.Sprintf("%s(%s)", name, id)
}
func (s *SKVMGuestInstance) getStateFilePathRootPrefix() string {
return path.Join(s.HomeDir(), STATE_FILE_PREFIX)
}
func (s *SKVMGuestInstance) IsLoaded() bool {
return s.Desc != nil
}
func (s *SKVMGuestInstance) HomeDir() string {
return path.Join(s.manager.ServersPath, s.Id)
}
@@ -200,19 +209,22 @@ func (s *SKVMGuestInstance) asyncScriptStart(ctx context.Context, params interfa
if err = s.saveVncPort(vncPort); err != nil {
goto finally
} else {
data.Set("vnc_port", jsonutils.NewInt(vncPort))
data.Set("vnc_port", jsonutils.NewInt(int64(vncPort)))
}
if err = s.saveScripts(data); err != nil {
goto finally
} else {
isStarted, err = s.scriptStart()
err = s.scriptStart()
if err == nil {
isStarted = true
}
}
finally:
if !isStarted {
log.Errorf("Start VM failed: %s", err)
time.Sleep((1 << (tried - 1)) * time.Seconde)
time.Sleep(time.Duration(1<<uint(tried-1)) * time.Second)
} else {
log.Infof("VM started ...")
}
@@ -225,18 +237,21 @@ func (s *SKVMGuestInstance) asyncScriptStart(ctx context.Context, params interfa
return nil, nil
} else {
log.Infof("Async start server %s failed: %s!!!", s.GetName(), err)
timeutils2.AddTimeout(100*time.Millisecond, s.SyncStatus())
timeutils2.AddTimeout(100*time.Millisecond, s.SyncStatus)
return nil, err
}
}
func (s *SKVMGuestInstance) saveScripts(data *jsonutils.JSONDict) error {
startScript := s.generateStartScript(data)
if err := fileutils2.FilePutContents(s.GetStartScriptPath, startScript, false); err != nil {
startScript, err := s.generateStartScript(data)
if err != nil {
return err
}
if err = fileutils2.FilePutContents(s.GetStartScriptPath(), startScript, false); err != nil {
return err
}
stopScript := s.generateStopScript(data)
return fileutils2.FilePutContents(s.GetStopScriptPath, stopScript, false)
return fileutils2.FilePutContents(s.GetStopScriptPath(), stopScript, false)
}
func (s *SKVMGuestInstance) GetStartScriptPath() string {
@@ -292,19 +307,19 @@ func (s *SKVMGuestInstance) IsMonitorAlive() bool {
return s.Monitor != nil && s.Monitor.IsConnected()
}
func (s *SKVMGuestInstance) ListStateFilePaths() []string {
files, err := ioutil.ReadDir(s.HomeDir())
if err == nil {
var ret = make([]string, 0)
for i := 0; i < len(files); i++ {
if strings.HasPrefix(files[i].Name(), STATE_FILE_PREFIX) {
ret = append(ret, files[i].Name())
}
}
return ret
}
return nil
}
// func (s *SKVMGuestInstance) ListStateFilePaths() []string {
// files, err := ioutil.ReadDir(s.HomeDir())
// if err == nil {
// var ret = make([]string, 0)
// for i := 0; i < len(files); i++ {
// if strings.HasPrefix(files[i].Name(), STATE_FILE_PREFIX) {
// ret = append(ret, files[i].Name())
// }
// }
// return ret
// }
// return nil
// }
func (s *SKVMGuestInstance) StartMonitor(ctx context.Context) {
timeutils2.AddTimeout(100*time.Millisecond, func() { s.delayStartMonitor(ctx) })
@@ -417,10 +432,15 @@ func (s *SKVMGuestInstance) GetVncPort() int {
return -1
}
func (s *SKVMGuestInstance) saveVncPort(port int64) error {
func (s *SKVMGuestInstance) saveVncPort(port int) error {
return fileutils2.FilePutContents(s.GetVncFilePath(), fmt.Sprintf("%d", port), false)
}
func (s *SKVMGuestInstance) DoResumeTask(ctx context.Context) {
s.startupTask = NewGuestResumeTask(ctx, s)
s.startupTask.Start()
}
func (s *SKVMGuestInstance) SyncStatus() {
if s.IsRunning() {
s.Monitor.GetBlockJobs(s.CheckBlockOrRunning)
@@ -447,9 +467,10 @@ func (s *SKVMGuestInstance) CheckBlockOrRunning(jobs int) {
func (s *SKVMGuestInstance) SaveDesc(desc jsonutils.JSONObject) error {
s.Desc = desc.(*jsonutils.JSONDict)
if err := fileutils2.FilePutContents(s.GetDescFilePath(), desc.String()); err != nil {
if err := fileutils2.FilePutContents(s.GetDescFilePath(), desc.String(), false); err != nil {
log.Errorln(err)
}
return nil
}
func (s *SKVMGuestInstance) StartGuest(ctx context.Context, params jsonutils.JSONObject) {
@@ -463,7 +484,7 @@ func (s *SKVMGuestInstance) DeployFs(deployInfo *guestfs.SDeployInfo) (jsonutils
diskId, _ := disks[0].GetString("disk_id")
disk := storageman.GetManager().GetStorageDisk(storageId, diskId)
return disk.DeployGuestFs(disk.GetPath, s.Desc, deployInfo)
return disk.DeployGuestFs(disk.GetPath(), s.Desc, deployInfo)
} else {
return nil, fmt.Errorf("Guest dosen't have disk ??")
}
@@ -514,7 +535,7 @@ func (s *SKVMGuestInstance) ExitCleanup(clearCgroup bool) {
pid := s.GetPid()
if pid > 0 {
// TODO: ClearCgroup
s.ClearCgroup(pid)
// s.ClearCgroup(pid)
}
}
if s.Monitor != nil {
@@ -527,28 +548,33 @@ func (s *SKVMGuestInstance) GetCleanFiles() []string {
return []string{s.GetPidFilePath(), s.GetVncFilePath()}
}
func (s *SKVMGuestInstance) delTmpDisks(ctx context.Context, migrated bool) {
func (s *SKVMGuestInstance) delTmpDisks(ctx context.Context, migrated bool) error {
disks, _ := s.Desc.GetArray("disks")
for _, disk := range disks {
if disk.Contains("path") {
diskPath, _ := disk.GetString("path")
d := storageman.GetManager().GetDiskByPath(diskPath)
if d != nil && d.GetType == storagetypes.STORAGE_LOCAL && migrated {
if d != nil && d.GetType() == storagetypes.STORAGE_LOCAL && migrated {
if err := d.DeleteAllSnapshot(); err != nil {
log.Errorln(err)
return err
}
if err := d.Delete(ctx); err != nil {
if _, err := d.Delete(ctx, nil); err != nil {
log.Errorln(err)
return err
}
}
}
}
return nil
}
func (s *SKVMGuestInstance) Delete(ctx context.Context, migrated bool) error {
// self._del_bw_limit()
// self._del_netmon_nic() ?? 需要开发?
s.delTmpDisks(ctx, migrated)
if err := s.delTmpDisks(ctx, migrated); err != nil {
return err
}
return exec.Command("rm", "-rf", s.HomeDir()).Run()
}
@@ -561,6 +587,15 @@ func (s *SKVMGuestInstance) Stop() bool {
}
}
func (s *SKVMGuestInstance) scriptStart() error {
err := exec.Command("sh", s.GetStartScriptPath()).Run()
if err != nil {
s.scriptStop()
return err
}
return nil
}
func (s *SKVMGuestInstance) scriptStop() bool {
err := exec.Command("sh", s.GetStopScriptPath()).Run()
if err != nil {
@@ -570,9 +605,13 @@ func (s *SKVMGuestInstance) scriptStop() bool {
return true
}
func (s *SKVMGuestInstance) ExecStopTask(ctx context.Context, params interface{}) {
timeout := params.(int64)
func (s *SKVMGuestInstance) ExecStopTask(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
timeout, ok := params.(int64)
if !ok {
return nil, hostutils.ParamsError
}
NewGuestStopTask(s, ctx, timeout).Start()
return nil, nil
}
func (s *SKVMGuestInstance) ExecSuspendTask(ctx context.Context) {
@@ -616,14 +655,14 @@ func (s *SKVMGuestInstance) compareDescDisks(newDesc jsonutils.JSONObject) ([]js
newDisks, _ := newDesc.GetArray("disks")
for _, disk := range newDisks {
driver, _ := disk.GetString("driver")
if utils.IsInStringArray("driver", []string{"virtio", "scsi"}) {
if utils.IsInStringArray(driver, []string{"virtio", "scsi"}) {
addDisks = append(addDisks, disk)
}
}
oldDisks, _ := s.Desc.GetArray("disks")
for _, disk := range oldDisks {
driver, _ := disk.GetString("driver")
if utils.IsInStringArray("driver", []string{"virtio", "scsi"}) {
if utils.IsInStringArray(driver, []string{"virtio", "scsi"}) {
var find = false
for idx, ndisk := range addDisks {
diskIndex, _ := disk.Int("index")
@@ -647,22 +686,23 @@ func (s *SKVMGuestInstance) compareDescCdrom(newDesc jsonutils.JSONObject) *stri
return nil
} else if !s.Desc.Contains("cdrom") && newDesc.Contains("cdrom") {
cdrom, _ := newDesc.GetString("cdrom", "path")
return cdrom
return &cdrom
} else if s.Desc.Contains("cdrom") && !newDesc.Contains("cdrom") {
return ""
var res = ""
return &res
} else {
cdrom, _ := s.Desc.GetString("cdrom", "path")
ncdrom, _ := newDesc.GetString("cdrom", "path")
if cdrom == ncdrom {
return nil
} else {
return ncdrom
return &ncdrom
}
}
}
func (s *SKVMGuestInstance) compareDescNetworks(newDesc jsonutils.JSONObject) ([]jsonutils.JSONObject, []jsonutils.JSONObject) {
var isVaild = func(net jsonutils.JSONObject) bool {
var isValid = func(net jsonutils.JSONObject) bool {
driver, _ := net.GetString("driver")
return driver == "virtio"
}
@@ -679,17 +719,20 @@ func (s *SKVMGuestInstance) compareDescNetworks(newDesc jsonutils.JSONObject) ([
}
var delNics, addNics = []jsonutils.JSONObject{}, []jsonutils.JSONObject{}
for _, n := range newDesc.GetArray("nics") {
nics, _ := newDesc.GetArray("nics")
for _, n := range nics {
if isValid(n) {
addNics = append(addNics, n)
}
}
for _, n := range s.Desc.GetArray("nics") {
nics, _ = newDesc.GetArray("nics")
for _, n := range nics {
if isValid(n) {
idx := findNet(addNics, n)
if idx >= 0 {
addNics = append(addNics[:idx], addNics[idx+1:])
// remove n
addNics = append(addNics[:idx], addNics[idx+1:]...)
} else {
delNics = append(delNics, n)
}
@@ -701,12 +744,12 @@ func (s *SKVMGuestInstance) compareDescNetworks(newDesc jsonutils.JSONObject) ([
// 目测sync_cgroup没有要用到,先不写
func (s *SKVMGuestInstance) SyncConfig(ctx context.Context, desc jsonutils.JSONObject, fwOnly bool) (jsonutils.JSONObject, error) {
var delDisks, addDisks, delNetworks, addNetworks []jsonutils.JSONObject
var cdrom string
var cdrom *string
if !fwOnly {
delDisks, addDisks := s.compareDescDisks(desc)
cdrom := s.compareDescCdrom(desc)
delNetworks, addNetworks := s.compareDescNetworks(desc)
delDisks, addDisks = s.compareDescDisks(desc)
cdrom = s.compareDescCdrom(desc)
delNetworks, addNetworks = s.compareDescNetworks(desc)
}
if err := s.SaveDesc(desc); err != nil {
return nil, err
@@ -732,7 +775,7 @@ func (s *SKVMGuestInstance) SyncConfig(ctx context.Context, desc jsonutils.JSONO
var tasks = []IGuestTasks{}
var callBack = func(errs []error) {
if len(err) > 0 {
if len(errs) == 0 {
hostutils.TaskComplete(ctx, nil)
} else {
var reason string
@@ -746,17 +789,19 @@ func (s *SKVMGuestInstance) SyncConfig(ctx context.Context, desc jsonutils.JSONO
if len(delDisks)+len(addDisks) > 0 || cdrom != nil {
task := NewGuestDiskSyncTask(s, delDisks, addDisks, cdrom)
runTaskNames = append(runTaskNames, jsonutils.NewString("disksync"))
tasks = append(tasks, tasks)
tasks = append(tasks, task)
}
if len(delNetworks)+len(addNetworks) > 0 {
task := NewGuestNetworkSyncTask(s, delNetworks, addNetworks)
runTaskNames = append(runTaskNames, jsonutils.NewString("networksync"))
tasks = append(tasks, tasks)
tasks = append(tasks, task)
}
NewGuestSyncConfigTaskExecutor(ctx, s, tasks, callBack).Start(1)
return jsonutils.NewDict(jsonutils.JSONPair{"task", runTaskNames}), nil
res := jsonutils.NewDict()
res.Set("task", jsonutils.NewArray(runTaskNames...))
return res, nil
}
func (s *SKVMGuestInstance) getApptags() []string {
@@ -783,7 +828,7 @@ func (s *SKVMGuestInstance) getStorageDeviceId() string {
}
func (s *SKVMGuestInstance) SetCgroup() {
s.cgroupId = s.GetPid()
s.cgroupId = fmt.Sprintf("%d", s.GetPid())
s.setCgroupIo()
s.setCgroupCpu()
}
@@ -839,7 +884,7 @@ func (s *SKVMGuestInstance) setCgroupCpu() {
}
func (s *SKVMGuestInstance) CreateFromDesc(desc jsonutils.JSONObject) error {
if !s.PrepareDir() {
if err := s.PrepareDir(); err != nil {
uuid, _ := desc.GetString("uuid")
return fmt.Errorf("Failed to create server dir %s", uuid)
}
@@ -862,7 +907,7 @@ func (s *SKVMGuestInstance) streamDisksComplete(ctx context.Context) {
disks, _ := s.Desc.GetArray("disks")
for i, disk := range disks {
diskpath, _ := disk.GetString("path")
d := storageman.GetManager().GetDiskByPath(diskPath)
d := storageman.GetManager().GetDiskByPath(diskpath)
if d != nil {
d.PostCreateFromImageFuse()
}
@@ -872,7 +917,8 @@ func (s *SKVMGuestInstance) streamDisksComplete(ctx context.Context) {
}
}
s.SaveDesc(s.Desc)
_, err := modules.Servers.PerformAction(ctx, s.GetId(), "stream-disks-complete", nil)
_, err := modules.Servers.PerformAction(hostutils.GetComputeSession(ctx),
s.GetId(), "stream-disks-complete", nil)
if err != nil {
log.Infof("stream disks complete sync error %s", err)
}
@@ -893,8 +939,13 @@ func (s *SKVMGuestInstance) SyncMetadata(meta *jsonutils.JSONDict) {
func (s *SKVMGuestInstance) SetVncPassword() {
password := seclib.RandomPassword(8)
s.VncPassword = password
var callback = func(res string) {
if len(res) > 0 {
log.Errorln("Set vnc password failed: %s", res)
}
}
timeutils2.AddTimeout(time.Second*3,
func() { s.Monitor.SetVncPassword(s.GetVdiProtocol(), password, nil) })
func() { s.Monitor.SetVncPassword(s.GetVdiProtocol(), password, callback) })
}
func (s *SKVMGuestInstance) ListStateFilePaths() []string {
@@ -959,7 +1010,7 @@ func (s *SKVMGuestInstance) ExecReloadDiskTask(ctx context.Context, disk storage
return nil, fmt.Errorf("Guest dosen't support reload disk")
}
} else {
return jsonutils.NewDict(jsonutils.JSONPair{"reopen", jsonutils.JSONTrue}), nil
return jsonutils.NewDict(jsonutils.NewPair("reopen", jsonutils.JSONTrue)), nil
}
}
@@ -990,8 +1041,8 @@ func (s *SKVMGuestInstance) StaticSaveSnapshot(
return nil, err
}
location := path.Join(disk.GetSnapshotDir(), snapshotId)
return jsonutils.NewDict(jsonutils.JSONPair{"localtion",
jsonutils.NewString(snapshotLocation)}), nil
return jsonutils.NewDict(jsonutils.NewPair("localtion",
jsonutils.NewString(location))), nil
}
func (s *SKVMGuestInstance) ExecDeleteSnapshotTask(
@@ -1021,5 +1072,27 @@ func (s *SKVMGuestInstance) deleteStaticSnapshotFile(
log.Errorln(err)
return nil, err
}
return jsonutils.NewDict(jsonutils.JSONPair{"deleted", jsonutils.JSONTrue}), nil
return jsonutils.NewDict(jsonutils.NewPair("deleted", jsonutils.JSONTrue)), nil
}
func (s *SKVMGuestInstance) PrepareMigrate(liveMigrage bool) (*jsonutils.JSONDict, error) {
disksBackFile := jsonutils.NewDict()
disks, _ := s.Desc.GetArray("disks")
for _, disk := range disks {
if disk.Contains("path") {
diskPath, _ := disk.GetString("path")
d := storageman.GetManager().GetDiskByPath(diskPath)
if d.GetType() == storagetypes.STORAGE_LOCAL {
back, err := d.PrepareMigrate(liveMigrage)
if err != nil {
return nil, err
}
if len(back) > 0 {
diskId, _ := disk.GetString("disk_id")
disksBackFile.Set(diskId, jsonutils.NewString(back))
}
}
}
}
return disksBackFile, nil
}
+62 -34
View File
@@ -3,10 +3,9 @@ package guestman
import (
"fmt"
"path"
"strconv"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/hostman/hostinfo"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/hostman/options"
"yunion.io/x/onecloud/pkg/hostman/storageman"
"yunion.io/x/onecloud/pkg/util/fileutils2"
@@ -32,7 +31,7 @@ const (
)
func (s *SKVMGuestInstance) IsKvmSupport() bool {
return hostinfo.Instance().IsKvmSupport()
return guestManger.GetHost().IsKvmSupport()
}
func (s *SKVMGuestInstance) IsVdiSpice() bool {
@@ -40,7 +39,7 @@ func (s *SKVMGuestInstance) IsVdiSpice() bool {
return vdi == "spice"
}
func (s *SKVMGuestInstance) getMonitorDesc(idstr, port, mode string) string {
func (s *SKVMGuestInstance) getMonitorDesc(idstr string, port int, mode string) string {
var cmd = ""
cmd += fmt.Sprintf(" -chardev socket,id=%sdev", idstr)
cmd += fmt.Sprintf(",port=%d", port)
@@ -124,7 +123,6 @@ func (s *SKVMGuestInstance) GetDiskAddr(idx int) int {
if s.IsVdiSpice() {
base += 10
}
idxNum, _ := strconv.Atoi(idx)
return base + idx
}
@@ -142,7 +140,7 @@ func (s *SKVMGuestInstance) GetDiskDeviceModel(driver string) string {
}
}
func (s *SKVMGuestInstance) getDriveDesc(disk jsonutils.JSONObject) string {
func (s *SKVMGuestInstance) getVdiskDesc(disk jsonutils.JSONObject) string {
diskIndex, _ := disk.Int("index")
diskDriver, _ := disk.GetString("driver")
@@ -151,7 +149,7 @@ func (s *SKVMGuestInstance) getDriveDesc(disk jsonutils.JSONObject) string {
cmd += fmt.Sprintf(",drive=drive_%s", diskIndex)
if diskDriver == DISK_DRIVER_VIRTIO {
cmd += fmt.Sprintf(",bus=%s,addr=0x%x", s.GetPciBus(), s.GetDiskAddr(int(diskIndex)))
} else if utils.IsInStringArray(iskDriver, []string{DISK_DRIVER_SCSI, DISK_DRIVER_PVSCSI}) {
} else if utils.IsInStringArray(diskDriver, []string{DISK_DRIVER_SCSI, DISK_DRIVER_PVSCSI}) {
cmd += ",bus=scsi.0"
} else if diskDriver == DISK_DRIVER_IDE {
cmd += fmt.Sprintf(",bus=ide.%d,unit=%d", diskIndex/2, diskIndex%2)
@@ -174,11 +172,31 @@ func (s *SKVMGuestInstance) getNicDownScriptPath(nic jsonutils.JSONObject) strin
return path.Join(s.HomeDir(), fmt.Sprintf("if-down-%s-%s.sh", bridge, ifname))
}
func (s *SKVMGuestInstance) getNetdevDesc(nic jsonutils.JSONObject) string {
func (s *SKVMGuestInstance) generateNicScripts(nic jsonutils.JSONObject) error {
bridge, _ := nic.GetString("bridge")
dev := guestManger.GetHost().GetBridgeDev(bridge)
if dev == nil {
return fmt.Errorf("Can't find bridge %s", bridge)
}
if err := dev.GenerateIfupScripts(s.getNicUpScriptPath(nic), nic); err != nil {
log.Errorln(err)
return err
}
if err := dev.GenerateIfdownScripts(s.getNicDownScriptPath(nic), nic); err != nil {
log.Errorln(err)
return err
}
return nil
}
func (s *SKVMGuestInstance) getNetdevDesc(nic jsonutils.JSONObject) (string, error) {
ifname, _ := nic.GetString("ifname")
driver, _ := nic.GetString("driver")
s.generateNicScripts(nic)
// TODO
if err := s.generateNicScripts(nic); err != nil {
return "", err
}
upscript := s.getNicUpScriptPath(nic)
downscript := s.getNicDownScriptPath(nic)
cmd := " -netdev type=tap"
@@ -189,7 +207,7 @@ func (s *SKVMGuestInstance) getNetdevDesc(nic jsonutils.JSONObject) string {
}
cmd += fmt.Sprintf(",script=%s", upscript)
cmd += fmt.Sprintf(",downscript=%s", downscript)
return cmd
return cmd, nil
}
func (s *SKVMGuestInstance) getNicDeviceModel(name string) string {
@@ -202,7 +220,7 @@ func (s *SKVMGuestInstance) getNicDeviceModel(name string) string {
}
}
func (s *SKVMGuestInstance) getNicAddr(index int) string {
func (s *SKVMGuestInstance) getNicAddr(index int) int {
var diskCnt = 10
disks, _ := s.Desc.GetArray("disks")
if len(disks) > 10 {
@@ -241,7 +259,7 @@ func (s *SKVMGuestInstance) getQgaDesc() string {
return cmd
}
func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) string {
func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) (string, error) {
var (
uuid, _ = s.Desc.GetString("uuid")
mem, _ = s.Desc.Int("mem")
@@ -249,7 +267,8 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) string
name, _ = s.Desc.GetString("name")
nics, _ = s.Desc.GetArray("nics")
disks, _ = s.Desc.GetArray("disks")
osname = s.GetOsname()
osname = s.getOsname()
cmd = ""
)
if osname == OS_NAME_MACOS {
@@ -261,7 +280,7 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) string
qemuVersion := options.HostOptions.DefaultQemuVersion
if data.Contains("qemu_version") {
qemuVersion, _ := data.GetString("qemu_version")
qemuVersion, _ = data.GetString("qemu_version")
}
if qemuVersion == "latest" {
qemuVersion = ""
@@ -288,17 +307,17 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) string
diskPath, _ := disk.GetString("path")
d := storageman.GetManager().GetDiskByPath(diskPath)
if d == nil {
return fmt.Errorf("get disk %s by storage error", diskPath)
return "", fmt.Errorf("get disk %s by storage error", diskPath)
}
diskIndex, _ := disk.Int("index")
cmd += d.GetDiskSetupScripts(diskIndex)
cmd += d.GetDiskSetupScripts(int(diskIndex))
}
cmd += fmt.Sprintf("STATE_FILE=`ls -d %s* | head -n 1`\n", s.getStateFilePathRootPrefix())
var qemuCmd = qemutils.GetQemu(qemuVersion)
cmd += fmt.Sprintf("DEFAULT_QEMU_CMD='%s'\n", qemu_cmd)
cmd += fmt.Sprintf("DEFAULT_QEMU_CMD='%s'\n", qemuCmd)
cmd += `if [ -n "$STATE_FILE" ]; then\n`
cmd += " QEMU_VER=`echo $STATE_FILE" +
` | grep -o '_[[:digit:]]\+\.[[:digit:]]\+.*'` + "`\n"
@@ -330,8 +349,8 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) string
cpuType = "host"
}
if !hostinfo.Instance().IsNestedVirtualization() {
cpu_type += ",kvm=off"
if !guestManger.GetHost().IsNestedVirtualization() {
cpuType += ",kvm=off"
}
// TODO
@@ -340,10 +359,10 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) string
} else {
cmd += " -no-kvm"
accel = "tcg"
cpu_type = "qemu64"
cpuType = "qemu64"
}
cmd += fmt.Sprintf(" -cpu %s", cpu_type)
cmd += fmt.Sprintf(" -cpu %s", cpuType)
// TODO hmp - -
cmd += s.getMonitorDesc("hmqmon", s.GetQmpMonitorPort(int(vncPort)), MODE_READLINE)
@@ -437,15 +456,15 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) string
diskDrivers = append(diskDrivers, driver)
}
if utils.IsInStringArray(DISK_DRIVER_SCSI, disk_drivers) {
if utils.IsInStringArray(DISK_DRIVER_SCSI, diskDrivers) {
cmd += " -device virtio-scsi-pci,id=scsi"
} else if utils.IsInStringArray(DISK_DRIVER_PVSCSI, disk_drivers) {
} else if utils.IsInStringArray(DISK_DRIVER_PVSCSI, diskDrivers) {
cmd += " -device pvscsi,id=scsi"
}
for _, disk := range disks {
format, _ := disk.GetString("format")
cmd += s.getDriveDesc(disk, disk["format"])
cmd += s.getDriveDesc(disk, format)
cmd += s.getVdiskDesc(disk)
}
@@ -479,19 +498,24 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) string
for _, nic := range nics {
if osname == OS_NAME_VMWARE {
nic.(jsonutils.JSONDict).Set("driver", jsonutils.NewString("vmxnet3"))
nic.(*jsonutils.JSONDict).Set("driver", jsonutils.NewString("vmxnet3"))
}
nicCmd, err := s.getNetdevDesc(nic)
if err != nil {
return "", err
} else {
cmd += nicCmd
}
cmd += s.getNetdevDesc(nic)
cmd += s.getVnicDesc(nic)
}
cmd += fmt.Sprintf(" -pidfile %s", S.GetPidFilePath())
cmd += fmt.Sprintf(" -pidfile %s", s.GetPidFilePath())
extraOptions, _ := s.Desc.GetMap("extra_options")
for k, v := range extraOptions {
cmd += fmt.Sprintf(" -%s %s", k, v.String())
}
cmd += self.getQgaDesc()
cmd += s.getQgaDesc()
if fileutils2.Exists("/dev/random") {
cmd += " -object rng-random,filename=/dev/random,id=rng0"
cmd += " -device virtio-rng-pci,rng=rng0,max-bytes=1024,period=1000"
@@ -499,7 +523,7 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) string
if jsonutils.QueryBoolean(data, "need_migrate", false) {
migratePort := s.manager.GetFreePortByBase(LIVE_MIGRATE_PORT_BASE)
s.Desc.Set("live_migrate_dest_port", jsonutils.NewInt(migratePort))
s.Desc.Set("live_migrate_dest_port", jsonutils.NewInt(int64(migratePort)))
cmd += fmt.Sprintf(" -incoming tcp:0:%d", migratePort)
} else if jsonutils.QueryBoolean(s.Desc, "is_slave", false) {
cmd += fmt.Sprintf(" -incoming tcp:0:%d",
@@ -517,7 +541,7 @@ func (s *SKVMGuestInstance) generateStartScript(data *jsonutils.JSONDict) string
cmd += ` $CMD\n`
cmd += `fi\n`
return cmd
return cmd, nil
}
func (s *SKVMGuestInstance) generateStopScript(data *jsonutils.JSONDict) string {
@@ -526,9 +550,9 @@ func (s *SKVMGuestInstance) generateStopScript(data *jsonutils.JSONDict) string
nics, _ = s.Desc.GetArray("nics")
)
cmd = ""
cmd += fmt.Sprintf("VNC_FILE=%s\n", self.GetVncFilePath())
cmd += fmt.Sprintf("PID_FILE=%s\n", self.GetPidFilePath())
cmd := ""
cmd += fmt.Sprintf("VNC_FILE=%s\n", s.GetVncFilePath())
cmd += fmt.Sprintf("PID_FILE=%s\n", s.GetPidFilePath())
cmd += "if [ -f $VNC_FILE ]; then\n"
cmd += " VNC=`cat $VNC_FILE`\n"
@@ -558,8 +582,12 @@ func (s *SKVMGuestInstance) generateStopScript(data *jsonutils.JSONDict) string
}
for _, nic := range nics {
ifname, _ := nic.GetString("ifname")
downscript := self.getNicDownScriptPath(nic)
downscript := s.getNicDownScriptPath(nic)
cmd += fmt.Sprintf("%s %s\n", downscript, ifname)
}
return cmd
}
func (s *SKVMGuestInstance) StartPresendArp() {
// TODO go func
}
@@ -3,13 +3,18 @@ package hostbridge
import (
"fmt"
"net"
"os"
"os/exec"
"strings"
"syscall"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/utils"
"yunion.io/x/onecloud/pkg/hostman/options"
"yunion.io/x/onecloud/pkg/util/bwutils"
"yunion.io/x/onecloud/pkg/util/fileutils2"
"yunion.io/x/onecloud/pkg/util/netutils2"
"yunion.io/x/onecloud/pkg/util/ovsutils"
)
@@ -21,6 +26,10 @@ type IBridgeDriver interface {
Interfaces() []string
GetMac() string
GenerateIfupScripts(scriptPath string, nic jsonutils.JSONObject) error
GenerateIfdownScripts(scriptPath string, nic jsonutils.JSONObject) error
RegisterHostlocalServer(mac, ip string) error
WarmupConfig() error
}
type SBaseBridgeDriver struct {
@@ -255,6 +264,233 @@ func (o *SOVSBridgeDriver) SetupBridgeDev() error {
return nil
}
func (o *SOVSBridgeDriver) GenerateIfdownScripts(scriptPath string, nic jsonutils.JSONObject) error {
script, err := o.getDownScripts(nic)
if err != nil {
log.Errorln(err)
return err
}
return o.saveFileExecutable(scriptPath, script)
}
func (o *SOVSBridgeDriver) GenerateIfupScripts(scriptPath string, nic jsonutils.JSONObject) error {
script, err := o.getUpScripts(nic)
if err != nil {
log.Errorln(err)
return err
}
return o.saveFileExecutable(scriptPath, script)
}
func (o *SOVSBridgeDriver) saveFileExecutable(scriptPath, script string) error {
if err := fileutils2.FilePutContents(scriptPath, script, false); err != nil {
return err
}
return os.Chmod(scriptPath, syscall.S_IRUSR|syscall.S_IWUSR|syscall.S_IXUSR)
}
func (o *SOVSBridgeDriver) getUpScripts(nic jsonutils.JSONObject) (string, error) {
var (
bridge, _ = nic.GetString("bridge")
ifname, _ = nic.GetString("ifname")
ip, _ = nic.GetString("ip")
mac, _ = nic.GetString("mac")
vlan, _ = nic.Int("vlan")
)
s := "#!/bin/bash\n\n"
s += fmt.Sprintf("SWITCH='%s'\n", bridge)
s += fmt.Sprintf("IF='%s'\n", ifname)
s += fmt.Sprintf("IP='%s'\n", ip)
s += fmt.Sprintf("MAC='%s'\n", mac)
s += fmt.Sprintf("VLAN_ID=%d\n", vlan)
limit, burst, err := bwutils.GetOvsBwValues(nic)
if err != nil {
return "", err
}
s += fmt.Sprintf("LIMIT=%d\n", limit)
s += fmt.Sprintf("BURST=%d\n", burst)
bwDownload, err := bwutils.GetDownloadBwValue(nic, options.HostOptions.BwDownloadBandwidth)
if err != nil {
return "", err
}
s += fmt.Sprintf("LIMIT_DOWNLOAD='%dmbit'\n", bwDownload)
if options.HostOptions.TunnelPaddingBytes > 0 {
s += fmt.Sprintf("/sbin/ifconfig $IF mtu %d\n",
1500+options.HostOptions.TunnelPaddingBytes)
}
s += "/sbin/ifconfig $IF 0.0.0.0 up\n"
s += "ovs-vsctl list-ifaces $SWITCH | grep -w $IF > /dev/null 2>&1\n"
s += "if [ $? -eq '0' ]; then\n"
s += " ovs-vsctl del-port $SWITCH $IF\n"
s += "fi\n"
s += "if [ \"$VLAN_ID\" -ne \"1\" ]; then\n"
s += " TAG=\"tag=$VLAN_ID\"\n"
s += "fi\n"
s += "ovs-vsctl add-port $SWITCH $IF $TAG\n"
s += "PORT=$(ovs-ofctl show $SWITCH | grep -w $IF)\n"
s += "PORT=$(echo $PORT | awk 'BEGIN{FS=\"(\"}{print $1}')\n"
s += "OFCTL=$(ovs-vsctl get-controller $SWITCH)\n"
s += `if [ -z "$OFCTL" ]; then\n`
s += " ovs-vsctl set Interface $IF ingress_policing_rate=$LIMIT\n"
s += " ovs-vsctl set Interface $IF ingress_policing_burst=$BURST\n"
for _, r := range o.GetOfRules(nic) {
s += " " + o.AddFlow(r.cond, r.priority, r.actions)
}
s += "fi\n"
s += `if [ $LIMIT_DOWNLOAD != "0mbit" ]; then\n`
s += " tc qdisc del dev $IF root 2>/dev/null\n"
s += " tc qdisc add dev $IF root handle 1: htb default 10\n"
s += " tc class add dev $IF parent 1: classid 1:1 htb " +
"rate $LIMIT_DOWNLOAD ceil $LIMIT_DOWNLOAD\n"
s += " tc class add dev $IF parent 1:1 classid 1:10 htb " +
"rate $LIMIT_DOWNLOAD ceil $LIMIT_DOWNLOAD\n"
s += "fi\n"
return s, nil
}
func (o *SOVSBridgeDriver) getDownScripts(nic jsonutils.JSONObject) (string, error) {
var (
bridge, _ = nic.GetString("bridge")
ifname, _ = nic.GetString("ifname")
ip, _ = nic.GetString("ip")
mac, _ = nic.GetString("mac")
vlan, _ = nic.Int("vlan")
)
s := "#!/bin/bash\n\n"
s += fmt.Sprintf("SWITCH='%s'\n", bridge)
s += fmt.Sprintf("IF='%s'\n", ifname)
s += fmt.Sprintf("IP='%s'\n", ip)
s += fmt.Sprintf("MAC='%s'\n", mac)
s += fmt.Sprintf("VLAN_ID=%d\n", vlan)
s += "PORT=$(ovs-ofctl show $SWITCH | grep -w $IF)\n"
s += "if [ $? -ne '0' ]; then\n"
s += " exit 0\n"
s += "fi\n"
s += "OFCTL=$(ovs-vsctl get-controller $SWITCH)\n"
s += "PORT=$(echo $PORT | awk 'BEGIN{FS=\"(\"}{print $1}')\n"
s += `if [ -z "$OFCTL" ]; then\n`
for _, r := range o.GetOfRules(nic) {
s += " " + o.DelFlow(r.cond)
}
s += "fi\n"
s += "/sbin/ifconfig $IF 0.0.0.0 down\n"
s += "ovs-vsctl -- --if-exists del-port $SWITCH $IF\n"
return s, nil
}
type SRule struct {
priority int
cond string
actions string
}
func (o *SOVSBridgeDriver) AddFlow(cond string, priority int, actions string) string {
s := ""
s += fmt.Sprintf("ovs-ofctl add-flow $SWITCH \"%s", cond)
s += fmt.Sprintf(" priority=%d", priority)
s += fmt.Sprintf(" actions=%s\"\n", actions)
return s
}
func (o *SOVSBridgeDriver) DoAddFlow(cond string, pri int, actions, swt string) error {
return exec.Command("ovs-ofctl", "add-flow", swt,
fmt.Sprintf("%s priority=%d actions=%s", cond, pri, actions)).Run()
}
func (o *SOVSBridgeDriver) DelFlow(cond string) string {
return fmt.Sprintf("ovs-ofctl del-flows $SWITCH \"%s\"\n", cond)
}
func (o *SOVSBridgeDriver) GetOfRules(nic jsonutils.JSONObject) []SRule {
rules := []SRule{}
metadataPort := o.GetMetadataServerPort()
rules = append(rules,
SRule{9000, fmt.Sprintf("table=0 in_port=local tcp nw_dst=$IP tp_src=%d", metadataPort),
"mod_nw_src=169.254.169.254,mod_tp_src:80,output:$PORT"},
SRule{9500, "table=0 in_port=$PORT udp tp_src=68 tp_dst=67", "local"},
SRule{8000, "table=0 in_port=$PORT", "resubmit(,1)"},
)
if vlan, _ := nic.Int("vlan"); vlan != 1 {
rules = append(rules,
SRule{4901, "table=1 dl_dst=$MAC,dl_vlan=$VLAN_ID", "strip_vlan,output:$PORT"})
}
rules = append(rules,
SRule{4900, "table=1 dl_dst=$MAC", "output:$PORT"})
return rules
}
func (o *SOVSBridgeDriver) GetMetadataServerPort() int {
return options.HostOptions.Port
}
func (o *SOVSBridgeDriver) RegisterHostlocalServer(mac, ip string) error {
if !options.HostOptions.EnableOpenflowController {
metadataPort := o.GetMetadataServerPort()
if err := o.DoAddFlow("table=0 ipv6", 20000, "drop", o.bridge.String()); err != nil {
return err
}
if err := o.DoAddFlow("table=0 tcp nw_dst=169.254.169.254 tp_dst=80", 10000,
fmt.Sprintf("mod_dl_dst:%s,mod_nw_dst:%s,mod_tp_dst:%d,local",
mac, ip, metadataPort),
o.bridge.String()); err != nil {
return err
}
log.Infof("OVS: metadata server %s:%d", ip, metadataPort)
k8sCidr := options.HostOptions.K8sClusterCidr
if len(k8sCidr) > 0 {
addr, mask, err := netutils2.PrefixSplit(k8sCidr)
if err != nil {
log.Errorln(err)
return err
}
k8sCidr = fmt.Sprintf("%s/%d", addr, mask)
err = o.DoAddFlow(fmt.Sprintf("table=0 ip,nw_dst=%s", k8sCidr),
10050, fmt.Sprintf("mod_dl_dst:%s,local", mac), o.bridge.String())
if err != nil {
return err
}
err = o.DoAddFlow("table=0", 0, "resubmit(,1)", o.bridge.String())
if err != nil {
return err
}
err = o.DoAddFlow("table=1", 0, "normal", o.bridge.String())
if err != nil {
return err
}
}
}
return nil
}
func (o *SOVSBridgeDriver) ovsSetParams(params map[string]map[string]string) {
for tbl, tblval := range params {
for k, v := range tblval {
exec.Command("ovs-vsctl", "set", tbl, o.bridge.String(),
fmt.Sprintf("%s=%s", k, v)).Run()
}
}
}
func (o *SOVSBridgeDriver) WarmupConfig() error {
// if options.OvsSflowBridges ...
if options.HostOptions.EnableOpenflowController {
// ...
} else {
params := map[string]map[string]string{
"bridge": {
"stp_enable": "false",
"fail_mode": "standalone",
"other-config:flow-eviction-threshold": "2500",
},
}
o.ovsSetParams(params)
}
return nil
}
func CleanOvsBridge() {
ovsutils.CleanAllHiddenPorts()
}
+97 -26
View File
@@ -18,12 +18,14 @@ import (
bare2 "yunion.io/x/onecloud/pkg/baremetal"
"yunion.io/x/onecloud/pkg/cloudcommon/storagetypes"
bare1 "yunion.io/x/onecloud/pkg/compute/baremetal"
"yunion.io/x/onecloud/pkg/hostman/hostinfo/hostbridge"
"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/mcclient/modules"
"yunion.io/x/onecloud/pkg/util/cgrouputils"
"yunion.io/x/onecloud/pkg/util/fileutils2"
"yunion.io/x/onecloud/pkg/util/httputils"
"yunion.io/x/onecloud/pkg/util/netutils2"
"yunion.io/x/onecloud/pkg/util/qemutils"
"yunion.io/x/onecloud/pkg/util/sysutils"
@@ -44,6 +46,8 @@ type SHostInfo struct {
isRegistered bool
IsRegistered chan struct{}
registerCallback func()
saved bool
pinger *SHostPingTask
kvmModuleSupport string
nestStatus string
@@ -66,6 +70,19 @@ type SHostInfo struct {
FullName string
}
func (h *SHostInfo) GetBridgeDev(bridge string) hostbridge.IBridgeDriver {
for _, n := range h.Nics {
if bridge == n.Bridge {
return n.BridgeDev
}
}
return nil
}
func (h *SHostInfo) GetHostId() string {
return h.HostId
}
func (h *SHostInfo) GetZone() string {
return h.Zone
}
@@ -633,6 +650,7 @@ func (h *SHostInfo) GetMasterMac() string {
return n.BridgeDev.GetMac()
}
}
return ""
}
func (h *SHostInfo) GetMatchNic(bridge, iface, mac string) *SNIC {
@@ -646,18 +664,21 @@ func (h *SHostInfo) GetMatchNic(bridge, iface, mac string) *SNIC {
}
func (h *SHostInfo) StartRegister(delay int, callback func()) {
h.registerCallback = callback
timeutils2.AddTimeout(delay*time.Second, h.register)
if callback != nil {
h.registerCallback = callback
}
timeutils2.AddTimeout(time.Duration(delay)*time.Second, h.register)
}
func (h *SHostInfo) register() {
if !h.isRegistered {
h.fetch_access_network_info()
h.fetchAccessNetworkInfo()
}
}
func (h *SHostInfo) onFail() {
h.StartRegister(30)
h.StartRegister(30, nil)
panic("register failed, try 30 seconds later...")
}
@@ -691,13 +712,13 @@ func (h *SHostInfo) getZoneInfo(zoneId string, standalone bool) {
zoneId, params)
if err != nil {
log.Errorln(err)
h.onFail(err)
h.onFail()
}
h.Zone, _ = res.GetString("name")
h.ZoneId, _ = res.GetString("id")
h.Cloudregion = res.GetString("cloudregion")
h.CloudregionId = res.GetString("cloudregion_id")
h.Cloudregion, _ = res.GetString("cloudregion")
h.CloudregionId, _ = res.GetString("cloudregion_id")
if res.Contains("manager_uri") {
h.ZoneManagerUri, _ = res.GetString("manager_uri")
}
@@ -737,11 +758,11 @@ func (h *SHostInfo) setHostname(name string) {
}
}
func (h *SHostInfo) fetchHostname() {
func (h *SHostInfo) fetchHostname() string {
if len(options.HostOptions.Hostname) > 0 {
return options.HostOptions.Hostname
} else {
masterIp = h.GetMasterIp()
masterIp := h.GetMasterIp()
return "host-" + masterIp
}
}
@@ -784,7 +805,7 @@ func (h *SHostInfo) updateHostRecord(hostId string) {
content.Set("mem_size", jsonutils.NewInt(int64(h.Mem.MemInfo.Total)))
content.Set("storage_driver", jsonutils.NewString(bare1.DISK_DRIVER_LINUX))
content.Set("storage_type", jsonutils.NewString(h.sysinfo.StorageType))
content.Set("storage_size", jsonutils.NewInt(storageman.GetManager().GetTotalCapacity()))
content.Set("storage_size", jsonutils.NewInt(int64(storageman.GetManager().GetTotalCapacity())))
// TODO optimize content data struct
content.Set("sys_info", jsonutils.Marshal(h.sysinfo))
@@ -802,7 +823,7 @@ func (h *SHostInfo) updateHostRecord(hostId string) {
body.Set("host", content)
session := hostutils.GetComputeSession(context.Background())
_, res, err := session.JSONVersionRequest("compute",
session.GetEndpointType(), method, url, nil, body, "v2")
session.GetEndpointType(), httputils.THttpMethod(method), url, nil, body, "v2")
if err != nil {
log.Errorln(err)
h.onFail()
@@ -845,7 +866,7 @@ func (h *SHostInfo) getReservedMem() int64 {
}
func (h *SHostInfo) putHostOffline() {
res, err := modules.Hosts.PerformAction(
_, err := modules.Hosts.PerformAction(
hostutils.GetComputeSession(context.Background()), h.HostId, "offline", nil)
if err != nil {
log.Errorln(err)
@@ -881,7 +902,7 @@ func (h *SHostInfo) getNetworkInfo() {
if nic != nil {
wire, _ := hostwire.GetString("wire")
wireId, _ := hostwire.GetString("wire_id")
bandwidth, err := hostwire.GetString("bandwidth")
bandwidth, err := hostwire.Int("bandwidth")
if err != nil {
bandwidth = 1000
}
@@ -921,7 +942,7 @@ func (h *SHostInfo) uploadNetworkInfo() {
h.getStoragecacheInfo()
}
func (h *SHostInfo) doUploadNicInfo(nic *SNIC) (jsonutils.JSONObject, error) {
func (h *SHostInfo) doUploadNicInfo(nic *SNIC) {
log.Infof("Upload NIC br:%s if:%s", nic.Bridge, nic.Inter)
content := jsonutils.NewDict()
content.Set("mac", jsonutils.NewString(nic.BridgeDev.GetMac()))
@@ -968,9 +989,9 @@ func (h *SHostInfo) onUploadNicInfoSucc(nic *SNIC) {
macAddr, _ := res.GetString("mac_addr")
nic = h.GetMatchNic(bridge, iface, macAddr)
if nic != nil {
wire, _ := hostwire.GetString("wire")
wireId, _ := hostwire.GetString("wire_id")
bandwidth, err := hostwire.GetString("bandwidth")
wire, _ := res.GetString("wire")
wireId, _ := res.GetString("wire_id")
bandwidth, err := res.Int("bandwidth")
if err != nil {
bandwidth = 1000
}
@@ -1036,21 +1057,22 @@ func (h *SHostInfo) getStorageInfo() {
func (h *SHostInfo) onGetStorageInfoSucc(hoststorages []jsonutils.JSONObject) {
var detachStorages = []jsonutils.JSONObject{}
storageManager := storageman.GetManager()
for _, hs := range hoststorages {
mountPoint, _ := hs.GetString("mount_point")
storagecacheId, _ := hs.GetString("storagecache_id")
storagetype, _ := hs.GetString("storage_type")
storageManager := storageman.GetManager()
imagecachePath, _ := hs.GetString("imagecache_path")
storageId, _ := hs.GetString("storage_id")
storageName, _ := hs.GetString("storage")
storageConf, _ := hs.Get("storage_conf")
storage := storageManager.NewSharedStorageInstance(mountPoint, storagetype)
if s != nil {
storageManager.Storages = append(storageManager.Storages, s)
if storage != nil {
storageManager.Storages = append(storageManager.Storages, storage)
}
storageManager.InitStorageImageCache(storagetype, storagecacheId, imagecachePath, s)
storageManager.InitSharedStorageImageCache(storagetype,
storagecacheId, imagecachePath, storage)
storage = storageManager.GetStorageByPath(mountPoint)
if storage != nil {
storage.SetStorageInfo(storageId, storageName, storageConf)
@@ -1077,7 +1099,7 @@ func (h *SHostInfo) uploadStorageInfo() {
}
}
// TODO
h.getIsolatedDevices()
// h.getIsolatedDevices()
}
func (h *SHostInfo) onSyncStorageInfoSucc(storage storageman.IStorage, storageInfo jsonutils.JSONObject) {
@@ -1106,8 +1128,9 @@ func (h *SHostInfo) onSucc() {
log.Infof("Host registration process success....")
h.isRegistered = true
// TODO
h.save()
if err := h.save(); err != nil {
panic(err.Error())
}
// TODO
h.StartPinger()
@@ -1121,6 +1144,53 @@ func (h *SHostInfo) onSucc() {
}
}
func (h *SHostInfo) StartPinger() {
h.pinger = NewHostPingTask(options.HostOptions.PingRegionInterval)
go h.pinger.Start()
}
func (h *SHostInfo) save() error {
if h.saved {
return nil
}
h.saved = true
if err := h.registerHostlocalServer(); err != nil {
return err
}
// TODO XXX >>> ???
// file put content
return h.setupBridges()
}
func (h *SHostInfo) setupBridges() error {
for _, n := range h.Nics {
if err := n.BridgeDev.WarmupConfig(); err != nil {
return err
}
}
return nil
}
func (h *SHostInfo) registerHostlocalServer() error {
for _, n := range h.Nics {
mac := h.GetMasterMac()
if len(mac) == 0 {
panic("len mac == 0")
}
ip := h.GetMasterIp()
if len(ip) == 0 {
panic("len ip == 0")
}
err := n.BridgeDev.RegisterHostlocalServer(mac, ip)
if err != nil {
log.Errorln(err)
return err
}
}
return nil
}
func NewHostInfo() (*SHostInfo, error) {
var res = new(SHostInfo)
res.sysinfo = &SSysInfo{}
@@ -1147,9 +1217,10 @@ var hostInfo *SHostInfo
func Instance() *SHostInfo {
if hostInfo == nil {
hostInfo, err := NewHostInfo()
var err error
hostInfo, err = NewHostInfo()
if err != nil {
log.Fatalf(err)
log.Fatalf(err.Error())
}
}
return hostInfo
+13
View File
@@ -0,0 +1,13 @@
package hostinfo
type SHostPingTask struct {
interval int
}
func NewHostPingTask(interval int) *SHostPingTask {
return &SHostPingTask{interval}
}
func (p *SHostPingTask) Start() {
//TODO
}
+6
View File
@@ -11,6 +11,7 @@ import (
"yunion.io/x/onecloud/pkg/appctx"
"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/cloudcommon/workmanager"
"yunion.io/x/onecloud/pkg/hostman/hostinfo/hostbridge"
"yunion.io/x/onecloud/pkg/hostman/options"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
@@ -23,7 +24,12 @@ type IHost interface {
GetHostId() string
GetMediumType() string
IsKvmSupport() bool
IsNestedVirtualization() bool
PutHostOnline() error
GetBridgeDev(bridge string) hostbridge.IBridgeDriver
}
func GetComputeSession(ctx context.Context) *mcclient.ClientSession {
+24
View File
@@ -311,3 +311,27 @@ func (m *HmpMonitor) GetBlockJobs(callback func(jobs int)) {
func (m *HmpMonitor) ReloadDiskBlkdev(device, path string, callback StringCallback) {
m.Query(fmt.Sprintf("reload_disk_snapshot_blkdev -n %s %s", device, path), callback)
}
func (m *HmpMonitor) DriveMirror(callback StringCallback, drive, target, syncMode string, unmap bool) {
cmd := "drive_mirror -n"
if syncMode == "full" {
cmd += " -f"
}
cmd += fmt.Sprintf(" %s %s", drive, target)
m.Query(cmd, callback)
}
func (m *HmpMonitor) BlockStream(drive string, callback StringCallback) {
var (
speed = 30 // MB/s
cmd = fmt.Sprintf("block_stream %s %d", drive, speed)
)
m.Query(cmd, callback)
}
func (m *HmpMonitor) SetVncPassword(proto, password string, callback StringCallback) {
if len(password) > 8 {
password = password[:8]
}
m.Query(fmt.Sprintf("set_password %s %s", proto, password), callback)
}
+5 -1
View File
@@ -14,7 +14,7 @@ type StringCallback func(string)
type Monitor interface {
Connect(host string, port int) error
Dicconnect()
Disconnect()
IsConnected() bool
// The callback function will be called in another goroutine
@@ -33,11 +33,15 @@ type Monitor interface {
DriveAdd(bus string, params map[string]string, callback StringCallback)
DeviceAdd(dev string, params map[string]interface{}, callback StringCallback)
BlockStream(drive string, callback StringCallback)
DriveMirror(callback StringCallback, drive, target, syncMode string, unmap bool)
MigrateSetCapability(capability, state string, callback StringCallback)
Migrate(destStr string, copyIncremental, copyFull bool, callback StringCallback)
GetMigrateStatus(callback StringCallback)
ReloadDiskBlkdev(device, path string, callback StringCallback)
SetVncPassword(proto, password string, callback StringCallback)
}
type MonitorErrorFunc func(error)
+55
View File
@@ -563,3 +563,58 @@ func (m *QmpMonitor) ReloadDiskBlkdev(device, path string, callback StringCallba
)
m.Query(cmd, cb)
}
func (m *QmpMonitor) DriveMirror(callback StringCallback, drive, target, syncMode string, unmap bool) {
var (
cb = func(res *Response) {
callback(m.actionResult(res))
}
cmd = &Command{
Execute: "drive-mirror",
Args: map[string]interface{}{
"device": drive,
"target": target,
"mode": "existing",
"sync": syncMode,
"unmap": unmap,
},
}
)
m.Query(cmd, cb)
}
func (m *QmpMonitor) BlockStream(drive string, callback StringCallback) {
var (
speed = 30 // MB/s
cb = func(res *Response) {
callback(m.actionResult(res))
}
cmd = &Command{
Execute: "block-stream",
Args: map[string]interface{}{
"device": drive,
"speed": speed,
},
}
)
m.Query(cmd, cb)
}
func (m *QmpMonitor) SetVncPassword(proto, password string, callback StringCallback) {
if len(password) > 8 {
password = password[:8]
}
var (
cb = func(res *Response) {
callback(m.actionResult(res))
}
cmd = &Command{
Execute: "set_password",
Args: map[string]interface{}{
"protocol": proto,
"password": password,
},
}
)
m.Query(cmd, cb)
}
+5 -1
View File
@@ -72,7 +72,11 @@ type SHostOptions struct {
DefaultWriteIopsPerCpu int `default:"416" help:"Default write iops per cpu for hard IO limit"`
SetVncPassword bool `default:"true" help:"Auto set vnc password after monitor connected"`
EnableCpuBinding bool `default:"true" help:"Enable cpu binding and rebalance"`
EnableCpuBinding bool `default:"true" help:"Enable cpu binding and rebalance"`
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"`
}
var HostOptions SHostOptions
+7 -7
View File
@@ -23,23 +23,23 @@ type SHostService struct {
}
func (host *SHostService) StartService() {
cloudcommon.ParseOptions(&options.HostOptions, &options.HostOptions.CommonOptions, os.Args, "host.conf")
cloudcommon.ParseOptions(&options.HostOptions, os.Args, "host.conf", "host")
// isolatedman.Init()
hostInstance := hostinfo.Instance()
if err := hostInstance.Init(); err != nil {
log.Fatalf(err)
log.Fatalf(err.Error())
}
if err := storageman.Init(hostInstance); err != nil {
log.Fatalf(err)
log.Fatalf(err.Error())
}
guestman.Init(hostInstance, options.HostOptions.ServersPath)
var c = make(chan struct{})
cloudcommon.InitAuth(&options.HostOptions.Options, func() {
cloudcommon.InitAuth(&options.HostOptions.CommonOptions, func() {
log.Infof("Auth complete!!")
hostInstance.StartRegister(5, guestman.GetGuestManager().Bootstrap)
@@ -48,13 +48,13 @@ func (host *SHostService) StartService() {
close(c)
})
app := cloudcommon.InitApp(&options.HostOptions.Options)
app := cloudcommon.InitApp(&options.HostOptions.CommonOptions, false)
host.TrapSignals(func() { host.quitSignalHandler(app) })
host.InitHandlers(app)
host.initHandlers(app)
<-c // wait host and guest init
cloudcommon.ServeForever(app, &options.HostOptions)
cloudcommon.ServeForever(app, &options.HostOptions.CommonOptions)
}
func (host *SHostService) quitSignalHandler(app *appsrv.Application) {
+1 -6
View File
@@ -271,12 +271,7 @@ func Manager() *SStorageManager {
}
func Init(host hostutils.IHost) error {
var (
err error
zone = host.GetZone()
hostId = host.GetHostId()
)
var err error
storageManager, err = NewStorageManager(host)
return err
}
+3 -4
View File
@@ -12,6 +12,7 @@ import (
)
type IDisk interface {
GetType() string
GetId() string
Probe() error
GetPath() string
@@ -19,24 +20,22 @@ type IDisk interface {
GetDiskDesc() jsonutils.JSONObject
GetDiskSetupScripts(idx int) string
// TODO DeleteAllSnapshot() error
DeleteAllSnapshot() error
Delete(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
Resize(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
PrepareSaveToGlance(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
ResetFromSnapshot(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
CleanupSnapshots(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
PrepareMigrate(liveMigrate bool) (string, error)
CreateFromUrl(context.Context, string) error
// TODO CreateFromSnapshot
CreateFromTemplate(context.Context, string, string, int64) (jsonutils.JSONObject, error)
CreateFromImageFuse(context.Context, string) error
CreateRaw(ctx context.Context, sizeMb int, diskFromat string, fsFormat string,
encryption bool, diskId string, back string) (jsonutils.JSONObject, error)
PostCreateFromImageFuse()
CreateSnapshot(snapshotId string) error
DeleteSnapshot(snapshotId, convertSnapshot string, pendingDelete bool) error
DeployGuestFs(diskPath string, guestDesc *jsonutils.JSONDict,
deployInfo *guestfs.SDeployInfo) (jsonutils.JSONObject, error)
}
+35 -4
View File
@@ -10,6 +10,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/appctx"
"yunion.io/x/onecloud/pkg/cloudcommon/storagetypes"
"yunion.io/x/onecloud/pkg/hostman/hostutils"
"yunion.io/x/onecloud/pkg/hostman/options"
"yunion.io/x/onecloud/pkg/hostman/storageman/remotefile"
@@ -33,6 +34,10 @@ func NewLocalDisk(storage IStorage, id string) *SLocalDisk {
return ret
}
func (d *SBaseDisk) GetType() string {
return storagetypes.STORAGE_LOCAL
}
func (d *SLocalDisk) getPath() string {
return path.Join(d.Storage.GetPath(), d.Id)
}
@@ -385,10 +390,10 @@ func (d *SLocalDisk) DeleteSnapshot(snapshotId, convertSnapshot string, pendingD
}
func (d *SLocalDisk) PrepareSaveToGlance(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
diskInfo, ok := params.(*jsonutils.JSONDict)
if !ok {
return nil, hostutils.ParamsError
}
// diskInfo, ok := params.(*jsonutils.JSONDict)
// if !ok {
// return nil, hostutils.ParamsError
// }
if err := d.Probe(); err != nil {
return nil, err
}
@@ -476,3 +481,29 @@ func (d *SLocalDisk) CleanupSnapshots(ctx context.Context, params interface{}) (
}
return nil, nil
}
func (d *SLocalDisk) DeleteAllSnapshot() error {
snapshotDir := d.GetSnapshotDir()
log.Infof("Delete disk(%s) snapshot dir %s", d.Id, snapshotDir)
return exec.Command("rm", "-rf", snapshotDir).Run()
}
func (d *SLocalDisk) PrepareMigrate(liveMigrate bool) (string, error) {
disk, err := qemuimg.NewQemuImage(d.getPath())
if err != nil {
log.Errorln(err)
return "", err
}
ret, err := disk.WholeChainFormatIs("qcow2")
if err != nil {
log.Errorln(err)
return "", err
}
if liveMigrate && !ret {
return "", fmt.Errorf("Disk format doesn't support live migrate")
}
if disk.IsChained() {
return disk.BackFilePath, nil
}
return "", nil
}
-1
View File
@@ -90,7 +90,6 @@ func (d *SKVMGuestDisk) findPartitions() error {
if err != nil {
return err
}
var partitions []*guestfs.SKVMGuestDiskPartition
for i := 0; i < len(files); i++ {
if files[i].Name() != dev && strings.HasPrefix(files[i].Name(), dev+"p") {
var part = guestfs.NewKVMGuestDiskPartition(path.Join(devpath, files[i].Name()))
+8 -5
View File
@@ -24,7 +24,7 @@ type IImageCacheManger interface {
AcquireImage(ctx context.Context, imageId, zone, srcUrl, format string) IImageCache
ReleaseImage(imageId string)
// LoadCache() error ???
LoadImageCache(imageId string)
}
type SBaseImageCacheManager struct {
@@ -78,12 +78,12 @@ func (c *SLocalImageCacheManager) loadCache() {
files, _ := ioutil.ReadDir(c.cachePath)
for _, f := range files {
if regutils.MatchUUIDExact(f.Name()) {
c.loadImageCache(f.Name())
c.LoadImageCache(f.Name())
}
}
}
func (c *SLocalImageCacheManager) loadImageCache(imageId string) {
func (c *SLocalImageCacheManager) LoadImageCache(imageId string) {
imageCache := NewLocalImageCache(imageId, c)
if imageCache.Load() {
c.cachedImages[imageId] = imageCache
@@ -155,7 +155,10 @@ func (c *SLocalImageCacheManager) PrefetchImageCache(ctx context.Context, data i
res.Set("image_id", jsonutils.NewString(imageId))
res.Set("path", jsonutils.NewString(imgCache.GetPath()))
var name, size = "", 0
var (
name string
size int64
)
if desc := imgCache.GetDesc(); desc != nil {
name = desc.Name
size = desc.Size
@@ -175,7 +178,6 @@ func (c *SLocalImageCacheManager) PrefetchImageCache(ctx context.Context, data i
} else {
return nil, fmt.Errorf("Failed to fetch image %s", imageId)
}
}
// TODO: AgentImageCacheManager
@@ -195,4 +197,5 @@ type SRbdImageCacheManager struct {
func NewRbdImageCacheManager() *SRbdImageCacheManager {
// TODO
return nil
}
+5 -6
View File
@@ -3,7 +3,6 @@ package storageman
import (
"context"
"fmt"
"path"
"sync"
"syscall"
@@ -22,7 +21,7 @@ type IStorage interface {
GetZone() string
SetStorageInfo(storageId, storageName string, conf jsonutils.JSONObject)
SyncStorageInfo()
SyncStorageInfo() (jsonutils.JSONObject, error)
StorageType() string
SetPath(string)
@@ -163,11 +162,11 @@ func (s *SBaseStorage) CreateDiskByDiskinfo(ctx context.Context, params interfac
switch {
case createParams.DiskInfo.Contains("snapshot"):
return s.CreateDiskFromSnpashot(ctx, disk, createParams) // TODO
return s.CreateDiskFromSnpashot(ctx, disk, createParams)
case createParams.DiskInfo.Contains("image_id"):
return s.CreateDiskFromTemplate(ctx, disk, createParams) // TODO
return s.CreateDiskFromTemplate(ctx, disk, createParams)
case createParams.DiskInfo.Contains("size"):
return s.CreateRawDisk(ctx, disk, createParams) // TODO
return s.CreateRawDisk(ctx, disk, createParams)
default:
return nil, fmt.Errorf("Not fount")
}
@@ -194,7 +193,7 @@ func (s *SBaseStorage) CreateDiskFromTemplate(ctx context.Context, disk IDisk, c
func (s *SBaseStorage) CreateDiskFromSnpashot(ctx context.Context, disk IDisk, createParams *SDiskCreateByDiskinfo) (jsonutils.JSONObject, error) {
var (
diskPath = path.Join(s.Path, createParams.DiskId)
// diskPath = path.Join(s.Path, createParams.DiskId)
snapshotUrl, _ = createParams.DiskInfo.GetString("snapshot_url")
transferProtocol, _ = createParams.DiskInfo.GetString("url")
)
+4 -4
View File
@@ -32,9 +32,9 @@ func AddStorageHandler(prefix string, app *appsrv.Application) {
auth.Authenticate(storageActions))
// TODO
app.AddHandler("POST",
fmt.Sprintf("%s/%s/<storageId>/delete-snapshots", prefix, keyWords),
auth.Authenticate(storageDeleteSnapshots))
// app.AddHandler("POST",
// fmt.Sprintf("%s/%s/<storageId>/delete-snapshots", prefix, keyWords),
// auth.Authenticate(storageDeleteSnapshots))
}
}
@@ -42,7 +42,7 @@ func storageActions(ctx context.Context, w http.ResponseWriter, r *http.Request)
params, _, body := appsrv.FetchEnv(ctx, w, r)
var action = params["<action>"]
if f, ok := storageActionFunc[action]; !ok {
if f, ok := storageActionFuncs[action]; !ok {
hostutils.Response(ctx, w, httperrors.NewNotFoundError("Not found"))
} else {
res, err := f(ctx, body)
+5 -5
View File
@@ -54,10 +54,10 @@ func (s *SLocalStorage) GetSnapshotDir() string {
return path.Join(s.Path, _SNAPSHOT_PATH_)
}
func (s *SLocalStorage) SyncStorageInfo() {
func (s *SLocalStorage) SyncStorageInfo() (jsonutils.JSONObject, error) {
content := jsonutils.NewDict()
content.Set("name", jsonutils.NewString(s.StorageName))
content.Set("capacity", jsonutils.NewInt(s.GetAvailSizeMb()))
content.Set("capacity", jsonutils.NewInt(int64(s.GetAvailSizeMb())))
content.Set("storage_type", jsonutils.NewString(s.StorageType()))
content.Set("medium_type", jsonutils.NewString(s.GetMediumType()))
content.Set("zone", jsonutils.NewString(s.GetZone()))
@@ -172,7 +172,7 @@ func (s *SLocalStorage) SaveToGlance(ctx context.Context, params interface{}) (j
if err := s.saveToGlance(ctx, imageId, imagePath, compress, format); err != nil {
log.Errorf("Save to glance failed: %s", err)
s.onSaveToGlanceFailed(ctx, imageId, imagePath, compress, format)
s.onSaveToGlanceFailed(ctx, imageId)
}
imagecacheManager := s.Manager.LocalStorageImagecacheManager
@@ -209,9 +209,9 @@ func (s *SLocalStorage) saveToGlance(ctx context.Context, imageId, imagePath str
defer kvmDisk.Umount(root)
osInfo = root.GetOs()
relInfo = root.GetReleaseInfo()
relInfo = root.GetReleaseInfo(root.GetPartition())
if compress {
if err := root.PrepareFsForTemplate(); err != nil {
if err := root.PrepareFsForTemplate(root.GetPartition()); err != nil {
log.Errorln(err)
return err
}
+67
View File
@@ -0,0 +1,67 @@
package bwutils
import (
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/util/netutils"
)
func GetBwValue(nicDesc jsonutils.JSONObject) int {
bw, err := nicDesc.Int("bw")
if err != nil {
ip, err := nicDesc.GetString("ip")
if err != nil {
bw = 1
} else {
ipv4, err := netutils.NewIPV4Addr(ip)
if err == nil && netutils.IsExitAddress(ipv4) {
bw = 1
} else {
bw = 10000
}
}
}
return int(bw)
}
func GetDownloadBwValue(nicDesc jsonutils.JSONObject, bwDownloadBandwidth int) (int, error) {
ip, _ := nicDesc.GetString("ip")
ifname, _ := nicDesc.GetString("ifname")
if len(ip) > 0 {
ipv4, err := netutils.NewIPV4Addr(ip)
if err != nil {
return 0, err
}
if netutils.IsExitAddress(ipv4) && len(ifname) > 0 && bwDownloadBandwidth > 0 {
bw := GetBwValue(nicDesc)
if bw > bwDownloadBandwidth {
return bw, nil
} else {
return bwDownloadBandwidth, nil
}
}
}
return 0, nil
}
func GetOvsBwValues(nicDesc jsonutils.JSONObject) (int, int, error) {
var bwOvs int
bw := GetBwValue(nicDesc)
ip, err := nicDesc.GetString("ip")
if err == nil {
ipv4, err := netutils.NewIPV4Addr(ip)
if err != nil {
return 0, 0, err
}
if netutils.IsExitAddress(ipv4) {
bwOvs = 1000
if bwOvs > bw*15 {
bwOvs = bw * 15
}
} else {
bwOvs = bw
}
} else {
bwOvs = bw
}
return bwOvs * 1000, bwOvs * 2000, nil
}
+1
View File
@@ -0,0 +1 @@
package cgrouputils
+77
View File
@@ -1,6 +1,7 @@
package netutils2
import (
"bytes"
"fmt"
"net"
"os/exec"
@@ -8,10 +9,12 @@ import (
"regexp"
"strconv"
"strings"
"unicode"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/util/netutils"
"yunion.io/x/pkg/util/regutils"
"yunion.io/x/onecloud/pkg/cloudcommon/types"
"yunion.io/x/onecloud/pkg/util/regutils2"
@@ -303,3 +306,77 @@ func (n *SNetInterface) GetSlaveAddresses() [][]string {
}
return slaves
}
func FormatMac(macStr string) string {
var ret = []byte{}
for i := 0; i < len(macStr); i++ {
if bytes.IndexByte([]byte("0123456789abcdef"), macStr[i]) >= 0 {
ret = append(ret, macStr[i])
} else if bytes.IndexByte([]byte("ABCDEF"), macStr[i]) >= 0 {
ret = append(ret, byte(unicode.ToLower(rune(macStr[i]))))
}
}
if len(ret) == 12 {
var res string
for i := 0; i < 12; i += 2 {
res += string(ret[i:i+2]) + ":"
}
return res[:len(res)-1]
}
return ""
}
func MacEqual(mac1, mac2 string) bool {
mac1 = FormatMac(mac1)
mac2 = FormatMac(mac2)
if len(mac1) > 0 && len(mac2) > 0 && mac1 == mac2 {
return true
}
return false
}
func netmask2len(mask string) int {
masks := []string{"0", "128", "192", "224", "240", "248", "252", "254", "255"}
for i := 0; i < len(masks); i++ {
if masks[i] == mask {
return i
}
}
return -1
}
func Netmask2Len(mask string) int {
data := strings.Split(mask, ".")
mlen := 0
for _, d := range data {
if d != "0" {
nle := netmask2len(d)
if nle < 0 {
return -1
}
mlen += nle
}
}
return mlen
}
func PrefixSplit(pref string) (string, int, error) {
slash := strings.Index(pref, "/")
var intMask int
var err error
if slash > 0 {
ip := pref[:slash]
mask := pref[slash+1:]
if regutils.MatchIPAddr(ip) {
intMask = Netmask2Len(mask)
} else {
intMask, err = strconv.Atoi(mask)
if err != nil {
return "", 0, err
}
}
return ip, intMask, nil
} else {
return pref, 32, nil
}
}
+34
View File
@@ -124,3 +124,37 @@ func TestNetBytes2Mask(t *testing.T) {
})
}
}
func TestFormatMac(t *testing.T) {
type args struct {
macStr string
}
tests := []struct {
name string
args args
want string
}{
{
name: "test-format-mac-1",
args: args{"FFFFFFFFFFFF"},
want: "ff:ff:ff:ff:ff:ff",
},
{
name: "test-format-mac-2",
args: args{"FFFFFFFFFF"},
want: "",
},
{
name: "test-format-mac-3",
args: args{"FFDDEECCBBAA"},
want: "ff:dd:ee:cc:bb:aa",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := FormatMac(tt.args.macStr); got != tt.want {
t.Errorf("FormatMac() = %v, want %v", got, tt.want)
}
})
}
}
+14
View File
@@ -466,3 +466,17 @@ func (img *SQemuImage) Fallocate() error {
func (img *SQemuImage) String() string {
return fmt.Sprintf("Qemu %s %d(%d) %s", img.Format, img.GetSizeMB(), img.GetActualSizeMB(), img.Path)
}
func (img *SQemuImage) WholeChainFormatIs(format string) (bool, error) {
if img.Format.String() != format {
return false, nil
}
if len(img.BackFilePath) > 0 {
backImg, err := NewQemuImage(img.BackFilePath)
if err != nil {
return false, err
}
return backImg.WholeChainFormatIs(format)
}
return true, nil
}