diff --git a/cmd/climc/shell/cloud_sku_rates.go b/cmd/climc/shell/cloud_sku_rates.go new file mode 100644 index 0000000000..d91d8f86b7 --- /dev/null +++ b/cmd/climc/shell/cloud_sku_rates.go @@ -0,0 +1,30 @@ +package shell + +import ( + "yunion.io/x/jsonutils" + "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/onecloud/pkg/mcclient/modules" +) + +func init() { + + type CloudSkuRateListOptions struct { + ParamIds []string `help:"param_id of the cloudSkuRate" nargs:"+"` + ParamKeys []string `help:"param_key of the cloudSkuRate" nargs:"+"` + } + + R(&CloudSkuRateListOptions{}, "cloud-sku-rate-list", "list cloud-sku-rates", func(s *mcclient.ClientSession, args *CloudSkuRateListOptions) error { + + params := jsonutils.NewDict() + params.Add(jsonutils.NewStringArray(args.ParamIds), "param_ids") + params.Add(jsonutils.NewStringArray(args.ParamKeys), "param_keys") + + result, err := modules.CloudSkuRates.List(s, params) + if err != nil { + return err + } + + printList(result, modules.CloudSkuRates.GetColumns(s)) + return nil + }) +} diff --git a/cmd/climc/shell/hosts.go b/cmd/climc/shell/hosts.go index 5ae2b87798..6dc6fc2736 100644 --- a/cmd/climc/shell/hosts.go +++ b/cmd/climc/shell/hosts.go @@ -25,6 +25,8 @@ func init() { HostType string `help:"Host type filter" choices:"baremetal|hypervisor|esxi|kubelet|hyperv|aliyun|azure|qcloud|aws|huawei"` AnyMac string `help:"Mac matches one of the host's interface"` + IsBaremetal *bool `help:"filter host list by is_baremetal=true|false"` + ResourceType string `help:"Resource type" choices:"shared|prepaid|dedicated"` Usable *bool `help:"List all zones that is usable"` diff --git a/pkg/baremetal/manager.go b/pkg/baremetal/manager.go index d2b119eedd..2fb7e50a39 100644 --- a/pkg/baremetal/manager.go +++ b/pkg/baremetal/manager.go @@ -600,13 +600,18 @@ func (b *SBaremetalInstance) NeedPXEBoot() bool { taskNeedPXEBoot = true } ret := false - if taskNeedPXEBoot || (task == nil && len(serverId) == 0) { + if taskNeedPXEBoot || (task == nil && len(serverId) == 0 && b.GetHostType() == "baremetal") { ret = true } log.Infof("Check task %s, server %s NeedPXEBoot: %v", taskName, serverId, ret) return ret } +func (b *SBaremetalInstance) GetHostType() string { + hostType, _ := b.desc.GetString("host_type") + return hostType +} + func (b *SBaremetalInstance) GetIPMINic(cliMac net.HardwareAddr) *types.SNic { nic := b.getNicByType(types.NIC_TYPE_IPMI) if nic == nil { diff --git a/pkg/baremetal/pxe/dhcp.go b/pkg/baremetal/pxe/dhcp.go index fbced04507..deb283094f 100644 --- a/pkg/baremetal/pxe/dhcp.go +++ b/pkg/baremetal/pxe/dhcp.go @@ -217,6 +217,7 @@ func (h *DHCPHandler) createOrUpdateBaremetal() (jsonutils.JSONObject, error) { params := jsonutils.NewDict() params.Add(jsonutils.NewString(models.HOST_TYPE_BAREMETAL), "host_type") params.Add(jsonutils.NewString(h.ClientMac.String()), "any_mac") + params.Add(jsonutils.JSONTrue, "is_baremetal") ret, err := modules.Hosts.List(session, params) if err != nil { return nil, err @@ -260,7 +261,7 @@ func (h *DHCPHandler) updateBaremetal(id string) (jsonutils.JSONObject, error) { params := jsonutils.NewDict() params.Add(jsonutils.NewString(h.ClientMac.String()), "access_mac") params.Add(jsonutils.NewString(h.baremetalManager.GetZoneId()), "zone_id") - params.Add(jsonutils.NewString("baremetal"), "host_type") + // params.Add(jsonutils.NewString("baremetal"), "host_type") params.Add(jsonutils.JSONTrue, "is_baremetal") session := h.baremetalManager.GetClientSession() desc, err := modules.Hosts.Update(session, id, params) diff --git a/pkg/cloudprovider/instance.go b/pkg/cloudprovider/instance.go index 61929f17b0..ea83502983 100644 --- a/pkg/cloudprovider/instance.go +++ b/pkg/cloudprovider/instance.go @@ -17,6 +17,8 @@ type SDiskInfo struct { type SManagedVMCreateConfig struct { Name string ExternalImageId string + ImageType string + OsType string OsDistribution string OsVersion string InstanceType string // InstanceType 不为空时,直接采用InstanceType创建机器。 diff --git a/pkg/compute/guestdrivers/aliyun.go b/pkg/compute/guestdrivers/aliyun.go index 03cceae0f6..dda30729f8 100644 --- a/pkg/compute/guestdrivers/aliyun.go +++ b/pkg/compute/guestdrivers/aliyun.go @@ -8,6 +8,7 @@ import ( "yunion.io/x/pkg/utils" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" @@ -137,6 +138,14 @@ func (self *SAliyunGuestDriver) GetGuestInitialStateAfterRebuild() string { return models.VM_READY } +func (self *SAliyunGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string { + userName := "root" + if desc.ImageType == "system" && desc.OsType == "Windows" { + userName = "Administrator" + } + return userName +} + /* func (self *SAliyunGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams()) if err != nil { @@ -150,6 +159,11 @@ func (self *SAliyunGuestDriver) GetGuestInitialStateAfterRebuild() string { return err } + userName := "root" + if desc.ImageType == "system" && desc.OsType == "Windows" { + userName = "Administrator" + } + action, err := config.GetString("action") if err != nil { return err @@ -182,7 +196,7 @@ func (self *SAliyunGuestDriver) GetGuestInitialStateAfterRebuild() string { return nil, err } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) + data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action) return data, nil }) @@ -212,7 +226,7 @@ func (self *SAliyunGuestDriver) GetGuestInitialStateAfterRebuild() string { return nil, err } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) + data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action) return data, nil }) @@ -273,7 +287,7 @@ func (self *SAliyunGuestDriver) GetGuestInitialStateAfterRebuild() string { } } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) + data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action) return data, nil }) diff --git a/pkg/compute/guestdrivers/aws.go b/pkg/compute/guestdrivers/aws.go index 72cd8e1cd3..f473b4c871 100644 --- a/pkg/compute/guestdrivers/aws.go +++ b/pkg/compute/guestdrivers/aws.go @@ -3,13 +3,16 @@ package guestdrivers import ( "context" "fmt" + "strings" "yunion.io/x/jsonutils" + "yunion.io/x/pkg/utils" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/billing" - "yunion.io/x/pkg/utils" ) type SAwsGuestDriver struct { @@ -21,6 +24,39 @@ func init() { models.RegisterGuestDriver(&driver) } +func fetchAwsUserName(desc cloudprovider.SManagedVMCreateConfig) string { + // 非公有云官方镜像 + if desc.ImageType != "system" { + return "root" + } + + // 公有云官方镜像 + dist := strings.ToLower(desc.OsDistribution) + if strings.Contains(dist, "centos") { + return "centos" + } else if strings.Contains(dist, "ubuntu") { + return "ubuntu" + } else if strings.Contains(dist, "windows") { + return "Administrator" + } else if strings.Contains(dist, "debian") { + return "admin" + } else if strings.Contains(dist, "suse") { + return "ec2-user" + } else if strings.Contains(dist, "fedora") { + return "ec2-user" + } else if strings.Contains(dist, "rhel") || strings.Contains(dist, "redhat") { + return "ec2-user" + } else if strings.Contains(dist, "amazon linux") { + return "ec2-user" + } else { + return "ec2-user" + } +} + +func (self *SAwsGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string { + return fetchAwsUserName(desc) +} + func (self *SAwsGuestDriver) GetHypervisor() string { return models.HYPERVISOR_AWS } @@ -128,6 +164,8 @@ func (self *SAwsGuestDriver) GetGuestInitialStateAfterRebuild() string { return err } + username := fetchAwsUserName(desc) + switch action { case "create": taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) { @@ -152,7 +190,7 @@ func (self *SAwsGuestDriver) GetGuestInitialStateAfterRebuild() string { return nil, err } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) + data := fetchIVMinfo(desc, iVM, guest.Id, username, desc.Password, action) return data, nil }) case "deploy": @@ -172,7 +210,7 @@ func (self *SAwsGuestDriver) GetGuestInitialStateAfterRebuild() string { return nil, err } - data := fetchIVMinfo(desc, iVM, guest.Id, ansible.PUBLIC_CLOUD_ANSIBLE_USER, desc.Password, action) + data := fetchIVMinfo(desc, iVM, guest.Id, username, desc.Password, action) return data, nil }) case "rebuild": @@ -224,7 +262,7 @@ func (self *SAwsGuestDriver) GetGuestInitialStateAfterRebuild() string { } } - data := fetchIVMinfo(desc, iVM, guest.Id, ansible.PUBLIC_CLOUD_ANSIBLE_USER, desc.Password, action) + data := fetchIVMinfo(desc, iVM, guest.Id, username, desc.Password, action) return data, nil }) diff --git a/pkg/compute/guestdrivers/azure.go b/pkg/compute/guestdrivers/azure.go index 71fb00dd8d..dc93fcd1d9 100644 --- a/pkg/compute/guestdrivers/azure.go +++ b/pkg/compute/guestdrivers/azure.go @@ -132,7 +132,7 @@ func (self *SAzureGuestDriver) GetGuestInitialStateAfterRebuild() string { return models.VM_READY } -func (self *SAzureGuestDriver) GetLinuxDefaultAccount() string { +func (self *SAzureGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string { return ansible.PUBLIC_CLOUD_ANSIBLE_USER } diff --git a/pkg/compute/guestdrivers/base.go b/pkg/compute/guestdrivers/base.go index 546b4b87d0..d771f6c59c 100644 --- a/pkg/compute/guestdrivers/base.go +++ b/pkg/compute/guestdrivers/base.go @@ -257,8 +257,12 @@ func (self *SBaseGuestDriver) GetGuestInitialStateAfterRebuild() string { return models.VM_READY } -func (self *SBaseGuestDriver) GetLinuxDefaultAccount() string { - return "root" +func (self *SBaseGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string { + userName := "root" + if desc.ImageType == "system" && desc.OsType == "Windows" { + userName = "Administrator" + } + return userName } func (self *SBaseGuestDriver) OnGuestChangeCpuMemFailed(ctx context.Context, guest *models.SGuest, data *jsonutils.JSONDict, task taskman.ITask) error { diff --git a/pkg/compute/guestdrivers/huawei.go b/pkg/compute/guestdrivers/huawei.go index 2fa4f96868..5a3831cedf 100644 --- a/pkg/compute/guestdrivers/huawei.go +++ b/pkg/compute/guestdrivers/huawei.go @@ -8,6 +8,7 @@ import ( "yunion.io/x/pkg/utils" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/billing" @@ -99,6 +100,19 @@ func (self *SHuaweiGuestDriver) GetGuestInitialStateAfterRebuild() string { return models.VM_RUNNING } +func (self *SHuaweiGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string { + userName := "root" + if desc.ImageType == "system" { + if desc.OsDistribution == "Ubuntu" { + userName = "ubuntu" + } + if desc.OsType == "Windows" { + userName = "Administrator" + } + } + return userName +} + /* func (self *SHuaweiGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams()) @@ -113,6 +127,16 @@ func (self *SHuaweiGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu return err } + userName := "root" + if desc.ImageType == "system" { + if desc.OsDistribution == "Ubuntu" { + userName = "ubuntu" + } + if desc.OsType == "Windows" { + userName = "Administrator" + } + } + action, err := config.GetString("action") if err != nil { return err @@ -145,7 +169,7 @@ func (self *SHuaweiGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu return nil, err } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) + data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action) return data, nil }) @@ -174,7 +198,7 @@ func (self *SHuaweiGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu return nil, err } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) + data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action) return data, nil }) @@ -235,7 +259,7 @@ func (self *SHuaweiGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu } } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) + data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action) return data, nil }) diff --git a/pkg/compute/guestdrivers/managedvirtual.go b/pkg/compute/guestdrivers/managedvirtual.go index f3c3742383..a4bfa0c830 100644 --- a/pkg/compute/guestdrivers/managedvirtual.go +++ b/pkg/compute/guestdrivers/managedvirtual.go @@ -61,6 +61,8 @@ func (self *SManagedVirtualizedGuestDriver) GetJsonDescAtHost(ctx context.Contex img := scimg.GetCachedimage() config.OsDistribution, _ = img.Info.GetString("properties", "os_distribution") config.OsVersion, _ = img.Info.GetString("properties", "os_version") + config.OsType, _ = img.Info.GetString("properties", "os_type") + config.ImageType = img.ImageType } } else { dataDisk := cloudprovider.SDiskInfo{ @@ -114,9 +116,9 @@ func (self *SManagedVirtualizedGuestDriver) RequestAttachDisk(ctx context.Contex return guest.StartSyncTask(ctx, task.GetUserCred(), false, task.GetTaskId()) } -func (self *SManagedVirtualizedGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { - return nil -} +// func (self *SManagedVirtualizedGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { +// return nil +// } func (self *SManagedVirtualizedGuestDriver) RequestStartOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, userCred mcclient.TokenCredential, task taskman.ITask) (jsonutils.JSONObject, error) { ihost, e := host.GetIHost() @@ -143,7 +145,7 @@ func (self *SManagedVirtualizedGuestDriver) RequestStartOnHost(ctx context.Conte return result, e } -func (self *SQcloudGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { +func (self *SManagedVirtualizedGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams()) if err != nil { log.Errorf("GetDeployConfigOnHost error: %v", err) @@ -194,7 +196,7 @@ func (self *SManagedVirtualizedGuestDriver) GetGuestInitialStateAfterRebuild() s return models.VM_READY } -func (self *SManagedVirtualizedGuestDriver) GetLinuxDefaultAccount() string { +func (self *SManagedVirtualizedGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string { return "root" } @@ -253,7 +255,7 @@ func (self *SManagedVirtualizedGuestDriver) RemoteDeployGuestForCreate(ctx conte return nil, err } - account := guest.GetDriver().GetLinuxDefaultAccount() + account := guest.GetDriver().GetLinuxDefaultAccount(desc) data := fetchIVMinfo(desc, iVM, guest.Id, account, desc.Password, "create") return data, nil @@ -288,7 +290,7 @@ func (self *SManagedVirtualizedGuestDriver) RemoteDeployGuestForDeploy(ctx conte return nil, err } - account := guest.GetDriver().GetLinuxDefaultAccount() + account := guest.GetDriver().GetLinuxDefaultAccount(desc) data := fetchIVMinfo(desc, iVM, guest.Id, account, desc.Password, "deploy") return data, nil @@ -354,7 +356,7 @@ func (self *SManagedVirtualizedGuestDriver) RemoteDeployGuestForRebuildRoot(ctx } } - account := guest.GetDriver().GetLinuxDefaultAccount() + account := guest.GetDriver().GetLinuxDefaultAccount(desc) data := fetchIVMinfo(desc, iVM, guest.Id, account, desc.Password, "rebuild") return data, nil diff --git a/pkg/compute/guestdrivers/qcloud.go b/pkg/compute/guestdrivers/qcloud.go index 47e215e9f6..79e8781542 100644 --- a/pkg/compute/guestdrivers/qcloud.go +++ b/pkg/compute/guestdrivers/qcloud.go @@ -153,6 +153,19 @@ func (self *SQcloudGuestDriver) GetGuestInitialStateAfterRebuild() string { return models.VM_READY } +func (self *SQcloudGuestDriver) GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string { + userName := "root" + if desc.ImageType == "system" { + if desc.OsDistribution == "Ubuntu" { + userName = "ubuntu" + } + if desc.OsType == "Windows" { + userName = "Administrator" + } + } + return userName +} + /* func (self *SQcloudGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams()) if err != nil { @@ -166,6 +179,16 @@ func (self *SQcloudGuestDriver) GetGuestInitialStateAfterRebuild() string { return err } + userName := "root" + if desc.ImageType == "system" { + if desc.OsDistribution == "Ubuntu" { + userName = "ubuntu" + } + if desc.OsType == "Windows" { + userName = "Administrator" + } + } + action, err := config.GetString("action") if err != nil { return err @@ -214,7 +237,7 @@ func (self *SQcloudGuestDriver) GetGuestInitialStateAfterRebuild() string { return nil, err } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) + data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action) return data, nil }) } else if action == "deploy" { @@ -243,7 +266,7 @@ func (self *SQcloudGuestDriver) GetGuestInitialStateAfterRebuild() string { return nil, err } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) + data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action) return data, nil }) } else if action == "rebuild" { @@ -304,7 +327,7 @@ func (self *SQcloudGuestDriver) GetGuestInitialStateAfterRebuild() string { } } - data := fetchIVMinfo(desc, iVM, guest.Id, "root", desc.Password, action) + data := fetchIVMinfo(desc, iVM, guest.Id, userName, desc.Password, action) return data, nil }) diff --git a/pkg/compute/models/guestdrivers.go b/pkg/compute/models/guestdrivers.go index c9ca3128ec..7248a8995e 100644 --- a/pkg/compute/models/guestdrivers.go +++ b/pkg/compute/models/guestdrivers.go @@ -65,7 +65,7 @@ type IGuestDriver interface { RemoteDeployGuestForRebuildRoot(ctx context.Context, guest *SGuest, ihost cloudprovider.ICloudHost, task taskman.ITask, desc cloudprovider.SManagedVMCreateConfig) (jsonutils.JSONObject, error) GetGuestInitialStateAfterCreate() string GetGuestInitialStateAfterRebuild() string - GetLinuxDefaultAccount() string + GetLinuxDefaultAccount(desc cloudprovider.SManagedVMCreateConfig) string OnGuestDeployTaskDataReceived(ctx context.Context, guest *SGuest, task taskman.ITask, data jsonutils.JSONObject) error diff --git a/pkg/compute/models/hosts.go b/pkg/compute/models/hosts.go index e4a1381607..50128d66bf 100644 --- a/pkg/compute/models/hosts.go +++ b/pkg/compute/models/hosts.go @@ -2518,17 +2518,14 @@ func (self *SHost) PerformStart(ctx context.Context, userCred mcclient.TokenCred } guest := self.GetBaremetalServer() if guest != nil { - if self.HostType != HOST_TYPE_BAREMETAL { - if !utils.IsInStringArray(guest.Status, []string{VM_ADMIN}) { - return nil, httperrors.NewBadRequestError("Cannot start baremetal with active guest") - } - } else { - if utils.ToBool(guest.GetMetadata("is_fake_baremetal_server", userCred)) { - return nil, self.InitializedGuestStart(ctx, userCred, guest) - } - self.SetStatus(userCred, BAREMETAL_START_MAINTAIN, "") - return guest.PerformStart(ctx, userCred, query, data) + if self.HostType == HOST_TYPE_BAREMETAL && utils.ToBool(guest.GetMetadata("is_fake_baremetal_server", userCred)) { + return nil, self.InitializedGuestStart(ctx, userCred, guest) } + // if !utils.IsInStringArray(guest.Status, []string{VM_ADMIN}) { + // return nil, httperrors.NewBadRequestError("Cannot start baremetal with active guest") + // } + self.SetStatus(userCred, BAREMETAL_START_MAINTAIN, "") + return guest.PerformStart(ctx, userCred, query, data) } params := jsonutils.NewDict() params.Set("force_reboot", jsonutils.NewBool(false)) @@ -2690,6 +2687,10 @@ func (self *SHost) BaremetalSyncRequest(ctx context.Context, method httputils.TH } func (self *SHost) StartSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { + guest := self.GetBaremetalServer() + if guest != nil { + return guest.StartSyncstatus(ctx, userCred, parentTaskId) + } task, err := taskman.TaskManager.NewTask(ctx, "BaremetalSyncStatusTask", self, userCred, nil, parentTaskId, "", nil) if err != nil { return err diff --git a/pkg/compute/models/skus.go b/pkg/compute/models/skus.go index e4f214822c..3cadd0530b 100644 --- a/pkg/compute/models/skus.go +++ b/pkg/compute/models/skus.go @@ -138,6 +138,17 @@ func inWhiteList(provider string) bool { } } +func excludeSkus(q *sqlchemy.SQuery) *sqlchemy.SQuery { + // 排除掉华为云对镜像有特殊要求的sku + return q.Filter( + sqlchemy.OR( + sqlchemy.NotEquals(q.Field("provider"), CLOUD_PROVIDER_HUAWEI), + sqlchemy.AND( + sqlchemy.Equals(q.Field("provider"), CLOUD_PROVIDER_HUAWEI), + sqlchemy.NotIn(q.Field("instance_type_family"), []string{"e1", "e2", "e3", "d1", "d2", "i3", "h2", "g1", "g3", "p2v", "p1", "pi1", "fp1", "fp1c"}), + ))) +} + func genInstanceType(family string, cpu, mem_mb int64) (string, error) { if cpu <= 0 { return "", fmt.Errorf("cpu_core_count should great than zero") @@ -398,6 +409,8 @@ func (self *SServerSkuManager) GetPropertyInstanceSpecs(ctx context.Context, use )) } + q = excludeSkus(q) + // 如果是查询私有云需要忽略zone参数 zone := jsonutils.GetAnyString(query, []string{"zone", "zone_id"}) if public_cloud && len(zone) > 0 { @@ -620,6 +633,8 @@ func (manager *SServerSkuManager) ListItemFilter(ctx context.Context, q *sqlchem return nil, err } + q = excludeSkus(q) + regionTable := CloudregionManager.Query().SubQuery() q = q.Join(regionTable, sqlchemy.Equals(regionTable.Field("id"), q.Field("cloudregion_id"))) diff --git a/pkg/compute/tasks/baremetal_server_sync_status_task.go b/pkg/compute/tasks/baremetal_server_sync_status_task.go index db2aa58874..4c5c89d6fd 100644 --- a/pkg/compute/tasks/baremetal_server_sync_status_task.go +++ b/pkg/compute/tasks/baremetal_server_sync_status_task.go @@ -23,9 +23,7 @@ func (self *BaremetalServerSyncStatusTask) OnInit(ctx context.Context, obj db.IS guest := obj.(*models.SGuest) baremetal := guest.GetHost() if baremetal == nil { - kwargs := jsonutils.NewDict() - kwargs.Set("status", jsonutils.NewString(models.VM_INIT)) - guest.PerformStatus(ctx, self.UserCred, nil, kwargs) + guest.SetStatus(self.UserCred, models.VM_INIT, "BaremetalServerSyncStatusTask") self.SetStageComplete(ctx, nil) return } @@ -41,24 +39,31 @@ func (self *BaremetalServerSyncStatusTask) OnInit(ctx context.Context, obj db.IS func (self *BaremetalServerSyncStatusTask) OnGuestStatusTaskComplete(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) { var status string + var hostStatus string if data.Contains("status") { statusStr, _ := data.GetString("status") switch statusStr { case "running": status = models.VM_RUNNING + hostStatus = models.HOST_STATUS_RUNNING case "stopped", "ready": status = models.VM_READY + hostStatus = models.HOST_STATUS_READY case "admin": status = models.VM_ADMIN + hostStatus = models.HOST_STATUS_RUNNING default: status = models.VM_INIT + hostStatus = models.HOST_STATUS_UNKNOWN } } else { status = models.VM_UNKNOWN + hostStatus = models.HOST_STATUS_UNKNOWN } - kwargs := jsonutils.NewDict() - kwargs.Set("status", jsonutils.NewString(status)) - guest.PerformStatus(ctx, self.UserCred, nil, kwargs) + guest.SetStatus(self.UserCred, status, "BaremetalServerSyncStatusTask") + host := guest.GetHost() + host.SetStatus(self.UserCred, hostStatus, "BaremetalServerSyncStatusTask") + self.SetStageComplete(ctx, nil) } diff --git a/pkg/hostman/storageman/diskutils.go b/pkg/hostman/storageman/diskutils.go index e00bcb9459..abf1dfa494 100644 --- a/pkg/hostman/storageman/diskutils.go +++ b/pkg/hostman/storageman/diskutils.go @@ -179,5 +179,5 @@ func (d *SKVMGuestDisk) Zerofree() { for _, part := range d.partitions { part.Zerofree() } - log.Infof("Zerofree takes %f seconds", time.Now().Sub(startTime).Seconds()) + log.Infof("Zerofree %d partitions takes %f seconds", len(d.partitions), time.Now().Sub(startTime).Seconds()) } diff --git a/pkg/hostman/storageman/storage_local.go b/pkg/hostman/storageman/storage_local.go index 70bc831817..b8284befed 100644 --- a/pkg/hostman/storageman/storage_local.go +++ b/pkg/hostman/storageman/storage_local.go @@ -219,17 +219,21 @@ func (s *SLocalStorage) saveToGlance(ctx context.Context, imageId, imagePath str if kvmDisk.Connect() { defer kvmDisk.Disconnect() - if root := kvmDisk.MountKvmRootfs(); root != nil { - defer kvmDisk.UmountKvmRootfs(root) + var err error + func() { + if root := kvmDisk.MountKvmRootfs(); root != nil { + defer kvmDisk.UmountKvmRootfs(root) - osInfo = root.GetOs() - relInfo = root.GetReleaseInfo(root.GetPartition()) - if compress { - if err := root.PrepareFsForTemplate(root.GetPartition()); err != nil { - log.Errorln(err) - return err + osInfo = root.GetOs() + relInfo = root.GetReleaseInfo(root.GetPartition()) + if compress { + err = root.PrepareFsForTemplate(root.GetPartition()) } } + }() + if err != nil { + log.Errorln(err) + return err } if compress { diff --git a/pkg/mcclient/modules/mod_cloud_sku_rates.go b/pkg/mcclient/modules/mod_cloud_sku_rates.go new file mode 100644 index 0000000000..c0a7490aee --- /dev/null +++ b/pkg/mcclient/modules/mod_cloud_sku_rates.go @@ -0,0 +1,13 @@ +package modules + +var ( + CloudSkuRates ResourceManager +) + +func init() { + CloudSkuRates = NewMeterManager("cloud_sku_rate", "cloud_sku_rates", + []string{"id", "data_id", "data_key", "hour_price", "month_price", "year_price"}, + []string{}, + ) + register(&CloudSkuRates) +} diff --git a/pkg/util/huawei/image.go b/pkg/util/huawei/image.go index 7985a522f7..f66b7d0dec 100644 --- a/pkg/util/huawei/image.go +++ b/pkg/util/huawei/image.go @@ -36,34 +36,39 @@ const ( type SImage struct { storageCache *SStoragecache - Schema string `json:"schema"` - MinDiskGB int64 `json:"min_disk"` - CreatedAt time.Time `json:"created_at"` - ImageSourceType string `json:"__image_source_type"` - ContainerFormat string `json:"container_format"` - File string `json:"file"` - UpdatedAt time.Time `json:"updated_at"` - Protected bool `json:"protected"` - Checksum string `json:"checksum"` - SupportKVMFPGAType string `json:"__support_kvm_fpga_type"` - ID string `json:"id"` - Isregistered string `json:"__isregistered"` - MinRamMB int `json:"min_ram"` - Lazyloading string `json:"__lazyloading"` - Owner string `json:"owner"` - OSType string `json:"__os_type"` - Imagetype string `json:"__imagetype"` - Visibility string `json:"visibility"` - VirtualEnvType string `json:"virtual_env_type"` - Platform string `json:"__platform"` - SizeGB int `json:"size"` - ImageSize int64 `json:"__image_size"` - OSBit string `json:"__os_bit"` - OSVersion string `json:"__os_version"` - Name string `json:"name"` - Self string `json:"self"` - DiskFormat string `json:"disk_format"` - Status string `json:"status"` + Schema string `json:"schema"` + MinDiskGB int64 `json:"min_disk"` + CreatedAt time.Time `json:"created_at"` + ImageSourceType string `json:"__image_source_type"` + ContainerFormat string `json:"container_format"` + File string `json:"file"` + UpdatedAt time.Time `json:"updated_at"` + Protected bool `json:"protected"` + Checksum string `json:"checksum"` + ID string `json:"id"` + Isregistered string `json:"__isregistered"` + MinRamMB int `json:"min_ram"` + Lazyloading string `json:"__lazyloading"` + Owner string `json:"owner"` + OSType string `json:"__os_type"` + Imagetype string `json:"__imagetype"` + Visibility string `json:"visibility"` + VirtualEnvType string `json:"virtual_env_type"` + Platform string `json:"__platform"` + SizeGB int `json:"size"` + ImageSize int64 `json:"__image_size"` + OSBit string `json:"__os_bit"` + OSVersion string `json:"__os_version"` + Name string `json:"name"` + Self string `json:"self"` + DiskFormat string `json:"disk_format"` + Status string `json:"status"` + SupportKVMFPGAType string `json:"__support_kvm_fpga_type"` + SupportKVMNVMEHIGHIO string `json:"__support_nvme_highio"` + SupportLargeMemory string `json:"__support_largememory"` + SupportDiskIntensive string `json:"__support_diskintensive"` + SupportXENGPUType string `json:"__support_xen_gpu_type"` + SupportKVMGPUType string `json:"__support_kvm_gpu_type"` } func (self *SImage) GetMinRamSizeMb() int { @@ -200,6 +205,34 @@ func (self *SRegion) GetImage(imageId string) (SImage, error) { return image, err } +func excludeImage(image SImage) bool { + if len(image.SupportDiskIntensive) > 0 { + return true + } + + if len(image.SupportKVMFPGAType) > 0 { + return true + } + + if len(image.SupportKVMGPUType) > 0 { + return true + } + + if len(image.SupportKVMNVMEHIGHIO) > 0 { + return true + } + + if len(image.SupportLargeMemory) > 0 { + return true + } + + if len(image.SupportXENGPUType) > 0 { + return true + } + + return false +} + // https://support.huaweicloud.com/api-ims/zh-cn_topic_0060804959.html func (self *SRegion) GetImages(status string, imagetype TImageOwnerType, name string, envType string) ([]SImage, error) { queries := map[string]string{} @@ -223,7 +256,18 @@ func (self *SRegion) GetImages(status string, imagetype TImageOwnerType, name st images := make([]SImage, 0) err := doListAllWithMarker(self.ecsClient.Images.List, queries, &images) - return images, err + + // 排除掉需要特定镜像才能创建的实例类型 + // https://support.huaweicloud.com/eu-west-0-api-ims/zh-cn_topic_0031617666.html#ZH-CN_TOPIC_0031617666__table48545918250 + // https://support.huaweicloud.com/productdesc-ecs/zh-cn_topic_0088142947.html + filtedImages := make([]SImage, 0) + for i := range images { + if !excludeImage(images[i]) { + filtedImages = append(filtedImages, images[i]) + } + } + + return filtedImages, err } func (self *SRegion) DeleteImage(imageId string) error { diff --git a/pkg/util/huawei/storagecache.go b/pkg/util/huawei/storagecache.go index c5ff63eb9b..6755e2858d 100644 --- a/pkg/util/huawei/storagecache.go +++ b/pkg/util/huawei/storagecache.go @@ -3,6 +3,7 @@ package huawei import ( "context" "fmt" + "math" "strings" "time" @@ -178,7 +179,8 @@ func (self *SStoragecache) uploadImage(ctx context.Context, userCred mcclient.To return "", err } - minDiskGB, _ := _image.Int("min_disk") + minDiskMB, _ := _image.Int("min_disk") + minDiskGB := int(math.Ceil(float64(minDiskMB) / 1024)) // 在使用OBS桶的外部镜像文件制作镜像时生效且为必选字段。取值为40~1024GB。 if minDiskGB < 40 { minDiskGB = 40 @@ -225,7 +227,7 @@ func (self *SStoragecache) uploadImage(ctx context.Context, userCred mcclient.To log.Debugf("uploadImage Match remote name %s", imageName) } - jobId, err := self.region.ImportImageJob(imageName, osDist, osVersion, osArch, bucketName, imageId, minDiskGB) + jobId, err := self.region.ImportImageJob(imageName, osDist, osVersion, osArch, bucketName, imageId, int64(minDiskGB)) if err != nil { log.Errorf("ImportImage error %s %s %s %s", jobId, imageId, bucketName, err) diff --git a/pkg/util/openstack/disk.go b/pkg/util/openstack/disk.go index cc79682a72..802f70dbc7 100644 --- a/pkg/util/openstack/disk.go +++ b/pkg/util/openstack/disk.go @@ -230,11 +230,11 @@ func (disk *SDisk) GetMountpoint() string { func (region *SRegion) CreateDisk(zoneName string, category string, name string, sizeGb int, desc string) (*SDisk, error) { params := map[string]map[string]interface{}{ "volume": { - "size": sizeGb, - "volume_type": category, - "name": name, - "description": desc, - "availability_zone": zoneName, + "size": sizeGb, + "volume_type": category, + "name": name, + "description": desc, + //"availability_zone": zoneName, }, } _, resp, err := region.CinderCreate("/volumes", "", jsonutils.Marshal(params)) diff --git a/pkg/util/openstack/instance.go b/pkg/util/openstack/instance.go index 82546ea8cf..37672e9f51 100644 --- a/pkg/util/openstack/instance.go +++ b/pkg/util/openstack/instance.go @@ -380,8 +380,11 @@ func (instance *SInstance) DeployVM(ctx context.Context, name string, password s } func (instance *SInstance) RebuildRoot(ctx context.Context, imageId string, passwd string, publicKey string, sysSizeGB int) (string, error) { - return "", instance.host.zone.region.ReplaceSystemDisk(instance.ID, imageId, passwd, publicKey, sysSizeGB) - + sysDiskId := "" + if len(instance.VolumesAttached) > 0 { + sysDiskId = instance.VolumesAttached[0].ID + } + return sysDiskId, instance.host.zone.region.ReplaceSystemDisk(instance.ID, imageId, passwd, publicKey, sysSizeGB) } func (instance *SInstance) ChangeConfig(ctx context.Context, ncpu int, vmem int) error { diff --git a/pkg/util/openstack/storage.go b/pkg/util/openstack/storage.go index 0827d20d58..a4f03fee3a 100644 --- a/pkg/util/openstack/storage.go +++ b/pkg/util/openstack/storage.go @@ -96,7 +96,7 @@ func (storage *SStorage) GetIStoragecache() cloudprovider.ICloudStoragecache { } func (storage *SStorage) CreateIDisk(name string, sizeGb int, desc string) (cloudprovider.ICloudDisk, error) { - disk, err := storage.zone.region.CreateDisk(storage.zone.ZoneName, storage.Name, name, sizeGb, desc) + disk, err := storage.zone.region.CreateDisk("", storage.Name, name, sizeGb, desc) if err != nil { log.Errorf("createDisk fail %v", err) return nil, err