This UI allows the user to select which devices they would like to include in the rest of the installation process, sorted out by their types. All devices not checked will never again be referenced by anaconda, though we may see their udev information in the logs from time to time. This UI supports two different ways of looking at things: the simple UI for regular Fedora users with basic devices, and the complex UI with many tabs and filtering options. --- dispatch.py | 3 +- gui.py | 1 + installclass.py | 1 + instdata.py | 2 + iw/DeviceSelector.py | 191 +++++++ iw/filter_gui.py | 528 +++++++++++++++++ kickstart.py | 2 + pixmaps/filter-menu.png | Bin 0 -> 456 bytes text.py | 1 + ui/filter.glade | 1431 +++++++++++++++++++++++++++++++++++++++++++++++ upgrade.py | 1 + 11 files changed, 2160 insertions(+), 1 deletions(-) create mode 100644 iw/DeviceSelector.py create mode 100644 iw/filter_gui.py create mode 100644 pixmaps/filter-menu.png create mode 100644 ui/filter.glade diff --git a/dispatch.py b/dispatch.py index dbf4269..5beb5bc 100644 --- a/dispatch.py +++ b/dispatch.py @@ -69,6 +69,7 @@ installSteps = [ ("language", ), ("keyboard", ), ("betanag", betaNagScreen, ), + ("filter", ), ("storageinit", storageInitialize, ), ("findrootparts", findRootParts, ), ("findinstall", ), @@ -76,7 +77,7 @@ installSteps = [ ("timezone", ), ("accounts", ), ("setuptime", setupTimezone, ), - ("parttype", ), + ("parttype", ), ("autopartitionexecute", doAutoPartition, ), ("partition", ), ("upgrademount", upgradeMountFilesystems, ), diff --git a/gui.py b/gui.py index c54e935..4d9542c 100755 --- a/gui.py +++ b/gui.py @@ -63,6 +63,7 @@ stepToClass = { "language" : ("language_gui", "LanguageWindow"), "keyboard" : ("kbd_gui", "KeyboardWindow"), "welcome" : ("welcome_gui", "WelcomeWindow"), + "filter" : ("filter_gui", "FilterWindow"), "zfcpconfig" : ("zfcp_gui", "ZFCPWindow"), "partition" : ("partition_gui", "PartitionWindow"), "parttype" : ("autopart_type", "PartitionTypeWindow"), diff --git a/installclass.py b/installclass.py index a490ce9..92c4acd 100644 --- a/installclass.py +++ b/installclass.py @@ -89,6 +89,7 @@ class BaseInstallClass(object): "language", "keyboard", "welcome", + "filter", "storageinit", "findrootparts", "betanag", diff --git a/instdata.py b/instdata.py index 2e1503d..04af9c0 100644 --- a/instdata.py +++ b/instdata.py @@ -299,4 +299,6 @@ class InstallData: self.isHeadless = 0 self.extraModules = extraModules + self.simpleFilter = True + self.reset() diff --git a/iw/DeviceSelector.py b/iw/DeviceSelector.py new file mode 100644 index 0000000..a542b21 --- /dev/null +++ b/iw/DeviceSelector.py @@ -0,0 +1,191 @@ +# +# Filtering UI for the simple path through the storage code. +# +# Copyright (C) 2009 Red Hat, Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +import gtk, gobject +import gtk.glade +import gui + +import gettext +_ = lambda x: gettext.ldgettext("anaconda", x) + +# The column that holds a python object containing information about the +# device in each row. This value really shouldn't be overridden. +OBJECT_COL = 0 + +# These columns can be overridden with the active= and visible= parameters to +# __init__. active indicates which column tracks whether the row is checked +# by default, and visible indicates which column tracks whether the row is +# seen or not. +VISIBLE_COL = 1 +ACTIVE_COL = 2 + +class DeviceDisplayer(object): + def _column_toggled(self, menuItem, col): + # This is called when a selection is made in the column visibility drop + # down menu, and obviously makes a column visible (or not). + col.set_visible(not col.get_visible()) + + def __init__(self, store, model, view, active=ACTIVE_COL, visible=VISIBLE_COL): + self.store = store + self.model = model + self.view = view + + self.menu = None + + self.active = active + self.visible = visible + + def addColumn(self, title, num, displayed=True): + cell = gtk.CellRendererText() + cell.set_property("yalign", 0) + + col = gtk.TreeViewColumn(title, cell, text=num, active=self.active) + col.set_visible(displayed) + col.set_expand(True) + col.set_resizable(True) + self.view.append_column(col) + + # This needs to be set on all columns or it will be impossible to sort + # by that column. + col.set_sort_column_id(num) + + if self.menu: + # Add a new entry to the drop-down menu. + item = gtk.CheckMenuItem(title) + item.set_active(displayed) + item.connect("toggled", self._column_toggled, col) + item.show() + self.menu.append(item) + + def createMenu(self): + self.menu = gtk.Menu() + + # Add a blank column at the (current) end of the view. This column + # exists only so we can have a header to click on and display the + # drop down allowing column configuration. + menuCol = gtk.TreeViewColumn("") + menuCol.set_clickable(True) + menuCol.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) + menuCol.set_fixed_width(30) + menuCol.connect("clicked", lambda col, menu: menu.popup(None, None, None, 0, 0), + self.menu) + + image = gui.readImageFromFile("filter-menu.png") + image.show_all() + menuCol.set_widget(image) + + # Make sure the menu column gets added after all other columns so it + # will be on the far right edge. + self.view.connect("show", lambda x: self.view.append_column(menuCol)) + + def getSelected(self): + """Return a list of all the items currently checked in the UI, or + an empty list if nothing is selected. + """ + retval = [] + iter = self.store.get_iter_first() + + while iter: + if self.store.get_value(iter, self.active): + retval.append(self.store[iter]) + + iter = self.store.iter_next(iter) + + return retval + +class DeviceSelector(DeviceDisplayer): + def createSelectionCol(self, title="", radioButton=False, toggledCB=None): + # Add a column full of checkboxes/radiobuttons in the first column of the view. + crt = gtk.CellRendererToggle() + crt.set_property("activatable", True) + crt.set_property("yalign", 0) + crt.set_radio(radioButton) + + crt.connect("toggled", self._device_toggled, toggledCB, radioButton) + + col = gtk.TreeViewColumn(title, crt, active=self.active) + col.set_alignment(0.75) + + if not radioButton: + self.allButton = gtk.ToggleButton() + col.connect("clicked", lambda *args: self.allButton.set_active(self.allButton.get_active() != True)) + + col.set_widget(self.allButton) + self.allButton.show_all() + + self.allButton.connect("toggled", self._all_clicked, toggledCB) + + self.view.append_column(col) + self.view.set_headers_clickable(True) + + def _all_clicked(self, button, cb=None): + # This is called when the Add/Remove all button is checked and does + # the obvious. + def _toggle_all(model, path, iter, set): + # Don't check the boxes of rows that aren't visible. + visible = model.get_value(iter, self.visible) + if not visible: + return + + # Don't try to set a row to active if it's already been checked. + # This prevents devices that have been checked before the all + # button was checked from getting double counted. + if model.get_value(iter, self.active) == set: + return + + model.set_value(iter, self.active, set) + + if cb: + cb(set, model.get_value(iter, OBJECT_COL)) + + set = button.get_active() + self.store.foreach(_toggle_all, set) + + def _device_toggled(self, button, row, cb, isRadio): + # This is called when the checkbox for a device is clicked or unclicked. + model = self.model + iter = model.get_iter(row) + + if not iter: + return + + while not self.store.iter_is_valid(iter): + iter = model.convert_iter_to_child_iter(iter) + model = model.get_model() + + if isRadio: + # This is lame, but there's no other way to do it. First we have + # to uncheck everything in the store, then we check the one that + # was clicked on. + for r in self.store: + r[self.active] = False + + self.store[iter][self.active] = True + else: + is_checked = self.store.get_value(iter, self.active) + self.store.set_value(iter, self.active, not is_checked) + + if cb: + cb(not is_checked, self.store.get_value(iter, OBJECT_COL)) + +# if self.callback.noneAreSelected(): +# self.allButton.set_active(False) +# elif self.callback.allAreSelected(): +# self.allButton.set_active(True) diff --git a/iw/filter_gui.py b/iw/filter_gui.py new file mode 100644 index 0000000..972d059 --- /dev/null +++ b/iw/filter_gui.py @@ -0,0 +1,528 @@ +# +# Storage filtering UI +# +# Copyright (C) 2009 Red Hat, Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +import block +import gtk, gobject +import gtk.glade +import gui +import parted +from DeviceSelector import * +from baseudev import * +from constants import * +from iw_gui import * +from storage.udev import * +from storage.devicelibs.mpath import * + +import gettext +_ = lambda x: gettext.ldgettext("anaconda", x) + +DEVICE_COL = 3 +MODEL_COL = 4 +CAPACITY_COL = 5 +VENDOR_COL = 6 +INTERCONNECT_COL = 7 +SERIAL_COL = 8 +WWID_COL = 9 +PATHS_COL = 10 +PORT_COL = 11 +TARGET_COL = 12 +LUN_COL = 13 + +# These are global because they need to be accessible across all Callback +# objects as the same values, and from the AdvancedFilterWindow object to add +# and remove devices when populating scrolled windows. +totalDevices = 0 +selectedDevices = 0 +totalSize = 0 +selectedSize = 0 + +# These are global so they can be accessed from all Callback objects. The +# basic callback defines its membership as anything that doesn't pass the +# is* methods. +def isCCISS(info): + return udev_device_is_cciss(info) + +def isRAID(info): + return udev_device_is_md(info) or udev_device_is_biosraid(info) + +def isMultipath(info): + return udev_device_is_multipath_member(info) + +def isOther(info) + return udev_device_is_iscsi(info) or udev_device_is_fcoe(info) + +class Callbacks(object): + def __init__(self, xml): + self.model = None + self.xml = xml + + self.sizeLabel = self.xml.get_widget("sizeLabel") + self.sizeLabel.connect("realize", self._update_size_label) + + def addToUI(self, tuple): + pass + + def deviceToggled(self, set, device): + global selectedDevices, totalDevices + global selectedSize, totalSize + + if set: + selectedDevices += 1 + selectedSize += device["XXX_SIZE"] + else: + selectedDevices -= 1 + selectedSize -= device["XXX_SIZE"] + + self._update_size_label() + + def isMember(self, info): + return info and not isRAID(info) and not isCCISS(info) and \ + not isMultipath(info) and not isOther(info) + + def visible(self, model, iter, view): + # Most basic visibility function - does the model say this row + # should be visible? Subclasses can define their own more specific + # visibility function, though they should also take a look at this + # one to see what the model says. + return self.isMember(model.get_value(iter, OBJECT_COL)) and \ + model.get_value(iter, 1) + + def _update_size_label(self, *args, **kwargs): + global selectedDevices, totalDevices + global selectedSize, totalSize + + self.sizeLabel.set_markup(_("<b>%s device(s) (%s MB) selected</b> out of %s device(s) (%s MB) total.") % (selectedDevices, selectedSize, totalDevices, totalSize)) + +class RAIDCallbacks(Callbacks): + def isMember(self, info): + return info and (isRAID(info) or isCCISS(info)) + +class FilteredCallbacks(Callbacks): + def __init__(self, *args, **kwargs): + Callbacks.__init__(self, *args, **kwargs) + + # Are we even applying the filtering UI? This is False when + # whateverFilterBy is empty, True the rest of the time. + self.filtering = False + + def reset(self): + self.notebook.set_current_page(0) + self.filtering = False + + def set(self, num): + self.notebook.set_current_page(num) + self.filtering = True + +class MPathCallbacks(FilteredCallbacks): + def __init__(self, *args, **kwargs): + FilteredCallbacks.__init__(self, *args, **kwargs) + + self._vendors = [] + self._interconnects = [] + + self.filterBy = self.xml.get_widget("mpathFilterBy") + self.notebook = self.xml.get_widget("mpathNotebook") + + self.vendorEntry = self.xml.get_widget("mpathVendorEntry") + self.interconnectEntry = self.xml.get_widget("mpathInterconnectEntry") + self.WWIDEntry = self.xml.get_widget("mpathWWIDEntry") + + self.vendorEntry.connect("changed", lambda entry: self.model.refilter()) + self.vendorEntry.connect("realize", self._populateUI) + self.interconnectEntry.connect("changed", lambda entry: self.model.refilter()) + self.WWIDEntry.connect("changed", lambda entry: self.model.refilter()) + + def addToUI(self, tuple): + if not tuple[VENDOR_COL] in self._vendors: + self._vendors.append(tuple[VENDOR_COL]) + + if not tuple[INTERCONNECT_COL] in self._interconnects: + self._interconnects.append(tuple[INTERCONNECT_COL]) + + def isMember(self, info): + return info and isMultipath(info) + + def visible(self, model, iter, view): + if not FilteredCallbacks.visible(self, model, iter, view): + return False + + if self.filtering: + if self.notebook.get_current_page() == 0: + return self._visible_by_interconnect(model, iter, view) + elif self.notebook.get_current_page() == 1: + return self._visible_by_vendor(model, iter, view) + elif self.notebook.get_current_page() == 2: + return self._visible_by_wwid(model, iter, view) + + return True + + def _populateUI(self, widget): + self._vendors.sort() + self.vendorEntry.set_model(gtk.ListStore(gobject.TYPE_STRING)) + for v in self._vendors: + self.vendorEntry.append_text(v) + + self._interconnects.sort() + self.interconnectEntry.set_model(gtk.ListStore(gobject.TYPE_STRING)) + for i in self._interconnects: + self.interconnectEntry.append_text(i) + + def _visible_by_vendor(self, model, iter, view): + return model.get_value(iter, VENDOR_COL) == self.vendorEntry.get_text() + + def _visible_by_interconnect(self, model, iter, view): + return model.get_value(iter, INTERCONNECT_COL) == self.interconnectEntry.get_text() + + def _visible_by_wwid(self, model, iter, view): + # FIXME: make this support globs, etc. + entered = self.WWIDEntry.get_text() + + return entered != "" and model.get_value(iter, WWID_COL).find(entered) != -1 + +class OtherCallbacks(MPathCallbacks): + def __init__(self, *args, **kwargs): + FilteredCallbacks.__init__(self, *args, **kwargs) + + self._vendors = [] + self._interconnects = [] + + self.filterBy = self.xml.get_widget("otherFilterBy") + self.notebook = self.xml.get_widget("otherNotebook") + + self.vendorEntry = self.xml.get_widget("otherVendorEntry") + self.interconnectEntry = self.xml.get_widget("otherInterconnectEntry") + self.WWIDEntry = self.xml.get_widget("otherWWIDEntry") + + self.vendorEntry.connect("changed", lambda entry: self.model.refilter()) + self.vendorEntry.connect("realize", self._populateUI) + self.interconnectEntry.connect("changed", lambda entry: self.model.refilter()) + self.WWIDEntry.connect("changed", lambda entry: self.model.refilter()) + + def isMember(self, info): + return info and isOther(info) + +class SearchCallbacks(FilteredCallbacks): + def __init__(self, *args, **kwargs): + FilteredCallbacks.__init__(self, *args, **kwargs) + + self._ports = [] + self._targets = [] + self._luns = [] + + self.filterBy = self.xml.get_widget("searchFilterBy") + self.notebook = self.xml.get_widget("searchNotebook") + + self.portEntry = self.xml.get_widget("searchPortEntry") + self.targetEntry = self.xml.get_widget("searchTargetEntry") + self.LUNEntry = self.xml.get_widget("searchLUNEntry") + self.WWIDEntry = self.xml.get_widget("searchWWIDEntry") + + # When these entries are changed, we need to redo the filtering. + # If we don't do filter-as-you-type, we'd need a Search/Clear button. + self.portEntry.connect("changed", lambda entry: self.model.refilter()) + self.targetEntry.connect("changed", lambda entry: self.model.refilter()) + self.LUNEntry.connect("changed", lambda entry: self.model.refilter()) + self.WWIDEntry.connect("changed", lambda entry: self.model.refilter()) + + def isMember(self, info): + return True + + def visible(self, model, iter, view): + if not model.get_value(iter, 1): + return False + + if self.filtering: + if self.notebook.get_current_page() == 0: + return self._visible_by_ptl(model, iter, view) + else: + return self._visible_by_wwid(model, iter, view) + + return True + + def _visible_by_ptl(self, model, iter, view): + rowPort = model.get_value(iter, PORT_COL) + rowTarget = model.get_value(iter, TARGET_COL) + rowLUN = model.get_value(iter, LUN_COL) + + enteredPort = self.portEntry.get_text() + enteredTarget = self.targetEntry.get_text() + enteredLUN = self.LUNEntry.get_text() + + return (not enteredPort or enteredPort and enteredPort == rowPort) and \ + (not enteredTarget or enteredTarget and enteredTarget == rowTarget) and \ + (not enteredLUN or enteredLUN and enteredLUN == rowLUN) + + def _visible_by_wwid(self, model, iter, view): + # FIXME: make this support globs, etc. + entered = self.WWIDEntry.get_text() + + return entered != "" and model.get_value(iter, WWID_COL).find(entered) != -1 + +class NotebookPage(object): + def __init__(self, store, name, xml, cb): + # Every page needs a ScrolledWindow to display the results in. + self.scroll = xml.get_widget("%sScroll" % name) + + self.sortedModel = gtk.TreeModelSort(store) + self.filteredModel = store.filter_new() + self.treeView = gtk.TreeView(self.filteredModel) + + self.scroll.add(self.treeView) + + self.cb = cb + self.cb.model = self.filteredModel + + self.ds = DeviceSelector(store, self.filteredModel, self.treeView, + visible=VISIBLE_COL, active=ACTIVE_COL) + self.ds.createMenu() + self.ds.createSelectionCol(toggledCB=self.cb.deviceToggled) + + self.filteredModel.set_visible_func(self.cb.visible, self.treeView) + + # Not every NotebookPage will have a filter box - just those that do + # some sort of filtering (obviously). + self.filterBox = xml.get_widget("%sFilterHBox" % name) + + if self.filterBox: + self.filterBy = xml.get_widget("%sFilterBy" % name) + self.filterBy.connect("changed", self._filter_by_changed) + + # However if the page has a filter box, then it must also have a + # notebook with an easily discoverable name. + self.notebook = xml.get_widget("%sNotebook" % name) + + def _filter_by_changed(self, combo): + active = combo.get_active() + + if active == -1: + self.cb.reset() + else: + self.cb.set(active) + + self.filteredModel.refilter() + +class FilterWindow(InstallWindow): + windowTitle = N_("Device Filter") + + def getNext(self): + # All pages use the same store, so we only need to use the first one. + # However, we do need to make sure all paths from multipath devices + # are in the list. + selected = set() + for dev in self.pages[0].ds.getSelected(): + for path in dev[PATHS_COL].split(): + selected.add(path) + + selected.add(udev_device_get_name(dev[OBJECT_COL])) + + if len(selected) == 0: + self.anaconda.intf.messageWindow(_("Error"), + _("You must select at least one " + "drive to be used for installation."), + custom_icon="error") + raise gui.StayOnScreen + + self.anaconda.id.storage.exclusiveDisks.extend(list(selected)) + + def _addTuple(self, tuple): + global totalDevices, totalSize + + self.store.append(None, tuple) + totalDevices += 1 + totalSize += tuple[0]["XXX_SIZE"] + + for pg in self.pages: + if pg.cb.isMember(tuple[0]): + pg.cb.addToUI(tuple) + + def _makeBasic(self): + np = NotebookPage(self.store, "basic", self.xml, Callbacks(self.xml)) + + np.ds.addColumn(_("Model"), MODEL_COL) + np.ds.addColumn(_("Capacity"), CAPACITY_COL) + np.ds.addColumn(_("Vendor"), VENDOR_COL) + np.ds.addColumn(_("Interconnect"), INTERCONNECT_COL) + np.ds.addColumn(_("Serial Number"), SERIAL_COL) + return np + + def _makeRAID(self): + np = NotebookPage(self.store, "raid", self.xml, RAIDCallbacks(self.xml)) + + np.ds.addColumn(_("Device"), DEVICE_COL) + np.ds.addColumn(_("Capacity"), CAPACITY_COL) + return np + + def _makeMPath(self): + np = NotebookPage(self.store, "mpath", self.xml, MPathCallbacks(self.xml)) + + np.ds.addColumn(_("WWID"), WWID_COL) + np.ds.addColumn(_("Capacity"), CAPACITY_COL) + np.ds.addColumn(_("Vendor"), VENDOR_COL) + np.ds.addColumn(_("Interconnect"), INTERCONNECT_COL) + np.ds.addColumn(_("Paths"), PATHS_COL) + return np + + def _makeOther(self) + np = NotebookPage(self.store, "other", self.xml, OtherCallbacks(self.xml)) + + np.ds.addColumn(_("WWID"), WWID_COL) + np.ds.addColumn(_("Capacity"), CAPACITY_COL) + np.ds.addColumn(_("Vendor"), VENDOR_COL) + np.ds.addColumn(_("Interconnect"), INTERCONNECT_COL) + return np + + def _makeSearch(self): + np = NotebookPage(self.store, "search", self.xml, SearchCallbacks(self.xml)) + + np.ds.addColumn(_("Model"), MODEL_COL) + np.ds.addColumn(_("Capacity"), CAPACITY_COL, displayed=False) + np.ds.addColumn(_("Vendor"), VENDOR_COL) + np.ds.addColumn(_("Interconnect"), INTERCONNECT_COL, displayed=False) + np.ds.addColumn(_("Serial Number"), SERIAL_COL, displayed=False) + np.ds.addColumn(_("WWID"), WWID_COL) + np.ds.addColumn(_("Port"), PORT_COL) + np.ds.addColumn(_("Target"), TARGET_COL) + np.ds.addColumn(_("LUN"), LUN_COL) + return np + + def _page_switched(self, notebook, useless, page_num): + # When the page is switched, we need to change what is visible so the + # Select All button only selects/deselected things on the current page. + # Unfortunately, the only way to do this is iterate over all rows and + # check for membership. + for line in self.store: + line[VISIBLE_COL] = self.pages[page_num].cb.isMember(line[OBJECT_COL]) + + def getScreen(self, anaconda): + (self.xml, self.vbox) = gui.getGladeWidget("filter.glade", "vbox") + self.buttonBox = self.xml.get_widget("buttonBox") + self.notebook = self.xml.get_widget("notebook") + + self.notebook.connect("switch-page", self._page_switched) + + 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), + # 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_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 anaconda.id.simpleFilter: + self.pages = [self._makeBasic()] + self.notebook.set_show_border(False) + self.notebook.set_show_tabs(False) + else: + self.pages = [self._makeBasic(), self._makeRAID(), + self._makeMPath(), self._makeOther(), + self._makeSearch()] + + udev_trigger(subsystem="block") + all_devices = filter(udev_device_is_disk, udev_get_block_devices()) + (all_devices, mpaths, partitions) = identifyMultipaths(all_devices) + + # 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. + (raid_devices, devices) = self.partition_list(lambda d: isRAID(d) and not isCCISS(d), + all_devices) + + for d in devices: + partedDevice = parted.Device(path="/dev/" + udev_device_get_name(d)) + d["XXX_SIZE"] = int(partedDevice.getSize()) + + tuple = (d, True, False, udev_device_get_name(d), + partedDevice.model, str(d["XXX_SIZE"]) + " MB", + udev_device_get_vendor(d), udev_device_get_bus(d), + udev_device_get_serial(d), udev_device_get_wwid(d), + "", "", "", "") + self._addTuple(tuple) + + for md in block.getRaidSets(): + md.activate(mknod=True, mkparts=False) + udev_settle() + + partedDevice = md.PedDevice + size = int(partedDevice.getSize()) + fstype = "" + + members = map(lambda m: m.get_devpath(), list(md.get_members())) + for d in raid_devices: + if udev_device_get_name(d) in members: + fstype = udev_device_get_format(d) + break + + # biosraid devices don't really get udev data, at least not in a + # way that's useful to the filtering UI. So we need to fake that + # data now so we have something to put into the store. + data = {"XXX_SIZE": size, "ID_FS_TYPE": fstype, "DM_NAME": md.name, + "name": md.name} + + tuple = (data, True, False, md.name, partedDevice.model, + str(size) + " MB", "", "", "", "", "", "", "", "") + self._addTuple(tuple) + + md.deactivate() + + for mpath in mpaths: + # We only need to grab information from the first device in the set. + partedDevice = parted.Device(path="/dev/" + udev_device_get_name(mpath[0])) + mpath[0]["XXX_SIZE"] = int(partedDevice.getSize()) + model = partedDevice.model + + # However, we do need all the paths making up this multipath set. + paths = "\n".join(map(udev_device_get_name, mpath)) + + tuple = (mpath[0], True, False, "", model, + str(mpath[0]["XXX_SIZE"]) + " MB", + udev_device_get_vendor(mpath[0]), + udev_device_get_bus(mpath[0]), + udev_device_get_serial(mpath[0]), + udev_device_get_wwid(mpath[0]), + paths, "", "", "") + self._addTuple(tuple) + + return self.vbox + + def partition_list(self, pred, lst): + pos = [] + neg = [] + + for ele in lst: + if pred(ele): + pos.append(ele) + else: + neg.append(ele) + + return (pos, neg) diff --git a/kickstart.py b/kickstart.py index a28eb03..147e48d 100644 --- a/kickstart.py +++ b/kickstart.py @@ -333,6 +333,7 @@ class IgnoreDisk(commands.ignoredisk.F8_IgnoreDisk): def execute(self, anaconda): anaconda.id.storage.ignoredDisks = self.ignoredisk anaconda.id.storage.exclusiveDisks = self.onlyuse + self.handler.skipSteps.extend(["filter"]) class IscsiData(commands.iscsi.F10_IscsiData): def execute(self, anaconda): @@ -1408,6 +1409,7 @@ def setSteps(anaconda): # out if we don't. if anaconda.id.displayMode == "t": missingSteps = [("bootloader", "Bootloader configuration"), + ("filter", "Disks to use in installation"), ("group-selection", "Package selection")] errors = [] diff --git a/pixmaps/filter-menu.png b/pixmaps/filter-menu.png new file mode 100644 index 0000000000000000000000000000000000000000..037519f9dcd2e216430a8a6a64974cfef9f68aa0 GIT binary patch literal 456 zcmV;(0XP1MP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004b3#c}2nYxW zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10YynfK~zYI?NmKW!%!4G_tD`MD!4hj8GKMkLWyMTl7hdY{s9-q z(3Fgw-Q4^G?!_?>2^~bFV}F8zgBc9hsUb~YqK$1)@W6$0&%M0!xbK6Q8M}no>FWD1 zXqAQWczjsQN2Aee6TQ*^z{`@vag4!WkQW@sDQ=`{(^O2fBkCFkx`qJ&ShV|CwEJs% z6)$7|X8-_?^LfsX-|w}06<-50uS5_8yoBd@Je*8<IGM8NdAVNf(eRb^{{B1oH~13T zYnrC1ws}(>0I2+3hhg|eL@fY_qDU5NuIr`%kY!n}3n4&6DF86@hwu9bwFcWp<1<i7 zb?WjT87QSXQp#t`vd#g(w(S!s<x{WMJ1zG%9+7F9XF`ZOBD!Jb3nIEolH_)41^{5& ywh7>YnJ;Iv*|oN*{5fqJN~xo|`tQ9(-^C~Aq4s7|cda@A0000<MNUMnLSTZTzQq;* literal 0 HcmV?d00001 diff --git a/text.py b/text.py index 89f017d..5b8900d 100644 --- a/text.py +++ b/text.py @@ -549,6 +549,7 @@ class InstallInterface: self.screen.finish() def setSteps(self, anaconda): + anaconda.dispatch.skipStep("filter") anaconda.dispatch.skipStep("basepkgsel") anaconda.dispatch.skipStep("group-selection") diff --git a/ui/filter.glade b/ui/filter.glade new file mode 100644 index 0000000..a889418 --- /dev/null +++ b/ui/filter.glade @@ -0,0 +1,1431 @@ +<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> +<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> + +<glade-interface> + +<widget class="GtkWindow" id="advancedFilterWindow"> + <property name="border_width">6</property> + <property name="title" translatable="yes" context="yes"></property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_NONE</property> + <property name="modal">False</property> + <property name="resizable">True</property> + <property name="destroy_with_parent">False</property> + <property name="decorated">True</property> + <property name="skip_taskbar_hint">False</property> + <property name="skip_pager_hint">False</property> + <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property> + <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> + <property name="focus_on_map">True</property> + <property name="urgency_hint">False</property> + + <child> + <widget class="GtkVBox" id="vbox"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label1"> + <property name="width_request">600</property> + <property name="visible">True</property> + <property name="label" translatable="yes">Please select both the drives you'd like to install the operating system on and any devices you'd like to automatically mount to your system below:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">True</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkNotebook" id="notebook"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="show_tabs">True</property> + <property name="show_border">True</property> + <property name="tab_pos">GTK_POS_TOP</property> + <property name="scrollable">False</property> + <property name="enable_popup">False</property> + + <child> + <widget class="GtkScrolledWindow" id="basicScroll"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <placeholder/> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label4"> + <property name="visible">True</property> + <property name="label" translatable="yes">Basic Devices</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> + <widget class="GtkScrolledWindow" id="raidScroll"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <placeholder/> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label5"> + <property name="visible">True</property> + <property name="label" translatable="yes">Firmware RAID</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="mpathVBox"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkHBox" id="mpathFilterHBox"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label11"> + <property name="visible">True</property> + <property name="label" translatable="yes">Filter By:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkComboBoxEntry" id="mpathFilterBy"> + <property name="visible">True</property> + <property name="items" translatable="yes">Interconnect +Vendor +WWID</property> + <property name="add_tearoffs">False</property> + <property name="has_frame">True</property> + <property name="focus_on_click">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkNotebook" id="mpathNotebook"> + <property name="visible">True</property> + <property name="show_tabs">False</property> + <property name="show_border">False</property> + <property name="tab_pos">GTK_POS_TOP</property> + <property name="scrollable">False</property> + <property name="enable_popup">False</property> + + <child> + <widget class="GtkHBox" id="hbox11"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label28"> + <property name="visible">True</property> + <property name="label" translatable="yes">Show Only Devices Using:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkComboBoxEntry" id="mpathInterconnectEntry"> + <property name="visible">True</property> + <property name="add_tearoffs">False</property> + <property name="has_frame">True</property> + <property name="focus_on_click">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label29"> + <property name="visible">True</property> + <property name="label" translatable="yes">label22</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox12"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label30"> + <property name="visible">True</property> + <property name="label" translatable="yes">Show Only Devices From:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkComboBoxEntry" id="mpathVendorEntry"> + <property name="visible">True</property> + <property name="add_tearoffs">False</property> + <property name="has_frame">True</property> + <property name="focus_on_click">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label31"> + <property name="visible">True</property> + <property name="label" translatable="yes">label23</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox13"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label32"> + <property name="visible">True</property> + <property name="label" translatable="yes">Show WWIDs that Include:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="mpathWWIDEntry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char">â??</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label33"> + <property name="visible">True</property> + <property name="label" translatable="yes">label24</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkScrolledWindow" id="mpathScroll"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <placeholder/> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label6"> + <property name="visible">True</property> + <property name="label" translatable="yes">Multipath Devices</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="otherVBox"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkHBox" id="otherFilterHBox"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label35"> + <property name="visible">True</property> + <property name="label" translatable="yes">Filter By:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkComboBoxEntry" id="otherFilterBy"> + <property name="visible">True</property> + <property name="items" translatable="yes">Interconnect +Vendor +WWID</property> + <property name="add_tearoffs">False</property> + <property name="has_frame">True</property> + <property name="focus_on_click">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkNotebook" id="otherNotebook"> + <property name="visible">True</property> + <property name="show_tabs">False</property> + <property name="show_border">False</property> + <property name="tab_pos">GTK_POS_TOP</property> + <property name="scrollable">False</property> + <property name="enable_popup">False</property> + + <child> + <widget class="GtkHBox" id="hbox15"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label36"> + <property name="visible">True</property> + <property name="label" translatable="yes">Show Only Devices Using:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkComboBoxEntry" id="otherInterconnectEntry"> + <property name="visible">True</property> + <property name="add_tearoffs">False</property> + <property name="has_frame">True</property> + <property name="focus_on_click">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label37"> + <property name="visible">True</property> + <property name="label" translatable="yes">label22</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox16"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label38"> + <property name="visible">True</property> + <property name="label" translatable="yes">Show Only Devices From:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkComboBoxEntry" id="otherVendorEntry"> + <property name="visible">True</property> + <property name="add_tearoffs">False</property> + <property name="has_frame">True</property> + <property name="focus_on_click">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label39"> + <property name="visible">True</property> + <property name="label" translatable="yes">label23</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox17"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label40"> + <property name="visible">True</property> + <property name="label" translatable="yes">Show WWIDs that Include:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="otherWWIDEntry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char">â??</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label41"> + <property name="visible">True</property> + <property name="label" translatable="yes">label24</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkScrolledWindow" id="otherScroll"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <placeholder/> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label34"> + <property name="visible">True</property> + <property name="label" translatable="yes">Other SAN Devices</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="searchVBox"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkHBox" id="searchFilterHBox"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label15"> + <property name="visible">True</property> + <property name="label" translatable="yes">Search By:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkComboBoxEntry" id="searchFilterBy"> + <property name="visible">True</property> + <property name="items" translatable="yes">Port / Target / LUN +Target WWID</property> + <property name="add_tearoffs">False</property> + <property name="has_frame">True</property> + <property name="focus_on_click">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkNotebook" id="searchNotebook"> + <property name="visible">True</property> + <property name="show_tabs">False</property> + <property name="show_border">False</property> + <property name="tab_pos">GTK_POS_TOP</property> + <property name="scrollable">False</property> + <property name="enable_popup">False</property> + + <child> + <widget class="GtkHBox" id="hbox6"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label18"> + <property name="visible">True</property> + <property name="label" translatable="yes">Port:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="searchPortEntry"> + <property name="width_request">50</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char">â??</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label19"> + <property name="visible">True</property> + <property name="label" translatable="yes">Target:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="searchTargetEntry"> + <property name="width_request">50</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char">â??</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label20"> + <property name="visible">True</property> + <property name="label" translatable="yes">LUN:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="searchLUNEntry"> + <property name="width_request">50</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char">â??</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label16"> + <property name="visible">True</property> + <property name="label" translatable="yes">label16</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox7"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label21"> + <property name="visible">True</property> + <property name="label" translatable="yes">WWID:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="searchWWIDEntry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char">â??</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label17"> + <property name="visible">True</property> + <property name="label" translatable="yes">label17</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label10"> + <property name="visible">True</property> + <property name="label" translatable="yes">Search Results:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkScrolledWindow" id="searchScroll"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <placeholder/> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label8"> + <property name="visible">True</property> + <property name="label" translatable="yes">Search</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkHButtonBox" id="buttonBox"> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_END</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkButton" id="addISCSIButton"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + + <child> + <widget class="GtkAlignment" id="alignment1"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + <property name="top_padding">0</property> + <property name="bottom_padding">0</property> + <property name="left_padding">0</property> + <property name="right_padding">0</property> + + <child> + <widget class="GtkHBox" id="hbox2"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">2</property> + + <child> + <widget class="GtkImage" id="image2"> + <property name="visible">True</property> + <property name="stock">gtk-add</property> + <property name="icon_size">4</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label9"> + <property name="visible">True</property> + <property name="label" translatable="yes">Add iSCSI Target</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="sizeLabel"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>%s devices (%s) selected</b> out of %s devices (%s) total.</property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox1"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkImage" id="image1"> + <property name="visible">True</property> + <property name="stock">gtk-dialog-info</property> + <property name="icon_size">4</property> + <property name="xalign">0.5</property> + <property name="yalign">0</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label3"> + <property name="width_request">600</property> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Tip:</b> Selecting a drive on this screen does not necessarily mean it will be wiped by the installation process. Also, note that post-installation you may mount drives you did not select here by modifying your /etc/fstab file.</property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">True</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> +</widget> + +</glade-interface> diff --git a/upgrade.py b/upgrade.py index c751533..99ae786 100644 --- a/upgrade.py +++ b/upgrade.py @@ -281,6 +281,7 @@ def setSteps(anaconda): "language", "keyboard", "welcome", + "filter", "installtype", "storageinit", "findrootparts", -- 1.6.5.1 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list