Skip to content

Commit 82051a9

Browse files
authored
Merge pull request #47 from lixiaojun629/develop
resize attached disk without stop uhost
2 parents 8d86a50 + 1d7888d commit 82051a9

138 files changed

Lines changed: 13519 additions & 2158 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Makefile

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

33
.PHONY : install
44
install:

base/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const DefaultBaseURL = "https://api.ucloud.cn/"
3636
const DefaultProfile = "default"
3737

3838
//Version 版本号
39-
const Version = "0.1.28"
39+
const Version = "0.1.29"
4040

4141
//ConfigIns 配置实例, 程序加载时生成
4242
var ConfigIns = &AggConfig{

base/util.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ func (p *Poller) Spoll(resourceID, pollText string, targetStates []string) {
477477
}
478478

479479
//Poll function
480-
func (p *Poller) Poll(resourceID, projectID, region, zone, pollText string, targetState []string) {
480+
func (p *Poller) Poll(resourceID, projectID, region, zone, pollText string, targetState []string) bool {
481481
w := waiter.StateWaiter{
482482
Pending: []string{"pending"},
483483
Target: []string{"avaliable"},
@@ -517,26 +517,25 @@ func (p *Poller) Poll(resourceID, projectID, region, zone, pollText string, targ
517517
Timeout: p.Timeout,
518518
}
519519

520+
var err error
520521
done := make(chan bool)
521522
go func() {
522-
if _, err := w.Wait(); err != nil {
523-
log.Error(err)
524-
if _, ok := err.(*waiter.TimeoutError); ok {
525-
done <- false
526-
return
527-
}
523+
if _, err = w.Wait(); err != nil {
524+
done <- false
525+
return
528526
}
529527
done <- true
530528
}()
531529

532530
spinner := ux.NewDotSpinner(p.Out)
533531
spinner.Start(pollText)
534532
ret := <-done
535-
if ret {
536-
spinner.Stop()
533+
if err != nil {
534+
spinner.Fail(err)
537535
} else {
538-
spinner.Timeout()
536+
spinner.Stop()
539537
}
538+
return ret
540539
}
541540

542541
//NewSpoller simple

cmd/uhost.go

Lines changed: 84 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ func NewCmdUHostCreate() *cobra.Command {
326326
}
327327

328328
wg := &sync.WaitGroup{}
329-
tokens := make(chan struct{}, 10)
329+
tokens := make(chan struct{}, 20)
330330
wg.Add(count)
331331
if count <= 5 {
332332
for i := 0; i < count; i++ {
@@ -582,7 +582,7 @@ func NewCmdUHostDelete(out io.Writer) *cobra.Command {
582582
_req.UHostId = sdk.String(id)
583583
reqs[idx] = &_req
584584
}
585-
coAction := newConcurrentAction(reqs, deleteUHost)
585+
coAction := newConcurrentAction(reqs, 50, deleteUHost)
586586
coAction.Do()
587587
},
588588
}
@@ -595,7 +595,7 @@ func NewCmdUHostDelete(out io.Writer) *cobra.Command {
595595
req.Zone = cmd.Flags().String("zone", "", "Optional. availability zone")
596596
isDestroy = cmd.Flags().Bool("destroy", false, "Optional. false,the uhost instance will be thrown to UHost recycle if you have permission; true,the uhost instance will be deleted directly")
597597
req.ReleaseEIP = cmd.Flags().Bool("release-eip", true, "Optional. false,Unbind EIP only; true, Unbind EIP and release it")
598-
req.ReleaseUDisk = cmd.Flags().Bool("delete-cloud-disk", false, "Optional. false, detach cloud disk only; true, detach cloud disk and delete it")
598+
req.ReleaseUDisk = cmd.Flags().Bool("delete-cloud-disk", true, "Optional. false, detach cloud disk only; true, detach cloud disk and delete it")
599599
yes = cmd.Flags().BoolP("yes", "y", false, "Optional. Do not prompt for confirmation.")
600600
cmd.Flags().SetFlagValues("destroy", "true", "false")
601601
cmd.Flags().SetFlagValues("release-eip", "true", "false")
@@ -679,19 +679,34 @@ func NewCmdUHostStop(out io.Writer) *cobra.Command {
679679
return cmd
680680
}
681681

682-
func stopUhostIns(req *uhost.StopUHostInstanceRequest, async bool, out io.Writer) {
682+
func promptStopUhostIns(req *uhost.StopUHostInstanceRequest, yes, async bool, promptText string, out io.Writer) bool {
683+
if !yes {
684+
agreeClose, err := ux.Prompt(promptText)
685+
if err != nil {
686+
base.LogError(err.Error())
687+
return false
688+
}
689+
if !agreeClose {
690+
return false
691+
}
692+
}
693+
return stopUhostIns(req, false, out)
694+
}
695+
696+
func stopUhostIns(req *uhost.StopUHostInstanceRequest, async bool, out io.Writer) bool {
683697
resp, err := base.BizClient.StopUHostInstance(req)
684698
if err != nil {
685699
base.HandleError(err)
686-
} else {
687-
text := fmt.Sprintf("uhost[%v] is shutting down", resp.UhostId)
688-
if async {
689-
fmt.Fprintln(out, text)
690-
} else {
691-
poller := base.NewPoller(describeUHostByID, out)
692-
poller.Poll(resp.UhostId, *req.ProjectId, *req.Region, *req.Zone, text, []string{status.HOST_STOPPED, status.HOST_FAIL})
693-
}
700+
return false
701+
}
702+
703+
text := fmt.Sprintf("uhost [%v] is shutting down", resp.UhostId)
704+
if async {
705+
fmt.Fprintln(out, text)
706+
return false
694707
}
708+
poller := base.NewPoller(describeUHostByID, out)
709+
return poller.Poll(resp.UhostId, *req.ProjectId, *req.Region, *req.Zone, text, []string{status.HOST_STOPPED, status.HOST_FAIL})
695710
}
696711

697712
//可并发调用版本
@@ -847,8 +862,41 @@ func NewCmdUHostPoweroff(out io.Writer) *cobra.Command {
847862
return cmd
848863
}
849864

850-
func resizeUhost(req *uhost.ResizeUHostInstanceRequest) {
865+
func resizeAttachedDisk(out io.Writer, req *uhost.ResizeAttachedDiskRequest, host *uhost.UHostInstanceSet, yes, async bool, promptText string) error {
866+
req.UHostId = &host.UHostId
867+
if host.State == status.HOST_RUNNING {
868+
err := tryStopUhost(req, host.UHostId, promptText, yes, async, out)
869+
if err != nil {
870+
return fmt.Errorf("try to stop uhost error :%w", err)
871+
}
872+
}
873+
req.DryRun = sdk.Bool(false)
874+
_, err := base.BizClient.ResizeAttachedDisk(req)
875+
if err != nil {
876+
return err
877+
}
878+
text := fmt.Sprintf("uhost [%s] disk [%s] resize", host.UHostId, *req.DiskId)
879+
if async {
880+
fmt.Fprintln(out, text)
881+
} else {
882+
poller := base.NewPoller(describeUHostByID, out)
883+
poller.Poll(host.UHostId, *req.ProjectId, *req.Region, *req.Zone, text, []string{status.HOST_RUNNING, status.HOST_STOPPED, status.HOST_FAIL})
884+
}
885+
return nil
886+
}
851887

888+
func tryStopUhost(req *uhost.ResizeAttachedDiskRequest, uhostID, promptText string, yes, async bool, out io.Writer) error {
889+
req.DryRun = sdk.Bool(true)
890+
resp, err := base.BizClient.ResizeAttachedDisk(req)
891+
if err != nil {
892+
return err
893+
}
894+
if resp.NeedRestart {
895+
stopReq := base.BizClient.NewStopUHostInstanceRequest()
896+
stopReq.UHostId = &uhostID
897+
promptStopUhostIns(stopReq, yes, async, promptText, out)
898+
}
899+
return nil
852900
}
853901

854902
//NewCmdUHostResize ucloud uhost resize
@@ -881,34 +929,24 @@ func NewCmdUHostResize(out io.Writer) *cobra.Command {
881929
return
882930
}
883931
inst := host.(*uhost.UHostInstanceSet)
884-
if inst.State == "Running" {
885-
if !*yes {
886-
confirmText := "Resize uhost must be done after the uhost is stopped. Do you want to stop this uhost?"
887-
if len(*uhostIDs) > 1 {
888-
confirmText = "Resize uhost must be done after the uhost is stopped. Do you want to stop those uhosts?"
889-
}
890-
agreeClose, err := ux.Prompt(confirmText)
891-
if err != nil {
892-
base.Cxt.Println(err)
893-
return
894-
}
895-
if !agreeClose {
896-
return
932+
stopReq := base.BizClient.NewStopUHostInstanceRequest()
933+
stopReq.ProjectId = req.ProjectId
934+
stopReq.Region = req.Region
935+
stopReq.Zone = req.Zone
936+
stopReq.UHostId = &id
937+
confirmText := "Resize uhost must be done after the uhost is stopped. Do you want to stop this uhost?"
938+
if req.CPU != nil || req.Memory != nil || *req.NetCapValue != 0 {
939+
if inst.State == status.HOST_RUNNING {
940+
ret := promptStopUhostIns(stopReq, *yes, *async, confirmText, out)
941+
if ret {
942+
inst.State = status.HOST_STOPPED
897943
}
898944
}
899-
_req := base.BizClient.NewStopUHostInstanceRequest()
900-
_req.ProjectId = req.ProjectId
901-
_req.Region = req.Region
902-
_req.Zone = req.Zone
903-
_req.UHostId = &id
904-
stopUhostIns(_req, false, out)
905-
}
906-
if req.CPU != nil || req.Memory != nil || *req.NetCapValue != 0 {
907945
resp, err := base.BizClient.ResizeUHostInstance(req)
908946
if err != nil {
909947
base.HandleError(err)
910948
} else {
911-
text := fmt.Sprintf("uhost [%v] cpu, memory resized", resp.UhostId)
949+
text := fmt.Sprintf("uhost [%v] cpu, memory resize", resp.UhostId)
912950
if *async {
913951
fmt.Fprintln(out, text)
914952
} else {
@@ -937,7 +975,13 @@ func NewCmdUHostResize(out io.Writer) *cobra.Command {
937975
_req.DiskSpace = &bootDiskSize
938976
_req.DiskId = &bootDisk.DiskId
939977
}
940-
} else if dataDiskSize != 0 {
978+
err := resizeAttachedDisk(out, _req, inst, *yes, *async, confirmText)
979+
if err != nil {
980+
base.HandleError(err)
981+
}
982+
}
983+
984+
if dataDiskSize != 0 {
941985
var dataDisk uhost.UHostDiskSet
942986
if len(dataDisks) > 1 {
943987
if dataDiskID == "" {
@@ -964,21 +1008,9 @@ func NewCmdUHostResize(out io.Writer) *cobra.Command {
9641008
}
9651009
_req.DiskSpace = &dataDiskSize
9661010
_req.DiskId = &dataDisk.DiskId
967-
}
968-
_req.ProjectId = req.ProjectId
969-
_req.Region = req.Region
970-
_req.Zone = req.Zone
971-
_req.UHostId = &id
972-
_, err := base.BizClient.ResizeAttachedDisk(_req)
973-
if err != nil {
974-
base.HandleError(err)
975-
} else {
976-
text := fmt.Sprintf("uhost [%v] disk resized", id)
977-
if *async {
978-
fmt.Fprintln(out, text)
979-
} else {
980-
poller := base.NewPoller(describeUHostByID, out)
981-
poller.Poll(id, *req.ProjectId, *req.Region, *req.Zone, text, []string{status.HOST_RUNNING, status.HOST_STOPPED, status.HOST_FAIL})
1011+
err := resizeAttachedDisk(out, _req, inst, *yes, *async, confirmText)
1012+
if err != nil {
1013+
base.HandleError(err)
9821014
}
9831015
}
9841016
}
@@ -1018,7 +1050,7 @@ func describeUHostByID(uhostID, projectID, region, zone string) (interface{}, er
10181050
return nil, err
10191051
}
10201052
if len(resp.UHostSet) < 1 {
1021-
return nil, nil
1053+
return nil, fmt.Errorf("uhost [%s] does not exist", uhostID)
10221054
}
10231055

10241056
return &resp.UHostSet[0], nil

cmd/umem.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ func NewCmdRedisRestart(out io.Writer) *cobra.Command {
302302
_req.GroupId = &id
303303
reqs[idx] = &_req
304304
}
305-
coAction := newConcurrentAction(reqs, restartRedis)
305+
coAction := newConcurrentAction(reqs, 10, restartRedis)
306306
coAction.Do()
307307
},
308308
}
@@ -531,7 +531,7 @@ func NewCmdMemcacheRestart(out io.Writer) *cobra.Command {
531531
_req.GroupId = &id
532532
reqs[idx] = &_req
533533
}
534-
coAction := newConcurrentAction(reqs, restartMemcache)
534+
coAction := newConcurrentAction(reqs, 10, restartMemcache)
535535
coAction.Do()
536536
},
537537
}

cmd/util.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,16 @@ type concurrentAction struct {
127127
tokens chan bool
128128
}
129129

130-
func newConcurrentAction(reqs []request.Common, actionFunc func(request.Common) (bool, []string)) *concurrentAction {
130+
func newConcurrentAction(reqs []request.Common, limit int, actionFunc func(request.Common) (bool, []string)) *concurrentAction {
131+
if limit <= 0 {
132+
limit = 10
133+
}
131134
return &concurrentAction{
132135
reqs: reqs,
133136
actionFunc: actionFunc,
134137
wg: &sync.WaitGroup{},
135138
result: make(chan bool),
136-
tokens: make(chan bool, 10), //控制并发量,最多是个并发
139+
tokens: make(chan bool, limit), //控制并发量,最多是个并发
137140
}
138141
}
139142

@@ -168,11 +171,12 @@ func (c *concurrentAction) Do() {
168171
}
169172

170173
case <-time.Tick(time.Second / 30):
171-
if count > 5 {
172-
refresh.Do(fmt.Sprintf("total:%d, doing:%d, success:%d, fail:%d", count, len(c.tokens), success, fail))
173-
}
174174
if count == (success+fail) && fail > 0 {
175175
fmt.Printf("Check logs in %s\n", base.GetLogFilePath())
176+
return
177+
}
178+
if count > 5 {
179+
refresh.Do(fmt.Sprintf("total:%d, doing:%d, success:%d, fail:%d", count, len(c.tokens), success, fail))
176180
}
177181
}
178182
}

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ require (
88
github.com/sirupsen/logrus v1.3.0
99
github.com/spf13/cobra v0.0.3
1010
github.com/spf13/pflag v1.0.3
11-
github.com/ucloud/ucloud-sdk-go v0.8.10
12-
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a
11+
github.com/ucloud/ucloud-sdk-go v0.13.2
12+
golang.org/x/sys v0.0.0-20190412213103-97732733099d
1313
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
1414
)
1515

go.sum

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,27 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM
5353
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
5454
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
5555
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
56-
github.com/ucloud/ucloud-sdk-go v0.8.10 h1:CNpVvsGRV2CDeme6pmAg8AcMxxBERYndcOzyu0dRgCg=
57-
github.com/ucloud/ucloud-sdk-go v0.8.10/go.mod h1:lM6fpI8y6iwACtlbHUav823/uKPdXsNBlnBpRF2fj3c=
56+
github.com/ucloud/ucloud-sdk-go v0.13.2 h1:KA7hMx2+E02p8ujw80xMPFfAvApnVUNHRyt3awc0HxQ=
57+
github.com/ucloud/ucloud-sdk-go v0.13.2/go.mod h1:dyLmFHmUfgb4RZKYQP9IArlvQ2pxzFthfhwxRzOEPIw=
5858
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648=
5959
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
6060
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
6161
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
6262
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
6363
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0=
6464
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
65+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
66+
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
67+
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
68+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
6569
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
6670
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
6771
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a h1:1n5lsVfiQW3yfsRGu98756EH1YthsFqr/5mxHduZW2A=
6872
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
6973
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
7074
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
75+
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
76+
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
7177
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
7278
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
7379
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=

ux/spinner.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,22 @@ func (s *Spinner) Stop() {
4343
fmt.Fprintf(s.out, output)
4444
}
4545

46-
// Timeout stop render
46+
// Timeout stop render
4747
func (s *Spinner) Timeout() {
4848
s.ticker.Stop()
4949
s.reset()
5050
output := fmt.Sprintf("%s...%s\n", s.DoingText, s.TimeoutText)
5151
fmt.Fprintf(s.out, output)
5252
}
5353

54+
// Fail stop render
55+
func (s *Spinner) Fail(err error) {
56+
s.ticker.Stop()
57+
s.reset()
58+
output := fmt.Sprintf("%s...fail: %v\n", s.DoingText, err)
59+
fmt.Fprintf(s.out, output)
60+
}
61+
5462
func (s *Spinner) reset() {
5563
if s.output == "" {
5664
return

vendor/github.com/ucloud/ucloud-sdk-go/private/utils/accessor.go

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)