git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@15809 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
		
			
				
	
	
		
			363 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			363 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
#!/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 @_;
 | 
						|
}
 | 
						|
 |