def getScreen(self, anaconda): self.intf = anaconda.intf self.anaconda = anaconda self.hostname = network.getDefaultHostname(anaconda) # load the UI (self.xml, self.align) = gui.getGladeWidget("network.glade", "network_align") self.icon = self.xml.get_widget("icon") self.hostnameEntry = self.xml.get_widget("hostnameEntry") self.hostnameEntry.set_text(self.hostname) self.netconfButton = self.xml.get_widget("netconfButton") self.netconfButton.connect("clicked", self._setupNetwork) if len(self.anaconda.network.netdevices) == 0 or flags.imageInstall: self.netconfButton.set_sensitive(False) # pressing Enter in confirm == clicking Next self.hostnameEntry.connect("activate", lambda w: self.ics.setGrabNext(1)) # load the icon gui.readImageFromFile("network.png", image=self.icon) return self.align
def addDrive(anaconda): (dxml, dialog) = gui.getGladeWidget("adddrive.glade", "addDriveDialog") gui.addFrame(dialog) dialog.show_all() if not iutil.isS390(): dxml.get_widget("zfcpRadio").hide() dxml.get_widget("zfcpRadio").set_group(None) if not pyanaconda.storage.iscsi.has_iscsi(): dxml.get_widget("iscsiRadio").set_sensitive(False) dxml.get_widget("iscsiRadio").set_active(False) dxml.get_widget("iscsiBindCheck").set_sensitive(False) else: dxml.get_widget("iscsiBindCheck").set_active(bool(pyanaconda.storage.iscsi.iscsi().ifaces)) dxml.get_widget("iscsiBindCheck").set_sensitive(pyanaconda.storage.iscsi.iscsi().mode == "none") if not pyanaconda.storage.fcoe.has_fcoe(): dxml.get_widget("fcoeRadio").set_sensitive(False) dxml.get_widget("fcoeRadio").set_active(False) def update_active_ifaces(): active_ifaces = network.getActiveNetDevs() dxml.get_widget("ifaceLabel").set_text(", ".join(active_ifaces)) def netconfButton_clicked(*args): from pyanaconda.iw.network_gui import setupNetwork setupNetwork(anaconda.intf) update_active_ifaces() dxml.get_widget("netconfButton").connect("clicked", netconfButton_clicked) update_active_ifaces() #figure out what advanced devices we have available and put focus on the first one group = dxml.get_widget("iscsiRadio").get_group() for button in reversed(group): if button is not None and button.get_property("sensitive"): button.set_active(True) button.grab_focus() break rc = dialog.run() dialog.hide() if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]: return False if dxml.get_widget("iscsiRadio").get_active() and pyanaconda.storage.iscsi.has_iscsi(): bind = dxml.get_widget("iscsiBindCheck").get_active() rc = addIscsiDrive(anaconda, bind) elif dxml.get_widget("fcoeRadio").get_active() and pyanaconda.storage.fcoe.has_fcoe(): rc = addFcoeDrive(anaconda) elif dxml.get_widget("zfcpRadio") is not None and dxml.get_widget("zfcpRadio").get_active(): rc = addZfcpDrive(anaconda) dialog.destroy() if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]: return False else: return True
def __init__(self, anaconda, repoObj): self.anaconda = anaconda self.backend = self.anaconda.backend self.intf = self.anaconda.intf self.repo = repoObj (self.dxml, self.dialog) = gui.getGladeWidget("addrepo.glade", "addRepoDialog") self.dxml.signal_autoconnect(self) self.notebook = self.dxml.get_widget("typeNotebook") self.nameEntry = self.dxml.get_widget("nameEntry") self.typeComboBox = self.dxml.get_widget("typeComboBox") self.baseurlEntry = self.dxml.get_widget("baseurlEntry") self.mirrorlistCheckbox = self.dxml.get_widget("mirrorlistCheckbox") self.proxyCheckbox = self.dxml.get_widget("proxyCheckbox") self.proxyEntry = self.dxml.get_widget("proxyEntry") self.proxyTable = self.dxml.get_widget("proxyTable") self.usernameEntry = self.dxml.get_widget("usernameEntry") self.passwordEntry = self.dxml.get_widget("passwordEntry") self.nfsServerEntry = self.dxml.get_widget("nfsServerEntry") self.nfsPathEntry = self.dxml.get_widget("nfsPathEntry") self.nfsOptionsEntry = self.dxml.get_widget("nfsOptionsEntry") self.partitionComboBox = self.dxml.get_widget("partitionComboBox") self.directoryChooser = self.dxml.get_widget("directoryChooserButton") self.dialog.set_title(_("Edit Repository")) # Remove these until they are actually implemented self.typeComboBox.remove_text(3)
def __init__(self, anaconda, repoObj): self.anaconda = anaconda self.backend = self.anaconda.backend self.intf = self.anaconda.intf self.repo = repoObj (self.dxml, self.dialog) = gui.getGladeWidget("addrepo.glade", "addRepoDialog") self.dxml.signal_autoconnect(self) self.notebook = self.dxml.get_widget("typeNotebook") self.nameEntry = self.dxml.get_widget("nameEntry") self.typeComboBox = self.dxml.get_widget("typeComboBox") self.baseurlEntry = self.dxml.get_widget("baseurlEntry") self.mirrorlistCheckbox = self.dxml.get_widget("mirrorlistCheckbox") self.proxyCheckbox = self.dxml.get_widget("proxyCheckbox") self.proxyEntry = self.dxml.get_widget("proxyEntry") self.proxyTable = self.dxml.get_widget("proxyTable") self.usernameEntry = self.dxml.get_widget("usernameEntry") self.passwordEntry = self.dxml.get_widget("passwordEntry") self.nfsServerEntry = self.dxml.get_widget("nfsServerEntry") self.nfsPathEntry = self.dxml.get_widget("nfsPathEntry") self.nfsOptionsEntry = self.dxml.get_widget("nfsOptionsEntry") self.partitionComboBox = self.dxml.get_widget("partitionComboBox") self.directoryChooser = self.dxml.get_widget("directoryChooserButton") self.dialog.set_title(_("Edit Repository")) # Remove these until they are actually implemented self.typeComboBox.remove_text(3)
def getScreen(self, anaconda): self.intf = anaconda.intf self.anaconda = anaconda self.hostname = network.getDefaultHostname(anaconda) # load the UI (self.xml, self.align) = gui.getGladeWidget("network.glade", "network_align") self.icon = self.xml.get_widget("icon") self.hostnameEntry = self.xml.get_widget("hostnameEntry") self.hostnameEntry.set_text(self.hostname) self.netconfButton = self.xml.get_widget("netconfButton") self.netconfButton.connect("clicked", self._setupNetwork) if len(self.anaconda.network.netdevices) == 0 or flags.imageInstall: self.netconfButton.set_sensitive(False) # pressing Enter in confirm == clicking Next self.hostnameEntry.connect("activate", lambda w: self.ics.setGrabNext(1)) # load the icon gui.readImageFromFile("network.png", image=self.icon) return self.align
def getScreen (self, anaconda): self.intf = anaconda.intf self.dispatch = anaconda.dispatch self.backend = anaconda.backend self.anaconda = anaconda self.tasks = anaconda.instClass.tasks self.repos = anaconda.backend.ayum.repos (self.xml, vbox) = gui.getGladeWidget("tasksel.glade", "taskBox") lbl = self.xml.get_widget("mainLabel") if anaconda.instClass.description: lbl.set_text(_(anaconda.instClass.description)) else: txt = lbl.get_text() lbl.set_text(txt %(productName,)) custom = not self.dispatch.stepInSkipList("group-selection") if custom: self.xml.get_widget("customRadio").set_active(True) else: self.xml.get_widget("customRadio").set_active(False) self.ts = self._createTaskStore() self.rs = self._createRepoStore() if len(self.ts.get_model()) == 0: self.xml.get_widget("cbVBox").hide() self.xml.get_widget("mainLabel").hide() self.xml.get_widget("addRepoButton").connect("clicked", self._addRepo) self.xml.get_widget("editRepoButton").connect("clicked", self._editRepo, self.rs) return vbox
def addZfcpDrive(anaconda): (dxml, dialog) = gui.getGladeWidget("zfcp-config.glade", "zfcpDialog") gui.addFrame(dialog) dialog.show_all() sg = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL) for w in ["devnumEntry", "wwpnEntry", "fcplunEntry"]: sg.add_widget(dxml.get_widget(w)) while True: dialog.present() rc = dialog.run() if rc != gtk.RESPONSE_APPLY: break devnum = dxml.get_widget("devnumEntry").get_text().strip() wwpn = dxml.get_widget("wwpnEntry").get_text().strip() fcplun = dxml.get_widget("fcplunEntry").get_text().strip() try: anaconda.storage.zfcp.addFCP(devnum, wwpn, fcplun) except ValueError as e: anaconda.intf.messageWindow(_("Error"), str(e)) continue break dialog.destroy() return rc
def addZfcpDrive(anaconda): (dxml, dialog) = gui.getGladeWidget("zfcp-config.glade", "zfcpDialog") gui.addFrame(dialog) dialog.show_all() sg = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL) for w in ["devnumEntry", "wwpnEntry", "fcplunEntry"]: sg.add_widget(dxml.get_widget(w)) while True: dialog.present() rc = dialog.run() if rc != gtk.RESPONSE_APPLY: break devnum = dxml.get_widget("devnumEntry").get_text().strip() wwpn = dxml.get_widget("wwpnEntry").get_text().strip() fcplun = dxml.get_widget("fcplunEntry").get_text().strip() try: anaconda.storage.zfcp.addFCP(devnum, wwpn, fcplun) except ValueError as e: anaconda.intf.messageWindow(_("Error"), str(e)) continue break dialog.destroy() return rc
def __init__(self): super(iSCSILoginDialog, self).__init__() (xml, self.dialog) = gui.getGladeWidget("iscsi-dialogs.glade", "login_dialog") # take credentials from the discovery dialog (self.credentials_xml, credentials_table) = gui.getGladeWidget("iscsi-dialogs.glade", "table_credentials") (credentials, rev_credentials) = self._credentials_widgets(self.credentials_xml) # and put them into the login dialog alignment alignment = xml.get_widget("login_credentials_alignment") alignment.add(credentials_table) # setup the combobox self.combobox = self._combo_box([ pih.CRED_NONE, pih.CRED_ONE, pih.CRED_BOTH, pih.CRED_REUSE ], credentials, rev_credentials) vbox = xml.get_widget("d_login_vbox") vbox.pack_start(self.combobox, expand=False)
def __init__(self): super(iSCSILoginDialog, self).__init__() (xml, self.dialog) = gui.getGladeWidget("iscsi-dialogs.glade", "login_dialog") # take credentials from the discovery dialog (self.credentials_xml, credentials_table) = gui.getGladeWidget("iscsi-dialogs.glade", "table_credentials") (credentials, rev_credentials) = self._credentials_widgets(self.credentials_xml) # and put them into the login dialog alignment alignment = xml.get_widget("login_credentials_alignment") alignment.add(credentials_table) # setup the combobox self.combobox = self._combo_box( [pih.CRED_NONE, pih.CRED_ONE, pih.CRED_BOTH, pih.CRED_REUSE], credentials, rev_credentials) vbox = xml.get_widget("d_login_vbox") vbox.pack_start(self.combobox, expand=False)
def addDrive(anaconda): (dxml, dialog) = gui.getGladeWidget("adddrive.glade", "addDriveDialog") gui.addFrame(dialog) dialog.show_all() if not iutil.isS390(): dxml.get_widget("zfcpRadio").hide() dxml.get_widget("zfcpRadio").set_group(None) if not pyanaconda.storage.iscsi.has_iscsi(): dxml.get_widget("iscsiRadio").set_sensitive(False) dxml.get_widget("iscsiRadio").set_active(False) if not pyanaconda.storage.fcoe.has_fcoe(): dxml.get_widget("fcoeRadio").set_sensitive(False) dxml.get_widget("fcoeRadio").set_active(False) #figure out what advanced devices we have available and put focus on the first one group = dxml.get_widget("iscsiRadio").get_group() for button in reversed(group): if button is not None and button.get_property("sensitive"): button.set_active(True) button.grab_focus() break rc = dialog.run() dialog.hide() if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]: return False if dxml.get_widget("iscsiRadio").get_active( ) and pyanaconda.storage.iscsi.has_iscsi(): rc = addIscsiDrive(anaconda) elif dxml.get_widget( "fcoeRadio").get_active() and pyanaconda.storage.fcoe.has_fcoe(): rc = addFcoeDrive(anaconda) elif dxml.get_widget("zfcpRadio") is not None and dxml.get_widget( "zfcpRadio").get_active(): rc = addZfcpDrive(anaconda) dialog.destroy() if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]: return False else: return True
def __init__(self, initiator, initiator_set): super(iSCSIDiscoveryDialog, self).__init__() (self.xml, self.dialog) = gui.getGladeWidget("iscsi-dialogs.glade", "discovery_dialog") self.initiator = self.xml.get_widget("initiator") self.initiator.set_text(initiator) if initiator_set: self.initiator.set_sensitive(False) (credentials, rev_credentials) = self._credentials_widgets(self.xml) self.combobox = self._combo_box([ pih.CRED_NONE, pih.CRED_ONE, pih.CRED_BOTH, ], credentials, rev_credentials) vbox = self.xml.get_widget("d_discovery_vbox") vbox.pack_start(self.combobox, expand=False)
def display_nodes_dialog(self, found_nodes, ifaces): def _login_button_disabler(device_selector, login_button, checked, item): login_button.set_sensitive(len(device_selector.getSelected()) > 0) (xml, dialog) = gui.getGladeWidget("iscsi-dialogs.glade", "nodes_dialog") store = gtk.TreeStore( gobject.TYPE_PYOBJECT, # teh object gobject.TYPE_BOOLEAN, # visible gobject.TYPE_BOOLEAN, # active (checked) gobject.TYPE_BOOLEAN, # immutable gobject.TYPE_STRING, # node name gobject.TYPE_STRING # node interface ) map(lambda node : store.append(None, ( node, # the object True, # visible True, # active False, # not immutable node.name, # node's name ifaces.get(node.iface, node.iface))), # node's interface found_nodes) # create and setup the device selector model = store.filter_new() view = gtk.TreeView(model) ds = DeviceSelector.DeviceSelector( store, model, view) callback = functools.partial(_login_button_disabler, ds, xml.get_widget("button_login")) ds.createSelectionCol(toggledCB=callback) ds.addColumn(_("Interface"), self.NODE_INTERFACE_COL) # attach the treeview to the dialog sw = xml.get_widget("nodes_scrolled_window") sw.add(view) sw.show_all() # run the dialog rc = self._run_dialog(dialog) # filter out selected nodes: selected_nodes = map(lambda raw : raw[0], ds.getSelected()) dialog.destroy() return (rc, selected_nodes)
def __init__(self, initiator, initiator_set): super(iSCSIDiscoveryDialog, self).__init__() (self.xml, self.dialog) = gui.getGladeWidget("iscsi-dialogs.glade", "discovery_dialog") self.initiator = self.xml.get_widget("initiator") self.initiator.set_text(initiator) if initiator_set: self.initiator.set_sensitive(False) (credentials, rev_credentials) = self._credentials_widgets(self.xml) self.combobox = self._combo_box([ pih.CRED_NONE, pih.CRED_ONE, pih.CRED_BOTH, ], credentials, rev_credentials) vbox = self.xml.get_widget("d_discovery_vbox") vbox.pack_start(self.combobox, expand=False)
def addDrive(anaconda): (dxml, dialog) = gui.getGladeWidget("adddrive.glade", "addDriveDialog") gui.addFrame(dialog) dialog.show_all() if not iutil.isS390(): dxml.get_widget("zfcpRadio").hide() dxml.get_widget("zfcpRadio").set_group(None) if not pyanaconda.storage.iscsi.has_iscsi(): dxml.get_widget("iscsiRadio").set_sensitive(False) dxml.get_widget("iscsiRadio").set_active(False) if not pyanaconda.storage.fcoe.has_fcoe(): dxml.get_widget("fcoeRadio").set_sensitive(False) dxml.get_widget("fcoeRadio").set_active(False) #figure out what advanced devices we have available and put focus on the first one group = dxml.get_widget("iscsiRadio").get_group() for button in reversed(group): if button is not None and button.get_property("sensitive"): button.set_active(True) button.grab_focus() break rc = dialog.run() dialog.hide() if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]: return False if dxml.get_widget("iscsiRadio").get_active() and pyanaconda.storage.iscsi.has_iscsi(): rc = addIscsiDrive(anaconda) elif dxml.get_widget("fcoeRadio").get_active() and pyanaconda.storage.fcoe.has_fcoe(): rc = addFcoeDrive(anaconda) elif dxml.get_widget("zfcpRadio") is not None and dxml.get_widget("zfcpRadio").get_active(): rc = addZfcpDrive(anaconda) dialog.destroy() if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]: return False else: return True
def display_success_dialog(self, success_nodes, fail_nodes, fail_reason, ifaces): (xml, dialog) = gui.getGladeWidget("iscsi-dialogs.glade", "success_dialog") w_success = xml.get_widget("label_success") w_success_win = xml.get_widget("scroll_window_success") w_success_val = xml.get_widget("text_success") w_fail = xml.get_widget("label_fail") w_fail_win = xml.get_widget("scroll_window_fail") w_fail_val = xml.get_widget("text_fail") w_reason = xml.get_widget("label_reason") w_reason_val = xml.get_widget("label_reason_val") w_retry = xml.get_widget("button_retry") w_separator = xml.get_widget("separator") if success_nodes: markup = "\n".join(map(lambda n: "%s via %s" % (n.name, ifaces.get(n.iface, n.iface)), success_nodes)) buf = gtk.TextBuffer() buf.set_text(markup) w_success.show() w_success_val.set_buffer(buf) w_success_win.show() if fail_nodes: markup = "\n".join(map(lambda n: "%s via %s" % (n.name, ifaces.get(n.iface, n.iface)), fail_nodes)) buf = gtk.TextBuffer() buf.set_text(markup) w_fail.show() w_fail_val.set_buffer(buf) w_fail_win.show() w_retry.show() if fail_reason: w_reason.show() w_reason_val.set_markup(fail_reason) w_reason_val.show() if success_nodes and fail_nodes: # only if there's anything to be separated display the separator w_separator.show() rc = self._run_dialog(dialog) dialog.destroy() return rc
def display_success_dialog(self, success_nodes, fail_nodes, fail_reason): (xml, dialog) = gui.getGladeWidget("iscsi-dialogs.glade", "success_dialog") w_success = xml.get_widget("label_success") w_success_win = xml.get_widget("scroll_window_success") w_success_val = xml.get_widget("text_success") w_fail = xml.get_widget("label_fail") w_fail_win = xml.get_widget("scroll_window_fail") w_fail_val = xml.get_widget("text_fail") w_reason = xml.get_widget("label_reason") w_reason_val = xml.get_widget("label_reason_val") w_retry = xml.get_widget("button_retry") w_separator = xml.get_widget("separator") if success_nodes: markup = "\n".join(map(lambda n: n.name, success_nodes)) buf = gtk.TextBuffer() buf.set_text(markup) w_success.show() w_success_val.set_buffer(buf) w_success_win.show() if fail_nodes: markup = "\n".join(map(lambda n: n.name, fail_nodes)) buf = gtk.TextBuffer() buf.set_text(markup) w_fail.show() w_fail_val.set_buffer(buf) w_fail_win.show() w_retry.show() if fail_reason: w_reason.show() w_reason_val.set_markup(fail_reason) w_reason_val.show() if success_nodes and fail_nodes: # only if there's anything to be separated display the separator w_separator.show() rc = self._run_dialog(dialog) dialog.destroy() return rc
def getScreen(self, anaconda): self.anaconda = anaconda self.intf = anaconda.intf (self.xml, self.align) = gui.getGladeWidget("account.glade", "account_align") self.icon = self.xml.get_widget("icon") self.capslock = self.xml.get_widget("capslock") self.pwlabel = self.xml.get_widget("pwlabel") self.pw = self.xml.get_widget("pw") self.confirmlabel = self.xml.get_widget("confirmlabel") self.confirm = self.xml.get_widget("confirm") # load the icon gui.readImageFromFile("root-password.png", image=self.icon) # connect hotkeys self.pwlabel.set_text_with_mnemonic(_("Root _Password:"******"_Confirm:")) self.confirmlabel.set_mnemonic_widget(self.confirm) # watch for Caps Lock so we can warn the user self.intf.icw.window.connect("key-release-event", lambda w, e: self.handleCapsLockRelease(w, e, self.capslock)) # we might have a root password already if not self.anaconda.users.rootPassword['isCrypted']: self.pw.set_text(self.anaconda.users.rootPassword['password']) self.confirm.set_text(self.anaconda.users.rootPassword['password']) # pressing Enter in confirm == clicking Next vbox = self.xml.get_widget("account_box") self.confirm.connect("activate", lambda widget, vbox=vbox: self.ics.setGrabNext(1)) # set initial caps lock label text self.setCapsLockLabel() return self.align
def display_nodes_dialog(self, found_nodes): (xml, dialog) = gui.getGladeWidget("iscsi-dialogs.glade", "nodes_dialog") store = gtk.TreeStore( gobject.TYPE_PYOBJECT, # teh object gobject.TYPE_BOOLEAN, # visible gobject.TYPE_BOOLEAN, # active (checked) gobject.TYPE_BOOLEAN, # immutable gobject.TYPE_STRING # node name ) map( lambda node: store.append( None, ( node, # the object True, # visible True, # active False, # not immutable node.name)), # node's name found_nodes) # create and setup the device selector model = store.filter_new() view = gtk.TreeView(model) ds = DeviceSelector.DeviceSelector(store, model, view) ds.createSelectionCol() ds.addColumn(_("Node Name"), self.NODE_NAME_COL) # attach the treeview to the dialog sw = xml.get_widget("nodes_scrolled_window") sw.add(view) sw.show_all() # run the dialog rc = self._run_dialog(dialog) # filter out selected nodes: selected_nodes = map(lambda raw: raw[0], ds.getSelected()) dialog.destroy() return (rc, selected_nodes)
def display_nodes_dialog(self, found_nodes): (xml, dialog) = gui.getGladeWidget("iscsi-dialogs.glade", "nodes_dialog") store = gtk.TreeStore( gobject.TYPE_PYOBJECT, # teh object gobject.TYPE_BOOLEAN, # visible gobject.TYPE_BOOLEAN, # active (checked) gobject.TYPE_BOOLEAN, # immutable gobject.TYPE_STRING # node name ) map(lambda node : store.append(None, ( node, # the object True, # visible True, # active False, # not immutable node.name)), # node's name found_nodes) # create and setup the device selector model = store.filter_new() view = gtk.TreeView(model) ds = DeviceSelector.DeviceSelector( store, model, view) ds.createSelectionCol() ds.addColumn(_("Node Name"), self.NODE_NAME_COL) # attach the treeview to the dialog sw = xml.get_widget("nodes_scrolled_window") sw.add(view) sw.show_all() # run the dialog rc = self._run_dialog(dialog) # filter out selected nodes: selected_nodes = map(lambda raw : raw[0], ds.getSelected()) dialog.destroy() return (rc, selected_nodes)
def getScreen(self, anaconda): # We skip the filter UI in basic storage mode if anaconda.simpleFilter: anaconda.storage.config.exclusiveDisks = [] return None (self.xml, self.vbox) = gui.getGladeWidget("filter.glade", "vbox") self.buttonBox = self.xml.get_widget("buttonBox") self.notebook = self.xml.get_widget("notebook") self.addAdvanced = self.xml.get_widget("addAdvancedButton") self.notebook.connect("switch-page", self._page_switched) self.addAdvanced.connect("clicked", self._add_advanced_clicked) self.pages = [] self.anaconda = anaconda # One common store that all the views on all the notebook tabs share. # Yes, this means a whole lot of columns that are going to be empty or # unused much of the time. Oh well. # Object, # visible, active (checked), immutable, # device, model, capacity, vendor, interconnect, serial number, wwid # paths, port, target, lun self.store = gtk.TreeStore(gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) self.store.set_sort_column_id(MODEL_COL, gtk.SORT_ASCENDING) # if we've already populated the device tree at least once we should # do our best to make sure any active devices get deactivated anaconda.storage.devicetree.teardownAll() # So that drives onlined by these show up in the filter UI iscsi.iscsi().startup(anaconda.intf) fcoe.fcoe().startup(anaconda.intf) zfcp.ZFCP().startup(anaconda.intf) dasd.DASD().startup(anaconda.intf, anaconda.storage.config.exclusiveDisks, anaconda.storage.config.zeroMbr) disks = self._getFilterDisks() mcw = MultipathConfigWriter() cfg = mcw.write() open("/etc/multipath.conf", "w+").write(cfg) del cfg del mcw topology = MultipathTopology(disks) # The device list could be really long, so we really only want to # iterate over it the bare minimum of times. Dividing this list up # now means fewer elements to iterate over later. singlepaths = filter(lambda info: self._device_size_is_nonzero(info), topology.singlepaths_iter()) (raids, nonraids) = self.split_list(lambda d: isRAID(d) and not isCCISS(d), singlepaths) self.pages = [self._makeBasic(), self._makeRAID(), self._makeMPath(), self._makeOther(), self._makeSearch()] self.populate(nonraids, topology.multipaths_iter(), raids) # If the "Add Advanced" button is ever clicked, we need to have a list # of what devices previously existed so we know what's new. Then we # can just add the new devices to the UI. This is going to be slow, # but the user has to click a button to get to the slow part. self._cachedDevices = NameCache(singlepaths) self._cachedRaidDevices = NameCache(raids) # Multipath is a little more complicated. Since mpaths is a list of # lists, we can't directly store that into the cache. Instead we want # to flatten it into a single list of all components of all multipaths # and store that. mpath_chain = itertools.chain(*topology.multipaths_iter()) self._cachedMPaths = NameCache(mpath_chain) # Switch to the first notebook page that displays any devices. i = 0 for pg in self.pages: if pg.getNVisible(): self.notebook.set_current_page(i) break i += 1 return self.vbox
def whichToShrink(storage, intf): def getActive(combo): act = combo.get_active_iter() return combo.get_model().get_value(act, 1) def comboCB(combo, shrinkSB): # partition to resize changed, let's update our spinbutton newSize = shrinkSB.get_value_as_int() part = getActive(combo) (reqlower, requpper) = getResizeMinMax(part) adj = shrinkSB.get_adjustment() adj.lower = max(1,reqlower) adj.upper = requpper adj.set_value(reqlower) (dxml, dialog) = gui.getGladeWidget("autopart.glade", "shrinkDialog") store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT) combo = dxml.get_widget("shrinkPartCombo") combo.set_model(store) crt = gtk.CellRendererText() combo.pack_start(crt, True) combo.set_attributes(crt, text = 0) combo.connect("changed", comboCB, dxml.get_widget("shrinkSB")) biggest = -1 for part in storage.partitions: if not part.exists: continue entry = None if part.resizable and part.format.resizable: entry = ("%s (%s, %d MB)" % (part.name, part.format.name, math.floor(part.format.size)), part) if entry: i = store.append(None) store[i] = entry combo.set_active_iter(i) if biggest == -1: biggest = i else: current = store.get_value(biggest, 1) if part.format.targetSize > current.format.targetSize: biggest = i if biggest > -1: combo.set_active_iter(biggest) if len(store) == 0: dialog.destroy() intf.messageWindow(_("Error"), _("No partitions are available to resize. Only " "physical partitions with specific filesystems " "can be resized."), type="warning", custom_icon="error") return (gtk.RESPONSE_CANCEL, []) gui.addFrame(dialog) dialog.show_all() runResize = True while runResize: rc = dialog.run() if rc != gtk.RESPONSE_OK: dialog.destroy() return (rc, []) request = getActive(combo) sb = dxml.get_widget("shrinkSB") sb.update() newSize = sb.get_value_as_int() actions = [] try: actions.append(ActionResizeFormat(request, newSize)) except ValueError as e: intf.messageWindow(_("Resize FileSystem Error"), _("%(device)s: %(msg)s") % {'device': request.format.device, 'msg': e.message}, type="warning", custom_icon="error") continue try: actions.append(ActionResizeDevice(request, newSize)) except ValueError as e: intf.messageWindow(_("Resize Device Error"), _("%(name)s: %(msg)s") % {'name': request.name, 'msg': e.message}, type="warning", custom_icon="error") continue else: # aligning the new partition end sector may have changed its size if request.targetSize != request.format.targetSize: request.format.targetSize = request.targetSize runResize = False dialog.destroy() return (rc, actions)
def getScreen(self, anaconda): self.anaconda = anaconda self.storage = anaconda.storage self.intf = anaconda.intf self.dispatch = anaconda.dispatch if self.anaconda.dir == DISPATCH_FORWARD: # Save system's partition type setting and restore user's self.anaconda.clearPartTypeSystem = self.storage.clearPartType if self.anaconda.clearPartTypeSelection is not None: self.storage.clearPartType = self.anaconda.clearPartTypeSelection (self.xml, vbox) = gui.getGladeWidget("autopart.glade", "parttypeTable") self.encryptButton = self.xml.get_widget("encryptButton") self.reviewButton = self.xml.get_widget("reviewButton") self.table = self.xml.get_widget("parttypeTable") self.prevrev = None self.reviewButton.set_active( not self.dispatch.stepInSkipList("partition")) self.encryptButton.set_active(self.storage.encryptedAutoPart) self.buttonGroup = pixmapRadioButtonGroup() self.buttonGroup.addEntry( "all", _("Use All Space"), pixmap=gui.readImageFromFile("partscheme-all.png"), descr=_("Removes all partitions on the selected " "device(s). This includes partitions " "created by other operating systems.\n\n" "<b>Tip:</b> This option will remove " "data from the selected device(s). Make " "sure you have backups.")) self.buttonGroup.addEntry( "replace", _("Replace Existing Linux System(s)"), pixmap=gui.readImageFromFile("partscheme-replace.png"), descr=_("Removes all Linux partitions on the " "selected device(s). This does " "not remove other partitions you may have " "on your storage device(s) (such as VFAT or " "FAT32).\n\n" "<b>Tip:</b> This option will remove " "data from the selected device(s). Make " "sure you have backups.")) self.buttonGroup.addEntry( "shrink", _("Shrink Current System"), pixmap=gui.readImageFromFile("partscheme-shrink.png"), descr=_("Shrinks existing partitions to create free " "space for the default layout.")) self.buttonGroup.addEntry( "freespace", _("Use Free Space"), pixmap=gui.readImageFromFile("partscheme-freespace.png"), descr=_("Retains your current data and partitions and " "uses only the unpartitioned space on the " "selected device(s), assuming you have enough " "free space available.")) self.buttonGroup.addEntry( "custom", _("Create Custom Layout"), pixmap=gui.readImageFromFile("partscheme-custom.png"), descr=_("Manually create your own custom layout on " "the selected device(s) using our partitioning " "tool.")) self.buttonGroup.setToggleCallback(self.typeChanged) widget = self.buttonGroup.render() self.table.attach(widget, 0, 1, 1, 2) # if not set in ks, use UI default if self.storage.clearPartChoice: self.buttonGroup.setCurrent(self.storage.clearPartChoice) else: if self.storage.clearPartType is None or self.storage.clearPartType == CLEARPART_TYPE_LINUX: self.buttonGroup.setCurrent("replace") elif self.storage.clearPartType == CLEARPART_TYPE_NONE: self.buttonGroup.setCurrent("freespace") elif self.storage.clearPartType == CLEARPART_TYPE_ALL: self.buttonGroup.setCurrent("all") if self.buttonGroup.getCurrent() == "custom": # make sure reviewButton is active and not sensitive if self.prevrev == None: self.prevrev = self.reviewButton.get_active() self.reviewButton.set_active(True) self.reviewButton.set_sensitive(False) self.encryptButton.set_sensitive(False) return vbox
def addIscsiDrive(anaconda): if not network.hasActiveNetDev(): if not anaconda.intf.enableNetwork(): return gtk.RESPONSE_CANCEL urlgrabber.grabber.reset_curl_obj() (dxml, dialog) = gui.getGladeWidget("iscsi-config.glade", "iscsiDialog") gui.addFrame(dialog) dialog.show_all() sg = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL) for w in [ "iscsiAddrEntry", "iscsiInitiatorEntry", "userEntry", "passEntry", "userinEntry", "passinEntry" ]: sg.add_widget(dxml.get_widget(w)) # get the initiator name if it exists and don't allow changing # once set initiator_entry = dxml.get_widget("iscsiInitiatorEntry") initiator_entry.set_text(anaconda.storage.iscsi.initiator) if anaconda.storage.iscsi.initiatorSet: initiator_entry.set_sensitive(False) while True: rc = dialog.run() if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]: break initiator = initiator_entry.get_text().strip() if len(initiator) == 0: anaconda.intf.messageWindow( _("Invalid Initiator Name"), _("You must provide an initiator name.")) continue anaconda.storage.iscsi.initiator = initiator target = dxml.get_widget("iscsiAddrEntry").get_text().strip() user = dxml.get_widget("userEntry").get_text().strip() pw = dxml.get_widget("passEntry").get_text().strip() user_in = dxml.get_widget("userinEntry").get_text().strip() pw_in = dxml.get_widget("passinEntry").get_text().strip() try: count = len(target.split(":")) idx = target.rfind("]:") # Check for IPV6 [IPV6-ip]:port if idx != -1: ip = target[1:idx] port = target[idx + 2:] # Check for IPV4 aaa.bbb.ccc.ddd:port elif count == 2: idx = target.rfind(":") ip = target[:idx] port = target[idx + 1:] else: ip = target port = "3260" network.sanityCheckIPString(ip) except (network.IPMissing, network.IPError) as msg: anaconda.intf.messageWindow(_("Error with Data"), msg) continue try: anaconda.storage.iscsi.addTarget(ip, port, user, pw, user_in, pw_in, anaconda.intf) except ValueError as e: anaconda.intf.messageWindow(_("Error"), str(e)) continue except IOError as e: anaconda.intf.messageWindow(_("Error"), str(e)) rc = gtk.RESPONSE_CANCEL break dialog.destroy() return rc
def getScreen(self, anaconda): # We skip the filter UI in basic storage mode if anaconda.simpleFilter: anaconda.storage.exclusiveDisks = [] return None (self.xml, self.vbox) = gui.getGladeWidget("filter.glade", "vbox") self.buttonBox = self.xml.get_widget("buttonBox") self.notebook = self.xml.get_widget("notebook") self.addAdvanced = self.xml.get_widget("addAdvancedButton") self.notebook.connect("switch-page", self._page_switched) self.addAdvanced.connect("clicked", self._add_advanced_clicked) self.pages = [] self.anaconda = anaconda # One common store that all the views on all the notebook tabs share. # Yes, this means a whole lot of columns that are going to be empty or # unused much of the time. Oh well. # Object, # visible, active (checked), immutable, # device, model, capacity, vendor, interconnect, serial number, wwid # paths, port, target, lun self.store = gtk.TreeStore( gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) self.store.set_sort_column_id(MODEL_COL, gtk.SORT_ASCENDING) # if we've already populated the device tree at least once we should # do our best to make sure any active devices get deactivated anaconda.storage.devicetree.teardownAll() udev_trigger(subsystem="block", action="change") # So that drives onlined by these show up in the filter UI iscsi.iscsi().startup(anaconda.intf) fcoe.fcoe().startup(anaconda.intf) zfcp.ZFCP().startup(anaconda.intf) dasd.DASD().startup(anaconda.intf, anaconda.storage.exclusiveDisks, anaconda.storage.zeroMbr) disks = self._getFilterDisks() mcw = MultipathConfigWriter() cfg = mcw.write() open("/etc/multipath.conf", "w+").write(cfg) del cfg del mcw (singlepaths, mpaths, partitions) = identifyMultipaths(disks) # The device list could be really long, so we really only want to # iterate over it the bare minimum of times. Dividing this list up # now means fewer elements to iterate over later. singlepaths = filter(lambda info: self._device_size_is_nonzero(info), singlepaths) (raids, nonraids) = self.split_list(lambda d: isRAID(d) and not isCCISS(d), singlepaths) self.pages = [ self._makeBasic(), self._makeRAID(), self._makeMPath(), self._makeOther(), self._makeSearch() ] self.populate(nonraids, mpaths, raids) # If the "Add Advanced" button is ever clicked, we need to have a list # of what devices previously existed so we know what's new. Then we # can just add the new devices to the UI. This is going to be slow, # but the user has to click a button to get to the slow part. self._cachedDevices = NameCache(singlepaths) self._cachedRaidDevices = NameCache(raids) # Multipath is a little more complicated. Since mpaths is a list of # lists, we can't directly store that into the cache. Instead we want # to flatten it into a single list of all components of all multipaths # and store that. lst = list(itertools.chain(*mpaths)) self._cachedMPaths = NameCache(lst) # Switch to the first notebook page that displays any devices. i = 0 for pg in self.pages: if pg.getNVisible(): self.notebook.set_current_page(i) break i += 1 return self.vbox
def addFcoeDrive(anaconda): (dxml, dialog) = gui.getGladeWidget("fcoe-config.glade", "fcoeDialog") combo = dxml.get_widget("fcoeNicCombo") dcb_cb = dxml.get_widget("dcbCheckbutton") # Populate the combo cell = gtk.CellRendererText() combo.pack_start(cell, True) combo.set_attributes(cell, text=0) cell.set_property("wrap-width", 525) combo.set_size_request(480, -1) store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING) combo.set_model(store) netdevs = anaconda.network.netdevices keys = netdevs.keys() keys.sort() selected_interface = None for dev in keys: i = store.append(None) desc = netdevs[dev].description if desc: desc = "%s - %s" % (dev, desc) else: desc = "%s" % (dev, ) mac = netdevs[dev].get("HWADDR") if mac: desc = "%s - %s" % (desc, mac) if selected_interface is None: selected_interface = i store[i] = (desc, dev) if selected_interface: combo.set_active_iter(selected_interface) else: combo.set_active(0) # Show the dialog gui.addFrame(dialog) dialog.show_all() sg = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL) sg.add_widget(dxml.get_widget("fcoeNicCombo")) while True: # make sure the dialog pops into foreground in case this is the second # time through the loop: dialog.present() rc = dialog.run() if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]: break iter = combo.get_active_iter() if iter is None: anaconda.intf.messageWindow(_("Error"), _("You must select a NIC to use."), type="warning", custom_icon="error") continue try: anaconda.storage.fcoe.addSan(store.get_value(iter, 1), dcb=dcb_cb.get_active(), intf=anaconda.intf) except IOError as e: anaconda.intf.messageWindow(_("Error"), str(e)) rc = gtk.RESPONSE_CANCEL break dialog.destroy() return rc
def _deviceChange(self, b, anaconda, *args): def __driveChange(combo, dxml, choices): if not choices.has_key("mbr"): return iter = combo.get_active_iter() if not iter: return first = combo.get_model()[iter][1] desc = choices["mbr"][1] dxml.get_widget("mbrRadio").set_label("%s - /dev/%s" %(_(desc), first)) dxml.get_widget("mbrRadio").set_data("bootDevice", first) def __genStore(combo, disks, active): model = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING) combo.set_model(model) cell = gtk.CellRendererText() combo.pack_start(cell, True) combo.set_attributes(cell, text = 0) for disk in disks: i = model.append(None) model[i] = ("%s %8.0f MB %s" %(disk.name, disk.size, disk.description), "%s" %(disk.name,)) if disk.name == active: combo.set_active_iter(i) return model (dxml, dialog) = gui.getGladeWidget("blwhere.glade", "blwhereDialog") gui.addFrame(dialog) dialog.set_transient_for(self.parent) dialog.show() choices = anaconda.platform.bootloaderChoices(self.bl) for t in ("mbr", "boot"): if not choices.has_key(t): continue (device, desc) = choices[t] w = dxml.get_widget("%sRadio" %(t,)) w.set_label("%s - /dev/%s" %(_(desc), device)) w.show() if self.bldev == device: w.set_active(True) else: w.set_active(False) w.set_data("bootDevice", device) for i in range(1, 5): if len(self.driveorder) < i: break combo = dxml.get_widget("bd%dCombo" %(i,)) lbl = dxml.get_widget("bd%dLabel" %(i,)) combo.show() lbl.show() partitioned = anaconda.storage.partitioned disks = anaconda.storage.disks bl_disks = [d for d in disks if d in partitioned] m = __genStore(combo, bl_disks, self.driveorder[i - 1]) dxml.get_widget("bd1Combo").connect("changed", __driveChange, dxml, choices) __driveChange(dxml.get_widget("bd1Combo"), dxml, choices) while 1: rc = dialog.run() if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]: break # set the boot device based on what they chose if dxml.get_widget("bootRadio").get_active(): self.bldev = dxml.get_widget("bootRadio").get_data("bootDevice") elif dxml.get_widget("mbrRadio").get_active(): self.bldev = dxml.get_widget("mbrRadio").get_data("bootDevice") else: raise RuntimeError, "No radio button selected!" # and adjust the boot order neworder = [] for i in range(1, 5): if len(self.driveorder) < i: break combo = dxml.get_widget("bd%dCombo" %(i,)) iter = combo.get_active_iter() if not iter: continue act = combo.get_model()[iter][1] if act not in neworder: neworder.append(act) for d in self.driveorder: if d not in neworder: neworder.append(d) self.driveorder = neworder break dialog.destroy() self.grubCB.set_label(_("_Install boot loader on /dev/%s.") % (self.bldev,)) return rc
def _deviceChange(self, b, anaconda, *args): def __driveChange(combo, dxml, choices): if not choices.has_key("mbr"): return iter = combo.get_active_iter() if not iter: return first = combo.get_model()[iter][1] desc = choices["mbr"][1] dxml.get_widget("mbrRadio").set_label("%s - /dev/%s" % (_(desc), first)) dxml.get_widget("mbrRadio").set_data("bootDevice", first) def __genStore(combo, disks, active): model = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING) combo.set_model(model) cell = gtk.CellRendererText() combo.pack_start(cell, True) combo.set_attributes(cell, text=0) for disk in disks: i = model.append(None) model[i] = ("%s %8.0f MB %s" % (disk.name, disk.size, disk.description), "%s" % (disk.name, )) if disk.name == active: combo.set_active_iter(i) return model (dxml, dialog) = gui.getGladeWidget("blwhere.glade", "blwhereDialog") gui.addFrame(dialog) dialog.set_transient_for(self.parent) dialog.show() choices = anaconda.platform.bootloaderChoices(self.bl) for t in ("mbr", "boot"): if not choices.has_key(t): continue (device, desc) = choices[t] w = dxml.get_widget("%sRadio" % (t, )) w.set_label("%s - /dev/%s" % (_(desc), device)) w.show() if self.bldev == device: w.set_active(True) else: w.set_active(False) w.set_data("bootDevice", device) for i in range(1, 5): if len(self.driveorder) < i: break combo = dxml.get_widget("bd%dCombo" % (i, )) lbl = dxml.get_widget("bd%dLabel" % (i, )) combo.show() lbl.show() partitioned = anaconda.storage.partitioned disks = anaconda.storage.disks bl_disks = [d for d in disks if d in partitioned] m = __genStore(combo, bl_disks, self.driveorder[i - 1]) dxml.get_widget("bd1Combo").connect("changed", __driveChange, dxml, choices) __driveChange(dxml.get_widget("bd1Combo"), dxml, choices) while 1: rc = dialog.run() if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]: break # set the boot device based on what they chose if dxml.get_widget("bootRadio").get_active(): self.bldev = dxml.get_widget("bootRadio").get_data( "bootDevice") elif dxml.get_widget("mbrRadio").get_active(): self.bldev = dxml.get_widget("mbrRadio").get_data("bootDevice") else: raise RuntimeError, "No radio button selected!" # and adjust the boot order neworder = [] for i in range(1, 5): if len(self.driveorder) < i: break combo = dxml.get_widget("bd%dCombo" % (i, )) iter = combo.get_active_iter() if not iter: continue act = combo.get_model()[iter][1] if act not in neworder: neworder.append(act) for d in self.driveorder: if d not in neworder: neworder.append(d) self.driveorder = neworder break dialog.destroy() self.grubCB.set_label( _("_Install boot loader on /dev/%s.") % (self.bldev, )) return rc
def addFcoeDrive(anaconda): (dxml, dialog) = gui.getGladeWidget("fcoe-config.glade", "fcoeDialog") combo = dxml.get_widget("fcoeNicCombo") dcb_cb = dxml.get_widget("dcbCheckbutton") # Populate the combo cell = gtk.CellRendererText() combo.pack_start(cell, True) combo.set_attributes(cell, text = 0) cell.set_property("wrap-width", 525) combo.set_size_request(480, -1) store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING) combo.set_model(store) netdevs = anaconda.network.netdevices keys = netdevs.keys() keys.sort() selected_interface = None for dev in keys: i = store.append(None) desc = netdevs[dev].description if desc: desc = "%s - %s" %(dev, desc) else: desc = "%s" %(dev,) mac = netdevs[dev].get("HWADDR") if mac: desc = "%s - %s" %(desc, mac) if selected_interface is None: selected_interface = i store[i] = (desc, dev) if selected_interface: combo.set_active_iter(selected_interface) else: combo.set_active(0) # Show the dialog gui.addFrame(dialog) dialog.show_all() sg = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL) sg.add_widget(dxml.get_widget("fcoeNicCombo")) while True: # make sure the dialog pops into foreground in case this is the second # time through the loop: dialog.present() rc = dialog.run() if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]: break iter = combo.get_active_iter() if iter is None: anaconda.intf.messageWindow(_("Error"), _("You must select a NIC to use."), type="warning", custom_icon="error") continue try: anaconda.storage.fcoe.addSan(store.get_value(iter, 1), dcb=dcb_cb.get_active(), intf=anaconda.intf) except IOError as e: anaconda.intf.messageWindow(_("Error"), str(e)) rc = gtk.RESPONSE_CANCEL break dialog.destroy() return rc
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): self.anaconda = anaconda self.storage = anaconda.storage self.intf = anaconda.intf self.dispatch = anaconda.dispatch if self.anaconda.dir == DISPATCH_FORWARD: # Save system's partition type setting and restore user's self.anaconda.clearPartTypeSystem = self.storage.config.clearPartType if self.anaconda.clearPartTypeSelection is not None: self.storage.config.clearPartType = self.anaconda.clearPartTypeSelection (self.xml, vbox) = gui.getGladeWidget("autopart.glade", "parttypeTable") self.encryptButton = self.xml.get_widget("encryptButton") self.reviewButton = self.xml.get_widget("reviewButton") self.lvmButton = self.xml.get_widget("lvmButton") self.table = self.xml.get_widget("parttypeTable") self.prevrev = None step_data = self.dispatch.step_data("parttype") self.reviewButton.set_active( step_data.get("review_checked", self.dispatch.step_enabled("partition"))) self.encryptButton.set_active(self.storage.encryptedAutoPart) self.lvmButton.set_active(self.storage.autoPartType == AUTOPART_TYPE_LVM) self.buttonGroup = pixmapRadioButtonGroup() self.buttonGroup.addEntry("all", _("Use _All Space"), pixmap=gui.readImageFromFile("partscheme-all.png"), descr=_("Removes all partitions on the selected " "device(s). This includes partitions " "created by other operating systems.\n\n" "<b>Tip:</b> This option will remove " "data from the selected device(s). Make " "sure you have backups.")) self.buttonGroup.addEntry("replace", _("Replace Existing _Linux System(s)"), pixmap=gui.readImageFromFile("partscheme-replace.png"), descr=_("Removes all Linux partitions on the " "selected device(s). This does " "not remove other partitions you may have " "on your storage device(s) (such as VFAT or " "FAT32).\n\n" "<b>Tip:</b> This option will remove " "data from the selected device(s). Make " "sure you have backups.")) self.buttonGroup.addEntry("shrink", _("_Shrink Current System"), pixmap=gui.readImageFromFile("partscheme-shrink.png"), descr=_("Shrinks existing partitions to create free " "space for the default layout.")) self.buttonGroup.addEntry("freespace", _("Use _Free Space"), pixmap=gui.readImageFromFile("partscheme-freespace.png"), descr=_("Retains your current data and partitions and " "uses only the unpartitioned space on the " "selected device(s), assuming you have enough " "free space available.")) self.buttonGroup.addEntry("custom", _("Create _Custom Layout"), pixmap=gui.readImageFromFile("partscheme-custom.png"), descr=_("Manually create your own custom layout on " "the selected device(s) using our partitioning " "tool.")) self.buttonGroup.setToggleCallback(self.typeChanged) widget = self.buttonGroup.render() self.table.attach(widget, 0, 1, 1, 2) # if not set in ks, use UI default if self.storage.clearPartChoice: self.buttonGroup.setCurrent(self.storage.clearPartChoice) else: if self.storage.config.clearPartType in (None, CLEARPART_TYPE_LINUX): self.buttonGroup.setCurrent("replace") elif self.storage.config.clearPartType == CLEARPART_TYPE_NONE: self.buttonGroup.setCurrent("freespace") elif self.storage.config.clearPartType == CLEARPART_TYPE_ALL: self.buttonGroup.setCurrent("all") if self.buttonGroup.getCurrent() == "custom": # make sure reviewButton is active and not sensitive if self.prevrev == None: self.prevrev = self.reviewButton.get_active() self.reviewButton.set_active(True) self.reviewButton.set_sensitive(False) self.encryptButton.set_sensitive(False) self.lvmButton.set_sensitive(False) return vbox
def whichToShrink(storage, intf): def getActive(combo): act = combo.get_active_iter() return combo.get_model().get_value(act, 1) def comboCB(combo, shrinkSB): # partition to resize changed, let's update our spinbutton newSize = shrinkSB.get_value_as_int() part = getActive(combo) (reqlower, requpper) = getResizeMinMax(part) adj = shrinkSB.get_adjustment() adj.lower = max(1, reqlower) adj.upper = requpper adj.set_value(reqlower) (dxml, dialog) = gui.getGladeWidget("autopart.glade", "shrinkDialog") store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT) combo = dxml.get_widget("shrinkPartCombo") combo.set_model(store) crt = gtk.CellRendererText() combo.pack_start(crt, True) combo.set_attributes(crt, text=0) combo.connect("changed", comboCB, dxml.get_widget("shrinkSB")) biggest = -1 for part in storage.partitions: if not part.exists: continue entry = None if part.resizable and part.format.resizable: entry = ( "%s (%s, %d MB)" % (part.name, part.format.name, math.floor(part.format.size)), part) if entry: i = store.append(None) store[i] = entry combo.set_active_iter(i) if biggest == -1: biggest = i else: current = store.get_value(biggest, 1) if part.format.targetSize > current.format.targetSize: biggest = i if biggest > -1: combo.set_active_iter(biggest) if len(store) == 0: dialog.destroy() intf.messageWindow(_("Error"), _("No partitions are available to resize. Only " "physical partitions with specific filesystems " "can be resized."), type="warning", custom_icon="error") return (gtk.RESPONSE_CANCEL, []) gui.addFrame(dialog) dialog.show_all() runResize = True while runResize: rc = dialog.run() if rc != gtk.RESPONSE_OK: dialog.destroy() return (rc, []) request = getActive(combo) newSize = dxml.get_widget("shrinkSB").get_value_as_int() actions = [] try: actions.append(ActionResizeFormat(request, newSize)) except ValueError as e: intf.messageWindow(_("Resize FileSystem Error"), _("%(device)s: %(msg)s") % { 'device': request.format.device, 'msg': e.message }, type="warning", custom_icon="error") continue try: actions.append(ActionResizeDevice(request, newSize)) except ValueError as e: intf.messageWindow(_("Resize Device Error"), _("%(name)s: %(msg)s") % { 'name': request.name, 'msg': e.message }, type="warning", custom_icon="error") continue runResize = False dialog.destroy() return (rc, actions)
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 _deviceChange(self, b, anaconda, *args): def __genStore(combo, disks, active): model = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT) combo.set_model(model) cell = gtk.CellRendererText() combo.pack_start(cell, True) combo.set_attributes(cell, text = 0) for disk in disks: i = model.append(None) model[i] = ("%s %8.0f MB %s" %(disk.name, disk.size, disk.description), disk) if disk.name == active: combo.set_active_iter(i) return model (dxml, dialog) = gui.getGladeWidget("blwhere.glade", "blwhereDialog") gui.addFrame(dialog) dialog.set_transient_for(self.parent) dialog.show() # XXX for md stage1, should we show md, first member disk, or first # disk? stage1 = anaconda.storage.bootLoaderDevice stage1_desc = anaconda.bootloader.device_description(stage1) choices = {"mbr": (stage1, stage1_desc)} stage2 = anaconda.storage.bootDevice try: stage2_desc = anaconda.bootloader.device_description(stage2) except ValueError: # stage2's type isn't valid as stage1, so don't offer "boot". pass else: choices["boot"] = (stage2, stage2_desc) for t in ("mbr", "boot"): if not choices.has_key(t): continue (device, desc) = choices[t] w = dxml.get_widget("%sRadio" %(t,)) w.set_label("%s - %s" %(desc, device.path)) w.show() w.set_active(self.bldev == device) w.set_data("bootDevice", device) bl_disks = anaconda.bootloader.drives for i in range(1, 5): if len(self.driveorder) < i: break combo = dxml.get_widget("bd%dCombo" %(i,)) lbl = dxml.get_widget("bd%dLabel" %(i,)) combo.show() lbl.show() m = __genStore(combo, bl_disks, self.driveorder[i - 1]) while True: rc = dialog.run() if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]: break # set the boot device based on what they chose if dxml.get_widget("bootRadio").get_active(): self.bldev = dxml.get_widget("bootRadio").get_data("bootDevice") elif dxml.get_widget("mbrRadio").get_active(): self.bldev = dxml.get_widget("mbrRadio").get_data("bootDevice") else: raise RuntimeError, "No radio button selected!" # and adjust the boot order neworder = [] for i in range(1, 5): if len(self.driveorder) < i: break combo = dxml.get_widget("bd%dCombo" %(i,)) iter = combo.get_active_iter() if not iter: continue act = combo.get_model()[iter][1].name if act not in neworder: neworder.append(act) for d in self.driveorder: if d not in neworder: neworder.append(d) self.driveorder = neworder break dialog.destroy() self.grubCB.set_label(_("_Install boot loader on %s.") % (self.bldev.path,)) return rc