github.com/misfo/deis@v1.0.1-0.20141111224634-e0eee0392b8a/deisctl/backend/fleet/start.go (about)

     1  package fleet
     2  
     3  import (
     4  	"fmt"
     5  	"sync"
     6  	"time"
     7  
     8  	"github.com/coreos/fleet/schema"
     9  )
    10  
    11  // Start units and wait for their desiredState
    12  func (c *FleetClient) Start(targets []string, wg *sync.WaitGroup, outchan chan string, errchan chan error) {
    13  	for _, target := range targets {
    14  		wg.Add(1)
    15  		go doStart(c, target, wg, outchan, errchan)
    16  	}
    17  	return
    18  }
    19  
    20  func doStart(c *FleetClient, target string, wg *sync.WaitGroup, outchan chan string, errchan chan error) {
    21  	defer wg.Done()
    22  
    23  	// prepare string representation
    24  	component, num, err := splitTarget(target)
    25  	if err != nil {
    26  		errchan <- err
    27  		return
    28  	}
    29  	name, err := formatUnitName(component, num)
    30  	if err != nil {
    31  		errchan <- err
    32  		return
    33  	}
    34  
    35  	requestState := "launched"
    36  	desiredState := "running"
    37  
    38  	if err := c.Fleet.SetUnitTargetState(name, requestState); err != nil {
    39  		errchan <- err
    40  		return
    41  	}
    42  
    43  	// start with the likely subState to avoid sending it across the channel
    44  	lastSubState := "dead"
    45  
    46  	for {
    47  		// poll for unit states
    48  		states, err := c.Fleet.UnitStates()
    49  		if err != nil {
    50  			errchan <- err
    51  			return
    52  		}
    53  
    54  		// FIXME: fleet UnitStates API forces us to iterate for now
    55  		var currentState *schema.UnitState
    56  		for _, s := range states {
    57  			if name == s.Name {
    58  				currentState = s
    59  				break
    60  			}
    61  		}
    62  		if currentState == nil {
    63  			errchan <- fmt.Errorf("could not find unit: %v", name)
    64  			return
    65  		}
    66  
    67  		// if subState changed, send it across the output channel
    68  		if lastSubState != currentState.SystemdSubState {
    69  			outchan <- fmt.Sprintf("\033[0;33m%v:\033[0m %v/%v                                 \r",
    70  				name, currentState.SystemdActiveState, currentState.SystemdSubState)
    71  		}
    72  
    73  		// break when desired state is reached
    74  		if currentState.SystemdSubState == desiredState {
    75  			return
    76  		}
    77  
    78  		lastSubState = currentState.SystemdSubState
    79  		time.Sleep(250 * time.Millisecond)
    80  	}
    81  }