From 5a5b16857a83eebc53add88cb38c454a191fe7f6 Mon Sep 17 00:00:00 2001 From: jbjohnso Date: Sun, 31 May 2009 18:52:35 +0000 Subject: [PATCH] -Add some modules to hold common plugin and virtualization plugin routines git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@3460 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- perl-xCAT/xCAT/Common.pm | 133 +++++++++++++++++++++++++++++++++++++ perl-xCAT/xCAT/VMCommon.pm | 36 ++++++++++ 2 files changed, 169 insertions(+) create mode 100644 perl-xCAT/xCAT/Common.pm create mode 100644 perl-xCAT/xCAT/VMCommon.pm diff --git a/perl-xCAT/xCAT/Common.pm b/perl-xCAT/xCAT/Common.pm new file mode 100644 index 000000000..3844243fd --- /dev/null +++ b/perl-xCAT/xCAT/Common.pm @@ -0,0 +1,133 @@ +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html + +#This contains functions common to most plugins + +package xCAT::Common; + +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} + + +# forward_data is a function used to aggregate output passed up from a set of +# children. This is commonly used due to make absolutely certain multiple +# writers trying to use a common file descriptor wouldn't corrupt each other. +# So instead, each child is given a dedicated filehandle and the parent +# uses this function to organize child data and send it up. +# locking might be a more straightforward approach, but locking experiments +# weren't as successful. +sub forward_data { + my $callback = shift; + my $fds = shift; + my @ready_fds = $fds->can_read(1); + my $rfh; + my $rc = @ready_fds; + foreach $rfh (@ready_fds) { + my $data; + if ($data = <$rfh>) { + while ($data !~ /ENDOFFREEZE6sK4ci/) { + $data .= <$rfh>; + } + eval { print $rfh "ACK\n"; }; #Ignore ack loss due to child giving up and exiting, we don't actually explicitly care about the acks + my $responses=thaw($data); + foreach (@$responses) { + $callback->($_); + } + } else { + $fds->remove($rfh); + close($rfh); + } + } + yield; #Try to avoid useless iterations as much as possible + return $rc; +} + +#This function pairs with the above. +#It either accepts pre-structured responses or the common ':' delimeted description/value pairs +#for example: +# send_data('n1',"Temperature: cold","Voltage: normal"); #report normal text, two pieces of data +# send_data('n1',[1,"Timeout communicationg with foobar]); #Report an error with a code +# send_data({},{}); +sub send_data { + my $node; + if (not ref $_[0]) { + $node = shift; + } + foreach(@_) { + my %output; + if (ref($_) eq HASH) { + print $out freeze([$_]); + print $out "\nENDOFFREEZE6sK4ci\n"; + yield(); + waitforack($out); + next; + } + my $line; + my $rc; + if (ref($_) eq ARRAY) { + $rc = $_->[0]; + $line = $_->[1]; + } else { + $line = $_; + } + + + (my $desc,my $text) = split (/:/,$line,2); + unless ($text) { + $text=$desc; + } else { + $desc =~ s/^\s+//; + $desc =~ s/\s+$//; + if ($desc) { + $output{node}->[0]->{data}->[0]->{desc}->[0]=$desc; + } + } + $text =~ s/^\s+//; + $text =~ s/\s+$//; + $output{node}->[0]->{name}->[0]=$node; + if ($rc) { + $output{node}->[0]->{errorcode} = $rc; + $output{node}->[0]->{error}->[0]->{contents}->[0]=$text; + } else { + $output{node}->[0]->{data}->[0]->{contents}->[0]=$text; + } + print $out freeze([\%output]); + print $out "\nENDOFFREEZE6sK4ci\n"; + yield(); + waitforack($out); + } +} + +#This function is intended to be used to process a request through the usage +#module. +sub usage_noderange { + my $request = shift; + my $callback=shift; + + #display usage statement if -h is present or no noderage is specified + my $noderange = $request->{node}; #Should be arrayref + my $command = $request->{command}->[0]; + my $extrargs = $request->{arg}; + my @exargs=($request->{arg}); + if (ref($extrargs)) { + @exargs=@$extrargs; + } + + my $usage_string=xCAT::Usage->parseCommand($command, @exargs); + if ($usage_string) { + $callback->({data=>$usage_string}); + $request = {}; + return; + } + + if (!$noderange) { + $usage_string="Missing Noderange\n"; + $usage_string .=xCAT::Usage->getUsage($command); + $callback->({data=>$usage_string}); + $request = {}; + return; + } +} + +1; diff --git a/perl-xCAT/xCAT/VMCommon.pm b/perl-xCAT/xCAT/VMCommon.pm new file mode 100644 index 000000000..0ddd38aa9 --- /dev/null +++ b/perl-xCAT/xCAT/VMCommon.pm @@ -0,0 +1,36 @@ +package xCAT::VMCommon; +use strict; +#Functions common to virtualization management (KVM, Xen, VMware) +sub grab_table_data{ #grab table data relevent to VM guest nodes + my $noderange=shift; + my $cfghash = shift; + my $callback=shift; + my $vmtab = xCAT::Table->new("vm"); + my $hmtab = xCAT::Table->new("nodehm"); + my $nttab = xCAT::Table->new("nodetype"); + if ($hmtab) { + $cfghash->{nodehm} = $hmtab->getNodesAttribs($noderange,['serialspeed']); + } + if ($nttab) { + $cfghash->{nodetype} = $nttab->getNodesAttribs($noderange,['os']); #allow us to guess RTC config + } + unless ($vmtab) { + $callback->({data=>["Cannot open vm table"]}); + return; + } + $cfghash->{vm} = $vmtab->getNodesAttribs($noderange,['node','host','migrationdest','storage','memory','cpus','nics','bootorder','virtflags']); + my $mactab = xCAT::Table->new("mac",-create=>1); + my $nrtab= xCAT::Table->new("noderes",-create=>1); + $cfghash->{mac} = $mactab->getAllNodeAttribs(['mac'],1); + my $macs; + my $mac; + foreach (keys %{$cfghash->{mac}}) { + $macs=$cfghash->{mac}->{$_}->[0]->{mac}; + foreach $mac (split /\|/,$macs) { + $mac =~ s/\!.*//; + $cfghash->{usedmacs}->{lc($mac)}=1; + } + } +} + +1;