Merge pull request #7620 from wanyaoqi/feature/wyq/arm-v2

feature: arm support
This commit is contained in:
yunion-ci-robot
2020-10-26 15:50:40 +08:00
committed by GitHub
30 changed files with 217 additions and 26 deletions
+6
View File
@@ -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__"`
+5
View File
@@ -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}
+4
View File
@@ -129,3 +129,7 @@ const (
HOST_HEALTH_STATUS_RUNNING = "running"
HOST_HEALTH_LOCK_PREFIX = "host-health"
)
const (
CPU_ARCH_AARCH64 = "aarch64"
)
+2
View File
@@ -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 {
+1
View File
@@ -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
}
+2 -1
View File
@@ -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 {
+25
View File
@@ -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, "")
}
+8
View File
@@ -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 {
+18 -1
View File
@@ -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, "")
+8
View File
@@ -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
}
+4
View File
@@ -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
+3
View File
@@ -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)
+2
View File
@@ -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 {
+16 -1
View File
@@ -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
}
+19 -1
View File
@@ -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"
}
}
+1 -1
View File
@@ -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,
+6 -3
View File
@@ -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 {
+4 -1
View File
@@ -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)
+1 -1
View File
@@ -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))
}
}
-3
View File
@@ -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")
+28 -7
View File
@@ -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")
}
}
+1
View File
@@ -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"`
+7 -1
View File
@@ -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 {
+2
View File
@@ -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,
+18 -1
View File
@@ -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
+3
View File
@@ -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 {
+11 -3
View File
@@ -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"
}
}
}