101860cde17da87a873a442d4eb8c98dbad7230b
[apex.git] / apex / builders / common_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 # Common building utilities for undercloud and overcloud
11
12 import git
13 import logging
14 import os
15
16 from apex import build_utils
17 from apex.common import constants as con
18 from apex.virtual import utils as virt_utils
19
20
21 def project_to_path(project):
22     """
23     Translates project to absolute file path
24     :param project: name of project
25     :return: File path
26     """
27     if project.startswith('openstack/'):
28         project = os.path.basename(project)
29     if 'puppet' in project:
30         return "/etc/puppet/modules/{}".format(project.replace('puppet-', ''))
31     elif 'tripleo-heat-templates' in project:
32         return "/usr/share/openstack-tripleo-heat-templates"
33     else:
34         # assume python
35         return "/usr/lib/python2.7/site-packages/{}".format(project)
36
37
38 def add_upstream_patches(patches, image, tmp_dir,
39                          default_branch=os.path.join('stable',
40                                                      con.DEFAULT_OS_VERSION)):
41     """
42     Adds patches from upstream OpenStack gerrit to Undercloud for deployment
43     :param patches: list of patches
44     :param image: undercloud image
45     :param tmp_dir: to store temporary patch files
46     :param default_branch: default branch to fetch commit (if not specified
47     in patch)
48     :return: None
49     """
50     virt_ops = list()
51     logging.debug("Evaluating upstream patches:\n{}".format(patches))
52     for patch in patches:
53         assert isinstance(patch, dict)
54         assert all(i in patch.keys() for i in ['project', 'change-id'])
55         if 'branch' in patch.keys():
56             branch = patch['branch']
57         else:
58             branch = default_branch
59         patch_diff = build_utils.get_patch(patch['change-id'],
60                                            patch['project'], branch)
61         if patch_diff:
62             patch_file = "{}.patch".format(patch['change-id'])
63             patch_file_path = os.path.join(tmp_dir, patch_file)
64             with open(patch_file_path, 'w') as fh:
65                 fh.write(patch_diff)
66             project_path = project_to_path(patch['project'])
67             virt_ops.extend([
68                 {con.VIRT_UPLOAD: "{}:{}".format(patch_file_path,
69                                                  project_path)},
70                 {con.VIRT_RUN_CMD: "cd {} && patch -p1 < {}".format(
71                     project_path, patch_file)}])
72             logging.info("Adding patch {} to {}".format(patch_file,
73                                                         image))
74         else:
75             logging.info("Ignoring patch:\n{}".format(patch))
76     if virt_ops:
77         virt_utils.virt_customize(virt_ops, image)
78
79
80 def add_repo(repo_url, repo_name, image, tmp_dir):
81     assert repo_name is not None
82     assert repo_url is not None
83     repo_file = "{}.repo".format(repo_name)
84     repo_file_path = os.path.join(tmp_dir, repo_file)
85     content = [
86         "[{}]".format(repo_name),
87         "name={}".format(repo_name),
88         "baseurl={}".format(repo_url),
89         "gpgcheck=0"
90     ]
91     logging.debug("Creating repo file {}".format(repo_name))
92     with open(repo_file_path, 'w') as fh:
93         fh.writelines("{}\n".format(line) for line in content)
94     logging.debug("Adding repo {} to {}".format(repo_file, image))
95     virt_utils.virt_customize([
96         {con.VIRT_UPLOAD: "{}:/etc/yum.repos.d/".format(repo_file_path)}],
97         image
98     )
99
100
101 def create_git_archive(repo_url, repo_name, tmp_dir,
102                        branch='master', prefix=''):
103     repo = git.Repo.clone_from(repo_url, os.path.join(tmp_dir, repo_name))
104     repo_git = repo.git
105     if branch != str(repo.active_branch):
106         repo_git.checkout("origin/{}".format(branch))
107     archive_path = os.path.join(tmp_dir, "{}.tar".format(repo_name))
108     with open(archive_path, 'wb') as fh:
109         repo.archive(fh, prefix=prefix)
110     logging.debug("Wrote archive file: {}".format(archive_path))
111     return archive_path