mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-05-10 15:53:11 +08:00
* feat(region,host): riscv64 cpu arch support * fix(region,host): compatible riscv64 * fix(host): add qemu v10.0.7 support
336 lines
11 KiB
Go
336 lines
11 KiB
Go
// 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 hostutils
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"os"
|
|
"path"
|
|
|
|
"yunion.io/x/jsonutils"
|
|
"yunion.io/x/log"
|
|
"yunion.io/x/pkg/appctx"
|
|
"yunion.io/x/pkg/util/regutils"
|
|
|
|
"yunion.io/x/onecloud/pkg/apis"
|
|
computeapi "yunion.io/x/onecloud/pkg/apis/compute"
|
|
hostapi "yunion.io/x/onecloud/pkg/apis/host"
|
|
"yunion.io/x/onecloud/pkg/appsrv"
|
|
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
|
|
"yunion.io/x/onecloud/pkg/cloudcommon/workmanager"
|
|
"yunion.io/x/onecloud/pkg/hostman/hostinfo/hostbridge"
|
|
"yunion.io/x/onecloud/pkg/hostman/hostutils/kubelet"
|
|
"yunion.io/x/onecloud/pkg/hostman/isolated_device"
|
|
"yunion.io/x/onecloud/pkg/hostman/options"
|
|
"yunion.io/x/onecloud/pkg/httperrors"
|
|
"yunion.io/x/onecloud/pkg/mcclient"
|
|
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
|
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
|
|
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
|
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
|
"yunion.io/x/onecloud/pkg/util/cgrouputils/cpuset"
|
|
"yunion.io/x/onecloud/pkg/util/fileutils2"
|
|
"yunion.io/x/onecloud/pkg/util/pod"
|
|
)
|
|
|
|
type SContainerCpufreqSimulateConfig struct {
|
|
CpuinfoMaxFreq int `json:"cpuinfo_max_freq"`
|
|
CpuinfoMinFreq int `json:"cpuinfo_min_freq"`
|
|
CpuinfoCurFreq int `json:"cpuinfo_cur_freq"`
|
|
CpuinfoTransitionLatency int `json:"cpuinfo_transition_latency"`
|
|
ScalingDriver string `json:"scaling_driver"`
|
|
ScalingGovernors string `json:"scaling_governor"`
|
|
ScalingMaxFreq int `json:"scaling_max_freq"`
|
|
ScalingMinFreq int `json:"scaling_min_freq"`
|
|
ScalingCurFreq int `json:"scaling_cur_freq"`
|
|
ScalingSetspeed string `json:"scaling_setspeed"`
|
|
ScalingAvailableGovernors string `json:"scaling_available_governors"`
|
|
}
|
|
|
|
type IGuestManager interface {
|
|
GetImageDeps(storageType string) []string
|
|
}
|
|
|
|
type IHost interface {
|
|
GetZoneId() string
|
|
GetHostId() string
|
|
GetMasterIp() string
|
|
GetCpuArchitecture() string
|
|
GetKernelVersion() string
|
|
IsAarch64() bool
|
|
IsX8664() bool
|
|
IsRiscv64() bool
|
|
GetHostTopology() *hostapi.HostTopology
|
|
GetReservedCpusInfo() (*cpuset.CPUSet, *cpuset.CPUSet)
|
|
GetReservedMemMb() int
|
|
|
|
IsHugepagesEnabled() bool
|
|
HugepageSizeKb() int
|
|
IsSchedulerNumaAllocateEnabled() bool
|
|
CpuCmtBound() float32
|
|
MemCmtBound() float32
|
|
|
|
IsKvmSupport() bool
|
|
IsNestedVirtualization() bool
|
|
|
|
PutHostOnline() error
|
|
StartDHCPServer()
|
|
|
|
GetBridgeDev(bridge string) hostbridge.IBridgeDriver
|
|
GetIsolatedDeviceManager() isolated_device.IsolatedDeviceManager
|
|
|
|
// SyncRootPartitionUsedCapacity() error
|
|
|
|
GetKubeletConfig() kubelet.KubeletConfig
|
|
|
|
// containerd related methods
|
|
IsContainerHost() bool
|
|
GetContainerRuntimeEndpoint() string
|
|
GetCRI() pod.CRI
|
|
GetContainerCPUMap() *pod.HostContainerCPUMap
|
|
GetContainerCpufreqSimulateConfig() *jsonutils.JSONDict
|
|
|
|
OnCatalogChanged(catalog mcclient.KeystoneServiceCatalogV3)
|
|
|
|
OnHostFilesChanged(hostfiles []computeapi.SHostFile) error
|
|
|
|
SetIGuestManager(guestman IGuestManager)
|
|
GetIGuestManager() IGuestManager
|
|
|
|
OnGuestLoadingComplete()
|
|
}
|
|
|
|
func GetComputeSession(ctx context.Context) *mcclient.ClientSession {
|
|
return auth.GetAdminSession(ctx, consts.GetRegion())
|
|
}
|
|
|
|
func GetK8sSession(ctx context.Context) *mcclient.ClientSession {
|
|
return auth.GetAdminSession(ctx, consts.GetRegion())
|
|
}
|
|
|
|
func GetImageSession(ctx context.Context) *mcclient.ClientSession {
|
|
return auth.AdminSession(ctx, consts.GetRegion(), consts.GetZone(), "")
|
|
}
|
|
|
|
func TaskFailed(ctx context.Context, reason string) {
|
|
if taskId := ctx.Value(appctx.APP_CONTEXT_KEY_TASK_ID); taskId != nil {
|
|
modules.ComputeTasks.TaskFailed2(GetComputeSession(ctx), taskId.(string), reason)
|
|
} else {
|
|
log.Errorf("Reqeuest task failed missing task id, with reason(%s)", reason)
|
|
}
|
|
}
|
|
|
|
func TaskFailed2(ctx context.Context, reason string, params *jsonutils.JSONDict) {
|
|
if taskId := ctx.Value(appctx.APP_CONTEXT_KEY_TASK_ID); taskId != nil {
|
|
modules.ComputeTasks.TaskFailed3(GetComputeSession(ctx), taskId.(string), reason, params)
|
|
} else {
|
|
log.Errorf("Reqeuest task failed missing task id, with reason(%s)", reason)
|
|
}
|
|
}
|
|
|
|
func TaskComplete(ctx context.Context, params jsonutils.JSONObject) {
|
|
if taskId := ctx.Value(appctx.APP_CONTEXT_KEY_TASK_ID); taskId != nil {
|
|
modules.ComputeTasks.TaskComplete(GetComputeSession(ctx), taskId.(string), params)
|
|
} else {
|
|
log.Errorln("Reqeuest task complete missing task id")
|
|
}
|
|
}
|
|
|
|
func K8sTaskFailed(ctx context.Context, reason string) {
|
|
if taskId := ctx.Value(appctx.APP_CONTEXT_KEY_TASK_ID); taskId != nil {
|
|
k8s.KubeTasks.TaskFailed2(GetK8sSession(ctx), taskId.(string), reason)
|
|
} else {
|
|
log.Errorf("Reqeuest k8s task failed missing task id, with reason(%s)", reason)
|
|
}
|
|
}
|
|
|
|
func K8sTaskComplete(ctx context.Context, params jsonutils.JSONObject) {
|
|
if taskId := ctx.Value(appctx.APP_CONTEXT_KEY_TASK_ID); taskId != nil {
|
|
k8s.KubeTasks.TaskComplete(GetK8sSession(ctx), taskId.(string), params)
|
|
} else {
|
|
log.Errorln("Reqeuest k8s task complete missing task id")
|
|
}
|
|
}
|
|
|
|
func GetWireOfIp(ctx context.Context, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
|
res, err := modules.Networks.List(GetComputeSession(ctx), params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(res.Data) == 1 {
|
|
wireId, _ := res.Data[0].GetString("wire_id")
|
|
return GetWireInfo(ctx, wireId)
|
|
} else {
|
|
return nil, fmt.Errorf("Fail to get network info: no networks")
|
|
}
|
|
}
|
|
|
|
func GetWireInfo(ctx context.Context, wireId string) (jsonutils.JSONObject, error) {
|
|
return modules.Wires.Get(GetComputeSession(ctx), wireId, nil)
|
|
}
|
|
|
|
func RemoteStoragecacheCacheImage(ctx context.Context, storagecacheId, imageId, status, spath string) (jsonutils.JSONObject, error) {
|
|
var query = jsonutils.NewDict()
|
|
query.Set("auto_create", jsonutils.JSONTrue)
|
|
var params = jsonutils.NewDict()
|
|
params.Set("status", jsonutils.NewString(status))
|
|
params.Set("path", jsonutils.NewString(spath))
|
|
return modules.Storagecachedimages.Update(GetComputeSession(ctx),
|
|
storagecacheId, imageId, query, params)
|
|
}
|
|
|
|
func UpdateResourceStatus(ctx context.Context, man modulebase.IResourceManager, id string, statusInput *apis.PerformStatusInput) (jsonutils.JSONObject, error) {
|
|
return man.PerformAction(GetComputeSession(ctx), id, "status", jsonutils.Marshal(statusInput))
|
|
}
|
|
|
|
func UpdateContainerStatus(ctx context.Context, cid string, statusInput *computeapi.ContainerPerformStatusInput) (jsonutils.JSONObject, error) {
|
|
return modules.Containers.PerformAction(GetComputeSession(ctx), cid, "status", jsonutils.Marshal(statusInput))
|
|
}
|
|
|
|
func UpdateServerStatus(ctx context.Context, sid string, statusInput *apis.PerformStatusInput) (jsonutils.JSONObject, error) {
|
|
return UpdateResourceStatus(ctx, &modules.Servers, sid, statusInput)
|
|
}
|
|
|
|
func UpdateServerContainersStatus(ctx context.Context, sid string, input *computeapi.ServerPerformStatusInput) (jsonutils.JSONObject, error) {
|
|
return modules.Servers.PerformAction(GetComputeSession(ctx), sid, "status", jsonutils.Marshal(input))
|
|
}
|
|
|
|
func UpdateServerProgress(ctx context.Context, sid string, progress, progressMbps float64) (jsonutils.JSONObject, error) {
|
|
params := map[string]float64{
|
|
"progress": progress,
|
|
"progress_mbps": progressMbps,
|
|
}
|
|
return modules.Servers.Update(GetComputeSession(ctx), sid, jsonutils.Marshal(params))
|
|
}
|
|
|
|
func UploadGuestStatus(ctx context.Context, sid string, resp *computeapi.HostUploadGuestStatusInput) (jsonutils.JSONObject, error) {
|
|
return modules.Servers.PerformAction(GetComputeSession(ctx), sid, "upload-status", jsonutils.Marshal(resp))
|
|
}
|
|
|
|
func UploadGuestsStatus(ctx context.Context, resp *computeapi.HostUploadGuestsStatusInput) (jsonutils.JSONObject, error) {
|
|
return modules.Servers.PerformClassAction(GetComputeSession(ctx), "upload-status", jsonutils.Marshal(resp))
|
|
}
|
|
|
|
func IsGuestDir(f os.FileInfo, serversPath string) bool {
|
|
if !regutils.MatchUUID(f.Name()) {
|
|
return false
|
|
}
|
|
if !f.Mode().IsDir() && f.Mode()&os.ModeSymlink == 0 {
|
|
return false
|
|
}
|
|
descFile := path.Join(serversPath, f.Name(), "desc")
|
|
if !fileutils2.Exists(descFile) {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func ResponseOk(ctx context.Context, w http.ResponseWriter) {
|
|
Response(ctx, w, map[string]string{"result": "ok"})
|
|
}
|
|
|
|
func Response(ctx context.Context, w http.ResponseWriter, res interface{}) {
|
|
if taskId := ctx.Value(appctx.APP_CONTEXT_KEY_TASK_ID); taskId != nil {
|
|
w.Header().Set("X-Request-Id", taskId.(string))
|
|
}
|
|
switch res.(type) {
|
|
case string:
|
|
appsrv.Send(w, res.(string))
|
|
case jsonutils.JSONObject:
|
|
appsrv.SendJSON(w, res.(jsonutils.JSONObject))
|
|
case error:
|
|
httperrors.GeneralServerError(ctx, w, res.(error))
|
|
default:
|
|
appsrv.SendStruct(w, res)
|
|
}
|
|
}
|
|
|
|
var (
|
|
wm *workmanager.SWorkManager
|
|
imageCacheW *workmanager.SWorkManager
|
|
backupW *workmanager.SWorkManager
|
|
k8sWm *workmanager.SWorkManager
|
|
|
|
imagePreCacheW *workmanager.SWorkManager
|
|
|
|
ParamsError = fmt.Errorf("Delay task parse params error")
|
|
)
|
|
|
|
func GetWorkManager() *workmanager.SWorkManager {
|
|
return wm
|
|
}
|
|
|
|
func DelayTask(ctx context.Context, task workmanager.DelayTaskFunc, params interface{}) {
|
|
wm.DelayTask(ctx, task, params)
|
|
}
|
|
|
|
func DelayImageCacheTask(ctx context.Context, task workmanager.DelayTaskFunc, params interface{}) {
|
|
imageCacheW.DelayTask(ctx, task, params)
|
|
}
|
|
|
|
func DelayImagePreCacheTask(ctx context.Context, task workmanager.DelayTaskFunc, params interface{}) {
|
|
imagePreCacheW.DelayTask(ctx, task, params)
|
|
}
|
|
|
|
func DelayBackupTask(ctx context.Context, task workmanager.DelayTaskFunc, params interface{}) {
|
|
backupW.DelayTask(ctx, task, params)
|
|
}
|
|
|
|
func DelayKubeTask(ctx context.Context, task workmanager.DelayTaskFunc, params interface{}) {
|
|
k8sWm.DelayTask(ctx, task, params)
|
|
}
|
|
|
|
func DelayTaskWithoutReqctx(ctx context.Context, task workmanager.DelayTaskFunc, params interface{}) {
|
|
wm.DelayTaskWithoutReqctx(ctx, task, params)
|
|
}
|
|
|
|
func DelayTaskWithWorker(
|
|
ctx context.Context, task workmanager.DelayTaskFunc,
|
|
params interface{}, worker *appsrv.SWorkerManager,
|
|
) {
|
|
wm.DelayTaskWithWorker(ctx, task, params, worker)
|
|
}
|
|
|
|
func InitWorkerManager() {
|
|
InitWorkerManagerWithCount(options.HostOptions.DefaultRequestWorkerCount)
|
|
initImageCacheWorkerManager()
|
|
}
|
|
|
|
func initImageCacheWorkerManager() {
|
|
imageCacheW = workmanager.NewWorkManger("ImageCacheDelayTaskWorkers", TaskFailed, TaskComplete, options.HostOptions.ImageCacheWorkerCount)
|
|
imagePreCacheW = workmanager.NewWorkManger("ImagePrefetchCacheDelayTaskWorkers", TaskFailed, TaskComplete, options.HostOptions.ImageCacheWorkerCount)
|
|
}
|
|
|
|
func initBackupWorkerManager() {
|
|
backupW = workmanager.NewWorkManger("BackupDelayTaskWorkers", TaskFailed, TaskComplete, options.HostOptions.BackupTaskWorkerCount)
|
|
}
|
|
|
|
func InitWorkerManagerWithCount(count int) {
|
|
wm = workmanager.NewWorkManger("GeneralDelayedTaskWorkers", TaskFailed, TaskComplete, count)
|
|
}
|
|
|
|
func InitK8sWorkerManager() {
|
|
k8sWm = workmanager.NewWorkManger("K8sDelayedTaskWorkers", K8sTaskFailed, K8sTaskComplete, options.HostOptions.DefaultRequestWorkerCount)
|
|
}
|
|
|
|
func Init() {
|
|
InitWorkerManager()
|
|
InitK8sWorkerManager()
|
|
initBackupWorkerManager()
|
|
}
|