def _map_device_to_grub_device(self, device): file_name = self._chroot_dir + "/boot/grub/glidevice.map" #If we can't find it, make it. If we STILL can't find it. die. if not GLIUtility.is_file(file_name): exitstatus1 = GLIUtility.spawn( "echo quit | " + self._chroot_dir + "/sbin/grub --batch --no-floppy --device-map=" + file_name, logfile=self._compile_logfile, append_log=True) if not GLIUtility.is_file(file_name): raise GLIException("BootloaderError", 'fatal', '_configure_grub', "Error making the new device map.") """ read the device map. sample looks like this: (fd0) /dev/floppy/0 (hd0) /dev/sda (hd1) /dev/hda (hd2) /dev/hdb """ # Search for the key f = open(file_name) #open the device map file = f.readlines() f.close() for i in range(len(file)): if file[i][6:-1] == device: return file[i][1:4] raise GLIException( "BootloaderError", 'fatal', '_map_device_to_grub_device', "ERROR, could not map" + device + " to anything in the device map")
def _partition_format_step(self, parted_disk, device, newparts): for part in newparts: newpart = newparts[part] devnode = newpart['devnode'] # This little hack is necessary because parted sucks goat nuts if newparts.get_disklabel() == "mac" and newpart['type'] == "free": self._delete_partition(parted_disk, newpart) continue if newpart['format'] and newpart['type'] not in ('extended', 'free'): # devnode = device + str(int(part)) if self._debug: self._logger.log("_partition_format_step(): devnode is %s in formatting code" % devnode) # if you need a special command and # some base options, place it here. format_cmds = { 'linux-swap': "mkswap", 'fat16': "mkfs.vfat -F 16", 'fat32': "mkfs.vfat -F 32", 'ntfs': "mkntfs", 'xfs': "mkfs.xfs -f", 'jfs': "mkfs.jfs -f", 'reiserfs': "mkfs.reiserfs -f", 'ext2': "mkfs.ext2", 'ext3': "mkfs.ext3" } if newpart['type'] in format_cmds: cmdname = format_cmds[newpart['type']] else: # this should catch everything else raise GLIException("PartitionFormatError", 'fatal', '_partition_format_step', "Unknown partition type " + newpart['type']) # sleep a bit first time.sleep(1) for tries in range(10): cmd = "%s %s %s" % (cmdname, newpart['mkfsopts'], devnode) self._logger.log(" Formatting partition %s as %s with: %s" % (str(part),newpart['type'],cmd)) ret = GLIUtility.spawn(cmd, logfile=self._compile_logfile, append_log=True) if not GLIUtility.exitsuccess(ret): self._logger.log("Try %d failed formatting partition %s...waiting 5 seconds" % (tries+1, devnode)) time.sleep(5) else: break else: raise GLIException("PartitionFormatError", 'fatal', '_partition_format_step', "Could not create %s filesystem on %s" % (newpart['type'], devnode))
def _configure_lilo(self): self.build_mode = self._install_profile.get_kernel_build_method() self._gather_lilo_drive_info() root = self._chroot_dir file_name3 = root + "/boot/kernel_name" root = self._chroot_dir exitstatus0 = GLIUtility.spawn("ls "+root+"/boot/kernel-* > "+file_name3) if (exitstatus0 != 0): raise GLIException("BootloaderError", 'fatal', '_configure_lilo', "Could not list kernels in /boot or no kernels found.") if self.build_mode == "genkernel" or self._install_profile.get_kernel_source_pkg() == "livecd-kernel": exitstatus1 = GLIUtility.spawn("ls "+root+"/boot/init* >> "+file_name3) if (exitstatus1 != 0): raise GLIException("BootloaderError", 'fatal', '_configure_lilo', "Could not list initrds in /boot") g = open(file_name3) kernel_name = g.readlines() g.close() if not kernel_name[0]: raise GLIException("BootloaderError", 'fatal', '_configure_lilo',"Error: We have no kernel in /boot to put in the grub.conf file!") kernel_name = map(string.strip, kernel_name) kernel_name[0] = kernel_name[0].split(root)[1] kernel_name[1] = kernel_name[1].split(root)[1] if self._install_profile.get_bootloader_kernel_args(): bootloader_kernel_args = self._install_profile.get_bootloader_kernel_args() else: bootloader_kernel_args = "" #------------------------------------------------------------- #time to build the lilo.conf newliloconf = "" if self._install_profile.get_boot_loader_mbr(): newliloconf += "boot="+self.mbr_device+" # Install LILO in the MBR \n" else: newliloconf += "boot="+self.boot_device+self.boot_minor+" # Install LILO in the MBR \n" newliloconf += "prompt # Give the user the chance to select another section\n" newliloconf += "timeout=50 # Wait 5 (five) seconds before booting the default section\n" newliloconf += "default=gentoo # When the timeout has passed, boot the \"gentoo\" section\n" newliloconf += "# Only if you use framebuffer. Otherwise remove the following line:\n" if not self._install_profile.get_kernel_bootsplash(): newliloconf += "#" newliloconf += "vga=788 # Framebuffer setting. Adjust to your own will\n" newliloconf += "image=/boot"+kernel_name[0][5:]+" \n" newliloconf += " label=gentoo \n read-only \n" if self.build_mode != "genkernel" and self._install_profile.get_kernel_source_pkg() != "livecd-kernel": newliloconf += " root="+self.root_device+self.root_minor+" \n" if bootloader_kernel_args: newliloconf += " append=\""+bootloader_kernel_args+"\" \n" else: newliloconf += " root=/dev/ram0 \n" newliloconf += " append=\"init=/linuxrc ramdisk=8192 real_root="+self.root_device+self.root_minor + " " + bootloader_kernel_args + "\" \n" newliloconf += " initrd=/boot"+kernel_name[1][5:] + "\n\n" newliloconf = self._lilo_add_windows(newliloconf) #now make the lilo.conf file file_name = root + "/etc/lilo.conf" try: shutil.move(file_name, file_name + ".OLDdefault") except: pass f = open(file_name, 'w') f.writelines(newliloconf) f.close() self._logger.log("Lilo installed and configured. Not run yet.")
def _partition_resize_step(self, parted_disk, device, oldparts, newparts): for oldpart in oldparts: tmppart_old = oldparts[oldpart] devnode = tmppart_old['devnode'] newminor = self._find_existing_in_new(oldpart, newparts) if not newminor or not newparts[newminor]['resized']: continue tmppart_new = newparts[newminor] type = tmppart_new['type'] start = tmppart_new['start'] end = start + (long(tmppart['mb']) * MEGABYTE / 512) - 1 total_sectors = end - start + 1 total_bytes = long(total_sectors) * 512 # Make sure calculated end sector doesn't overlap start sector of next partition nextminor = self._find_next_partition(newminor, newparts) if nextminor: if newparts[nextminor]['start'] and end >= newparts[nextminor]['start']: self._logger.log(" End sector for growing partition overlaps with start of next partition...fixing") end = newparts[nextminor]['start'] - 1 # sleep a bit first time.sleep(3) # now sleep until it exists while not GLIUtility.is_file(device + str(minor)): self._logger.log("Waiting for device node " + devnode + " to exist before resizing") time.sleep(1) # one bit of extra sleep is needed, as there is a blip still time.sleep(3) if type in ("ext2", "ext3"): ret = GLIUtility.spawn("resize2fs " + devnode + " " + str(total_sectors) + "s", logfile=self._compile_logfile, append_log=True) if not GLIUtility.exitsuccess(ret): # Resize error raise GLIException("PartitionResizeError", 'fatal', 'partition', "could not resize ext2/3 filesystem on " + devnode) elif type == "ntfs": ret = GLIUtility.spawn("yes | ntfsresize -v --size " + str(total_bytes) + " " + devnode, logfile=self._compile_logfile, append_log=True) if not GLIUtility.exitsuccess(ret): # Resize error raise GLIException("PartitionResizeError", 'fatal', 'partition', "could not resize NTFS filesystem on " + devnode) elif type in ("linux-swap", "fat32", "fat16"): parted_fs = parted_disk.get_partition(part).geom.file_system_open() resize_constraint = parted_fs.get_resize_constraint() if total_sectors < resize_constraint.min_size or start != resize_constraint.start_range.start: raise GLIException("PartitionError", 'fatal', 'partition', "New size specified for " + device + str(minor) + " is not within allowed boundaries (blame parted)") new_geom = resize_constraint.start_range.duplicate() new_geom.set_start(start) new_geom.set_end(end) try: parted_fs.resize(new_geom) except: raise GLIException("PartitionResizeError", 'fatal', 'partition', "could not resize " + device + str(minor)) self._logger.log(" Deleting old minor " + str(oldpart) + " to be recreated in 3rd pass") self._delete_partition(parted_disk, oldpart) parted_disk.delete_all() parted_disk.commit()
def set_ip(dev, ip, broadcast, netmask): if not is_ip(ip) or not is_ip(netmask) or not is_ip(broadcast): raise GLIException("GLIUtilityError", 'fatal','set_ip', ip + ", " + netmask + "and, " + broadcast + "must be a valid IP's!") if not is_eth_device(dev): raise GLIException("GLIUtilityError", 'fatal','set_ip', dev + "is not a valid ethernet device!") options = "%s inet %s broadcast %s netmask %s" % (dev, ip, broadcast, netmask) status = spawn("ifconfig " + options) if not exitsuccess(status): return False return True
def _setup_lilo(self): #------------------------------------------------------------- #OK, now that the file is built. Install lilo. exitstatus = GLIUtility.spawn("/sbin/lilo",chroot=self._chroot_dir, logfile=self._compile_logfile, append_log=True) if exitstatus != 0: raise GLIException("LiloInstallError", 'fatal', '_setup_lilo', "Running lilo failed!") self._logger.log("Bootloader: lilo has been run/installed!")
def install_bootloader(self): "Installs and configures bootloader" # # THIS IS ARCHITECTURE DEPENDANT!!! # This is the x86 way.. it uses grub bootloader_pkg = self._install_profile.get_boot_loader_pkg() # first install bootloader if bootloader_pkg and bootloader_pkg.lower() != "none": exitstatus = self._portage.emerge(bootloader_pkg) # if not GLIUtility.exitsuccess(exitstatus): # raise GLIException("BootLoaderEmergeError", 'fatal', 'install_bootloader', "Could not emerge bootloader!") # else: self._logger.log("Emerged the selected bootloader.") # now configure said bootloader # null boot-loader first if bootloader_pkg.lower() == "none": return elif "grub" in bootloader_pkg: # this catches 'grub-static' as well as '=sys-boot/grub-0.95*' self._configure_grub() elif "lilo" in bootloader_pkg: self._configure_lilo() # probably should add in some more bootloaders # dvhtool, raincoat, netboot, gnu-efi, cromwell, syslinux, psoload else: raise GLIException( "BootLoaderError", 'fatal', 'install_bootloader', "Don't know how to configure this bootloader: " + bootloader_pkg)
def strtobool(input): if type(input) != str: raise GLIException("GLIUtilityError", 'fatal','strtobool',"The input must be a string!") if string.lower(input) == 'true': return True else: return False
def set_default_route(route): if not is_ip(route): raise GLIException("GLIUtilityError", 'fatal', 'set_default_route', route + " is not an ip address!") status = spawn("route add default gw " + route) if not exitsuccess(status): return False return True
def set_network_netmask(self, xml_path, netmask, xml_attr=None): if not GLIUtility.is_ip(netmask): raise GLIException( "IPAddressError", 'fatal', 'set_network_netmask', 'The specified netmask is not a valid IP Address!') else: # Need to guess the netmask... just in case (probably need the gateway..) pass self._network_netmask = netmask
def set_architecture_template(self, xml_path, architecture_template, xml_attr): if not architecture_template in [ "x86", "amd64", "ppc", "sparc", "hppa", "alpha" ]: raise GLIException( "UnsupportedArchitectureTemplateError", 'fatal', 'set_architecture_template', 'Architecture Template specified is not supported!') self._architecture_template = architecture_template
def setup_and_run_bootloader(self): bootloader_pkg = self._install_profile.get_boot_loader_pkg() if bootloader_pkg.lower() == "none": return elif "grub" in bootloader_pkg: # this catches 'grub-static' as well as '=sys-boot/grub-0.95*' self._setup_grub() elif "lilo" in bootloader_pkg: self._setup_lilo() # probably should add in some more bootloaders # dvhtool, raincoat, netboot, gnu-efi, cromwell, syslinux, psoload else: raise GLIException("BootLoaderError",'fatal','setup_and_run_bootloader',"Don't know how to configure this bootloader: "+bootloader_pkg)
def _gather_grub_drive_info(self): self.boot_minor = "" self.boot_device = "" self.root_device = "" self.root_minor = "" self.mbr_device = "" self.grub_root_minor = "" self.grub_boot_minor = "" self.grub_boot_drive = "" self.grub_root_drive = "" self.grub_mbr_drive = "" minornum = 0 #Assign root to the root mount point to make lines more readable root = self._chroot_dir self.foundboot = False parts = self._install_profile.get_partition_tables() for device in parts: tmp_partitions = parts[device] #.get_install_profile_structure() for partition in tmp_partitions: mountpoint = tmp_partitions[partition]['mountpoint'] if (mountpoint == "/boot"): self.foundboot = True if (((mountpoint == "/") and (not self.foundboot)) or (mountpoint == "/boot")): self.boot_minor = str( int(tmp_partitions[partition]['minor'])) self.grub_boot_minor = str( int(tmp_partitions[partition]['minor']) - 1) self.boot_device = device self.mbr_device = device if mountpoint == "/": self.root_minor = str( int(tmp_partitions[partition]['minor'])) self.grub_root_minor = str( int(tmp_partitions[partition]['minor']) - 1) self.root_device = device #RESET the boot device if one is stored already if self._install_profile.get_boot_device(): self.mbr_device = self._install_profile.get_boot_device() self._logger.log("Found a mbr device: " + self.mbr_device) self.grub_boot_drive = self._map_device_to_grub_device( self.boot_device) self.grub_root_drive = self._map_device_to_grub_device( self.root_device) self.grub_mbr_drive = self._map_device_to_grub_device(self.mbr_device) if (not self.grub_root_drive) or (not self.grub_boot_drive): raise GLIException( "BootloaderError", 'fatal', '_gather_grub_drive_info', "Couldn't find the drive num in the list from the device.map")
def get_eth_info(device): """Pass in the eth device's number (0, 1, 2, etc). Returns network information in a tuple. Order is hw_addr, ip_addr, mask, bcast, route, and whether it's up (True or False). """ hw_addr = 'None' ip_addr = 'None' mask = 'None' bcast = 'None' gw = 'None' up = False if len(str(device)) == 1: device = "eth" + str(device) if not is_eth_device(device): raise GLIException("GLIUtilityError", 'fatal', "get_eth_info", device + " is not a valid ethernet device!") status, device_info = spawn("/sbin/ifconfig " + device, return_output=True) if exitsuccess(status): for line in device_info.splitlines(): line = line.strip() if 'HWaddr' in line: hw_addr = line.split('HWaddr',1)[1].strip() if 'inet addr' in line: ip_addr = line.split(' ')[0].split(':')[1] if 'Bcast' in line: bcast = line.split(' ')[1].split(':')[1] if 'Mask' in line: mask = line.split(' ')[2].split(':')[1] if line.startswith('UP'): up = True else: raise GLIException("GLIUtilityError", 'fatal', "get_eth_info", device_info) gw = spawn(r"/sbin/route -n | grep -e '^0\.0\.0\.0' | sed -e 's:^0\.0\.0\.0 \+::' -e 's: \+.\+$::'", return_output=True)[1].strip() return (hw_addr, ip_addr, mask, bcast, gw, up)
def fetch_and_unpack_tarball(tarball_uri, target_directory, temp_directory="/tmp", keep_permissions=False, cc=None): "Fetches a tarball from tarball_uri and extracts it into target_directory" # Get tarball info tarball_filename = tarball_uri.split("/")[-1] # Get the tarball if not get_uri(tarball_uri, temp_directory + "/" + tarball_filename, cc): raise GLIException("GLIUtilityError", 'fatal', 'fetch_and_unpack_tarball',"Could not fetch " + tarball_uri) # Reset tar options tar_options = "xv" # If the tarball is bzip'd if tarball_filename.split(".")[-1] == "tbz" or tarball_filename.split(".")[-1] == "bz2": format_option = "j" # If the tarball is gzip'd elif tarball_filename.split(".")[-1] == "tgz" or tarball_filename.split(".")[-1] == "gz": format_option = "z" tar_options += format_option # If we want to keep permissions if keep_permissions: tar_options = tar_options + "p" # Get number of files in tarball tarfiles = 0 if cc: cc.addNotification("progress", (0, "Determining the number of files in " + tarball_filename)) tarfiles = int(spawn("tar -t" + format_option + "f " + temp_directory + "/" + tarball_filename + " 2>/dev/null | wc -l", return_output=True)[1].strip()) # Unpack the tarball exitstatus = spawn("tar -" + tar_options + " -f " + temp_directory + "/" + tarball_filename + " -C " + target_directory, display_on_tty8=True, logfile="/tmp/compile_output.log", append_log=True, linecount=tarfiles, cc=cc, status_message="Unpacking " + tarball_filename) # change this to the logfile variable if not exitsuccess(exitstatus): raise GLIException("GLIUtilityError", 'fatal', 'fetch_and_unpack_tarball',"Could not unpack " + tarball_uri + " to " + target_directory)
def install_bootloader(self): "Installs and configures bootloader" # # THIS IS ARCHITECTURE DEPENDANT!!! # This is the ppc way.. it uses yaboot for new world. if self._install_profile.get_boot_loader_pkg() or self._install_profile.get_boot_loader_pkg() == "none": exitstatus = self._emerge(self._install_profile.get_boot_loader_pkg()) if exitstatus != 0: raise GLIException("BootLoaderEmergeError", 'fatal', 'install_bootloader', "Could not emerge bootloader!") else: pass if self._install_profile.get_boot_loader_pkg() == "yaboot": self._configure_yaboot() else: raise Exception("BootLoaderError",'fatal','install_bootloader',"Invalid bootloader selected:"+self._install_profile.get_boot_loader_pkg())
def _setup_grub(self): #------------------------------------------------------------- #OK, now that the file is built. Install grub. #cp /proc/mounts /etc/mtab #grub-install --root-directory=/boot /dev/hda #shutil.copy("/proc/mounts",root +"/etc/mtab") self._gather_grub_drive_info() grubinstallstring = "echo -en 'root ("+self.grub_boot_drive + "," + self.grub_boot_minor + ")\n" if not self._install_profile.get_boot_loader_mbr(): grubinstallstring +="setup ("+self.grub_boot_drive + "," + self.grub_boot_minor + ")\n" else: grubinstallstring +="setup ("+self.grub_mbr_drive+")\n" grubinstallstring += "quit\n' | "+self._chroot_dir+"/sbin/grub --batch --no-floppy" if self._debug: self._logger.log("DEBUG: _configure_grub(): Grub install string: " + grubinstallstring) exitstatus = GLIUtility.spawn(grubinstallstring, logfile=self._compile_logfile, append_log=True) if not GLIUtility.exitsuccess(exitstatus): raise GLIException("GrubInstallError", 'fatal', '_setup_grub', "Could not install grub!") self._logger.log("Bootloader: grub has been installed!")
def load_install_profile(self): install_profile = None if self._install_profile == None: if self._configuration != None: success = GLIUtility.get_uri( self._configuration.get_profile_uri(), '/tmp/install_profile.xml') if success: self._logger.log( "Profile downloaded succesfully, loading it now.") self.output("Profile downloaded... loading it now...") install_profile = GLIInstallProfile.InstallProfile() install_profile.parse('/tmp/install_profile.xml') else: raise GLIException( "InstallProfileError", 'fatal', 'get_install_profile', 'Could not download/copy the install profile from: ' + self._configuration.get_profile_uri()) self._install_profile = install_profile
def detect_devices(): devices = [] # Make sure sysfs exists # TODO: rewrite for 2.4 support if not os.path.exists("/sys/bus"): raise GLIException("GLIStorageDeviceError", 'fatal', 'detect_devices', "no sysfs found (you MUST use a kernel >2.6)") # Make sure /proc/partitions exists if not os.path.exists("/proc/partitions"): raise GLIException( "GLIStorageDeviceError", 'fatal', 'detect_devices', "/proc/partitions does not exist! Please make sure procfs is in your kernel and mounted!" ) # Load /proc/partitions into the variable 'partitions' partitions = [] for line in open("/proc/partitions"): tmpparts = line.split() if len(tmpparts) < 4 or not tmpparts[0].isdigit( ) or not tmpparts[1].isdigit(): continue # Get the major, minor and device name major = int(tmpparts[0]) minor = int(tmpparts[1]) device = "/dev/" + tmpparts[3] # If there is no /dev/'device_name', then scan # all the devices in /dev to try and find a # devices with the same major and minor if not os.path.exists(device): device = None for path, dirs, files in os.walk("/dev"): for d_file in files: full_file = os.path.join(path, d_file) if not os.path.exists(full_file): continue statres = os.stat(full_file) fmaj = os.major(statres.st_rdev) fmin = os.minor(statres.st_rdev) if fmaj == major and fmin == minor: device = full_file break if not device: continue partitions.append((major, minor, device)) # Scan sysfs for the devices of type 'x' # 'x' being a member of the list below: # Compaq cards.../sys/block/{cciss,ida}!cXdX/dev for dev_glob in ("/sys/bus/ide/devices/*/block*/dev", "/sys/bus/scsi/devices/*/block*/dev", "/sys/block/cciss*/dev", "/sys/block/ida*/dev"): sysfs_devices = glob(dev_glob) if not sysfs_devices: continue for sysfs_device in sysfs_devices: # Get the major and minor info try: major, minor = open(sysfs_device).read().split(":") major = int(major) minor = int(minor) except: raise GLIException("GLIStorageDeviceError", 'fatal', 'detect_devices', "invalid major/minor in " + sysfs_device) # Find a device listed in /proc/partitions # that has the same minor and major as our # current block device. for record in partitions: if major == record[0] and minor == record[1]: devices.append(record[2]) # For testing the partitioning code if GLIUtility.is_file("/tmp/disk.img"): devices.append("/tmp/disk.img") # We have assembled the list of devices, so return it return devices
def set_network_ip(self, xml_path, ip, xml_attr=None): if not GLIUtility.is_ip(ip): raise GLIException( "IPAddressError", 'fatal', 'set_network_ip', 'The specified IP ' + ip + ' is not a valid IP Address!') self._network_ip = ip
def set_network_interface(self, xml_path, interface, xml_attr=None): if not GLIUtility.is_eth_device(interface): raise GLIException( "InterfaceError", 'fatal', 'set_network_interface', "Interface " + interface + " must be a valid device!") self._network_interface = interface
def set_network_gateway(self, xml_path, gateway, xml_attr=None): if not GLIUtility.is_ip(gateway): raise GLIException( "IPAddressError", 'fatal', 'set_network_gateway', "The gateway IP provided is not a valid gateway!!") self._network_gateway = gateway
def set_network_dhcp_options(self, xml_path, options, xml_attr=None): if not GLIUtility.is_realstring(options): raise GLIException( "BadDHCPOptionsError", 'fatal', 'set_network_dhcp_options', 'The specified dhcp_optioons is not a valid string!') self._network_dhcp_options = options
def set_network_broadcast(self, xml_path, broadcast, xml_attr=None): if not GLIUtility.is_ip(broadcast): raise GLIException( "IPAddressError", 'fatal', 'set_network_broadcast', 'The specified broadcast is not a valid IP Address!') self._network_broadcast = broadcast
def configure_networking(self): if self._configuration.get_verbose(): self._logger.log("DEBUG: beginning of configure_networking()") # Do networking setup right here. if self._configuration.get_network_type() != None: type = self._configuration.get_network_type() if type == "null" or type == "none": # don't do anything, it's not our problem if the user specifies this. return elif type == "dhcp": if self._configuration.get_verbose(): self._logger.log( "DEBUG: configure_networking(): DHCP selected") # Run dhcpcd. try: interface = self._configuration.get_network_interface() dhcp_options = self._configuration.get_network_dhcp_options( ) except: self._logger.log( "No interface found.. defaulting to eth0.") interface = "eth0" dhcp_options = "" if interface and not dhcp_options: if self._configuration.get_verbose(): self._logger.log( "DEBUG: configure_networking(): running '/sbin/dhcpcd -n " + interface + "'") status = GLIUtility.spawn("/sbin/dhcpcd -t 15 -n " + interface) elif interface and dhcp_options: if self._configuration.get_verbose(): self._logger.log( "DEBUG: configure_networking(): running '/sbin/dhcpcd " + dhcp_options + " " + interface + "'") status = GLIUtility.spawn("/sbin/dhcpcd -t 15 " + dhcp_options + " " + interface) else: if self._configuration.get_verbose(): self._logger.log( "DEBUG: configure_networking(): running '/sbin/dhcpcd -n'" ) status = GLIUtility.spawn("/sbin/dhcpcd -t 15 -n") if self._configuration.get_verbose(): self._logger.log( "DEBUG: configure_networking(): call to /sbin/dhcpcd complete" ) if not GLIUtility.exitsuccess(status): raise GLIException( "DHCPError", 'fatal', 'configure_networking', "Failed to get a dhcp address for " + interface + ".") elif type == "manual" and self._configuration.get_interactive(): # Drop to bash shell and let them configure it themselves print "Please configure & test your network device." GLIUtility.spawn_bash() elif type == "manual" and not self._interactive.get_interactive(): print "You cannot manually configure the network in non-interactive mode!" print "Please fix either the network settings or the interactive mode!" sys.exit(1) elif type == "static": if self._configuration.get_verbose(): self._logger.log( "DEBUG: configure_networking(): setting static IP") # Configure the network from the settings they gave. net_interface = self._configuration.get_network_interface() net_ip = self._configuration.get_network_ip() net_broadcast = self._configuration.get_network_broadcast() net_netmask = self._configuration.get_network_netmask() if not GLIUtility.set_ip(net_interface, net_ip, net_broadcast, net_netmask): raise GLIException("SetIPError", 'fatal', 'configure_networking', "Could not set the IP address!") route = self._configuration.get_network_gateway() if not GLIUtility.set_default_route(route): raise GLIException("DefaultRouteError", 'fatal', 'configure_networking', "Could not set the default route!") dns_servers = self._configuration.get_dns_servers() if dns_servers: try: resolv_conf = open("/etc/resolv.conf", "w") for dns_server in dns_servers: resolv_conf.write("nameserver " + dns_server + "\n") resolv_conf.close() except: raise GLIException("DNSServerError", 'fatal', 'configure_networking', "Could not set the DNS servers!") if self._configuration.get_verbose(): self._logger.log( "DEBUG: configure_networking(): done setting static IP" )
def do_recommended(self): free_minor = 0 recommended_parts = [{ 'type': "ext2", 'size': 100, 'mountpoint': "/boot" }, { 'type': "linux-swap", 'size': 512, 'mountpoint': "" }, { 'type': "ext3", 'size': "*", 'mountpoint': "/" }] to_create = [] physical_memory = int( GLIUtility.spawn( r"free -m | egrep '^Mem:' | sed -e 's/^Mem: \+//' -e 's/ \+.\+$//'", return_output=True)[1].strip()) # parts = self.get_ordered_partition_list() # Search for concurrent unallocated space >=4GB for part in self._partitions: if part.get_type() == "free" and part.get_mb() >= 4096: free_minor = part.get_minor() break if not free_minor: raise GLIException( "RecommendedPartitionLayoutError", "notice", "do_recommended", "You do not have atleast 4GB of concurrent unallocated space. Please remove some partitions and try again." ) remaining_free = self.get_partition(free_minor).get_mb() for newpart in recommended_parts: # extended/logical partitions suck like a hoover if self._labelinfo['extended'] and free_minor == ( 3 + FREE_MINOR_FRAC_PRI ) and not newpart == recommended_parts[-1]: if self.get_extended_partition(): raise GLIException( "RecommendedPartitionLayoutError", "notice", "do_recommended", "This code is not yet robust enough to handle automatic partitioning with your current layout." ) to_create.append({ 'type': "extended", 'size': remaining_free, 'mountpoint': "", 'free_minor': free_minor }) free_minor = 4 + FREE_MINOR_FRAC_LOG newpart['free_minor'] = free_minor # Small hack to calculate optimal swap partition size if newpart[ 'type'] == "linux-swap" and physical_memory and physical_memory < 1024: newpart['size'] = physical_memory * 2 to_create.append(newpart) free_minor = free_minor + 1 if not newpart['size'] == "*": remaining_free = remaining_free - newpart['size'] for newpart in to_create: if newpart['size'] == "*": # This doesn't seem quite right...it should probably be set to remaining_free # newpart['size'] = self.get_partition(newpart['free_minor']).get_mb() newpart['size'] = remaining_free self.add_partition(newpart['free_minor'], newpart['size'], 0, 0, newpart['type'], mountpoint=newpart['mountpoint'])
def set_network_type(self, xml_path, network_type, xml_attr): if not network_type in ('static', 'dhcp', 'null', 'none'): raise GLIException("NoSuchTypeError", 'fatal', 'set_network_type', "You can only have a static or dhcp network!") self._network_type = network_type
def _configure_grub(self): self.build_mode = self._install_profile.get_kernel_build_method() self._gather_grub_drive_info() root = self._chroot_dir exitstatus2, kernel_names = GLIUtility.spawn("ls -1 --color=no " + root + "/boot/pentoo", return_output=True) self._logger.log("Output of Kernel Names:\n" + kernel_names) if not GLIUtility.exitsuccess(exitstatus2): raise GLIException("BootloaderError", 'fatal', '_configure_grub', "Error listing the kernels in /boot") if self.build_mode == "genkernel" or self._install_profile.get_kernel_source_pkg( ) == "livecd-kernel": exitstatus3, initrd_names = GLIUtility.spawn( "ls -1 --color=no " + root + "/boot/pentoo.igz", return_output=True) self._logger.log("Output of Initrd Names:\n" + initrd_names) if not GLIUtility.exitsuccess(exitstatus3): raise GLIException("BootloaderError", 'fatal', '_configure_grub', "Error listing the initrds") self._logger.log( "Bootloader: the three information gathering commands have been run" ) if not kernel_names[0]: raise GLIException( "BootloaderError", 'fatal', '_configure_grub', "Error: We have no kernel in /boot to put in the grub.conf file!" ) #------------------------------------------------------------- #OK, now that we have all the info, let's build that grub.conf newgrubconf = "" newgrubconf += "default 0\ntimeout 30\n" if self.foundboot: #we have a /boot newgrubconf += "splashimage=(" + self.grub_boot_drive + "," + self.grub_boot_minor + ")/grub/splash.xpm.gz\n" else: #we have / and /boot needs to be included newgrubconf += "splashimage=(" + self.grub_boot_drive + "," + self.grub_boot_minor + ")/boot/grub/splash.xpm.gz\n" if self._install_profile.get_bootloader_kernel_args(): bootloader_kernel_args = self._install_profile.get_bootloader_kernel_args( ) else: bootloader_kernel_args = "" kernel_names = map(string.strip, kernel_names.strip().split("\n")) initrd_names = map(string.strip, initrd_names.strip().split("\n")) grub_kernel_name = kernel_names[-1].split(root)[-1] if initrd_names: grub_initrd_name = initrd_names[-1].split(root)[-1] # for i in range(len(kernel_names)): # grub_kernel_name = kernel_names[i].split(root)[-1] # for i in range(len(initrd_names)): #this should be okay if blank. # grub_initrd_name = initrd_names[i].split(root)[-1] #i think this means take the last one it finds.. i.e. the newest. newgrubconf += "title=Gentoo Linux\n" newgrubconf += "root (" + self.grub_boot_drive + "," + self.grub_boot_minor + ")\n" if self.build_mode != "genkernel" and self._install_profile.get_kernel_source_pkg( ) != "livecd-kernel": #using CUSTOM kernel if self.foundboot: newgrubconf += "kernel " + grub_kernel_name[ 5:] + " root=" + self.root_device + self.root_minor + "\n" else: newgrubconf += "kernel /boot" + grub_kernel_name[ 5:] + " root=" + self.root_device + self.root_minor + "\n" else: #using genkernel so it has an initrd. if self.foundboot: newgrubconf += "kernel " + grub_kernel_name[ 5:] + " root=/dev/ram0 init=/linuxrc ramdisk=8192 real_root=" newgrubconf += self.root_device + self.root_minor + " " + bootloader_kernel_args + "\n" newgrubconf += "initrd " + grub_initrd_name[5:] + "\n" else: newgrubconf += "kernel /boot" + grub_kernel_name[ 5:] + " root=/dev/ram0 init=/linuxrc ramdisk=8192 real_root=" newgrubconf += self.root_device + self.root_minor + " " + bootloader_kernel_args + "\n" newgrubconf += "initrd /boot" + grub_initrd_name[5:] + "\n" newgrubconf = self._grub_add_windows(newgrubconf) #now make the grub.conf file file_name = root + "/boot/grub/grub.conf" try: shutil.move(file_name, file_name + ".OLDdefault") except: pass f = open(file_name, 'w') f.writelines(newgrubconf) f.close() self._logger.log( "Grub installed and configured. Contents of grub.conf:\n" + newgrubconf) self._logger.log( "Grub has not yet been run. If a normal install, it will now be run." )
def set_profile_uri(self, xml_path, profile_uri, xml_attr): if profile_uri != None and not GLIUtility.is_uri(profile_uri): raise GLIException("URIError", 'fatal', 'set_profile_uri', "The URI specified is not valid!") self._profile_uri = profile_uri
def partition(self): """ TODO: before step 3, wipe drive and use the default disklabel for arch skip fixed partitions in all passes (in GLISD maybe?) """ parts_old = {} parts_new = self._install_profile.get_partition_tables() for device in GLIStorageDevice.detect_devices(): parts_old[device] = GLIStorageDevice.Device( device, arch=self._client_configuration.get_architecture_template()) parts_old[device].set_partitions_from_disk() self.notify_frontend("progress", (0, "Examining partitioning data")) total_steps = float(len(parts_new) * 4) # 4 for the number of passes over each device cur_progress = 0 for device in parts_new: # Skip this device in parts_new if device isn't detected on current system if not device in parts_old: self._logger.log( "There is no physical device " + device + " detected to match the entry in the install profile...skipping" ) continue # This just makes things simpler in the code newparts = parts_new[device] oldparts = parts_old[device] # Check to see if the old and new partition table structures are the same...skip if they are if not self._check_table_changed(oldparts, newparts): self._logger.log("Partition table for " + device + " is unchanged...skipping") continue self._logger.log("partition(): Processing " + device + "...") # Commit ritual sepuku if there are any mounted filesystems on this device if GLIUtility.spawn("mount | grep '^" + device + "'", return_output=True)[1].strip(): raise GLIException( "PartitionsMountedError", 'fatal', 'partition', "Cannot partition " + device + " due to filesystems being mounted") # We also can't handle "unknown" partitions for part in newparts: if newparts[part]['type'] == "unknown": raise GLIException( "UnknownPartitionTypeError", 'fatal', 'partition', "Refusing to partition this drive due to the presence of an unknown type of partition" ) # Create pyparted objects for this device parted_dev = parted.PedDevice.get(device) try: parted_disk = parted.PedDisk.new(parted_dev) except: if self._debug: self._logger.log( "partition(): could not load existing disklabel...creating new one" ) parted_disk = parted_dev.disk_new_fresh( parted.disk_type_get( (newparts.get_disklabel() or GLIStorageDevice.archinfo[self._architecture_name]))) # Iterate through new partitions and check for 'origminor' and 'format' == False for part in newparts: tmppart_new = newparts[part] if not tmppart_new['origminor'] or tmppart_new['format']: continue if not tmppart_new['origminor'] in oldparts: raise GLIException( "MissingPartitionsError", 'fatal', 'partition', "Cannot find the existing partition that a new one refers to. This is not a bug. This is in fact your (the user's) fault. You should not reuse the installprofile.xml from a previous install that started the partitioning step." ) tmppart_old = oldparts[tmppart_new['origminor']] if parted_disk.type.check_feature( parted.DISK_TYPE_PARTITION_NAME): tmppart_new['name'] = tmppart_old['name'] tmppart_new['flags'] = tmppart_old['flags'] if tmppart_new['resized']: # Partition is being resized in the new layout self._logger.log( " Partition " + str(part) + " has origminor " + str(tmppart_new['origminor']) + " and it being resized...saving start sector " + str(tmppart_old['start'])) tmppart_new['start'] = tmppart_old['start'] tmppart_new['end'] = 0 else: # Partition is untouched in the new layout self._logger.log(" Partition " + str(part) + " has origminor " + str(tmppart_new['origminor']) + "...saving start sector " + str(tmppart_old['start']) + " and end sector " + str(tmppart_old['end'])) tmppart_new['start'] = tmppart_old['start'] tmppart_new['end'] = tmppart_old['end'] if self._check_table_layout_changed(parts_old[device], parts_new[device]): # First pass to delete old partitions that aren't resized self.notify_frontend( "progress", (cur_progress / total_steps, "Deleting partitioning that aren't being resized for " + device)) cur_progress += 1 self._partition_delete_step(parted_disk, oldparts, newparts) # Second pass to resize old partitions that need to be resized self._logger.log("Partitioning: Second pass...") self.notify_frontend( "progress", (cur_progress / total_steps, "Resizing remaining partitions for " + device)) cur_progress += 1 self._partition_resize_step(parted_disk, device, oldparts, newparts) # Wiping disk and creating blank disklabel try: parted_disk = parted_dev.disk_new_fresh( parted.disk_type_get(newparts.get_disklabel())) parted_disk.commit() except: raise GLIException("DiskLabelCreationError", 'fatal', 'partition', "Could not create a blank disklabel!") # Third pass to create new partition table self._logger.log( "Partitioning: Third pass....creating partitions") self.notify_frontend( "progress", (cur_progress / total_steps, "Recreating partition table for " + device)) cur_progress += 1 self._partition_recreate_step(parted_disk, newparts) else: cur_progress += 3 # Fourth pass to format partitions self._logger.log("Partitioning: formatting partitions") self.notify_frontend("progress", (cur_progress / total_steps, "Formatting partitions for " + device)) cur_progress += 1 self._partition_format_step(parted_disk, device, newparts) # All done for this device self.notify_frontend("progress", (cur_progress / total_steps, "Done with partitioning for " + device)) cur_progress += 1