Exemplo n.º 1
0
	def do_list(self, args):
		"""List existing images in Talus
		
		image list

		Examples:

		List all images in Talus:

			image list
		"""
		parts = shlex.split(args)

		search = self._search_terms(parts, user_default_filter=False)

		if "sort" not in search:
			search["sort"] = "timestamps.created"

		if "--all" not in parts and "num" not in search:
			search["num"] = 20
			self.out("showing first 20 results, use --all to see everything")

		fields = []
		for image in self._talus_client.image_iter(**search):
			fields.append([
				image.id,
				image.name,
				image.status["name"],
				image.tags,
				self._nice_name(image, "base_image") if image.base_image is not None else None,
				self._nice_name(image, "os"),
				image.md5,
			])

		print(tabulate(fields, headers=Image.headers()))
Exemplo n.º 2
0
    def do_tree(self, args):
        """Show the entire snapshot tree
        """
        parts = shlex.split(args)
        search = self._search_terms(parts, user_default_filter=False)
        search.setdefault("base_image", "null")

        base_images = Image.objects(**search)
        self._print_snapshot_tree(base_images)
Exemplo n.º 3
0
    def _show_image_in_tree(self, image):
        curr_image = image
        tree = []
        curr_image = image
        while curr_image.base_image is not None:
            curr_image = Image.find_one(id=curr_image.base_image)
            tree.append(curr_image)
        tree.reverse()

        lines = []
        idx = 0
        for ancestor_image in tree:
            self._get_tree_lines(ancestor_image, lines, indent_level=idx, recurse=False)
            idx += 1

        image.name = Colors.OKGREEN + image.name + Colors.ENDC
        self._get_tree_lines(image, lines, indent_level=len(tree))

        image.refresh()

        print("Snapshot Tree:")
        print("")
        self._print_snapshot_tree([image], lines=lines)
Exemplo n.º 4
0
	def do_create(self, args):
		"""Create a new image in talus using an existing base image. Anything not explicitly
		specified will be inherited from the base image, except for the name, which is required.

		create -n NAME -b BASEID_NAME [-d DESC] [-t TAG1,TAG2,..] [-u USER] [-p PASS] [-o OSID] [-i]

			     -o,--os    ID or name of the operating system model
		       -b,--base    ID or name of the base image
		       -n,--name    The name of the resulting image (default: basename(FILE))
			   -d,--desc    A description of the image (default: "")
			   -t,--tags    Tags associated with the image (default: [])
			     --shell    Forcefully drop into an interactive shell
		-v,--vagrantfile    A vagrant file that will be used to congfigure the image
		-i,--interactive    To interact with the imported image for setup (default: False)

		Examples:

		To create a new image based on the image with id 222222222222222222222222 and adding
		a new description and allowing for manual user setup:

			image create -b 222222222222222222222222 -d "some new description" -i
		"""
		args = shlex.split(args)
		if self._go_interactive(args):
			image = Image()
			self._prep_model(image)
			image.username = "******"
			image.password = "******"
			image.md5 = " "
			image.desc = "some description"
			image.status = {
				"name": "create",
				"vagrantfile": None,
				"user_interaction": True
			}

			while True:
				model_cmd = self._make_model_cmd(image)
				model_cmd.add_field(
					"interactive",
					Field(True),
					lambda x,v: x.status.update({"user_interaction": v}),
					lambda x: x.status["user_interaction"],
					desc="If the image requires user interaction for configuration",
				)
				model_cmd.add_field(
					"vagrantfile",
					Field(str),
					lambda x,v: x.status.update({"vagrantfile": open(v).read()}),
					lambda x: x.status["vagrantfile"],
					desc="The path to the vagrantfile that will configure the image"
				)
				cancelled = model_cmd.cmdloop()
				if cancelled:
					break

				error = False
				if image.os is None:
					self.err("You must specify the os")
					error = True

				if image.name is None or image.name == "":
					self.err("You must specify a name for the image")
					error = True

				if image.base_image is None:
					self.err("You must specify the base_image for your new image")
					error = True

				if error:
					continue

				try:
					image.timestamps = {"created": time.time()}
					image.save()
					self.ok("created new image {}".format(image.id))
				except errors.TalusApiError as e:
					self.err(e.message)
				else:
					self._wait_for_image(image, image.status["user_interaction"])

				return

		parser = self._argparser()
		parser.add_argument("--os", "-o", default=None)
		parser.add_argument("--base", "-b", default=None)
		parser.add_argument("--name", "-n", default=None)
		parser.add_argument("--desc", "-d", default="")
		parser.add_argument("--tags", "-t", default="")
		parser.add_argument("--vagrantfile", "-v", default=None, type=argparse.FileType("rb"))
		parser.add_argument("--interactive", "-i", action="store_true", default=False)

		args = parser.parse_args(args)

		if args.name is None:
			raise errors.TalusApiError("You must specify an image name")

		vagrantfile_contents = None
		if args.vagrantfile is not None:
			vagrantfile_contents = args.vagrantfile.read()

		if args.tags is not None:
			args.tags = args.tags.split(",")

		error = False
		validation = {
			"os"	: "You must set the os",
			"base"	: "You must set the base",
			"name"	: "You must set the name",
		}
		error = False
		for k,v in validation.iteritems():
			if getattr(args, k) is None:
				self.err(v)
				error = True

		if error:
			parser.print_help()
			return

		image = self._talus_client.image_create(
			image_name				= args.name,
			base_image_id_or_name	= args.base,
			os_id					= args.os,
			desc					= args.desc,
			tags					= args.tags,
			vagrantfile				= vagrantfile_contents,
			user_interaction		= args.interactive
		)

		self._wait_for_image(image, args.interactive)