Skip to content

Commit

Permalink
Merge pull request #11 from lixiaojun629/develop
Browse files Browse the repository at this point in the history
uhost & image & disk-snapshot
  • Loading branch information
lixiaojun629 authored Dec 12, 2018
2 parents d862e75 + 7c43df8 commit 02bb05d
Show file tree
Hide file tree
Showing 136 changed files with 2,527 additions and 1,819 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
## Change Log
v0.1.5
* support batch operation.

v0.1.4
* add udisk.
* polling udisk and uhost long time operation
* async complete resource-id

v0.1.3
* integrate auto completion.
Expand Down
13 changes: 10 additions & 3 deletions base/client.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
package base

import (
pudisk "github.com/ucloud/ucloud-sdk-go/private/services/udisk"
puhost "github.com/ucloud/ucloud-sdk-go/private/services/uhost"
"github.com/ucloud/ucloud-sdk-go/services/pathx"
"github.com/ucloud/ucloud-sdk-go/services/uaccount"
"github.com/ucloud/ucloud-sdk-go/services/udisk"
"github.com/ucloud/ucloud-sdk-go/services/uhost"
"github.com/ucloud/ucloud-sdk-go/services/ulb"
"github.com/ucloud/ucloud-sdk-go/services/unet"
"github.com/ucloud/ucloud-sdk-go/services/vpc"
"github.com/ucloud/ucloud-sdk-go/ucloud"
"github.com/ucloud/ucloud-sdk-go/ucloud/auth"
)

//PrivateUDiskClient 私有模块的udisk client 即未在官网开放的接口
type PrivateUDiskClient = pudisk.UDiskClient

//PrivateUHostClient 私有模块的udisk client 即未在官网开放的接口
type PrivateUHostClient = puhost.UHostClient

//Client aggregate client for business
type Client struct {
uaccount.UAccountClient
uhost.UHostClient
unet.UNetClient
ulb.ULBClient
vpc.VPCClient
pathx.PathXClient
udisk.UDiskClient
PrivateUHostClient
}

