Skip to content

Commit b4bf9d6

Browse files
authored
Merge pull request #36 from lixiaojun629/develop
ucloud 0.1.22
2 parents bf15b16 + d70b32f commit b4bf9d6

10 files changed

Lines changed: 275 additions & 101 deletions

File tree

Dockerfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
FROM ubuntu:18.04
22
RUN apt-get update && apt-get install wget -y
3-
RUN wget https://github.com/ucloud/ucloud-cli/releases/download/0.1.20/ucloud-cli-linux-0.1.20-amd64.tgz
4-
RUN tar -zxf ucloud-cli-linux-0.1.20-amd64.tgz -C /usr/local/bin/
5-
RUN echo "complete -C $(which ucloud) ucloud" >> ~/.bashrc
3+
RUN wget https://github.com/ucloud/ucloud-cli/releases/download/0.1.21/ucloud-cli-linux-0.1.21-amd64.tgz
4+
RUN tar -zxf ucloud-cli-linux-0.1.21-amd64.tgz -C /usr/local/bin/
5+
RUN echo "complete -C $(which ucloud) ucloud" >> ~/.bashrc

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export VERSION=0.1.21
1+
export VERSION=0.1.22
22

33
.PHONY : install
44
install:

base/config.go

Lines changed: 67 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,24 @@ const LocalFileMode os.FileMode = 0600
2626
//DefaultTimeoutSec default timeout for requesting api, 15s
2727
const DefaultTimeoutSec = 15
2828

29+
//DefaultMaxRetryTimes default timeout for requesting api, 15s
30+
const DefaultMaxRetryTimes = 3
31+
2932
//DefaultBaseURL location of api server
3033
const DefaultBaseURL = "https://api.ucloud.cn/"
3134

3235
//DefaultProfile name of default profile
3336
const DefaultProfile = "default"
3437

3538
//Version 版本号
36-
const Version = "0.1.21"
39+
const Version = "0.1.22"
3740

3841
//ConfigIns 配置实例, 程序加载时生成
3942
var ConfigIns = &AggConfig{
40-
Profile: DefaultProfile,
41-
BaseURL: DefaultBaseURL,
42-
Timeout: DefaultTimeoutSec,
43+
Profile: DefaultProfile,
44+
BaseURL: DefaultBaseURL,
45+
Timeout: DefaultTimeoutSec,
46+
MaxRetryTimes: sdk.Int(DefaultMaxRetryTimes),
4347
}
4448

4549
//AggConfigListIns 配置列表, 进程启动时从本地文件加载
@@ -66,17 +70,20 @@ type GlobalFlag struct {
6670
Config bool
6771
Signup bool
6872
Profile string
73+
PublicKey string
74+
PrivateKey string
6975
}
7076

7177
//CLIConfig cli_config element
7278
type CLIConfig struct {
73-
ProjectID string `json:"project_id"`
74-
Region string `json:"region"`
75-
Zone string `json:"zone"`
76-
BaseURL string `json:"base_url"`
77-
Timeout int `json:"timeout_sec"`
78-
Profile string `json:"profile"`
79-
Active bool `json:"active"` //是否生效
79+
ProjectID string `json:"project_id"`
80+
Region string `json:"region"`
81+
Zone string `json:"zone"`
82+
BaseURL string `json:"base_url"`
83+
Timeout int `json:"timeout_sec"`
84+
Profile string `json:"profile"`
85+
Active bool `json:"active"` //是否生效
86+
MaxRetryTimes *int `json:"max_retry_times"`
8087
}
8188

