mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 02:37:24 +08:00
Merge pull request #1082 in YUNIONIO/onecloud from ~WANYAOQI/onecloud:feature/wyq/host-server-v2 to release/2.6.0
* commit '91f109977f65a9b6419975948ff2dd90fb61d649': fix backup server add backup delete status fix create bakcup server and some bugs bug fix
This commit is contained in:
Generated
+2
-2
@@ -1730,11 +1730,11 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:cec4892868ae1c9fec0d2cace79d4c43e620345cc3c070d004dec09caf197208"
|
||||
digest = "1:6a0bb09937441c871c34278e62ea9c80320a6b9894d63261f5c4246c07aeb510"
|
||||
name = "yunion.io/x/structarg"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "f39549642b91f03f0b46403f9856d4750e3e59eb"
|
||||
revision = "f370514c4558e64e798bd83abaff263dabef9f3a"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
|
||||
@@ -340,9 +340,11 @@ func (self *SKVMGuestDriver) RequestRebuildRootDisk(ctx context.Context, guest *
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestSyncToBackup(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
|
||||
body := jsonutils.NewDict()
|
||||
body.Set("backup_nbd_server_uri", jsonutils.NewString(guest.GetMetadata("backup_nbd_server_uri", task.GetUserCred())))
|
||||
host := guest.GetHost()
|
||||
desc := guest.GetDriver().GetJsonDescAtHost(ctx, task.GetUserCred(), guest, host)
|
||||
body := jsonutils.NewDict()
|
||||
body.Add(desc, "desc")
|
||||
body.Set("backup_nbd_server_uri", jsonutils.NewString(guest.GetMetadata("backup_nbd_server_uri", task.GetUserCred())))
|
||||
url := fmt.Sprintf("%s/servers/%s/drive-mirror", host.ManagerUri, guest.Id)
|
||||
header := self.getTaskRequestHeader(task)
|
||||
_, _, err := httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "POST", url, header, body, false)
|
||||
|
||||
@@ -432,10 +432,10 @@ func (self *SGuest) PerformAttachdisk(ctx context.Context, userCred mcclient.Tok
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SGuest) StartSyncTask(ctx context.Context, userCred mcclient.TokenCredential, fw_only bool, parentTaskId string) error {
|
||||
func (self *SGuest) StartSyncTask(ctx context.Context, userCred mcclient.TokenCredential, fwOnly bool, parentTaskId string) error {
|
||||
|
||||
data := jsonutils.NewDict()
|
||||
if fw_only {
|
||||
if fwOnly {
|
||||
data.Add(jsonutils.JSONTrue, "fw_only")
|
||||
} else if err := self.SetStatus(userCred, VM_SYNC_CONFIG, ""); err != nil {
|
||||
log.Errorf(err.Error())
|
||||
@@ -2250,7 +2250,7 @@ func (self *SGuest) AllowPerformSwitchToBackup(ctx context.Context, userCred mcc
|
||||
}
|
||||
|
||||
func (self *SGuest) PerformSwitchToBackup(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
if self.Status == VM_BLOCK_STREAM {
|
||||
if !utils.IsInStringArray(self.Status, []string{VM_READY, VM_RUNNING}) {
|
||||
return nil, httperrors.NewBadRequestError("Cannot swith to backup when guest in status %s", self.Status)
|
||||
}
|
||||
if len(self.BackupHostId) == 0 {
|
||||
@@ -2370,6 +2370,9 @@ func (self *SGuest) PerformDeleteBackup(ctx context.Context, userCred mcclient.T
|
||||
taskData := jsonutils.NewDict()
|
||||
taskData.Set("pruge", jsonutils.NewBool(jsonutils.QueryBoolean(data, "purge", false)))
|
||||
taskData.Set("host_id", jsonutils.NewString(self.BackupHostId))
|
||||
taskData.Set("failed_status", jsonutils.NewString(VM_BACKUP_DELETE_FAILED))
|
||||
|
||||
self.SetStatus(userCred, VM_DELETING_BACKUP, "delete backup server")
|
||||
if task, err := taskman.TaskManager.NewTask(
|
||||
ctx, "GuestDeleteOnHostTask", self, userCred, taskData, "", "", nil); err != nil {
|
||||
log.Errorf(err.Error())
|
||||
|
||||
@@ -64,6 +64,8 @@ const (
|
||||
VM_BACKUP_CREATE_FAILED = "backup_create_fail"
|
||||
VM_DEPLOYING_BACKUP = "deploying_backup"
|
||||
VM_DEPLOYING_BACKUP_FAILED = "deploging_backup_fail"
|
||||
VM_DELETING_BACKUP = "deleting_backup"
|
||||
VM_BACKUP_DELETE_FAILED = "backup_delete_fail"
|
||||
|
||||
VM_ATTACH_DISK_FAILED = "attach_disk_fail"
|
||||
VM_DETACH_DISK_FAILED = "detach_disk_fail"
|
||||
|
||||
+23
-8
@@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
@@ -18,23 +20,23 @@ type GuestDeleteOnHostTask struct {
|
||||
}
|
||||
|
||||
func (self *GuestDeleteOnHostTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
guest := obj.(*models.SGuest)
|
||||
hostId, err := self.Params.GetString("host_id")
|
||||
if err != nil {
|
||||
self.SetStageFailed(ctx, "Missing param host id")
|
||||
self.OnFail(ctx, guest, "Missing param host id")
|
||||
return
|
||||
}
|
||||
host := models.HostManager.FetchHostById(hostId)
|
||||
if host == nil {
|
||||
self.SetStageFailed(ctx, "Host is nil")
|
||||
self.OnFail(ctx, guest, "Host is nil")
|
||||
return
|
||||
}
|
||||
guest := obj.(*models.SGuest)
|
||||
|
||||
self.SetStage("OnStopGuest", nil)
|
||||
self.Params.Set("is_force", jsonutils.JSONTrue)
|
||||
if err := guest.GetDriver().RequestStopOnHost(ctx, guest, host, self); err != nil {
|
||||
self.SetStageFailed(ctx, err.Error())
|
||||
return
|
||||
log.Errorf("RequestStopGuestForDelete fail %s", err)
|
||||
self.OnStopGuest(ctx, guest, nil)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +52,7 @@ func (self *GuestDeleteOnHostTask) OnStopGuest(ctx context.Context, guest *model
|
||||
storage := models.StorageManager.FetchStorageById(disk.BackupStorageId)
|
||||
if storage != nil && !isPurge {
|
||||
if err := host.GetHostDriver().RequestDeallocateBackupDiskOnHost(ctx, host, storage, disk, self); err != nil {
|
||||
self.SetStageFailed(ctx, err.Error())
|
||||
self.OnFail(ctx, guest, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -59,7 +61,7 @@ func (self *GuestDeleteOnHostTask) OnStopGuest(ctx context.Context, guest *model
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
self.SetStageFailed(ctx, err.Error())
|
||||
self.OnFail(ctx, guest, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -79,9 +81,22 @@ func (self *GuestDeleteOnHostTask) OnUnDeployGuest(ctx context.Context, guest *m
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
self.SetStageFailed(ctx, err.Error())
|
||||
self.OnFail(ctx, guest, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
self.SetStage("OnSync", nil)
|
||||
guest.StartSyncTask(ctx, self.UserCred, false, self.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *GuestDeleteOnHostTask) OnSync(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
func (self *GuestDeleteOnHostTask) OnFail(ctx context.Context, guest *models.SGuest, reason string) {
|
||||
failedStatus, _ := self.Params.GetString("failed_status")
|
||||
if len(failedStatus) > 0 {
|
||||
guest.SetStatus(self.UserCred, failedStatus, reason)
|
||||
}
|
||||
self.SetStageFailed(ctx, reason)
|
||||
}
|
||||
@@ -36,7 +36,7 @@ func (self *GuestSyncConfTask) OnInit(ctx context.Context, obj db.IStandaloneMod
|
||||
|
||||
func (self *GuestSyncConfTask) OnSyncComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
guest := obj.(*models.SGuest)
|
||||
if fw_only, _ := self.GetParams().Bool("fw_only"); fw_only {
|
||||
if fwOnly, _ := self.GetParams().Bool("fw_only"); fwOnly {
|
||||
db.OpsLog.LogEvent(guest, db.ACT_SYNC_CONF, nil, self.UserCred)
|
||||
self.SetStageComplete(ctx, guest.GetShortDesc(ctx))
|
||||
} else if data.Contains("task") {
|
||||
|
||||
@@ -161,9 +161,6 @@ func guestMonitor(ctx context.Context, sid string, body jsonutils.JSONObject) (i
|
||||
return nil, err
|
||||
} else {
|
||||
var res = <-c
|
||||
if len(res) > 1 {
|
||||
res = res[1 : len(res)-1]
|
||||
}
|
||||
lines := strings.Split(res, "\\r\\n")
|
||||
|
||||
return strDict{"results": strings.Join(lines, "\n")}, nil
|
||||
@@ -314,8 +311,12 @@ func guestDriveMirror(ctx context.Context, sid string, body jsonutils.JSONObject
|
||||
if err != nil {
|
||||
return nil, httperrors.NewMissingParameterError("backup_nbd_server_uri")
|
||||
}
|
||||
desc, err := body.Get("desc")
|
||||
if err != nil {
|
||||
return nil, httperrors.NewMissingParameterError("desc")
|
||||
}
|
||||
hostutils.DelayTaskWithoutReqctx(ctx, guestman.GetGuestManager().StartDriveMirror,
|
||||
&guestman.SDriverMirror{sid, backupNbdServerUri})
|
||||
&guestman.SDriverMirror{sid, backupNbdServerUri, desc})
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ type SLiveMigrate struct {
|
||||
type SDriverMirror struct {
|
||||
Sid string
|
||||
NbdServerUri string
|
||||
Desc jsonutils.JSONObject
|
||||
}
|
||||
|
||||
type SReloadDisk struct {
|
||||
|
||||
@@ -74,10 +74,9 @@ func (m *SGuestManager) VerifyExistingGuests(pendingDelete bool) {
|
||||
params.Set("limit", jsonutils.NewInt(0))
|
||||
params.Set("admin", jsonutils.JSONTrue)
|
||||
params.Set("system", jsonutils.JSONTrue)
|
||||
params.Set("host", jsonutils.NewString(m.host.GetHostId()))
|
||||
params.Set("pending_delete", jsonutils.NewBool(pendingDelete))
|
||||
params.Set("get_backup_guests_on_host", jsonutils.JSONTrue)
|
||||
params.Set("filter.0", jsonutils.NewString(
|
||||
fmt.Sprintf("host_id.equals(%s)", m.host.GetHostId())))
|
||||
if len(m.CandidateServers) > 0 {
|
||||
keys := make([]string, len(m.CandidateServers))
|
||||
var index = 0
|
||||
@@ -314,7 +313,7 @@ func (m *SGuestManager) CpusetBalance(ctx context.Context, params interface{}) (
|
||||
|
||||
func (m *SGuestManager) Status(sid string) string {
|
||||
if guest, ok := m.Servers[sid]; ok {
|
||||
if guest.IsMaster() && !guest.IsMirrorJobSucc() {
|
||||
if guest.Monitor != nil && guest.IsMaster() && !guest.IsMirrorJobSucc() {
|
||||
return "block_stream"
|
||||
}
|
||||
if guest.IsRunning() {
|
||||
@@ -643,6 +642,9 @@ func (m *SGuestManager) StartDriveMirror(ctx context.Context, params interface{}
|
||||
return nil, hostutils.ParamsError
|
||||
}
|
||||
guest := guestManger.Servers[mirrorParams.Sid]
|
||||
if err := guest.SaveDesc(mirrorParams.Desc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
task := NewDriveMirrorTask(ctx, guest, mirrorParams.NbdServerUri, "top", nil)
|
||||
task.Start()
|
||||
return nil, nil
|
||||
|
||||
@@ -452,7 +452,7 @@ func (s *SGuestResumeTask) onStartRunning() {
|
||||
if options.HostOptions.SetVncPassword {
|
||||
s.SetVncPassword()
|
||||
}
|
||||
s.syncMetadata()
|
||||
s.SyncMetadataInfo()
|
||||
s.SyncStatus()
|
||||
timeutils2.AddTimeout(time.Second*5, s.SetCgroup)
|
||||
disksIdx := s.GetNeedMergeBackingFileDiskIndexs()
|
||||
@@ -481,18 +481,6 @@ func (s *SGuestResumeTask) onStreamComplete(disksIdx []int) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SGuestResumeTask) syncMetadata() {
|
||||
meta := jsonutils.NewDict()
|
||||
meta.Set("__qemu_version", jsonutils.NewString(s.GetQemuVersionStr()))
|
||||
meta.Set("__vnc_port", jsonutils.NewInt(int64(s.GetVncPort())))
|
||||
|
||||
if len(s.VncPassword) > 0 {
|
||||
meta.Set("__vnc_password", jsonutils.NewString(s.VncPassword))
|
||||
}
|
||||
|
||||
s.SyncMetadata(meta)
|
||||
}
|
||||
|
||||
func (s *SGuestResumeTask) removeStatefile() {
|
||||
go s.CleanStatefiles()
|
||||
}
|
||||
@@ -522,7 +510,7 @@ func NewGuestStreamDisksTask(ctx context.Context, guest *SKVMGuestInstance, call
|
||||
}
|
||||
|
||||
func (s *SGuestStreamDisksTask) Start() {
|
||||
s.Monitor.GetBlockJobs(s.onInitCheckStreamJobs)
|
||||
s.Monitor.GetBlockJobCounts(s.onInitCheckStreamJobs)
|
||||
}
|
||||
|
||||
func (s *SGuestStreamDisksTask) onInitCheckStreamJobs(jobs int) {
|
||||
@@ -592,7 +580,7 @@ func (s *SGuestStreamDisksTask) startWaitBlockStream(res string) {
|
||||
s.c = nil
|
||||
return
|
||||
case <-time.After(time.Second * 1):
|
||||
s.Monitor.GetBlockJobs(s.checkStreamJobs)
|
||||
s.Monitor.GetBlockJobCounts(s.checkStreamJobs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ func (s *SKVMGuestInstance) delayStartMonitor(ctx context.Context) {
|
||||
}
|
||||
|
||||
func (s *SKVMGuestInstance) onReceiveQMPEvent(event *monitor.Event) {
|
||||
if event.Event == "BLOCK_JOB_READY" && s.IsMaster() {
|
||||
if event.Event == `"BLOCK_JOB_READY"` && s.IsMaster() {
|
||||
if itype, ok := event.Data["type"]; ok {
|
||||
stype, _ := itype.(string)
|
||||
if stype == "mirror" {
|
||||
@@ -355,13 +355,11 @@ func (s *SKVMGuestInstance) onReceiveQMPEvent(event *monitor.Event) {
|
||||
s.mirrorJobSuccCount = new(int)
|
||||
*s.mirrorJobSuccCount = 1
|
||||
}
|
||||
if *s.mirrorJobSuccCount == s.DiskCount() {
|
||||
if *s.mirrorJobSuccCount >= s.DiskCount() {
|
||||
hostutils.UpdateServerStatus(context.Background(), s.GetId(), "running")
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if event.Event == "BLOCK_JOB_ERROR" && s.IsMaster() {
|
||||
modules.Servers.PerformAction(hostutils.GetComputeSession(context.Background()), s.GetId(), "mirror-job-failed", nil)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,11 +379,19 @@ func (s *SKVMGuestInstance) onGetQemuVersion(ctx context.Context, version string
|
||||
body.Set("live_migrate_dest_port", migratePort)
|
||||
hostutils.TaskComplete(ctx, body)
|
||||
} else if jsonutils.QueryBoolean(s.Desc, "is_slave", false) {
|
||||
if len(appctx.AppContextTaskId(ctx)) > 0 {
|
||||
if ctx != nil && len(appctx.AppContextTaskId(ctx)) > 0 {
|
||||
s.startQemuBuiltInNbdServer(ctx)
|
||||
}
|
||||
} else if jsonutils.QueryBoolean(s.Desc, "is_master", false) && ctx == nil {
|
||||
return
|
||||
} else if jsonutils.QueryBoolean(s.Desc, "is_master", false) {
|
||||
s.startDiskBackupMirror(ctx)
|
||||
if ctx != nil {
|
||||
s.DoResumeTask(ctx)
|
||||
} else {
|
||||
if options.HostOptions.SetVncPassword {
|
||||
s.SetVncPassword()
|
||||
}
|
||||
s.SyncMetadataInfo()
|
||||
}
|
||||
} else {
|
||||
s.DoResumeTask(ctx)
|
||||
}
|
||||
@@ -402,14 +408,42 @@ func (s *SKVMGuestInstance) onMonitorDisConnect(err error) {
|
||||
s.Monitor = nil
|
||||
}
|
||||
|
||||
func (s *SKVMGuestInstance) startDiskBackupMirror(ctx context.Context) {
|
||||
if ctx == nil || len(appctx.AppContextTaskId(ctx)) == 0 {
|
||||
status := "running"
|
||||
if !s.IsMirrorJobSucc() {
|
||||
status = "block_stream"
|
||||
}
|
||||
hostutils.UpdateServerStatus(context.Background(), s.GetId(), status)
|
||||
} else {
|
||||
metadata, _ := s.Desc.Get("metadata")
|
||||
if metadata == nil || !metadata.Contains("backup_nbd_server_uri") {
|
||||
hostutils.TaskFailed(ctx, "Missing dest nbd location")
|
||||
}
|
||||
nbdUri, _ := metadata.GetString("backup_nbd_server_uri")
|
||||
|
||||
onSucc := func() {
|
||||
cb := func(res string) { log.Infof("On backup mirror server(%s) resume start", s.Id) }
|
||||
s.Monitor.SimpleCommand("cont", cb)
|
||||
}
|
||||
NewDriveMirrorTask(ctx, s, nbdUri, "top", onSucc).Start()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SKVMGuestInstance) startQemuBuiltInNbdServer(ctx context.Context) {
|
||||
if ctx == nil || len(appctx.AppContextTaskId(ctx)) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
nbdServerPort := s.manager.GetFreePortByBase(BUILT_IN_NBD_SERVER_PORT_BASE)
|
||||
var onNbdServerStarted = func(res string) {
|
||||
if len(res) > 0 {
|
||||
log.Errorln("Start Qemu Builtin nbd server error %s", res)
|
||||
log.Errorf("Start Qemu Builtin nbd server error %s", res)
|
||||
hostutils.TaskFailed(ctx, res)
|
||||
} else {
|
||||
hostutils.TaskComplete(ctx, nil)
|
||||
res := jsonutils.NewDict()
|
||||
res.Set("nbd_server_port", jsonutils.NewInt(int64(nbdServerPort)))
|
||||
hostutils.TaskComplete(ctx, res)
|
||||
}
|
||||
}
|
||||
s.Monitor.StartNbdServer(nbdServerPort, true, true, onNbdServerStarted)
|
||||
@@ -435,7 +469,31 @@ func (s *SKVMGuestInstance) DiskCount() int {
|
||||
}
|
||||
|
||||
func (s *SKVMGuestInstance) IsMirrorJobSucc() bool {
|
||||
return s.mirrorJobSuccCount != nil && *s.mirrorJobSuccCount == s.DiskCount()
|
||||
res := make(chan *jsonutils.JSONArray)
|
||||
s.Monitor.GetBlockJobs(func(jobs *jsonutils.JSONArray) {
|
||||
res <- jobs
|
||||
})
|
||||
select {
|
||||
case <-time.After(time.Second * 3):
|
||||
return false
|
||||
case v := <-res:
|
||||
if v != nil {
|
||||
if len(v.Value()) == 0 {
|
||||
return true
|
||||
}
|
||||
mirrorSuccCount := 0
|
||||
for _, val := range v.Value() {
|
||||
jobType, _ := val.GetString("type")
|
||||
jobStatus, _ := val.GetString("status")
|
||||
if jobType == "mirror" && jobStatus == "ready" {
|
||||
mirrorSuccCount += 1
|
||||
}
|
||||
}
|
||||
return mirrorSuccCount == s.DiskCount()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SKVMGuestInstance) CleanStartupTask() {
|
||||
@@ -503,7 +561,7 @@ func (s *SKVMGuestInstance) DoResumeTask(ctx context.Context) {
|
||||
|
||||
func (s *SKVMGuestInstance) SyncStatus() {
|
||||
if s.IsRunning() {
|
||||
s.Monitor.GetBlockJobs(s.CheckBlockOrRunning)
|
||||
s.Monitor.GetBlockJobCounts(s.CheckBlockOrRunning)
|
||||
return
|
||||
}
|
||||
var status = "ready"
|
||||
@@ -538,16 +596,17 @@ func (s *SKVMGuestInstance) SaveDesc(desc jsonutils.JSONObject) error {
|
||||
}
|
||||
|
||||
func (s *SKVMGuestInstance) StartGuest(ctx context.Context, params jsonutils.JSONObject) {
|
||||
hostutils.DelayTask(ctx, s.asyncScriptStart, params)
|
||||
hostutils.DelayTaskWithoutReqctx(ctx, s.asyncScriptStart, params)
|
||||
}
|
||||
|
||||
func (s *SKVMGuestInstance) DeployFs(deployInfo *guestfs.SDeployInfo) (jsonutils.JSONObject, error) {
|
||||
disks, _ := s.Desc.GetArray("disks")
|
||||
if len(disks) > 0 {
|
||||
storageId, _ := disks[0].GetString("storage_id")
|
||||
diskId, _ := disks[0].GetString("disk_id")
|
||||
|
||||
disk := storageman.GetManager().GetStorageDisk(storageId, diskId)
|
||||
diskPath, _ := disks[0].GetString("path")
|
||||
disk := storageman.GetManager().GetDiskByPath(diskPath)
|
||||
if disk == nil {
|
||||
return nil, fmt.Errorf("Cannot find disk index 0")
|
||||
}
|
||||
return disk.DeployGuestFs(disk.GetPath(), s.Desc, deployInfo)
|
||||
} else {
|
||||
return nil, fmt.Errorf("Guest dosen't have disk ??")
|
||||
@@ -1017,6 +1076,18 @@ func (s *SKVMGuestInstance) SetVncPassword() {
|
||||
func() { s.Monitor.SetVncPassword(s.GetVdiProtocol(), password, callback) })
|
||||
}
|
||||
|
||||
func (s *SKVMGuestInstance) SyncMetadataInfo() {
|
||||
meta := jsonutils.NewDict()
|
||||
meta.Set("__qemu_version", jsonutils.NewString(s.GetQemuVersionStr()))
|
||||
meta.Set("__vnc_port", jsonutils.NewInt(int64(s.GetVncPort())))
|
||||
|
||||
if len(s.VncPassword) > 0 {
|
||||
meta.Set("__vnc_password", jsonutils.NewString(s.VncPassword))
|
||||
}
|
||||
|
||||
s.SyncMetadata(meta)
|
||||
}
|
||||
|
||||
func (s *SKVMGuestInstance) ListStateFilePaths() []string {
|
||||
var ret = []string{}
|
||||
if fileutils2.Exists(s.HomeDir()) {
|
||||
|
||||
@@ -45,7 +45,7 @@ func NewBaseBridgeDriver(bridge, inter, ip string) (*SBaseBridgeDriver, error) {
|
||||
bd.bridge = netutils2.NewNetInterface(bridge)
|
||||
if len(inter) > 0 {
|
||||
bd.inter = netutils2.NewNetInterface(inter)
|
||||
if bd.inter == nil {
|
||||
if !bd.inter.Exist() {
|
||||
return nil, fmt.Errorf("%s not exists", inter)
|
||||
}
|
||||
bd.ip = ip
|
||||
@@ -132,7 +132,7 @@ func (d *SBaseBridgeDriver) ConfirmToConfig(exists bool, infs []string) (bool, e
|
||||
|
||||
func (d *SBaseBridgeDriver) SetupAddresses(mask net.IPMask) error {
|
||||
var addr string
|
||||
if len(d.ip) > 0 {
|
||||
if len(d.ip) == 0 {
|
||||
addr, mask = netutils2.GetSecretInterfaceAddress()
|
||||
} else {
|
||||
addr = d.ip
|
||||
|
||||
@@ -46,6 +46,8 @@ func NewDHCPRelay(guestDHCPConn *dhcp.Conn, addrs []string) (*SDHCPRelay, error)
|
||||
log.Errorln(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Infof("Set Relay To Address: %s, %d", addr, port)
|
||||
relay.destaddr = net.ParseIP(addr)
|
||||
relay.destport = port
|
||||
relay.cache = sync.Map{}
|
||||
@@ -66,7 +68,7 @@ func (r *SDHCPRelay) Start() {
|
||||
func (r *SDHCPRelay) Setup(addr string) error {
|
||||
var err error
|
||||
r.srcaddr = addr
|
||||
log.Infof("DHCP Relay Bind addr %s port %d", r.srcaddr, DEFAULT_DHCP_RELAY_PORT)
|
||||
log.Infof("DHCP Relay Server Bind addr %s port %d", r.srcaddr, DEFAULT_DHCP_RELAY_PORT)
|
||||
r.server, r.conn, err = dhcp.NewDHCPServer2(r.srcaddr, DEFAULT_DHCP_RELAY_PORT)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
@@ -94,7 +96,7 @@ func (r *SDHCPRelay) ServeDHCP(pkt dhcp.Packet, addr *net.UDPAddr, intf *net.Int
|
||||
}
|
||||
|
||||
func (r *SDHCPRelay) Relay(pkt dhcp.Packet, addr *net.UDPAddr, intf *net.Interface) (dhcp.Packet, error) {
|
||||
log.Infof("Receive DHCP Relay Rquest FROM %s", pkt.CHAddr())
|
||||
log.Infof("Receive DHCP Relay Rquest FROM %s %s", pkt.SIAddr(), pkt.CHAddr())
|
||||
|
||||
// clean cache first
|
||||
var now = time.Now().Add(time.Second * -30)
|
||||
|
||||
@@ -32,7 +32,10 @@ func NewGuestDHCPServer(iface string, relay []string) (*SGuestDHCPServer, error)
|
||||
guestdhcp = new(SGuestDHCPServer)
|
||||
)
|
||||
|
||||
guestdhcp.server, guestdhcp.conn, err = dhcp.NewDHCPServer2(DEFAULT_DHCP_BIND_ADDR, options.HostOptions.DhcpServerPort)
|
||||
log.Infof("DHCP Server Bind: %s %d",
|
||||
DEFAULT_DHCP_BIND_ADDR, options.HostOptions.DhcpServerPort)
|
||||
guestdhcp.server, guestdhcp.conn, err = dhcp.NewDHCPServer2(
|
||||
DEFAULT_DHCP_BIND_ADDR, options.HostOptions.DhcpServerPort)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ func (n *SNIC) EnableDHCPRelay() bool {
|
||||
log.Errorln(err)
|
||||
return false
|
||||
}
|
||||
if len(options.HostOptions.GoDhcpRelay) > 0 && !netutils.IsExitAddress(v4Ip) {
|
||||
if len(options.HostOptions.DhcpRelay) > 0 && !netutils.IsExitAddress(v4Ip) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
@@ -269,7 +269,7 @@ func NewNIC(desc string) (*SNIC, error) {
|
||||
|
||||
var dhcpRelay []string
|
||||
if nic.EnableDHCPRelay() {
|
||||
dhcpRelay = options.HostOptions.GoDhcpRelay
|
||||
dhcpRelay = options.HostOptions.DhcpRelay
|
||||
}
|
||||
nic.dhcpServer, err = hostdhcp.NewGuestDHCPServer(nic.Bridge, dhcpRelay)
|
||||
if err != nil {
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/onecloud/pkg/util/regutils2"
|
||||
)
|
||||
|
||||
type HmpMonitor struct {
|
||||
@@ -299,7 +300,7 @@ func (m *HmpMonitor) GetMigrateStatus(callback StringCallback) {
|
||||
m.Query("info migrate", cb)
|
||||
}
|
||||
|
||||
func (m *HmpMonitor) GetBlockJobs(callback func(jobs int)) {
|
||||
func (m *HmpMonitor) GetBlockJobCounts(callback func(jobs int)) {
|
||||
cb := func(output string) {
|
||||
lines := strings.Split(output, "\n")
|
||||
if lines[0] == "No active jobs" {
|
||||
@@ -312,6 +313,32 @@ func (m *HmpMonitor) GetBlockJobs(callback func(jobs int)) {
|
||||
m.Query("info block-jobs", cb)
|
||||
}
|
||||
|
||||
func (m *HmpMonitor) GetBlockJobs(callback func(*jsonutils.JSONArray)) {
|
||||
cb := func(output string) {
|
||||
lines := strings.Split(output, "\n")
|
||||
if lines[0] == "No active jobs" {
|
||||
callback(nil)
|
||||
} else {
|
||||
res := jsonutils.NewArray()
|
||||
re := regexp.MustCompile(`Type (?P<type>\w+), device (?P<device>\w+)`)
|
||||
for i := 0; i < len(lines); i++ {
|
||||
m := regutils2.GetParams(re, lines[i])
|
||||
if len(m) > 0 {
|
||||
jobType, _ := m["type"]
|
||||
device, _ := m["device"]
|
||||
jobInfo := jsonutils.NewDict()
|
||||
jobInfo.Set("type", jsonutils.NewString(jobType))
|
||||
jobInfo.Set("device", jsonutils.NewString(device))
|
||||
res.Add(jobInfo)
|
||||
}
|
||||
}
|
||||
callback(res)
|
||||
}
|
||||
}
|
||||
|
||||
m.Query("info block-jobs", cb)
|
||||
}
|
||||
|
||||
func (m *HmpMonitor) ReloadDiskBlkdev(device, path string, callback StringCallback) {
|
||||
m.Query(fmt.Sprintf("reload_disk_snapshot_blkdev -n %s %s", device, path), callback)
|
||||
}
|
||||
|
||||
@@ -23,7 +23,8 @@ type Monitor interface {
|
||||
|
||||
QueryStatus(StringCallback)
|
||||
GetVersion(StringCallback)
|
||||
GetBlockJobs(func(jobs int))
|
||||
GetBlockJobCounts(func(jobs int))
|
||||
GetBlockJobs(func(*jsonutils.JSONArray))
|
||||
|
||||
GetBlocks(callback func(*jsonutils.JSONArray))
|
||||
EjectCdrom(dev string, callback StringCallback)
|
||||
|
||||
@@ -149,7 +149,7 @@ func (m *QmpMonitor) read(r io.Reader) {
|
||||
m.callBack(res)
|
||||
} else if val, ok := objmap["return"]; ok {
|
||||
var res = &Response{}
|
||||
res.Return = *val
|
||||
res.Return = []byte(*val)
|
||||
if id, ok := objmap["id"]; ok {
|
||||
res.Id = string(*id)
|
||||
}
|
||||
@@ -305,10 +305,11 @@ func (m *QmpMonitor) HumanMonitorCommand(cmd string, callback StringCallback) {
|
||||
}
|
||||
|
||||
cb = func(res *Response) {
|
||||
log.Debugf("Monitor ret: %s", res.Return)
|
||||
if res.ErrorVal != nil {
|
||||
callback(res.ErrorVal.Error())
|
||||
} else {
|
||||
callback(string(res.Return))
|
||||
callback(strings.Trim(string(res.Return), `""`))
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -595,7 +596,7 @@ func (m *QmpMonitor) GetMigrateStatus(callback StringCallback) {
|
||||
m.Query(cmd, cb)
|
||||
}
|
||||
|
||||
func (m *QmpMonitor) GetBlockJobs(callback func(jobs int)) {
|
||||
func (m *QmpMonitor) GetBlockJobCounts(callback func(jobs int)) {
|
||||
var cb = func(res *Response) {
|
||||
if res.ErrorVal != nil {
|
||||
log.Errorln(res.ErrorVal.Error())
|
||||
@@ -614,6 +615,25 @@ func (m *QmpMonitor) GetBlockJobs(callback func(jobs int)) {
|
||||
m.Query(&Command{Execute: "query-block-jobs"}, cb)
|
||||
}
|
||||
|
||||
func (m *QmpMonitor) GetBlockJobs(callback func(*jsonutils.JSONArray)) {
|
||||
var cb = func(res *Response) {
|
||||
if res.ErrorVal != nil {
|
||||
log.Errorln(res.ErrorVal.Error())
|
||||
callback(nil)
|
||||
} else {
|
||||
ret, err := jsonutils.Parse(res.Return)
|
||||
if err != nil {
|
||||
log.Errorf("Parse qmp res error: %s", err)
|
||||
callback(nil)
|
||||
} else {
|
||||
jobs, _ := ret.(*jsonutils.JSONArray)
|
||||
callback(jobs)
|
||||
}
|
||||
}
|
||||
}
|
||||
m.Query(&Command{Execute: "query-block-jobs"}, cb)
|
||||
}
|
||||
|
||||
func (m *QmpMonitor) ReloadDiskBlkdev(device, path string, callback StringCallback) {
|
||||
var (
|
||||
cb = func(res *Response) {
|
||||
|
||||
@@ -51,9 +51,7 @@ type SHostOptions struct {
|
||||
|
||||
DefaultQemuVersion string `help:"Default qemu version" default:"2.9.1"`
|
||||
|
||||
// XXX: Need configure
|
||||
// dhcp_relay = ('10.168.222.236', 67) => dhcp_relay = ['10.168.222.236', '67']
|
||||
GoDhcpRelay []string `help:"DHCP relay upstream"`
|
||||
DhcpRelay []string `help:"DHCP relay upstream"`
|
||||
DhcpLeaseTime int `default:"100663296" help:"DHCP lease time in seconds"`
|
||||
DhcpRenewalTime int `default:"67108864" help:"DHCP renewal time in seconds"`
|
||||
|
||||
|
||||
@@ -72,12 +72,7 @@ func (s *SBaseSystemService) IsInstalled() bool {
|
||||
}
|
||||
|
||||
func (s *SBaseSystemService) GetStatus() map[string]string {
|
||||
res, err := procutils.NewCommand("systemctl", "status", s.name).Run()
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return nil
|
||||
}
|
||||
|
||||
res, _ := procutils.NewCommand("systemctl", "status", s.name).Run()
|
||||
var ret = make(map[string]string, 0)
|
||||
lines := strings.Split(string(res), "\n")
|
||||
for _, line := range lines {
|
||||
|
||||
@@ -488,7 +488,7 @@ func ResizeDiskFs(diskPath string, sizeMb int) error {
|
||||
return fmt.Errorf("%s", output)
|
||||
}
|
||||
if len(part[6]) > 0 {
|
||||
err := ResizePartitionFs(part[7], part[6])
|
||||
err, _ := ResizePartitionFs(part[7], part[6], false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -498,12 +498,26 @@ func ResizeDiskFs(diskPath string, sizeMb int) error {
|
||||
}
|
||||
|
||||
func FsckExtFs(fpath string) bool {
|
||||
cmd := []string{"e2fsck", "-f", "-p", fpath}
|
||||
if _, err := procutils.NewCommand(cmd[0], cmd[1:]...).Run(); err != nil {
|
||||
log.Debugf("Exec command: %v", []string{"e2fsck", "-f", "-p", fpath})
|
||||
cmd := exec.Command("e2fsck", "-f", "-p", fpath)
|
||||
if err := cmd.Start(); err != nil {
|
||||
log.Errorln(err)
|
||||
return false
|
||||
} else {
|
||||
err = cmd.Wait()
|
||||
if err != nil {
|
||||
if exiterr, ok := err.(*exec.ExitError); ok {
|
||||
ws := exiterr.Sys().(syscall.WaitStatus)
|
||||
if ws.ExitStatus() < 4 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
log.Errorln(err)
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func FsckXfsFs(fpath string) bool {
|
||||
@@ -515,9 +529,9 @@ func FsckXfsFs(fpath string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func ResizePartitionFs(fpath, fs string) error {
|
||||
func ResizePartitionFs(fpath, fs string, raiseError bool) (error, bool) {
|
||||
if len(fs) == 0 {
|
||||
return nil
|
||||
return nil, false
|
||||
}
|
||||
var (
|
||||
cmds = [][]string{}
|
||||
@@ -531,7 +545,11 @@ func ResizePartitionFs(fpath, fs string) error {
|
||||
}
|
||||
} else if strings.HasPrefix(fs, "ext") {
|
||||
if !FsckExtFs(fpath) {
|
||||
return fmt.Errorf("Failed to fsck ext fs %s", fpath)
|
||||
if raiseError {
|
||||
return fmt.Errorf("Failed to fsck ext fs %s", fpath), false
|
||||
} else {
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
cmds = [][]string{{"resize2fs", fpath}}
|
||||
} else if fs == "xfs" {
|
||||
@@ -540,7 +558,7 @@ func ResizePartitionFs(fpath, fs string) error {
|
||||
_, err = procutils.NewCommand("umount", "-f", tmpPoint).Run()
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return err
|
||||
return err, false
|
||||
}
|
||||
}
|
||||
FsckXfsFs(fpath)
|
||||
@@ -559,11 +577,15 @@ func ResizePartitionFs(fpath, fs string) error {
|
||||
_, err := procutils.NewCommand(cmd[0], cmd[1:]...).Run()
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return err
|
||||
if raiseError {
|
||||
return err, false
|
||||
} else {
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return nil, true
|
||||
}
|
||||
|
||||
func GetDevUuid(dev string) map[string]string {
|
||||
|
||||
@@ -179,6 +179,11 @@ func (n *SNetInterface) String() string {
|
||||
return n.name
|
||||
}
|
||||
|
||||
func (n *SNetInterface) Exist() bool {
|
||||
_, err := net.InterfaceByName(n.name)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func (n *SNetInterface) FetchInter() *net.Interface {
|
||||
inter, err := net.InterfaceByName(n.name)
|
||||
if err != nil {
|
||||
|
||||
+5
-1
@@ -888,7 +888,11 @@ func (this *ArgumentParser) parseKeyValue(key, value string) error {
|
||||
arg := this.findOptionalArgument(key)
|
||||
if arg != nil {
|
||||
if arg.IsMulti() {
|
||||
value = strings.Trim(value, "[]")
|
||||
if value[0] == '(' {
|
||||
value = strings.Trim(value, "()")
|
||||
} else {
|
||||
value = strings.Trim(value, "[]")
|
||||
}
|
||||
values := utils.FindWords([]byte(value), 0)
|
||||
for _, v := range values {
|
||||
e := arg.SetValue(v)
|
||||
|
||||
Reference in New Issue
Block a user