Skip to content
This repository was archived by the owner on Apr 18, 2018. It is now read-only.

Commit 391a676

Browse files
committed
Merge pull request #7 from dnephin/speed_up_fig_up
Speed up fig up
2 parents 2c2fccc + 2f80545 commit 391a676

File tree

5 files changed

+148
-80
lines changed

5 files changed

+148
-80
lines changed

fig/cli/main.py

+2
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ def up(self, project, options):
417417
--no-color Produce monochrome output.
418418
--no-deps Don't start linked services.
419419
--no-recreate If containers already exist, don't recreate them.
420+
--no-build Don't build an image if it's missing
420421
"""
421422
insecure_registry = options['--allow-insecure-ssl']
422423
detached = options['-d']
@@ -432,6 +433,7 @@ def up(self, project, options):
432433
start_links=start_links,
433434
recreate=recreate,
434435
insecure_registry=insecure_registry,
436+
do_build=not options['--no-build'],
435437
)
436438

437439
to_attach = [c for s in project.get_services(service_names) for c in s.containers()]

fig/project.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -167,14 +167,23 @@ def build(self, service_names=None, no_cache=False):
167167
else:
168168
log.info('%s uses an image, skipping' % service.name)
169169

170-
def up(self, service_names=None, start_links=True, recreate=True, insecure_registry=False):
170+
def up(self,
171+
service_names=None,
172+
start_links=True,
173+
recreate=True,
174+
insecure_registry=False,
175+
do_build=True):
171176
running_containers = []
172177
for service in self.get_services(service_names, include_links=start_links):
173178
if recreate:
174-
for (_, container) in service.recreate_containers(insecure_registry=insecure_registry):
179+
for (_, container) in service.recreate_containers(
180+
insecure_registry=insecure_registry,
181+
do_build=do_build):
175182
running_containers.append(container)
176183
else:
177-
for container in service.start_or_create_containers(insecure_registry=insecure_registry):
184+
for container in service.start_or_create_containers(
185+
insecure_registry=insecure_registry,
186+
do_build=do_build):
178187
running_containers.append(container)
179188

180189
return running_containers

fig/service.py

+44-19
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@
4949
'workdir' : 'working_dir',
5050
}
5151

52+
DOCKER_START_KEYS = [
53+
'cap_add',
54+
'cap_drop',
55+
'dns',
56+
'env_file',
57+
'net',
58+
'privileged',
59+
'restart',
60+
]
61+
5262
VALID_NAME_CHARS = '[a-zA-Z0-9]'
5363

5464

@@ -144,7 +154,8 @@ def restart(self, **options):
144154

145155
def scale(self, desired_num):
146156
"""
147-
Adjusts the number of containers to the specified number and ensures they are running.
157+
Adjusts the number of containers to the specified number and ensures
158+
they are running.
148159
149160
- creates containers until there are at least `desired_num`
150161
- stops containers until there are at most `desired_num` running
@@ -191,12 +202,24 @@ def remove_stopped(self, **options):
191202
log.info("Removing %s..." % c.name)
192203
c.remove(**options)
193204

