mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-08-30 17:13:08 +08:00
support create arm virtual machine
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,此参数会根据存储设置,若不指定,则作为调度的一个参考
|
||||
//
|
||||
//
|
||||
@@ -472,6 +476,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 (
|
||||
CPU_ARCH_X86 = "x86"
|
||||
CPU_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 {
|
||||
|
||||
@@ -78,6 +78,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
|
||||
}
|
||||
|
||||
@@ -361,7 +361,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.CPU_ARCH_ARM
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestChangeVmConfig(ctx context.Context, guest *models.SGuest, task taskman.ITask, instanceType string, vcpuCount, vmemSize int64) error {
|
||||
|
||||
@@ -115,6 +115,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"`
|
||||
}
|
||||
@@ -1688,6 +1691,7 @@ func fillDiskConfigBySnapshot(userCred mcclient.TokenCredential, diskConfig *api
|
||||
diskConfig.Backend = storage.StorageType
|
||||
diskConfig.Fs = ""
|
||||
diskConfig.Mountpoint = ""
|
||||
diskConfig.OsArch = snapshot.OsArch
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1716,6 +1720,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.CPU_ARCH_ARM
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1766,6 +1773,7 @@ func (self *SDisk) fetchDiskInfo(diskConfig *api.DiskConfig) {
|
||||
}
|
||||
self.DiskFormat = diskConfig.Format
|
||||
self.DiskSize = diskConfig.SizeMb
|
||||
self.OsArch = diskConfig.OsArch
|
||||
}
|
||||
|
||||
type DiskInfo struct {
|
||||
|
||||
@@ -195,6 +195,15 @@ func (self *SGuest) PerformSaveImage(ctx context.Context, userCred mcclient.Toke
|
||||
osType = "Linux"
|
||||
}
|
||||
properties.Add(jsonutils.NewString(osType), "os_type")
|
||||
if self.OsArch == api.CPU_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")
|
||||
|
||||
@@ -261,8 +270,16 @@ func (self *SGuest) PerformSaveGuestImage(ctx context.Context, userCred mcclient
|
||||
osType = "Linux"
|
||||
}
|
||||
properties.Add(jsonutils.NewString(osType), "os_type")
|
||||
if self.OsArch == api.CPU_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, "")
|
||||
|
||||
@@ -146,6 +146,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"`
|
||||
@@ -1146,6 +1149,10 @@ func (manager *SGuestManager) validateCreateData(
|
||||
}
|
||||
}
|
||||
|
||||
if arch := imgProperties["os_arch"]; strings.Contains(arch, "aarch") {
|
||||
input.OsArch = api.CPU_ARCH_ARM
|
||||
}
|
||||
|
||||
if len(imgProperties) == 0 {
|
||||
imgProperties = map[string]string{"os_type": "Linux"}
|
||||
}
|
||||
@@ -4867,6 +4874,7 @@ func (self *SGuest) ToSchedDesc() *schedapi.ScheduleInput {
|
||||
|
||||
config.Hypervisor = self.GetHypervisor()
|
||||
desc.ServerConfig = *config
|
||||
desc.OsArch = self.OsArch
|
||||
return desc
|
||||
}
|
||||
|
||||
|
||||
@@ -527,6 +527,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"`
|
||||
@@ -346,6 +347,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,9 +325,17 @@ func (l *sLinuxRootFs) GetOs() string {
|
||||
|
||||
func (l *sLinuxRootFs) GetArch(rootFs IDiskPartition) string {
|
||||
if rootFs.Exists("/lib64", false) && rootFs.Exists("/usr/lib64", false) {
|
||||
return "x86_64"
|
||||
if hostCpuArch == "aarch64" {
|
||||
return "aarch64"
|
||||
} else {
|
||||
return "x86_64"
|
||||
}
|
||||
} else {
|
||||
return "x86"
|
||||
if hostCpuArch == "aarch64" {
|
||||
return "aarch32"
|
||||
} else {
|
||||
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,
|
||||
|
||||
@@ -376,7 +376,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")
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -134,6 +134,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
|
||||
// 从镜像时长导入的镜像校验和
|
||||
|
||||
@@ -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.CPU_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