[Ovirt-devel] [PATCH 2/2] Enables users to migrate virtual machines between hosts.
Darryl L. Pierce
dpierce at redhat.com
Fri Dec 4 21:03:45 UTC 2009
Users select a virtual machine on their current libvirt host. They then
select a target machine, which must have been previously configured as a
connection. They confirm the migration and then it runs.
---
Makefile.am | 1 +
nodeadmin/addhost.py | 10 ++++-
nodeadmin/libvirtworker.py | 6 +++
nodeadmin/migratedomain.py | 81 ++++++++++++++++++++++++++++++++++++++++++++
nodeadmin/nodemenu.py | 28 +++++++++------
nodeadmin/setup.py.in | 1 +
ovirt-node.spec.in | 2 +
7 files changed, 115 insertions(+), 14 deletions(-)
create mode 100644 nodeadmin/migratedomain.py
diff --git a/Makefile.am b/Makefile.am
index e673aa4..c044d78 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -48,6 +48,7 @@ EXTRA_DIST = \
nodeadmin/listpools.py \
nodeadmin/mainmenu.py \
nodeadmin/menuscreen.py \
+ nodeadmin/migratedomain.py \
nodeadmin/networkconfig.py \
nodeadmin/netmenu.py \
nodeadmin/nodeadmin.py \
diff --git a/nodeadmin/addhost.py b/nodeadmin/addhost.py
index ef35b7d..ebcb4ea 100644
--- a/nodeadmin/addhost.py
+++ b/nodeadmin/addhost.py
@@ -59,7 +59,9 @@ class AddHostConfigScreen(ConfigScreen):
def validate_input(self, page, errors):
if page is DETAILS_PAGE:
- if len(self.__hostname.value()) > 0:
+ if self.__connection.getSelection() is CONNECTION_LOCAL:
+ return True
+ elif len(self.__hostname.value()) > 0:
return True
else:
errors.append("You must enter a remote hostname.")
@@ -115,8 +117,12 @@ class AddHostConfigScreen(ConfigScreen):
grid.setField(Label(HYPERVISORS[self.__hypervisor.getSelection()]), 1, 0, anchorLeft = 1)
grid.setField(Label("Connection:"), 0, 1, anchorRight = 1)
grid.setField(Label(CONNECTIONS[self.__connection.getSelection()]), 1, 1, anchorLeft = 1)
+ if self.__connection.getSelection() is not CONNECTION_LOCAL:
+ hostname = self.__hostname.value()
+ else:
+ hostname = "local"
grid.setField(Label("Hostname:"), 0, 2, anchorRight = 1)
- grid.setField(Label(self.__hostname.value()), 1, 2, anchorLeft = 1)
+ grid.setField(Label(hostname), 1, 2, anchorLeft = 1)
grid.setField(Label("Autoconnect on Startup:"), 0, 3, anchorRight = 1)
label = "Yes"
if not self.__autoconnect.value(): label = "No"
diff --git a/nodeadmin/libvirtworker.py b/nodeadmin/libvirtworker.py
index 15d1c58..b35509f 100644
--- a/nodeadmin/libvirtworker.py
+++ b/nodeadmin/libvirtworker.py
@@ -126,6 +126,12 @@ class LibvirtWorker:
domain = self.get_domain(name)
domain.undefine()
+ def migrate_domain(self, name, target):
+ '''Migrates the specified domain to the target machine.'''
+ target_conn = libvirt.open(target)
+ virtmachine = self.get_domain(name)
+ virtmachine.migrate(target_conn, libvirt.VIR_MIGRATE_LIVE, None, None, 0)
+
def list_networks(self, defined = True, started = True):
'''Lists all networks.'''
result = []
diff --git a/nodeadmin/migratedomain.py b/nodeadmin/migratedomain.py
new file mode 100644
index 0000000..8c8c268
--- /dev/null
+++ b/nodeadmin/migratedomain.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+#
+# migratedomain.py - Copyright (C) 2009 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at 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; version 2 of the License.
+#
+# 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. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+from snack import *
+from libvirtworker import LibvirtWorker
+from configscreen import *
+
+LIST_DOMAINS = 1
+SELECT_TARGET = 2
+CONFIRM_PAGE = 3
+
+class MigrateDomainConfigScreen(DomainListConfigScreen):
+ def __init__(self):
+ DomainListConfigScreen.__init__(self, "Migrate Virtual Machine")
+ self.__configured = False
+
+ def get_elements_for_page(self, screen, page):
+ if page is LIST_DOMAINS: return self.get_domain_list_page(screen)
+ elif page is SELECT_TARGET: return self.get_target_page(screen)
+ elif page is CONFIRM_PAGE: return self.get_confirm_page(screen)
+
+ def page_has_next(self, page):
+ if page is LIST_DOMAINS: return self.has_selectable_domains()
+ else: return page < CONFIRM_PAGE
+
+ def page_has_back(self, page):
+ return page < CONFIRM_PAGE
+
+ def page_has_finish(self, page):
+ return page is CONFIRM_PAGE
+
+ def validate_input(self, page, errors):
+ if page is LIST_DOMAINS: return self.get_selected_domain() is not None
+ elif page is SELECT_TARGET:
+ if self.__targets.current() is None:
+ errors.append("Please enter a target hostname or IP address.")
+ return False
+ elif page is CONFIRM_PAGE:
+ if not self.__confirm.value():
+ errors.append("You must confirm migrating this virtual machine to proceed.")
+ return False
+ return True
+
+ def process_input(self, page):
+ if page is CONFIRM_PAGE:
+ self.get_libvirt().migrate_domain(self.get_selected_domain(), self.__targets.current())
+ self.set_finished()
+
+ def get_target_page(self, screen):
+ self.__targets = Listbox(0)
+ for connection in self.get_virt_manager_config().get_connection_list():
+ self.__targets.append(connection, connection)
+ return [Label("Select A Target Host"),
+ self.__targets]
+
+ def get_confirm_page(self, screen):
+ self.__confirm = Checkbox("Confirm migrating this virtual machine.")
+ grid = Grid(1, 1)
+ grid.setField(self.__confirm, 0, 0)
+ return [grid]
+
+def MigrateDomain():
+ screen = MigrateDomainConfigScreen()
+ screen.start()
diff --git a/nodeadmin/nodemenu.py b/nodeadmin/nodemenu.py
index 16be89c..f213e09 100755
--- a/nodeadmin/nodemenu.py
+++ b/nodeadmin/nodemenu.py
@@ -26,17 +26,19 @@ from startdomain import StartDomain
from stopdomain import StopDomain
from removedomain import RemoveDomain
from listdomains import ListDomains
+from migratedomain import MigrateDomain
from createuser import CreateUser
import utils
import logging
-ADD_DOMAIN = 1
-START_DOMAIN = 2
-STOP_DOMAIN = 3
-REMOVE_DOMAIN = 4
-LIST_DOMAINS = 5
-CREATE_USER = 6
+ADD_DOMAIN = 1
+START_DOMAIN = 2
+STOP_DOMAIN = 3
+REMOVE_DOMAIN = 4
+LIST_DOMAINS = 5
+MIGRATE_DOMAIN = 6
+CREATE_USER = 7
class NodeMenuScreen(MenuScreen):
def __init__(self):
@@ -48,15 +50,17 @@ class NodeMenuScreen(MenuScreen):
("Stop A Virtual Machine", STOP_DOMAIN),
("Remove A Virtual Machine", REMOVE_DOMAIN),
("List All Virtual Machines", LIST_DOMAINS),
+ ("Migrate Virtual Machine", MIGRATE_DOMAIN),
("Create A User", CREATE_USER))
def handle_selection(self, item):
- if item is ADD_DOMAIN: AddDomain()
- elif item is START_DOMAIN: StartDomain()
- elif item is STOP_DOMAIN: StopDomain()
- elif item is REMOVE_DOMAIN: RemoveDomain()
- elif item is LIST_DOMAINS: ListDomains()
- elif item is CREATE_USER: CreateUser()
+ if item is ADD_DOMAIN: AddDomain()
+ elif item is START_DOMAIN: StartDomain()
+ elif item is STOP_DOMAIN: StopDomain()
+ elif item is REMOVE_DOMAIN: RemoveDomain()
+ elif item is LIST_DOMAINS: ListDomains()
+ elif item is MIGRATE_DOMAIN: MigrateDomain()
+ elif item is CREATE_USER: CreateUser()
def NodeMenu():
screen = NodeMenuScreen()
diff --git a/nodeadmin/setup.py.in b/nodeadmin/setup.py.in
index 17bfe93..0a95dcc 100644
--- a/nodeadmin/setup.py.in
+++ b/nodeadmin/setup.py.in
@@ -29,6 +29,7 @@ setup(name = "nodeadmin",
'startvm = nodeadmin.startdomain:StartDomain',
'stopvm = nodeadmin.stopdomain:StopDomain',
'rmvm = nodeadmin.removedomain:RemoveDomain',
+ 'migratevm = nodeadmin.migratedomain:MigradeDomain',
'createuser = nodeadmin.createuser:CreateUser',
'listvms = nodeadmin.listdomains:ListDomains',
'definenet = nodeadmin.definenet:DefineNetwork',
diff --git a/ovirt-node.spec.in b/ovirt-node.spec.in
index f056f3f..8815b1c 100644
--- a/ovirt-node.spec.in
+++ b/ovirt-node.spec.in
@@ -187,6 +187,7 @@ cd -
%{__install} -p -m0755 nodeadmin/adddomain.py %{buildroot}%{python_sitelib}/nodeadmin
%{__install} -p -m0644 nodeadmin/domainconfig.py %{buildroot}%{python_sitelib}/nodeadmin
%{__install} -p -m0755 nodeadmin/listdomains.py %{buildroot}%{python_sitelib}/nodeadmin
+%{__install} -p -m0755 nodeadmin/migratedomain.py %{buildroot}%{python_sitelib}/nodeadmin
%{__install} -p -m0755 nodeadmin/removedomain.py %{buildroot}%{python_sitelib}/nodeadmin
%{__install} -p -m0755 nodeadmin/startdomain.py %{buildroot}%{python_sitelib}/nodeadmin
%{__install} -p -m0755 nodeadmin/stopdomain.py %{buildroot}%{python_sitelib}/nodeadmin
@@ -383,6 +384,7 @@ fi
%{_bindir}/stopvm
%{_bindir}/rmvm
%{_bindir}/listpools
+%{_bindir}/migratevm
%{_bindir}/listvms
%{_bindir}/rmpool
%{_bindir}/rmvolume
--
1.6.5.2
More information about the ovirt-devel
mailing list