Esempio n. 1
0
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}
Esempio n. 2
0
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}
Esempio n. 3
0
    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__()
Esempio n. 4
0
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}
Esempio n. 5
0
 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()
Esempio n. 6
0
 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()
Esempio n. 7
0
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}
Esempio n. 8
0
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()
Esempio n. 9
0
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)
Esempio n. 10
0
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