def installed_vbox_error(self): msg = _( "We have detected an existing VirtualBox installation on this computer.\n" "%s is not compatible with this version of VirtualBox, please remove this VirtualBox installation to run %s.\n\n" "Note that if you want to use your own VirtualBox installation, you need to reboot your computer." ) % (conf.PRODUCTNAME, conf.PRODUCTNAME) gui.dialog_info(title=_("VirtualBox detected"), msg=msg) sys.exit(1)
def look_for_virtualbox(self): # Check virtualbox binaries logging.debug("Checking VirtualBox binaries") if not path.exists(path.join(conf.BIN, self.VIRTUALBOX_EXECUTABLE)): logging.debug("Missing binaries in " + conf.BIN) gui.dialog_info( msg=_("The VirtualBox binaries could not be found"), title=_("Missing binaries")) sys.exit(1)
def rights_error(self): msg = _("You don't have enough permissions to run %s.") % ( conf.PRODUCTNAME, ) logging.debug("Using Windows version " + str(platform.win32_ver())) if platform.win32_ver()[0].lower() == "vista": msg += _( "Run %s as Administrator by right clicking on %s and select : 'Run as administrator'" ) % (conf.PRODUCTNAME, path.splitext(conf.WINDOWSEXE)[0]) else: msg += _( "Run %s as Administrator by right clicking on %s and select : 'Run as ...'" ) % (conf.PRODUCTNAME, path.splitext(conf.WINDOWSEXE)[0]) gui.dialog_info(title=_("Not enough permissions"), msg=msg) sys.exit(1)
def prepare(self): if not self.is_admin(): self.execv(self.get_respawn_command(), True) if isinstance(self, GenericLinuxBackend): gui.dialog_info( title=_("Warning"), msg= _("Your Linux distribution is not officially supported by %s\n" "You may or may not encounter errors. Install PyQt4 and VirtualBox... and pray :)" ) % (conf.PRODUCTNAME, )) self.call(["rmmod", "kvm-intel"]) self.call(["rmmod", "kvm-amd"]) self.call(["rmmod", "kvm"])
def prepare_device(self, disk): # TODO: # Use chflags cmd insteadof fstab workaround # when conf.PARTS == "all". # Also use chflags to avoid system mounts # other volume than UFO, if they are mountable. if conf.PARTS == "all": if conf.MOBILE: if path.exists("/etc/fstab"): shutil.copyfile("/etc/fstab", "/etc/fstab.bak") for partition in glob.glob(disk + "s*"): volname = grep( self.call(["diskutil", "info", partition], output=True)[1], "Volume Name:").split() if not volname or len(volname) < 3: continue volname = volname[2] fstype = grep( self.call(["diskutil", "info", partition], output=True)[1], "File System:").split() if fstype: fstype = fstype[2] fstype = { "MS-DOS": "msdos", "Ext2": "ext2", "Ext3": "ext3" }.get(fstype, fstype) logging.debug( 'echo "LABEL=%s none %s rw,noauto" >> /etc/fstab' % (volname, fstype)) if conf.MOBILE: append_to_end( "/etc/fstab", "LABEL=%s none %s rw,noauto\n" % (volname, fstype)) retcode = self.call(["diskutil", "unmount", partition]) if not retcode: logging.debug("Unable to umount %s, exiting script" % (conf.DEV, )) gui.dialog_info( title="Erreur", msg=_('Unable to unmount the volume ') + str(volname), error=True) return retcode return 0 return 0
def execv(self, cmd, root=False): if root: tries = 0 while tries < 3: logging.debug("Asking user password") remember = False password = gui.dialog_password(remember=False) if password == None: ret = -1 break self.call(["sudo", "-k"]) ret = self.call([["echo", str(password)], ["sudo", "-S", "touch", sys.executable]], log=False)[0] if ret == 0: if remember: output = self.call(["sudo", "-l"], output=True)[1] if not "NOPASSWD: /Volumes/UFO/Mac-Intel/UFO.app/Contents/MacOS/UFO" in output: sudoline = os.environ[ "USER"] + " ALL=(ALL) NOPASSWD: /Volumes/UFO/Mac-Intel/UFO.app/Contents/MacOS/UFO" self.call([ "sudo", "-n", "-s", "echo -e " + sudoline + " >> /etc/sudoers" ]) break else: gui.dialog_info( title=_("Error"), msg= _("Sorry, couldn't authenticate. Please check your password." ), error=True) tries += 1 if ret == 0: cmd = ["sudo"] + cmd else: return logging.debug("Environment: " + str(os.environ)) logging.debug("execv: " + " ".join(cmd)) logging.shutdown() #os.execv(cmd[0], cmd) self.call(cmd, spawn=True)
def on_dl(_self): if _self.dl_mutex: return _self.dl_mutex = True filedialog = QtGui.QFileDialog( self, _("Please select a destination directory for the download" ), os.getcwd()) filedialog.setFileMode(QtGui.QFileDialog.Directory) filedialog.setOption(QtGui.QFileDialog.ShowDirsOnly, True) if filedialog.exec_() != QtGui.QDialog.Accepted: _self.dl_mutex = False return _self.dest_dir = unicode(filedialog.selectedFiles()[0]) _self.dest_file = os.path.join(_self.dest_dir, "ufo-key-latest.img") logging.debug("Downloading " + conf.IMGURL + " to " + _self.dest_file) retcode = gui.download_file( conf.IMGURL, _self.dest_file, title=_("Downloading %s key image") % (conf.PRODUCTNAME, ), msg=_("Please wait while the image is being downloaded"), autoclose=True, autostart=True) if not retcode: _self.edit.setText(_self.dest_file) else: gui.dialog_info( title=_("Warning"), msg= _("The download has encountered a fatal error, please check your Internet connection and retry" )) _self.dl_mutex = False
def self_update(ufo_dir, relaunch): try: latest_version, x, x = get_latest_version() latest_version = ".".join(map(str, latest_version)) try: if sys.platform == "darwin": mount = utils.grep( utils.call(["mount"], output=True)[1], ufo_dir) if mount: dev = mount.split()[0] utils.call(["diskutil", "unmount", dev]) utils.call(["diskutil", "mount", dev]) except: pass url = conf.UPDATEURL + "/launcher-" + latest_version + ".tar.bz2" filename = tempfile.mkstemp()[1] logging.debug("Downloading " + url + " to " + filename) retcode = gui.download_file( url, filename, title=_("Downloading update"), msg=_("Please wait while the update is being downloaded"), success_msg=_( "Your key will now be updated.<br>" "This operation can take a few minutes<br><br>\n" "<b>The USB key absolutely must not be unplugged during this process.</b>" )) if retcode: raise Exception("Download was canceled") logging.debug("Extracting update " + filename + " to " + ufo_dir) import tarfile tar = tarfile.open(filename) filelist = path.join(ufo_dir, ".data", "launcher.filelist") gui.wait_command( cmd=[ remove_deprecated_files, tar, filelist, os.path.normcase(ufo_dir) ], title=_("Removing old files"), msg=_("Please wait while the old files are being removed")) if sys.platform == "darwin": gui.wait_command( cmd=["tar", "-C", ufo_dir, "-xjf", filename], title=_("Installing update"), msg=_( "Please wait while the update is being installed.<br><br>" "<b>The USB key absolutely must not be unplugged.</b>")) mount = utils.grep(utils.call(["mount"], output=True)[1], ufo_dir) if mount: dev = mount.split()[0] utils.call(["diskutil", "unmount", dev]) utils.call(["diskutil", "mount", dev]) # At this point we consider that update terminated successfully, # as tar command return higher than 0 when all files has been copied. success = True else: success = gui.extract_tar( tgz=tar, dest=os.path.normcase(ufo_dir), title=_("Installing update"), msg=_( "Please wait while the update is being installed.<br><br>" "<b>The USB key absolutely must not be unplugged.</b>")) tar.close() if not success: raise Exception("Installation has failed") logging.debug("Updating settings.conf") cp = ConfigParser() cp.read([conf.conf_file]) cp.set("launcher", "VERSION", latest_version) cp.write(open(conf.conf_file, "w")) gui.dialog_info(title=_("Information"), msg=_("Your %s launcher is up to date (v") % (conf.PRODUCTNAME, ) + latest_version + ") !") try: os.remove(filename) except: pass except: gui.dialog_info( title=_("Error"), msg=_("An error occurred. You key could not be updated.")) import traceback info = sys.exc_info() logging.debug("Unexpected error: " + str(info[1])) logging.debug("".join(traceback.format_tb(info[2]))) logging.debug("Exception while updating") logging.debug("Restarting UFO launcher : " + relaunch) logging.shutdown() os.execv(relaunch, [relaunch, "--respawn"])
def unsupported_platform(self, arch): msg = _("We're sorry but your architecture (%s) is not yet supported." ) % (arch, ) gui.dialog_info(title=_("Unsupported architecture"), msg=msg) sys.exit(1)
def configure_virtual_machine(self, create_vmdk=True): if not conf.VMDK and not conf.CONFIGUREVM: logging.debug("Skipping configuration of the VM") self.vbox.close_session() return logging.debug("VMDK = " + conf.VMDK + " create_vmdk " + str(create_vmdk)) if conf.ROOTVDI: self.vbox.current_machine.attach_harddisk(conf.ROOTVDI, conf.DRIVERANK) conf.DRIVERANK += 1 elif conf.VMDK and create_vmdk: rank = conf.DRIVERANK if conf.LIVECD: rank += 1 vmdk = path.normpath(path.join(conf.DATA_DIR, conf.VMDK)) if os.path.exists(vmdk): os.unlink(vmdk) if conf.PARTS == "all": logging.debug("Getting size of " + conf.DEV) blockcount = self.get_device_size(conf.DEV) logging.debug("Creating VMDK file %s with %s of size %d: " % (vmdk, conf.DEV, blockcount)) createrawvmdk.createrawvmdk(vmdk, conf.DEV, blockcount) else: logging.debug( "Creating vbox VMDK file %s with %s, partitions %s: " % (vmdk, conf.DEV, conf.PARTS)) if os.path.exists(vmdk[:len(vmdk) - 5] + "-pt.vmdk"): os.unlink(vmdk[:len(vmdk) - 5] + "-pt.vmdk") device_parts = self.get_device_parts(conf.DEV) for current_part in device_parts: device_parts.get(current_part).append( str(current_part) in conf.PARTS.split(',')) blockcount = self.get_device_size(conf.DEV) createrawvmdk.createrawvmdk(vmdk, conf.DEV, blockcount, self.get_mbr(self.open(conf.DEV)), device_parts, self.RELATIVE_VMDK_POLICY) self.vbox.current_machine.attach_harddisk(vmdk, rank) conf.DRIVERANK += 1 if conf.CONFIGUREVM: # compute reasonable memory size if conf.RAMSIZE == conf.AUTO_INTEGER: if self.vbox.vbox_version() >= "2.1.0": freeram = self.vbox.host.get_free_ram() else: freeram = self.get_free_ram() ram = max(2 * freeram / 3, conf.MINRAM) # The VM is a lot slower if we use high memory if not conf.USEHIGHMEM: ram = min(2048, ram) else: ram = conf.RAMSIZE # Cannot give more than 3584 Mo of RAM ram = min(3584, ram) if int(ram) <= int(conf.MINRAM): gui.dialog_info( title=_("Warning"), msg= _("The available memory on this computer is low.\n" "This can deeply impact the speed of the %s virtual machine.\n\n" "Closing some applications or restarting the computer may help" ) % (conf.PRODUCTNAME, ), error=False) logging.debug("Setting RAM to " + str(ram)) self.vbox.current_machine.set_ram_size(ram) # Set number of processors if self.vbox.vbox_version( ) >= "3.0.0" and self.vbox.host.is_virt_ex_available(): logging.debug("Settings CPU capabilities: VT=%s PAE=%s nested_paging=%s" % \ (conf.PAE, conf.VT, conf.NESTEDPAGING)) self.vbox.current_machine.set_cpu_capabilities( PAE=conf.PAE, VT=conf.VT, nested_paging=conf.NESTEDPAGING) if conf.CPUS == conf.AUTO_INTEGER: nbprocs = int(self.vbox.host.get_nb_procs()) logging.debug( str(nbprocs) + " processor(s) available on host") if nbprocs >= 2: nbprocs = max(2, nbprocs / 2) else: try: nbprocs = conf.CPUS except: nbprocs = 1 logging.debug("Setting number of processor to " + str(nbprocs)) self.vbox.current_machine.set_procs(nbprocs) # Set 3D acceleration self.vbox.current_machine.enable_3D(conf.ACCEL3D and self.vbox.supports_3D()) # check host network adapter conf.NETTYPE, adpt_name = self.find_network_device() if conf.NETTYPE == conf.NET_NAT: attach_type = self.vbox.constants.NetworkAttachmentType_Null host_adapter = '' logging.debug(conf.SCRIPT_NAME + ": using nat networking") elif conf.NETTYPE == conf.NET_HOST: attach_type = self.vbox.constants.NetworkAttachmentType_Bridged host_adapter = adpt_name logging.debug("Using net bridge on " + adpt_name) self.vbox.current_machine.set_network_adapter( attach_type=attach_type, host_adapter=host_adapter, mac_address=conf.MACADDR) if conf.MACADDR == "": conf.write_value_to_file( "vm", "macaddr", self.vbox.current_machine.get_mac_addr()) for protocol in ["HTTP", "HTTPS", "FTP", "SOCKS"]: proxy, port = "", 0 confvalue = getattr(conf, "PROXY" + protocol) if confvalue == conf.AUTO_STRING: if protocol != "socks": value = self.get_proxy(protocol + "://agorabox.org") if value: proxy, port = value else: proxy, port = confvalue.split(":") if proxy and port: setattr(conf, "PROXY" + protocol, "%s:%d" % (proxy, int(port))) # attach boot iso if conf.BOOTFLOPPY: logging.debug("Using boot floppy image " + conf.BOOTFLOPPY) self.vbox.current_machine.attach_floppy(conf.BOOTFLOPPY) self.vbox.current_machine.set_boot_device('Floppy') if conf.BOOTISO: logging.debug("Using boot iso image " + conf.BOOTISO) failed = self.vbox.current_machine.attach_dvd(conf.BOOTISO) if not conf.LIVECD: self.vbox.current_machine.set_boot_device('DVD') else: logging.debug("Using host dvd drive") failed = self.vbox.current_machine.attach_dvd( host_drive=True, blacklist=["UFO"]) conf.DRIVERANK += 0 if failed else 1 if conf.LIVECD or not conf.BOOTISO and not conf.BOOTFLOPPY: logging.debug("Using hard disk for booting") self.vbox.current_machine.set_boot_device('HardDisk') if conf.LIVECD: logging.debug("Setting bootdisk %s for Live CD at rank %d" % ( conf.BOOTDISK, conf.DRIVERANK, )) self.vbox.current_machine.attach_harddisk( conf.BOOTDISK, conf.DRIVERANK) conf.DRIVERANK += 1 if conf.RESOLUTION: self.fullscreen = False resolution = conf.RESOLUTION hostres = self.find_resolution() if hostres != "" and \ (int(hostres.split("x")[0]) <= int(conf.RESOLUTION.split("x")[0]) or \ int(hostres.split("x")[1]) <= int(conf.RESOLUTION.split("x")[1])): resolution = hostres self.fullscreen = True if resolution != "": logging.debug("Using " + resolution + " as initial resolution") self.vbox.current_machine.set_resolution(resolution) self.vbox.current_machine.set_boot_logo( glob.glob(path.join(conf.IMGDIR, "ufo-*.bmp"))[0]) # set host home shared folder if not conf.USESERVICE: for host_share in self.get_host_shares(): self.vbox.current_machine.add_shared_folder( host_share['sharename'], host_share['sharepath'], writable=True) self.vbox.current_machine.set_guest_property( "/UFO/Com/HostToGuest/Shares/ReadyToMount/" + host_share['sharename'], host_share['displayed']) logging.debug( "Setting shared folder : %s, %s" % (host_share['sharepath'], host_share['displayed'])) self.dnddir = tempfile.mkdtemp(suffix="ufodnd") self.vbox.current_machine.add_shared_folder("DnD", self.dnddir, writable=True) logging.debug("Setting shared folder : " + self.dnddir + ", DnD") logging.debug("conf.SWAPFILE: " + conf.SWAPFILE) if conf.SWAPFILE: try: swap_rank = conf.DRIVERANK if not conf.LIVECD or sys.platform != "win32": self.tmp_swapdir = tempfile.mkdtemp(suffix="ufo-swap") logging.debug("self.tmp_swapdir = " + self.tmp_swapdir) shutil.copyfile( conf.SWAPFILE, path.join(self.tmp_swapdir, path.basename(conf.SWAPFILE))) else: self.tmp_swapdir = conf.DATA_DIR self.vbox.current_machine.attach_harddisk( path.join(self.tmp_swapdir, path.basename(conf.SWAPFILE)), swap_rank) conf.DRIVERANK += 1 swap_dev = "sd" + chr(swap_rank + ord('a')) self.vbox.current_machine.set_guest_property( "/UFO/Storages/Swap/Device", swap_dev) free_size = self.get_free_space( self.tmp_swapdir) / (1024 * 1024) if free_size: swap_size = min(conf.SWAPSIZE, free_size) self.vbox.current_machine.set_guest_property( "/UFO/Storages/Swap/Size", str(swap_size)) except: logging.debug("Exception while creating swap") logging.debug("conf.OVERLAYFILE: " + conf.OVERLAYFILE) if conf.OVERLAYFILE: try: self.tmp_overlaydir = tempfile.mkdtemp(suffix="ufo-overlay") logging.debug("self.tmp_overlaydir = " + self.tmp_overlaydir) tmp_overlay = path.join(self.tmp_overlaydir, path.basename(conf.OVERLAYFILE)) shutil.copyfile(conf.OVERLAYFILE, tmp_overlay) self.vbox.current_machine.attach_harddisk( tmp_overlay, conf.DRIVERANK) conf.DRIVERANK += 1 # TODO: # Set guest prop about max size of the overlay to # to set appropriate quota within guest side. # # free_size = self.get_free_space(self.tmp_overlaydir) / (1024*1024) # if free_size: # virtual_box.machine.set_guest_property("overlay_quota", ...) except: logging.debug("Exception while creating overlay") # manage password keyring if keyring: if conf.USER: password = self.get_password() if password: self.keyring_valid = True self.set_credentials(conf.USER, password) else: logging.debug("Found no credentials") else: self.keyring_valid = None self.credentials = self.set_credentials # build removable devices attachments self.check_usb_devices() # set debug mode if conf.GUESTDEBUG: gui.dialog_info( msg=_("%s is running in debug mode.\n" "Be aware to disable debug mode at the next session.") % (conf.PRODUCTNAME, ), title=_("Debug mode")) for guestprop in conf.get_all_guestprops(): self.vbox.current_machine.set_guest_property( guestprop.get_name(), str(guestprop)) self.vbox.close_session()
def look_for_virtualbox(self): logging.debug("Checking VirtualBox binaries") kernel = "kernel" if os.uname()[2].endswith("PAE"): kernel += "-PAE" if not path.exists(path.join(conf.BIN, self.VIRTUALBOX_EXECUTABLE)): logging.debug("Installing Agorabox repository for VirtualBox") gui.wait_command( ["yum", "-y", "install", "yum-priorities"], **self.get_generic_installation_messages("yum-priorities")) gui.wait_command([ "rpm", "-ivf", self.AGORABOX_VBOX_REPO + "agorabox-virtualbox-yum-repository-1.0.noarch.rpm" ], msg=_("Setting Yum Agorabox repository")) logging.debug("Kernel is: " + kernel) logging.debug("Installing VirtualBox") gui.wait_command( [ "yum", "-y", "install", "VirtualBox-OSE", "VirtualBox-OSE-kmodsrc", kernel, kernel + "-devel", "gcc", "make", "lzma", "xz" ], msg= _("Installing VirtualBox Open Source edition. This can take a few minutes" )) version = self.call( ["rpm", "-q", "--queryformat", "%{VERSION}", "VirtualBox-OSE"], output=True)[1] kmod_name = "VirtualBox-OSE-kmod-" + str(version) lsmod = self.call([["lsmod"], ["grep", "vboxdrv"]], output=True)[1] if not lsmod: cant_compile = False need_reboot = False import yum yumbase = yum.YumBase() yumbase.doConfigSetup() pkglist = yumbase.doPackageLists('installed') devel_exactmatch, devel_matched, devel_unmatched = yum.packages.parsePackages( pkglist.installed, [kernel + "-devel"]) devel_exactmatch.sort(key=lambda x: x.version) kern_exactmatch, kern_matched, kern_unmatched = yum.packages.parsePackages( pkglist.installed, [kernel]) kern_exactmatch.sort(key=lambda x: x.version) yumbase.close() yumbase.closeRpmDB() if devel_exactmatch: latest = devel_exactmatch[-1] if not os.uname()[2].startswith( "%s-%s" % (devel_exactmatch[-1].version, devel_exactmatch[-1].release)): cant_compile = True if kern_exactmatch: latest = kern_exactmatch[-1] if not os.uname()[2].startswith("%s-%s" % (kern_exactmatch[-1].version, kern_exactmatch[-1].release)): need_reboot = True if cant_compile: if need_reboot: msg = _( "You are not running the latest installed version of the kernel.\nA reboot is required for %s to work." ) % (conf.PRODUCTNAME, ) else: msg = _( "An error has occurred during the installation of VirtualBox.\nPlease install the latest %s and %s-devel packages." ) % (kernel, kernel) gui.dialog_info(title=_("Warning"), msg=msg, error=False) sys.exit(0) logging.debug( "Decompressing drivers source code from /usr/share/%s/%s.tar" % ( kmod_name, kmod_name, )) tarfile = glob.glob("/usr/share/%s/%s.tar.*" % ( kmod_name, kmod_name, ))[0] tarext = os.path.splitext(tarfile)[1][1:] utils.call([ "tar", "--use-compress-program", tarext, "-xf", "/usr/share/%s/%s.tar.%s" % ( kmod_name, kmod_name, tarext, ) ], cwd=tempfile.gettempdir()) compdir = os.path.join(tempfile.gettempdir(), kmod_name, "vboxdrv") logging.debug("Compiling vboxdrv source code in %s" % (compdir, )) gui.wait_command(["make", "install", "-C", compdir], msg=_("Compiling VirtualBox drivers")) logging.debug("Loading vboxdrv module") self.call(["/etc/sysconfig/modules/VirtualBox-OSE.modules"]) LinuxBackend.look_for_virtualbox(self)
def validatePage(_self): if self.reverse: missing_device_title = _("Missing source device") missing_device_msg = _("Please select a source device") missing_file_title = _("Missing target image") missing_file_msg = _("Please specify a target image") else: missing_device_title = _("Missing target device") missing_device_msg = _("Please select a target device") missing_file_title = _("Missing source image") missing_file_msg = _( "Please specify a source image or download one by " "clicking the 'Download it' button") # checking device selection if _self.usb_list.currentItem() == None: gui.dialog_info(title=missing_device_title, msg=missing_device_msg) return False # checking file selection edit = unicode(_self.edit.text()) if not edit or (not os.path.exists(edit) and not self.reverse): gui.dialog_info(title=missing_file_title, msg=missing_file_msg) return False if self.reverse: self.source = unicode( self.usbs[_self.usb_list.currentRow()][0]) self.target = unicode(edit) source_size = self.backend.get_device_size( self.source) * 512 disk_space = self.backend.get_free_space( os.path.dirname(self.target)) if disk_space < source_size: gui.dialog_info( title=_("Insufficient disk space"), msg= _("The available size on your disk is insufficient. " "You need more than %d Mo free on your disk to backup your device." "<br><br>Please free some space and retry.") % ((source_size - disk_space) / 1024 / 1024)) return False else: self.source = unicode(edit) self.target = unicode( self.usbs[_self.usb_list.currentRow()][0]) if self.device_size < self.total_size: gui.dialog_info( title=_("The selected target is too small"), msg= _("The size of the source you have selected (%d Mo)" " is bigger than the size of the selected target (%d Mo)." "<br><br>Please select a source equal or smaller than the target." ) % (self.total_size / 1024 / 1024, self.device_size / 1024 / 1024)) return False if not self.reverse: response = gui.dialog_question( title=_("All data on the device will be lost"), msg= _("To setup %s on your device, " "the device needs to be formatted. Are you sure you want to continue ?" ) % (conf.PRODUCTNAME, ), dangerous=True) if response != _("Yes"): return False self.umounted = False for possible_dev in [self.source, self.target]: for usb in self.usbs: if possible_dev == usb[0]: self.umounted = True while not self.backend.umount_device(usb[0]): input = gui.dialog_error_report( _("Warning"), _("%s is not able to umount <b>\"") % (conf.PRODUCTNAME, ) + usb[0] + _("\"</b> because it seems to be busy.\n" "Please close the program that is using it and retry." ), _("Retry"), error=False) if not input: return False time.sleep(0.3) sizes = [] for part in self.parts: sizes.append(_self.get_partition_size(part)) for i, part in enumerate(self.parts): part["size"] = sizes[i] return True