// NewClient will return a aggregate client
Expand All @@ -29,9 +36,9 @@ func NewClient(config *ucloud.Config, credential *auth.Credential) *Client {
*uaccount.NewClient(config, credential),
*uhost.NewClient(config, credential),
*unet.NewClient(config, credential),
*ulb.NewClient(config, credential),
*vpc.NewClient(config, credential),
*pathx.NewClient(config, credential),
*udisk.NewClient(config, credential),
*puhost.NewClient(config, credential),
}
}
1 change: 0 additions & 1 deletion base/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ func init() {
ConfigInstance.LoadConfig()
timeout, _ := time.ParseDuration("15s")
ClientConfig = &sdk.Config{
ProjectId: ConfigInstance.ProjectID,
BaseUrl: "https://api.ucloud.cn/",
Timeout: timeout,
UserAgent: fmt.Sprintf("UCloud CLI v%s", Version),
Expand Down
190 changes: 147 additions & 43 deletions base/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/ucloud/ucloud-sdk-go/ucloud/response"

"github.com/ucloud/ucloud-cli/model"
"github.com/ucloud/ucloud-cli/ux"
)

//ConfigPath 配置文件路径
Expand Down Expand Up @@ -263,59 +264,162 @@ var RegionLabel = map[string]string{
"afr-nigeria": "Lagos",
}

//Poll 轮询
func Poll(describeFunc func(string, string, string, string) (interface{}, error)) func(string, string, string, string, []string) chan bool {
stateFields := []string{"State", "Status"}
return func(resourceID, projectID, region, zone string, targetState []string) chan bool {
w := waiter.StateWaiter{
Pending: []string{"pending"},
Target: []string{"avaliable"},
Refresh: func() (interface{}, string, error) {
inst, err := describeFunc(resourceID, projectID, region, zone)
if err != nil {
return nil, "", err
}
//Poller 轮询器
type Poller struct {
stateFields []string
DescribeFunc func(string, string, string, string) (interface{}, error)
Out io.Writer
Timeout time.Duration
SdescribeFunc func(string) (interface{}, error)
}

//Spoll 简化版
func (p *Poller) Spoll(resourceID, pollText string, targetStates []string) {
w := waiter.StateWaiter{
Pending: []string{"pending"},
Target: []string{"avaliable"},
Refresh: func() (interface{}, string, error) {
inst, err := p.SdescribeFunc(resourceID)
if err != nil {
return nil, "", err
}

if inst == nil {
return nil, "pending", nil
if inst == nil {
return nil, "pending", nil
}
instValue := reflect.ValueOf(inst)
instValue = reflect.Indirect(instValue)
instType := instValue.Type()
if instValue.Kind() != reflect.Struct {
return nil, "", fmt.Errorf("Instance is not struct")
}
state := ""
for i := 0; i < instValue.NumField(); i++ {
for _, sf := range p.stateFields {
if instType.Field(i).Name == sf {
state = instValue.Field(i).String()
}
}
instValue := reflect.ValueOf(inst)
instValue = reflect.Indirect(instValue)
instType := instValue.Type()
if instValue.Kind() != reflect.Struct {
return nil, "", fmt.Errorf("Instance is not struct")
}
if state != "" {
for _, t := range targetStates {
if t == state {
return inst, "avaliable", nil
}
}
state := ""
for i := 0; i < instValue.NumField(); i++ {
for _, sf := range stateFields {
if instType.Field(i).Name == sf {
state = instValue.Field(i).String()
}
}
return nil, "pending", nil

},
Timeout: p.Timeout,
}

done := make(chan bool)
go func() {
if resp, err := w.Wait(); err != nil {
log.Error(err)
if _, ok := err.(*waiter.TimeoutError); ok {
done <- false
return
}
} else {
log.Infof("%#v", resp)
}
done <- true
}()

spinner := ux.NewDotSpinner(p.Out)
spinner.Start(pollText)
ret := <-done
if ret {
spinner.Stop()
} else {
spinner.Timeout()
}
}

//Poll function
func (p *Poller) Poll(resourceID, projectID, region, zone, pollText string, targetState []string) {
w := waiter.StateWaiter{
Pending: []string{"pending"},
Target: []string{"avaliable"},
Refresh: func() (interface{}, string, error) {
inst, err := p.DescribeFunc(resourceID, projectID, region, zone)
if err != nil {
return nil, "", err
}

if inst == nil {
return nil, "pending", nil
}
instValue := reflect.ValueOf(inst)
instValue = reflect.Indirect(instValue)
instType := instValue.Type()
if instValue.Kind() != reflect.Struct {
return nil, "", fmt.Errorf("Instance is not struct")
}
state := ""
for i := 0; i < instValue.NumField(); i++ {
for _, sf := range p.stateFields {
if instType.Field(i).Name == sf {
state = instValue.Field(i).String()
}
}
if state != "" {
for _, t := range targetState {
if t == state {
return inst, "avaliable", nil
}
}
if state != "" {
for _, t := range targetState {
if t == state {
return inst, "avaliable", nil
}
}
return nil, "pending", nil
}
return nil, "pending", nil

},
Timeout: 5 * time.Minute,
}
},
Timeout: p.Timeout,
}

done := make(chan bool)
go func() {
if resp, err := w.Wait(); err != nil {
log.Error(err)
} else {
log.Infof("%#v", resp)
done := make(chan bool)
go func() {
if resp, err := w.Wait(); err != nil {
log.Error(err)
if _, ok := err.(*waiter.TimeoutError); ok {
done <- false
return
}
done <- true
}()
return done
} else {
log.Infof("%#v", resp)
}
done <- true
}()

spinner := ux.NewDotSpinner(p.Out)
spinner.Start(pollText)
ret := <-done
if ret {
spinner.Stop()
} else {
spinner.Timeout()
}
}

//NewSpoller simple
func NewSpoller(describeFunc func(string) (interface{}, error), out io.Writer) *Poller {
return &Poller{
SdescribeFunc: describeFunc,
Out: out,
stateFields: []string{"State", "Status"},
Timeout: 10 * time.Minute,
}
}

//NewPoller 轮询
func NewPoller(describeFunc func(string, string, string, string) (interface{}, error), out io.Writer) *Poller {
return &Poller{
DescribeFunc: describeFunc,
Out: out,
stateFields: []string{"State", "Status"},
Timeout: 10 * time.Minute,
}
}

Expand Down
Loading

0 comments on commit 02bb05d

Please sign in to comment.