summaryrefslogtreecommitdiffstats
path: root/apex/builders/common_builder.py
diff options
context:
space:
mode:
Diffstat (limited to 'apex/builders/common_builder.py')
-rw-r--r--apex/builders/common_builder.py95
1 files changed, 81 insertions, 14 deletions
diff --git a/apex/builders/common_builder.py b/apex/builders/common_builder.py
index 0cd683c3..10fab9b6 100644
--- a/apex/builders/common_builder.py
+++ b/apex/builders/common_builder.py
@@ -9,11 +9,13 @@
# Common building utilities for undercloud and overcloud
+import datetime
import git
import json
import logging
import os
import re
+import urllib.parse
import apex.builders.overcloud_builder as oc_builder
from apex import build_utils
@@ -52,7 +54,9 @@ def project_to_docker_image(project):
"""
# Fetch all docker containers in docker hub with tripleo and filter
# based on project
- hub_output = utils.open_webpage(con.DOCKERHUB_OOO, timeout=10)
+
+ hub_output = utils.open_webpage(
+ urllib.parse.urljoin(con.DOCKERHUB_OOO, '?page_size=1024'), timeout=10)
try:
results = json.loads(hub_output.decode())['results']
except Exception as e:
@@ -72,6 +76,60 @@ def project_to_docker_image(project):
return docker_images
+def is_patch_promoted(change, branch, docker_image=None):
+ """
+ Checks to see if a patch that is in merged exists in either the docker
+ container or the promoted tripleo images
+ :param change: gerrit change json output
+ :param branch: branch to use when polling artifacts (does not include
+ stable prefix)
+ :param docker_image: container this applies to if (defaults to None)
+ :return: True if the patch exists in a promoted artifact upstream
+ """
+ assert isinstance(change, dict)
+ assert 'status' in change
+
+ # if not merged we already know this is not closed/abandoned, so we know
+ # this is not promoted
+ if change['status'] != 'MERGED':
+ return False
+ assert 'submitted' in change
+ # drop microseconds cause who cares
+ stime = re.sub('\..*$', '', change['submitted'])
+ submitted_date = datetime.datetime.strptime(stime, "%Y-%m-%d %H:%M:%S")
+ # Patch applies to overcloud/undercloud
+ if docker_image is None:
+ oc_url = urllib.parse.urljoin(
+ con.UPSTREAM_RDO.replace('master', branch), 'overcloud-full.tar')
+ oc_mtime = utils.get_url_modified_date(oc_url)
+ if oc_mtime > submitted_date:
+ logging.debug("oc image was last modified at {}, which is"
+ "newer than merge date: {}".format(oc_mtime,
+ submitted_date))
+ return True
+ else:
+ # must be a docker patch, check docker tag modified time
+ docker_url = con.DOCKERHUB_OOO.replace('tripleomaster',
+ "tripleo{}".format(branch))
+ url_path = "{}/tags/{}".format(docker_image, con.DOCKER_TAG)
+ docker_url = urllib.parse.urljoin(docker_url, url_path)
+ logging.debug("docker url is: {}".format(docker_url))
+ docker_output = utils.open_webpage(docker_url, 10)
+ logging.debug('Docker web output: {}'.format(docker_output))
+ hub_mtime = json.loads(docker_output.decode())['last_updated']
+ hub_mtime = re.sub('\..*$', '', hub_mtime)
+ # docker modified time is in this format '2018-06-11T15:23:55.135744Z'
+ # and we drop microseconds
+ hub_dtime = datetime.datetime.strptime(hub_mtime, "%Y-%m-%dT%H:%M:%S")
+ if hub_dtime > submitted_date:
+ logging.debug("docker image: {} was last modified at {}, which is"
+ "newer than merge date: {}".format(docker_image,
+ hub_dtime,
+ submitted_date))
+ return True
+ return False
+
+
def add_upstream_patches(patches, image, tmp_dir,
default_branch=os.path.join('stable',
con.DEFAULT_OS_VERSION),
@@ -99,20 +157,29 @@ def add_upstream_patches(patches, image, tmp_dir,
branch = default_branch
patch_diff = build_utils.get_patch(patch['change-id'],
patch['project'], branch)
- if patch_diff:
+ project_path = project_to_path(patch['project'])
+ # If docker tag and python we know this patch belongs on docker
+ # container for a docker service. Therefore we build the dockerfile
+ # and move the patch into the containers directory. We also assume
+ # this builder call is for overcloud, because we do not support
+ # undercloud containers
+ if docker_tag and 'python' in project_path:
+ # Projects map to multiple THT services, need to check which
+ # are supported
+ ooo_docker_services = project_to_docker_image(patch['project'])
+ docker_img = ooo_docker_services[0]
+ else:
+ ooo_docker_services = []
+ docker_img = None
+ change = build_utils.get_change(con.OPENSTACK_GERRIT,
+ patch['project'], branch,
+ patch['change-id'])
+ patch_promoted = is_patch_promoted(change,
+ branch.replace('/stable', ''),
+ docker_img)
+
+ if patch_diff and not patch_promoted:
patch_file = "{}.patch".format(patch['change-id'])
- project_path = project_to_path(patch['project'])
- # If docker tag and python we know this patch belongs on docker
- # container for a docker service. Therefore we build the dockerfile
- # and move the patch into the containers directory. We also assume
- # this builder call is for overcloud, because we do not support
- # undercloud containers
- if docker_tag and 'python' in project_path:
- # Projects map to multiple THT services, need to check which
- # are supported
- ooo_docker_services = project_to_docker_image(patch['project'])
- else:
- ooo_docker_services = []
# If we found services, then we treat the patch like it applies to
# docker only
if ooo_docker_services: