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 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 policy_path(name): """ Return the path to a given policy file or None if VSAN datastore doesn't exist """ path = vsan_info.get_vsan_dockvols_path() if not path: return None return os.path.join(path, 'policies', name)
def list_volumes_and_policies(): """ Return a list of vmdks and the policies in use""" vmdks_and_policies = [] path = vsan_info.get_vsan_dockvols_path() if not path: return [] for vmdk in vmdk_utils.list_vmdks(path): policy = kv_get_vsan_policy_name(os.path.join(path, vmdk)) vmdks_and_policies.append({'volume': vmdk, 'policy': policy}) return vmdks_and_policies
def get_policies(): """ Return a dict of all VSAN policy names to policy content. """ policies = {} path = vsan_info.get_vsan_dockvols_path() if not path: return {} path = make_policies_dir(path) for name in os.listdir(path): with open(os.path.join(path, name)) as f: content = f.read() policies[name] = content return policies
def list_volumes_and_policies(): """ Return a list of vmdks and the policies in use""" vmdks_and_policies = [] path = vsan_info.get_vsan_dockvols_path() if not path: return [] for volume in vmdk_utils.get_volumes("*"): logging.debug("volume data is %s", volume) policy = kv_get_vsan_policy_name(os.path.join(volume['path'], volume['filename'])) vmdks_and_policies.append({'volume': volume['filename'], 'policy': policy, 'path': volume['path']}) return vmdks_and_policies
def delete(name): """ Remove a given policy. If the policy does not exist return an error string, otherwise return None """ path = vsan_info.get_vsan_dockvols_path() if not path: return ERROR_NO_VSAN_DATASTORE vmdk = policy_in_use(path, name) if vmdk: return 'Error: Cannot remove. Policy is in use by {0}'.format(vmdk) try: os.remove(policy_path(name)) except: logging.exception("Failed to remove %s policy file", name) return 'Error: {0} does not exist'.format(name) return None
def create(name, content): """ Create a new storage policy and save it as dockvols/policies/name in the VSAN datastore. If there are VSAN volumes currently using a policy with the same name, creation will fail. Return a string on error and None on success. """ datastore_path = vsan_info.get_vsan_dockvols_path() if not datastore_path: return ERROR_NO_VSAN_DATASTORE policies_dir = make_policies_dir(datastore_path) filename = os.path.join(policies_dir, name) if os.path.isfile(filename): return 'Error: Policy already exists' if not validate_vsan_policy_string(content): return 'Error: Invalid policy string' return create_policy_file(filename, content)
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))
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))
def update_vsan_objects_with_policy(name, content): """ Find all VSAN objects using the policy given by `name` and update the policy contents in their objects. Returns an error string containing the list of volumes that failed to update, or a msg if there were no volumes to update. Returns None if all volumes were updated successfully. Note: This function assumes datastore_path exists. """ update_count = 0 failed_updates = [] dockvols_path = vsan_info.get_vsan_dockvols_path() print("This operation may take a while. Please be patient.") for v in list_volumes_and_policies(): if v['policy'] == name: volume_name = v['volume'] vmdk_path = os.path.join(dockvols_path, volume_name) if vsan_info.set_policy(vmdk_path, content): update_count = 1 else: failed_updates.append(volume_name) if len(failed_updates) != 0: if update_count == 0: # All volumes failed to update, so reset the original policy os.rename(policy_path(backup_policy_filename(name)), policy_path(name)) else: log_failed_updates(failed_updates, name) return ('Successfully updated {0} volumes.\n' 'Failed to update volumes: {0}').format( update_count, failed_updates) # Remove old policy file on success os.remove(policy_path(backup_policy_filename(name))) return None
def update_vsan_objects_with_policy(name, content): """ Find all VSAN objects using the policy given by `name` and update the policy contents in their objects. Returns an error string containing the list of volumes that failed to update, or a msg if there were no volumes to update. Returns None if all volumes were updated successfully. Note: This function assumes datastore_path exists. """ update_count = 0 failed_updates = [] dockvols_path = vsan_info.get_vsan_dockvols_path() print("This operation may take a while. Please be patient.") for v in list_volumes_and_policies(): if v['policy'] == name: volume_name = v['volume'] vmdk_path = os.path.join(dockvols_path, volume_name) if vsan_info.set_policy(vmdk_path, content): update_count = 1 else: failed_updates.append(volume_name) if len(failed_updates) != 0: if update_count == 0: # All volumes failed to update, so reset the original policy os.rename(policy_path(backup_policy_filename(name)), policy_path(name)) else: log_failed_updates(failed_updates, name) return ('Successfully updated {0} volumes.\n' 'Failed to update volumes: {0}').format(update_count, failed_updates) # Remove old policy file on success os.remove(policy_path(backup_policy_filename(name))) return None
def setUp(self): self.policy_path = os.path.join(vsan_info.get_vsan_dockvols_path(), 'policies/test_policy') self.name = 'test_policy' self.content = ('(("proportionalCapacity" i50) ' '("hostFailuresToTolerate" i0))')