def startup(self, intf, exclusiveDisks, zeroMbr): """ Look for any unformatted DASDs in the system and offer the user the option for format them with dasdfmt or exit the installer. """ if self.started: return self.started = True out = "/dev/tty5" err = "/dev/tty5" if not iutil.isS390(): return log.info("Checking for unformatted DASD devices:") for device in os.listdir("/sys/block"): if not device.startswith("dasd"): continue statusfile = "/sys/block/%s/device/status" % (device,) if not os.path.isfile(statusfile): continue f = open(statusfile, "r") status = f.read().strip() f.close() if status in ["unformatted"] and device not in exclusiveDisks: bypath = deviceNameToDiskByPath(device) if not bypath: bypath = "/dev/" + device log.info(" %s (%s) status is %s, needs dasdfmt" % (device, bypath, status,)) self._dasdlist.append((device, bypath)) if not len(self._dasdlist): log.info(" no unformatted DASD devices found") return askUser = True if zeroMbr: askUser = False elif not intf and not zeroMbr: log.info(" non-interactive kickstart install without zerombr " "command, unable to run dasdfmt, exiting installer") sys.exit(0) c = len(self._dasdlist) if intf and askUser: devs = '' for dasd, bypath in self._dasdlist: devs += "%s\n" % (bypath,) rc = intf.questionInitializeDASD(c, devs) if rc == 1: log.info(" not running dasdfmt, continuing installation") return # gather total cylinder count argv = ["-t", "-v"] + self.commonArgv for dasd, bypath in self._dasdlist: buf = iutil.execWithCapture(self.dasdfmt, argv + ["/dev/" + dasd], stderr=err) for line in buf.splitlines(): if line.startswith("Drive Geometry: "): # line will look like this: # Drive Geometry: 3339 Cylinders * 15 Heads = 50085 Tracks cyls = long(filter(lambda s: s, line.split(' '))[2]) self.totalCylinders += cyls break # format DASDs argv = ["-P"] + self.commonArgv update = self._updateProgressWindow title = P_("Formatting DASD Device", "Formatting DASD Devices", c) msg = P_("Preparing %d DASD device for use with Linux..." % c, "Preparing %d DASD devices for use with Linux..." % c, c) if intf: if self.totalCylinders: pw = intf.progressWindow(title, msg, 1.0) else: pw = intf.progressWindow(title, msg, 100, pulse=True) for dasd, bypath in self._dasdlist: log.info("Running dasdfmt on %s" % (bypath,)) arglist = argv + ["/dev/" + dasd] try: if intf and self.totalCylinders: ret = iutil.execWithCallback(self.dasdfmt, arglist, stdout=out, stderr=err, callback=update, callback_data=pw, echo=False) rc = ret.rc elif intf: ret = iutil.execWithPulseProgress(self.dasdfmt, arglist, stdout=out, stderr=err, progress=pw) rc = ret.rc else: rc = iutil.execWithRedirect(self.dasdfmt, arglist, stdout=out, stderr=err) except Exception as e: raise DasdFormatError(e, bypath) if rc: raise DasdFormatError("dasdfmt failed: %s" % rc, bypath) if intf: pw.pop()
def getScreen (self, anaconda): # We can't just use exclusiveDisks here because of kickstart. First, # the kickstart file could have used ignoredisk --drives= in which case # exclusiveDisks would be empty. Second, ignoredisk is entirely # optional in which case neither list would be populated. Luckily, # storage.disks takes isIgnored into account and that handles both these # issues. disks = filter(lambda d: not d.format.hidden, anaconda.storage.disks) self.anaconda = anaconda # Skip this screen as well if there's only one disk to use. if len(disks) == 1: self.resetStorage(clear=[disks[0].name], boot=disks[0].name) return None (xml, self.vbox) = gui.getGladeWidget("cleardisks.glade", "vbox") self.leftScroll = xml.get_widget("leftScroll") self.rightScroll = xml.get_widget("rightScroll") self.addButton = xml.get_widget("addButton") self.removeButton = xml.get_widget("removeButton") self.installTargetImage = xml.get_widget("installTargetImage") self.installTargetTip = xml.get_widget("installTargetTip") self.leftVisible = 1 self.leftActive = 2 self.rightVisible = 4 self.rightActive = 5 # One store for both views. First the obejct, then a visible/active for # the left hand side, then a visible/active for the right hand side, then # all the other stuff. # # NOTE: the third boolean is a placeholder. DeviceSelector uses the third # slot in the store to determine whether the row is immutable or not. We # just need to put False in there for everything. self.store = gtk.TreeStore(gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) self.store.set_sort_column_id(6, gtk.SORT_ASCENDING) # The left view shows all the drives that will just be mounted, but # can still be moved to the right hand side. self.leftFilteredModel = self.store.filter_new() self.leftSortedModel = gtk.TreeModelSort(self.leftFilteredModel) self.leftTreeView = gtk.TreeView(self.leftSortedModel) self.leftFilteredModel.set_visible_func(lambda model, iter, view: model.get_value(iter, self.leftVisible), self.leftTreeView) self.leftScroll.add(self.leftTreeView) self.leftDS = DeviceSelector(self.store, self.leftSortedModel, self.leftTreeView, visible=self.leftVisible, active=self.leftActive) self.leftDS.createMenu() self.leftDS.addColumn(_("Model"), 6) self.leftDS.addColumn(_("Capacity"), 7) self.leftDS.addColumn(_("Vendor"), 8) self.leftDS.addColumn(_("Identifier"), 9) self.leftDS.addColumn(_("Interconnect"), 10, displayed=False) # The right view show all the drives that will be wiped during install. self.rightFilteredModel = self.store.filter_new() self.rightSortedModel = gtk.TreeModelSort(self.rightFilteredModel) self.rightTreeView = gtk.TreeView(self.rightSortedModel) self.rightFilteredModel.set_visible_func(lambda model, iter, view: model.get_value(iter, self.rightVisible), self.rightTreeView) self.rightScroll.add(self.rightTreeView) self.rightDS = DeviceSelector(self.store, self.rightSortedModel, self.rightTreeView, visible=self.rightVisible, active=self.rightActive) self.rightDS.createSelectionCol(title=_("Boot\nLoader"), radioButton=True) self.rightDS.createMenu() self.rightDS.addColumn(_("Model"), 6) self.rightDS.addColumn(_("Capacity"), 7) self.rightDS.addColumn(_("Identifier"), 9) # Store the first disk (according to bootloader ordering) for # auto boot device selection self.bootDisk = getattr(self.anaconda.bootloader.stage1_drive, "name", self.anaconda.bootloader.drives[0].name) if self.anaconda.storage.doAutoPart: use_disks = self.anaconda.storage.config.clearPartDisks else: use_disks = [d.name for d in disks if not d.protected] self.addButton.set_sensitive(False) self.removeButton.set_sensitive(False) # The device filtering UI set up exclusiveDisks as a list of the names # of all the disks we should use later on. Now we need to go get those, # look up some more information in the devicetree, and set up the # selector. for d in disks: rightVisible = d.name in use_disks rightActive = rightVisible and d.name == self.bootDisk leftVisible = not rightVisible if hasattr(d, "wwid"): ident = d.wwid else: try: ident = deviceNameToDiskByPath(d.name) if ident.startswith("/dev/disk/by-path/"): ident = ident.replace("/dev/disk/by-path/", "") except DeviceNotFoundError: ident = d.name self.store.append(None, (d, leftVisible, True, False, rightVisible, rightActive, d.model, str(int(d.size)) + " MB", d.vendor, ident, d.bus)) self.addButton.connect("clicked", self._add_clicked) self.removeButton.connect("clicked", self._remove_clicked) # Also allow moving devices back and forth with double click, enter, etc. self.leftTreeView.connect("row-activated", self._add_clicked) self.rightTreeView.disconnect(self.rightDS._activated_id) self.rightTreeView.connect("row-activated", self._remove_clicked) # And let the user select multiple devices at a time. self.leftTreeView.get_selection().set_mode(gtk.SELECTION_MULTIPLE) self.rightTreeView.get_selection().set_mode(gtk.SELECTION_MULTIPLE) if self.anaconda.storage.config.clearPartType == CLEARPART_TYPE_LINUX: self.installTargetTip.set_markup(_("<b>Tip:</b> All Linux filesystems on the install target devices will be reformatted and wiped of any data. Make sure you have backups.")) elif self.anaconda.storage.config.clearPartType == CLEARPART_TYPE_ALL: self.installTargetTip.set_markup(_("<b>Tip:</b> The install target devices will be reformatted and wiped of any data. Make sure you have backups.")) else: self.installTargetTip.set_markup(_("<b>Tip:</b> Your filesystems on the install target devices will not be reformatted unless you choose to do so during customization.")) return self.vbox
def getScreen (self, anaconda): # We can't just use exclusiveDisks here because of kickstart. First, # the kickstart file could have used ignoredisk --drives= in which case # exclusiveDisks would be empty. Second, ignoredisk is entirely # optional in which case neither list would be populated. Luckily, # storage.disks takes isIgnored into account and that handles both these # issues. disks = filter(lambda d: not d.format.hidden, anaconda.storage.disks) # Skip this screen as well if there's only one disk to use. if len(disks) == 1: anaconda.storage.clearPartDisks = [disks[0].name] anaconda.bootloader.drivelist = [disks[0].name] return None (xml, self.vbox) = gui.getGladeWidget("cleardisks.glade", "vbox") self.leftScroll = xml.get_widget("leftScroll") self.rightScroll = xml.get_widget("rightScroll") self.addButton = xml.get_widget("addButton") self.removeButton = xml.get_widget("removeButton") self.installTargetImage = xml.get_widget("installTargetImage") self.installTargetTip = xml.get_widget("installTargetTip") self.anaconda = anaconda self.leftVisible = 1 self.leftActive = 2 self.rightVisible = 4 self.rightActive = 5 # One store for both views. First the obejct, then a visible/active for # the left hand side, then a visible/active for the right hand side, then # all the other stuff. # # NOTE: the third boolean is a placeholder. DeviceSelector uses the third # slot in the store to determine whether the row is immutable or not. We # just need to put False in there for everything. self.store = gtk.TreeStore(gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) self.store.set_sort_column_id(6, gtk.SORT_ASCENDING) # The left view shows all the drives that will just be mounted, but # can still be moved to the right hand side. self.leftFilteredModel = self.store.filter_new() self.leftSortedModel = gtk.TreeModelSort(self.leftFilteredModel) self.leftTreeView = gtk.TreeView(self.leftSortedModel) self.leftFilteredModel.set_visible_func(lambda model, iter, view: model.get_value(iter, self.leftVisible), self.leftTreeView) self.leftScroll.add(self.leftTreeView) self.leftDS = DeviceSelector(self.store, self.leftSortedModel, self.leftTreeView, visible=self.leftVisible, active=self.leftActive) self.leftDS.createMenu() self.leftDS.addColumn(_("Model"), 6) self.leftDS.addColumn(_("Capacity"), 7) self.leftDS.addColumn(_("Vendor"), 8) self.leftDS.addColumn(_("Identifier"), 9) self.leftDS.addColumn(_("Interconnect"), 10, displayed=False) # The right view show all the drives that will be wiped during install. self.rightFilteredModel = self.store.filter_new() self.rightSortedModel = gtk.TreeModelSort(self.rightFilteredModel) self.rightTreeView = gtk.TreeView(self.rightSortedModel) self.rightFilteredModel.set_visible_func(lambda model, iter, view: model.get_value(iter, self.rightVisible), self.rightTreeView) self.rightScroll.add(self.rightTreeView) self.rightDS = DeviceSelector(self.store, self.rightSortedModel, self.rightTreeView, visible=self.rightVisible, active=self.rightActive) self.rightDS.createSelectionCol(title=_("Boot\nLoader"), radioButton=True) self.rightDS.createMenu() self.rightDS.addColumn(_("Model"), 6) self.rightDS.addColumn(_("Capacity"), 7) self.rightDS.addColumn(_("Identifier"), 9) # Store the first disk (according to our detected BIOS order) for # auto boot device selection names = map(lambda d: d.name, disks) self.bootDisk = sorted(names, self.anaconda.storage.compareDisks)[0] # The device filtering UI set up exclusiveDisks as a list of the names # of all the disks we should use later on. Now we need to go get those, # look up some more information in the devicetree, and set up the # selector. for d in disks: rightVisible = d.name in self.anaconda.storage.clearPartDisks rightActive = rightVisible and \ d.name in self.anaconda.bootloader.drivelist[:1] leftVisible = not rightVisible if hasattr(d, "wwid"): ident = d.wwid else: try: ident = deviceNameToDiskByPath(d.name) if ident.startswith("/dev/disk/by-path/"): ident = ident.replace("/dev/disk/by-path/", "") except DeviceNotFoundError: ident = d.name self.store.append(None, (d, leftVisible, True, False, rightVisible, rightActive, d.model, str(int(d.size)) + " MB", d.vendor, ident, d.bus)) self.addButton.connect("clicked", self._add_clicked) self.removeButton.connect("clicked", self._remove_clicked) # Also allow moving devices back and forth with double click, enter, etc. self.leftTreeView.connect("row-activated", self._add_clicked) self.rightTreeView.disconnect(self.rightDS._activated_id) self.rightTreeView.connect("row-activated", self._remove_clicked) # And let the user select multiple devices at a time. self.leftTreeView.get_selection().set_mode(gtk.SELECTION_MULTIPLE) self.rightTreeView.get_selection().set_mode(gtk.SELECTION_MULTIPLE) if self.anaconda.storage.clearPartType == CLEARPART_TYPE_LINUX: self.installTargetTip.set_markup(_("<b>Tip:</b> All Linux filesystems on the install target devices will be reformatted and wiped of any data. Make sure you have backups.")) elif self.anaconda.storage.clearPartType == CLEARPART_TYPE_ALL: self.installTargetTip.set_markup(_("<b>Tip:</b> The install target devices will be reformatted and wiped of any data. Make sure you have backups.")) else: self.installTargetTip.set_markup(_("<b>Tip:</b> Your filesystems on the install target devices will not be reformatted unless you choose to do so during customization.")) return self.vbox
def startup(self, intf, exclusiveDisks, zeroMbr): """ Look for any unformatted DASDs in the system and offer the user the option for format them with dasdfmt or exit the installer. """ if self.started: return self.started = True out = "/dev/tty5" err = "/dev/tty5" if not iutil.isS390(): return log.info("Checking for unformatted DASD devices:") for device in os.listdir("/sys/block"): if not device.startswith("dasd"): continue statusfile = "/sys/block/%s/device/status" % (device, ) if not os.path.isfile(statusfile): continue f = open(statusfile, "r") status = f.read().strip() f.close() if status in ["unformatted"] and device not in exclusiveDisks: bypath = deviceNameToDiskByPath(device) if not bypath: bypath = "/dev/" + device log.info(" %s (%s) status is %s, needs dasdfmt" % ( device, bypath, status, )) self._dasdlist.append((device, bypath)) if not len(self._dasdlist): log.info(" no unformatted DASD devices found") return askUser = True if zeroMbr: askUser = False elif not intf and not zeroMbr: log.info(" non-interactive kickstart install without zerombr " "command, unable to run dasdfmt, exiting installer") sys.exit(0) c = len(self._dasdlist) if intf and askUser: devs = '' for dasd, bypath in self._dasdlist: devs += "%s\n" % (bypath, ) rc = intf.questionInitializeDASD(c, devs) if rc == 1: log.info(" not running dasdfmt, continuing installation") return # gather total cylinder count argv = ["-t", "-v"] + self.commonArgv for dasd, bypath in self._dasdlist: buf = iutil.execWithCapture(self.dasdfmt, argv + ["/dev/" + dasd], stderr=err) for line in buf.splitlines(): if line.startswith("Drive Geometry: "): # line will look like this: # Drive Geometry: 3339 Cylinders * 15 Heads = 50085 Tracks cyls = long(filter(lambda s: s, line.split(' '))[2]) self.totalCylinders += cyls break # format DASDs argv = ["-P"] + self.commonArgv update = self._updateProgressWindow title = P_("Formatting DASD Device", "Formatting DASD Devices", c) msg = P_("Preparing %d DASD device for use with Linux..." % c, "Preparing %d DASD devices for use with Linux..." % c, c) if intf: if self.totalCylinders: pw = intf.progressWindow(title, msg, 1.0) else: pw = intf.progressWindow(title, msg, 100, pulse=True) for dasd, bypath in self._dasdlist: log.info("Running dasdfmt on %s" % (bypath, )) arglist = argv + ["/dev/" + dasd] try: if intf and self.totalCylinders: ret = iutil.execWithCallback(self.dasdfmt, arglist, stdout=out, stderr=err, callback=update, callback_data=pw, echo=False) rc = ret.rc elif intf: ret = iutil.execWithPulseProgress(self.dasdfmt, arglist, stdout=out, stderr=err, progress=pw) rc = ret.rc else: rc = iutil.execWithRedirect(self.dasdfmt, arglist, stdout=out, stderr=err) except Exception as e: raise DasdFormatError(e, bypath) if rc: raise DasdFormatError("dasdfmt failed: %s" % rc, bypath) if intf: pw.pop()