Source code for invirtualenv_plugins.docker

import logging
import os
import subprocess
from jinja2 import Template
import pkg_resources
import shutil

from invirtualenv.plugin_base import InvirtualenvPlugin
from invirtualenv.utility import csv_list, str_to_dict, find_executable


logger = logging.getLogger(__name__)


DOCKERFILE_TEMPLATE = """FROM {{docker_container['base_image']|default('ubuntu:17.10')}}

{% if docker_container['workdir_start'] %}WORKDIR {{docker_container['workdir_start']}}
{% endif -%}
{% if docker_container['add'] or docker_container['files'] or docker_container['copy'] %}# Files
{% endif -%}
{%- if docker_container['add'] %}{% for file_line in docker_container['add'] %}ADD {{file_line}}
{% endfor %}{% endif -%}
{%- if docker_container['files'] %}{% for file_line in docker_container['files'] %}COPY {{file_line}}
{% endfor %}{% endif -%}
{%- if docker_container['copy'] %}{% for file_line in docker_container['copy'] %}COPY {{file_line}}
{% endfor %}{% endif -%}
{%- if docker_container['add'] or docker_container['files'] or docker_container['copy'] %}
{% endif -%}
{% if docker_container['setenv'] or docker_container['env'] %}# Environment Settings
{% endif -%}{% if docker_container['setenv'] %}{% for setting, value in docker_container['setenv'].items() %}ENV {{setting}}="{{value}}"
{% endfor %}{% endif -%}
{%- if docker_container['env'] %}{% for setting, value in docker_container['env'].items() %}ENV {{setting}}="{{value}}"
{% endfor %}{% endif -%}
{%- if docker_container['env'] or docker_container['setenv'] %}
{% endif -%}
{% if docker_container['expose'] %}# Ports
{% for expose_port in docker_container['expose'] %}EXPOSE {{expose_port}}
{% endfor %}{% endif -%}
{%- if docker_container['expose'] %}
{% endif -%}
{% if docker_container['label'] %}# Labels
{% for label in docker_container['label'] %}LABEL {{label}}
{% endfor %}{% endif -%}
{%- if docker_container['label'] %}
{% endif -%}
{%- if docker_container['volume'] %}# Volumes
{% for volume in docker_container['volume'] %}VOLUME {{volume}}
{% endfor %}{% endif -%}
{%- if docker_container['volume'] %}
{% endif -%}
{%- if docker_container['run_before'] %}# Pre Invirtulenv Commands
{% for runline in docker_container['run_before'] %}RUN {{runline}}
{% endfor %}{% endif -%}
{%- if docker_container['run_before'] %}
{% endif -%}
# Set up invirtualenv in the container
ENV PATH="/var/lib/invirtualenv/installvenv/bin:${PATH}"
COPY docker_build.sh /tmp/docker_build.sh
COPY deploy.conf /var/lib/invirtualenv/deploy.conf
RUN chmod 755 /tmp/docker_build.sh
RUN /tmp/docker_build.sh
RUN rm /tmp/docker_build.sh

{% if docker_container['run_after'] %}# Post Invirtualenv Commands
{% for runline in docker_container['run_after'] %}RUN {{runline}}
{% endfor %}{% endif -%}
{%- if docker_container['run_after'] %}
{% endif -%}

{% if docker_container['entrypoint'] %}ENTRYPOINT {{docker_container['entrypoint']}}
{% endif -%}
{% if docker_container['cmd'] %}CMD {{docker_container['cmd']}}
{% endif -%}
{% if docker_container['healthcheck'] %}HEALTHCHECK {{docker_container['healthcheck']}}
{% endif -%}
{% if docker_container['stopsignal'] %}STOPSIGNAL {{docker_container['stopsignal']}}
{% endif -%}
{% if docker_container['user'] %}USER {{docker_container['user']}}
{% endif -%}
"""

DOCKER_CONFIG_DEFAULT = """[docker_container]
add=
base_image=ubuntu:17.10
cmd=
container_name=
copy:
entrypoint=
env:
expose:
deb_deps:
files:
healthcheck=
label:
rpm_deps:
run_before:
run_after:
setenv:
stopsignal=
user=
volume:
workdir_start=
"""


[docs]class InvirtualenvDocker(InvirtualenvPlugin): package_formats = ['docker'] package_template = DOCKERFILE_TEMPLATE config_default = DOCKER_CONFIG_DEFAULT default_config_filename = 'Dockerfile.invirtualenv' config_types = { 'docker_container': { 'add': list, 'base_image': str, 'container_name': str, 'cmd': str, 'copy': list, 'deb_deps': list, 'entrypoint': str, 'env': str_to_dict, 'expose': list, 'files': list, 'healthcheck': str, 'label': list, 'rpm_deps': list, 'run_before': list, 'run_after': list, 'setenv': str_to_dict, 'stopsignal': str, 'user': str, 'volume': list, 'workdir_start': str, } }
[docs] def system_requirements_ok(self): if find_executable('docker'): return True logger.debug('The docker command is not present, disabling the rpm plugin') return False
[docs] def generate_wheel_archive(self, filename=None): # For docker containers we don't use wheels pass
[docs] def write_command_scripts(self): shutil.copyfile(pkg_resources.resource_filename(__name__, 'docker_scripts/docker_build.sh'), 'docker_build.sh')
[docs] def generate_wheel_packages(self, wheeldir): # For docker containers there is no need to generate and store wheels return {}
[docs] def run_package_command(self, package_hashes, wheel_dir='wheels'): logger.debug('Config') logger.debug(self.config) if not self.config['docker_container'].get('container_name', None): self.config['docker_container']['container_name'] = 'invirtualenvapp/' + self.config['global']['name'] self.config['docker_container']['files'].append('deploy.conf /var/lib/invirtualenv/deploy.conf') for package, hash in package_hashes.items(): source_filename = os.path.join(wheel_dir, package) dest_filename = '/var/lib/invirtualenv/wheels/{name}/{package}'.format(name=self.config['global']['name'], package=package) self.config['docker_container']['files'].append(source_filename + ' ' + dest_filename) self.write_command_scripts() logger.debug('Dockerfile') logger.debug(self.render_template_with_config()) with open('Dockerfile', 'w') as dockerfile_handle: dockerfile_handle.write(self.render_template_with_config()) container_tag = '{name}:{version}'.format(name=self.config['docker_container']['container_name'], version=self.config['global']['version']) command = [find_executable('docker'), 'build', '-t', container_tag, '.'] logger.debug('Running command %r', ' '.join(command)) subprocess.check_call(command) return container_tag