예제 #1
0
    def testPolicy(self):
        # info for testPolicy
        testInfo = [
            #    size     policy   expected success?
            ["2000kb", "good", True, "zeroedthick"],
            ["14000pb", "good", False, "zeroedthick"],
            ["bad size", "good", False, "eagerzeroedthick"],
            ["100mb", "impossible", True, "eagerzeroedthick"],
            ["100mb", "good", True, "thin"],
        ]
        path = vsan_info.get_vsan_dockvols_path()
        i = 0
        for unit in testInfo:
            vol_name = '{0}{1}'.format(self.volName, i)
            vmdk_path = vmdk_utils.get_vmdk_path(path,vol_name)
            i = i+1
            # create a volume with requests size/policy and check vs expected result
            err = vmdk_ops.createVMDK(vm_name=self.vm_name,
                                      vmdk_path=vmdk_path,
                                      vol_name=vol_name,
                                      opts={volume_kv.VSAN_POLICY_NAME: unit[1],
                                            volume_kv.SIZE: unit[0],
                                            volume_kv.DISK_ALLOCATION_FORMAT: unit[3]})
            self.assertEqual(err == None, unit[2], err)

            # clean up should fail if the created should have failed.
            err = vmdk_ops.removeVMDK(vmdk_path)
            self.assertEqual(err == None, unit[2], err)
예제 #2
0
def executeRequest(vm_uuid, vm_name, config_path, cmd, full_vol_name, opts):
    """
    Executes a <cmd> request issused from a VM.
    The request is about volume <full_volume_name> in format volume@datastore.
    If @datastore is omitted, the one where the VM resides is used.
    For VM, the function gets vm_uuid, vm_name and config_path
    <opts> is a json options string blindly passed to a specific operation

    Returns None (if all OK) or error string
    """
    vm_datastore = get_datastore_name(config_path)
    error_info, tenant_uuid, tenant_name = auth.authorize(vm_uuid, vm_datastore, cmd, opts)
    if error_info:
        return err(error_info)

    if cmd == "list":
        return listVMDK(vm_datastore, tenant_name)

    try:
        vol_name, datastore = parse_vol_name(full_vol_name)
    except ValidationError as ex:
        return err(str(ex))
    if not datastore:
        datastore = vm_datastore
    elif datastore not in known_datastores():
        return err("Invalid datastore '%s'.\n" \
                   "Known datastores: %s.\n" \
                   "Default datastore: %s" \
                   % (datastore, ", ".join(known_datastores()), vm_datastore))

    # get /vmfs/volumes/<volid>/dockvols path on ESX:
    path = get_vol_path(datastore, tenant_name)
    logging.debug("executeRequest %s %s", tenant_name, path)
    if path is None:
        return err("Failed to initialize volume path {0}".format(path))

    vmdk_path = vmdk_utils.get_vmdk_path(path, vol_name)

    if cmd == "get":
        response = getVMDK(vmdk_path, vol_name, datastore)
    elif cmd == "create":
        response = createVMDK(vmdk_path, vm_name, vol_name, opts)
        # create succeed, insert infomation of this volume to volumes table
        if not response:
            if tenant_uuid:
                vol_size_in_MB = convert.convert_to_MB(auth.get_vol_size(opts))
                auth.add_volume_to_volumes_table(tenant_uuid, datastore, vol_name, vol_size_in_MB)
            else:
                logging.warning(" VM %s does not belong to any tenant", vm_name)
                                      
    elif cmd == "remove":
        response = removeVMDK(vmdk_path)
    elif cmd == "attach":
        response = attachVMDK(vmdk_path, vm_uuid)
    elif cmd == "detach":
        response = detachVMDK(vmdk_path, vm_uuid)
    else:
        return err("Unknown command:" + cmd)

    return response
    def testPolicy(self):
        # info for testPolicy
        testInfo = [
            #    size     policy   expected success?
            ["2000kb", "good", True, "zeroedthick"],
            ["14000pb", "good", False, "zeroedthick"],
            ["bad size", "good", False, "eagerzeroedthick"],
            ["100mb", "impossible", True, "eagerzeroedthick"],
            ["100mb", "good", True, "thin"],
        ]
        path = vsan_info.get_vsan_dockvols_path()
        i = 0
        for unit in testInfo:
            vol_name = '{0}{1}'.format(self.volName, i)
            vmdk_path = vmdk_utils.get_vmdk_path(path, vol_name)
            i = i + 1
            # create a volume with requests size/policy and check vs expected result
            err = vmdk_ops.createVMDK(vm_name=self.vm_name,
                                      vmdk_path=vmdk_path,
                                      vol_name=vol_name,
                                      opts={
                                          volume_kv.VSAN_POLICY_NAME: unit[1],
                                          volume_kv.SIZE: unit[0],
                                          volume_kv.DISK_ALLOCATION_FORMAT:
                                          unit[3]
                                      })
            self.assertEqual(err == None, unit[2], err)

            # clean up should fail if the created should have failed.
            err = vmdk_ops.removeVMDK(vmdk_path)
            self.assertEqual(err == None, unit[2], err)
 def setUp(self):
     self.name = vmdk_utils.get_vmdk_path(path, self.volName)
     self.policy_names = ['good', 'impossible']
     self.orig_policy_content = ('(("proportionalCapacity" i0) '
                                 '("hostFailuresToTolerate" i0))')
     self.new_policy_content = '(("hostFailuresToTolerate" i0))'
     for n in self.policy_names:
         vsan_policy.create(n, self.orig_policy_content)
