def _check_drbdconfig_data(action, drbdconfig): if not cutils.is_int_like(drbdconfig['link_util']): raise wsme.exc.ClientSideError( _("DRBD link_util must be an integer.")) if not cutils.is_float_like(drbdconfig['rtt_ms']): raise wsme.exc.ClientSideError( _("DRBD rtt_ms must be a float.")) if ((int(drbdconfig['link_util']) < constants.DRBD_LINK_UTIL_MIN) or (int(drbdconfig['link_util']) > constants.DRBD_LINK_UTIL_MAX)): raise wsme.exc.ClientSideError( _("DRBD link_util must be within: %d to %d" % (constants.DRBD_LINK_UTIL_MIN, constants.DRBD_LINK_UTIL_MAX))) if float(drbdconfig['rtt_ms']) < constants.DRBD_RTT_MS_MIN: raise wsme.exc.ClientSideError( _("DRBD rtt_ms must be at least: %.1f ms" % constants.DRBD_RTT_MS_MIN)) if float(drbdconfig['rtt_ms']) > constants.DRBD_RTT_MS_MAX: raise wsme.exc.ClientSideError( _("DRBD rtt_ms must less than: %.1f ms" % constants.DRBD_RTT_MS_MAX)) return drbdconfig
def _check_ceph_mon(new_cephmon, old_cephmon=None): if not cutils.is_int_like(new_cephmon['ceph_mon_gib']): raise wsme.exc.ClientSideError(_("ceph_mon_gib must be an integer.")) new_ceph_mon_gib = int(new_cephmon['ceph_mon_gib']) if old_cephmon: old_ceph_mon_gib = int(old_cephmon['ceph_mon_gib']) + 1 else: old_ceph_mon_gib = constants.SB_CEPH_MON_GIB_MIN if new_ceph_mon_gib < old_ceph_mon_gib \ or new_ceph_mon_gib > constants.SB_CEPH_MON_GIB_MAX: raise wsme.exc.ClientSideError( _("ceph_mon_gib = %s. Value must be between %s and %s." % (new_ceph_mon_gib, old_ceph_mon_gib, constants.SB_CEPH_MON_GIB_MAX)))
def get_http_port(): # Get the http_port from /etc/platform/platform.conf. prefix = "http_port=" http_port = cconstants.SERVICE_PARAM_HTTP_PORT_HTTP_DEFAULT if os.path.isfile(tsc.PLATFORM_CONF_FILE): with open(tsc.PLATFORM_CONF_FILE, 'r') as platform_file: for line in platform_file: line = line.strip() if line.startswith(prefix): port = line[len(prefix):] if utils.is_int_like(port): LOG.info("Agent found %s%s" % (prefix, port)) http_port = port break else: LOG.info("http_port entry: %s in platform.conf " "is not an integer" % port) return http_port
def _partition_pre_patch_checks(partition_obj, patch_obj, host_obj): """Check current vs. updated parameters.""" # Reject operation if we are upgrading the system. cutils._check_upgrade(pecan.request.dbapi, host_obj) for p in patch_obj: if p['path'] == '/size_mib': if not cutils.is_int_like(p['value']): raise wsme.exc.ClientSideError( _("Requested partition size must be an integer " "greater than 0: %s ") % p['value']) if int(p['value']) <= 0: raise wsme.exc.ClientSideError( _("Requested partition size must be an integer " "greater than 0: %s GiB") % (int(p['value']) / 1024)) if int(p['value']) <= partition_obj.size_mib: raise wsme.exc.ClientSideError( _("Requested partition size must be larger than current " "size: %s GiB <= %s GiB") % (int(p['value']) / 1024, math.floor(float(partition_obj.size_mib) / 1024 * 1000) / 1000.0))
def update_many(self, isystem_uuid, patch): """Update the current controller_fs configuration.""" if self._from_isystems and not isystem_uuid: raise exception.InvalidParameterValue(_( "System id not specified.")) # Validate input filesystem names controller_fs_list = pecan.request.dbapi.controller_fs_get_list() valid_fs_list = [] if controller_fs_list: valid_fs_list = {fs.name: fs.size for fs in controller_fs_list} reinstall_required = False reboot_required = False force_resize = False modified_fs = [] for p_list in patch: p_obj_list = jsonpatch.JsonPatch(p_list) for p_obj in p_obj_list: if p_obj['path'] == '/action': value = p_obj['value'] patch.remove(p_list) if value == constants.FORCE_ACTION: force_resize = True LOG.info("Force action resize selected") break for p_list in patch: p_obj_list = jsonpatch.JsonPatch(p_list) for p_obj in p_obj_list: if p_obj['path'] == '/name': fs_display_name = p_obj['value'] if fs_display_name == constants.FILESYSTEM_DISPLAY_NAME_CGCS: fs_name = constants.FILESYSTEM_NAME_CGCS else: fs_name = fs_display_name elif p_obj['path'] == '/size': size = p_obj['value'] if fs_name not in valid_fs_list.keys() or fs_display_name == constants.FILESYSTEM_NAME_CGCS: msg = _("ControllerFs update failed: invalid filesystem " "'%s' " % fs_display_name) raise wsme.exc.ClientSideError(msg) elif not cutils.is_int_like(size): msg = _("ControllerFs update failed: filesystem '%s' " "size must be an integer " % fs_display_name) raise wsme.exc.ClientSideError(msg) elif int(size) <= int(valid_fs_list[fs_name]): msg = _("ControllerFs update failed: size for filesystem '%s' " "should be bigger than %s " % ( fs_display_name, valid_fs_list[fs_name])) raise wsme.exc.ClientSideError(msg) elif (fs_name == constants.FILESYSTEM_NAME_CGCS and StorageBackendConfig.get_backend(pecan.request.dbapi, constants.CINDER_BACKEND_CEPH)): if force_resize: LOG.warn("Force resize ControllerFs: %s, though Ceph " "storage backend is configured" % fs_display_name) else: raise wsme.exc.ClientSideError( _("ControllerFs %s size is not modifiable as Ceph is " "configured. Update size via Ceph Storage Pools." % fs_display_name)) if fs_name in constants.SUPPORTED_REPLICATED_FILEYSTEM_LIST: if utils.is_drbd_fs_resizing(): raise wsme.exc.ClientSideError( _("A drbd sync operation is currently in progress. " "Retry again later.") ) modified_fs += [fs_name] controller_fs_list_new = [] for fs in controller_fs_list: replaced = False for p_list in patch: p_obj_list = jsonpatch.JsonPatch(p_list) for p_obj in p_obj_list: if p_obj['path'] == '/name': if p_obj['value'] == constants.FILESYSTEM_DISPLAY_NAME_CGCS: p_obj['value'] = constants.FILESYSTEM_NAME_CGCS if p_obj['value'] == fs['name']: try: controller_fs_list_new += [ControllerFs( **jsonpatch.apply_patch(fs.as_dict(), p_obj_list))] replaced = True break except utils.JSONPATCH_EXCEPTIONS as e: raise exception.PatchError(patch=p_list, reason=e) if replaced: break if not replaced: controller_fs_list_new += [fs] cgtsvg_growth_gib = _check_controller_multi_fs_data( pecan.request.context, controller_fs_list_new) if _check_controller_state(): _check_controller_multi_fs(controller_fs_list_new, cgtsvg_growth_gib=cgtsvg_growth_gib) for fs in controller_fs_list_new: if fs.name in modified_fs: value = {'size': fs.size} if fs.replicated: value.update({'state': constants.CONTROLLER_FS_RESIZING_IN_PROGRESS}) pecan.request.dbapi.controller_fs_update(fs.uuid, value) try: # perform rpc to conductor to perform config apply pecan.request.rpcapi.update_storage_config( pecan.request.context, update_storage=False, reinstall_required=reinstall_required, reboot_required=reboot_required, filesystem_list=modified_fs ) except Exception as e: msg = _("Failed to update filesystem size ") LOG.error("%s with patch %s with exception %s" % (msg, patch, e)) raise wsme.exc.ClientSideError(msg)
def test_is_int_like(self): self.assertTrue(utils.is_int_like(1)) self.assertTrue(utils.is_int_like("1")) self.assertTrue(utils.is_int_like("514")) self.assertTrue(utils.is_int_like("0")) self.assertFalse(utils.is_int_like(1.1)) self.assertFalse(utils.is_int_like("1.1")) self.assertFalse(utils.is_int_like("1.1.1")) self.assertFalse(utils.is_int_like(None)) self.assertFalse(utils.is_int_like("0.")) self.assertFalse(utils.is_int_like("aaaaaa")) self.assertFalse(utils.is_int_like("....")) self.assertFalse(utils.is_int_like("1g")) self.assertFalse( utils.is_int_like("0cc3346e-9fef-4445-abe6-5d2b2690ec64")) self.assertFalse(utils.is_int_like("a1"))
def update_many(self, isystem_uuid, patch): """Update the current controller_fs configuration.""" if self._from_isystems and not isystem_uuid: raise exception.InvalidParameterValue( _("System id not specified.")) # Validate input filesystem names controller_fs_list = pecan.request.dbapi.controller_fs_get_list() valid_fs_list = [] if controller_fs_list: valid_fs_list = {fs.name: fs.size for fs in controller_fs_list} reinstall_required = False reboot_required = False modified_fs = [] update_fs_list = [] for p_list in patch: p_obj_list = jsonpatch.JsonPatch(p_list) for p_obj in p_obj_list: if p_obj['path'] == '/name': fs_name = p_obj['value'] if fs_name in update_fs_list: msg = _("Duplicate fs_name " "'%s' in parameter list" % fs_name) raise wsme.exc.ClientSideError(msg) else: update_fs_list.append(fs_name) elif p_obj['path'] == '/size': size = p_obj['value'] if fs_name not in valid_fs_list.keys(): msg = _("ControllerFs update failed: invalid filesystem " "'%s' " % fs_name) raise wsme.exc.ClientSideError(msg) elif not cutils.is_int_like(size): msg = _("ControllerFs update failed: filesystem '%s' " "size must be an integer " % fs_name) raise wsme.exc.ClientSideError(msg) elif int(size) <= int(valid_fs_list[fs_name]): msg = _("ControllerFs update failed: size for filesystem '%s' " "should be bigger than %s " % (fs_name, valid_fs_list[fs_name])) raise wsme.exc.ClientSideError(msg) if fs_name in constants.SUPPORTED_REPLICATED_FILEYSTEM_LIST: if utils.is_drbd_fs_resizing(): raise wsme.exc.ClientSideError( _("A drbd sync operation is currently in progress. " "Retry again later.")) modified_fs += [fs_name] controller_fs_list_new = [] for fs in controller_fs_list: replaced = False for p_list in patch: p_obj_list = jsonpatch.JsonPatch(p_list) for p_obj in p_obj_list: if p_obj['value'] == fs['name']: try: controller_fs_list_new += [ ControllerFs(**jsonpatch.apply_patch( fs.as_dict(), p_obj_list)) ] replaced = True break except utils.JSONPATCH_EXCEPTIONS as e: raise exception.PatchError(patch=p_list, reason=e) if replaced: break if not replaced: controller_fs_list_new += [fs] cgtsvg_growth_gib = _check_controller_multi_fs_data( pecan.request.context, controller_fs_list_new) if _check_controller_state(): _check_controller_multi_fs(controller_fs_list_new, cgtsvg_growth_gib=cgtsvg_growth_gib) for fs in controller_fs_list_new: if fs.name in modified_fs: value = {'size': fs.size} if fs.replicated: value.update({ 'state': constants.CONTROLLER_FS_RESIZING_IN_PROGRESS }) pecan.request.dbapi.controller_fs_update(fs.uuid, value) try: # perform rpc to conductor to perform config apply pecan.request.rpcapi.update_storage_config( pecan.request.context, update_storage=False, reinstall_required=reinstall_required, reboot_required=reboot_required, filesystem_list=modified_fs) except Exception as e: msg = _("Failed to update filesystem size ") LOG.error("%s with patch %s with exception %s" % (msg, patch, e)) raise wsme.exc.ClientSideError(msg)
def update_many(self, ihost_uuid, patch): """Update existing filesystems for a host.""" LOG.info("patch_data: %s" % patch) # Validate input filesystem names current_host_fs_list = pecan.request.dbapi.host_fs_get_by_ihost( ihost_uuid) host = pecan.request.dbapi.ihost_get(ihost_uuid) modified_fs = [] for p_list in patch: p_obj_list = jsonpatch.JsonPatch(p_list) for p_obj in p_obj_list: if p_obj['path'] == '/action': value = p_obj['value'] patch.remove(p_list) for p_list in patch: p_obj_list = jsonpatch.JsonPatch(p_list) for p_obj in p_obj_list: if p_obj['path'] == '/name': fs_display_name = p_obj['value'] fs_name = fs_display_name elif p_obj['path'] == '/size': size = p_obj['value'] if fs_name not in [fs['name'] for fs in current_host_fs_list]: msg = _("HostFs update failed: invalid filesystem " "'%s' " % fs_display_name) raise wsme.exc.ClientSideError(msg) elif not cutils.is_int_like(size): msg = _("HostFs update failed: filesystem '%s' " "size must be an integer " % fs_display_name) raise wsme.exc.ClientSideError(msg) current_size = [ fs['size'] for fs in current_host_fs_list if fs['name'] == fs_name ][0] if int(size) <= int(current_size): msg = _("HostFs update failed: size for filesystem '%s' " "should be bigger than %s " % (fs_display_name, current_size)) raise wsme.exc.ClientSideError(msg) modified_fs += [fs_name] if not modified_fs: msg = _("HostFs update failed: no filesystems to update") raise wsme.exc.ClientSideError(msg) host_fs_list_new = [] for fs in current_host_fs_list: replaced = False for p_list in patch: p_obj_list = jsonpatch.JsonPatch(p_list) for p_obj in p_obj_list: if p_obj['value'] == fs['name']: try: host_fs_list_new += [ HostFs(**jsonpatch.apply_patch( fs.as_dict(), p_obj_list)) ] replaced = True break except utils.JSONPATCH_EXCEPTIONS as e: raise exception.PatchError(patch=p_list, reason=e) if replaced: break if not replaced: host_fs_list_new += [fs] requested_growth_gib = \ _calculate_requested_growth(current_host_fs_list, host_fs_list_new) LOG.info("Requested growth in GiB: %s" % requested_growth_gib) cgtsvg_free_space_gib = utils.get_node_cgtsvg_limit(host) if requested_growth_gib > cgtsvg_free_space_gib: msg = _("HostFs update failed: Not enough free space on %s. " "Current free space %s GiB, " "requested total increase %s GiB" % (constants.LVG_CGTS_VG, cgtsvg_free_space_gib, requested_growth_gib)) LOG.warning(msg) raise wsme.exc.ClientSideError(msg) for fs in host_fs_list_new: if fs.name in modified_fs: value = {'size': fs.size} pecan.request.dbapi.host_fs_update(fs.uuid, value) try: if (host.invprovision in [constants.PROVISIONED, constants.PROVISIONING]): # perform rpc to conductor to perform config apply pecan.request.rpcapi.update_host_filesystem_config( pecan.request.context, host=host, filesystem_list=modified_fs, ) except Exception as e: msg = _("Failed to update filesystem size for %s" % host.name) LOG.error("%s with patch %s with exception %s" % (msg, patch, e)) raise wsme.exc.ClientSideError(msg)