mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-26 17:05:33 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			463 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			463 lines
		
	
	
		
			12 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);
 | |
|     $rc = &buildxcatsyncfile_new($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_IGNORE_STATUS=1 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;
 | |
|     }
 | |
| }
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   buildxcatsyncfile_new
 | |
|     Descriptions:
 | |
|         Convert CSM CFM configuration file to xCAT sycnfile
 | |
|     Arguments:
 | |
|         param1: (Input) The dir of CFM configuration files
 | |
|         param2: (Output) The xCAT syncfile
 | |
|     Returns:
 | |
|         0 - success
 | |
|         0 - fail
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub buildxcatsyncfile_new {
 | |
|     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";
 | |
|     my @xcatsyncfile;
 | |
| 
 | |
|     # 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);
 | |
|             my ($root2,      $strippeddestfile) = split("cfmlocal", $destfile);
 | |
|             chomp $strippeddestfile;
 | |
|             chop $strippeddestfile;
 | |
|             $destfile = $strippeddestfile;
 | |
| 
 | |
|             # get rid of parenthesis
 | |
|             my ($paren, $tnodes) = split(/\(/, $tmpnodes);
 | |
|             my ($nodes, $paren2) = split(/\)/, $tnodes);
 | |
|             chomp $nodes;
 | |
| 
 | |
|             # create an appropriate noderange ( comma seperated)
 | |
|             my @nodes = split(/ /, $nodes);
 | |
|             my $goodnr = "";
 | |
|             foreach my $node (@nodes) {
 | |
|                 if ($node !~ /^\s*$/) {
 | |
| 
 | |
|                     #skip blanks
 | |
|                     my @shorthost = split(/\./, $node);
 | |
|                     $goodnr .= $shorthost[0];
 | |
|                     $goodnr .= ",";
 | |
|                 }
 | |
|             }
 | |
|             chop $goodnr;
 | |
| 
 | |
|             push @xcatsyncfile, "$sourcefile -> ($goodnr) $destfile";
 | |
|         }
 | |
| 
 | |
|         close(CFM);
 | |
|     }
 | |
| 
 | |
|     open(XCATSF, "> $xcatfile")
 | |
|       or die "Can't open $xcatfile for writing: $!";
 | |
| 
 | |
|     foreach (@xcatsyncfile) {
 | |
|         print XCATSF $_ . "\n";
 | |
|     }
 | |
|     close(XCATSF);
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| 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 @_;
 | |
| }
 | |
| 
 |