From pmialon at linagora.com Tue Dec 1 16:47:08 2009 From: pmialon at linagora.com (Pierre-Gilles Mialon) Date: Tue, 1 Dec 2009 17:47:08 +0100 Subject: [Ovirt-devel] Re: [PATCH] fix storages crazyness In-Reply-To: <4B016429.1080803@linagora.com> References: <1255030846-8053-1-git-send-email-mloiseleur@linagora.com> <4B016429.1080803@linagora.com> Message-ID: <200912011747.08546.pmialon@linagora.com> Hi, Could you please have a look at this patch ? We really need it, and I think that almost user need it too. It ensure that a disk is assigned only once to one vm (wich means never two times or more the same disk for a single vm). This became usefull when the number of message in qpidd increase. Thanks, Le lundi 16 novembre 2009 15:39:37 Michel Loiseleur, vous avez ?crit : > Hi, > > Just to point you this patch, which is quite important and not ACK at > the moment. > > Thanks, > > Loiseleur Michel a ?crit : > > Signed-off-by: Loiseleur Michel > > --- > > app/models/vm.rb | 2 +- > > 1 files changed, 1 insertions(+), 1 deletions(-) > > > > diff --git a/app/models/vm.rb b/app/models/vm.rb > > index 88e0aef..0be3f89 100644 > > --- a/app/models/vm.rb > > +++ b/app/models/vm.rb > > @@ -27,7 +27,7 @@ class Vm < ActiveRecord::Base > > find(:all, :conditions=>{:state=>Task::STATE_QUEUED}) > > end > > end > > - has_and_belongs_to_many :storage_volumes > > + has_and_belongs_to_many :storage_volumes, :uniq => true > > > > has_many :nics, :dependent => :destroy > -- Pierre-Gilles Mialon Responsable h?bergement :: Head of Hosting services pmialon at linagora.com :: +33.1 58 18 65 46 Linagora :: http://www.linagora.com 27 rue de Berri :: 75008 PARIS -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: This is a digitally signed message part. URL: From imain at redhat.com Wed Dec 2 08:19:23 2009 From: imain at redhat.com (Ian Main) Date: Wed, 2 Dec 2009 00:19:23 -0800 Subject: [Ovirt-devel] Re: [PATCH] fix storages crazyness In-Reply-To: <200912011747.08546.pmialon@linagora.com> References: <1255030846-8053-1-git-send-email-mloiseleur@linagora.com> <4B016429.1080803@linagora.com> <200912011747.08546.pmialon@linagora.com> Message-ID: <20091202001923.26ea30c9@tp.mains.priv> On Tue, 1 Dec 2009 17:47:08 +0100 "Pierre-Gilles Mialon" wrote: > Hi, > > Could you please have a look at this patch ? We really need it, and I think > that almost user need it too. It ensure that a disk is assigned only once to > one vm (wich means never two times or more the same disk for a single vm). > This became usefull when the number of message in qpidd increase. I am curious how this affects the qmf/qpid end of things? I understand the relationship change but it's not clear to me how this effects qpidd etc. Thanks! Ian From pmialon at linagora.com Wed Dec 2 10:02:13 2009 From: pmialon at linagora.com (Pierre-Gilles Mialon) Date: Wed, 2 Dec 2009 11:02:13 +0100 Subject: [Ovirt-devel] Re: [PATCH] fix storages crazyness In-Reply-To: <20091202001923.26ea30c9@tp.mains.priv> References: <1255030846-8053-1-git-send-email-mloiseleur@linagora.com> <200912011747.08546.pmialon@linagora.com> <20091202001923.26ea30c9@tp.mains.priv> Message-ID: <200912021102.13771.pmialon@linagora.com> Le mercredi 2 d?cembre 2009 09:19:23 Ian Main, vous avez ?crit : > On Tue, 1 Dec 2009 17:47:08 +0100 > > "Pierre-Gilles Mialon" wrote: > > Hi, > > > > Could you please have a look at this patch ? We really need it, and I > > think that almost user need it too. It ensure that a disk is assigned > > only once to one vm (wich means never two times or more the same disk for > > a single vm). This became usefull when the number of message in qpidd > > increase. > > I am curious how this affects the qmf/qpid end of things? I understand the > relationship change but it's not clear to me how this effects qpidd etc. One of the comportment we actually notice, is that when the number of qpidd message increase, ruby-qmf produce errors like returning multiple times the same object. That affect the creation of the vm and produce bad domain xml with two, three or more times the same disk. So fixing this ensure that if Qmf::query return a bad output, the vm will start. -- Pierre-Gilles Mialon Responsable h?bergement :: Head of Hosting services pmialon at linagora.com :: +33.1 58 18 65 46 Linagora :: http://www.linagora.com 27 rue de Berri :: 75008 PARIS -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: This is a digitally signed message part. URL: From pmialon at linagora.com Wed Dec 2 10:27:38 2009 From: pmialon at linagora.com (Pierre-Gilles Mialon) Date: Wed, 2 Dec 2009 11:27:38 +0100 Subject: [Ovirt-devel] Qmf::Query Hang in db-omatic Message-ID: <200912021127.38497.pmialon@linagora.com> Hi all, We use for preproduction purpose the next branche of oVirt. We notice that a lot of bugs appears when the number of message in qpidd increase. It seems that qpidd is doing the job and that most of the issue are due to Qmf::Query . For example in db-omatic lines 265,296 When you restart db-omatic, if you have multiple node, you have mutiple threads launch (line 266) that hang on : qmf_host = @qmfc.objects(Qmf::Query.new(:class => "node"), 'hostname' => host_info['hostname']) The function never return. But qpidd never stop to answer correctly to the request done by ruby-qmf. A workarround for us consist to : - stopping all the libvirt-qpid on every node, - restarting db-omatic - starting libvirt-qpid sequentially on every node. Doing this way work, and gave to us a concistent db for db-omatic. What do you thing if we replace the Thread.new on line 266 by a begin ? Because the concurrency of the requests on qpidd made by db-omatic seems the origin of the hang. if state == Host::STATE_AVAILABLE Thread.new do @logger.info "#{host_info['hostname']} has moved to available, sleeping for updates to vms." sleep(20) # At this point we want to set all domains that are # unreachable to stopped. We're using a thread here to # sleep for 10 seconds outside of the main dbomatic loop. # If after 10 seconds with this host up there are still # domains set to 'unreachable', then we're going to guess # the node rebooted and so the domains should be set to # stopped. @logger.info "Checking for dead VMs on newly available host #{host_info['hostname']}." # Double check to make sure this host is still up. begin qmf_host = @qmfc.objects(Qmf::Query.new(:class => "node"), 'hostname' => host_info['hostname']) if !qmf_host @logger.info "Host #{host_info['hostname']} is not up after waiting 20 seconds, skipping dead VM check." else db_vm = Vm.find(:all, :conditions => ["host_id = ? AND state = ?", db_host.id, Vm::STATE_UNREACHABLE]) db_vm.each do |vm| @logger.info "Moving vm #{vm.description} in state #{vm.state} to state stopped." set_vm_stopped(vm) vm.save! end end rescue Exception => e # just log any errors here @logger.info "Exception checking for dead VMs (could be normal): #{e.message}" @logger.info e.backtrace end end end -- Pierre-Gilles Mialon Responsable h?bergement :: Head of Hosting services pmialon at linagora.com :: +33.1 58 18 65 46 Linagora :: http://www.linagora.com 27 rue de Berri :: 75008 PARIS -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 198 bytes Desc: This is a digitally signed message part. URL: From evenit at gmail.com Wed Dec 2 13:24:15 2009 From: evenit at gmail.com (Fabien Dupont) Date: Wed, 2 Dec 2009 14:24:15 +0100 Subject: [Ovirt-devel] Is there a plan for managing physical servers as well ? Message-ID: <5b315b760912020524s4dcd3f5byef530b8fdcf2cdc@mail.gmail.com> Hi all. I'm a complete newbie to oVirt but not to underlying technologies such as cobbler and libvirt, and I'm maybe not the first to ask... I'm looking for a complete solution to manage my hosts, both virtual and physical. oVirt uses Cobbler for provisionning, Augeas for configuration, FreeIPA for identity management... but those technologies are not specific to virtual machines. In fact, I already use Cobbler to provision all of my machines, Puppet (which has a binding to augeas in latest release) to configure my nodes and we are looking close at FreeIPA (thinking of migrating from OpenLDAP). From my point of view, a virtual machine is just a special case of generic machine. Thus, I wondered if there's a plan to provide generic machine management in oVirt, even if the name is tied to virtual machine ;) Or you may know another project doing it. Thanks. -- Fabien -------------- next part -------------- An HTML attachment was scrubbed... URL: From jguiditt at redhat.com Wed Dec 2 15:48:48 2009 From: jguiditt at redhat.com (Jason Guiditta) Date: Wed, 02 Dec 2009 10:48:48 -0500 Subject: [Ovirt-devel] ovirt web interface 500 Internal Server error In-Reply-To: <20091014121758.0qdpeft178ooc8wo@webmail.provincia.torino.it> References: <20091014121758.0qdpeft178ooc8wo@webmail.provincia.torino.it> Message-ID: <1259768929.3238.32.camel@lenovo> On Wed, 2009-10-14 at 12:17 +0200, ignazio.cassano at provincia.torino.it wrote: > Hello, > I built ovirt this morning and ovirt web interface does not work anymore. > I am able to login but only dashboard and networks are visible... > no default hardware pool is visible. > On /var/log/httpd/error.log I read: > > /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/connection_adapters/abstract_adapter.rb:212:in `log': PGError: ERROR: relation "pools" does not exist > (ActiveRecord::StatementInvalid) > > Thanks It looks as though no one replied to this on the list. Was your issue fixed via irc? If not, and you are still having this problem, I was talking to someone today with a similar error, though I am not sure it is exactly the same. If you are running a build from master, try applying the change in this patch: http://git.fedorahosted.org/git/ovirt/server.git?p=ovirt/server.git;a=commitdiff;h=e028546ed0f414dff128236a367fd57c5223d2a2 Then restart the ovirt-mongrel-rails service If that does not work, please let us know if you are running a release or building from next (next is preferred, has many bug fixes). You might also want to check your database to make sure those tables exist (via psql) and provide us an errors in logs from /var/log/ovirt-server. -j From fishy at linux.vnet.ibm.com Thu Dec 3 10:39:09 2009 From: fishy at linux.vnet.ibm.com (fishy) Date: Thu, 03 Dec 2009 16:09:09 +0530 Subject: [Ovirt-devel] [RFC][PATCH v2] edit-livecd : fail on error in arbitrary code In-Reply-To: <4AFD1A73.5020904@linux.vnet.ibm.com> References: <4AF96D92.4090503@linux.vnet.ibm.com> <4AFB30B9.2020607@redhat.com> <4AFD1A73.5020904@linux.vnet.ibm.com> Message-ID: <4B17954D.8010205@linux.vnet.ibm.com> Please the patch listed here On 11/13/2009 02:06 PM, abhishek misra wrote: > Hello All, > > Below are David's comments on my last patch > > David Huff wrote: >> I took a look at this today, I am not sure that a requirement for 'CODE' >> to touch a "fail" file is the best way to address this. >> >> I assume your script is mounting proc inside the ext filesystem, ie to >> use yum or something. And using trap and a similar mnt function, like >> what is in edit-livecd, is not cleaning up all the mounts in this case? >> >> A fix may be to use /proc/mounts instead of df when adding the Exits in >> the mnt function. >> >> Also can you clarify the statement, "note that it may not always be >> possible to return some error code on failure in 'CODE'" I am not really >> sure what you mean here. >> >> Does this make sense? >> >> -D > David, you were right about proc , I've now taken care of that in my > 'CODE' > > Here is another patch that tries to achieve the same without using > 'touch fail' > > 1. removed compound statement ( list ) > I found that its usage does not prevent trap to come into action > if $CODE fails (which is desired ) > but allows commands after (list) to continue executing ( which is > not desired ) > > 2 added addExit "cd -" > when $CODE fails and control returns to edit-livecd script, it is > still in $WDIR/ex > this causes failure when trap attempts umount > > 3 added EXIT=${EXIT/cd - ;/} > we no longer need it if $CODE goes well > > 4 added cd - > we need it as we removed (list) > > 5 removed set +/- e > > Signed-off-by: Abhishek Misra > --- > > --- a/edit-livecd 2009-11-10 17:23:21.000000000 +0530 > +++ b/edit-livecd 2009-11-13 14:03:50.000000000 +0530 > @@ -161,12 +161,11 @@ mnt "-t ext2 $WDIR/sq-w/LiveOS/ext3fs.im > > echo ">>> Updating CD content" > if [ -n "$CODE" ]; then > - ( > cd $WDIR/ex > - set +e > + addExit "cd -" > eval "$CODE" > - set -e > - ) > + EXIT=${EXIT/cd - ;/} > + cd - > else > echo "***" > echo "*** Pausing to allow manual changes. Press any key to > continue." > > _______________________________________________ > Ovirt-devel mailing list > Ovirt-devel at redhat.com > https://www.redhat.com/mailman/listinfo/ovirt-devel From fishy at linux.vnet.ibm.com Thu Dec 3 10:44:32 2009 From: fishy at linux.vnet.ibm.com (fishy) Date: Thu, 03 Dec 2009 16:14:32 +0530 Subject: [Ovirt-devel] [RFC][PATCH v2] edit-livecd : fail on error in arbitrary code In-Reply-To: <4B17954D.8010205@linux.vnet.ibm.com> References: <4AF96D92.4090503@linux.vnet.ibm.com> <4AFB30B9.2020607@redhat.com> <4AFD1A73.5020904@linux.vnet.ibm.com> <4B17954D.8010205@linux.vnet.ibm.com> Message-ID: <4B179690.9060907@linux.vnet.ibm.com> Purpose : fail iso build on encountering error in arbitrary code '$CODE' On 12/03/2009 04:09 PM, fishy wrote: > Please the patch listed here > > On 11/13/2009 02:06 PM, abhishek misra wrote: >> Hello All, >> >> Below are David's comments on my last patch >> >> David Huff wrote: >>> I took a look at this today, I am not sure that a requirement for >>> 'CODE' >>> to touch a "fail" file is the best way to address this. >>> >>> I assume your script is mounting proc inside the ext filesystem, ie to >>> use yum or something. And using trap and a similar mnt function, like >>> what is in edit-livecd, is not cleaning up all the mounts in this case? >>> >>> A fix may be to use /proc/mounts instead of df when adding the Exits in >>> the mnt function. >>> >>> Also can you clarify the statement, "note that it may not always be >>> possible to return some error code on failure in 'CODE'" I am not >>> really >>> sure what you mean here. >>> >>> Does this make sense? >>> >>> -D >> David, you were right about proc , I've now taken care of that in my >> 'CODE' >> >> Here is another patch that tries to achieve the same without using >> 'touch fail' >> >> 1. removed compound statement ( list ) >> I found that its usage does not prevent trap to come into action >> if $CODE fails (which is desired ) >> but allows commands after (list) to continue executing ( which is >> not desired ) >> >> 2 added addExit "cd -" >> when $CODE fails and control returns to edit-livecd script, it is >> still in $WDIR/ex >> this causes failure when trap attempts umount >> >> 3 added EXIT=${EXIT/cd - ;/} >> we no longer need it if $CODE goes well >> >> 4 added cd - >> we need it as we removed (list) >> >> 5 removed set +/- e >> >> Signed-off-by: Abhishek Misra > >> --- >> >> --- a/edit-livecd 2009-11-10 17:23:21.000000000 +0530 >> +++ b/edit-livecd 2009-11-13 14:03:50.000000000 +0530 >> @@ -161,12 +161,11 @@ mnt "-t ext2 $WDIR/sq-w/LiveOS/ext3fs.im >> >> echo ">>> Updating CD content" >> if [ -n "$CODE" ]; then >> - ( >> cd $WDIR/ex >> - set +e >> + addExit "cd -" >> eval "$CODE" >> - set -e >> - ) >> + EXIT=${EXIT/cd - ;/} >> + cd - >> else >> echo "***" >> echo "*** Pausing to allow manual changes. Press any key to >> continue." >> >> _______________________________________________ >> Ovirt-devel mailing list >> Ovirt-devel at redhat.com >> https://www.redhat.com/mailman/listinfo/ovirt-devel > > _______________________________________________ > Ovirt-devel mailing list > Ovirt-devel at redhat.com > https://www.redhat.com/mailman/listinfo/ovirt-devel From dpierce at redhat.com Thu Dec 3 21:24:34 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Thu, 3 Dec 2009 16:24:34 -0500 Subject: [Ovirt-devel] Refactored, fixed and ready to review... Message-ID: <1259875476-26455-1-git-send-email-dpierce@redhat.com> This set of patches needed some reworking since they would not apply on top of next. They are ready for review and to be pushed. From dpierce at redhat.com Thu Dec 3 21:24:35 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Thu, 3 Dec 2009 16:24:35 -0500 Subject: [Ovirt-devel] [PATCH 1/2] Provides a new storage administration system to the managed node. In-Reply-To: <1259875476-26455-1-git-send-email-dpierce@redhat.com> References: <1259875476-26455-1-git-send-email-dpierce@redhat.com> Message-ID: <1259875476-26455-2-git-send-email-dpierce@redhat.com> Users can now: * Add a new storage pool. * Delete a storage pool. * Start and stop storage pools. * Add a new storage volume. * Delete a storage volume. * List existing storage pools, with details. Signed-off-by: Darryl L. Pierce --- nodeadmin/listpools.py~ | 65 ++++++++++++++++++++++++++++++++++++++++++++++ nodeadmin/poolconfig.py~ | 46 ++++++++++++++++++++++++++++++++ nodeadmin/removepool.py~ | 46 ++++++++++++++++++++++++++++++++ nodeadmin/setup.py | 46 ++++++++++++++++++++++++++++++++ nodeadmin/stoppool.py~ | 64 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 267 insertions(+), 0 deletions(-) create mode 100644 nodeadmin/listpools.py~ create mode 100644 nodeadmin/poolconfig.py~ create mode 100644 nodeadmin/removepool.py~ create mode 100644 nodeadmin/setup.py create mode 100644 nodeadmin/stoppool.py~ diff --git a/nodeadmin/listpools.py~ b/nodeadmin/listpools.py~ new file mode 100644 index 0000000..6302c46 --- /dev/null +++ b/nodeadmin/listpools.py~ @@ -0,0 +1,65 @@ +# listpools.py - Copyright (C) 2009 Red Hat, Inc. +# Written by Darryl L. Pierce +# +# 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 configscreen import * + +LIST_PAGE = 1 +DETAILS_PAGE = 2 + +class ListStoragePoolsConfigScreen(StorageListConfigScreen): + def __init__(self): + StorageListConfigScreen.__init__(self, "List Storage Pools") + + def get_elements_for_page(self, screen, page): + if page is LIST_PAGE: return self.get_storage_pool_list_page(screen) + elif page is DETAILS_PAGE: return self.get_pool_details_page(screen) + + def page_has_next(self, page): + if page is LIST_PAGE and self.has_selectable_pools(): + return True + return False + + def page_has_back(self, page): + if page is DETAILS_PAGE: return True + return False + + def get_pool_details_page(self, screen): + pool = self.get_libvirt().get_storage_pool(self.get_selected_pool()) + volumes = Listbox(0); + for name in pool.listVolumes(): + volumes = Listbox(0); + for name in pool.listVolumes(): + volume = pool.storageVolLookupByName(name) + volumes.append("%s (%0.1f G)" % (name, volume.info()[1] / 1024**3), name) + grid = Grid(2, 3) + grid.setField(Label("Name:"), 0, 0, anchorRight = 1) + grid.setField(Label(pool.name()), 1, 0, anchorLeft = 1) + grid.setField(Label("Volumes:"), 0, 1, anchorRight = 1) + grid.setField(volumes, 1, 1, anchorLeft = 1) + grid.setField(Label("Autostart:"), 0, 2, anchorRight = 1) + label = "No" + if pool.autostart(): label = "Yes" + grid.setField(Label(label), 1, 2, anchorLeft = 1) + return [Label("Details For Storage Pool: %s" % self.get_selected_pool()), + grid] + +def ListStoragePools(): + screen = ListStoragePoolsConfigScreen() + screen.start() diff --git a/nodeadmin/poolconfig.py~ b/nodeadmin/poolconfig.py~ new file mode 100644 index 0000000..6bc9fa0 --- /dev/null +++ b/nodeadmin/poolconfig.py~ @@ -0,0 +1,46 @@ +# poolconfig.py - Copyright (C) 2009 Red Hat, Inc. +# Written by Darryl L. Pierce +# +# 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 virtinst import Storage + +ROOT_TARGET_PATH="/var/lib/libvirt/images/%s" + +class PoolConfig: + def __init__(self, libvirt): + self.__libvirt = libvirt + self.__name = "" + self.set_type(None) + self.__format = None + self.__hostname = "" + self.__target_path = "" + self.__source_path = "" + self.__build_pool = False + + def get_pool(self): + return self.__pool + + def set_name(self, name): + self.__name = name + + def get_name(self): + return self.__name + + def set_type(self, pooltype): + self.__type = pooltype + self.__needs_target_path = False + self.__needs_format = False diff --git a/nodeadmin/removepool.py~ b/nodeadmin/removepool.py~ new file mode 100644 index 0000000..cd9c2d5 --- /dev/null +++ b/nodeadmin/removepool.py~ @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# +# removepool.py - Copyright (C) 2009 Red Hat, Inc. +# Written by Darryl L. Pierce +# +# 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 configscreen import * + +LIST_POOLS_PAGE = 1 +CONFIRM_PAGE = 2 + +class RemoveStoragePoolConfigScreen(StorageListConfigScreen): + def __init__(self): + StorageListConfigScreen.__init__(self, "Remove A Storage Pool") + + def get_elements_for_page(self, screen, page): + if page is LIST_POOLS_PAGE: return self.get_storage_pool_list_page(screen) + elif page is CONFIRM_PAGE: return self.get_confirm_page(screen) + + def page_has_next(self, page): + return page is LIST_POOLS_PAGE and self.has_selectable_pools() + + def page_has_back(self, page): + return False + + def page_has_finish(self, page): + return page is CONFIRM_PAGE + + def validate_input(self, page, errors): + if page is LIST_POOLS_PAGE: + if self.get_selected_pool() is not None: diff --git a/nodeadmin/setup.py b/nodeadmin/setup.py new file mode 100644 index 0000000..9af2752 --- /dev/null +++ b/nodeadmin/setup.py @@ -0,0 +1,46 @@ +# setup.py - Copyright (C) 2009 Red Hat, Inc. +# Written by Darryl L. Pierce +# +# 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 setuptools import setup, find_packages + +setup(name = "nodeadmin", + version = "1.0.3", + package_dir = {'nodeadmin': 'nodeadmin'}, + packages = find_packages('.'), + entry_points = { + 'console_scripts': [ + 'nodeadmin = nodeadmin.nodeadmin:NodeAdmin', + 'addvm = nodeadmin.adddomain:AddDomain', + 'startvm = nodeadmin.startdomain:StartDomain', + 'stopvm = nodeadmin.stopdomain:StopDomain', + 'rmvm = nodeadmin.removedomain:RemoveDomain', + 'createuser = nodeadmin.createuser:CreateUser', + 'listvms = nodeadmin.listdomains:ListDomains', + 'definenet = nodeadmin.definenet:DefineNetwork', + 'createnet = nodeadmin.createnetwork:CreateNetwork', + 'destroynet = nodeadmin.destroynetwork:DestroyNetwork', + 'undefinenet = nodeadmin.undefinenetwork:UndefineNetwork', + 'listnets = nodeadmin.listnetworks:ListNetworks', + 'addpool = nodeadmin.addpool:AddStoragePool', + 'rmpool = nodeadmin.removepool:RemoveStoragePool', + 'startpool = nodeadmin.startpool:StartStoragePool', + 'stoppool = nodeadmin.stoppool:StopStoragePool', + 'addvolume = nodeadmin.addvolume:AddStorageVolume', + 'rmvolume = nodeadmin.removevolume:RemoveStorageVolume', + 'listpools = nodeadmin.listpools:ListPools'] + }) diff --git a/nodeadmin/stoppool.py~ b/nodeadmin/stoppool.py~ new file mode 100644 index 0000000..80a2f0b --- /dev/null +++ b/nodeadmin/stoppool.py~ @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# +# stoppool.py - Copyright (C) 2009 Red Hat, Inc. +# Written by Darryl L. Pierce +# +# 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 configscreen import * + +LIST_POOLS_PAGE = 1 +FINAL_PAGE = 2 + +class StopStoragePoolConfigScreen(StorageListConfigScreen): + def __init__(self): + StorageListConfigScreen.__init__(self, "Stop A Storage Pool") + + def get_elements_for_page(self, screen, page): + if page is LIST_POOLS_PAGE: return self.get_storage_pool_list_page(screen, defined = False) + elif page is FINAL_PAGE: return self.get_final_page(screen) + + def page_has_next(self, page): + return page is LIST_POOLS_PAGE and self.has_selectable_pools() + + def page_has_back(self, page): + return False + + def page_has_finish(self, page): + return page is FINAL_PAGE + + def validate_input(self, page, errors): + if page is LIST_POOLS_PAGE: + if self.get_selected_pool() is not None: + if page is LIST_POOLS_PAGE: + if self.get_selected_pool() is not None: + return True + else: + errors.append("Please select a storage pool to be stopped.") + return False + + def process_input(self, page): + if page is LIST_POOLS_PAGE: + self.get_libvirt().destroy_storage_pool(self.get_selected_pool()) + self.set_finished() + + def get_final_page(self, screen): + return [Label("Storage pool stopped: %s" % self.get_selected_pool())] + +def StopStoragePool(): + screen = StopStoragePoolConfigScreen() + screen.start() -- 1.6.5.2 From dpierce at redhat.com Thu Dec 3 21:24:36 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Thu, 3 Dec 2009 16:24:36 -0500 Subject: [Ovirt-devel] [PATCH 2/2] Refactor domain storage setup to use pool and volume selection screens. In-Reply-To: <1259875476-26455-2-git-send-email-dpierce@redhat.com> References: <1259875476-26455-1-git-send-email-dpierce@redhat.com> <1259875476-26455-2-git-send-email-dpierce@redhat.com> Message-ID: <1259875476-26455-3-git-send-email-dpierce@redhat.com> Now, when the user elects to use managed storage, they're show the list of available storage pools. Then, after selecting one, the user is shown the list of volumes on that pool. These are then used to create the domain. Signed-off-by: Darryl L. Pierce --- Makefile.am | 1 + nodeadmin/adddomain.py | 192 ++++++++++++++++++++++++++------------------ nodeadmin/domainconfig.py | 17 +++- nodeadmin/libvirtworker.py | 34 ++++---- 4 files changed, 145 insertions(+), 99 deletions(-) diff --git a/Makefile.am b/Makefile.am index 56d9aef..de3bd18 100644 --- a/Makefile.am +++ b/Makefile.am @@ -48,6 +48,7 @@ EXTRA_DIST = \ nodeadmin/netmenu.py \ nodeadmin/nodeadmin.py \ nodeadmin/nodemenu.py \ + nodeadmin/poolconfig.py \ nodeadmin/removedomain.py \ nodeadmin/removepool.py \ nodeadmin/removevolume.py \ diff --git a/nodeadmin/adddomain.py b/nodeadmin/adddomain.py index bb06a62..30b1e39 100755 --- a/nodeadmin/adddomain.py +++ b/nodeadmin/adddomain.py @@ -37,10 +37,11 @@ OS_VARIANT_PAGE = 12 RAM_CPU_PAGE = 13 ENABLE_STORAGE_PAGE = 14 LOCAL_STORAGE_PAGE = 15 -MANAGED_STORAGE_PAGE = 16 -BRIDGE_PAGE = 17 -VIRT_DETAILS_PAGE = 18 -CONFIRM_PAGE = 19 +SELECT_POOL_PAGE = 16 +SELECT_VOLUME_PAGE = 17 +BRIDGE_PAGE = 18 +VIRT_DETAILS_PAGE = 19 +CONFIRM_PAGE = 20 LOCATION="location" KICKSTART="kickstart" @@ -58,24 +59,25 @@ class DomainConfigScreen(ConfigScreen): self.__config.set_virt_type(self.get_libvirt().get_default_virt_type()) def get_elements_for_page(self, screen, page): - if page == VM_DETAILS_PAGE: return self.get_vm_details_page(screen) - elif page == LOCAL_INSTALL_PAGE: return self.get_local_install_page(screen) - elif page == SELECT_CDROM_PAGE: return self.get_select_cdrom_page(screen) - elif page == SELECT_ISO_PAGE: return self.get_select_iso_page(screen) - elif page == NETWORK_INSTALL_PAGE: return self.get_network_install_page(screen) - elif page == OS_TYPE_PAGE: return self.get_os_type_page(screen) - elif page == OS_VARIANT_PAGE: return self.get_os_variant_page(screen) - elif page == RAM_CPU_PAGE: return self.get_ram_and_cpu_page(screen) - elif page == ENABLE_STORAGE_PAGE: return self.get_enable_storage_page(screen) - elif page == LOCAL_STORAGE_PAGE: return self.get_local_storage_page(screen) - elif page == MANAGED_STORAGE_PAGE: return self.get_managed_storage_page(screen) - elif page == BRIDGE_PAGE: return self.get_bridge_page(screen) - elif page == VIRT_DETAILS_PAGE: return self.get_virt_details_page(screen) - elif page == CONFIRM_PAGE: return self.get_confirm_page(screen) + if page is VM_DETAILS_PAGE: return self.get_vm_details_page(screen) + elif page is LOCAL_INSTALL_PAGE: return self.get_local_install_page(screen) + elif page is SELECT_CDROM_PAGE: return self.get_select_cdrom_page(screen) + elif page is SELECT_ISO_PAGE: return self.get_select_iso_page(screen) + elif page is NETWORK_INSTALL_PAGE: return self.get_network_install_page(screen) + elif page is OS_TYPE_PAGE: return self.get_os_type_page(screen) + elif page is OS_VARIANT_PAGE: return self.get_os_variant_page(screen) + elif page is RAM_CPU_PAGE: return self.get_ram_and_cpu_page(screen) + elif page is ENABLE_STORAGE_PAGE: return self.get_enable_storage_page(screen) + elif page is LOCAL_STORAGE_PAGE: return self.get_local_storage_page(screen) + elif page is SELECT_POOL_PAGE: return self.get_select_pool_page(screen) + elif page is SELECT_VOLUME_PAGE: return self.get_select_volume_page(screen) + elif page is BRIDGE_PAGE: return self.get_bridge_page(screen) + elif page is VIRT_DETAILS_PAGE: return self.get_virt_details_page(screen) + elif page is CONFIRM_PAGE: return self.get_confirm_page(screen) return [] def validate_input(self, page, errors): - if page == VM_DETAILS_PAGE: + if page is VM_DETAILS_PAGE: if len(self.__guest_name.value()) > 0: if self.get_libvirt().domain_exists(self.__guest_name.value()): errors.append("Guest name '%s' is already in use." % self.__guest_name.value()) @@ -83,12 +85,12 @@ class DomainConfigScreen(ConfigScreen): return True else: errors.append("Guest name must be a string between 0 and 50 characters.") - elif page == LOCAL_INSTALL_PAGE: + elif page is LOCAL_INSTALL_PAGE: if self.__install_source.getSelection() == DomainConfig.INSTALL_SOURCE_CDROM: return True elif self.__install_source.getSelection() == DomainConfig.INSTALL_SOURCE_ISO: return True - elif page == SELECT_CDROM_PAGE: + elif page is SELECT_CDROM_PAGE: if self.__install_media.getSelection() != None: if len(self.get_hal().list_installable_volumes()) == 0: errors.append("No installable media is available.") @@ -96,7 +98,7 @@ class DomainConfigScreen(ConfigScreen): return True else: errors.append("You must select an install media.") - elif page == SELECT_ISO_PAGE: + elif page is SELECT_ISO_PAGE: if len(self.__iso_path.value()) > 0: if os.path.exists(self.__iso_path.value()): if os.path.isfile(self.__iso_path.value()): @@ -108,14 +110,14 @@ class DomainConfigScreen(ConfigScreen): errors.append(self.__iso_path.value()) else: errors.append("An install media selection is required.") - elif page == NETWORK_INSTALL_PAGE: + elif page is NETWORK_INSTALL_PAGE: if len(self.__install_url.value()) > 0: return True else: errors.append("An install tree is required.") - elif page == OS_TYPE_PAGE: return True - elif page == OS_VARIANT_PAGE: return True - elif page == RAM_CPU_PAGE: + elif page is OS_TYPE_PAGE: return True + elif page is OS_VARIANT_PAGE: return True + elif page is RAM_CPU_PAGE: if (len(self.__memory.value()) > 0 and len(self.__cpus.value()) > 0) \ and (int(self.__memory.value()) > 0 and int(self.__cpus.value()) > 0): return True @@ -128,8 +130,8 @@ class DomainConfigScreen(ConfigScreen): errors.append("A value must be entered for CPUs.") elif int(self.__cpus.value()) <= 0: errors.append("A positive integer value must be entered for memory.") - elif page == ENABLE_STORAGE_PAGE: return True - elif page == LOCAL_STORAGE_PAGE: + elif page is ENABLE_STORAGE_PAGE: return True + elif page is LOCAL_STORAGE_PAGE: if len(self.__storage_size.value()) > 0: if float(self.__storage_size.value()) > 0: return True @@ -137,12 +139,17 @@ class DomainConfigScreen(ConfigScreen): errors.append("A positive value must be entered for the storage size.") else: errors.append("A value must be entered for the storage size.") - elif page == MANAGED_STORAGE_PAGE: - if self.__existing_storage.getSelection() is not None: + elif page is SELECT_POOL_PAGE: + if self.__storage_pool.getSelection() is not None: + return True + else: + errors.append("Please select a storage pool.") + elif page is SELECT_VOLUME_PAGE: + if self.__storage_volume.getSelection() is not None: return True else: errors.append("Please select a storage volume.") - elif page == BRIDGE_PAGE: + elif page is BRIDGE_PAGE: if self.__network_bridges.getSelection() != None: if len(self.__mac_address.value()) > 0: # TODO: regex check the format @@ -151,62 +158,66 @@ class DomainConfigScreen(ConfigScreen): errors.append("MAC address must be supplied.") else: errors.append("A network bridge must be selected.") - elif page == VIRT_DETAILS_PAGE: + elif page is VIRT_DETAILS_PAGE: if self.__virt_types.getSelection() != None and self.__architectures.getSelection() != None: return True if self.__virt_types.getSelection() is None: errors.append("Please select a virtualization type.") if self.__architectures.getSelection() is None: errors.append("Please selection an architecture.") - elif page == CONFIRM_PAGE: return True + elif page is CONFIRM_PAGE: return True return False def process_input(self, page): - if page == VM_DETAILS_PAGE: + if page is VM_DETAILS_PAGE: self.__config.set_guest_name(self.__guest_name.value()) self.__config.set_install_type(self.__install_type.getSelection()) - elif page == LOCAL_INSTALL_PAGE: + elif page is LOCAL_INSTALL_PAGE: self.__config.set_use_cdrom_source(self.__install_source.getSelection() == DomainConfig.INSTALL_SOURCE_CDROM) - elif page == SELECT_CDROM_PAGE: + elif page is SELECT_CDROM_PAGE: self.__config.set_install_media(self.__install_media.getSelection()) - elif page == SELECT_ISO_PAGE: + elif page is SELECT_ISO_PAGE: self.__config.set_iso_path(self.__iso_path.value()) - elif page == NETWORK_INSTALL_PAGE: + elif page is NETWORK_INSTALL_PAGE: self.__config.set_install_url(self.__install_url.value()) self.__config.set_kickstart_url(self.__kickstart_url.value()) self.__config.set_kernel_options(self.__kernel_options.value()) - elif page == OS_TYPE_PAGE: + elif page is OS_TYPE_PAGE: self.__config.set_os_type(self.__os_types.getSelection()) - elif page == OS_VARIANT_PAGE: + elif page is OS_VARIANT_PAGE: self.__config.set_os_variant(self.__os_variants.getSelection()) - elif page == RAM_CPU_PAGE: + elif page is RAM_CPU_PAGE: self.__config.set_memory(int(self.__memory.value())) self.__config.set_cpus(int(self.__cpus.value())) - elif page == ENABLE_STORAGE_PAGE: + elif page is ENABLE_STORAGE_PAGE: self.__config.set_enable_storage(self.__enable_storage.value()) if self.__storage_type.getSelection() == DomainConfig.NEW_STORAGE: self.__config.set_use_local_storage(True) elif self.__storage_type.getSelection() == DomainConfig.EXISTING_STORAGE: self.__config.set_use_local_storage(False) - elif page == LOCAL_STORAGE_PAGE: + elif page is LOCAL_STORAGE_PAGE: self.__config.set_storage_size(float(self.__storage_size.value())) self.__config.set_allocate_storage(self.__allocate_storage.value()) - elif page == MANAGED_STORAGE_PAGE: + elif page is SELECT_POOL_PAGE: self.__config.set_use_local_storage(False) - self.__config.set_existing_storage(self.__existing_storage.getSelection()) - self.__config.set_storage_size(self.get_libvirt().get_storage_size(self.__existing_storage.getSelection())) - elif page == BRIDGE_PAGE: + self.__config.set_storage_pool(self.__storage_pool.getSelection()) + elif page is SELECT_VOLUME_PAGE: + self.__config.set_storage_volume(self.__storage_volume.getSelection()) + volume = self.get_libvirt().get_storage_volume(self.__config.get_storage_pool(), + self.__config.get_storage_volume()) + self.__config.set_storage_size(volume.info()[1] / 1024.0 ** 3) + elif page is BRIDGE_PAGE: self.__config.set_network_bridge(self.__network_bridges.getSelection()) - elif page == VIRT_DETAILS_PAGE: + elif page is VIRT_DETAILS_PAGE: self.__config.set_virt_type(self.__virt_types.getSelection()) self.__config.set_architecture(self.__architectures.getSelection()) - elif page == CONFIRM_PAGE: + elif page is CONFIRM_PAGE: self.get_libvirt().define_domain(self.__config, CreateMeter()) self.set_finished() def get_back_page(self, page): result = page - if page == OS_TYPE_PAGE: + if page is OS_TYPE_PAGE: install_type = self.__config.get_install_type() if install_type == DomainConfig.LOCAL_INSTALL: if self.__config.get_use_cdrom_source(): @@ -217,24 +228,26 @@ class DomainConfigScreen(ConfigScreen): result = NETWORK_INSTALL_PAGE elif install_type == DomainConfig.PXE_INSTALL: result = VM_DETAILS_PAGE - elif page == LOCAL_STORAGE_PAGE or page == MANAGED_STORAGE_PAGE: + elif page is LOCAL_STORAGE_PAGE or page is SELECT_VOLUME_PAGE: + result = ENABLE_STORAGE_PAGE + elif page is SELECT_POOL_PAGE: result = ENABLE_STORAGE_PAGE - elif page == NETWORK_INSTALL_PAGE: + elif page is NETWORK_INSTALL_PAGE: result = VM_DETAILS_PAGE - elif page == SELECT_CDROM_PAGE or page == SELECT_ISO_PAGE: + elif page is SELECT_CDROM_PAGE or page == SELECT_ISO_PAGE: result = LOCAL_INSTALL_PAGE - elif page == BRIDGE_PAGE: + elif page is BRIDGE_PAGE: if self.__config.get_use_local_storage(): result = LOCAL_STORAGE_PAGE else: - result = MANAGED_STORAGE_PAGE + result = SELECT_VOLUME_PAGE else: if page > 1: result = page - 1 return result def get_next_page(self, page): result = page - if page == VM_DETAILS_PAGE: + if page is VM_DETAILS_PAGE: install_type = self.__config.get_install_type() if install_type == DomainConfig.LOCAL_INSTALL: result = LOCAL_INSTALL_PAGE @@ -242,34 +255,36 @@ class DomainConfigScreen(ConfigScreen): result = NETWORK_INSTALL_PAGE elif install_type == DomainConfig.PXE_INSTALL: result = OS_TYPE_PAGE - elif page == LOCAL_INSTALL_PAGE: + elif page is LOCAL_INSTALL_PAGE: if self.__config.get_use_cdrom_source(): result = SELECT_CDROM_PAGE else: result = SELECT_ISO_PAGE - elif page == SELECT_CDROM_PAGE or page == SELECT_ISO_PAGE: + elif page is SELECT_CDROM_PAGE or page == SELECT_ISO_PAGE: result = OS_TYPE_PAGE - elif page == NETWORK_INSTALL_PAGE: + elif page is NETWORK_INSTALL_PAGE: result = OS_TYPE_PAGE - elif page == ENABLE_STORAGE_PAGE: + elif page is ENABLE_STORAGE_PAGE: result = BRIDGE_PAGE if self.__config.get_enable_storage(): if self.__config.get_use_local_storage(): result = LOCAL_STORAGE_PAGE else: - result = MANAGED_STORAGE_PAGE - elif page == LOCAL_STORAGE_PAGE or page == MANAGED_STORAGE_PAGE: + result = SELECT_POOL_PAGE + elif page is LOCAL_STORAGE_PAGE: result = BRIDGE_PAGE else: result = page + 1 return result def page_has_finish(self, page): - if page == CONFIRM_PAGE: return True + if page is CONFIRM_PAGE: return True return False def page_has_next(self, page): - if page < CONFIRM_PAGE: + if page is SELECT_POOL_PAGE: return self.__has_pools + elif page is SELECT_VOLUME_PAGE: return self.__has_volumes + elif page < CONFIRM_PAGE: return True def get_vm_details_page(self, screen): @@ -393,25 +408,44 @@ class DomainConfigScreen(ConfigScreen): return [Label("Configure local storage"), grid] - def get_managed_storage_page(self, screen): - volumes = [] - for volume in self.get_libvirt().list_storage_volumes(): - volumes.append(["%s (%d GB)" % (volume.name(), volume.info()[1] / (1024 ** 3)), - volume.name(), - self.__config.is_existing_storage(volume.name())]) - self.__existing_storage = RadioBar(screen, (volumes)) - grid = Grid(2, 1) - grid.setField(Label("Existing storage:"), 0, 0) - grid.setField(self.__existing_storage, 1, 0) - return [Label("Configure managed storage"), + def get_select_pool_page(self, screen): + pools = [] + for pool in self.get_libvirt().list_storage_pools(): + pools.append([pool, pool, pool == self.__config.get_storage_pool()]) + if len(pools) > 0: + self.__storage_pool = RadioBar(screen, (pools)) + grid = Grid(2, 1) + grid.setField(Label("Storage pool:"), 0, 0, anchorTop = 1) + grid.setField(self.__storage_pool, 1, 0) + self.__has_pools = True + else: + grid = Label("There are no storage pools available.") + self.__has_pools = False + return [Label("Configure Managed Storage: Select A Pool"), grid] + def get_select_volume_page(self, screen): + volumes = [] + for volume in self.get_libvirt().list_storage_volumes(self.__config.get_storage_pool()): + volumes.append([volume, volume, volume == self.__config.get_storage_volume()]) + if len(volumes) > 0: + self.__storage_volume = RadioBar(screen, (volumes)) + grid = Grid(2, 1) + grid.setField(Label("Storage volumes:"), 0, 0, anchorTop = 1) + grid.setField(self.__storage_volume, 1, 0) + self.__has_volumes = True + else: + grid = Label("This storage pool has no defined volumes.") + self.__has_volumes = False + return [Label("Configure Managed Storage: Select A Volume"), + grid] + def get_bridge_page(self, screen): bridges = [] for bridge in self.get_libvirt().list_bridges(): - bridges.append(["Virtual network '%s'" % bridge.name(), bridge.name(), self.__config.get_network_bridge() == bridge.name()]) + bridges.append(["Virtual network '%s'" % bridge.name(), bridge.name(), self.__config.get_network_bridge() is bridge.name()]) self.__network_bridges = RadioBar(screen, (bridges)) - if self.__config.get_mac_address() == None: + if self.__config.get_mac_address() is None: self.__config.set_mac_address(self.get_libvirt().generate_mac_address()) self.__mac_address = Entry(20, self.__config.get_mac_address()) grid = Grid(1, 1) @@ -448,7 +482,9 @@ class DomainConfigScreen(ConfigScreen): grid.setField(Label("CPUs:"), 0, 3, anchorRight = 1) grid.setField(Label("%d" % self.__config.get_cpus()), 1, 3, anchorLeft = 1) grid.setField(Label("Storage:"), 0, 4, anchorRight = 1) - grid.setField(Label(self.__config.get_existing_storage()), 1, 4, anchorLeft = 1) + grid.setField(Label("%s (on %s)" % (self.__config.get_storage_volume(), + self.__config.get_storage_pool())), + 1, 4, anchorLeft = 1) grid.setField(Label("Network:"), 0, 5, anchorRight = 1) grid.setField(Label(self.__config.get_network_bridge()), 1, 5, anchorLeft = 1) return [Label("Ready to begin installation of %s" % self.__config.get_guest_name()), diff --git a/nodeadmin/domainconfig.py b/nodeadmin/domainconfig.py index ef39fe0..4466e67 100644 --- a/nodeadmin/domainconfig.py +++ b/nodeadmin/domainconfig.py @@ -50,7 +50,8 @@ class DomainConfig: self.__use_local_storage = True self.__storage_size = 8.0 self.__allocate_storage = True - self.__existing_storage = "" + self.__storage_pool = "" + self.__storage_volume = "" self.__network_bridge = None self.__mac_address = None self.__virt_type = None @@ -177,11 +178,17 @@ class DomainConfig: def get_allocate_storage(self): return self.__allocate_storage - def set_existing_storage(self, storage): - self.__existing_storage = storage + def set_storage_pool(self, pool): + self.__storage_pool = pool - def get_existing_storage(self): - return self.__existing_storage + def get_storage_pool(self): + return self.__storage_pool + + def set_storage_volume(self, volume): + self.__storage_volume = volume + + def get_storage_volume(self): + return self.__storage_volume def is_existing_storage(self, storage): return self.__existing_storage == storage diff --git a/nodeadmin/libvirtworker.py b/nodeadmin/libvirtworker.py index b2acabe..f31266c 100644 --- a/nodeadmin/libvirtworker.py +++ b/nodeadmin/libvirtworker.py @@ -196,6 +196,11 @@ class LibvirtWorker: '''Returns the storage pool with the specified name.''' return self.__conn.storagePoolLookupByName(name) + def list_storage_volumes(self, poolname): + '''Returns the list of all defined storage volumes for a given pool.''' + pool = self.get_storage_pool(poolname) + return pool.listVolumes() + def define_storage_volume(self, config, meter): '''Defines a new storage volume.''' self.create_storage_pool(config.get_pool().name()) @@ -204,10 +209,15 @@ class LibvirtWorker: def remove_storage_volume(self, poolname, volumename): '''Removes the specified storage volume.''' - pool = self.get_storage_pool(poolname) - volume = pool.storageVolLookupByName(volumename) + volume = self.get_storage_volume(poolname, volumename) volume.delete(0) + def get_storage_volume(self, poolname, volumename): + '''Returns a reference to the specified storage volume.''' + pool =self.get_storage_pool(poolname) + volume = pool.storageVolLookupByName(volumename) + return volume + def list_bridges(self): '''Lists all defined and active bridges.''' bridges = self.__conn.listNetworks() @@ -221,21 +231,9 @@ class LibvirtWorker: def generate_mac_address(self): return self.__net.macaddr - def list_storage_volumes(self): - '''Lists all defined storage volumes.''' - pools = self.__conn.listStoragePools() - pools.extend(self.__conn.listDefinedStoragePools()) - result = [] - for name in pools: - pool = self.__conn.storagePoolLookupByName(name) - for volname in pool.listVolumes(): - volume = self.__conn.storageVolLookupByPath("/var/lib/libvirt/images/%s" % volname) - result.append(volume) - return result - - def get_storage_size(self, name): + def get_storage_size(self, poolname, volumename): '''Returns the size of the specified storage volume.''' - volume = self.__conn.storageVolLookupByPath("/var/lib/libvirt/images/%s" % name) + volume = self.get_storage_volume(poolname, volumename) return volume.info()[1] / (1024.0 ** 3) def get_virt_types(self): @@ -381,6 +379,10 @@ class LibvirtWorker: pool_object = pool, suffix = ".img") path = os.path.join(DEFAULT_POOL_TARGET_PATH, path) + else: + volume = self.get_storage_volume(config.get_storage_pool(), + config.get_storage_volume()) + path = volume.path() if path is not None: storage= virtinst.VirtualDisk(conn = self.__conn, -- 1.6.5.2 From dpierce at redhat.com Thu Dec 3 21:30:26 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Thu, 3 Dec 2009 16:30:26 -0500 Subject: [Ovirt-devel] Re: [PATCH] Provides an explicit upgrade path for an installed node. In-Reply-To: <1258385963-5787-2-git-send-email-dpierce@redhat.com> References: <1258385963-5787-1-git-send-email-dpierce@redhat.com> <1258385963-5787-2-git-send-email-dpierce@redhat.com> Message-ID: <20091203213026.GF6458@mcpierce-desktop.usersys.redhat.com> On Mon, Nov 16, 2009 at 10:39:23AM -0500, Darryl L. Pierce wrote: > This patch allows the node to be upgraded without destroying any > configuration. The new kernel argument, ovirt_upgrade, will boot cause > the node to install the upgraded image, then reboot. > > Resolves: rhbz#532547 Can I get an ACK or feedback on this patch, please? -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Delivering value year after year. Red Hat ranks #1 in value among software vendors. http://www.redhat.com/promo/vendor/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: not available URL: From dpierce at redhat.com Thu Dec 3 21:32:26 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Thu, 3 Dec 2009 16:32:26 -0500 Subject: [Ovirt-devel] Re: [PATCH] Static IPv4 addresses entered are validated when they're entered. In-Reply-To: <1257969747-2216-1-git-send-email-dpierce@redhat.com> References: <1257969747-2216-1-git-send-email-dpierce@redhat.com> Message-ID: <20091203213226.GG6458@mcpierce-desktop.usersys.redhat.com> On Wed, Nov 11, 2009 at 03:02:27PM -0500, Darryl L. Pierce wrote: > If the address is not blank then it is validated. Only those that are > properly formed are accepted. Otherwise an error message is displayed > and the user is prompted again. > > Resolves: rhbz#536912 - validation for static IP should be optimized > > Signed-off-by: Darryl L. Pierce > --- Can I get an ACK or feedback on this patch, please? -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Delivering value year after year. Red Hat ranks #1 in value among software vendors. http://www.redhat.com/promo/vendor/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: not available URL: From dpierce at redhat.com Thu Dec 3 21:42:23 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Thu, 3 Dec 2009 16:42:23 -0500 Subject: [Ovirt-devel] Rebased against next... Message-ID: <1259876545-27386-1-git-send-email-dpierce@redhat.com> This set of patches have been rebased since the originals have grown stale. From dpierce at redhat.com Thu Dec 3 21:42:24 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Thu, 3 Dec 2009 16:42:24 -0500 Subject: [Ovirt-devel] [PATCH 1/2] Users can now work with remote libvirt hosts. In-Reply-To: <1259876545-27386-1-git-send-email-dpierce@redhat.com> References: <1259876545-27386-1-git-send-email-dpierce@redhat.com> Message-ID: <1259876545-27386-2-git-send-email-dpierce@redhat.com> The user can: * select a remote machine * add a remote machine * remove a remote machine Signed-off-by: Darryl L. Pierce --- Makefile.am | 5 ++ nodeadmin/addhost.py | 129 ++++++++++++++++++++++++++++++++++++++++++++ nodeadmin/changehost.py | 58 ++++++++++++++++++++ nodeadmin/configscreen.py | 36 ++++++++++++- nodeadmin/definenet.py | 1 + nodeadmin/hostconnect.py | 29 ++++++++++ nodeadmin/hostmenu.py | 46 ++++++++++++++++ nodeadmin/libvirtworker.py | 53 +++++++++++++++++- nodeadmin/mainmenu.py | 14 +++-- nodeadmin/removehost.py | 66 ++++++++++++++++++++++ ovirt-node.spec.in | 5 ++ 11 files changed, 434 insertions(+), 8 deletions(-) create mode 100644 nodeadmin/addhost.py create mode 100644 nodeadmin/changehost.py create mode 100644 nodeadmin/hostconnect.py create mode 100644 nodeadmin/hostmenu.py create mode 100644 nodeadmin/removehost.py diff --git a/Makefile.am b/Makefile.am index b3929de..1671405 100644 --- a/Makefile.am +++ b/Makefile.am @@ -28,11 +28,15 @@ EXTRA_DIST = \ images/syslinux-vesa-splash.jpg \ nodeadmin/__init__.py \ nodeadmin/adddomain.py \ + nodeadmin/addhost.py \ + nodeadmin/changehost.py \ nodeadmin/configscreen.py \ nodeadmin/createnetwork.py \ nodeadmin/createuser.py \ nodeadmin/destroynetwork.py \ nodeadmin/halworker.py \ + nodeadmin/hostconnect.py \ + nodeadmin/hostmenu.py \ nodeadmin/libvirtworker.py \ nodeadmin/userworker.py \ nodeadmin/mainmenu.py \ @@ -40,6 +44,7 @@ EXTRA_DIST = \ nodeadmin/netmenu.py \ nodeadmin/nodemenu.py \ nodeadmin/removedomain.py \ + nodeadmin/removehost.py \ nodeadmin/undefinenetwork.py \ nodeadmin/startdomain.py \ nodeadmin/stopdomain.py \ diff --git a/nodeadmin/addhost.py b/nodeadmin/addhost.py new file mode 100644 index 0000000..ef35b7d --- /dev/null +++ b/nodeadmin/addhost.py @@ -0,0 +1,129 @@ +# addhost.py - Copyright (C) 2009 Red Hat, Inc. +# Written by Darryl L. Pierce +# +# 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 configscreen import * + +DETAILS_PAGE = 1 +CONFIRM_PAGE = 2 + +HYPERVISOR_XEN = "xen" +HYPERVISOR_KVM = "kvm" + +HYPERVISORS = {HYPERVISOR_XEN : "Xen", + HYPERVISOR_KVM : "QEMU/KVM"} + +CONNECTION_LOCAL = "local" +CONNECTION_KERBEROS = "kerberos" +CONNECTION_SSL = "ssl" +CONNECTION_SSH = "ssh" + +CONNECTIONS = {CONNECTION_LOCAL : "Local", + CONNECTION_KERBEROS : "Remote Password or Kerberos", + CONNECTION_SSL : "Remote SSL/TLS with x509 certificate", + CONNECTION_SSH : "Remote tunnel over SSH"} + +class AddHostConfigScreen(ConfigScreen): + def __init__(self): + ConfigScreen.__init__(self, "Add A Remote Host") + self.__configured = False + + def get_elements_for_page(self, screen, page): + if page is DETAILS_PAGE: return self.get_details_page(screen) + elif page is CONFIRM_PAGE: return self.get_confirm_page(screen) + + def page_has_next(self, page): + return page < CONFIRM_PAGE + + def page_has_back(self, page): + return page > DETAILS_PAGE + + def page_has_finish(self, page): + return page is CONFIRM_PAGE + + def validate_input(self, page, errors): + if page is DETAILS_PAGE: + if len(self.__hostname.value()) > 0: + return True + else: + errors.append("You must enter a remote hostname.") + elif page is CONFIRM_PAGE: return True + return False + + def process_input(self, page): + if page is CONFIRM_PAGE: + hv = self.__hypervisor.getSelection() + conn = self.__connection.getSelection() + hostname = self.__hostname.value() + + if hv is HYPERVISOR_XEN: + if conn is CONNECTION_LOCAL: url = "xen:///" + elif conn is CONNECTION_KERBEROS: url = "xen+tcp:///" + hostname + "/" + elif conn is CONNECTION_SSL: url = "xen+tls:///" + hostname + "/" + elif conn is CONNECTION_SSH: url = "xen+ssh:///" + hostname + "/" + elif hv is HYPERVISOR_KVM: + if conn is CONNECTION_LOCAL: url = "qemu:///system" + elif conn is CONNECTION_KERBEROS: url = "qemu+tcp://" + hostname + "/system" + elif conn is CONNECTION_SSL: url = "qemu+tls://" + hostname + "/system" + elif conn is CONNECTION_SSH: url = "qemu+ssh://" + hostname + "/system" + + self.get_virt_manager_config().add_connection(url) + self.set_finished() + + def get_details_page(self, screen): + if not self.__configured: + self.__hypervisor = RadioBar(screen, ((HYPERVISORS[HYPERVISOR_XEN], HYPERVISOR_XEN, True), + (HYPERVISORS[HYPERVISOR_KVM], HYPERVISOR_KVM, False))) + self.__connection = RadioBar(screen, ((CONNECTIONS[CONNECTION_LOCAL], CONNECTION_LOCAL, True), + (CONNECTIONS[CONNECTION_KERBEROS], CONNECTION_KERBEROS, False), + (CONNECTIONS[CONNECTION_SSL], CONNECTION_SSL, False), + (CONNECTIONS[CONNECTION_SSH], CONNECTION_SSH, False))) + self.__hostname = Entry(50, "") + self.__autoconnect = Checkbox("Autoconnect on Startup") + self.__configured = True + grid = Grid(2, 4) + grid.setField(Label("Hypervisor:"), 0, 0, anchorRight = 1, anchorTop = 1) + grid.setField(self.__hypervisor, 1, 0, anchorLeft = 1) + grid.setField(Label("Connection:"), 0, 1, anchorRight = 1, anchorTop = 1) + grid.setField(self.__connection, 1, 1, anchorLeft = 1) + grid.setField(Label("Hostname:"), 0, 2, anchorRight = 1) + grid.setField(self.__hostname, 1, 2, anchorLeft = 1) + grid.setField(Label(""), 0, 3, anchorRight = 1) + grid.setField(self.__autoconnect, 1, 3, anchorLeft = 1) + return [Label("Add Connection"), + grid] + + def get_confirm_page(self, screen): + grid = Grid(2, 4) + grid.setField(Label("Hypervisor:"), 0, 0, anchorRight = 1) + 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) + grid.setField(Label("Hostname:"), 0, 2, anchorRight = 1) + grid.setField(Label(self.__hostname.value()), 1, 2, anchorLeft = 1) + grid.setField(Label("Autoconnect on Startup:"), 0, 3, anchorRight = 1) + label = "Yes" + if not self.__autoconnect.value(): label = "No" + grid.setField(Label(label), 1, 3, anchorLeft = 1) + return [Label("Confirm Connection"), + grid] + +def AddHost(): + screen = AddHostConfigScreen() + screen.start() diff --git a/nodeadmin/changehost.py b/nodeadmin/changehost.py new file mode 100644 index 0000000..23e6854 --- /dev/null +++ b/nodeadmin/changehost.py @@ -0,0 +1,58 @@ +# changehost.py - Copyright (C) 2009 Red Hat, Inc. +# Written by Darryl L. Pierce +# +# 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 * + +import logging +import libvirtworker +from configscreen import * + +CONNECTION_LIST_PAGE = 1 +CONNECTED_PAGE = 2 + +class ChangeHostConfigScreen(HostListConfigScreen): + def __init__(self): + HostListConfigScreen.__init__(self, "Change Host") + + def get_elements_for_page(self, screen, page): + if page is CONNECTION_LIST_PAGE: return self.get_connection_list_page(screen) + elif page is CONNECTED_PAGE: return self.get_connected_page(screen) + + def process_input(self, page): + if page is CONNECTION_LIST_PAGE: + logging.info("Changing libvirt connection to %s" % self.get_selected_connection()) + libvirtworker.set_default_url(self.get_selected_connection()) + self.get_libvirt().open_connection(self.get_selected_connection()) + elif page is CONNECTED_PAGE: self.set_finished() + + def page_has_next(self, page): + if page is CONNECTION_LIST_PAGE: return self.has_selectable_connections() + return False + + def page_has_back(self, page): + return page > CONNECTION_LIST_PAGE + + def page_has_finish(self, page): + return page is CONNECTED_PAGE + + def get_connected_page(self, screen): + return [Label("Connected to %s" % self.get_selected_connection())] + +def ChangeHost(): + screen = ChangeHostConfigScreen() + screen.start() diff --git a/nodeadmin/configscreen.py b/nodeadmin/configscreen.py index f214aea..98e0338 100644 --- a/nodeadmin/configscreen.py +++ b/nodeadmin/configscreen.py @@ -18,7 +18,7 @@ from snack import * from halworker import HALWorker -from libvirtworker import LibvirtWorker +from libvirtworker import * import traceback BACK_BUTTON = "back" @@ -35,6 +35,7 @@ class ConfigScreen: self.__finished = False self.__hal = HALWorker() self.__libvirt = LibvirtWorker() + self.__vm_config = VirtManagerConfig() def get_hal(self): return self.__hal @@ -42,6 +43,9 @@ class ConfigScreen: def get_libvirt(self): return self.__libvirt + def get_virt_manager_config(self): + return self.__vm_config + def set_finished(self): self.__finished = True @@ -179,3 +183,33 @@ class NetworkListConfigScreen(ConfigScreen): def has_selectable_networks(self): return self.__has_networks + +class HostListConfigScreen(ConfigScreen): + '''Provides a base class for working with lists of libvirt hosts.''' + + def __init__(self, title): + ConfigScreen.__init__(self, title) + + def get_connection_list_page(self, screen): + connections = self.get_virt_manager_config().get_connection_list() + result = None + + if len(connections) > 0: + self.__has_connections = True + self.__connection_list = Listbox(0) + for connection in connections: + self.__connection_list.append(connection, connection) + result = self.__connection_list + else: + self.__has_connections = False + result = Label("There are no defined connections.") + grid = Grid(1, 1) + grid.setField(result, 0, 0) + return [Label("Host List"), + grid] + + def get_selected_connection(self): + return self.__connection_list.current() + + def has_selectable_connections(self): + return self.__has_connections diff --git a/nodeadmin/definenet.py b/nodeadmin/definenet.py index 4aa37d5..6dff18f 100644 --- a/nodeadmin/definenet.py +++ b/nodeadmin/definenet.py @@ -20,6 +20,7 @@ from snack import * from IPy import IP import traceback import logging +import re from configscreen import ConfigScreen from networkconfig import NetworkConfig diff --git a/nodeadmin/hostconnect.py b/nodeadmin/hostconnect.py new file mode 100644 index 0000000..a1be569 --- /dev/null +++ b/nodeadmin/hostconnect.py @@ -0,0 +1,29 @@ +# hostconnect.py - Copyright (C) 2009 Red Hat, Inc. +# Written by Darryl L. Pierce +# +# 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 configscreen import * + +class HostConnectConfigScreen(ConfigScreen): + def __init__(self): + ConfigScree + +def HostConnect(): + screen = HostConnectConfigScreen() + screen.start() diff --git a/nodeadmin/hostmenu.py b/nodeadmin/hostmenu.py new file mode 100644 index 0000000..4054d6b --- /dev/null +++ b/nodeadmin/hostmenu.py @@ -0,0 +1,46 @@ +# hostmenu.py - Copyright (C) 2009 Red Hat, Inc. +# Written by Darryl L. Pierce +# +# 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 menuscreen import MenuScreen +from changehost import ChangeHost +from addhost import AddHost +from removehost import RemoveHost + +SELECT_HOST = 1 +ADD_HOST = 2 +REMOVE_HOST = 3 + +class HostMenuScreen(MenuScreen): + def __init__(self): + MenuScreen.__init__(self, "Host Menu Screen") + + def get_menu_items(self): + return (("Select A Host", SELECT_HOST), + ("Add A Host", ADD_HOST), + ("Remove A Host", REMOVE_HOST)) + + def handle_selection(self, item): + if item is SELECT_HOST: ChangeHost() + elif item is ADD_HOST: AddHost() + elif item is REMOVE_HOST: RemoveHost() + +def HostMenu(): + screen = HostMenuScreen() + screen.start() diff --git a/nodeadmin/libvirtworker.py b/nodeadmin/libvirtworker.py index ba07605..2998486 100644 --- a/nodeadmin/libvirtworker.py +++ b/nodeadmin/libvirtworker.py @@ -21,20 +21,69 @@ import libvirt import os import virtinst import utils +import logging from domainconfig import DomainConfig DEFAULT_POOL_TARGET_PATH="/var/lib/libvirt/images" +DEFAULT_URL="qemu:///system" + +default_url = DEFAULT_URL + +def set_default_url(url): + logging.info("Changing DEFAULT_URL to %s" % url) + global default_url + + default_url = url + +def get_default_url(): + logging.info("Returning default URL of %s" % default_url) + return default_url + +class VirtManagerConfig: + def __init__(self, filename = "/etc/remote-libvirt.conf"): + self.__filename = filename + + def get_connection_list(self): + result = [] + if os.path.exists(self.__filename): + input = file(self.__filename, "r") + for entry in input: result.append(entry[0:-1]) + return result + + def add_connection(self, connection): + connections = self.get_connection_list() + if connections.count(connection) is 0: + connections.append(connection) + self._save_connections(connections) + + def remove_connection(self, connection): + connections = self.get_connection_list() + if connections.count(connection) > 0: + connections.remove(connection) + self._save_connections(connections) + + def _save_connections(self, connections): + output = file(self.__filename, "w") + for entry in connections: + print >> output, entry + output.close class LibvirtWorker: '''Provides utilities for interfacing with libvirt.''' - def __init__(self, url = "qemu:///system"): - self.__conn = libvirt.open(url) + def __init__(self, url = None): + if url is None: url = get_default_url() + logging.info("Connecting to libvirt: %s" % url) + self.open_connection(url) self.__capabilities = virtinst.CapabilitiesParser.parse(self.__conn.getCapabilities()) self.__net = virtinst.VirtualNetworkInterface(conn = self.__conn) self.__net.setup(self.__conn) (self.__new_guest, self.__new_domain) = virtinst.CapabilitiesParser.guest_lookup(conn = self.__conn) + def open_connection(self, url): + '''Lets the user change the url for the connection.''' + self.__conn = libvirt.open(url) + def list_domains(self, defined = True, started = True): '''Lists all domains.''' result = [] diff --git a/nodeadmin/mainmenu.py b/nodeadmin/mainmenu.py index 73501fa..944ffeb 100755 --- a/nodeadmin/mainmenu.py +++ b/nodeadmin/mainmenu.py @@ -19,15 +19,17 @@ from snack import * import traceback -from menuscreen import MenuScreen -from nodemenu import NodeMenu -from netmenu import NetworkMenu +from menuscreen import MenuScreen +from nodemenu import NodeMenu +from netmenu import NetworkMenu +from hostmenu import HostMenu import utils import logging NODE_MENU = 1 NETWORK_MENU = 2 +HOST_MENU = 3 EXIT_CONSOLE = 99 class MainMenuScreen(MenuScreen): @@ -35,12 +37,14 @@ class MainMenuScreen(MenuScreen): MenuScreen.__init__(self, "Main Menu") def get_menu_items(self): - return (("Node Administration", NODE_MENU), - ("Network Administration", NETWORK_MENU)) + return (("Node Administration", NODE_MENU), + ("Network Administration", NETWORK_MENU), + ("Host Administration", HOST_MENU)) def handle_selection(self, page): if page is NODE_MENU: NodeMenu() elif page is NETWORK_MENU: NetworkMenu() + elif page is HOST_MENU: HostMenu() def MainMenu(): screen = MainMenuScreen() diff --git a/nodeadmin/removehost.py b/nodeadmin/removehost.py new file mode 100644 index 0000000..cf3c46c --- /dev/null +++ b/nodeadmin/removehost.py @@ -0,0 +1,66 @@ +# removehost.py - Copyright (C) 2009 Red Hat, Inc. +# Written by Darryl L. Pierce +# +# 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 configscreen import * + +SELECT_HOST_PAGE = 1 +CONFIRM_REMOVE_PAGE = 2 + +class RemoveHostConfigScreen(HostListConfigScreen): + def __init__(self): + HostListConfigScreen.__init__(self, "Remove Host Connection") + + def get_elements_for_page(self, screen, page): + if page is SELECT_HOST_PAGE: return self.get_connection_list_page(screen) + elif page is CONFIRM_REMOVE_PAGE: return self.get_confirm_remove_page(screen) + + def page_has_next(self, page): + return page is SELECT_HOST_PAGE and self.has_selectable_connections() + + def page_has_back(self, page): + return page is CONFIRM_REMOVE_PAGE + + def page_has_finish(self, page): + return page is CONFIRM_REMOVE_PAGE + + def validate_input(self, page, errors): + if page is SELECT_HOST_PAGE: return True + elif page is CONFIRM_REMOVE_PAGE: + if self.__confirm.value(): + return True + else: + errors.append("You must confirm removing the connection.") + return False + + def process_input(self, page): + if page is CONFIRM_REMOVE_PAGE: + self.get_virt_manager_config().remove_connection(self.get_selected_connection()) + self.set_finished() + + def get_confirm_remove_page(self, screen): + self.__confirm = Checkbox("Remove this connection: %s" % self.get_selected_connection(), 0) + grid = Grid(1, 1) + grid.setField(self.__confirm, 0, 0) + return [Label("Remove Host Connection"), + grid] + +def RemoveHost(): + screen = RemoveHostConfigScreen() + screen.start() diff --git a/ovirt-node.spec.in b/ovirt-node.spec.in index 56e3aad..23ca2bf 100644 --- a/ovirt-node.spec.in +++ b/ovirt-node.spec.in @@ -198,6 +198,11 @@ cd - %{__install} -p -m0755 nodeadmin/destroynetwork.py %{buildroot}%{python_sitelib}/nodeadmin %{__install} -p -m0755 nodeadmin/undefinenetwork.py %{buildroot}%{python_sitelib}/nodeadmin +%{__install} -p -m0755 nodeadmin/addhost.py %{buildroot}%{python_sitelib}/nodeadmin +%{__install} -p -m0644 nodeadmin/changehost.py %{buildroot}%{python_sitelib}/nodeadmin +%{__install} -p -m0755 nodeadmin/hostmenu.py %{buildroot}%{python_sitelib}/nodeadmin +%{__install} -p -m0755 nodeadmin/removehost.py %{buildroot}%{python_sitelib}/nodeadmin + %{__install} -p -m0755 nodeadmin/createuser.py %{buildroot}%{python_sitelib}/nodeadmin %{__install} -p -m0644 nodeadmin/halworker.py %{buildroot}%{python_sitelib}/nodeadmin -- 1.6.5.2 From dpierce at redhat.com Thu Dec 3 21:42:25 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Thu, 3 Dec 2009 16:42:25 -0500 Subject: [Ovirt-devel] [PATCH 2/2] Enables users to migrate virtual machines between hosts. In-Reply-To: <1259876545-27386-2-git-send-email-dpierce@redhat.com> References: <1259876545-27386-1-git-send-email-dpierce@redhat.com> <1259876545-27386-2-git-send-email-dpierce@redhat.com> Message-ID: <1259876545-27386-3-git-send-email-dpierce@redhat.com> 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 --- 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 +# +# 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 From jboggs at redhat.com Fri Dec 4 14:47:05 2009 From: jboggs at redhat.com (Joey Boggs) Date: Fri, 04 Dec 2009 09:47:05 -0500 Subject: Fwd: Re: [Ovirt-devel] [PATCH 1/2] Provides a new storage administration system to the managed node. Message-ID: <4B1920E9.2090305@redhat.com> resending ack -------- Original Message -------- Subject: Re: [Ovirt-devel] [PATCH 1/2] Provides a new storage administration system to the managed node. Date: Mon, 09 Nov 2009 15:22:56 -0500 From: Joey Boggs To: Darryl L. Pierce , ovirt-devel at redhat.com Darryl L. Pierce wrote: > On Mon, Nov 09, 2009 at 02:54:50PM -0500, Joey Boggs wrote: > >> ACK pending below comments: >> >> For lvm -It creates a pool fine, when creating a volume its missing the >> volume group name when running lvcreate >> >> +-----+ An Exception Has Occurred +-----+ >> Couldn't create storage volume '1.img': 'internal error '/sbin/lvcreate >> --name 1.img -L 1024K /tmp/lvm' exited with non-zero status 3 and signal >> 0 >> Volume group name expected (no slash) Run `lvcreate --help' for more >> information. >> > > Does the same thing happen with virt-manager when doing the same thing? > > virt-manager works fine but here's what wrong /sbin/lvcreate --name 1.img -L 1024K /tmp/lvm' exited with non-zero status 3 and signal 0 /tmp/lvm should be /dev/$poolname not the target path, if you run the command manually and sub in the right path. >> iscsi creates a pool fine but when you reach creating a volume it tells >> you it's no implemented, any way to block this option for even being >> available or alert the user ahead of time? >> >> >> All the other options create pools/volumes fine >> > > I'm not sure if there's an easy way to block it without forcing us to > have to do an upgrade later when it's implemented. When I first saw > that, I double checked virt-manager and it's doing the same thing, > giving an error that the iSCSI pool is not available. So at least in > that way we're consistent. > > ok wfm _______________________________________________ Ovirt-devel mailing list Ovirt-devel at redhat.com https://www.redhat.com/mailman/listinfo/ovirt-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From dpierce at redhat.com Fri Dec 4 15:45:43 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Fri, 4 Dec 2009 10:45:43 -0500 Subject: [Ovirt-devel] Refactored, fixed and ready to review... In-Reply-To: <1259875476-26455-1-git-send-email-dpierce@redhat.com> References: <1259875476-26455-1-git-send-email-dpierce@redhat.com> Message-ID: <20091204154543.GH28789@mcpierce-desktop.usersys.redhat.com> On Thu, Dec 03, 2009 at 04:24:34PM -0500, Darryl L. Pierce wrote: > This set of patches needed some reworking since they would not apply on top of > next. They are ready for review and to be pushed. Patches are pushed upstream now. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Delivering value year after year. Red Hat ranks #1 in value among software vendors. http://www.redhat.com/promo/vendor/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: not available URL: From dpierce at redhat.com Fri Dec 4 21:03:43 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Fri, 4 Dec 2009 16:03:43 -0500 Subject: [Ovirt-devel] Rebased patches... Message-ID: <1259960625-19704-1-git-send-email-dpierce@redhat.com> I've rebased the host config and migration patches after pushing the storage patches upstream. From dpierce at redhat.com Fri Dec 4 21:03:44 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Fri, 4 Dec 2009 16:03:44 -0500 Subject: [Ovirt-devel] [PATCH 1/2] Users can now work with remote libvirt hosts. In-Reply-To: <1259960625-19704-1-git-send-email-dpierce@redhat.com> References: <1259960625-19704-1-git-send-email-dpierce@redhat.com> Message-ID: <1259960625-19704-2-git-send-email-dpierce@redhat.com> The user can: * select a remote machine * add a remote machine * remove a remote machine --- nodeadmin/mainmenu.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/nodeadmin/mainmenu.py b/nodeadmin/mainmenu.py index f805ed9..9c435fd 100755 --- a/nodeadmin/mainmenu.py +++ b/nodeadmin/mainmenu.py @@ -42,7 +42,7 @@ class MainMenuScreen(MenuScreen): return (("Node Administration", NODE_MENU), ("Network Administration", NETWORK_MENU), ("Storage Pool Administration", STORAGE_MENU), - ("Host Administration", HOST_MENU)) + ("Host Administration", HOST_MENU)) def handle_selection(self, page): if page is NODE_MENU: NodeMenu() -- 1.6.5.2 From dpierce at redhat.com Fri Dec 4 21:03:45 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Fri, 4 Dec 2009 16:03:45 -0500 Subject: [Ovirt-devel] [PATCH 2/2] Enables users to migrate virtual machines between hosts. In-Reply-To: <1259960625-19704-2-git-send-email-dpierce@redhat.com> References: <1259960625-19704-1-git-send-email-dpierce@redhat.com> <1259960625-19704-2-git-send-email-dpierce@redhat.com> Message-ID: <1259960625-19704-3-git-send-email-dpierce@redhat.com> 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 +# +# 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 From dpierce at redhat.com Mon Dec 7 22:12:07 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Mon, 7 Dec 2009 17:12:07 -0500 Subject: [Ovirt-devel] Rebased... Message-ID: <1260223928-2621-1-git-send-email-dpierce@redhat.com> This version of the patch was rebased to go on top of recent changes committed to ovirt-config-networking on next. From dpierce at redhat.com Mon Dec 7 22:12:08 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Mon, 7 Dec 2009 17:12:08 -0500 Subject: [Ovirt-devel] [PATCH] Static IPv4 addresses entered are validated when they're entered. In-Reply-To: <1260223928-2621-1-git-send-email-dpierce@redhat.com> References: <1260223928-2621-1-git-send-email-dpierce@redhat.com> Message-ID: <1260223928-2621-2-git-send-email-dpierce@redhat.com> If the address is not blank then it is validated. Only those that are properly formed are accepted. Otherwise an error message is displayed and the user is prompted again. Resolves: rhbz#536912 - validation for static IP should be optimized Signed-off-by: Darryl L. Pierce --- scripts/ovirt-config-networking | 28 +++++++++++++++++++++++++--- 1 files changed, 25 insertions(+), 3 deletions(-) diff --git a/scripts/ovirt-config-networking b/scripts/ovirt-config-networking index f9c6a4c..ec154c2 100755 --- a/scripts/ovirt-config-networking +++ b/scripts/ovirt-config-networking @@ -30,6 +30,28 @@ if ! is_local_storage_configured; then exit 99 fi +# $1 - the variable name to set +# $2 - the input prompt +function input_ipv4_address { + local varname=$1 + local prompt=$2 + + eval $varname=\"\" + + while true; do + read -ep "${prompt}: " + + if [ -z "$REPLY" ]; then return; fi + + if is_valid_ipv4 $REPLY; then + eval $varname=\"$REPLY\" + return + else + printf "\nThe address $REPLY is not a valid IPv4 address.\n" + fi + done +} + # Checks that a network interface was already configured. function has_configured_interface { @@ -169,9 +191,9 @@ function configure_interface ;; S|s) printf "\n" - read -ep "IP Address: "; IPADDR=$REPLY - read -ep " Netmask: "; NETMASK=$REPLY - read -ep " Gateway: "; GATEWAY=$REPLY + input_ipv4_address IPADDR "IP Address" + input_ipv4_address NETMASK " Netmask" + input_ipv4_address GATEWAY " Gateway" BR_CONFIG="$BR_CONFIG\nset $BR_ROOT/BOOTPROTO none" BR_CONFIG="$BR_CONFIG\nset $BR_ROOT/IPADDR $IPADDR" -- 1.6.5.2 From jboggs at redhat.com Mon Dec 7 23:10:18 2009 From: jboggs at redhat.com (Joey Boggs) Date: Mon, 07 Dec 2009 18:10:18 -0500 Subject: [Ovirt-devel] [PATCH] Static IPv4 addresses entered are validated when they're entered. In-Reply-To: <1260223928-2621-2-git-send-email-dpierce@redhat.com> References: <1260223928-2621-1-git-send-email-dpierce@redhat.com> <1260223928-2621-2-git-send-email-dpierce@redhat.com> Message-ID: <4B1D8B5A.803@redhat.com> On 12/07/2009 05:12 PM, Darryl L. Pierce wrote: > If the address is not blank then it is validated. Only those that are > properly formed are accepted. Otherwise an error message is displayed > and the user is prompted again. > > Resolves: rhbz#536912 - validation for static IP should be optimized > > Signed-off-by: Darryl L. Pierce > --- > scripts/ovirt-config-networking | 28 +++++++++++++++++++++++++--- > 1 files changed, 25 insertions(+), 3 deletions(-) > > diff --git a/scripts/ovirt-config-networking b/scripts/ovirt-config-networking > index f9c6a4c..ec154c2 100755 > --- a/scripts/ovirt-config-networking > +++ b/scripts/ovirt-config-networking > @@ -30,6 +30,28 @@ if ! is_local_storage_configured; then > exit 99 > fi > > +# $1 - the variable name to set > +# $2 - the input prompt > +function input_ipv4_address { > + local varname=$1 > + local prompt=$2 > + > + eval $varname=\"\" > + > + while true; do > + read -ep "${prompt}: " > + > + if [ -z "$REPLY" ]; then return; fi > + > + if is_valid_ipv4 $REPLY; then > + eval $varname=\"$REPLY\" > + return > + else > + printf "\nThe address $REPLY is not a valid IPv4 address.\n" > + fi > + done > +} > + > # Checks that a network interface was already configured. > function has_configured_interface > { > @@ -169,9 +191,9 @@ function configure_interface > ;; > S|s) > printf "\n" > - read -ep "IP Address: "; IPADDR=$REPLY > - read -ep " Netmask: "; NETMASK=$REPLY > - read -ep " Gateway: "; GATEWAY=$REPLY > + input_ipv4_address IPADDR "IP Address" > + input_ipv4_address NETMASK " Netmask" > + input_ipv4_address GATEWAY " Gateway" > > BR_CONFIG="$BR_CONFIG\nset $BR_ROOT/BOOTPROTO none" > BR_CONFIG="$BR_CONFIG\nset $BR_ROOT/IPADDR $IPADDR" > ACK From dpierce at redhat.com Tue Dec 8 13:55:20 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Tue, 8 Dec 2009 08:55:20 -0500 Subject: [Ovirt-devel] [PATCH] Static IPv4 addresses entered are validated when they're entered. In-Reply-To: <4B1D8B5A.803@redhat.com> References: <1260223928-2621-1-git-send-email-dpierce@redhat.com> <1260223928-2621-2-git-send-email-dpierce@redhat.com> <4B1D8B5A.803@redhat.com> Message-ID: <20091208135520.GA29189@mcpierce-desktop.usersys.redhat.com> On Mon, Dec 07, 2009 at 06:10:18PM -0500, Joey Boggs wrote: > ACK Thank you. This is now pushed upstream. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Delivering value year after year. Red Hat ranks #1 in value among software vendors. http://www.redhat.com/promo/vendor/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: not available URL: From jboggs at redhat.com Tue Dec 8 20:41:33 2009 From: jboggs at redhat.com (Joey Boggs) Date: Tue, 8 Dec 2009 15:41:33 -0500 Subject: [Ovirt-devel] [PATCH node] iscsi remote root basework This lays most of the groundwork for iscsi installation and configuration. At this time configuring iscsi is disabled due to multiple issues with dependent pieces. Message-ID: <1260304893-14904-1-git-send-email-jboggs@redhat.com> - dracut does not currently support booting a dmsquash file system on an iscsiroot - can not be configured in standalone mode since networking is not up, although works fine if ovirt-config-setup is run once booted. Signed-off-by: Joey Boggs --- recipe/common-pkgs.ks | 1 + scripts/ovirt-config-boot | 67 ++++++++++++++++---- scripts/ovirt-config-storage | 142 +++++++++++++++++++++++++++++++++++++++-- scripts/ovirt-functions | 8 +++ 4 files changed, 199 insertions(+), 19 deletions(-) diff --git a/recipe/common-pkgs.ks b/recipe/common-pkgs.ks index daff195..9bd3b07 100644 --- a/recipe/common-pkgs.ks +++ b/recipe/common-pkgs.ks @@ -73,3 +73,4 @@ kpartx # workaround for gpxe issue with the virt-preview qemu on F11 host kernel # https://bugzilla.redhat.com/show_bug.cgi?id=512358 etherboot-zroms-kvm +dracut-network diff --git a/scripts/ovirt-config-boot b/scripts/ovirt-config-boot index 470f57b..4c4e3d7 100755 --- a/scripts/ovirt-config-boot +++ b/scripts/ovirt-config-boot @@ -29,9 +29,28 @@ ovirt_boot_setup() { local disk2 local partN=-1 log "installing the image." + if [ -h /dev/disk/by-label/Boot ]; then + mount_boot + mountpoint /boot + if [ $? -ne 0 ] ; then + log "Boot partition not available" + return 1 + fi + grub_dev_label="Boot" + # Grab OVIRT_ISCSI VARIABLES from boot partition for upgrading + # file created only if OVIRT_ISCSI_ENABLED=y + if [ -f /boot/ovirt ]; then + . /boot/ovirt + iscsiadm -p $OVIRT_ISCSI_TARGET_IP:$OVIRT_ISCSI_TARGET_PORT -m discovery -t sendtargets + log "Restarting iscsi service" + service iscsi restart + fi + else + grub_dev_label="RootBackup" + fi mount_liveos # check that /boot mounted ok and find partition number for GRUB - eval $(readlink -f /dev/disk/by-label/RootBackup|awk {' + eval $(readlink -f /dev/disk/by-label/$grub_dev_label|awk {' print "disk=" substr($1,1,length($1)-1); print "disk2=" substr($1,1,length($1)-2); partN=substr($1,length($1),1); partN--; @@ -75,9 +94,10 @@ ovirt_boot_setup() { fi if [ $rc -ne 0 ]; then log "root partition not available." - log "$(lvdisplay -c)" + log "$(ls -al /dev/disk/by-label)" return $rc fi + mount $candidate_dev /liveos # install oVirt Node image for local boot if [ -e "$live/syslinux" ]; then @@ -87,12 +107,25 @@ ovirt_boot_setup() { else syslinux= fi - rm -rf /liveos/boot/grub + rm -rf /liveos/LiveOS - mkdir -p /liveos/boot/grub mkdir -p /liveos/LiveOS + + if [ "$OVIRT_ISCSI_ENABLED" == "y" ]; then + initrd_dest="/boot" + grub_dir="/boot/grub" + grub_prefix="/grub" + else + initrd_dest="/liveos" + grub_dir="/liveos/boot/grub" + grub_prefix="/boot/grub" + fi + + rm -rf $grub_dir + mkdir -p $grub_dir + cp -p $live/LiveOS/squashfs.img /liveos/LiveOS \ - && cp -p $live/$syslinux/vmlinuz0 /liveos + && cp -p $live/$syslinux/vmlinuz0 $initrd_dest rc=$? if [ $rc -ne 0 ]; then log "image copy failed." @@ -139,17 +172,23 @@ set -e\ # lvm is not static in Fedora cp /lib$bit/libreadline.so.5 /lib$bit/libncurses.so.5 lib$bit fi + find $init_script bin/lvm lib$bit -type f | cpio -H newc --quiet -o | gzip -9 | - cat $live/$syslinux/initrd0.img - > /liveos/initrd0.img + cat $live/$syslinux/initrd0.img - > $initrd_dest/initrd0.img version=$(rpm -q --qf '%{version}' ovirt-node) release=$(rpm -q --qf '%{release}' ovirt-node) # reorder tty0 to allow both serial and phys console after installation - bootparams="ro root=LABEL=Root roottypefs=ext3 console=tty0 \ + if [ "$OVIRT_ISCSI_ENABLED" == "y" ]; then + bootparams="ro root=LABEL=live:Root roottypefs=ext3 console=tty0 \ + netroot=iscsi:$OVIRT_ISCSI_TARGET_IP::$OVIRT_ISCSI_TARGET_PORT::$OVIRT_ISCSI_NODE_NAME ip=eth0:dhcp" + else + bootparams="ro root=LABEL=live:Root roottypefs=ext3 console=tty0 \ $(echo $bootparams | sed s/console=tty0//g)" - cat > /liveos/boot/grub/grub.conf << EOF + fi + cat > $grub_dir/grub.conf << EOF default=0 timeout=5 hiddenmenu @@ -158,11 +197,11 @@ title oVirt Node (${version}-${release}) kernel /vmlinuz0 $bootparams initrd /initrd0.img EOF - echo "(hd0) $disk" > /liveos/boot/grub/device.map - ( cd /usr/share/grub/*; cp -p stage? e2fs_stage1_5 /liveos/boot/grub ) - grub --device-map=/liveos/boot/grub/device.map < $grub_dir/device.map + ( cd /usr/share/grub/*; cp -p stage? e2fs_stage1_5 $grub_dir ) + grub --device-map=$grub_dir/device.map <&2 +select OVIRT_ISCSI_NODE_NAME in $ISCSI_NODE_NAMES ; do +log " Selected Node Name: $OVIRT_ISCSI_NODE_NAME" +break; +done + +augtool < References: <1260304893-14904-1-git-send-email-jboggs@redhat.com> Message-ID: <4B1EBAA3.3000205@redhat.com> On 12/08/2009 03:41 PM, Joey Boggs wrote: > - dracut does not currently support booting a dmsquash file system on an iscsiroot > - can not be configured in standalone mode since networking is not up, although works fine if ovirt-config-setup is run once booted. > > Signed-off-by: Joey Boggs > --- > recipe/common-pkgs.ks | 1 + > scripts/ovirt-config-boot | 67 ++++++++++++++++---- > scripts/ovirt-config-storage | 142 +++++++++++++++++++++++++++++++++++++++-- > scripts/ovirt-functions | 8 +++ > 4 files changed, 199 insertions(+), 19 deletions(-) > > diff --git a/recipe/common-pkgs.ks b/recipe/common-pkgs.ks > index daff195..9bd3b07 100644 > --- a/recipe/common-pkgs.ks > +++ b/recipe/common-pkgs.ks > @@ -73,3 +73,4 @@ kpartx > # workaround for gpxe issue with the virt-preview qemu on F11 host kernel > # https://bugzilla.redhat.com/show_bug.cgi?id=512358 > etherboot-zroms-kvm > +dracut-network > diff --git a/scripts/ovirt-config-boot b/scripts/ovirt-config-boot > index 470f57b..4c4e3d7 100755 > --- a/scripts/ovirt-config-boot > +++ b/scripts/ovirt-config-boot > @@ -29,9 +29,28 @@ ovirt_boot_setup() { > local disk2 > local partN=-1 > log "installing the image." > + if [ -h /dev/disk/by-label/Boot ]; then > + mount_boot > + mountpoint /boot > + if [ $? -ne 0 ] ; then > + log "Boot partition not available" > + return 1 > + fi > + grub_dev_label="Boot" > + # Grab OVIRT_ISCSI VARIABLES from boot partition for upgrading > + # file created only if OVIRT_ISCSI_ENABLED=y > + if [ -f /boot/ovirt ]; then > + . /boot/ovirt > + iscsiadm -p $OVIRT_ISCSI_TARGET_IP:$OVIRT_ISCSI_TARGET_PORT -m discovery -t sendtargets > + log "Restarting iscsi service" > + service iscsi restart > + fi > + else > + grub_dev_label="RootBackup" > + fi > mount_liveos > # check that /boot mounted ok and find partition number for GRUB > - eval $(readlink -f /dev/disk/by-label/RootBackup|awk {' > + eval $(readlink -f /dev/disk/by-label/$grub_dev_label|awk {' > print "disk=" substr($1,1,length($1)-1); > print "disk2=" substr($1,1,length($1)-2); > partN=substr($1,length($1),1); partN--; > @@ -75,9 +94,10 @@ ovirt_boot_setup() { > fi > if [ $rc -ne 0 ]; then > log "root partition not available." > - log "$(lvdisplay -c)" > + log "$(ls -al /dev/disk/by-label)" > return $rc > fi > + > mount $candidate_dev /liveos > # install oVirt Node image for local boot > if [ -e "$live/syslinux" ]; then > @@ -87,12 +107,25 @@ ovirt_boot_setup() { > else > syslinux= > fi > - rm -rf /liveos/boot/grub > + > rm -rf /liveos/LiveOS > - mkdir -p /liveos/boot/grub > mkdir -p /liveos/LiveOS > + > + if [ "$OVIRT_ISCSI_ENABLED" == "y" ]; then > + initrd_dest="/boot" > + grub_dir="/boot/grub" > + grub_prefix="/grub" > + else > + initrd_dest="/liveos" > + grub_dir="/liveos/boot/grub" > + grub_prefix="/boot/grub" > + fi > + > + rm -rf $grub_dir > + mkdir -p $grub_dir > + > cp -p $live/LiveOS/squashfs.img /liveos/LiveOS \ > -&& cp -p $live/$syslinux/vmlinuz0 /liveos > +&& cp -p $live/$syslinux/vmlinuz0 $initrd_dest > rc=$? > if [ $rc -ne 0 ]; then > log "image copy failed." > @@ -139,17 +172,23 @@ set -e\ > # lvm is not static in Fedora > cp /lib$bit/libreadline.so.5 /lib$bit/libncurses.so.5 lib$bit > fi > + > find $init_script bin/lvm lib$bit -type f | > cpio -H newc --quiet -o | > gzip -9 | > - cat $live/$syslinux/initrd0.img -> /liveos/initrd0.img > + cat $live/$syslinux/initrd0.img -> $initrd_dest/initrd0.img > > version=$(rpm -q --qf '%{version}' ovirt-node) > release=$(rpm -q --qf '%{release}' ovirt-node) > # reorder tty0 to allow both serial and phys console after installation > - bootparams="ro root=LABEL=Root roottypefs=ext3 console=tty0 \ > + if [ "$OVIRT_ISCSI_ENABLED" == "y" ]; then > + bootparams="ro root=LABEL=live:Root roottypefs=ext3 console=tty0 \ > + netroot=iscsi:$OVIRT_ISCSI_TARGET_IP::$OVIRT_ISCSI_TARGET_PORT::$OVIRT_ISCSI_NODE_NAME ip=eth0:dhcp" > + else > + bootparams="ro root=LABEL=live:Root roottypefs=ext3 console=tty0 \ > $(echo $bootparams | sed s/console=tty0//g)" > - cat> /liveos/boot/grub/grub.conf<< EOF > + fi > + cat> $grub_dir/grub.conf<< EOF > default=0 > timeout=5 > hiddenmenu > @@ -158,11 +197,11 @@ title oVirt Node (${version}-${release}) > kernel /vmlinuz0 $bootparams > initrd /initrd0.img > EOF > - echo "(hd0) $disk"> /liveos/boot/grub/device.map > - ( cd /usr/share/grub/*; cp -p stage? e2fs_stage1_5 /liveos/boot/grub ) > - grub --device-map=/liveos/boot/grub/device.map< + echo "(hd0) $disk"> $grub_dir/device.map > + ( cd /usr/share/grub/*; cp -p stage? e2fs_stage1_5 $grub_dir ) > + grub --device-map=$grub_dir/device.map< root (hd0,$partN) > -setup --prefix=/boot/grub (hd0) > +setup --prefix=$grub_prefix (hd0) > EOF > rc=$? > if [ $rc -ne 0 ]; then > @@ -175,6 +214,10 @@ EOF > e2label $candidate_dev RootUpdate > > rm -rf $tmpdir > + if [ "$OVIRT_ISCSI_ENABLED" == "y" ]; then > + # copy default for when Root/HostVG is inaccessible(iscsi upgrade > + cp $OVIRT_DEFAULTS /boot > + fi > log "done." > } > > diff --git a/scripts/ovirt-config-storage b/scripts/ovirt-config-storage > index 57aaebd..f9a5b41 100755 > --- a/scripts/ovirt-config-storage > +++ b/scripts/ovirt-config-storage > @@ -21,13 +21,13 @@ if is_booted_from_local_disk; then > fi > > default_overcommit=0.5 > - > +default_boot_size=50 > default_root_size=256 > default_config_size=5 > default_logging_size=2048 > # -1 indicates data partition should use remaining disk > default_data_size=-1 > - > +boot_min_size=50 > root_min_size=256 > config_min_size=5 > logging_min_size=5 > @@ -206,6 +206,11 @@ get_dev_name() > do_configure() > { > local name_and_size > + if [ "$OVIRT_ISCSI_ENABLED" == "y" ]; then > + printf "\n\nPlease select the disk to use for the Boot partition.\n\n" > + BOOTDRIVE=$(get_dev_name) || return 0 > + get_drive_size $BOOTDRIVE BOOTDRIVESPACE > + fi > printf "\n\nPlease select the disk to use for the Root.\n\n" > ROOTDRIVE=$(get_dev_name) || return 0 > get_drive_size $ROOTDRIVE ROOTDRIVESPACE > @@ -230,7 +235,12 @@ do_configure() > fi > > local space_left=$HOSTVGDRIVESPACE > - for part in swap root config logging data ; do > + if [ "$OVIRT_ISCSI_ENABLED" == "y" ]; then > + partlist="boot swap root config logging data" > + else > + partlist="swap root config logging data" > + fi > + for part in $partlist ; do > part_regexp="^0$" > if [ "$part" = "data" ]; then > part_regexp="^\-1|0$" > @@ -276,12 +286,19 @@ do_configure() > # save input variables > augtool< set /files$OVIRT_DEFAULTS/OVIRT_INIT $ROOTDRIVE > +set /files$OVIRT_DEFAULTS/OVIRT_VOL_BOOT_SIZE $BOOT_SIZE > set /files$OVIRT_DEFAULTS/OVIRT_VOL_SWAP_SIZE $SWAP_SIZE > set /files$OVIRT_DEFAULTS/OVIRT_VOL_ROOT_SIZE $ROOT_SIZE > set /files$OVIRT_DEFAULTS/OVIRT_VOL_CONFIG_SIZE $CONFIG_SIZE > set /files$OVIRT_DEFAULTS/OVIRT_VOL_LOGGING_SIZE $LOGGING_SIZE > set /files$OVIRT_DEFAULTS/OVIRT_VOL_DATA_SIZE $DATA_SIZE > EOF > + > + if [ -n $BOOTDRIVE ]; then > + augtool< +set /files$OVIRT_DEFAULTS/OVIRT_BOOT_INIT $BOOTDRIVE > +EOF > + fi > } > > do_review() > @@ -356,20 +373,33 @@ perform_partitioning() > partprobe -s $ROOTDRIVE > > MEM_SIZE_MB=$(echo "scale=0; $MEM_SIZE_MB / 1024;" | bc -l) > + local boot_size_si=$(echo "scale=0; $BOOT_SIZE * (1024 * 1024) / (1000 * 1000)" | bc -l) > log "Labeling Drive: $ROOTDRIVE" > parted $ROOTDRIVE -s "mklabel ${LABEL_TYPE}" > + if [ -n "$BOOTDRIVE" ]; then > + dd if=/dev/zero of=$BOOTDRIVE bs=1024K count=1 > + blockdev --rereadpt $BOOTDRIVE > + partprobe -s $BOOTDRIVE > + log "Creating boot partition" > + parted $BOOTDRIVE -s "mklabel ${LABEL_TYPE}" > + parted $BOOTDRIVE -s "mkpartfs primary ext2 0M ${boot_size_si}M" > + fi > if [ $ROOTDRIVE != $HOSTVGDRIVE ]; then > log "Labeling Drive: $HOSTVGDRIVE" > parted $HOSTVGDRIVE -s "mklabel ${LABEL_TYPE}" > fi > log "Creating Root and RootBackup Partitions" > let RootBackup_end=${ROOT_SIZE}*2 > - parted $ROOTDRIVE -s "mkpartfs primary ext2 0M ${ROOT_SIZE}M" > - parted $ROOTDRIVE -s "mkpartfs primary ext2 ${ROOT_SIZE}M ${RootBackup_end}M" > + parted $ROOTDRIVE -s "mkpart primary ext2 0M ${ROOT_SIZE}M" > + parted $ROOTDRIVE -s "mkpart primary ext2 ${ROOT_SIZE}M ${RootBackup_end}M" > # sleep to ensure filesystems are created before continuing > sleep 10 > - e2label ${ROOTDRIVE}1 Root > - e2label ${ROOTDRIVE}2 RootBackup > + if [ -n "$BOOTDRIVE" ]; then > + mke2fs ${BOOTDRIVE}1 -L Boot > + tune2fs -c 0 -i 0 ${BOOTDRIVE}1 > + fi > + mke2fs ${ROOTDRIVE}1 -L Root > + mke2fs ${ROOTDRIVE}2 -L RootBackup > tune2fs -c 0 -i 0 ${ROOTDRIVE}1 > tune2fs -c 0 -i 0 ${ROOTDRIVE}2 > log "Creating LVM partition" > @@ -468,6 +498,7 @@ perform_partitioning() > > do_confirm() > { > + > if [ -z "$ROOTDRIVE" ]; then > printf "\nNo storage device selected.\n" > return > @@ -502,6 +533,101 @@ do_confirm() > done > } > > +do_iscsi_target() > +{ > +while true; do > + OPTIONS="\"Target IP\" \"Target Port\"" #\"CHAP Username\" \"CHAP Password\"" > + printf "\nPress Enter to leave option blank or Q to quit (default Target Port is 3260)\n" > + eval set $OPTIONS > + PS3="Choose an option: " > + for OPTION in "$@"; do > + while true; do > + read -ep "Enter $OPTION: " > + if [[ $REPLY == "q" || $REPLY == "Q" ]]; then > + return > + fi > + > + if [ "$OPTION" == "Target IP" ]; then > + OVIRT_ISCSI_TARGET_IP=$REPLY > + if [ -n "$REPLY" ]; then > + break; > + fi > + > + elif [ "$OPTION" == "Target Port" ]; then > + OVIRT_ISCSI_TARGET_PORT=$REPLY > + if [ -z "$REPLY" ]; then > + OVIRT_ISCSI_TARGET_PORT="3260" > + break; > + else > + break; > + fi > + > + elif [ "$OPTION" == "CHAP Username" ]; then > + OVIRT_ISCSI_CHAP_USERNAME=$REPLY > + break > + > + elif [ "$OPTION" == "CHAP Password" ]; then > + OVIRT_ISCSI_CHAP_PASSWORD=$REPLY > + break; > + fi > + done > + done > + > + cat< + > +The iSCSI target be configured as follows: > +================================================ > + Target IP: $OVIRT_ISCSI_TARGET_IP > + Target Port: $OVIRT_ISCSI_TARGET_PORT > + > +EOF > +# Username: $OVIRT_ISCSI_CHAP_USERNAME > +# Password: $OVIRT_ISCSI_CHAP_PASSWORD > +#EOF > + > +if ask_yes_or_no "Is this correct ([Y]es/[N]o)?" true true; then > + > + OVIRT_ISCSI_ENABLED="y" > + augtool< +set /files/etc/default/ovirt/OVIRT_ISCSI_ENABLED y > +set /files/etc/default/ovirt/OVIRT_ISCSI_TARGET_IP $OVIRT_ISCSI_TARGET_IP > +set /files/etc/default/ovirt/OVIRT_ISCSI_TARGET_PORT $OVIRT_ISCSI_TARGET_PORT > +EOF > + > + if [[ -n "$OVIRT_ISCSI_CHAP_USERNAME"&& -n "$OVIRT_ISCSI_CHAP_PASSWORD" ]]; then > + log "setting iscsid.conf username/password" > + augtool< +set /files/etc/iscsi/iscsid.conf/node.session.auth.authmethod CHAP > +set /files/etc/iscsi/iscsid.conf/node.session.auth.username $OVIRT_ISCSI_CHAP_USERNAME > +set /files/etc/iscsi/iscsid.conf/node.session.auth.password $OVIRT_ISCSI_CHAP_PASSWORD > +set /files/etc/default/ovirt/OVIRT_ISCSI_CHAP_USERNAME $OVIRT_ISCSI_CHAP_USERNAME > +set /files/etc/default/ovirt/OVIRT_ISCSI_CHAP_PASSWORD $OVIRT_ISCSI_CHAP_PASSWORD > +EOF > + fi > + > + iscsiadm -p $OVIRT_ISCSI_TARGET_IP:$OVIRT_ISCSI_TARGET_PORT -m discovery -t sendtargets > + log "Restarting iscsi service" > + service iscsi restart > + > +ISCSI_NODE_NAMES="$(iscsiadm -m discovery -p $OVIRT_ISCSI_TARGET_IP:$OVIRT_ISCSI_TARGET_PORT -t sendtargets|awk {'print $2'})" > + > +printf "\n\n Select iSCSI target node\n\n">&2 > +select OVIRT_ISCSI_NODE_NAME in $ISCSI_NODE_NAMES ; do > +log " Selected Node Name: $OVIRT_ISCSI_NODE_NAME" > +break; > +done > + > +augtool< +set /files/etc/default/ovirt/OVIRT_ISCSI_ENABLED y > +set /files/etc/default/ovirt/OVIRT_ISCSI_TARGET_IP $OVIRT_ISCSI_TARGET_IP > +set /files/etc/default/ovirt/OVIRT_ISCSI_TARGET_PORT $OVIRT_ISCSI_TARGET_PORT > +set /files/etc/default/ovirt/OVIRT_ISCSI_NODE_NAME $OVIRT_ISCSI_NODE_NAME > +EOF > +break; > +fi > +done > +} > + > MEM_SIZE_MB=$(awk '/MemTotal:/ { print $2 }' /proc/meminfo) > case $MEM_SIZE_MB in > ''|*[^0-9]*) die failed to get system memory size;; > @@ -527,6 +653,7 @@ fi > > CALC_SWAP_SIZE=$(echo "scale=0; ${BASE_SWAP_SIZE} + ${OVERCOMMIT_SWAP_SIZE};" | bc -l) > > +BOOT_SIZE=${OVIRT_VOL_BOOT_SIZE:-$default_boot_size} > SWAP_SIZE=${OVIRT_VOL_SWAP_SIZE:-$CALC_SWAP_SIZE} > ROOT_SIZE=${OVIRT_VOL_ROOT_SIZE:-$default_root_size} > CONFIG_SIZE=${OVIRT_VOL_CONFIG_SIZE:-$default_config_size} > @@ -577,6 +704,7 @@ else > select OPTION in "$@" > do > case "$OPTION" in > + "Enable iSCSI Target") do_iscsi_target; break ;; > "Configure Storage") do_configure ; break ;; > "Review") do_review ; break ;; > "Commit Changes And Quit") do_confirm ; break ;; > diff --git a/scripts/ovirt-functions b/scripts/ovirt-functions > index 7cf8613..7cd9c81 100644 > --- a/scripts/ovirt-functions > +++ b/scripts/ovirt-functions > @@ -304,6 +304,14 @@ mount_config() { > fi > } > > +mount_boot() { > + > + if grep -q " /boot " /etc/mtab; then > + return 0 > + fi > + mkdir -p /boot > + mount /dev/disk/by-label/Boot /boot > +} > # stop any service which keeps /var/log busy > # keep the list of services > unmount_logging_services() { > This also fixes the live booting option in grub for dracut with the node-images. Just building and running a normal install to "local storage" that doesn't fail is the expected result for now. From dpierce at redhat.com Tue Dec 8 21:13:52 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Tue, 8 Dec 2009 16:13:52 -0500 Subject: [Ovirt-devel] Rebased patches, fixed a rebasing problem... Message-ID: <1260306834-32625-1-git-send-email-dpierce@redhat.com> The previous patch set had an error and one development branch's changes showed up twice, and two different change sets. So it was missing the bulk of the configuration work. This patch set fixes that. From dpierce at redhat.com Tue Dec 8 21:13:53 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Tue, 8 Dec 2009 16:13:53 -0500 Subject: [Ovirt-devel] [PATCH 1/2] Users can now work with remote libvirt hosts. In-Reply-To: <1260306834-32625-1-git-send-email-dpierce@redhat.com> References: <1260306834-32625-1-git-send-email-dpierce@redhat.com> Message-ID: <1260306834-32625-2-git-send-email-dpierce@redhat.com> The user can: * select a remote machine * add a remote machine * remove a remote machine Signed-off-by: Darryl L. Pierce --- ...rs-can-now-work-with-remote-libvirt-hosts.patch | 628 ++++++++++++++++++++ ...rs-to-migrate-virtual-machines-between-ho.patch | 253 ++++++++ Makefile.am | 5 + nodeadmin/addhost.py | 129 ++++ nodeadmin/changehost.py | 58 ++ nodeadmin/configscreen.py | 36 ++- nodeadmin/definenet.py | 1 + nodeadmin/hostconnect.py | 29 + nodeadmin/hostmenu.py | 46 ++ nodeadmin/libvirtworker.py | 53 ++- nodeadmin/mainmenu.py | 24 +- nodeadmin/removehost.py | 66 ++ ovirt-node.spec.in | 5 + 13 files changed, 1320 insertions(+), 13 deletions(-) create mode 100644 0001-Users-can-now-work-with-remote-libvirt-hosts.patch create mode 100644 0002-Enables-users-to-migrate-virtual-machines-between-ho.patch create mode 100644 nodeadmin/addhost.py create mode 100644 nodeadmin/changehost.py create mode 100644 nodeadmin/hostconnect.py create mode 100644 nodeadmin/hostmenu.py create mode 100644 nodeadmin/removehost.py diff --git a/0001-Users-can-now-work-with-remote-libvirt-hosts.patch b/0001-Users-can-now-work-with-remote-libvirt-hosts.patch new file mode 100644 index 0000000..a6c2342 --- /dev/null +++ b/0001-Users-can-now-work-with-remote-libvirt-hosts.patch @@ -0,0 +1,628 @@ +From f4bd14953ef3ff1335b6980563ebbf64cb97153a Mon Sep 17 00:00:00 2001 +From: Darryl L. Pierce +Date: Wed, 28 Oct 2009 16:29:53 -0400 +Subject: [PATCH 1/2] Users can now work with remote libvirt hosts. + +The user can: + * select a remote machine + * add a remote machine + * remove a remote machine +--- + Makefile.am | 5 ++ + nodeadmin/addhost.py | 129 ++++++++++++++++++++++++++++++++++++++++++++ + nodeadmin/changehost.py | 58 ++++++++++++++++++++ + nodeadmin/configscreen.py | 36 ++++++++++++- + nodeadmin/definenet.py | 1 + + nodeadmin/hostconnect.py | 29 ++++++++++ + nodeadmin/hostmenu.py | 46 ++++++++++++++++ + nodeadmin/libvirtworker.py | 53 +++++++++++++++++- + nodeadmin/mainmenu.py | 14 +++-- + nodeadmin/removehost.py | 66 ++++++++++++++++++++++ + ovirt-node.spec.in | 5 ++ + 11 files changed, 434 insertions(+), 8 deletions(-) + create mode 100644 nodeadmin/addhost.py + create mode 100644 nodeadmin/changehost.py + create mode 100644 nodeadmin/hostconnect.py + create mode 100644 nodeadmin/hostmenu.py + create mode 100644 nodeadmin/removehost.py + +diff --git a/Makefile.am b/Makefile.am +index b3929de..1671405 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -28,11 +28,15 @@ EXTRA_DIST = \ + images/syslinux-vesa-splash.jpg \ + nodeadmin/__init__.py \ + nodeadmin/adddomain.py \ ++ nodeadmin/addhost.py \ ++ nodeadmin/changehost.py \ + nodeadmin/configscreen.py \ + nodeadmin/createnetwork.py \ + nodeadmin/createuser.py \ + nodeadmin/destroynetwork.py \ + nodeadmin/halworker.py \ ++ nodeadmin/hostconnect.py \ ++ nodeadmin/hostmenu.py \ + nodeadmin/libvirtworker.py \ + nodeadmin/userworker.py \ + nodeadmin/mainmenu.py \ +@@ -40,6 +44,7 @@ EXTRA_DIST = \ + nodeadmin/netmenu.py \ + nodeadmin/nodemenu.py \ + nodeadmin/removedomain.py \ ++ nodeadmin/removehost.py \ + nodeadmin/undefinenetwork.py \ + nodeadmin/startdomain.py \ + nodeadmin/stopdomain.py \ +diff --git a/nodeadmin/addhost.py b/nodeadmin/addhost.py +new file mode 100644 +index 0000000..ef35b7d +--- /dev/null ++++ b/nodeadmin/addhost.py +@@ -0,0 +1,129 @@ ++# addhost.py - Copyright (C) 2009 Red Hat, Inc. ++# Written by Darryl L. Pierce ++# ++# 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 configscreen import * ++ ++DETAILS_PAGE = 1 ++CONFIRM_PAGE = 2 ++ ++HYPERVISOR_XEN = "xen" ++HYPERVISOR_KVM = "kvm" ++ ++HYPERVISORS = {HYPERVISOR_XEN : "Xen", ++ HYPERVISOR_KVM : "QEMU/KVM"} ++ ++CONNECTION_LOCAL = "local" ++CONNECTION_KERBEROS = "kerberos" ++CONNECTION_SSL = "ssl" ++CONNECTION_SSH = "ssh" ++ ++CONNECTIONS = {CONNECTION_LOCAL : "Local", ++ CONNECTION_KERBEROS : "Remote Password or Kerberos", ++ CONNECTION_SSL : "Remote SSL/TLS with x509 certificate", ++ CONNECTION_SSH : "Remote tunnel over SSH"} ++ ++class AddHostConfigScreen(ConfigScreen): ++ def __init__(self): ++ ConfigScreen.__init__(self, "Add A Remote Host") ++ self.__configured = False ++ ++ def get_elements_for_page(self, screen, page): ++ if page is DETAILS_PAGE: return self.get_details_page(screen) ++ elif page is CONFIRM_PAGE: return self.get_confirm_page(screen) ++ ++ def page_has_next(self, page): ++ return page < CONFIRM_PAGE ++ ++ def page_has_back(self, page): ++ return page > DETAILS_PAGE ++ ++ def page_has_finish(self, page): ++ return page is CONFIRM_PAGE ++ ++ def validate_input(self, page, errors): ++ if page is DETAILS_PAGE: ++ if len(self.__hostname.value()) > 0: ++ return True ++ else: ++ errors.append("You must enter a remote hostname.") ++ elif page is CONFIRM_PAGE: return True ++ return False ++ ++ def process_input(self, page): ++ if page is CONFIRM_PAGE: ++ hv = self.__hypervisor.getSelection() ++ conn = self.__connection.getSelection() ++ hostname = self.__hostname.value() ++ ++ if hv is HYPERVISOR_XEN: ++ if conn is CONNECTION_LOCAL: url = "xen:///" ++ elif conn is CONNECTION_KERBEROS: url = "xen+tcp:///" + hostname + "/" ++ elif conn is CONNECTION_SSL: url = "xen+tls:///" + hostname + "/" ++ elif conn is CONNECTION_SSH: url = "xen+ssh:///" + hostname + "/" ++ elif hv is HYPERVISOR_KVM: ++ if conn is CONNECTION_LOCAL: url = "qemu:///system" ++ elif conn is CONNECTION_KERBEROS: url = "qemu+tcp://" + hostname + "/system" ++ elif conn is CONNECTION_SSL: url = "qemu+tls://" + hostname + "/system" ++ elif conn is CONNECTION_SSH: url = "qemu+ssh://" + hostname + "/system" ++ ++ self.get_virt_manager_config().add_connection(url) ++ self.set_finished() ++ ++ def get_details_page(self, screen): ++ if not self.__configured: ++ self.__hypervisor = RadioBar(screen, ((HYPERVISORS[HYPERVISOR_XEN], HYPERVISOR_XEN, True), ++ (HYPERVISORS[HYPERVISOR_KVM], HYPERVISOR_KVM, False))) ++ self.__connection = RadioBar(screen, ((CONNECTIONS[CONNECTION_LOCAL], CONNECTION_LOCAL, True), ++ (CONNECTIONS[CONNECTION_KERBEROS], CONNECTION_KERBEROS, False), ++ (CONNECTIONS[CONNECTION_SSL], CONNECTION_SSL, False), ++ (CONNECTIONS[CONNECTION_SSH], CONNECTION_SSH, False))) ++ self.__hostname = Entry(50, "") ++ self.__autoconnect = Checkbox("Autoconnect on Startup") ++ self.__configured = True ++ grid = Grid(2, 4) ++ grid.setField(Label("Hypervisor:"), 0, 0, anchorRight = 1, anchorTop = 1) ++ grid.setField(self.__hypervisor, 1, 0, anchorLeft = 1) ++ grid.setField(Label("Connection:"), 0, 1, anchorRight = 1, anchorTop = 1) ++ grid.setField(self.__connection, 1, 1, anchorLeft = 1) ++ grid.setField(Label("Hostname:"), 0, 2, anchorRight = 1) ++ grid.setField(self.__hostname, 1, 2, anchorLeft = 1) ++ grid.setField(Label(""), 0, 3, anchorRight = 1) ++ grid.setField(self.__autoconnect, 1, 3, anchorLeft = 1) ++ return [Label("Add Connection"), ++ grid] ++ ++ def get_confirm_page(self, screen): ++ grid = Grid(2, 4) ++ grid.setField(Label("Hypervisor:"), 0, 0, anchorRight = 1) ++ 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) ++ grid.setField(Label("Hostname:"), 0, 2, anchorRight = 1) ++ grid.setField(Label(self.__hostname.value()), 1, 2, anchorLeft = 1) ++ grid.setField(Label("Autoconnect on Startup:"), 0, 3, anchorRight = 1) ++ label = "Yes" ++ if not self.__autoconnect.value(): label = "No" ++ grid.setField(Label(label), 1, 3, anchorLeft = 1) ++ return [Label("Confirm Connection"), ++ grid] ++ ++def AddHost(): ++ screen = AddHostConfigScreen() ++ screen.start() +diff --git a/nodeadmin/changehost.py b/nodeadmin/changehost.py +new file mode 100644 +index 0000000..23e6854 +--- /dev/null ++++ b/nodeadmin/changehost.py +@@ -0,0 +1,58 @@ ++# changehost.py - Copyright (C) 2009 Red Hat, Inc. ++# Written by Darryl L. Pierce ++# ++# 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 * ++ ++import logging ++import libvirtworker ++from configscreen import * ++ ++CONNECTION_LIST_PAGE = 1 ++CONNECTED_PAGE = 2 ++ ++class ChangeHostConfigScreen(HostListConfigScreen): ++ def __init__(self): ++ HostListConfigScreen.__init__(self, "Change Host") ++ ++ def get_elements_for_page(self, screen, page): ++ if page is CONNECTION_LIST_PAGE: return self.get_connection_list_page(screen) ++ elif page is CONNECTED_PAGE: return self.get_connected_page(screen) ++ ++ def process_input(self, page): ++ if page is CONNECTION_LIST_PAGE: ++ logging.info("Changing libvirt connection to %s" % self.get_selected_connection()) ++ libvirtworker.set_default_url(self.get_selected_connection()) ++ self.get_libvirt().open_connection(self.get_selected_connection()) ++ elif page is CONNECTED_PAGE: self.set_finished() ++ ++ def page_has_next(self, page): ++ if page is CONNECTION_LIST_PAGE: return self.has_selectable_connections() ++ return False ++ ++ def page_has_back(self, page): ++ return page > CONNECTION_LIST_PAGE ++ ++ def page_has_finish(self, page): ++ return page is CONNECTED_PAGE ++ ++ def get_connected_page(self, screen): ++ return [Label("Connected to %s" % self.get_selected_connection())] ++ ++def ChangeHost(): ++ screen = ChangeHostConfigScreen() ++ screen.start() +diff --git a/nodeadmin/configscreen.py b/nodeadmin/configscreen.py +index f214aea..98e0338 100644 +--- a/nodeadmin/configscreen.py ++++ b/nodeadmin/configscreen.py +@@ -18,7 +18,7 @@ + + from snack import * + from halworker import HALWorker +-from libvirtworker import LibvirtWorker ++from libvirtworker import * + import traceback + + BACK_BUTTON = "back" +@@ -35,6 +35,7 @@ class ConfigScreen: + self.__finished = False + self.__hal = HALWorker() + self.__libvirt = LibvirtWorker() ++ self.__vm_config = VirtManagerConfig() + + def get_hal(self): + return self.__hal +@@ -42,6 +43,9 @@ class ConfigScreen: + def get_libvirt(self): + return self.__libvirt + ++ def get_virt_manager_config(self): ++ return self.__vm_config ++ + def set_finished(self): + self.__finished = True + +@@ -179,3 +183,33 @@ class NetworkListConfigScreen(ConfigScreen): + + def has_selectable_networks(self): + return self.__has_networks ++ ++class HostListConfigScreen(ConfigScreen): ++ '''Provides a base class for working with lists of libvirt hosts.''' ++ ++ def __init__(self, title): ++ ConfigScreen.__init__(self, title) ++ ++ def get_connection_list_page(self, screen): ++ connections = self.get_virt_manager_config().get_connection_list() ++ result = None ++ ++ if len(connections) > 0: ++ self.__has_connections = True ++ self.__connection_list = Listbox(0) ++ for connection in connections: ++ self.__connection_list.append(connection, connection) ++ result = self.__connection_list ++ else: ++ self.__has_connections = False ++ result = Label("There are no defined connections.") ++ grid = Grid(1, 1) ++ grid.setField(result, 0, 0) ++ return [Label("Host List"), ++ grid] ++ ++ def get_selected_connection(self): ++ return self.__connection_list.current() ++ ++ def has_selectable_connections(self): ++ return self.__has_connections +diff --git a/nodeadmin/definenet.py b/nodeadmin/definenet.py +index 4aa37d5..6dff18f 100644 +--- a/nodeadmin/definenet.py ++++ b/nodeadmin/definenet.py +@@ -20,6 +20,7 @@ from snack import * + from IPy import IP + import traceback + import logging ++import re + + from configscreen import ConfigScreen + from networkconfig import NetworkConfig +diff --git a/nodeadmin/hostconnect.py b/nodeadmin/hostconnect.py +new file mode 100644 +index 0000000..a1be569 +--- /dev/null ++++ b/nodeadmin/hostconnect.py +@@ -0,0 +1,29 @@ ++# hostconnect.py - Copyright (C) 2009 Red Hat, Inc. ++# Written by Darryl L. Pierce ++# ++# 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 configscreen import * ++ ++class HostConnectConfigScreen(ConfigScreen): ++ def __init__(self): ++ ConfigScree ++ ++def HostConnect(): ++ screen = HostConnectConfigScreen() ++ screen.start() +diff --git a/nodeadmin/hostmenu.py b/nodeadmin/hostmenu.py +new file mode 100644 +index 0000000..4054d6b +--- /dev/null ++++ b/nodeadmin/hostmenu.py +@@ -0,0 +1,46 @@ ++# hostmenu.py - Copyright (C) 2009 Red Hat, Inc. ++# Written by Darryl L. Pierce ++# ++# 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 menuscreen import MenuScreen ++from changehost import ChangeHost ++from addhost import AddHost ++from removehost import RemoveHost ++ ++SELECT_HOST = 1 ++ADD_HOST = 2 ++REMOVE_HOST = 3 ++ ++class HostMenuScreen(MenuScreen): ++ def __init__(self): ++ MenuScreen.__init__(self, "Host Menu Screen") ++ ++ def get_menu_items(self): ++ return (("Select A Host", SELECT_HOST), ++ ("Add A Host", ADD_HOST), ++ ("Remove A Host", REMOVE_HOST)) ++ ++ def handle_selection(self, item): ++ if item is SELECT_HOST: ChangeHost() ++ elif item is ADD_HOST: AddHost() ++ elif item is REMOVE_HOST: RemoveHost() ++ ++def HostMenu(): ++ screen = HostMenuScreen() ++ screen.start() +diff --git a/nodeadmin/libvirtworker.py b/nodeadmin/libvirtworker.py +index ba07605..2998486 100644 +--- a/nodeadmin/libvirtworker.py ++++ b/nodeadmin/libvirtworker.py +@@ -21,20 +21,69 @@ import libvirt + import os + import virtinst + import utils ++import logging + + from domainconfig import DomainConfig + + DEFAULT_POOL_TARGET_PATH="/var/lib/libvirt/images" ++DEFAULT_URL="qemu:///system" ++ ++default_url = DEFAULT_URL ++ ++def set_default_url(url): ++ logging.info("Changing DEFAULT_URL to %s" % url) ++ global default_url ++ ++ default_url = url ++ ++def get_default_url(): ++ logging.info("Returning default URL of %s" % default_url) ++ return default_url ++ ++class VirtManagerConfig: ++ def __init__(self, filename = "/etc/remote-libvirt.conf"): ++ self.__filename = filename ++ ++ def get_connection_list(self): ++ result = [] ++ if os.path.exists(self.__filename): ++ input = file(self.__filename, "r") ++ for entry in input: result.append(entry[0:-1]) ++ return result ++ ++ def add_connection(self, connection): ++ connections = self.get_connection_list() ++ if connections.count(connection) is 0: ++ connections.append(connection) ++ self._save_connections(connections) ++ ++ def remove_connection(self, connection): ++ connections = self.get_connection_list() ++ if connections.count(connection) > 0: ++ connections.remove(connection) ++ self._save_connections(connections) ++ ++ def _save_connections(self, connections): ++ output = file(self.__filename, "w") ++ for entry in connections: ++ print >> output, entry ++ output.close + + class LibvirtWorker: + '''Provides utilities for interfacing with libvirt.''' +- def __init__(self, url = "qemu:///system"): +- self.__conn = libvirt.open(url) ++ def __init__(self, url = None): ++ if url is None: url = get_default_url() ++ logging.info("Connecting to libvirt: %s" % url) ++ self.open_connection(url) + self.__capabilities = virtinst.CapabilitiesParser.parse(self.__conn.getCapabilities()) + self.__net = virtinst.VirtualNetworkInterface(conn = self.__conn) + self.__net.setup(self.__conn) + (self.__new_guest, self.__new_domain) = virtinst.CapabilitiesParser.guest_lookup(conn = self.__conn) + ++ def open_connection(self, url): ++ '''Lets the user change the url for the connection.''' ++ self.__conn = libvirt.open(url) ++ + def list_domains(self, defined = True, started = True): + '''Lists all domains.''' + result = [] +diff --git a/nodeadmin/mainmenu.py b/nodeadmin/mainmenu.py +index 73501fa..944ffeb 100755 +--- a/nodeadmin/mainmenu.py ++++ b/nodeadmin/mainmenu.py +@@ -19,15 +19,17 @@ + from snack import * + import traceback + +-from menuscreen import MenuScreen +-from nodemenu import NodeMenu +-from netmenu import NetworkMenu ++from menuscreen import MenuScreen ++from nodemenu import NodeMenu ++from netmenu import NetworkMenu ++from hostmenu import HostMenu + + import utils + import logging + + NODE_MENU = 1 + NETWORK_MENU = 2 ++HOST_MENU = 3 + EXIT_CONSOLE = 99 + + class MainMenuScreen(MenuScreen): +@@ -35,12 +37,14 @@ class MainMenuScreen(MenuScreen): + MenuScreen.__init__(self, "Main Menu") + + def get_menu_items(self): +- return (("Node Administration", NODE_MENU), +- ("Network Administration", NETWORK_MENU)) ++ return (("Node Administration", NODE_MENU), ++ ("Network Administration", NETWORK_MENU), ++ ("Host Administration", HOST_MENU)) + + def handle_selection(self, page): + if page is NODE_MENU: NodeMenu() + elif page is NETWORK_MENU: NetworkMenu() ++ elif page is HOST_MENU: HostMenu() + + def MainMenu(): + screen = MainMenuScreen() +diff --git a/nodeadmin/removehost.py b/nodeadmin/removehost.py +new file mode 100644 +index 0000000..cf3c46c +--- /dev/null ++++ b/nodeadmin/removehost.py +@@ -0,0 +1,66 @@ ++# removehost.py - Copyright (C) 2009 Red Hat, Inc. ++# Written by Darryl L. Pierce ++# ++# 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 configscreen import * ++ ++SELECT_HOST_PAGE = 1 ++CONFIRM_REMOVE_PAGE = 2 ++ ++class RemoveHostConfigScreen(HostListConfigScreen): ++ def __init__(self): ++ HostListConfigScreen.__init__(self, "Remove Host Connection") ++ ++ def get_elements_for_page(self, screen, page): ++ if page is SELECT_HOST_PAGE: return self.get_connection_list_page(screen) ++ elif page is CONFIRM_REMOVE_PAGE: return self.get_confirm_remove_page(screen) ++ ++ def page_has_next(self, page): ++ return page is SELECT_HOST_PAGE and self.has_selectable_connections() ++ ++ def page_has_back(self, page): ++ return page is CONFIRM_REMOVE_PAGE ++ ++ def page_has_finish(self, page): ++ return page is CONFIRM_REMOVE_PAGE ++ ++ def validate_input(self, page, errors): ++ if page is SELECT_HOST_PAGE: return True ++ elif page is CONFIRM_REMOVE_PAGE: ++ if self.__confirm.value(): ++ return True ++ else: ++ errors.append("You must confirm removing the connection.") ++ return False ++ ++ def process_input(self, page): ++ if page is CONFIRM_REMOVE_PAGE: ++ self.get_virt_manager_config().remove_connection(self.get_selected_connection()) ++ self.set_finished() ++ ++ def get_confirm_remove_page(self, screen): ++ self.__confirm = Checkbox("Remove this connection: %s" % self.get_selected_connection(), 0) ++ grid = Grid(1, 1) ++ grid.setField(self.__confirm, 0, 0) ++ return [Label("Remove Host Connection"), ++ grid] ++ ++def RemoveHost(): ++ screen = RemoveHostConfigScreen() ++ screen.start() +diff --git a/ovirt-node.spec.in b/ovirt-node.spec.in +index 56e3aad..23ca2bf 100644 +--- a/ovirt-node.spec.in ++++ b/ovirt-node.spec.in +@@ -198,6 +198,11 @@ cd - + %{__install} -p -m0755 nodeadmin/destroynetwork.py %{buildroot}%{python_sitelib}/nodeadmin + %{__install} -p -m0755 nodeadmin/undefinenetwork.py %{buildroot}%{python_sitelib}/nodeadmin + ++%{__install} -p -m0755 nodeadmin/addhost.py %{buildroot}%{python_sitelib}/nodeadmin ++%{__install} -p -m0644 nodeadmin/changehost.py %{buildroot}%{python_sitelib}/nodeadmin ++%{__install} -p -m0755 nodeadmin/hostmenu.py %{buildroot}%{python_sitelib}/nodeadmin ++%{__install} -p -m0755 nodeadmin/removehost.py %{buildroot}%{python_sitelib}/nodeadmin ++ + %{__install} -p -m0755 nodeadmin/createuser.py %{buildroot}%{python_sitelib}/nodeadmin + + %{__install} -p -m0644 nodeadmin/halworker.py %{buildroot}%{python_sitelib}/nodeadmin +-- +1.6.5.2 + diff --git a/0002-Enables-users-to-migrate-virtual-machines-between-ho.patch b/0002-Enables-users-to-migrate-virtual-machines-between-ho.patch new file mode 100644 index 0000000..a56ce52 --- /dev/null +++ b/0002-Enables-users-to-migrate-virtual-machines-between-ho.patch @@ -0,0 +1,253 @@ +From c565f28b25bd6b77b6a61ce92c2c70248f08130d Mon Sep 17 00:00:00 2001 +From: Darryl L. Pierce +Date: Wed, 11 Nov 2009 10:51:23 -0500 +Subject: [PATCH 2/2] Enables users to migrate virtual machines between hosts. + +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 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 ++# ++# 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 + diff --git a/Makefile.am b/Makefile.am index de3bd18..e673aa4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -28,8 +28,10 @@ EXTRA_DIST = \ images/syslinux-vesa-splash.jpg \ nodeadmin/__init__.py \ nodeadmin/adddomain.py \ + nodeadmin/addhost.py \ nodeadmin/addpool.py \ nodeadmin/addvolume.py \ + nodeadmin/changehost.py \ nodeadmin/configscreen.py \ nodeadmin/createmeter.py \ nodeadmin/createnetwork.py \ @@ -38,6 +40,8 @@ EXTRA_DIST = \ nodeadmin/destroynetwork.py \ nodeadmin/domainconfig.py \ nodeadmin/halworker.py \ + nodeadmin/hostconnect.py \ + nodeadmin/hostmenu.py \ nodeadmin/libvirtworker.py \ nodeadmin/listdomains.py \ nodeadmin/listnetworks.py \ @@ -50,6 +54,7 @@ EXTRA_DIST = \ nodeadmin/nodemenu.py \ nodeadmin/poolconfig.py \ nodeadmin/removedomain.py \ + nodeadmin/removehost.py \ nodeadmin/removepool.py \ nodeadmin/removevolume.py \ nodeadmin/startdomain.py \ diff --git a/nodeadmin/addhost.py b/nodeadmin/addhost.py new file mode 100644 index 0000000..ef35b7d --- /dev/null +++ b/nodeadmin/addhost.py @@ -0,0 +1,129 @@ +# addhost.py - Copyright (C) 2009 Red Hat, Inc. +# Written by Darryl L. Pierce +# +# 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 configscreen import * + +DETAILS_PAGE = 1 +CONFIRM_PAGE = 2 + +HYPERVISOR_XEN = "xen" +HYPERVISOR_KVM = "kvm" + +HYPERVISORS = {HYPERVISOR_XEN : "Xen", + HYPERVISOR_KVM : "QEMU/KVM"} + +CONNECTION_LOCAL = "local" +CONNECTION_KERBEROS = "kerberos" +CONNECTION_SSL = "ssl" +CONNECTION_SSH = "ssh" + +CONNECTIONS = {CONNECTION_LOCAL : "Local", + CONNECTION_KERBEROS : "Remote Password or Kerberos", + CONNECTION_SSL : "Remote SSL/TLS with x509 certificate", + CONNECTION_SSH : "Remote tunnel over SSH"} + +class AddHostConfigScreen(ConfigScreen): + def __init__(self): + ConfigScreen.__init__(self, "Add A Remote Host") + self.__configured = False + + def get_elements_for_page(self, screen, page): + if page is DETAILS_PAGE: return self.get_details_page(screen) + elif page is CONFIRM_PAGE: return self.get_confirm_page(screen) + + def page_has_next(self, page): + return page < CONFIRM_PAGE + + def page_has_back(self, page): + return page > DETAILS_PAGE + + def page_has_finish(self, page): + return page is CONFIRM_PAGE + + def validate_input(self, page, errors): + if page is DETAILS_PAGE: + if len(self.__hostname.value()) > 0: + return True + else: + errors.append("You must enter a remote hostname.") + elif page is CONFIRM_PAGE: return True + return False + + def process_input(self, page): + if page is CONFIRM_PAGE: + hv = self.__hypervisor.getSelection() + conn = self.__connection.getSelection() + hostname = self.__hostname.value() + + if hv is HYPERVISOR_XEN: + if conn is CONNECTION_LOCAL: url = "xen:///" + elif conn is CONNECTION_KERBEROS: url = "xen+tcp:///" + hostname + "/" + elif conn is CONNECTION_SSL: url = "xen+tls:///" + hostname + "/" + elif conn is CONNECTION_SSH: url = "xen+ssh:///" + hostname + "/" + elif hv is HYPERVISOR_KVM: + if conn is CONNECTION_LOCAL: url = "qemu:///system" + elif conn is CONNECTION_KERBEROS: url = "qemu+tcp://" + hostname + "/system" + elif conn is CONNECTION_SSL: url = "qemu+tls://" + hostname + "/system" + elif conn is CONNECTION_SSH: url = "qemu+ssh://" + hostname + "/system" + + self.get_virt_manager_config().add_connection(url) + self.set_finished() + + def get_details_page(self, screen): + if not self.__configured: + self.__hypervisor = RadioBar(screen, ((HYPERVISORS[HYPERVISOR_XEN], HYPERVISOR_XEN, True), + (HYPERVISORS[HYPERVISOR_KVM], HYPERVISOR_KVM, False))) + self.__connection = RadioBar(screen, ((CONNECTIONS[CONNECTION_LOCAL], CONNECTION_LOCAL, True), + (CONNECTIONS[CONNECTION_KERBEROS], CONNECTION_KERBEROS, False), + (CONNECTIONS[CONNECTION_SSL], CONNECTION_SSL, False), + (CONNECTIONS[CONNECTION_SSH], CONNECTION_SSH, False))) + self.__hostname = Entry(50, "") + self.__autoconnect = Checkbox("Autoconnect on Startup") + self.__configured = True + grid = Grid(2, 4) + grid.setField(Label("Hypervisor:"), 0, 0, anchorRight = 1, anchorTop = 1) + grid.setField(self.__hypervisor, 1, 0, anchorLeft = 1) + grid.setField(Label("Connection:"), 0, 1, anchorRight = 1, anchorTop = 1) + grid.setField(self.__connection, 1, 1, anchorLeft = 1) + grid.setField(Label("Hostname:"), 0, 2, anchorRight = 1) + grid.setField(self.__hostname, 1, 2, anchorLeft = 1) + grid.setField(Label(""), 0, 3, anchorRight = 1) + grid.setField(self.__autoconnect, 1, 3, anchorLeft = 1) + return [Label("Add Connection"), + grid] + + def get_confirm_page(self, screen): + grid = Grid(2, 4) + grid.setField(Label("Hypervisor:"), 0, 0, anchorRight = 1) + 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) + grid.setField(Label("Hostname:"), 0, 2, anchorRight = 1) + grid.setField(Label(self.__hostname.value()), 1, 2, anchorLeft = 1) + grid.setField(Label("Autoconnect on Startup:"), 0, 3, anchorRight = 1) + label = "Yes" + if not self.__autoconnect.value(): label = "No" + grid.setField(Label(label), 1, 3, anchorLeft = 1) + return [Label("Confirm Connection"), + grid] + +def AddHost(): + screen = AddHostConfigScreen() + screen.start() diff --git a/nodeadmin/changehost.py b/nodeadmin/changehost.py new file mode 100644 index 0000000..23e6854 --- /dev/null +++ b/nodeadmin/changehost.py @@ -0,0 +1,58 @@ +# changehost.py - Copyright (C) 2009 Red Hat, Inc. +# Written by Darryl L. Pierce +# +# 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 * + +import logging +import libvirtworker +from configscreen import * + +CONNECTION_LIST_PAGE = 1 +CONNECTED_PAGE = 2 + +class ChangeHostConfigScreen(HostListConfigScreen): + def __init__(self): + HostListConfigScreen.__init__(self, "Change Host") + + def get_elements_for_page(self, screen, page): + if page is CONNECTION_LIST_PAGE: return self.get_connection_list_page(screen) + elif page is CONNECTED_PAGE: return self.get_connected_page(screen) + + def process_input(self, page): + if page is CONNECTION_LIST_PAGE: + logging.info("Changing libvirt connection to %s" % self.get_selected_connection()) + libvirtworker.set_default_url(self.get_selected_connection()) + self.get_libvirt().open_connection(self.get_selected_connection()) + elif page is CONNECTED_PAGE: self.set_finished() + + def page_has_next(self, page): + if page is CONNECTION_LIST_PAGE: return self.has_selectable_connections() + return False + + def page_has_back(self, page): + return page > CONNECTION_LIST_PAGE + + def page_has_finish(self, page): + return page is CONNECTED_PAGE + + def get_connected_page(self, screen): + return [Label("Connected to %s" % self.get_selected_connection())] + +def ChangeHost(): + screen = ChangeHostConfigScreen() + screen.start() diff --git a/nodeadmin/configscreen.py b/nodeadmin/configscreen.py index 7654697..02ab5b4 100644 --- a/nodeadmin/configscreen.py +++ b/nodeadmin/configscreen.py @@ -18,7 +18,7 @@ from snack import * from halworker import HALWorker -from libvirtworker import LibvirtWorker +from libvirtworker import * import traceback BACK_BUTTON = "back" @@ -35,6 +35,7 @@ class ConfigScreen: self.__finished = False self.__hal = HALWorker() self.__libvirt = LibvirtWorker() + self.__vm_config = VirtManagerConfig() def get_hal(self): return self.__hal @@ -42,6 +43,9 @@ class ConfigScreen: def get_libvirt(self): return self.__libvirt + def get_virt_manager_config(self): + return self.__vm_config + def set_finished(self): self.__finished = True @@ -231,3 +235,33 @@ class StorageListConfigScreen(ConfigScreen): def has_selectable_volumes(self): return self.__has_volumes + +class HostListConfigScreen(ConfigScreen): + '''Provides a base class for working with lists of libvirt hosts.''' + + def __init__(self, title): + ConfigScreen.__init__(self, title) + + def get_connection_list_page(self, screen): + connections = self.get_virt_manager_config().get_connection_list() + result = None + + if len(connections) > 0: + self.__has_connections = True + self.__connection_list = Listbox(0) + for connection in connections: + self.__connection_list.append(connection, connection) + result = self.__connection_list + else: + self.__has_connections = False + result = Label("There are no defined connections.") + grid = Grid(1, 1) + grid.setField(result, 0, 0) + return [Label("Host List"), + grid] + + def get_selected_connection(self): + return self.__connection_list.current() + + def has_selectable_connections(self): + return self.__has_connections diff --git a/nodeadmin/definenet.py b/nodeadmin/definenet.py index 4aa37d5..6dff18f 100644 --- a/nodeadmin/definenet.py +++ b/nodeadmin/definenet.py @@ -20,6 +20,7 @@ from snack import * from IPy import IP import traceback import logging +import re from configscreen import ConfigScreen from networkconfig import NetworkConfig diff --git a/nodeadmin/hostconnect.py b/nodeadmin/hostconnect.py new file mode 100644 index 0000000..a1be569 --- /dev/null +++ b/nodeadmin/hostconnect.py @@ -0,0 +1,29 @@ +# hostconnect.py - Copyright (C) 2009 Red Hat, Inc. +# Written by Darryl L. Pierce +# +# 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 configscreen import * + +class HostConnectConfigScreen(ConfigScreen): + def __init__(self): + ConfigScree + +def HostConnect(): + screen = HostConnectConfigScreen() + screen.start() diff --git a/nodeadmin/hostmenu.py b/nodeadmin/hostmenu.py new file mode 100644 index 0000000..4054d6b --- /dev/null +++ b/nodeadmin/hostmenu.py @@ -0,0 +1,46 @@ +# hostmenu.py - Copyright (C) 2009 Red Hat, Inc. +# Written by Darryl L. Pierce +# +# 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 menuscreen import MenuScreen +from changehost import ChangeHost +from addhost import AddHost +from removehost import RemoveHost + +SELECT_HOST = 1 +ADD_HOST = 2 +REMOVE_HOST = 3 + +class HostMenuScreen(MenuScreen): + def __init__(self): + MenuScreen.__init__(self, "Host Menu Screen") + + def get_menu_items(self): + return (("Select A Host", SELECT_HOST), + ("Add A Host", ADD_HOST), + ("Remove A Host", REMOVE_HOST)) + + def handle_selection(self, item): + if item is SELECT_HOST: ChangeHost() + elif item is ADD_HOST: AddHost() + elif item is REMOVE_HOST: RemoveHost() + +def HostMenu(): + screen = HostMenuScreen() + screen.start() diff --git a/nodeadmin/libvirtworker.py b/nodeadmin/libvirtworker.py index f31266c..15d1c58 100644 --- a/nodeadmin/libvirtworker.py +++ b/nodeadmin/libvirtworker.py @@ -21,15 +21,60 @@ import libvirt import os import virtinst import utils +import logging from domainconfig import DomainConfig DEFAULT_POOL_TARGET_PATH="/var/lib/libvirt/images" +DEFAULT_URL="qemu:///system" + +default_url = DEFAULT_URL + +def set_default_url(url): + logging.info("Changing DEFAULT_URL to %s" % url) + global default_url + + default_url = url + +def get_default_url(): + logging.info("Returning default URL of %s" % default_url) + return default_url + +class VirtManagerConfig: + def __init__(self, filename = "/etc/remote-libvirt.conf"): + self.__filename = filename + + def get_connection_list(self): + result = [] + if os.path.exists(self.__filename): + input = file(self.__filename, "r") + for entry in input: result.append(entry[0:-1]) + return result + + def add_connection(self, connection): + connections = self.get_connection_list() + if connections.count(connection) is 0: + connections.append(connection) + self._save_connections(connections) + + def remove_connection(self, connection): + connections = self.get_connection_list() + if connections.count(connection) > 0: + connections.remove(connection) + self._save_connections(connections) + + def _save_connections(self, connections): + output = file(self.__filename, "w") + for entry in connections: + print >> output, entry + output.close class LibvirtWorker: '''Provides utilities for interfacing with libvirt.''' - def __init__(self, url = "qemu:///system"): - self.__conn = libvirt.open(url) + def __init__(self, url = None): + if url is None: url = get_default_url() + logging.info("Connecting to libvirt: %s" % url) + self.open_connection(url) self.__capabilities = virtinst.CapabilitiesParser.parse(self.__conn.getCapabilities()) self.__net = virtinst.VirtualNetworkInterface(conn = self.__conn) self.__net.setup(self.__conn) @@ -39,6 +84,10 @@ class LibvirtWorker: '''Returns the underlying connection.''' return self.__conn + def open_connection(self, url): + '''Lets the user change the url for the connection.''' + self.__conn = libvirt.open(url) + def list_domains(self, defined = True, started = True): '''Lists all domains.''' result = [] diff --git a/nodeadmin/mainmenu.py b/nodeadmin/mainmenu.py index 52d9298..9c435fd 100755 --- a/nodeadmin/mainmenu.py +++ b/nodeadmin/mainmenu.py @@ -23,14 +23,16 @@ from menuscreen import MenuScreen from nodemenu import NodeMenu from netmenu import NetworkMenu from storagemenu import StoragePoolMenu +from hostmenu import HostMenu import utils import logging -NODE_MENU = 1 -NETWORK_MENU = 2 -STORAGE_MENU = 3 -EXIT_CONSOLE = 4 +NODE_MENU = 1 +NETWORK_MENU = 2 +STORAGE_MENU = 3 +HOST_MENU = 4 +EXIT_CONSOLE = 99 class MainMenuScreen(MenuScreen): def __init__(self): @@ -39,12 +41,14 @@ class MainMenuScreen(MenuScreen): def get_menu_items(self): return (("Node Administration", NODE_MENU), ("Network Administration", NETWORK_MENU), - ("Storage Pool Administration", STORAGE_MENU)) - - def handle_selection(self, item): - if item is NODE_MENU: NodeMenu() - elif item is NETWORK_MENU: NetworkMenu() - elif item is STORAGE_MENU: StoragePoolMenu() + ("Storage Pool Administration", STORAGE_MENU), + ("Host Administration", HOST_MENU)) + + def handle_selection(self, page): + if page is NODE_MENU: NodeMenu() + elif page is NETWORK_MENU: NetworkMenu() + elif page is STORAGE_MENU: StoragePoolMenu() + elif page is HOST_MENU: HostMenu() def MainMenu(): screen = MainMenuScreen() diff --git a/nodeadmin/removehost.py b/nodeadmin/removehost.py new file mode 100644 index 0000000..cf3c46c --- /dev/null +++ b/nodeadmin/removehost.py @@ -0,0 +1,66 @@ +# removehost.py - Copyright (C) 2009 Red Hat, Inc. +# Written by Darryl L. Pierce +# +# 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 configscreen import * + +SELECT_HOST_PAGE = 1 +CONFIRM_REMOVE_PAGE = 2 + +class RemoveHostConfigScreen(HostListConfigScreen): + def __init__(self): + HostListConfigScreen.__init__(self, "Remove Host Connection") + + def get_elements_for_page(self, screen, page): + if page is SELECT_HOST_PAGE: return self.get_connection_list_page(screen) + elif page is CONFIRM_REMOVE_PAGE: return self.get_confirm_remove_page(screen) + + def page_has_next(self, page): + return page is SELECT_HOST_PAGE and self.has_selectable_connections() + + def page_has_back(self, page): + return page is CONFIRM_REMOVE_PAGE + + def page_has_finish(self, page): + return page is CONFIRM_REMOVE_PAGE + + def validate_input(self, page, errors): + if page is SELECT_HOST_PAGE: return True + elif page is CONFIRM_REMOVE_PAGE: + if self.__confirm.value(): + return True + else: + errors.append("You must confirm removing the connection.") + return False + + def process_input(self, page): + if page is CONFIRM_REMOVE_PAGE: + self.get_virt_manager_config().remove_connection(self.get_selected_connection()) + self.set_finished() + + def get_confirm_remove_page(self, screen): + self.__confirm = Checkbox("Remove this connection: %s" % self.get_selected_connection(), 0) + grid = Grid(1, 1) + grid.setField(self.__confirm, 0, 0) + return [Label("Remove Host Connection"), + grid] + +def RemoveHost(): + screen = RemoveHostConfigScreen() + screen.start() diff --git a/ovirt-node.spec.in b/ovirt-node.spec.in index 325fecc..f056f3f 100644 --- a/ovirt-node.spec.in +++ b/ovirt-node.spec.in @@ -198,6 +198,11 @@ cd - %{__install} -p -m0755 nodeadmin/destroynetwork.py %{buildroot}%{python_sitelib}/nodeadmin %{__install} -p -m0755 nodeadmin/undefinenetwork.py %{buildroot}%{python_sitelib}/nodeadmin +%{__install} -p -m0755 nodeadmin/addhost.py %{buildroot}%{python_sitelib}/nodeadmin +%{__install} -p -m0644 nodeadmin/changehost.py %{buildroot}%{python_sitelib}/nodeadmin +%{__install} -p -m0755 nodeadmin/hostmenu.py %{buildroot}%{python_sitelib}/nodeadmin +%{__install} -p -m0755 nodeadmin/removehost.py %{buildroot}%{python_sitelib}/nodeadmin + %{__install} -p -m0755 nodeadmin/createuser.py %{buildroot}%{python_sitelib}/nodeadmin %{__install} -p -m0644 nodeadmin/halworker.py %{buildroot}%{python_sitelib}/nodeadmin -- 1.6.5.2 From dpierce at redhat.com Tue Dec 8 21:13:54 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Tue, 8 Dec 2009 16:13:54 -0500 Subject: [Ovirt-devel] [PATCH 2/2] Enables users to migrate virtual machines between hosts. In-Reply-To: <1260306834-32625-2-git-send-email-dpierce@redhat.com> References: <1260306834-32625-1-git-send-email-dpierce@redhat.com> <1260306834-32625-2-git-send-email-dpierce@redhat.com> Message-ID: <1260306834-32625-3-git-send-email-dpierce@redhat.com> 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 --- 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 +# +# 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 From sseago at redhat.com Wed Dec 9 17:44:03 2009 From: sseago at redhat.com (Scott Seago) Date: Wed, 09 Dec 2009 12:44:03 -0500 Subject: [Ovirt-devel] [PATCH] fix storages crazyness In-Reply-To: <1255030846-8053-1-git-send-email-mloiseleur@linagora.com> References: <1255030846-8053-1-git-send-email-mloiseleur@linagora.com> Message-ID: <4B1FE1E3.5030403@redhat.com> Loiseleur Michel wrote: > Signed-off-by: Loiseleur Michel > --- > app/models/vm.rb | 2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) > > diff --git a/app/models/vm.rb b/app/models/vm.rb > index 88e0aef..0be3f89 100644 > --- a/app/models/vm.rb > +++ b/app/models/vm.rb > @@ -27,7 +27,7 @@ class Vm < ActiveRecord::Base > find(:all, :conditions=>{:state=>Task::STATE_QUEUED}) > end > end > - has_and_belongs_to_many :storage_volumes > + has_and_belongs_to_many :storage_volumes, :uniq => true > > has_many :nics, :dependent => :destroy > > ACK, This works for removing duplicate entries when returning the list of storage volumes. This won't prevent duplicate records from being created in the first place, though. So this can be pushed as-is, but we should probably resolve the duplication at the source as well -- why are we getting duplicate entries? In addition, we could put a unique constraint at the database level if necessary. Scott From jboggs at redhat.com Thu Dec 10 19:13:10 2009 From: jboggs at redhat.com (Joey Boggs) Date: Thu, 10 Dec 2009 14:13:10 -0500 Subject: [Ovirt-devel] [PATCH node] Enables stateless iscsi remote boot Message-ID: <1260472390-8107-1-git-send-email-jboggs@redhat.com> Used in conjunction with livecd-iso-to-iscsi. Creates a local boot partition with vmlinuz/initrd and grub configuration. Disk Partitioning > enable iscsi target > configure storage > local install and reboot --- scripts/ovirt-config-boot | 131 +++++++++++++++++++-------------- scripts/ovirt-config-storage | 164 +++++++++++++++++++++++++----------------- tools/livecd-iso-to-iscsi | 3 + 3 files changed, 177 insertions(+), 121 deletions(-) diff --git a/scripts/ovirt-config-boot b/scripts/ovirt-config-boot index 4c4e3d7..7978010 100755 --- a/scripts/ovirt-config-boot +++ b/scripts/ovirt-config-boot @@ -48,7 +48,7 @@ ovirt_boot_setup() { else grub_dev_label="RootBackup" fi - mount_liveos + # check that /boot mounted ok and find partition number for GRUB eval $(readlink -f /dev/disk/by-label/$grub_dev_label|awk {' print "disk=" substr($1,1,length($1)-1); @@ -62,54 +62,57 @@ ovirt_boot_setup() { return 1 fi - mountpoint /liveos - if [ $? -ne 0 ] ; then - log "Root partition not available" - return 1 - fi + if [ "$OVIRT_ISCSI_ENABLED" != "y" ]; then + mount_liveos + mountpoint /liveos + if [ $? -ne 0 ] ; then + log "Root partition not available" + return 1 + fi - if [ ! -e "$disk" ]; then - # e.g. c0d0p1 - disk="$disk2" - fi - mkdir -p /liveos - # prepare Root partition update - candidate= - if [ -e /dev/disk/by-label/RootBackup ]; then - candidate=RootBackup - elif [ -e /dev/disk/by-label/RootUpdate ]; then - candidate=RootUpdate - elif [ -e /dev/disk/by-label/RootNew ]; then - candidate=RootNew - fi - if [ -z "$candidate" ]; then - rc=1 - elif [ "$candidate" = "RootNew" ]; then - umount /liveos - rc=0 - else - candidate_dev=$(readlink -f /dev/disk/by-label/$candidate) - e2label $candidate_dev RootNew - rc=$? - fi - if [ $rc -ne 0 ]; then - log "root partition not available." - log "$(ls -al /dev/disk/by-label)" - return $rc - fi + if [ ! -e "$disk" ]; then + # e.g. c0d0p1 + disk="$disk2" + fi + # prepare Root partition update + candidate= + if [ -e /dev/disk/by-label/RootBackup ]; then + candidate=RootBackup + elif [ -e /dev/disk/by-label/RootUpdate ]; then + candidate=RootUpdate + elif [ -e /dev/disk/by-label/RootNew ]; then + candidate=RootNew + fi + if [ -z "$candidate" ]; then + rc=1 + elif [ "$candidate" = "RootNew" ]; then + umount /liveos + rc=0 + else + candidate_dev=$(readlink -f /dev/disk/by-label/$candidate) + e2label $candidate_dev RootNew + rc=$? + fi + if [ $rc -ne 0 ]; then + log "root partition not available." + log "$(ls -al /dev/disk/by-label)" + return $rc + fi - mount $candidate_dev /liveos - # install oVirt Node image for local boot - if [ -e "$live/syslinux" ]; then - syslinux=syslinux - elif [ -e "$live/isolinux" ]; then - syslinux=isolinux - else - syslinux= - fi + mount $candidate_dev /liveos - rm -rf /liveos/LiveOS - mkdir -p /liveos/LiveOS + rm -rf /liveos/LiveOS + mkdir -p /liveos/LiveOS + + fi + # install oVirt Node image for local boot + if [ -e "$live/syslinux" ]; then + syslinux=syslinux + elif [ -e "$live/isolinux" ]; then + syslinux=isolinux + else + syslinux= + fi if [ "$OVIRT_ISCSI_ENABLED" == "y" ]; then initrd_dest="/boot" @@ -124,13 +127,22 @@ ovirt_boot_setup() { rm -rf $grub_dir mkdir -p $grub_dir - cp -p $live/LiveOS/squashfs.img /liveos/LiveOS \ - && cp -p $live/$syslinux/vmlinuz0 $initrd_dest + cp -p $live/$syslinux/vmlinuz0 $initrd_dest rc=$? if [ $rc -ne 0 ]; then - log "image copy failed." - return $rc + log "kernel image copy failed." + return $rc + fi + + if [ "$OVIRT_ISCSI_ENABLED" != "y" ]; then + cp -p $live/LiveOS/squashfs.img /liveos/LiveOS + rc=$? + if [ $rc -ne 0 ]; then + log "squashfs image copy failed." + return $rc + fi fi + # append LVM support to the livecd initramfs tmpdir=$(mktemp -d) cd $tmpdir @@ -182,10 +194,10 @@ set -e\ release=$(rpm -q --qf '%{release}' ovirt-node) # reorder tty0 to allow both serial and phys console after installation if [ "$OVIRT_ISCSI_ENABLED" == "y" ]; then - bootparams="ro root=LABEL=live:Root roottypefs=ext3 console=tty0 \ + bootparams="ro root=LABEL=ovirt-node-root roottypefs=ext3 console=tty0 \ netroot=iscsi:$OVIRT_ISCSI_TARGET_IP::$OVIRT_ISCSI_TARGET_PORT::$OVIRT_ISCSI_NODE_NAME ip=eth0:dhcp" else - bootparams="ro root=LABEL=live:Root roottypefs=ext3 console=tty0 \ + bootparams="ro root=live:LABEL=Root roottypefs=ext3 console=tty0 \ $(echo $bootparams | sed s/console=tty0//g)" fi cat > $grub_dir/grub.conf << EOF @@ -209,9 +221,11 @@ EOF return $rc fi - umount /liveos - # mark new Root ready to go, reboot() in ovirt-function switches it to active - e2label $candidate_dev RootUpdate + if [ "$OVIRT_ISCSI_ENABLED" != "y" ]; then + umount /liveos + # mark new Root ready to go, reboot() in ovirt-function switches it to active + e2label $candidate_dev RootUpdate + fi rm -rf $tmpdir if [ "$OVIRT_ISCSI_ENABLED" == "y" ]; then @@ -253,7 +267,12 @@ if [ $rc -eq 0 -a "$doreboot" = "yes" ]; then disable_firstboot ovirt_store_firstboot_config stop_log - reboot + + if [ "$OVIRT_ISCSI_ENABLED" != "y" ]; then + reboot + else + /sbin/reboot + fi fi stop_log exit $rc diff --git a/scripts/ovirt-config-storage b/scripts/ovirt-config-storage index f9a5b41..2ffcaa4 100755 --- a/scripts/ovirt-config-storage +++ b/scripts/ovirt-config-storage @@ -85,17 +85,23 @@ check_partition_sizes() fi printf "\n" - get_drive_size $ROOTDRIVE ROOTDRIVESPACE - get_drive_size $HOSTVGDRIVE HOSTVGDRIVESPACE - ROOT_NEED_SIZE=$(echo "scale=0; $ROOT_SIZE * 2"| bc -l) - HOSTVG_NEED_SIZE=$(echo "scale=0;" \ - "$SWAP_SIZE + $CONFIG_SIZE + $LOGGING_SIZE + $min_data_size" | bc -l) - - if [ $ROOTDRIVE == $HOSTVGDRIVE ]; then - drive_list="ROOT" - ROOT_NEED_SIZE=$(echo "scale=0; $ROOT_SIZE * 2 + $HOSTVG_NEED_SIZE"| bc -l) + if [ "$OVIRT_ISCSI_ENABLED" == "y" ]; then + get_drive_size $BOOTDRIVE BOOTDRIVESPACE + drive_list="BOOT" + BOOT_NEED_SIZE=$BOOT_SIZE else - drive_list="ROOT HOSTVG" + get_drive_size $ROOTDRIVE ROOTDRIVESPACE + get_drive_size $HOSTVGDRIVE HOSTVGDRIVESPACE + ROOT_NEED_SIZE=$(echo "scale=0; $ROOT_SIZE * 2"| bc -l) + HOSTVG_NEED_SIZE=$(echo "scale=0;" \ + "$SWAP_SIZE + $CONFIG_SIZE + $LOGGING_SIZE + $min_data_size" | bc -l) + + if [ $ROOTDRIVE == $HOSTVGDRIVE ]; then + drive_list="ROOT" + ROOT_NEED_SIZE=$(echo "scale=0; $ROOT_SIZE * 2 + $HOSTVG_NEED_SIZE"| bc -l) + else + drive_list="ROOT HOSTVG" + fi fi for drive in $drive_list; do @@ -120,22 +126,26 @@ check_partition_sizes() done # check if an existing HostVG exists on a device other than the target - devices="$(pvs -o pv_name,vg_name --noheadings | \ - grep "HostVG"|grep -v $HOSTVGDRIVE|awk '{ print $1 }')" - rc=0 - if [ -n "$devices" ]; then - printf "\n" - printf "There appears to already be an installation on another device:\n" - for device in $devices; do - udi=$(hal-find-by-property --key block.device --string $device) - printf "\t$device ($(basename "$udi"))\n" - done - printf "We cannot proceed until either device is removed from the system\n" - printf "or until the HostVG volume group is removed.\n" - printf "\nTo re-install the node, please select \"Uninstall Node\" from the main\n" - printf "menu and then try to partition.\n" - printf "\n" - rc=1 + if [ "$OVIRT_ISCSI_ENABLED" != "y" ]; then + devices="$(pvs -o pv_name,vg_name --noheadings | \ + grep "HostVG"|grep -v $HOSTVGDRIVE|awk '{ print $1 }')" + rc=0 + if [ -n "$devices" ]; then + printf "\n" + printf "There appears to already be an installation on another device:\n" + for device in $devices; do + udi=$(hal-find-by-property --key block.device --string $device) + printf "\t$device ($(basename "$udi"))\n" + done + printf "We cannot proceed until either device is removed from the system\n" + printf "or until the HostVG volume group is removed.\n" + printf "\nTo re-install the node, please select \"Uninstall Node\" from the main\n" + printf "menu and then try to partition.\n" + printf "\n" + rc=1 + fi + else + rc=0 fi return $rc @@ -210,16 +220,17 @@ do_configure() printf "\n\nPlease select the disk to use for the Boot partition.\n\n" BOOTDRIVE=$(get_dev_name) || return 0 get_drive_size $BOOTDRIVE BOOTDRIVESPACE + echo $BOOTDRIVE + else + printf "\n\nPlease select the disk to use for the Root.\n\n" + ROOTDRIVE=$(get_dev_name) || return 0 + get_drive_size $ROOTDRIVE ROOTDRIVESPACE + + printf "\n\nPlease select the disk to use for the HostVG.\n\n" + HOSTVGDRIVE=$(get_dev_name) || return 0 + get_drive_size $HOSTVGDRIVE HOSTVGDRIVESPACE + echo $HOSTVGDRIVESPACE fi - printf "\n\nPlease select the disk to use for the Root.\n\n" - ROOTDRIVE=$(get_dev_name) || return 0 - get_drive_size $ROOTDRIVE ROOTDRIVESPACE - - printf "\n\nPlease select the disk to use for the HostVG.\n\n" - HOSTVGDRIVE=$(get_dev_name) || return 0 - get_drive_size $HOSTVGDRIVE HOSTVGDRIVESPACE - echo $HOSTVGDRIVESPACE - printf "\n\nPlease configure storage partitions.\n\n" printf "* Enter partition sizes in MB.\n" printf "* A value of 0 indicates the partition should be disabled.\n" @@ -236,7 +247,8 @@ do_configure() local space_left=$HOSTVGDRIVESPACE if [ "$OVIRT_ISCSI_ENABLED" == "y" ]; then - partlist="boot swap root config logging data" + partlist="boot" # swap root config logging data" + local space_left=$BOOTDRIVESPACE else partlist="swap root config logging data" fi @@ -303,24 +315,25 @@ EOF do_review() { - if [ -z "$ROOTDRIVE" ]; then + if [[ -z "$ROOTDRIVE" && "$OVIRT_ISCSI_ENABLED" != "y" ]]; then printf "\nNo Root storage device selected.\n" return fi - local data_size_display="$DATA_SIZE MB" - if [ "$DATA_SIZE" = -1 ]; then + if [ "$OVIRT_ISCSI_ENABLED" != "y" ]; then + local data_size_display="$DATA_SIZE MB" + if [ "$DATA_SIZE" = -1 ]; then - if [ $ROOTDRIVE == $HOSTVGDRIVE ]; then - local remaining_mb=$(( $ROOTDRIVESPACE - $SWAP_SIZE \ - - $ROOT_SIZE * 2 - $CONFIG_SIZE - $LOGGING_SIZE )) - else - local remaining_mb=$(( $HOSTVGDRIVESPACE - $SWAP_SIZE - $CONFIG_SIZE - $LOGGING_SIZE )) + if [ $ROOTDRIVE == $HOSTVGDRIVE ]; then + local remaining_mb=$(( $ROOTDRIVESPACE - $SWAP_SIZE \ + - $ROOT_SIZE * 2 - $CONFIG_SIZE - $LOGGING_SIZE )) + else + local remaining_mb=$(( $HOSTVGDRIVESPACE - $SWAP_SIZE - $CONFIG_SIZE - $LOGGING_SIZE )) + fi + data_size_display="$remaining_mb MB" fi - data_size_display="$remaining_mb MB" - fi - cat < References: <20091119184402.GL27346@us.ibm.com> Message-ID: <20091210223448.GJ5525@us.ibm.com> * Ryan Harper [2009-11-19 12:47]: > Create /etc/ovirt-early.d and add a kernel parameter, ovirt_early > which can specify one or more strings which reference scripts > that will be embedded into the ovirt-node image. ovirt-early pre-* > are called after processing command line parameters but before mount > the config partition in ovirt-early start(), and post-* are called > at the very end of the start() function. > > Update ovirt-node specfile to create /etc/ovirt-early.d > > Signed-off-by: Ryan Harper Any feedback? Do you want a resend? -- Ryan Harper Software Engineer; Linux Technology Center IBM Corp., Austin, Tx ryanh at us.ibm.com From apevec at gmail.com Fri Dec 11 00:09:03 2009 From: apevec at gmail.com (Alan Pevec) Date: Fri, 11 Dec 2009 01:09:03 +0100 Subject: [Ovirt-devel] [PATCH]v2 Add ovirt-early vendor hooks In-Reply-To: <20091210223448.GJ5525@us.ibm.com> References: <20091119184402.GL27346@us.ibm.com> <20091210223448.GJ5525@us.ibm.com> Message-ID: <2be7262f0912101609m165c31b0j3b40dcf625a72170@mail.gmail.com> On Thu, Dec 10, 2009 at 11:34 PM, Ryan Harper wrote: > * Ryan Harper [2009-11-19 12:47]: >> Create /etc/ovirt-early.d and add a kernel parameter, ovirt_early >> which can specify one or more strings which reference scripts >> that will be embedded into the ovirt-node image. ?ovirt-early pre-* >> are called after processing command line parameters but before mount >> the config partition in ovirt-early start(), and post-* are called >> at the very end of the start() function. >> >> Update ovirt-node specfile to create /etc/ovirt-early.d >> >> Signed-off-by: Ryan Harper > > Any feedback? ?Do you want a resend? Sorry for the delay, patch looks good - ACK and pushed Thanks! From ovirt at proinbox.com Fri Dec 11 23:41:55 2009 From: ovirt at proinbox.com (ovirt at proinbox.com) Date: Fri, 11 Dec 2009 18:41:55 -0500 Subject: [Ovirt-devel] Physical Network Devices table empty Message-ID: <1260574915.13783.1349691525@webmail.messagingengine.com> My aim is to install a standalone node on the following hardware & run the management server in one of it's VMs. Dell Poweredge 2950 PERC 6/i RAID0 6x: 25G / 1T / 4.4T Dual Xeon 5470 quad-core 3.3GHz / 20G RAM Dual onboard Broadcom NetXtreme II BCM5708 NICs I downloaded the [1]oVirt Node 1.0.2-1.fc11.x86_64 iso from the [2]website & boot in standalone mode per [3]instructions on the wiki. When entering the "4) Networking Setup" menu, there aren't any devices present: Physical Networking Devices (*=PXE boot interface) Name Driver MAC 1) DNS 3) Abort 2) NTP 4) Save And Return To Menu Please select an interface or configuration option: _ Both "1) DNS" & "2) NTP" menu options require an interface be configured prior to offering their own configuration options, and thus remain undefined. Please advise. References 1. http://ovirt.org/files/ovirt-node-image-1.0.2-1.fc11.x86_64.iso 2. http://ovirt.org/download.html 3. http://ovirt.org/page/Node_Standalone_Operation -------------- next part -------------- An HTML attachment was scrubbed... URL: From apevec at gmail.com Sat Dec 12 01:03:10 2009 From: apevec at gmail.com (Alan Pevec) Date: Sat, 12 Dec 2009 02:03:10 +0100 Subject: [Ovirt-devel] Physical Network Devices table empty In-Reply-To: <1260574915.13783.1349691525@webmail.messagingengine.com> References: <1260574915.13783.1349691525@webmail.messagingengine.com> Message-ID: <2be7262f0912111703s33e48cc3n87145a6d8a33955b@mail.gmail.com> On Sat, Dec 12, 2009 at 12:41 AM, wrote: > My aim is to install a standalone node on the following hardware & run the > management server in one of it's VMs. > > Dell Poweredge 2950 > PERC 6/i RAID0 6x: 25G / 1T / 4.4T > Dual Xeon 5470 quad-core 3.3GHz / 20G RAM > Dual onboard Broadcom NetXtreme II BCM5708 NICs Looks like driver for that NIC failed to load, please go to Shell option and check in dmesg for errors probably due to missing firmware. There was a patch just after 1.0.2 release which fixes firmware missing in the image: http://git.fedorahosted.org/git/ovirt/?p=ovirt/node-image.git;a=commitdiff;h=4134abf597efbc7bb8c13772eca69d8c94eb3df5 1.0.3 should be out next week, but in the meantime you can try building ovirt-node-image from "next" branch. > I downloaded the oVirt Node 1.0.2-1.fc11.x86_64 iso from the website & boot > in standalone mode per instructions on the wiki. > > When entering the "4) Networking Setup" menu, there aren't any devices > present: > > Physical Networking Devices (*=PXE boot interface) > ?Name?????????? Driver????????????? MAC > 1) DNS?????????????????????????????????????????? 3) Abort > 2) NTP?????????????????????????????????????????? 4) Save And Return To Menu > Please select an interface or configuration option: _ From ovirt at proinbox.com Sat Dec 12 02:38:42 2009 From: ovirt at proinbox.com (ovirt at proinbox.com) Date: Fri, 11 Dec 2009 21:38:42 -0500 Subject: [Ovirt-devel] Physical Network Devices table empty In-Reply-To: <2be7262f0912111703s33e48cc3n87145a6d8a33955b@mail.gmail.com> References: <1260574915.13783.1349691525@webmail.messagingengine.com> <2be7262f0912111703s33e48cc3n87145a6d8a33955b@mail.gmail.com> Message-ID: <1260585522.970.1349710091@webmail.messagingengine.com> dmesg|grep "firmware" bnx2: 0000:03:00.0: firmware: requesting bnx2/bnx2-mips-06-4.6.16.fw bnx2: Can't load firmware file "bnx2/bnx2-mips-06-4.6.16.fw" bnx2: 0000:07:00.0: firmware: requesting bnx2/bnx2-mips-06-4.6.16.fw bnx2: Can't load firmware file "bnx2/bnx2-mips-06-4.6.16.fw" - thanks. On Sat, 12 Dec 2009 02:03 +0100, "Alan Pevec" wrote: > On Sat, Dec 12, 2009 at 12:41 AM, wrote: > > My aim is to install a standalone node on the following hardware & run the > > management server in one of it's VMs. > > > > Dell Poweredge 2950 > > PERC 6/i RAID0 6x: 25G / 1T / 4.4T > > Dual Xeon 5470 quad-core 3.3GHz / 20G RAM > > Dual onboard Broadcom NetXtreme II BCM5708 NICs > > Looks like driver for that NIC failed to load, please go to Shell > option and check in dmesg for errors > probably due to missing firmware. There was a patch just after 1.0.2 > release which fixes firmware missing in the image: > http://git.fedorahosted.org/git/ovirt/?p=ovirt/node-image.git;a=commitdiff;h=4134abf597efbc7bb8c13772eca69d8c94eb3df5 > 1.0.3 should be out next week, but in the meantime you can try > building ovirt-node-image from "next" branch. > > > I downloaded the oVirt Node 1.0.2-1.fc11.x86_64 iso from the website & boot > > in standalone mode per instructions on the wiki. > > > > When entering the "4) Networking Setup" menu, there aren't any devices > > present: > > > > Physical Networking Devices (*=PXE boot interface) > > ?Name?????????? Driver????????????? MAC > > 1) DNS?????????????????????????????????????????? 3) Abort > > 2) NTP?????????????????????????????????????????? 4) Save And Return To Menu > > Please select an interface or configuration option: _ From dpierce at redhat.com Mon Dec 14 15:35:52 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Mon, 14 Dec 2009 10:35:52 -0500 Subject: [Ovirt-devel] [PATCH] Bumped the size of the node image to 700M. Message-ID: <1260804952-23226-1-git-send-email-dpierce@redhat.com> Signed-off-by: Darryl L. Pierce --- common-install.ks | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/common-install.ks b/common-install.ks index 9bcdaa3..b482139 100644 --- a/common-install.ks +++ b/common-install.ks @@ -4,7 +4,7 @@ timezone --utc UTC auth --useshadow --enablemd5 selinux --enforcing firewall --disabled -part / --size 650 --fstype ext2 +part / --size 700 --fstype ext2 services --enabled=auditd,ntpd,ntpdate,collectd,iptables,network,rsyslog,libvirt-qpid # This requires a new fixed version of livecd-creator to honor the --append settings. bootloader --timeout=30 --append="console=tty0 console=ttyS0,115200n8" -- 1.6.5.2 From apevec at gmail.com Mon Dec 14 17:47:04 2009 From: apevec at gmail.com (Alan Pevec) Date: Mon, 14 Dec 2009 18:47:04 +0100 Subject: [Ovirt-devel] [PATCH] Bumped the size of the node image to 700M. In-Reply-To: <1260804952-23226-1-git-send-email-dpierce@redhat.com> References: <1260804952-23226-1-git-send-email-dpierce@redhat.com> Message-ID: <2be7262f0912140947g27c92es5bf86b7e40695bd6@mail.gmail.com> ACK as an emergency measure, image size did increase with latest additions But at the same time, please put TODO comment that dependencies should be re-examined for unused parts which could be blacklisted. Alan -------------- next part -------------- An HTML attachment was scrubbed... URL: From dpierce at redhat.com Mon Dec 14 18:34:58 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Mon, 14 Dec 2009 13:34:58 -0500 Subject: [Ovirt-devel] [PATCH] Bumped the size of the node image to 700M. In-Reply-To: <2be7262f0912140947g27c92es5bf86b7e40695bd6@mail.gmail.com> References: <1260804952-23226-1-git-send-email-dpierce@redhat.com> <2be7262f0912140947g27c92es5bf86b7e40695bd6@mail.gmail.com> Message-ID: <20091214183458.GB6041@mcpierce-desktop.usersys.redhat.com> On Mon, Dec 14, 2009 at 06:47:04PM +0100, Alan Pevec wrote: > ACK as an emergency measure, image size did increase with latest additions > But at the same time, please put TODO comment that dependencies should be > re-examined for unused parts which could be blacklisted. Will do. I'll add that then push. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Delivering value year after year. Red Hat ranks #1 in value among software vendors. http://www.redhat.com/promo/vendor/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: not available URL: From fishy at linux.vnet.ibm.com Tue Dec 15 06:10:46 2009 From: fishy at linux.vnet.ibm.com (fishy) Date: Tue, 15 Dec 2009 11:40:46 +0530 Subject: [Ovirt-devel] [RFC][PATCH v2] edit-livecd : fail on error in arbitrary code In-Reply-To: <4B179690.9060907@linux.vnet.ibm.com> References: <4AF96D92.4090503@linux.vnet.ibm.com> <4AFB30B9.2020607@redhat.com> <4AFD1A73.5020904@linux.vnet.ibm.com> <4B17954D.8010205@linux.vnet.ibm.com> <4B179690.9060907@linux.vnet.ibm.com> Message-ID: <4B272866.5010008@linux.vnet.ibm.com> Please the patch listed here On 12/03/2009 04:14 PM, fishy wrote: > Purpose : fail iso build on encountering error in arbitrary code '$CODE' > > On 12/03/2009 04:09 PM, fishy wrote: >> Please the patch listed here >> >> On 11/13/2009 02:06 PM, abhishek misra wrote: >>> Hello All, >>> >>> Below are David's comments on my last patch >>> >>> David Huff wrote: >>>> I took a look at this today, I am not sure that a requirement for >>>> 'CODE' >>>> to touch a "fail" file is the best way to address this. >>>> >>>> I assume your script is mounting proc inside the ext filesystem, ie to >>>> use yum or something. And using trap and a similar mnt function, like >>>> what is in edit-livecd, is not cleaning up all the mounts in this >>>> case? >>>> >>>> A fix may be to use /proc/mounts instead of df when adding the >>>> Exits in >>>> the mnt function. >>>> >>>> Also can you clarify the statement, "note that it may not always be >>>> possible to return some error code on failure in 'CODE'" I am not >>>> really >>>> sure what you mean here. >>>> >>>> Does this make sense? >>>> >>>> -D >>> David, you were right about proc , I've now taken care of that in my >>> 'CODE' >>> >>> Here is another patch that tries to achieve the same without using >>> 'touch fail' >>> >>> 1. removed compound statement ( list ) >>> I found that its usage does not prevent trap to come into action >>> if $CODE fails (which is desired ) >>> but allows commands after (list) to continue executing ( which >>> is not desired ) >>> >>> 2 added addExit "cd -" >>> when $CODE fails and control returns to edit-livecd script, it is >>> still in $WDIR/ex >>> this causes failure when trap attempts umount >>> >>> 3 added EXIT=${EXIT/cd - ;/} >>> we no longer need it if $CODE goes well >>> >>> 4 added cd - >>> we need it as we removed (list) >>> >>> 5 removed set +/- e >>> >>> Signed-off-by: Abhishek Misra >> >>> --- >>> >>> --- a/edit-livecd 2009-11-10 17:23:21.000000000 +0530 >>> +++ b/edit-livecd 2009-11-13 14:03:50.000000000 +0530 >>> @@ -161,12 +161,11 @@ mnt "-t ext2 $WDIR/sq-w/LiveOS/ext3fs.im >>> >>> echo ">>> Updating CD content" >>> if [ -n "$CODE" ]; then >>> - ( >>> cd $WDIR/ex >>> - set +e >>> + addExit "cd -" >>> eval "$CODE" >>> - set -e >>> - ) >>> + EXIT=${EXIT/cd - ;/} >>> + cd - >>> else >>> echo "***" >>> echo "*** Pausing to allow manual changes. Press any key to >>> continue." >>> >>> _______________________________________________ >>> Ovirt-devel mailing list >>> Ovirt-devel at redhat.com >>> https://www.redhat.com/mailman/listinfo/ovirt-devel >> >> _______________________________________________ >> Ovirt-devel mailing list >> Ovirt-devel at redhat.com >> https://www.redhat.com/mailman/listinfo/ovirt-devel > > _______________________________________________ > Ovirt-devel mailing list > Ovirt-devel at redhat.com > https://www.redhat.com/mailman/listinfo/ovirt-devel From apevec at gmail.com Tue Dec 15 09:36:36 2009 From: apevec at gmail.com (Alan Pevec) Date: Tue, 15 Dec 2009 10:36:36 +0100 Subject: [Ovirt-devel] [RFC][PATCH v2] edit-livecd : fail on error in arbitrary code In-Reply-To: <4B272866.5010008@linux.vnet.ibm.com> References: <4AF96D92.4090503@linux.vnet.ibm.com> <4AFB30B9.2020607@redhat.com> <4AFD1A73.5020904@linux.vnet.ibm.com> <4B17954D.8010205@linux.vnet.ibm.com> <4B179690.9060907@linux.vnet.ibm.com> <4B272866.5010008@linux.vnet.ibm.com> Message-ID: <2be7262f0912150136i40580142y2905fbf13da62338@mail.gmail.com> ACK - works as advertised and propagates the script return code correctly I'm sorry for the delay - I've pushed this now with a minor modification (delExit instead of setting EXIT variable directly): --- a/edit-livecd +++ b/edit-livecd @@ -127,6 +127,11 @@ addExit() { trap "$EXIT" EXIT HUP TERM INT QUIT } +delExit() { + EXIT=${EXIT/$@ ; /} + trap "$EXIT" EXIT HUP TERM INT QUIT +} + mnt() { local margs="$1" ; shift local mp="$WDIR/$1" @@ -164,7 +169,7 @@ if [ -n "$CODE" ]; then cd $WDIR/ex addExit "cd -" eval "$CODE" - EXIT=${EXIT/cd - ;/} + delExit "cd -" cd - else echo "***" Speaking of edit-livecd, David posted few months ago edit-livecd.py - reimplementation in Python which was proposed for inclusion into livecd-tools - we need to restart that thread on livecd list: https://www.redhat.com/archives/ovirt-devel/2009-September/msg00139.html Abhishek, could you please have a look at that script and gives us your feedback? Alan -------------- next part -------------- An HTML attachment was scrubbed... URL: From dpierce at redhat.com Tue Dec 15 14:47:44 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Tue, 15 Dec 2009 09:47:44 -0500 Subject: [Ovirt-devel] [PATCH] The autotest timeout is now a command line configurable option. Message-ID: <1260888464-32652-1-git-send-email-dpierce@redhat.com> By default it's 120 ms, but can be changed through command line arguments. Signed-off-by: Darryl L. Pierce --- autotest.sh | 16 ++++++++++------ 1 files changed, 10 insertions(+), 6 deletions(-) diff --git a/autotest.sh b/autotest.sh index c67931a..bcd9bd5 100755 --- a/autotest.sh +++ b/autotest.sh @@ -62,6 +62,7 @@ Usage: $ME [-n test_name] [LOGFILE] -i: set the ISO filename (defualt: ovirt-node-image.iso) -n: the name of the specific autotest to run (default: run all autotests) -d: enable more verbose output (default: disabled) + -t: change the timeout between markers (in ms, default: 120) -v: enable tracing (default: disabled) -w: launch virt-viewer for each VM (default: no window shown) -h: display this help and exit @@ -484,7 +485,7 @@ test_stateless_pxe () { boot_with_pxe "${nodename}" "standalone firstboot=no" "${workdir}" expect -c ' -set timeout 120 +set timeout '${timeout_period}' log_file -noappend stateless-pxe.log @@ -526,7 +527,7 @@ test_stateless_pxe_with_nohd () { boot_with_pxe "${nodename}" "firstboot=no" "${workdir}" expect -c ' -set timeout 120 +set timeout '${timeout_period}' log_file -noappend stateless-pxe.log @@ -575,7 +576,7 @@ test_stateful_pxe () { # verify the booting and installation expect -c ' -set timeout 120 +set timeout '${timeout_period}' log_file -noappend stateful-pxe.log spawn sudo virsh console '"${nodename}"' @@ -608,7 +609,7 @@ exit 3' boot_from_hd "${nodename}" expect -c ' -set timeout 120 +set timeout '${timeout_period}' log_file stateful-pxe.log send_log "Restarted node, booting from hard disk.\n" @@ -704,13 +705,15 @@ isofile="${PWD}/ovirt-node-image.iso" show_viewer=false vm_prefix="$$" preserve_vm=false +timeout_period="120" -while getopts di:n:pvwh c; do +while getopts di:n:pt:vwh c; do case $c in d) debugging=true;; i) isofile=($OPTARG);; n) tests=($OPTARG);; - p) preserve_vm=true;; + p) preserve_vm=true;; + t) timeout_period=($OPTARG);; v) set -v;; w) show_viewer=true;; h) usage; exit 0;; @@ -738,6 +741,7 @@ log "Logging results to file: ${RESULTS}" log "Begin Testing: ${isoname}" log "Tests: ${tests}" + log "Timeout: ${timeout_period} ms" for test in ${tests}; do execute_test $test -- 1.6.5.2 From dpierce at redhat.com Tue Dec 15 15:34:09 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Tue, 15 Dec 2009 10:34:09 -0500 Subject: [Ovirt-devel] [PATCH] If the specified ISO does not exist, then the script dies. Message-ID: <1260891249-3681-1-git-send-email-dpierce@redhat.com> Before any tests are run, the ISO is checked and if it doesn't exist then the script exits with an explicit failure. Signed-off-by: Darryl L. Pierce --- autotest.sh | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/autotest.sh b/autotest.sh index c67931a..904b961 100755 --- a/autotest.sh +++ b/autotest.sh @@ -723,6 +723,10 @@ done isoname=$(basename $isofile) isofile="$(cd `dirname $isofile`; pwd)/${isoname}" +if ! [ -s "${isofile}" ]; then + die "Missing or invalid file: ${isofile}" +fi + shift $(($OPTIND - 1)) set +u -- 1.6.5.2 From ignazio.cassano at provincia.torino.it Wed Dec 16 15:19:44 2009 From: ignazio.cassano at provincia.torino.it (ignazio.cassano at provincia.torino.it) Date: Wed, 16 Dec 2009 16:19:44 +0100 Subject: [Ovirt-devel] ovirt.org Message-ID: <20091216161944.861577ljx8rp2xe8@webmail2.provincia.torino.it> Hello , anyone can tell me why ovirt.org site is not reachable ? Thanks Ignazio From jboggs at redhat.com Wed Dec 16 15:22:26 2009 From: jboggs at redhat.com (Joey Boggs) Date: Wed, 16 Dec 2009 10:22:26 -0500 Subject: [Ovirt-devel] ovirt.org In-Reply-To: <20091216161944.861577ljx8rp2xe8@webmail2.provincia.torino.it> References: <20091216161944.861577ljx8rp2xe8@webmail2.provincia.torino.it> Message-ID: <4B28FB32.3060102@redhat.com> On 12/16/2009 10:19 AM, ignazio.cassano at provincia.torino.it wrote: > Hello , > anyone can tell me why ovirt.org site is not reachable ? > Thanks > Ignazio > > _______________________________________________ > Ovirt-devel mailing list > Ovirt-devel at redhat.com > https://www.redhat.com/mailman/listinfo/ovirt-devel DNS issues from what I hear, you can get to it via ovirt.et.redhat.com in the meantime. From apevec at redhat.com Thu Dec 17 16:12:47 2009 From: apevec at redhat.com (Alan Pevec) Date: Thu, 17 Dec 2009 17:12:47 +0100 Subject: [Ovirt-devel] Re: [PATCH] Provides an explicit upgrade path for an installed node. In-Reply-To: <20091203213026.GF6458@mcpierce-desktop.usersys.redhat.com> References: <1258385963-5787-1-git-send-email-dpierce@redhat.com> <1258385963-5787-2-git-send-email-dpierce@redhat.com> <20091203213026.GF6458@mcpierce-desktop.usersys.redhat.com> Message-ID: <4B2A587F.7060700@redhat.com> Darryl L. Pierce wrote: > On Mon, Nov 16, 2009 at 10:39:23AM -0500, Darryl L. Pierce wrote: >> This patch allows the node to be upgraded without destroying any >> configuration. The new kernel argument, ovirt_upgrade, will boot cause >> the node to install the upgraded image, then reboot. >> >> Resolves: rhbz#532547 > > Can I get an ACK or feedback on this patch, please? ACK - I rebased it to current next and pushed From dpierce at redhat.com Thu Dec 17 20:04:56 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Thu, 17 Dec 2009 15:04:56 -0500 Subject: [Ovirt-devel] Re: [PATCH] Provides an explicit upgrade path for an installed node. In-Reply-To: <4B2A587F.7060700@redhat.com> References: <1258385963-5787-1-git-send-email-dpierce@redhat.com> <1258385963-5787-2-git-send-email-dpierce@redhat.com> <20091203213026.GF6458@mcpierce-desktop.usersys.redhat.com> <4B2A587F.7060700@redhat.com> Message-ID: <20091217200455.GF7205@mcpierce-desktop.usersys.redhat.com> On Thu, Dec 17, 2009 at 05:12:47PM +0100, Alan Pevec wrote: > Darryl L. Pierce wrote: > >On Mon, Nov 16, 2009 at 10:39:23AM -0500, Darryl L. Pierce wrote: > >>This patch allows the node to be upgraded without destroying any > >>configuration. The new kernel argument, ovirt_upgrade, will boot cause > >>the node to install the upgraded image, then reboot. > >> > >>Resolves: rhbz#532547 > > > >Can I get an ACK or feedback on this patch, please? > > ACK - I rebased it to current next and pushed Thank you. :) -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Delivering value year after year. Red Hat ranks #1 in value among software vendors. http://www.redhat.com/promo/vendor/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: not available URL: From dpierce at redhat.com Fri Dec 18 16:13:57 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Fri, 18 Dec 2009 11:13:57 -0500 Subject: [Ovirt-devel] Rebased patches, fixed a rebasing problem... In-Reply-To: <1260306834-32625-1-git-send-email-dpierce@redhat.com> References: <1260306834-32625-1-git-send-email-dpierce@redhat.com> Message-ID: <20091218161357.GK7205@mcpierce-desktop.usersys.redhat.com> On Tue, Dec 08, 2009 at 04:13:52PM -0500, Darryl L. Pierce wrote: > The previous patch set had an error and one development branch's changes > showed up twice, and two different change sets. So it was missing the bulk > of the configuration work. This patch set fixes that. If there are no objections, I'm going to push these upstream now and we'll fix any issues that come up afterward. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Delivering value year after year. Red Hat ranks #1 in value among software vendors. http://www.redhat.com/promo/vendor/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: not available URL: From apevec at redhat.com Fri Dec 18 16:37:25 2009 From: apevec at redhat.com (Alan Pevec) Date: Fri, 18 Dec 2009 17:37:25 +0100 Subject: [Ovirt-devel] Re: Rebased patches, fixed a rebasing problem... In-Reply-To: <20091218161357.GK7205@mcpierce-desktop.usersys.redhat.com> References: <1260306834-32625-1-git-send-email-dpierce@redhat.com> <20091218161357.GK7205@mcpierce-desktop.usersys.redhat.com> Message-ID: <4B2BAFC5.3090403@redhat.com> Darryl L. Pierce wrote: > On Tue, Dec 08, 2009 at 04:13:52PM -0500, Darryl L. Pierce wrote: >> The previous patch set had an error and one development branch's changes >> showed up twice, and two different change sets. So it was missing the bulk >> of the configuration work. This patch set fixes that. > > If there are no objections, I'm going to push these upstream now and > we'll fix any issues that come up afterward. ACK - I already pushed when I was flushing my patch queue, but forgot to reply here. Please verify I picked the right patch versions: http://git.fedorahosted.org/git/ovirt/?p=ovirt/node.git;a=commitdiff;h=0727dd3b45347ba3b70c5536065819a4e9b7034c http://git.fedorahosted.org/git/ovirt/?p=ovirt/node.git;a=commitdiff;h=5470e00f914214db77739a405708bc6f07c9f616 From dpierce at redhat.com Fri Dec 18 16:51:47 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Fri, 18 Dec 2009 11:51:47 -0500 Subject: [Ovirt-devel] Re: Rebased patches, fixed a rebasing problem... In-Reply-To: <4B2BAFC5.3090403@redhat.com> References: <1260306834-32625-1-git-send-email-dpierce@redhat.com> <20091218161357.GK7205@mcpierce-desktop.usersys.redhat.com> <4B2BAFC5.3090403@redhat.com> Message-ID: <20091218165147.GL7205@mcpierce-desktop.usersys.redhat.com> On Fri, Dec 18, 2009 at 05:37:25PM +0100, Alan Pevec wrote: > Darryl L. Pierce wrote: > >On Tue, Dec 08, 2009 at 04:13:52PM -0500, Darryl L. Pierce wrote: > >>The previous patch set had an error and one development branch's changes > >>showed up twice, and two different change sets. So it was missing the bulk > >>of the configuration work. This patch set fixes that. > > > >If there are no objections, I'm going to push these upstream now and > >we'll fix any issues that come up afterward. > > ACK - I already pushed when I was flushing my patch queue, but forgot to reply here. > Please verify I picked the right patch versions: > > http://git.fedorahosted.org/git/ovirt/?p=ovirt/node.git;a=commitdiff;h=0727dd3b45347ba3b70c5536065819a4e9b7034c > http://git.fedorahosted.org/git/ovirt/?p=ovirt/node.git;a=commitdiff;h=5470e00f914214db77739a405708bc6f07c9f616 That seems to be one step back from the last one I pushed. I had a change in changehost.py that both showed the current remote host and also had better handling when a host is selected but becomes unavailable. I'll rebase and add those changes. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Delivering value year after year. Red Hat ranks #1 in value among software vendors. http://www.redhat.com/promo/vendor/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: not available URL: From ufm at ufm.su Sun Dec 20 11:38:39 2009 From: ufm at ufm.su (Fyodor Ustinov) Date: Sun, 20 Dec 2009 13:38:39 +0200 Subject: [Ovirt-devel] Install oVirt in fc11/fc12 Message-ID: <4B2E0CBF.8000708@ufm.su> Hi. Show you how to install oVirt in FC11/FC12? I acted on instructions http://ovirt.et.redhat.com/install-instructions.html, but there were problems with the versions of the module locale (requires 2.0.4 and installed 2.0.5). WBR, Fyodor. From apevec at gmail.com Mon Dec 21 08:45:12 2009 From: apevec at gmail.com (Alan Pevec) Date: Mon, 21 Dec 2009 09:45:12 +0100 Subject: [Ovirt-devel] [RFC][PATCH v2] edit-livecd : fail on error in arbitrary code In-Reply-To: <4B2DBB43.4030302@linux.vnet.ibm.com> References: <4AF96D92.4090503@linux.vnet.ibm.com> <4AFB30B9.2020607@redhat.com> <4AFD1A73.5020904@linux.vnet.ibm.com> <4B17954D.8010205@linux.vnet.ibm.com> <4B179690.9060907@linux.vnet.ibm.com> <4B272866.5010008@linux.vnet.ibm.com> <2be7262f0912150136i40580142y2905fbf13da62338@mail.gmail.com> <4B2DBB43.4030302@linux.vnet.ibm.com> Message-ID: <2be7262f0912210045k553d3370o167509d9e9b3b570@mail.gmail.com> Hi, On Sun, Dec 20, 2009 at 6:50 AM, fishy wrote: > Thank You Alan, I however did not find the said patch in here > http://git.et.redhat.com/?p=ovirt-node-image.git;a=summary > > Is there some place else its supposed to go ? two things: - we moved oVirt GIT repositories to Fedorahosted, mapping is http://git.et.redhat.com/?p=ovirt-.git;a=summary -> http://git.fedorahosted.org/git/ovirt/?p=ovirt/.git;a=summary i.e. node repositories: http://git.fedorahosted.org/git/ovirt/?p=ovirt/node.git;a=summary http://git.fedorahosted.org/git/ovirt/?p=ovirt/node-image.git;a=summary - node-image scripts are now in http://git.fedorahosted.org/git/ovirt/?p=ovirt/node.git;a=tree;f=tools;hb=next node-image.git is now just a wrapper to include oVirt node image: http://git.fedorahosted.org/git/ovirt/?p=ovirt/node-image.git;a=blob;f=README;hb=next Please bear with us while we're updating documentation to reflect those changes. Thanks, Alan Pevec -------------- next part -------------- An HTML attachment was scrubbed... URL: From jboggs at redhat.com Mon Dec 21 16:13:03 2009 From: jboggs at redhat.com (Joey Boggs) Date: Mon, 21 Dec 2009 11:13:03 -0500 Subject: [Ovirt-devel] [PATCH] If the specified ISO does not exist, then the script dies. In-Reply-To: <1260891249-3681-1-git-send-email-dpierce@redhat.com> References: <1260891249-3681-1-git-send-email-dpierce@redhat.com> Message-ID: <4B2F9E8F.10501@redhat.com> On 12/15/2009 10:34 AM, Darryl L. Pierce wrote: > Before any tests are run, the ISO is checked and if it doesn't exist > then the script exits with an explicit failure. > > Signed-off-by: Darryl L. Pierce > --- > autotest.sh | 4 ++++ > 1 files changed, 4 insertions(+), 0 deletions(-) > > diff --git a/autotest.sh b/autotest.sh > index c67931a..904b961 100755 > --- a/autotest.sh > +++ b/autotest.sh > @@ -723,6 +723,10 @@ done > isoname=$(basename $isofile) > isofile="$(cd `dirname $isofile`; pwd)/${isoname}" > > +if ! [ -s "${isofile}" ]; then > + die "Missing or invalid file: ${isofile}" > +fi > + > shift $(($OPTIND - 1)) > > set +u > ACK From jboggs at redhat.com Mon Dec 21 16:13:14 2009 From: jboggs at redhat.com (Joey Boggs) Date: Mon, 21 Dec 2009 11:13:14 -0500 Subject: [Ovirt-devel] [PATCH] The autotest timeout is now a command line configurable option. In-Reply-To: <1260888464-32652-1-git-send-email-dpierce@redhat.com> References: <1260888464-32652-1-git-send-email-dpierce@redhat.com> Message-ID: <4B2F9E9A.4080009@redhat.com> On 12/15/2009 09:47 AM, Darryl L. Pierce wrote: > By default it's 120 ms, but can be changed through command line > arguments. > > Signed-off-by: Darryl L. Pierce > --- > autotest.sh | 16 ++++++++++------ > 1 files changed, 10 insertions(+), 6 deletions(-) > > diff --git a/autotest.sh b/autotest.sh > index c67931a..bcd9bd5 100755 > --- a/autotest.sh > +++ b/autotest.sh > @@ -62,6 +62,7 @@ Usage: $ME [-n test_name] [LOGFILE] > -i: set the ISO filename (defualt: ovirt-node-image.iso) > -n: the name of the specific autotest to run (default: run all autotests) > -d: enable more verbose output (default: disabled) > + -t: change the timeout between markers (in ms, default: 120) > -v: enable tracing (default: disabled) > -w: launch virt-viewer for each VM (default: no window shown) > -h: display this help and exit > @@ -484,7 +485,7 @@ test_stateless_pxe () { > boot_with_pxe "${nodename}" "standalone firstboot=no" "${workdir}" > > expect -c ' > -set timeout 120 > +set timeout '${timeout_period}' > > log_file -noappend stateless-pxe.log > > @@ -526,7 +527,7 @@ test_stateless_pxe_with_nohd () { > boot_with_pxe "${nodename}" "firstboot=no" "${workdir}" > > expect -c ' > -set timeout 120 > +set timeout '${timeout_period}' > > log_file -noappend stateless-pxe.log > > @@ -575,7 +576,7 @@ test_stateful_pxe () { > > # verify the booting and installation > expect -c ' > -set timeout 120 > +set timeout '${timeout_period}' > log_file -noappend stateful-pxe.log > > spawn sudo virsh console '"${nodename}"' > @@ -608,7 +609,7 @@ exit 3' > boot_from_hd "${nodename}" > > expect -c ' > -set timeout 120 > +set timeout '${timeout_period}' > log_file stateful-pxe.log > > send_log "Restarted node, booting from hard disk.\n" > @@ -704,13 +705,15 @@ isofile="${PWD}/ovirt-node-image.iso" > show_viewer=false > vm_prefix="$$" > preserve_vm=false > +timeout_period="120" > > -while getopts di:n:pvwh c; do > +while getopts di:n:pt:vwh c; do > case $c in > d) debugging=true;; > i) isofile=($OPTARG);; > n) tests=($OPTARG);; > - p) preserve_vm=true;; > + p) preserve_vm=true;; > + t) timeout_period=($OPTARG);; > v) set -v;; > w) show_viewer=true;; > h) usage; exit 0;; > @@ -738,6 +741,7 @@ log "Logging results to file: ${RESULTS}" > > log "Begin Testing: ${isoname}" > log "Tests: ${tests}" > + log "Timeout: ${timeout_period} ms" > > for test in ${tests}; do > execute_test $test > ACK From dpierce at redhat.com Mon Dec 21 16:24:46 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Mon, 21 Dec 2009 11:24:46 -0500 Subject: [Ovirt-devel] [PATCH] If the specified ISO does not exist, then the script dies. In-Reply-To: <4B2F9E8F.10501@redhat.com> References: <1260891249-3681-1-git-send-email-dpierce@redhat.com> <4B2F9E8F.10501@redhat.com> Message-ID: <20091221162446.GC23399@mcpierce-desktop.usersys.redhat.com> On Mon, Dec 21, 2009 at 11:13:03AM -0500, Joey Boggs wrote: > On 12/15/2009 10:34 AM, Darryl L. Pierce wrote: > >Before any tests are run, the ISO is checked and if it doesn't exist > >then the script exits with an explicit failure. > > > >Signed-off-by: Darryl L. Pierce > >--- > > autotest.sh | 4 ++++ > > 1 files changed, 4 insertions(+), 0 deletions(-) > > > >diff --git a/autotest.sh b/autotest.sh > >index c67931a..904b961 100755 > >--- a/autotest.sh > >+++ b/autotest.sh > >@@ -723,6 +723,10 @@ done > > isoname=$(basename $isofile) > > isofile="$(cd `dirname $isofile`; pwd)/${isoname}" > > > >+if ! [ -s "${isofile}" ]; then > >+ die "Missing or invalid file: ${isofile}" > >+fi > >+ > > shift $(($OPTIND - 1)) > > > > set +u > ACK Thank you. This is now pushed upstream. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Delivering value year after year. Red Hat ranks #1 in value among software vendors. http://www.redhat.com/promo/vendor/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: not available URL: From dpierce at redhat.com Mon Dec 21 16:25:47 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Mon, 21 Dec 2009 11:25:47 -0500 Subject: [Ovirt-devel] [PATCH] The autotest timeout is now a command line configurable option. In-Reply-To: <4B2F9E9A.4080009@redhat.com> References: <1260888464-32652-1-git-send-email-dpierce@redhat.com> <4B2F9E9A.4080009@redhat.com> Message-ID: <20091221162547.GD23399@mcpierce-desktop.usersys.redhat.com> On Mon, Dec 21, 2009 at 11:13:14AM -0500, Joey Boggs wrote: > On 12/15/2009 09:47 AM, Darryl L. Pierce wrote: > >By default it's 120 ms, but can be changed through command line > >arguments. > > > >Signed-off-by: Darryl L. Pierce > >--- > > autotest.sh | 16 ++++++++++------ > > 1 files changed, 10 insertions(+), 6 deletions(-) > > > >diff --git a/autotest.sh b/autotest.sh > >index c67931a..bcd9bd5 100755 > >--- a/autotest.sh > >+++ b/autotest.sh > >@@ -62,6 +62,7 @@ Usage: $ME [-n test_name] [LOGFILE] > > -i: set the ISO filename (defualt: ovirt-node-image.iso) > > -n: the name of the specific autotest to run (default: run all autotests) > > -d: enable more verbose output (default: disabled) > >+ -t: change the timeout between markers (in ms, default: 120) > > -v: enable tracing (default: disabled) > > -w: launch virt-viewer for each VM (default: no window shown) > > -h: display this help and exit > >@@ -484,7 +485,7 @@ test_stateless_pxe () { > > boot_with_pxe "${nodename}" "standalone firstboot=no" "${workdir}" > > > > expect -c ' > >-set timeout 120 > >+set timeout '${timeout_period}' > > > > log_file -noappend stateless-pxe.log > > > >@@ -526,7 +527,7 @@ test_stateless_pxe_with_nohd () { > > boot_with_pxe "${nodename}" "firstboot=no" "${workdir}" > > > > expect -c ' > >-set timeout 120 > >+set timeout '${timeout_period}' > > > > log_file -noappend stateless-pxe.log > > > >@@ -575,7 +576,7 @@ test_stateful_pxe () { > > > > # verify the booting and installation > > expect -c ' > >-set timeout 120 > >+set timeout '${timeout_period}' > > log_file -noappend stateful-pxe.log > > > > spawn sudo virsh console '"${nodename}"' > >@@ -608,7 +609,7 @@ exit 3' > > boot_from_hd "${nodename}" > > > > expect -c ' > >-set timeout 120 > >+set timeout '${timeout_period}' > > log_file stateful-pxe.log > > > > send_log "Restarted node, booting from hard disk.\n" > >@@ -704,13 +705,15 @@ isofile="${PWD}/ovirt-node-image.iso" > > show_viewer=false > > vm_prefix="$$" > > preserve_vm=false > >+timeout_period="120" > > > >-while getopts di:n:pvwh c; do > >+while getopts di:n:pt:vwh c; do > > case $c in > > d) debugging=true;; > > i) isofile=($OPTARG);; > > n) tests=($OPTARG);; > >- p) preserve_vm=true;; > >+ p) preserve_vm=true;; > >+ t) timeout_period=($OPTARG);; > > v) set -v;; > > w) show_viewer=true;; > > h) usage; exit 0;; > >@@ -738,6 +741,7 @@ log "Logging results to file: ${RESULTS}" > > > > log "Begin Testing: ${isoname}" > > log "Tests: ${tests}" > >+ log "Timeout: ${timeout_period} ms" > > > > for test in ${tests}; do > > execute_test $test > ACK Thanks. This is now pushed upstream. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Delivering value year after year. Red Hat ranks #1 in value among software vendors. http://www.redhat.com/promo/vendor/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: not available URL: From dpierce at redhat.com Mon Dec 21 16:49:47 2009 From: dpierce at redhat.com (Darryl L. Pierce) Date: Mon, 21 Dec 2009 11:49:47 -0500 Subject: [Ovirt-devel] [PATCH] Fixed errors when the user selects a different remove libvirt host. Message-ID: <1261414187-2481-1-git-send-email-dpierce@redhat.com> Now the app will show the current connection. When the user selects a different host then any connection exception is caught and the previous connection restored. Signed-off-by: Darryl L. Pierce --- nodeadmin/changehost.py | 6 ++++-- nodeadmin/configscreen.py | 5 ++++- nodeadmin/libvirtworker.py | 16 +++++++++++++++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/nodeadmin/changehost.py b/nodeadmin/changehost.py index 23e6854..f604c03 100644 --- a/nodeadmin/changehost.py +++ b/nodeadmin/changehost.py @@ -27,7 +27,10 @@ CONNECTED_PAGE = 2 class ChangeHostConfigScreen(HostListConfigScreen): def __init__(self): - HostListConfigScreen.__init__(self, "Change Host") + HostListConfigScreen.__init__(self, "") + + def get_title(self): + return "Currently: %s" % self.get_libvirt().get_url() def get_elements_for_page(self, screen, page): if page is CONNECTION_LIST_PAGE: return self.get_connection_list_page(screen) @@ -36,7 +39,6 @@ class ChangeHostConfigScreen(HostListConfigScreen): def process_input(self, page): if page is CONNECTION_LIST_PAGE: logging.info("Changing libvirt connection to %s" % self.get_selected_connection()) - libvirtworker.set_default_url(self.get_selected_connection()) self.get_libvirt().open_connection(self.get_selected_connection()) elif page is CONNECTED_PAGE: self.set_finished() diff --git a/nodeadmin/configscreen.py b/nodeadmin/configscreen.py index 02ab5b4..7a23325 100644 --- a/nodeadmin/configscreen.py +++ b/nodeadmin/configscreen.py @@ -37,6 +37,9 @@ class ConfigScreen: self.__libvirt = LibvirtWorker() self.__vm_config = VirtManagerConfig() + def get_title(self): + return self.__title + def get_hal(self): return self.__hal @@ -83,7 +86,7 @@ class ConfigScreen: screen = SnackScreen() elements = self.get_elements_for_page(screen, self.__current_page) # TODO: need to set the form height to the number of elements on the page - gridform = GridForm(screen, self.__title, 1, 10) + gridform = GridForm(screen, self.get_title(), 1, 10) current_element = 0 for element in elements: gridform.add(element, 0, current_element) diff --git a/nodeadmin/libvirtworker.py b/nodeadmin/libvirtworker.py index b35509f..3338f80 100644 --- a/nodeadmin/libvirtworker.py +++ b/nodeadmin/libvirtworker.py @@ -74,6 +74,8 @@ class LibvirtWorker: def __init__(self, url = None): if url is None: url = get_default_url() logging.info("Connecting to libvirt: %s" % url) + self.__url = None + self.__conn = None self.open_connection(url) self.__capabilities = virtinst.CapabilitiesParser.parse(self.__conn.getCapabilities()) self.__net = virtinst.VirtualNetworkInterface(conn = self.__conn) @@ -84,9 +86,21 @@ class LibvirtWorker: '''Returns the underlying connection.''' return self.__conn + def get_url(self): + return self.__url + def open_connection(self, url): '''Lets the user change the url for the connection.''' - self.__conn = libvirt.open(url) + old_conn = self.__conn + old_url = self.__url + try: + self.__conn = libvirt.open(url) + self.__url = url + set_default_url(url) + except Exception, error: + self.__conn = old_conn + self.__url = old_url + raise error def list_domains(self, defined = True, started = True): '''Lists all domains.''' -- 1.6.5.2 From mburns at redhat.com Tue Dec 22 22:01:40 2009 From: mburns at redhat.com (Mike Burns) Date: Tue, 22 Dec 2009 17:01:40 -0500 Subject: [Ovirt-devel] ovirt.org In-Reply-To: <4B28FB32.3060102@redhat.com> References: <20091216161944.861577ljx8rp2xe8@webmail2.provincia.torino.it> <4B28FB32.3060102@redhat.com> Message-ID: <1261519300.3763.312.camel@localhost.localdomain> On Wed, 2009-12-16 at 10:22 -0500, Joey Boggs wrote: > On 12/16/2009 10:19 AM, ignazio.cassano at provincia.torino.it wrote: > > Hello , > > anyone can tell me why ovirt.org site is not reachable ? > > Thanks > > Ignazio > > > > _______________________________________________ > > Ovirt-devel mailing list > > Ovirt-devel at redhat.com > > https://www.redhat.com/mailman/listinfo/ovirt-devel > > > DNS issues from what I hear, you can get to it via ovirt.et.redhat.com > in the meantime. > > _______________________________________________ > Ovirt-devel mailing list > Ovirt-devel at redhat.com > https://www.redhat.com/mailman/listinfo/ovirt-devel ovirt.org is available again. Sorry for the inconvenience From gfortaine at live.com Sat Dec 26 10:17:08 2009 From: gfortaine at live.com (Guillaume FORTAINE) Date: Sat, 26 Dec 2009 11:17:08 +0100 Subject: [Ovirt-devel] oVirtBIOS : Virtualization Firmware Message-ID: Misters, Let me introduce myself : Guillaume FORTAINE, Engineer in Computer Science. Me and my partners are currently working on a Virtualization Firmware. After an analysis of the various solutions (Citrix, VMware and Microsoft), it seemed natural to our eyes, to enable a true bare-metal hypervisor, to go as close as possible to the hardware, hence the BIOS. That's why we are currently going further since the first successful prototype of the coreboot GSOC project AVATT (All Virtual All The Time) [1] [2]. Coreboot is an open source hardware initialization firmware. It does some basic hardware init, then hands over control to one of many possible payloads. This Google Summer of Code sponsored project suggested the idea of implementing a Linux kernel with KVM (Kernel Virtual Machine to provide Type I Hypervisor abilities to Linux) as a coreboot payload (=Virtualization inside the BIOS). In a second step, we plan to put also oVirt as virtual machine management software stack to have an Enterprise-Grade Virtualization Firmware. However, we would greatly appreciate to ask you a few questions and we would greatly appreciate that you enlighten us, if possible, please. 1) Would it be possible to have an oVirt From Scratch ? To quote [3] : "Image building is heavily based on Fedora-ish features like kickstart and livecd-creator, this will be significant effort to port to equivalent Debian tools." 2) Would it fit in 32 MBytes, without a kernel, by tuning the build process (eGlibc [4] + ruby-mini [5] + Gcc -Os + Lzma for rootfs) ? 3) Do we need a writeable Flash chip ? 4) What would be the needed Red Hat resources (time/people/funding) to fulfil the above requests and to complete the Roadmap [6] to have an Enterprise-Grade oVirt Stack ? 5) And to conclude, our last and most important question : as IT Professionals, would you appreciate to have an oVirtBIOS inside your Hardware ? To quote [7] : "There's actually a lot to be said for the embedded hypervisor. Lots of IT environments--especially enterprise ones--do indeed have a mix of operating systems and operating system versions. Given that, there is indeed a lot to be said for the idea that hypervisors just come with the server as a sort of superset to the firmware, like BIOS, already loaded on every system. Then IT administrators could just configure any guest OSs they want on top." One of my partner has already done a successful Linux + KVM BIOS prototype and to include oVirt is the logical next step. We are already in discussion with several OEMs to have a convenient Hardware Platform (especially with IOMMU [8] to provide high-performance I/O inside the virtual machines) This is Firmware Engineering at the highest-level, not 'marketing fluff' like Citrix Xen for OEMs or VMWare ESXi, because it would be the first true Bare-Metal Hypervisor in the World and we definitely believe that it could revolutionize the industry. Merry Christmas, We look forward to your answer, Best Regards, Guillaume FORTAINE [1] http://www.coreboot.org/AVATT [2] http://www.slideshare.net/majeru/all-virtual-all-the-time [3] https://www.redhat.com/archives/ovirt-devel/2009-September/msg00107.html [4] http://www.eglibc.org [5] https://dev.openwrt.org/browser/packages/lang/ruby [6] http://ovirt.et.redhat.com/milestones.html [7] http://news.cnet.com/8301-13556_3-10170884-61.html [8] http://www.ibm.com/developerworks/linux/library/l-pci-passthrough/index.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From dennisml at conversis.de Sat Dec 26 12:40:27 2009 From: dennisml at conversis.de (Dennis J.) Date: Sat, 26 Dec 2009 13:40:27 +0100 Subject: [Ovirt-devel] oVirtBIOS : Virtualization Firmware In-Reply-To: References: Message-ID: <4B36043B.6020800@conversis.de> On 12/26/2009 11:17 AM, Guillaume FORTAINE wrote: [ SNIP] > > This is Firmware Engineering at the highest-level, not 'marketing fluff' > like Citrix Xen for OEMs > or VMWare ESXi, because it would be the first true Bare-Metal Hypervisor > in the World and > we definitely believe that it could revolutionize the industry. Why should I care? Don't get me wrong the idea sound interesting but I don't really see why it is so vitally important to put the HV right into the BIOS. The problem is that you loose support for a lot of hardware that cannot be booted with coreboot. Earlier this year we had to come up with a virtualization solution to host 80 VMs quickly and our first shot was VMWare ESX but that failed because ESX refused to work with the commodity hardware we were using. So we went with RHEL Xen instead which works beautifully on pretty much any system precisely because it isn't so closely wedded to any particular hardware. I think using a regular BIOS that boots a minimal Kernel/Initrd from a flash chip gives you pretty much the same benefits of a tiny footprint but actually works with pretty much every machine out there. Regards, Dennis From apevec at gmail.com Sun Dec 27 12:30:19 2009 From: apevec at gmail.com (Alan Pevec) Date: Sun, 27 Dec 2009 13:30:19 +0100 Subject: [Ovirt-devel] oVirtBIOS : Virtualization Firmware In-Reply-To: <4B36043B.6020800@conversis.de> References: <4B36043B.6020800@conversis.de> Message-ID: <2be7262f0912270430i20ff9779i837466311a505411@mail.gmail.com> On Sat, Dec 26, 2009 at 1:40 PM, Dennis J. wrote: > On 12/26/2009 11:17 AM, Guillaume FORTAINE wrote: ...snip... > I think using a regular BIOS that boots a minimal Kernel/Initrd from a flash > chip gives you pretty much the same benefits of a tiny footprint but > actually works with pretty much every machine out there. That's exactly the idea of oVirt Node - use standard Fedora packages in order to keep Fedora QA and hardware support. We specifically avoided busybox, uClib and such, and image should still fit in 128MB flash - I mean, can you really buy <128MB flash these days? There's also PXE boot option, then you don't need locally stored image at all. Alan From gfortaine at live.com Sun Dec 27 16:28:17 2009 From: gfortaine at live.com (Guillaume FORTAINE) Date: Sun, 27 Dec 2009 17:28:17 +0100 Subject: [Ovirt-devel] oVirtBIOS : (High-Performance) Virtualization Firmware Message-ID: Dear Dennis, > Why should I care? Don't get me wrong the idea sound interesting but I > don't really see why it is so vitally important to put the HV right > into the BIOS. The problem is that you loose support for a lot of > hardware that cannot be booted with coreboot. Our engineering solution comes from a real world problem : faulty firmware (BIOS or UEFI) implementations prevent efficient I/O Virtualization. To quote David Woodhouse, lead Intel embedded software developer for the Linux Kernel and principal maintainer of the file drivers/pci/intel-iommu.c [0] ( Intel's I/O Virtualization, to provide high performance inside the virtual machines ) [1] : "Well done, Dell and HP -- although I didn't think it was possible, you have _further_ lowered my already-unprintable opinion of closed source BIOSes and BIOS engineers" "We _really_ need open source firmware. Or at _least_ firmware written by competent engineers -- but I think we've all fairly much given up on that happening by now?" Many commits of the file intel-iommu.c are related to BIOS bugs [2] [3] [4] [5] [6] [7]. And it is evident that Intel will not be able to test each firmware version on each IOMMU capable Hardware. By ensuring a full use of hardware capabilities inside Virtual Machines, through a custom Virtualization Firmware, it lowers the TCO (Total Cost of Ownership), thus requiring less frequent hardware upgrades that can be substantial saves on a large scale volume or a critical requirement for budget aware customers. > Earlier this year we had to come up with a virtualization solution to > host 80 VMs quickly and our first shot was VMWare ESX but that failed > because ESX refused to work with the commodity hardware we were using. > So we went with RHEL Xen instead which works beautifully on pretty > much any system precisely because it isn't so closely wedded to any > particular hardware. > I think using a regular BIOS that boots a minimal Kernel/Initrd from a > flash chip gives you pretty much the same benefits of a tiny footprint > but actually works with pretty much every machine out there. We would greatly appreciate to invite you to a further reading of this Phoronix article entitled : "KVM Virtualization Performance With Linux 2.6.31" [8] : "The disk benchmarks took a large hit when running Ubuntu 9.10 "Karmic Koala" within a virtual machine using KVM, but that is to no surprise considering the setup." "Benchmarking Apache with the Kernel-based Virtual Machine took a huge performance hit," Our engineering target is to achieve 1:1 parity in terms of performance between real-hardware and a virtual machine. Each product has specific needs that is why we are very pleased that you were satisfied by your Virtualization Solution, to quote : "So we went with RHEL Xen instead which works beautifully", however it will not be the case for performance and budget aware customers. Best Regards, Guillaume FORTAINE [0] http://git.infradead.org/iommu-2.6.git/blob/e0fc7e0b4b5e69616f10a894ab9afff3c64be74e:/drivers/pci/intel-iommu.c [1] http://patchwork.kernel.org/patch/42841/ [2] http://git.infradead.org/iommu-2.6.git/commit/e0fc7e0b4b5e69616f10a894ab9afff3c64be74e [3] http://git.infradead.org/iommu-2.6.git/commit/2ff729f5445cc47d1910386c36e53fc6b1c5e47a [4] http://git.infradead.org/iommu-2.6.git/commit/6ecbf01c7ce4c0f4c3bdfa0e64ac6258328fda6c [5] http://git.infradead.org/iommu-2.6.git/commit/5854d9c8d18359b1fc2f23c0ef2d51dd53281bd6 [6] http://git.infradead.org/iommu-2.6.git/commit/86cf898e1d0fca245173980e3897580db38569a8 [7] http://git.infradead.org/iommu-2.6.git/commit/0815565adfe3f4c369110c57d8ffe83caefeed68 [8] http://www.phoronix.com/scan.php?page=article&item=linux_2631_kvm&num=6 -------------- next part -------------- An HTML attachment was scrubbed... URL: From ovirt at proinbox.com Sun Dec 27 18:14:14 2009 From: ovirt at proinbox.com (ovirt at proinbox.com) Date: Sun, 27 Dec 2009 13:14:14 -0500 Subject: [Ovirt-devel] I'm all for it Message-ID: <1261937654.12375.1351893309@webmail.messagingengine.com> Hello all- First off I'm not a dev, just a small business owner trying to start up. I don't have a budget for much of anything & wind up doing most everything myself, which for the last year includes evaluating virtual infrastructure offerings. It's quite discouraging to see just how much doesn't "just work" for someone like me- unfortunately oVirt included (no firmware package to initialize Broadcom NetXtreme II's on the standalone iso). I usually move on when "build" is mentioned & have no aspirations to learn git & thus, testing oVirt's on pause until a new iso's released. Not to mention how it feels to hit a feature paywall after tinkering a few days with something. I'd very much like to try something like what Mr. Fortaine's speaking of, & I hope to see it realized one day, in a way that wouldn't require someone like me to hire a consultant to implement. Just my 2 cents. -Chris Bartels President / CEO Nocturnal Feast From pmyers at redhat.com Mon Dec 28 19:39:34 2009 From: pmyers at redhat.com (Perry Myers) Date: Mon, 28 Dec 2009 14:39:34 -0500 Subject: [Ovirt-devel] I'm all for it In-Reply-To: <1261937654.12375.1351893309@webmail.messagingengine.com> References: <1261937654.12375.1351893309@webmail.messagingengine.com> Message-ID: <4B390976.9040800@redhat.com> On 12/27/2009 01:14 PM, ovirt at proinbox.com wrote: > Hello all- > > First off I'm not a dev, just a small business owner trying to start up. > I don't have a budget for much of anything & wind up doing most > everything myself, which for the last year includes evaluating virtual > infrastructure offerings. > > It's quite discouraging to see just how much doesn't "just work" for > someone like me- unfortunately oVirt included (no firmware package to > initialize Broadcom NetXtreme II's on the standalone iso). I usually > move on when "build" is mentioned & have no aspirations to learn git & > thus, testing oVirt's on pause until a new iso's released. oVirt is an open source community driven project and like most upstream stuff it requires a fair amount of technical aptitude to get running. We are working to try to make it easier to use, but there is definitely a difference between upstream projects that you can download and use for free and productized versions of those projects where you have a company offering formal documentation, training and support. The phrase, 'you get what you pay for' comes to mind. :) To the specific issue that you mentioned: Is the driver firmware for that particular network card open sourced and included in Fedora? If not (i.e. if it's a proprietary firmware) then it can't be included by default in oVirt Node since it would probably violate licensing. We do have a tool called edit-livecd that can be used to insert things like additional proprietary RPMs into an existing ISO, but the insertion of these proprietary RPMs/firmwares would need to be done by the end user (again due to licensing). If it's not in the Node presently because we're just not including a package that is needed from the standard Fedora repos, please let us know what packages you need and we can add them in. Also, as we have said in the past: patches and requests for features are welcome. oVirt Node is a community driven project, so we can only provide the features that the community helps us to define, prioritize and build. > Not to mention how it feels to hit a feature paywall after tinkering a > few days with something. > > I'd very much like to try something like what Mr. Fortaine's speaking > of, & I hope to see it realized one day, in a way that wouldn't require > someone like me to hire a consultant to implement. I'm not 100% sure I understand what Mr. Fortaine is getting at from the emails he has sent out. (i.e. I'm not sure if he is driving at a particular usage model of oVirt Node or if he is advocating a BIOS HV implementation) There are two solutions for an 'embedded hypervisor' that I can see: 1. open source BIOS that implements HV capabilities 2. stripped down Linux using KVM that can run in minimal footprint and be embedded on system flash or PXE booted oVirt Node project is focused on #2 above. #1 is an interesting idea, but is outside the scope of this project and also outside the scope of our technical capabilities presently. Thanks, Perry From dennisml at conversis.de Tue Dec 29 01:08:43 2009 From: dennisml at conversis.de (Dennis J.) Date: Tue, 29 Dec 2009 02:08:43 +0100 Subject: [Ovirt-devel] I'm all for it In-Reply-To: <4B390976.9040800@redhat.com> References: <1261937654.12375.1351893309@webmail.messagingengine.com> <4B390976.9040800@redhat.com> Message-ID: <4B39569B.8000402@conversis.de> On 12/28/2009 08:39 PM, Perry Myers wrote: > On 12/27/2009 01:14 PM, ovirt at proinbox.com wrote: >> Hello all- >> >> First off I'm not a dev, just a small business owner trying to start up. >> I don't have a budget for much of anything& wind up doing most >> everything myself, which for the last year includes evaluating virtual >> infrastructure offerings. >> >> It's quite discouraging to see just how much doesn't "just work" for >> someone like me- unfortunately oVirt included (no firmware package to >> initialize Broadcom NetXtreme II's on the standalone iso). I usually >> move on when "build" is mentioned& have no aspirations to learn git& >> thus, testing oVirt's on pause until a new iso's released. > > oVirt is an open source community driven project and like most upstream > stuff it requires a fair amount of technical aptitude to get running. We > are working to try to make it easier to use, but there is definitely a > difference between upstream projects that you can download and use for > free and productized versions of those projects where you have a company > offering formal documentation, training and support. The phrase, 'you get > what you pay for' comes to mind. :) When is oVirt going to reach a stability that makes it possible to consider it for deployment? Right now it seems to be too much in flux to roll it out in any serious way. What is the roadmap for the project? Regards, Dennis From tom at sarkoon.com Tue Dec 29 04:02:50 2009 From: tom at sarkoon.com (Thomas Samson) Date: Mon, 28 Dec 2009 20:02:50 -0800 Subject: [Ovirt-devel] Install oVirt in fc11/fc12 Message-ID: <4B397F6A.8040108@sarkoon.com> I apologize in advance if I'm responding to this thread inappropriately, as I just subscribed to this mailing list in order to add to this discussion topic. I'm not a developer, but I am interested in creating clusters of stateless nodes using ovirt and hope to contribute in the form of feedback and bug reports. Fyodor Ustinov wrote: > Show you how to install oVirt in FC11/FC12? I acted on instructions > http://ovirt.et.redhat.com/install-instructions.html, but there were > problems with the versions of the module locale (requires 2.0.4 and > installed 2.0.5). I am also having difficulty installing ovirt using the current instructions, though I believe I've gotten further than you have. After multiple days of troubleshooting and reinstalling I finally managed to get the web interface up at https://adminserver/ovirt, however it only shows the Tasks section and the event "500 Internal Server Error" appears over and over again. To fix your locale module issue, see the gem commands in my list of steps below. Can someone help us get this working? Any help would be appreciated! Here are the steps I performed in order to get this far. Is there an easier way to install ovirt than this? > boot from Fedora-11-x86_64-DVD.iso and install Base system > service NetworkManager stop > chkconfig NetworkManager off > chkconfig network on > configure /etc/sysconfig/network-scripts/ifcfg-eth0 and ifcfg-eth1 > with static ip addresses > add default gateway to /etc/sysconfig/network > add search domains and nameservers to /etc/resolv.conf > service network restart > yum update > edit /etc/selinux/config to set selinux to permissive > yum install ovirt-server ovirt-server-installer livecd-tools > gem install locale -v 2.0.4 > gem install locale_rails -v 2.0.4 > gem install gettext -v 2.0.4 > gem install gettext_rails -v 2.0.4 > gem install gettext_activerecord -v 2.0.4 > gem uninstall gettext_rails -v 2.1.0 > gem uninstall gettext_activerecord -v 2.1.0 > gem uninstall gettext -v 2.1.0 > gem uninstall locale_rails -v 2.0.5 > gem uninstall locale -v 2.0.5 > gem uninstall actionmailer -v 2.3.5 > gem uninstall actionpack -v 2.3.5 > gem uninstall activerecord -v 2.3.5 > gem uninstall activeresource -v 2.3.5 > gem uninstall activesupport -v 2.3.5 > wget > http://ovirt.org/repos/ovirt/11/x86_64/ovirt-node-image-1.0.2-1.fc11.x86_64.rpm > wget > http://ovirt.org/repos/ovirt/11/x86_64/ovirt-node-image-pxe-1.0.2-1.fc11.x86_64.rpm > rpm -ivh ovirt-node-image-1.0.2-1.fc11.x86_64.rpm > rpm -ivh ovirt-node-image-pxe-1.0.2-1.fc11.x86_64.rpm > ovirt-install (respond to the interactive prompts as the installation > instructions suggest) > yum install perl-Mozilla-LDAP mozldap-tools lm_sensors-devel > net-snmp-devel openssl-devel > rpm -ivh > http://kojipkgs.fedoraproject.org/packages/fedora-ds-base/1.2.0/4.fc11/x86_64/fedora-ds-base-1.2.0-4.fc11.x86_64.rpm > ace -v -l logfile.txt install ovirt > reboot -Tom From stanislav.ievlev at gmail.com Tue Dec 29 07:27:11 2009 From: stanislav.ievlev at gmail.com (Stanislav Ievlev) Date: Tue, 29 Dec 2009 10:27:11 +0300 Subject: [Ovirt-devel] Q: ovirt and lease manager Message-ID: Greetings! Has Ovirt an own lease manager? It it possible to use Ovirt with some extrernal lease manager like Haizei (http://haizea.cs.uchicago.edu/whatis.html)? -- With best regards Stanislav Ievlev From gfortaine at live.com Tue Dec 29 07:31:01 2009 From: gfortaine at live.com (Guillaume FORTAINE) Date: Tue, 29 Dec 2009 08:31:01 +0100 Subject: [Ovirt-devel] Ganeti from Google (was Re : I'm all for it) In-Reply-To: <4B39569B.8000402@conversis.de> References: <1261937654.12375.1351893309@webmail.messagingengine.com> <4B390976.9040800@redhat.com> <4B39569B.8000402@conversis.de> Message-ID: Misters, > When is oVirt going to reach a stability that makes it possible to > consider it for deployment? Right now it seems to be too much in flux > to roll it out in any serious way. What is the roadmap for the project? I would greatly appreciate to have your comments about this open source project used by Google in a production environment, if possible, please : http://code.google.com/p/ganeti/ What is Ganeti Ganeti is a cluster virtual server management software tool built on top of existing virtualization technologies such as Xen or KVM and other Open Source software. Ganeti requires pre-installed virtualization software on your servers in order to function. Once installed, the tool will take over the management part of the virtual instances (Xen DomU), e.g. disk creation management, operating system installation for these instances (in co-operation with OS-specific install scripts), and startup, shutdown, failover between physical systems. It has been designed to facilitate cluster management of virtual servers and to provide fast and simple recovery after physical failures using commodity hardware. Features Ganeti provides the following features for managed instances: -Support for Xen virtualization: Support for PVM and HVM instances Live migration support Virtual console (on PVM) or VNC (on HVM) to control instances Support for virtio or emulated devices -Support for KVM virtualization: (from Ganeti 2.0) Live migration support Support for fully virtualized instances Support for semi-virtualized instances (kernel residing on the host) Support for VNC or serial access Support for virtio or emulated devices -Recommended cluster size 1-40 physical nodes -Disk management: Plain LVM volumes Files (from Ganeti 2.0) across-the-network raid1 (using DRBD) for quick recovery in case of physical system failure -Instance disk partitioning supported from Ganeti 2.0 -Export/import mechanism for backup purposes or migration between clusters From gfortaine at live.com Tue Dec 29 07:39:23 2009 From: gfortaine at live.com (Guillaume FORTAINE) Date: Tue, 29 Dec 2009 08:39:23 +0100 Subject: [Ovirt-devel] I'm all for it In-Reply-To: <4B390976.9040800@redhat.com> References: <1261937654.12375.1351893309@webmail.messagingengine.com> <4B390976.9040800@redhat.com> Message-ID: > I'm not 100% sure I understand what Mr. Fortaine is getting at from the > emails he has sent out. (i.e. I'm not sure if he is driving at a > particular usage model of oVirt Node or if he is advocating a BIOS HV > implementation) > We are advocating a BIOS HV implementation.This design proposal come from 3 engineering concerns : a) Performance Faulty firmware (BIOS or UEFI) implementations prevent efficient I/O Virtualization. To quote David Woodhouse, lead Intel embedded software developer for the Linux Kernel and principal maintainer of the file drivers/pci/intel-iommu.c [3] ( Intel's I/O Virtualization, to provide high performance I/O inside the virtual machines ) [4] : "Well done, Dell and HP -- although I didn't think it was possible, you have _further_ lowered my already-unprintable opinion of closed source BIOSes and BIOS engineers. We _really_ need open source firmware. Or at _least_ firmware written by competent engineers -- but I think we've all fairly much given up on that happening by now?" Because many commits of the file intel-iommu.c are related to BIOS bugs [5] [6] [7] [8] [9] [10]. And it is evident that Intel will not be able to test each firmware version on each IOMMU capable Hardware. By the way, we would greatly appreciate to invite you to a further reading of this Phoronix article entitled : "Intel Core i7 Virtualization Performance" [11] on a X58 chipset (with IOMMU support, according to the Xen wiki) [12] : "Linux's Kernel-based Virtual Machine performed quite well in a number of tests when compared to the host OS speed and VirtualBox, but particularly when it came to the disk-related tests KVM did not fair well at all." The engineering target is to achieve 1:1 parity in terms of performance between real-hardware and a virtual machine. By ensuring a full use of hardware capabilities inside the Virtual Machines, through a custom Virtualization Firmware, it lowers the TCO (Total Cost of Ownership), thus requiring less frequent hardware upgrades that can be substantial saves on a large scale volume or a critical requirement for budget aware customers. b) Out-of-the-box support By compiling a custom Linux Kernel inside the Firmware, we can ensure full Hardware Support, skipping painful devices incompatibilities, thus providing the best out-of-the-box experience. To quote [13]: "Hello all- First off I'm not a dev, just a small business owner trying to start up. I don't have a budget for much of anything & wind up doing most everything myself, which for the last year includes evaluating virtual infrastructure offerings. It's quite discouraging to see just how much doesn't "just work" for someone like me- unfortunately oVirt included (no firmware package to initialize Broadcom NetXtreme II's on the standalone iso). I usually move on when "build" is mentioned & have no aspirations to learn git & thus, testing oVirt's on pause until a new iso's released. Not to mention how it feels to hit a feature paywall after tinkering a few days with something. I'd very much like to try something like what Mr. Fortaine's speaking of, & I hope to see it realized one day, in a way that wouldn't require someone like me to hire a consultant to implement. Just my 2 cents. -Chris Bartels President / CEO Nocturnal Feast" c) Cost By leveraging Open Source Technology, we could provide a solution at the fraction of the cost than the current ones, especially VMWare ESX Server (2250 USD) and Microsoft Server 2008 R2 with Hyper-V (2500 USD) [14] Indeed, two Volume x86 servers with a BIOS HV will cost the equivalent of a licence for 1 VMWare/Microsoft Hypervisor. Best Regards, Guillaume FORTAINE [3] http://git.infradead.org/iommu-2.6.git/blob/e0fc7e0b4b5e69616f10a894ab9afff3c64be74e:/drivers/pci/intel-iommu.c [4] http://patchwork.kernel.org/patch/42841/ [5] http://git.infradead.org/iommu-2.6.git/commit/e0fc7e0b4b5e69616f10a894ab9afff3c64be74e [6] http://git.infradead.org/iommu-2.6.git/commit/2ff729f5445cc47d1910386c36e53fc6b1c5e47a [7] http://git.infradead.org/iommu-2.6.git/commit/6ecbf01c7ce4c0f4c3bdfa0e64ac6258328fda6c [8] http://git.infradead.org/iommu-2.6.git/commit/5854d9c8d18359b1fc2f23c0ef2d51dd53281bd6 [9] http://git.infradead.org/iommu-2.6.git/commit/86cf898e1d0fca245173980e3897580db38569a8 [10] http://git.infradead.org/iommu-2.6.git/commit/0815565adfe3f4c369110c57d8ffe83caefeed68 [11] http://www.phoronix.com/scan.php?page=article&item=intel_corei7_virt&num=6 [12] http://wiki.xensource.com/xenwiki/VTdHowTo [13] https://www.redhat.com/archives/ovirt-devel/2009-December/msg00063.html [14] http://www.virtualization.info/2009/11/red-hat-releases-enterprise.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From is at eseco.de Tue Dec 29 09:01:39 2009 From: is at eseco.de (Ingmar Schraub) Date: Tue, 29 Dec 2009 10:01:39 +0100 Subject: [Ovirt-devel] Ganeti from Google (was Re : I'm all for it) In-Reply-To: References: <1261937654.12375.1351893309@webmail.messagingengine.com> <4B390976.9040800@redhat.com> <4B39569B.8000402@conversis.de> Message-ID: <4B39C573.5070809@eseco.de> Guillaume FORTAINE wrote: > Misters, > >> When is oVirt going to reach a stability that makes it possible to >> consider it for deployment? Right now it seems to be too much in flux >> to roll it out in any serious way. What is the roadmap for the project? > > I would greatly appreciate to have your comments about this open source > project used by Google in a production environment, if possible, please : > > http://code.google.com/p/ganeti/ Does ganeti provide a decent web based management solution? (I am not familiar with Ganeti, just wondering...). There is the ganeti-gui project. But it hasn't released any code yet and is just a single person project apparently. There are always the same set of questions: - who is using this technology? - for what purpose is it used? - what are the goals of the project? Maybe someone doesn't need a web management solution (or any GUI-based solution) at all. Maybe then ovirt is an overkill. Maybe someone is looking for an embedded solution or even adding KVM&Co. to the BIOS onto the flash. Those are all different possibilities and targets. I don't think, that one project for any requirement makes sense. I think, ovirt has a great potential. But it takes more time to make it usable for average users. I gave it a try some months ago. I struggled as well, but it gave me a nice impression. Maybe you could give ganeti a try and report back here? If neither existing open source project is what you are looking for, why not starting your own one? Regards, Ingmar From gfortaine at live.com Tue Dec 29 12:35:30 2009 From: gfortaine at live.com (Guillaume FORTAINE) Date: Tue, 29 Dec 2009 13:35:30 +0100 Subject: [Ovirt-devel] Ganeti from Google (was Re : I'm all for it) In-Reply-To: <4B39C573.5070809@eseco.de> References: <1261937654.12375.1351893309@webmail.messagingengine.com> <4B390976.9040800@redhat.com> <4B39569B.8000402@conversis.de> <4B39C573.5070809@eseco.de> Message-ID: On 12/29/2009 10:01 AM, Ingmar Schraub wrote: > Maybe you could give ganeti a try and report back here? > > http://blog.cosmicegg.net/2009/11/installing-ganeti-cluster-hardware.html Installing a Ganeti cluster - Hardware built I finally "got" what Ganeti is and decided to create my own test bed to try it out. For the most part, Ganeti manages xen domu's using DRBD for redundancy. By default, DRBD only allows two nodes to replicate data (usually for a fail over cluster). So if you have a virtual machine on ServerA and it fails, you can fail your virtual machine over to ServerB. What Ganeti allows you to do though is to then designate ServerC as the next fail over node, sets up DRBD, and begins syncing between the two. There are some great slides about this in the PDF file at the Ganeti site. I was able to build up three servers out of spare parts around the office and have begun to configure them for use. They each have two 64 bit procs and eight gigs of ram. I made 700 gig disk space available using RAID 5, but I might have been better off with no raid from what I'm reading in the install doc (better IO). Already it's been a nice learning experience for me, as I learned about reducing the amount of resources Dom0 takes up. The install guide is for Debian, but I'm trying to make it work for my CentOS 5.4 systems. So far so goo From pmyers at redhat.com Tue Dec 29 13:23:19 2009 From: pmyers at redhat.com (Perry Myers) Date: Tue, 29 Dec 2009 08:23:19 -0500 Subject: [Ovirt-devel] I'm all for it In-Reply-To: References: <1261937654.12375.1351893309@webmail.messagingengine.com> <4B390976.9040800@redhat.com> Message-ID: <4B3A02C7.4040206@redhat.com> On 12/29/2009 02:39 AM, Guillaume FORTAINE wrote: > >> I'm not 100% sure I understand what Mr. Fortaine is getting at from the >> emails he has sent out. (i.e. I'm not sure if he is driving at a >> particular usage model of oVirt Node or if he is advocating a BIOS HV >> implementation) >> > > We are advocating a BIOS HV implementation.This design proposal come > from 3 engineering concerns : I agree that there is a good case for trying to move this functionality into BIOS/firmware. However, as I stated earlier that is not what the oVirt Node project is working on at the current time. As Ingmar suggested earlier in this thread, if oVirt isn't the project that meets your needs, and what you need (BIOS HV implementation) isn't in our roadmap, then perhaps starting a new open source project to accomplish this makes sense. Thanks, Perry From tom at sarkoon.com Wed Dec 30 20:58:45 2009 From: tom at sarkoon.com (Thomas Samson) Date: Wed, 30 Dec 2009 12:58:45 -0800 Subject: [Ovirt-devel] Install oVirt in fc11/fc12 In-Reply-To: <4B397F6A.8040108@sarkoon.com> References: <4B397F6A.8040108@sarkoon.com> Message-ID: <4B3BBF05.6020705@sarkoon.com> Thomas Samson wrote: > I am also having difficulty installing ovirt using the current > instructions, though I believe I've gotten further than you have. > After multiple days of troubleshooting and reinstalling I finally > managed to get the web interface up at https://adminserver/ovirt, > however it only shows the Tasks section and the event "500 Internal > Server Error" appears over and over again. I still haven't been able to resolve this error. The server's daily LogWatch email shows this: 500 Internal Server Error /ovirt/tree/return_filtered_list: 3256 Time(s) This is what I see: TIA, -Tom