import os import docker from .version import BlenderVersion from pathlib import Path 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:///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(): print(f'Dockerfile not found: {self._docker_file}') exit(1) self.args = { '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'\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: {self._docker_image}') except BuildError as e: print("Hey something went wrong with image build!") for line in e.build_log: if 'stream' in line: print(line['stream'].strip()) raise @staticmethod def tag(self): print('\tSet Tags version and/or Latest') pass def test(self): 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): self._docker_client.images.push( repository=self._repository, tag=self._blender_version.tag_name(), stream=True, )