Skip to content

Commit

Permalink
Add support for renaming LVM LVs and VGs
Browse files Browse the repository at this point in the history
  • Loading branch information
vojtechtrefny committed Jan 10, 2022
1 parent 82d5bda commit 0812873
Show file tree
Hide file tree
Showing 10 changed files with 401 additions and 99 deletions.
1 change: 1 addition & 0 deletions blivetgui/actions_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def create_menu(self):
items = [("add", self.blivet_gui.add_device),
("delete", self.blivet_gui.delete_selected_partition),
("resize", self.blivet_gui.resize_device),
("rename", self.blivet_gui.rename_device),
("format", self.blivet_gui.format_device),
("label", self.blivet_gui.edit_label),
("unmount", self.blivet_gui.umount_partition),
Expand Down
1 change: 1 addition & 0 deletions blivetgui/actions_toolbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def __init__(self, blivet_gui):
items = [("add", "clicked", self.blivet_gui.add_device),
("delete", "clicked", self.blivet_gui.delete_selected_partition),
("resize", "activate", self.blivet_gui.resize_device),
("rename", "activate", self.blivet_gui.rename_device),
("format", "activate", self.blivet_gui.format_device),
("unmount", "clicked", self.blivet_gui.umount_partition),
("decrypt", "clicked", self.blivet_gui.decrypt_device),
Expand Down
20 changes: 20 additions & 0 deletions blivetgui/blivet_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,20 @@ def relabel_format(self, user_input):
return ProxyDataContainer(success=True, actions=[label_ac], message=None,
exception=None, traceback=None)

def rename_device(self, user_input):
rename_ac = blivet.deviceaction.ActionConfigureDevice(device=user_input.edit_device,
attr="name",
new_value=user_input.name)

try:
self.storage.devicetree.actions.add(rename_ac)
except Exception as e: # pylint: disable=broad-except
return ProxyDataContainer(success=False, actions=None, message=None, exception=e,
traceback=traceback.format_exc())
else:
return ProxyDataContainer(success=True, actions=[rename_ac], message=None,
exception=None, traceback=None)

def edit_lvmvg_device(self, user_input):
""" Edit LVM Volume group
"""
Expand Down Expand Up @@ -1410,6 +1424,12 @@ def get_mountpoints(self):

return list(self.storage.mountpoints.keys())

def get_names(self):
""" Return list of currently used device names
"""

return self.storage.names

def get_supported_filesystems(self, installer_mode=False):
_fs_types = []

Expand Down
24 changes: 24 additions & 0 deletions blivetgui/blivetgui.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,30 @@ def resize_device(self, _widget=None):
self._handle_user_change()
self.update_partitions_view()

def rename_device(self, _widget=None):
device = self.list_partitions.selected_partition[0]
names = self.client.remote_call("get_names")

dialog = edit_dialog.RenameDialog(self.main_window, device, names,
installer_mode=self.installer_mode)
message = _("Failed to rename the device:")
user_input = self.run_dialog(dialog)
if user_input.rename:
result = self.client.remote_call("rename_device", user_input)
if not result.success:
if not result.exception:
self.show_error_dialog(result.message)
else:
self._reraise_exception(result.exception, result.traceback, message,
dialog_window=dialog.dialog)
else:
if result.actions:
action_str = _("rename {name} {type}").format(name=device.name, type=device.type)
self.list_actions.append("edit", action_str, result.actions)

self._handle_user_change()
self.update_partitions_view()

def format_device(self, _widget=None):
device = self.list_partitions.selected_partition[0]

Expand Down
83 changes: 82 additions & 1 deletion blivetgui/dialogs/edit_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from gi.repository import Gtk

from .size_chooser import SizeChooser
from .helpers import is_mountpoint_valid, is_label_valid
from .helpers import is_mountpoint_valid, is_label_valid, is_name_valid
from ..dialogs import message_dialogs
from ..gui_utils import locate_ui_file
from ..communication.proxy_utils import ProxyDataContainer
Expand Down Expand Up @@ -432,6 +432,87 @@ def _on_format_button(self, _button):
self.dialog.response(Gtk.ResponseType.ACCEPT)


class RenameDialog(object):

def __init__(self, main_window, edit_device, names, installer_mode=False):
self.main_window = main_window
self.edit_device = edit_device
self.names = names
self.installer_mode = installer_mode

self.builder = Gtk.Builder()
self.builder.set_translation_domain("blivet-gui")
self.builder.add_from_file(locate_ui_file("rename_dialog.ui"))

self.dialog = self.builder.get_object("rename_dialog")
self.dialog.set_transient_for(self.main_window)

self.entry_rename = self.builder.get_object("entry_rename")

button_cancel = self.builder.get_object("button_cancel")
button_cancel.connect("clicked", self._on_cancel_button)

button_rename = self.builder.get_object("button_rename")
button_rename.connect("clicked", self._on_rename_button)

def set_decorated(self, decorated):
self.dialog.set_decorated(decorated)

# no decoration --> display dialog title in the dialog
if not decorated:
label = self.builder.get_object("label_title")
title = self.dialog.get_title()
label.set_text(title)

def _validate_user_input(self, name):
if not is_name_valid(self.edit_device.type, name):
msg = _("\"{0}\" is not a valid name.").format(name)
message_dialogs.ErrorDialog(self, msg,
not self.installer_mode) # do not show decoration in installer mode
return False

if hasattr(self.edit_device, "lvname"):
old_name = self.edit_device.lvname
new_name = "%s-%s" % (self.edit_device.vg.name, name)
else:
old_name = self.edit_device.name
new_name = name

if name == old_name:
msg = _("Selected device is already named \"{0}\".").format(name)
message_dialogs.ErrorDialog(self.dialog, msg,
not self.installer_mode) # do not show decoration in installer mode
return False

if new_name in self.names:
msg = _("Selected name \"{0}\" is already in use.").format(name)
message_dialogs.ErrorDialog(self.dialog, msg,
not self.installer_mode) # do not show decoration in installer mode
return False

return True

def run(self):
response = self.dialog.run()

if response == Gtk.ResponseType.REJECT:
self.dialog.destroy()
return ProxyDataContainer(edit_device=self.edit_device, rename=False, name=None)
else:
new_name = self.entry_rename.get_text()
if not self._validate_user_input(new_name):
return self.run()
else:
self.dialog.destroy()
return ProxyDataContainer(edit_device=self.edit_device, rename=True, name=new_name)

def _on_cancel_button(self, _button):
self.dialog.response(Gtk.ResponseType.REJECT)

def _on_rename_button(self, _button):
self.dialog.response(Gtk.ResponseType.ACCEPT)


class UnmountDialog(object):

def __init__(self, main_window, edit_device, mountpoints, installer_mode=False):
Expand Down
9 changes: 9 additions & 0 deletions blivetgui/list_partitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,12 @@ def _allow_relabel_device(self, device):

return device.format.labeling() and device.format.relabels()

def _allow_rename_device(self, device):
if device.protected or device.format.status:
return False

return hasattr(device, "_renamable") and device._renamable

def _allow_add_device(self, device):
if device.protected:
return False
Expand Down Expand Up @@ -311,6 +317,9 @@ def activate_action_buttons(self, selected_device):
if self._allow_relabel_device(device):
self.blivet_gui.activate_device_actions(["label"])

if self._allow_rename_device(device):
self.blivet_gui.activate_device_actions(["rename"])

if self._allow_add_device(device):
self.blivet_gui.activate_device_actions(["add"])

Expand Down
16 changes: 16 additions & 0 deletions data/ui/blivet-gui.ui
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@
<property name="use-underline">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem_rename">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Rename</property>
<property name="use-underline">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem_format">
<property name="visible">True</property>
Expand Down Expand Up @@ -123,6 +131,14 @@
<property name="use-underline">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="button_rename">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Rename</property>
<property name="use-underline">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="button_format">
<property name="visible">True</property>
Expand Down
98 changes: 98 additions & 0 deletions data/ui/rename_dialog.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
<requires lib="gtk+" version="3.16"/>
<object class="GtkDialog" id="rename_dialog">
<property name="can-focus">False</property>
<property name="title" translatable="yes">Rename device</property>
<property name="window-position">center-on-parent</property>
<property name="type-hint">dialog</property>
<property name="gravity">center</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area">
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="button_cancel">
<property name="label" translatable="yes">Cancel</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="yalign">0.62000000476837158</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button_rename">
<property name="label" translatable="yes" context="Dialog|Format" comments="Perform selected format change on this device.">Rename</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="box">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-left">12</property>
<property name="margin-right">12</property>
<property name="margin-top">8</property>
<property name="margin-bottom">8</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkLabel" id="label_rename">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-right">6</property>
<property name="label" translatable="yes">Enter new name for this device:</property>
<property name="justify">center</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry_rename">
<property name="visible">True</property>
<property name="can-focus">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
Loading

0 comments on commit 0812873

Please sign in to comment.