def get_list(args): '''获取镜像列表''' ret_list = [] storage_api = StorageAPI() image_api = ImageAPI() cephpool = storage_api.get_pool_by_id(args['ceph_id']) if not cephpool.managed_by(args['req_user']): return {'res': False, 'err': ERR_AUTH_PERM} # if 'enable' in args: # enable = args['enable'] # else: # enable = None # 非得改接口…… enable = True image_list = image_api.get_image_list_by_pool_id(args['ceph_id'], enable) for image in image_list: ret_list.append({ 'id': image.id, 'ceph_id': image.cephpool_id, 'name': image.name, 'version': image.version, 'type': image.type_name, 'order': image.order }) return {'res': True, 'list': ret_list}
def get(args): '''获取ceph资源池信息''' ret_list = [] api = StorageAPI() try: pool = api.get_pool_by_id(args['cephpool_id']) if not pool.managed_by(args['req_user']): return {'res': False, 'err': ERR_AUTH_PERM} except Exception as e: print(e) if pool: return { 'res': True, 'info':{ 'id': pool.id, 'pool': pool.pool, 'type': pool.type, 'center_id': pool.center_id, 'host': pool.host, 'port': pool.port, 'uuid': pool.uuid } } return {'res': False, 'err': ERR_CEPHPOOL_ID}
def __init__(self, manager=None, storage_api=None, vm_api=None, group_api=None, quota=None): if not manager: self.manager = CephManager() else: self.manager = manager if not storage_api: self.storage_api = StorageAPI() else: self.storage_api = storage_api if not vm_api: self.vm_api = VmAPI() else: self.vm_api = vm_api if not group_api: self.group_api = GroupAPI() else: self.group_api = group_api if not quota: self.quota = CephQuota() else: self.quota = quota super().__init__()
def get_list(args): '''获取ceph资源池列表''' #如果参数中有group_id,则返回group可用的ceph资源列表 if 'group_id' in args and args['group_id']: return _get_pool_list_by_group_id(args) ret_list = [] storage_api = StorageAPI() center_api = CenterAPI() if not center_api.center_id_exists(args['center_id']): return {'res': False, 'err': ERR_CENTER_ID} center = center_api.get_center_by_id(args['center_id']) try: if not center.managed_by(args['req_user']): return {'res': False, 'err': ERR_AUTH_PERM} pool_list = storage_api.get_pool_list_by_center_id(args['center_id']) except Exception as e: print(e) raise e for pool in pool_list: ret_list.append({ 'id': pool.id, 'pool': pool.pool, 'type': pool.type, 'center_id': pool.center_id, 'host': pool.host, 'port': pool.port, 'uuid': pool.uuid }) return {'res': True, 'list': ret_list}
def __init__(self, manager=None, storage_api=None): if manager: self.manager = manager else: self.manager = ImageManager() if storage_api: self.storage_api = storage_api else: self.storage_api = StorageAPI()
def save(self): try: from storage.api import StorageAPI cephpool = StorageAPI().get_pool_by_id(self.cephpool_id) if cephpool: if not cephpool.exists(self.snap): create_success = cephpool.create_snap(self.snap) protect_success = cephpool.protect_snap(self.snap) if create_success and protect_success: self.snap_exists = True else: self.snap_exists = False except: self.snap_exists = False print('auto create snap error.') super(self.__class__, self).save()
def _get_pool_list_by_group_id(args): '''获取指定计算集群(group)可使用的ceph资源池列表,即根据group可用的quota进行筛选''' ret_list = [] storage_api = StorageAPI() center_api = CenterAPI() volume_api = VolumeAPI() group_id = 'group_id' in args and args['group_id'] print(group_id) group = GroupAPI().get_group_by_id(group_id) if not group.managed_by(args['req_user']): return {'res': False, 'err': ERR_AUTH_PERM} quota_list = volume_api.quota.get_quota_list_by_group_id(group_id=group_id) print(quota_list) pool_list = [] for q in quota_list: if not q['cephpool_id']: continue try: pool = storage_api.get_pool_by_id(q['cephpool_id']) pool_list.append(pool) except Exception as e: print(e) for pool in pool_list: ret_list.append({ 'id': pool.id, 'pool': pool.pool, 'type': pool.type, 'center_id': pool.center_id, 'host': pool.host, 'port': pool.port, 'uuid': pool.uuid }) return {'res': True, 'list': ret_list}
class ImageAPI(object): def __init__(self, manager=None, storage_api=None): if manager: self.manager = manager else: self.manager = ImageManager() if storage_api: self.storage_api = storage_api else: self.storage_api = StorageAPI() def _valid_diskname(self, disk_name): try: disk_name = str(disk_name) except: return False if len(disk_name) <= 0: return False return True def init_disk(self, image_id, disk_name): '''初始化磁盘''' image = self.manager.get_image_by_id(image_id) if not self._valid_diskname(disk_name): raise Error(ERR_DISK_NAME) return self.storage_api.clone(image.cephpool_id, image.snap, disk_name) def rm_disk(self, image_id, disk_name): image = self.manager.get_image_by_id(image_id) if not self._valid_diskname(disk_name): raise Error(ERR_DISK_NAME) return self.storage_api.rm(image.cephpool_id, disk_name) def archive_disk(self, image_id, disk_name, archive_disk_name=None, cephpool_id=None): if archive_disk_name == None: archive_disk_name = 'x_' + datetime.now().strftime( "%Y%m%d%H%M%S") + '_' + str(disk_name) #archive_disk_name = 'x_'+datetime.now().strftime("%Y%m%d%H%M%S%f")+'_'+str(disk_name) else: if not self._valid_diskname(disk_name): raise Error(ERR_DISK_NAME) if not cephpool_id: image = self.manager.get_image_by_id(image_id) cephpool_id = image.cephpool_id if self.storage_api.mv(cephpool_id, disk_name, archive_disk_name): return archive_disk_name return False def disk_exists(self, image_id, disk_name, cephpool_id=None): if not cephpool_id: image = self.manager.get_image_by_id(image_id) cephpool_id = image.cephpool_id return self.storage_api.exists(cephpool_id, disk_name) def restore_disk(self, image_id, archive_disk_name): try: disk_name = archive_disk_name[2:38] except: raise Error(ERR_DISK_NAME) if not self._valid_diskname(disk_name): raise Error(ERR_DISK_NAME) image = self.manager.get_image_by_id(image_id) if self.storage_api.mv(image.cephpool_id, archive_disk_name, disk_name): return True return False def get_image_info_by_id(self, image_id): '''根据镜像ID获取镜像相关的信息, 返回数据格式: { 'image_snap': *******, 'image_name': *******, 'image_version': ***, 'ceph_id': *, 'ceph_host': *.*.*.*, 'ceph_port': ****, 'ceph_uuid': ************************, 'ceph_pool': ******, 'ceph_username': ***** } ''' res = self.manager.get_image_info(image_id) if not res: raise Error(ERR_IMAGE_INFO) return res def get_xml_tpl(self, image_id): image = self.manager.get_image_by_id(image_id) return image.xml def get_image_by_id(self, image_id): return self.manager.get_image_by_id(image_id) def get_image_list_by_pool_id(self, pool_id, enable=None): return self.manager.get_image_list_by_pool_id(pool_id, enable) def get_image_type_list(self): return self.manager.get_image_type_list()
class VolumeAPI(object): def __init__(self, manager=None, storage_api=None, vm_api=None, group_api=None, quota=None): if not manager: self.manager = CephManager() else: self.manager = manager if not storage_api: self.storage_api = StorageAPI() else: self.storage_api = storage_api if not vm_api: self.vm_api = VmAPI() else: self.vm_api = vm_api if not group_api: self.group_api = GroupAPI() else: self.group_api = group_api if not quota: self.quota = CephQuota() else: self.quota = quota super().__init__() def create(self, pool_id, size, group_id=None): cephpool = self.storage_api.get_pool_by_id(pool_id) if not cephpool: raise Error(ERR_VOLUME_CREATE_NOPOOL) if type(size) != int or size <= 0: raise Error(ERR_INT_VOLUME_SIZE) return self.manager.create_volume(cephpool, size, group_id) def delete(self, volume_id, force=False): volume = self.get_volume_by_id(volume_id) if volume.vm: raise Error(ERR_DEL_MOUNTED_VOLUME) cephpool_id = volume.cephpool_id tmp_volume_name = 'x_{}_{}'.format( datetime.now().strftime("%Y%m%d%H%M%S"), volume_id) if self.storage_api.mv(cephpool_id, volume_id, tmp_volume_name): if not volume.delete(): self.storage_api.mv(cephpool_id, tmp_volume_name, volume_id) return False if force == True: if not self.storage_api.rm(cephpool_id, tmp_volume_name): print(ERR_CEPH_RM) else: raise Error(ERR_CEPH_MV) return True def resize(self, volume_id, size): volume = self.get_volume_by_id(volume_id) #if not self.quota.group_quota_validate(volume.group_id, size, volume.size): if not self.quota.group_pool_quota_validate( volume.group_id, volume.cephpool_id, size, volume.size): raise Error(ERR_VOLUME_QUOTA_G) # if not self.quota.volume_quota_validate(volume.group_id, size): if not self.quota.volume_pool_quota_validate(volume.group_id, volume.cephpool_id, size): raise Error(ERR_VOLUME_QUOTA_V) if self.storage_api.resize(volume.cephpool_id, volume.id, size): return volume.resize(size) else: raise Error(ERR_CEPH_RESIZE) def _get_disk_xml(self, volume, dev): cephpool = self.storage_api.get_pool_by_id(volume.cephpool_id) xml = volume.xml_tpl % { 'driver': 'qemu', 'auth_user': cephpool.username, 'auth_type': 'ceph', 'auth_uuid': cephpool.uuid, 'source_protocol': 'rbd', 'pool': cephpool.pool, 'name': volume.id, 'host': cephpool.host, 'port': cephpool.port, 'dev': dev } return xml def mount(self, vm_uuid, volume_id): volume = self.get_volume_by_id(volume_id) vm = self.vm_api.get_vm_by_uuid(vm_uuid) if vm.group_id != volume.group_id: return False disk_list = vm.get_disk_list() mounted_volume_list = self.get_volume_list(vm_uuid=vm_uuid) for v in mounted_volume_list: disk_list.append(v.dev) print(disk_list) i = 0 while True: j = i d = '' while True: d += chr(ord('a') + j % 26) j //= 26 if j <= 0: break if not 'vd' + d in disk_list: dev = 'vd' + d break i += 1 xml = self._get_disk_xml(volume, dev) print(xml) if volume.mount(vm_uuid, dev): try: if self.vm_api.attach_device(vm_uuid, xml): return True except Error as e: volume.umount() raise e return False def umount(self, volume_id): volume = self.get_volume_by_id(volume_id) vm_uuid = volume.vm if self.vm_api.vm_uuid_exists(vm_uuid): vm = self.vm_api.get_vm_by_uuid(vm_uuid) disk_list = vm.get_disk_list() if not volume.dev in disk_list: if volume.umount(): return True return False xml = self._get_disk_xml(volume, volume.dev) if self.vm_api.detach_device(vm_uuid, xml): try: if volume.umount(): return True except Error as e: self.vm_api.attach_device(vm_uuid, xml) raise e else: if volume.umount(): return True return False def set_remark(self, volume_id, content): volume = self.get_volume_by_id(volume_id) return volume.set_remark(content) def get_volume_list_by_pool_id(self, cephpool_id): cephpool = self.storage_api.get_pool_by_id(cephpool_id) return self.manager.get_volume_list(cephpool_id=cephpool_id) def get_volume_list_by_user_id(self, user_id): return self.manager.get_volume_list(user_id=user_id) def get_volume_list_by_group_id(self, group_id): return self.manager.get_volume_list(group_id=group_id) def get_volume_list_by_vm_uuid(self, vm_uuid): return self.manager.get_volume_list(vm_uuid=vm_uuid) def get_volume_list(self, user_id=None, creator=None, cephpool_id=None, group_id=None, vm_uuid=None): return self.manager.get_volume_list(user_id=user_id, creator=creator, cephpool_id=cephpool_id, group_id=group_id, vm_uuid=vm_uuid) def get_volume_by_id(self, volume_id): return self.manager.get_volume_by_id(volume_id) def set_user_id(self, volume_id, user_id): volume = self.get_volume_by_id(volume_id) return volume.set_user_id(user_id) def set_group_id(self, volume_id, group_id): volume = self.get_volume_by_id(volume_id) return volume.set_group_id(group_id)
class ImageAPI(object): def __init__(self, manager=None, storage_api=None): if manager: self.manager = manager else: self.manager = ImageManager() if storage_api: self.storage_api = storage_api else: self.storage_api = StorageAPI() def _valid_diskname(self, disk_name): try: disk_name = str(disk_name) except: return False if len(disk_name) <= 0: return False return True def init_disk(self, image_id, disk_name): '''初始化磁盘''' image = self.manager.get_image_by_id(image_id) if not self._valid_diskname(disk_name): raise Error(ERR_DISK_NAME) return self.storage_api.clone(image.cephpool_id, image.snap, disk_name) def rm_disk(self, image_id, disk_name): image = self.manager.get_image_by_id(image_id) if not self._valid_diskname(disk_name): raise Error(ERR_DISK_NAME) if self.storage_api.rm(image.cephpool_id, disk_name): return self._batch_delete_snaps_db_by_disk_name(disk_name) return False def archive_disk(self, image_id, disk_name, archive_disk_name=None, cephpool_id=None): if archive_disk_name == None: archive_disk_name = 'x_' + datetime.now().strftime( "%Y%m%d%H%M%S") + '_' + str(disk_name) #archive_disk_name = 'x_'+datetime.now().strftime("%Y%m%d%H%M%S%f")+'_'+str(disk_name) else: if not self._valid_diskname(disk_name): raise Error(ERR_DISK_NAME) if not cephpool_id: image = self.manager.get_image_by_id(image_id) cephpool_id = image.cephpool_id if self.storage_api.mv(cephpool_id, disk_name, archive_disk_name): self._batch_update_disk_of_disk_snap(disk_name, archive_disk_name) return archive_disk_name return False def disk_exists(self, image_id, disk_name, cephpool_id=None): if not cephpool_id: image = self.manager.get_image_by_id(image_id) cephpool_id = image.cephpool_id return self.storage_api.exists(cephpool_id, disk_name) def restore_disk(self, image_id, archive_disk_name, disk_name=None): try: if not disk_name: disk_name = archive_disk_name[17:] except: raise Error(ERR_DISK_NAME) if not self._valid_diskname(disk_name): raise Error(ERR_DISK_NAME) image = self.manager.get_image_by_id(image_id) if self.storage_api.mv(image.cephpool_id, archive_disk_name, disk_name): self._batch_update_disk_of_disk_snap(archive_disk_name, disk_name) return True return False def get_image_info_by_id(self, image_id): '''根据镜像ID获取镜像相关的信息, 返回数据格式: { 'image_snap': *******, 'image_name': *******, 'image_version': ***, 'ceph_id': *, 'ceph_host': *.*.*.*, 'ceph_port': ****, 'ceph_uuid': ************************, 'ceph_pool': ******, 'ceph_username': ***** } ''' res = self.manager.get_image_info(image_id) if not res: raise Error(ERR_IMAGE_INFO) return res def get_xml_tpl(self, image_id): image = self.manager.get_image_by_id(image_id) return image.xml def get_image_by_id(self, image_id): return self.manager.get_image_by_id(image_id) def get_image_list_by_pool_id(self, pool_id, enable=None): return self.manager.get_image_list_by_pool_id(pool_id, enable) def get_image_type_list(self): return self.manager.get_image_type_list() def create_disk_snap(self, cephpool_id, disk, image_id, vm_uuid, remarks=None): if not self.disk_exists(image_id, disk, cephpool_id=cephpool_id): if settings.DEBUG: print('[create_disk_snap]', '磁盘不存在', disk) return None snap = datetime.now().strftime("%Y%m%d%H%M%S") fullname = "%s@%s" % (disk, snap) if self.storage_api.create_snap(cephpool_id, fullname): snap_obj = self.manager.create_disk_snap_db(cephpool_id, disk, snap, image_id, vm_uuid, remarks=remarks) if settings.DEBUG: print('[create_disk_snap]', '快照创建成功') return snap_obj if settings.DEBUG: print('[create_disk_snap]', '快照创建失败') return None def get_disk_snap_list_by_disk(self, disk): if self._valid_diskname(disk): return self.manager.get_disk_snap_list_by_disk(disk) return [] def get_disk_snap_by_id(self, disk, snap_id): return self.manager.get_disk_snap_by_id(disk, snap_id) def rollback_disk_snap(self, disk, snap_id): disk_snap = self.get_disk_snap_by_id(disk, snap_id) res = self.storage_api.rollback_snap(disk_snap.cephpool_id, disk_snap.fullname) return res def _batch_update_disk_of_disk_snap(self, old_disk_name, new_disk_name): """批量更新指定disk的快照的disk""" if self._valid_diskname(new_disk_name): return self.manager.batch_update_disk_of_disk_snap( old_disk_name, new_disk_name) return False def _batch_delete_snaps_db_by_disk_name(self, disk): """批量删除指定disk的快照记录""" if self._valid_diskname(disk): return self.manager.batch_delete_disk_snap_db_by_disk(disk) return False def delete_disk_snap_by_id(self, disk, snap_id): disk_snap = self.get_disk_snap_by_id(disk, snap_id) try: if self.storage_api.rm_snap(disk_snap.cephpool_id, disk_snap.fullname): disk_snap.delete() return True except Exception as e: print(e) return False def set_disk_snap_remarks(self, disk, snap_id, remarks): disk_snap = self.get_disk_snap_by_id(disk, snap_id) if disk_snap.set_remarks(remarks): return True return False