From ec637515f82cdb18f0dd97340bbd7503de10d35a Mon Sep 17 00:00:00 2001 From: mbusb Date: Thu, 20 Apr 2017 23:44:19 +0530 Subject: [PATCH] Improvement in loopback.cfg creation 1. Changed logic to convert syslinux config files to loopback.cfg 2. Added improvement in GUI (install and uninstall icons on buttons). But this does not work at the moment. --- scripts/_7zip.py | 2 +- scripts/grub.py | 216 ++++++--------------------------- scripts/gui/install.png | Bin 0 -> 20967 bytes scripts/gui/multibootusb.ui | 30 ++++- scripts/gui/ui_multibootusb.py | 19 ++- scripts/gui/uninstall.png | Bin 0 -> 18916 bytes 6 files changed, 79 insertions(+), 188 deletions(-) create mode 100644 scripts/gui/install.png create mode 100644 scripts/gui/uninstall.png diff --git a/scripts/_7zip.py b/scripts/_7zip.py index da550f1..c802f07 100644 --- a/scripts/_7zip.py +++ b/scripts/_7zip.py @@ -48,7 +48,7 @@ def extract_iso(src, dst, pattern=None, suppress_out=True): _cmd = _7zip + cli_option + ' x -y -o' + gen.quote(dst) + ' ' + gen.quote(src) + suppress_out else: _cmd = _7zip + ' -y x ' + gen.quote(src) + ' -o' + dst + ' ' + gen.quote(pattern) + ' -r' + suppress_out - gen.log('Executing ' + _cmd) + gen.log('Executing ==> ' + _cmd) _7zip_process = subprocess.Popen(_cmd, universal_newlines=True, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) config.status_text = 'Status: Extracting ' + os.path.basename(src).strip() diff --git a/scripts/grub.py b/scripts/grub.py index 71054c6..6ae28fa 100644 --- a/scripts/grub.py +++ b/scripts/grub.py @@ -189,33 +189,47 @@ def write_to_file(file_path, _strings): def extract_kernel_line(search_text, match_line, isolinux_dir): + """ + Function to check if kernel/linux line present in isolinux.cfg file is valid. + If valid, then convert them in to grub accepted format + :param search_text: Type of text is to be searched. Typically kernel or linux + :param match_line: Line containing kernel ot linux from isolinux supported .cfg files + :param isolinux_dir: Path to isolinux directory of an ISO + :return: Valid grub2 accepted kernel/linux line after conversion. If nothing found return ''. + """ kernel_line = '' + # Remove '=' from linux/kernel parameter if (search_text + '=') in match_line: kernel_path = match_line.replace((search_text + '='), '').strip() search_text = search_text.replace('=', '') else: - kernel_path = match_line.replace(search_text, '').strip() - print(os.path.join(config.usb_mount, 'multibootusb', iso.iso_basename(config.image_path))) - print(os.path.join(config.usb_mount, 'multibootusb', iso.iso_basename(config.image_path), kernel_path)) - print(os.path.join(config.usb_mount, 'multibootusb', iso.iso_basename(config.image_path), isolinux_dir, kernel_path)) - if os.path.join(config.usb_mount, 'multibootusb', iso.iso_basename(config.image_path), kernel_path): + kernel_path = match_line.replace(search_text, '', 1).strip() + + # Check if kernel/linux exist using absolute path (kernel_path) + if os.path.exists(os.path.join(config.usb_mount, kernel_path)): kernel_line = search_text.lower().replace('kernel', 'linux') + ' ' + kernel_path.strip() - elif os.path.join(config.usb_mount, 'multibootusb', iso.iso_basename(config.image_path), isolinux_dir, kernel_path): + + # Check if path to kernel/linux exist in isolinux directory and return absolute path + elif os.path.exists(os.path.join(config.usb_mount, 'multibootusb', iso.iso_basename(config.image_path), isolinux_dir, kernel_path)): kernel_line = search_text.lower().replace('kernel', 'linux') + ' /multibootusb/' + \ - isolinux_dir + '/' + kernel_path.strip() + iso.iso_basename(config.image_path) + '/' + isolinux_dir + '/' + kernel_path.strip() + # Check if multiple kernel/linux exist and convert it to grub accepted line + # Found such entries in manjaro and slitaz elif ',/' in kernel_path: kernel_line = search_text.lower().replace('kernel', 'linux') + ' ' + kernel_path.strip() kernel_line = kernel_line.replace(',/', ' /') + + # Same as above but I found this only in dban elif 'z,' in kernel_path: kernel_line = search_text.lower().replace('kernel', 'linux') + ' ' + kernel_path.strip() - kernel_line = kernel_line.replace('z,', ' /multibootusb') + kernel_line = kernel_line.replace('z,', ' /multibootusb/' + iso.iso_basename(config.image_path) + '/' + + iso.isolinux_bin_dir(config.image_path).replace('\\', '/') + '/') else: kernel_line = '' - - return kernel_line + return kernel_line.replace('\\', '/').replace('//', '/') def iso2grub2(iso_dir): @@ -245,8 +259,6 @@ def iso2grub2(iso_dir): data = cfg_file_str.read() # Make sure that lines with menu label, kernel and append are available for processing ext_text = re.finditer('(menu label|label)(.*?)(?=(menu label|label))', data, re.I|re.DOTALL) - # if (sum(1 for j in ext_text)) == 0: - # ext_text = re.finditer('(menu label|label)(.*?)\Z', data, re.I|re.DOTALL) if ext_text: for m in ext_text: menuentry = '' @@ -255,12 +267,11 @@ def iso2grub2(iso_dir): boot_options = '' initrd_line = '' initrd = '' - print('---------->', os.path.join(config.usb_mount, 'multibootusb', - iso.iso_basename(config.image_path))) + # Extract line containing 'menu label' and convert to menu entry of grub2 if 'menu label' in m.group().lower(): menu_line = re.search('menu label(.*)\s', m.group(), re.I).group() - menuentry = 'menuentry ' + re.sub(r'menu label', '', menu_line, re.I, ).strip() + menuentry = 'menuentry ' + gen.quote(re.sub(r'menu label', '', menu_line, re.I, ).strip()) # Ensure that we do not have caps menu label in the menuentry menuentry = menuentry.replace('MENU LABEL', '') @@ -268,27 +279,23 @@ def iso2grub2(iso_dir): # Probably config does not use 'menu label' line. Just line containing 'label' # and convert to menu entry of grub2 menu_line = re.search('^label(.*)\s', m.group(), re.I).group() - menuentry = 'menuentry ' + re.sub(r'label', '', menu_line, re.I, ).strip() + menuentry = 'menuentry ' + gen.quote(re.sub(r'label', '', menu_line, re.I, ).strip()) # Ensure that we do not have caps label in the menuentry menuentry = menuentry.replace('LABEL', '') - # Extract kernel line and change to linux line of grub2 if 'kernel' in m.group().lower() or 'linux' in m.group().lower(): - # print(m.group()) - print('---------->', os.path.join(config.usb_mount, 'multibootusb', - iso.iso_basename(config.image_path))) kernel_text = re.findall('((kernel|linux)[= ].*?[ \s])', m.group(), re.I) match_count = len(re.findall('((kernel|linux)[= ].*?[ \s])', m.group(), re.I)) - if match_count is 1: kernel_line = extract_kernel_line(kernel_text[0][1], kernel_text[0][0], iso_bin_dir) elif match_count > 2: for _lines in kernel_text: + kernel_line = extract_kernel_line(_lines[0][1], _lines[0][0], + iso_bin_dir) if kernel_line is '': continue else: - kernel_line = extract_kernel_line(kernel_text[0][1], _lines[0][0], iso_bin_dir) break if 'initrd' in m.group().lower(): @@ -298,10 +305,11 @@ def iso2grub2(iso_dir): initrd_line = extract_kernel_line(initrd_text[0][1], initrd_text[0][0], iso_bin_dir) elif match_count > 2: for _lines in initrd_text: - if kernel_line is '': + initrd_line = extract_kernel_line(_lines[0][1], _lines[0][0], + iso_bin_dir) + if initrd_line is '': continue else: - initrd_line = extract_kernel_line(initrd_text[0][1], _lines[0][0], iso_bin_dir) break if 'append' in m.group().lower(): @@ -315,174 +323,20 @@ def iso2grub2(iso_dir): else: linux = '' - print(menuentry) - print(linux) - print(initrd_line) - if menuentry.strip() and linux.strip() and initrd_line.strip(): - #print('\n', menuentry) - #print(linux) - #print(initrd_line, '\n') write_to_file(grub_file_path, menuentry + '{') write_to_file(grub_file_path, ' ' + linux) write_to_file(grub_file_path, ' ' + initrd_line) write_to_file(grub_file_path, '}\n') elif menuentry.strip() and linux.strip(): - #print('\n', menuentry) - #print(linux, '\n') - write_to_file(grub_file_path, menuentry + '{') - write_to_file(grub_file_path, ' ' + linux) - write_to_file(grub_file_path, '}\n') - - if os.path.exists(grub_file_path): - gen.log( - 'loopback.cfg file successfully created.\nYou must send this file for debugging if something goes wrong.') - return 'loopback.cfg' - else: - gen.log('Could not convert syslinux config to loopback.cfg') - return False -''' -def iso2grub2(iso_dir): - """ - Function to convert syslinux configuration to grub2 accepted configuration format. Features implemented are similar - to that of grub2 'loopback.cfg'. This 'loopback.cfg' file can be later on caled directly from grub2. The main - advantage of this function is to generate the 'loopback.cfg' file automatically without manual involvement. - :param iso_dir: Path to distro install directory for looping through '.cfg' files. - :param file_out: Path to 'loopback.cfg' file. By default it is set to root of distro install directory. - :return: - """ - grub_file_path = os.path.join(config.usb_mount, 'multibootusb', iso.iso_basename(config.image_path), 'loopback.cfg') - gen.log('loopback.cfg file is set to ' + grub_file_path) - # Loop though the distro installed directory for finding config files - for dirpath, dirnames, filenames in os.walk(iso_dir): - for f in filenames: - # We will strict to only files ending with '.cfg' extension. This is the file extension isolinux or syslinux - # recommends for writing configurations - if f.endswith(".cfg") or f.endswith('.CFG'): - cfg_file_path = os.path.join(dirpath, f) - # We will omit the grub directory - if 'grub' not in cfg_file_path: - # we will use only files containing strings which can be converted to grub2 cfg style - if string_in_file(cfg_file_path, 'menu label') or string_in_file(cfg_file_path, 'label'): - with open(cfg_file_path, "r", errors='ignore') as cfg_file_str: - data = cfg_file_str.read() - # Make sure that lines with menu label, kernel and append are available for processing - ext_text = re.finditer('(menu label|label)(.*?)(?=(menu label|label))', data, re.I|re.DOTALL) - # if (sum(1 for j in ext_text)) == 0: - # ext_text = re.finditer('(menu label|label)(.*?)\Z', data, re.I|re.DOTALL) - if ext_text: - for m in ext_text: - menuentry = '' - kernel = '' - boot_options = '' - initrd = '' - # print(m.group()) - - # Extract line containing 'menu label' and convert to menu entry of grub2 - if 'menu label' in m.group().lower(): - menu_line = re.search('menu label(.*)\s', m.group(), re.I).group() - menuentry = 'menuentry ' + gen.quote(re.sub(r'menu label', '', menu_line, re.I, ).strip()) - # Ensure that we do not have caps menu label in the menuentry - menuentry = menuentry.replace('MENU LABEL', '') - elif 'label ' in m.group().lower(): - # Probably config does not use 'menu label' line. Just line containing 'label' - # and convert to menu entry of grub2 - menu_line = re.search('^label(.*)\s', m.group(), re.I).group() - menuentry = 'menuentry ' + gen.quote(re.sub(r'label', '', menu_line, re.I, ).strip()) - # Ensure that we do not have caps label in the menuentry - menuentry = menuentry.replace('LABEL', '') - - # Extract kernel line and change to linux line of grub2 - if 'kernel' in m.group().lower() or 'linux ' in m.group().lower(): - kernel_line = re.findall('((kernel|linux)[= ].*?[ \s])', m.group(), re.I)[0][0] - - kernel = kernel_line.strip().replace('kernel', 'linux') - kernel = kernel.strip().replace('KERNEL', 'linux') - if 'linux=/multibootusb' in kernel.lower(): - kernel = kernel.strip().replace('linux=', 'linux ') - - elif 'linux=' in kernel.lower(): - kernel = kernel.strip().replace('linux=', 'linux /multibootusb/' + - iso.iso_basename(config.image_path) + '/' - + iso.isolinux_bin_dir(config.image_path).replace('\\', '/') + '/') - elif 'linux /' not in kernel: - kernel = kernel.strip().replace('linux ', 'linux /multibootusb/' + - iso.iso_basename(config.image_path) + '/' - + iso.isolinux_bin_dir(config.image_path).replace('\\', '/') + '/') - - # Ensure that we do not have linux parameter in caps - kernel = kernel.replace('LINUX ', 'linux ') - kernel = kernel.replace('Linux ', 'linux ') - # Fix for solus os. Patch welcome. - if config.distro == 'fedora' and '/linux' in kernel: - kernel = kernel.replace('/linux', '/kernel') - - # Ensure that initrd is present in the config file - if 'initrd' in m.group().lower(): - # Extract only initrd line which starts in first in the line - if re.search('^initrd', m.group(), re.I|re.MULTILINE): - initrd = re.findall('(initrd[= ].*?[ \s])', m.group(), re.I)[0] - if not initrd: - # print('initrd not in seperate line') - initrd = re.findall('(initrd[= ].*[ \s])', initrd, re.I|re.DOTALL)[0] - # Ensure that multiple initrd of syslinux are converted to grub2 - # standard - initrd = initrd.replace(',/', ' /') - initrd = initrd.replace('z,', 'z /multibootusb/' + - iso.iso_basename(config.image_path) + '/' - + iso.isolinux_bin_dir(config.image_path).replace('\\', '/') + '/') - #print('initrd') - else: - # Extract initrd parameter from within the line - initrd = re.findall('(initrd[= ].*?[ ])', m.group(), re.I|re.DOTALL)[0] - initrd = initrd.replace(',/', ' /') - initrd = initrd.replace('z,', 'z /multibootusb/' + - iso.iso_basename(config.image_path) + '/' - + iso.isolinux_bin_dir(config.image_path).replace('\\', '/') + '/') - #print(initrd) - - # Ensure that we change the relative path to absolute path - if 'initrd=/multibootusb' in initrd.lower(): - initrd = initrd.strip().replace('initrd=', 'initrd ') - initrd = initrd.strip().replace('INITRD=', 'initrd ') - - elif 'initrd=' in initrd.lower(): - initrd = initrd.strip().replace('initrd=', 'initrd /multibootusb/' + - iso.iso_basename(config.image_path) + '/' - + iso.isolinux_bin_dir(config.image_path).replace('\\', '/') + '/') - - # Ensure that there is no caps which is not accepted by grub2 - initrd = initrd.replace('INITRD', 'initrd') - - # Extract append line for getting boot options - if 'append' in m.group().lower(): - append = re.search('append (.*)\s', m.group(), re.I).group() - boot_options = re.sub(r'((initrd[= ])(.*?)[ ])', '', append, re.I, flags=re.DOTALL) - - # Ensure that there is no append line exisit - boot_options = re.sub(r'append', '', boot_options, re.I).strip() - boot_options = boot_options.replace('APPEND', '') - - # We will ensure that all options are met as per grub2 specifications and - # write to file - linux = kernel.strip() + ' ' + boot_options.strip().strip() - if menuentry and linux and initrd: - # print('\n', menuentry) - # print(linux) - # print(initrd) - write_to_file(grub_file_path, menuentry + '{') - write_to_file(grub_file_path, ' ' + linux) - write_to_file(grub_file_path, ' ' + initrd) - write_to_file(grub_file_path, '}\n') - elif menuentry and linux.strip(): write_to_file(grub_file_path, menuentry + '{') write_to_file(grub_file_path, ' ' + linux) write_to_file(grub_file_path, '}\n') if os.path.exists(grub_file_path): - gen.log('loopback.cfg file successfully created.\nYou must send this file for debugging if something goes wrong.') + gen.log( + 'loopback.cfg file is successfully created.\nYou must send this file for debugging if something goes wrong.') return 'loopback.cfg' else: - gen.log('Could not convert syslinux config to loopback.cfg') + gen.log('Failed to convert syslinux config file to loopback.cfg') return False -''' \ No newline at end of file diff --git a/scripts/gui/install.png b/scripts/gui/install.png new file mode 100644 index 0000000000000000000000000000000000000000..c2a6f9e951a4cf369b28bad0fdb9acadcec19182 GIT binary patch literal 20967 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 - 3 + 0 @@ -349,13 +349,39 @@ Uninstall distro + + + uninstall.pnguninstall.png + + + + 16 + 18 + + + + + 16777215 + 16777215 + + Install distro + + + install.pnginstall.png + + + + 16 + 18 + + @@ -909,7 +935,7 @@ 0 0 629 - 19 + 21 diff --git a/scripts/gui/ui_multibootusb.py b/scripts/gui/ui_multibootusb.py index 366132c..bfad24f 100644 --- a/scripts/gui/ui_multibootusb.py +++ b/scripts/gui/ui_multibootusb.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'gui/multibootusb.ui' +# Form implementation generated from reading ui file 'scripts\gui\multibootusb.ui' # -# Created by: PyQt5 UI code generator 5.5.1 +# Created by: PyQt5 UI code generator 5.6 # # WARNING! All changes made in this file will be lost! @@ -167,9 +167,18 @@ class Ui_MainWindow(object): self.gridLayout.setContentsMargins(5, 5, 5, 5) self.gridLayout.setObjectName("gridLayout") self.button_uninstall_distro = QtWidgets.QPushButton(self.tab_multibootusb) + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap("uninstall.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.button_uninstall_distro.setIcon(icon) + self.button_uninstall_distro.setIconSize(QtCore.QSize(16, 18)) self.button_uninstall_distro.setObjectName("button_uninstall_distro") self.gridLayout.addWidget(self.button_uninstall_distro, 0, 3, 1, 1) self.button_install_distro = QtWidgets.QPushButton(self.tab_multibootusb) + self.button_install_distro.setMaximumSize(QtCore.QSize(16777215, 16777215)) + icon1 = QtGui.QIcon() + icon1.addPixmap(QtGui.QPixmap("install.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.button_install_distro.setIcon(icon1) + self.button_install_distro.setIconSize(QtCore.QSize(16, 18)) self.button_install_distro.setObjectName("button_install_distro") self.gridLayout.addWidget(self.button_install_distro, 0, 2, 1, 1) self.slider_persistence = QtWidgets.QSlider(self.tab_multibootusb) @@ -229,6 +238,7 @@ class Ui_MainWindow(object): self.tab_syslinux = QtWidgets.QWidget() self.tab_syslinux.setObjectName("tab_syslinux") self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.tab_syslinux) + self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0) self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.gridLayout_2 = QtWidgets.QGridLayout() self.gridLayout_2.setObjectName("gridLayout_2") @@ -277,6 +287,7 @@ class Ui_MainWindow(object): self.tab_testboot = QtWidgets.QWidget() self.tab_testboot.setObjectName("tab_testboot") self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.tab_testboot) + self.verticalLayout_2.setContentsMargins(0, 0, 0, 0) self.verticalLayout_2.setObjectName("verticalLayout_2") self.gridLayout_6 = QtWidgets.QGridLayout() self.gridLayout_6.setContentsMargins(-1, 10, -1, -1) @@ -355,7 +366,7 @@ class Ui_MainWindow(object): self.verticalLayout_7.addWidget(self.progressbar) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) - self.menubar.setGeometry(QtCore.QRect(0, 0, 629, 19)) + self.menubar.setGeometry(QtCore.QRect(0, 0, 629, 21)) self.menubar.setNativeMenuBar(True) self.menubar.setObjectName("menubar") self.menuFile = QtWidgets.QMenu(self.menubar) @@ -376,7 +387,7 @@ class Ui_MainWindow(object): self.menubar.addAction(self.menu_Help.menuAction()) self.retranslateUi(MainWindow) - self.tabWidget.setCurrentIndex(3) + self.tabWidget.setCurrentIndex(0) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): diff --git a/scripts/gui/uninstall.png b/scripts/gui/uninstall.png new file mode 100644 index 0000000000000000000000000000000000000000..ed5737b98413e41ea131a0b8a6d32aecce533e42 GIT binary patch literal 18916 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�BhOe&b4zY^@=7HfleQMvR8d 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 literal 0 HcmV?d00001