Beispiel #1
0
    def do_terminal(self, args, arguments):
        """
        ::

          Usage:
              terminal [--os=OS]
                       [--command=COMMAND]
                       [--shell=SHELL]
                       [--interactive=INTERACTIVE]
                       [--window=WINDOW]

          Starts a docker container in interactive mode in a new terminal
          and executes the command in it.

          Arguments:
              --command=COMMAND   the command
              --os=OS        the os      [default: cloudmesh/book:latest]
              --shell=SHELL              [default: /bin/bash]
              --window=WINDOW            [default: True]
              --interactive=INTERACTIVE  [default: True]

          Options:
              -f      specify the file


          Description:
              terminal --os="cloudmesh/book:1.7" --command=ls
        """

        # m = Manager()

        map_parameters(arguments, 'os', 'command', 'interactive', 'shell',
                       'window')
        arguments.cwd = os.getcwd()

        if arguments.command is None:
            arguments.command = ""
        else:
            arguments.command += ";"

        VERBOSE.print(arguments, label='arguments', verbose=1)

        if arguments.os is None:
            Shell.terminal(command=arguments.command)
        else:

            if arguments.interactive.lower() in ['true', 'on']:
                arguments.interactive = "-it"
            else:
                arguments.interactive = ""
                arguments.shell = ""

            VERBOSE.print(arguments, label='arguments', verbose=1)

            command = "cd {cwd}; docker run -v {cwd}:{cwd} -w {cwd} --rm {interactive} {os} {command}{shell}".format(
                **arguments)
            print(command)
            Shell.terminal(command=command)

        return ""
Beispiel #2
0
    def __init__(self,
                 name=None,
                 configuration="~/.cloudmesh/cloudmesh4.yaml"):
        """
        Initializes the provider. The default parameters are read from the configutation
        file that is defined in yaml format.
        :param name: The name of the provider as defined in the yaml file
        :param configuration: The location of the yaml configuration file
        """
        conf = Config(configuration)["cloudmesh"]
        self.user = conf["profile"]
        self.spec = conf["cloud"][name]
        self.cloud = name
        cred = self.spec["credentials"]
        self.cloudtype = self.spec["cm"]["kind"]
        super().__init__(name, conf)

        VERBOSE.print(cred, verbose=8)

        if self.cloudtype in Provider.ProviderMapper:

            self.driver = get_driver(Provider.ProviderMapper[self.cloudtype])

            if self.cloudtype == 'openstack':

                if cred["OS_PASSWORD"] == 'TBD':
                    Console.error("The password TBD is not allowed")

                self.cloudman = self.driver(
                    cred["OS_USERNAME"],
                    cred["OS_PASSWORD"],
                    ex_force_auth_url=cred['OS_AUTH_URL'],
                    ex_force_auth_version='2.0_password',
                    ex_tenant_name=cred['OS_TENANT_NAME'])
            elif self.cloudtype == 'azure_asm':

                self.cloudman = self.driver(
                    subscription_id=cred['AZURE_SUBSCRIPTION_ID'],
                    key_file=path_expand(cred['AZURE_KEY_FILE']))

            elif self.cloudtype == 'aws':

                self.cloudman = self.driver(cred["EC2_ACCESS_ID"],
                                            cred["EC2_SECRET_KEY"],
                                            region=cred["EC2_REGION"])

            if self.cloudtype == 'google':
                self.cloudman = self.driver(
                    cred["client_email"],
                    cred[
                        "path_to_json_file"],  # should be placed in .cloudmesh
                    project=cred["project"])
        else:
            print("Specified provider not available")
            self.cloudman = False
        self.default_image = None
        self.default_size = None
        self.public_key_path = conf["profile"]["publickey"]
Beispiel #3
0
    def __init__(self, config_path='~/.cloudmesh/cloudmesh4.yaml',
                 encrypted=False):
        """
        Initialize the Config class.

        :param config_path: A local file path to cloudmesh yaml config
            with a root element `cloudmesh`. Default: `~/.cloudmesh/cloudmesh4.yaml`
        """

        self.__dict__ = self.__shared_state
        if "data" not in self.__dict__:

            VERBOSE.print("Load config", verbose=9)

            self.config_path = Path(path_expand(config_path)).resolve()
            self.config_folder = dirname(self.config_path)

            if not exists(self.config_folder):
                mkdir(self.config_folder)

            if not isfile(self.config_path):
                source = Path(join(dirname(realpath(__file__)),
                                   "../../etc/cloudmesh4.yaml"))

                copyfile(source.resolve(), self.config_path)

            #with open(self.config_path, "r") as stream:
            #    # self.data = yaml.load(stream, Loader=yaml.FullLoader)
            #    self.data = yaml.load(stream, Loader=yaml.SafeLoader)

            with open(self.config_path, "r") as stream:
                content = stream.read()
                content = path_expand(content)
                content = self.spec_replace(content)
                self.data = yaml.load(content, Loader=yaml.SafeLoader)


            # self.data is loaded as nested OrderedDict, can not use set or get methods directly
            if self.data is None:
                raise EnvironmentError(
                    "Failed to load configuration file cloudmesh4.yaml, please check the path and file locally")

            #
            # populate default variables
            #

            self.variable_database = Variables(filename="~/.cloudmesh/var-data")
            self.set_debug_defaults()

            default = self.default()

            for name in self.default():
                if name not in self.variable_database:
                    self.variable_database[name] = default[name]
            if "cloud" in default:
                self.cloud = default["cloud"]
            else:
                self.cloud = None
Beispiel #4
0
 def __init__(self, filename, secret):
     self.data = dotdict({
         'file': filename,
         'secret': secret,
         'pem': path_expand('~/.ssh/id_rsa.pem'),
         'key': path_expand('~/.ssh/id_rsa')
     })
     VERBOSE.print(self.data, verbose=9)
     if not os.path.exists(self.data["pem"]):
         self.pem_create()
