diff --git a/bootstrapvz/providers/docker/README.rst b/bootstrapvz/providers/docker/README.rst
new file mode 100644
index 0000000..155ebf9
--- /dev/null
+++ b/bootstrapvz/providers/docker/README.rst
@@ -0,0 +1,53 @@
+Docker
+======
+
+The `Docker `__ provider creates a docker image
+from scratch, creates a Dockerfile for it and imports the image to a repo
+specified in the manifest.
+
+In order to reduce the size of the image, it is highly recommend
+to make use of the `minimize_size <../../plugins/minimize_size>`__ plugin.
+With optimal settings a 64-bit jessie image can be whittled down to 81.95 MB
+(built on Dec 13th 2015 with ``manifests/examples/docker/minimized-jessie.yml``).
+
+
+Manifest settings
+-----------------
+
+Provider
+~~~~~~~~
+
+- ``repository``: Repository to which the image should be imported.
+ ``required``
+
+- ``tag``: Name with which the image should be tagged.
+ ``required``
+
+- ``dockerfile``: Inline dockerfile that should be appended to
+ the one created by the bootstrapper.
+ ``optional``
+
+- ``labels``: Labels that should be added to the dockerfile.
+ The image name specified at the top of the manifest
+ will be added as the label ``name``.
+ Check out the `docker docs `__
+ for more information about custom labels.
+ `Project atomic `__
+ also has some `useful recommendations `__
+ for generic container labels.
+ ``optional``
+ ``manifest vars``
+
+Example:
+
+.. code:: yaml
+
+ ---
+ provider:
+ name: docker
+ repository: bootstrap-vz
+ tag: latest
+ dockerfile: >
+ CMD /bin/bash
+ labels:
+ description: Debian {system.release} {system.architecture}
diff --git a/bootstrapvz/providers/docker/__init__.py b/bootstrapvz/providers/docker/__init__.py
index a02eede..452c1fd 100644
--- a/bootstrapvz/providers/docker/__init__.py
+++ b/bootstrapvz/providers/docker/__init__.py
@@ -25,6 +25,8 @@ def resolve_tasks(taskset, manifest):
taskset.update(task_groups.cleanup_group)
taskset.update([tasks.commands.AddRequiredCommands,
+ tasks.image.PopulateDockerfileLabels,
+ tasks.image.CreateDockerfile,
tasks.image.CreateImage,
])
diff --git a/bootstrapvz/providers/docker/manifest-schema.yml b/bootstrapvz/providers/docker/manifest-schema.yml
index d0f8140..dd50ff6 100644
--- a/bootstrapvz/providers/docker/manifest-schema.yml
+++ b/bootstrapvz/providers/docker/manifest-schema.yml
@@ -10,6 +10,21 @@ properties:
type: string
tag:
type: string
+ labels:
+ type: object
+ properties:
+ # https://github.com/projectatomic/ContainerApplicationGenericLabels
+ distribution-scope:
+ type: string
+ enum:
+ - private
+ - authoritative-source-only
+ - restricted
+ - public
+ patternProperties:
+ ^.+$: {type: string}
+ dockerfile:
+ type: string
required: [repository, tag]
system:
type: object
diff --git a/bootstrapvz/providers/docker/tasks/image.py b/bootstrapvz/providers/docker/tasks/image.py
index 0b074bb..2ce99b9 100644
--- a/bootstrapvz/providers/docker/tasks/image.py
+++ b/bootstrapvz/providers/docker/tasks/image.py
@@ -3,16 +3,62 @@ from bootstrapvz.common import phases
from bootstrapvz.common.tools import log_check_call
+class PopulateDockerfileLabels(Task):
+ description = 'Populating dockerfile labels'
+ phase = phases.image_registration
+
+ @classmethod
+ def run(cls, info):
+ import pyrfc3339
+ from datetime import datetime
+ import pytz
+ labels = {}
+ labels['name'] = info.manifest.name.format(**info.manifest_vars)
+ # Inspired by https://github.com/projectatomic/ContainerApplicationGenericLabels
+ # See here for the discussion on the debian-cloud mailing list
+ # https://lists.debian.org/debian-cloud/2015/05/msg00071.html
+ labels['architecture'] = info.manifest.system['architecture']
+ labels['build-date'] = pyrfc3339.generate(datetime.utcnow().replace(tzinfo=pytz.utc))
+ if 'labels' in info.manifest.provider:
+ for label, value in info.manifest.provider['labels'].items():
+ labels[label] = value.format(**info.manifest_vars)
+ info._docker['dockerfile_labels'] = labels
+
+
+class CreateDockerfile(Task):
+ description = 'Creating dockerfile'
+ phase = phases.image_registration
+ predecessors = [PopulateDockerfileLabels]
+
+ @classmethod
+ def run(cls, info):
+ # pipes.quote converts newlines into \n rather than just prefixing
+ # it with a backslash, so we need to escape manually
+ def escape(value):
+ value = value.replace('"', '\\"')
+ value = value.replace('\n', '\\\n')
+ value = '"' + value + '"'
+ return value
+ labels = []
+ for label, value in info._docker['dockerfile_labels'].items():
+ labels.append(label + '=' + escape(value))
+ # Add some nice newlines and indentation
+ info._docker['dockerfile'] = 'LABEL ' + ' \\\n '.join(labels) + '\n'
+ if 'dockerfile' in info.manifest.provider:
+ info._docker['dockerfile'] += info.manifest.provider['dockerfile'] + '\n'
+
+
class CreateImage(Task):
description = 'Creating docker image'
phase = phases.image_registration
+ predecessors = [CreateDockerfile]
@classmethod
def run(cls, info):
from pipes import quote
tar_cmd = ['tar', '--create', '--numeric-owner',
'--directory', info.volume.path, '.']
- docker_cmd = ['docker', 'import', '-',
+ docker_cmd = ['docker', 'import', '--change', info._docker['dockerfile'], '-',
info.manifest.provider['repository'] + ':' + info.manifest.provider['tag']]
cmd = ' '.join(map(quote, tar_cmd)) + ' | ' + ' '.join(map(quote, docker_cmd))
[info._docker['container_id']] = log_check_call(cmd, shell=True)
diff --git a/manifests/examples/docker/jessie.yml b/manifests/examples/docker/minimized-jessie.yml
similarity index 85%
rename from manifests/examples/docker/jessie.yml
rename to manifests/examples/docker/minimized-jessie.yml
index b383766..71be5da 100644
--- a/manifests/examples/docker/jessie.yml
+++ b/manifests/examples/docker/minimized-jessie.yml
@@ -4,6 +4,10 @@ provider:
name: docker
repository: bootstrap-vz
tag: latest
+ labels:
+ description: Debian {system.release} {system.architecture}
+ dockerfile: >
+ CMD /bin/bash
bootstrapper:
workspace: /target
variant: minbase
diff --git a/setup.py b/setup.py
index a0e4854..829388c 100644
--- a/setup.py
+++ b/setup.py
@@ -25,6 +25,7 @@ setup(name='bootstrap-vz',
'pyyaml >= 3.10',
'boto >= 2.14.0',
'docopt >= 0.6.1',
+ 'pyrfc3339 >= 1.0',
],
license='Apache License, Version 2.0',
description='Bootstrap Debian images for virtualized environments',