From b54fffd9a27b2d5c1518b615d48c18a0eaef5a1b Mon Sep 17 00:00:00 2001 From: lixinyu Date: Tue, 16 Jan 2024 10:28:32 +0800 Subject: [PATCH] clear: optimize the clear container task * the clear is used to clear container that created by bitbake command, but the clear task rely on .env which placed on compile directory because .env record container id on itself, however there is a flaw is that if the .env is deleted manual the clear can not delete container any more. so we make a container.log, it's role is to record container id, thus clear command can delete container with container id come from container.log Signed-off-by: lixinyu --- .../app/plugins/bitbake/in_container.py | 5 ++ src/oebuild/app/plugins/clear/clear.py | 29 +++++---- src/oebuild/container_log.py | 60 +++++++++++++++++++ 3 files changed, 82 insertions(+), 12 deletions(-) create mode 100644 src/oebuild/container_log.py diff --git a/src/oebuild/app/plugins/bitbake/in_container.py b/src/oebuild/app/plugins/bitbake/in_container.py index e71b567..44f79ff 100644 --- a/src/oebuild/app/plugins/bitbake/in_container.py +++ b/src/oebuild/app/plugins/bitbake/in_container.py @@ -18,6 +18,7 @@ from docker.models.containers import Container,ExecResult from oebuild.parse_env import ParseEnv, EnvContainer from oebuild.docker_proxy import DockerProxy from oebuild.configure import Configure +from oebuild.container_log import ContainerLog from oebuild.parse_compile import ParseCompile, DockerParam from oebuild.m_log import logger from oebuild.app.plugins.bitbake.base_build import BaseBuild @@ -57,6 +58,10 @@ class InContainer(BaseBuild): return self.deal_env_container(env=parse_env,docker_param=docker_param) + # record the container id to container.log + container_log = ContainerLog( + config_dir=os.path.join(self.configure.oebuild_topdir(), ".oebuild")) + container_log.append_container_id(self.container_id) self.exec_compile(parse_compile=parse_compile, command=command) def _trans_docker_param(self, diff --git a/src/oebuild/app/plugins/clear/clear.py b/src/oebuild/app/plugins/clear/clear.py index c6663f8..ded02cc 100644 --- a/src/oebuild/app/plugins/clear/clear.py +++ b/src/oebuild/app/plugins/clear/clear.py @@ -20,6 +20,7 @@ from docker.errors import DockerException from oebuild.command import OebuildCommand import oebuild.util as oebuild_util from oebuild.configure import Configure +from oebuild.container_log import ContainerLog from oebuild.docker_proxy import DockerProxy from oebuild.m_log import logger @@ -97,17 +98,21 @@ class Clear(OebuildCommand): except KeyError: continue - # get all container which name start with oebuild and delete it, - # in case when user rm build directory then legacy container - # containers = self.client.get_all_container() - # for container in containers: - # container_name = str(container.attrs.get('Name')).lstrip("/") - # if container_name.startswith("oebuild_"): - # try: - # DockerProxy().stop_container(container=container) - # DockerProxy().delete_container(container=container) - # logger.info(f"delete container: {container.short_id} successful") - # except: - # continue + # delete container from container.log + container_log = ContainerLog( + config_dir=os.path.join(self.configure.oebuild_topdir(), ".oebuild")) + containerids_list = container_log.read_container_ids() + for container_id in containerids_list: + self._delete_container(container_id=container_id) + container_log.remove_container_log() logger.info("clear container finished") + + def _delete_container(self, container_id: str): + try: + container = self.client.get_container(container_id=container_id) + DockerProxy().stop_container(container=container) + DockerProxy().delete_container(container=container) + logger.info("Delete container: %s successful",container.short_id) + except DockerException: + return diff --git a/src/oebuild/container_log.py b/src/oebuild/container_log.py new file mode 100644 index 0000000..b45eaf1 --- /dev/null +++ b/src/oebuild/container_log.py @@ -0,0 +1,60 @@ +''' +Copyright (c) 2023 openEuler Embedded +oebuild is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +''' + +import os + +class ContainerLog: + ''' + the class is to record container id which created by command bitbake into container.log, + also can clean container with container id from container.log. the class aim to clear + containers that not use anymore + ''' + def __init__(self, config_dir:str) -> None: + self.id_prefix = "oebuild_" + self.container_log_path = os.path.join(config_dir, "container.log") + if not os.path.exists(self.container_log_path): + self._create_container_log() + + def _create_container_log(self): + with open(self.container_log_path, 'w', encoding="utf-8") as f: + banner = ''' +# do not edit any more, this file is created autometic and managerd by oebuild. this file +# records the container id list created by command bitbake, and will be used to clear container +''' + f.write(banner) + + def read_container_ids(self,) -> list: + ''' + read container.log and get container ids, before return the ids the function will deal + the data, just return the valid container ids + ''' + container_ids = [] + with open(self.container_log_path, 'r', encoding="utf-8") as f: + lines = f.readlines() + for line in lines: + line = line.strip('\n') + if line.startswith(self.id_prefix): + container_ids.append(line.lstrip(self.id_prefix)) + return container_ids + + def append_container_id(self, container_id): + ''' + append container id to container.log + ''' + with open(self.container_log_path, 'a', encoding="utf-8") as f: + f.write(f"{self.id_prefix}{container_id}\n") + + def remove_container_log(self): + ''' + delete the container.log, this function is invoked when have rm all other containers + ''' + os.remove(self.container_log_path) -- Gitee