mirror of
https://github.com/kevingruesser/bootstrap-vz.git
synced 2025-08-22 18:00:35 +00:00
Add dockerfile to image, support labels, add documentation
This commit is contained in:
parent
7393d7cfb5
commit
5dada603eb
6 changed files with 122 additions and 1 deletions
53
bootstrapvz/providers/docker/README.rst
Normal file
53
bootstrapvz/providers/docker/README.rst
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
Docker
|
||||||
|
======
|
||||||
|
|
||||||
|
The `Docker <https://www.docker.com/>`__ 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 <https://docs.docker.com/engine/userguide/labels-custom-metadata/>`__
|
||||||
|
for more information about custom labels.
|
||||||
|
`Project atomic <http://www.projectatomic.io/>`__
|
||||||
|
also has some `useful recommendations <https://github.com/projectatomic/ContainerApplicationGenericLabels>`__
|
||||||
|
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}
|
|
@ -25,6 +25,8 @@ def resolve_tasks(taskset, manifest):
|
||||||
taskset.update(task_groups.cleanup_group)
|
taskset.update(task_groups.cleanup_group)
|
||||||
|
|
||||||
taskset.update([tasks.commands.AddRequiredCommands,
|
taskset.update([tasks.commands.AddRequiredCommands,
|
||||||
|
tasks.image.PopulateDockerfileLabels,
|
||||||
|
tasks.image.CreateDockerfile,
|
||||||
tasks.image.CreateImage,
|
tasks.image.CreateImage,
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,21 @@ properties:
|
||||||
type: string
|
type: string
|
||||||
tag:
|
tag:
|
||||||
type: string
|
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]
|
required: [repository, tag]
|
||||||
system:
|
system:
|
||||||
type: object
|
type: object
|
||||||
|
|
|
@ -3,16 +3,62 @@ from bootstrapvz.common import phases
|
||||||
from bootstrapvz.common.tools import log_check_call
|
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):
|
class CreateImage(Task):
|
||||||
description = 'Creating docker image'
|
description = 'Creating docker image'
|
||||||
phase = phases.image_registration
|
phase = phases.image_registration
|
||||||
|
predecessors = [CreateDockerfile]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls, info):
|
def run(cls, info):
|
||||||
from pipes import quote
|
from pipes import quote
|
||||||
tar_cmd = ['tar', '--create', '--numeric-owner',
|
tar_cmd = ['tar', '--create', '--numeric-owner',
|
||||||
'--directory', info.volume.path, '.']
|
'--directory', info.volume.path, '.']
|
||||||
docker_cmd = ['docker', 'import', '-',
|
docker_cmd = ['docker', 'import', '--change', info._docker['dockerfile'], '-',
|
||||||
info.manifest.provider['repository'] + ':' + info.manifest.provider['tag']]
|
info.manifest.provider['repository'] + ':' + info.manifest.provider['tag']]
|
||||||
cmd = ' '.join(map(quote, tar_cmd)) + ' | ' + ' '.join(map(quote, docker_cmd))
|
cmd = ' '.join(map(quote, tar_cmd)) + ' | ' + ' '.join(map(quote, docker_cmd))
|
||||||
[info._docker['container_id']] = log_check_call(cmd, shell=True)
|
[info._docker['container_id']] = log_check_call(cmd, shell=True)
|
||||||
|
|
|
@ -4,6 +4,10 @@ provider:
|
||||||
name: docker
|
name: docker
|
||||||
repository: bootstrap-vz
|
repository: bootstrap-vz
|
||||||
tag: latest
|
tag: latest
|
||||||
|
labels:
|
||||||
|
description: Debian {system.release} {system.architecture}
|
||||||
|
dockerfile: >
|
||||||
|
CMD /bin/bash
|
||||||
bootstrapper:
|
bootstrapper:
|
||||||
workspace: /target
|
workspace: /target
|
||||||
variant: minbase
|
variant: minbase
|
1
setup.py
1
setup.py
|
@ -25,6 +25,7 @@ setup(name='bootstrap-vz',
|
||||||
'pyyaml >= 3.10',
|
'pyyaml >= 3.10',
|
||||||
'boto >= 2.14.0',
|
'boto >= 2.14.0',
|
||||||
'docopt >= 0.6.1',
|
'docopt >= 0.6.1',
|
||||||
|
'pyrfc3339 >= 1.0',
|
||||||
],
|
],
|
||||||
license='Apache License, Version 2.0',
|
license='Apache License, Version 2.0',
|
||||||
description='Bootstrap Debian images for virtualized environments',
|
description='Bootstrap Debian images for virtualized environments',
|
||||||
|
|
Loading…
Add table
Reference in a new issue