def create_template_from_volume(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = AgentRsp() volume_abs_path = translate_absolute_path_from_install_path(cmd.volumePath) install_abs_path = translate_absolute_path_from_install_path(cmd.installPath) if cmd.sharedVolume: lvm.do_active_lv(volume_abs_path, lvm.LvmlockdLockType.SHARE, True) with lvm.RecursiveOperateLv(volume_abs_path, shared=cmd.sharedVolume, skip_deactivate_tags=[IMAGE_TAG]): virtual_size = linux.qcow2_virtualsize(volume_abs_path) total_size = 0 for qcow2 in linux.qcow2_get_file_chain(volume_abs_path): total_size += int(lvm.get_lv_size(qcow2)) if total_size > virtual_size: total_size = virtual_size if not lvm.lv_exists(install_abs_path): lvm.create_lv_from_absolute_path(install_abs_path, total_size, "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time())) with lvm.OperateLv(install_abs_path, shared=False, delete_when_exception=True): linux.create_template(volume_abs_path, install_abs_path) logger.debug('successfully created template[%s] from volume[%s]' % (cmd.installPath, cmd.volumePath)) if cmd.compareQcow2 is True: logger.debug("comparing qcow2 between %s and %s") bash.bash_errorout("time qemu-img compare %s %s" % (volume_abs_path, install_abs_path)) logger.debug("confirmed qcow2 %s and %s are identical" % (volume_abs_path, install_abs_path)) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def offline_merge_snapshots(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = OfflineMergeSnapshotRsp() src_abs_path = translate_absolute_path_from_install_path(cmd.srcPath) dst_abs_path = translate_absolute_path_from_install_path(cmd.destPath) with lvm.RecursiveOperateLv(src_abs_path, shared=True): virtual_size = linux.qcow2_virtualsize(src_abs_path) if not lvm.lv_exists(dst_abs_path): lvm.create_lv_from_absolute_path( dst_abs_path, virtual_size, "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time())) with lvm.RecursiveOperateLv(dst_abs_path, shared=False): if not cmd.fullRebase: linux.qcow2_rebase(src_abs_path, dst_abs_path) else: tmp_lv = 'tmp_%s' % uuidhelper.uuid() tmp_abs_path = os.path.join(os.path.dirname(dst_abs_path), tmp_lv) tmp_abs_path = os.path.join(os.path.dirname(dst_abs_path), tmp_lv) logger.debug("creating temp lv %s" % tmp_abs_path) lvm.create_lv_from_absolute_path( tmp_abs_path, virtual_size, "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time())) with lvm.OperateLv(tmp_abs_path, shared=False, delete_when_exception=True): linux.create_template(dst_abs_path, tmp_abs_path) lvm.lv_rename(tmp_abs_path, dst_abs_path, overwrite=True) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def offline_merge_snapshots(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = OfflineMergeSnapshotRsp() src_abs_path = translate_absolute_path_from_install_path(cmd.srcPath) dst_abs_path = translate_absolute_path_from_install_path(cmd.destPath) with lvm.RecursiveOperateLv(src_abs_path, shared=True): virtual_size = linux.qcow2_virtualsize(src_abs_path) if not lvm.lv_exists(dst_abs_path): lvm.create_lv_from_absolute_path(dst_abs_path, virtual_size, "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time())) with lvm.RecursiveOperateLv(dst_abs_path, shared=False): if not cmd.fullRebase: linux.qcow2_rebase(src_abs_path, dst_abs_path) else: tmp_lv = 'tmp_%s' % uuidhelper.uuid() tmp_abs_path = os.path.join(os.path.dirname(dst_abs_path), tmp_lv) tmp_abs_path = os.path.join(os.path.dirname(dst_abs_path), tmp_lv) logger.debug("creating temp lv %s" % tmp_abs_path) lvm.create_lv_from_absolute_path(tmp_abs_path, virtual_size, "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time())) with lvm.OperateLv(tmp_abs_path, shared=False, delete_when_exception=True): linux.create_template(dst_abs_path, tmp_abs_path) lvm.lv_rename(tmp_abs_path, dst_abs_path, overwrite=True) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def download_from_sftp(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = AgentRsp() install_abs_path = translate_absolute_path_from_install_path( cmd.primaryStorageInstallPath) size = linux.sftp_get(cmd.hostname, cmd.sshKey, cmd.backupStorageInstallPath, install_abs_path, cmd.username, cmd.sshPort, True) if not lvm.lv_exists(install_abs_path): lvm.create_lv_from_absolute_path( install_abs_path, size, "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time())) with lvm.OperateLv(install_abs_path, shared=False, delete_when_exception=True): linux.scp_download(cmd.hostname, cmd.sshKey, cmd.backupStorageInstallPath, install_abs_path, cmd.username, cmd.sshPort) logger.debug('successfully download %s/%s to %s' % (cmd.hostname, cmd.backupStorageInstallPath, cmd.primaryStorageInstallPath)) self.do_active_lv(cmd.primaryStorageInstallPath, cmd.lockType, False) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def create_empty_volume(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = AgentRsp() install_abs_path = translate_absolute_path_from_install_path(cmd.installPath) if cmd.backingFile: qcow2_options = self.calc_qcow2_option(self, cmd.qcow2Options, True, cmd.provisioning) backing_abs_path = translate_absolute_path_from_install_path(cmd.backingFile) with lvm.RecursiveOperateLv(backing_abs_path, shared=True): virtual_size = linux.qcow2_virtualsize(backing_abs_path) 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())) with lvm.OperateLv(install_abs_path, shared=False, delete_when_exception=True): linux.qcow2_create_with_backing_file_and_option(backing_abs_path, install_abs_path, qcow2_options) 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())) if cmd.volumeFormat != 'raw': qcow2_options = self.calc_qcow2_option(self, cmd.qcow2Options, False, cmd.provisioning) with lvm.OperateLv(install_abs_path, shared=False, delete_when_exception=True): linux.qcow2_create_with_option(install_abs_path, cmd.size, qcow2_options) linux.qcow2_fill(0, 1048576, install_abs_path) 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) return jsonobject.dumps(rsp)
def create_template_from_volume(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = AgentRsp() volume_abs_path = translate_absolute_path_from_install_path( cmd.volumePath) install_abs_path = translate_absolute_path_from_install_path( cmd.installPath) if cmd.sharedVolume: lvm.do_active_lv(volume_abs_path, lvm.LvmlockdLockType.SHARE, True) with lvm.RecursiveOperateLv(volume_abs_path, shared=cmd.sharedVolume, skip_deactivate_tag=IMAGE_TAG): virtual_size = linux.qcow2_virtualsize(volume_abs_path) if not lvm.lv_exists(install_abs_path): lvm.create_lv_from_absolute_path( install_abs_path, virtual_size, "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time())) with lvm.OperateLv(install_abs_path, shared=False, delete_when_exception=True): linux.create_template(volume_abs_path, install_abs_path) logger.debug( 'successfully created template[%s] from volume[%s]' % (cmd.installPath, cmd.volumePath)) if cmd.compareQcow2 is True: logger.debug("comparing qcow2 between %s and %s") bash.bash_errorout("time qemu-img compare %s %s" % (volume_abs_path, install_abs_path)) logger.debug("confirmed qcow2 %s and %s are identical" % (volume_abs_path, install_abs_path)) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def create_empty_volume(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = AgentRsp() install_abs_path = translate_absolute_path_from_install_path(cmd.installPath) if cmd.backingFile: qcow2_options = self.calc_qcow2_option(self, cmd.qcow2Options, True, cmd.provisioning) backing_abs_path = translate_absolute_path_from_install_path(cmd.backingFile) with lvm.RecursiveOperateLv(backing_abs_path, shared=True): virtual_size = linux.qcow2_virtualsize(backing_abs_path) 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())) with lvm.OperateLv(install_abs_path, shared=False, delete_when_exception=True): linux.qcow2_create_with_backing_file_and_option(backing_abs_path, install_abs_path, qcow2_options) elif not lvm.lv_exists(install_abs_path): qcow2_options = self.calc_qcow2_option(self, cmd.qcow2Options, False, cmd.provisioning) lvm.create_lv_from_cmd(install_abs_path, cmd.size, cmd, "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time())) with lvm.OperateLv(install_abs_path, shared=False, delete_when_exception=True): linux.qcow2_create_with_option(install_abs_path, cmd.size, qcow2_options) linux.qcow2_fill(0, 1048576, install_abs_path) 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) return jsonobject.dumps(rsp)
def convert_volume_provisioning(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = ConvertVolumeProvisioningRsp() if cmd.provisioningStrategy != "ThinProvisioning": raise NotImplementedError abs_path = translate_absolute_path_from_install_path(cmd.installPath) with lvm.RecursiveOperateLv(abs_path, shared=False): image_offest = long( bash.bash_o( "qemu-img check %s | grep 'Image end offset' | awk -F ': ' '{print $2}'" % abs_path).strip()) current_size = long(lvm.get_lv_size(abs_path)) virtual_size = linux.qcow2_virtualsize(abs_path) size = image_offest + cmd.addons[ lvm.thinProvisioningInitializeSize] if size > current_size: size = current_size if size > virtual_size: size = virtual_size lvm.resize_lv(abs_path, size, True) rsp.actualSize = size 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 = AgentRsp() template_abs_path_cache = translate_absolute_path_from_install_path( cmd.templatePathInCache) install_abs_path = translate_absolute_path_from_install_path( cmd.installPath) qcow2_options = self.calc_qcow2_option(self, cmd.qcow2Options, True, cmd.provisioning) with lvm.RecursiveOperateLv(template_abs_path_cache, shared=True, skip_deactivate_tags=[IMAGE_TAG]): virtual_size = linux.qcow2_virtualsize(template_abs_path_cache) 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())) with lvm.OperateLv(install_abs_path, shared=False, delete_when_exception=True): linux.qcow2_clone_with_option(template_abs_path_cache, install_abs_path, qcow2_options) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def connect(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = ConnectRsp() diskPaths = set() def config_lvm(host_id): lvm.backup_lvm_config() lvm.reset_lvm_conf_default() lvm.config_lvm_by_sed("use_lvmlockd", "use_lvmlockd=1", ["lvm.conf", "lvmlocal.conf"]) lvm.config_lvm_by_sed("use_lvmetad", "use_lvmetad=0", ["lvm.conf", "lvmlocal.conf"]) lvm.config_lvm_by_sed("host_id", "host_id=%s" % host_id, ["lvm.conf", "lvmlocal.conf"]) lvm.config_lvm_by_sed("sanlock_lv_extend", "sanlock_lv_extend=%s" % DEFAULT_SANLOCK_LV_SIZE, ["lvm.conf", "lvmlocal.conf"]) lvm.config_lvm_by_sed("lvmlockd_lock_retries", "lvmlockd_lock_retries=6", ["lvm.conf", "lvmlocal.conf"]) lvm.config_lvm_by_sed("issue_discards", "issue_discards=1", ["lvm.conf", "lvmlocal.conf"]) lvm.config_sanlock_by_sed("sh_retries", "sh_retries=20") lvm.config_sanlock_by_sed("logfile_priority", "logfile_priority=7") lvm.config_sanlock_by_sed("renewal_read_extend_sec", "renewal_read_extend_sec=24") lvm.config_sanlock_by_sed("debug_renew", "debug_renew=1") lvm.config_sanlock_by_sed("use_watchdog", "use_watchdog=0") config_lvm(cmd.hostId) for diskUuid in cmd.sharedBlockUuids: disk = CheckDisk(diskUuid) diskPaths.add(disk.get_path()) lvm.start_lvmlockd() lvm.check_gl_lock() rsp.isFirst = self.create_vg_if_not_found(cmd.vgUuid, diskPaths, cmd.hostUuid, cmd.forceWipe) lvm.start_vg_lock(cmd.vgUuid) lvm.clean_vg_exists_host_tags(cmd.vgUuid, cmd.hostUuid, HEARTBEAT_TAG) lvm.add_vg_tag(cmd.vgUuid, "%s::%s::%s" % (HEARTBEAT_TAG, cmd.hostUuid, time.time())) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) rsp.hostId = lvm.get_running_host_id(cmd.vgUuid) return jsonobject.dumps(rsp)
def connect(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = ConnectRsp() diskPaths = set() def config_lvm(host_id, enableLvmetad=False): lvm.backup_lvm_config() lvm.reset_lvm_conf_default() lvm.config_lvm_by_sed("use_lvmlockd", "use_lvmlockd=1", ["lvm.conf", "lvmlocal.conf"]) if enableLvmetad: lvm.config_lvm_by_sed("use_lvmetad", "use_lvmetad=1", ["lvm.conf", "lvmlocal.conf"]) else: lvm.config_lvm_by_sed("use_lvmetad", "use_lvmetad=0", ["lvm.conf", "lvmlocal.conf"]) lvm.config_lvm_by_sed("host_id", "host_id=%s" % host_id, ["lvm.conf", "lvmlocal.conf"]) lvm.config_lvm_by_sed("sanlock_lv_extend", "sanlock_lv_extend=%s" % DEFAULT_SANLOCK_LV_SIZE, ["lvm.conf", "lvmlocal.conf"]) lvm.config_lvm_by_sed("lvmlockd_lock_retries", "lvmlockd_lock_retries=6", ["lvm.conf", "lvmlocal.conf"]) lvm.config_lvm_by_sed("issue_discards", "issue_discards=1", ["lvm.conf", "lvmlocal.conf"]) lvm.config_lvm_by_sed("reserved_stack", "reserved_stack=256", ["lvm.conf", "lvmlocal.conf"]) lvm.config_lvm_by_sed("reserved_memory", "reserved_memory=131072", ["lvm.conf", "lvmlocal.conf"]) lvm.config_lvm_filter(["lvm.conf", "lvmlocal.conf"]) lvm.config_sanlock_by_sed("sh_retries", "sh_retries=20") lvm.config_sanlock_by_sed("logfile_priority", "logfile_priority=7") lvm.config_sanlock_by_sed("renewal_read_extend_sec", "renewal_read_extend_sec=24") lvm.config_sanlock_by_sed("debug_renew", "debug_renew=1") lvm.config_sanlock_by_sed("use_watchdog", "use_watchdog=0") sanlock_hostname = "%s-%s-%s" % (cmd.vgUuid[:8], cmd.hostUuid[:8], bash.bash_o("hostname").strip()[:20]) lvm.config_sanlock_by_sed("our_host_name", "our_host_name=%s" % sanlock_hostname) config_lvm(cmd.hostId, cmd.enableLvmetad) for diskUuid in cmd.sharedBlockUuids: disk = CheckDisk(diskUuid) diskPaths.add(disk.get_path()) lvm.start_lvmlockd() lvm.check_gl_lock() logger.debug("find/create vg %s lock..." % cmd.vgUuid) rsp.isFirst = self.create_vg_if_not_found(cmd.vgUuid, diskPaths, cmd.hostUuid, cmd.forceWipe) lvm.check_stuck_vglk() logger.debug("starting vg %s lock..." % cmd.vgUuid) lvm.start_vg_lock(cmd.vgUuid) if lvm.lvm_vgck(cmd.vgUuid, 60)[0] is False and lvm.lvm_check_operation(cmd.vgUuid) is False: lvm.drop_vg_lock(cmd.vgUuid) logger.debug("restarting vg %s lock..." % cmd.vgUuid) lvm.check_gl_lock() lvm.start_vg_lock(cmd.vgUuid) lvm.clean_vg_exists_host_tags(cmd.vgUuid, cmd.hostUuid, HEARTBEAT_TAG) lvm.add_vg_tag(cmd.vgUuid, "%s::%s::%s::%s" % (HEARTBEAT_TAG, cmd.hostUuid, time.time(), bash.bash_o('hostname').strip())) self.clear_stalled_qmp_socket() rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) rsp.hostId = lvm.get_running_host_id(cmd.vgUuid) rsp.vgLvmUuid = lvm.get_vg_lvm_uuid(cmd.vgUuid) rsp.hostUuid = cmd.hostUuid return jsonobject.dumps(rsp)
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 check_bits(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = CheckBitsRsp() install_abs_path = translate_absolute_path_from_install_path(cmd.path) rsp.existing = lvm.lv_exists(install_abs_path) if cmd.vgUuid is not None and lvm.vg_exists(cmd.vgUuid): rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid, False) return jsonobject.dumps(rsp)
def active_lv(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = AgentRsp() rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) self.do_active_lv(cmd.installPath, cmd.lockType, cmd.recursive) return jsonobject.dumps(rsp)
def active_lv(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = AgentRsp() rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid, raise_exception=False) self.do_active_lv(cmd.installPath, cmd.lockType, cmd.recursive) return jsonobject.dumps(rsp)
def check_bits(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = CheckBitsRsp() install_abs_path = translate_absolute_path_from_install_path(cmd.path) rsp.existing = lvm.lv_exists(install_abs_path) if cmd.vgUuid is not None and lvm.vg_exists(cmd.vgUuid): rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid, False) return jsonobject.dumps(rsp)
def download_from_sftp(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = AgentRsp() install_abs_path = translate_absolute_path_from_install_path(cmd.primaryStorageInstallPath) self.do_download_from_sftp(cmd, install_abs_path) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def create_template_from_volume(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = VolumeRsp() volume_abs_path = get_absolute_path_from_install_path(cmd.volumePath) snap_name = cmd.installPath.split("/")[-1] lvm.create_lvm_snapshot(volume_abs_path, snapName=snap_name) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def download_from_sftp(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = AgentRsp() install_abs_path = translate_absolute_path_from_install_path(cmd.primaryStorageInstallPath) self.do_download_from_sftp(cmd, install_abs_path) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def get_volume_size(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = GetVolumeSizeRsp() install_abs_path = translate_absolute_path_from_install_path(cmd.installPath) rsp.size = lvm.get_lv_size(install_abs_path) rsp.actualSize = rsp.size rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def get_backing_chain(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = GetBackingChainRsp() abs_path = translate_absolute_path_from_install_path(cmd.installPath) with lvm.RecursiveOperateLv(abs_path, shared=True, skip_deactivate_tags=[IMAGE_TAG], delete_when_exception=False): rsp.backingChain = linux.qcow2_get_file_chain(abs_path) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def delete_bits(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = AgentRsp() if cmd.folder: raise Exception("not support this operation") self.do_delete_bits(cmd.path) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def delete_bits(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = AgentRsp() if cmd.folder: raise Exception("not support this operation") self.do_delete_bits(cmd.path) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def get_volume_size(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = GetVolumeSizeRsp() install_abs_path = translate_absolute_path_from_install_path(cmd.installPath) with lvm.OperateLv(install_abs_path, shared=True): rsp.size = linux.qcow2_virtualsize(install_abs_path) rsp.actualSize = lvm.get_lv_size(install_abs_path) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def revert_volume_from_snapshot(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = RevertVolumeFromSnapshotRsp() snapshot_abs_path = get_absolute_path_from_install_path( cmd.snapshotInstallPath) install_abs_path = get_absolute_path_from_install_path(cmd.installPath) rsp.size = False rsp.error = "not supported yet!" rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return rsp
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 get_volume_size(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = GetVolumeSizeRsp() install_abs_path = get_absolute_path_from_install_path(cmd.installPath) r = drbd.DrbdResource(cmd.installPath.split("/")[-1]) with drbd.OperateDrbd(r): rsp.size = linux.qcow2_virtualsize(r.get_dev_path()) rsp.actualSize = lvm.get_lv_size(install_abs_path) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) rsp._init_from_drbd(r) return jsonobject.dumps(rsp)
def get_backing_chain(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = GetBackingChainRsp() abs_path = translate_absolute_path_from_install_path(cmd.installPath) with lvm.RecursiveOperateLv(abs_path, shared=True, skip_deactivate_tags=[IMAGE_TAG], delete_when_exception=False): rsp.backingChain = linux.qcow2_get_file_chain(abs_path) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def check_disks(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = AgentRsp() for diskUuid in cmd.sharedBlockUuids: disk = CheckDisk(diskUuid) path = disk.get_path() if cmd.rescan: disk.rescan(path.split("/")[-1]) if cmd.vgUuid is not None and lvm.vg_exists(cmd.vgUuid): rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size( cmd.vgUuid, False) return jsonobject.dumps(rsp)
def create_thin_pool_if_not_found(vgUuid, init_pool_ratio): def round_sector(size, sector): return round(float(size) / float(sector)) * sector if lvm.lv_exists("/dev/%s/%s_thinpool" % (vgUuid, vgUuid)): return tot, avil = lvm.get_vg_size(vgUuid) init_pool_size = float(tot) * float(init_pool_ratio) # meta_size = "%s" % ((tot / DEFAULT_CHUNK_SIZE) * 48 * 2) # ref: https://www.kernel.org/doc/Documentation/device-mapper/thin-provisioning.txt meta_size = 1024**3 # ref: https://www.systutorials.com/docs/linux/man/7-lvmthin/#lbBD bash.bash_errorout( "lvcreate --type thin-pool -L %sB -c %sB --poolmetadatasize %sB -n %s_thinpool %s" % (int(round_sector(init_pool_size, 4096)), DEFAULT_CHUNK_SIZE, meta_size, vgUuid, vgUuid))
def connect(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = ConnectRsp() diskPaths = set() def config_lvm(host_id): lvm.backup_lvm_config() lvm.reset_lvm_conf_default() lvm.config_lvm_by_sed("use_lvmlockd", "use_lvmlockd=1", ["lvm.conf", "lvmlocal.conf"]) lvm.config_lvm_by_sed("use_lvmetad", "use_lvmetad=0", ["lvm.conf", "lvmlocal.conf"]) lvm.config_lvm_by_sed("host_id", "host_id=%s" % host_id, ["lvm.conf", "lvmlocal.conf"]) lvm.config_lvm_by_sed("sanlock_lv_extend", "sanlock_lv_extend=%s" % DEFAULT_SANLOCK_LV_SIZE, ["lvm.conf", "lvmlocal.conf"]) lvm.config_lvm_by_sed("lvmlockd_lock_retries", "lvmlockd_lock_retries=6", ["lvm.conf", "lvmlocal.conf"]) lvm.config_lvm_by_sed("issue_discards", "issue_discards=1", ["lvm.conf", "lvmlocal.conf"]) lvm.config_lvm_by_sed("reserved_memory", "reserved_memory=65536", ["lvm.conf", "lvmlocal.conf"]) lvm.config_sanlock_by_sed("sh_retries", "sh_retries=20") lvm.config_sanlock_by_sed("logfile_priority", "logfile_priority=7") lvm.config_sanlock_by_sed("renewal_read_extend_sec", "renewal_read_extend_sec=24") lvm.config_sanlock_by_sed("debug_renew", "debug_renew=1") lvm.config_sanlock_by_sed("use_watchdog", "use_watchdog=0") sanlock_hostname = "%s-%s-%s" % (cmd.vgUuid[:8], cmd.hostUuid[:8], bash.bash_o("hostname").strip()[:20]) lvm.config_sanlock_by_sed("our_host_name", "our_host_name=%s" % sanlock_hostname) config_lvm(cmd.hostId) for diskUuid in cmd.sharedBlockUuids: disk = CheckDisk(diskUuid) diskPaths.add(disk.get_path()) lvm.start_lvmlockd() lvm.check_gl_lock() logger.debug("find/create vg %s lock..." % cmd.vgUuid) rsp.isFirst = self.create_vg_if_not_found(cmd.vgUuid, diskPaths, cmd.hostUuid, cmd.forceWipe) lvm.check_stuck_vglk() logger.debug("starting vg %s lock..." % cmd.vgUuid) lvm.start_vg_lock(cmd.vgUuid) if lvm.lvm_vgck(cmd.vgUuid, 15)[0] is False: lvm.drop_vg_lock(cmd.vgUuid) logger.debug("restarting vg %s lock..." % cmd.vgUuid) lvm.check_gl_lock() lvm.start_vg_lock(cmd.vgUuid) lvm.clean_vg_exists_host_tags(cmd.vgUuid, cmd.hostUuid, HEARTBEAT_TAG) lvm.add_vg_tag(cmd.vgUuid, "%s::%s::%s::%s" % (HEARTBEAT_TAG, cmd.hostUuid, time.time(), bash.bash_o('hostname').strip())) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) rsp.hostId = lvm.get_running_host_id(cmd.vgUuid) return jsonobject.dumps(rsp)
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 check_disks(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = AgentRsp() if cmd.failIfNoPath: CheckDisk.set_fail_if_no_path() for diskUuid in cmd.sharedBlockUuids: disk = CheckDisk(diskUuid) path = disk.get_path() if cmd.rescan: disk.rescan(path.split("/")[-1]) if cmd.vgUuid is not None and lvm.vg_exists(cmd.vgUuid): rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid, False) return jsonobject.dumps(rsp)
def add_disk(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) disk = CheckDisk(cmd.diskUuid) command = shell.ShellCmd("vgs --nolocking %s -otags | grep %s" % (cmd.vgUuid, INIT_TAG)) command(is_exception=False) if command.return_code != 0: self.create_vg_if_not_found(cmd.vgUuid, [disk.get_path()], cmd.hostUuid, cmd.forceWipe) else: lvm.check_gl_lock() if cmd.forceWipe is True: lvm.wipe_fs([disk.get_path()], cmd.vgUuid) lvm.add_pv(cmd.vgUuid, disk.get_path(), DEFAULT_VG_METADATA_SIZE) rsp = AgentRsp rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def add_disk(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) disk = CheckDisk(cmd.diskUuid) command = shell.ShellCmd("vgs %s -otags | grep %s" % (cmd.vgUuid, INIT_TAG)) command(is_exception=False) if command.return_code != 0: self.create_vg_if_not_found(cmd.vgUuid, [disk.get_path()], cmd.hostUuid, cmd.forceWipe) else: lvm.check_gl_lock() if cmd.forceWipe is True: lvm.wipe_fs([disk.get_path()], cmd.vgUuid) lvm.add_pv(cmd.vgUuid, disk.get_path(), DEFAULT_VG_METADATA_SIZE) rsp = AgentRsp 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 = AgentRsp() template_abs_path_cache = translate_absolute_path_from_install_path(cmd.templatePathInCache) install_abs_path = translate_absolute_path_from_install_path(cmd.installPath) qcow2_options = self.calc_qcow2_option(self, cmd.qcow2Options, True, cmd.provisioning) with lvm.RecursiveOperateLv(template_abs_path_cache, shared=True, skip_deactivate_tags=[IMAGE_TAG]): virtual_size = linux.qcow2_virtualsize(template_abs_path_cache) 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())) with lvm.OperateLv(install_abs_path, shared=False, delete_when_exception=True): linux.qcow2_clone_with_option(template_abs_path_cache, install_abs_path, qcow2_options) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def merge_snapshot(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = MergeSnapshotRsp() snapshot_abs_path = translate_absolute_path_from_install_path(cmd.snapshotInstallPath) workspace_abs_path = translate_absolute_path_from_install_path(cmd.workspaceInstallPath) with lvm.RecursiveOperateLv(snapshot_abs_path, shared=True): virtual_size = linux.qcow2_virtualsize(snapshot_abs_path) if not lvm.lv_exists(workspace_abs_path): lvm.create_lv_from_absolute_path(workspace_abs_path, virtual_size, "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time())) with lvm.OperateLv(workspace_abs_path, shared=False, delete_when_exception=True): linux.create_template(snapshot_abs_path, workspace_abs_path) rsp.size, rsp.actualSize = linux.qcow2_size_and_actual_size(workspace_abs_path) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) rsp.actualSize = rsp.size return jsonobject.dumps(rsp)
def merge_snapshot(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = MergeSnapshotRsp() snapshot_abs_path = translate_absolute_path_from_install_path(cmd.snapshotInstallPath) workspace_abs_path = translate_absolute_path_from_install_path(cmd.workspaceInstallPath) with lvm.RecursiveOperateLv(snapshot_abs_path, shared=True): virtual_size = linux.qcow2_virtualsize(snapshot_abs_path) if not lvm.lv_exists(workspace_abs_path): lvm.create_lv_from_absolute_path(workspace_abs_path, virtual_size, "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time())) with lvm.OperateLv(workspace_abs_path, shared=False, delete_when_exception=True): linux.create_template(snapshot_abs_path, workspace_abs_path) rsp.size, rsp.actualSize = linux.qcow2_size_and_actual_size(workspace_abs_path) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) rsp.actualSize = rsp.size 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 offline_merge_snapshots(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = OfflineMergeSnapshotRsp() src_abs_path = translate_absolute_path_from_install_path(cmd.srcPath) dst_abs_path = translate_absolute_path_from_install_path(cmd.destPath) with lvm.RecursiveOperateLv(src_abs_path, shared=True): virtual_size = linux.qcow2_virtualsize(src_abs_path) if not lvm.lv_exists(dst_abs_path): lvm.create_lv_from_absolute_path( dst_abs_path, virtual_size, "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time())) with lvm.RecursiveOperateLv(dst_abs_path, shared=False): if not cmd.fullRebase: linux.qcow2_rebase(src_abs_path, dst_abs_path) else: # TODO(weiw): add tmp disk and then rename is better linux.create_template(src_abs_path, dst_abs_path) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def collect_lvm_capacity_statistics(): metrics = { 'vg_size': GaugeMetricFamily('vg_size', 'volume group size', None, ['vg_name']), 'vg_avail': GaugeMetricFamily('vg_avail', 'volume group and thin pool free size', None, ['vg_name']), } r, o, e = bash_roe("vgs --nolocking --noheading -oname") if r != 0 or len(o.splitlines()) == 0: return metrics.values() vg_names = o.splitlines() for name in vg_names: name = name.strip() size, avail = lvm.get_vg_size(name, False) metrics['vg_size'].add_metric([name], float(size)) metrics['vg_avail'].add_metric([name], float(avail)) return metrics.values()
def convert_volume_provisioning(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = ConvertVolumeProvisioningRsp() if cmd.provisioningStrategy != "ThinProvisioning": raise NotImplementedError abs_path = translate_absolute_path_from_install_path(cmd.installPath) with lvm.RecursiveOperateLv(abs_path, shared=False): image_offest = long( bash.bash_o("qemu-img check %s | grep 'Image end offset' | awk -F ': ' '{print $2}'" % abs_path).strip()) current_size = long(lvm.get_lv_size(abs_path)) virtual_size = linux.qcow2_virtualsize(abs_path) size = image_offest + cmd.addons[lvm.thinProvisioningInitializeSize] if size > current_size: size = current_size if size > virtual_size: size = virtual_size lvm.resize_lv(abs_path, size, True) rsp.actualSize = size rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def create_template_from_volume(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) rsp = AgentRsp() volume_abs_path = translate_absolute_path_from_install_path( cmd.volumePath) install_abs_path = translate_absolute_path_from_install_path( cmd.installPath) with lvm.RecursiveOperateLv(volume_abs_path, shared=False): virtual_size = linux.qcow2_virtualsize(volume_abs_path) if not lvm.lv_exists(install_abs_path): lvm.create_lv_from_absolute_path( install_abs_path, virtual_size, "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time())) with lvm.OperateLv(install_abs_path, shared=False, delete_when_exception=True): linux.create_template(volume_abs_path, install_abs_path) logger.debug('successfully created template[%s] from volume[%s]' % (cmd.installPath, cmd.volumePath)) rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid) return jsonobject.dumps(rsp)
def collect_lvm_capacity_statistics(): metrics = { 'vg_size': GaugeMetricFamily('vg_size', 'volume group size', None, ['vg_name']), 'vg_avail': GaugeMetricFamily('vg_avail', 'volume group and thin pool free size', None, ['vg_name']), } r = bash_r("grep -Ev '^[[:space:]]*#|^[[:space:]]*$' /etc/multipath/wwids") if r == 0: linux.set_fail_if_no_path() r, o, e = bash_roe("vgs --nolocking --noheading -oname") if r != 0 or len(o.splitlines()) == 0: return metrics.values() vg_names = o.splitlines() for name in vg_names: name = name.strip() size, avail = lvm.get_vg_size(name, False) metrics['vg_size'].add_metric([name], float(size)) metrics['vg_avail'].add_metric([name], float(avail)) return metrics.values()
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)