def test_image_deletion(dockerhost, helloworld_image): with create_docker_client() as client: try: client.images.get('hello-world') except docker.errors.ImageNotFound: pytest.fail('Fixture image hello-world was not pulled') dockerhost.remove_image(helloworld_image) with create_docker_client() as client: with pytest.raises(docker.errors.ImageNotFound): client.images.get('hello-world')
def logs(self, instance: DockerContainer, env: DockerHost, **kwargs) -> Generator[str, None, None]: self._validate(instance, env) with create_docker_client(env.host) as client: container = client.containers.get(instance.name) yield from self._logs(container, **kwargs)
def run(self, instance: DockerContainer, image: DockerImage, env: DockerHost, rm=True, detach=True, **kwargs): if not (isinstance(instance, DockerContainer) and isinstance( image, DockerImage) and isinstance(env, DockerHost)): raise TypeError( 'DockerRunner works with DockerContainer, DockerImage and DockerHost only' ) with create_docker_client(env.host) as client: login_to_registry(client, image.registry) from docker.errors import ContainerError # FIXME try: # always detach from container and just stream logs if detach=False container = client.containers.run(image.get_uri(), name=instance.name, auto_remove=rm, ports=instance.ports_mapping, detach=True, **instance.params, **kwargs) if not detach: try: # infinite loop of logs while container running or if everything ok for log in self._logs(container, stream=True): logger.debug(log) self._sleep() if not self._is_service_running(client, instance.name): raise DockerRunnerException( "The container died unexpectedly.") except KeyboardInterrupt: logger.info('Interrupted. Stopping the container') container.stop() else: self._sleep() if not self._is_service_running(client, instance.name): if not rm: for log in self._logs(container, stdout=False, stderr=True): raise DockerRunnerException( "The container died unexpectedly.", log) else: # Can't get logs from removed container raise DockerRunnerException( "The container died unexpectedly. Try to run the container " "with detach=False or rm=False args to get more info." ) except ContainerError as e: if e.stderr: print(e.stderr.decode(), file=sys.stderr) raise
def has_local_image(img_name: str) -> bool: if not has_docker(): return False with create_docker_client() as client: try: client.images.get(img_name) except docker.errors.ImageNotFound: return False return True
def get_image_output(image_params): image_uri = image_params.get_uri() with create_docker_client() as client: if isinstance(image_params.registry, RemoteDockerRegistry): # remove to ensure that image was pushed to remote registry, if so following `run` call will pull it back client.images.remove(image_uri) try: yield client.containers.run(image_uri, remove=True).decode('utf8').strip() except docker.errors.ContainerError as e: yield e.stderr.decode('utf8') finally: client.images.remove(image_uri)
def _build_image(self, context_dir): tag = self.params.get_uri() logger.debug('Building docker image %s from %s...', tag, context_dir) with create_docker_client() as client: login_to_registry(client, self.params.registry) if not self.force_overwrite: try: client.images.get(tag) raise ValueError( f'Image {tag} already exists. Change name or set force_overwrite=True.' ) except errors.ImageNotFound: pass else: try: client.images.remove( tag) # to avoid spawning dangling images except errors.ImageNotFound: pass try: _, logs = client.images.build(path=context_dir, tag=tag, rm=True) logger.info('Built image %s', tag) _print_docker_logs(logs) if isinstance(self.params.registry, RemoteDockerRegistry): client.images.push(tag) logger.info( 'Pushed image %s to remote registry at host %s', tag, self.params.registry.host) return Image(tag, params=self.params) except errors.BuildError as e: _print_docker_logs(e.build_log, logging.ERROR) raise
def helloworld_image(): with create_docker_client() as client: client.images.pull('hello-world:latest') image = Image('hello-world', 0, 0, Image.Params()) image.params.name = 'hello-world' yield image
def rm_image(image_tag: str, host: str = ''): with create_docker_client(host) as client: tags = [t for i in client.images.list() for t in i.tags] if any(image_tag == t for t in tags): client.images.remove(image_tag, force=True)
def rm_container(container_name: str, host: str = ''): with create_docker_client(host) as client: containers = client.containers.list() if any(container_name == c.name for c in containers): client.containers.get(container_name).remove(force=True)
def stop(self, instance: DockerContainer, env: DockerHost, **kwargs): self._validate(instance, env) with create_docker_client(env.host) as client: container = client.containers.get(instance.name) container.stop()
def is_running(self, instance: DockerContainer, env: DockerHost, **kwargs) -> bool: self._validate(instance, env) with create_docker_client(env.host) as client: return self._is_service_running(client, instance.name)