Skip to content

Commit 3056ae4

Browse files
committed
Add a no-build option to fig up, to save time when services were already freshly built.
Signed-off-by: Daniel Nephin <dnephin@gmail.com>
1 parent 5b777ee commit 3056ae4

File tree

5 files changed

+63
-24
lines changed

5 files changed

+63
-24
lines changed

fig/cli/main.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ def up(self, project, options):
425425
--no-color Produce monochrome output.
426426
--no-deps Don't start linked services.
427427
--no-recreate If containers already exist, don't recreate them.
428+
--no-build Don't build an image, even if it's missing
428429
"""
429430
insecure_registry = options['--allow-insecure-ssl']
430431
detached = options['-d']
@@ -440,7 +441,8 @@ def up(self, project, options):
440441
start_links=start_links,
441442
recreate=recreate,
442443
insecure_registry=insecure_registry,
443-
detach=options['-d']
444+
detach=options['-d'],
445+
do_build=not options['--no-build'],
444446
)
445447

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

fig/project.py

+15-3
Original file line numberDiff line numberDiff line change
@@ -167,14 +167,26 @@ 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, detach=False):
170+
def up(self,
171+
service_names=None,
172+
start_links=True,
173+
recreate=True,
174+
insecure_registry=False,
175+
detach=False,
176+
do_build=True):
171177
running_containers = []
172178
for service in self.get_services(service_names, include_links=start_links):
173179
if recreate:
174-
for (_, container) in service.recreate_containers(insecure_registry=insecure_registry, detach=detach):
180+
for (_, container) in service.recreate_containers(
181+
insecure_registry=insecure_registry,
182+
detach=detach,
183+
do_build=do_build):
175184
running_containers.append(container)
176185
else:
177-
for container in service.start_or_create_containers(insecure_registry=insecure_registry, detach=detach):
186+
for container in service.start_or_create_containers(
187+
insecure_registry=insecure_registry,
188+
detach=detach,
189+
do_build=do_build):
178190
running_containers.append(container)
179191

180192
return running_containers

fig/service.py

+14-6
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
'cap_add',
5555
'cap_drop',
5656
'dns',
57-
'dns_search',
57+
'dns_search',
5858
'env_file',
5959
'net',
6060
'privileged',
@@ -236,15 +236,18 @@ def create_container(self,
236236
return Container.create(self.client, **container_options)
237237
raise
238238

239-
def recreate_containers(self, insecure_registry=False, **override_options):
239+
def recreate_containers(self, insecure_registry=False, do_build=True, **override_options):
240240
"""
241241
If a container for this service doesn't exist, create and start one. If there are
242242
any, stop them, create+start new ones, and remove the old containers.
243243
"""
244244
containers = self.containers(stopped=True)
245245
if not containers:
246246
log.info("Creating %s..." % self._next_container_name(containers))
247-
container = self.create_container(insecure_registry=insecure_registry, **override_options)
247+
container = self.create_container(
248+
insecure_registry=insecure_registry,
249+
do_build=do_build,
250+
**override_options)
248251
self.start_container(container)
249252
return [(None, container)]
250253
else:
@@ -283,7 +286,7 @@ def recreate_container(self, container, **override_options):
283286
container.remove()
284287

285288
options = dict(override_options)
286-
new_container = self.create_container(**options)
289+
new_container = self.create_container(do_build=False, **options)
287290
self.start_container(new_container, intermediate_container=intermediate_container)
288291

289292
intermediate_container.remove()
@@ -330,14 +333,19 @@ def start_container(self, container, intermediate_container=None, **override_opt
330333
)
331334
return container
332335

333-
def start_or_create_containers(self, insecure_registry=False, detach=False):
336+
def start_or_create_containers(
337+
self,
338+
insecure_registry=False,
339+
detach=False,
340+
do_build=True):
334341
containers = self.containers(stopped=True)
335342

336343
if not containers:
337344
log.info("Creating %s..." % self._next_container_name(containers))
338345
new_container = self.create_container(
339346
insecure_registry=insecure_registry,
340-
detach=detach
347+
detach=detach,
348+
do_build=do_build,
341349
)
342350
return [self.start_container(new_container)]
343351
else:

tests/integration/service_test.py

+14-14
Original file line numberDiff line numberDiff line change
@@ -391,34 +391,34 @@ def test_dns_list(self):
391391

392392
def test_restart_always_value(self):
393393
service = self.create_service('web', restart='always')
394-
container = service.start_container().inspect()
395-
self.assertEqual(container['HostConfig']['RestartPolicy']['Name'], 'always')
394+
container = create_and_start_container(service)
395+
self.assertEqual(container.get('HostConfig.RestartPolicy.Name'), 'always')
396396

397397
def test_restart_on_failure_value(self):
398398
service = self.create_service('web', restart='on-failure:5')
399-
container = service.start_container().inspect()
400-
self.assertEqual(container['HostConfig']['RestartPolicy']['Name'], 'on-failure')
401-
self.assertEqual(container['HostConfig']['RestartPolicy']['MaximumRetryCount'], 5)
399+
container = create_and_start_container(service)
400+
self.assertEqual(container.get('HostConfig.RestartPolicy.Name'), 'on-failure')
401+
self.assertEqual(container.get('HostConfig.RestartPolicy.MaximumRetryCount'), 5)
402402

403403
def test_cap_add_list(self):
404404
service = self.create_service('web', cap_add=['SYS_ADMIN', 'NET_ADMIN'])
405-
container = service.start_container().inspect()
406-
self.assertEqual(container['HostConfig']['CapAdd'], ['SYS_ADMIN', 'NET_ADMIN'])
405+
container = create_and_start_container(service)
406+
self.assertEqual(container.get('HostConfig.CapAdd'), ['SYS_ADMIN', 'NET_ADMIN'])
407407

408408
def test_cap_drop_list(self):
409409
service = self.create_service('web', cap_drop=['SYS_ADMIN', 'NET_ADMIN'])
410-
container = service.start_container().inspect()
411-
self.assertEqual(container['HostConfig']['CapDrop'], ['SYS_ADMIN', 'NET_ADMIN'])
410+
container = create_and_start_container(service)
411+
self.assertEqual(container.get('HostConfig.CapDrop'), ['SYS_ADMIN', 'NET_ADMIN'])
412412

413413
def test_dns_search_single_value(self):
414414
service = self.create_service('web', dns_search='example.com')
415-
container = service.start_container().inspect()
416-
self.assertEqual(container['HostConfig']['DnsSearch'], ['example.com'])
415+
container = create_and_start_container(service)
416+
self.assertEqual(container.get('HostConfig.DnsSearch'), ['example.com'])
417417

418418
def test_dns_search_list(self):
419419
service = self.create_service('web', dns_search=['dc1.example.com', 'dc2.example.com'])
420-
container = service.start_container().inspect()
421-
self.assertEqual(container['HostConfig']['DnsSearch'], ['dc1.example.com', 'dc2.example.com'])
420+
container = create_and_start_container(service)
421+
self.assertEqual(container.get('HostConfig.DnsSearch'), ['dc1.example.com', 'dc2.example.com'])
422422

423423
def test_working_dir_param(self):
424424
service = self.create_service('container', working_dir='/working/dir/sample')
@@ -433,7 +433,7 @@ def test_split_env(self):
433433

434434
def test_env_from_file_combined_with_env(self):
435435
service = self.create_service('web', environment=['ONE=1', 'TWO=2', 'THREE=3'], env_file=['tests/fixtures/env/one.env', 'tests/fixtures/env/two.env'])
436-
env = service.start_container().environment
436+
env = create_and_start_container(service).environment
437437
for k,v in {'ONE': '1', 'TWO': '2', 'THREE': '3', 'FOO': 'baz', 'DOO': 'dah'}.iteritems():
438438
self.assertEqual(env[k], v)
439439

tests/unit/service_test.py

+17
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,23 @@ def test_latest_is_used_when_tag_is_not_specified(self):
228228
service.create_container()
229229
self.assertEqual(Container.create.call_args[1]['image'], 'someimage:latest')
230230

231+
def test_create_container_with_build(self):
232+
self.mock_client.images.return_value = []
233+
service = Service('foo', client=self.mock_client, build='.')
234+
service.build = mock.create_autospec(service.build)
235+
service.create_container(do_build=True)
236+
237+
self.mock_client.images.assert_called_once_with(name=service.full_name)
238+
service.build.assert_called_once_with()
239+
240+
def test_create_container_no_build(self):
241+
self.mock_client.images.return_value = []
242+
service = Service('foo', client=self.mock_client, build='.')
243+
service.create_container(do_build=False)
244+
245+
self.assertFalse(self.mock_client.images.called)
246+
self.assertFalse(self.mock_client.build.called)
247+
231248

232249
class ServiceVolumesTest(unittest.TestCase):
233250

0 commit comments

Comments
 (0)