summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lumens <clumens@redhat.com>2009-10-05 15:12:36 -0400
committerChris Lumens <clumens@redhat.com>2009-12-11 17:15:35 -0500
commit2984bbb90f3be6568cdeb9af1834b56ba245c92f (patch)
tree051d2d40714a466b84ccddfcb1e92598901f6104
parent92cb83bec3dcd1b2590538b10af58332ab017522 (diff)
downloadanaconda-2984bbb90f3be6568cdeb9af1834b56ba245c92f.tar.gz
anaconda-2984bbb90f3be6568cdeb9af1834b56ba245c92f.tar.xz
anaconda-2984bbb90f3be6568cdeb9af1834b56ba245c92f.zip
Add a step to prompt for the cleardisks UI.
This UI is the screen that allows the user to select which devices will be wiped during installation and which should just be mounted. It also allows selecting which device the bootloader should be installed to.
-rw-r--r--dispatch.py1
-rwxr-xr-xgui.py1
-rw-r--r--installclass.py1
-rw-r--r--iw/cleardisks_gui.py201
-rw-r--r--kickstart.py2
-rw-r--r--text.py1
-rw-r--r--ui/cleardisks.glade300
-rw-r--r--upgrade.py1
8 files changed, 508 insertions, 0 deletions
diff --git a/dispatch.py b/dispatch.py
index 5beb5bc7b..3c0db0cc7 100644
--- a/dispatch.py
+++ b/dispatch.py
@@ -78,6 +78,7 @@ installSteps = [
("accounts", ),
("setuptime", setupTimezone, ),
("parttype", ),
+ ("cleardiskssel", ),
("autopartitionexecute", doAutoPartition, ),
("partition", ),
("upgrademount", upgradeMountFilesystems, ),
diff --git a/gui.py b/gui.py
index cbacd530d..89feee026 100755
--- a/gui.py
+++ b/gui.py
@@ -67,6 +67,7 @@ stepToClass = {
"zfcpconfig" : ("zfcp_gui", "ZFCPWindow"),
"partition" : ("partition_gui", "PartitionWindow"),
"parttype" : ("autopart_type", "PartitionTypeWindow"),
+ "cleardiskssel": ("cleardisks_gui", "ClearDisksWindow"),
"findinstall" : ("examine_gui", "UpgradeExamineWindow"),
"addswap" : ("upgrade_swap_gui", "UpgradeSwapWindow"),
"upgrademigratefs" : ("upgrade_migratefs_gui", "UpgradeMigrateFSWindow"),
diff --git a/installclass.py b/installclass.py
index 92c4acd3c..8cdb880b7 100644
--- a/installclass.py
+++ b/installclass.py
@@ -94,6 +94,7 @@ class BaseInstallClass(object):
"findrootparts",
"betanag",
"installtype",
+ "cleardiskssel",
"parttype",
"autopartitionexecute",
"partition",
diff --git a/iw/cleardisks_gui.py b/iw/cleardisks_gui.py
new file mode 100644
index 000000000..2ac8c6812
--- /dev/null
+++ b/iw/cleardisks_gui.py
@@ -0,0 +1,201 @@
+#
+# Select which disks to clear and which ones to just mount.
+#
+# 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 gui
+from DeviceSelector import *
+from constants import *
+import isys
+from iw_gui import *
+from storage.udev import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class ClearDisksWindow (InstallWindow):
+ windowTitle = N_("Clear Disks Selector")
+
+ def getNext (self):
+ # All the rows that are visible in the right hand side should be cleared.
+ cleardisks = []
+ for row in self.store:
+ if row[self.rightVisible]:
+ cleardisks.append(row[OBJECT_COL].name)
+
+ if len(cleardisks) == 0:
+ self.anaconda.intf.messageWindow(_("Error"),
+ _("You must select at least one "
+ "drive to be used for installation."),
+ custom_icon="error")
+ raise gui.StayOnScreen
+
+ # The selected row is the disk to boot from.
+ selected = self.rightDS.getSelected()
+
+ if len(selected) == 0:
+ self.anaconda.intf.messageWindow(_("Error"),
+ _("You must select one drive to "
+ "boot from."),
+ custom_icon="error")
+ raise gui.StayOnScreen
+
+ bootDisk = selected[0][OBJECT_COL].name
+
+ cleardisks.sort(isys.compareDrives)
+
+ self.anaconda.id.storage.clearPartDisks.extend(cleardisks + [bootDisk])
+ self.anaconda.id.bootloader.drivelist = [bootDisk] + cleardisks
+
+ def getScreen (self, anaconda):
+ (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 = 3
+ self.rightActive = 4
+
+ # 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.
+ self.store = gtk.TreeStore(gobject.TYPE_PYOBJECT,
+ 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(5, 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.leftSortedModel = gtk.TreeModelSort(self.store)
+ self.leftFilteredModel = self.store.filter_new()
+ self.leftTreeView = gtk.TreeView(self.leftFilteredModel)
+
+ 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.leftFilteredModel,
+ self.leftTreeView, visible=self.leftVisible,
+ active=self.leftActive)
+ self.leftDS.createMenu()
+ self.leftDS.addColumn(_("Model"), 5)
+ self.leftDS.addColumn(_("Capacity"), 6)
+ self.leftDS.addColumn(_("Vendor"), 7)
+ self.leftDS.addColumn(_("Interconnect"), 8, displayed=False)
+ self.leftDS.addColumn(_("Serial Number"), 9, displayed=False)
+
+ # The right view show all the drives that will be wiped during install.
+ self.rightSortedModel = gtk.TreeModelSort(self.store)
+ self.rightFilteredModel = self.store.filter_new()
+ self.rightTreeView = gtk.TreeView(self.rightFilteredModel)
+
+ 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.rightFilteredModel,
+ self.rightTreeView, visible=self.rightVisible,
+ active=self.rightActive)
+ self.rightDS.createSelectionCol(title=_("Boot"), radioButton=True)
+ self.rightDS.addColumn(_("Model"), 5)
+ self.rightDS.addColumn(_("Capacity"), 6)
+
+ # 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 self.anaconda.id.storage.exclusiveDisks:
+ device = self.anaconda.id.storage.devicetree.getDeviceByName(d)
+ if not device:
+ continue
+
+ self.store.append(None, (device, True, True, False, False,
+ device.partedDevice.model,
+ str(int(device.size)) + " MB",
+ device.vendor, "", device.serial))
+
+ self.addButton.connect("clicked", self._add_clicked)
+ self.removeButton.connect("clicked", self._remove_clicked)
+
+ if self.anaconda.id.storage.clearPartType == CLEARPART_TYPE_LINUX:
+ self.installTargetTip.set_markup(_("<b>Tip:</b> All Linux filesystems on install target devices will be reformatted and wiped of any data. Make sure you have backups."))
+ elif self.anaconda.id.storage.clearPartType == CLEARPART_TYPE_ALL:
+ self.installTargetTip.set_markup(_("<b>Tip:</b> 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 install target devices will not be wiped unless you choose to do so during customization."))
+
+ return self.vbox
+
+ def _add_clicked(self, button):
+ (filteredModel, filteredIter) = self.leftTreeView.get_selection().get_selected()
+
+ if not filteredIter:
+ return
+
+ # If this is the first row going into the rightDS, it should be checked
+ # by default.
+ if self.rightDS.getNVisible() == 0:
+ active = True
+ else:
+ active = False
+
+ sortedIter = self.leftFilteredModel.convert_iter_to_child_iter(filteredIter)
+
+ self.store.set_value(sortedIter, self.leftVisible, False)
+ self.store.set_value(sortedIter, self.rightVisible, True)
+ self.store.set_value(sortedIter, self.rightActive, active)
+
+ self.leftFilteredModel.refilter()
+ self.rightFilteredModel.refilter()
+
+ def _remove_clicked(self, button):
+ (filteredModel, filteredIter) = self.rightTreeView.get_selection().get_selected()
+
+ if not filteredIter:
+ return
+
+ sortedIter = self.rightFilteredModel.convert_iter_to_child_iter(filteredIter)
+
+ # If we're removing a row that was checked and there are other rows
+ # available, check the first visible one.
+ if self.store.get_value(sortedIter, self.rightActive) and self.rightDS.getNVisible() > 1:
+ i = 0
+
+ # Make sure to skip the current row, of course.
+ while not self.store[i][self.rightVisible] or self.store[i][0] == self.store[sortedIter][0]:
+ i += 1
+
+ self.store[i][self.rightActive] = True
+
+ self.store.set_value(sortedIter, self.leftVisible, True)
+ self.store.set_value(sortedIter, self.rightVisible, False)
+ self.store.set_value(sortedIter, self.rightActive, False)
+
+ self.leftFilteredModel.refilter()
+ self.rightFilteredModel.refilter()
diff --git a/kickstart.py b/kickstart.py
index 1ba98361c..569123570 100644
--- a/kickstart.py
+++ b/kickstart.py
@@ -296,6 +296,7 @@ class ClearPart(commands.clearpart.FC3_ClearPart):
anaconda.id.storage.reinitializeDisks = self.initAll
clearPartitions(anaconda.id.storage)
+ self.handler.skipSteps.append("cleardisksel")
class FcoeData(commands.fcoe.F13_FcoeData):
def execute(self, anaconda):
@@ -1436,6 +1437,7 @@ def setSteps(anaconda):
if anaconda.id.displayMode == "t":
missingSteps = [("bootloader", "Bootloader configuration"),
("filter", "Disks to use in installation"),
+ ("cleardisksel", "Disks to clear"),
("group-selection", "Package selection")]
errors = []
diff --git a/text.py b/text.py
index fbb83f3df..c984f8ba8 100644
--- a/text.py
+++ b/text.py
@@ -550,6 +550,7 @@ class InstallInterface:
def setSteps(self, anaconda):
anaconda.dispatch.skipStep("filter")
+ anaconda.dispatch.skipStep("cleardisksel")
anaconda.dispatch.skipStep("basepkgsel")
anaconda.dispatch.skipStep("group-selection")
diff --git a/ui/cleardisks.glade b/ui/cleardisks.glade
new file mode 100644
index 000000000..956ecfebb
--- /dev/null
+++ b/ui/cleardisks.glade
@@ -0,0 +1,300 @@
+<?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="cleardisksWindow">
+ <property name="border_width">6</property>
+ <property name="width_request">600</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">12</property>
+
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="width_request">600</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Below are the storage devices you've selected to be a part of this installation. Please indicate using the arrows below which devices you'd like to use as data drives (these will not be formatted, only mounted) and which devices you'd like to use as system drives (these may be formatted).</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="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Data Storage Devices&lt;/b&gt; (to be mounted only)</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.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="GtkScrolledWindow" id="leftScroll">
+ <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="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVButtonBox" id="vbuttonbox1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkButton" id="addButton">
+ <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="GtkImage" id="image3">
+ <property name="visible">True</property>
+ <property name="stock">gtk-go-forward</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>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="removeButton">
+ <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="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="stock">gtk-go-back</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>
+ </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="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Install Target Devices&lt;/b&gt;</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.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="GtkScrolledWindow" id="rightScroll">
+ <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="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">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="installTargetHBox">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkImage" id="installTargetImage">
+ <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="installTargetTip">
+ <property name="width_request">600</property>
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Tip:&lt;/b&gt; Install target devices will be reformatted and wiped of any data. Make sure you have backups.</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 3dfd4fec9..f9caa11ca 100644
--- a/upgrade.py
+++ b/upgrade.py
@@ -266,6 +266,7 @@ def setSteps(anaconda):
"keyboard",
"welcome",
"filter",
+ "cleardisksel",
"installtype",
"storageinit",
"findrootparts",