Compare commits

...

47 Commits

Author SHA1 Message Date
Zexi Li
9c2cc664f6 Merge pull request #8883 from ioito/hotfix/qx-rds-network-params
fix(region): compatible rds network params
2020-11-20 12:03:19 +08:00
Qu Xuan
42582043ee fix(region): compatible rds network params 2020-11-20 11:44:10 +08:00
Zexi Li
690aef8f4e Merge pull request #8875 from ioito/automated-cherry-pick-of-#8873-upstream-release-3.4
Automated cherry pick of #8873: optimized: server delete log and wait time
2020-11-20 10:04:32 +08:00
Zexi Li
eb7173085e Merge pull request #8880 from ioito/automated-cherry-pick-of-#8876-upstream-release-3.4
Automated cherry pick of #8876: feat: rds recovery new instance from backup supported
2020-11-19 20:53:14 +08:00
Qu Xuan
b6917c5604 feat: rds recovery new instance from backup supported 2020-11-19 20:39:56 +08:00
Qu Xuan
47349e71b9 optimized: server delete log and wait time 2020-11-19 16:27:18 +08:00
Zexi Li
b9565f288a Merge pull request #8862 from swordqiu/automated-cherry-pick-of-#8860-upstream-release-3.4
Automated cherry pick of #8860: fix: add host.memoty.total and host.cpu.total usage stats
2020-11-19 11:03:21 +08:00
Qiu Jian
6b0ae74acb fix: add host.memoty.total and host.cpu.total usage stats 2020-11-19 01:26:37 +08:00
Zexi Li
438a0cb0b7 Merge pull request #8846 from zhaoxiangchun/automated-cherry-pick-of-#8844-upstream-release-3.4
Automated cherry pick of #8844: detach AlertResource on alertDisable
2020-11-18 21:16:36 +08:00
Zexi Li
3fb97c99b6 Merge pull request #8852 from swordqiu/automated-cherry-pick-of-#8850-upstream-release-3.4
Automated cherry pick of #8850: fix: add host-joint resources into domain level resources
2020-11-18 21:15:07 +08:00
yunion-ci-robot
ad8459053f Merge pull request #8855 from zhasm/automated-cherry-pick-of-#8849-upstream-release-3.4
Automated cherry pick of #8849: docker 交叉编译规则更新
2020-11-18 16:36:13 +08:00
Zhang Dongliang
491a9ece55 docker 交叉编译规则更新 2020-11-18 16:14:31 +08:00
Qiu Jian
ba2a188f0d fix: add host-joint resources into domain level resources 2020-11-18 15:26:39 +08:00
zhaoxiangchun
ea793d9902 detach AlertResource on alertDisable
1. 报警规则禁用时,detach 关联的报警资源

影响范围:报警规则的禁用;logger日志服务i18n的日志展示
2020-11-18 12:21:25 +08:00
Zexi Li
4b4964e58e Merge pull request #8840 from rainzm/automated-cherry-pick-of-#8827-upstream-release-3.4
Automated cherry pick of #8827: fix(notify): be compatible with keystone's UsersV3.GetById
2020-11-17 17:52:11 +08:00
rainzm
4a06b38da8 fix: add err handler for notifyRobot 2020-11-17 17:13:15 +08:00
rainzm
96400124ba feat(notify): enable watching user in keystone 2020-11-17 17:13:15 +08:00
rainzm
aee0299d71 fix(notify): be compatible with keystone's UsersV3.GetById
Fill UsersV3.GetById with user's name, it will return user's info.
2020-11-17 17:13:15 +08:00
Zexi Li
cbea17b4c4 Merge pull request #8835 from ioito/automated-cherry-pick-of-#8823-upstream-release-3.4
Automated cherry pick of #8823: optimized: aliyun create rds backup
2020-11-17 14:52:30 +08:00
Zexi Li
4acb237f70 Merge pull request #8833 from zhaoxiangchun/automated-cherry-pick-of-#8816-upstream-release-3.4
Automated cherry pick of #8816: modify  alertResource ws info
2020-11-17 14:51:29 +08:00
Qu Xuan
3a8e998718 optimized: aliyun create rds backup 2020-11-17 14:30:42 +08:00
zhaoxiangchun
bef9af4c3b modify alertResource ws info
ignore_alert:ture 前端不再进行弹窗提示
2020-11-17 14:23:28 +08:00
Zexi Li
3e17ee7519 Merge pull request #8805 from wanyaoqi/automated-cherry-pick-of-#8803-upstream-release-3.4
Automated cherry pick of #8803: host: restart etcd session on keepalive failed
2020-11-17 14:20:24 +08:00
yunion-ci-robot
d3aba7285a Merge pull request #8819 from ioito/automated-cherry-pick-of-#8817-upstream-release-3.4
Automated cherry pick of #8817: fix: add error cause
2020-11-16 21:42:06 +08:00
Qu Xuan
43f4f5f946 fix: add error cause 2020-11-16 14:57:37 +08:00
Zexi Li
4d3c7f3059 Merge pull request #8785 from tb365/automated-cherry-pick-of-#8783-upstream-release-3.4
Automated cherry pick of #8783: aliyun finance cloud region add suffix
2020-11-15 08:00:55 +08:00
Zexi Li
fd26fc1947 Merge pull request #8808 from zhaoxiangchun/automated-cherry-pick-of-#8806-upstream-release-3.4
Automated cherry pick of #8806: commonalert bugfix:
2020-11-15 07:55:32 +08:00
Zexi Li
b74f61fe1d Merge pull request #8811 from swordqiu/automated-cherry-pick-of-#8809-upstream-release-3.4
Automated cherry pick of #8809: fix: baremetal usage should exclude converted hypervisor
2020-11-15 07:52:46 +08:00
Qiu Jian
dc19e7b035 fix: baremetal usage should exclude converted hypervisor 2020-11-15 01:42:32 +08:00
zhaoxiangchun
37272588fa commonalert bugfix:
1.修改消息模版内容:对matches信息进行聚合只返回对应的name信息。解决body消息超过限制
2.报警资源:每次以策略匹配的最新matches为标准。进行updateOrCreate 和
  delete操作。

影响范围:消息模版、报警资源数量
2020-11-14 18:44:14 +08:00
wanyaoqi
029530ac34 host: restart etcd session on keepalive failed 2020-11-14 15:27:10 +08:00
yunion-ci-robot
c047d69a53 Merge pull request #8802 from swordqiu/automated-cherry-pick-of-#8800-upstream-release-3.4
Automated cherry pick of #8800: fix: host memory usage status not correct
2020-11-14 11:22:04 +08:00
yunion-ci-robot
6f76c5d670 Merge pull request #8798 from yousong/automated-cherry-pick-of-#8796-upstream-release-3.4
Automated cherry pick of #8796: vendor: update yunion.io/x/jsonutils
2020-11-14 00:11:06 +08:00
Qiu Jian
71ddac232d fix: host memory usage status not correct 2020-11-13 23:59:51 +08:00
Yousong Zhou
ca9859f126 vendor: update yunion.io/x/jsonutils
See yunionio/onecloud#8357
2020-11-13 18:46:27 +08:00
Zexi Li
7db6ad9a01 Merge pull request #8788 from swordqiu/automated-cherry-pick-of-#8786-upstream-release-3.4
Automated cherry pick of #8786: fix: keystone init empty catalogy cause panic
2020-11-13 15:24:09 +08:00
Qiu Jian
b545066e05 fix: keystone init empty catalogy cause panic 2020-11-13 14:56:24 +08:00
TangBin
befef016dc aliyun finance cloud zone add suffix 2020-11-13 14:44:30 +08:00
TangBin
c32ad0ac5b aliyun finance cloud region add suffix 2020-11-13 14:44:29 +08:00
Zexi Li
ecc75aa231 Merge pull request #8773 from swordqiu/automated-cherry-pick-of-#8771-upstream-release-3.4
Automated cherry pick of #8771: feature: allow join project across domain
2020-11-13 10:39:50 +08:00
Zexi Li
202e0bf266 Merge pull request #8778 from zhaoxiangchun/automated-cherry-pick-of-#8776-upstream-release-3.4
Automated cherry pick of #8776: suggestalet bugfix
2020-11-13 10:39:14 +08:00
zhaoxiangchun
c4d4700d26 suggestalet bugfix
1.安全组规则的in规则为全开放的主机 筛选逻辑修改
2.修复无法正确过滤用户所属资源的bug
2020-11-12 21:32:15 +08:00
Qiu Jian
1fce2ec30c feature: allow join project across domain 2020-11-12 20:41:27 +08:00
Zexi Li
dfe7661c61 Merge pull request #8762 from ioito/automated-cherry-pick-of-#8760-upstream-release-3.4
Automated cherry pick of #8760: fix: avoid panic
2020-11-12 19:31:31 +08:00
Zexi Li
5a28b3c13e Merge pull request #8766 from ioito/automated-cherry-pick-of-#8764-upstream-release-3.4
Automated cherry pick of #8764: fix: support resize qcloud hssd disk
2020-11-12 18:51:40 +08:00
Qu Xuan
27c8861b64 fix: support resize qcloud hssd disk 2020-11-12 16:48:17 +08:00
Qu Xuan
e9459b4a7d fix: avoid panic 2020-11-12 16:20:16 +08:00
68 changed files with 886 additions and 269 deletions

View File

@@ -1,18 +1,9 @@
## {{.title}}
- 时间: {{.start_time}}
- 级别: {{.level}}
- 详情地址: {{.web_url}}/commonalerts
{{.title}}
策略名称: {{.name}}
触发时间: {{.start_time}}
报警级别: {{.level}}
触发条件: {{.description}}
资源数量:{{len .matches}}
资源名称:{{.resource_name}}
{{ range .matches}}
- 指标: {{.metric}}
- 触发值: {{html .value_str}}
### 触发条件:
- {{html $.description}}
### 标签
> 名称: {{ index .tags "name" }}
> ip: {{ index .tags "ip" }}
> 平台: {{ index .tags "brand" }}
------
{{- end}}
详情地址: {{.web_url}}/commonalerts

View File

@@ -1,18 +1,9 @@
## {{.title}}
- Time: {{.start_time}}
- Level: {{.level}}
- WebUrl: {{.web_url}}/commonalerts
{{.title}}
AlertName: {{.name}}
Time: {{.start_time}}
Level: {{.level}}
TriggerCondition: {{html .description}}
ResourceCount: {{len .matches}}
ResourceName: {{.resource_name}}
{{ range .matches}}
- Metric: {{.metric}}
- Trigger value: {{html .value_str}}
### Trigger condition:
- {{html $.description }}
### Label
> Name: {{ index .tags "name" }}
> IP: {{ index .tags "ip" }}
> Brand: {{ index .tags "brand" }}
------
{{- end}}
WebUrl: {{.web_url}}/commonalerts

2
go.mod
View File

