def on_execute_button_clicked(self, widget, data=None): # Check if the configuration file has already beeen created if os.path.isfile(selflib.configfile_location) == False : create_configuration() # Check if at least one Linux partition has been configured: if selflib.partition_set == [] : selflib.error_dialog(_("Your configuration is not complete. Please, select at least one Linux booting partition and define its Boot menu label.\n")) self.UndoButton.clicked() else: selflib.warning_dialog(_("You are about to install a new LILO bootloader. Are you sure you want to continue?")) if selflib.response_to_warning[0] == gtk.RESPONSE_YES: # If previous lilosetup.conf file exist, save it as lilosetup.old if os.path.isfile(selflib.chroot_mnt + "/etc/lilosetup.conf") == True : os.rename(selflib.chroot_mnt + "/etc/lilosetup.conf", selflib.chroot_mnt +'/etc/lilosetup.old') shutil.copy(selflib.configfile_location, selflib.chroot_mnt + "/etc/lilosetup.conf") # Copy /boot/salix graphics to selflib.chroot_mnt if needed if os.path.isfile(selflib.chroot_mnt + "/boot/salix.bmp") == False : if os.path.isfile("/boot/salix.bmp") == True : shutil.copy("/boot/salix.bmp", selflib.chroot_mnt + "/boot/salix.bmp") elif os.path.isfile("/mnt/live/memory/images/01-core.lzm/boot/salix.bmp") == True : shutil.copy("/mnt/live/memory/images/01-core.lzm/boot/salix.bmp", selflib.chroot_mnt + "/boot/salix.bmp") # Execute Lilo lilo_command = "lilo -v -r " + selflib.chroot_mnt + " -C /etc/lilosetup.conf > /var/log/lilosetup.log" output = commands.getstatusoutput(lilo_command) if 0 in output : selflib.info_dialog(_("The installation of your new LILO bootloader was succesful. You can now exit LiloSetup and reboot your computer.\n")) self.ExecuteButton.set_sensitive(False) else: selflib.error_dialog(_("The installation of your new LILO bootloader failed. Please verify /var/log/lilosetup.log, modify your settings and try again.\n")) self.ExecuteButton.set_sensitive(False) if selflib.response_to_warning[0] == gtk.RESPONSE_NO: pass
def on_edit_button_clicked(self, widget, data=None): """ Opens the edit lilosetup.conf dialog. """ # Check if the configuration file has already beeen created if os.path.isfile(selflib.configfile_location) == False : create_configuration() try : if os.path.isfile("/usr/bin/mousepad") : subprocess.call('/usr/bin/mousepad ' + selflib.configfile_location + ' 2>/dev/null', shell=True) elif os.path.isfile("/usr/bin/leafpad") : subprocess.call('/usr/bin/leafpad ' + selflib.configfile_location + ' 2>/dev/null', shell=True) elif os.path.isfile("/usr/bin/gedit") : subprocess.call('/usr/bin/gedit ' + selflib.configfile_location + ' 2>/dev/null', shell=True) elif os.path.isfile("/usr/bin/kwrite") : subprocess.call('/usr/bin/kwrite ' + selflib.configfile_location + ' 2>/dev/null', shell=True) elif os.path.isfile("/usr/bin/geany") : subprocess.call('/usr/bin/geany ' + selflib.configfile_location + ' 2>/dev/null', shell=True) else : subprocess.call('xdg-open ' + selflib.configfile_location + ' 2>/dev/null', shell=True) # Ensure changes are taken into account subprocess.call('sync', shell=True) subprocess.call('rm -f ' + selflib.configfile_location + '~ 2>/dev/null', shell=True) self.UpButton.set_sensitive(False) self.DownButton.set_sensitive(False) self.ExecuteButton.set_sensitive(True) self.BootPartitionTreeview.get_selection().unselect_all() self.BootPartitionTreeview.set_sensitive(False) except : self.EditButton.set_sensitive(False) selflib.error_dialog(_("Sorry, LiloSetup is unable to find a suitable text editor in your system. You will not be able to manually modify LiloSetup configuration.\n"))
def on_label_cellrenderercombo_edited(self, widget, row_number, new_text): # Retrieve the selected label row iter bootlabelchoice = self.BootPartitionTreeview.get_selection() self.BootPartitionListStore, iter = bootlabelchoice.get_selected() # We ensure there are no identical labels if any(new_text in item for item in selflib.already_there) : for item in selflib.already_there[:] : # The user could change his mind and leave a label unchanged after starting edition, in which case we shouldn't warn him if (row_number,new_text) in selflib.already_there : break else : selflib.error_dialog(_("You have used the same label for different Operating Systems. Please verify and correct.\n")) # Remove the item from the list if it already set before setting back to default try : selflib.already_there.remove((row_number,new_text)) except ValueError : pass # Reset the default value of the label self.BootPartitionListStore.set_value(iter, 3, _("Set...")) self.BootPartitionListStore.set_value(iter, 4, 'gtk-edit') # Re-enables buttons if there are other valid entries if selflib.already_there != [] : self.UndoButton.set_sensitive(True) self.EditButton.set_sensitive(True) self.ExecuteButton.set_sensitive(True) self.UpButton.set_sensitive(True) self.DownButton.set_sensitive(True) break # We need to ensure that the labels do not contain empty space elif ' ' in new_text : selflib.error_dialog(_("\nAn Operating System label should not contain any space. \n\nPlease verify and correct.\n")) # We ensure that the label is less than 15 characters long elif len(new_text) > 15 : selflib.error_dialog(_("\nAn Operating System label should not hold more than 15 characters. \n\nPlease verify and correct.\n")) else: # Allow for successive editing of the same partition for item in selflib.already_there[:] : if row_number in item : selflib.already_there.remove(item) if new_text != _("Set..."): selflib.already_there.append((row_number,new_text)) # Set the new partition row value on the fourth column (3) self.BootPartitionListStore.set_value(iter, 3, new_text) if new_text != _("Set..."): self.BootPartitionListStore.set_value(iter, 4, 'gtk-yes') else: self.BootPartitionListStore.set_value(iter, 4, 'gtk-edit') # Re-enables buttons if there are other valid entries if selflib.already_there != [] : self.UndoButton.set_sensitive(True) self.EditButton.set_sensitive(True) self.ExecuteButton.set_sensitive(True) self.UpButton.set_sensitive(True) self.DownButton.set_sensitive(True)
def create_configuration(): """ Populate lilosetup.conf & mounts needed partition(s) to lilo's chrooted partition. """ shutil.copy(selflib.stub_location, selflib.configfile_location) # Re-initialize key variables # Temporary mountpoint list del selflib.temp_mount[:] # This is for retrieving all the partition rows values BootPartitionsValues = [] x = 0 while x <= 20 : try : treeiter = self.BootPartitionListStore.get_iter(x) x += 1 BootPartitionsValues.append(self.BootPartitionListStore.get(treeiter, 0, 1, 2, 3)) except ValueError : break for set in BootPartitionsValues: windows_sys_labels = ['Microsoft', 'Windows'] # We skip the partitions that have not been configured by the user if _('Set...') in set[3] : pass # If Windows partition: elif set[2] in windows_sys_labels : # Append to lilosetup.conf stub = open(selflib.configfile_location, "a") stub.write("#\n") stub.write(_("# Windows bootable partition config begins\n")) stub.write("other = " + set[0] + "\n") stub.write("label = " + set[3] + "\n") stub.write(_("# Windows bootable partition config ends\n")) stub.close() else: # Applies to Linux partitions # Let's determines Lilo's chrooted Linux partition directory, only happens one. am_i_first = 'cat ' + selflib.configfile_location + ' | grep -i uuid' already_done = commands.getoutput(am_i_first).splitlines() if already_done == []: # This is the first Linux partition, the one we will chroot in to launch lilo! chroot_dev = set[0] mount_inconf = '' # Defines how the partitions 'appears' mounted from the 'chrooted' partition's viewpoint other_mnt = '' # we need this blank for the first Linux partition # Check if lilo's chroot directory is mounted CHROOT_MNT="mount | grep -v \/mnt\/live | grep " + chroot_dev + " | awk -F' ' '{print $3 }'" selflib.chroot_mnt = commands.getoutput(CHROOT_MNT) # chrooted partition mountpoint if selflib.chroot_mnt == '' : # Either it is not mounted or else it is used as the current root filesystem (/) but linked to /dev/root check_if_root = commands.getoutput("ls -l /dev/root | grep " + chroot_dev.replace("/dev/", "")) if check_if_root in chroot_dev : # The link leads to the 'chrooted' device, it is the current file system. selflib.chroot_mnt = "/" else : # It is not mounted, let's create a temporary mountpoint ourselves selflib.temp_chroot_mnt = selflib.work_dir + chroot_dev.replace('dev', 'mnt') try: os.makedirs(selflib.temp_chroot_mnt) except OSError : pass # Mount the 'chrooted' partition chroot_mnt_command = "mount " + chroot_dev + " " + selflib.temp_chroot_mnt + " 2>/dev/null" subprocess.call(chroot_mnt_command, shell=True) selflib.chroot_mnt = selflib.temp_chroot_mnt if selflib.chroot_mnt != "/" : # This is necessary only if we execute lilo from a 'real' chrooted partition subprocess.call("mount --bind /dev " + selflib.chroot_mnt + "/dev 2>/dev/null", shell=True) selflib.temp_mount.append(selflib.chroot_mnt + "/dev") # allows unmounting temporary mountpoints later subprocess.call("mount -t proc proc " + selflib.chroot_mnt + "/proc 2>/dev/null", shell=True) selflib.temp_mount.append(selflib.chroot_mnt + "/proc") # allows unmounting temporary mountpoints later else : # This applies to all subsequent partitions # How this partition is --or should be-- mounted on a the current partition if selflib.chroot_mnt == "/" : mount_info=commands.getoutput("mount").splitlines() while mount_info: if set[0] in mount_info[0]: other_mnt = mount_info[0].split()[2] mount_info.remove(mount_info[0]) if other_mnt == '': # We need to create a temporary mountpoint ourself & mount it: temp_other_mnt = selflib.work_dir + set[0].replace('dev', 'mnt') try : os.makedirs(temp_other_mnt) selflib.temp_dir.append(temp_other_mnt) except OSError : pass other_mnt = temp_other_mnt # all needed temporary mountpoints on chrooted partitions exist, we can now mount them mnt_command = "mount " + set[0] + " " + other_mnt + " 2>/dev/null" subprocess.call(mnt_command, shell=True) selflib.temp_mount.append(other_mnt) # allows cleanup temporary mountpoints later # Else, how this partition should (and will) be mounted on a 'real' chrooted partition else : other_mnt = '' # reinitialization # We create a fork, chroot in the child process & pipe the mount info to the parent process # If lilosetup is executed from a 32bit environment it can't chroot to a 64bit environment. if os.path.isdir('/lib64') is not True and os.path.isdir(selflib.chroot_mnt + '/lib64') is True: pass else : r, w = os.pipe() # these are file descriptors, not file objects pid = os.fork() if pid: selflib.chroot_mnt # Parent process os.close(w) # use os.close() to close a file descriptor r = os.fdopen(r) # turn r into a file object other_mnt = r.read() os.waitpid(pid, 0) # make sure the child process gets cleaned up else: # Child process os.close(r) w = os.fdopen(w, 'w') os.chroot(selflib.chroot_mnt) # We use fake mounting to avoid dealing with eventual fstab UUID schemes subprocess.call("mount -af 2>/dev/null", shell=True) # Retrieve the mount info mount_info=commands.getoutput("mount").splitlines() while mount_info: if set[0] in mount_info[0]: other_mnt = mount_info[0].split()[2] elif set[0].replace('hd', 'sd') in mount_info[0]: other_mnt = mount_info[0].split()[2] elif set[0].replace('sd', 'hd') in mount_info[0]: other_mnt = mount_info[0].split()[2] mount_info.remove(mount_info[0]) w.write(other_mnt) w.close() # Exit child process sys.exit(0) if other_mnt == '': # we need to create a temporary mountpoint ourselves temp_other_mnt = selflib.work_dir + set[0].replace('dev', 'mnt') try : os.makedirs(selflib.chroot_mnt + temp_other_mnt) selflib.temp_dir.append(selflib.chroot_mnt + temp_other_mnt) except OSError : pass other_mnt = temp_other_mnt # all needed temporary mountpoints on chrooted partitions exist, we can now mount them mnt_command = "mount " + set[0] + " " + selflib.chroot_mnt + other_mnt + " 2>/dev/null" subprocess.call(mnt_command, shell=True) selflib.temp_mount.append(selflib.chroot_mnt +other_mnt) # allows cleanup temporary mountpoints later mount_inconf = other_mnt # defines how the partition 'appears' mounted in lilosetup.conf # Confirm that the partition is configured selflib.partition_set.append("OK") # Append to lilosetup.conf stub = open(selflib.configfile_location, "a") # There maybe a few kernels in the same partition # Some of them may have an initrd, which we assume have exactly the same suffix. if selflib.chroot_mnt != "/": vmlist = sorted(glob.glob(selflib.chroot_mnt + other_mnt + "/boot/vmlinuz*")) initlist = sorted(glob.glob(selflib.chroot_mnt + other_mnt + "/boot/initr*")) if selflib.chroot_mnt == "/": vmlist = sorted(glob.glob(other_mnt + "/boot/vmlinuz*")) initlist = sorted(glob.glob(other_mnt + "/boot/initr*")) # Remove directories for i in vmlist : if os.path.isdir(i) : vmlist.remove(i) for i in initlist : if os.path.isdir(i) : initlist.remove(i) # Remove symbolic links for i in vmlist : if os.path.islink(i) : vmlist.remove(i) for i in initlist : if os.path.islink(i) : initlist.remove(i) # There could be a few kernels in the same partition: it = 0 y = 1 while it < len(vmlist) : stub.write("#\n") stub.write(_("# Linux bootable partition config begins\n")) try : vmlinuz_file_path = vmlist[it].split("boot")[1] stub.write("image = " + mount_inconf + "/boot" + vmlinuz_file_path + "\n") vmlinuz_suffix = vmlinuz_file_path.split('/')[-1].replace("vmlinuz", "") except: selflib.error_dialog(_("One of your partitions does not seem to hold a valid kernel file. Please verify and correct LiloSetup configuration file manually.\n")) # We'll use uuid to avoid libata/non-libata confusion # Find the uuid linked to the partition linked_partition = set[0].split('/')[-1] uuid_line = commands.getoutput('ls -l /dev/disk/by-uuid | grep ' + linked_partition).split('->')[0].split()[-1] if 'Fedora' in set[2]: stub.write('append = "root=UUID=' + uuid_line +' "\n') else: stub.write("root = /dev/disk/by-uuid/" + uuid_line +"\n") if len(vmlist) == 1 : # There is only one kernel so only one entry for this partition stub.write("label = " + set[3] + "\n") else: # There is more than one kernel in the same partition, we need to create multiple entries # We need to ensure that the label is not too long new_label = set[3] + vmlinuz_suffix if len(new_label) >= 14 : corrected_label = set[3] + '-' + str(y) stub.write("label = " + corrected_label +"\n") else: stub.write("label = " + new_label +"\n") # Add the initrd if suffix is matching kernel for i in initlist: if vmlinuz_suffix in i: initrd_file_path = i.split("boot")[1] stub.write("initrd = " + mount_inconf + "/boot" + initrd_file_path + "\n") break # If only one kernel & one initrd, we can assume they match even if their suffix do not. if it == 0 and vmlinuz_suffix not in i: if len(initlist) == 1 and len(vmlist) == 1: initrd_file_path = initlist[0].split("boot")[1] stub.write("initrd = " + mount_inconf + "/boot" + initrd_file_path + "\n") stub.write("read-only\n") stub.write(_("# Linux bootable partition config ends\n")) y += 1 it += 1 stub.close()
os.rename(selflib.chroot_mnt + "/etc/lilosetup.conf", selflib.chroot_mnt +'/etc/lilosetup.old') shutil.copy(selflib.configfile_location, selflib.chroot_mnt + "/etc/lilosetup.conf") # Copy /boot/salix graphics to selflib.chroot_mnt if needed if os.path.isfile(selflib.chroot_mnt + "/boot/salix.bmp") == False : if os.path.isfile("/boot/salix.bmp") == True : shutil.copy("/boot/salix.bmp", selflib.chroot_mnt + "/boot/salix.bmp") elif os.path.isfile("/mnt/live/memory/images/01-core.lzm/boot/salix.bmp") == True : shutil.copy("/mnt/live/memory/images/01-core.lzm/boot/salix.bmp", selflib.chroot_mnt + "/boot/salix.bmp") # Execute Lilo lilo_command = "lilo -v -r " + selflib.chroot_mnt + " -C /etc/lilosetup.conf > /var/log/lilosetup.log" output = commands.getstatusoutput(lilo_command) if 0 in output : selflib.info_dialog(_("The installation of your new LILO bootloader was succesful. You can now exit LiloSetup and reboot your computer.\n")) self.ExecuteButton.set_sensitive(False) else: selflib.error_dialog(_("The installation of your new LILO bootloader failed. Please verify /var/log/lilosetup.log, modify your settings and try again.\n")) self.ExecuteButton.set_sensitive(False) if selflib.response_to_warning[0] == gtk.RESPONSE_NO: pass if __name__ == '__main__': # If no root privilege, displays the version, an error message and then exit if os.getuid() != 0: selflib.error_dialog(_("<b>Sorry!</b>\n\nRoot privileges are required to run this program.")) print application_name + ', version ' + application_version sys.exit(1) # Otherwise, displays the version and the GUI, and then wait for signal print application_name + ', version ' + application_version LiloSetup() gtk.main()