Add Hardware: added the missing filesystem types for LXC guests.

This means tweaking the UI to input a memory usage for the 'ram'
filesystem type.
This commit is contained in:
Cédric Bosdonnat 2014-01-21 10:05:28 +01:00 committed by Cole Robinson
parent dc439b2c1c
commit 2f505822a1
6 changed files with 180 additions and 18 deletions

View File

@ -42,5 +42,13 @@
<source dir='/foo/bar'/>
<target dir='/bar/baz'/>
</filesystem>
<filesystem type='ram'>
<source usage='1024' units='MB'/>
<target dir='/bar/baz'/>
</filesystem>
<filesystem type='block'>
<source dev='/foo/bar'/>
<target dir='/bar/baz'/>
</filesystem>
</devices>
</domain>

View File

@ -43,5 +43,14 @@
<target dir="/bar/baz"/>
<readonly/>
</filesystem>
<filesystem type="ram">
<source usage="123" units="KiB"/>
<target dir="/bar/baz"/>
</filesystem>
<filesystem type="block">
<source dev="/dev/new"/>
<target dir="/bar/baz"/>
<readonly/>
</filesystem>
</devices>
</domain>

View File

@ -606,6 +606,8 @@ class XMLParseTest(unittest.TestCase):
dev2 = guest.get_devices("filesystem")[1]
dev3 = guest.get_devices("filesystem")[2]
dev4 = guest.get_devices("filesystem")[3]
dev5 = guest.get_devices("filesystem")[4]
dev6 = guest.get_devices("filesystem")[5]
check = self._make_checker(dev1)
check("type", None, "mount")
@ -635,6 +637,16 @@ class XMLParseTest(unittest.TestCase):
check("wrpolicy", None, "immediate")
check("readonly", False, True)
check = self._make_checker(dev5)
check("type", "ram")
check("source", "1024", 123)
check("units", "MB", "KiB")
check = self._make_checker(dev6)
check("type", "block")
check("source", "/foo/bar", "/dev/new")
check("readonly", False, True)
self._alter_compare(guest.get_xml_config(), outfile)
def testAlterSounds(self):

View File

@ -1888,7 +1888,7 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">5</property>
<property name="top_attach">6</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
@ -1905,13 +1905,13 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">6</property>
<property name="top_attach">7</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox16">
<object class="GtkHBox" id="fs-source-box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
@ -2041,7 +2041,7 @@
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">5</property>
<property name="top_attach">6</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
@ -2056,7 +2056,62 @@
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">6</property>
<property name="top_attach">7</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="fs-ram-source-title">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label">Usage:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">fs-source</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">5</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="fs-ram-source-box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkSpinButton" id="fs-ram-source-spin">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">1</property>
<property name="adjustment">adjustment6</property>
<property name="climb_rate">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="fs-ram-units-combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
<signal name="changed" handler="on_fs_ram_units_combo_changed" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">5</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>

View File

