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  }