[CORD-2846]
Add git branch and tags to docker image tags built imagebuilder
Change-Id: I5e28440dd662845a782ad730531b4c9893e39d87
diff --git a/scripts/imagebuilder.py b/scripts/imagebuilder.py
old mode 100755
new mode 100644
index 1fd06e5..27ff8d2
--- a/scripts/imagebuilder.py
+++ b/scripts/imagebuilder.py
@@ -168,23 +168,32 @@
pull_only_images = [img for img in conf['pull_only_images']
if split_name(img)[0]
- in map(lambda x: split_name(x)[0], filter_list['docker_image_whitelist'])]
+ in map(lambda x: split_name(x)[0],
+ filter_list['docker_image_whitelist'])]
- pull_only_images = map(override_tags(filter_list['docker_image_whitelist']), pull_only_images)
+ pull_only_images = map(override_tags(
+ filter_list['docker_image_whitelist']),
+ pull_only_images)
+
except:
LOG.exception("Problem with filter list file")
sys.exit(1)
+
def override_tags(image_list_with_tags):
+
untagged_whitelist = map(lambda x: split_name(x)[0], image_list_with_tags)
+
def inner(i):
img_name = split_name(i)[0]
- tag_override = split_name(image_list_with_tags[untagged_whitelist.index(img_name)])[1]
+ tag_override = split_name(image_list_with_tags[
+ untagged_whitelist.index(img_name)])[1]
if tag_override:
return "%s:%s" % (img_name, tag_override)
return i
return inner
+
def split_name(input_name):
""" split a docker image name in the 'name:tag' format into components """
@@ -204,14 +213,14 @@
class RepoRepo():
""" git repo managed by repo tool"""
- manifest_branch = ""
-
- def __init__(self, name, path, remote):
+ def __init__(self, name, path, remote_url, remote_branch, short_branch):
self.name = name
self.path = path
- self.remote = remote
- self.git_url = "%s%s" % (remote, name)
+ self.git_url = "%s%s" % (remote_url, name)
+ self.remote_branch = remote_branch
+ self.short_branch = short_branch
+ self.git_tags = []
try:
self.git_repo_o = git.Repo(self.abspath())
@@ -224,6 +233,16 @@
self.head_commit_t = time.strftime("%Y-%m-%dT%H:%M:%SZ", commit_t)
LOG.debug(" commit date: %s" % self.head_commit_t)
+ for tag in self.git_repo_o.tags:
+ if tag.commit == self.git_repo_o.head.commit:
+ self.git_tags.append(str(tag))
+
+ if self.git_tags:
+ LOG.debug(" tags referring to this commit: %s" %
+ ", ".join(self.git_tags))
+ else:
+ LOG.debug(" No git tags refer to this commit")
+
self.clean = not self.git_repo_o.is_dirty(untracked_files=True)
LOG.debug(" clean: %s" % self.clean)
@@ -245,7 +264,7 @@
global conf
if not branch:
- branch = self.manifest_branch
+ branch = self.remote_branch
LOG.debug(" Looking for changes in path: %s" % test_path)
@@ -297,17 +316,19 @@
LOG.exception("Error loading repo manifest")
sys.exit(1)
- # Find the default branch
+ # Find the branch names
default = self.manifest_xml.find('default')
- self.branch = "%s/%s" % (default.attrib['remote'],
- default.attrib['revision'])
+
+ self.short_branch = default.attrib['revision']
+ self.remote_branch = "%s/%s" % (default.attrib['remote'],
+ default.attrib['revision'])
# Find the remote URL for these repos
remote = self.manifest_xml.find('remote')
- self.remote = remote.attrib['review']
+ self.remote_url = remote.attrib['review']
- LOG.info("Manifest is on branch '%s' with remote '%s'" %
- (self.branch, self.remote))
+ LOG.info("Manifest is on remote branch '%s' with remote url '%s'" %
+ (self.remote_branch, self.remote_url))
project_repos = {}
@@ -324,8 +345,10 @@
repo_name)
for repo_name, repo_path in project_repos.iteritems():
- self.repos[repo_name] = RepoRepo(repo_name, repo_path, self.remote)
- self.repos[repo_name].manifest_branch = self.branch
+ self.repos[repo_name] = RepoRepo(repo_name, repo_path,
+ self.remote_url,
+ self.remote_branch,
+ self.short_branch)
def get_repo(self, repo_name):
return self.repos[repo_name]
@@ -439,7 +462,7 @@
return True # unbuildable images are clean
def parents_clean(self):
- """ if all parents are clean """
+ """ Returns true if self and all parents are clean """
if self.buildable():
if not self.clean:
@@ -522,7 +545,8 @@
clean = False
if clean:
- comp_l[prefix + "version"] = self.repo_d.manifest_branch
+ comp_l[prefix + "version"] = "%s-%s" % \
+ (self.repo_d.short_branch, self.repo_d.head_commit)
comp_l[prefix + "vcs-ref"] = \
component['repo_d'].head_commit
else:
@@ -555,7 +579,8 @@
cl[prefix + "vcs-url"] = self.repo_d.git_url
if self.clean:
- cl[prefix + "version"] = self.repo_d.manifest_branch
+ cl[prefix + "version"] = "%s-%s" % (self.repo_d.short_branch,
+ self.repo_d.head_commit)
cl[prefix + "vcs-ref"] = self.repo_d.head_commit
else:
cl[prefix + "version"] = "dirty"
@@ -594,7 +619,8 @@
if self.clean:
self.labels['org.label-schema.version'] = \
- self.repo_d.manifest_branch
+ "%s-%s" % (self.repo_d.short_branch,
+ self.repo_d.head_commit)
self.labels['org.label-schema.vcs-ref'] = \
self.repo_d.head_commit
self.labels['org.opencord.vcs-commit-date'] = \
@@ -615,16 +641,30 @@
# if clean and parents clean, add tags for branch/commit
if self.parents_clean():
+
+ # add build tag
if build_tag not in self.tags:
self.tags.append(build_tag)
- commit_tag = self.repo_d.head_commit
+ # add branch tag
+ branch_tag = self.repo_d.short_branch
+ if branch_tag not in self.tags:
+ self.tags.append(branch_tag)
+
+ # Add <branch>-<commit> tag, which is used to pull
+ commit_tag = "%s-%s" % (self.repo_d.short_branch,
+ self.repo_d.head_commit)
if commit_tag not in self.tags:
self.tags.append(commit_tag)
- # pulling is done via raw_name, set tag to commit
+ # this is most specific tag, so pull using it
self.raw_name = "%s:%s" % (self.name, commit_tag)
+ # add all tags in git that point at the commit
+ for gt in self.repo_d.git_tags:
+ if gt not in self.tags:
+ self.tags.append(gt)
+
LOG.debug("All tags: %s" % ", ".join(self.tags))
def _find_parent_names(self):
@@ -819,7 +859,10 @@
""" Connect to docker daemon """
try:
- self.dc = DockerClient()
+ # get a "high level" Docker object with conf from the environment
+ hl_dc = docker.from_env()
+ # use the low level APIClient (same as the 1.x API)
+ self.dc = hl_dc.api
except requests.ConnectionError:
LOG.debug("Docker connection not available")
sys.exit(1)
@@ -884,7 +927,8 @@
else: # doesn't have good labels
- # if it has a build_tag, and a good image hasn't already been tagged
+ # if it has a build_tag, and a good image hasn't
+ # already been tagged
if has_build_tag and (image.status != DI_EXISTS):
LOG.info(" Image %s has obsolete labels and"
" build_tag, remove" % pe_image['Id'])
@@ -1187,8 +1231,7 @@
sys.exit(1)
except (DockerErrors.NotFound, DockerErrors.ImageNotFound) as e:
- LOG.warning("Image could not be pulled: %s , %s" %
- (e.errno, e.strerror))
+ LOG.warning("Image could not be pulled: %s" % e)
self.failed_pull.append({
"tags": [image.raw_name, ],
@@ -1243,11 +1286,13 @@
def _build_image(self, image):
+ global build_tag
+
LOG.info("Building docker image for %s" % image.raw_name)
if self.dc is not None:
- build_tag = "%s:%s" % (image.name, image.tags[0])
+ image_build_tag = "%s:%s" % (image.name, build_tag)
buildargs = image.buildargs()
context_tar = image.context_tarball()
@@ -1273,7 +1318,7 @@
try:
LOG.info("Building image: %s" % image)
- for stat_d in self.dc.build(tag=build_tag,
+ for stat_d in self.dc.build(tag=image_build_tag,
buildargs=buildargs,
nocache=args.build,
custom_context=True,
@@ -1312,7 +1357,7 @@
LOG.exception("Error building docker image")
self.failed_build.append({
- "tags": [build_tag, ],
+ "tags": [image_build_tag, ],
})
return
@@ -1332,16 +1377,20 @@
LOG.info("Built Image: %s, duration: %s, id: %s" %
(image.name, duration, image.image_id))
+ self.tag_image(image)
+
+ # don't push the build_tag to dockerhub
+ built_tags = list(image.tags)
+ built_tags.remove(build_tag)
+
self.built.append({
"id": image.image_id,
- "tags": [build_tag, ],
- "push_name": image.raw_name,
+ "tags": built_tags,
"build_log": bl_path,
"duration": duration.total_seconds(),
"base": image.name.split(":")[0],
})
- self.tag_image(image)
image.status = DI_EXISTS
@@ -1357,13 +1406,12 @@
from docker import __version__ as docker_version
# handle the docker-py v1 to v2 API differences
- if LooseVersion(docker_version) >= LooseVersion('2.0.0'):
- from docker import APIClient as DockerClient
- else:
+ if LooseVersion(docker_version) < LooseVersion('2.0.0'):
LOG.error("Unsupported python docker module - "
"remove docker-py 1.x, install docker 2.x")
sys.exit(1)
+ import docker
from docker import utils as DockerUtils
from docker import errors as DockerErrors