Skip to content

Commit b14228b

Browse files
committed
fix(scheduler/coreos): skip announcer containers for start, stop, destroy
With #1269 we stopped creating announce containers except for web and cmd types, but we still attempt to perform actions on them for start, stop, and destroy. This commit adds logic to wrap all of these scheduler actions in a conditional which skips (and logs) announce operations. TESTING: rebuild the controller ```console $ make -C controller stop build start ``` Then, deploy an application which has either a cmd or web proctype, as well as a non-standard type. I modified the Procfile for our example-ruby-sinatra like so: ``` web: bundle exec ruby web.rb -p ${PORT:-5000} clock: echo flava flavvvvvvv ``` Scale the app, start/stop processes, etc. You should see successful operations for both, and note that the clock type has no announce containers. The output of ```deis ps``` should always show them as being up: ``` === exotic-icehouse Processes --- web: web.1 up (v3) web.2 up (v3) web.3 up (v3) --- clock: clock.1 up (v3) clock.2 up (v3) clock.3 up (v3) ``` fixes #1273 closes #1275
1 parent bd460ce commit b14228b

3 files changed

Lines changed: 52 additions & 22 deletions

File tree

controller/api/models.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -304,19 +304,25 @@ def _get_command(self):
304304

305305
_command = property(_get_command)
306306

307+
def _command_announceable(self):
308+
return self._command.lower() in ['start web', '']
309+
307310
@close_db_connections
308311
@transition(field=state, source=INITIALIZED, target=CREATED)
309312
def create(self):
310313
image = self.release.image
311314
c_type = self.type
312-
self._scheduler.create(self._job_id, image, self._command.format(**locals()))
315+
self._scheduler.create(name=self._job_id,
316+
image=image,
317+
command=self._command.format(**locals()),
318+
use_announcer=self._command_announceable())
313319

314320
@close_db_connections
315321
@transition(field=state,
316322
source=[CREATED, UP, DOWN],
317323
target=UP, crashed=DOWN)
318324
def start(self):
319-
self._scheduler.start(self._job_id)
325+
self._scheduler.start(self._job_id, self._command_announceable())
320326

321327
@close_db_connections
322328
@transition(field=state,
@@ -332,23 +338,26 @@ def deploy(self, release):
332338
new_job_id = self._job_id
333339
image = self.release.image
334340
c_type = self.type
335-
self._scheduler.create(new_job_id, image, self._command.format(**locals()))
336-
self._scheduler.start(new_job_id)
341+
self._scheduler.create(name=new_job_id,
342+
image=image,
343+
command=self._command.format(**locals()),
344+
use_announcer=self._command_announceable())
345+
self._scheduler.start(new_job_id, self._command_announceable())
337346
# destroy old container
338-
self._scheduler.destroy(old_job_id)
347+
self._scheduler.destroy(old_job_id, self._command_announceable())
339348

340349
@close_db_connections
341350
@transition(field=state, source=UP, target=DOWN)
342351
def stop(self):
343-
self._scheduler.stop(self._job_id)
352+
self._scheduler.stop(self._job_id, self._command_announceable())
344353

345354
@close_db_connections
346355
@transition(field=state,
347356
source=[INITIALIZED, CREATED, UP, DOWN],
348357
target=DESTROYED)
349358
def destroy(self):
350359
# TODO: add check for active connections before killing
351-
self._scheduler.destroy(self._job_id)
360+
self._scheduler.destroy(self._job_id, self._command_announceable())
352361

353362
@transition(field=state,
354363
source=[INITIALIZED, CREATED, DESTROYED],

controller/scheduler/coreos.py

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,17 @@ def tearDown(self):
4646
"""
4747
return
4848

49+
# announcer helpers
50+
51+
def _log_skipped_announcer(self, action, name):
52+
"""
53+
Logs a message stating that this operation doesn't require an announcer
54+
"""
55+
print "-- skipping announcer {} for {}".format(action, name)
56+
4957
# job api
5058

51-
def create(self, name, image, command='', template=None):
59+
def create(self, name, image, command='', template=None, use_announcer=True):
5260
"""
5361
Create a new job
5462
"""
@@ -57,11 +65,10 @@ def create(self, name, image, command='', template=None):
5765
self._create_container(name, image, command, template or CONTAINER_TEMPLATE, env)
5866
self._create_log(name, image, command, LOG_TEMPLATE, env)
5967

60-
# only announce web and cmd processes
61-
if command.lower() in ['start web', '']:
68+
if use_announcer:
6269
self._create_announcer(name, image, command, ANNOUNCE_TEMPLATE, env)
6370
else:
64-
print "-- skipping announcer for {} - cmd type is {}".format(name,command)
71+
self._log_skipped_announcer('create', name)
6572

6673
def _create_container(self, name, image, command, template, env):
6774
l = locals().copy()
@@ -87,16 +94,20 @@ def _create_log(self, name, image, command, template, env):
8794
return subprocess.check_call('fleetctl.sh submit {name}-log.service'.format(**locals()), # noqa
8895
shell=True, env=env)
8996

90-
def start(self, name):
97+
def start(self, name, use_announcer=True):
9198
"""
9299
Start an idle job
93100
"""
94101
print 'Starting {name}'.format(**locals())
95102
env = self.env.copy()
96103
self._start_container(name, env)
97104
self._start_log(name, env)
98-
self._start_announcer(name, env)
99-
self._wait_for_announcer(name, env)
105+
106+
if use_announcer:
107+
self._start_announcer(name, env)
108+
self._wait_for_announcer(name, env)
109+
else:
110+
self._log_skipped_announcer('start', name)
100111

101112
def _start_log(self, name, env):
102113
subprocess.check_call(
@@ -125,13 +136,18 @@ def _wait_for_announcer(self, name, env):
125136
else:
126137
raise RuntimeError('Container failed to start')
127138

128-
def stop(self, name):
139+
def stop(self, name, use_announcer=True):
129140
"""
130141
Stop a running job
131142
"""
132143
print 'Stopping {name}'.format(**locals())
133144
env = self.env.copy()
134-
self._stop_announcer(name, env)
145+
146+
if use_announcer:
147+
self._stop_announcer(name, env)
148+
else:
149+
self._log_skipped_announcer('stop', name)
150+
135151
self._stop_container(name, env)
136152
self._stop_log(name, env)
137153

@@ -150,13 +166,18 @@ def _stop_log(self, name, env):
150166
'fleetctl.sh stop -block-attempts=600 {name}-log.service'.format(**locals()),
151167
shell=True, env=env)
152168

153-
def destroy(self, name):
169+
def destroy(self, name, use_announcer=True):
154170
"""
155171
Destroy an existing job
156172
"""
157173
print 'Destroying {name}'.format(**locals())
158174
env = self.env.copy()
159-
self._destroy_announcer(name, env)
175+
176+
if use_announcer:
177+
self._destroy_announcer(name, env)
178+
else:
179+
self._log_skipped_announcer('destroy', name)
180+
160181
self._destroy_container(name, env)
161182
self._destroy_log(name, env)
162183

controller/scheduler/mock.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,25 @@ def tearDown(self):
2626

2727
# job api
2828

29-
def create(self, name, image, command):
29+
def create(self, name, image, command, use_announcer):
3030
"""
3131
Create a new job
3232
"""
3333
return {'state': 'inactive'}
3434

35-
def start(self, name):
35+
def start(self, name, use_announcer):
3636
"""
3737
Start an idle job
3838
"""
3939
return {'state': 'active'}
4040

41-
def stop(self, name):
41+
def stop(self, name, use_announcer):
4242
"""
4343
Stop a running job
4444
"""
4545
return {'state': 'inactive'}
4646

47-
def destroy(self, name):
47+
def destroy(self, name, use_announcer):
4848
"""
4949
Destroy an existing job
5050
"""

0 commit comments

Comments
 (0)