def do_convert(args): volume_abs_path = args[1] raw_volume_abs_path = volume_abs_path + RAW_SUFFIX qcow2_volume_abs_path = volume_abs_path + QCOW2_SUFFIX check(volume_abs_path, raw_volume_abs_path) volume_size = lvm.get_lv_size(volume_abs_path) lvm.create_lv_from_absolute_path(raw_volume_abs_path, volume_size) with lvm.RecursiveOperateLv(volume_abs_path, shared=False, delete_when_exception=False): with lvm.OperateLv(raw_volume_abs_path, shared=False, delete_when_exception=False): lvm.add_lv_tag(volume_abs_path, START_TAG) r, o, e = qcow2_convert_to_raw(volume_abs_path, raw_volume_abs_path) if r != 0: logger.warn("convert failed: %s, removing tag and raw volume") lvm.clean_lv_tag(volume_abs_path, START_TAG) lvm.delete_lv(raw_volume_abs_path) return lvm.add_lv_tag(volume_abs_path, DONE_TAG) lvm.clean_lv_tag(volume_abs_path, START_TAG) lvm.lv_rename(volume_abs_path, qcow2_volume_abs_path, overwrite=False) lvm.lv_rename(raw_volume_abs_path, volume_abs_path, overwrite=False)
def migrate_volumes(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = AgentRsp() for struct in cmd.migrateVolumeStructs: target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath) current_abs_path = translate_absolute_path_from_install_path(struct.currentInstallPath) with lvm.OperateLv(current_abs_path, shared=True): virtual_size = lvm.get_lv_size(current_abs_path) if lvm.lv_exists(target_abs_path): target_ps_uuid = get_primary_storage_uuid_from_install_path(struct.targetInstallPath) raise Exception("found %s already exists on ps %s" % (target_abs_path, target_ps_uuid)) lvm.create_lv_from_absolute_path(target_abs_path, virtual_size, "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time())) lvm.active_lv(target_abs_path, lvm.LvmlockdLockType.SHARE) try: for struct in cmd.migrateVolumeStructs: target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath) current_abs_path = translate_absolute_path_from_install_path(struct.currentInstallPath) with lvm.OperateLv(current_abs_path, shared=True): bash.bash_errorout("cp %s %s" % (current_abs_path, target_abs_path)) for struct in cmd.migrateVolumeStructs: target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath) current_abs_path = translate_absolute_path_from_install_path(struct.currentInstallPath) with lvm.RecursiveOperateLv(current_abs_path, shared=True): previous_ps_uuid = get_primary_storage_uuid_from_install_path(struct.currentInstallPath) target_ps_uuid = get_primary_storage_uuid_from_install_path(struct.targetInstallPath) current_backing_file = linux.qcow2_get_backing_file(current_abs_path) # type: str target_backing_file = current_backing_file.replace(previous_ps_uuid, target_ps_uuid) if current_backing_file is not None and current_backing_file != "": lvm.do_active_lv(target_backing_file, lvm.LvmlockdLockType.SHARE, False) logger.debug("rebase %s to %s" % (target_abs_path, target_backing_file)) linux.qcow2_rebase_no_check(target_backing_file, target_abs_path) if struct.compareQcow2: bash.bash_errorout("time qemu-img compare %s %s" % (current_abs_path, target_abs_path)) except Exception as e: for struct in cmd.migrateVolumeStructs: target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath) if struct.currentInstallPath == struct.targetInstallPath: logger.debug("current install path %s equals target %s, skip to delete" % (struct.currentInstallPath, struct.targetInstallPath)) else: logger.debug("error happened, delete lv %s" % target_abs_path) lvm.delete_lv(target_abs_path, False) raise e finally: for struct in cmd.migrateVolumeStructs: target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath) lvm.deactive_lv(target_abs_path) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def do_delete_bits(self, path): install_abs_path = translate_absolute_path_from_install_path(path) if lvm.has_lv_tag(install_abs_path, IMAGE_TAG): logger.info('deleting lv image: ' + install_abs_path) lvm.delete_image(install_abs_path, IMAGE_TAG) else: logger.info('deleting lv volume: ' + install_abs_path) lvm.delete_lv(install_abs_path)
def __exit__(self, exc_type, exc_val, exc_tb): if exc_val is not None and self.delete_when_exception is True: self.resource.destroy() lvm.delete_lv(self.resource.config.local_host.disk, False) return if self.current_role == DrbdRole.Secondary and not self.shared: self.resource.demote()
def create_empty_volume(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = VolumeRsp() install_abs_path = get_absolute_path_from_install_path(cmd.installPath) drbdResource = drbd.DrbdResource( self.get_name_from_installPath(cmd.installPath), False) drbdResource.config.local_host.hostname = cmd.local_host_name drbdResource.config.local_host.disk = install_abs_path drbdResource.config.local_host.minor = cmd.local_host_port - DRBD_START_PORT drbdResource.config.local_host.address = "%s:%s" % ( cmd.local_address, cmd.local_host_port) drbdResource.config.remote_host.hostname = cmd.remote_host_name drbdResource.config.remote_host.disk = install_abs_path drbdResource.config.remote_host.minor = cmd.remote_host_port - DRBD_START_PORT drbdResource.config.remote_host.address = "%s:%s" % ( cmd.remote_address, cmd.remote_host_port) drbdResource.config.write_config() try: if cmd.backingFile: backing_abs_path = get_absolute_path_from_install_path( cmd.backingFile) virtual_size = linux.qcow2_virtualsize(backing_abs_path) lvm.create_lv_from_cmd( install_abs_path, virtual_size, cmd, "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time()), False) lvm.active_lv(install_abs_path) drbdResource.initialize(cmd.init, cmd, backing_abs_path) elif not lvm.lv_exists(install_abs_path): lvm.create_lv_from_cmd( install_abs_path, cmd.size, cmd, "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time()), False) lvm.active_lv(install_abs_path) drbdResource.initialize(cmd.init, cmd) except Exception as e: drbdResource.destroy() lvm.delete_lv(install_abs_path) logger.debug( 'failed to create empty volume[uuid:%s, size:%s] at %s' % (cmd.volumeUuid, cmd.size, cmd.installPath)) raise e logger.debug( 'successfully create empty volume[uuid:%s, size:%s] at %s' % (cmd.volumeUuid, cmd.size, cmd.installPath)) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) rsp._init_from_drbd(drbdResource) return jsonobject.dumps(rsp)
def do_delete_bits(self, path): install_abs_path = get_absolute_path_from_install_path(path) if lvm.has_lv_tag(install_abs_path, IMAGE_TAG): logger.info('deleting lv image: ' + install_abs_path) if lvm.lv_exists(install_abs_path): lvm.delete_image(install_abs_path, IMAGE_TAG) else: logger.info('deleting lv volume: ' + install_abs_path) r = drbd.DrbdResource(self.get_name_from_installPath(path)) r.destroy() lvm.delete_lv(install_abs_path) lvm.delete_snapshots(install_abs_path)
def delete_bits(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = AgentRsp() if cmd.folder: raise Exception("not support this operation") install_abs_path = translate_absolute_path_from_install_path(cmd.path) if lvm.has_lv_tag(install_abs_path, IMAGE_TAG): logger.info('deleting lv image: ' + install_abs_path) lvm.delete_image(install_abs_path, IMAGE_TAG) else: logger.info('deleting lv volume: ' + install_abs_path) lvm.delete_lv(install_abs_path) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def create_root_volume(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = VolumeRsp() template_abs_path_cache = get_absolute_path_from_install_path( cmd.templatePathInCache) install_abs_path = get_absolute_path_from_install_path(cmd.installPath) drbdResource = drbd.DrbdResource( self.get_name_from_installPath(cmd.installPath), False) drbdResource.config.local_host.hostname = cmd.local_host_name drbdResource.config.local_host.disk = install_abs_path drbdResource.config.local_host.minor = cmd.local_host_port - DRBD_START_PORT drbdResource.config.local_host.address = "%s:%s" % ( cmd.local_address, cmd.local_host_port) drbdResource.config.remote_host.hostname = cmd.remote_host_name drbdResource.config.remote_host.disk = install_abs_path drbdResource.config.remote_host.minor = cmd.remote_host_port - DRBD_START_PORT drbdResource.config.remote_host.address = "%s:%s" % ( cmd.remote_address, cmd.remote_host_port) drbdResource.config.write_config() virtual_size = linux.qcow2_virtualsize(template_abs_path_cache) try: lvm.qcow2_lv_recursive_active(template_abs_path_cache, lvm.LvmlockdLockType.SHARE) if not lvm.lv_exists(install_abs_path): lvm.create_lv_from_cmd( install_abs_path, virtual_size, cmd, "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time()), False) lvm.active_lv(install_abs_path) drbdResource.initialize(cmd.init, cmd, template_abs_path_cache) except Exception as e: drbdResource.destroy() lvm.delete_lv(install_abs_path) raise e rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) rsp._init_from_drbd(drbdResource) return jsonobject.dumps(rsp)
def do_delete_qcwo2(op, vguuid): paths = do_find_qcow2(vguuid) if op == "find_qcow2": return for path in paths: lvm.delete_lv(path)
def migrate_volumes(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = AgentRsp() for struct in cmd.migrateVolumeStructs: target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath) current_abs_path = translate_absolute_path_from_install_path(struct.currentInstallPath) with lvm.OperateLv(current_abs_path, shared=True): lv_size = lvm.get_lv_size(current_abs_path) if lvm.lv_exists(target_abs_path): target_ps_uuid = get_primary_storage_uuid_from_install_path(struct.targetInstallPath) raise Exception("found %s already exists on ps %s" % (target_abs_path, target_ps_uuid)) lvm.create_lv_from_absolute_path(target_abs_path, lvm.getOriginalSize(lv_size), "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time())) lvm.active_lv(target_abs_path, lvm.LvmlockdLockType.SHARE) try: for struct in cmd.migrateVolumeStructs: target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath) current_abs_path = translate_absolute_path_from_install_path(struct.currentInstallPath) with lvm.OperateLv(current_abs_path, shared=True): bash.bash_errorout("cp %s %s" % (current_abs_path, target_abs_path)) for struct in cmd.migrateVolumeStructs: target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath) current_abs_path = translate_absolute_path_from_install_path(struct.currentInstallPath) with lvm.RecursiveOperateLv(current_abs_path, shared=True): previous_ps_uuid = get_primary_storage_uuid_from_install_path(struct.currentInstallPath) target_ps_uuid = get_primary_storage_uuid_from_install_path(struct.targetInstallPath) current_backing_file = linux.qcow2_get_backing_file(current_abs_path) # type: str target_backing_file = current_backing_file.replace(previous_ps_uuid, target_ps_uuid) if struct.compareQcow2: logger.debug("comparing qcow2 between %s and %s" % (current_abs_path, target_abs_path)) if not self.compare(current_abs_path, target_abs_path): raise Exception("qcow2 %s and %s are not identical" % (current_abs_path, target_abs_path)) logger.debug("confirmed qcow2 %s and %s are identical" % (current_abs_path, target_abs_path)) if current_backing_file is not None and current_backing_file != "": lvm.do_active_lv(target_backing_file, lvm.LvmlockdLockType.SHARE, False) logger.debug("rebase %s to %s" % (target_abs_path, target_backing_file)) linux.qcow2_rebase_no_check(target_backing_file, target_abs_path) except Exception as e: for struct in cmd.migrateVolumeStructs: target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath) if struct.currentInstallPath == struct.targetInstallPath: logger.debug("current install path %s equals target %s, skip to delete" % (struct.currentInstallPath, struct.targetInstallPath)) else: logger.debug("error happened, delete lv %s" % target_abs_path) lvm.delete_lv(target_abs_path, False) raise e finally: for struct in cmd.migrateVolumeStructs: target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath) lvm.deactive_lv(target_abs_path) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def active_lv(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = ActiveRsp() rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size( cmd.vgUuid, raise_exception=False) install_abs_path = get_absolute_path_from_install_path(cmd.installPath) if lvm.has_lv_tag(install_abs_path, IMAGE_TAG): lvm.qcow2_lv_recursive_active(install_abs_path, lvm.LvmlockdLockType.SHARE) return jsonobject.dumps(rsp) drbdResource = drbd.DrbdResource( self.get_name_from_installPath(cmd.installPath)) if cmd.role == drbd.DrbdRole.Secondary: drbdResource.demote() rsp._init_from_drbd(drbdResource) return jsonobject.dumps(rsp) if self.test_network_ok_to_peer(drbdResource.config.remote_host.address.split(":")[0]) is False \ and mini_fencer.test_fencer(cmd.vgUuid, drbdResource.name) is False: raise Exception("can not connect storage network or fencer") if cmd.checkPeer and drbdResource.get_remote_role( ) == drbd.DrbdRole.Primary: raise Exception("remote is also in primary role, can not promote") if drbdResource.get_dstate() != "UpToDate": raise Exception("local data is not uptodate, can not promote") lvm.qcow2_lv_recursive_active(install_abs_path, lvm.LvmlockdLockType.EXCLUSIVE) try: drbdResource.promote() except Exception as e: if not cmd.force: raise e if self.test_network_ok_to_peer( drbdResource.config.remote_host.address.split(":")[0]): raise Exception( "storage network address %s still connected, wont force promote" % drbdResource.config.remote_host.address.split(":")[0]) if cmd.vmNics: for vmNic in cmd.vmNics: if self.test_network_ok_to_peer(vmNic.ipAddress, vmNic.bridgeName): raise Exception( "could arping %s via %s, it may split brain, wont proceed force promote" % (vmNic.ipAddress, vmNic.bridgeName)) snap_path = None try: snap_path = lvm.create_lvm_snapshot(install_abs_path) drbdResource.promote(True, 2, 2) rsp.snapPath = snap_path except Exception as ee: if snap_path is not None: lvm.delete_lv(snap_path) raise ee rsp._init_from_drbd(drbdResource) return jsonobject.dumps(rsp)