-Working clonevm for both directiors for kvm

git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@7314 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
jbjohnso 2010-08-30 21:01:35 +00:00
parent 9bea5c5075
commit efb2a9b5a4

View File

@ -151,7 +151,6 @@ sub get_storage_pool_by_url {
#ok, it is netfs, now check source..
my $checkhost = $pool->findnodes("/pool/source/host")->[0]->getAttribute("name");
my $checkpath = $pool->findnodes("/pool/source/dir")->[0]->getAttribute("path");
print "$checkhost eq $host and $checkpath eq $path\n"; #) { #TODO: check name resolution to see if they match really even if not strictly the same
if ($checkhost eq $host and $checkpath eq $path) { #TODO: check name resolution to see if they match really even if not strictly the same
last;
}
@ -1455,8 +1454,7 @@ sub promote_vm_to_master {
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);
my $tmpnod = $parsedxml->findnodes('/domain/uuid/text()')->[0]->setData("none"); #get rid of the VM specific uuid
$target =~ /^(.*)\/([^\/]*)\z/;
my $directory=$1;
@ -1555,6 +1553,7 @@ sub promote_vm_to_master {
$mastertabentry->{$_}=$confdata->{vm}->{$node}->[0]->{$_};
}
}
$mastertabentry->{storage}=$directory;
$mastertabentry->{vintage}=localtime;
$mastertabentry->{originator}=$requester;
$updatetable->{vmmaster}->{$mastername}=$mastertabentry;
@ -1585,7 +1584,6 @@ sub clonevm {
}
sub clone_vm_from_master {
=cut
my %args = @_;
my $base=$args{base};
my $vmmastertab=xCAT::Table->new('vmmaster',-create=>0);
@ -1603,33 +1601,94 @@ sub clone_vm_from_master {
return;
}
my $newnodexml = $parser->parse_string($kvmmasteref->{xml});
if ($masterref->{nics} and $masterref->{nics} ne $confdata->{vm}->{$node}->[0]->{nics}) {
$confdata->{vm}->{$node}->[0]->{nics}=$masterref->{nics};
$updatetable->{vm}->{$node}->{nics}=$masterref->{nics};
$newnodexml->findnodes("/domain/name/text()")->[0]->setData($node); #set name correctly
my $uuid=getNodeUUID($node);
$newnodexml->findnodes("/domain/uuid/text()")->[0]->setData($uuid); #put in correct uuid
#set up mac addresses and such right...
fixup_clone_network(mastername=>$mastername,mastertableentry=>$masteref,kvmmastertableentry=>$kvmmasteref,xmlinprogress=>$newnodexml);
#ok, now the fun part, storage...
my $disk;
my $url;
if ($confdata->{vm}->{$node}->[0]->{storage}) {
unless ($confdata->{vm}->{$node}->[0]->{storage} =~ /^nfs:/) {
die "not implemented";
}
$url = $confdata->{vm}->{$node}->[0]->{storage};
} else {
$url = $masteref->{storage};
$updatetable->{vm}->{$node}->{storage}=$url;
}
$confdata->{vm}->{$node}->[0]->{nics}=$masteref->{nics};
if ($masteref->{storagemodel} and not $confdata->{vm}->{$node}->[0]->{storagemodel}) {
$updatetable->{vm}->{$node}->{storagemodel}=$masteref->{storagemodel};
}
$url =~ s/,.*//;
my $destinationpool = get_storage_pool_by_url($url);
foreach $disk ($newnodexml->findnodes("/domain/devices/disk")) {
my $srcfilename = $disk->findnodes("./source")->[0]->getAttribute("file");
my $filename = $srcfilename;
$filename =~ s/^.*$mastername/$node/;
$filename =~ m!\.([^\.]*)\z!;
my $format=$1;
my $newbasexml="<volume><name>$filename</name><target><format type='$format'/></target><capacity>0</capacity><backingStore><path>$srcfilename</path><format type='$format'/></backingStore></volume>";
my $newvol = $destinationpool->create_volume($newbasexml);
my $newfilename=$newvol->get_path();
$disk->findnodes("./source")->[0]->setAttribute("file"=>$newfilename);
}
my $textxml=$newnodexml->toString();
$updatetable->{kvm_nodedata}->{$node}->{xml}=$textxml;
}
sub build_nicstruct {
if ($confdata->{vm}->{$node}->[0]->{nics}) {
......
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/text()')->[0];
$tmpnod->setData($mastername); #name the xml whatever the master name is to be
foreach ($parsedxml->findnodes("/domain/devices/interface/mac")) { #clear all mac addresses
if ($_->hasAttribute("address")) { $_->setAttribute("address"=>''); }
sub fixup_clone_network {
my %args = @_;
my $newnodexml = $args{xmlinprogress};
my $mastername=$args{mastername};
my $masteref=$args{mastertableentry};
my $kvmmasteref=$args{kvmmastertableentry};
unless (ref ($confdata->{vm}->{$node})) {
$confdata->{vm}->{$node}=[{nics=>$masteref->{nics}}];
$updatetable->{vm}->{$node}->{nics}=$masteref->{nics};
}
unless ($confdata->{vm}->{$node}->[0]->{nics}) { #if no nic configuration yet, take the one stored in the master
$confdata->{vm}->{$node}->[0]->{nics}=$masteref->{nics};
$updatetable->{vm}->{$node}->{nics}=$masteref->{nics};
}
my @nics;
if ($confdata->{vm}->{$node}->[0]->{nics}) { #could still be empty if it came from master that way
@nics = split /,/,$confdata->{vm}->{$node}->[0]->{nics};
} else {
@nics = ('virbr0');
}
my @nicsinmaster = $newnodexml->findnodes("/domain/devices/interface");
if (scalar @nicsinmaster > scalar @nics) { #we don't have enough places to attach nics to..
xCAT::SvrUtils::sendmsg([1,"KVM master $mastername has ".scalar @nicsinmaster." but this vm only has ".scalar @nics." defined"], $callback,$node);
return;
}
my $nicstruct;
my @macs=xCAT::VMCommon::getMacAddresses($confdata,$node,scalar @nics);
foreach $nicstruct (@nicsinmaster) {
my $bridge = shift @nics;
$bridge =~ s/.*://;
$bridge =~ s/=.*//;
$nicstruct->findnodes("./mac")->[0]->setAttribute("address"=>shift @macs);
$nicstruct->findnodes("./source")->[0]->setAttribute("bridge"=>$bridge);
}
my $nic;
my $deviceroot=$newnodexml->findnodes("/domain/devices")->[0];
foreach $nic (@nics) { #need more xml to throw at it..
my $type = 'e1000'; #better default fake nic than rtl8139, relevant to most
$nic =~ s/.*://; #the detail of how the bridge was built is of no
#interest to this segment of code
if ($confdata->{vm}->{$node}->[0]->{nicmodel}) {
$type = $confdata->{vm}->{$node}->[0]->{nicmodel};
}
if ($nic =~ /=/) {
($nic,$type) = split /=/,$nic,2;
}
my $xmlsnippet = "<interface type='bridge'><mac address='".(shift @macs)."'/><source bridge='".$nic."'/><model type='$type'/></interface>";
my $chunk = $parser->parse_balanced_chunk($xmlsnippet);
$deviceroot->appendChild($chunk);
}
=cut
}
sub mkvm {
shift; #Throuw away first argument
@ -2107,7 +2166,7 @@ sub process_request {
$callback->({error=>"Can't find ".join(",",keys %orphans),errorcode=>[1]});
return;
}
} elsif ($command eq "mkvm") { #must adopt to create
} elsif ($command eq "mkvm" or $command eq "clonevm") { #must adopt to create
unless (adopt(\%orphans,\%hyphash)) {
$callback->({error=>"Can't find ".join(",",keys %orphans),errorcode=>[1]});
return 1;