Skip to content

Commit a5dc3b4

Browse files
committed
Merge pull request #3718 from krancour/plane-placement
feat(platform): support placement options for each plane and router mesh
2 parents 2f5171f + 46c83c1 commit a5dc3b4

50 files changed

Lines changed: 376 additions & 49 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ dev-cluster: discovery-url
2727
ssh-add ~/.vagrant.d/insecure_private_key
2828
deisctl config platform set sshPrivateKey=$(HOME)/.vagrant.d/insecure_private_key
2929
deisctl config platform set domain=local3.deisapp.com
30+
deisctl config platform set enablePlacementOptions=true
3031
deisctl install platform
3132

3233
discovery-url:

contrib/coreos/user-data.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ coreos:
77
public-ip: $private_ipv4
88
# allow etcd to slow down at times
99
etcd_request_timeout: 3.0
10+
metadata: controlPlane=true,dataPlane=true,routerMesh=true
1011
units:
1112
- name: etcd.service
1213
command: start

controller/scheduler/fleet.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,10 @@ def _create_container(self, name, image, command, unit, **kwargs):
150150
f['value'] = f['value'].format(**l)
151151
# prepare tags only if one was provided
152152
tags = kwargs.get('tags', {})
153-
if tags:
154-
tagset = ' '.join(['"{}={}"'.format(k, v) for k, v in tags.viewitems()])
153+
tagset = ' '.join(['"{}={}"'.format(k, v) for k, v in tags.viewitems()])
154+
if settings.ENABLE_PLACEMENT_OPTIONS in ['true', 'True', 'TRUE', '1']:
155155
unit.append({"section": "X-Fleet", "name": "MachineMetadata",
156-
"value": tagset})
156+
"value": tagset + ' "dataPlane=true"'})
157157
# post unit to fleet
158158
self._put_unit(name, {"desiredState": "loaded", "options": unit})
159159

controller/templates/confd_settings.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
# platform domain must be provided
2525
DEIS_DOMAIN = '{{ getv "/deis/platform/domain" }}'
2626

27+
ENABLE_PLACEMENT_OPTIONS = """{{ if exists "/deis/platform/enablePlacementOptions" }}{{ getv "/deis/platform/enablePlacementOptions" }}{{ else }}false{{end}}"""
28+
2729
# use the private registry module
2830
REGISTRY_MODULE = 'registry.private'
2931
REGISTRY_URL = '{{ getv "/deis/registry/protocol" }}://{{ getv "/deis/registry/host" }}:{{ getv "/deis/registry/port" }}' # noqa

deisctl/backend/fleet/create.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package fleet
33
import (
44
"fmt"
55
"io"
6+
"strconv"
67
"strings"
78
"sync"
89
"time"
@@ -96,7 +97,15 @@ func (c *FleetClient) createServiceUnit(component string, num int) (name string,
9697
if err != nil {
9798
return "", nil, err
9899
}
99-
uf, err = NewUnit(component, c.templatePaths)
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)
100109
if err != nil {
101110
return
102111
}

deisctl/backend/fleet/create_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import (
66
"sync"
77
"testing"
88

9+
"github.com/deis/deis/deisctl/config/model"
10+
"github.com/deis/deis/deisctl/test/mock"
11+
912
"github.com/coreos/fleet/schema"
1013
)
1114

@@ -30,7 +33,9 @@ func TestCreate(t *testing.T) {
3033
testFleetClient := stubFleetClient{testUnits: []*schema.Unit{}, unitsMutex: &sync.Mutex{},
3134
unitStatesMutex: &sync.Mutex{}}
3235

33-
c := &FleetClient{templatePaths: []string{name}, Fleet: &testFleetClient}
36+
testConfigBackend := mock.ConfigBackend{Expected: []*model.ConfigNode{{Key: "/deis/platform/enablePlacementOptions", Value: "true"}}}
37+
38+
c := &FleetClient{templatePaths: []string{name}, Fleet: &testFleetClient, configBackend: testConfigBackend}
3439

3540
var errOutput string
3641
var wg sync.WaitGroup

deisctl/backend/fleet/fleet.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ import (
66
"path"
77
"text/tabwriter"
88

9+
"github.com/deis/deis/deisctl/config"
10+
911
"github.com/coreos/fleet/client"
1012
"github.com/coreos/fleet/machine"
1113
)
1214

1315
// FleetClient used to wrap Fleet API calls
1416
type FleetClient struct {
15-
Fleet client.API
17+
Fleet client.API
18+
configBackend config.Backend
1619

1720
// used to cache MachineStates
1821
machineStates map[string]*machine.MachineState
@@ -25,7 +28,7 @@ type FleetClient struct {
2528

2629
// NewClient returns a client used to communicate with Fleet
2730
// using the Registry API
28-
func NewClient() (*FleetClient, error) {
31+
func NewClient(cb config.Backend) (*FleetClient, error) {
2932
client, err := getRegistryClient()
3033
if err != nil {
3134
return nil, err
@@ -41,6 +44,6 @@ func NewClient() (*FleetClient, error) {
4144
out := new(tabwriter.Writer)
4245
out.Init(os.Stdout, 0, 8, 1, '\t', 0)
4346

44-
return &FleetClient{Fleet: client, templatePaths: templatePaths, runner: sshCommandRunner{},
47+
return &FleetClient{Fleet: client, configBackend: cb, templatePaths: templatePaths, runner: sshCommandRunner{},
4548
out: out, errWriter: os.Stderr}, nil
4649
}

deisctl/backend/fleet/fleet_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import (
66
"sync"
77
"testing"
88

9+
"github.com/deis/deis/deisctl/config/model"
10+
"github.com/deis/deis/deisctl/test/mock"
11+
912
"github.com/coreos/fleet/machine"
1013
"github.com/coreos/fleet/schema"
1114
)
@@ -176,8 +179,10 @@ func TestNewClient(t *testing.T) {
176179
// set required flags
177180
Flags.Endpoint = "http://127.0.0.1:4001"
178181

182+
testConfigBackend := mock.ConfigBackend{Expected: []*model.ConfigNode{}}
183+
179184
// instantiate client
180-
_, err := NewClient()
185+
_, err := NewClient(testConfigBackend)
181186
if err != nil {
182187
t.Fatal(err)
183188
}

deisctl/backend/fleet/scale_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import (
77
"sync"
88
"testing"
99

10+
"github.com/deis/deis/deisctl/config/model"
11+
"github.com/deis/deis/deisctl/test/mock"
12+
1013
"github.com/coreos/fleet/schema"
1114
)
1215

@@ -30,7 +33,9 @@ func TestScaleUp(t *testing.T) {
3033

3134
testFleetClient := stubFleetClient{testUnits: testUnits, testUnitStates: []*schema.UnitState{}, unitsMutex: &sync.Mutex{}, unitStatesMutex: &sync.Mutex{}}
3235

33-
c := &FleetClient{templatePaths: []string{name}, Fleet: &testFleetClient}
36+
testConfigBackend := mock.ConfigBackend{Expected: []*model.ConfigNode{{Key: "/deis/platform/enablePlacementOptions", Value: "true"}}}
37+
38+
c := &FleetClient{templatePaths: []string{name}, Fleet: &testFleetClient, configBackend: testConfigBackend}
3439

3540
var errOutput string
3641
var wg sync.WaitGroup

deisctl/backend/fleet/unit.go

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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
1530
func (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

Comments
 (0)