fix(region): fixModelarts

This commit is contained in:
mhf
2023-04-13 16:23:51 +08:00
parent f8c1c9944d
commit ee72b8862f
18 changed files with 328 additions and 87 deletions

View File

@@ -1,5 +1,3 @@
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:v0.3.5-1
COPY ./build/esxi-agent/root/opt/ /opt/
ADD ./_output/alpine-build/bin/esxi-agent /opt/yunion/bin/esxi-agent

4
go.mod
View File

@@ -84,9 +84,9 @@ require (
k8s.io/client-go v0.19.3
k8s.io/cluster-bootstrap v0.19.3
moul.io/http2curl/v2 v2.3.0
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230407102918-dd668c09f13d
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230413051450-19d2c693bfa2
yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656
yunion.io/x/jsonutils v1.0.1-0.20220819091305-3bab322ab4fd
yunion.io/x/jsonutils v1.0.1-0.20230412125709-357258302671
yunion.io/x/log v1.0.1-0.20230411060016-feb3f46ab361
yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900
yunion.io/x/pkg v1.0.1-0.20230327034731-79f520e7d373

8
go.sum
View File

@@ -1185,14 +1185,14 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230407102918-dd668c09f13d h1:6UQnGSIqyux7wF9qJdEXwluos8Mb9zQoEzxq2U91ugs=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230407102918-dd668c09f13d/go.mod h1:VBAtfyGMDW11x5JmF0vUEmn/PmNpZ8CKBAQCiyz+cDY=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230413051450-19d2c693bfa2 h1:/VWhFOinPOIoaA8v7eqndrrkaAzu9tWrauRXiJvrIO4=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230413051450-19d2c693bfa2/go.mod h1:VBAtfyGMDW11x5JmF0vUEmn/PmNpZ8CKBAQCiyz+cDY=
yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656 h1:0zlZD5uhZoIHgLVAWCz2aHaYk2ZrNsACCYD7R6EIBII=
yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
yunion.io/x/jsonutils v0.0.0-20220106020632-953b71a4c3a8/go.mod h1:p0nyMqGA/apTxxyLIU/o1k4V7Vujl2O6ey30L594sYE=
yunion.io/x/jsonutils v1.0.1-0.20220819091305-3bab322ab4fd h1:QUAIH9oqQoDRz/byjE8id4yZE1qbCc53QzhsfcLzQp8=
yunion.io/x/jsonutils v1.0.1-0.20220819091305-3bab322ab4fd/go.mod h1:L5QYTYqiL+f56wzir14TWHurE3Vcn9elaFiQpPWhXsg=
yunion.io/x/jsonutils v1.0.1-0.20230412125709-357258302671 h1:bx33Bs3JeAf+OF6oGXGC4x181w8f7Qwcu3XLDTwVXIA=
yunion.io/x/jsonutils v1.0.1-0.20230412125709-357258302671/go.mod h1:L5QYTYqiL+f56wzir14TWHurE3Vcn9elaFiQpPWhXsg=
yunion.io/x/log v0.0.0-20190514041436-04ce53b17c6b/go.mod h1:+gauLs73omeJAPlsXcevLsJLKixV+sR/E7WSYTSx1fE=
yunion.io/x/log v0.0.0-20190629062853-9f6483a7103d/go.mod h1:LC6f/4FozL0iaAbnFt2eDX9jlsyo3WiOUPm03d7+U4U=
yunion.io/x/log v1.0.0/go.mod h1:LC6f/4FozL0iaAbnFt2eDX9jlsyo3WiOUPm03d7+U4U=

View File

@@ -24,6 +24,7 @@ import (
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/util/netutils"
"yunion.io/x/pkg/utils"
"yunion.io/x/sqlchemy"
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
@@ -302,7 +303,7 @@ func (self *SModelartsPool) ValidateDeleteCondition(ctx context.Context, info js
if self.DisableDelete.IsTrue() {
return httperrors.NewInvalidStatusError("ModelartsPool is locked, cannot delete")
}
if self.Status != api.MODELARTS_POOL_STATUS_RUNNING && self.Status != api.MODELARTS_POOL_STATUS_UNKNOWN {
if utils.IsInStringArray(self.Status, []string{api.MODELARTS_POOL_STATUS_CREATING, api.MODELARTS_POOL_STATUS_DELETING}) {
return httperrors.NewInvalidStatusError("ModelartsPool status cannot support delete")
}
return self.SStatusStandaloneResourceBase.ValidateDeleteCondition(ctx, nil)

View File

@@ -17,7 +17,6 @@ package tasks
import (
"context"
"strings"
"time"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
@@ -48,11 +47,6 @@ func (modelartsCreateTask *ModelartsPoolCreateTask) taskFailed(ctx context.Conte
func (modelartsCreateTask *ModelartsPoolCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
pool := obj.(*models.SModelartsPool)
iRegion, err := pool.GetIRegion()
if err != nil {
modelartsCreateTask.taskFailed(ctx, pool, api.MODELARTS_POOL_STATUS_CREATE_FAILED, errors.Wrapf(err, "pool.GetIRegion"))
return
}
opts := &cloudprovider.ModelartsPoolCreateOption{
Name: pool.Name,
@@ -62,19 +56,9 @@ func (modelartsCreateTask *ModelartsPoolCreateTask) OnInit(ctx context.Context,
Cidr: pool.Cidr,
}
ipool, err := iRegion.CreateIModelartsPool(opts)
if err != nil {
modelartsCreateTask.taskFailed(ctx, pool, api.MODELARTS_POOL_STATUS_CREATE_FAILED, errors.Wrapf(err, "iRegion.CreateIModelartsPool"))
return
}
err = db.SetExternalId(pool, modelartsCreateTask.GetUserCred(), ipool.GetGlobalId())
if err != nil {
modelartsCreateTask.taskFailed(ctx, pool, api.MODELARTS_POOL_STATUS_CREATE_FAILED, errors.Wrapf(err, "db.SetExternalId"))
return
}
modelartsCreateTask.SetStage("OnModelartsPoolCreateComplete", nil)
// withDelay
modelartsCreateTask.WaitStatus(ctx, ipool, pool)
modelartsCreateTask.WaitStatus(ctx, opts, pool)
}
func (modelartsCreateTask *ModelartsPoolCreateTask) taskComplete(ctx context.Context, pool *models.SModelartsPool) {
@@ -85,17 +69,26 @@ func (modelartsCreateTask *ModelartsPoolCreateTask) taskComplete(ctx context.Con
})
}
func (modelartsCreateTask *ModelartsPoolCreateTask) WaitStatus(ctx context.Context, ipool cloudprovider.ICloudModelartsPool, pool *models.SModelartsPool) error {
func (modelartsCreateTask *ModelartsPoolCreateTask) WaitStatus(ctx context.Context, opts *cloudprovider.ModelartsPoolCreateOption, pool *models.SModelartsPool) error {
taskman.LocalTaskRun(modelartsCreateTask, func() (jsonutils.JSONObject, error) {
time.Sleep(2 * time.Minute)
err := cloudprovider.WaitMultiStatus(ipool, []string{api.MODELARTS_POOL_STATUS_RUNNING, api.MODELARTS_POOL_STATUS_CREATE_FAILED}, 15*time.Second, 2*time.Hour)
iRegion, err := pool.GetIRegion()
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "pool.GetIRegion")
}
if ipool.GetStatus() == api.MODELARTS_POOL_STATUS_CREATE_FAILED {
return nil, errors.Error("create_failed")
} else {
callback := func(id string) {
db.SetExternalId(pool, modelartsCreateTask.GetUserCred(), id)
}
ipool, err := iRegion.CreateIModelartsPool(opts, callback)
if err != nil {
return nil, errors.Wrapf(err, "iRegion.CreateIModelartsPool")
}
switch ipool.GetStatus() {
case api.MODELARTS_POOL_STATUS_RUNNING:
return nil, nil
case api.MODELARTS_POOL_STATUS_CREATE_FAILED:
return nil, errors.Errorf(ipool.GetStatusMessage())
default:
return nil, errors.Errorf(ipool.GetStatus())
}
})
return nil

View File

@@ -38,8 +38,8 @@ func init() {
taskman.RegisterTask(ModelartsPoolDeleteTask{})
}
func (modelartsDeleteTask *ModelartsPoolDeleteTask) taskFailed(ctx context.Context, mp *models.SModelartsPool, err error) {
mp.SetStatus(modelartsDeleteTask.UserCred, api.MODELARTS_POOL_STATUS_DELETE_FAILED, err.Error())
func (modelartsDeleteTask *ModelartsPoolDeleteTask) taskFailed(ctx context.Context, status string, mp *models.SModelartsPool, err error) {
mp.SetStatus(modelartsDeleteTask.UserCred, status, err.Error())
db.OpsLog.LogEvent(mp, db.ACT_DELETE_FAIL, err, modelartsDeleteTask.UserCred)
logclient.AddActionLogWithStartable(modelartsDeleteTask, mp, logclient.ACT_DELOCATE, err, modelartsDeleteTask.UserCred, false)
modelartsDeleteTask.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
@@ -58,18 +58,26 @@ func (modelartsDeleteTask *ModelartsPoolDeleteTask) OnInit(ctx context.Context,
modelartsDeleteTask.taskComplete(ctx, pool)
return
}
modelartsDeleteTask.taskFailed(ctx, pool, errors.Wrapf(err, "iMp.GetIModelartsPoolById"))
modelartsDeleteTask.taskFailed(ctx, api.MODELARTS_POOL_STATUS_DELETE_FAILED, pool, errors.Wrapf(err, "iMp.GetIModelartsPoolById"))
return
}
err = iMp.Delete()
if err != nil {
modelartsDeleteTask.taskFailed(ctx, pool, errors.Wrapf(err, "iMp.Delete"))
modelartsDeleteTask.taskFailed(ctx, api.MODELARTS_POOL_STATUS_DELETE_FAILED, pool, errors.Wrapf(err, "iMp.Delete"))
return
}
err = cloudprovider.WaitDeleted(iMp, time.Second*10, time.Minute*10)
err = cloudprovider.WaitStatus(iMp, api.MODELARTS_POOL_STATUS_UNKNOWN, time.Second*15, time.Minute*20)
if err != nil {
modelartsDeleteTask.taskFailed(ctx, pool, errors.Wrapf(err, "iMp.WaitDeleted"))
return
if errors.Cause(err) == errors.ErrTimeout {
modelartsDeleteTask.taskFailed(ctx, api.MODELARTS_POOL_STATUS_TIMEOUT, pool, errors.Wrapf(err, "ErrTimeout"))
return
} else if errors.Cause(err) == errors.ErrNotFound {
modelartsDeleteTask.taskComplete(ctx, pool)
return
} else {
modelartsDeleteTask.taskFailed(ctx, api.MODELARTS_POOL_STATUS_DELETE_FAILED, pool, errors.Wrapf(err, "default:"))
return
}
}
modelartsDeleteTask.taskComplete(ctx, pool)
}

4
vendor/modules.txt vendored
View File

@@ -1457,7 +1457,7 @@ sigs.k8s.io/structured-merge-diff/v4/value
# sigs.k8s.io/yaml v1.2.0
## explicit; go 1.12
sigs.k8s.io/yaml
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230407102918-dd668c09f13d
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20230413051450-19d2c693bfa2
## explicit; go 1.18
yunion.io/x/cloudmux/pkg/apis
yunion.io/x/cloudmux/pkg/apis/billing
@@ -1536,7 +1536,7 @@ yunion.io/x/cloudmux/pkg/multicloud/zstack/provider
yunion.io/x/executor/apis
yunion.io/x/executor/client
yunion.io/x/executor/server
# yunion.io/x/jsonutils v1.0.1-0.20220819091305-3bab322ab4fd
# yunion.io/x/jsonutils v1.0.1-0.20230412125709-357258302671
## explicit; go 1.12
yunion.io/x/jsonutils
# yunion.io/x/log v1.0.1-0.20230411060016-feb3f46ab361

View File

@@ -629,7 +629,7 @@ func (self *SBaseProvider) GetIModelartsPoolById(id string) (ICloudModelartsPool
return nil, errors.Wrapf(ErrNotImplemented, "GetIModelartsPoolDetail")
}
func (self *SBaseProvider) CreateIModelartsPool(pool *ModelartsPoolCreateOption) (ICloudModelartsPool, error) {
func (self *SBaseProvider) CreateIModelartsPool(pool *ModelartsPoolCreateOption, callback func(id string)) (ICloudModelartsPool, error) {
return nil, errors.Wrapf(ErrNotImplemented, "CreateIModelartsPool")
}
@@ -938,6 +938,7 @@ type ICloudModelartsPool interface {
GetWorkType() string
GetNodeCount() int
ChangeConfig(opts *ModelartsPoolChangeConfigOptions) error
GetStatusMessage() string
}
type ICloudModelartsPoolSku interface {

View File

@@ -194,7 +194,7 @@ type ICloudRegion interface {
GetIModelartsPools() ([]ICloudModelartsPool, error)
GetIModelartsPoolById(id string) (ICloudModelartsPool, error)
CreateIModelartsPool(pool *ModelartsPoolCreateOption) (ICloudModelartsPool, error)
CreateIModelartsPool(pool *ModelartsPoolCreateOption, callback func(externalId string)) (ICloudModelartsPool, error)
GetIModelartsPoolSku() ([]ICloudModelartsPoolSku, error)
GetIMiscResources() ([]ICloudMiscResource, error)

View File

@@ -1,4 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
// 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 esxi
var ovfTemplate = `<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.dmtf.org/ovf/envelope/1"
xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1"
xmlns:cim="http://schemas.dmtf.org/wbem/wscim/1/common"
@@ -62,4 +78,4 @@
</Item>
</VirtualHardwareSection>
</VirtualSystem>
</Envelope>
</Envelope>`

View File

@@ -1075,14 +1075,14 @@ func stat(name string) (*info, error) {
func (di *info) ovf() (string, error) {
var buf bytes.Buffer
tmpl, err := template.ParseFiles("/opt/yunion/share/vmware/ovf.xml")
tmpl, err := template.New("ovf").Parse(ovfTemplate)
if err != nil {
return "", err
return "", errors.Wrapf(err, "template.New")
}
err = tmpl.Execute(&buf, di)
if err != nil {
return "", err
return "", errors.Wrapf(err, "tmpl.Execute")
}
return buf.String(), nil

View File

@@ -191,7 +191,15 @@ func (self *SHuaweiClient) modelartsPoolNetworkCreate(params map[string]interfac
func (self *SHuaweiClient) modelartsPoolById(poolName string) (jsonutils.JSONObject, error) {
endpoint := self.resetEndpoint(self.endpoints.Modelarts, "modelarts")
uri := fmt.Sprintf("https://%s/v2/%s/pools/%s", endpoint, self.projectId, poolName)
return self.request(httputils.GET, uri, url.Values{}, nil)
res, err := self.request(httputils.GET, uri, url.Values{}, nil)
if err != nil {
if strings.Contains(err.Error(), "not found") {
return nil, errors.ErrNotFound
} else {
return nil, err
}
}
return res, nil
}
func (cli *SHuaweiClient) modelartsPoolListWithStatus(resource, status string, params map[string]interface{}) (jsonutils.JSONObject, error) {

View File

@@ -21,6 +21,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/billing"
"yunion.io/x/pkg/utils"
billing_api "yunion.io/x/cloudmux/pkg/apis/billing"
"yunion.io/x/cloudmux/pkg/apis/compute"
@@ -130,7 +131,7 @@ func (self *SRegion) GetIModelartsPools() ([]cloudprovider.ICloudModelartsPool,
return res, nil
}
func (self *SRegion) CreateIModelartsPool(args *cloudprovider.ModelartsPoolCreateOption) (cloudprovider.ICloudModelartsPool, error) {
func (self *SRegion) CreateIModelartsPool(args *cloudprovider.ModelartsPoolCreateOption, callback func(id string)) (cloudprovider.ICloudModelartsPool, error) {
if len(args.Cidr) == 0 {
args.Cidr = "192.168.128.0/17"
}
@@ -196,15 +197,36 @@ func (self *SRegion) CreateIModelartsPool(args *cloudprovider.ModelartsPoolCreat
if err != nil {
return nil, errors.Wrap(err, "SHuaweiClient.CreatePools")
}
pool := &SModelartsPool{}
obj.Unmarshal(&pool)
res := []cloudprovider.ICloudModelartsPool{}
for i := 0; i < 1; i++ {
pool.region = self
res = append(res, pool)
pool := &SModelartsPool{
region: self,
}
obj.Unmarshal(pool)
if callback != nil {
callback(pool.GetId())
}
// 对于新建后可能会存在一段时间list查不到
time.Sleep(2 * time.Minute)
return self.waitCreate(pool)
}
return res[0], nil
func (region *SRegion) waitCreate(pool *SModelartsPool) (cloudprovider.ICloudModelartsPool, error) {
startTime := time.Now()
for time.Since(startTime) < 2*time.Hour {
pool.RefreshForCreate()
if utils.IsInStringArray(pool.GetStatus(), []string{compute.MODELARTS_POOL_STATUS_RUNNING, compute.MODELARTS_POOL_STATUS_CREATE_FAILED}) {
return pool, nil
}
time.Sleep(15 * time.Second)
}
return nil, errors.ErrTimeout
}
func (self *SRegion) GetIModelartsPoolsWithStatus(status string) ([]jsonutils.JSONObject, error) {
resObj, err := self.client.modelartsPoolListWithStatus("pools", status, nil)
if err != nil {
return nil, err
}
return resObj.GetArray("items")
}
func (self *SRegion) DeletePool(poolName string) (jsonutils.JSONObject, error) {
@@ -219,14 +241,11 @@ func (self *SRegion) GetIModelartsPoolById(poolId string) (cloudprovider.ICloudM
}
return nil, errors.Wrap(err, "region.modelartsPoolByName")
}
pool := &SModelartsPool{}
obj.Unmarshal(&pool)
res := []cloudprovider.ICloudModelartsPool{}
for i := 0; i < 1; i++ {
pool.region = self
res = append(res, pool)
pool := &SModelartsPool{
region: self,
}
return res[0], nil
obj.Unmarshal(pool)
return pool, nil
}
func (self *SRegion) MonitorPool(poolId string) (*SModelartsMetrics, error) {
@@ -385,15 +404,14 @@ func (self *SModelartsPool) SetAutoRenew(bc billing.SBillingCycle) error {
return nil
}
func (self *SModelartsPool) Refresh() error {
func (self *SModelartsPool) RefreshForCreate() error {
self.Status.Resource = SNodeStatus{}
pool, err := self.region.client.modelartsPoolById(self.GetId())
if err == nil {
pool.Unmarshal(self)
return nil
return pool.Unmarshal(self)
}
if !strings.Contains(err.Error(), "not found") {
return errors.Wrap(err, "modelartsPoolById")
if errors.Cause(err) != errors.ErrNotFound {
return err
}
pools := make([]SModelartsPool, 0)
@@ -413,7 +431,16 @@ func (self *SModelartsPool) Refresh() error {
return jsonutils.Update(self, pool)
}
}
return nil
return err
}
func (self *SModelartsPool) Refresh() error {
self.Status.Resource = SNodeStatus{}
pool, err := self.region.client.modelartsPoolById(self.GetId())
if err != nil {
return err
}
return pool.Unmarshal(self)
}
func (self *SModelartsPool) SetTags(tags map[string]string, replace bool) error {
@@ -428,6 +455,10 @@ func (self *SModelartsPool) Delete() error {
return nil
}
func (self *SModelartsPool) GetStatusMessage() string {
return self.Status.Message
}
func (self *SModelartsPool) GetInstanceType() string {
return self.Spec.Resource[0].Flavor

View File

@@ -21,6 +21,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/billing"
"yunion.io/x/pkg/utils"
billing_api "yunion.io/x/cloudmux/pkg/apis/billing"
"yunion.io/x/cloudmux/pkg/apis/compute"
@@ -129,7 +130,7 @@ func (self *SRegion) GetIModelartsPools() ([]cloudprovider.ICloudModelartsPool,
return res, nil
}
func (self *SRegion) CreateIModelartsPool(args *cloudprovider.ModelartsPoolCreateOption) (cloudprovider.ICloudModelartsPool, error) {
func (self *SRegion) CreateIModelartsPool(args *cloudprovider.ModelartsPoolCreateOption, callback func(id string)) (cloudprovider.ICloudModelartsPool, error) {
if len(args.Cidr) == 0 {
args.Cidr = "192.168.20.0/24"
}
@@ -195,15 +196,28 @@ func (self *SRegion) CreateIModelartsPool(args *cloudprovider.ModelartsPoolCreat
if err != nil {
return nil, errors.Wrap(err, "SHuaweiClient.CreatePools")
}
pool := &SModelartsPool{}
obj.Unmarshal(&pool)
res := []cloudprovider.ICloudModelartsPool{}
for i := 0; i < 1; i++ {
pool.region = self
res = append(res, pool)
pool := &SModelartsPool{
region: self,
}
obj.Unmarshal(pool)
if callback != nil {
callback(pool.GetId())
}
// 对于新建后可能会存在一段时间list查不到
time.Sleep(2 * time.Minute)
return self.waitCreate(pool)
}
return res[0], nil
func (region *SRegion) waitCreate(pool *SModelartsPool) (cloudprovider.ICloudModelartsPool, error) {
startTime := time.Now()
for time.Since(startTime) < 2*time.Hour {
pool.RefreshForCreate()
if utils.IsInStringArray(pool.GetStatus(), []string{compute.MODELARTS_POOL_STATUS_RUNNING, compute.MODELARTS_POOL_STATUS_CREATE_FAILED}) {
return pool, nil
}
time.Sleep(15 * time.Second)
}
return nil, errors.ErrTimeout
}
func (self *SRegion) DeletePool(poolName string) (jsonutils.JSONObject, error) {
@@ -339,6 +353,10 @@ func (self *SModelartsPool) GetStatus() string {
return res
}
func (self *SModelartsPool) GetStatusMessage() string {
return self.Status.Message
}
func (self *SModelartsPool) GetSysTags() map[string]string {
return nil
}
@@ -384,15 +402,14 @@ func (self *SModelartsPool) SetAutoRenew(bc billing.SBillingCycle) error {
return nil
}
func (self *SModelartsPool) Refresh() error {
func (self *SModelartsPool) RefreshForCreate() error {
self.Status.Resource = SNodeStatus{}
pool, err := self.region.client.modelartsPoolById(self.GetId())
if err == nil {
pool.Unmarshal(self)
return nil
return pool.Unmarshal(self)
}
if !strings.Contains(err.Error(), "not found") {
return errors.Wrap(err, "modelartsPoolById")
if errors.Cause(err) != errors.ErrNotFound {
return err
}
pools := make([]SModelartsPool, 0)
@@ -412,7 +429,16 @@ func (self *SModelartsPool) Refresh() error {
return jsonutils.Update(self, pool)
}
}
return nil
return err
}
func (self *SModelartsPool) Refresh() error {
self.Status.Resource = SNodeStatus{}
pool, err := self.region.client.modelartsPoolById(self.GetId())
if err != nil {
return err
}
return pool.Unmarshal(self)
}
func (self *SModelartsPool) SetTags(tags map[string]string, replace bool) error {
@@ -429,7 +455,6 @@ func (self *SModelartsPool) Delete() error {
func (self *SModelartsPool) GetInstanceType() string {
return self.Spec.Resource[0].Flavor
}
func (self *SModelartsPool) GetWorkType() string {

View File

@@ -385,10 +385,14 @@ func (self *SRegion) GetIModelartsPoolById(id string) (cloudprovider.ICloudModel
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIModelartsPoolDetail")
}
func (self *SRegion) CreateIModelartsPool(pool *cloudprovider.ModelartsPoolCreateOption) (cloudprovider.ICloudModelartsPool, error) {
func (self *SRegion) CreateIModelartsPool(pool *cloudprovider.ModelartsPoolCreateOption, callback func(id string)) (cloudprovider.ICloudModelartsPool, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "CreateIModelartsPool")
}
func (self *SRegion) GetStatusMessage() string {
return ""
}
func (self *SRegion) GetIModelartsPoolSku() ([]cloudprovider.ICloudModelartsPoolSku, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetIModelartsPoolSku")
}

View File

@@ -251,6 +251,12 @@ func Marshal(obj interface{}) JSONObject {
}
func marshalValue(objValue reflect.Value, info *reflectutils.SStructFieldInfo, omitEmpty bool) JSONObject {
return tryStdMarshal(objValue, func(v reflect.Value) JSONObject {
return _marshalValue(v, info, omitEmpty)
})
}
func _marshalValue(objValue reflect.Value, info *reflectutils.SStructFieldInfo, omitEmpty bool) JSONObject {
switch objValue.Type() {
case JSONDictPtrType, JSONArrayPtrType, JSONBoolPtrType, JSONIntPtrType, JSONFloatPtrType, JSONStringPtrType, JSONObjectType:
if objValue.IsNil() {

119
vendor/yunion.io/x/jsonutils/std_json.go generated vendored Normal file
View File

@@ -0,0 +1,119 @@
// 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 jsonutils
import (
"encoding/json"
"fmt"
"reflect"
)
func tryStdUnmarshal(jo JSONObject, v reflect.Value, unmarshalFunc func(value reflect.Value) error) error {
u := IsImplementStdUnmarshaler(v)
if u != nil {
return u.UnmarshalJSON([]byte(jo.String()))
}
return unmarshalFunc(v)
}
func IsImplementStdUnmarshaler(v reflect.Value) json.Unmarshaler {
return indirectStdUnmarshaler(v)
}
func indirectStdUnmarshaler(v reflect.Value) json.Unmarshaler {
v0 := v
haveAddr := false
// If v is a named type and is addressable,
// start with its address, so that if the type has pointer methods,
// we find them
if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {
haveAddr = true
v = v.Addr()
}
for {
// Load value from interface, but only if the result will be
// usefully addressable.
if v.Kind() == reflect.Interface && !v.IsNil() {
e := v.Elem()
if e.Kind() == reflect.Ptr && !e.IsNil() && e.Elem().Kind() == reflect.Ptr {
haveAddr = false
v = e
continue
}
}
if v.Kind() != reflect.Ptr {
break
}
// Prevent infinite loop if v is an interface pointing to its own address:
// var v interface{}
// v = &v
if v.Elem().Kind() == reflect.Interface && v.Elem().Elem() == v {
v = v.Elem()
break
}
if v.IsNil() {
v.Set(reflect.New(v.Type().Elem()))
}
if v.Type().NumMethod() > 0 && v.CanInterface() {
if u, ok := v.Interface().(json.Unmarshaler); ok {
return u
}
}
if haveAddr {
v = v0 // restore original value after round-trip Value.Addr().Elem()
haveAddr = false
} else {
v = v.Elem()
}
}
return nil
}
func IsImplementStdMarshaler(v reflect.Value) json.Marshaler {
return indirectStdMarshaler(v)
}
func indirectStdMarshaler(v reflect.Value) json.Marshaler {
if v.Kind() == reflect.Ptr && v.IsNil() {
return nil
}
if v.Type().NumMethod() > 0 && v.CanInterface() {
if u, ok := v.Interface().(json.Marshaler); ok {
return u
}
}
return nil
}
func tryStdMarshal(v reflect.Value, marshalFunc func(v reflect.Value) JSONObject) JSONObject {
m := IsImplementStdMarshaler(v)
if m != nil {
data, err := m.MarshalJSON()
if err != nil {
panic(fmt.Sprintf("MarshalJSON of %q error: %v", v.String(), err))
}
jo, err := Parse(data)
if err != nil {
panic(fmt.Sprintf("Parse data %q to json of %q error: %v", data, v.String(), err))
}
return jo
}
return marshalFunc(v)
}

View File

@@ -50,6 +50,10 @@ func (this *JSONDict) Unmarshal(obj interface{}, keys ...string) error {
return jsonUnmarshal(this, obj, keys)
}
func (this *JSONString) Unmarshal(obj interface{}, keys ...string) error {
return jsonUnmarshal(this, obj, keys)
}
func jsonUnmarshal(jo JSONObject, o interface{}, keys []string) error {
if len(keys) > 0 {
var err error = nil
@@ -75,6 +79,10 @@ func (this *JSONValue) unmarshalValue(val reflect.Value) error {
}
func (this *JSONInt) unmarshalValue(val reflect.Value) error {
return tryStdUnmarshal(this, val, this._unmarshalValue)
}
func (this *JSONInt) _unmarshalValue(val reflect.Value) error {
switch val.Type() {
case JSONIntType:
json := val.Interface().(JSONInt)
@@ -137,6 +145,10 @@ func (this *JSONInt) unmarshalValue(val reflect.Value) error {
}
func (this *JSONBool) unmarshalValue(val reflect.Value) error {
return tryStdUnmarshal(this, val, this._unmarshalValue)
}
func (this *JSONBool) _unmarshalValue(val reflect.Value) error {
switch val.Type() {
case JSONBoolType:
json := val.Interface().(JSONBool)
@@ -204,6 +216,10 @@ func (this *JSONBool) unmarshalValue(val reflect.Value) error {
}
func (this *JSONFloat) unmarshalValue(val reflect.Value) error {
return tryStdUnmarshal(this, val, this._unmarshalValue)
}
func (this *JSONFloat) _unmarshalValue(val reflect.Value) error {
switch val.Type() {
case JSONFloatType:
json := val.Interface().(JSONFloat)
@@ -280,6 +296,13 @@ func (this *JSONFloat) unmarshalValue(val reflect.Value) error {
}
func (this *JSONString) unmarshalValue(val reflect.Value) error {
if val.Type() == gotypes.TimeType {
return this._unmarshalValue(val)
}
return tryStdUnmarshal(this, val, this._unmarshalValue)
}
func (this *JSONString) _unmarshalValue(val reflect.Value) error {
switch val.Type() {
case JSONStringType:
json := val.Interface().(JSONString)
@@ -390,6 +413,10 @@ func (this *JSONString) unmarshalValue(val reflect.Value) error {
}
func (this *JSONArray) unmarshalValue(val reflect.Value) error {
return tryStdUnmarshal(this, val, this._unmarshalValue)
}
func (this *JSONArray) _unmarshalValue(val reflect.Value) error {
switch val.Type() {
case JSONArrayType:
array := val.Interface().(JSONArray)
@@ -447,6 +474,10 @@ func (this *JSONArray) unmarshalValue(val reflect.Value) error {
}
func (this *JSONDict) unmarshalValue(val reflect.Value) error {
return tryStdUnmarshal(this, val, this._unmarshalValue)
}
func (this *JSONDict) _unmarshalValue(val reflect.Value) error {
switch val.Type() {
case JSONDictType:
dict := val.Interface().(JSONDict)