Browse Source

Add support for building images

Ben Firshman 12 years ago
parent
commit
88b04aaa9c
3 changed files with 29 additions and 6 deletions
  1. 17 6
      plum/service.py
  2. 2 0
      plum/tests/fixtures/simple-dockerfile/Dockerfile
  3. 10 0
      plum/tests/service_test.py

+ 17 - 6
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):

+ 2 - 0
plum/tests/fixtures/simple-dockerfile/Dockerfile

@@ -0,0 +1,2 @@
+FROM ubuntu
+CMD echo "success"

+ 10 - 0
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))
+