diff --git a/.run/Automation Builder.run.xml b/.run/Automation Builder.run.xml new file mode 100644 index 0000000..e9c8ff4 --- /dev/null +++ b/.run/Automation Builder.run.xml @@ -0,0 +1,26 @@ + + + + + \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index d986d8f..c2f57c2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:latest AS b3dock +FROM ubuntu:25.10 AS b3dock # Setup all software version request ARG b3d_vs_major=5.2 @@ -6,36 +6,34 @@ ARG b3d_vs_minor=0 LABEL Author="stilobique" LABEL Title="Blender Docker for Unit Test" -LABEL maintainer="Aurelien Vaillant contact@aurelien-vaillant.net" +LABEL Maintainer="Aurelien Vaillant contact@aurelien-vaillant.net" #ENV TZ=Europe/Paris #RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone ## 01. Start First stage to build blender # Install dependencies -RUN apt-get update && apt-get install -y git git-lfs +RUN apt-get update && apt-get install -y git git-lfs python3 sudo # Compile Blender RUN git clone --depth 1 --branch v${b3d_vs_major}.${b3d_vs_minor} \ - https://projects.blender.org/blender/blender.git /opt/blender - -# Get dependencies -COPY ./scripts/gen_packages_txt.py /opt/blender/build_files/build_environment/gen_packages_txt.py -RUN cd /opt/blender/build_files/build_environment && \ - python gen_packages_txt.py -RUN cd /opt/blender/build_files/build_environment && chmod a+x ./install_linux_packages.py && \ - python install_linux_packages.py - -RUN cd /opt/blender && make update -RUN cd /opt/blender && make -j$(nproc) + https://projects.blender.org/blender/blender.git /opt/blender && \ + chmod a+x /opt/blender/build_files/build_environment/install_linux_packages.py && \ + python3 /opt/blender/build_files/build_environment/install_linux_packages.py + +RUN cd /opt/blender && \ + make update && \ + make -j$(nproc) ## 02. Build optimissed image ## Setup a Multistage optimisation -FROM ubuntu:25.04 AS final +FROM ubuntu:25.10 AS final -COPY --from=b3dock /opt/blender/build_files/build_environment/packages.txt /tmp/packages.txt -RUN apt-get update && xargs -a /tmp/packages.txt apt-get install -y +#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 useradd -m -s /bin/bash bld diff --git a/blender/docker.py b/blender/docker.py index e15f507..c4ebaa3 100644 --- a/blender/docker.py +++ b/blender/docker.py @@ -3,16 +3,18 @@ import docker from .version import BlenderVersion from pathlib import Path -from docker.errors import BuildError +from docker.errors import BuildError, APIError, ContainerError, ImageNotFound class BlenderDocker: def __init__(self, blender: BlenderVersion): self._blender_version = blender # Todo get a user config - # self._docker_client = docker.DockerClient(base_url=f'unix://{Path.home()}/.docker/desktop/docker.sock') self._docker_client = docker.DockerClient(base_url=f'unix:///var/run/docker.sock') + self.login() self._docker_image = None + self._repository = 'stilobique/blender' + self._docker_image_name = self._blender_version.format_to_tag(self._repository) self._docker_file = Path(os.getcwd(), 'Dockerfile') if not self._docker_file.exists(): @@ -23,21 +25,36 @@ class BlenderDocker: 'b3d_vs_major': f'{self._blender_version.major}', 'b3d_vs_minor': f'{self._blender_version.minor}.{self._blender_version.hotfix}', } + + def login(self): + try: + print('Login to Hub Docker.') + self._docker_client.login( + username=os.environ['DOCKER_HUB_USER'], + password=os.environ['DOCKER_HUB_PASSWORD'] + ) + + except APIError as e: + print(f'Login failed with error: {e}') + exit(1) + def build(self): try: print('\tBuilding Blender Docker') print(f'\tWhere to build: {os.getcwd()}') print(f'\tArgs: {self.args}') - print(f'\tTage generated: {self._blender_version.format_to_tag()}') - build = self._docker_client.images.build( - path=os.getcwd(), - buildargs=self.args, - tag=self._blender_version.format_to_tag(), - quiet=False, + print(f'\tTag: {self._docker_image_name}') + self._docker_image = self._docker_client.images.build( + path=os.getcwd(), + # nocache=True, + buildargs=self.args, + tag=self._docker_image_name, + quiet=True, + rm=True, + forcerm=True ) - print(f'\tBuilding Blender Docker Image done: {build}') - return build + print(f'\tBuilding Blender Docker Image done: {self._docker_image}') except BuildError as e: print("Hey something went wrong with image build!") @@ -51,13 +68,44 @@ class BlenderDocker: print('\tSet Tags version and/or Latest') pass - @staticmethod def test(self): - print('\tTesting Blender Docker') - # docker run --rm stilobique/blender:5.1.2 ./blender --version - pass - + try: + print('\tTesting your Blender Docker image') + print(f'\tLoad: {self._docker_image_name}') + + test = self._docker_client.containers.run( + name=f"Blender-Docker-Testing-{self._blender_version.tag_name_slugify()}", + image=self._docker_image_name, + command=['./blender', '--version'], + auto_remove = True, + remove=True, + detach=True, + stdout=True + ) + + print(f'\tResult: {test.logs()}') + + return True + + except ContainerError as e: + print(f'Container error: {e}') + exit(1) + + except ImageNotFound as e: + print(f'Image not found: {e}') + exit(1) + + except APIError as e: + print(f'API error: {e}') + for line in e.build_log: + if 'stream' in line: + print(line['stream'].strip()) + exit(1) + def push(self): - # TODO Login to hub - pass + self._docker_client.images.push( + repository=self._repository, + tag=self._blender_version.tag_name(), + stream=True, + ) \ No newline at end of file diff --git a/blender/version.py b/blender/version.py index 4fa09ea..5f61284 100644 --- a/blender/version.py +++ b/blender/version.py @@ -18,9 +18,16 @@ class BlenderVersion: self.minor = version[1] self.hotfix = version[2] - def format_to_tag(self) -> str: + def format_to_tag(self, repository: str) -> str: """From version information, format to return a string""" + return f'{repository}:{self.major}.{self.minor}.{self.hotfix}' + + def tag_name(self) -> str: + """Return the tag name 'latest', 'X.Y.Z'...""" return f'{self.major}.{self.minor}.{self.hotfix}' + + def tag_name_slugify(self): + return f'{self.major}-{self.minor}-{self.hotfix}' def __str__(self): return str(self.major + '.' + self.minor + '.' + self.hotfix) \ No newline at end of file diff --git a/main.py b/main.py index 666d57c..534b909 100644 --- a/main.py +++ b/main.py @@ -1,45 +1,23 @@ -import os - from blender.version import BlenderVersion from blender.docker import BlenderDocker -# TODO Update readme file badge with blender version -# TODO add a check if the image build are stored in the docker register -def build_docker(b3d_version: (str, str), latest: bool = False): - """ - Generate docker image, request the blender version (major, minor) with the keyword b3d_version, and can be - tagged with latest or only blender version info. - """ - client = docker.from_env() - if os.environ.get('docker_hub_password'): - client.login(username=os.environ['docker_hub_user'], password=os.environ['docker_hub_password']) - - # Init all data to build the docker image - args = { - 'b3d_vs_major': str(b3d_version[0]), - 'b3d_vs_minor': str(b3d_version[1]), - } - docker_repo = 'stilobique/blender' - if latest: - tag = 'latest' - else: - tag = f'{args["b3d_vs_major"]}.{args["b3d_vs_minor"]}' - completed_tag_name = f'{docker_repo}:{args["b3d_vs_major"]}.{args["b3d_vs_minor"]}' - - print('\t1 -> Build from image file') - client.images.build(path=os.getcwd(), buildargs=args, tag=completed_tag_name, rm=True, forcerm=True) - - print(f'\t2 -> Push the new images with tag {tag}') - push = client.images.push(repository=docker_repo, tag=tag, stream=True) - print(f'\t\tDebug push :\n\t\t{push}') +# Todo Update readme file badge with blender version if __name__ == "__main__": + # Todo use the manual entry can be error prone (need to make a basic regex to check this entry) version = BlenderVersion(input("Give the blender version (X.Y.Z): ")) - - # build_docker(b3d_version=(f'{version.major}', f'{version.minor}.{version.hotfix}'), - # latest=False) print(f"Build a blender version {version}.") docker = BlenderDocker(version) - docker.build() \ No newline at end of file + docker.build() + + print('Test your image.') + test = docker.test() + + if test: + print('Push this image.') + docker.push() + + # Todo: Add a latest tag, check if this version are the latest + # Todo: Add a LTS tag, check if this version are a LTS \ No newline at end of file