def a_built_image(self, options, harpoon_options=None, images=None, **kwargs): ident = str(uuid.uuid1()) ident_tag = "{0}:latest".format(ident) conf = self.make_image(options, harpoon_options, **kwargs) if images: images[conf.image_name] = conf conf.image_name = ident if images: images[conf.image_name] = conf cached = Builder().make_image(conf, images) else: cached = Builder().build_image(conf) try: yield cached, conf finally: try: self.docker_client.remove_image(ident_tag) except docker.errors.APIError as error: print("Failed to delete the image", error)
def pull_all(collector, **kwargs): """Pull all the images""" images = collector.configuration["images"] for layer in Builder().layered(images, only_pushable=True): for image_name, image in layer: log.info("Pulling %s", image_name) Syncer().pull(image, ignore_missing=image.harpoon.ignore_missing)
def make_all(overview, configuration, images, **kwargs): """Creates all the images in layered order""" push = configuration["harpoon"].do_push only_pushable = configuration["harpoon"].only_pushable if push: only_pushable = True for layer in Builder().layered(images, only_pushable=only_pushable): for _, image in layer: Builder().make_image(image, images, ignore_deps=True, ignore_parent=True) print("Created image {0}".format(image.image_name)) if push and image.image_index: Syncer().push(image)
def build_and_run(self, images): """Make this image and run it""" Builder().make_image(self, images) try: Runner().run_container(self, images) except DockerAPIError as error: raise BadImage("Failed to start the container", error=error)
def push(overview, configuration, images, image): """Push an image""" if not image.image_index: raise BadOption( "The chosen image does not have a image_index configuration", wanted=image.name) Builder().make_image(image, images) Syncer().push(image)
def pull_all(collector, image, **kwargs): """Pull all the images""" images = collector.configuration["images"] for layer in Builder().layered(images, only_pushable=True): for image_name, image in layer: log.info("Pulling %s", image_name) pull(collector, image, **kwargs)
def push(collector, image, **kwargs): """Push an image""" if not image.image_index: raise BadOption( "The chosen image does not have a image_index configuration", wanted=image.name) Builder().make_image(image, collector.configuration["images"], pushing=True) Syncer().push(image)
def show(overview, configuration, images, **kwargs): """Show what images we have""" flat = configuration.get("harpoon.flat", False) only_pushable = configuration.get("harpoon.only_pushable", False) for index, layer in enumerate(Builder().layered( images, only_pushable=only_pushable)): if flat: for _, image in layer: print(image.image_name) else: print("Layer {0}".format(index)) for _, image in layer: print(" {0}".format(image.display_line())) print("")
def push(collector, image, **kwargs): """Push an image""" if not image.image_index: raise BadOption( "The chosen image does not have a image_index configuration", wanted=image.name) tag = kwargs["artifact"] if tag is NotSpecified: tag = collector.configuration["harpoon"].tag if tag is not NotSpecified: image.tag = tag Builder().make_image(image, collector.configuration["images"], pushing=True) Syncer().push(image)
def make_all(collector, **kwargs): """Creates all the images in layered order""" configuration = collector.configuration push = configuration["harpoon"].do_push only_pushable = configuration["harpoon"].only_pushable if push: only_pushable = True tag = kwargs.get("artifact", NotSpecified) if tag is NotSpecified: tag = configuration["harpoon"].tag images = configuration["images"] for layer in Builder().layered(images, only_pushable=only_pushable): for _, image in layer: if tag is not NotSpecified: image.tag = tag Builder().make_image(image, images, ignore_deps=True, ignore_parent=True) print("Created image {0}".format(image.image_name)) if push and image.image_index: Syncer().push(image)
conf.harpoon.docker_context.remove_image(ident) for unwanted in (conf.image_name, "{0}:latest".format(conf.image_name), "{0}-tester:latest".format(conf.image_name)): if unwanted in originals["tags"]: print("Removing unwanted image: {0}".format(unwanted)) conf.harpoon.docker_context.remove_image(unwanted) set_originals() ######################## ### TEST DEFINITIONS ######################## @test it "just runs the docker commands and action the first time along with the tester image": cached = Builder().make_image(conf, {conf.name: conf}) collected["images"].append(conf.image_name) assert_only_extra_tags("{0}:latest".format(conf.image_name), "{0}-tester:latest".format(conf.image_name)) last_id = None commands = [] for line in conf.harpoon.docker_context.history(conf.image_name): if os.environ["BASE_IMAGE"] in (line["Tags"] or []): break last_id = line['Id'] commands.append(line["CreatedBy"]) self.assertEqual(commands , [ '/bin/sh -c #(nop) CMD ["/bin/sh" "-c" "sh"]' , '/bin/sh -c sh -c \'cat /tmp/lines > /tmp/lines2; echo \'"\'"\'another_line\'"\'"\' >> /tmp/lines2; mv /tmp/lines2 /tmp/lines\''
def make(overview, configuration, images, image): """Just create an image""" Builder().make_image(image, images) print("Created image {0}".format(image.image_name))
if "harpoon" not in options: options["harpoon"] = harpoon everything = {"harpoon": harpoon, "mtime": mtime, "_key_name_1": "awesome_image", "config_root": config_root} return HarpoonSpec().image_spec.normalise(Meta(everything, []), options) it "Builds an image": ident = str(uuid.uuid1()) ident_tag = "{0}:latest".format(ident) images = self.docker_client.images() repo_tags = [image["RepoTags"] for image in images] assert all(ident_tag not in repo_tag_list for repo_tag_list in repo_tags), images conf = self.make_image({"context": False, "commands": ["FROM {0}".format(os.environ["BASE_IMAGE"])]}) conf.image_name = ident Builder().build_image(conf) images = self.docker_client.images() repo_tags = [image["RepoTags"] for image in images] assert any(ident_tag in repo_tag_list for repo_tag_list in repo_tags), "Couldn't find {0} in {1}".format(ident_tag, images) self.docker_client.remove_image(ident_tag) it "knows if the build was cached": from_line = "FROM {0}".format(os.environ["BASE_IMAGE"]) commands1 = [from_line] commands2 = [from_line, "RUN echo {0}".format(uuid.uuid1())] commands3 = commands2 + [["ADD", {"content": "blah", "dest": "/tmp/blah", "mtime": mtime}]] with self.a_built_image({"context": False, "commands": commands1}) as (cached, conf1): assert cached
def make(collector, image, **kwargs): """Just create an image""" Builder().make_image(image, collector.configuration["images"]) print("Created image {0}".format(image.image_name))
def pull(self, conf, ignore_missing=False): """Push this image""" with Builder().remove_replaced_images(conf): self.push_or_pull(conf, "pull", ignore_missing=ignore_missing)
def pull_parents(collector, **kwargs): """Pull all the parents of the images""" images = collector.configuration["images"] for layer in Builder().layered(images, only_pushable=True): for image_name, image in layer: pull_parent(collector, image, ignore_defined=True)