Fixes for snapshots
[apex.git] / apex / builders / overcloud_builder.py
1 ##############################################################################
2 # Copyright (c) 2017 Tim Rozet (trozet@redhat.com) and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9
10 # Used to modify overcloud qcow2 image
11
12 import logging
13 import os
14 import tarfile
15
16 import apex.builders.common_builder
17 from apex.common import constants as con
18 from apex.common.exceptions import ApexBuildException
19 from apex.virtual import utils as virt_utils
20
21
22 def inject_opendaylight(odl_version, image, tmp_dir, uc_ip,
23                         os_version, docker_tag=None):
24     assert odl_version in con.VALID_ODL_VERSIONS
25     # add repo
26     if odl_version == 'master':
27         odl_pkg_version = con.VALID_ODL_VERSIONS[-2]
28         branch = odl_version
29     else:
30         odl_pkg_version = odl_version
31         branch = "stable/{}".format(odl_version)
32     odl_url = "https://nexus.opendaylight.org/content/repositories" \
33               "/opendaylight-{}-epel-7-x86_64-devel/".format(odl_pkg_version)
34     repo_name = "opendaylight-{}".format(odl_pkg_version)
35     apex.builders.common_builder.add_repo(odl_url, repo_name, image, tmp_dir)
36     # download puppet-opendaylight
37     archive = apex.builders.common_builder.create_git_archive(
38         repo_url=con.PUPPET_ODL_URL, repo_name='puppet-opendaylight',
39         tmp_dir=tmp_dir, branch=branch, prefix='opendaylight/')
40     # install ODL, puppet-odl
41     virt_ops = [
42         {con.VIRT_UPLOAD: "{}:/etc/puppet/modules/".format(archive)},
43         {con.VIRT_RUN_CMD: 'rm -rf /etc/puppet/modules/opendaylight'},
44         {con.VIRT_RUN_CMD: "cd /etc/puppet/modules/ && tar xvf "
45                            "puppet-opendaylight.tar"},
46         {con.VIRT_INSTALL: "java-1.8.0-openjdk"}
47     ]
48     if docker_tag:
49         docker_cmds = [
50             "RUN yum remove opendaylight -y",
51             "RUN echo $'[opendaylight]\\n\\",
52             "baseurl={}\\n\\".format(odl_url),
53             "gpgcheck=0\\n\\",
54             "enabled=1' > /etc/yum.repos.d/opendaylight.repo",
55             "RUN yum -y install opendaylight"
56         ]
57         src_img_uri = "{}:8787/tripleo{}/centos-binary-{}:" \
58                       "{}".format(uc_ip, os_version, 'opendaylight',
59                                   docker_tag)
60         build_dockerfile('opendaylight', tmp_dir, docker_cmds, src_img_uri)
61     else:
62         virt_ops.append({con.VIRT_INSTALL: 'opendaylight'})
63     virt_utils.virt_customize(virt_ops, image)
64     logging.info("OpenDaylight injected into {}".format(image))
65
66
67 def build_dockerfile(service, tmp_dir, docker_cmds, src_image_uri):
68     """
69     Builds docker file per service and stores it in a
70     tmp_dir/containers/<service> directory.  If the Dockerfile already exists,
71     simply append the docker cmds to it.
72     :param service: name of sub-directory to store Dockerfile in
73     :param tmp_dir: Temporary directory to store the container's dockerfile in
74     :param docker_cmds: List of commands to insert into the dockerfile
75     :param src_image_uri: Docker URI format for where the source image exists
76     :return: None
77     """
78     logging.debug("Building Dockerfile for {} with docker_cmds: {}".format(
79         service, docker_cmds))
80     c_dir = os.path.join(tmp_dir, 'containers')
81     service_dir = os.path.join(c_dir, service)
82     if not os.path.isdir(service_dir):
83         os.makedirs(service_dir, exist_ok=True)
84     from_cmd = "FROM {}\n".format(src_image_uri)
85     service_file = os.path.join(service_dir, 'Dockerfile')
86     assert isinstance(docker_cmds, list)
87     if os.path.isfile(service_file):
88         append_cmds = True
89     else:
90         append_cmds = False
91     with open(service_file, "a+") as fh:
92         if not append_cmds:
93             fh.write(from_cmd)
94         fh.write('\n'.join(docker_cmds))
95
96
97 def archive_docker_patches(tmp_dir):
98     """
99     Archives Overcloud docker patches into a tar file for upload to Undercloud
100     :param tmp_dir: temporary directory where containers folder is stored
101     :return: None
102     """
103     container_path = os.path.join(tmp_dir, 'containers')
104     if not os.path.isdir(container_path):
105         raise ApexBuildException("Docker directory for patches not found: "
106                                  "{}".format(container_path))
107     archive_file = os.path.join(tmp_dir, 'docker_patches.tar.gz')
108     with tarfile.open(archive_file, "w:gz") as tar:
109         tar.add(container_path, arcname=os.path.basename(container_path))