Beispiel #5
0
 def __init__(self,
              name=None,
              configuration="~/.cloudmesh/.cloudmesh4.yaml"):
     VERBOSE.print(f"Init Docker {name}", verbose=9)
     self.config = Config()
     conf = Config(configuration)["cloudmesh"]
     self.user = conf["profile"]
     self.spec = conf["cloud"][name]
     self.cloud = name
     cred = self.spec["credentials"]
     self.cloudtype = self.spec["cm"]["kind"]
    def test_04_list_flavors(self):
        HEADING()
        flavors = self.p.flavors()
        # pprint (flavors)

        VERBOSE.print(flavors, verbose=9)

        print(
            Printer.flatwrite(flavors,
                              sort_keys=["name", "vcpus", "disk"],
                              order=["name", "vcpus", "ram", "disk"],
                              header=["Name", "VCPUS", "RAM", "Disk"]))
    def test_03_list_images(self):
        HEADING()
        images = self.p.images()

        VERBOSE.print(images, verbose=9)

        print(
            Printer.flatwrite(
                images,
                sort_keys=["name", "extra.minDisk"],
                order=["name", "extra.minDisk", "updated", "driver"],
                header=["Name", "MinDisk", "Updated", "Driver"]))
    def test_04_list_vm(self):
        HEADING()
        vms = self.p.list()
        # pprint (vms)

        VERBOSE.print(vms, verbose=9)

        print(
            Printer.flatwrite(vms,
                              sort_keys=("name"),
                              order=[
                                  "name", "state", "extra.task_state",
                                  "extra.vm_state", "extra.userId",
                                  "extra.key_name", "private_ips", "public_ips"
                              ],
                              header=[
                                  "Name", "State", "Task state", "VM state",
                                  "User Id", "SSHKey", "Private ips",
                                  "Public ips"
                              ]))
Beispiel #9
0
    def do_config(self, args, arguments):
        """
        ::

           Usage:
             config  -h | --help
             config encrypt [SOURCE]
             config decrypt [SOURCE]
             config edit [SOURCE]
             config set ATTRIBUTE=VALUE
             config set ATTRIBUTE
             config ssh keygen
             config ssh verify
             config ssh check
             config ssh pem

           Arguments:
             SOURCE           the file to encrypted or decrypted.
                              an .enc is added to the filename or removed form it
                              dependent of if you encrypt or decrypt
             ATTRIBUTE=VALUE  sets the attribute with . notation in the
                              configuration file.
             ATTRIBUTE        reads the attribute from the terminal and sets it
                              in the configuration file
                              If the attribute is a password, * is written instead
                              of the character included

           Options:
              --name=KEYNAME                The name of a key


           Description:

             config check
                checks if the ssh key ~/.ssh/id_rsa has a password. Verifies it
                through entering the passphrase

             Key generation

                Keys must be generated with

                    ssh-keygen -t rsa -m pem
                    openssl rsa -in ~/.ssh/id_rsa -out ~/.ssh/id_rsa.pem

                or
                    cms config ssh keygen

                Key validity can be checked with

                    cms config check

                The key password can be verified with

                    cms config verify


                ssh-add

                cms config encrypt ~/.cloudmesh/cloudmesh4.yaml
                cms config decrypt ~/.cloudmesh/cloudmesh4.yaml


                config set ATTRIBUTE=VALUE

                    config set profile.name=Gregor


        """
        # d = Config()                #~/.cloudmesh/cloudmesh4.yaml
        # d = Config(encryted=True)   # ~/.cloudmesh/cloudmesh4.yaml.enc

        arguments.SOURCE = arguments.SOURCE or \
                           path_expand("~/.cloudmesh/cloudmesh4.yaml")
        arguments.DESTINATION = arguments.SOURCE + ".enc"

        VERBOSE.print(arguments, verbose=9)

        e = EncryptFile(arguments.SOURCE, arguments.DESTINATION)

        if arguments.encrypt:

            e.encrypt()
            Console.ok("{SOURCE} --> {DESTINATION}".format(**arguments))
            Console.ok("file encrypted")
            return ""

        elif arguments.decrypt:
            # if the file is existed
            if not os.path.exists(arguments.DESTINATION):
                Console.error(
                    "encrypted file {DESTINATION} does not exist".format(
                        **arguments))

            e.decrypt(arguments.SOURCE, arguments.DESTINATION)
            Console.ok("{DESTINATION} --> {SOURCE}".format(**arguments))

            Console.ok("file decrypted")
            return ""

        elif arguments.ssh and arguments.verify:
            e.pem_verify()

        elif arguments.ssh and arguments.check:
            key = "~/.ssh/id_rsa"
            r = e.check_key(key)
            if r:
                Console.ok(f"Key {key} is valid")
            # does not work as it does not change it to pem format
            # e.check_passphrase()

        elif arguments.ssh and arguments.pem:

            r = e.pem_create()

        elif arguments.set:

            Console.error("not implemented")
            raise NotImplementedError

        elif arguments.ssh and arguments.keygen:

            e.ssh_keygen()

        return ""
