github.com/technosophos/deis@v1.7.1-0.20150915173815-f9005256004b/deisctl/backend/fleet/start.go (about) 1 package fleet 2 3 import ( 4 "fmt" 5 "io" 6 "sync" 7 "time" 8 9 "github.com/coreos/fleet/schema" 10 "github.com/deis/deis/pkg/prettyprint" 11 ) 12 13 // Start units and wait for their desiredState 14 func (c *FleetClient) Start(targets []string, wg *sync.WaitGroup, out, ew io.Writer) { 15 // expand @* targets 16 expandedTargets, err := c.expandTargets(targets) 17 if err != nil { 18 io.WriteString(ew, err.Error()) 19 return 20 } 21 22 for _, target := range expandedTargets { 23 wg.Add(1) 24 go doStart(c, target, wg, out, ew) 25 } 26 return 27 } 28 29 func doStart(c *FleetClient, target string, wg *sync.WaitGroup, out, ew io.Writer) { 30 defer wg.Done() 31 32 // prepare string representation 33 component, num, err := splitTarget(target) 34 if err != nil { 35 io.WriteString(ew, err.Error()) 36 return 37 } 38 name, err := formatUnitName(component, num) 39 if err != nil { 40 io.WriteString(ew, err.Error()) 41 return 42 } 43 44 requestState := "launched" 45 desiredState := "running" 46 47 if err := c.Fleet.SetUnitTargetState(name, requestState); err != nil { 48 io.WriteString(ew, err.Error()) 49 return 50 } 51 52 // start with the likely subState to avoid sending it across the channel 53 lastSubState := "dead" 54 55 for { 56 // poll for unit states 57 states, err := c.Fleet.UnitStates() 58 if err != nil { 59 io.WriteString(ew, err.Error()) 60 return 61 } 62 63 // FIXME: fleet UnitStates API forces us to iterate for now 64 var currentState *schema.UnitState 65 for _, s := range states { 66 if name == s.Name { 67 currentState = s 68 break 69 } 70 } 71 if currentState == nil { 72 fmt.Fprintf(ew, "Could not find unit: %v\n", name) 73 return 74 } 75 76 // if subState changed, send it across the output channel 77 if lastSubState != currentState.SystemdSubState { 78 l := prettyprint.Overwritef(stateFmt, name, currentState.SystemdActiveState, currentState.SystemdSubState) 79 fmt.Fprintf(out, l) 80 } 81 82 // break when desired state is reached 83 if currentState.SystemdSubState == desiredState { 84 fmt.Fprintln(out) 85 return 86 } 87 88 lastSubState = currentState.SystemdSubState 89 90 if lastSubState == "failed" { 91 o := prettyprint.Colorize("{{.Red}}The service '%s' failed while starting.{{.Default}}\n") 92 fmt.Fprintf(ew, o, target) 93 return 94 } 95 time.Sleep(250 * time.Millisecond) 96 } 97 }