github.com/didip/deis@v1.4.1/deisctl/backend/fleet/unit.go (about) 1 package fleet 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "path" 8 "strconv" 9 "strings" 10 11 "github.com/coreos/fleet/unit" 12 ) 13 14 // path hierarchy for finding systemd service templates 15 var templatePaths = []string{ 16 os.Getenv("DEISCTL_UNITS"), 17 path.Join(os.Getenv("HOME"), ".deis", "units"), 18 "/var/lib/deis/units", 19 } 20 21 // Units returns a list of units filtered by target 22 func (c *FleetClient) Units(target string) (units []string, err error) { 23 allUnits, err := c.Fleet.Units() 24 if err != nil { 25 return 26 } 27 for _, u := range allUnits { 28 if strings.Contains(u.Name, target) { 29 units = append(units, u.Name) 30 } 31 } 32 if len(units) == 0 { 33 err = fmt.Errorf("could not find unit: %s", target) 34 } 35 return 36 } 37 38 // nextUnit returns the next unit number for a given component 39 func (c *FleetClient) nextUnit(component string) (num int, err error) { 40 units, err := c.Units(component) 41 if err != nil { 42 return 43 } 44 num, err = nextUnitNum(units) 45 if err != nil { 46 return 47 } 48 return 49 } 50 51 // lastUnit returns the last unit number for a given component 52 func (c *FleetClient) lastUnit(component string) (num int, err error) { 53 units, err := c.Units(component) 54 if err != nil { 55 return 56 } 57 num, err = lastUnitNum(units) 58 if err != nil { 59 return 60 } 61 return 62 } 63 64 // NewUnit takes a component type and returns a Fleet unit 65 // that includes the relevant systemd service template 66 func NewUnit(component string) (uf *unit.UnitFile, err error) { 67 template, err := readTemplate(component) 68 if err != nil { 69 return 70 } 71 uf, err = unit.NewUnitFile(string(template)) 72 if err != nil { 73 return 74 } 75 return 76 } 77 78 // formatUnitName returns a properly formatted systemd service name 79 // using the given component type and number 80 func formatUnitName(component string, num int) (unitName string, err error) { 81 component = strings.TrimPrefix(component, "deis-") 82 if num == 0 { 83 return "deis-" + component + ".service", nil 84 } 85 return "deis-" + component + "@" + strconv.Itoa(num) + ".service", nil 86 } 87 88 // readTemplate returns the contents of a systemd template for the given component 89 func readTemplate(component string) (out []byte, err error) { 90 templateName := "deis-" + component + ".service" 91 var templateFile string 92 93 // look in $DEISCTL_UNITS env var, then the local and global root paths 94 for _, p := range templatePaths { 95 if p == "" { 96 continue 97 } 98 filename := path.Join(p, templateName) 99 if _, err := os.Stat(filename); err == nil { 100 templateFile = filename 101 break 102 } 103 } 104 105 if templateFile == "" { 106 return nil, fmt.Errorf("Could not find unit template for %v", component) 107 } 108 out, err = ioutil.ReadFile(templateFile) 109 if err != nil { 110 return 111 } 112 return 113 }