Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export VERSION=0.1.28
export VERSION=0.1.29

.PHONY : install
install:
Expand Down
2 changes: 1 addition & 1 deletion base/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const DefaultBaseURL = "https://api.ucloud.cn/"
const DefaultProfile = "default"

//Version 版本号
const Version = "0.1.28"
const Version = "0.1.29"

//ConfigIns 配置实例, 程序加载时生成
var ConfigIns = &AggConfig{
Expand Down
19 changes: 9 additions & 10 deletions base/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ func (p *Poller) Spoll(resourceID, pollText string, targetStates []string) {
}

//Poll function
func (p *Poller) Poll(resourceID, projectID, region, zone, pollText string, targetState []string) {
func (p *Poller) Poll(resourceID, projectID, region, zone, pollText string, targetState []string) bool {
w := waiter.StateWaiter{
Pending: []string{"pending"},
Target: []string{"avaliable"},
Expand Down Expand Up @@ -517,26 +517,25 @@ func (p *Poller) Poll(resourceID, projectID, region, zone, pollText string, targ
Timeout: p.Timeout,
}

var err error
done := make(chan bool)
go func() {
if _, err := w.Wait(); err != nil {
log.Error(err)
if _, ok := err.(*waiter.TimeoutError); ok {
done <- false
return
}
if _, err = w.Wait(); err != nil {
done <- false
return
}
done <- true
}()

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

//NewSpoller simple
Expand Down
136 changes: 84 additions & 52 deletions cmd/uhost.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ func NewCmdUHostCreate() *cobra.Command {
}

wg := &sync.WaitGroup{}
tokens := make(chan struct{}, 10)
tokens := make(chan struct{}, 20)
wg.Add(count)
if count <= 5 {
for i := 0; i < count; i++ {
Expand Down Expand Up @@ -582,7 +582,7 @@ func NewCmdUHostDelete(out io.Writer) *cobra.Command {
_req.UHostId = sdk.String(id)
reqs[idx] = &_req
}
coAction := newConcurrentAction(reqs, deleteUHost)
coAction := newConcurrentAction(reqs, 50, deleteUHost)
coAction.Do()
},
}
Expand All @@ -595,7 +595,7 @@ func NewCmdUHostDelete(out io.Writer) *cobra.Command {
req.Zone = cmd.Flags().String("zone", "", "Optional. availability zone")
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")
req.ReleaseEIP = cmd.Flags().Bool("release-eip", true, "Optional. false,Unbind EIP only; true, Unbind EIP and release it")
req.ReleaseUDisk = cmd.Flags().Bool("delete-cloud-disk", false, "Optional. false, detach cloud disk only; true, detach cloud disk and delete it")
req.ReleaseUDisk = cmd.Flags().Bool("delete-cloud-disk", true, "Optional. false, detach cloud disk only; true, detach cloud disk and delete it")
yes = cmd.Flags().BoolP("yes", "y", false, "Optional. Do not prompt for confirmation.")
cmd.Flags().SetFlagValues("destroy", "true", "false")
cmd.Flags().SetFlagValues("release-eip", "true", "false")
Expand Down Expand Up @@ -679,19 +679,34 @@ func NewCmdUHostStop(out io.Writer) *cobra.Command {
return cmd
}

func stopUhostIns(req *uhost.StopUHostInstanceRequest, async bool, out io.Writer) {
func promptStopUhostIns(req *uhost.StopUHostInstanceRequest, yes, async bool, promptText string, out io.Writer) bool {
if !yes {
agreeClose, err := ux.Prompt(promptText)
if err != nil {
base.LogError(err.Error())
return false
}
if !agreeClose {
return false
}
}
return stopUhostIns(req, false, out)
}

func stopUhostIns(req *uhost.StopUHostInstanceRequest, async bool, out io.Writer) bool {
resp, err := base.BizClient.StopUHostInstance(req)
if err != nil {
base.HandleError(err)
} else {
text := fmt.Sprintf("uhost[%v] is shutting down", resp.UhostId)
if async {
fmt.Fprintln(out, text)
} else {
poller := base.NewPoller(describeUHostByID, out)
poller.Poll(resp.UhostId, *req.ProjectId, *req.Region, *req.Zone, text, []string{status.HOST_STOPPED, status.HOST_FAIL})
}
return false
}

text := fmt.Sprintf("uhost [%v] is shutting down", resp.UhostId)
if async {
fmt.Fprintln(out, text)
return false
}
poller := base.NewPoller(describeUHostByID, out)
return poller.Poll(resp.UhostId, *req.ProjectId, *req.Region, *req.Zone, text, []string{status.HOST_STOPPED, status.HOST_FAIL})
}

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

func resizeUhost(req *uhost.ResizeUHostInstanceRequest) {
func resizeAttachedDisk(out io.Writer, req *uhost.ResizeAttachedDiskRequest, host *uhost.UHostInstanceSet, yes, async bool, promptText string) error {
req.UHostId = &host.UHostId
if host.State == status.HOST_RUNNING {
err := tryStopUhost(req, host.UHostId, promptText, yes, async, out)
if err != nil {
return fmt.Errorf("try to stop uhost error :%w", err)
}
}
req.DryRun = sdk.Bool(false)
_, err := base.BizClient.ResizeAttachedDisk(req)
if err != nil {
return err
}
text := fmt.Sprintf("uhost [%s] disk [%s] resize", host.UHostId, *req.DiskId)
if async {
fmt.Fprintln(out, text)
} else {
poller := base.NewPoller(describeUHostByID, out)
poller.Poll(host.UHostId, *req.ProjectId, *req.Region, *req.Zone, text, []string{status.HOST_RUNNING, status.HOST_STOPPED, status.HOST_FAIL})
}
return nil
}

func tryStopUhost(req *uhost.ResizeAttachedDiskRequest, uhostID, promptText string, yes, async bool, out io.Writer) error {
req.DryRun = sdk.Bool(true)
resp, err := base.BizClient.ResizeAttachedDisk(req)
if err != nil {
return err
}
if resp.NeedRestart {
stopReq := base.BizClient.NewStopUHostInstanceRequest()
stopReq.UHostId = &uhostID
promptStopUhostIns(stopReq, yes, async, promptText, out)
}
return nil
}

//NewCmdUHostResize ucloud uhost resize
Expand Down Expand Up @@ -881,34 +929,24 @@ func NewCmdUHostResize(out io.Writer) *cobra.Command {
return
}
inst := host.(*uhost.UHostInstanceSet)
if inst.State == "Running" {
if !*yes {
confirmText := "Resize uhost must be done after the uhost is stopped. Do you want to stop this uhost?"
if len(*uhostIDs) > 1 {
confirmText = "Resize uhost must be done after the uhost is stopped. Do you want to stop those uhosts?"
}
agreeClose, err := ux.Prompt(confirmText)
if err != nil {
base.Cxt.Println(err)
return
}
if !agreeClose {
return
stopReq := base.BizClient.NewStopUHostInstanceRequest()
stopReq.ProjectId = req.ProjectId
stopReq.Region = req.Region
stopReq.Zone = req.Zone
stopReq.UHostId = &id
confirmText := "Resize uhost must be done after the uhost is stopped. Do you want to stop this uhost?"
if req.CPU != nil || req.Memory != nil || *req.NetCapValue != 0 {
if inst.State == status.HOST_RUNNING {
ret := promptStopUhostIns(stopReq, *yes, *async, confirmText, out)
if ret {
inst.State = status.HOST_STOPPED
}
}
_req := base.BizClient.NewStopUHostInstanceRequest()
_req.ProjectId = req.ProjectId
_req.Region = req.Region
_req.Zone = req.Zone
_req.UHostId = &id
stopUhostIns(_req, false, out)
}
if req.CPU != nil || req.Memory != nil || *req.NetCapValue != 0 {
resp, err := base.BizClient.ResizeUHostInstance(req)
if err != nil {
base.HandleError(err)
} else {
text := fmt.Sprintf("uhost [%v] cpu, memory resized", resp.UhostId)
text := fmt.Sprintf("uhost [%v] cpu, memory resize", resp.UhostId)
if *async {
fmt.Fprintln(out, text)
} else {
Expand Down Expand Up @@ -937,7 +975,13 @@ func NewCmdUHostResize(out io.Writer) *cobra.Command {
_req.DiskSpace = &bootDiskSize
_req.DiskId = &bootDisk.DiskId
}
} else if dataDiskSize != 0 {
err := resizeAttachedDisk(out, _req, inst, *yes, *async, confirmText)
if err != nil {
base.HandleError(err)
}
}

if dataDiskSize != 0 {
var dataDisk uhost.UHostDiskSet
if len(dataDisks) > 1 {
if dataDiskID == "" {
Expand All @@ -964,21 +1008,9 @@ func NewCmdUHostResize(out io.Writer) *cobra.Command {
}
_req.DiskSpace = &dataDiskSize
_req.DiskId = &dataDisk.DiskId
}
_req.ProjectId = req.ProjectId
_req.Region = req.Region
_req.Zone = req.Zone
_req.UHostId = &id
_, err := base.BizClient.ResizeAttachedDisk(_req)
if err != nil {
base.HandleError(err)
} else {
text := fmt.Sprintf("uhost [%v] disk resized", id)
if *async {
fmt.Fprintln(out, text)
} else {
poller := base.NewPoller(describeUHostByID, out)
poller.Poll(id, *req.ProjectId, *req.Region, *req.Zone, text, []string{status.HOST_RUNNING, status.HOST_STOPPED, status.HOST_FAIL})
err := resizeAttachedDisk(out, _req, inst, *yes, *async, confirmText)
if err != nil {
base.HandleError(err)
}
}
}
Expand Down Expand Up @@ -1018,7 +1050,7 @@ func describeUHostByID(uhostID, projectID, region, zone string) (interface{}, er
return nil, err
}
if len(resp.UHostSet) < 1 {
return nil, nil
return nil, fmt.Errorf("uhost [%s] does not exist", uhostID)
}

return &resp.UHostSet[0], nil
Expand Down
4 changes: 2 additions & 2 deletions cmd/umem.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ func NewCmdRedisRestart(out io.Writer) *cobra.Command {
_req.GroupId = &id
reqs[idx] = &_req
}
coAction := newConcurrentAction(reqs, restartRedis)
coAction := newConcurrentAction(reqs, 10, restartRedis)
coAction.Do()
},
}
Expand Down Expand Up @@ -531,7 +531,7 @@ func NewCmdMemcacheRestart(out io.Writer) *cobra.Command {
_req.GroupId = &id
reqs[idx] = &_req
}
coAction := newConcurrentAction(reqs, restartMemcache)
coAction := newConcurrentAction(reqs, 10, restartMemcache)
coAction.Do()
},
}
Expand Down
14 changes: 9 additions & 5 deletions cmd/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,16 @@ type concurrentAction struct {
tokens chan bool
}

func newConcurrentAction(reqs []request.Common, actionFunc func(request.Common) (bool, []string)) *concurrentAction {
func newConcurrentAction(reqs []request.Common, limit int, actionFunc func(request.Common) (bool, []string)) *concurrentAction {
if limit <= 0 {
limit = 10
}
return &concurrentAction{
reqs: reqs,
actionFunc: actionFunc,
wg: &sync.WaitGroup{},
result: make(chan bool),
tokens: make(chan bool, 10), //控制并发量,最多是个并发
tokens: make(chan bool, limit), //控制并发量,最多是个并发
}
}

Expand Down Expand Up @@ -168,11 +171,12 @@ func (c *concurrentAction) Do() {
}

case <-time.Tick(time.Second / 30):
if count > 5 {
refresh.Do(fmt.Sprintf("total:%d, doing:%d, success:%d, fail:%d", count, len(c.tokens), success, fail))
}
if count == (success+fail) && fail > 0 {
fmt.Printf("Check logs in %s\n", base.GetLogFilePath())
return
}
if count > 5 {
refresh.Do(fmt.Sprintf("total:%d, doing:%d, success:%d, fail:%d", count, len(c.tokens), success, fail))
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ require (
github.com/sirupsen/logrus v1.3.0
github.com/spf13/cobra v0.0.3
github.com/spf13/pflag v1.0.3
github.com/ucloud/ucloud-sdk-go v0.8.10
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a
github.com/ucloud/ucloud-sdk-go v0.13.2
golang.org/x/sys v0.0.0-20190412213103-97732733099d
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
)

Expand Down
10 changes: 8 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,27 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/ucloud/ucloud-sdk-go v0.8.10 h1:CNpVvsGRV2CDeme6pmAg8AcMxxBERYndcOzyu0dRgCg=
github.com/ucloud/ucloud-sdk-go v0.8.10/go.mod h1:lM6fpI8y6iwACtlbHUav823/uKPdXsNBlnBpRF2fj3c=
github.com/ucloud/ucloud-sdk-go v0.13.2 h1:KA7hMx2+E02p8ujw80xMPFfAvApnVUNHRyt3awc0HxQ=
github.com/ucloud/ucloud-sdk-go v0.13.2/go.mod h1:dyLmFHmUfgb4RZKYQP9IArlvQ2pxzFthfhwxRzOEPIw=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a h1:1n5lsVfiQW3yfsRGu98756EH1YthsFqr/5mxHduZW2A=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
Expand Down
10 changes: 9 additions & 1 deletion ux/spinner.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,22 @@ func (s *Spinner) Stop() {
fmt.Fprintf(s.out, output)
}

// Timeout stop render
// Timeout stop render
func (s *Spinner) Timeout() {
s.ticker.Stop()
s.reset()
output := fmt.Sprintf("%s...%s\n", s.DoingText, s.TimeoutText)
fmt.Fprintf(s.out, output)
}

// Fail stop render
func (s *Spinner) Fail(err error) {
s.ticker.Stop()
s.reset()
output := fmt.Sprintf("%s...fail: %v\n", s.DoingText, err)
fmt.Fprintf(s.out, output)
}

func (s *Spinner) reset() {
if s.output == "" {
return
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading