github.com/spg/deis@v1.7.3/deisctl/backend/fleet/stop.go (about)

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