From 88b04aaa9c56fe26dfdfe31d49450dc0947a1c5d Mon Sep 17 00:00:00 2001 From: Ben Firshman Date: Fri, 13 Dec 2013 20:36:10 +0000 Subject: [PATCH] Add support for building images --- plum/service.py | 23 ++++++++++++++----- .../fixtures/simple-dockerfile/Dockerfile | 2 ++ plum/tests/service_test.py | 10 ++++++++ 3 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 plum/tests/fixtures/simple-dockerfile/Dockerfile diff --git a/plum/service.py b/plum/service.py index 254bc9d999..3bcbdb2bac 100644 --- a/plum/service.py +++ b/plum/service.py @@ -5,6 +5,8 @@ class Service(object): def __init__(self, name, client=None, links=[], **options): if not re.match('^[a-zA-Z0-9_]+$', name): raise ValueError('Invalid name: %s' % name) + if 'image' in options and 'build' in options: + raise ValueError('Service %s has both an image and build path specified. A service can either be built to image or use an existing image, not both.') self.name = name self.client = client @@ -17,7 +19,7 @@ class Service(object): def start(self): if len(self.containers) == 0: - self.start_container() + return self.start_container() def stop(self): self.scale(0) @@ -30,15 +32,12 @@ class Service(object): self.stop_container() def start_container(self, **override_options): - options = dict(self.options) - options.update(override_options) - number = self.next_container_number() - name = make_name(self.name, number) - container = self.client.create_container(name=name, **options) + container = self.client.create_container(**self._get_container_options(override_options)) self.client.start( container['Id'], links=self._get_links(), ) + return container['Id'] def stop_container(self): self.client.kill(self.containers[0]['Id']) @@ -64,6 +63,18 @@ class Service(object): links[name] = name return links + def _get_container_options(self, override_options): + keys = ['image', 'command', 'hostname', 'user', 'detach', 'stdin_open', 'tty', 'mem_limit', 'ports', 'environment', 'dns', 'volumes', 'volumes_from'] + container_options = dict((k, self.options[k]) for k in keys if k in self.options) + container_options.update(override_options) + + number = self.next_container_number() + container_options['name'] = make_name(self.name, number) + + if 'build' in self.options: + container_options['image'] = self.client.build(self.options['build'])[0] + + return container_options def make_name(prefix, number): diff --git a/plum/tests/fixtures/simple-dockerfile/Dockerfile b/plum/tests/fixtures/simple-dockerfile/Dockerfile new file mode 100644 index 0000000000..b7fd870f05 --- /dev/null +++ b/plum/tests/fixtures/simple-dockerfile/Dockerfile @@ -0,0 +1,2 @@ +FROM ubuntu +CMD echo "success" diff --git a/plum/tests/service_test.py b/plum/tests/service_test.py index ed2c3db784..571e0efbff 100644 --- a/plum/tests/service_test.py +++ b/plum/tests/service_test.py @@ -78,4 +78,14 @@ class NameTestCase(DockerClientTestCase): db.stop() web.stop() + def test_start_container_builds_images(self): + service = Service( + name='test', + client=self.client, + build='plum/tests/fixtures/simple-dockerfile', + ) + container = service.start() + self.client.wait(container) + self.assertIn('success', self.client.logs(container)) +