From c6c9cb77ea201ee79b5c2d0179475d6f9d62ad01 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sep 28 2017 11:23:37 +0000 Subject: Issue #55: Narrow scope of project - remove container related features - focus specifically on modulemd generation --- diff --git a/Pipfile.lock b/Pipfile.lock index aecbada..bf60840 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -46,13 +46,6 @@ ], "version": "==3.0.4" }, - "dockerfile-parse": { - "hashes": [ - "sha256:6a739e5a69443383aab2dcdd5b1d55e99735a6345f9175c56f8becfed188cc7f", - "sha256:50a38c49f0f0c4d6fcb911fdaa2f22c064ab8c6365093a9f470e78be6e393423" - ], - "version": "==0.0.7" - }, "fedmod": { "editable": true, "path": "." diff --git a/README.md b/README.md index 6907e90..e171558 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,28 @@ -# Modularity-tools +# fedmod modularity tools + +fedmod provides tools for working with Fedora's modulemd metadata format +that aren't related to actually building them (for build commands, see +fedpkg and mbs-build). + +Currently, this consists of: + +* `fedmod rpm2module`: generates a draft modulemd file based on existing RPM + name. + +## Project status + +`fedmod` is pre-release software originally written to work with the F26 Boltron +prototype, and doesn't currently pass its own self tests without appropriate +prior configuration of the test system. + +It's in the process of being updated to have a clearer development focus, +and to work with the native modularity metadata provided in Fedora 27. + +## Modulemd creation + +`fedmod rpm2module` creates a modulemd file from the given package names. +Output is written as `modulemd-output.yaml` when multiple packages are given +as input, and `.yaml` when a single package is given. ## Local development @@ -10,11 +34,9 @@ The currently preferred means of installation is local installation with pip. This will pull in the required Python level dependencies from PyPI. -Some tests aren't currently available from PyPI, and will need to be installed -system-wide (exact list TBD). - -Note that the CLI name, the distribution package name, and the import package -name are all currently still subject to revision: https://pagure.io/modularity/modularity-tools/issue/49 +Some dependencies aren't currently available from PyPI, and will need to be +installed system-wide (exact list TBD, but includes at least dnf and libsolv's +Python bindings). ### How to run tests @@ -22,9 +44,14 @@ To start a shell that's correctly configured to run the tests with the library and all necessary dependencies installed: $ pipenv --three --site-packages - $ pipenv install --dev + $ PIP_IGNORE_INSTALLED=1 pipenv install --dev $ pipenv shell +The `PIP_IGNORE_INSTALLED=1` setting means that everything available to `pip` +will be installed into the virtual environment based on `Pipfile.lock`, and only +components that aren't installable with `pip` will be used from the system +Python installation. + The tests can then be run in the launched subshell with: $ pytest tests @@ -37,53 +64,7 @@ To see the Python level dependencies graph: $ pew toggleglobalsitepackages $ pipenv graph + $ pew toggleglobalsitepackages (If you don't turn off global site-packages access first, you'll get the -dependency graph of all the system Python components as well) - - -## modtools docker2openshift - -The tool is used for generation OpenShift template from Dockerfile and from [https://github.com/container-images/container-image-template/blob/master/openshift-template.yml](openshift-template.yml) already prepared by Modularity team. -As Dockerfile as openshift-template.yml have to exist in the directory. - -### How to use modtools docker2openshift -Run the command with following parameters: - - `./modtools docker2openshift --dockerfile IMAGENAME` - - where parameters mean: - * dockerfile ... means full path to Dockerfile - * IMAGENAME ... means image name in register. Can be taken from command `docker images` or from some other registry. - -The output of **modtools docker2openshift** command is OpenShift template stored in temporary directory - -Example usage: -```bash - ./modtools docker2openshift --dockerfile path/to/Dockerfile image/repository/url -/path/to/Dockerfile - OpenShift template is generated here: /tmp/tmpM0teUC/openshift-template.yml -``` - -## modtools module2dockerfile - -The tool exists to ease creation of module related Dockerfiles. It pre-filles -the information from modulemd file, but be aware, the generated Dockerfile -needs to be manualy extended by other info (configuration, volumes, etc.). - -### How to use modtools module2dockerfile -Run the command with following parameters: -```bash -./modtools module2dockerfile --template MODULEMD_FILE -``` - where parameters mean: - * template - base for Dockerfile, if you don't want otherwise use this file: https://github.com/container-images/container-image-template/blob/master/Dockerfile.template - * modulemd.yaml - path to the modulemd file - - -## Modulemd creation - -modtools rpm2module script creates modulemd file from package names. Output is written in modulemd-output.yaml -file (multiple packages as input) or in file named after package name (single package as input). - -Please make sure you have latest module-build-service and dnf installed before running. +dependency graph of all the installed system Python components as well) diff --git a/fedmod/cli.py b/fedmod/cli.py index fb5c333..4f6259a 100644 --- a/fedmod/cli.py +++ b/fedmod/cli.py @@ -3,9 +3,6 @@ import argparse import logging from .module_generator import ModuleGenerator -from .oc_template import OpenShiftTemplateGenerator -from .mod2dockerfile import ModulemdDockerfileGenerator - class ModtoolsCLI(object): """ Class for processing data from commandline """ @@ -35,46 +32,6 @@ class ModtoolsCLI(object): help="Specify list of packages for module.", ) - parser_docker2openshift = subparsers.add_parser( - "docker2openshift", parents=[base_parser], - help="Generates openshift template from dockerfile", - description="Creates an OpenShift template YAML file.", - ) - - parser_docker2openshift.add_argument( - "image", - metavar='IMAGE', - help="docker image name (like NAME or docker.io/USER/NAME)", - ) - parser_docker2openshift.add_argument( - "--dockerfile", - help="Specify Dockerfile name. Default is Dockerfile." - ) - - parser_module2dockerfile = subparsers.add_parser( - 'module2dockerfile', parents=[base_parser], - help="Generates dockerfile from modulemd file", - description="Creates Dockerfile with suggestions and pre-filled values" - ) - - parser_module2dockerfile.add_argument( - "modulemd_file", - metavar='MODULEMD_FILE', - help='Specify path to modulemd file' - ) - - parser_module2dockerfile.add_argument( - "--output", - nargs='?', - help='Specify custom output file.' - ) - - parser_module2dockerfile.add_argument( - "--template", - help='Specify custom Dockerfile template', - required=True - ) - return parser def __init__(self, args=None): @@ -100,14 +57,6 @@ class ModtoolsCLIHelper(object): mg = ModuleGenerator(cli.args.pkgs) mg.run() - if cli.args.cmd_name == 'docker2openshift': - otg = OpenShiftTemplateGenerator(cli.args) - otg.run() - - if cli.args.cmd_name == 'module2dockerfile': - mtd = ModulemdDockerfileGenerator(cli.args) - mtd.run() - except KeyboardInterrupt: print('\nInterrupted by user') except Exception as e: diff --git a/fedmod/mod2dockerfile.py b/fedmod/mod2dockerfile.py deleted file mode 100644 index dafee67..0000000 --- a/fedmod/mod2dockerfile.py +++ /dev/null @@ -1,49 +0,0 @@ -import modulemd -import os -import tempfile -import shutil -from string import Template - - -class PercentTemplate(Template): - delimiter = '%%' - - -class ModulemdDockerfileGenerator(object): - - def __init__(self, args=None): - self.dockerfile_path = args.output - self.modulemd_path = args.modulemd_file - self.template_path=args.template - - def load_modulemd(self): - self.mmd = modulemd.ModuleMetadata() - self.mmd.load(self.modulemd_path) - - self.values = {'NAME': self.mmd.name,'VERSION': self.mmd.version, - 'DESCRIPTION': self.mmd.description, 'SUMMARY': self.mmd.summary, - 'API_PACKAGES': ' '.join(self.mmd.api.rpms)} - - def generate_dockerfile(self): - tmplFile = open(self.template_path) - tmpl = PercentTemplate(tmplFile.read()) - self.result = tmpl.safe_substitute(self.values) - - def save_result(self): - if self.dockerfile_path is not None: - output_file = self.dockerfile_path - else: - tmp_dir = tempfile.mkdtemp() - if os.path.isdir(tmp_dir): - shutil.rmtree(tmp_dir) - os.makedirs(tmp_dir) - output_file = os.path.join(tmp_dir, os.path.basename('Dockerfile')) - - with open(output_file, 'w') as f: - f.write(self.result) - print("Modulemd template is generated here: %s" % (output_file)) - - def run(self): - self.load_modulemd() - self.generate_dockerfile() - self.save_result() diff --git a/fedmod/oc_template.py b/fedmod/oc_template.py deleted file mode 100644 index 10b803e..0000000 --- a/fedmod/oc_template.py +++ /dev/null @@ -1,335 +0,0 @@ -from __future__ import absolute_import, print_function - -import os -import ast -import yaml -import tempfile -import shutil -import re -import shlex - -from dockerfile_parse import DockerfileParser - -# Dockerfile path -DOCKERFILE = "Dockerfile" - -EXPOSE = "EXPOSE" -VOLUME = "VOLUME" -LABEL = "LABEL" -ENV = "ENV" -PORTS = "PORTS" - -# OpenShift template -OPENSHIFT_TEMPLATE = "openshift-template.yml" - - -def get_string(value): - return ast.literal_eval(value) - - -class OpenShiftTemplateGenerator(object): - """ - Class generates an OpenShift template - It requires openshift-template.yml file. - """ - - dockerfile = None - oc_template = None - docker_dict = {} - - def __init__(self, args=None, dir_name=None): - if dir_name is None: - self.dir = os.getcwd() - else: - self.dir = dir_name - self.docker_image = args.image - if args.dockerfile is None: - self.dockerfile = 'Dockerfile' - else: - self.dockerfile = os.path.join(self.dir, args.dockerfile) - self.docker_dict = {} - - def _exist_docker_file(self): - """ - Function checks if docker file exists - :return: True if exists - """ - if not os.path.exists(self.dockerfile): - print("Dockerfile has to exists in the %s directory." % self.dir) - return False - return True - - def _exist_openshift_template(self): - """ - Function checks if openshift template exists - :return: True if exists - """ - if self.oc_template is None: - print("%s has to exists in the %s directory." % (OPENSHIFT_TEMPLATE, self.dir)) - return False - return True - - def _get_openshift_template(self): - """ - Function sets openshift template. - """ - for f in os.listdir(self.dir): - if os.path.isdir(os.path.join(self.dir, f)): - continue - file_name = os.path.join(self.dir, f) - if f == OPENSHIFT_TEMPLATE: - self.oc_template = file_name - - def _get_expose(self, value): - """Function returns exposes as field""" - return value.split() - - def _get_env(self, value): - """Function gets env as field""" - return shlex.split(value) - - def _get_volume(self, value): - """Function evaluates a value and returns as string.""" - return get_string(value) - - def _get_label(self, value): - """ - Function returns label from Docker file - except INSTALL, UNINSTALL and RUN label used by atomic. - :param value: row from Dockerfile - :return: label_dict - """ - untracked_values = ['INSTALL', 'UNINSTALL', 'RUN'] - if [f for f in untracked_values if value.startswith(f)]: - return None - labels = re.sub('\s\s+', ';', value).split(';') - labels = [l.replace('"', '') for l in labels] - label_dict = {} - for l in labels: - if len(l.split('=')) == 2: - label_dict[l.split('=')[0]] = l.split('=')[1] - elif re.match('maintainer', l, re.I): - label_dict['maintainer'] = l.split(' ',1)[1] - else: - raise ValueError("Unrecogised label: ", l) - return label_dict - - def _get_docker_tags(self): - """ - Function analyses dockerfile and extracts - ENV, VOLUME, EXPOSE and LABEL directives. - """ - if not self._exist_docker_file(): - return - tmp_dir = tempfile.mkdtemp() - if os.path.isdir(tmp_dir): - shutil.rmtree(tmp_dir) - os.makedirs(tmp_dir) - shutil.copyfile(self.dockerfile, os.path.join(tmp_dir, "Dockerfile")) - dfp = DockerfileParser(path=tmp_dir) - inst = "instruction" - allowed_tags = [ENV, EXPOSE, VOLUME, LABEL] - functions = {ENV: self._get_env, - EXPOSE: self._get_expose, - VOLUME: self._get_volume, - LABEL: self._get_label} - - for struct in dfp.structure: - key = struct[inst] - val = struct["value"] - if key in allowed_tags: - if key == LABEL: - if key not in self.docker_dict: - self.docker_dict[key] = {} - value = functions[key](val) - if value is not None: - self.docker_dict[key].update(value) - else: - if key not in self.docker_dict: - self.docker_dict[key] = [] - ret_val = functions[key](val) - for v in ret_val: - if v not in self.docker_dict[key]: - self.docker_dict[key].append(v) - - shutil.rmtree(tmp_dir) - - def _load_oc_template(self): - """ - Function loads openshift template - :return: YAML dictionary - """ - if not self._exist_openshift_template(): - return None - with open(self.oc_template, 'r') as f: - try: - templ = yaml.load(f) - except yaml.YAMLError as exc: - print(exc) - raise - return templ - - def _get_labels(self, templ): - labels = None - try: - labels = templ['metadata']['labels'] - except KeyError: - labels = {} - raise_exception = False - try: - labels['description'] = self.docker_dict[LABEL]['description'] - except KeyError: - print("Label Description is missing in Dockerfile. It is mandatory.") - raise_exception = True - try: - labels['tags'] = self.docker_dict[LABEL]['io.openshift.tags'] - except KeyError: - print('Label tags is missing in Dockerfile. It is mandatory.') - raise_exception = True - if raise_exception: - raise KeyError - labels['template'] = self.docker_image - return labels - - def _get_docker_labels(self): - """ - Function returns docker labels - :return: label dictionary - """ - if LABEL in self.docker_dict and self.docker_dict[LABEL]: - return self.docker_dict[LABEL] - return None - - def _get_docker_volumes(self): - """ - Function returns docker volumes and labels - :return: volume list, volume names - """ - volume_list = [] - volume_names = [] - if VOLUME in self.docker_dict and self.docker_dict[VOLUME]: - for p in self.docker_dict[VOLUME]: - volume_list.append({'mountPath': p, - 'name': 'name' + p.replace('/', '-')}) - volume_names.append({'name': 'name' + p.replace('/', '-'), - 'emptyDir': {} - }) - return volume_list, volume_names - - def _get_docker_env(self): - """ - Function return docker ENV directives - :return: list of ENV variables - """ - env_list = [] - if ENV in self.docker_dict and self.docker_dict[ENV]: - for e in self.docker_dict[ENV]: - key, val = e.split('=') - env_list.append({'name': key, - 'value': val}) - return env_list - - def _get_docker_expose(self): - """ - Function return docker EXPOSE directives - :return: list of PORTS - """ - ports_list = [] - if EXPOSE in self.docker_dict and self.docker_dict[EXPOSE]: - for p in self.docker_dict[EXPOSE]: - ports_list.append({'containerPort': int(p)}) - return ports_list - - def write_oc_template(self, templ): - """ - Function writes a YAML dictionary into template - :param templ: YAML template with all data - :return: - """ - tmp_dir = tempfile.mkdtemp() - if os.path.isdir(tmp_dir): - shutil.rmtree(tmp_dir) - os.makedirs(tmp_dir) - tmp_file = os.path.join(tmp_dir, os.path.basename(self.oc_template)) - with open(tmp_file, 'w') as f: - try: - yaml.safe_dump(templ, f, default_flow_style=False) - print("OpenShift template is generated here: %s" % (tmp_file)) - except yaml.YAMLError as exc: - print(exc) - raise - - def get_docker_directives(self, templ): - """ - Function collects all directives - :param templ: - :return: label_list, volume_list, volume_names, env_list, ports_list - """ - labels = volume_list = volume_names = env_list = ports_list = None - if self.docker_dict: - labels = self._get_labels(templ) - volume_list, volume_names = self._get_docker_volumes() - env_list = self._get_docker_env() - ports_list = self._get_docker_expose() - return labels, volume_list, volume_names, env_list, ports_list - - def generate_oc_template(self, templ, labels, volume_list, volume_names, env_list, ports_list): - """ - Function fulfills template with data taken from Dockerfile. - :param templ: YAML openshift templates - :param labels: list of labels - :param volume_list: volume list - :param volume_names: volume names - :param env_list: env list - :param ports_list: port list - :return: template with all data - """ - templ['metadata']['name'] = self.docker_image - templ['metadata']['labels'] = labels - for obj in templ['objects']: - obj['spec']['dockerImageRepository'] = self.docker_image - obj['metadata']['name'] = self.docker_image - if 'template' in obj['spec']: - obj['spec']['template']['metadata']['labels']['name'] = self.docker_image - containers = obj['spec']['template']['spec']['containers'][0] - if env_list: - containers["env"] = env_list - else: - containers.pop("env") - if ports_list: - containers["ports"] = ports_list - else: - containers.pop("ports") - if volume_list: - containers['volumeMounts'] = volume_list - obj['spec']['template']['spec']['volumes'] = volume_names - else: - containers.pop('volumeMounts') - obj['spec']['template']['spec'].pop('volumes') - containers['name'] = self.docker_image - containers['image'] = self.docker_image - - if 'triggers' in obj['spec']: - for trig in obj['spec']['triggers']: - trig['imageChangeParams']['containerNames'] = [self.docker_image] - trig['imageChangeParams']['from']['name'] = self.docker_image + ":latest" - - return templ - - def run(self): - """ - Main function - :return: - """ - self._get_openshift_template() - if not self._exist_docker_file() or not self._exist_openshift_template(): - return 1 - self._get_docker_tags() - templ = self._load_oc_template() - try: - tmpl = self.generate_oc_template(templ, *self.get_docker_directives(templ)) - except KeyError: - return 1 - self.write_oc_template(tmpl) - - diff --git a/setup.py b/setup.py index aa233c8..14e5daa 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( "metapackages) into module definitions in Fedora's modulemd format." ), license='MIT', - keywords='modularization modularity module modulemd openshift template docker', + keywords='modularization modularity module modulemd fedora', url='https://pagure.io/modularity/modularity-tools', entry_point={ 'console_scripts': [ @@ -26,7 +26,6 @@ setup( install_requires=[ 'modulemd', 'pdc-client', - 'dockerfile-parse', ], packages=find_packages(), ) diff --git a/tests/Dockerfile-Cockpit b/tests/Dockerfile-Cockpit deleted file mode 100644 index 8f729de..0000000 --- a/tests/Dockerfile-Cockpit +++ /dev/null @@ -1,31 +0,0 @@ -FROM registry.fedoraproject.org/fedora:26 -MAINTAINER "Stef Walter" - -ENV VERSION=135 RELEASE=1 -LABEL BZComponent="cockpit" \ - Name="$FGC/cockpit" \ - Version="$VERSION" \ - Release="$RELEASE.$DISTTAG" \ - Architecture="x86_64" - - -RUN dnf install -y cockpit-ws cockpit-dashboard - -RUN mkdir -p /container && ln -s /host/proc/1 /container/target-namespace -ADD atomic-install /container/atomic-install -ADD atomic-uninstall /container/atomic-uninstall -ADD atomic-run /container/atomic-run -RUN chmod -v +x /container/atomic-install -RUN chmod -v +x /container/atomic-uninstall -RUN chmod -v +x /container/atomic-run - -# Make the container think it's the host OS version -RUN rm -f /etc/os-release /usr/lib/os-release && ln -sv /host/etc/os-release /etc/os-release && ln -sv /host/usr/lib/os-release /usr/lib/os-release - -LABEL INSTALL /usr/bin/docker run --rm --privileged -v /:/host IMAGE /container/atomic-install -LABEL UNINSTALL /usr/bin/docker run --rm --privileged -v /:/host IMAGE /container/atomic-uninstall -LABEL RUN /usr/bin/docker run -d --privileged --pid=host -v /:/host IMAGE /container/atomic-run --local-ssh - -# Look ma, no EXPOSE - -CMD ["/container/atomic-run"] diff --git a/tests/test_oc_template.py b/tests/test_oc_template.py deleted file mode 100644 index d14a30c..0000000 --- a/tests/test_oc_template.py +++ /dev/null @@ -1,303 +0,0 @@ -# - *- coding: utf-8 -*- - - -import pytest -import tempfile -import shutil -import os -import six -import six.moves.urllib.request as urllib - -from fedmod.cli import ModtoolsCLI -from fedmod.oc_template import OpenShiftTemplateGenerator -from fedmod.oc_template import VOLUME, ENV, EXPOSE, LABEL - - -def init_oc_template_generator(dockerfile, image_name, working_dir): - arguments = ['docker2openshift','--dockerfile', dockerfile, image_name] - cli = ModtoolsCLI(arguments) - ostg = OpenShiftTemplateGenerator(cli, working_dir) - oc_template = urllib.URLopener() - oc_template.retrieve('https://raw.githubusercontent.com/container-images/container-image-template/master/openshift-template.yml', - os.path.join(os.path.dirname(__file__), 'openshift-template.yml')) - return ostg - - -class TestOCTemplate(object): - ostg = None - WORKING_DIR = '' - TESTS_DIR = os.path.dirname(__file__) - docker_tags = {} - - def setup(self): - self.WORKING_DIR = tempfile.mkdtemp(prefix="ostg-") - self.ostg = init_oc_template_generator(os.path.join(self. TESTS_DIR, 'files', 'Dockerfile'), - 'docker_image', - self.TESTS_DIR) - os.chdir(self.WORKING_DIR) - self.ostg._get_openshift_template() - self.docker_tags = self.ostg._get_docker_tags() - - def teardown(self): - os.chdir(self.TESTS_DIR) - shutil.rmtree(self.WORKING_DIR) - - def test_oc_check_docker_tags(self): - expected_tags = {VOLUME: ['/var/log', '/var/spool/log', '/var/spool/mail'], - ENV: ['POSTFIX_SMTP_PORT=10025'], - EXPOSE: ['1234', '2345', '6789'], - LABEL: {u'io.k8s.description': u'IO_K8S_DESCRIPTION.', - u'version': u'1.0', - u'description': u'DESCRIPTION.', - u'io.openshift.expose-services': u'1234:EXPOSE_SERVICES', - u'io.k8s.display-name': u'IO_K8S_DISPLAY_NAME.', - u'io.openshift.tags': u'TAGS', - u'summary': u'Testing Summary.'}} - for key, value in six.iteritems(self.ostg.docker_dict): - if key in expected_tags: - assert value == expected_tags[key] - else: - print(key) - assert False - - def test_check_missing_exposes(self): - expected_tags = {VOLUME: ['/var/log', '/var/spool/log', '/var/spool/mail'], - ENV: ['POSTFIX_SMTP_PORT=10025'], - LABEL: {'io.k8s.description': 'IO_K8S_DESCRIPTION.', - 'version': '1.0', - 'description': 'DESCRIPTION.', - 'io.openshift.expose-services': '1234:EXPOSE_SERVICES', - 'io.k8s.display-name': 'IO_K8S_DISPLAY_NAME.', - 'io.openshift.tags': 'TAGS', - 'summary': 'Testing Summary.'}} - self.ostg.docker_dict.pop('EXPOSE') - for key, value in six.iteritems(self.ostg.docker_dict): - if key in expected_tags: - assert value == expected_tags[key] - else: - print(key) - assert False - - def test_check_missing_labels(self): - expected_tags = {VOLUME: ['/var/log', '/var/spool/log', '/var/spool/mail'], - EXPOSE: ['1234', '2345', '6789'], - ENV: ['POSTFIX_SMTP_PORT=10025'] - } - self.ostg.docker_dict.pop('LABEL') - for key, value in six.iteritems(self.ostg.docker_dict): - if key in expected_tags: - assert value == expected_tags[key] - else: - assert False - - def test_check_missing_some_labels(self): - expected_tags = {VOLUME: ['/var/log', '/var/spool/log', '/var/spool/mail'], - ENV: ['POSTFIX_SMTP_PORT=10025'], - EXPOSE: ['1234', '2345', '6789'], - LABEL: {u'io.k8s.description': 'IO_K8S_DESCRIPTION.', - 'version': '1.0', - 'description': 'DESCRIPTION.', - 'io.openshift.tags': 'TAGS', - 'summary': 'Testing Summary.'}} - self.ostg.docker_dict['LABEL'].pop('io.openshift.expose-services') - self.ostg.docker_dict['LABEL'].pop('io.k8s.display-name') - for key, value in six.iteritems(self.ostg.docker_dict): - if key in expected_tags: - assert value == expected_tags[key] - else: - print(key) - assert False - - def test_check_missing_all(self): - expected_tags = {} - self.ostg.docker_dict.pop('LABEL') - self.ostg.docker_dict.pop('VOLUME') - self.ostg.docker_dict.pop('ENV') - self.ostg.docker_dict.pop('EXPOSE') - for key, value in six.iteritems(self.ostg.docker_dict): - if key in expected_tags: - assert value == expected_tags[key] - else: - print(key) - assert False - - def test_oc_template_generation(self): - tmpl = self.ostg._load_oc_template() - assert True - - def test_docker_volumes(self): - expected_volume_list = [{'mountPath': '/var/log', 'name': 'name-var-log'}, - {'mountPath': '/var/spool/log', 'name': 'name-var-spool-log'}, - {'mountPath': '/var/spool/mail', 'name': 'name-var-spool-mail'}] - expected_volume_names = [{'emptyDir': {}, 'name': 'name-var-log'}, - {'emptyDir': {}, 'name': 'name-var-spool-log'}, - {'emptyDir': {}, 'name': 'name-var-spool-mail'}] - volume_list, volume_names = self.ostg._get_docker_volumes() - assert volume_list == expected_volume_list - assert volume_names == expected_volume_names - - def test_docker_env(self): - expected_env_list = [{'name': 'POSTFIX_SMTP_PORT', 'value': '10025'}] - env_list = self.ostg._get_docker_env() - assert env_list == expected_env_list - - def test_docker_expose(self): - expected_expose_list = [{'containerPort': 1234}, - {'containerPort': 2345}, - {'containerPort': 6789}] - expose_list = self.ostg._get_docker_expose() - assert expose_list == expected_expose_list - - def test_generate_oc(self): - expected_tmpl = {'apiVersion': 'v1', - 'kind': 'Template', - 'metadata': {'name': 'docker_image', - 'labels': {'description': u'DESCRIPTION.', 'tags': u'TAGS', - 'template': 'docker_image'}, - }, - 'objects': [{'apiVersion': 'v1', - 'kind': 'ImageStream', - 'metadata': {'name': 'docker_image'}, - 'spec': {'dockerImageRepository': 'docker_image'}, - 'tags': [{'name': 'latest'}]}, - {'apiVersion': 'v1', - 'kind': 'DeploymentConfig', - 'metadata': {'name': 'docker_image'}, - 'spec': {'dockerImageRepository': 'docker_image', - 'replicas': 1, - 'strategy': {'type': 'Rolling'}, - 'template': {'metadata': {'labels': {'name': 'docker_image'}}, - 'spec': {'containers': [{'env': [{'name': u'POSTFIX_SMTP_PORT', - 'value': u'10025'}], - 'image': 'docker_image', - 'imagePullPolicy': 'Never', - 'name': 'docker_image', - 'ports': [{'containerPort': 1234}, - {'containerPort': 2345}, - {'containerPort': 6789}], - 'volumeMounts': [{'mountPath': '/var/log', - 'name': 'name-var-log'}, - {'mountPath': '/var/spool/log', - 'name': 'name-var-spool-log'}, - {'mountPath': '/var/spool/mail', - 'name': 'name-var-spool-mail'}]}], - 'volumes': [{'emptyDir': {}, - 'name': 'name-var-log'}, - {'emptyDir': {}, - 'name': 'name-var-spool-log'}, - {'emptyDir': {}, - 'name': 'name-var-spool-mail'}]}}, - 'triggers': [{'imageChangeParams': {'automatic': True, - 'containerNames': ['docker_image'], - 'from': {'kind': 'ImageStreamTag', - 'name': 'docker_image:latest'}}, - 'type': 'ImageChange'}] - } - }] - } - templ = self.ostg._load_oc_template() - (args) = self.ostg.get_docker_directives(templ) - tmpl = self.ostg.generate_oc_template(templ, *args) - assert tmpl == expected_tmpl - - def test_missing_annotation(self): - expected_tmpl = {'apiVersion': 'v1', - 'kind': 'Template', - 'metadata': {'labels': {'tags': u'TAGS', - 'template': 'docker_image'}, - 'name': 'docker_image'}, - 'objects': [{'apiVersion': 'v1', - 'kind': 'ImageStream', - 'metadata': {'name': 'docker_image'}, - 'spec': {'dockerImageRepository': 'docker_image'}, - 'tags': [{'name': 'latest'}]}, - {'apiVersion': 'v1', - 'kind': 'DeploymentConfig', - 'metadata': {'name': 'docker_image'}, - 'spec': {'dockerImageRepository': 'docker_image', - 'replicas': 1, - 'strategy': {'type': 'Rolling'}, - 'template': {'metadata': {'labels': {'name': 'docker_image'}}, - 'spec': {'containers': [{'env': [{'name': u'POSTFIX_SMTP_PORT', - 'value': u'10025'}], - 'image': 'docker_image', - 'imagePullPolicy': 'Never', - 'name': 'docker_image', - 'ports': [{'containerPort': 1234}, - {'containerPort': 2345}, - {'containerPort': 6789}], - 'volumeMounts': [{'mountPath': '/var/log', - 'name': 'name-var-log'}, - {'mountPath': '/var/spool/log', - 'name': 'name-var-spool-log'}, - {'mountPath': '/var/spool/mail', - 'name': 'name-var-spool-mail'}]}], - 'volumes': [{'emptyDir': {}, - 'name': 'name-var-log'}, - {'emptyDir': {}, - 'name': 'name-var-spool-log'}, - {'emptyDir': {}, - 'name': 'name-var-spool-mail'}]}}, - 'triggers': [{'imageChangeParams': {'automatic': True, - 'containerNames': ['docker_image'], - 'from': {'kind': 'ImageStreamTag', - 'name': 'docker_image:latest'}}, - 'type': 'ImageChange'}] - } - }] - } - templ = self.ostg._load_oc_template() - labels, volume_list, volume_names, env_list, ports_list = self.ostg.get_docker_directives(templ) - del labels['description'] - tmpl = self.ostg.generate_oc_template(templ, - labels, - volume_list, - volume_names, - env_list, - ports_list) - assert tmpl == expected_tmpl - - -class TestCockpitDockerFromDistGit(object): - ostg = None - WORKING_DIR = '' - TESTS_DIR = os.path.dirname(__file__) - docker_tags = {} - cockpit_name = None - - def setup(self): - self.WORKING_DIR = tempfile.mkdtemp(prefix="ostg-") - self.cockpit_name = 'Dockerfile-Cockpit' - docker = urllib.URLopener() - docker.retrieve('http://pkgs.fedoraproject.org/cgit/container/cockpit.git/plain/Dockerfile', - os.path.join(os.path.dirname(__file__), self.cockpit_name)) - self.ostg = init_oc_template_generator(self.cockpit_name, - 'docker_image', - self.TESTS_DIR) - self.ostg._get_openshift_template() - self.ostg._get_docker_tags() - - def test_cockit_env(self): - expected_env = [{'name': u'VERSION', - 'value': u'135'}, - {'name': u'RELEASE', - 'value': u'1'} - ] - assert expected_env == self.ostg._get_docker_env() - - def test_cockit_label(self): - expected_label = {u'Architecture': u'x86_64', - u'BZComponent': u'cockpit', - u'Name': u'$FGC/cockpit', - u'Release': u'$RELEASE.$DISTTAG', - u'Version': u'$VERSION'} - assert expected_label == self.ostg._get_docker_labels() - - def test_cockit_volume(self): - expected_volume = ([],[]) - assert expected_volume == self.ostg._get_docker_volumes() - - def teardown(self): - os.chdir(self.TESTS_DIR) - os.unlink(self.cockpit_name) - shutil.rmtree(self.WORKING_DIR)