github.com/scaleway/scaleway-cli@v1.11.1/pkg/commands/start.go (about)

     1  // Copyright (C) 2015 Scaleway. All rights reserved.
     2  // Use of this source code is governed by a MIT-style
     3  // license that can be found in the LICENSE.md file.
     4  
     5  package commands
     6  
     7  import (
     8  	"fmt"
     9  	"sync"
    10  	"time"
    11  
    12  	"github.com/Sirupsen/logrus"
    13  	"github.com/scaleway/scaleway-cli/pkg/api"
    14  )
    15  
    16  // StartArgs are flags for the `RunStart` function
    17  type StartArgs struct {
    18  	Servers  []string
    19  	Wait     bool
    20  	Timeout  float64
    21  	SetState string
    22  }
    23  
    24  // RunStart is the handler for 'scw start'
    25  func RunStart(ctx CommandContext, args StartArgs) error {
    26  	hasError := false
    27  	errChan := make(chan error)
    28  	successChan := make(chan string)
    29  	remainingItems := len(args.Servers)
    30  
    31  	for _, needle := range args.Servers {
    32  		go api.StartServerOnce(ctx.API, needle, args.Wait, successChan, errChan)
    33  	}
    34  
    35  	if args.Timeout > 0 {
    36  		go func() {
    37  			time.Sleep(time.Duration(args.Timeout*1000) * time.Millisecond)
    38  			// FIXME: avoid use of fatalf
    39  			logrus.Fatalf("Operation timed out")
    40  		}()
    41  	}
    42  
    43  	for {
    44  		select {
    45  		case name := <-successChan:
    46  			fmt.Println(name)
    47  			remainingItems--
    48  		case err := <-errChan:
    49  			logrus.Errorf("%s", err)
    50  			remainingItems--
    51  			hasError = true
    52  		}
    53  
    54  		if remainingItems == 0 {
    55  			break
    56  		}
    57  	}
    58  	if args.SetState != "" {
    59  		var wg sync.WaitGroup
    60  
    61  		for _, needle := range args.Servers {
    62  			wg.Add(1)
    63  			go func(n string) {
    64  				defer wg.Done()
    65  				serverID, err := ctx.API.GetServerID(n)
    66  				if err != nil {
    67  					return
    68  				}
    69  
    70  				for {
    71  					server, err := ctx.API.GetServer(serverID)
    72  					if err != nil {
    73  						logrus.Errorf("%s", err)
    74  						return
    75  					}
    76  					if server.StateDetail == "kernel-started" {
    77  						err = ctx.API.PatchServer(serverID, api.ScalewayServerPatchDefinition{
    78  							StateDetail: &args.SetState,
    79  						})
    80  						if err != nil {
    81  							logrus.Errorf("%s", err)
    82  						}
    83  						return
    84  					}
    85  					time.Sleep(1 * time.Second)
    86  				}
    87  			}(needle)
    88  		}
    89  		wg.Wait()
    90  	}
    91  	if hasError {
    92  		return fmt.Errorf("at least 1 server failed to start")
    93  	}
    94  	return nil
    95  }