mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-01 15:07:17 +08:00
Merge pull request #7620 from wanyaoqi/feature/wyq/arm-v2
feature: arm support
This commit is contained in:
@@ -141,6 +141,10 @@ type DiskConfig struct {
|
||||
// requried: false
|
||||
Mountpoint string `json:"mountpoint"`
|
||||
|
||||
// 操作系统CPU架构
|
||||
// required: false
|
||||
OsArch string `json:"os_arch"`
|
||||
|
||||
//后端存储类型,若指定了存储ID,此参数会根据存储设置,若不指定,则作为调度的一个参考
|
||||
//
|
||||
//
|
||||
@@ -492,6 +496,8 @@ type ServerCreateInput struct {
|
||||
// swagger:ignore
|
||||
OsType string `json:"os_type"`
|
||||
// swagger:ignore
|
||||
OsArch string `json:"os_arch"`
|
||||
// swagger:ignore
|
||||
DisableUsbKbd bool `json:"disable_usb_kbd"`
|
||||
// swagger:ignore
|
||||
OsProfile jsonutils.JSONObject `json:"__os_profile__"`
|
||||
|
||||
@@ -170,6 +170,11 @@ const (
|
||||
CPU_MODE_HOST = "host"
|
||||
)
|
||||
|
||||
const (
|
||||
OS_ARCH_X86 = "x86"
|
||||
OS_ARCH_ARM = "arm"
|
||||
)
|
||||
|
||||
var VM_RUNNING_STATUS = []string{VM_START_START, VM_STARTING, VM_RUNNING, VM_BLOCK_STREAM, VM_BLOCK_STREAM_FAIL}
|
||||
var VM_CREATING_STATUS = []string{VM_CREATE_NETWORK, VM_CREATE_DISK, VM_START_DEPLOY, VM_DEPLOYING}
|
||||
|
||||
|
||||
@@ -129,3 +129,7 @@ const (
|
||||
HOST_HEALTH_STATUS_RUNNING = "running"
|
||||
HOST_HEALTH_LOCK_PREFIX = "host-health"
|
||||
)
|
||||
|
||||
const (
|
||||
CPU_ARCH_AARCH64 = "aarch64"
|
||||
)
|
||||
|
||||
@@ -41,6 +41,8 @@ type SnapshotCreateInput struct {
|
||||
OutOfChain bool `json:"out_of_chain"`
|
||||
// swagger:ignore
|
||||
ManagerId string `json:"manager_id"`
|
||||
// swagger:ignore
|
||||
OsArch string `json:"os_arch"`
|
||||
}
|
||||
|
||||
type SSnapshotPolicyCreateInput struct {
|
||||
|
||||
@@ -80,6 +80,7 @@ type ScheduleInput struct {
|
||||
CpuDesc string `json:"cpu_desc"`
|
||||
CpuMicrocode string `json:"cpu_microcode"`
|
||||
CpuMode string `json:"cpu_mode"`
|
||||
OsArch string `json:"os_arch"`
|
||||
|
||||
PendingUsages []jsonutils.JSONObject
|
||||
}
|
||||
|
||||
@@ -364,7 +364,8 @@ func (self *SKVMGuestDriver) RequestAssociateEip(ctx context.Context, userCred m
|
||||
|
||||
func (self *SKVMGuestDriver) NeedStopForChangeSpec(guest *models.SGuest, cpuChanged, memChanged bool) bool {
|
||||
return guest.GetMetadata("hotplug_cpu_mem", nil) != "enable" ||
|
||||
(memChanged && guest.GetMetadata("__hugepage", nil) == "native")
|
||||
(memChanged && guest.GetMetadata("__hugepage", nil) == "native") ||
|
||||
guest.OsArch == api.OS_ARCH_ARM
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestChangeVmConfig(ctx context.Context, guest *models.SGuest, task taskman.ITask, instanceType string, vcpuCount, vmemSize int64) error {
|
||||
|
||||
@@ -55,6 +55,7 @@ type SCapabilities struct {
|
||||
StorageTypes []string `json:",allowempty"` // going to remove on 2.14
|
||||
DataStorageTypes []string `json:",allowempty"` // going to remove on 2.14
|
||||
GPUModels []string `json:",allowempty"`
|
||||
HostCpuArchs []string `json:",allowempty"` // x86_64 aarch64
|
||||
MinNicCount int
|
||||
MaxNicCount int
|
||||
MinDataDiskCount int
|
||||
@@ -121,6 +122,7 @@ func GetCapabilities(ctx context.Context, userCred mcclient.TokenCredential, que
|
||||
capa.MaxDataDiskCount = getMaxDataDiskCount(region, zone)
|
||||
capa.DBInstance = getDBInstanceInfo(region, zone)
|
||||
capa.Usable = isUsable(ownerId, scope, region, zone)
|
||||
capa.HostCpuArchs = getHostCpuArchs(region, zone, domainId)
|
||||
if query == nil {
|
||||
query = jsonutils.NewDict()
|
||||
}
|
||||
@@ -617,6 +619,29 @@ func getGPUs(region *SCloudregion, zone *SZone, domainId string) []string {
|
||||
return gpus
|
||||
}
|
||||
|
||||
func getHostCpuArchs(region *SCloudregion, zone *SZone, domainId string) []string {
|
||||
q := HostManager.Query("cpu_architecture").Equals("enabled", true).
|
||||
Equals("host_status", "online").Equals("host_type", api.HOST_TYPE_HYPERVISOR)
|
||||
if len(domainId) > 0 {
|
||||
ownerId := &db.SOwnerId{DomainId: domainId}
|
||||
q = HostManager.FilterByOwner(q, ownerId, rbacutils.ScopeDomain)
|
||||
}
|
||||
if zone != nil {
|
||||
q = q.Equals("zone_id", zone.Id)
|
||||
}
|
||||
if region != nil {
|
||||
subq := ZoneManager.Query("id").Equals("cloudregion_id", region.Id).SubQuery()
|
||||
q = q.Filter(sqlchemy.In(q.Field("zone_id"), subq))
|
||||
}
|
||||
q = q.Distinct()
|
||||
res := []string{}
|
||||
if err := q.All(&res); err != nil && err != sql.ErrNoRows {
|
||||
log.Errorf("failed fetch host cpu archs %s", err)
|
||||
return nil
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func getNetworkCount(ownerId mcclient.IIdentityProvider, scope rbacutils.TRbacScope, region *SCloudregion, zone *SZone) (int, error) {
|
||||
return getNetworkCountByFilter(ownerId, scope, region, zone, tristate.None, "")
|
||||
}
|
||||
|
||||
@@ -116,6 +116,9 @@ type SDisk struct {
|
||||
// example: sys
|
||||
DiskType string `width:"32" charset:"ascii" nullable:"true" list:"user" update:"admin" json:"disk_type"`
|
||||
|
||||
// cpu架构
|
||||
OsArch string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional"`
|
||||
|
||||
// # is persistent
|
||||
Nonpersistent bool `default:"false" list:"user" json:"nonpersistent"`
|
||||
|
||||
@@ -1699,6 +1702,7 @@ func fillDiskConfigBySnapshot(userCred mcclient.TokenCredential, diskConfig *api
|
||||
diskConfig.Backend = storage.StorageType
|
||||
diskConfig.Fs = ""
|
||||
diskConfig.Mountpoint = ""
|
||||
diskConfig.OsArch = snapshot.OsArch
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1727,6 +1731,9 @@ func fillDiskConfigByImage(ctx context.Context, userCred mcclient.TokenCredentia
|
||||
if diskConfig.SizeMb != api.DISK_SIZE_AUTOEXTEND && diskConfig.SizeMb < image.MinDiskMB {
|
||||
diskConfig.SizeMb = image.MinDiskMB // MB
|
||||
}
|
||||
if strings.Contains(image.Properties["os_arch"], "aarch") {
|
||||
diskConfig.OsArch = api.OS_ARCH_ARM
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1777,6 +1784,7 @@ func (self *SDisk) fetchDiskInfo(diskConfig *api.DiskConfig) {
|
||||
}
|
||||
self.DiskFormat = diskConfig.Format
|
||||
self.DiskSize = diskConfig.SizeMb
|
||||
self.OsArch = diskConfig.OsArch
|
||||
}
|
||||
|
||||
type DiskInfo struct {
|
||||
|
||||
@@ -198,6 +198,15 @@ func (self *SGuest) PerformSaveImage(ctx context.Context, userCred mcclient.Toke
|
||||
osType = "Linux"
|
||||
}
|
||||
properties.Add(jsonutils.NewString(osType), "os_type")
|
||||
if self.OsArch == api.OS_ARCH_ARM {
|
||||
var osArch string
|
||||
if osArch = self.GetMetadata("os_arch", nil); len(osArch) == 0 {
|
||||
host := self.GetHost()
|
||||
osArch = host.CpuArchitecture
|
||||
}
|
||||
properties.Add(jsonutils.NewString(osArch), "os_arch")
|
||||
kwargs.Set("os_arch", jsonutils.NewString(self.OsArch))
|
||||
}
|
||||
kwargs.Add(properties, "properties")
|
||||
kwargs.Add(jsonutils.NewBool(restart), "restart")
|
||||
|
||||
@@ -264,8 +273,16 @@ func (self *SGuest) PerformSaveGuestImage(ctx context.Context, userCred mcclient
|
||||
osType = "Linux"
|
||||
}
|
||||
properties.Add(jsonutils.NewString(osType), "os_type")
|
||||
if self.OsArch == api.OS_ARCH_ARM {
|
||||
var osArch string
|
||||
if osArch = self.GetMetadata("os_arch", nil); len(osArch) == 0 {
|
||||
host := self.GetHost()
|
||||
osArch = host.CpuArchitecture
|
||||
}
|
||||
properties.Add(jsonutils.NewString(osArch), "os_arch")
|
||||
kwargs.Set("os_arch", jsonutils.NewString(self.OsArch))
|
||||
}
|
||||
kwargs.Add(properties, "properties")
|
||||
|
||||
kwargs.Add(images, "images")
|
||||
|
||||
s := auth.GetSession(ctx, userCred, options.Options.Region, "")
|
||||
|
||||
@@ -147,6 +147,9 @@ type SGuest struct {
|
||||
// 虚拟化技术
|
||||
// example: kvm
|
||||
Hypervisor string `width:"16" charset:"ascii" nullable:"false" default:"kvm" list:"user" create:"required"`
|
||||
// 虚拟机CPU架构
|
||||
// example: x86 arm
|
||||
OsArch string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional"`
|
||||
|
||||
// 套餐名称
|
||||
InstanceType string `width:"64" charset:"utf8" nullable:"true" list:"user" create:"optional"`
|
||||
@@ -1165,6 +1168,10 @@ func (manager *SGuestManager) validateCreateData(
|
||||
}
|
||||
}
|
||||
|
||||
if arch := imgProperties["os_arch"]; strings.Contains(arch, "aarch") {
|
||||
input.OsArch = api.OS_ARCH_ARM
|
||||
}
|
||||
|
||||
if len(imgProperties) == 0 {
|
||||
imgProperties = map[string]string{"os_type": "Linux"}
|
||||
}
|
||||
@@ -4950,6 +4957,7 @@ func (self *SGuest) ToSchedDesc() *schedapi.ScheduleInput {
|
||||
|
||||
config.Hypervisor = self.GetHypervisor()
|
||||
desc.ServerConfig = *config
|
||||
desc.OsArch = self.OsArch
|
||||
return desc
|
||||
}
|
||||
|
||||
|
||||
@@ -528,6 +528,10 @@ func (manager *SHostManager) CustomizeFilterList(ctx context.Context, q *sqlchem
|
||||
return filters, nil
|
||||
}
|
||||
|
||||
func (self *SHost) IsArmHost() bool {
|
||||
return self.CpuArchitecture == api.CPU_ARCH_AARCH64
|
||||
}
|
||||
|
||||
func (self *SHost) GetZone() *SZone {
|
||||
if len(self.ZoneId) == 0 {
|
||||
return nil
|
||||
|
||||
@@ -66,6 +66,8 @@ type SInstanceSnapshot struct {
|
||||
KeypairId string `width:"36" charset:"ascii" nullable:"true" list:"user"`
|
||||
// 操作系统类型
|
||||
OsType string `width:"36" charset:"ascii" nullable:"true" list:"user"`
|
||||
// CPU架构
|
||||
OsArch string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional"`
|
||||
// 套餐名称
|
||||
InstanceType string `width:"64" charset:"utf8" nullable:"true" list:"user" create:"optional"`
|
||||
}
|
||||
@@ -283,6 +285,7 @@ func (manager *SInstanceSnapshotManager) CreateInstanceSnapshot(
|
||||
instanceSnapshot.SecGroups = jsonutils.Marshal(secIds)
|
||||
}
|
||||
instanceSnapshot.OsType = guest.OsType
|
||||
instanceSnapshot.OsArch = guest.OsArch
|
||||
instanceSnapshot.ServerMetadata = serverMetadata
|
||||
instanceSnapshot.InstanceType = guest.InstanceType
|
||||
err := manager.TableSpec().Insert(ctx, instanceSnapshot)
|
||||
|
||||
@@ -72,6 +72,7 @@ type SSnapshot struct {
|
||||
DiskType string `width:"32" charset:"ascii" nullable:"true" list:"user" create:"optional"`
|
||||
// 操作系统类型
|
||||
OsType string `width:"32" charset:"ascii" nullable:"true" list:"user" create:"optional"`
|
||||
OsArch string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional"`
|
||||
|
||||
// create disk from snapshot, snapshot as disk backing file
|
||||
RefCount int `nullable:"false" default:"0" list:"user"`
|
||||
@@ -357,6 +358,7 @@ func (manager *SSnapshotManager) ValidateCreateData(
|
||||
input.DiskId = disk.Id
|
||||
input.DiskType = disk.DiskType
|
||||
input.Size = disk.DiskSize
|
||||
input.OsArch = disk.OsArch
|
||||
|
||||
storage := disk.GetStorage()
|
||||
if len(disk.ExternalId) == 0 {
|
||||
|
||||
@@ -14,18 +14,27 @@
|
||||
|
||||
package fsdriver
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/util/procutils"
|
||||
)
|
||||
|
||||
type newRootFsDriverFunc func(part IDiskPartition) IRootFsDriver
|
||||
|
||||
var (
|
||||
privatePrefixes []string
|
||||
rootfsDrivers = make([]newRootFsDriverFunc, 0)
|
||||
hostCpuArch string
|
||||
)
|
||||
|
||||
func GetRootfsDrivers() []newRootFsDriverFunc {
|
||||
return rootfsDrivers
|
||||
}
|
||||
|
||||
func Init(initPrivatePrefixes []string) {
|
||||
func Init(initPrivatePrefixes []string) error {
|
||||
if len(initPrivatePrefixes) > 0 {
|
||||
privatePrefixes = make([]string, len(initPrivatePrefixes))
|
||||
copy(privatePrefixes, initPrivatePrefixes)
|
||||
@@ -41,4 +50,10 @@ func Init(initPrivatePrefixes []string) {
|
||||
rootfsDrivers = append(rootfsDrivers, NewEsxiRootFs)
|
||||
rootfsDrivers = append(rootfsDrivers, NewWindowsRootFs)
|
||||
rootfsDrivers = append(rootfsDrivers, NewAndroidRootFs)
|
||||
cpuArch, err := procutils.NewCommand("uname", "-m").Output()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "get cpu architecture")
|
||||
}
|
||||
hostCpuArch = strings.TrimSpace(string(cpuArch))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
@@ -325,8 +325,26 @@ func (l *sLinuxRootFs) GetOs() string {
|
||||
|
||||
func (l *sLinuxRootFs) GetArch(rootFs IDiskPartition) string {
|
||||
if rootFs.Exists("/lib64", false) && rootFs.Exists("/usr/lib64", false) {
|
||||
files := rootFs.ListDir("/lib64", false)
|
||||
for i := 0; i < len(files); i++ {
|
||||
if strings.HasPrefix(files[i], "ld-") {
|
||||
if strings.Contains(files[i], "aarch64") {
|
||||
return "aarch64"
|
||||
} else if strings.Contains(files[i], "x86") {
|
||||
return "x86_64"
|
||||
}
|
||||
}
|
||||
}
|
||||
return "x86_64"
|
||||
} else {
|
||||
files := rootFs.ListDir("/lib", false)
|
||||
for i := 0; i < len(files); i++ {
|
||||
if strings.HasPrefix(files[i], "ld-") {
|
||||
if strings.Contains(files[i], "arm") {
|
||||
return "aarch32"
|
||||
}
|
||||
}
|
||||
}
|
||||
return "x86"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ func (w *SWindowsRootFs) GetReleaseInfo(IDiskPartition) *deployapi.ReleaseInfo {
|
||||
if tool.CheckPath() {
|
||||
distro := tool.GetProductName()
|
||||
version := tool.GetVersion()
|
||||
arch := tool.GetArch()
|
||||
arch := tool.GetArch(hostCpuArch)
|
||||
lan := tool.GetInstallLanguage()
|
||||
return &deployapi.ReleaseInfo{
|
||||
Distro: distro,
|
||||
|
||||
@@ -246,7 +246,9 @@ func (m *SGuestManager) StartCpusetBalancer() {
|
||||
}
|
||||
|
||||
func (m *SGuestManager) cpusetBalance() {
|
||||
cgrouputils.RebalanceProcesses(nil)
|
||||
if !options.HostOptions.DisableSetCgroup {
|
||||
cgrouputils.RebalanceProcesses(nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *SGuestManager) IsGuestDir(f os.FileInfo) bool {
|
||||
@@ -841,8 +843,9 @@ func (m *SGuestManager) ExitGuestCleanup() {
|
||||
guest.ExitCleanup(false)
|
||||
return true
|
||||
})
|
||||
|
||||
cgrouputils.CgroupCleanAll()
|
||||
if !options.HostOptions.DisableSetCgroup {
|
||||
cgrouputils.CgroupCleanAll()
|
||||
}
|
||||
}
|
||||
|
||||
func (m *SGuestManager) GetHost() hostutils.IHost {
|
||||
|
||||
@@ -606,7 +606,10 @@ func (s *SGuestResumeTask) onStartRunning() {
|
||||
s.OnResumeSyncMetadataInfo()
|
||||
s.optimizeOom()
|
||||
s.doBlockIoThrottle()
|
||||
timeutils2.AddTimeout(time.Second*5, s.SetCgroup)
|
||||
if !options.HostOptions.DisableSetCgroup {
|
||||
timeutils2.AddTimeout(time.Second*5, s.SetCgroup)
|
||||
}
|
||||
|
||||
disksIdx := s.GetNeedMergeBackingFileDiskIndexs()
|
||||
if len(disksIdx) > 0 {
|
||||
s.startStreamDisks(disksIdx)
|
||||
|
||||
@@ -620,7 +620,7 @@ func (s *SKVMGuestInstance) clearCgroup(pid int) {
|
||||
pid = s.cgroupPid
|
||||
}
|
||||
log.Infof("cgroup destroy %d", pid)
|
||||
if pid > 0 {
|
||||
if pid > 0 && !options.HostOptions.DisableSetCgroup {
|
||||
cgrouputils.CgroupDestroy(strconv.Itoa(pid))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/hostman/storageman"
|
||||
"yunion.io/x/onecloud/pkg/hostman/storageman/diskhandlers"
|
||||
"yunion.io/x/onecloud/pkg/hostman/storageman/storagehandler"
|
||||
"yunion.io/x/onecloud/pkg/hostman/system_service"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/util/procutils"
|
||||
"yunion.io/x/onecloud/pkg/util/sysutils"
|
||||
@@ -70,8 +69,6 @@ func (host *SHostService) InitService() {
|
||||
execlient.Init(options.HostOptions.ExecutorSocketPath)
|
||||
procutils.SetRemoteExecutor()
|
||||
}
|
||||
|
||||
system_service.Init()
|
||||
}
|
||||
|
||||
func (host *SHostService) OnExitService() {}
|
||||
|
||||
@@ -382,7 +382,9 @@ func (s *SDeployService) InitService() {
|
||||
if err := s.PrepareEnv(); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
fsdriver.Init(DeployOption.PrivatePrefixes)
|
||||
if err := fsdriver.Init(DeployOption.PrivatePrefixes); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
s.O = &DeployOption.BaseOptions
|
||||
if len(DeployOption.DeployServerSocketPath) == 0 {
|
||||
log.Fatalf("missing deploy server socket path")
|
||||
|
||||
@@ -166,6 +166,11 @@ func (h *SHostInfo) Init() error {
|
||||
if err := h.detectHostInfo(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := hostbridge.Prepare(options.HostOptions.BridgeDriver); err != nil {
|
||||
log.Errorln(err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -337,13 +342,10 @@ func (h *SHostInfo) prepareEnv() error {
|
||||
if err != nil {
|
||||
log.Errorf("modprobe error: %s", output)
|
||||
}
|
||||
if !cgrouputils.Init() {
|
||||
return fmt.Errorf("Cannot initialize control group subsystem")
|
||||
}
|
||||
|
||||
if err := hostbridge.Prepare(options.HostOptions.BridgeDriver); err != nil {
|
||||
log.Errorln(err)
|
||||
return err
|
||||
if !options.HostOptions.DisableSetCgroup {
|
||||
if !cgrouputils.Init() {
|
||||
return fmt.Errorf("Cannot initialize control group subsystem")
|
||||
}
|
||||
}
|
||||
|
||||
// err = h.resetIptables()
|
||||
@@ -400,6 +402,7 @@ func (h *SHostInfo) detectHostInfo() error {
|
||||
|
||||
h.detectStorageSystem()
|
||||
|
||||
system_service.Init()
|
||||
if options.HostOptions.CheckSystemServices {
|
||||
if err := h.checkSystemServices(); err != nil {
|
||||
return err
|
||||
@@ -606,6 +609,24 @@ func (h *SHostInfo) detectOsDist() {
|
||||
log.Infof("DetectOsDist %s %s", h.sysinfo.OsDistribution, h.sysinfo.OsVersion)
|
||||
if len(h.sysinfo.OsDistribution) == 0 {
|
||||
log.Errorln("Failed to detect distribution info")
|
||||
content, err := procutils.NewRemoteCommandAsFarAsPossible("cat", "/etc/os-release").Output()
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
}
|
||||
for _, line := range strings.Split(string(content), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if strings.HasPrefix(line, "ID=") {
|
||||
h.sysinfo.OsDistribution = line[3:]
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(line, "VERSION=") {
|
||||
h.sysinfo.OsVersion = strings.Trim(line[8:], "\"")
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
if utils.IsInStringArray(h.sysinfo.OsDistribution, []string{"uos", "debian", "ubuntu"}) {
|
||||
system_service.SetOpenvswitchName("openvswitch-switch")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@ type SHostOptions struct {
|
||||
WindowsDefaultAdminUser bool `default:"true" help:"Default account for Windows system is Administrator"`
|
||||
|
||||
HostCpuPassthrough bool `default:"true" help:"if it is true, set qemu cpu type as -cpu host, otherwise, qemu64. default is true"`
|
||||
DisableSetCgroup bool `default:"false" help:"disable cgroup for guests"`
|
||||
|
||||
MaxReservedMemory int `default:"10240" help:"host reserved memory"`
|
||||
|
||||
|
||||
@@ -18,8 +18,14 @@ type SOpenvswitch struct {
|
||||
*SBaseSystemService
|
||||
}
|
||||
|
||||
var openvswitch = "openvswitch"
|
||||
|
||||
func SetOpenvswitchName(name string) {
|
||||
openvswitch = name
|
||||
}
|
||||
|
||||
func NewOpenvswitchService() *SOpenvswitch {
|
||||
return &SOpenvswitch{NewBaseSystemService("openvswitch", nil)}
|
||||
return &SOpenvswitch{NewBaseSystemService(openvswitch, nil)}
|
||||
}
|
||||
|
||||
func (s *SOpenvswitch) Reload(kwargs map[string]interface{}) error {
|
||||
|
||||
@@ -67,6 +67,8 @@ type SGuestImage struct {
|
||||
db.SSharableVirtualResourceBase
|
||||
|
||||
Protected tristate.TriState `nullable:"false" default:"true" list:"user" get:"user" create:"optional" update:"user"`
|
||||
// 操作系统CPU架构
|
||||
OsArch string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional"`
|
||||
}
|
||||
|
||||
func (manager *SGuestImageManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
|
||||
@@ -36,6 +36,7 @@ import (
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
api "yunion.io/x/onecloud/pkg/apis/image"
|
||||
"yunion.io/x/onecloud/pkg/appsrv"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
@@ -134,6 +135,8 @@ type SImage struct {
|
||||
IsGuestImage tristate.TriState `nullable:"false" default:"false" create:"optional" list:"user"`
|
||||
// 是否是数据盘镜像
|
||||
IsData tristate.TriState `nullable:"false" default:"false" create:"optional" list:"user"`
|
||||
// 操作系统CPU架构
|
||||
OsArch string `width:"16" charset:"ascii" nullable:"true" list:"user" create:"optional"`
|
||||
|
||||
// image copy from url, save origin checksum before probe
|
||||
// 从镜像时长导入的镜像校验和
|
||||
@@ -547,6 +550,21 @@ func (self *SImage) PostCreate(ctx context.Context, userCred mcclient.TokenCrede
|
||||
quotas.CancelPendingUsage(ctx, userCred, &pendingUsage, &cancelUsage, true)
|
||||
}
|
||||
|
||||
detectedProperties, err := ImagePropertyManager.GetProperties(self.Id)
|
||||
if err == nil {
|
||||
if osArch := detectedProperties[api.IMAGE_OS_ARCH]; strings.Contains(osArch, "aarch") {
|
||||
props, _ := data.Get("properties")
|
||||
if props != nil {
|
||||
dict := props.(*jsonutils.JSONDict)
|
||||
dict.Set(api.IMAGE_OS_ARCH, jsonutils.NewString(osArch))
|
||||
}
|
||||
db.Update(self, func() error {
|
||||
self.OsArch = compute.OS_ARCH_ARM
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if data.Contains("properties") {
|
||||
// update properties
|
||||
props, _ := data.Get("properties")
|
||||
@@ -575,7 +593,6 @@ func (self *SImage) PostCreate(ctx context.Context, userCred mcclient.TokenCrede
|
||||
self.startImageCopyFromUrlTask(ctx, userCred, copyFrom, "")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// After image probe and customization, image size and checksum changed
|
||||
|
||||
@@ -131,6 +131,9 @@ func (self *ImageProbeTask) updateImageMetadata(
|
||||
|
||||
func (self *ImageProbeTask) updateImageInfo(ctx context.Context, image *models.SImage, imageInfo *deployapi.ImageInfo) {
|
||||
imageProperties := jsonutils.Marshal(imageInfo.OsInfo).(*jsonutils.JSONDict)
|
||||
if len(imageInfo.OsInfo.Arch) > 0 {
|
||||
imageProperties.Set(api.IMAGE_OS_ARCH, jsonutils.NewString(imageInfo.OsInfo.Arch))
|
||||
}
|
||||
if len(imageInfo.OsType) > 0 {
|
||||
imageProperties.Set(api.IMAGE_OS_TYPE, jsonutils.NewString(imageInfo.OsType))
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ const (
|
||||
ErrSubtotalOfSplitExceedsDiskSize = `subtotal of split exceeds disk size`
|
||||
ErrBaremetalHasAlreadyBeenOccupied = `baremetal has already been occupied`
|
||||
ErrPrepaidHostOccupied = `prepaid host occupied`
|
||||
ErrHostCpuArchitectureNotMatch = `host cpu architecture not match`
|
||||
|
||||
ErrUnknown = `unknown error`
|
||||
)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package guest
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/scheduler/algorithm/predicates"
|
||||
"yunion.io/x/onecloud/pkg/scheduler/core"
|
||||
)
|
||||
@@ -53,6 +54,13 @@ func (f *CPUPredicate) Execute(u *core.Unit, c core.Candidater) (bool, []core.Pr
|
||||
|
||||
useRsvd := h.UseReserved()
|
||||
getter := c.Getter()
|
||||
if d.OsArch == compute.OS_ARCH_ARM {
|
||||
host := getter.Host()
|
||||
if !host.IsArmHost() {
|
||||
h.Exclude(predicates.ErrHostCpuArchitectureNotMatch)
|
||||
return h.GetResult()
|
||||
}
|
||||
}
|
||||
freeCPUCount := getter.FreeCPUCount(useRsvd)
|
||||
reqCPUCount := int64(d.Ncpu)
|
||||
if freeCPUCount < reqCPUCount {
|
||||
|
||||
@@ -605,13 +605,21 @@ func (w *SWinRegTool) GetInstallLanguage() string {
|
||||
}
|
||||
}
|
||||
|
||||
func (w *SWinRegTool) GetArch() string {
|
||||
func (w *SWinRegTool) GetArch(hostCpuArch string) string {
|
||||
prodKey := `HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\CurrentVersion`
|
||||
ver := w.GetRegistry(prodKey)
|
||||
if len(ver) > 0 {
|
||||
return "x86_64"
|
||||
if hostCpuArch == "aarch64" {
|
||||
return "aarch64"
|
||||
} else {
|
||||
return "x86_64"
|
||||
}
|
||||
} else {
|
||||
return "x86"
|
||||
if hostCpuArch == "aarch64" {
|
||||
return "aarch32"
|
||||
} else {
|
||||
return "x86"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user