Beispiel #10
0
    def do_vm(self, args, arguments):
        """
        ::

            Usage:
                vm start [--cloud=CLOUD]
                         [--name=NAME]
                vm stop [--cloud=CLOUD]
                        [--name=NAME]
                vm delete [--cloud=CLOUD]
                          [--name=NAME]
                vm list [--cloud=CLOUDS]
                vm boot [--name=NAME]
                        [--cloud=CLOUD]
                        [--image=IMAGE]
                        [--flavor=FLAVOR]
                vm ssh  [--cloud=CLOUD]
                        [--name=NAME]
                        [--command=COMMAND]
                vm info [--cloud=CLOUD]
                        [--format=FORMAT]
                vm resize [NAMES] [--size=SIZE]
                vm images [--cloud=CLOUD]
                vm flavors [--cloud=CLOUD]

            Arguments:
                NAMES          server name. By default it is set to the name of last vm from database.
                NAME           server name.

            Options:
                --ip=IP           give the public ip of the server
                --cloud=CLOUD     give a cloud to work on, if not given, selected
                                  or default cloud will be used
                --flavor=FLAVOR   give the name or id of the flavor
                --image=IMAGE     give the name or id of the image
                --command=COMMAND specify the commands to be executed


            Description:
                commands used to boot, start or delete servers of a cloud

                vm boot [options...]
                    Boots servers on a cloud, user may specify flavor, image
                    .etc, otherwise default values will be used, see how to set
                    default values of a cloud: cloud help

                vm start [options...]
                    Starts a suspended or stopped vm instance.

                vm stop [options...]
                    Stops a vm instance .

                vm delete [options...]

                    Delete servers of a cloud, user may delete a server by its
                    name or id, delete servers of a group or servers of a cloud,
                    give prefix and/or range to find servers by their names.
                    Or user may specify more options to narrow the search

                vm ssh [options...]
                    login to a server or execute commands on it

                vm list [options...]
                    same as command "list vm", please refer to it

                vm status [options...]
                    Retrieves status of the VM requested

                vm refresh [--cloud=CLOUDS]
                    this command refreshes the data for virtual machines,
                    images and flavors for the specified clouds.

            Tip:
                give the VM name, but in a hostlist style, which is very
                convenient when you need a range of VMs e.g. sample[1-3]
                => ['sample1', 'sample2', 'sample3']
                sample[1-3,18] => ['sample1', 'sample2', 'sample3', 'sample18']

            Quoting commands:
                cm vm login gvonlasz-004 --command=\"uname -a\"

        """

        def map_parameters(arguments, *args):
            for arg in args:
                flag = "--" + arg
                if flag in arguments:
                    arguments[arg] = arguments[flag]
                else:
                    arguments[arg] = None

        def get_cloud_and_names(label, arguments):
            names = []
            clouds = []
            if arguments["--cloud"]:
                clouds = get_clouds(arguments, variables)
            else:
                clouds = get_clouds(arguments, variables)

            names = get_names(arguments, variables)

            return clouds, names

        def get_cloud_and_names_commands(label, arguments):
            names = []
            clouds = []
            commands = []
            if arguments["--cloud"]:
                clouds = get_clouds(arguments, variables)
            else:
                clouds = get_clouds(arguments, variables)
            names = get_names(arguments, variables)
            commands = get_commands(arguments, variables)
            return clouds, names, commands

        def get_clouds(arguments, variables):
        
            clouds = arguments["cloud"] or arguments["--cloud"]          
            if "active" == clouds:
                active = Active()
                clouds = active.clouds()
            else:
                clouds = clouds

            if (clouds is None) or (clouds == ""):
                Console.error("you need to specify a cloud")
                return None
            return clouds

        def get_names(arguments, variables):
            names = arguments["NAME"] or arguments["NAMES"] or arguments["--name"] or variables["vm"]
            if names is None:
                Console.error("you need to specify a vm")
                return None
            else:
                return names

        def get_image(arguments, variables):
            image = arguments["image"] or arguments["--image"]
            if image is None:
                Console.error("you need to specify an image")
                return None
            else:
                return image

        def get_command(arguments, variables):
            command = arguments["command"] or arguments["--command"]
            if command is None:
                Console.error("you need to specify a command")
                return None
            else:
                return command

        def get_flavor(arguments, variables):
            flavor = arguments["flavor"] or arguments["--flavor"]
            if flavor is None:
                Console.error("you need to specify a flavor")
                return None
            else:
                return flavor

        def get_commands(label, arguments):
            names = []
            if label in ["delete", "stop", "start"]:
                clouds = get_clouds(arguments, variables)
                names = get_names(arguments, variables)
                return clouds, names

            elif label in ["list", "flavors", "images"]:
                clouds = get_clouds(arguments, variables)
                return clouds

            elif "boot" == label:
                clouds = get_clouds(arguments, variables)
                names = get_names(arguments, variables)
                image = get_image(arguments, variables)
                flavor = get_flavor(arguments, variables)
                return clouds, names, image, flavor

            elif "ssh" == label:
                clouds = get_clouds(arguments, variables)
                names = get_names(arguments, variables)
                command = get_command(arguments, variables)
                return clouds, names, command

        map_parameters(arguments,
                       'cloud',
                       'command',
                       'flavor',
                       'format',
                       'image',
                       'ip',
                       'name',
                       'NAME')

        VERBOSE.print(arguments, verbose=9)

        variables = Variables()

        
        if arguments.images:
            clouds = get_commands("images", arguments)
            if clouds is None:
                return ""
            else:
                p = Provider(clouds)
                images = p.p.images()
                print(Printer.flatwrite(images,
                                sort_keys=("name"),
                                order=["name", "id", "driver"],
                                header=["Name", "Id", "Driver"])
                )
        elif arguments.flavors:
            clouds = get_commands("flavors", arguments)
            if clouds is None:
                return ""
            else:
                p = Provider(clouds)
                flavors = p.p.flavors()
                print(Printer.flatwrite(flavors,
                                sort_keys=("name", "disk"),
                                order=["name", "id", "ram", "disk"],
                                header=["Name", "Id", "RAM", "Disk"])
                )

        elif arguments.boot:

            print("Creating a new vm")
            clouds, names, image, flavor = get_commands("boot", arguments)
            if clouds is None or names is None or image is None or flavor is None:
                return ""
            else:
                p = Provider(clouds)
                node = p.p.create(name=names, size=flavor, image=image)
                print(Printer.flatwrite(node,
                                sort_keys=("name"),
                                order=["name", "state", "public_ips", "private_ips", "size", "image"],
                                header=["Name", "State", "Public IP", "Private IP", "Size", "Image"])
                )  
    
        elif arguments.start:
            print("Starting the requested vm")
            clouds, names = get_commands("start", arguments)
            if clouds is None or names is None:
                return ""
            else:
                p = Provider(clouds)
                node = p.p.start(name=names)

        elif arguments.stop:
            print("Stopping the requested vm")
            clouds, names = get_commands("stop", arguments)
            if clouds is None or names is None:
                return ""
            else:
                p = Provider(clouds)
                node = p.p.stop(name=names)


        elif arguments.delete:
            print("Delete the specified VM")
            clouds, names = get_commands("delete", arguments)
            if clouds is None or names is None:
                return ""
            else:
                p = Provider(clouds)
                p.p.destroy(name=names)

            return ""

        elif arguments.list:
            print("list the vms in the cloud")

            clouds = get_commands("list", arguments)
            if clouds is None:
                return ""
            else:
                p = Provider(clouds)
                vms = p.p.list()
                print(Printer.flatwrite(vms,
                                sort_keys=("name"),
                                order=["name", "state", "public_ips", "private_ips", "size", "image"],
                                header=["Name", "State", "Public IP", "Private IP", "Size", "Image"])
                )


        elif arguments.resize:
            """
            vm resize [NAMES] [--size=SIZE]
            """
            pass

        elif arguments.ssh:

            print("ssh  into the vm and execute command")

            clouds, names, command = get_commands("ssh", arguments)
            if clouds is None or names is None or command is None:
                return ""
            else:
                p = Provider(clouds)
                p.p.ssh(name=names, command=command)
