func doCreate(c *FleetClient, unit *schema.Unit, wg *sync.WaitGroup, out, ew io.Writer) { defer wg.Done() // create unit definition if err := c.Fleet.CreateUnit(unit); err != nil { // ignore units that already exist if err.Error() != "job already exists" { fmt.Fprintln(ew, err.Error()) return } } desiredState := string(job.JobStateLoaded) tpl := prettyprint.Colorize("{{.Yellow}}%v:{{.Default}} loaded") msg := fmt.Sprintf(tpl, unit.Name) // schedule the unit if err := c.Fleet.SetUnitTargetState(unit.Name, desiredState); err != nil { fmt.Fprintln(ew, err) return } // loop until the unit actually exists in unit states outerLoop: for { time.Sleep(250 * time.Millisecond) unitStates, err := c.Fleet.UnitStates() if err != nil { fmt.Fprintln(ew, err) } for _, us := range unitStates { if strings.HasPrefix(us.Name, unit.Name) { break outerLoop } } } fmt.Fprintln(out, msg) }
func doDestroy(c *FleetClient, target string, wg *sync.WaitGroup, out, ew io.Writer) { defer wg.Done() // prepare string representation component, num, err := splitTarget(target) if err != nil { fmt.Fprintln(ew, err.Error()) return } name, err := formatUnitName(component, num) if err != nil { fmt.Fprintln(ew, err.Error()) return } tpl := prettyprint.Colorize("{{.Yellow}}%v:{{.Default}} destroyed") destroyed := fmt.Sprintf(tpl, name) // tell fleet to destroy the unit c.Fleet.DestroyUnit(name) // loop until the unit is actually gone from unit states outerLoop: for { time.Sleep(250 * time.Millisecond) unitStates, err := c.Fleet.UnitStates() if err != nil { fmt.Fprintln(ew, err.Error()) } for _, us := range unitStates { if strings.HasPrefix(us.Name, name) { continue outerLoop } } fmt.Fprintln(out, destroyed) return } }
func doStart(c *FleetClient, target string, wg *sync.WaitGroup, out, ew io.Writer) { defer wg.Done() // prepare string representation component, num, err := splitTarget(target) if err != nil { io.WriteString(ew, err.Error()) return } name, err := formatUnitName(component, num) if err != nil { io.WriteString(ew, err.Error()) return } requestState := "launched" desiredState := "running" if err := c.Fleet.SetUnitTargetState(name, requestState); err != nil { io.WriteString(ew, err.Error()) return } // start with the likely subState to avoid sending it across the channel lastSubState := "dead" for { // poll for unit states states, err := c.Fleet.UnitStates() if err != nil { io.WriteString(ew, err.Error()) return } // FIXME: fleet UnitStates API forces us to iterate for now var currentState *schema.UnitState for _, s := range states { if name == s.Name { currentState = s break } } if currentState == nil { fmt.Fprintf(ew, "Could not find unit: %v\n", name) return } // if subState changed, send it across the output channel if lastSubState != currentState.SystemdSubState { l := prettyprint.Overwritef(stateFmt, name, currentState.SystemdActiveState, currentState.SystemdSubState) fmt.Fprintf(out, l) } // break when desired state is reached if currentState.SystemdSubState == desiredState { fmt.Fprintln(out) return } lastSubState = currentState.SystemdSubState if lastSubState == "failed" { o := prettyprint.Colorize("{{.Red}}The service '%s' failed while starting.{{.Default}}\n") fmt.Fprintf(ew, o, target) return } time.Sleep(250 * time.Millisecond) } }
package fleet import ( "fmt" "io" "sync" "time" "github.com/coreos/fleet/schema" "github.com/deis/deis/pkg/prettyprint" ) var stateFmt = prettyprint.Colorize("{{.Yellow}}%v:{{.Default}} %v/%v") // Stop units and wait for their desiredState func (c *FleetClient) Stop(targets []string, wg *sync.WaitGroup, out, ew io.Writer) { // expand @* targets expandedTargets, err := c.expandTargets(targets) if err != nil { fmt.Fprintln(ew, err.Error()) return } for _, target := range expandedTargets { wg.Add(1) go doStop(c, target, wg, out, ew) } return } func doStop(c *FleetClient, target string, wg *sync.WaitGroup, out, ew io.Writer) {