@ -67,6 +67,7 @@ class vmmAddHardware(vmmGObjectUI):
self.is_customize_dialog = is_customize_dialog
self.storage_browser = None
self.fs_units = "mb"
self._dev = None
@ -95,6 +96,7 @@ class vmmAddHardware(vmmGObjectUI):
"on_fs_type_combo_changed": self.change_fs_type,
"on_fs_driver_combo_changed": self.change_fs_driver,
"on_fs_source_browse_clicked": self.browse_fs_source,
"on_fs_ram_units_combo_changed": self.change_ram_units,
"on_usbredir_type_changed": self.change_usbredir_type,
@ -298,28 +300,45 @@ class vmmAddHardware(vmmGObjectUI):
combo = self.widget("watchdog-action")
uihelpers.build_watchdogaction_combo(self.vm, combo)
def simple_store_set(comboname, values):
def simple_store_set(comboname, values, units=False):
combo = self.widget(comboname)
model = Gtk.ListStore(str, str)
combo.set_model(model)
text = Gtk.CellRendererText()
combo.pack_start(text, True)
combo.add_attribute(text, 'text', 1)
model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
for val in values:
model.append([val, val.capitalize()])
if not units:
model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
for val in values:
model.append([val, val.capitalize()])
else:
for val in values:
model.append([val.lower(), val])
# Filesystem widgets
simple_store_set("fs-type-combo",
[VirtualFilesystem.TYPE_MOUNT,
VirtualFilesystem.TYPE_TEMPLATE])
if self.conn.is_openvz():
simple_store_set("fs-type-combo", [VirtualFilesystem.TYPE_MOUNT,
VirtualFilesystem.TYPE_TEMPLATE])
elif self.conn.is_lxc():
simple_store_set("fs-type-combo", [VirtualFilesystem.TYPE_MOUNT,
VirtualFilesystem.TYPE_FILE,
VirtualFilesystem.TYPE_BLOCK,
VirtualFilesystem.TYPE_RAM])
else:
simple_store_set("fs-type-combo", [VirtualFilesystem.TYPE_MOUNT])
simple_store_set("fs-mode-combo", VirtualFilesystem.MODES)
simple_store_set("fs-driver-combo", VirtualFilesystem.DRIVERS)
simple_store_set("fs-wrpolicy-combo", VirtualFilesystem.WRPOLICIES)
self.show_pair_combo("fs-type", self.conn.is_openvz())
self.show_pair_combo("fs-type", self.conn.is_openvz() or self.conn.is_lxc())
self.show_check_button("fs-readonly",
self.conn.is_qemu() or self.conn.is_lxc())
simple_store_set("fs-ram-units-combo", ["B", "KB", "MB", "GB",
"TB", "PB", "EB", "KiB",
"MiB", "GiB", "TiB", "PiB",
"EiB"], True)
# Smartcard widgets
combo = self.widget("smartcard-mode")
uihelpers.build_smartcard_mode_combo(self.vm, combo)
@ -505,6 +524,7 @@ class vmmAddHardware(vmmGObjectUI):
self.widget("fs-source").set_text("")
self.widget("fs-target").set_text("")
self.widget("fs-readonly").set_active(False)
self.widget("fs-ram-units-combo").set_active(2)
# Video params
uihelpers.populate_video_combo(self.vm, self.widget("video-model"))
@ -907,6 +927,14 @@ class vmmAddHardware(vmmGObjectUI):
return combo.get_model()[combo.get_active()][0]
def get_config_fs_units(self):
name = "fs-ram-units-combo"
combo = self.widget(name)
if not combo.get_visible():
return None
return combo.get_model()[combo.get_active()][1]
# Smartcard getters
def get_config_smartcard_mode(self):
mode = self.widget("smartcard-mode")
@ -1303,6 +1331,10 @@ class vmmAddHardware(vmmGObjectUI):
self.show_pair_combo("fs-driver", show_driver_combo)
self.show_pair_combo("fs-wrpolicy", show_wrpolicy_combo)
show_ram_source = fstype == VirtualFilesystem.TYPE_RAM
uihelpers.set_grid_row_visible(self.widget("fs-ram-source-box"), show_ram_source)
uihelpers.set_grid_row_visible(self.widget("fs-source-box"), not show_ram_source)
def change_fs_driver(self, src):
fsdriver = None
idx = src.get_active()
@ -1319,6 +1351,42 @@ class vmmAddHardware(vmmGObjectUI):
uihelpers.set_grid_row_visible(self.widget("fs-wrpolicy-box"),
show_wrpol)
def change_ram_units(self, ignore):
units = self.get_config_fs_units()
usage = uihelpers.spin_get_helper(self.widget("fs-ram-source-spin"))
upper = self.convert_units(16, "eib", units.lower())
self.widget("fs-ram-source-spin").get_adjustment().set_upper(upper)
new_value = self.convert_units(usage, self.fs_units, units.lower())
self.widget("fs-ram-source-spin").set_value(new_value)
self.fs_units = units.lower()
def convert_units(self, value, old_unit, new_unit):
def get_factor(unit):
factor = 1000
if unit[-2:] == 'ib':
factor = 1024
return factor
def get_power(unit):
powers = ('k', 'm', 'g', 't', 'p', 'e')
power = 0
if unit[0] in powers:
power = powers.index(unit[0]) + 1
return power
# First convert it all into bytes
factor = get_factor(old_unit)
power = get_power(old_unit)
in_bytes = value * pow(factor, power)
# Then convert it to the target unit
factor = get_factor(new_unit)
power = get_power(new_unit)
return in_bytes / pow(factor, power)
######################
@ -1737,14 +1805,18 @@ class vmmAddHardware(vmmGObjectUI):
conn = self.conn.get_backend()
source = self.widget("fs-source").get_text()
target = self.widget("fs-target").get_text()
usage = uihelpers.spin_get_helper(self.widget("fs-ram-source-spin"))
mode = self.get_config_fs_mode()
fstype = self.get_config_fs_type()
readonly = self.get_config_fs_readonly()
driver = self.get_config_fs_driver()
wrpolicy = self.get_config_fs_wrpolicy()
units = self.get_config_fs_units()
if not source:
if not source and fstype != VirtualFilesystem.TYPE_RAM:
return self.err.val_err(_("A filesystem source must be specified"))
elif usage == 0 and fstype == VirtualFilesystem.TYPE_RAM:
return self.err.val_err(_("A RAM filesystem usage must be specified"))
if not target:
return self.err.val_err(_("A filesystem target must be specified"))
@ -1754,7 +1826,11 @@ class vmmAddHardware(vmmGObjectUI):
try:
self._dev = virtinst.VirtualFilesystem(conn)
self._dev.source = source
if fstype == VirtualFilesystem.TYPE_RAM:
self._dev.source = usage
self._dev.units = units
else:
self._dev.source = source
self._dev.target = target
if mode:
self._dev.mode = mode

View File

@ -26,14 +26,13 @@ from virtinst.xmlbuilder import XMLProperty
class VirtualFilesystem(VirtualDevice):
virtual_device_type = VirtualDevice.VIRTUAL_DEV_FILESYSTEM
_target_props = ["dir", "name", "file", "dev"]
TYPE_MOUNT = "mount"
TYPE_TEMPLATE = "template"
TYPE_FILE = "file"
TYPE_BLOCK = "block"
TYPE_RAM = "ram"
TYPE_DEFAULT = "default"
TYPES = [TYPE_MOUNT, TYPE_TEMPLATE, TYPE_FILE, TYPE_BLOCK, TYPE_DEFAULT]
TYPES = [TYPE_MOUNT, TYPE_TEMPLATE, TYPE_FILE, TYPE_BLOCK, TYPE_RAM, TYPE_DEFAULT]
MODE_PASSTHROUGH = "passthrough"
MODE_MAPPED = "mapped"
@ -67,6 +66,8 @@ class VirtualFilesystem(VirtualDevice):
return "file"
elif fs_type == VirtualFilesystem.TYPE_BLOCK:
return "dev"
elif fs_type == VirtualFilesystem.TYPE_RAM:
return "usage"
return "dir"
@ -85,6 +86,7 @@ class VirtualFilesystem(VirtualDevice):
readonly = XMLProperty("./readonly", is_bool=True)
units = XMLProperty("./source/@units")
def _make_source_xpath(self):
return "./source/@" + self.type_to_source_prop(self.type)