From 99c824e2f901d0ae33846693a70c66f3fa8da590 Mon Sep 17 00:00:00 2001 From: jbjohnso Date: Fri, 27 Aug 2010 23:46:06 +0000 Subject: [PATCH] -Starting the clonevm implementation in earnest git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@7288 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- perl-xCAT/xCAT/Schema.pm | 15 +++++- perl-xCAT/xCAT/VMCommon.pm | 3 +- xCAT-server/lib/xcat/plugins/kvm.pm | 77 +++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 2 deletions(-) diff --git a/perl-xCAT/xCAT/Schema.pm b/perl-xCAT/xCAT/Schema.pm index a6c3a1216..68e1664ac 100644 --- a/perl-xCAT/xCAT/Schema.pm +++ b/perl-xCAT/xCAT/Schema.pm @@ -70,7 +70,7 @@ domain => { }, }, ############################################################################### -# This is a table for kvm plugin to use to maintain persistent config data +# The next two are for kvm plugin to use to maintain persistent config data # not feasibly determined from contextual data ############################################################################### kvm_nodedata => { @@ -88,6 +88,19 @@ kvm_nodedata => { disable => "Set to 'yes' or '1' to comment out this row.", }, }, +kvm_masterdata => { + cols => [qw(name xml comments disable)], + keys => [qw(name)], + table_desc=>'Persistant store for KVM plugin for masters', + types => { + xml => 'VARCHAR(16000)', + }, + descriptions => { + name => 'The name of the relevant master', + xml => 'The XML description to be customized for clones of this master', + disable => "Set to 'yes' or '1' to comment out this row.", + }, +}, #domains => { diff --git a/perl-xCAT/xCAT/VMCommon.pm b/perl-xCAT/xCAT/VMCommon.pm index 5a33666e5..40fa4fcd7 100644 --- a/perl-xCAT/xCAT/VMCommon.pm +++ b/perl-xCAT/xCAT/VMCommon.pm @@ -16,7 +16,8 @@ sub grab_table_data{ #grab table data relevent to VM guest nodes $cfghash->{nodehm} = $hmtab->getNodesAttribs($noderange,['serialspeed']); } if ($nttab) { - $cfghash->{nodetype} = $nttab->getNodesAttribs($noderange,['os','arch']); #allow us to guess RTC config + $cfghash->{nodetype} = $nttab->getNodesAttribs($noderange,['os','arch','profile']); #allow us to guess RTC config + #also needed for vmware guestid and also data for vmmaster } unless ($vmtab) { $callback->({data=>["Cannot open vm table"]}); diff --git a/xCAT-server/lib/xcat/plugins/kvm.pm b/xCAT-server/lib/xcat/plugins/kvm.pm index a664e7b6b..296d69835 100644 --- a/xCAT-server/lib/xcat/plugins/kvm.pm +++ b/xCAT-server/lib/xcat/plugins/kvm.pm @@ -60,6 +60,7 @@ my $mactab; my %usedmacs; my $status_noop="XXXno-opXXX"; my $callback; +my $requester; #used to track the user sub handled_commands { #unless ($libvirtsupport) { @@ -1410,6 +1411,79 @@ sub get_disks_by_userspecs { return @returnxmls; } +sub clonevm { + shift; #throw away node + @ARGV=@_; + my $target; + my $base; + my $detach; + my $force; + GetOptions( + 'f' => \$force, + 'b=s' => \$base, + 't=s' => \$target, + 'd' => \$detach, + ); + if ($base and $target) { + xCAT::SvrUtils::sendmsg([1,"Cannot specify both base (-b) and target (-t)"], $callback,$node); + return; + } + if ($target) { #we need to take a single vm and create a master out of it + unless ($target =~ /^nfs:\/\//) { + xCAT::SvrUtils::sendmsg([1,"KVM plugin only has nfs://// support at this moment"], $callback,$node); + return; + } + my $dom; + eval { + $dom = $hypconn->get_domain_by_name($node); + }; + if ($dom and not $force) { + xCAT::SvrUtils::sendmsg([1,"VM shut be shut down before attempting to clone (-f to copy unclean disks)"], $callback,$node); + return; + } + my $xml; + if ($dom) { + $xml = $dom->get_xml_description(); + } else { + $xml = $confdata->{kvm_nodedata}->{$node}->[0]->{xml}; + } + unless ($xml) { + xCAT::SvrUtils::sendmsg([1,"VM must be created before it can be cloned"], $callback,$node); + return; + } + my $parsedxml = $parser->parse_string($xml); + my $tmpnod = $parsedxml->findnodes('/domain/uuid')->[0]; #get rid of the VM specific uuid + $tmpnod->parentNode->removeChild($tmpnod); + + $target =~ /^(.*)\/([^\/]*)\z/; + my $directory=$1; + my $mastername=$2; + + $tmpnod = $parsedxml->findnodes('/domain/name')->[0]; + $tmpnod->setData($mastername); #name the xml whatever the master name is to be + my $poolobj = get_storage_pool_by_url($directory); + unless ($poolobj) { + xCAT::SvrUtils::sendmsg([1,"unable to reach $directory from hypervisor"], $callback,$node); + return; + } + #arguments validated, on with our lives + my $xmltemplate = + my $mastertabentry={}; + foreach (qw/os arch profile/) { + if (defined ($confdata->{nodetype}->{$node}->[0]->{$_})) { + $mastertabentry->{$_}=$confdata->{nodetype}->{$node}->[0]->{$_}; + } + } + foreach (qw/storagemodel nics/) { + if (defined ($confdata->{vm}->{$node}->[0]->{$_})) { + $mastertabentry->{$_}=$confdata->{vm}->{$node}->[0]->{$_}; + } + } + $mastertabentry->{vintage}=localtime; + $mastertabentry->{originator}=$requester; + } +} + sub mkvm { shift; #Throuw away first argument @ARGV=@_; @@ -1677,6 +1751,9 @@ sub process_request { %hypstats=(); %offlinevms=(); my $request = shift; + if ($request->{_xcat_authname}->[0]) { + $requester=$request->{_xcat_authname}->[0]; + } $callback = shift; unless ($libvirtsupport) { $libvirtsupport = eval {