def build_docker_image(name: str, obj, server: Server = None, env: DockerEnv = None, tag: str = 'latest', repository: str = None, force_overwrite: bool = False, **kwargs) -> Image: """Build docker image from object :param name: name of the resultimg image :param obj: obj to build image. must be convertible to Buildable: Model, Pipeline, list of one of those, etc. :param server: server to build image with :param env: DockerEnv to build in. Default - local docker daemon :param tag: image tag :param repository: image repository :param force_overwrite: wheter to force overwrite existing image :parma kwargs: additional arguments for DockerBuilder.build_image """ if server is None: try: from ebonite.ext.flask import FlaskServer server = FlaskServer() except ImportError: raise RuntimeError( 'cannot use default FlaskServer - flask or flasgger are not installed' ) env = env or DockerEnv() source = BuildableAnalyzer.analyze(obj, server=server) builder: DockerBuilder = env.get_builder() params = builder.create_image(name, env, tag, repository) builder.build_image(source, params, env, force_overwrite, **kwargs) image = Image(name, source, params=params) image.environment = RuntimeEnvironment('temp_env', params=env) return image.bind_builder(builder)
def delete_image(self, image: Image, meta_only: bool = False, cascade: bool = False): """" Deletes existing image from metadata repository and image provider :param image: image ot delete :param meta_only: should image be deleted only from metadata :param cascade: whether to delete nested RuntimeInstances """ return image.delete(meta_only, cascade)
def create_image(self, obj, name: str = None, task: Task = None, server: Server = None, environment: RuntimeEnvironment = None, debug=False, skip_build=False, builder_args: Dict[str, object] = None, **kwargs) -> Image: """ Builds image of model service and stores it to repository :param obj: model/list of models/pipeline or any object that has existing Hook for it to wrap into service :param name: name of image to build :param task: task to put image into :param server: server to build image with :param environment: env to build for :param debug: flag to build debug image :param skip_build: wheter to skip actual image build :param builder_args: kwargs for image.build :param kwargs: additional kwargs for builder :return: :class:`~ebonite.core.objects.Image` instance representing built image """ from ebonite.core.analyzer.buildable import BuildableAnalyzer if server is None: server = self.get_default_server() if environment is None: environment = self.get_default_environment() buildable = BuildableAnalyzer.analyze( obj, server=server, debug=debug).bind_meta_repo(self.meta_repo) task = task or buildable.task if task is None: raise ValueError( f'cannot infer task for buildable {buildable}, please provide it manually' ) if name is not None and self.meta_repo.get_image_by_name( name, task) is not None: raise ExistingImageError(name) builder = environment.params.get_builder() image = Image(name, buildable) image.params = builder.create_image(image.name, environment.params, **kwargs) image.task = task image.environment = environment self.meta_repo.create_image(image) if not skip_build: try: image.build(**(builder_args or {})) except Exception: self.meta_repo.delete_image(image) raise return self._bind(self.meta_repo.save_image(image))
def factory(docker_env: DockerEnv): envs.append(docker_env) with docker_env.daemon.client() as c: image = c.images.pull( 'hello-world:latest') # pull hello-world image if isinstance(image, list): image = image[0] docker_image = DockerImage(f'{HELLO_WORLD_NAME}_{len(envs)}', registry=docker_env.registry) image.tag(docker_image.uri ) # tag image as *registry*/ebonite-hello-world if isinstance(docker_env.registry, RemoteRegistry): c.images.push(docker_image.uri) # push tag to repository c.images.remove(docker_image.uri) # remove from local registry return Image('hello-world', BuildableMock(), 0, docker_image)
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