class TestName:
    image_test = False
    vbox = '6.0.4'
    image_name = "generic/ubuntu1810"
    size = 1024
    cloud = "vagrant"

    def print_images(self):
        images = self.p.images()
        print(
            Printer.flatwrite(images,
                              sort_keys=["name"],
                              order=["name", "provider", "version"],
                              header=["Name", "Provider", "Version"]))

    def next_name(self):
        self.name_generator.incr()
        self.new_name = str(self.name_generator)
        return self.new_name

    def setup(self):
        banner("setup", c="-")
        self.user = Config()["cloudmesh.profile.user"]
        self.name_generator = Name(experiment="exp",
                                   group="grp",
                                   user=self.user,
                                   kind="vm",
                                   counter=1)

        self.name = str(self.name_generator)
        self.name_generator.incr()
        self.new_name = str(self.name_generator)
        self.p = Provider(name=self.cloud)

    def test_01_version(self):
        HEADING()
        r = self.p.version()
        pprint(r)
        assert self.vbox_version == r["virtualbox"]["extension"]["version"]
        assert self.vbox_version == r["virtualbox"]["version"]

    def test_02_list_os(self):
        HEADING()
        ostypes = self.p.list_os()
        print(
            Printer.write(ostypes,
                          order=[
                              "id", "64_bit", "description", "family_descr",
                              "family_id"
                          ],
                          header=[
                              "id", "64_bit", "description", "family_descr",
                              "family_id"
                          ]))

    def test_03_name(self):
        HEADING()
        print(self.name)
        assert self.name == "exp-grp-{user}-vm-1".format(user=self.user)

    def test_04_list_images(self):
        HEADING()
        self.print_images()

    def test_05_delete_image(self):
        HEADING()
        if self.image_test:
            name = "generic/ubuntu1810"
            try:
                images = self.p.delete_image(self.image_name)
                print("delete", self.image_name)
            except:
                print("image", self.image_name, "nor found")
            self.print_images()
        else:
            print("not executed as image_test is not True. ok")

    def test_06_add_image(self):
        HEADING()
        if self.image_test:
            images = self.p.add_image(self.image_name)
            print("I", images)
            self.print_images()
            assert images.status == 0
        else:
            print("not executed as image_test is not True. ok")

    def test_07_list_vm(self):
        HEADING()

        vms = self.p.info()
        pprint(vms)
        print(
            Printer.flatwrite(
                vms,
                order=[
                    "vagrant.name", "vbox.name", "vagrant.id",
                    "vagrant.provider", "vagrant.state", "vagrant.hostname"
                ],
                header=["name", "vbox", "id", "provider", "state",
                        "hostname"]))

    def test_10_create(self):
        HEADING()

        name = self.next_name()

        print("Name", name)

        self.p.create(
            name=self.name,
            image=self.image_name,
            size=self.size,
            # username as the keypair name based on
            # the key implementation logic
            ex_keyname=self.user,
            ex_security_groups=['default'])

        directory = Path(
            path_expand("~/.cloudmesh/vagrant/exp-grp-gregor-vm-1"))

        assert directory.is_dir()

        time.sleep(5)
        nodes = self.p.list()
        pprint(nodes)

        node = self.p.find(nodes, name=self.name)
        pprint(node)

        nodes = self.p.list(raw=False)
        for node in nodes:
            if node.name == self.name:
                self.testnode = node
                break

        assert node is not None
Example #2
0
class Provider(object):
    def __init__(self,
                 name=None,
                 configuration="~/.cloudmesh/.cloudmesh4.yaml"):
        self.kind = Config(
            configuration)["cloudmesh"]["cloud"][name]["cm"]["kind"]
        self.name = name

        # Console.msg("FOUND Kind", self.kind)

        if self.kind in ["openstack", "aws"]:
            self.p = LibCloudProvider(name=name, configuration=configuration)
        elif self.kind in ["vagrant", "virtualbox"]:
            self.p = VirtualboxCloudProvider(name=name,
                                             configuration=configuration)

    def cloudname(self):
        return self.name

    @DatabaseUpdate()
    def keys(self):
        return self.p.keys()

    @DatabaseUpdate()
    def list(self):
        return self.p.list()

    @DatabaseUpdate()
    def images(self):
        return self.p.images()

    @DatabaseUpdate()
    def flavor(self):
        return self.p.flavors()

    def add_collection(self, d, *args):
        if d is None:
            return None
        label = '-'.join(args)
        for entry in d:
            entry['collection'] = label
        return d

    @DatabaseUpdate()
    def images(self):
        return self.p.images()

    # name
    # cloud
    # kind
    @DatabaseUpdate()
    def flavors(self):
        return self.p.flavors()

    def start(self, name=None):
        return self.p.start(name=name)

    def stop(self, name=None):
        return self.p.stop(name=name)

    def info(self, name=None):
        return self.p.info(name=name)

    def resume(self, name=None):
        return self.p.resume(name=name)

    def reboot(self, name=None):
        return self.p.reboot(name=name)

    def create(self, name=None, image=None, size=None, timeout=360, **kwargs):
        self.p.create(name=name, image=image, size=size, timeout=360, **kwargs)

    def rename(self, name=None, destination=None):
        self.p.rename(name=name, destination=name)
