def _create(partition, iprofile=None, applyprofile=None): # Reject operation if we are upgrading the system. ihostid = partition.get('forihostid') or partition.get('ihost_uuid') ihost = pecan.request.dbapi.ihost_get(ihostid) cutils._check_upgrade(pecan.request.dbapi, ihost) if uuidutils.is_uuid_like(ihostid): forihostid = ihost['id'] else: forihostid = ihostid partition.update({'forihostid': forihostid}) # Add any additional default values # Semantic Checks _semantic_checks(constants.PARTITION_CMD_CREATE, partition) # Set the proposed device_path partition['device_node'], partition['device_path'] =\ _build_device_node_path(partition) # Set the status of the new partition if (ihost.invprovision in [constants.PROVISIONED, constants.PROVISIONING] and not iprofile): partition['status'] = constants.PARTITION_CREATE_IN_SVC_STATUS else: partition['status'] = constants.PARTITION_CREATE_ON_UNLOCK_STATUS # If the host is unprovisioned, reflect the size of this partition # in the available space reported for the disk. idiskid = partition.get('idisk_id') or partition.get('idisk_uuid') idisk = pecan.request.dbapi.idisk_get(idiskid) new_available_mib = idisk.available_mib - partition['size_mib'] pecan.request.dbapi.idisk_update(idiskid, {'available_mib': new_available_mib}) try: # Update the database new_partition = pecan.request.dbapi.partition_create( forihostid, partition) # Check if this host has been provisioned. If so, attempt an in-service # action. If not, we'll just stage the DB changes to and let the unlock # apply the manifest changes # - PROVISIONED: standard controller/worker (after config_controller) # - PROVISIONING: AIO (after config_controller) and before worker # configuration if (ihost.invprovision in [constants.PROVISIONED, constants.PROVISIONING] and not iprofile): # Instruct puppet to implement the change pecan.request.rpcapi.update_partition_config( pecan.request.context, partition) except exception.HTTPNotFound: msg = _("Creating partition failed for host %s ") % (ihost['hostname']) raise wsme.exc.ClientSideError(msg) except exception.PartitionAlreadyExists: msg = _("Disk partition %s already exists." % partition.get('device_path')) raise wsme.exc.ClientSideError(msg) return new_partition
def _delete(partition): # Reject operation if we are upgrading the system unless it is a new host. ihostid = partition.get('forihostid') or partition.get('ihost_uuid') ihost = pecan.request.dbapi.ihost_get(ihostid) cutils._check_upgrade(pecan.request.dbapi, ihost) # Semantic Checks. _semantic_checks(constants.PARTITION_CMD_DELETE, partition) if partition.get('status') in constants.PARTITION_STATUS_SEND_DELETE_RPC: # Set the status of the partition part_dict = {'status': constants.PARTITION_DELETING_STATUS} # Mark the partition as deleting and send the request to the host. try: pecan.request.dbapi.partition_update(partition['uuid'], part_dict) # Instruct puppet to implement the change pecan.request.rpcapi.update_partition_config(pecan.request.context, partition) except exception.HTTPNotFound: msg = _("Marking partition for deletion failed: host %s") %\ (ihost['hostname']) raise wsme.exc.ClientSideError(msg) else: if (partition.get('status') == constants.PARTITION_CREATE_ON_UNLOCK_STATUS): idiskid = partition.get('idisk_id') or partition.get('idisk_uuid') idisk = pecan.request.dbapi.idisk_get(idiskid) new_available_mib = idisk.available_mib + partition['size_mib'] pecan.request.dbapi.idisk_update( idiskid, {'available_mib': new_available_mib}) # Handle the delete case where the create failed (partitioning issue or # puppet issue) and we don't have a valid device_path or when the # partition will be created on unlock. Just delete the partition entry. try: pecan.request.dbapi.partition_destroy(partition['uuid']) except exception.HTTPNotFound: msg = _("Partition deletion failed for host %s") %\ (ihost['hostname']) raise wsme.exc.ClientSideError(msg)
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))