Beispiel #11
0
    def do_batch(self, args, arguments):
        """
        ::

          Usage:
            batch job create
                --name=NAME
                --cluster=CLUSTER
                --script=SCRIPT
                --executable=EXECUTABLE
                --destination=DESTINATION
                --source=SOURCE
                [--companion-file=COMPANION_FILE]
                [--outfile-name=OUTPUT_FILE_NAME]
                [--suffix=SUFFIX]
                [--overwrite]
            batch job run [--name=NAMES] [--format=FORMAT]
            batch job fetch [--name=NAMES]
            batch job remove [--name=NAMES]
            batch job clean [--name=NAMES]
            batch job set [--name=NAMES] PARAMETER=VALUE
            batch job list [--name=NAMES] [--depth=DEPTH]
            batch cluster test [--cluster=CLUSTERS]
            batch cluster list [--cluster=CLUSTERS] [--depth=DEPTH]
            batch cluster remove [--cluster=CLUSTERS]
            batch cluster set [--cluster=CLUSTERS] PARAMETER=VALUE

          Arguments:
              FILE   a file name
              INPUT_TYPE  tbd

          Options:
              -f      specify the file
              --depth=DEPTH   [default: 1]
              --format=FORMAT    [default: table]

          Description:

            This command allows to submit batch jobs to queuing systems hosted
            in an HBC center as a service directly form your commandline.

            We assume that a number of experiments are conducted with possibly
            running the script multiple times. Each experiment will save the
            batch script in its own folder.

            The output of the script can be saved in a destination folder. A virtual
            directory is used to coordinate all saved files.

            The files can be located due to the use of the virtual directory on
            multiple different data or file services

            Authentication to the Batch systems is done viw the underlaying HPC
            center authentication. We assume that the user has an account to
            submit on these systems.

            (SSH, 2 factor, XSEDE-account) TBD.

          Experiments:

            experiments are jobs that can be run multiple times and create input
            and output file sin them

            cloudmesh:
             experiment:
               job:
                 name: {cloudmesh.profile.user.name}-01
                 directory: ~/experiment/{experiment.job.name}
                 output:  {cloudmesh.experiment.job.name}/output
                 input:  ~/experiment/{experiment.job.name}/input
                 script: script.sh
                 source ,,,
                 destination: {cloudmesh.experiment.job.directory}


            I do not know what companion file is

          Examples:

             batch job run [--name=NAMES] [--format=FORMAT]

                runs jobs with the given names

             LOTS OF DOCUMENTATION MISSING HERE

                [--companion-file=COMPANION_FILE]
                [--outfile-name=OUTPUT_FILE_NAME]
                [--suffix=SUFFIX] [--overwrite]




        """

        #
        # create slurm manager so it can be used in all commands
        #
        slurm_manager = SlurmCluster()  # debug=arguments["--debug"])

        arguments["--cloud"] = "test"
        arguments["NAME"] = "fix"

        map_parameters(arguments,
                       "cloud",
                       "name",
                       "cluster",
                       "script",
                       "type",
                       "destination",
                       "source",
                       "format")

        # if not arguments.create

        #    find cluster name from Variables()
        #    if no cluster is defined look it up in yaml in batch default:
        #    if not defined there fail

        #    clusters = Parameter.expand(arguments.cluster)
        #    name = Parameters.expand[argumnets.name)
        #    this will return an array of clusters and names of jobs and all cluster
        #    job or clusterc commands will be executed on them
        #    see the vm
        #
        #    if active: False in the yaml file for the cluster this cluster is not used and scipped.

        VERBOSE.print(arguments, verbose=9)

        variables = Variables()
        # do not use print but use ,Console.msg(), Console.error(), Console.ok()
        if arguments.tester:
            print("running ... ")
            slurm_manager.tester()
        elif arguments.run and arguments.job:

            # config = Config()["cloudmesh.batch"]

            names = Parameter.expand(arguments.name)

            # clouds, names = Arguments.get_cloud_and_names("refresh", arguments,
            #                                    variables)

            data = []
            for name in names:
                entry = SlurmCluster.job_specification()
                data.append(entry)

            '''
             data = {
            "cm": {
                "cloud": "karst_debug",
                "kind": "batch-job",
                "name": "job012",
            },
            "batch": {
                "source": "~/.cloudmesh/batch/dir",
                "destination": "~/.cloudmesh/dir/",
                "status": "running"
            }
            }'''

            try:
                raise NotImplementedError
            except Exception as e:
                Console.error("Haha", traceflag=True)

            pprint(data)
            print(Printer.flatwrite(
                data,
                order=["cm.name", "cm.kind", "batch.status"],
                header=["Name", "Kind", "Status"],
                output=arguments.format)
            )

            return ""
        elif arguments.job and arguments.create:
            # if not arguments.name:
                # raise ValueError
            # assert input_type in ['params', 'params+file'], "Input type can be either params or params+file"
            # if input_type == 'params+file':
            #     assert arguments.get("--argfile-path") is not None, "Input type is params+file but the input \
            #         filename is not specified"
            job_name = arguments.name
            cluster_name = arguments.cluster
            script_path = Path(arguments.script)
            if not script_path.exists():
                raise FileNotFoundError
            executable_path = Path(arguments['--executable'])
            if not executable_path.exists():
                raise FileNotFoundError
            destination = Path(arguments.destination)
            if not destination.is_absolute():
                Console.error("destination path must be absolute",
                              traceflag=True)
                raise FileNotFoundError
            source = Path(arguments.source)
            if not source.exists():
                raise FileNotFoundError
            if arguments.experiment is None:
                experiment_name = 'job' + self.suffix_generator()
            else:
                experiment_name = arguments.experiment + self.suffix_generator()
            # overwrite = False if type(arguments.get("--overwrite")) is None else arguments.get("--overwrite")
            if arguments.get("--companion-file") is None:
                companion_file = Path()
            else:
                companion_file = Path(arguments.get("--companion-file"))
            slurm_manager.create(job_name,
                                 cluster_name,
                                 script_path,
                                 executable_path,
                                 destination,
                                 source,
                                 experiment_name,
                                 companion_file)

        elif arguments.remove:
            if arguments.cluster:
                slurm_manager.remove("cluster", arguments.get("CLUSTER_NAME"))
            if arguments.job:
                slurm_manager.remove("job", arguments.get("JOB_NAME"))

        elif arguments.list:
            max_depth = 1 if arguments.get("DEPTH") is None else int(arguments.get("DEPTH"))
            if arguments.get("clusters"):
                slurm_manager.list("clusters", max_depth)
            elif arguments.get("jobs"):
                slurm_manager.list("jobs", max_depth)

        elif arguments.set:
            if arguments.get("cluster"):
                cluster_name = arguments.get("CLUSTER_NAME")
                parameter = arguments.get("PARAMETER")
                value = arguments.get("VALUE")
                slurm_manager.set_param("cluster", cluster_name, parameter, value)

            if arguments.job:
                config_name = arguments.get("JOB_NAME")
                parameter = arguments.get("PARAMETER")
                value = arguments.get("VALUE")
                slurm_manager.set_param("job-metadata", config_name, parameter, value)
        elif arguments.start and arguments.job:
            job_name = arguments.get("JOB_NAME")
            slurm_manager.run(job_name)
        elif arguments.get("fetch"):
            job_name = arguments.get("JOB_NAME")
            slurm_manager.fetch(job_name)
        elif arguments.test:
            cluster_name = arguments.get("CLUSTER_NAME")
            slurm_manager.connection_test(cluster_name)
        elif arguments.clean:
            job_name = arguments.get("JOB_NAME")
            slurm_manager.clean_remote(job_name)
