Fixes deployment on CentOS 7.6
[apex.git] / apex / builders / undercloud_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 undercloud qcow2 image
11 import logging
12 import json
13 import os
14 import subprocess
15
16 from apex.common import constants as con
17 from apex.common import utils
18 from apex.virtual import utils as virt_utils
19
20
21 def add_upstream_packages(image):
22     """
23     Adds required base upstream packages to Undercloud for deployment
24     :param image:
25     :return: None
26     """
27     virt_ops = list()
28     pkgs = [
29         'epel-release',
30         'openstack-utils',
31         'python2-networking-sfc',
32         'openstack-ironic-inspector',
33         'subunit-filters',
34         'docker-distribution',
35         'openstack-tripleo-validations',
36         'libguestfs-tools',
37         'python-tripleoclient',
38         'openstack-tripleo-heat-templates'
39     ]
40     # Remove incompatible python-docker version
41     virt_ops.append({con.VIRT_RUN_CMD: "yum remove -y python-docker-py"})
42
43     for pkg in pkgs:
44         virt_ops.append({con.VIRT_INSTALL: pkg})
45     virt_utils.virt_customize(virt_ops, image)
46
47
48 def inject_calipso_installer(tmp_dir, image):
49     """
50     Downloads calipso installer script from artifacts.opnfv.org
51     and puts it under /root/ for further installation process.
52     :return:
53     """
54     calipso_file = os.path.basename(con.CALIPSO_INSTALLER_URL)
55     calipso_url = con.CALIPSO_INSTALLER_URL.replace(calipso_file, '')
56     utils.fetch_upstream_and_unpack(tmp_dir, calipso_url, [calipso_file])
57
58     virt_ops = [
59         {con.VIRT_UPLOAD: "{}/{}:/root/".format(tmp_dir, calipso_file)}]
60     virt_utils.virt_customize(virt_ops, image)
61     logging.info("Calipso injected into {}".format(image))
62
63 # TODO(trozet): add unit testing for calipso injector
64 # TODO(trozet): add rest of build for undercloud here as well
65
66
67 def update_repos(image, branch):
68     virt_ops = [
69         {con.VIRT_RUN_CMD: "rm -f /etc/yum.repos.d/delorean*"},
70         {con.VIRT_RUN_CMD: "yum-config-manager --add-repo "
71                            "https://trunk.rdoproject.org/centos7/{}"
72                            "/delorean.repo".format(con.RDO_TAG)},
73         {con.VIRT_RUN_CMD: "yum clean all"},
74         {con.VIRT_INSTALL: "python2-tripleo-repos"},
75         {con.VIRT_RUN_CMD: "tripleo-repos -b {} {} ceph".format(branch,
76                                                                 con.RDO_TAG)}
77     ]
78     virt_utils.virt_customize(virt_ops, image)
79
80
81 def expand_disk(image, desired_size=50):
82     """
83     Expands a disk image to desired_size in GigaBytes
84     :param image: image to resize
85     :param desired_size: desired size in GB
86     :return: None
87     """
88     # there is a lib called vminspect which has some dependencies and is
89     # not yet available in pip. Consider switching to this lib later.
90     try:
91         img_out = json.loads(subprocess.check_output(
92             ['qemu-img', 'info', '--output=json', image],
93             stderr=subprocess.STDOUT).decode())
94         disk_gb_size = int(img_out['virtual-size'] / 1000000000)
95         if disk_gb_size < desired_size:
96             logging.info("Expanding disk image: {}. Current size: {} is less"
97                          "than require size: {}".format(image, disk_gb_size,
98                                                         desired_size))
99             diff_size = desired_size - disk_gb_size
100             subprocess.check_call(['qemu-img', 'resize', image,
101                                    "+{}G".format(diff_size)],
102                                   stderr=subprocess.STDOUT)
103
104     except (subprocess.CalledProcessError, json.JSONDecodeError, KeyError) \
105             as e:
106         logging.warning("Unable to resize disk, disk may not be large "
107                         "enough: {}".format(e))