github.com/technosophos/deis@v1.7.1-0.20150915173815-f9005256004b/deisctl/backend/fleet/create.go (about) 1 package fleet 2 3 import ( 4 "fmt" 5 "io" 6 "strconv" 7 "strings" 8 "sync" 9 "time" 10 11 "github.com/coreos/fleet/job" 12 "github.com/coreos/fleet/schema" 13 "github.com/coreos/fleet/unit" 14 15 "github.com/deis/deis/pkg/prettyprint" 16 ) 17 18 // Create schedules unit files for the given components. 19 func (c *FleetClient) Create( 20 targets []string, wg *sync.WaitGroup, out, ew io.Writer) { 21 22 units := make([]*schema.Unit, len(targets)) 23 24 for i, target := range targets { 25 unitName, unitFile, err := c.createUnitFile(target) 26 if err != nil { 27 fmt.Fprintf(ew, "Error creating: %s\n", err) 28 return 29 } 30 units[i] = &schema.Unit{ 31 Name: unitName, 32 Options: schema.MapUnitFileToSchemaUnitOptions(unitFile), 33 } 34 } 35 36 for _, unit := range units { 37 wg.Add(1) 38 go doCreate(c, unit, wg, out, ew) 39 } 40 } 41 42 func doCreate(c *FleetClient, unit *schema.Unit, wg *sync.WaitGroup, out, ew io.Writer) { 43 defer wg.Done() 44 45 // create unit definition 46 if err := c.Fleet.CreateUnit(unit); err != nil { 47 // ignore units that already exist 48 if err.Error() != "job already exists" { 49 fmt.Fprintln(ew, err.Error()) 50 return 51 } 52 } 53 54 desiredState := string(job.JobStateLoaded) 55 tpl := prettyprint.Colorize("{{.Yellow}}%v:{{.Default}} loaded") 56 msg := fmt.Sprintf(tpl, unit.Name) 57 58 // schedule the unit 59 if err := c.Fleet.SetUnitTargetState(unit.Name, desiredState); err != nil { 60 fmt.Fprintln(ew, err) 61 return 62 } 63 64 // loop until the unit actually exists in unit states 65 outerLoop: 66 for { 67 time.Sleep(250 * time.Millisecond) 68 unitStates, err := c.Fleet.UnitStates() 69 if err != nil { 70 fmt.Fprintln(ew, err) 71 } 72 for _, us := range unitStates { 73 if strings.HasPrefix(us.Name, unit.Name) { 74 break outerLoop 75 } 76 } 77 } 78 79 fmt.Fprintln(out, msg) 80 } 81 82 func (c *FleetClient) createUnitFile(target string) (unitName string, uf *unit.UnitFile, err error) { 83 component, num, err := splitTarget(target) 84 if err != nil { 85 return 86 } 87 unitName, uf, err = c.createServiceUnit(component, num) 88 if err != nil { 89 return unitName, uf, err 90 } 91 return 92 } 93 94 // Create normal service unit 95 func (c *FleetClient) createServiceUnit(component string, num int) (name string, uf *unit.UnitFile, err error) { 96 name, err = formatUnitName(component, num) 97 if err != nil { 98 return "", nil, err 99 } 100 decorateStr, err := c.configBackend.GetWithDefault("/deis/platform/enablePlacementOptions", "false") 101 if err != nil { 102 return "", nil, err 103 } 104 decorate, err := strconv.ParseBool(decorateStr) 105 if err != nil { 106 return "", nil, err 107 } 108 uf, err = NewUnit(component, c.templatePaths, decorate) 109 if err != nil { 110 return 111 } 112 return name, uf, nil 113 }