add back the csm to xcat migration tools

git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/branches/2.8@15810 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
lissav 2013-04-03 13:16:56 +00:00
parent 811829c9b5
commit 99dd2a7520
2 changed files with 1092 additions and 0 deletions

View File

@ -0,0 +1,362 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
#
#####################################################
# cfm2xcat:
#
# This routine will read in cfmupdatenode distribution files
# and build the files need to input to xdcp rsync function
# in xCAT.
#
# cfm2xcat will run cfmupdatenode -a, it sets the environment
# variable CSM_CFM_SAVE_DISTFILE to the file path input with the -i option
# to save the built cfm distribution file(s).
# These are normally deleted after cfm runs.
#
# cfm2xcat will then take the files that were created from calling
# cfmupdatenode and create xCAT xdcp files synch files and store them in the
# path input with the -o flag.
#
# Example:
# cfm2xcat -i <...cfmsave> -o < path to output file>
# cfm2xcat -i /tmp/cfmsave -o /tmp/xcat/xcatdistfile
#
# The routine will process all the /.../cfmsave* files and when finished,
# you will have the new files xcatdistfile* and noderange* generated which
# will be the correct format to input to the xdcp -F command in xCAT to run
# the equivalent syncing of files that you were running on CSM.
#
# Take the files in the /tmp/xcat/* directory from the example above and
# place on your xCAT Management Node. Then run for each file combination:
# xdcp ^/tmp/xcat/noderange1 -F /tmp/xcat/xcatdistfile1
# More information is in the manpage for cfm2xcat and xdcp
#####################################################
use strict;
use warnings;
use Getopt::Long;
use Data::Dumper;
my $help;
my $input;
my $output;
my $rc = 0;
if (
!GetOptions(
'h|help' => \$help,
'i|input=s' => \$input,
'o|output=s' => \$output,
)
)
{
&usage;
exit 1;
}
if ($help)
{
&usage;
exit 0;
}
if (!($input))
{
print "Input file path must be supplied with the -i flag.\n";
exit 1;
}
if (!($output))
{
print "Output file path and name must be supplied with the -o flag.\n";
exit 1;
}
# call cfmupdatenode and build cfm distribution files
&buildcfmdistfiles($input);
if (-e ($input)) # if anything built
{
# build the xcat sync files
$rc = &buildxcatrsyncfiles($input, $output);
if ($rc == 0)
{
print
"Conversion finished, please carefully review $output files! Make sure that all the files list to sync to the nodes are relevant and available on the xCAT system in the directory indicated. \n";
}
else
{
print " Error converting cfm file to xdcp files.\n";
}
}
else
{
print " Error building CFM dist files, or nothing to do.\n";
}
exit 0;
# end main
#
#
# Builds the CFM distribution files from the cfmupdatenode -a call
#
sub buildcfmdistfiles
{
my ($cfmfile) = @_;
my $cmd;
my @output;
# remove old files , if they exist
my $tmpcfmfile = $cfmfile;
if (-e ($tmpcfmfile))
{
$tmpcfmfile .= "*";
$cmd = "rm $tmpcfmfile";
@output = runcmd($cmd);
if ($::RUNCMD_RC != 0)
{
print " Error running $cmd.\n";
return 1;
}
}
# export the CSM_CFM_SAVE_DISTFILE variable to the input (-i)
# path, makes cfmupdatenode save the dist file(s) from the run in a
# file by that name
$cmd = "CSM_CFM_SAVE_DISTFILE=$cfmfile cfmupdatenode -a";
# run the cfmupdate command
@output = runcmd($cmd);
if ($::RUNCMD_RC != 0)
{
print " Error running $cmd.\n";
return 1;
}
else
{
return 0;
}
}
#
#
# Builds the xdcp sync files from the CFM dist files
#
sub buildxcatrsyncfiles
{
my ($CFMfiles, $xcatfile) = @_;
my $cmd;
my @output;
my %noderangequeue;
# remove old files, if they exist
my $tmpxcatfile = $xcatfile;
if (-e ($tmpxcatfile))
{
$tmpxcatfile .= "*";
$cmd = "rm $tmpxcatfile";
@output = runcmd($cmd);
if ($::RUNCMD_RC != 0)
{
print " Error running $cmd.\n";
return 1;
}
}
# get list of CFM files that were built
$cmd = "ls $CFMfiles";
$cmd .= "*";
my @CFMfilelist = runcmd($cmd);
if ($::RUNCMD_RC != 0)
{
print " Error running $cmd.\n";
return 1;
}
my $msg = "Building xCat rsync files $xcatfile from $CFMfiles\n";
print "$msg";
# For each CFM output file, open the CFM input file to read
foreach my $cfmfile (@CFMfilelist)
{
open(CFM, "< $cfmfile")
or die "Can't open $cfmfile for reading: $!";
#
# convert the CFM rdist format to the xdcp format for rsync
# build a hash of noderange -> to distribution files
#
while (my $line = <CFM>)
{
chomp $line;
if ($line =~ /^#/) # skip commments
{
next;
}
if ($line =~ /.runclocal/) # skip sending runclocal
{
next;
}
my ($sourcefile, $rest) = split("->", $line);
my ($tmpnodes, $destfile) = split("install", $rest);
# get rid of parenthesis
my ($paren, $tnodes) = split(/\(/, $tmpnodes);
my ($nodes, $paren2) = split(/\)/, $tnodes);
chomp $nodes;
# strip off /cfmroot and /var/opt/csm/cfmlocal paths
my ($root, $strippedsourcefile) = split("cfmroot", $sourcefile);
chomp $strippedsourcefile;
my ($root2, $strippeddestfile) = split("cfmlocal", $destfile);
chomp $strippeddestfile;
chop $strippeddestfile;
$noderangequeue{$nodes}{'files'}{$strippedsourcefile} =
$strippeddestfile;
}
close(CFM);
}
#
# now take the hash and build the xdcp file(s), key is the noderange
# (use short hostname)
# one for each noderange and a matching noderange file
# for example xdcpfile1 xdcpfile1.noderange
#
my $index;
foreach (keys %noderangequeue)
{
my $noderange = $_;
# open the xCAT output files to write
my $newxcatfilenr = $xcatfile;
$newxcatfilenr .= ".nr";
# file to hold the noderange
if ($index)
{ # processing more than one noderange then building
# more than one xdcp file
$newxcatfilenr .= "$index";
}
open(XCATNR, "> $newxcatfilenr")
or die "Can't open $newxcatfilenr for writing: $!";
# create an appropriate noderange ( comma seperated)
my @nodes = split(/ /, $noderange);
my $goodnr = "";
foreach my $node (@nodes)
{
if ($node !~ /^\s*$/)
{ #skip blanks
my @shorthost = split(/\./, $node);
$goodnr .= $shorthost[0];
$goodnr .= ",";
}
}
chop $goodnr;
# write into the noderange file
write_line_nr($goodnr);
write_line_nr("\n");
# file to hold the rsync interface file to file list
my $newxcatfile = $xcatfile;
# file to hold the noderange
if ($index)
{ # processing more than one noderange then building
# more than one xdcp file
$newxcatfile .= "$index";
}
open(XCAT, "> $newxcatfile")
or die "Can't open $newxcatfile for writing: $!";
my $srcfile;
my $destfile;
foreach my $sourcefile (keys %{$noderangequeue{$noderange}{'files'}})
{
$srcfile = $sourcefile;
$destfile = $noderangequeue{$noderange}{'files'}{$sourcefile};
write_line($srcfile);
write_line("-> ");
write_line($destfile);
write_line("\n");
}
close(XCAT);
close(XCATNR);
$index++;
}
return 0;
}
#
# runs the input command and handles the errors. Returns the output
#
sub runcmd
{
my ($cmd) = @_;
my $rc = 0;
$::RUNCMD_RC = 0;
my $outref = [];
@$outref = `$cmd`;
if ($?)
{
$rc = $?;
$::RUNCMD_RC = $rc;
if ($rc > 0)
{
my $msg = "$cmd returned rc=$rc @$outref\n";
print "$msg";
}
}
chomp(@$outref);
return @$outref;
}
sub usage
{
print "CFM distribution file to xCAT xdcp rsync migration facility.\n";
print "Usage:\n";
print "\t-h - usage\n";
print
"\t-i - Complete path to the CFM file(s) saved to be converted for xCAT.";
print " Be sure directory exists.\n";
print
"\t-o - Complete Path to the xCAT xdcp rsync input file(s) created from.";
print " the CFM file. Be sure directory exists.\n";
print
" Example: cfm2xcat -i /tmp/migration/cfmfiles -o /tmp/migration/xdcpfiles.";
print "\n";
return;
}
#
# write to xCAT rsync files
#
sub write_line
{
print XCAT @_;
}
#
# write to xCAT rsync noderange files
#
sub write_line_nr
{
print XCATNR @_;
}

View File

@ -0,0 +1,730 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
#
#####################################################
#
# This script will read the CSM database and build
# xCAT stanza files to be input into an xCAT database
# using the chdef command
# example node.stanza | chdef -z
#
#####################################################
use strict;
use warnings;
use Getopt::Long;
use Data::Dumper;
my $needhelp = 0;
my $directory = "/tmp/csm2xcat";
if (
!GetOptions("help" => \$needhelp,
"dir=s" => \$directory,)
)
{
&usage;
exit 1;
}
if ($needhelp)
{
&usage;
exit 0;
}
#Create the users choice directory
mkdir $directory unless -d $directory;
# create a log
open(LOG, ">$directory/conversion.log")
or die "Can't open logfile for writing: $!";
&log_this("Conversion started at " . scalar(localtime()));
# build the stanza files for the site table
# rsh/rcp attribute not longer supported. Leave logic here
# incase we decide there are other attribute needed
#&getSiteinfo;
# build the stanza files for the node
&getNodeinfo;
# build the stanza files for the devices
&getDevinfo;
log_this("Conversion finished at " . scalar(localtime()));
print
"Conversion finished, please carefully review $directory/conversion.log and check results in the $directory stanza files before using chdef -z to update the database!\n";
close(LOG);
exit 0;
# end main
#
# logger
#
sub log_this
{
print LOG join('', @_), "\n";
}
#
# write to stanza files
#
sub write_stanza
{
print STANZA @_;
}
#
# runs csmconfig or uses the csmconfig.output file
# and builds site table stanza file
#
sub getSiteinfo
{
log_this("Reading Site information\n");
print "Running csmconfg to read site info!\n";
# open the site stanza file
my $stanzafile = "$directory/site.stanza";
open(STANZA, ">$stanzafile")
or die "Can't open $stanzafile for writing: $!";
write_stanza("# <xCAT data object stanza file>\n\n");
write_stanza("clustersite:\n");
write_stanza(" objtype=site\n");
my @results;
my $cmd;
# use of file is for debug
my $csmconfiginfofile = "$directory/csmconfigdebug.output";
if (-e $csmconfiginfofile)
{ # use the imported file
$cmd = "cat $csmconfiginfofile";
log_this("Reading $csmconfiginfofile information\n");
@results = runcmd($cmd);
}
else
{ # run the command
$cmd = "/opt/csm/bin/csmconfig";
@results = runcmd($cmd);
}
if ($::RUNCMD_RC != 0)
{
my $msg = "Error processing csmconfig information\n";
log_this($msg);
print "$msg";
close(STANZA);
return;
}
foreach my $line (@results)
{
my $xcatline;
$line =~ s/\s*//g; #remove extra blanks
my ($attr, $value) = split(/=/, $line);
if ($attr eq "RemoteShell")
{
if ($value)
{
$xcatline = " rsh=";
$xcatline .= "$value\n";
}
}
if ($attr eq "RemoteCopyCmd")
{
if ($value)
{
$xcatline = " rcp=";
$xcatline .= "$value\n";
}
}
if ($xcatline)
{
write_stanza($xcatline);
}
}
close(STANZA);
return 0;
}
#
# runs lsnodes -l and build node stanza file
#
sub getNodeinfo
{
# open the node stanza file
my $stanzafile = "$directory/node.stanza";
open(STANZA, ">$stanzafile")
or die "Can't open $stanzafile for writing: $!";
write_stanza("# <xCAT data object stanza file\n");
log_this("Reading Node information\n");
print "Running lsnode -l for node info!\n";
my $OS = "";
my $GRP = "";
my $ARCH = "";
my $DISTNAME = "";
my @results;
my $cmd;
my $lsnodefile = "$directory/lsnodedebug.output";
# use of file is for debug
if (-e $lsnodefile)
{ # use the imported file
log_this("Reading $lsnodefile information\n");
$cmd = "cat $lsnodefile";
@results = runcmd($cmd);
}
else
{ # run the command
$cmd = "/opt/csm/bin/lsnode -l";
@results = runcmd($cmd);
}
if ($::RUNCMD_RC != 0)
{
my $msg = "Error processing lsnode information\n";
log_this($msg);
print "$msg";
close(STANZA);
return;
}
#
# build hash of lsnode info
#
my $output = buildNodehash(\@results);
my %nodehash = %$output;
my %attrhash;
my $nodename;
my $attributes;
# my $test = $nodehash{"c55n03.ppd.pok.ibm.com"}{"PowerStatus"};
while (($nodename, $attributes) = each %nodehash)
{
#
# build commonly needed attributes
#
%attrhash = %$attributes;
# get osname, distribution name for later
$OS = $attrhash{"InstallOSName"};
my $tmpname = $attrhash{"InstallDistributionName"};
$DISTNAME = lc($tmpname);
my $pkgarch = $attrhash{"InstallPkgArchitecture"};
if ($pkgarch)
{
if ($OS eq "LINUX")
{
$ARCH = $pkgarch; # save arch
}
else
{ #AIX
$ARCH = "ppc64";
}
}
#
# first process the nodename
#
my $value;
my $xcatline;
my $attr;
my $grplist = get_groups($nodename);
if (!(grep /compute/, $grplist))
{
$grplist .= ",compute";
}
if (!(grep /all/, $grplist))
{
$grplist .= ",all";
}
$GRP = $grplist; # save for setting up other tables
my $shortnodename = get_shortname($nodename);
$xcatline = "$shortnodename:\n"; # write node name
$xcatline .= " objtype=node\n";
if ($grplist)
{
$xcatline .= " groups=$grplist\n";
$xcatline .= " profile=compute\n";
}
$xcatline .= " status=defined\n";
if ($xcatline)
{
write_stanza($xcatline);
$xcatline = "";
}
#now process all the attributes associated with the nodename
#my $test = $attrhash{"InstallServer"};
#my $test1 = $attrhash{"Mode"};
while (($attr, $value) = each %$attributes)
{
#if ($attr eq "InstallServer")
#{
# if ($value)
# {
# $xcatline = " xcatmaster=$value\n";
# $xcatline .= " servicenode=$value\n";
#}
#}
# since we are suggesting that the xCAT MN is a different machine
# than the CSM MS, we will not use the Management Server value
#if ($attr eq "ManagementServer")
#{
# my $installserver = $attrhash{"InstallServer"};
# if ($installserver eq "") # if no install server, use MN
# {
# if ($value)
# {
# $xcatline = " xcatmaster=$value\n";
# }
# }
#}
if ($attr eq "InstallOSName")
{
if ($value)
{
if ($value eq "AIX")
{
$xcatline = " os=$value\n";
$xcatline .= " arch=ppc64\n";
}
}
}
if ($attr eq "InstallDistributionVersion")
{
if ( $value
&& $DISTNAME) # put together DistributeName and Version
{
$xcatline = " os=$DISTNAME";
$xcatline .= "$value\n";
}
}
if ($attr eq "InstallPkgArchitecture") # filled in for Linux
{
if ($value)
{
if ($OS eq "LINUX")
{
$xcatline = " arch=$value\n";
if ($value =~ /86/)
{
$xcatline .= " netboot=pxe\n";
}
if ($value =~ /ppc/)
{
$xcatline .= " netboot=yaboot\n";
}
}
}
}
if ($attr eq "HWControlPoint")
{
if ($value)
{
$xcatline = " hcp=$value\n";
}
}
if ($attr eq "LParID")
{
if ($ARCH =~ /ppc/)
{
if ($value)
{ # this is an LPAR
$xcatline = " id=$value\n";
$xcatline .= " hwtype=lpar\n";
$xcatline .= " nodetype=ppc\n";
}
}
}
if ($attr eq "ConsoleMethod")
{
if ($value)
{
$xcatline = " cons=$value\n";
}
}
if ($attr eq "ConsolePortNum")
{
if ($value)
{
$xcatline = " termport=$value\n";
}
}
if ($attr eq "PowerMethod")
{
if ($value)
{
if ($value eq "xseries")
{
$value = "ipmi";
}
$xcatline = " power=$value\n";
$xcatline .= " mgt=$value\n";
}
}
if ($attr eq "InstallAdapterMacaddr")
{
if ($value)
{
$xcatline = " mac=$value\n";
}
}
if ($attr eq "HWSerialNum")
{
if ($value)
{
$xcatline = " serial=$value\n";
}
}
if ($attr eq "ConsoleSerialSpeed")
{
if ($value)
{
$xcatline = " serialspeed=$value\n";
$xcatline .= " serialflow=hard\n"; # hardcoded
}
}
if ($attr eq "ConsoleSerialDevice")
{
if ($value)
{
$xcatline = " serialport=$value\n";
}
}
if ($attr eq "ConsoleServerName")
{
if ($value)
{
$xcatline = " termserver=$value\n";
}
}
if ($xcatline)
{
write_stanza($xcatline);
$xcatline = "";
}
}
$xcatline = "\n";
write_stanza($xcatline);
$xcatline = "";
}
close(STANZA);
return 0;
}
#
# runs lshwdev -l stanza file and builds node stanza file for xCAT
#
sub getDevinfo
{
# open the node stanza file
my $stanzafile = "$directory/device.stanza";
open(STANZA, ">$stanzafile")
or die "Can't open $stanzafile for writing: $!";
write_stanza("# <xCAT data object stanza file\n");
log_this("Reading Device information\n");
print "Running lshwdev -l for device info!\n";
my $MN;
my $OS;
my $hwmodel;
my @results;
my $cmd;
my $HWMODEL = "";
# use of file is for debug
my $lshwdevfile = "$directory/lshwdevdebug.output";
if (-e $lshwdevfile)
{ # use the imported file
log_this("Reading $lshwdevfile information\n");
$cmd = "cat $lshwdevfile";
@results = runcmd($cmd);
}
else
{ # run the command
$cmd = "/opt/csm/bin/lshwdev -l";
@results = runcmd($cmd);
}
if ($::RUNCMD_RC != 0)
{
my $msg = "Error processing lshwdev information\n";
log_this($msg);
print "$msg";
close(STANZA);
return;
}
#
# build hash of lshwdev info
#
my $output = buildNodehash(\@results);
my %nodehash = %$output;
my %attrhash;
my $nodename;
my $attributes;
while (($nodename, $attributes) = each %nodehash)
{
#
# build commonly needed attributes
#
%attrhash = %$attributes;
$HWMODEL = $attrhash{"HWModel"};
#
# first process the devicename
#
my $value;
my $xcatline;
my $attr;
my $grplist = get_dev_groups($nodename);
my $shortnodename = get_shortname($nodename);
$xcatline = "$shortnodename:\n"; # write node name
$xcatline .= " objtype=node\n";
if ($grplist)
{
$xcatline .= " groups=$grplist\n";
}
$xcatline .= " status=defined\n";
if ($xcatline)
{
write_stanza($xcatline);
$xcatline = "";
}
#now process all the attributes associated with the device
while (($attr, $value) = each %$attributes)
{
if ($attr eq "DeviceType")
{
if ($value)
{
my $lcvalue = lc($value);
$xcatline = " nodetype=ppc\n";
if ($lcvalue eq "hmc") {
$xcatline .= " mgt=$lcvalue\n";
$xcatline .= " hwtype=$lcvalue\n";
}
}
}
if ($attr eq "HWType") # put Model and type together
{
if ($value)
{
$xcatline = " mtm=$HWMODEL";
$xcatline .= "-";
$xcatline .= "$value\n";
}
}
if ($attr eq "HWSerialNum")
{
if ($value)
{
$xcatline = " serial=$value\n";
}
}
if ($attr eq "PhysicalLocation")
{
if ($value)
{
$xcatline = " room=$value\n";
}
}
if ($attr eq "Macaddr")
{
if ($value)
{
$xcatline = " mac=$value\n";
}
}
if ($xcatline)
{
write_stanza($xcatline);
$xcatline = "";
}
}
$xcatline = "\n";
write_stanza($xcatline);
$xcatline = "";
}
close(STANZA);
return 0;
}
#
# change to short hostname for xCAT
# if ip address, just return it
#
sub get_shortname
{
my $hostname = shift();
# if not ip address
if ($hostname !~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/)
{
my @shorthost = split(/\./, $hostname);
return $shorthost[0];
}
else
{ # return ip address
return $hostname;
}
}
#
# get list of groups for input hostname
#
sub get_groups
{
my $hostname = shift();
my $grouplist;
my @results;
my $cmd;
# use of file is for debug
my $groupfile = "$directory/nodegrpdebug.output";
if (-e $groupfile)
{ # use the imported file
$cmd = "cat $groupfile";
@results = runcmd($cmd);
}
else
{ # run the command
$cmd = "/opt/csm/bin/nodegrp -s $hostname";
@results = runcmd($cmd);
}
foreach my $line (@results)
{
$grouplist .= $line;
$grouplist .= ",";
}
chop $grouplist; # get rid of last comma
return $grouplist;
}
#
# get list of groups for input device
#
sub get_dev_groups
{
my $devname = shift();
my $grouplist;
my $cmd;
my @results;
my $hwgroupfile = "$directory/hwdevgrpdebug.output";
if (-e $hwgroupfile)
{ # use the imported file
$cmd = "cat $hwgroupfile";
@results = runcmd($cmd);
}
else
{ # run the command
$cmd = "/opt/csm/bin/hwdevgrp -s $devname";
@results = runcmd($cmd);
}
foreach my $line (@results)
{
$grouplist .= $line;
$grouplist .= ",";
}
chop $grouplist; # get rid of last comma
return $grouplist;
}
#
# build node hash. Build a hash of hashes, each entry
# nodex=> {
# attribute=>value
# attribute=>value
# .
#
#
sub buildNodehash
{
my ($info) = @_;
my @nodeinfo = @$info;
my %nodehash;
my $nodename;
foreach my $line (@nodeinfo)
{
$line =~ s/\s*//g; #remove extra blanks
my ($attr, $value) = split(/=/, $line);
if (($attr eq "Hostname") || ($attr eq "Name"))
{
$nodename = $value; # set the hash key
}
else
{ # all other lines are part of hash
$nodehash{$nodename}{$attr} = $value;
}
}
return \%nodehash;
}
#
# runs the input command and handles the errors. Returns the output
#
sub runcmd
{
my ($cmd) = @_;
my $rc = 0;
$::RUNCMD_RC = 0;
my $outref = [];
@$outref = `$cmd`;
if ($?)
{
$rc = $? ;
$::RUNCMD_RC = $rc;
if ($rc > 0)
{
my $msg = "$cmd returned rc=$rc @$outref\n";
log_this($msg);
print "$msg";
}
}
chomp(@$outref);
return @$outref;
}
sub usage
{
print "CSM database to xCAT stanza files migration utility.\n";
print
"Reads the CSM database and creates xCAT stanza files that \ncan be imported using the chdef command into the xCAT database.\n";
print "Usage:\n";
print "\t--help - usage\n";
print
"\t--dir - output directory for stanza files.\n Default is /tmp/csm2xcat.\n";
print "\n";
return;
}