def test_pull_base_image_with_registry(tmpdir): mock_docker() source_params = {"provider": "path", "uri": "file://%s" % str(tmpdir), "tmpdir": str(tmpdir)} with open(os.path.join(str(tmpdir), DOCKERFILE_FILENAME), "wt") as fp: fp.writelines(["FROM %s/namespace/repo:tag\n" % LOCALHOST_REGISTRY]) s = get_source_instance_for(source_params) t = DockerTasker() b = InsideBuilder(s, "") pulled_tags = b.pull_base_image(LOCALHOST_REGISTRY, insecure=True) assert isinstance(pulled_tags, set)
def test_pull_base_image(tmpdir, source_params): if MOCK: mock_docker() source_params.update({"tmpdir": str(tmpdir)}) s = get_source_instance_for(source_params) t = DockerTasker() b = InsideBuilder(s, "") pulled_tags = b.pull_base_image(LOCALHOST_REGISTRY, insecure=True) assert isinstance(pulled_tags, set) assert len(pulled_tags) == 2 for reg_img_name in pulled_tags: reg_img_name = ImageName.parse(reg_img_name) assert t.inspect_image(reg_img_name) is not None assert reg_img_name.repo == git_base_image.repo assert reg_img_name.tag == git_base_image.tag # clean t.remove_image(git_base_image)
class DockerBuildWorkflow(object): """ This class defines a workflow for building images: 1. pull image from registry 2. tag it properly if needed 3. obtain source 4. build image 5. tag it 6. push it to registries """ def __init__(self, source, image, parent_registry=None, target_registries=None, prebuild_plugins=None, prepublish_plugins=None, postbuild_plugins=None, plugin_files=None, parent_registry_insecure=False, target_registries_insecure=False, dont_pull_base_image=False, **kwargs): """ :param source: dict, where/how to get source code to put in image :param image: str, tag for built image ([registry/]image_name[:tag]) :param parent_registry: str, registry to pull base image from :param target_registries: list of str, list of registries to push image to (might change in future) :param prebuild_plugins: dict, arguments for pre-build plugins :param prepublish_plugins: dict, arguments for test-build plugins :param postbuild_plugins: dict, arguments for post-build plugins :param plugin_files: list of str, load plugins also from these files :param parent_registry_insecure: bool, allow connecting to parent registry over plain http :param target_registries_insecure: bool, allow connecting to target registries over plain http :param dont_pull_base_image: bool, don't pull or update base image specified in dockerfile """ self.source = get_source_instance_for(source, tmpdir=tempfile.mkdtemp()) self.image = image self.parent_registry = parent_registry self.parent_registry_insecure = parent_registry_insecure self.prebuild_plugins_conf = prebuild_plugins self.prepublish_plugins_conf = prepublish_plugins self.postbuild_plugins_conf = postbuild_plugins self.prebuild_results = {} self.postbuild_results = {} self.plugin_files = plugin_files self.kwargs = kwargs self.builder = None self.build_logs = None self.built_image_inspect = None self.base_image_inspect = None self.dont_pull_base_image = dont_pull_base_image self.pulled_base_images = set() # squashed image tarball # set by squash plugin self.exported_squashed_image = {} self.tag_conf = TagConf() self.push_conf = PushConf() if target_registries: self.push_conf.add_docker_registries(target_registries, insecure=target_registries_insecure) # mapping of downloaded files; DON'T PUT ANYTHING BIG HERE! # "path/to/file" -> "content" self.files = {} if kwargs: logger.warning("unprocessed keyword arguments: %s", kwargs) def build_docker_image(self): """ build docker image :return: BuildResults """ self.builder = InsideBuilder(self.source, self.image) try: if not self.dont_pull_base_image: self.pulled_base_images = self.builder.pull_base_image(self.parent_registry, insecure=self.parent_registry_insecure) self.base_image_inspect = self.builder.tasker.inspect_image(self.builder.base_image) # time to run pre-build plugins, so they can access cloned repo, # base image logger.info("running pre-build plugins") prebuild_runner = PreBuildPluginsRunner(self.builder.tasker, self, self.prebuild_plugins_conf, plugin_files=self.plugin_files) try: prebuild_runner.run() except PluginFailedException as ex: logger.error("one or more prebuild plugins failed: %s", ex) return build_result = self.builder.build() self.build_logs = build_result.logs if not build_result.is_failed(): self.built_image_inspect = self.builder.inspect_built_image() # run prepublish plugins prepublish_runner = PrePublishPluginsRunner(self.builder.tasker, self, self.prepublish_plugins_conf, plugin_files=self.plugin_files) try: prepublish_runner.run() except PluginFailedException as ex: logger.error("one or more prepublish plugins failed: %s", ex) return if not build_result.is_failed(): for registry in self.push_conf.docker_registries: self.builder.push_built_image(registry.uri, insecure=registry.insecure) postbuild_runner = PostBuildPluginsRunner(self.builder.tasker, self, self.postbuild_plugins_conf, plugin_files=self.plugin_files) try: postbuild_runner.run() except PluginFailedException as ex: logger.error("one or more postbuild plugins failed: %s", ex) return return build_result finally: self.source.remove_tmpdir()