diff --git a/multibootusb b/multibootusb index 76b8096..3340d35 100755 --- a/multibootusb +++ b/multibootusb @@ -66,6 +66,7 @@ Options: -y or --yes : Default yes for user input during install. Will not wait for user. -u or --uninstall : List and uninstall distro from an USB disk. + -r or --raw : Write ISO image diretly to USB disk. Will destroy data. -d or --debug : Enable debug messages (very verbose!) Example for making a bootable USB from the command line: @@ -91,6 +92,14 @@ Example for installing multiple distros without user intervention: Windows: python3 multibootusb -c -i ../../favourite.iso,../../other-distro.iso -t G: + +Example for writing ISO image to target USB disk (will destroy data on USB disk): + + Linux: + python3 multibootusb -c -r -i ../../favourite.iso -t /dev/sdb + + Windows: + python3 multibootusb -c -i -r ../../favourite.iso -t G: ''') exit(2) @@ -112,8 +121,9 @@ if __name__ == '__main__': admin.runAsAdmin() sys.exit(0) try: - opts, args = getopt.getopt(sys.argv[1:], 'i:t:yvhcud', - ['iso=', 'target=', 'yes', 'version', 'help', 'command', 'uninstall', 'debug']) + opts, args = getopt.getopt(sys.argv[1:], 'i:t:yvhcudr', + ['iso=', 'target=', 'yes', 'version', 'help', 'command', 'uninstall', 'debug', + 'raw']) except getopt.GetoptError: usage() sys.exit(2) @@ -139,6 +149,8 @@ if __name__ == '__main__': config.debug = True elif opt in ('-y', '--yes'): config.yes = True + elif opt in ('-r', '--raw'): + config.cli_dd = True else: gui = True #start_gui() @@ -165,6 +177,8 @@ if gui is False: elif config.image_path is '' or config.usb_disk is '': log('\nOptions \'-i\' and \'-t\' must be supplied together. See the usage below.') usage() + elif config.cli_dd is True: + cli_dd() else: running_from() cli_install_distro() diff --git a/scripts/config.py b/scripts/config.py index da8e6c5..ed99756 100644 --- a/scripts/config.py +++ b/scripts/config.py @@ -26,7 +26,7 @@ iso_file_list = '' iso_bin_dir = '' process_exist = None yes = False - +cli_dd = False imager_iso_link = "" imager_usb_disk_selected = "" diff --git a/scripts/mbusb_cli.py b/scripts/mbusb_cli.py index 1c9030c..71e3a9b 100644 --- a/scripts/mbusb_cli.py +++ b/scripts/mbusb_cli.py @@ -7,6 +7,7 @@ # under the terms of GNU General Public License, v.2 or above import os +import ctypes from . import usb from . import gen from .iso import * @@ -14,6 +15,7 @@ from .uninstall_distro import * from .distro import * from .syslinux import * from .install import * +from . import imager def read_input_uninstall(): @@ -26,6 +28,20 @@ def read_input_uninstall(): return response +def is_root(): + """ + Check if user has admin rights + :return: + """ + if platform.system() == 'Linux': + if os.getuid() == 0: + return True + elif platform.system() == 'Windows': + if ctypes.windll.shell32.IsUserAnAdmin() == 1: + return True + + return False + def cli_install_distro(): # if platform.system() == 'Linux': # if os.getuid() != 0: @@ -114,3 +130,40 @@ def cli_uninstall_distro(): unin_distro() else: log('No distro installed on ' + config.usb_disk) + + +def cli_dd(): + """ + Function to write ISO image directly to USB disk using dd + :return: + """ + if platform.system() == 'Linux': + if config.usb_disk[-1].isdigit() is True: + log('Selected USB is a disk partition. Please select the whole disk eg. \'/dev/sdb\'') + sys.exit(2) + elif is_root() is False: + log("You need to have root privileges to run this script.\nPlease try again using admin privilege (sudo).") + sys.exit(2) + + if not os.path.exists(config.image_path): + log('ISO image path does not exist. Please correct the path.') + sys.exit(2) + else: + if config.yes is not True: + log('Initiating destructive writing process for ' + iso.iso_basename(config.image_path)) + log('\nSelected ISO is :' + quote(iso_name(config.image_path))) + log('Selected target device is :' + quote(config.usb_disk)) + log('Writing ISO directly to target USB disk ' + quote(config.usb_disk) + ' will DESTROY ALL DATA.' + '\n') + log('Please confirm the option.') + log('Y/y/Yes/yes/YES or N/n/No/no/NO') + if read_input_yes() is True: + if platform.system() == 'Linux': + imager.dd_linux() + else: + imager.dd_win() + else: + log('Operation cancelled by user. Exiting...') + sys.exit(2) + else: + log('\nAuto install is not recommended in direct writing method. Please choose without \'-y\' option.\n') + sys.exit(2) diff --git a/scripts/usb.py b/scripts/usb.py index 9a4e013..6dfdd89 100644 --- a/scripts/usb.py +++ b/scripts/usb.py @@ -101,17 +101,15 @@ def list_devices(fixed=False): from . import pyudev context = pyudev.Context() - for device in context.list_devices(subsystem='block', ID_BUS="usb"): - if device.get('ID_PART_TABLE_TYPE') is not None: - devices.append(str(device.get('DEVNAME'))) - gen.log("\t" + device.get('DEVNAME')) - - if fixed is True: - devices = [] - for device in context.list_devices(subsystem='block'): + for device in context.list_devices(subsystem='block'): + if fixed is True: if device.get('DEVTYPE') in ['disk', 'partition'] and device.get('ID_PART_TABLE_TYPE'): devices.append(str(device.get('DEVNAME'))) gen.log("\t" + device.get('DEVNAME')) + else: + if device.get('ID_BUS') in ['usb'] and device.get('ID_PART_TABLE_TYPE'): + devices.append(str(device.get('DEVNAME'))) + gen.log("\t" + device.get('DEVNAME')) except Exception as e: gen.log(e)