Example #3
0
class Vm(ComputeNodeABC):
    def __init__(self, cloud):
        self.mongo = CmDatabase()
        self.config = Config().data["cloudmesh"]
        self.kind = self.config["cloudmesh"][cloud]["cm"]["kind"]
        super().__init__(cloud, self.config)

        if self.kind == 'azure':
            self.provider = LibcloudProvider(self.config)
        elif self.kind == 'aws':
            self.provider = LibcloudProvider(self.config)
        elif self.kind == 'vm':
            self.provider = LibcloudProvider("chameleon")
        elif self.kind == "vbox":  # not sure about vbox vs vagrant in vbox provider
            self.provider = VboxProvider("vagrant")
        else:
            raise NotImplementedError(f"Cloud `{self.kind}` not supported.")

    @DatabaseUpdate(collection="cloudmesh", ComputeNodeABC.map_default)
    def start(self, name):
        """
        start the node based on the id
        :param name:
        :return: VM document
        """
        info = self.info(name)
        if info["state"] != "running":
            info = self.provider.start(name)
        return info

    @DatabaseUpdate(collection="cloudmesh", ComputeNodeABC.map_default)
    def stop(self, name=None):
        """
        stop the node based on the ide
        :param name:
        :return: VM document
        """
        return self.provider.stop(name)

    @DatabaseUpdate(collection="cloudmesh", ComputeNodeABC.map_default)
    def resume(self, name=None):
        """
        start the node based on id
        :param name:
        """
        return self.start(name)

    @DatabaseUpdate(collection="cloudmesh", ComputeNodeABC.map_default)
    def suspend(self, name=None):
        """
        stop the node based on id
        :param name:
        """
        return self.provider.suspend(name)

    @DatabaseUpdate(collection="cloudmesh", ComputeNodeABC.map_default)
    def destroy(self, name=None):
        """
        delete the node based on id
        :param name:
        :return: True/False
        """
        result = self.provider.destroy(name)
        # self.mongo.delete_document('cloud', 'name', name)
        return result

    @DatabaseUpdate(collection="cloudmesh", ComputeNodeABC.map_vm_create)
    def create(self, name=None):
        """
        create a new node
        :param name: the name for the new node
        :return:
        """
        name = name or self.new_name()
        return self.provider.create(name=name)

    @DatabaseUpdate(collection="cloudmesh", ComputeNodeABC.map_default)
    def nodes(self):
        return self.provider.vagrant_nodes()

    # @DatabaseUpdate(collection="cloudmesh", ComputeNodeManagerABC._map_default)
    def info(self, name=None):
        """
        show node information based on id

        TODO: seems like this should look in mongo, not self.nodes
            probably the solution is a more broad change to dynamically
            set the provider based on a name/cloud lookup in mongo.

        :param name:
        :return: all information about one node
        """
        return self.provider.info(name)

    def new_name(self, experiment=None, group=None, user=None):
        """
        Generate a VM name with the format `experiment-group-name-<counter>` where `counter`
        represents a running count of VMs created.

        Defaults can be modified in the cloudmesh4.yaml file.

        :param experiment:
        :param group:
        :param user:
        :return: The generated name.
        """
        experiment = experiment or self.config["default"]["experiment"]
        group = group or self.config["default"]["group"]
        user = user or getpass.getuser()

        counter = Counter()
        count = counter.get()
        name = Name()
        name_format = {
            'experiment': experiment,
            'group': group,
            'user': user,
            'counter': count
        }
        name.set_schema('instance')
        counter.incr()
        return name.get(name_format)

    def get_public_ips(self, name=None):
        """
        Returns all the public ips available if a name is not given.
        If a name is provided, the ip of the vm name would be returned.
        :param name: name of the VM.
        :return: Dictionary of VMs with their public ips
        """
        if name is None:
            filters = {"$exists": True, "$not": {"$size": 0}}
            documents = self.mongo.find('cloud', 'public_ips', filters)
            if documents is None:
                return None
            else:
                result = {}
                for document in documents:
                    result[document['name']] = document['public_ips']
                return result
        else:
            public_ips = self.mongo.find_document('cloud', 'name',
                                                  name)['public_ips']
            if not public_ips:
                return None
            else:
                return {name: public_ips}

    def set_public_ip(self, name, public_ip):
        """
        Assign the given public ip to the given VM.
        :param name: name of the VM
        :param public_ip: public ip to be assigned.
        """
        if name is not None and public_ip is not None:
            self.provider.set_public_ip(name, public_ip)

    def remove_public_ip(self, name):
        """
        Deletes the public ip of the given VM.
        :param name: name of the VM
        """
        if name is not None:
            self.provider.remove_public_ip(name)