mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-02-11 16:05:51 -06:00
Make virt-manager remember last used paths
This patch makes virt-manager remember last used paths for disk images, saved snapshots, restored snapshots, media paths and also screenshot paths not to bother users with changing paths from the default location per HV technology. Useful when installing multiple domains and having all the media/image files in non-default locations.
This commit is contained in:
parent
f918e05d31
commit
fd480885bc
@ -272,5 +272,70 @@
|
||||
<long>Whether to install a sound device for remote VMs or not</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/::PACKAGE::/paths/default-image-path</key>
|
||||
<applyto>/apps/::PACKAGE::/paths/default-image-path</applyto>
|
||||
<owner>::PACKAGE::</owner>
|
||||
<type>string</type>
|
||||
<default></default>
|
||||
|
||||
<locale name="C">
|
||||
<short>Default image path</short>
|
||||
<long>Default path for choosing VM images</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/::PACKAGE::/paths/default-media-path</key>
|
||||
<applyto>/apps/::PACKAGE::/paths/default-media-path</applyto>
|
||||
<owner>::PACKAGE::</owner>
|
||||
<type>string</type>
|
||||
<default></default>
|
||||
|
||||
<locale name="C">
|
||||
<short>Default media path</short>
|
||||
<long>Default path for choosing media</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/::PACKAGE::/paths/default-save-path</key>
|
||||
<applyto>/apps/::PACKAGE::/paths/default-save-path</applyto>
|
||||
<owner>::PACKAGE::</owner>
|
||||
<type>string</type>
|
||||
<default></default>
|
||||
|
||||
<locale name="C">
|
||||
<short>Default save domain path</short>
|
||||
<long>Default path for saving VM snaphots</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/::PACKAGE::/paths/default-restore-path</key>
|
||||
<applyto>/apps/::PACKAGE::/paths/default-restore-path</applyto>
|
||||
<owner>::PACKAGE::</owner>
|
||||
<type>string</type>
|
||||
<default></default>
|
||||
|
||||
<locale name="C">
|
||||
<short>Default restore path</short>
|
||||
<long>Default path for stored VM snapshots</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/::PACKAGE::/paths/default-screenshot-path</key>
|
||||
<applyto>/apps/::PACKAGE::/paths/default-screenshot-path</applyto>
|
||||
<owner>::PACKAGE::</owner>
|
||||
<type>string</type>
|
||||
<default></default>
|
||||
|
||||
<locale name="C">
|
||||
<short>Default screenshot path</short>
|
||||
<long>Default path for saving screenshots from VMs</long>
|
||||
</locale>
|
||||
</schema>
|
||||
</schemalist>
|
||||
</gconfschemafile>
|
||||
|
@ -701,14 +701,15 @@ class vmmAddHardware(gobject.GObject):
|
||||
|
||||
conn = self.vm.get_connection()
|
||||
if self.storage_browser == None:
|
||||
self.storage_browser = vmmStorageBrowser(self.config, conn)
|
||||
self.storage_browser = vmmStorageBrowser(self.config, conn, False)
|
||||
if self._browse_cb_id:
|
||||
self.storage_browser.disconnect(self._browse_cb_id)
|
||||
|
||||
self._browse_cb_id = self.storage_browser.connect("storage-browse-finish", set_storage_cb)
|
||||
self.storage_browser.local_args = { "dialog_name": dialog_name,
|
||||
"start_folder": folder,
|
||||
"confirm_func": confirm_func, }
|
||||
"confirm_func": confirm_func,
|
||||
"browse_reason":
|
||||
self.config.CONFIG_DIR_IMAGE }
|
||||
self.storage_browser.show(conn)
|
||||
return None
|
||||
|
||||
|
@ -149,11 +149,13 @@ class vmmChooseCD(gobject.GObject):
|
||||
|
||||
def _browse_file(self, dialog_name):
|
||||
if self.storage_browser == None:
|
||||
self.storage_browser = vmmStorageBrowser(self.config, self.conn)
|
||||
#self.topwin)
|
||||
self.storage_browser = vmmStorageBrowser(self.config, self.conn,
|
||||
True)
|
||||
self.storage_browser.connect("storage-browse-finish",
|
||||
self.set_storage_path)
|
||||
self.storage_browser.local_args = { "dialog_name": dialog_name }
|
||||
self.storage_browser.local_args = { "dialog_name": dialog_name,
|
||||
"browse_reason":
|
||||
self.config.CONFIG_DIR_MEDIA }
|
||||
self.storage_browser.show(self.conn)
|
||||
return None
|
||||
|
||||
|
@ -45,6 +45,13 @@ DEFAULT_VIRT_SAVE_DIR = "/var/lib/libvirt"
|
||||
|
||||
class vmmConfig:
|
||||
|
||||
# GConf directory names for saving last used paths
|
||||
CONFIG_DIR_IMAGE = "image"
|
||||
CONFIG_DIR_MEDIA = "media"
|
||||
CONFIG_DIR_SAVE = "save"
|
||||
CONFIG_DIR_RESTORE = "restore"
|
||||
CONFIG_DIR_SCREENSHOT = "screenshot"
|
||||
|
||||
CONSOLE_SCALE_NEVER = 0
|
||||
CONSOLE_SCALE_FULLSCREEN = 1
|
||||
CONSOLE_SCALE_ALWAYS = 2
|
||||
@ -261,6 +268,36 @@ class vmmConfig:
|
||||
self.conf.set_bool(self.conf_dir + "/vmlist-fields/network_traffic", state)
|
||||
|
||||
|
||||
def get_default_directory(self, conn, _type):
|
||||
if not _type:
|
||||
logging.error("Unknown type for get_default_directory")
|
||||
return
|
||||
|
||||
try:
|
||||
path = self.conf.get_value(self.conf_dir + "/paths/default-%s-path"
|
||||
% _type)
|
||||
except:
|
||||
path = None
|
||||
|
||||
if not path:
|
||||
if (_type == self.CONFIG_DIR_IMAGE or
|
||||
_type == self.CONFIG_DIR_MEDIA):
|
||||
path = self.get_default_image_dir(conn)
|
||||
if (_type == self.CONFIG_DIR_SAVE or
|
||||
_type == self.CONFIG_DIR_RESTORE):
|
||||
path = self.get_default_save_dir(conn)
|
||||
|
||||
logging.debug("get_default_directory(%s): returning %s" % (_type, path))
|
||||
return path
|
||||
|
||||
def set_default_directory(self, folder, _type):
|
||||
if not _type:
|
||||
logging.error("Unknown type for set_default_directory")
|
||||
return
|
||||
|
||||
logging.debug("set_default_directory(%s): saving %s" % (_type, folder))
|
||||
self.conf.set_value(self.conf_dir + "/paths/default-%s-path" % _type,
|
||||
folder)
|
||||
|
||||
def on_vmlist_domain_id_visible_changed(self, callback):
|
||||
self.conf.notify_add(self.conf_dir + "/vmlist-fields/domain_id", callback)
|
||||
|
@ -996,7 +996,8 @@ class vmmCreate(gobject.GObject):
|
||||
|
||||
def browse_iso(self, ignore1=None, ignore2=None):
|
||||
self._browse_file(_("Locate ISO Image"),
|
||||
self.set_iso_storage_path)
|
||||
self.set_iso_storage_path,
|
||||
is_media=True)
|
||||
self.window.get_widget("install-local-box").activate()
|
||||
|
||||
def toggle_enable_storage(self, src):
|
||||
@ -1004,7 +1005,8 @@ class vmmCreate(gobject.GObject):
|
||||
|
||||
def browse_storage(self, ignore1):
|
||||
self._browse_file(_("Locate existing storage"),
|
||||
self.set_disk_storage_path)
|
||||
self.set_disk_storage_path,
|
||||
is_media=False)
|
||||
|
||||
def toggle_storage_select(self, src):
|
||||
act = src.get_active()
|
||||
@ -1648,13 +1650,20 @@ class vmmCreate(gobject.GObject):
|
||||
logging.exception("Error detecting distro.")
|
||||
self.detectedDistro = (None, None)
|
||||
|
||||
def _browse_file(self, dialog_name, callback, folder=None):
|
||||
def _browse_file(self, dialog_name, callback, folder=None, is_media=False):
|
||||
if self.storage_browser == None:
|
||||
self.storage_browser = vmmStorageBrowser(self.config, self.conn)
|
||||
self.storage_browser = vmmStorageBrowser(self.config, self.conn,
|
||||
is_media)
|
||||
self.storage_browser.connect("storage-browse-finish",
|
||||
callback)
|
||||
if is_media:
|
||||
reason = self.config.CONFIG_DIR_MEDIA
|
||||
else:
|
||||
reason = self.config.CONFIG_DIR_IMAGE
|
||||
|
||||
self.storage_browser.local_args = { "dialog_name": dialog_name,
|
||||
"start_folder": folder}
|
||||
"start_folder": folder,
|
||||
"browse_reason": reason}
|
||||
self.storage_browser.show(self.conn)
|
||||
|
||||
def show_help(self, ignore):
|
||||
|
@ -1410,8 +1410,10 @@ class vmmDetails(gobject.GObject):
|
||||
# user to choose what image format they'd like to save in....
|
||||
path = util.browse_local(self.window.get_widget("vmm-details"),
|
||||
_("Save Virtual Machine Screenshot"),
|
||||
_type = ("*.png", "PNG files"),
|
||||
dialog_type = gtk.FILE_CHOOSER_ACTION_SAVE)
|
||||
self.config, self.vm.get_connection(),
|
||||
_type = ("png", "PNG files"),
|
||||
dialog_type = gtk.FILE_CHOOSER_ACTION_SAVE,
|
||||
browse_reason=self.config.CONFIG_DIR_SCREENSHOT)
|
||||
if not path:
|
||||
return
|
||||
|
||||
|
@ -406,8 +406,9 @@ class vmmEngine(gobject.GObject):
|
||||
|
||||
path = util.browse_local(src.window.get_widget("vmm-details"),
|
||||
_("Save Virtual Machine"),
|
||||
self.config.get_default_save_dir(con),
|
||||
dialog_type=gtk.FILE_CHOOSER_ACTION_SAVE)
|
||||
self.config, self.get_connection(uri),
|
||||
dialog_type=gtk.FILE_CHOOSER_ACTION_SAVE,
|
||||
browse_reason=self.config.CONFIG_DIR_SAVE)
|
||||
|
||||
if not path:
|
||||
return
|
||||
|
@ -397,7 +397,8 @@ class vmmManager(gobject.GObject):
|
||||
|
||||
path = util.browse_local(self.window.get_widget("vmm-manager"),
|
||||
_("Restore Virtual Machine"),
|
||||
self.config.get_default_save_dir(conn))
|
||||
self.config, conn,
|
||||
browse_reason=self.config.CONFIG_DIR_RESTORE)
|
||||
|
||||
if not path:
|
||||
return
|
||||
|
@ -38,7 +38,7 @@ class vmmStorageBrowser(gobject.GObject):
|
||||
gobject.TYPE_NONE, [str]),
|
||||
}
|
||||
|
||||
def __init__(self, config, conn):
|
||||
def __init__(self, config, conn, is_media=False):
|
||||
self.__gobject_init__()
|
||||
self.window = gtk.glade.XML(config.get_glade_dir() + \
|
||||
"/vmm-storage-browse.glade",
|
||||
@ -58,8 +58,14 @@ class vmmStorageBrowser(gobject.GObject):
|
||||
# Add Volume wizard
|
||||
self.addvol = None
|
||||
|
||||
if is_media:
|
||||
reason = self.config.CONFIG_DIR_MEDIA
|
||||
else:
|
||||
reason = self.config.CONFIG_DIR_IMAGE
|
||||
|
||||
# Arguments to pass to util.browse_local for local storage
|
||||
self.local_args = {"dialog_name": _("Choose local storage")}
|
||||
self.local_args = {"dialog_name": _("Choose local storage"),
|
||||
"browse_reason": reason, }
|
||||
|
||||
self.window.signal_autoconnect({
|
||||
"on_vmm_storage_browse_delete_event" : self.close,
|
||||
@ -232,7 +238,8 @@ class vmmStorageBrowser(gobject.GObject):
|
||||
"".join(traceback.format_exc()))
|
||||
|
||||
def browse_local(self, src):
|
||||
filename = util.browse_local(parent=self.topwin, **self.local_args)
|
||||
filename = util.browse_local(parent=self.topwin, config=self.config,
|
||||
conn=self.conn, **self.local_args)
|
||||
if filename:
|
||||
self._do_finish(path=filename)
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
import logging
|
||||
import gtk
|
||||
import libxml2
|
||||
import os.path
|
||||
|
||||
import libvirt
|
||||
|
||||
@ -90,17 +91,24 @@ def xml_parse_wrapper(xml, parse_func, *args, **kwargs):
|
||||
return ret
|
||||
|
||||
|
||||
def browse_local(parent, dialog_name, start_folder=None, _type=None,
|
||||
dialog_type=gtk.FILE_CHOOSER_ACTION_OPEN, confirm_func=None):
|
||||
def browse_local(parent, dialog_name, config, conn, start_folder=None,
|
||||
_type=None, dialog_type=gtk.FILE_CHOOSER_ACTION_OPEN,
|
||||
confirm_func=None, browse_reason=None):
|
||||
"""
|
||||
Helper function for launching a filechooser
|
||||
|
||||
@param parent: Parent window for the filechooser
|
||||
@param dialog_name: String to use in the title bar of the filechooser.
|
||||
@param config: vmmConfig used by calling class
|
||||
@param conn: vmmConnection used by calling class
|
||||
@param start_folder: Folder the filechooser is viewing at startup
|
||||
@param _type: File extension to filter by (e.g. "iso", "png")
|
||||
@param dialog_type: Maps to FileChooserDialog 'action'
|
||||
@param confirm_func: Optional callback function if file is chosen.
|
||||
@param browse_reason: The vmmConfig.CONFIG_DIR* reason we are browsing.
|
||||
If set, this will override the 'folder' parameter with the gconf
|
||||
value, and store the user chosen path.
|
||||
|
||||
"""
|
||||
|
||||
overwrite_confirm = False
|
||||
@ -109,6 +117,9 @@ def browse_local(parent, dialog_name, start_folder=None, _type=None,
|
||||
choose_button = gtk.STOCK_SAVE
|
||||
overwrite_confirm = True
|
||||
|
||||
if browse_reason:
|
||||
start_folder = config.get_default_directory(conn, browse_reason)
|
||||
|
||||
fcdialog = gtk.FileChooserDialog(dialog_name, parent,
|
||||
dialog_type,
|
||||
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
|
||||
@ -142,10 +153,15 @@ def browse_local(parent, dialog_name, start_folder=None, _type=None,
|
||||
if(response == gtk.RESPONSE_ACCEPT):
|
||||
filename = fcdialog.get_filename()
|
||||
fcdialog.destroy()
|
||||
return filename
|
||||
ret = filename
|
||||
else:
|
||||
fcdialog.destroy()
|
||||
return None
|
||||
ret = None
|
||||
|
||||
if ret and browse_reason and not ret.startwith("/dev"):
|
||||
config.set_default_directory(os.path.dirname(ret), browse_reason)
|
||||
|
||||
return ret
|
||||
|
||||
def dup_conn(config, conn, libconn=None, return_conn_class=False):
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user