363 lines
8.9 KiB
Plaintext
363 lines
8.9 KiB
Plaintext
|
#!/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 @_;
|
||
|
}
|
||
|
|