mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/yunionio/cloudpods.git
synced 2026-09-20 08:03:53 +08:00
Merge pull request #3682 from swordqiu/automated-cherry-pick-of-#3681-upstream-release-2.12
Automated cherry pick of #3681: fix: baremetal server rebuild root fail to cache image
This commit is contained in:
38
pkg/apis/compute/guests.go
Normal file
38
pkg/apis/compute/guests.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
)
|
||||
|
||||
type ServerRebuildRootInput struct {
|
||||
apis.Meta
|
||||
|
||||
Image string `json:"image"`
|
||||
ImageId string `json:"image_id"`
|
||||
Keypair string `json:"keypair"`
|
||||
KeypairId string `json:"keypair_id"`
|
||||
ResetPassword *bool `json:"reset_password"`
|
||||
Password string `json:"password"`
|
||||
AutoStart *bool `json:"auto_start"`
|
||||
AllDisks *bool `json:"all_disks"`
|
||||
}
|
||||
|
||||
func (i ServerRebuildRootInput) GetImageName() string {
|
||||
if len(i.Image) > 0 {
|
||||
return i.Image
|
||||
}
|
||||
if len(i.ImageId) > 0 {
|
||||
return i.ImageId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (i ServerRebuildRootInput) GetKeypairName() string {
|
||||
if len(i.Keypair) > 0 {
|
||||
return i.Keypair
|
||||
}
|
||||
if len(i.KeypairId) > 0 {
|
||||
return i.KeypairId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -258,7 +258,7 @@ func (self *SBaremetalGuestDriver) RequestGuestCreateAllDisks(ctx context.Contex
|
||||
if storageCache == nil {
|
||||
return fmt.Errorf("no valid storage cache")
|
||||
}
|
||||
return storageCache.StartImageCacheTask(ctx, task.GetUserCred(), imageId, diskCat.Root.DiskFormat, false, task.GetTaskId())
|
||||
return storageCache.StartImageCacheTask(ctx, task.GetUserCred(), imageId, "qcow2", false, task.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) NeedRequestGuestHotAddIso(ctx context.Context, guest *models.SGuest) bool {
|
||||
@@ -401,6 +401,15 @@ func (self *SBaremetalGuestDriver) GetGuestVncInfo(ctx context.Context, userCred
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) RequestRebuildRootDisk(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
|
||||
subtask, err := taskman.TaskManager.NewTask(ctx, "ManagedGuestRebuildRootTask", guest, task.GetUserCred(), task.GetParams(), task.GetTaskId(), "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
subtask.ScheduleRun(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) PerformStart(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, data *jsonutils.JSONDict) error {
|
||||
return guest.StartGueststartTask(ctx, userCred, data, "")
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import (
|
||||
|
||||
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
imageapi "yunion.io/x/onecloud/pkg/apis/image"
|
||||
schedapi "yunion.io/x/onecloud/pkg/apis/scheduler"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/cmdline"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
@@ -1279,13 +1280,26 @@ func (self *SGuest) AllowPerformRebuildRoot(ctx context.Context, userCred mcclie
|
||||
}
|
||||
|
||||
func (self *SGuest) PerformRebuildRoot(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
imageId, _ := data.GetString("image_id")
|
||||
input := api.ServerRebuildRootInput{}
|
||||
err := data.Unmarshal(&input)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("invalid input: %s", err)
|
||||
}
|
||||
|
||||
imageId := input.GetImageName()
|
||||
|
||||
if len(imageId) > 0 {
|
||||
img, err := CachedimageManager.getImageInfo(ctx, userCred, imageId, false)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewNotFoundError("failed to find %s", imageId)
|
||||
}
|
||||
diskCat := self.CategorizeDisks()
|
||||
if img.MinDiskMB == 0 || img.Status != imageapi.IMAGE_STATUS_ACTIVE {
|
||||
return nil, httperrors.NewInputParameterError("invlid image")
|
||||
}
|
||||
if img.MinDiskMB > diskCat.Root.DiskSize {
|
||||
return nil, httperrors.NewInputParameterError("image size exceeds root disk size")
|
||||
}
|
||||
osType, _ := img.Properties["os_type"]
|
||||
osName := self.GetMetadata("os_name", userCred)
|
||||
if len(osName) == 0 && len(osType) == 0 && strings.ToLower(osType) != strings.ToLower(osName) {
|
||||
@@ -1313,20 +1327,26 @@ func (self *SGuest) PerformRebuildRoot(ctx context.Context, userCred mcclient.To
|
||||
return nil, httperrors.NewInvalidStatusError("Cannot reset root in status %s", self.Status)
|
||||
}
|
||||
|
||||
autoStart := jsonutils.QueryBoolean(data, "auto_start", false)
|
||||
autoStart := false
|
||||
if input.AutoStart != nil {
|
||||
autoStart = *input.AutoStart
|
||||
}
|
||||
var needStop = false
|
||||
if self.Status == api.VM_RUNNING {
|
||||
needStop = true
|
||||
}
|
||||
resetPasswd := jsonutils.QueryBoolean(data, "reset_password", true)
|
||||
passwd, _ := data.GetString("password")
|
||||
resetPasswd := true
|
||||
if input.ResetPassword != nil {
|
||||
resetPasswd = *input.ResetPassword
|
||||
}
|
||||
passwd := input.Password
|
||||
if len(passwd) > 0 {
|
||||
if !seclib2.MeetComplxity(passwd) {
|
||||
return nil, httperrors.NewWeakPasswordError()
|
||||
}
|
||||
}
|
||||
|
||||
keypairStr := jsonutils.GetAnyString(data, []string{"keypair", "keypair_id"})
|
||||
keypairStr := input.GetKeypairName()
|
||||
if len(keypairStr) > 0 {
|
||||
keypairObj, err := KeypairManager.FetchByIdOrName(userCred, keypairStr)
|
||||
if err != nil {
|
||||
@@ -1350,7 +1370,10 @@ func (self *SGuest) PerformRebuildRoot(ctx context.Context, userCred mcclient.To
|
||||
}
|
||||
}
|
||||
|
||||
allDisks := jsonutils.QueryBoolean(data, "all_disks", false)
|
||||
allDisks := false
|
||||
if input.AllDisks != nil {
|
||||
allDisks = *input.AllDisks
|
||||
}
|
||||
|
||||
return nil, self.StartRebuildRootTask(ctx, userCred, imageId, needStop, autoStart, passwd, resetPasswd, allDisks)
|
||||
}
|
||||
@@ -1393,19 +1416,11 @@ func (self *SGuest) StartRebuildRootTask(ctx context.Context, userCred mcclient.
|
||||
data.Set("all_disks", jsonutils.JSONFalse)
|
||||
}
|
||||
self.SetStatus(userCred, api.VM_REBUILD_ROOT, "request start rebuild root")
|
||||
if self.GetHypervisor() == api.HYPERVISOR_BAREMETAL {
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "BaremetalServerRebuildRootTask", self, userCred, data, "", "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
task.ScheduleRun(nil)
|
||||
} else {
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "GuestRebuildRootTask", self, userCred, data, "", "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
task.ScheduleRun(nil)
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "GuestRebuildRootTask", self, userCred, data, "", "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
)
|
||||
|
||||
type BaremetalServerRebuildRootTask struct {
|
||||
SGuestBaseTask
|
||||
}
|
||||
|
||||
func init() {
|
||||
taskman.RegisterTask(BaremetalServerRebuildRootTask{})
|
||||
}
|
||||
|
||||
func (self *BaremetalServerRebuildRootTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
|
||||
guest := obj.(*models.SGuest)
|
||||
if jsonutils.QueryBoolean(self.Params, "need_stop", false) {
|
||||
self.SetStage("OnStopServerComplete", nil)
|
||||
guest.StartGuestStopTask(ctx, self.UserCred, false, self.GetTaskId())
|
||||
return
|
||||
}
|
||||
self.StartRebuildRootDisk(ctx, guest)
|
||||
}
|
||||
|
||||
func (self *BaremetalServerRebuildRootTask) OnStopServerComplete(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
|
||||
self.StartRebuildRootDisk(ctx, guest)
|
||||
}
|
||||
|
||||
func (self *BaremetalServerRebuildRootTask) StartRebuildRootDisk(ctx context.Context, guest *models.SGuest) {
|
||||
if guest.Status != api.VM_ADMIN {
|
||||
guest.SetStatus(self.UserCred, api.VM_REBUILD_ROOT, "")
|
||||
}
|
||||
imageId, _ := self.Params.GetString("image_id")
|
||||
db.OpsLog.LogEvent(guest, db.ACT_REBUILDING_ROOT, imageId, self.UserCred)
|
||||
gds := guest.CategorizeDisks()
|
||||
oldStatus := gds.Root.Status
|
||||
_, err := db.Update(gds.Root, func() error {
|
||||
gds.Root.TemplateId = imageId
|
||||
gds.Root.Status = api.DISK_REBUILD
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
self.SetStageFailed(ctx, err.Error())
|
||||
logclient.AddActionLogWithStartable(self, guest, logclient.ACT_VM_REBUILD, err, self.UserCred, false)
|
||||
return
|
||||
} else {
|
||||
db.OpsLog.LogEvent(gds.Root, db.ACT_UPDATE_STATUS,
|
||||
fmt.Sprintf("%s=>%s", oldStatus, api.DISK_REBUILD), self.UserCred)
|
||||
}
|
||||
self.SetStage("OnRebuildRootDiskComplete", nil)
|
||||
|
||||
// clear logininfo
|
||||
loginParams := make(map[string]interface{})
|
||||
loginParams["login_account"] = "none"
|
||||
loginParams["login_key"] = "none"
|
||||
loginParams["login_key_timestamp"] = "none"
|
||||
guest.SetAllMetadata(ctx, loginParams, self.UserCred)
|
||||
guest.StartGuestDeployTask(ctx, self.UserCred, self.Params, "rebuild", self.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *BaremetalServerRebuildRootTask) OnRebuildRootDiskComplete(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
|
||||
db.OpsLog.LogEvent(guest, db.ACT_REBUILD_ROOT, "", self.UserCred)
|
||||
self.SetStage("OnSyncStatusComplete", nil)
|
||||
guest.StartSyncstatus(ctx, self.UserCred, self.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *BaremetalServerRebuildRootTask) OnRebuildRootDiskCompleteFailed(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
|
||||
db.OpsLog.LogEvent(guest, db.ACT_REBUILD_ROOT_FAIL, data, self.UserCred)
|
||||
if guest.Status != api.VM_ADMIN {
|
||||
guest.SetStatus(self.UserCred, api.VM_REBUILD_ROOT_FAIL, "")
|
||||
}
|
||||
}
|
||||
|
||||
func (self *BaremetalServerRebuildRootTask) OnSyncStatusComplete(ctx context.Context, _ *models.SGuest, _ jsonutils.JSONObject) {
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
@@ -236,14 +236,8 @@ type ManagedGuestRebuildRootTask struct {
|
||||
func (self *ManagedGuestRebuildRootTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
guest := obj.(*models.SGuest)
|
||||
|
||||
diskCat := guest.CategorizeDisks()
|
||||
imageId := diskCat.Root.GetTemplateId()
|
||||
format := diskCat.Root.DiskFormat
|
||||
storage := diskCat.Root.GetStorage()
|
||||
cache := storage.GetStoragecache()
|
||||
|
||||
self.SetStage("OnHostCacheImageComplete", nil)
|
||||
cache.StartImageCacheTask(ctx, self.UserCred, imageId, format, false, self.GetTaskId())
|
||||
guest.GetDriver().RequestGuestCreateAllDisks(ctx, guest, self)
|
||||
}
|
||||
|
||||
func (self *ManagedGuestRebuildRootTask) OnHostCacheImageComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
|
||||
Reference in New Issue
Block a user