From cb415007bab56b9cdb0b5a31a5dc150fa89f670f Mon Sep 17 00:00:00 2001 From: lissav Date: Wed, 3 Apr 2013 13:15:25 +0000 Subject: [PATCH] add back the csm to xcat migration tools git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@15809 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- xCAT-server/share/xcat/scripts/cfm2xcat | 362 ++++++++++++ xCAT-server/share/xcat/scripts/csm2xcat | 730 ++++++++++++++++++++++++ 2 files changed, 1092 insertions(+) create mode 100755 xCAT-server/share/xcat/scripts/cfm2xcat create mode 100755 xCAT-server/share/xcat/scripts/csm2xcat diff --git a/xCAT-server/share/xcat/scripts/cfm2xcat b/xCAT-server/share/xcat/scripts/cfm2xcat new file mode 100755 index 000000000..edc85a832 --- /dev/null +++ b/xCAT-server/share/xcat/scripts/cfm2xcat @@ -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 = ) + { + 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 @_; +} + diff --git a/xCAT-server/share/xcat/scripts/csm2xcat b/xCAT-server/share/xcat/scripts/csm2xcat new file mode 100755 index 000000000..b6782b629 --- /dev/null +++ b/xCAT-server/share/xcat/scripts/csm2xcat @@ -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("# \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("# $stanzafile") + or die "Can't open $stanzafile for writing: $!"; + write_stanza("# { +# 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; +} +