def delete_lv(self, vg_name, lv_name): # 首先判断vg以及lv是否存在 vgs = self.get_vgs() for vg in vgs: if vg_name == vg['name']: for lv in vg['lvs']: # 判断lv是否存在 if lv_name == lv['name']: break else: raise exception.LVNotExists(lv=lv_name) break else: logging.error("the vg %s is not exist", vg_name) raise exception.VGNotExists(vg=vg_name) try: cmdutils.execute("umount", "/dev/%s/%s" % (vg_name, lv_name), run_as_root=True, ignore_exit_code=True) out, err = cmdutils.execute("lvremove", "-f", "/dev/%s/%s" % (vg_name, lv_name), run_as_root=True, ignore_exit_code=True) if err: logging.error("lvremove failed:%s", err) raise exception.LVRemoveError(lv=lv_name, error=err) cmdutils.run_cmd("sed -i '/%s-%s/d' /etc/fstab" % (vg_name, lv_name)) logging.info("delete lv %s end", lv_name) except Exception as e: logging.error("delete lv failed:%s", e) raise e
def mount_nfs(self, nfs_server, name): if not os.path.exists(constants.NFS_MOUNT_POINT_PREFIX + name): os.mkdir(constants.NFS_MOUNT_POINT_PREFIX + name) out, err = cmdutils.execute("mount", "-v", run_as_root=True, ignore_exit_code=True) if constants.NFS_MOUNT_POINT_PREFIX + name in out: logging.info("the device is in mount status, go on") else: out, err = cmdutils.execute( 'mount', '-t', 'nfs', '-o', 'nosuid,noexec,nodev,noatime,nodiratime,vers=3,rsize=1048576,wsize=1048576', '{}'.format(nfs_server), '{}'.format(constants.NFS_MOUNT_POINT_PREFIX + name), run_as_root=True, ignore_exit_code=True) logging.info("mount {}, out:{} , err:{}".format( constants.NFS_MOUNT_POINT_PREFIX + name, out, err)) if err: logging.error("mount nfs error:%s", err) return # 修改开机自动挂载 self._write_fstab(nfs_server, name) disk_usage = psutil.disk_usage(constants.NFS_MOUNT_POINT_PREFIX + name) return disk_usage.used, disk_usage.free, disk_usage.total
def convert(self, template): source_path = template['backing_file'] dest_path = template['dest_file'] logging.info("start convert, source:%s, dest:%s", source_path, dest_path) if template['need_convert']: logging.info("convert from %s to %s", source_path, dest_path) cmdutils.execute('qemu-img', 'convert', '-f', 'qcow2', '-O', 'qcow2', source_path, dest_path, run_as_root=True) else: logging.info("generate base image from origin image") try: shutil.copy(source_path, dest_path) except IOError as e: logging.error("copy image failed:%s", e) raise exception.ImageCopyIOError(source_path) logging.info("generat new image success") return {'path': dest_path}
def start_self_upgrade(cmd=False): # 是否是通过命令行启动的自升级程序 logger.info("start self upgrade, cmd:%s", cmd) upgrade_path = os.path.join(constants.BASE_DIR, 'yzy_upgrade') if not cmd: if os.path.exists(const.SELF_UPGRADE_FILE): os.remove(const.SELF_UPGRADE_FILE) exe_cmd = [upgrade_path, "self_upgrade"] subprocess.Popen(exe_cmd) return get_error_result() logger.info("begin stop upgrade") # 停止升级服务 stdout, stderr = execute("systemctl", "stop", "yzy-upgrade") if stderr: return get_error_result("StopServiceError", service="yzy-upgrade") logger.info("start replace file") try: os.remove(upgrade_path) source = os.path.join(const.UPGRADE_KVM_PATH, 'yzy_upgrade') logger.info("copy %s to %s", source, upgrade_path) shutil.copy2(source, upgrade_path) except: logger.exception("copy file failed", exc_info=True) return get_error_result("UpgradeSlavesError") # 重启服务 stdout, stderr = execute("systemctl", "start", "yzy-upgrade") if stderr: return get_error_result("StartServiceError", service="yzy-upgrade") # 增加自升级标志 with open(const.SELF_UPGRADE_FILE, 'w') as fd: fd.write("") return get_error_result()
def _connect(self, nbd_device, disk_file, mount_point): """connect the disk image to nbd, and mount the system partition""" try: logging.info("connect the virtual disk to nbd device") cmdutils.execute('qemu-nbd', '-c', nbd_device, disk_file, run_as_root=True) if constants.OS_TYPE_XP == self.instance['os_type'] or \ constants.OS_TYPE_LINUX == self.instance['os_type']: nbdpoint = 'p1' else: nbdpoint = 'p2' device = '%s%s' % (nbd_device, nbdpoint) self.check_and_mount(device, mount_point) return True except Exception: fault = traceback.format_exc() message = "Instance[%s] connect nbd device[%s] error:%s " % ( self.instance['uuid'], nbd_device, fault) logging.error(message) try: self.umount_nbd(mount_point=mount_point) except: pass raise exception.NBDConnectException(message=message)
def _make_iso9660(self, path, tmpdir): publisher = "%(product)s %(version)s" % { 'product': 'yzy_kvm', 'version': '1.0.0' } cmdutils.execute( 'mkisofs', '-o', path, '-ldots', '-allow-lowercase', '-allow-multidot', '-l', '-input-charset', 'utf8', '-output-charset', 'utf8', '-publisher', publisher, '-hidden', 'ipinfo', '-quiet', '-J', '-r', # '-V', 'config-2', tmpdir, attempts=1, run_as_root=False)
def get_adapter_name(self, reg_file): logging.info("get the ip interface info") cmdutils.execute("sed -i '1d' %s" % (reg_file, ), run_as_root=True, shell=True) cf = ConfigParser() conf = reg_file cf.read(conf) sections = cf.sections() adapters = "" for section in sections: if section.startswith( "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\Tcpip\Parameters\Adapters\{" ): adapters = section adapters_list = adapters.split("\\") interface = "HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\services\\Tcpip\\Parameters\\Interfaces\\%s" % adapters_list[ -1] cmdutils.execute( "sed -i '1i Windows Registry Editor Version 5.00' %s" % (reg_file, ), run_as_root=True, shell=True) return interface
def extend_vg(self, vg_name, paths): vgs = self.get_vgs() for vg in vgs: if vg_name == vg['name']: break else: logging.error("the vg %s is not exist", vg_name) raise exception.VGNotExists(vg=vg_name) pvs = self.get_pvs() for path in paths: if path in pvs: logging.info("the device %s is pv already, skip", path) else: out, err = cmdutils.execute("pvcreate", "-f", path, run_as_root=True, ignore_exit_code=True) if err: logging.error("create pv failed:%s", err) if "not found" in err: err = "'%s'不存在" % path raise exception.PVCreateError(pv=path, error=err) out, err = cmdutils.execute("vgextend", vg_name, path, run_as_root=True, ignore_exit_code=True) if err: logging.error("vgextend failed:%s", err) if "is already in volume group" in err: err = "'%s'已经存在于卷组中" % path raise exception.VGExtendError(vg=vg_name, error=err) logging.info("device %s extend to vg %s success", path, vg_name)
def _prepare_iso_disk(self, disk): logging.info("prepare disk for instance, disk:%s", disk) # system disk and data disk in different position base_path = disk['base_path'] # create the disk file disk_file = "%s/%s%s" % (base_path, constants.VOI_FILE_PREFIX, disk['uuid']) cmdutils.execute('qemu-img', 'create', '-f', 'qcow2', disk_file, disk['size'], run_as_root=True) logging.info("create the disk %s success", disk_file) return disk_file
def set_fix_ip(self, reg_file): interface = self.get_adapter_name(reg_file) # "EnableDHCP"=dword:00000000 logging.info("disable dhcp") cmd = 'crudini --set %s "%s" \\"EnableDHCP\\" %s' % ( reg_file, interface, "dword:00000000") cmdutils.execute(cmd, run_as_root=True, shell=True) # ipaddr = self._create_hex_ip(ip, type=7) # cmd = 'crudini --set %s "%s" \\"IPAddress\\" %s' % (reg_file, interface, ipaddr) # 这样设置在 = 两边会有空格,导致merge失败 # cmdutils.execute(cmd, run_as_root=True, shell=True) """
def create_data_file(self, instance, disk, version): backing_dir = os.path.join(disk['base_path'], constants.IMAGE_CACHE_DIRECTORY_NAME) backing_file_name = constants.VOI_BASE_PREFIX % str(0) + disk['uuid'] backing_file = os.path.join(backing_dir, backing_file_name) logging.info("create base file %s", backing_file) cmdutils.execute('qemu-img', 'create', '-f', 'qcow2', backing_file, disk['size'], run_as_root=True) # 默认基础镜像 diff_file = backing_file # 只保留两个版本 if version <= constants.IMAGE_COMMIT_VERSION: for i in range(version): file_name = constants.VOI_BASE_PREFIX % str(i + 1) + disk['uuid'] base_file_name = constants.VOI_BASE_PREFIX % str(i) + disk['uuid'] diff_file = os.path.join(backing_dir, file_name) base_file = os.path.join(backing_dir, base_file_name) logging.info("create diff file %s, backing_file:%s", diff_file, base_file) cmdutils.execute('qemu-img', 'create', '-f', 'qcow2', diff_file, '-o', 'backing_file=%s' % base_file, run_as_root=True) else: file_name = constants.VOI_BASE_PREFIX % str(version - 1) + disk['uuid'] base_file_name = constants.VOI_BASE_PREFIX % str(0) + disk['uuid'] diff_file = os.path.join(backing_dir, file_name) base_file = os.path.join(backing_dir, base_file_name) logging.info("create diff file %s, backing_file:%s", diff_file, base_file) cmdutils.execute('qemu-img', 'create', '-f', 'qcow2', diff_file, '-o', 'backing_file=%s' % base_file, run_as_root=True) file_name = constants.VOI_BASE_PREFIX % str(version) + disk['uuid'] base_file_name = constants.VOI_BASE_PREFIX % str(version - 1) + disk['uuid'] diff_file = os.path.join(backing_dir, file_name) base_file = os.path.join(backing_dir, base_file_name) logging.info("create diff file %s, backing_file:%s", diff_file, base_file) cmdutils.execute('qemu-img', 'create', '-f', 'qcow2', diff_file, '-o', 'backing_file=%s' % base_file, run_as_root=True) logging.info("create base file end") # 下面是基于最后一个差异盘创建模板目前使用的差异盘 disk_file_name = constants.VOI_FILE_PREFIX + disk['uuid'] disk_file = os.path.join(disk['base_path'], disk_file_name) logging.info("create diff file %s, backing_file:%s", disk_file, diff_file) cmdutils.execute('qemu-img', 'create', '-f', 'qcow2', disk_file, '-o', 'backing_file=%s' % diff_file, run_as_root=True) guest = self._host.get_guest(instance) disk['path'] = disk_file disk['order'] = False storage_configs = self._get_guest_storage_config([disk]) for config in storage_configs: try: guest.attach_device(config, True, False) logging.info("attach disk %s success", disk['path']) except Exception as e: logging.error("attach disk failed:%s", e) raise exception.ChangeCdromPathError(domain=instance['uuid'], error=str(e)) return True
def create_qcow2_file(self, disk_file, size): dir_path = os.path.dirname(disk_file) if not os.path.exists(dir_path): os.makedirs(dir_path) cmdutils.execute('qemu-img', 'create', '-f', 'qcow2', disk_file, size, run_as_root=True) logging.info("create qcow2 file success") return True
def recreate_disks(self, disks): for disk in disks: try: os.remove(disk['disk_file']) except: pass cmdutils.execute('qemu-img', 'create', '-f', 'qcow2', disk['disk_file'], '-o', 'backing_file=%s' % disk['backing_file'], run_as_root=True)
def check_and_mount(self, device, mount_point): """check if the nbd device exists""" logging.info("check nbd mount state") stdout, stderr = cmdutils.execute('ls', device, run_as_root=True) if stderr: time.sleep(0.5) raise Exception("the nbd partitions not found") logging.info("mount the nbd device to %s", mount_point) stdout, stderr = cmdutils.execute('mount.ntfs-3g', device, mount_point, run_as_root=True) if stderr: time.sleep(0.5) raise Exception("mount device failed")
def reset_instance(self, instance, images): logging.info("reset the vi template:%s", instance) try: self.change_cdrom_path(instance, '', attach=False) except: pass self._destroy(instance) for image in images: logging.info("delete the file:%s", image['image_path']) try: os.remove(image['image_path']) except: pass cmdutils.execute('qemu-img', 'create', '-f', 'qcow2', image['image_path'], '-o', 'backing_file=%s' % image['backing_path'], run_as_root=True)
def rollback_services(self, master=False): try: service_list = ["yzy-compute", "yzy-monitor"] if master: service_list.extend([ "yzy-server", "yzy-scheduler", "yzy-terminal", "yzy-terminal-agent", "nginx", "yzy-web" ]) for service_name in service_list: logger.info("restart service %s", service_name) stdout, stderr = execute("systemctl", "restart", service_name) if stderr: return get_error_result("StartServiceError", service=service_name) except Exception as e: logger.exception("rollback_services Exception: %s" % str(e), exc_info=True) return get_error_result("OtherError") # 检查旧版服务是否启动成功 failed_ret = self._check_services_status(master) if failed_ret: return get_error_result("StartServiceError", service=", ".join(failed_ret)) # 回滚完成,清空升级包目录、临时目录 self._clean_pkg_dirs() return get_error_result()
def resize_disk(self, images): for image in images: try: logging.info("resize file %s", image['disk_file']) size = '+%sG' % image['size'] cmdutils.execute('qemu-img', 'resize', image['disk_file'], size, run_as_root=True) except Exception as e: logging.error("resize image file failed:%s", e) raise exception.ImageResizeError(image=image['disk_file'], error=e) logging.info("resize image success") return True
def _set_hostname(self, mount_point): try: reg_file = '%s.reg' % self.instance['uuid'] self.create_hostname_reg_file(self.instance['name'], reg_file) merge_cmd = "hivexregedit --merge %s/%s --prefix 'HKEY_LOCAL_MACHINE\SYSTEM' %s" % \ (mount_point, self._get_reg_location(), reg_file) cmdutils.execute(merge_cmd, run_as_root=True, shell=True) logging.info("merge hostname info to regedit success") try: os.remove(reg_file) logging.info("remove hostname reg file") except: pass except Exception as e: message = "%s,instance_uuid[%s] set compute name error:%s" % ( self.thread_id, self.instance['uuid'], e) logging.error(message) raise exception.ModifyComputeNameException(message)
def resize_disk(self, images): for image in images: base_path = image['base_path'] image_file = os.path.join(base_path, constants.VOI_FILE_PREFIX + image['image_id']) try: # 先查出该盘的大小 stdout, stderror = cmdutils.execute('qemu-img info %s' % image_file, shell=True, timeout=20, run_as_root=True) logging.info("qemu-img info execute end, stdout:%s, stderror:%s", stdout, stderror) current_size = int(re.search(r"virtual size: (\d+)G \((\d+) bytes\)", stdout).group(1)) logging.info("resize file %s", image_file) size = '+%sG' % (int(image['tag_size']) - current_size) cmdutils.execute('qemu-img', 'resize', image_file, size, run_as_root=True) except Exception as e: logging.error("resize image file failed:%s", e) raise exception.ImageResizeError(image=image_file, error=e) logging.info("resize image success") return True
def umount_nfs(self, name): out, err = cmdutils.execute("mount", "-v", run_as_root=True, ignore_exit_code=True) if constants.NFS_MOUNT_POINT_PREFIX + name not in out: logging.info("the device is not in mount status, go on") else: out, err = cmdutils.execute( "umount", "{}".format(constants.NFS_MOUNT_POINT_PREFIX + name), run_as_root=True, ignore_exit_code=True) if err: logging.error("umount nfs error:%s", err) else: # 修改开机自动挂载 cmdutils.run_cmd("sed -i '/{}/d' /etc/fstab".format('nfs_' + name)) logging.info("umount {}, out:{} , err:{}".format( constants.NFS_MOUNT_POINT_PREFIX + name, out, err))
def show_mount(self, ip_addr): out, err = cmdutils.execute("showmount", "-e", "{}".format(ip_addr), run_as_root=True, ignore_exit_code=True) res = out.split('\n')[1:-1] return build_result( "Success", { "mount_list": [mount_point.replace('*', '').strip() for mount_point in res] })
def rollback(self, rollback_version, cur_version, images): if rollback_version != 0 and cur_version > constants.IMAGE_COMMIT_VERSION: rollback_version = 1 cur_version = 2 for image in images: file_name = constants.VOI_FILE_PREFIX + image['image_id'] disk_file = os.path.join(image['base_path'], file_name) backing_file_name = constants.VOI_BASE_PREFIX % str(rollback_version) + image['image_id'] backing_dir = os.path.join(image['base_path'], constants.IMAGE_CACHE_DIRECTORY_NAME) backing_file = os.path.join(backing_dir, backing_file_name) try: logging.info("delete file %s", disk_file) os.remove(disk_file) except: pass cmdutils.execute('qemu-img', 'create', '-f', 'qcow2', disk_file, '-o', 'backing_file=%s' % backing_file, run_as_root=True) logging.info("rollback the version, image:%s", image) delete_file = os.path.join(backing_dir, constants.VOI_BASE_PREFIX % str(cur_version) + image['image_id']) try: logging.info("delete file %s", delete_file) os.remove(delete_file) # 删除种子文件 torrent_file = delete_file + ".torrent" if os.path.exists(torrent_file): os.remove(torrent_file) stdout, stderror = cmdutils.execute('qemu-img info %s' % disk_file, shell=True, timeout=20, run_as_root=True) # 获取该盘的大小 logging.info("qemu-img info execute end, stdout:%s, stderror:%s", stdout, stderror) current_size = int(re.search(r"virtual size: (\d+)G \((\d+) bytes\)", stdout).group(1)) image["size"] = current_size except Exception as e: logging.error("", exc_info=True) pass return images
def disconnect_nbd(self, nbd_device, mount_point): self.umount_nbd(mount_point) logging.info("disconnect nbd, nbd_device:%s", nbd_device) stdout, stderr = cmdutils.execute('qemu-nbd', '-d', nbd_device, run_as_root=True) if stderr: message = "Instance[%s] disconnect nbd[%s] failed:%s" % ( nbd_device, self.instance['uuid'], stderr) logging.error(message) raise exception.NBDDisconnectException(message) logging.info("disconnect nbd success")
def execute(self, cmds, addl_env=None, check_exit_code=True, log_errors=True, run_as_root=False): ns_params = [] if self._parent.namespace: run_as_root = True ns_params = ['ip', 'netns', 'exec', self._parent.namespace] env_params = [] if addl_env: env_params = (['env'] + ['%s=%s' % pair for pair in addl_env.items()]) cmd = ns_params + env_params + list(cmds) return cmdutils.execute(*cmd, check_exit_code=check_exit_code, log_errors=log_errors, run_as_root=run_as_root)
def get_mounted_part(self): mount_path = list() out, err = cmdutils.execute('mount', '-t', 'ext4', run_as_root=True, ignore_exit_code=True) for mount in out.split('\n'): if mount: path = mount.split()[0].strip() if not path.startswith("/dev/mapper"): mount_path.append(path) out, err = cmdutils.execute('mount', '-t', 'xfs', run_as_root=True, ignore_exit_code=True) for mount in out.split('\n'): if mount: path = mount.split()[0].strip() if not path.startswith("/dev/mapper"): mount_path.append(path) logging.info("get mounted path:%s", mount_path) return mount_path
def copy_images(self, images): images.sort(key=lambda x:x['image_path']) pre_image = None for image in images: try: logging.info("copy file from %s to %s", image['image_path'], image['dest_path']) shutil.copy(image['image_path'], image['dest_path']) if pre_image and pre_image["type"] == image["type"]: backing_file = pre_image['dest_path'] dest_path = image['dest_path'] stdout, stderr = cmdutils.execute('qemu-img', 'rebase', '-u', '-b', backing_file, dest_path, run_as_root=True) if stderr: raise exception.ImageRebaseError(image=dest_path, error=stderr) pre_image = image except IOError as e: logging.error("copy image failed:%s", e) raise exception.ImageCopyIOError(image['image_path']) logging.info("copy new image success") return True
def _run_script(self, script_path): try: if not os.path.exists(script_path): logger.error("script_path %s do not exist", script_path) return True logger.info("run script: %s", script_path) os.chmod(script_path, stat.S_IEXEC) stdout, stderr = execute(script_path, shell=True, run_as_root=True) logger.info("stdout:%s, stderr:%s", stdout, stderr) if stderr: logger.error("run script failed: %s, stderr: %s", script_path, stderr) return False except Exception as e: logger.exception("_run_script Exception: %s" % str(e), exc_info=True) return False logger.info("run script success: %s" % script_path) return True
def _start_services(self, master=False): try: service_list = ["yzy-compute", "yzy-monitor"] if master: service_list.extend([ "yzy-server", "yzy-scheduler", "yzy-terminal", "yzy-terminal-agent", "nginx", "yzy-web" ]) for service_name in service_list: logger.info("start service %s", service_name) stdout, stderr = execute("systemctl", "start", service_name) if stderr: return get_error_result("StartServiceError", service=service_name) except Exception as e: logger.exception("start services exception: %s" % str(e), exc_info=True) return get_error_result("OtherError") return get_error_result()
def create_share_disk(self, disk, version): backing_dir = os.path.join(disk['base_path'], constants.IMAGE_CACHE_DIRECTORY_NAME) backing_file_name = constants.VOI_SHARE_BASE_PREFIX % str(0) + disk['uuid'] backing_file = os.path.join(backing_dir, backing_file_name) logging.info("create voi share disk base file %s", backing_file) disk_size = "%sG" % disk["size"] cmdutils.execute('qemu-img', 'create', '-f', 'qcow2', backing_file, disk_size, run_as_root=True) # 默认基础镜像 diff_file = backing_file # 只保留两个版本 if version <= constants.IMAGE_COMMIT_VERSION: for i in range(version): file_name = constants.VOI_SHARE_BASE_PREFIX % str(i + 1) + disk['uuid'] base_file_name = constants.VOI_SHARE_BASE_PREFIX % str(i) + disk['uuid'] diff_file = os.path.join(backing_dir, file_name) base_file = os.path.join(backing_dir, base_file_name) logging.info("create share disk diff file %s, backing_file:%s", diff_file, base_file) cmdutils.execute('qemu-img', 'create', '-f', 'qcow2', diff_file, '-o', 'backing_file=%s' % base_file, run_as_root=True) else: file_name = constants.VOI_SHARE_BASE_PREFIX % str(version - 1) + disk['uuid'] base_file_name = constants.VOI_SHARE_BASE_PREFIX % str(0) + disk['uuid'] diff_file = os.path.join(backing_dir, file_name) base_file = os.path.join(backing_dir, base_file_name) logging.info("create share disk diff file %s, backing_file:%s", diff_file, base_file) cmdutils.execute('qemu-img', 'create', '-f', 'qcow2', diff_file, '-o', 'backing_file=%s' % base_file, run_as_root=True) file_name = constants.VOI_SHARE_BASE_PREFIX % str(version) + disk['uuid'] base_file_name = constants.VOI_SHARE_BASE_PREFIX % str(version - 1) + disk['uuid'] diff_file = os.path.join(backing_dir, file_name) base_file = os.path.join(backing_dir, base_file_name) logging.info("create share disk diff file %s, backing_file:%s", diff_file, base_file) cmdutils.execute('qemu-img', 'create', '-f', 'qcow2', diff_file, '-o', 'backing_file=%s' % base_file, run_as_root=True) logging.info("create voi share disk base file end") return True
def get_unused_part(self): out, err = cmdutils.execute('ls', '-l', '/dev/disk/by-id', run_as_root=True, ignore_exit_code=True) if err: logging.error("get device by-id failed:%s", err) return list() parts = list() for disk_single in out.split('\n'): if disk_single.strip() and -1 != disk_single.find('part'): ret_info = self.extract_disk_name(disk_single) if ret_info: parts.append("/dev/%s" % ret_info['alias']) for disk_single in out.split('\n'): if disk_single.strip() and -1 == disk_single.find('part'): ret_info = self.extract_disk_name(disk_single) if ret_info.get( 'alias') and not ret_info['alias'].startswith('sr'): for part in parts: if ret_info['alias'] in part: break else: parts.append("/dev/%s" % ret_info['alias']) logging.info("get all parts from by-id:%s", parts) pvs = self.get_pvs() mounted = self.get_mounted_part() # 过滤掉作为pv的 for pv in pvs: if pv in parts: parts.remove(pv) # 过滤掉已经挂载使用的 for mount in mounted: if mount in parts: parts.remove(mount) logging.info("get disk parts info:%s", parts) return parts