194-
def create_container(self, one_off=False, insecure_registry=False, **override_options):
205+
def create_container(self,
206+
one_off=False,
207+
insecure_registry=False,
208+
do_build=True,
209+
**override_options):
195210
"""
196211
Create a container for this service. If the image doesn't exist, attempt to pull
197212
it.
198213
"""
199-
container_options = self._get_container_create_options(override_options, one_off=one_off)
214+
container_options = self._get_container_create_options(
215+
override_options,
216+
one_off=one_off)
217+
218+
if (do_build and
219+
self.can_be_built() and
220+
not self.client.images(name=self.full_name)):
221+
self.build()
222+
200223
try:
201224
return Container.create(self.client, **container_options)
202225
except APIError as e:
@@ -211,15 +234,18 @@ def create_container(self, one_off=False, insecure_registry=False, **override_op
211234
return Container.create(self.client, **container_options)
212235
raise
213236

214-
def recreate_containers(self, insecure_registry=False, **override_options):
237+
def recreate_containers(self, insecure_registry=False, do_build=True, **override_options):
215238
"""
216239
If a container for this service doesn't exist, create and start one. If there are
217240
any, stop them, create+start new ones, and remove the old containers.
218241
"""
219242
containers = self.containers(stopped=True)
220243
if not containers:
221244
log.info("Creating %s..." % self._next_container_name(containers))
222-
container = self.create_container(insecure_registry=insecure_registry, **override_options)
245+
container = self.create_container(
246+
insecure_registry=insecure_registry,
247+
do_build=do_build,
248+
**override_options)
223249
self.start_container(container)
224250
return [(None, container)]
225251
else:
@@ -257,7 +283,7 @@ def recreate_container(self, container, **override_options):
257283
container.remove()
258284

259285
options = dict(override_options)
260-
new_container = self.create_container(**options)
286+
new_container = self.create_container(do_build=False, **options)
261287
self.start_container(new_container, intermediate_container=intermediate_container)
262288

263289
intermediate_container.remove()
@@ -271,8 +297,7 @@ def start_container_if_stopped(self, container, **options):
271297
log.info("Starting %s..." % container.name)
272298
return self.start_container(container, **options)
273299

274-
def start_container(self, container=None, intermediate_container=None, **override_options):
275-
container = container or self.create_container(**override_options)
300+
def start_container(self, container, intermediate_container=None, **override_options):
276301
options = dict(self.options, **override_options)
277302
port_bindings = build_port_bindings(options.get('ports') or [])
278303

@@ -303,12 +328,14 @@ def start_container(self, container=None, intermediate_container=None, **overrid
303328
)
304329
return container
305330

306-
def start_or_create_containers(self, insecure_registry=False):
331+
def start_or_create_containers(self, insecure_registry=False, do_build=True):
307332
containers = self.containers(stopped=True)
308333

309334
if not containers:
310335
log.info("Creating %s..." % self._next_container_name(containers))
311-
new_container = self.create_container(insecure_registry=insecure_registry)
336+
new_container = self.create_container(
337+
insecure_registry=insecure_registry,
338+
do_build=do_build)
312339
return [self.start_container(new_container)]
313340
else:
314341
return [self.start_container_if_stopped(c) for c in containers]
@@ -400,14 +427,11 @@ def _get_container_create_options(self, override_options, one_off=False):
400427
container_options['environment'] = merge_environment(container_options)
401428

402429
if self.can_be_built():
403-
if len(self.client.images(name=self._build_tag_name())) == 0:
404-
self.build()
405-
container_options['image'] = self._build_tag_name()
430+
container_options['image'] = self.full_name
406431

407432
# Delete options which are only used when starting
408-
for key in ['privileged', 'net', 'dns', 'restart', 'cap_add', 'cap_drop', 'env_file']:
409-
if key in container_options:
410-
del container_options[key]
433+
for key in DOCKER_START_KEYS:
434+
container_options.pop(key, None)
411435

412436
return container_options
413437

@@ -416,7 +440,7 @@ def build(self, no_cache=False):
416440

417441
build_output = self.client.build(
418442
self.options['build'],
419-
tag=self._build_tag_name(),
443+
tag=self.full_name,
420444
stream=True,
421445
rm=True,
422446
nocache=no_cache,
@@ -436,14 +460,15 @@ def build(self, no_cache=False):
436460
image_id = match.group(1)
437461

438462
if image_id is None:
439-
raise BuildError(self)
463+
raise BuildError(self, event if all_events else 'Unknown')
440464

441465
return image_id
442466

443467
def can_be_built(self):
444468
return 'build' in self.options
445469

446-
def _build_tag_name(self):
470+
@property
471+
def full_name(self):
447472
"""
448473
The tag to give to images built for this service.
449474
"""

0 commit comments

Comments
 (0)