예제 #5
0
 def setUp(self):
     self.name = vmdk_utils.get_vmdk_path(path, self.volName)
     self.policy_names = ['good', 'impossible']
     self.orig_policy_content = ('(("proportionalCapacity" i0) '
                                  '("hostFailuresToTolerate" i0))')
     self.new_policy_content = '(("hostFailuresToTolerate" i0))'
     for n in self.policy_names:
         vsan_policy.create(n, self.orig_policy_content)
예제 #6
0
def executeRequest(vm_uuid, vm_name, config_path, cmd, full_vol_name, opts):
    """
    Executes a <cmd> request issused from a VM.
    The request is about volume <full_volume_name> in format volume@datastore.
    If @datastore is omitted, the one where the VM resides is used.
    For VM, the function gets vm_uuid, vm_name and config_path
    <opts> is a json options string blindly passed to a specific operation

    Returns None (if all OK) or error string
    """

    vm_datastore = get_datastore_name(config_path)
    if cmd == "list":
        return listVMDK(vm_datastore)

    try:
        vol_name, datastore = parse_vol_name(full_vol_name)
    except ValidationError as ex:
        return err(str(ex))
    if not datastore:
        datastore = vm_datastore
    elif datastore not in known_datastores():
        return err("Invalid datastore '%s'.\n" \
                   "Known datastores: %s.\n" \
                   "Default datastore: %s" \
                   % (datastore, ", ".join(known_datastores()), vm_datastore))

    # get /vmfs/volumes/<volid>/dockvols path on ESX:
    path = get_vol_path(datastore)

    if path is None:
        return err("Failed to initialize volume path {0}".format(path))

    vmdk_path = vmdk_utils.get_vmdk_path(path, vol_name)

    if cmd == "get":
        response = getVMDK(vmdk_path, vol_name, datastore)
    elif cmd == "create":
        response = createVMDK(vmdk_path, vm_name, vol_name, opts)
    elif cmd == "remove":
        response = removeVMDK(vmdk_path)
    elif cmd == "attach":
        response = attachVMDK(vmdk_path, vm_uuid)
    elif cmd == "detach":
        response = detachVMDK(vmdk_path, vm_uuid)
    else:
        return err("Unknown command:" + cmd)

    return response
예제 #7
0
def executeRequest(vm_uuid, vm_name, config_path, cmd, full_vol_name, opts):
    """
    Executes a <cmd> request issused from a VM.
    The request is about volume <full_volume_name> in format volume@datastore.
    If @datastore is omitted, the one where the VM resides is used.
    For VM, the function gets vm_uuid, vm_name and config_path
    <opts> is a json options string blindly passed to a specific operation

    Returns None (if all OK) or error string
    """

    vm_datastore = get_datastore_name(config_path)
    if cmd == "list":
        return listVMDK(vm_datastore)

    try:
        vol_name, datastore = parse_vol_name(full_vol_name)
    except ValidationError as ex:
        return err(str(ex))
    if not datastore:
        datastore = vm_datastore
    elif datastore not in known_datastores():
        return err("Invalid datastore '%s'.\n" \
                   "Known datastores: %s.\n" \
                   "Default datastore: %s" \
                   % (datastore, ", ".join(known_datastores()), vm_datastore))

    # get /vmfs/volumes/<volid>/dockvols path on ESX:
    path = get_vol_path(datastore)

    if path is None:
        return err("Failed to initialize volume path {0}".format(path))

    vmdk_path = vmdk_utils.get_vmdk_path(path, vol_name)

    if cmd == "get":
        response = getVMDK(vmdk_path, vol_name, datastore)
    elif cmd == "create":
        response = createVMDK(vmdk_path, vm_name, vol_name, opts)
    elif cmd == "remove":
        response = removeVMDK(vmdk_path)
    elif cmd == "attach":
        response = attachVMDK(vmdk_path, vm_uuid)
    elif cmd == "detach":
        response = detachVMDK(vmdk_path, vm_uuid)
    else:
        return err("Unknown command:" + cmd)

    return response
    def testPolicyUpdate(self):
        path = vsan_info.get_vsan_dockvols_path()
        vmdk_path = vmdk_utils.get_vmdk_path(path, self.volName)
        err = vmdk_ops.createVMDK(vm_name=self.vm_name,
                                  vmdk_path=vmdk_path,
                                  vol_name=self.volName,
                                  opts={'vsan-policy-name': 'good'})
        self.assertEqual(err, None, err)
        self.assertEqual(None,
                         vsan_policy.update('good', self.new_policy_content))
        # Setting an identical policy returns an error msg
        self.assertNotEqual(
            None, vsan_policy.update('good', self.new_policy_content))

        backup_policy_file = vsan_policy.backup_policy_filename(self.name)
        #Ensure there is no backup policy file
        self.assertFalse(os.path.isfile(backup_policy_file))

        # Fail to update because of a bad policy, and ensure there is no backup
        self.assertNotEqual(None, vsan_policy.update('good', 'blah'))
        self.assertFalse(os.path.isfile(backup_policy_file))
