[node-patches] Change in ovirt-node[master]: installer: Add storage vol page and more
fabiand at fedoraproject.org
fabiand at fedoraproject.org
Mon Jan 28 17:34:53 UTC 2013
Fabian Deutsch has uploaded a new change for review.
Change subject: installer: Add storage vol page and more
......................................................................
installer: Add storage vol page and more
Change-Id: I5d485cb9d5740012cd666fd7a28c640af12bdfca
Signed-off-by: Fabian Deutsch <fabiand at fedoraproject.org>
---
M scripts/tui/src/ovirt/node/base.py
M scripts/tui/src/ovirt/node/config/defaults.py
M scripts/tui/src/ovirt/node/installer/boot_device_page.py
M scripts/tui/src/ovirt/node/installer/installation_device_page.py
M scripts/tui/src/ovirt/node/installer/password_page.py
M scripts/tui/src/ovirt/node/installer/progress_page.py
A scripts/tui/src/ovirt/node/installer/storage_vol_page.py
M scripts/tui/src/ovirt/node/ui/urwid_builder.py
M scripts/tui/src/ovirt/node/ui/widgets.py
9 files changed, 240 insertions(+), 62 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/ovirt-node refs/changes/81/11481/1
diff --git a/scripts/tui/src/ovirt/node/base.py b/scripts/tui/src/ovirt/node/base.py
index c929696..ec501b8 100644
--- a/scripts/tui/src/ovirt/node/base.py
+++ b/scripts/tui/src/ovirt/node/base.py
@@ -64,7 +64,8 @@
for idx, cb in enumerate(self.callbacks):
self.logger.debug("(%d/%d) Emitting from %s: %s" %
(idx + 1, len(self.callbacks), self, cb))
- cb(target, userdata)
+ if cb(target, userdata) is False:
+ self.logger.debug("Breaking callback sequence")
return self
def connect(self, cb):
diff --git a/scripts/tui/src/ovirt/node/config/defaults.py b/scripts/tui/src/ovirt/node/config/defaults.py
index 00a1a71..679ba95 100644
--- a/scripts/tui/src/ovirt/node/config/defaults.py
+++ b/scripts/tui/src/ovirt/node/config/defaults.py
@@ -1164,13 +1164,13 @@
return tx
-class Storage(NodeConfigFileSection):
- """Configure storage
- This is a class to handle the storage parameters used at installation time
+class Installation(NodeConfigFileSection):
+ """Configure installation
+ This is a class to handle the parameters used at installation time
>>> fn = "/tmp/cfg_dummy"
>>> cfgfile = ConfigFile(fn, SimpleProvider)
- >>> n = Storage(cfgfile)
+ >>> n = Installation(cfgfile)
>>> kwargs = {"init": "/dev/sda", "root_install": "/dev/sdb"}
>>> n.update(**kwargs)
>>> data = n.retrieve().items()
@@ -1181,7 +1181,6 @@
>>> data[6:9]
[('logging_size', None), ('swap_size', None), ('root_size', None)]
"""
- # FIXME this key is new!
keys = ("OVIRT_INIT",
"OVIRT_ROOT_INSTALL",
"OVIRT_OVERCOMMIT",
@@ -1191,13 +1190,28 @@
"OVIRT_VOL_LOGGING_SIZE",
"OVIRT_VOL_CONFIG_SIZE",
"OVIRT_VOL_DATA_SIZE",
+ "OVIRT_INSTALL"
)
@NodeConfigFileSection.map_and_update_defaults_decorator
- def update(self, init, root_install, overcommit, root_size, efi_size,
- swap_size, logging_size, config_size, data_size):
+ def update(self, init, root_install, overcommit, root_size,
+ efi_size, swap_size, logging_size,
+ config_size, data_size, install):
# FIXME no checking!
- pass
+ return {"OVIRT_INIT": ",".join(init)}
+
+ def retrieve(self):
+ cfg = dict(NodeConfigFileSection.retrieve(self))
+ cfg.update({"init": cfg["init"].split(",")})
+ return cfg
def transaction(self):
return None
+
+ def install_on(self, init):
+ """Convenience function which can be used to set the parameters which
+ are going to be picked up by the installer backend to install Node on
+ the given storage with the given othere params
+ """
+ self.update(init=init,
+ install=1)
diff --git a/scripts/tui/src/ovirt/node/installer/boot_device_page.py b/scripts/tui/src/ovirt/node/installer/boot_device_page.py
index 8133aa2..748f00b 100644
--- a/scripts/tui/src/ovirt/node/installer/boot_device_page.py
+++ b/scripts/tui/src/ovirt/node/installer/boot_device_page.py
@@ -85,6 +85,7 @@
return devices
def on_change(self, changes):
+ self.logger.debug("Boot device changes: %s" % changes)
if changes.contains_any(["boot.device"]):
device = changes["boot.device"]
if device == "other":
@@ -98,20 +99,21 @@
def on_merge(self, effective_changes):
changes = self.pending_changes(False)
- if changes.contains_any(["boot.device"]):
+ if changes.contains_any(["button.back"]):
+ self.application.ui.navigate.to_previous_plugin()
+
+ elif changes.contains_any(["button.next", "boot.device"]):
+ self.application.ui.navigate.to_next_plugin()
+
+ elif changes.contains_any(["boot.device"]):
device = changes["boot.device"]
if device == "other":
self._dialog = CustomDeviceDialog("custom", "x", "y")
return self._dialog
- if changes.contains_any(["boot.device.custom"]):
+ elif changes.contains_any(["boot.device.custom"]):
self._dialog.close()
self.application.ui.navigate.to_next_plugin()
-
- if changes.contains_any(["button.next", "boot.device"]):
- self.application.ui.navigate.to_next_plugin()
- elif changes.contains_any(["button.back"]):
- self.application.ui.navigate.to_previous_plugin()
class DeviceDetails(ui.Label):
diff --git a/scripts/tui/src/ovirt/node/installer/installation_device_page.py b/scripts/tui/src/ovirt/node/installer/installation_device_page.py
index e7c2dd6..d2528ec 100644
--- a/scripts/tui/src/ovirt/node/installer/installation_device_page.py
+++ b/scripts/tui/src/ovirt/node/installer/installation_device_page.py
@@ -36,12 +36,11 @@
return 40
def model(self):
- self._model.update({"installation.device": ""})
devices = self._device_list()
if devices:
first_dev = devices[0][0]
- self._model["label.details"] = first_dev
- self._model["installation.device"] = first_dev
+ self._model["installation.device.details"] = first_dev
+ self._model["installation.device.current"] = first_dev
return self._model
def validators(self):
@@ -56,10 +55,11 @@
ws = [ui.Header("header[0]", page_title)]
if devices:
- ws += [ui.Table("installation.device", "", " %6s %11s %5s" %
+ ws += [ui.Table("installation.device.current", "",
+ " %6s %11s %5s" %
("Location", "Device Name", "Size"), devices,
multi=True),
- DeviceDetails("label.details", "(No device)")
+ DeviceDetails("installation.device.details", "(No device)")
]
else:
ws += [ui.Label("installation.no_device",
@@ -83,18 +83,20 @@
for name, d in all_devices], key=lambda t: t[0])
def on_change(self, changes):
- if changes.contains_any(["installation.device"]):
- highlighted_device = changes["installation.device"]
- selected_devices = self.widgets["installation.device"].selection()
- self.logger.debug("devices: %s" % selected_devices)
+ if changes.contains_any(["installation.device.current"]):
+ highlighted_device = changes["installation.device.current"]
+ selected_devices = self.widgets["installation.device.current"].selection()
+ self.logger.debug("selected devices: %s" % selected_devices)
+ changes["installation.devices"] = selected_devices
self._model.update(changes)
- w = self.widgets["label.details"]
+ w = self.widgets["installation.device.details"]
if highlighted_device:
w.set_device(highlighted_device)
def on_merge(self, effective_changes):
changes = self.pending_changes(False)
- if changes.contains_any(["installation.device", "button.next"]):
- self.application.ui.navigate.to_next_plugin()
- elif changes.contains_any(["button.back"]):
+ self.logger.debug("All inst changes: %s" % changes)
+ if changes.contains_any(["button.back"]):
self.application.ui.navigate.to_previous_plugin()
+ elif changes.contains_any(["button.next"]):
+ self.application.ui.navigate.to_next_plugin()
diff --git a/scripts/tui/src/ovirt/node/installer/password_page.py b/scripts/tui/src/ovirt/node/installer/password_page.py
index 3a61c22..1de11dc 100644
--- a/scripts/tui/src/ovirt/node/installer/password_page.py
+++ b/scripts/tui/src/ovirt/node/installer/password_page.py
@@ -65,7 +65,7 @@
def on_merge(self, effective_changes):
changes = self.pending_changes(False)
- if changes.contains_any(["root.password_confirmation", "button.next"]):
- self.application.ui.navigate.to_next_plugin()
- elif changes.contains_any(["button.back"]):
+ if changes.contains_any(["button.back"]):
self.application.ui.navigate.to_previous_plugin()
+ elif changes.contains_any(["root.password_confirmation", "button.next"]):
+ self.application.ui.navigate.to_next_plugin()
diff --git a/scripts/tui/src/ovirt/node/installer/progress_page.py b/scripts/tui/src/ovirt/node/installer/progress_page.py
index 76e0177..8ffe761 100644
--- a/scripts/tui/src/ovirt/node/installer/progress_page.py
+++ b/scripts/tui/src/ovirt/node/installer/progress_page.py
@@ -19,6 +19,7 @@
# MA 02110-1301, USA. A copy of the GNU General Public License is
# also available at http://www.gnu.org/copyleft/gpl.html.
from ovirt.node import plugins, ui, utils
+from ovirt.node.config import defaults
import threading
import time
@@ -105,11 +106,13 @@
tx = utils.Transaction("Installation")
app = self.progress_plugin.application
- tx.append(self.UpdateDefaultsFromModels(app))
- tx.append(self.PartitionAndFormat())
+ model_tx = self.UpdateDefaultsFromModels(app)
+ model_tx.prepare()
+ tx.append(model_tx)
+ tx.append(self.PartitionAndFormat(model_tx.config["installation.devices"]))
tx.append(self.SetPassword("the-password"))
- tx.append(self.InstallBootloader())
- tx.append(self.SetKeyboardLayout("da-layout"))
+ tx.append(self.InstallBootloader(model_tx.config["boot.device"]))
+ tx.append(self.SetKeyboardLayout(model_tx.config["keyboard.layout"]))
return tx
@@ -130,14 +133,28 @@
self.logger.debug("Merged config: %s" % (model))
except NotImplementedError:
self.logger.debug("Merged no config.")
+ self.config = config
self.logger.debug("Final config: %s" % config)
+ # Update/Write the config file
+ model = defaults.Installation()
+ model.update(init=[config["boot.device"]] +
+ config["installation.devices"],
+ install="1")
+ kbd = defaults.Keyboard()
+ kbd.update(config["keyboard.layout"])
+
def commit(self):
- #model = defaults.Storage()
+ #model = defaults.Installation()
raise NotImplementedError
class PartitionAndFormat(utils.Transaction.Element):
- title = "Partitioning and Creating File Systems"
+ title_tpl = "Partitioning and Creating File Systems on '%s'"
+
+ def __init__(self, dst):
+ self.dst = dst
+ self.title = self.title_tpl % dst
+ super(InstallerThread.PartitionAndFormat, self).__init__()
def commit(self):
from ovirtnode import storage
@@ -160,7 +177,12 @@
raise RuntimeError("Failed to set root password")
class InstallBootloader(utils.Transaction.Element):
- title = "Installing Bootloader Configuration"
+ title_tpl = "Installing Bootloader Configuration to '%s'"
+
+ def __init__(self, dst):
+ self.dst = dst
+ self.title = self.title_tpl % dst
+ super(InstallerThread.InstallBootloader, self).__init__()
def commit(self):
from ovirtnode.install import Install
@@ -170,12 +192,12 @@
raise RuntimeError("Failed to set install bootloader")
class SetKeyboardLayout(utils.Transaction.Element):
- title = "Setting keyboard layout to '{kbd_layout}'"
+ title_tpl = "Setting keyboard layout to '%s'"
def __init__(self, kbd_layout):
- super(InstallerThread.SetKeyboardLayout, self).__init__()
self.kbd_layout = kbd_layout
- self.title = self.title.format(kbd_layout=kbd_layout)
+ self.title = self.title_tpl % kbd_layout
+ super(InstallerThread.SetKeyboardLayout, self).__init__()
def commit(self):
utils.Keyboard().set_layout(self.kbd_layout)
diff --git a/scripts/tui/src/ovirt/node/installer/storage_vol_page.py b/scripts/tui/src/ovirt/node/installer/storage_vol_page.py
new file mode 100644
index 0000000..4538908
--- /dev/null
+++ b/scripts/tui/src/ovirt/node/installer/storage_vol_page.py
@@ -0,0 +1,121 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# storage_vol_page.py - Copyright (C) 2013 Red Hat, Inc.
+# Written by Fabian Deutsch <fabiand at redhat.com>
+#
+# 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; version 2 of the License.
+#
+# 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+"""
+Storage Volume page of the installer
+"""
+from ovirt.node import plugins, ui, utils, valid
+
+
+class Plugin(plugins.NodePlugin):
+ _model = {}
+
+ def name(self):
+ return "Storage Sizes"
+
+ def rank(self):
+ return 20
+
+ def model(self):
+ self._model = {}
+ predefined = self.__get_default_sizes()
+ # cfg = config.defaults.Storage() FIXME respect defaults entries
+ self._model.update(predefined)
+ return self._model
+
+ def validators(self):
+ is_zero = valid.Number(exactly=0)
+ min_swap, min_logging = self.__get_min_sizes()
+ return {"storage.efi_size":
+ valid.Number(bounds=[0, None]),
+ "storage.root_size":
+ valid.Number(bounds=[0, None]),
+ "storage.swap_size":
+ valid.Number(bounds=[min_swap, None]) | is_zero,
+ "storage.config_size":
+ valid.Number(bounds=[5, None]),
+ "storage.logging_size":
+ valid.Number(bounds=[min_logging, None]) | is_zero,
+ "storage.data_size":
+ valid.Number(bounds=[0, None]),
+ }
+
+ def ui_content(self):
+ ws = [ui.Header("header[0]", "Storage Volumes"),
+ ui.Label("label[0]", "Please enter the sizes for the " +
+ "following partitions in MB"),
+ ui.Divider("divider[0]"),
+ ui.Entry("storage.efi_size", "UEFI/Bios:", enabled=False),
+ ui.Divider("divider[1]"),
+ ui.Entry("storage.root_size", "Root & RootBackup:",
+ enabled=False),
+ ui.Label("label[1]", "(2 partitions at 256MB each)"),
+ ui.Divider("divider[2]"),
+ ui.Entry("storage.swap_size", "Swap:"),
+ ui.Entry("storage.config_size", "Config:"),
+ ui.Entry("storage.logging_size", "Logging:"),
+ ui.Entry("storage.data_size", "Data:"),
+ ]
+ self.widgets.add(ws)
+ page = ui.Page("storage", ws)
+ page.buttons = [ui.QuitButton("button.quit", "Quit"),
+ ui.Button("button.back", "Back"),
+ ui.SaveButton("button.next", "Next")]
+ return page
+
+ def on_change(self, changes):
+ # FIXME
+ pass
+
+ def on_merge(self, effective_changes):
+ changes = self.pending_changes(False)
+ # FIXME
+ if changes.contains_any(["button.back"]):
+ self.application.ui.navigate.to_previous_plugin()
+ elif changes.contains_any(["button.next"]):
+ self.application.ui.navigate.to_next_plugin()
+
+ def __get_min_sizes(self):
+ if self.application.args.dry:
+ return 2048, 256
+ from ovirtnode.storage import Storage
+ stor = Storage()
+ return stor.MIN_SWAP_SIZE, stor.MIN_LOGGING_SIZE
+
+ def __get_default_sizes(self):
+ if self.application.args.dry:
+ return {"storage.efi_size": "256",
+ "storage.root_size": "50",
+ "storage.swap_size": "0",
+ "storage.config_size": "5",
+ "storage.logging_size": "2048",
+ "storage.data_size": "0",
+ }
+ from ovirtnode.storage import Storage
+ stor = Storage()
+ sizes = {"storage.efi_size": stor.EFI_SIZE,
+ "storage.root_size": stor.ROOT_SIZE,
+ "storage.swap_size": stor.SWAP_SIZE,
+ "storage.config_size": stor.CONFIG_SIZE,
+ "storage.logging_size": stor.LOGGING_SIZE,
+ "storage.data_size": stor.DATA_SIZE,
+ }
+ return sizes
diff --git a/scripts/tui/src/ovirt/node/ui/urwid_builder.py b/scripts/tui/src/ovirt/node/ui/urwid_builder.py
index 5cfa89c..c5d5833 100644
--- a/scripts/tui/src/ovirt/node/ui/urwid_builder.py
+++ b/scripts/tui/src/ovirt/node/ui/urwid_builder.py
@@ -70,8 +70,7 @@
def on_item_text_change_cb(w, v):
self.logger.debug("Element changed, updating label " +
"'%s': %s" % (w, v))
- widget.text(ui_label.text())
- self.application.ui.force_redraw()
+ widget.text(v)
ui_label.on_value_change.connect(on_item_text_change_cb)
return widget
@@ -229,30 +228,33 @@
def _build_table(self, ui_table):
children = []
- selected = None
for key, label in ui_table.items:
c = self._build_tableitem(ui_table, key, label)
children.append(c)
- if key == ui_table.selection():
- selected = c
widget = uw.TableWidget(ui_table.label, ui_table.header,
- children, selected,
+ children, ui_table.multi,
ui_table.height, ui_table.enabled())
+ for c in children:
+ c._table = widget
+
+ if ui_table.multi:
+ widget.selection(ui_table.selection())
+ else:
+ widget.focus(ui_table.selection())
+
def on_change_cb(w, d=None):
- ui_table.on_change({ui_table.path: w._key})
if ui_table.multi:
ui_table.selection(widget.selection())
else:
ui_table.selection(w._key)
+ ui_table.on_change({ui_table.path: w._key})
urwid.connect_signal(widget, "changed", on_change_cb)
def on_item_value_change_cb(p, v):
- for c in children:
- if c._key in v:
- c.selected(True)
+ widget.selection(v)
ui_table.on_value_change.connect(on_item_value_change_cb)
@@ -263,6 +265,7 @@
c._key = key
def on_activate_cb(w, data):
+ ui_table.selection(w._table.selection())
ui_table.on_change({ui_table.path: w._key})
ui_table.on_activate({ui_table.path: w._key})
@@ -533,6 +536,7 @@
def force_redraw(self):
if self.__loop:
+ self.logger.debug("Redrawing screen")
self.__loop.draw_screen()
def size(self):
diff --git a/scripts/tui/src/ovirt/node/ui/widgets.py b/scripts/tui/src/ovirt/node/ui/widgets.py
index 447c4cc..7a95435 100644
--- a/scripts/tui/src/ovirt/node/ui/widgets.py
+++ b/scripts/tui/src/ovirt/node/ui/widgets.py
@@ -70,11 +70,14 @@
return True
def is_selected(self):
- return self._text.text.startswith(self.checkboxes[True])
+ if self.multi:
+ return self._text.text.startswith(self.checkboxes[True])
+ return True
def select(self, is_selected=True):
- new_text = "%s%s" % (self.checkboxes[is_selected], self.title)
- self._text.set_text(new_text)
+ if self.multi:
+ new_text = "%s%s" % (self.checkboxes[is_selected], self.title)
+ self._text.set_text(new_text)
def __build_child(self):
self._text = SelectableText(self.title)
@@ -85,6 +88,7 @@
def __handle_activate(self):
if self.multi:
is_checked = self.is_selected()
+ LOGGER.debug("handling activate: %s" % is_checked)
self.select(not is_checked)
self._emit('activate', self)
@@ -106,7 +110,7 @@
_position = 0
- def __init__(self, label, header, items, selected_item, height, enabled):
+ def __init__(self, label, header, items, multi, height, enabled):
self.__label = urwid.Text(label)
self.__label_attrmap = urwid.AttrMap(self.__label, self._label_attr)
self.__header = urwid.Text(header)
@@ -115,9 +119,7 @@
self.__walker = urwid.SimpleListWalker(self.__items)
self.__list = urwid.ListBox(self.__walker)
# self.__list_linebox = urwid.LineBox(self.__list)
-
- if selected_item:
- self.set_focus(items.index(selected_item))
+ self.multi = multi
def __on_item_change():
widget, self._position = self.__list.get_focus()
@@ -148,9 +150,19 @@
def set_focus(self, n):
self.__list.set_focus(n)
- def selection(self):
- selection = [w._key for w in self.__items if w.is_selected()]
- return selection
+ def focus(self, key):
+ for c in self.__items:
+ if c._key == key:
+ self.set_focus(self.__items.index(c))
+
+ def selection(self, selection=None):
+ if selection:
+ for c in self.__items:
+ LOGGER.debug("checking: %s" % c)
+ if self.multi and c._key in selection:
+ c.select(True)
+ selected = [w._key for w in self.__items if w.is_selected()]
+ return selected
class PluginMenuEntry(TableEntryWidget):
--
To view, visit http://gerrit.ovirt.org/11481
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I5d485cb9d5740012cd666fd7a28c640af12bdfca
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-node
Gerrit-Branch: master
Gerrit-Owner: Fabian Deutsch <fabiand at fedoraproject.org>
More information about the node-patches
mailing list