From decd0018309dc9d700438c60d27928b33c1b4176 Mon Sep 17 00:00:00 2001 From: shinji-s Date: Mon, 30 Apr 2018 23:57:44 +0900 Subject: [PATCH 1/4] Avoid catch-all exception handling. --- multibootusb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/multibootusb b/multibootusb index ae831e0..dc1be11 100644 --- a/multibootusb +++ b/multibootusb @@ -33,13 +33,13 @@ try: from scripts import admin from scripts import gen from scripts import config -except: +except ImportError: try: from .scripts.mbusb_cli import * from .scripts import admin from .scripts import gen from .scripts import config - except: + except ImportError: import scripts gui = True From 1744cd34cbfdc59ec0871bdade3a80f174c00f9f Mon Sep 17 00:00:00 2001 From: Shinji Suzuki Date: Wed, 25 Apr 2018 02:55:44 +0900 Subject: [PATCH 2/4] Recreate syslinux.bin upon distro installation. Start isolating os dependency into osdriver.py Cleanup gen.resurce_path() --- data/multibootusb/syslinux.bin | Bin 512 -> 0 bytes scripts/gen.py | 26 ++++++++-------- scripts/osdriver.py | 53 +++++++++++++++++++++++++++++++++ scripts/syslinux.py | 19 ++++++++++-- 4 files changed, 82 insertions(+), 16 deletions(-) delete mode 100644 data/multibootusb/syslinux.bin create mode 100644 scripts/osdriver.py diff --git a/data/multibootusb/syslinux.bin b/data/multibootusb/syslinux.bin deleted file mode 100644 index d887d40a9646b373107a72bd347658d5eb334fe5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 512 zcmaDIF(EiI*vHc^G=hPNLxF*b0SJCDFxWHvXJFs}vJ2ib+_44;GJxe68Q35kDA~ZE z$*^{Ad~m3ri(`-i2)H?h7#jiUUw;fw_FddlRvp9^E*I8!aHHD(it5ix`)=;8VBp_k z&c7f`;ZlXP;em~8o%WsXOrKMhcJWEnbol-V0D`l^uamk%S9O=JIQWi*@l*3J|1!hI zUz^yAwZFM;sV`Nv@ZC|OkY=ms9uQJ0&``VMZ7EmU|I#-={Ngo#U?7m*^O_w*o5|E{ z;dt?qp-5QaNh$xqR~$~AVp28D5A8dFmi^wnDs+qEi_;860*${zSCw*oJIGkVdW_Aj zmLYA&1%ty3X}dt)+|AJNf{!7s(N3me;b*7((vp`yn9`Wp5~|aL#Zszw3NXCZP76v4 zU<=M-%o6B)mX@%^=|wq1T4HaCKoR5Nv;@NgFEW7KN4G#GYo{fo@ozVir~#68QZ;Gc zzZsrvKb7|Vdz$TkW(J0G@dHoT9626#9PPNagOTZlK2RgjkVhvCzx7?)lTqDwFRh=g zf??mS+BFIXN;tRh?Pg~ " + extlinu_cmd) @@ -153,12 +161,16 @@ def syslinux_default(usb_disk): config.status_text = 'mbr install is successful...' log("\nmbr install is success...\n") if set_boot_flag(usb_disk) is True: + create_syslinux_bs(usb_disk, usb_mount) return True elif usb_fs in syslinux_fs: if platform.system() == "Linux": - return linux_install_default_bootsector(usb_disk, mbr_install_cmd) + r = linux_install_default_bootsector(usb_disk, mbr_install_cmd) + if r: + create_syslinux_bs(usb_disk, usb_mount) + return r elif platform.system() == "Windows": syslinux = resource_path(os.path.join(multibootusb_host_dir(), "syslinux", "bin", "syslinux4.exe")) config.status_text = 'Installing default syslinux version 4...' @@ -189,6 +201,7 @@ def syslinux_default(usb_disk): else: log('Disk uses GPT and mbr install is not required...') ''' + create_syslinux_bs(usb_disk, usb_mount) return True else: From 9fa2d1d834fba3cb351c4d841fbb6b7cd4d1f7fd Mon Sep 17 00:00:00 2001 From: shinji-s Date: Fri, 4 May 2018 06:49:01 +0900 Subject: [PATCH 3/4] Restore 'shell=True" arg when executing chmod.(It can not be omitted unless the command is given as a list or the command is a fullpath to an executable without args.) --- scripts/syslinux.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/syslinux.py b/scripts/syslinux.py index 1ffa0f2..b3eb639 100644 --- a/scripts/syslinux.py +++ b/scripts/syslinux.py @@ -96,7 +96,7 @@ def linux_install_default_bootsector(usb_disk, mbr_install_cmd): with usb.UnmountedContext(usb_disk, config.update_usb_mount): syslinux_cmd = [syslinux_path, '-i', '-d', 'multibootusb', usb_disk] if os.access(syslinux_path, os.X_OK) is False: - subprocess.call('chmod +x ' + syslinux_path) + subprocess.call('chmod +x ' + syslinux_path, shell=True) log("\nExecuting ==> %s\n" % syslinux_cmd) config.status_text = 'Installing default syslinux version 4...' if subprocess.call(syslinux_cmd) == 0: From a18421943658e25c4fff9c21176938b0c227fde5 Mon Sep 17 00:00:00 2001 From: shinji-s Date: Fri, 4 May 2018 16:09:50 +0900 Subject: [PATCH 4/4] Set log location at '/var/log/multibootusb.log' and show that info before installation of a distro commences. Use 'RotatingFileHandler' instead of 'os.remove()' to rotate log because trying to remove file without closing the open handle causes exception on Windows. Move a handleful of funtions from gen.py to osdriver.py to avoid cyclic dependency. --- scripts/gen.py | 100 +------------------------------------------ scripts/mbusb_gui.py | 7 ++- scripts/osdriver.py | 94 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 98 insertions(+), 103 deletions(-) diff --git a/scripts/gen.py b/scripts/gen.py index 6e0ae3a..46e6e57 100644 --- a/scripts/gen.py +++ b/scripts/gen.py @@ -18,71 +18,13 @@ import re import ctypes from . import config +from .osdriver import get_physical_disk_number, wmi_get_drive_info, \ + log, resource_path def scripts_dir_path(): return os.path.dirname(os.path.realpath(__file__)) -def log(message, info=True, error=False, debug=False, _print=True): - """ - Dirty function to log messages to file and also print on screen. - :param message: - :param info: - :param error: - :param debug: - :return: - """ - # LOG_FILE_PATH = os.path.join(multibootusb_host_dir(), 'multibootusb.log') - LOG_FILE_PATH = mbusb_log_file() - if os.path.exists(LOG_FILE_PATH): - log_file_size = os.path.getsize(LOG_FILE_PATH) / (1024.0 * 1024.0) - if log_file_size > 1: - print('Removing log file as it crosses beyond 1mb') - os.remove(LOG_FILE_PATH) - logging.basicConfig(filename=LOG_FILE_PATH, - filemode='a', - format='%(asctime)s.%(msecs)03d %(name)s %(levelname)s %(message)s', - datefmt='%H:%M:%S', - level=logging.DEBUG) - if _print is True: - print(message) - - # remove ANSI color codes from logs - # message_clean = re.compile(r'\x1b[^m]*m').sub('', message) - - if info is True: - logging.info(message) - elif error is not False: - logging.error(message) - elif debug is not False: - logging.debug(message) - - - -def resource_path(relativePath): - """ - Function to detect the correct path of file when working with sourcecode/install or binary. - :param relativePath: Path to file/data. - :return: Modified path to file/data. - """ - # This is not strictly needed because Windows recognize '/' - # as a path separator but we follow the discipline here. - relativePath = relativePath.replace('/', os.sep) - for dir_ in [ - os.path.abspath('.'), - os.path.abspath('..'), - getattr(sys, '_MEIPASS', None), - os.path.dirname(os.path.dirname( # go up two levels - os.path.realpath(__file__))), - '/usr/share/multibootusb'.replace('/', os.sep), - ]: - if dir_ is None: - continue - fullpath = os.path.join(dir_, relativePath) - if os.path.exists(fullpath): - return fullpath - log("Could not find resource '%s'." % relativePath) - def print_version(): """ Simple log the version number of the multibootusb application @@ -129,23 +71,6 @@ def sys_64bits(): return sys.maxsize > 2**32 -def mbusb_log_file(): - """ - Function to genrate path to log file. - Under linux path is created as /tmp/multibootusb.log - Under Windows the file is created under installation directory - """ - if platform.system() == "Linux": - # home_dir = os.path.expanduser('~') - # log_file = os.path.join(home_dir, "multibootusb.log") - log_file = os.path.join(tempfile.gettempdir(), "multibootusb.log") - elif platform.system() == "Windows": - # log_file = os.path.join(tempfile.gettempdir(), "multibootusb", "multibootusb.log") - log_file = os.path.join("multibootusb.log") - - return log_file - - def multibootusb_host_dir(): """ Cross platform way to detect multibootusb directory on host system. @@ -486,28 +411,7 @@ class MemoryCheck(): """ totalMemory = os.popen("free -m").readlines()[1].split()[1] return int(totalMemory) - -def wmi_get_drive_info(usb_disk): - assert platform.system() == 'Windows' - import wmi - c = wmi.WMI() - for partition in c.Win32_DiskPartition(): - logical_disks = partition.associators("Win32_LogicalDiskToPartition") - # Here, 'disk' is a windows logical drive rather than a physical drive - for disk in logical_disks: - if disk.Caption == usb_disk: - return (partition, disk) - raise RuntimeError('Failed to obtain drive information ' + usb_disk) -def get_physical_disk_number(usb_disk): - """ - Get the physical disk number as detected ny Windows. - :param usb_disk: USB disk (Like F:) - :return: Disk number. - """ - partition, logical_disk = wmi_get_drive_info(usb_disk) - log("Physical Device Number is %d" % partition.DiskIndex) - return partition.DiskIndex if __name__ == '__main__': log(quote("""Test-string""")) diff --git a/scripts/mbusb_gui.py b/scripts/mbusb_gui.py index 7a8845f..7af7598 100644 --- a/scripts/mbusb_gui.py +++ b/scripts/mbusb_gui.py @@ -36,6 +36,7 @@ from . import persistence from . import config from . import admin from . import qemu +from . import osdriver from .update_cfg_file import update_distro_cfg_files import scripts.gui.resources @@ -685,9 +686,11 @@ Selected USB disk: %s USB mount point: %s Selected distro: %s -Proceed with installation?'''.lstrip() % \ - (config.usb_disk, config.usb_mount, iso_name(config.image_path)) +Log location: %s +Proceed with installation?'''.lstrip() % \ + (config.usb_disk, config.usb_mount, iso_name(config.image_path), + osdriver.mbusb_log_file()) reply = QtWidgets.QMessageBox.question( self, 'Review selection...', msg) if reply == QtWidgets.QMessageBox.Yes: diff --git a/scripts/osdriver.py b/scripts/osdriver.py index f1c5383..ca0ef39 100644 --- a/scripts/osdriver.py +++ b/scripts/osdriver.py @@ -1,8 +1,80 @@ +import logging +import logging.handlers import os import platform import subprocess +import sys + + +def log(message, info=True, error=False, debug=False, _print=True): + """ + Dirty function to log messages to file and also print on screen. + :param message: + :param info: + :param error: + :param debug: + :return: + """ + if _print is True: + print(message) + + # remove ANSI color codes from logs + # message_clean = re.compile(r'\x1b[^m]*m').sub('', message) + + if info is True: + logging.info(message) + elif error is not False: + logging.error(message) + elif debug is not False: + logging.debug(message) + +def resource_path(relativePath): + """ + Function to detect the correct path of file when working with sourcecode/install or binary. + :param relativePath: Path to file/data. + :return: Modified path to file/data. + """ + # This is not strictly needed because Windows recognize '/' + # as a path separator but we follow the discipline here. + relativePath = relativePath.replace('/', os.sep) + for dir_ in [ + os.path.abspath('.'), + os.path.abspath('..'), + getattr(sys, '_MEIPASS', None), + os.path.dirname(os.path.dirname( # go up two levels + os.path.realpath(__file__))), + '/usr/share/multibootusb'.replace('/', os.sep), + ]: + if dir_ is None: + continue + fullpath = os.path.join(dir_, relativePath) + if os.path.exists(fullpath): + return fullpath + log("Could not find resource '%s'." % relativePath) + +def get_physical_disk_number(usb_disk): + """ + Get the physical disk number as detected ny Windows. + :param usb_disk: USB disk (Like F:) + :return: Disk number. + """ + partition, logical_disk = wmi_get_drive_info(usb_disk) + log("Physical Device Number is %d" % partition.DiskIndex) + return partition.DiskIndex + +def wmi_get_drive_info(usb_disk): + assert platform.system() == 'Windows' + import wmi + c = wmi.WMI() + for partition in c.Win32_DiskPartition(): + logical_disks = partition.associators("Win32_LogicalDiskToPartition") + # Here, 'disk' is a windows logical drive rather than a physical drive + for disk in logical_disks: + if disk.Caption == usb_disk: + return (partition, disk) + raise RuntimeError('Failed to obtain drive information ' + usb_disk) + -from .gen import get_physical_disk_number, log, resource_path class Base: @@ -25,7 +97,10 @@ class Windows(Base): def physical_disk(self, usb_disk): return r'\\.\physicaldrive%d' % get_physical_disk_number(usb_disk) - + + def mbusb_log_file(self): + return os.path.join(os.getcwd(), 'multibootusb.log') + class Linux(Base): def __init__(self): @@ -37,6 +112,10 @@ class Linux(Base): def physical_disk(self, usb_disk): return usb_disk.rstrip('0123456789') + def mbusb_log_file(self): + return '/var/log/multibootusb.log' + + driverClass = { 'Windows' : Windows, 'Linux' : Linux, @@ -48,6 +127,15 @@ osdriver = driverClass() for func_name in [ 'run_dd', 'physical_disk', + 'mbusb_log_file', ]: globals()[func_name] = getattr(osdriver, func_name) - + + +logging.root.setLevel(logging.DEBUG) +fmt = '%(asctime)s.%(msecs)03d %(name)s %(levelname)s %(message)s' +datefmt = '%H:%M:%S' +the_handler = logging.handlers.RotatingFileHandler( + osdriver.mbusb_log_file(), 'a', 1024*1024, 5) +the_handler.setFormatter(logging.Formatter(fmt, datefmt)) +logging.root.addHandler(the_handler)