[gnome-boxes] Create VM before 'review' page
- From: Zeeshan Ali Khattak <zeeshanak src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-boxes] Create VM before 'review' page
- Date: Tue, 26 Jun 2012 14:35:41 +0000 (UTC)
commit 13bca42b991bb72143a49faa25ebff856fae930b
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date: Wed May 16 16:46:00 2012 +0300
Create VM before 'review' page
This means that we now move most of the failure points before arriving to
review page. If user hits 'create' on the review page, the VM is simply
launched. OTOH if user hits 'back' or 'cancel', the created VM is deleted
along with its volume (cheap operation).
Why do we need this change?
If you look at the later commit, you'll notice that we at least need to
create the configuration(s) before 'review' since we need information
about the new domain to display to user. Now its an interesting question
whether we should only create configuration before hand or the whole
machine.
The reasons I decided to go with the latter approach was:
1. I recalled mccann saying that we should ensure that we have everything
ready at the 'review' page. I agree with that since its better to error
out during preparation and setup rather than after we told user that
everything is ready, she/he clicks create and we go *boom*.
2. IMHO it makes for a much better end-user experience if user has to
wait less on each step rather than wait a long time on one step.
3. I did try to change this to only create config before review page
rather than the whole VM. The problem is that we can't create complete
domain configuration before creation of main storage volume as we can
only reliably get the path of the volume *after* the volume is
created. So we'll either have to have a partial domain config at review
and we add the volume's path at creation time (seems pretty ugly to me)
or we create the volume before review page (which brings us to the same
potential issues as with pre-creating the VM).
https://bugzilla.gnome.org/show_bug.cgi?id=674209
src/app.vala | 2 +
src/wizard.vala | 69 +++++++++++++++++++++++++++++++++++++++---------------
2 files changed, 52 insertions(+), 19 deletions(-)
---
diff --git a/src/app.vala b/src/app.vala
index ede6b4b..9865ed4 100644
--- a/src/app.vala
+++ b/src/app.vala
@@ -523,6 +523,8 @@ private class Boxes.App: Boxes.UI {
machine.suspend.begin ();
}
+ wizard.cleanup ();
+
return false;
}
diff --git a/src/wizard.vala b/src/wizard.vala
index bb143d5..3fb7f14 100644
--- a/src/wizard.vala
+++ b/src/wizard.vala
@@ -16,6 +16,7 @@ private class Boxes.Wizard: Boxes.UI {
private GtkClutter.Actor gtk_actor;
private GenericArray<Gtk.Label> steps;
private Gtk.Notebook notebook;
+ private Gtk.Button cancel_button;
private Gtk.Button back_button;
private Gtk.Button next_button;
private Boxes.WizardSource wizard_source;
@@ -30,11 +31,14 @@ private class Boxes.Wizard: Boxes.UI {
private VMCreator vm_creator;
private InstallerMedia? install_media;
+ private LibvirtMachine? machine;
private WizardPage _page;
private WizardPage page {
get { return _page; }
set {
+ back_button.sensitive = value != WizardPage.INTRODUCTION;
+
var forwards = value > page;
switch (value) {
@@ -67,20 +71,33 @@ private class Boxes.Wizard: Boxes.UI {
break;
case WizardPage.REVIEW:
- if (!review ())
- return;
+ back_button.sensitive = false;
+ next_button.sensitive = false;
+ cancel_button.sensitive = false;
+ review.begin ((source, result) => {
+ back_button.sensitive = true;
+ next_button.sensitive = true;
+ cancel_button.sensitive = true;
+
+ if (!review.end (result))
+ page = page - 1;
+ });
break;
case WizardPage.LAST:
skip_review_for_live = false;
- create.begin ((source, result) => {
- if (create.end (result))
- App.app.ui_state = UIState.COLLECTION;
- else
- App.app.notificationbar.display_error (_("Box creation failed!"));
- });
+ if (create ())
+ App.app.ui_state = UIState.COLLECTION;
+ else
+ App.app.notificationbar.display_error (_("Box creation failed!"));
return;
}
+ } else {
+ switch (page) {
+ case WizardPage.REVIEW:
+ destroy_machine ();
+ break;
+ }
}
if (skip_page (value))
@@ -97,7 +114,6 @@ private class Boxes.Wizard: Boxes.UI {
/* highlight in white current page label */
steps.get (page).modify_fg (Gtk.StateType.NORMAL, get_color ("white"));
- back_button.sensitive = page != WizardPage.INTRODUCTION;
next_button.label = page != WizardPage.REVIEW ? _("C_ontinue") : _("C_reate");
}
}
@@ -157,22 +173,26 @@ private class Boxes.Wizard: Boxes.UI {
setup_ui ();
}
- private async bool create () {
+ public void cleanup () {
+ destroy_machine ();
+ }
+
+ private bool create () {
if (source == null) {
if (install_media == null)
return false;
next_button.sensitive = false;
try {
- var machine = yield vm_creator.create_vm (install_media, null);
vm_creator.launch_vm (machine, install_media);
- } catch (IOError.CANCELLED cancel_error) { // We did this, so ignore!
} catch (GLib.Error error) {
warning (error.message);
+
return false;
}
install_media = null;
+ machine = null;
wizard_source.uri = "";
return true;
@@ -286,19 +306,22 @@ private class Boxes.Wizard: Boxes.UI {
return true;
}
- private bool review () {
+ private async bool review () {
+ summary.clear ();
+
if (install_media != null && install_media is UnattendedInstaller) {
try {
(install_media as UnattendedInstaller).check_needed_info ();
- } catch (UnattendedInstallerError.SETUP_INCOMPLETE error) {
+ machine = yield vm_creator.create_vm (install_media, null);
+ } catch (IOError.CANCELLED cancel_error) { // We did this, so ignore!
+ return false;
+ } catch (GLib.Error error) {
App.app.notificationbar.display_error (error.message);
return false;
}
}
- summary.clear ();
-
review_label.set_text (_("Will create a new box with the following properties:"));
if (source != null) {
@@ -521,11 +544,12 @@ private class Boxes.Wizard: Boxes.UI {
tool_item.child = label;
toolbar.insert (tool_item, 0);
- var cancel = new Gtk.Button.from_stock (Gtk.Stock.CANCEL);
+ cancel_button = new Gtk.Button.from_stock (Gtk.Stock.CANCEL);
tool_item = new Gtk.ToolItem ();
- tool_item.child = cancel;
+ tool_item.child = cancel_button;
toolbar.insert (tool_item, 1);
- cancel.clicked.connect (() => {
+ cancel_button.clicked.connect (() => {
+ destroy_machine ();
wizard_source.page = SourcePage.MAIN;
App.app.ui_state = UIState.COLLECTION;
});
@@ -575,6 +599,13 @@ private class Boxes.Wizard: Boxes.UI {
fade_actor (actor, opacity);
}
+ private void destroy_machine () {
+ if (machine != null) {
+ machine.delete ();
+ machine = null;
+ }
+ }
+
private class WizardSummary: GLib.Object {
public Gtk.Widget widget { get { return table; } }
private Gtk.Table table;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]