mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 02:37:24 +08:00
host complie success
This commit is contained in:
@@ -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,
|
||||
}
|
||||
|
||||
@@ -11,7 +11,8 @@ type SBaseParms struct {
|
||||
}
|
||||
|
||||
type SGuestDeploy struct {
|
||||
SGuestBaseParms
|
||||
Sid string
|
||||
Body jsonutils.JSONObject
|
||||
IsInit bool
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package hostinfo
|
||||
|
||||
type SHostPingTask struct {
|
||||
interval int
|
||||
}
|
||||
|
||||
func NewHostPingTask(interval int) *SHostPingTask {
|
||||
return &SHostPingTask{interval}
|
||||
}
|
||||
|
||||
func (p *SHostPingTask) Start() {
|
||||
//TODO
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()))
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
package cgrouputils
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user