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.
Signed-off-by: Darryl L. Pierce <[email protected]> --- 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 1671405..f557ea2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -41,6 +41,7 @@ EXTRA_DIST = \ nodeadmin/userworker.py \ nodeadmin/mainmenu.py \ nodeadmin/menuscreen.py \ + nodeadmin/migratedomain.py \ nodeadmin/netmenu.py \ nodeadmin/nodemenu.py \ nodeadmin/removedomain.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 2998486..878b01c 100644 --- a/nodeadmin/libvirtworker.py +++ b/nodeadmin/libvirtworker.py @@ -122,6 +122,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 <[email protected]> +# +# 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 1e6e028..8b17487 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 23ca2bf..f46bd2b 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 @@ -380,6 +381,7 @@ fi %{_bindir}/startvm %{_bindir}/stopvm %{_bindir}/rmvm +%{_bindir}/migratevm %{_bindir}/listvms %{_bindir}/definenet %{_bindir}/createnet -- 1.6.5.2 _______________________________________________ Ovirt-devel mailing list [email protected] https://www.redhat.com/mailman/listinfo/ovirt-devel
