From ce896972a0b263e1d83b61f071e5ccbb945c8696 Mon Sep 17 00:00:00 2001 From: xudan Date: Mon, 27 Mar 2017 03:32:50 +0000 Subject: dovetail tool: change function pull_image JIRA: DOVETAIL-378 1. test_runner checks the result of cmd "pull image". If fail to pull, then break the running. 2. pull_image will return None when there are errors, otherwise return image name. 3. if there is an old image named the same as the new one, the old one's tag will be changed into . In this case, the old image needs to be removed. 4. if there are some containers using this old image, the remove will be skipped rather than logging error. Change-Id: I940cb18911112d5e13f3c14f87ddbdbaced3538a Signed-off-by: xudan --- dovetail/container.py | 45 +++++++++++++++++++++++++++------------------ dovetail/test_runner.py | 7 ++++--- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/dovetail/container.py b/dovetail/container.py index 878b21cb..71fa346f 100644 --- a/dovetail/container.py +++ b/dovetail/container.py @@ -35,10 +35,14 @@ class Container(object): def get(cls, type): return cls.container_list[type] - @staticmethod - def get_docker_image(type): - return '%s:%s' % (dt_cfg.dovetail_config[type]['image_name'], - dt_cfg.dovetail_config[type]['docker_tag']) + @classmethod + def get_docker_image(cls, type): + try: + return '%s:%s' % (dt_cfg.dovetail_config[type]['image_name'], + dt_cfg.dovetail_config[type]['docker_tag']) + except KeyError as e: + cls.logger.error('There is no %s in %s config file.', e, type) + return None # get the openrc_volume for creating the container @classmethod @@ -136,16 +140,24 @@ class Container(object): if ret == 0: return image_id else: - return False + return None + # remove the image according to the image_id + # if there exists containers using this image, then skip @classmethod def remove_image(cls, image_id): + cmd = "sudo docker ps -aq -f 'ancestor=%s'" % (image_id) + ret, msg = dt_utils.exec_cmd(cmd, cls.logger) + if msg and ret == 0: + cls.logger.debug('image %s has containers, skip.', image_id) + return True cmd = 'sudo docker rmi %s' % (image_id) + cls.logger.debug('remove image %s', image_id) ret, msg = dt_utils.exec_cmd(cmd, cls.logger) if ret == 0: cls.logger.debug('remove image %s successfully', image_id) return True - cls.logger.error('image %s has containers, fail to remove.', image_id) + cls.logger.error('fail to remove image %s.', image_id) return False @classmethod @@ -158,33 +170,30 @@ class Container(object): cls.logger.debug('success to pull docker image %s!', image_name) return True - # returncode 0: succeed to pull new image and remove the old one - # returncode 1: fail to pull the image - # returncode 2: succeed to pull but fail to get the new image id - # returncode 3: fail to remove the old image @classmethod def pull_image(cls, validate_type): docker_image = cls.get_docker_image(validate_type) + if not docker_image: + return None if cls.has_pull_latest_image[validate_type] is True: cls.logger.debug('%s is already the newest version.', docker_image) - return 0 + return docker_image old_image_id = cls.get_image_id(docker_image) if not cls.pull_image_only(docker_image): - return 1 + return None cls.has_pull_latest_image[validate_type] = True new_image_id = cls.get_image_id(docker_image) if not new_image_id: cls.logger.error("fail to get the new image's id %s", docker_image) - return 2 + return None + if not old_image_id: + return docker_image if new_image_id == old_image_id: cls.logger.debug('image %s has no changes, no need to remove.', docker_image) else: - if old_image_id: - cls.logger.debug('remove the old image %s', old_image_id) - if not cls.remove_image(old_image_id): - return 3 - return 0 + cls.remove_image(old_image_id) + return docker_image @classmethod def check_image_exist(cls, validate_type): diff --git a/dovetail/test_runner.py b/dovetail/test_runner.py index ea58768c..1ac9f196 100644 --- a/dovetail/test_runner.py +++ b/dovetail/test_runner.py @@ -35,10 +35,11 @@ class DockerRunner(object): self.logger.error('%s image not exist offline running', self.testcase.validate_type()) return - container_id = Container.create(self.testcase.validate_type()) else: - Container.pull_image(self.testcase.validate_type()) - container_id = Container.create(self.testcase.validate_type()) + if not Container.pull_image(self.testcase.validate_type()): + self.logger.error("Failed to pull the image.") + return + container_id = Container.create(self.testcase.validate_type()) if not container_id: self.logger.error('failed to create container') return -- cgit 1.2.3-korg