Beispiel #12
0
    def do_image(self, args, arguments):
        """
        ::

            Usage:
                image list [NAMES] [--cloud=CLOUD] [--refresh] [--output=OUTPUT]

            Options:
               --output=OUTPUT  the output format [default: table]
               --cloud=CLOUD    the cloud name
               --refresh        live data taken from the cloud

            Description:
                cm image list
                cm image list --output=csv
                cm image list 58c9552c-8d93-42c0-9dea-5f48d90a3188 --refresh
        """

        map_parameters(arguments, "refresh", "cloud", "output")

        VERBOSE.print(arguments, verbose=9)

        variables = Variables()

        if arguments.list and arguments.refresh:

            names = []

            clouds, names = Arguments.get_cloud_and_names(
                "list", arguments, variables)

            print("AAA", clouds, names)

            for cloud in clouds:
                print(f"cloud {cloud}")
                provider = Provider(name=cloud)
                images = provider.images()

                order = provider.p.output['vm']['order']  # not pretty
                header = provider.p.output['vm']['header']  # not pretty

                print(
                    Printer.flatwrite(images,
                                      sort_keys=["name"],
                                      order=order,
                                      header=header,
                                      output=arguments.output))
            return ""

        elif arguments.list:

            names = []

            clouds, names = Arguments.get_cloud_and_names(
                "list", arguments, variables)

            print(clouds, names)
            try:

                for cloud in clouds:
                    print(f"List {cloud}")
                    p = Provider(cloud)
                    kind = p.kind

                    collection = "{cloud}-image".format(cloud=cloud,
                                                        kind=p.kind)
                    db = CmDatabase()
                    vms = db.find(collection=collection)

                    order = p.p.output['vm']['order']  # not pretty
                    header = p.p.output['vm']['header']  # not pretty

                    print(
                        Printer.flatwrite(vms,
                                          sort_keys=["name"],
                                          order=order,
                                          header=header,
                                          output=arguments.output))

            except Exception as e:

                VERBOSE.print(e, verbose=9)

            return ""
