Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
#
|
|
|
|
# Copyright (C) 2013 Red Hat, Inc.
|
|
|
|
# Copyright (C) 2013 Cole Robinson <crobinso@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; 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, write to the Free Software
|
|
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
|
|
# MA 02110-1301 USA.
|
|
|
|
#
|
|
|
|
|
|
|
|
import datetime
|
2013-09-30 20:41:10 -05:00
|
|
|
import glob
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
import logging
|
2013-09-30 20:41:10 -05:00
|
|
|
import os
|
|
|
|
import StringIO
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
|
|
|
# pylint: disable=E0611
|
|
|
|
from gi.repository import Gdk
|
2013-09-30 20:41:10 -05:00
|
|
|
from gi.repository import GdkPixbuf
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
from gi.repository import Gtk
|
|
|
|
# pylint: enable=E0611
|
|
|
|
|
2013-09-30 15:33:45 -05:00
|
|
|
from virtinst import DomainSnapshot
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
from virtinst import util
|
|
|
|
|
|
|
|
from virtManager import uihelpers
|
|
|
|
from virtManager.baseclass import vmmGObjectUI
|
|
|
|
from virtManager.asyncjob import vmmAsyncJob
|
|
|
|
|
|
|
|
|
2013-09-30 20:41:10 -05:00
|
|
|
mimemap = {
|
|
|
|
"image/x-portable-pixmap": "ppm",
|
|
|
|
"image/png": "png",
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
def _mime_to_ext(val, reverse=False):
|
|
|
|
for m, e in mimemap.items():
|
|
|
|
if val == m and not reverse:
|
|
|
|
return e
|
|
|
|
if val == e and reverse:
|
|
|
|
return m
|
|
|
|
logging.debug("Don't know how to convert %s=%s to %s",
|
|
|
|
reverse and "extension" or "mime", val,
|
|
|
|
reverse and "mime" or "extension")
|
|
|
|
|
|
|
|
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
class vmmSnapshotPage(vmmGObjectUI):
|
|
|
|
def __init__(self, vm, builder, topwin):
|
2013-09-22 15:10:16 -05:00
|
|
|
vmmGObjectUI.__init__(self, "snapshots.ui",
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
None, builder=builder, topwin=topwin)
|
|
|
|
|
|
|
|
self.vm = vm
|
|
|
|
|
|
|
|
self._initial_populate = False
|
|
|
|
|
2013-10-05 13:57:58 -05:00
|
|
|
self._snapmenu = None
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
self._init_ui()
|
|
|
|
|
|
|
|
self._snapshot_new = self.widget("snapshot-new")
|
|
|
|
self._snapshot_new.set_transient_for(self.topwin)
|
2013-09-30 15:37:46 -05:00
|
|
|
self.bind_escape_key_close_helper(self._snapshot_new,
|
|
|
|
self._snapshot_new_close)
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
|
|
|
self.builder.connect_signals({
|
|
|
|
"on_snapshot_add_clicked": self._on_add_clicked,
|
|
|
|
"on_snapshot_delete_clicked": self._on_delete_clicked,
|
|
|
|
"on_snapshot_start_clicked": self._on_start_clicked,
|
|
|
|
"on_snapshot_apply_clicked": self._on_apply_clicked,
|
2013-09-30 15:04:11 -05:00
|
|
|
"on_snapshot_list_changed": self._snapshot_selected,
|
2013-10-05 13:57:58 -05:00
|
|
|
"on_snapshot_list_button_press_event": self._popup_snapshot_menu,
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
|
|
|
# 'Create' dialog
|
|
|
|
"on_snapshot_new_delete_event": self._snapshot_new_close,
|
|
|
|
"on_snapshot_new_ok_clicked": self._on_new_ok_clicked,
|
|
|
|
"on_snapshot_new_cancel_clicked" : self._snapshot_new_close,
|
2013-09-30 15:04:11 -05:00
|
|
|
"on_snapshot_new_name_changed" : self._snapshot_new_name_changed,
|
2013-10-05 13:47:10 -05:00
|
|
|
"on_snapshot_new_name_activate": self._on_new_ok_clicked,
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
})
|
|
|
|
|
|
|
|
self.top_box = self.widget("snapshot-top-box")
|
|
|
|
self.widget("snapshot-top-window").remove(self.top_box)
|
2013-09-30 14:52:37 -05:00
|
|
|
self.widget("snapshot-list").get_selection().emit("changed")
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
|
|
|
|
|
|
|
##############
|
|
|
|
# Init stuff #
|
|
|
|
##############
|
|
|
|
|
|
|
|
def _cleanup(self):
|
|
|
|
self.vm = None
|
|
|
|
|
|
|
|
self._snapshot_new.destroy()
|
|
|
|
self._snapshot_new = None
|
|
|
|
|
|
|
|
def _init_ui(self):
|
2013-09-30 13:28:43 -05:00
|
|
|
blue = Gdk.color_parse("#0072A8")
|
|
|
|
self.widget("header").modify_bg(Gtk.StateType.NORMAL, blue)
|
|
|
|
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
self.widget("snapshot-notebook").set_show_tabs(False)
|
|
|
|
|
|
|
|
buf = Gtk.TextBuffer()
|
|
|
|
buf.connect("changed", self._description_changed)
|
|
|
|
self.widget("snapshot-description").set_buffer(buf)
|
|
|
|
|
2013-09-30 13:28:43 -05:00
|
|
|
buf = Gtk.TextBuffer()
|
|
|
|
self.widget("snapshot-new-description").set_buffer(buf)
|
|
|
|
|
2013-09-30 17:46:54 -05:00
|
|
|
# [name, row label, tooltip, icon name, sortname]
|
|
|
|
model = Gtk.ListStore(str, str, str, str, str)
|
2013-09-30 16:53:55 -05:00
|
|
|
model.set_sort_column_id(4, Gtk.SortType.ASCENDING)
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
|
|
|
col = Gtk.TreeViewColumn("")
|
|
|
|
col.set_min_width(150)
|
|
|
|
col.set_expand(True)
|
|
|
|
col.set_spacing(6)
|
2013-09-30 16:36:38 -05:00
|
|
|
img = Gtk.CellRendererPixbuf()
|
|
|
|
img.set_property("stock-size", Gtk.IconSize.LARGE_TOOLBAR)
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
txt = Gtk.CellRendererText()
|
2013-09-30 16:36:38 -05:00
|
|
|
col.pack_start(img, False)
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
col.pack_start(txt, False)
|
2013-09-30 16:36:38 -05:00
|
|
|
col.add_attribute(txt, 'markup', 1)
|
|
|
|
col.add_attribute(img, 'icon-name', 3)
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
2013-09-30 16:53:55 -05:00
|
|
|
def _sep_cb(_model, _iter, ignore):
|
|
|
|
return not bool(_model[_iter][0])
|
|
|
|
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
slist = self.widget("snapshot-list")
|
|
|
|
slist.set_model(model)
|
|
|
|
slist.set_tooltip_column(2)
|
|
|
|
slist.append_column(col)
|
2013-09-30 16:53:55 -05:00
|
|
|
slist.set_row_separator_func(_sep_cb, None)
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
2013-10-05 13:57:58 -05:00
|
|
|
# Snapshot popup menu
|
|
|
|
menu = Gtk.Menu()
|
|
|
|
|
|
|
|
item = Gtk.ImageMenuItem(_("_Start snapshot"))
|
|
|
|
item.set_use_underline(True)
|
|
|
|
img = Gtk.Image()
|
|
|
|
img.set_from_stock(Gtk.STOCK_MEDIA_PLAY, Gtk.IconSize.MENU)
|
|
|
|
item.set_image(img)
|
|
|
|
item.show()
|
|
|
|
item.connect("activate", self._on_start_clicked)
|
|
|
|
menu.add(item)
|
|
|
|
|
|
|
|
item = Gtk.ImageMenuItem(_("_Delete snapshot"))
|
|
|
|
item.set_use_underline(True)
|
|
|
|
img = Gtk.Image()
|
|
|
|
img.set_from_stock(Gtk.STOCK_DELETE, Gtk.IconSize.MENU)
|
|
|
|
item.set_image(img)
|
|
|
|
item.show()
|
|
|
|
item.connect("activate", self._on_delete_clicked)
|
|
|
|
menu.add(item)
|
|
|
|
|
|
|
|
self._snapmenu = menu
|
|
|
|
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
|
|
|
###################
|
|
|
|
# Functional bits #
|
|
|
|
###################
|
|
|
|
|
2013-09-30 14:56:09 -05:00
|
|
|
def _get_selected_snapshot(self):
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
widget = self.widget("snapshot-list")
|
|
|
|
selection = widget.get_selection()
|
|
|
|
model, treepath = selection.get_selected()
|
|
|
|
if treepath is None:
|
|
|
|
return None
|
2013-09-30 17:46:54 -05:00
|
|
|
try:
|
|
|
|
name = model[treepath][0]
|
|
|
|
for snap in self.vm.list_snapshots():
|
|
|
|
if name == snap.get_name():
|
|
|
|
return snap
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
return None
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
2013-09-30 20:41:10 -05:00
|
|
|
def _refresh_snapshots(self, select_name=None):
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
self.vm.refresh_snapshots()
|
2013-09-30 20:41:10 -05:00
|
|
|
self._populate_snapshot_list(select_name)
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
|
|
|
def show_page(self):
|
|
|
|
if not self._initial_populate:
|
|
|
|
self._populate_snapshot_list()
|
|
|
|
|
|
|
|
def _set_error_page(self, msg):
|
|
|
|
self._set_snapshot_state(None)
|
|
|
|
self.widget("snapshot-notebook").set_current_page(1)
|
|
|
|
self.widget("snapshot-error-label").set_text(msg)
|
|
|
|
|
2013-09-30 20:41:10 -05:00
|
|
|
def _populate_snapshot_list(self, select_name=None):
|
2013-09-30 17:46:54 -05:00
|
|
|
cursnap = self._get_selected_snapshot()
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
model = self.widget("snapshot-list").get_model()
|
|
|
|
model.clear()
|
|
|
|
|
|
|
|
try:
|
|
|
|
snapshots = self.vm.list_snapshots()
|
|
|
|
except Exception, e:
|
|
|
|
logging.exception(e)
|
|
|
|
self._set_error_page(_("Error refreshing snapshot list: %s") %
|
|
|
|
str(e))
|
|
|
|
return
|
|
|
|
|
2013-09-30 16:53:55 -05:00
|
|
|
has_external = False
|
|
|
|
has_internal = False
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
for snap in snapshots:
|
2013-09-23 07:34:50 -05:00
|
|
|
desc = snap.get_xmlobj().description
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
if not uihelpers.can_set_row_none:
|
|
|
|
desc = desc or ""
|
|
|
|
|
2013-09-30 16:36:38 -05:00
|
|
|
name = snap.get_name()
|
|
|
|
state = util.xml_escape(snap.run_status())
|
2013-09-30 16:53:55 -05:00
|
|
|
if snap.is_external():
|
|
|
|
has_external = True
|
|
|
|
sortname = "3%s" % name
|
|
|
|
external = " (%s)" % _("External")
|
|
|
|
else:
|
|
|
|
has_internal = True
|
|
|
|
external = ""
|
|
|
|
sortname = "1%s" % name
|
|
|
|
|
|
|
|
label = "%s\n<span size='small'>%s: %s%s</span>" % (
|
|
|
|
(name, _("State"), state, external))
|
2013-09-30 17:46:54 -05:00
|
|
|
model.append([name, label, desc, snap.run_status_icon_name(),
|
2013-09-30 16:53:55 -05:00
|
|
|
sortname])
|
|
|
|
|
|
|
|
if has_internal and has_external:
|
|
|
|
model.append([None, None, None, None, "2"])
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
2013-09-30 20:41:10 -05:00
|
|
|
select_name = select_name or (cursnap and cursnap.get_name() or None)
|
|
|
|
uihelpers.set_row_selection(self.widget("snapshot-list"), select_name)
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
self._initial_populate = True
|
|
|
|
|
2013-09-30 20:41:10 -05:00
|
|
|
def _make_screenshot_pixbuf(self, mime, sdata):
|
|
|
|
loader = GdkPixbuf.PixbufLoader.new_with_mime_type(mime)
|
|
|
|
loader.write(sdata)
|
|
|
|
pixbuf = loader.get_pixbuf()
|
|
|
|
loader.close()
|
|
|
|
|
|
|
|
maxsize = 450
|
|
|
|
def _scale(big, small, maxsize):
|
|
|
|
if big <= maxsize:
|
|
|
|
return big, small
|
|
|
|
factor = float(maxsize) / float(big)
|
|
|
|
return maxsize, int(factor * float(small))
|
|
|
|
|
|
|
|
width = pixbuf.get_width()
|
|
|
|
height = pixbuf.get_height()
|
|
|
|
if width > height:
|
|
|
|
width, height = _scale(width, height, maxsize)
|
|
|
|
else:
|
|
|
|
height, width = _scale(height, width, maxsize)
|
|
|
|
|
|
|
|
return pixbuf.scale_simple(width, height,
|
|
|
|
GdkPixbuf.InterpType.BILINEAR)
|
|
|
|
|
|
|
|
def _read_screenshot_file(self, name):
|
|
|
|
if not name:
|
|
|
|
return
|
|
|
|
|
|
|
|
cache_dir = self.vm.get_cache_dir()
|
|
|
|
basename = os.path.join(cache_dir, "snap-screenshot-%s" % name)
|
|
|
|
files = glob.glob(basename + ".*")
|
|
|
|
if not files:
|
|
|
|
return
|
|
|
|
|
|
|
|
filename = files[0]
|
|
|
|
mime = _mime_to_ext(os.path.splitext(filename)[1][1:], reverse=True)
|
|
|
|
if not mime:
|
|
|
|
return
|
|
|
|
return self._make_screenshot_pixbuf(mime, file(filename, "rb").read())
|
|
|
|
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
def _set_snapshot_state(self, snap=None):
|
|
|
|
self.widget("snapshot-notebook").set_current_page(0)
|
|
|
|
|
2013-09-23 07:34:50 -05:00
|
|
|
xmlobj = snap and snap.get_xmlobj() or None
|
|
|
|
name = snap and xmlobj.name or ""
|
|
|
|
desc = snap and xmlobj.description or ""
|
2013-09-30 16:11:22 -05:00
|
|
|
state = snap and snap.run_status() or ""
|
|
|
|
icon = snap and snap.run_status_icon_name() or None
|
2013-09-30 16:53:55 -05:00
|
|
|
is_external = snap and snap.is_external() or False
|
|
|
|
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
timestamp = ""
|
|
|
|
if snap:
|
|
|
|
timestamp = str(datetime.datetime.fromtimestamp(
|
2013-09-23 07:34:50 -05:00
|
|
|
xmlobj.creationTime))
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
|
|
|
title = ""
|
|
|
|
if name:
|
2013-09-30 14:56:09 -05:00
|
|
|
title = "<b>Snapshot '%s':</b>" % util.xml_escape(name)
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
|
|
|
self.widget("snapshot-title").set_markup(title)
|
|
|
|
self.widget("snapshot-timestamp").set_text(timestamp)
|
|
|
|
self.widget("snapshot-description").get_buffer().set_text(desc)
|
|
|
|
|
|
|
|
self.widget("snapshot-status-text").set_text(state)
|
2013-09-30 16:11:22 -05:00
|
|
|
if icon:
|
|
|
|
self.widget("snapshot-status-icon").set_from_icon_name(
|
|
|
|
icon, Gtk.IconSize.MENU)
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
2013-09-30 16:53:55 -05:00
|
|
|
uihelpers.set_grid_row_visible(self.widget("snapshot-mode"),
|
|
|
|
is_external)
|
|
|
|
if is_external:
|
|
|
|
is_mem = xmlobj.memory_type == "external"
|
|
|
|
is_disk = [d.snapshot == "external" for d in xmlobj.disks]
|
|
|
|
if is_mem and is_disk:
|
|
|
|
mode = _("External disk and memory")
|
|
|
|
elif is_mem:
|
|
|
|
mode = _("External memory only")
|
|
|
|
else:
|
|
|
|
mode = _("External disk only")
|
|
|
|
self.widget("snapshot-mode").set_text(mode)
|
|
|
|
|
2013-09-30 20:41:10 -05:00
|
|
|
sn = self._read_screenshot_file(name)
|
|
|
|
self.widget("snapshot-screenshot").set_visible(bool(sn))
|
|
|
|
self.widget("snapshot-screenshot-label").set_visible(not bool(sn))
|
|
|
|
if sn:
|
|
|
|
self.widget("snapshot-screenshot").set_from_pixbuf(sn)
|
|
|
|
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
self.widget("snapshot-add").set_sensitive(True)
|
|
|
|
self.widget("snapshot-delete").set_sensitive(bool(snap))
|
|
|
|
self.widget("snapshot-start").set_sensitive(bool(snap))
|
|
|
|
self.widget("snapshot-apply").set_sensitive(False)
|
|
|
|
|
|
|
|
|
2013-09-30 13:28:43 -05:00
|
|
|
##################
|
|
|
|
# 'New' handling #
|
|
|
|
##################
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
2013-09-30 20:41:10 -05:00
|
|
|
def _take_screenshot(self):
|
|
|
|
stream = None
|
|
|
|
try:
|
|
|
|
stream = self.vm.conn.get_backend().newStream(0)
|
|
|
|
screen = 0
|
|
|
|
flags = 0
|
|
|
|
mime = self.vm.get_backend().screenshot(stream, screen, flags)
|
|
|
|
|
|
|
|
ret = StringIO.StringIO()
|
|
|
|
def _write_cb(_stream, data, userdata):
|
|
|
|
ignore = stream
|
|
|
|
ignore = userdata
|
|
|
|
ret.write(data)
|
|
|
|
|
|
|
|
stream.recvAll(_write_cb, None)
|
|
|
|
return mime, ret.getvalue()
|
|
|
|
finally:
|
|
|
|
try:
|
|
|
|
if stream:
|
|
|
|
stream.finish()
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
|
|
|
def _get_screenshot(self):
|
|
|
|
if not self.vm.is_active():
|
|
|
|
logging.debug("Skipping screenshot since VM is not active")
|
|
|
|
return
|
|
|
|
if not self.vm.get_graphics_devices():
|
|
|
|
logging.debug("Skipping screenshot since VM has no graphics")
|
|
|
|
return
|
|
|
|
|
|
|
|
try:
|
|
|
|
mime, sdata = self._take_screenshot()
|
|
|
|
except:
|
|
|
|
logging.exception("Error taking screenshot")
|
|
|
|
return
|
|
|
|
|
|
|
|
ext = _mime_to_ext(mime)
|
|
|
|
if not ext:
|
|
|
|
return
|
|
|
|
|
|
|
|
newpix = self._make_screenshot_pixbuf(mime, sdata)
|
|
|
|
setattr(newpix, "vmm_mimetype", mime)
|
|
|
|
setattr(newpix, "vmm_sndata", sdata)
|
|
|
|
return newpix
|
|
|
|
|
2013-09-30 13:28:43 -05:00
|
|
|
def _reset_new_state(self):
|
2013-09-30 15:33:45 -05:00
|
|
|
collidelist = [s.get_xmlobj().name for s in self.vm.list_snapshots()]
|
|
|
|
default_name = DomainSnapshot.find_free_name(
|
|
|
|
self.vm.get_backend(), collidelist)
|
|
|
|
|
|
|
|
self.widget("snapshot-new-name").set_text(default_name)
|
2013-09-30 15:04:11 -05:00
|
|
|
self.widget("snapshot-new-name").emit("changed")
|
2013-09-30 13:28:43 -05:00
|
|
|
self.widget("snapshot-new-description").get_buffer().set_text("")
|
2013-09-30 15:37:46 -05:00
|
|
|
self.widget("snapshot-new-ok").grab_focus()
|
2013-09-30 16:40:01 -05:00
|
|
|
self.widget("snapshot-new-status-text").set_text(self.vm.run_status())
|
|
|
|
self.widget("snapshot-new-status-icon").set_from_icon_name(
|
|
|
|
self.vm.run_status_icon_name(), Gtk.IconSize.MENU)
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
2013-09-30 20:41:10 -05:00
|
|
|
sn = self._get_screenshot()
|
|
|
|
uihelpers.set_grid_row_visible(
|
|
|
|
self.widget("snapshot-new-screenshot"), bool(sn))
|
|
|
|
if sn:
|
|
|
|
self.widget("snapshot-new-screenshot").set_from_pixbuf(sn)
|
|
|
|
|
|
|
|
|
2013-09-30 15:04:11 -05:00
|
|
|
def _snapshot_new_name_changed(self, src):
|
|
|
|
self.widget("snapshot-new-ok").set_sensitive(bool(src.get_text()))
|
|
|
|
|
2013-09-30 20:41:10 -05:00
|
|
|
def _new_finish_cb(self, error, details, newname):
|
2013-09-06 19:59:01 -05:00
|
|
|
self.topwin.set_sensitive(True)
|
|
|
|
self.topwin.get_window().set_cursor(
|
|
|
|
Gdk.Cursor.new(Gdk.CursorType.TOP_LEFT_ARROW))
|
|
|
|
|
|
|
|
if error is not None:
|
|
|
|
error = _("Error creating snapshot: %s") % error
|
|
|
|
self.err.show_err(error, details=details)
|
|
|
|
return
|
2013-09-30 20:41:10 -05:00
|
|
|
self._refresh_snapshots(newname)
|
2013-09-06 19:59:01 -05:00
|
|
|
|
2013-09-30 13:28:43 -05:00
|
|
|
def _validate_new_snapshot(self):
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
name = self.widget("snapshot-new-name").get_text()
|
2013-09-30 13:28:43 -05:00
|
|
|
desc = self.widget("snapshot-new-description"
|
|
|
|
).get_buffer().get_property("text")
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
2013-09-30 13:28:43 -05:00
|
|
|
try:
|
2013-09-30 15:33:45 -05:00
|
|
|
newsnap = DomainSnapshot(self.vm.conn.get_backend())
|
2013-09-30 13:28:43 -05:00
|
|
|
newsnap.name = name
|
|
|
|
newsnap.description = desc or None
|
|
|
|
newsnap.validate()
|
2013-09-30 20:41:10 -05:00
|
|
|
newsnap.get_xml_config()
|
|
|
|
return newsnap
|
2013-09-30 13:28:43 -05:00
|
|
|
except Exception, e:
|
|
|
|
return self.err.val_err(_("Error validating snapshot: %s" % e))
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
2013-09-30 20:41:10 -05:00
|
|
|
def _get_screenshot_data_for_save(self):
|
|
|
|
snwidget = self.widget("snapshot-new-screenshot")
|
|
|
|
if not snwidget.is_visible():
|
|
|
|
return None, None
|
|
|
|
|
|
|
|
sn = snwidget.get_pixbuf()
|
|
|
|
if not sn:
|
|
|
|
return None, None
|
|
|
|
|
|
|
|
mime = getattr(sn, "vmm_mimetype", None)
|
|
|
|
sndata = getattr(sn, "vmm_sndata", None)
|
|
|
|
return mime, sndata
|
|
|
|
|
|
|
|
def _do_create_snapshot(self, asyncjob, xml, name, mime, sndata):
|
|
|
|
ignore = asyncjob
|
|
|
|
|
|
|
|
self.vm.create_snapshot(xml)
|
|
|
|
|
|
|
|
try:
|
|
|
|
cachedir = self.vm.get_cache_dir()
|
|
|
|
basesn = os.path.join(cachedir, "snap-screenshot-%s" % name)
|
|
|
|
|
|
|
|
# Remove any pre-existing screenshots so we don't show stale data
|
|
|
|
for ext in mimemap.values():
|
|
|
|
p = basesn + "." + ext
|
|
|
|
if os.path.exists(basesn + "." + ext):
|
|
|
|
os.unlink(p)
|
|
|
|
|
|
|
|
if not mime or not sndata:
|
|
|
|
return
|
|
|
|
|
|
|
|
filename = basesn + "." + _mime_to_ext(mime)
|
|
|
|
logging.debug("Writing screenshot to %s", filename)
|
|
|
|
file(filename, "wb").write(sndata)
|
|
|
|
except:
|
|
|
|
logging.exception("Error saving screenshot")
|
|
|
|
|
2013-09-30 13:28:43 -05:00
|
|
|
def _create_new_snapshot(self):
|
2013-09-30 20:41:10 -05:00
|
|
|
snap = self._validate_new_snapshot()
|
|
|
|
if not snap:
|
2013-09-30 13:28:43 -05:00
|
|
|
return
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
2013-09-30 20:41:10 -05:00
|
|
|
xml = snap.get_xml_config()
|
|
|
|
name = snap.name
|
|
|
|
mime, sndata = self._get_screenshot_data_for_save()
|
|
|
|
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
self.topwin.set_sensitive(False)
|
|
|
|
self.topwin.get_window().set_cursor(
|
|
|
|
Gdk.Cursor.new(Gdk.CursorType.WATCH))
|
|
|
|
|
|
|
|
self._snapshot_new_close()
|
|
|
|
progWin = vmmAsyncJob(
|
2013-09-30 20:41:10 -05:00
|
|
|
self._do_create_snapshot, [xml, name, mime, sndata],
|
|
|
|
self._new_finish_cb, [name],
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
_("Creating snapshot"),
|
|
|
|
_("Creating virtual machine snapshot"),
|
|
|
|
self.topwin)
|
2013-09-06 19:59:01 -05:00
|
|
|
progWin.run()
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
2013-09-30 13:28:43 -05:00
|
|
|
|
|
|
|
#############
|
|
|
|
# Listeners #
|
|
|
|
#############
|
|
|
|
|
2013-10-05 13:57:58 -05:00
|
|
|
def _popup_snapshot_menu(self, src, event):
|
|
|
|
ignore = src
|
|
|
|
if event.button != 3:
|
|
|
|
return
|
|
|
|
self._snapmenu.popup(None, None, None, None, 0, event.time)
|
|
|
|
|
2013-09-30 13:28:43 -05:00
|
|
|
def _snapshot_new_close(self, *args, **kwargs):
|
|
|
|
ignore = args
|
|
|
|
ignore = kwargs
|
|
|
|
self._snapshot_new.hide()
|
|
|
|
return 1
|
|
|
|
|
|
|
|
def _description_changed(self, ignore):
|
|
|
|
self.widget("snapshot-apply").set_sensitive(True)
|
|
|
|
|
|
|
|
def _on_apply_clicked(self, ignore):
|
2013-09-30 14:56:09 -05:00
|
|
|
snap = self._get_selected_snapshot()
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
if not snap:
|
|
|
|
return
|
|
|
|
|
2013-09-30 13:28:43 -05:00
|
|
|
desc_widget = self.widget("snapshot-description")
|
|
|
|
desc = desc_widget.get_buffer().get_property("text") or ""
|
|
|
|
|
|
|
|
xmlobj = snap.get_xmlobj()
|
|
|
|
origxml = xmlobj.get_xml_config()
|
|
|
|
xmlobj.description = desc
|
|
|
|
newxml = xmlobj.get_xml_config()
|
|
|
|
|
2013-10-01 09:21:44 -05:00
|
|
|
uihelpers.log_redefine_xml_diff(snap, origxml, newxml)
|
2013-09-30 13:28:43 -05:00
|
|
|
if newxml == origxml:
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
return
|
2013-09-30 13:28:43 -05:00
|
|
|
self.vm.create_snapshot(newxml, redefine=True)
|
|
|
|
snap.refresh_xml()
|
|
|
|
self._refresh_snapshots()
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
2013-09-30 13:28:43 -05:00
|
|
|
def _on_new_ok_clicked(self, ignore):
|
|
|
|
return self._create_new_snapshot()
|
|
|
|
|
|
|
|
def _on_add_clicked(self, ignore):
|
|
|
|
if self._snapshot_new.is_visible():
|
|
|
|
return
|
|
|
|
self._reset_new_state()
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
self._snapshot_new.show()
|
2013-10-05 13:47:10 -05:00
|
|
|
self.widget("snapshot-new-name").grab_focus()
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
|
|
|
def _on_start_clicked(self, ignore):
|
2013-09-30 14:56:09 -05:00
|
|
|
snap = self._get_selected_snapshot()
|
2013-10-05 13:57:58 -05:00
|
|
|
result = self.err.yes_no(_("Are you sure you want to run "
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
"snapshot '%s'? All disk changes since "
|
2013-09-30 16:53:55 -05:00
|
|
|
"the last snapshot was created will be "
|
|
|
|
"discarded.") % snap.get_name())
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
if not result:
|
|
|
|
return
|
|
|
|
|
2013-10-05 13:57:58 -05:00
|
|
|
logging.debug("Running snapshot '%s'", snap.get_name())
|
2013-10-05 09:03:56 -05:00
|
|
|
vmmAsyncJob.simple_async(self.vm.revert_to_snapshot,
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
[snap], self,
|
2013-10-05 13:57:58 -05:00
|
|
|
_("Running snapshot"),
|
|
|
|
_("Running snapshot '%s'") % snap.get_name(),
|
|
|
|
_("Error running snapshot '%s'") %
|
2013-09-06 19:59:01 -05:00
|
|
|
snap.get_name(),
|
|
|
|
finish_cb=self._refresh_snapshots)
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
|
|
|
def _on_delete_clicked(self, ignore):
|
2013-09-30 14:56:09 -05:00
|
|
|
snap = self._get_selected_snapshot()
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
if not snap:
|
|
|
|
return
|
|
|
|
|
|
|
|
result = self.err.yes_no(_("Are you sure you want to permanently "
|
|
|
|
"delete the snapshot '%s'?") %
|
|
|
|
snap.get_name())
|
|
|
|
if not result:
|
|
|
|
return
|
|
|
|
|
|
|
|
logging.debug("Deleting snapshot '%s'", snap.get_name())
|
2013-10-05 09:03:56 -05:00
|
|
|
vmmAsyncJob.simple_async(snap.delete, [], self,
|
|
|
|
_("Deleting snapshot"),
|
|
|
|
_("Deleting snapshot '%s'") % snap.get_name(),
|
2013-09-06 19:59:01 -05:00
|
|
|
_("Error deleting snapshot '%s'") % snap.get_name(),
|
|
|
|
finish_cb=self._refresh_snapshots)
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
|
|
|
|
|
|
|
|
def _snapshot_selected(self, selection):
|
2013-09-30 17:46:54 -05:00
|
|
|
ignore = selection
|
|
|
|
snap = self._get_selected_snapshot()
|
|
|
|
if not snap:
|
Initial snapshot support
This adds initial UI for managing snapshots: list, run/revert, delete,
add, and redefining (for changing <description>) supported, but currently
only for internal snapshots. The UI is mostly in its final form except for
some bells and whistles.
The real remaining question is what do we want to advertise and support.
Internal (qcow2) snapshots are by far the simplest to manage, very
mature, and already have the semantics we want.
However most recent libvirt and qemu work has been to facilitate
external snapshots, which are more extensible and can be performed
live, and with qemu-ga coordination for extra safety. However
they make things much harder for virt-manager at the moment.
Until we have a plan, this work should be considered experimental
and not be relied upon.
2013-08-02 09:18:47 -05:00
|
|
|
self._set_error_page(_("No snapshot selected."))
|
|
|
|
return
|
|
|
|
|
|
|
|
try:
|
|
|
|
self._set_snapshot_state(snap)
|
|
|
|
except Exception, e:
|
|
|
|
logging.exception(e)
|
|
|
|
self._set_error_page(_("Error selecting snapshot: %s") % str(e))
|