@@ -141,7 +141,7 @@ require (
k8s.io/cluster-bootstrap v0.17.3
k8s.io/kubernetes v1.16.0
yunion.io/x/executor v0.0.0-20200227030256-a18417815e74
yunion.io/x/jsonutils v0.0.0-20201105032201-9d0fba742954
yunion.io/x/jsonutils v0.0.0-20201110084044-3e4e1cb49769
yunion.io/x/log v0.0.0-20200313080802-57a4ce5966b3
yunion.io/x/ovsdb v0.0.0-20200526071744-27bf0940cbc7
yunion.io/x/pkg v0.0.0-20201028134817-3ed15ee169bc

2
go.sum
View File

@@ -1126,6 +1126,8 @@ yunion.io/x/executor v0.0.0-20200227030256-a18417815e74/go.mod h1:Uxuou9WQIeJXNp
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
yunion.io/x/jsonutils v0.0.0-20201105032201-9d0fba742954 h1:gGU3uGxw82voqh3tVrTY4q43lLLooqgF662PqOeEpKY=
yunion.io/x/jsonutils v0.0.0-20201105032201-9d0fba742954/go.mod h1:p0nyMqGA/apTxxyLIU/o1k4V7Vujl2O6ey30L594sYE=
yunion.io/x/jsonutils v0.0.0-20201110084044-3e4e1cb49769 h1:LIQ4hhLGQuQK+XxlV+8JrKBuL37WUT+5ZTVxBwHOTD4=
yunion.io/x/jsonutils v0.0.0-20201110084044-3e4e1cb49769/go.mod h1:p0nyMqGA/apTxxyLIU/o1k4V7Vujl2O6ey30L594sYE=
yunion.io/x/log v0.0.0-20190514041436-04ce53b17c6b/go.mod h1:+gauLs73omeJAPlsXcevLsJLKixV+sR/E7WSYTSx1fE=
yunion.io/x/log v0.0.0-20190629062853-9f6483a7103d h1:59zrDL7Ft+hDukguJRmLr/Gdu/9V75x+yX99ovZwfaA=
yunion.io/x/log v0.0.0-20190629062853-9f6483a7103d/go.mod h1:LC6f/4FozL0iaAbnFt2eDX9jlsyo3WiOUPm03d7+U4U=

View File

@@ -24,12 +24,13 @@ type DBInstanceCreateInput struct {
apis.VirtualResourceCreateInput
DeletePreventableCreateInput
// Ip子网名称或Id,建议使用Id
// Ip子网Id
// 谷歌云并不实际使用Ip子网,仅仅通过Ip子网确定Vpc
// required: true
Network string `json:"network"`
NetworkId string `json:"network_id"`
// swagger:ignore
NetworkId string
Network string `json:"network" yunion-deprecated-by:"network_id"`
// Ip子网内的地址,不填则按照ip子网的地址分配策略分配一个ip
// required: false
@@ -66,8 +67,10 @@ type DBInstanceCreateInput struct {
// swagger:ignore
CloudregionId string
VpcId string `json:"vpc_id"`
// swagger:ignore
VpcId string
Vpc string `json:"vpc" yunion-deprecated-by:"vpc_id"`
// swagger:ignore
ManagerId string
@@ -142,6 +145,9 @@ type DBInstanceCreateInput struct {
// required: true
DiskSizeGB int `json:"disk_size_gb"`
// 指定连接端口
Port int `json:"port"`
// rds初始化密码
// 阿里云不需要此参数
// 华为云会默认创建一个用户,若不传此参数, 则为随机密码
@@ -163,6 +169,9 @@ type DBInstanceCreateInput struct {
// swagger:ignore
Provider string
// 从备份中创建新实例
DBInstancebackupId string `json:"dbinstancebackup_id"`
}
type SDBInstanceChangeConfigInput struct {

View File

@@ -19,9 +19,10 @@ type NotificationTemplateCreateInput struct {
}
type NotificationTemplateConfig struct {
Title string `json:"title"`
Name string `json:"name"`
Matches []EvalMatch `json:"matches"`
Title string `json:"title"`
Name string `json:"name"`
ResourceName string `json:"resource_name"`
Matches []EvalMatch `json:"matches"`
// PrevAlertState AlertStateType `json:"prev_alert_state"`
// State AlertStateType `json:"state"`
NoDataFound bool `json:"no_data"`

View File

@@ -332,7 +332,13 @@ func notifyRobot(ctx context.Context, robot string, recipientId []string, isGrou
if err != nil {
return err
}
jarray, _ := result.Get("types")
if result == nil {
return nil
}
jarray, err := result.Get("types")
if err != nil {
return err
}
cTypes := jarray.(*jsonutils.JSONArray).GetStringArray()
for _, ct := range cTypes {
RawNotifyWithCtx(ctx, recipientId, isGroup, npk.TNotifyChannel(ct), priority, event, data)

View File

@@ -30,6 +30,7 @@ import (
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/gotypes"
"yunion.io/x/pkg/util/netutils"
"yunion.io/x/pkg/util/regutils"
@@ -821,3 +822,15 @@ func NewIPv4AddrValidator(key string) *ValidatorIPv4Addr {
v.SetParent(v)
return v
}
var ValidateModel = func(userCred mcclient.TokenCredential, manager db.IStandaloneModelManager, id *string) (db.IModel, error) {
model, err := manager.FetchByIdOrName(userCred, *id)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2(manager.Keyword(), *id)
}
return nil, httperrors.NewGeneralError(err)
}
*id = model.GetId()
return model, nil
}

View File

@@ -16,6 +16,14 @@ package cloudprovider
import "yunion.io/x/onecloud/pkg/util/billing"
type TBackupMethod string
const (
BackupMethodLogical = TBackupMethod("Logical")
BackupMethodPhysical = TBackupMethod("Physical")
BackupMethodUnknown = TBackupMethod("")
)
type SDBInstanceNetwork struct {
IP string
NetworkId string
@@ -55,6 +63,9 @@ type SManagedDBInstanceCreateConfig struct {
ProjectId string
BillingCycle *billing.SBillingCycle
// 仅从备份恢复到新实例用到
RdsId string
}
type SManagedDBInstanceChangeConfig struct {

View File

@@ -816,6 +816,9 @@ type ICloudDBInstanceBackup interface {
GetBackupSizeMb() int
GetDBNames() string
GetBackupMode() string
GetBackupMethod() TBackupMethod
CreateICloudDBInstance(opts *SManagedDBInstanceCreateConfig) (ICloudDBInstance, error)
Delete() error
}

View File

@@ -649,8 +649,7 @@ func (self *SManagedVirtualizedGuestDriver) RequestUndeployGuestOnHost(ctx conte
if errors.Cause(err) == cloudprovider.ErrNotFound {
return nil, nil
}
log.Errorf("host.GetIHost fail %s", err)
return nil, err
return nil, errors.Wrapf(err, "host.GetIHost")
}
// 创建失败时external id为空。此时直接返回即可。不需要再调用公有云api
@@ -663,14 +662,11 @@ func (self *SManagedVirtualizedGuestDriver) RequestUndeployGuestOnHost(ctx conte
if errors.Cause(err) == cloudprovider.ErrNotFound {
return nil, nil
}
log.Errorf("ihost.GetIVMById fail %s", err)
return nil, err
return nil, errors.Wrapf(err, "ihost.GetIVMById(%s)", guest.ExternalId)
}
err = ivm.DeleteVM(ctx)
if err != nil {
log.Errorf("ivm.DeleteVM fail %s", err)
return nil, err
return nil, errors.Wrapf(err, "ivm.DeleteVM")
}
for _, guestdisk := range guest.GetDisks() {
@@ -682,16 +678,14 @@ func (self *SManagedVirtualizedGuestDriver) RequestUndeployGuestOnHost(ctx conte
if errors.Cause(err) == cloudprovider.ErrNotFound {
continue
}
log.Errorf("disk.GetIDisk fail %s", err)
return nil, err
return nil, errors.Wrapf(err, "disk.GetIDisk")
}
if idisk.GetStatus() == api.DISK_DEALLOC {
continue
}
err = idisk.Delete(ctx)
if err != nil {
log.Errorf("idisk.Delete fail %s", err)
return nil, err
return nil, errors.Wrapf(err, "idisk.Delete")
}
}
}

View File

@@ -49,20 +49,21 @@ func (self *SQcloudHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb
if sizeGb%10 != 0 {
return fmt.Errorf("The disk size must be a multiple of 10Gb")
}
if storage.StorageType == api.STORAGE_CLOUD_BASIC {
if sizeGb < 10 || sizeGb > 16000 {
return fmt.Errorf("The %s disk size must be in the range of 10 ~ 16000GB", storage.StorageType)
}
} else if storage.StorageType == api.STORAGE_CLOUD_PREMIUM {
if sizeGb < 50 || sizeGb > 16000 {
return fmt.Errorf("The %s disk size must be in the range of 50 ~ 16000GB", storage.StorageType)
}
} else if storage.StorageType == api.STORAGE_CLOUD_SSD {
if sizeGb < 100 || sizeGb > 16000 {
return fmt.Errorf("The %s disk size must be in the range of 100 ~ 16000GB", storage.StorageType)
}
} else {
return fmt.Errorf("Not support create %s disk", storage.StorageType)
min, max := 0, 0
switch storage.StorageType {
case api.STORAGE_CLOUD_BASIC:
min, max = 10, 16000
case api.STORAGE_CLOUD_PREMIUM:
min, max = 50, 16000
case api.STORAGE_CLOUD_SSD:
min, max = 100, 16000
case api.STORAGE_CLOUD_HSSD:
min, max = 20, 320000
default:
return fmt.Errorf("Not support create or resize %s disk", storage.StorageType)
}
if sizeGb < min || sizeGb > max {
return fmt.Errorf("The %s disk size must be in the range of %d ~ %dGB", storage.StorageType, min, max)
}
return nil
}

View File

@@ -85,9 +85,8 @@ type SDBInstanceBackup struct {
// example: 32
BackupSizeMb int `nullable:"false" list:"user" json:"backup_size_mb"`
// RDS实例Id
// example: 239b9663-6d06-4ef4-8cfc-320a7fb6660d
// DBInstanceId string `width:"36" charset:"ascii" name:"dbinstance_id" nullable:"false" list:"user" create:"required" index:"true"`
// 备份方式 Logical|Physical
BackupMethod string `width:"32" charset:"ascii" nullable:"true" list:"user" create:"optional" json:"backup_method"`
}
func (manager *SDBInstanceBackupManager) GetContextManagers() [][]db.IModelManager {
@@ -369,6 +368,46 @@ func (backup *SDBInstanceBackup) GetIRegion() (cloudprovider.ICloudRegion, error
}
func (backup *SDBInstanceBackup) GetIDBInstanceBackup() (cloudprovider.ICloudDBInstanceBackup, error) {
if len(backup.ExternalId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty external id")
}
if len(backup.DBInstanceId) > 0 {
rds, err := backup.GetDBInstance()
if err != nil {
return nil, errors.Wrapf(err, "GetDBInstance")
}
iRds, err := rds.GetIDBInstance()
if err != nil {
return nil, errors.Wrapf(err, "GetIDBInstance")
}
err = cloudprovider.Wait(time.Second*3, time.Second*15, func() (bool, error) {
backups, err := iRds.GetIDBInstanceBackups()
if err != nil {
return false, errors.Wrapf(err, "GetIDBInstanceBackups")
}
for i := range backups {
if backups[i].GetGlobalId() == backup.ExternalId {
return true, nil
}
}
log.Warningf("failed to found backup %s", backup.ExternalId)
return false, nil
})
if err != nil {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "timeout for search backup %s", backup.ExternalId)
}
backups, err := iRds.GetIDBInstanceBackups()
if err != nil {
return nil, errors.Wrapf(err, "GetIDBInstanceBackups")
}
for i := range backups {
if backups[i].GetGlobalId() == backup.ExternalId {
return backups[i], nil
}
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "search backup %s", backup.ExternalId)
}
iRegion, err := backup.GetIRegion()
if err != nil {
return nil, errors.Wrap(err, "backup.GetIRegion")
@@ -439,6 +478,7 @@ func (self *SDBInstanceBackup) SyncWithCloudDBInstanceBackup(
self.Engine = extBackup.GetEngine()
self.EngineVersion = extBackup.GetEngineVersion()
self.DBNames = extBackup.GetDBNames()
self.BackupMethod = string(extBackup.GetBackupMethod())
if dbinstanceId := extBackup.GetDBInstanceId(); len(dbinstanceId) > 0 {
//有可能云上删除了实例,未删除备份
@@ -497,6 +537,7 @@ func (manager *SDBInstanceBackupManager) newFromCloudDBInstanceBackup(
backup.BackupSizeMb = extBackup.GetBackupSizeMb()
backup.DBNames = extBackup.GetDBNames()
backup.BackupMode = extBackup.GetBackupMode()
backup.BackupMethod = string(extBackup.GetBackupMethod())
backup.ExternalId = extBackup.GetGlobalId()
if dbinstanceId := extBackup.GetDBInstanceId(); len(dbinstanceId) > 0 {
@@ -591,3 +632,67 @@ func (manager *SDBInstanceBackupManager) ListItemExportKeys(ctx context.Context,
func (self *SDBInstanceBackup) GetChangeOwnerCandidateDomainIds() []string {
return self.SManagedResourceBase.GetChangeOwnerCandidateDomainIds()
}
func (self *SDBInstanceBackup) fillRdsConfig(output *api.DBInstanceCreateInput) error {
if self.Status != api.DBINSTANCE_BACKUP_READY {
return fmt.Errorf("backup %s status is %s require %s", self.Name, self.Status, api.DBINSTANCE_BACKUP_READY)
}
if len(self.DBInstanceId) == 0 {
if len(self.Engine) == 0 {
return fmt.Errorf("backup engine %s is unknown", self.Name)
}
output.Engine = self.Engine
if len(self.EngineVersion) == 0 {
return fmt.Errorf("backup engine version %s is unknown", self.Name)
}
output.EngineVersion = self.EngineVersion
return nil
}
rds, err := self.GetDBInstance()
if err != nil {
return errors.Wrapf(err, "backup.GetDBInstance")
}
if len(output.NetworkId) == 0 {
network, _ := rds.GetDBNetwork()
if network != nil {
output.NetworkId = network.NetworkId
}
}
if output.VcpuCount == 0 {
output.VcpuCount = rds.VcpuCount
}
if output.VmemSizeMb == 0 {
output.VmemSizeMb = rds.VmemSizeMb
}
if output.DiskSizeGB == 0 {
output.DiskSizeGB = rds.DiskSizeGB
}
if output.Port == 0 {
output.Port = rds.Port
}
if len(output.Category) == 0 {
output.Category = rds.Category
}
if len(output.StorageType) == 0 {
output.StorageType = rds.StorageType
}
output.Engine = rds.Engine
output.EngineVersion = rds.EngineVersion
if len(output.InstanceType) == 0 {
output.InstanceType = rds.InstanceType
}
if len(output.VpcId) == 0 {
output.VpcId = rds.VpcId
}
if len(output.Zone1) == 0 {
output.Zone1 = rds.Zone1
}
if len(output.Zone2) == 0 {
output.Zone2 = rds.Zone2
}
if len(output.Zone3) == 0 {
output.Zone3 = rds.Zone3
}
return nil
}

View File

@@ -18,6 +18,7 @@ import (
"context"
"database/sql"
"fmt"
"net"
"strings"
"time"
@@ -135,6 +136,9 @@ type SDBInstance struct {
Zone2 string `width:"36" charset:"ascii" nullable:"false" create:"optional" list:"user"`
// 可用区3
Zone3 string `width:"36" charset:"ascii" nullable:"false" create:"optional" list:"user"`
// 从备份创建新实例
DBInstancebackupId string `width:"36" name:"dbinstancebackup_id" charset:"ascii" nullable:"false" create:"optional"`
}
func (manager *SDBInstanceManager) GetContextManagers() [][]db.IModelManager {
@@ -274,8 +278,18 @@ func (man *SDBInstanceManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field
}
func (man *SDBInstanceManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.DBInstanceCreateInput) (*jsonutils.JSONDict, error) {
if len(input.DBInstancebackupId) > 0 {
_backup, err := validators.ValidateModel(userCred, DBInstanceBackupManager, &input.DBInstancebackupId)
if err != nil {
return nil, err
}
backup := _backup.(*SDBInstanceBackup)
err = backup.fillRdsConfig(&input)
if err != nil {
return nil, err
}
}
data := input.JSON(input)
networkV := validators.NewModelIdOrNameValidator("network", "network", ownerId)
addressV := validators.NewIPv4AddrValidator("address")
secgroupV := validators.NewModelIdOrNameValidator("secgroup", "secgroup", ownerId)
masterV := validators.NewModelIdOrNameValidator("master_instance", "dbinstance", ownerId)
@@ -283,7 +297,6 @@ func (man *SDBInstanceManager) ValidateCreateData(ctx context.Context, userCred
zone2V := validators.NewModelIdOrNameValidator("zone2", "zone", ownerId)
zone3V := validators.NewModelIdOrNameValidator("zone3", "zone", ownerId)
keyV := map[string]validators.IValidator{
"network": networkV,
"address": addressV.Optional(true),
"master": masterV.ModelIdKey("master_instance_id").Optional(true),
"secgroup": secgroupV.Optional(true),
@@ -318,10 +331,36 @@ func (man *SDBInstanceManager) ValidateCreateData(ctx context.Context, userCred
}
}
network := networkV.Model.(*SNetwork)
input.NetworkExternalId = network.ExternalId
var vpc *SVpc
var network *SNetwork
if len(input.NetworkId) > 0 {
_network, err := validators.ValidateModel(userCred, NetworkManager, &input.NetworkId)
if err != nil {
return nil, err
}
network = _network.(*SNetwork)
input.NetworkExternalId = network.ExternalId
if len(input.Address) > 0 {
ip := net.ParseIP(input.Address).To4()
if ip == nil {
return nil, httperrors.NewInputParameterError("invalid address: %s", input.Address)
}
addr, _ := netutils.NewIPV4Addr(input.Address)
if !network.IsAddressInRange(addr) {
return nil, httperrors.NewInputParameterError("Ip %s not in network %s(%s) range", input.Address, network.Name, network.Id)
}
}
vpc = network.GetVpc()
} else if len(input.VpcId) > 0 {
_vpc, err := validators.ValidateModel(userCred, VpcManager, &input.VpcId)
if err != nil {
return nil, err
}
vpc = _vpc.(*SVpc)
} else {
return nil, httperrors.NewMissingParameterError("vpc_id")
}
vpc := network.GetVpc()
input.VpcId = vpc.Id
input.ManagerId = vpc.ManagerId
cloudprovider := vpc.GetCloudprovider()

View File

@@ -2503,19 +2503,25 @@ func (manager *SHostManager) totalCountQ(
q = q.Filter(cond(hosts.Field("enabled")))
}
if !isBaremetal.IsNone() {
cond := sqlchemy.IsFalse
if isBaremetal.Bool() {
cond = sqlchemy.IsTrue
q = q.Filter(sqlchemy.AND(
sqlchemy.IsTrue(hosts.Field("is_baremetal")),
sqlchemy.Equals(hosts.Field("host_type"), api.HOST_TYPE_BAREMETAL),
))
} else {
q = q.Filter(sqlchemy.OR(
sqlchemy.IsFalse(hosts.Field("is_baremetal")),
sqlchemy.NotEquals(hosts.Field("host_type"), api.HOST_TYPE_BAREMETAL),
))
}
q = q.Filter(cond(hosts.Field("is_baremetal")))
}
isolatedDevices := IsolatedDeviceManager.Query().SubQuery()
iq := isolatedDevices.Query(
isolatedDevices.Field("host_id"),
isolatedDevices.Field("reserved_memory", "isolated_reserved_memory"),
isolatedDevices.Field("reserved_cpu", "isolated_reserved_cpu"),
isolatedDevices.Field("reserved_storage", "isolated_reserved_storage"),
).IsNullOrEmpty("guest_id").SubQuery()
sqlchemy.SUM("isolated_reserved_memory", isolatedDevices.Field("reserved_memory")),
sqlchemy.SUM("isolated_reserved_cpu", isolatedDevices.Field("reserved_cpu")),
sqlchemy.SUM("isolated_reserved_storage", isolatedDevices.Field("reserved_storage")),
).IsNullOrEmpty("guest_id").GroupBy(isolatedDevices.Field("host_id")).SubQuery()
q = q.LeftJoin(iq, sqlchemy.Equals(q.Field("id"), iq.Field("host_id")))
q.AppendField(
iq.Field("isolated_reserved_memory"),
@@ -2523,6 +2529,7 @@ func (manager *SHostManager) totalCountQ(
iq.Field("isolated_reserved_storage"),
)
q = AttachUsageQuery(q, hosts, hostTypes, resourceTypes, providers, brands, cloudEnv, rangeObjs)
log.Debugf("hostCount: %s", q.String())
return q
}
@@ -2543,9 +2550,11 @@ type HostsCountStat struct {
StorageSize int64
Count int64
Memory int64
MemoryTotal int64
MemoryVirtual float64
MemoryReserved int64
CPU int64
CPUTotal int64
CPUVirtual float64
IsolatedReservedMemory int64
IsolatedReservedCpu int64
@@ -2573,6 +2582,9 @@ func (manager *SHostManager) calculateCount(q *sqlchemy.SQuery) HostsCountStat {
irMem int64 = 0
irCpu int64 = 0
irStore int64 = 0
totalMem int64 = 0
totalCPU int64 = 0
)
stats := make([]HostStat, 0)
err := q.All(&stats)
@@ -2590,7 +2602,9 @@ func (manager *SHostManager) calculateCount(q *sqlchemy.SQuery) HostsCountStat {
aMem := usableSize(stat.MemSize, stat.MemReserved)
aCpu := usableSize(int(stat.CpuCount), int(stat.CpuReserved))
tMem += int64(aMem)
totalMem += int64(stat.MemSize)
tCPU += int64(aCpu)
totalCPU += int64(stat.CpuCount)
if stat.MemCmtbound <= 0.0 {
stat.MemCmtbound = options.Options.DefaultMemoryOvercommitBound
}
@@ -2608,9 +2622,11 @@ func (manager *SHostManager) calculateCount(q *sqlchemy.SQuery) HostsCountStat {
StorageSize: tStore,
Count: tCnt,
Memory: tMem,
MemoryTotal: totalMem,
MemoryVirtual: tVmem,
MemoryReserved: rMem,
CPU: tCPU,
CPUTotal: totalCPU,
CPUVirtual: tVCPU,
IsolatedReservedCpu: irCpu,
IsolatedReservedMemory: irMem,

View File

@@ -154,6 +154,7 @@ type IDBInstanceDriver interface {
ValidateResetDBInstancePassword(ctx context.Context, userCred mcclient.TokenCredential, instance *SDBInstance, account string) error
RequestCreateDBInstance(ctx context.Context, userCred mcclient.TokenCredential, dbinstance *SDBInstance, task taskman.ITask) error
RequestCreateDBInstanceFromBackup(ctx context.Context, userCred mcclient.TokenCredential, dbinstance *SDBInstance, task taskman.ITask) error
RequestCreateDBInstanceBackup(ctx context.Context, userCred mcclient.TokenCredential, instance *SDBInstance, backup *SDBInstanceBackup, task taskman.ITask) error
RequestChangeDBInstanceConfig(ctx context.Context, userCred mcclient.TokenCredential, instance *SDBInstance, task taskman.ITask) error

View File

@@ -42,6 +42,9 @@ var (
"recyclebins",
// migrate system resources to domain resources
"hosts",
"baremetalnetworks",
"hoststorages",
"hostwires",
"isolated-devices",
"vpcs",
"storages",

View File

@@ -1000,25 +1000,26 @@ func (self *SAliyunRegionDriver) ValidateCreateDBInstanceData(ctx context.Contex
return input, httperrors.NewInputParameterError("slave dbinstance not support prepaid billing type")
}
wire := network.GetWire()
if wire == nil {
return input, httperrors.NewGeneralError(fmt.Errorf("failed to found wire for network %s(%s)", network.Name, network.Id))
}
zone := wire.GetZone()
if zone == nil {
return input, httperrors.NewGeneralError(fmt.Errorf("failed to found zone for wire %s(%s)", wire.Name, wire.Id))
}
match := false
for _, sku := range skus {
if utils.IsInStringArray(zone.Id, []string{sku.Zone1, sku.Zone2, sku.Zone3}) {
match = true
break
if network != nil {
wire := network.GetWire()
if wire == nil {
return input, httperrors.NewGeneralError(fmt.Errorf("failed to found wire for network %s(%s)", network.Name, network.Id))
}
zone := wire.GetZone()
if zone == nil {
return input, httperrors.NewGeneralError(fmt.Errorf("failed to found zone for wire %s(%s)", wire.Name, wire.Id))
}
}
if !match {
return input, httperrors.NewInputParameterError("failed to match any skus in the network %s(%s) zone %s(%s)", network.Name, network.Id, zone.Name, zone.Id)
match := false
for _, sku := range skus {
if utils.IsInStringArray(zone.Id, []string{sku.Zone1, sku.Zone2, sku.Zone3}) {
match = true
break
}
}
if !match {
return input, httperrors.NewInputParameterError("failed to match any skus in the network %s(%s) zone %s(%s)", network.Name, network.Id, zone.Name, zone.Id)
}
}
var master *models.SDBInstance
@@ -1100,37 +1101,6 @@ func (self *SAliyunRegionDriver) IsSupportedBillingCycle(bc billing.SBillingCycl
return false
}
func (self *SAliyunRegionDriver) RequestCreateDBInstanceBackup(ctx context.Context, userCred mcclient.TokenCredential, instance *models.SDBInstance, backup *models.SDBInstanceBackup, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
iRds, err := instance.GetIDBInstance()
if err != nil {
return nil, errors.Wrap(err, "instance.GetIDBInstance")
}
desc := &cloudprovider.SDBInstanceBackupCreateConfig{
Name: backup.Name,
}
if len(backup.DBNames) > 0 {
desc.Databases = strings.Split(backup.DBNames, ",")
}
_, err = iRds.CreateIBackup(desc)
if err != nil {
return nil, errors.Wrap(err, "iRds.CreateBackup")
}
backups, err := iRds.GetIDBInstanceBackups()
if err != nil {
return nil, errors.Wrap(err, "iRds.GetIDBInstanceBackups")
}
result := models.DBInstanceBackupManager.SyncDBInstanceBackups(ctx, userCred, backup.GetCloudprovider(), instance, backup.GetRegion(), backups)
log.Infof("SyncDBInstanceBackups for dbinstance %s(%s) result: %s", instance.Name, instance.Id, result.Result())
instance.SetStatus(userCred, api.DBINSTANCE_RUNNING, "")
return nil, nil
})
return nil
}
func (self *SAliyunRegionDriver) ValidateCreateDBInstanceAccountData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, instance *models.SDBInstance, input api.DBInstanceAccountCreateInput) (api.DBInstanceAccountCreateInput, error) {
if len(input.Name) < 2 || len(input.Name) > 16 {
return input, httperrors.NewInputParameterError("Aliyun DBInstance account name length shoud be 2~16 characters")

View File

@@ -285,6 +285,10 @@ func (self *SBaseRegionDriver) RequestCreateDBInstance(ctx context.Context, user
return fmt.Errorf("Not Implement RequestCreateDBInstance")
}
func (self *SBaseRegionDriver) RequestCreateDBInstanceFromBackup(ctx context.Context, userCred mcclient.TokenCredential, dbinstance *models.SDBInstance, task taskman.ITask) error {
return fmt.Errorf("Not Implement RequestCreateDBInstanceFromBackup")
}
func (self *SBaseRegionDriver) RequestCreateDBInstanceBackup(ctx context.Context, userCred mcclient.TokenCredential, dbinstance *models.SDBInstance, backup *models.SDBInstanceBackup, task taskman.ITask) error {
return fmt.Errorf("Not Implement RequestCreateDBInstanceBackup")
}

View File

@@ -1738,6 +1738,73 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateDBInstance(ctx cont
return nil
}
func (self *SManagedVirtualizationRegionDriver) RequestCreateDBInstanceFromBackup(ctx context.Context, userCred mcclient.TokenCredential, rds *models.SDBInstance, task taskman.ITask) error {
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
_backup, err := models.DBInstanceBackupManager.FetchById(rds.DBInstancebackupId)
if err != nil {
return nil, errors.Wrapf(err, "DBInstanceBackupManager.FetchById(%s)", rds.DBInstancebackupId)
}
backup := _backup.(*models.SDBInstanceBackup)
iBackup, err := backup.GetIDBInstanceBackup()
if err != nil {
return nil, errors.Wrapf(err, "backup.GetIDBInstanceBackup")
}
vpc, err := rds.GetVpc()
if err != nil {
return nil, errors.Wrap(err, "rds.GetVpc()")
}
desc := cloudprovider.SManagedDBInstanceCreateConfig{
Name: rds.Name,
Description: rds.Description,
StorageType: rds.StorageType,
DiskSizeGB: rds.DiskSizeGB,
VcpuCount: rds.VcpuCount,
VmemSizeMb: rds.VmemSizeMb,
VpcId: vpc.ExternalId,
Engine: rds.Engine,
EngineVersion: rds.EngineVersion,
Category: rds.Category,
Port: rds.Port,
}
if len(backup.DBInstanceId) > 0 {
parentRds, err := backup.GetDBInstance()
if err != nil {
return nil, errors.Wrapf(err, "backup.GetDBInstance")
}
desc.RdsId = parentRds.ExternalId
}
log.Debugf("create from backup params: %s", jsonutils.Marshal(desc).String())
if rds.BillingType == billing_api.BILLING_TYPE_PREPAID {
bc, err := billing.ParseBillingCycle(rds.BillingCycle)
if err != nil {
log.Errorf("failed to parse billing cycle %s: %v", rds.BillingCycle, err)
} else if bc.IsValid() {
desc.BillingCycle = &bc
desc.BillingCycle.AutoRenew = rds.AutoRenew
}
}
iRds, err := iBackup.CreateICloudDBInstance(&desc)
if err != nil {
return nil, errors.Wrapf(err, "iBackup.CreateICloudDBInstance")
}
err = db.SetExternalId(rds, userCred, iRds.GetGlobalId())
if err != nil {
return nil, errors.Wrapf(err, "db.SetExternalId")
}
err = cloudprovider.WaitStatus(iRds, api.DBINSTANCE_RUNNING, time.Second*5, time.Hour*1)
if err != nil {
return nil, errors.Wrapf(err, "cloudprovider.WaitStatus runing")
}
return nil, nil
})
return nil
}
func (self *SManagedVirtualizationRegionDriver) RequestCreateElasticcache(ctx context.Context, userCred mcclient.TokenCredential, elasticcache *models.SElasticcache, task taskman.ITask) error {
task.ScheduleRun(nil)
return nil
@@ -2347,14 +2414,9 @@ func (self *SManagedVirtualizationRegionDriver) RequestCreateDBInstanceBackup(ct
return nil, errors.Wrapf(err, "iRegion.GetIDBInstanceBackupById(%s)", backupId)
}
_, err = db.Update(backup, func() error {
backup.StartTime = iBackup.GetStartTime()
backup.EndTime = iBackup.GetEndTime()
backup.BackupSizeMb = iBackup.GetBackupSizeMb()
return nil
})
err = backup.SyncWithCloudDBInstanceBackup(ctx, userCred, iBackup, instance.GetCloudprovider())
if err != nil {
return nil, errors.Wrap(err, "db.Update")
log.Warningf("sync backup info error: %v", err)
}
instance.SetStatus(userCred, api.DBINSTANCE_RUNNING, "")

View File

@@ -48,12 +48,17 @@ func (self *DBInstanceCreateTask) OnInit(ctx context.Context, obj db.IStandalone
self.CreateDBInstance(ctx, dbinstance)
}
func (self *DBInstanceCreateTask) CreateDBInstance(ctx context.Context, dbinstance *models.SDBInstance) {
region := dbinstance.GetRegion()
func (self *DBInstanceCreateTask) CreateDBInstance(ctx context.Context, rds *models.SDBInstance) {
region := rds.GetRegion()
self.SetStage("OnCreateDBInstanceComplete", nil)
err := region.GetDriver().RequestCreateDBInstance(ctx, self.UserCred, dbinstance, self)
var err error
if len(rds.DBInstancebackupId) > 0 {
err = region.GetDriver().RequestCreateDBInstanceFromBackup(ctx, self.UserCred, rds, self)
} else {
err = region.GetDriver().RequestCreateDBInstance(ctx, self.UserCred, rds, self)
}
if err != nil {
self.taskFailed(ctx, dbinstance, err)
self.taskFailed(ctx, rds, err)
return
}
}

View File

@@ -708,7 +708,9 @@ func hostUsage(
result := models.HostManager.TotalCount(userCred, scope, rangeObjs, "", "", hostTypes, resourceTypes, providers, brands, cloudEnv, enabled, isBaremetal)
count[prefix] = result.Count
count[fmt.Sprintf("%s.memory", prefix)] = result.Memory
count[fmt.Sprintf("%s.memory.total", prefix)] = result.MemoryTotal
count[fmt.Sprintf("%s.cpu", prefix)] = result.CPU
count[fmt.Sprintf("%s.cpu.total", prefix)] = result.CPUTotal
count[fmt.Sprintf("%s.memory.virtual", prefix)] = result.MemoryVirtual
count[fmt.Sprintf("%s.cpu.virtual", prefix)] = result.CPUVirtual
count[fmt.Sprintf("%s.memory.reserved", prefix)] = result.MemoryReserved

View File

@@ -17,6 +17,7 @@ package host_health
import (
"context"
"fmt"
"time"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
@@ -87,7 +88,7 @@ func (c *SEtcdClient) OnKeepaliveFailure() {
for timeout > 0 {
timeout -= c.requestExpend
if err := c.cli.RestartSession(); err != nil {
log.Errorf("restart session failed %s", err)
log.Errorf("etcd restart session failed %s", err)
} else {
break
}
@@ -99,6 +100,7 @@ func (c *SEtcdClient) OnKeepaliveFailure() {
); err != nil {
log.Errorf("put host key failed %s", err)
} else {
log.Infof("etcd client restart session success")
return
}
}
@@ -106,6 +108,27 @@ func (c *SEtcdClient) OnKeepaliveFailure() {
if c.onUnhealthy != nil {
c.onUnhealthy()
}
go c.Reconnect()
}
func (c *SEtcdClient) Reconnect() {
for {
if err := c.cli.RestartSession(); err != nil {
log.Errorf("restart session failed %s", err)
time.Sleep(1 * time.Second)
} else {
break
}
}
if err := c.cli.PutSession(context.Background(),
fmt.Sprintf("%s/%s", api.HOST_HEALTH_PREFIX, c.hostId),
api.HOST_HEALTH_STATUS_RUNNING,
); err != nil {
log.Errorf("put host key failed %s", err)
go c.Reconnect()
} else {
return
}
}
func (c *SEtcdClient) Stop() error {

View File

@@ -30,6 +30,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/policy"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/keystone/options"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/util/rbacutils"
@@ -249,7 +250,7 @@ func (manager *SAssignmentManager) ProjectAddUser(ctx context.Context, userCred
return err
}
if project.DomainId != user.DomainId {
if project.DomainId != api.DEFAULT_DOMAIN_ID {
if project.DomainId != api.DEFAULT_DOMAIN_ID && !options.Options.AllowJoinProjectsAcrossDomains {
return httperrors.NewInputParameterError("join user into project of default domain or identical domain")
} else if !db.IsAllowPerform(rbacutils.ScopeSystem, userCred, user, "join-project") {
return httperrors.NewForbiddenError("not enough privilege")
@@ -349,7 +350,7 @@ func (manager *SAssignmentManager) projectAddGroup(ctx context.Context, userCred
return err
}
if project.DomainId != group.DomainId {
if project.DomainId != api.DEFAULT_DOMAIN_ID {
if project.DomainId != api.DEFAULT_DOMAIN_ID && !options.Options.AllowJoinProjectsAcrossDomains {
return httperrors.NewInputParameterError("join group into project of default domain or identical domain")
} else if !db.IsAllowPerform(rbacutils.ScopeSystem, userCred, group, "join-project") {
return httperrors.NewForbiddenError("not enough privilege")

View File

@@ -344,8 +344,14 @@ func (role *SRole) UpdateInContext(ctx context.Context, userCred mcclient.TokenC
if !ok {
return nil, httperrors.NewInputParameterError("not supported update context %s", ctxObjs[0].Keyword())
}
if project.DomainId != role.DomainId && !role.GetIsPublic() {
return nil, httperrors.NewInputParameterError("inconsistent domain for project and roles")
if project.DomainId != role.DomainId {
projectOwner := &db.SOwnerId{
ProjectId: project.Id,
DomainId: project.DomainId,
}
if !role.IsSharable(projectOwner) {
return nil, httperrors.NewInputParameterError("inconsistent domain for project and roles")
}
}
err := validateJoinProject(userCred, project, []string{role.Name})
if err != nil {

View File

@@ -52,6 +52,8 @@ type SKeystoneOptions struct {
DefaultPolicyQuota int `default:"100" help:"default quota for policy per domain, default is 500"`
SessionEndpointType string `help:"Client session end point type"`
AllowJoinProjectsAcrossDomains bool `help:"allow users/groups to join projects across domains" default:"false"`
}
var (

View File

@@ -64,7 +64,7 @@ func policyReadFilter(session *mcclient.ClientSession, s jsonutils.JSONObject, q
}
func policyWriteFilter(session *mcclient.ClientSession, s jsonutils.JSONObject, query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
ret := jsonutils.NewDict()
ret := s.(*jsonutils.JSONDict).CopyExcludes("policy")
if s.Contains("policy") {
blobJson, err := s.Get("policy")
if err != nil {
@@ -81,17 +81,6 @@ func policyWriteFilter(session *mcclient.ClientSession, s jsonutils.JSONObject,
// ret.Add(jsonutils.NewString(blobJson.String()), "blob")
ret.Add(blobJson, "blob")
}
for _, k := range []string{
"type", "enabled", "domain", "domain_id", "project_domain", "description", "is_public", "public_scope", "shared_domains",
} {
if s.Contains(k) {
val, err := s.Get(k)
if err != nil {
return nil, err
}
ret.Add(val, k)
}
}
return ret, nil
}

View File

@@ -0,0 +1,66 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package options
import (
"fmt"
"strings"
"yunion.io/x/jsonutils"
)
type DBInstanceCreateOptions struct {
NAME string `help:"DBInstance Name"`
InstanceType string `help:"InstanceType for DBInstance"`
VcpuCount int `help:"Core of cpu for DBInstance"`
VmemSizeMb int `help:"Memory size of DBInstance"`
Port int `help:"Port of DBInstance"`
Category string `help:"Category of DBInstance"`
Network string `help:"Network of DBInstance"`
Address string `help:"Address of DBInstance"`
Engine string `help:"Engine of DBInstance"`
EngineVersion string `help:"EngineVersion of DBInstance Engine"`
StorageType string `help:"StorageTyep of DBInstance"`
Secgroup string `help:"Secgroup name or Id for DBInstance"`
Zone string `help:"ZoneId or name for DBInstance"`
DiskSizeGB int `help:"Storage size for DBInstance"`
Duration string `help:"Duration for DBInstance"`
AllowDelete *bool `help:"not lock dbinstance" `
Tags []string `help:"Tags info,prefix with 'user:', eg: user:project=default" json:"-"`
DBInstancebackupId string `help:"create dbinstance from backup" json:"dbinstancebackup_id"`
}
func (opts *DBInstanceCreateOptions) Params() (*jsonutils.JSONDict, error) {
params, err := StructToParams(opts)
if err != nil {
return nil, err
}
Tagparams := jsonutils.NewDict()
for _, tag := range opts.Tags {
info := strings.Split(tag, "=")
if len(info) == 2 {
if len(info[0]) == 0 {
return nil, fmt.Errorf("invalidate tag info %s", tag)
}
Tagparams.Add(jsonutils.NewString(info[1]), info[0])
} else if len(info) == 1 {
Tagparams.Add(jsonutils.NewString(info[0]), info[0])
} else {
return nil, fmt.Errorf("invalidate tag info %s", tag)
}
}
params.Add(Tagparams, "__meta__")
return params, nil
}

View File

@@ -27,6 +27,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/gotypes"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/identity"
@@ -147,7 +148,11 @@ func (this *ClientSession) GetServiceVersionURL(service, endpointType, apiVersio
endpointType = this.endpointType
}
service = this.getServiceName(service, apiVersion)
url, err := this.GetServiceCatalog().GetServiceURL(service, this.region, this.zone, endpointType)
catalog := this.GetServiceCatalog()
if gotypes.IsNil(catalog) {
return this.client.authUrl, nil
}
url, err := catalog.GetServiceURL(service, this.region, this.zone, endpointType)
if err != nil && service == api.SERVICE_TYPE {
return this.client.authUrl, nil
}

View File

@@ -17,6 +17,7 @@ package alerting
import (
"context"
"fmt"
"strings"
"time"
"yunion.io/x/jsonutils"
@@ -186,15 +187,16 @@ func (c *EvalContext) GetNotificationTemplateConfig() monitor.NotificationTempla
desc += "Error: " + c.Error.Error()
}
return monitor.NotificationTemplateConfig{
Title: c.GetNotificationTitle(),
Name: c.Rule.Name,
Matches: c.GetEvalMatches(),
StartTime: c.StartTime.Format("2006-01-02 15:04:05"),
EndTime: c.EndTime.Format("2006-01-02 15:04:05"),
Description: desc,
Level: c.Rule.Level,
NoDataFound: c.NoDataFound,
WebUrl: c.GetCallbackURLPrefix(),
Title: c.GetNotificationTitle(),
Name: c.Rule.Name,
ResourceName: c.GetResourceNameOfMathes(),
Matches: c.GetEvalMatches(),
StartTime: c.StartTime.Format("2006-01-02 15:04:05"),
EndTime: c.EndTime.Format("2006-01-02 15:04:05"),
Description: desc,
Level: c.Rule.Level,
NoDataFound: c.NoDataFound,
WebUrl: c.GetCallbackURLPrefix(),
}
}
@@ -211,3 +213,17 @@ func (c *EvalContext) GetEvalMatches() []monitor.EvalMatch {
}
return ret
}
func (c *EvalContext) GetResourceNameOfMathes() string {
names := strings.Builder{}
matches := c.GetEvalMatches()
for i, match := range matches {
if name, ok := match.Tags["name"]; ok {
names.WriteString(name)
if i < len(matches)-1 {
names.WriteString("、")
}
}
}
return names.String()
}

View File

@@ -151,8 +151,9 @@ func GetNotifyTemplateConfigOfEN(ctx *alerting.EvalContext) monitor.Notification
// Notify sends the alert notification.
func (oc *OneCloudNotifier) Notify(ctx *alerting.EvalContext, _ jsonutils.JSONObject) error {
log.Infof("Sending alert notification %s to onecloud", ctx.GetRuleTitle())
oc.Ctx = i18n.WithLangTag(oc.Ctx, language.Chinese)
var config monitor.NotificationTemplateConfig
lang := i18n.Lang(ctx.Ctx)
lang := i18n.Lang(oc.Ctx)
switch lang {
case language.English:
config = GetNotifyTemplateConfigOfEN(ctx)
@@ -239,7 +240,7 @@ type sendUserImpl struct {
}
func (s *sendUserImpl) send() error {
return notifyclient.NotifyAllWithoutRobot(s.Setting.UserIds, false, notify.TNotifyPriority(s.msg.Priority),
return notifyclient.NotifyAllWithoutRobotWithCtx(s.Ctx, s.Setting.UserIds, false, notify.TNotifyPriority(s.msg.Priority),
"DEFAULT", jsonutils.Marshal(&s.config))
}
@@ -248,7 +249,7 @@ type sendSysImpl struct {
}
func (s *sendSysImpl) send() error {
notifyclient.SystemNotify(notify.TNotifyPriority(s.msg.Priority), "DEFAULT",
notifyclient.SystemNotifyWithCtx(s.Ctx, notify.TNotifyPriority(s.msg.Priority), "DEFAULT",
jsonutils.Marshal(&s.config))
return nil
}

View File

@@ -36,14 +36,21 @@ func (drvF *nodeDriverF) GetType() monitor.AlertResourceType {
func (drvF *nodeDriverF) IsEvalMatched(input monitor.EvalMatch) bool {
tags := input.Tags
_, hasResType := tags[hostconsts.TELEGRAF_TAG_KEY_RES_TYPE]
resType, hasResType := tags[hostconsts.TELEGRAF_TAG_KEY_RES_TYPE]
if !hasResType {
return false
}
_, hasHostType := tags[hostconsts.TELEGRAF_TAG_KEY_HOST_TYPE]
if resType != hostconsts.TELEGRAF_TAG_ONECLOUD_RES_TYPE {
return false
}
hostType, hasHostType := tags[hostconsts.TELEGRAF_TAG_KEY_HOST_TYPE]
if !hasHostType {
return false
}
if hostType != hostconsts.TELEGRAF_TAG_ONECLOUD_HOST_TYPE_HOST &&
hostType != hostconsts.TELEGRAF_TAG_ONECLOUD_HOST_TYPE_CONTROLLER {
return false
}
_, hasHost := tags[NODE_TAG_HOST_KEY]
if !hasHost {
return false

View File

@@ -109,15 +109,49 @@ func (m *SAlertResourceManager) ReconcileFromRecord(ctx context.Context, userCre
if err != nil {
return errors.Wrapf(err, "Get record %s eval data", record.GetId())
}
oldResources, err := m.getResourceFromAlertId(record.AlertId)
if err != nil {
return errors.Wrap(err, "ReconcileFromRecord getResourceFromAlertId error")
}
errs := make([]error, 0)
for _, match := range matches {
if err := m.reconcileFromRecordMatch(ctx, userCred, ownerId, record, match); err != nil {
errs = append(errs, err)
}
}
if len(errs) == 0 {
delErrs := m.deleteOldResource(ctx, userCred, record, oldResources)
if len(delErrs) != 0 {
errs = append(errs, delErrs...)
}
}
return errors.NewAggregate(errs)
}
func (m *SAlertResourceManager) deleteOldResource(ctx context.Context, userCred mcclient.TokenCredential,
record *SAlertRecord, oldResources []SAlertResource) (errs []error) {
matches, _ := record.GetEvalData()
needDelResources := make([]SAlertResource, 0)
LoopRes:
for _, oldResource := range oldResources {
for _, match := range matches {
resourceD, _ := GetAlertResourceDriver(match)
if oldResource.Name == resourceD.GetUniqCond().Name {
continue LoopRes
}
}
needDelResources = append(needDelResources, oldResource)
}
for i, _ := range needDelResources {
if err := needDelResources[i].DetachAlert(ctx, userCred, record.AlertId); err != nil {
errs = append(errs, errors.Wrapf(err, "deleteOldResource remove resource %s alert %s",
needDelResources[i].GetName(),
record.AlertId))
}
}
return
}
type AlertResourceUniqCond struct {
Type monitor.AlertResourceType
Name string
@@ -142,6 +176,17 @@ func (m *SAlertResourceManager) getResourceFromMatch(ctx context.Context, userCr
return &objs[0], nil
}
func (m *SAlertResourceManager) getResourceFromAlertId(alertId string) ([]SAlertResource, error) {
searchResourceIdQuery := GetAlertResourceAlertManager().Query(GetAlertResourceAlertManager().GetMasterFieldName())
searchResourceIdQuery = searchResourceIdQuery.Equals(GetAlertResourceAlertManager().GetSlaveFieldName(), alertId)
query := m.Query().In("id", searchResourceIdQuery.SubQuery())
objs := make([]SAlertResource, 0)
if err := db.FetchModelObjects(m, query, &objs); err != nil {
return nil, errors.Wrapf(err, "getResourceFromAlertId:%s error", alertId)
}
return objs, nil
}
func (m *SAlertResourceManager) reconcileFromRecordMatch(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, record *SAlertRecord, match monitor.EvalMatch) error {
drv, err := GetAlertResourceDriver(match)
if err != nil {
@@ -450,7 +495,7 @@ func (manager *SAlertResourceManager) GetAdminRoleUsers(ctx context.Context, use
userId, err := roleAssign.GetString("user", "id")
if err != nil {
log.Errorf("roleAssign:%v", roleAssign)
return
continue
}
//_, err = mc_modules.NotifyReceiver.GetById(session, userId, jsonutils.NewDict())
//if err != nil {
@@ -474,6 +519,7 @@ func (manager *SAlertResourceManager) sendWebsocketInfo(uids []string, alertReso
params.Set("obj_name", jsonutils.NewString(""))
params.Set("success", jsonutils.JSONTrue)
params.Set("action", jsonutils.NewString("alertResourceCount"))
params.Set("ignore_alert", jsonutils.JSONTrue)
params.Set("notes", jsonutils.NewString(fmt.Sprintf("priority=%s; content=%s", string(npk.NotifyPriorityCritical),
jsonutils.Marshal(&alertResourceCount).String())))
for _, uid := range uids {

View File

@@ -17,6 +17,7 @@ import (
"yunion.io/x/onecloud/pkg/apis"
"yunion.io/x/onecloud/pkg/apis/monitor"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
merrors "yunion.io/x/onecloud/pkg/monitor/errors"
@@ -926,3 +927,44 @@ func (alert *SCommonAlert) PerformConfig(ctx context.Context, userCred mcclient.
})
return jsonutils.Marshal(alert), err
}
func (alert *SCommonAlert) AllowPerformDisable(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformDisableInput) bool {
return db.IsProjectAllowPerform(userCred, alert, "disable")
}
func (alert *SCommonAlert) PerformDisable(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformDisableInput) (jsonutils.JSONObject, error) {
err := db.EnabledPerformEnable(alert, ctx, userCred, false)
if err != nil {
return nil, errors.Wrap(err, "EnabledPerformEnable")
}
err = alert.StartDetachTask(ctx, userCred)
if err != nil {
return nil, errors.Wrap(err, "alert StartDetachTask error")
}
return nil, nil
}
func (alert *SCommonAlert) StartDetachTask(ctx context.Context, userCred mcclient.TokenCredential) error {
task, err := taskman.TaskManager.NewTask(ctx, "DetachAlertResourceTask", alert, userCred, jsonutils.NewDict(), "", "", nil)
if err != nil {
return err
}
task.ScheduleRun(nil)
return nil
}
func (alert *SCommonAlert) DetachAlertResourceOnDisable(ctx context.Context,
userCred mcclient.TokenCredential) (errs []error) {
resources, err := GetAlertResourceManager().getResourceFromAlertId(alert.Id)
if err != nil {
errs = append(errs, errors.Wrap(err, "getResourceFromAlert error"))
return
}
for _, resource := range resources {
err := resource.DetachAlert(ctx, userCred, alert.Id)
if err != nil {
errs = append(errs, errors.Wrapf(err, "resource:%s DetachAlert:%s err", resource.Id, alert.Id))
}
}
return
}

View File

@@ -205,6 +205,11 @@ func (man *SSuggestSysAlertManager) ValidateCreateData(
return data, nil
}
func (self *SSuggestSysAlert) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return nil
}
func (man *SSuggestSysAlertManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
@@ -319,7 +324,7 @@ func (self *SSuggestSysAlert) Delete(ctx context.Context, userCred mcclient.Toke
}
func (self *SSuggestSysAlert) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DeleteModel(ctx, userCred, self)
return self.SVirtualResourceBase.Delete(ctx, userCred)
}
func (self *SSuggestSysAlert) StartDeleteTask(

View File

@@ -7,6 +7,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
compute_api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/apis/monitor"
@@ -94,27 +95,18 @@ func (drv *SecGroupRuleInServer) getSecGroupIdsInThisRule() ([]string, error) {
}
func (drv *SecGroupRuleInServer) getServersBySecGroupIds(secGroupIdArr []string) ([]jsonutils.JSONObject, error) {
i, count := 1, 0
param := jsonutils.NewDict()
param.Add(jsonutils.NewString("hypervisor.notin(baremetal,container)"), "filter.0")
filterSecGroupIds := make([]string, 0)
jump := false
for {
tmp := count + 50
if tmp > len(secGroupIdArr) {
tmp = len(secGroupIdArr)
jump = true
servers := make([]jsonutils.JSONObject, 0)
for _, secGroupId := range secGroupIdArr {
param.Set("secgroup_id", jsonutils.NewString(secGroupId))
serversPart, err := ListAllResources(&modules.Servers, param)
if err != nil {
return nil, errors.Wrap(err, "SecGroupRuleInServer getServers error")
}
filterSecGroupIds = secGroupIdArr[count:tmp]
param.Add(jsonutils.NewString(fmt.Sprintf("`secgroup.in(%s)", strings.Join(filterSecGroupIds, ","))),
fmt.Sprintf("filter.%d", i))
if jump {
break
}
i++
count = tmp
servers = append(servers, serversPart...)
}
return ListAllResources(&modules.Servers, param)
return servers, nil
}
func (drv *SecGroupRuleInServer) StartResolveTask(ctx context.Context, userCred mcclient.TokenCredential,

View File

@@ -0,0 +1,46 @@
package tasks
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/monitor/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type DetachAlertResourceTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(&DetachAlertResourceTask{})
}
func (self *DetachAlertResourceTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
alert := obj.(*models.SCommonAlert)
errs := alert.DetachAlertResourceOnDisable(ctx, self.GetUserCred())
if len(errs) != 0 {
msg := jsonutils.NewString(fmt.Sprintf("fail to DetachAlertResourceOnAlertDisable:%s.err:%v", alert.Name, errors.NewAggregate(errs)))
self.taskFail(ctx, alert, msg)
return
}
err := models.GetAlertResourceManager().NotifyAlertResourceCount(ctx)
if err != nil {
log.Errorf("DetachAlertResourceTask NotifyAlertResourceCount error:%v", err)
}
logclient.AddActionLogWithStartable(self, alert, logclient.ACT_DETACH_ALERTRESOURCE, nil, self.UserCred, true)
self.SetStageComplete(ctx, nil)
}
func (self *DetachAlertResourceTask) taskFail(ctx context.Context, alert *models.SCommonAlert, msg jsonutils.JSONObject) {
db.OpsLog.LogEvent(alert, db.ACT_DETACH, msg, self.GetUserCred())
logclient.AddActionLogWithStartable(self, alert, logclient.ACT_DETACH_ALERTRESOURCE, msg, self.UserCred, false)
self.SetStageFailed(ctx, msg)
return
}

View File

@@ -429,7 +429,7 @@ func (self *SAliyunClient) GetIHostById(id string) (cloudprovider.ICloudHost, er
ihost, err := self.iregions[i].GetIHostById(id)
if err == nil {
return ihost, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}
@@ -441,7 +441,7 @@ func (self *SAliyunClient) GetIVpcById(id string) (cloudprovider.ICloudVpc, erro
ihost, err := self.iregions[i].GetIVpcById(id)
if err == nil {
return ihost, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}
@@ -453,7 +453,7 @@ func (self *SAliyunClient) GetIStorageById(id string) (cloudprovider.ICloudStora
ihost, err := self.iregions[i].GetIStorageById(id)
if err == nil {
return ihost, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}

View File

@@ -19,8 +19,7 @@ import (
"strings"
"time"
"github.com/coredns/coredns/plugin/pkg/log"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/utils"
@@ -184,9 +183,13 @@ func (rds *SDBInstance) GetIDBInstanceBackups() ([]cloudprovider.ICloudDBInstanc
return ibackups, nil
}
func (rds *SDBInstance) CreateIBackup(conf *cloudprovider.SDBInstanceBackupCreateConfig) (string, error) {
func (self *SRegion) CreateDBInstanceBackup(rdsId string, databases []string) (string, error) {
rds, err := self.GetDBInstanceDetail(rdsId)
if err != nil {
return "", errors.Wrapf(err, "GetDBInstanceDetail")
}
params := map[string]string{
"DBInstanceId": rds.DBInstanceId,
"DBInstanceId": rdsId,
}
switch rds.Engine {
case api.DBINSTANCE_TYPE_MYSQL:
@@ -199,9 +202,9 @@ func (rds *SDBInstance) CreateIBackup(conf *cloudprovider.SDBInstanceBackupCreat
params["BackupMethod"] = "Snapshot"
} else {
params["BackupMethod"] = "Physical"
if len(conf.Databases) > 0 {
if len(databases) > 0 {
params["BackupStrategy"] = "db"
params["DBName"] = strings.Join(conf.Databases, ",")
params["DBName"] = strings.Join(databases, ",")
params["BackupMethod"] = "Logical"
}
}
@@ -218,7 +221,7 @@ func (rds *SDBInstance) CreateIBackup(conf *cloudprovider.SDBInstanceBackupCreat
case api.DBINSTANCE_TYPE_PPAS:
params["BackupMethod"] = "Physical"
}
body, err := rds.region.rdsRequest("CreateBackup", params)
body, err := self.rdsRequest("CreateBackup", params)
if err != nil {
return "", errors.Wrap(err, "CreateBackup")
}
@@ -226,7 +229,11 @@ func (rds *SDBInstance) CreateIBackup(conf *cloudprovider.SDBInstanceBackupCreat
if err != nil {
return "", errors.Wrap(err, "body.BackupJobId")
}
return "", rds.region.waitBackupCreateComplete(rds.DBInstanceId, jobId)
return self.waitBackupCreateComplete(rds.DBInstanceId, jobId)
}
func (rds *SDBInstance) CreateIBackup(conf *cloudprovider.SDBInstanceBackupCreateConfig) (string, error) {
return rds.region.CreateDBInstanceBackup(rds.DBInstanceId, conf.Databases)
}
func (backup *SDBInstanceBackup) Delete() error {
@@ -249,6 +256,7 @@ type SDBInstanceBackupJob struct {
TaskAction string
BackupStatus string
BackupJobId string
BackupId string
}
type SDBInstanceBackupJobs struct {
@@ -279,25 +287,70 @@ func (region *SRegion) GetDBInstanceBackupJobs(instanceId, jobId string) (*SDBIn
return &jobs, nil
}
func (region *SRegion) waitBackupCreateComplete(instanceId, jobId string) error {
for i := 0; i < 20*40; i++ {
func (region *SRegion) waitBackupCreateComplete(instanceId, jobId string) (string, error) {
err := cloudprovider.Wait(time.Second*10, time.Minute*40, func() (bool, error) {
jobs, err := region.GetDBInstanceBackupJobs(instanceId, jobId)
if err != nil {
return errors.Wrapf(err, "region.GetDBInstanceBackupJobs(%s, %s)", instanceId, jobId)
return false, errors.Wrapf(err, "region.GetDBInstanceBackupJobs(%s, %s)", instanceId, jobId)
}
if len(jobs.BackupJob) == 0 {
return nil
return true, nil
}
for _, job := range jobs.BackupJob {
log.Infof("instance %s backup job %s status: %s(%s)", instanceId, jobId, job.BackupStatus, job.Process)
if job.BackupStatus == "Finished" && job.BackupJobId == jobId {
return nil
return true, nil
}
if job.BackupStatus == "Failed" && job.BackupJobId == jobId {
return fmt.Errorf("instance %s backup job %s failed", instanceId, jobId)
return false, fmt.Errorf("instance %s backup job %s failed", instanceId, jobId)
}
}
time.Sleep(time.Second * 3)
return false, nil
})
if err != nil {
return "", errors.Wrapf(err, "wait backup create job")
}
return fmt.Errorf("timeout for waiting create job complete")
jobs, err := region.GetDBInstanceBackupJobs(instanceId, jobId)
if err != nil {
return "", errors.Wrapf(err, "region.GetDBInstanceBackupJobs(%s, %s)", instanceId, jobId)
}
for _, job := range jobs.BackupJob {
if job.BackupStatus == "Finished" && job.BackupJobId == jobId {
if len(job.BackupId) == 0 {
return "", fmt.Errorf("Missing backup id")
}
return job.BackupId, nil
}
}
return "", fmt.Errorf("failed to found backup job %s backupid", jobId)
}
func (self *SDBInstanceBackup) GetBackupMethod() cloudprovider.TBackupMethod {
return cloudprovider.TBackupMethod(self.BackupMethod)
}
func (self *SDBInstanceBackup) CreateICloudDBInstance(opts *cloudprovider.SManagedDBInstanceCreateConfig) (cloudprovider.ICloudDBInstance, error) {
rdsId, err := self.region.CreateDBInstanceByBackup(self.BackupId, opts)
if err != nil {
return nil, errors.Wrapf(err, "CreateDBInstanceByBackup")
}
return self.region.GetDBInstanceDetail(rdsId)
}
func (self *SRegion) CreateDBInstanceByBackup(backupId string, opts *cloudprovider.SManagedDBInstanceCreateConfig) (string, error) {
params := map[string]string{
"DBInstanceId": opts.RdsId,
"DBInstanceStorageType": opts.StorageType,
"PayType": "Postpaid",
"BackupId": backupId,
}
resp, err := self.rdsRequest("CloneDBInstance", params)
if err != nil {
return "", errors.Wrapf(err, "rdsRequest")
}
rdsId, err := resp.GetString("DBInstanceId")
if err != nil {
return "", fmt.Errorf("missing DBInstanceId after CloneDBInstance")
}
return rdsId, nil
}

View File

@@ -352,7 +352,7 @@ func (self *SAliyunProvider) GetICloudDnsZoneById(id string) (cloudprovider.IClo
if err == nil {
return privateIzone, nil
} else {
if err != cloudprovider.ErrNotFound {
if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}
@@ -361,7 +361,7 @@ func (self *SAliyunProvider) GetICloudDnsZoneById(id string) (cloudprovider.IClo
if err == nil {
return publicIzone, nil
} else {
if err != cloudprovider.ErrNotFound {
if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}

View File

@@ -15,6 +15,8 @@
package aliyun
import (
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
@@ -55,7 +57,7 @@ const (
func (self *SAliyunClient) EnableImageImport() error {
_, err := self.GetRole(AliyunECSImageImportRole)
if err != nil {
if err != cloudprovider.ErrNotFound {
if errors.Cause(err) != cloudprovider.ErrNotFound {
return err
}
_, err = self.CreateRole(AliyunECSImageImportRole,

View File

@@ -196,7 +196,11 @@ func (self *SRegion) GetId() string {
}
func (self *SRegion) GetName() string {
return fmt.Sprintf("%s %s", CLOUD_PROVIDER_ALIYUN_CN, self.LocalName)
if self.GetCloudEnv() == ALIYUN_FINANCE_CLOUDENV && !strings.Contains(self.LocalName, "金融") {
return fmt.Sprintf("%s %s %s", CLOUD_PROVIDER_ALIYUN_CN, self.LocalName, "金融云")
} else {
return fmt.Sprintf("%s %s", CLOUD_PROVIDER_ALIYUN_CN, self.LocalName)
}
}
func (self *SRegion) GetGlobalId() string {
@@ -212,7 +216,7 @@ func (self *SRegion) GetProvider() string {
}
func (self *SRegion) GetCloudEnv() string {
return ""
return self.client.cloudEnv
}
func (self *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo {
@@ -619,7 +623,7 @@ func (self *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
ihost, err := izones[i].GetIHostById(id)
if err == nil {
return ihost, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}
@@ -635,7 +639,7 @@ func (self *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, er
istore, err := izones[i].GetIStorageById(id)
if err == nil {
return istore, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}

View File

@@ -15,6 +15,8 @@
package shell
import (
"fmt"
"yunion.io/x/onecloud/pkg/multicloud/aliyun"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
@@ -61,4 +63,18 @@ func init() {
return nil
})
type DBInstanceBackupCreateOptions struct {
INSTANCE_ID string
Database []string
}
shellutils.R(&DBInstanceBackupCreateOptions{}, "dbinstance-backup-create", "Create dbintance backup", func(cli *aliyun.SRegion, args *DBInstanceBackupCreateOptions) error {
backupId, err := cli.CreateDBInstanceBackup(args.INSTANCE_ID, args.Database)
if err != nil {
return err
}
fmt.Println("backup id: ", backupId)
return nil
})
}

View File

@@ -157,15 +157,13 @@ func (self *SStoragecache) uploadImage(ctx context.Context, userCred mcclient.To
bucketName := strings.ToLower(fmt.Sprintf("imgcache-%s-%s", self.region.GetId(), image.ImageId))
exist, err := self.region.IBucketExist(bucketName)
if err != nil {
log.Errorf("IsBucketExist err %s", err)
return "", err
return "", errors.Wrapf(err, "IBucketExist(%s)", bucketName)
}
if !exist {
log.Debugf("Bucket %s not exists, to create ...", bucketName)
err = self.region.CreateIBucket(bucketName, "", "")
if err != nil {
log.Errorf("Create bucket error %s", err)
return "", err
return "", errors.Wrapf(err, "CreateIBucket %s", bucketName)
}
} else {
log.Debugf("Bucket %s exists", bucketName)
@@ -175,15 +173,13 @@ func (self *SStoragecache) uploadImage(ctx context.Context, userCred mcclient.To
bucket, err := self.region.GetIBucketByName(bucketName)
if err != nil {
log.Errorf("Bucket error %s %s", bucketName, err)
return "", err
return "", errors.Wrapf(err, "GetIBucketByName %s", bucketName)
}
log.Debugf("To upload image to bucket %s ...", bucketName)
err = cloudprovider.UploadObject(context.Background(), bucket, image.ImageId, 0, reader, sizeByte, "", "", nil, false)
// err = bucket.PutObject(image.ImageId, reader)
if err != nil {
log.Errorf("PutObject error %s %s", image.ImageId, err)
return "", err
return "", errors.Wrapf(err, "UploadObject %s", image.ImageId)
}
defer bucket.DeleteObject(context.Background(), image.ImageId) // remove object
@@ -214,22 +210,19 @@ func (self *SStoragecache) uploadImage(ctx context.Context, userCred mcclient.To
// ensure privileges
err = self.region.GetClient().EnableImageImport()
if err != nil {
log.Errorf("fail to enable import privileges: %s", err)
return "", err
return "", errors.Wrapf(err, "EnableImageImport")
}
task, err := self.region.ImportImage(imageName, image.OsArch, image.OsType, image.OsDistribution, bucketName, image.ImageId)
if err != nil {
log.Errorf("ImportImage error %s %s %s", image.ImageId, bucketName, err)
return "", err
return "", errors.Wrapf(err, "ImportImage %s %s", image.ImageId, bucketName)
}
// timeout: 1hour = 3600 seconds
err = self.region.waitTaskStatus(ImportImageTask, task.TaskId, TaskStatusFinished, 15*time.Second, 3600*time.Second)
if err != nil {
log.Errorf("waitTaskStatus %s", err)
return task.ImageId, err
return task.ImageId, errors.Wrapf(err, "waitTaskStatus")
}
return task.ImageId, nil

View File

@@ -16,6 +16,7 @@ package aliyun
import (
"fmt"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
@@ -139,7 +140,11 @@ func (self *SZone) GetId() string {
}
func (self *SZone) GetName() string {
return fmt.Sprintf("%s %s", CLOUD_PROVIDER_ALIYUN_CN, self.LocalName)
if self.region.GetCloudEnv() == ALIYUN_FINANCE_CLOUDENV && !strings.Contains(self.LocalName, "金融") {
return fmt.Sprintf("%s %s %s", CLOUD_PROVIDER_ALIYUN_CN, self.LocalName, "金融云")
} else {
return fmt.Sprintf("%s %s", CLOUD_PROVIDER_ALIYUN_CN, self.LocalName)
}
}
func (self *SZone) GetGlobalId() string {

View File

@@ -25,6 +25,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/apis/billing"
api "yunion.io/x/onecloud/pkg/apis/compute"
@@ -188,7 +189,7 @@ func (self *SDisk) GetMountpoint() string {
}
func (self *SDisk) Delete(ctx context.Context) error {
if _, err := self.storage.zone.region.GetDisk(self.DiskId); err == cloudprovider.ErrNotFound {
if _, err := self.storage.zone.region.GetDisk(self.DiskId); err != nil && errors.Cause(err) == cloudprovider.ErrNotFound {
log.Errorf("Failed to find disk %s when delete", self.DiskId)
return nil
}

View File

@@ -380,7 +380,7 @@ func (self *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
ihost, err := izones[i].GetIHostById(id)
if err == nil {
return ihost, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}
@@ -413,7 +413,7 @@ func (self *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, er
istore, err := izones[i].GetIStorageById(id)
if err == nil {
return istore, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}

View File

@@ -17,7 +17,10 @@ package multicloud
import (
"fmt"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SDBInstanceBackupBase struct {
@@ -35,3 +38,11 @@ func (backup *SDBInstanceBackupBase) Delete() error {
func (backup *SDBInstanceBackupBase) GetProjectId() string {
return ""
}
func (backup *SDBInstanceBackupBase) CreateICloudDBInstance(opts *cloudprovider.SManagedDBInstanceCreateConfig) (cloudprovider.ICloudDBInstance, error) {
return nil, errors.Wrap(cloudprovider.ErrNotImplemented, "CreateICloudDBInstance")
}
func (backup *SDBInstanceBackupBase) GetBackupMethod() cloudprovider.TBackupMethod {
return cloudprovider.BackupMethodUnknown
}

View File

@@ -15,6 +15,7 @@
package esxi
import (
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/compute"
@@ -53,7 +54,7 @@ func (cli *SESXiClient) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
}
for _, host := range hosts {
vm, err := host.GetIVMById(id)
if err != cloudprovider.ErrNotFound {
if errors.Cause(err) != cloudprovider.ErrNotFound {
return vm, err
}
}
@@ -67,7 +68,7 @@ func (self *SESXiClient) GetIDiskById(id string) (cloudprovider.ICloudDisk, erro
}
for _, storage := range storages {
disk, err := storage.GetIDiskById(id)
if err != cloudprovider.ErrNotFound {
if errors.Cause(err) != cloudprovider.ErrNotFound {
return disk, err
}
}

View File

@@ -1173,7 +1173,7 @@ func (host *SHost) newLocalStorageCache() (*SDatastoreImageCache, error) {
}
_, err := ds.CheckFile(ctx, IMAGE_CACHE_DIR_NAME)
if err != nil {
if err != cloudprovider.ErrNotFound {
if errors.Cause(err) != cloudprovider.ErrNotFound {
// return nil, err
if len(errmsg) > 0 {
errmsg += ","

View File

@@ -23,6 +23,7 @@ import (
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/multicloud"
)
type OperationError struct {
@@ -32,6 +33,7 @@ type OperationError struct {
}
type SDBInstanceBackup struct {
multicloud.SDBInstanceBackupBase
rds *SDBInstance
Kind string

View File

@@ -247,7 +247,7 @@ func (region *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error)
ihost, err := izones[i].GetIHostById(id)
if err == nil {
return ihost, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}

View File

@@ -384,7 +384,7 @@ func (self *SHuaweiClient) GetIHostById(id string) (cloudprovider.ICloudHost, er
ihost, err := self.iregions[i].GetIHostById(id)
if err == nil {
return ihost, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}
@@ -396,7 +396,7 @@ func (self *SHuaweiClient) GetIVpcById(id string) (cloudprovider.ICloudVpc, erro
ivpc, err := self.iregions[i].GetIVpcById(id)
if err == nil {
return ivpc, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}
@@ -408,7 +408,7 @@ func (self *SHuaweiClient) GetIStorageById(id string) (cloudprovider.ICloudStora
istorage, err := self.iregions[i].GetIStorageById(id)
if err == nil {
return istorage, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}

View File

@@ -46,6 +46,10 @@ func (o *SObject) GetAcl() cloudprovider.TBucketACLType {
input.Bucket = o.bucket.Name
input.Key = o.Key
output, err := obscli.GetObjectAcl(input)
if err != nil {
log.Errorf("GetObjectAcl error: %v", err)
return acl
}
acl = obsAcl2CannedAcl(output.Grants)
return acl
}

View File

@@ -644,7 +644,7 @@ func (self *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
ihost, err := izones[i].GetIHostById(id)
if err == nil {
return ihost, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}
@@ -677,7 +677,7 @@ func (self *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, er
istore, err := izones[i].GetIStorageById(id)
if err == nil {
return istore, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}

View File

@@ -121,7 +121,7 @@ func (region *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error)
ihost, err := izones[i].GetIHostById(id)
if err == nil {
return ihost, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}

View File

@@ -678,8 +678,7 @@ func (self *SRegion) DeleteVM(instanceId string) error {
if errors.Cause(err) == cloudprovider.ErrNotFound {
return nil
}
log.Errorf("Fail to get instance status on DeleteVM: %s", err)
return err
return errors.Wrapf(err, "self.GetInstanceStatus")
}
log.Debugf("Instance status on delete is %s", status)
if status != InstanceStatusStopped {
@@ -730,10 +729,11 @@ func (self *SRegion) DeployVM(instanceId string, name string, password string, k
}
func (self *SInstance) DeleteVM(ctx context.Context) error {
if err := self.host.zone.region.DeleteVM(self.InstanceId); err != nil {
return err
err := self.host.zone.region.DeleteVM(self.InstanceId)
if err != nil {
return errors.Wrapf(err, "region.DeleteVM(%s)", self.InstanceId)
}
return cloudprovider.WaitDeleted(self, 10*time.Second, 300*time.Second) // 5minutes
return cloudprovider.WaitDeleted(self, 10*time.Second, 10*time.Minute) // 5minutes
}
func (self *SRegion) UpdateVM(instanceId string, name, osType string) error {

View File

@@ -749,7 +749,7 @@ func (client *SQcloudClient) GetIHostById(id string) (cloudprovider.ICloudHost,
ihost, err := client.iregions[i].GetIHostById(id)
if err == nil {
return ihost, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}
@@ -761,7 +761,7 @@ func (client *SQcloudClient) GetIVpcById(id string) (cloudprovider.ICloudVpc, er
ihost, err := client.iregions[i].GetIVpcById(id)
if err == nil {
return ihost, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}
@@ -773,7 +773,7 @@ func (client *SQcloudClient) GetIStorageById(id string) (cloudprovider.ICloudSto
ihost, err := client.iregions[i].GetIStorageById(id)
if err == nil {
return ihost, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}

View File

@@ -349,7 +349,7 @@ func (self *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
ihost, err := izones[i].GetIHostById(id)
if err == nil {
return ihost, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}
@@ -365,7 +365,7 @@ func (self *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, er
istore, err := izones[i].GetIStorageById(id)
if err == nil {
return istore, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}

View File

@@ -310,7 +310,7 @@ func (self *SRegion) GetIHostById(id string) (cloudprovider.ICloudHost, error) {
ihost, err := izones[i].GetIHostById(id)
if err == nil {
return ihost, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}
@@ -343,7 +343,7 @@ func (self *SRegion) GetIStorageById(id string) (cloudprovider.ICloudStorage, er
istore, err := izones[i].GetIStorageById(id)
if err == nil {
return istore, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}

View File

@@ -337,7 +337,7 @@ func (self *SUcloudClient) GetIHostById(id string) (cloudprovider.ICloudHost, er
ihost, err := self.iregions[i].GetIHostById(id)
if err == nil {
return ihost, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}
@@ -349,7 +349,7 @@ func (self *SUcloudClient) GetIVpcById(id string) (cloudprovider.ICloudVpc, erro
ihost, err := self.iregions[i].GetIVpcById(id)
if err == nil {
return ihost, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}
@@ -361,7 +361,7 @@ func (self *SUcloudClient) GetIStorageById(id string) (cloudprovider.ICloudStora
ihost, err := self.iregions[i].GetIStorageById(id)
if err == nil {
return ihost, nil
} else if err != cloudprovider.ErrNotFound {
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, err
}
}

View File

@@ -243,6 +243,8 @@ func (rm *SReceiverManager) ValidateCreateData(ctx context.Context, userCred mcc
return input, err
}
uname, _ := userObj.GetString("name")
uid, _ := userObj.GetString("id")
input.UID = uid
input.UName = uname
domainId, _ := userObj.GetString("domain_id")
input.ProjectDomainId = domainId
@@ -260,7 +262,9 @@ func (rm *SReceiverManager) ValidateCreateData(ctx context.Context, userCred mcc
return input, err
}
uid, _ := userObj.GetString("id")
uname, _ := userObj.GetString("name")
input.UID = uid
input.UName = uname
domainId, _ := userObj.GetString("domain_id")
input.ProjectDomainId = domainId
}
@@ -862,6 +866,9 @@ func (rm *SReceiverManager) OnUpdate(oldObj, newObj *jsonutils.JSONDict) {
log.Errorf("fail to FetchByIDs: %v", err)
return
}
if len(receivers) == 0 {
return
}
receiver := &receivers[0]
uname, _ := newObj.GetString("name")
domainId, _ := newObj.GetString("domain_id")
@@ -885,6 +892,9 @@ func (rm *SReceiverManager) OnDelete(obj *jsonutils.JSONDict) {
log.Errorf("fail to FetchByIDs: %v", err)
return
}
if len(receivers) == 0 {
return
}
receiver := &receivers[0]
err = receiver.Delete(context.Background(), auth.GetAdminSession(context.Background(), "", "").GetToken())
if err != nil {

View File

@@ -58,6 +58,11 @@ func StartService() {
db.EnsureAppInitSyncDB(applicaion, dbOpts, models.InitDB)
defer cloudcommon.CloseDB()
err := models.ReceiverManager.StartWatchUserInKeystone()
if err != nil {
log.Logger().Panic(err.Error())
}
// init notify service
models.NotifyService = rpc.NewSRpcService(opts.SocketFileDir, models.ConfigManager, models.TemplateManager)
models.NotifyService.InitAll()

View File

@@ -180,4 +180,6 @@ const (
ACT_SYNC_VPCS = "sync_vpcs"
ACT_SYNC_RECORD_SETS = "sync_record_sets"
ACT_DETACH_ALERTRESOURCE = "detach_alertresoruce"
)

View File

@@ -609,4 +609,8 @@ func init() {
EN("Freeze").
CN("解冻资源"),
)
t.Set(ACT_DETACH_ALERTRESOURCE, i18n.NewTableEntry().
EN("Detach AlertResource").
CN("取消关联报警资源"),
)
}

View File

@@ -100,6 +100,11 @@ build_process() {
build_bin $component
build_bundle_libraries $component
img_name="$REGISTRY/$component:$TAG"
if [[ "$(uname -m)" == aarch64 ]]; then
img_name="${img_name}-arm64"
fi
build_image $img_name $DOCKER_DIR/Dockerfile.$component $SRC_DIR
push_image "$img_name"
}
@@ -129,6 +134,28 @@ build_process_with_buildx() {
esac
}
function general_build(){
local current_arch
case $(uname -m) in
x86_64)
current_arch=amd64
;;
aarch64)
current_arch=arm64
;;
esac
local component=$1
# 如果未指定,则默认使用当前架构
local arch=${2:-$current_arch}
if [[ "$current_arch" == "$arch" ]]; then
build_process $component
else
build_process_with_buildx $component $arch
fi
}
ALL_COMPONENTS=$(ls cmd | grep -v '.*cli$' | xargs)
if [ "$#" -lt 1 ]; then
@@ -160,14 +187,11 @@ for component in $COMPONENTS; do
case "$ARCH" in
all)
for arch in "arm64" "amd64"; do
build_process_with_buildx $component $arch
general_build $component $arch
done
;;
arm64|amd64)
build_process_with_buildx $component $ARCH
;;
*)
build_process $component
general_build $component $ARCH
;;
esac
done

2
vendor/modules.txt vendored
View File

@@ -1067,7 +1067,7 @@ sigs.k8s.io/yaml
yunion.io/x/executor/apis
yunion.io/x/executor/client
yunion.io/x/executor/server
# yunion.io/x/jsonutils v0.0.0-20201105032201-9d0fba742954
# yunion.io/x/jsonutils v0.0.0-20201110084044-3e4e1cb49769
yunion.io/x/jsonutils
# yunion.io/x/log v0.0.0-20200313080802-57a4ce5966b3
yunion.io/x/log

View File

@@ -217,7 +217,11 @@ func Marshal(obj interface{}) JSONObject {
if obj == nil {
return JSONNull
}
objValue := reflect.Indirect(reflect.ValueOf(obj))
val := reflect.ValueOf(obj)
if kind := val.Kind(); val.IsZero() && kind == reflect.Ptr {
return JSONNull
}
objValue := reflect.Indirect(val)
return marshalValue(objValue, nil)
}