Beispiel #13
0
    def do_vm(self, args, arguments):
        """
        ::

            Usage:
                vm ping [NAMES] [--cloud=CLOUDS] [--count=N] [--processors=PROCESSORS]
                vm check [NAMES] [--cloud=CLOUDS] [--processors=PROCESSORS]
                vm status [NAMES] [--cloud=CLOUDS]
                vm console [NAME] [--force]
                vm start [NAMES] [--cloud=CLOUD] [--dryrun]
                vm stop [NAMES] [--cloud=CLOUD] [--dryrun]
                vm terminate [NAMES] [--cloud=CLOUD] [--dryrun]
                vm delete [NAMES] [--cloud=CLOUD] [--dryrun]
                vm refresh [--cloud=CLOUDS]
                vm list [NAMES]
                        [--cloud=CLOUDS]
                        [--output=OUTPUT]
                        [--refresh]
                vm boot [--name=NAME]
                        [--cloud=CLOUD]
                        [--username=USERNAME]
                        [--image=IMAGE]
                        [--flavor=FLAVOR]
                        [--public]
                        [--secgroup=SECGROUPs]
                        [--key=KEY]
                        [--dryrun]
                vm boot [--n=COUNT]
                        [--cloud=CLOUD]
                        [--username=USERNAME]
                        [--image=IMAGE]
                        [--flavor=FLAVOR]
                        [--public]
                        [--secgroup=SECGROUPS]
                        [--key=KEY]
                        [--dryrun]
                vm run [--name=NAMES] [--username=USERNAME] [--dryrun] COMMAND
                vm script [--name=NAMES] [--username=USERNAME] [--dryrun] SCRIPT
                vm ip assign [NAMES]
                          [--cloud=CLOUD]
                vm ip show [NAMES]
                           [--group=GROUP]
                           [--cloud=CLOUD]
                           [--output=OUTPUT]
                           [--refresh]
                vm ip inventory [NAMES]
                vm ssh [NAMES] [--username=USER]
                         [--quiet]
                         [--ip=IP]
                         [--key=KEY]
                         [--command=COMMAND]
                         [--modify-knownhosts]
                vm rename [OLDNAMES] [NEWNAMES] [--force] [--dryrun]
                vm wait [--cloud=CLOUD] [--interval=SECONDS]
                vm info [--cloud=CLOUD]
                        [--output=OUTPUT]
                vm username USERNAME [NAMES] [--cloud=CLOUD]
                vm resize [NAMES] [--size=SIZE]

            Arguments:
                OUTPUT         the output format
                COMMAND        positional arguments, the commands you want to
                               execute on the server(e.g. ls -a) separated by ';',
                               you will get a return of executing result instead of login to
                               the server, note that type in -- is suggested before
                               you input the commands
                NAME           server name. By default it is set to the name of last vm from database.
                NAMES          server name. By default it is set to the name of last vm from database.
                KEYPAIR_NAME   Name of the vm keypair to be used to create VM. Note this is
                               not a path to key.
                NEWNAMES       New names of the VM while renaming.
                OLDNAMES       Old names of the VM while renaming.

            Options:
                --output=OUTPUT   the output format [default: table]
                -H --modify-knownhosts  Do not modify ~/.ssh/known_hosts file
                                      when ssh'ing into a machine
                --username=USERNAME   the username to login into the vm. If not
                                      specified it will be guessed
                                      from the image name and the cloud
                --ip=IP          give the public ip of the server
                --cloud=CLOUD    give a cloud to work on, if not given, selected
                                 or default cloud will be used
                --count=COUNT    give the number of servers to start
                --detail         for table, a brief version
                                 is used as default, use this flag to print
                                 detailed table
                --flavor=FLAVOR  give the name or id of the flavor
                --group=GROUP          give the group name of server
                --secgroup=SECGROUP    security group name for the server
                --image=IMAGE    give the name or id of the image
                --key=KEY        specify a key to use, input a string which
                                 is the full path to the private key file
                --keypair_name=KEYPAIR_NAME   Name of the vm keypair to
                                              be used to create VM.
                                              Note this is not a path to key.
                --user=USER      give the user name of the server that you want
                                 to use to login
                --name=NAME      give the name of the virtual machine
                --force          rename/ delete vms without user's confirmation
                --command=COMMAND
                                 specify the commands to be executed


            Description:
                commands used to boot, start or delete servers of a cloud

                vm default [options...]
                    Displays default parameters that are set for vm boot either
                    on the default cloud or the specified cloud.

                vm boot [options...]
                    Boots servers on a cloud, user may specify flavor, image
                    .etc, otherwise default values will be used, see how to set
                    default values of a cloud: cloud help

                vm start [options...]
                    Starts a suspended or stopped vm instance.

                vm stop [options...]
                    Stops a vm instance .

                vm delete [options...]

                    Delete servers of a cloud, user may delete a server by its
                    name or id, delete servers of a group or servers of a cloud,
                    give prefix and/or range to find servers by their names.
                    Or user may specify more options to narrow the search

                vm floating_ip_assign [options...]
                    assign a public ip to a VM of a cloud

                vm ip show [options...]
                    show the ips of VMs

                vm ssh [options...]
                    login to a server or execute commands on it

                vm list [options...]
                    same as command "list vm", please refer to it

                vm status [options...]
                    Retrieves status of last VM booted on cloud and displays it.

                vm refresh [--cloud=CLOUDS]
                    this command refreshes the data for virtual machines,
                    images and flavors for the specified clouds.

                vm ping [NAMES] [--cloud=CLOUDS] [--count=N] [--processors=PROCESSORS]
                     pings the specified virtual machines, while using at most N pings.
                     The ping is executed in parallel.
                     If names are specifies the ping is restricted to the given names in
                     parameter format. If clouds are specified, names that are not in
                     these clouds are ignored. If the name is set in the variables
                     this name is used.

            Tip:
                give the VM name, but in a hostlist style, which is very
                convenient when you need a range of VMs e.g. sample[1-3]
                => ['sample1', 'sample2', 'sample3']
                sample[1-3,18] => ['sample1', 'sample2', 'sample3', 'sample18']

            Quoting commands:
                cm vm login gvonlasz-004 --command=\"uname -a\"

            Limitations:

                Azure: rename is not supported
        """

        map_parameters(arguments, 'active', 'cloud', 'command', 'dryrun',
                       'flavor', 'force', 'output', 'group', 'image',
                       'interval', 'ip', 'key', 'modify-knownhosts', 'n',
                       'name', 'public', 'quiet', 'secgroup', 'size',
                       'username')

        VERBOSE.print(arguments, verbose=9)

        variables = Variables()

        if arguments.refresh:

            names = []

            clouds, names = Arguments.get_cloud_and_names(
                "refresh", arguments, variables)

            return ""

        elif arguments.ping:

            # TODO: IMPLEMENT
            names = []
            pings = int(arguments.N or 3)

            names = []

            clouds, names = Arguments.get_cloud_and_names(
                "ping", arguments, variables)

            for name in names:

                ping = Shell.live("ping -c {N} {name}".format(name=name,
                                                              N=arguments.N))
                print(ping)
            else:
                return True

            return ""

        elif arguments.check:

            names = []

            clouds, names = Arguments.get_cloud_and_names(
                "check", arguments, variables)

            return ""

        elif arguments.status:

            names = []

            clouds, names = Arguments.get_cloud_and_names(
                "status", arguments, variables)

            return ""

        elif arguments.start:

            names = []

            clouds, names = Arguments.get_cloud_and_names(
                "start", arguments, variables)

            return ""

        elif arguments.stop:

            names = []

            clouds, names = Arguments.get_cloud_and_names(
                "stop", arguments, variables)

            return ""

        elif arguments.terminate:

            names = []

            clouds, names = Arguments.get_cloud_and_names(
                "terminate", arguments, variables)

            return ""

        elif arguments.delete:

            clouds, names = Arguments.get_cloud_and_names(
                "delete", arguments, variables)

            return ""

        elif arguments.boot:

            print("boot the vm")

        elif arguments.list:
            # vm list [NAMES]
            #   [--cloud=CLOUDS]
            #   [--output=OUPTUT]
            #   [--refresh]

            # if no clouds find the clouds of all specified vms by name
            # find all vms of the clouds,
            # print only those vms specified by name, if no name is given print all for the cloud
            # print("list the vms")

            clouds, names = Arguments.get_cloud_and_names(
                "list", arguments, variables)

            # print("Clouds:", clouds)

            if arguments.NAMES is not None:
                names = Parameter.expand(arguments.NAMES)
                Console.error("NAMES, not yet implemented" + str(names))

                try:
                    if arguments["--refresh"]:
                        pass
                        # find all clouds in db
                        # iterate over the clouds
                        # for each name in name queue, find it and add it to the cloud vm list
                        # for each cloud print the vms
                    else:
                        pass
                        # find all clouds in db
                        # iterate over all clouds
                        # find the vm with the name
                        # add it to the cloud list
                        # for each cloud print the vms
                except Exception as e:

                    VERBOSE.print(e, verbose=9)

                return ""
            else:
                try:
                    if arguments["--refresh"]:
                        for cloud in clouds:
                            Console.ok("refresh " + cloud)

                            p = Provider(cloud)
                            vms = p.list()

                            order = p.p.output['vm']['order']  # not pretty
                            header = p.p.output['vm']['header']  # not pretty

                            print(
                                Printer.flatwrite(vms,
                                                  sort_keys=["cm.name"],
                                                  order=order,
                                                  header=header,
                                                  output=arguments.output))

                    else:
                        for cloud in clouds:
                            p = Provider(cloud)
                            kind = p.kind

                            # pprint(p.__dict__)
                            # pprint(p.p.__dict__) # not pretty

                            collection = "{cloud}-node".format(cloud=cloud,
                                                               kind=p.kind)
                            db = CmDatabase()
                            vms = db.find(collection=collection)

                            # pprint(vms)
                            # print(arguments.output)
                            # print(p.p.output['vm'])

                            order = p.p.output['vm']['order']  # not pretty
                            header = p.p.output['vm']['header']  # not pretty

                            print(
                                Printer.flatwrite(vms,
                                                  sort_keys=["cm.name"],
                                                  order=order,
                                                  header=header,
                                                  output=arguments.output))

                except Exception as e:

                    VERBOSE.print(e, verbose=9)

            return ""

        elif arguments.info:
            """
            vm info [--cloud=CLOUD] [--output=OUTPUT]
            """
            print("info for the vm")

            cloud, names = Arguments.get_cloud_and_names(
                "info", arguments, variables)

        elif arguments.rename:

            print("rename the vm")

            v = Variables()
            cloud = v["cloud"]

            p = Provider(cloud)

            try:
                oldnames = Parameter.expand(arguments["OLDNAMES"])
                newnames = Parameter.expand(arguments["NEWNAMES"])
                force = arguments["--force"]

                if oldnames is None or newnames is None:
                    Console.error("Wrong VMs specified for rename",
                                  traceflag=False)
                elif len(oldnames) != len(newnames):
                    Console.error("The number of VMs to be renamed is wrong",
                                  traceflag=False)
                else:
                    print(oldnames)
                    print(newnames)
                    for i in range(0, len(oldnames)):
                        oldname = oldnames[i]
                        newname = newnames[i]
                        if arguments["--dryrun"]:
                            Console.ok("Rename {} to {}".format(
                                oldname, newname))
                        else:
                            print(f"rename {oldname} -> {newname}")

                            p.rename(source=oldname, destination=newname)

                    msg = "info. OK."
                    Console.ok(msg)
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem renameing instances", traceflag=True)

        elif arguments["ip"] and arguments["show"]:

            print("show the ips")
            """
            vm ip show [NAMES]
                   [--group=GROUP]
                   [--cloud=CLOUD]
                   [--output=OUTPUT]
                   [--refresh]

            """

        elif arguments["ip"] and arguments["assign"]:
            """
            vm ip assign [NAMES] [--cloud=CLOUD]
            """
            print("assign the public ip")

        elif arguments["ip"] and arguments["inventory"]:
            """
            vm ip inventory [NAMES]

            """
            print("list ips that could be assigned")

        elif arguments.username:
            """
            vm username USERNAME [NAMES] [--cloud=CLOUD]
            """
            print("sets the username for the vm")

        elif arguments.default:

            print("sets defaults for the vm")

        elif arguments.run:
            """
            vm run [--name=NAMES] [--username=USERNAME] [--dryrun] COMMAND

            """
            pass
        elif arguments.script:
            """
            vm script [--name=NAMES] [--username=USERNAME] [--dryrun] SCRIPT
            """
            pass

        elif arguments.resize:
            """
            vm resize [NAMES] [--size=SIZE]
            """
            pass

        elif arguments.ssh:
            """
            vm ssh [NAMES] [--username=USER]
                 [--quiet]
                 [--ip=IP]
                 [--key=KEY]
                 [--command=COMMAND]
                 [--modify-knownhosts]
            """
            print("ssh  the vm")

        elif arguments.console:
            # vm console [NAME] [--force]

            names = Arguments.get_names(arguments, variables)

            for name in names:
                # r = vm.console(name,force=argument.force)
                Console.msg("{label} {name}".format(label="console",
                                                    name=name))
            return

        elif arguments.wait:
            """
            vm wait [--cloud=CLOUD] [--interval=SECONDS]
            """
            print("waits for the vm till its ready and one can login")
