@@ -11,6 +11,21 @@ import (
1111 "github.com/coreos/fleet/unit"
1212)
1313
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+ // and the same for systemd service "decorators" for optionally isolating
22+ // control plane, data plane, and router mesh
23+ var decoratorPaths = []string {
24+ path .Join (os .Getenv ("DEISCTL_UNITS" ), "decorators" ),
25+ path .Join (os .Getenv ("HOME" ), ".deis" , "units" , "decorators" ),
26+ "/var/lib/deis/units/decorators" ,
27+ }
28+
1429// Units returns a list of units filtered by target
1530func (c * FleetClient ) Units (target string ) (units []string , err error ) {
1631 allUnits , err := c .Fleet .Units ()
@@ -56,14 +71,19 @@ func (c *FleetClient) lastUnit(component string) (num int, err error) {
5671
5772// NewUnit takes a component type and returns a Fleet unit
5873// that includes the relevant systemd service template
59- func NewUnit (component string , templatePaths []string ) (uf * unit.UnitFile , err error ) {
74+ func NewUnit (component string , templatePaths []string , decorate bool ) (uf * unit.UnitFile , err error ) {
6075 template , err := readTemplate (component , templatePaths )
6176 if err != nil {
6277 return
6378 }
64- uf , err = unit .NewUnitFile (string (template ))
65- if err != nil {
66- return
79+ if decorate {
80+ decorator , err := readDecorator (component )
81+ if err != nil {
82+ return nil , err
83+ }
84+ uf , err = unit .NewUnitFile (string (template ) + "\n " + string (decorator ))
85+ } else {
86+ uf , err = unit .NewUnitFile (string (template ))
6787 }
6888 return
6989}
@@ -104,3 +124,26 @@ func readTemplate(component string, templatePaths []string) (out []byte, err err
104124 }
105125 return
106126}
127+
128+ // readDecorator returns the contents of a file containing a snippet that can
129+ // optionally be grafted on to the end of a corresponding systemd unit to
130+ // achieve isolation of the control plane, data plane, and router mesh
131+ func readDecorator (component string ) (out []byte , err error ) {
132+ decoratorName := "deis-" + component + ".service.decorator"
133+ var decoratorFile string
134+
135+ // look in $DEISCTL_UNITS env var, then the local and global root paths
136+ for _ , p := range decoratorPaths {
137+ filename := path .Join (p , decoratorName )
138+ if _ , err := os .Stat (filename ); err == nil {
139+ decoratorFile = filename
140+ break
141+ }
142+ }
143+
144+ if decoratorFile == "" {
145+ return
146+ }
147+ out , err = ioutil .ReadFile (decoratorFile )
148+ return
149+ }
0 commit comments