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.')