Beispiel #14
0
 def _execute(self, command):
     VERBOSE.print(command, verbose=9)
     os.system(command)
Beispiel #15
0
    def do_queue(self, args, arguments):
        """
        ::

          Usage:
            queue create --name=NAME --policy=POLICY --cluster=CLUSTER
                [--charge=CHARGE]
                [--unit=UNIT]
            queue activate [--name=NAME]
            queue deactivate [--name=NAME]
            queue set unit
            queue connection_test --job=JOB
            queue cluster list [--cluster=CLUSTERS] [--depth=DEPTH]
            queue cluster remove [--cluster=CLUSTERS]
            queue cluster set [--cluster=CLUSTERS] PARAMETER=VALUE

          Arguments:
              FILE   a file name
              INPUT_TYPE  tbd

          Options:
              -f      specify the file
              --depth=DEPTH   [default: 1]
              --format=FORMAT    [default: table]

          Description:

            This command creates a queue that is associated with a cloud.

            We assume that a number of experiments are conducted with possibly
            running the script multiple times. Each experiment will save the
            batch script in its own folder.

            The output of the script can be saved in a destination folder. A virtual
            directory is used to coordinate all saved files.

            The files can be located due to the use of the virtual directory on
            multiple different data or file services

            Authentication to the Batch systems is done viw the underlaying HPC
            center authentication. We assume that the user has an account to
            submit on these systems.

            (SSH, 2 factor, XSEDE-account) TBD.

          Examples:

             LOTS OF DOCUMENTATION MISSING HERE

                [--companion-file=COMPANION_FILE]
                [--outfile-name=OUTPUT_FILE_NAME]
                [--suffix=SUFFIX] [--overwrite]




        """

        #
        # create slurm manager so it can be used in all commands
        #
        queue = Queue()  # debug=arguments["--debug"])

        # arguments["--cloud"] = "test"
        # arguments["NAME"] = "fix"

        # map_parameters(arguments,
        #                "cloud",
        #                "name",
        #                "cluster",
        #                "script",
        #                "type",
        #                "destination",
        #                "source",
        #                "format")

        # if not arguments.create

        #    find cluster name from Variables()
        #    if no cluster is defined look it up in yaml in batch default:
        #    if not defined there fail

        #    clusters = Parameter.expand(arguments.cluster)
        #    name = Parameters.expand[argumnets.name)
        #    this will return an array of clusters and names of jobs and all cluster
        #    job or clusterc commands will be executed on them
        #    see the vm
        #
        #    if active: False in the yaml file for the cluster this cluster is not used and scipped.

        VERBOSE.print(arguments, verbose=9)
        implemented_policies = ['FIFO', 'FILO']
        variables = Variables()

        # docopt for some reason does not show all of the arguments in dot
        # format that's the reason I used -- format.
        if   arguments.create and \
             arguments['--name'] and \
             arguments['--cluster'] and \
             arguments['--policy']:

            queue_name = arguments['--name']
            cluster_name = arguments['--cluster']
            policy = arguments['--policy']
            if policy.upper() not in ['FIFO', 'FILO']:
                Console.error("Policy {policy} not defined, currently "
                              "implemented policies are {policies} ".format(
                                  policy=policy.upper(),
                                  policies=implemented_policies))
                return
            charge = arguments['--charge']
            unit = arguments['--unit']
            queue.create(queue_name, cluster_name, policy, charge, unit)