예제 #9
0
    def testPolicyUpdate(self):
        path = vsan_info.get_vsan_dockvols_path()
        vmdk_path = vmdk_utils.get_vmdk_path(path, self.volName)
        err = vmdk_ops.createVMDK(vm_name=self.vm_name,
                                  vmdk_path=vmdk_path,
                                  vol_name=self.volName,
                                  opts={'vsan-policy-name': 'good'})
        self.assertEqual(err, None, err)
        self.assertEqual(None, vsan_policy.update('good',
                                                  self.new_policy_content))
        # Setting an identical policy returns an error msg
        self.assertNotEqual(None, vsan_policy.update('good',
                                                     self.new_policy_content))

        backup_policy_file = vsan_policy.backup_policy_filename(self.name)
        #Ensure there is no backup policy file
        self.assertFalse(os.path.isfile(backup_policy_file))

        # Fail to update because of a bad policy, and ensure there is no backup
        self.assertNotEqual(None, vsan_policy.update('good', 'blah'))
        self.assertFalse(os.path.isfile(backup_policy_file))
예제 #10
0
def set_vol_opts(name, options):
    # Create a dict of the options, the options are provided as
    # "access=read-only" and we get a dict like {'access': 'read-only'}
    opts_list = "".join(options.replace("=", ":").split())
    opts = dict(i.split(":") for i in opts_list.split(","))

    # create volume path
    try:
       vol_name, datastore = parse_vol_name(name)
    except ValidationError as ex:
       logging.exception(ex)
       return False

    if not datastore:
       msg = "Invalid datastore '{0}'.\n".format(datastore)
       logging.warning(msg)
       return False

    # get /vmfs/volumes/<datastore>/dockvols path on ESX:
    path = get_vol_path(datastore)

    if path is None:
       msg = "Failed to get datastore path {0}".format(path)
       logging.warning(msg)
       return False

    vmdk_path = vmdk_utils.get_vmdk_path(path, vol_name)

    if not os.path.isfile(vmdk_path):
       msg = 'Volume {0} not found.'.format(vol_name)
       logging.warning(msg)
       return False
   
    # For now only allow resetting the access and attach-as options.
    valid_opts = {
        kv.ACCESS : kv.ACCESS_TYPES,
        kv.ATTACH_AS : kv.ATTACH_AS_TYPES
    }

    invalid = frozenset(opts.keys()).difference(valid_opts.keys())
    if len(invalid) != 0:
        msg = 'Invalid options: {0} \n'.format(list(invalid)) \
               + 'Options that can be edited: ' \
               + '{0}'.format(list(valid_opts))
        raise ValidationError(msg)

    has_invalid_opt_value = False   
    for key in opts.keys():
        if key in valid_opts:
            if not opts[key] in valid_opts[key]:
                msg = 'Invalid option value {0}.\n'.format(opts[key]) +\
                    'Supported values are {0}.\n'.format(valid_opts[key])
                logging.warning(msg)
                has_invalid_opt_value = True
                
    if has_invalid_opt_value:
        return False   
    
    vol_meta = kv.getAll(vmdk_path)
    if vol_meta:
       if not vol_meta[kv.VOL_OPTS]:
           vol_meta[kv.VOL_OPTS] = {} 
       for key in opts.keys():
           vol_meta[kv.VOL_OPTS][key] = opts[key]
       return kv.setAll(vmdk_path, vol_meta)

    return False