8289
//CredentialConfig credential element
@@ -88,15 +95,16 @@ type CredentialConfig struct {
8895

8996
//AggConfig 聚合配置 config+credential
9097
type AggConfig struct {
91-
Profile string `json:"profile"`
92-
Active bool `json:"active"`
93-
ProjectID string `json:"project_id"`
94-
Region string `json:"region"`
95-
Zone string `json:"zone"`
96-
BaseURL string `json:"base_url"`
97-
Timeout int `json:"timeout_sec"`
98-
PublicKey string `json:"public_key"`
99-
PrivateKey string `json:"private_key"`
98+
Profile string `json:"profile"`
99+
Active bool `json:"active"`
100+
ProjectID string `json:"project_id"`
101+
Region string `json:"region"`
102+
Zone string `json:"zone"`
103+
BaseURL string `json:"base_url"`
104+
Timeout int `json:"timeout_sec"`
105+
PublicKey string `json:"public_key"`
106+
PrivateKey string `json:"private_key"`
107+
MaxRetryTimes *int `json:"max_retry_times"`
100108
}
101109

102110
//ConfigPublicKey 输入公钥
@@ -157,6 +165,7 @@ func (p *AggConfig) copyToCLIConfig(target *CLIConfig) {
157165
target.Region = p.Region
158166
target.Zone = p.Zone
159167
target.Active = p.Active
168+
target.MaxRetryTimes = p.MaxRetryTimes
160169
}
161170

162171
func (p *AggConfig) copyToCredentialConfig(target *CredentialConfig) {
@@ -267,15 +276,16 @@ func (p *AggConfigManager) Load() error {
267276
}
268277

269278
p.configs[profile] = &AggConfig{
270-
PrivateKey: cred.PrivateKey,
271-
PublicKey: cred.PublicKey,
272-
Profile: config.Profile,
273-
ProjectID: config.ProjectID,
274-
Region: config.Region,
275-
Zone: config.Zone,
276-
BaseURL: config.BaseURL,
277-
Timeout: config.Timeout,
278-
Active: config.Active,
279+
PrivateKey: cred.PrivateKey,
280+
PublicKey: cred.PublicKey,
281+
Profile: config.Profile,
282+
ProjectID: config.ProjectID,
283+
Region: config.Region,
284+
Zone: config.Zone,
285+
BaseURL: config.BaseURL,
286+
Timeout: config.Timeout,
287+
Active: config.Active,
288+
MaxRetryTimes: config.MaxRetryTimes,
279289
}
280290
}
281291

@@ -393,6 +403,12 @@ func (p *AggConfigManager) parseCLIConfigs() ([]CLIConfig, error) {
393403
if err != nil {
394404
return nil, fmt.Errorf("parse cli config faild: %v", err)
395405
}
406+
//特殊处理未配置max_retry_times的情况,v0.1.21之前硬编码重试次数为3
407+
for idx := range configs {
408+
if configs[idx].MaxRetryTimes == nil {
409+
configs[idx].MaxRetryTimes = sdk.Int(DefaultMaxRetryTimes)
410+
}
411+
}
396412
return configs, nil
397413
}
398414

@@ -476,15 +492,16 @@ func adaptOldConfig() error {
476492
return err
477493
}
478494
ac := &AggConfig{
479-
Profile: DefaultProfile,
480-
ProjectID: oc.ProjectID,
481-
Region: oc.Region,
482-
Zone: oc.Zone,
483-
BaseURL: DefaultBaseURL,
484-
Timeout: DefaultTimeoutSec,
485-
Active: true,
486-
PrivateKey: oc.PrivateKey,
487-
PublicKey: oc.PublicKey,
495+
Profile: DefaultProfile,
496+
ProjectID: oc.ProjectID,
497+
Region: oc.Region,
498+
Zone: oc.Zone,
499+
BaseURL: DefaultBaseURL,
500+
Timeout: DefaultTimeoutSec,
501+
Active: true,
502+
PrivateKey: oc.PrivateKey,
503+
PublicKey: oc.PublicKey,
504+
MaxRetryTimes: sdk.Int(DefaultMaxRetryTimes),
488505
}
489506
err = os.Rename(ConfigFilePath, ConfigFilePath+".old")
490507
if err != nil {
@@ -515,12 +532,19 @@ func GetBizClient(ac *AggConfig) (*Client, error) {
515532
Region: ac.Region,
516533
Zone: ac.Zone,
517534
ProjectId: ac.ProjectID,
518-
MaxRetries: 3,
535+
MaxRetries: *ac.MaxRetryTimes,
519536
}
520537

521-
AuthCredential = &auth.Credential{
522-
PublicKey: ac.PublicKey,
523-
PrivateKey: ac.PrivateKey,
538+
if Global.PublicKey != "" && Global.PrivateKey != "" {
539+
AuthCredential = &auth.Credential{
540+
PublicKey: Global.PublicKey,
541+
PrivateKey: Global.PrivateKey,
542+
}
543+
} else {
544+
AuthCredential = &auth.Credential{
545+
PublicKey: ac.PublicKey,
546+
PrivateKey: ac.PrivateKey,
547+
}
524548
}
525549

526550
return NewClient(ClientConfig, AuthCredential), err
@@ -551,7 +575,7 @@ func InitConfig() {
551575
var ok bool
552576
ins, ok = AggConfigListIns.GetAggConfigByProfile(Global.Profile)
553577
if !ok {
554-
HandleError(fmt.Errorf("Profile %s does not exist", Global.Profile))
578+
LogError("Profile %s does not exist", Global.Profile)
555579
}
556580
}
557581

base/log.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,17 @@ func GetLogFilePath() string {
5656
func LogInfo(logs ...string) {
5757
mu.Lock()
5858
defer mu.Unlock()
59+
goID := curGoroutineID()
5960
for _, line := range logs {
60-
logger.Info(line)
61+
logger.WithField("GoroutineID", goID).Info(line)
6162
}
6263
}
6364

6465
//LogError 记录日志
6566
func LogError(logs ...string) {
67+
goID := curGoroutineID()
6668
for _, line := range logs {
67-
logger.Error(line)
69+
logger.WithField("GoroutineID", goID).Error(line)
6870
fmt.Fprintln(out, line)
6971
}
7072
}

base/util.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,9 @@ func displaySlice(listVal reflect.Value, fieldList []string) {
213213
field := elemVal.Field(j)
214214
fieldName := elemType.Field(j).Name
215215
if _, ok := showFieldMap[fieldName]; ok {
216+
if field.Kind() == reflect.Ptr {
217+
field = field.Elem()
218+
}
216219
text := fmt.Sprintf("%v", field.Interface())
217220
cells := strings.Split(text, "\n")
218221
for i, cell := range cells {
@@ -627,3 +630,19 @@ func Confirm(yes bool, text string) bool {
627630
}
628631
return sure
629632
}
633+
634+
func curGoroutineID() int64 {
635+
var (
636+
buf [64]byte
637+
n = runtime.Stack(buf[:], false)
638+
stk = strings.TrimPrefix(string(buf[:n]), "goroutine ")
639+
)
640+
641+
idField := strings.Fields(stk)[0]
642+
id, err := strconv.Atoi(idField)
643+
if err != nil {
644+
panic(fmt.Errorf("can not get goroutine id: %v", err))
645+
}
646+
647+
return int64(id)
648+
}

cmd/configure.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"strconv"
2020

2121
"github.com/spf13/cobra"
22+
sdk "github.com/ucloud/ucloud-sdk-go/ucloud"
2223
uerr "github.com/ucloud/ucloud-sdk-go/ucloud/error"
2324

2425
"github.com/ucloud/ucloud-cli/base"
@@ -204,6 +205,14 @@ func NewCmdConfig() *cobra.Command {
204205
cacheConfig.Timeout = cfg.Timeout
205206
}
206207

208+
if *cfg.MaxRetryTimes == 0 {
209+
if *cacheConfig.MaxRetryTimes == 0 {
210+
cacheConfig.MaxRetryTimes = sdk.Int(base.DefaultMaxRetryTimes)
211+
}
212+
} else {
213+
cacheConfig.MaxRetryTimes = cfg.MaxRetryTimes
214+
}
215+
207216
if cfg.Region != "" {
208217
cacheConfig.Region = cfg.Region
209218
}
@@ -274,6 +283,7 @@ func NewCmdConfig() *cobra.Command {
274283
flags.StringVar(&cfg.ProjectID, "project-id", "", "Optional. Set default project. For instance 'org-xxxxxx'. See 'ucloud project list")
275284
flags.StringVar(&cfg.BaseURL, "base-url", "", "Optional. Set default base url. For instance 'https://api.ucloud.cn/'")
276285
flags.IntVar(&cfg.Timeout, "timeout-sec", 0, "Optional. Set default timeout for requesting API. Unit: seconds")
286+
cfg.MaxRetryTimes = flags.Int("max-retry-times", 0, "Optional. Set default max-retry-times for idempotent APIs which can be called many times without side effect, for example 'ReleaseEIP'")
277287
flags.StringVar(&active, "active", "", "Optional. Mark the profile to be effective or not. Accept valeus: true or false")
278288

279289
flags.SetFlagValues("active", "true", "false")
@@ -344,6 +354,7 @@ func NewCmdConfigAdd() *cobra.Command {
344354
flags.StringVar(&cfg.ProjectID, "project-id", "", "Optional. Set default project. For instance 'org-xxxxxx'. See 'ucloud project list")
345355
flags.StringVar(&cfg.BaseURL, "base-url", base.DefaultBaseURL, "Optional. Set default base url. For instance 'https://api.ucloud.cn/'")
346356
flags.IntVar(&cfg.Timeout, "timeout-sec", base.DefaultTimeoutSec, "Optional. Set default timeout for requesting API. Unit: seconds")
357+
cfg.MaxRetryTimes = flags.Int("max-retry-times", base.DefaultMaxRetryTimes, "Optional. Set default max-retry-times for idempotent APIs which can be called many times without side effect, for example 'ReleaseEIP'")
347358
flags.StringVar(&active, "active", "false", "Optional. Mark the profile to be effective or not. Accept valeus: true or false")
348359

349360
flags.SetFlagValues("active", "true", "false")
@@ -363,7 +374,7 @@ func NewCmdConfigAdd() *cobra.Command {
363374

364375
//NewCmdConfigUpdate ucloud config update
365376
func NewCmdConfigUpdate() *cobra.Command {
366-
var timeout, active string
377+
var timeout, active, maxRetries string
367378
cfg := &base.AggConfig{}
368379
cmd := &cobra.Command{
369380
Use: "update",
@@ -426,7 +437,21 @@ func NewCmdConfigUpdate() *cobra.Command {
426437
}
427438

428439
if cacheConfig.Timeout <= 0 {
429-
base.HandleError(fmt.Errorf("timeout-sec must be larger than 0, accept %d", cfg.Timeout))
440+
base.HandleError(fmt.Errorf("timeout-sec must be greater than 0, accept %d", cfg.Timeout))
441+
return
442+
}
443+
444+
if maxRetries != "" {
445+
times, err := strconv.Atoi(maxRetries)
446+
if err != nil {
447+
base.HandleError(fmt.Errorf("parse max-retry-times failed: %v", err))
448+
return
449+
}
450+
cacheConfig.MaxRetryTimes = &times
451+
}
452+
453+
if *cacheConfig.MaxRetryTimes < 0 {
454+
base.HandleError(fmt.Errorf("max-retry-timesc must be greater than or equal to 0, accept %d", cfg.MaxRetryTimes))
430455
return
431456
}
432457

@@ -457,6 +482,7 @@ func NewCmdConfigUpdate() *cobra.Command {
457482
flags.StringVar(&cfg.ProjectID, "project-id", "", "Optional. Set default project. For instance 'org-xxxxxx'. See 'ucloud project list")
458483
flags.StringVar(&cfg.BaseURL, "base-url", "", "Optional. Set default base url. For instance 'https://api.ucloud.cn/'")
459484
flags.StringVar(&timeout, "timeout-sec", "", "Optional. Set default timeout for requesting API. Unit: seconds")
485+
flags.StringVar(&maxRetries, "max-retry-times", "", "Optional. Set default max retry times for idempotent APIs which can be called many times without side effect, for example 'ReleaseEIP'")
460486
flags.StringVar(&active, "active", "", "Optional. Mark the profile to be effective")
461487

462488
flags.SetFlagValuesFunc("profile", func() []string { return base.AggConfigListIns.GetProfileNameList() })

0 commit comments

Comments
 (0)