From b66f62a3f3df90f06932cfdce7064441e2a385a8 Mon Sep 17 00:00:00 2001 From: stilobique Date: Mon, 20 Jul 2026 23:34:59 +0200 Subject: [PATCH] Update logs setup. Add clean dockers env. Fix Dockerfile with the latest step. --- .gitignore | 3 ++ .run/Clean docker Images .run.xml | 26 ++++++++++ Dockerfile | 4 +- blender/docker.py | 61 +++++++++++++++++++----- blender/misc.py | 79 +++++++++++++++++++++++++++++++ main.py | 4 +- 6 files changed, 162 insertions(+), 15 deletions(-) create mode 100644 .run/Clean docker Images .run.xml create mode 100644 blender/misc.py diff --git a/.gitignore b/.gitignore index edc3ca6..b9c2a64 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +### Logs +**/logs/** + ### Config/setup """ *.env diff --git a/.run/Clean docker Images .run.xml b/.run/Clean docker Images .run.xml new file mode 100644 index 0000000..fb9d001 --- /dev/null +++ b/.run/Clean docker Images .run.xml @@ -0,0 +1,26 @@ + + + + + \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index c2f57c2..3bb10c8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,8 +32,8 @@ FROM ubuntu:25.10 AS final #COPY --from=b3dock /opt/blender/build_files/build_environment/packages.txt /tmp/packages.txt COPY --from=b3dock /opt/blender/build_files/build_environment/install_linux_packages.py /tmp/install_linux_packages.py -RUN apt-get update && apt-get install -y python3 -RUN python3 /tmp/install_linux_packages.py --no-sudo +RUN apt-get update && apt-get install -y python3 sudo +RUN python3 /tmp/install_linux_packages.py RUN useradd -m -s /bin/bash bld diff --git a/blender/docker.py b/blender/docker.py index c4ebaa3..447cf3e 100644 --- a/blender/docker.py +++ b/blender/docker.py @@ -1,5 +1,6 @@ import os import docker +import logging from .version import BlenderVersion from pathlib import Path @@ -7,7 +8,7 @@ from docker.errors import BuildError, APIError, ContainerError, ImageNotFound class BlenderDocker: - def __init__(self, blender: BlenderVersion): + def __init__(self, blender: BlenderVersion, severity: int = logging.WARNING): self._blender_version = blender # Todo get a user config self._docker_client = docker.DockerClient(base_url=f'unix:///var/run/docker.sock') @@ -21,12 +22,37 @@ class BlenderDocker: print(f'Dockerfile not found: {self._docker_file}') exit(1) - self.args = { + self._args = { 'b3d_vs_major': f'{self._blender_version.major}', 'b3d_vs_minor': f'{self._blender_version.minor}.{self._blender_version.hotfix}', } + self._severity = severity + + def _get_logger(self, name: str) -> logging.Logger: + """ + Private Method to set a logger for a specific method set (by his name) + :param name: Make the logger file name. + :return: + """ + log_dir = Path('logs') + log_dir.mkdir(parents=True, exist_ok=True) + + logger = logging.getLogger(f'blender_docker.{name}') + logger.setLevel(self._severity) + logger.propagate = False + + if not logger.handlers: + handler = logging.FileHandler(log_dir / f'{name}.log') + handler.setFormatter(logging.Formatter( + '%(asctime)s|%(name)s [%(levelname)s] %(message)s' + )) + logger.addHandler(handler) + + return logger + def login(self): + """Login to the Docker Hub""" try: print('Login to Hub Docker.') self._docker_client.login( @@ -39,28 +65,39 @@ class BlenderDocker: exit(1) def build(self): + """Build the Blender Docker Image""" + logger = self._get_logger('build') try: - print('\tBuilding Blender Docker') - print(f'\tWhere to build: {os.getcwd()}') - print(f'\tArgs: {self.args}') - print(f'\tTag: {self._docker_image_name}') - self._docker_image = self._docker_client.images.build( + logger.info('Building Blender Docker Image') + logger.info(f'\tBuilds withs args: {self._args}') + logger.info(f'\tTag generate: {self._docker_image_name}') + + self._docker_image, build_logs = self._docker_client.images.build( path=os.getcwd(), # nocache=True, - buildargs=self.args, + buildargs=self._args, tag=self._docker_image_name, - quiet=True, + quiet=False, rm=True, forcerm=True ) - print(f'\tBuilding Blender Docker Image done: {self._docker_image}') + # Debug log: + for chunk in build_logs: + if 'stream' in chunk: + line = chunk['stream'].strip() + if line: + logger.debug(line) + + elif 'error' in chunk: + logger.error(chunk['error']) + except BuildError as e: - print("Hey something went wrong with image build!") + logger.exception(f'Build docker image failed: {e}') for line in e.build_log: if 'stream' in line: - print(line['stream'].strip()) + logger.debug(line['stream'].strip()) raise @staticmethod diff --git a/blender/misc.py b/blender/misc.py new file mode 100644 index 0000000..df2e6e2 --- /dev/null +++ b/blender/misc.py @@ -0,0 +1,79 @@ +import logging +import os +import json + +from pathlib import Path +from subprocess import run, CalledProcessError + +# def clean_all_dockers(): +# # bash docker context use default && docker system prune -a -f +# # bash docker context use podman && docker system prune -a -f +# # bash docker context use desktop-linux && docker system prune -a -f +# docker_client = docker.DockerClient(base_url=f'unix:///var/run/docker.sock') + + +def clean_all_dockers(): + """ + Nettoie Docker pour tous les contextes disponibles (default, podman, ...). + Equivalent a, pour chaque contexte : + docker context use + docker system prune -a -f + Puis remet le contexte d'origine en place a la fin. + """ + logs_dir = Path(os.getcwd(), 'logs') + logs_dir.mkdir(parents=True, exist_ok=True) + + logger = logging.getLogger('blender_docker.clean') + logger.setLevel(logging.DEBUG) + logger.propagate = False + if not logger.handlers: + handler = logging.FileHandler(logs_dir / 'clean.log') + handler.setFormatter(logging.Formatter( + '%(asctime)s|%(name)s [%(levelname)s] %(message)s' + )) + logger.addHandler(handler) + + # Contexte courant, pour le restaurer a la fin + original_context = run( + ['docker', 'context', 'show'], + capture_output=True, text=True, check=True + ).stdout.strip() + logger.info(f'Contexte d\'origine: {original_context}') + + # Liste de tous les contextes disponibles (format json, un objet par ligne) + contexts_raw = run( + ['docker', 'context', 'ls', '--format', '{{json .}}'], + capture_output=True, text=True, check=True + ).stdout.strip().splitlines() + contexts = [json.loads(line)['Name'] for line in contexts_raw if line] + + print(f'\tContextes trouves: {contexts}') + logger.info(f'Contextes trouves: {contexts}') + + for context in contexts: + try: + print(f'\tNettoyage du contexte: {context}') + logger.info(f'Nettoyage du contexte: {context}') + + run(['docker', 'context', 'use', context], check=True) + + result = run( + ['docker', 'system', 'prune', '-a', '-f'], + capture_output=True, text=True, check=True + ) + + print(f'\t{result.stdout.strip()}') + logger.info(result.stdout.strip()) + + except CalledProcessError as e: + print(f'\tErreur sur le contexte {context}: {e.stderr.strip()}') + logger.error(f'Erreur sur le contexte {context}: {e.stderr.strip()}') + + # On remet le contexte d'origine + run(['docker', 'context', 'use', original_context], check=True) + print(f'\tContexte restaure: {original_context}') + logger.info(f'Contexte restaure: {original_context}') + + +if __name__ == '__main__': + clean_all_dockers() \ No newline at end of file diff --git a/main.py b/main.py index 534b909..90a0d45 100644 --- a/main.py +++ b/main.py @@ -1,3 +1,5 @@ +from logging import INFO + from blender.version import BlenderVersion from blender.docker import BlenderDocker @@ -9,7 +11,7 @@ if __name__ == "__main__": version = BlenderVersion(input("Give the blender version (X.Y.Z): ")) print(f"Build a blender version {version}.") - docker = BlenderDocker(version) + docker = BlenderDocker(blender=version, severity=INFO) docker.build() print('Test your image.')