File:  [LON-CAPA] / loncom / build / loncaparestoreconfigurations
Revision 1.15: download - view: text, annotated - select for diffs
Wed Jan 22 02:00:01 2003 UTC (21 years, 4 months ago) by harris41
Branches: MAIN
CVS tags: HEAD
removing deprecated sections; updating documentation; beautification fixes
(BUG 1185 PARTIAL FIX)

    1: #!/usr/bin/perl
    2: 
    3: # loncaparestoreconfigurations - restore data to new LON-CAPA conf files
    4: #
    5: # $Id: loncaparestoreconfigurations,v 1.15 2003/01/22 02:00:01 harris41 Exp $
    6: #
    7: # YEAR=2000
    8: # Scott Harrison 10/25, 11/02, 12/14
    9: # YEAR=2001
   10: # Scott Harrison 05/09, 06/01, 11/27
   11: # YEAR=2002
   12: # Scott Harrison 03/03, 05/15, 7/27
   13: # YEAR=2003
   14: # Scott Harrison 01/21
   15: #
   16: ###
   17: 
   18: # This tool helps in updating a system.  It restores information for
   19: # configuration files (.lpmlnew or other backup notations).
   20: 
   21: # By default, the .lpmlsave suffix is used.
   22: # Alternatively, there can be two other invocations
   23: # Invocation #1:
   24: #   ARGV[0]=suffix
   25: #   ARGV[1]=.bak
   26: # Invocation #2:
   27: #   ARGV[0]=lasttimestamp
   28: 
   29: # The criteria for the lasttimestamp is that the 
   30: # file suffix is a '.' followed by a 14-digit
   31: # time-stamp (YYYYMMDDhhmmss).
   32: # The time-stamp with the greatest value is
   33: # taken as the backup file.
   34: 
   35: # --------------------------------------------- Define program version variable
   36: $VERSION = sprintf("%d.%02d", q$Revision: 1.15 $ =~ /(\d+)\.(\d+)/);
   37: 
   38: # ---------------------------------------------- Process command-line arguments
   39: my $suffix='.lpmlsave';
   40: my $suffixpragma='';
   41: if ($ARGV[0] eq 'suffix') {
   42:     $suffix=$ARGV[1] if $ARGV[1]=~/^[\.\w]+$/;
   43: }
   44: elsif ($ARGV[0] eq 'lasttimestamp') {
   45:     $suffixpragma='lasttimestamp';
   46: }
   47: 
   48: use strict; # restrict unsafe and poorly coded constructs
   49: 
   50: # ------------------------------------ Configuration files to be concerned with
   51: my @special_conf_files=(
   52: 			'/etc/httpd/conf/loncapa.conf',
   53: 			);
   54: 
   55: my %pvar; # store the PerlSetVar variable key/value combinations
   56: 
   57: # --------------------------------------------- Process the configuration files
   58: # NOTE that I have structured this processing to make NO assumptions
   59: # about the processing of each configuration file.  So, in terms
   60: # of keeping each file's processing algorithms self-contained, I am not
   61: # modularizing things (where it is obvious that they might be modularized.)
   62: CONFLOOP: foreach (@special_conf_files) {
   63: 
   64:     my $lpmlold; # holds information that needs to be read
   65:     my $lpmlnew; # holds information that needs to be modified
   66: 
   67:     my $lpmlnew_file; # file location of information that needs to be modified
   68: 
   69: # ---------------------------------------------------------------- loncapa.conf
   70:     if (/^\/etc\/httpd\/conf\/loncapa.conf$/ and
   71: 	-e '/etc/httpd/conf/loncapa.conf')
   72:       {
   73: 	if ($suffixpragma eq 'lasttimestamp' and
   74: 	    -e '/etc/httpd/conf/loncapa.conf')
   75: 	  {
   76: 	    $suffix=&getsuffix('/etc/httpd/conf/loncapa.conf');
   77: 	    unless (-e '/etc/httpd/conf/loncapa.conf'.$suffix)
   78: 	      {
   79: 		next CONFLOOP;
   80: 	      }
   81: 	    $lpmlold="\n".&readfile('/etc/httpd/conf/loncapa.conf'.$suffix);
   82: 	    $lpmlnew_file='/etc/httpd/conf/loncapa.conf';
   83: 	    $lpmlnew=&readfile($lpmlnew_file);
   84: 	  }
   85: 	else
   86: 	  {
   87: 	    $lpmlold="\n".&readfile('/etc/httpd/conf/loncapa.conf');
   88: 	    $lpmlnew_file='/etc/httpd/conf/loncapa.conf'.$suffix;
   89: 	    unless (-e $lpmlnew_file)
   90: 	      {
   91: 		next CONFLOOP;
   92: 	      }
   93: 	    $lpmlnew=&readfile($lpmlnew_file);
   94: 	  }
   95: 	while($lpmlold=~/\n\s*PerlSetVar\s+(\S+)\s+(\S+)/mcg)
   96: 	  {
   97: 	    my $pkey=$1; my $pval=$2;
   98: 	    $pvar{$pkey}=$pval;
   99: 	  }
  100: 	foreach my $pkey (keys %pvar)
  101: 	  {
  102: 	    my $pval=$pvar{$pkey};
  103: 	    $lpmlnew=~s/(\n\s*PerlSetVar\s+$pkey\s+)\S+/$1$pval/;
  104: 	  }
  105: 	open(OUT,'>'.$lpmlnew_file) or
  106: 	    die('Cannot open '.$lpmlnew_file.' for output'."\n");
  107: 	print(OUT $lpmlnew);
  108: 	close(OUT);
  109:       }
  110: 
  111: # ---------------------- smb.conf (probably will be deprecated in 2004 or 2005)
  112:     elsif (/^\/etc\/smb.conf$/ and -e "/etc/smb.conf$suffix")
  113:       {
  114: 	if ($suffixpragma eq 'lasttimestamp')
  115: 	  {
  116: 	    $suffix=&getsuffix('/etc/smb.conf');
  117: 	    unless (-e '/etc/httpd/conf/loncapa.conf'.$suffix)
  118: 	      {
  119: 		next CONFLOOP;
  120: 	      }
  121: 	    $lpmlnew = &readfile('/etc/smb.conf');
  122: 	    $lpmlnew_file = '/etc/smb.conf';
  123: 	  }
  124: 	else
  125: 	  {
  126: 	    $lpmlnew = &readfile('/etc/smb.conf'.$suffix);
  127: 	    $lpmlnew_file = '/etc/smb.conf'.$suffix;
  128: 	  }
  129: 	$lpmlnew =~ s/\{\{\{\{\[(.*?)\]\}\}\}\}/$pvar{$1}/ge;
  130: 	open(OUT,'>'.$lpmlnew_file) or
  131: 	    die('Cannot open '.$lpmlnew_file.' for output'."\n");
  132: 	print(OUT $lpmlnew);
  133: 	close(OUT);
  134:       }
  135:     elsif (/^\/etc\/samba\/smb.conf$/ and -e "/etc/samba/smb.conf$suffix")
  136:       {
  137: 	if ($suffixpragma eq 'lasttimestamp')
  138: 	  {
  139: 	    $suffix = &getsuffix('/etc/samba/smb.conf');
  140: 	    unless (-e '/etc/samba/smb.conf'.$suffix)
  141: 	      {
  142: 		next CONFLOOP;
  143: 	      }
  144: 	    $lpmlnew = &readfile('/etc/samba/smb.conf');
  145: 	    $lpmlnew_file = '/etc/samba/smb.conf';
  146: 	  }
  147: 	else
  148: 	  {
  149: 	    $lpmlnew = &readfile('/etc/samba/smb.conf'.$suffix);
  150: 	    $lpmlnew_file = '/etc/samba/smb.conf'.$suffix;
  151: 	  }
  152: 	$lpmlnew =~ s/\{\{\{\{\[(.*?)\]\}\}\}\}/$pvar{$1}/ge;
  153: 	open(OUT,'>'.$lpmlnew_file) or
  154: 	    die('Cannot open '.$lpmlnew_file.' for output'."\n");
  155: 	print(OUT $lpmlnew);
  156: 	close(OUT);
  157:       }
  158:   }
  159: 
  160: # --------------------------------- getsuffix: get the latest time stamp suffix
  161: # === INPUT:  filename without suffix
  162: # === OUTPUT: the latest time stamp suffix; 14 digits YYYYMMDDhhmmss
  163: # === ERROR:  cannot read the directory in which the filenames reside
  164: sub getsuffix ($)
  165:   {
  166:     my ($file) = @_;
  167:     print("$file\n");
  168:     my $dir = $file; $dir =~ s/([^\/]+)$//;
  169:     my $filename = $1;
  170:     opendir(DIR,$dir) or
  171: 	die('Cannot open directory '.$dir.' for viewing'."\n");
  172:     my @a = grep {/$filename\.\d{14}/} readdir(DIR);
  173:     closedir(DIR);
  174:     map {s/$filename\.//;} @a;
  175:     my @b = sort {$a<=>$b} @a;
  176:     my $suffix = '.'.$b[$#b];
  177:     return($suffix);
  178:   }
  179: 
  180: # -------------------------- readfile: get the file contents in a scalar string
  181: # === INPUT:  filename
  182: # === OUTPUT: the filename's contents
  183: # === ERROR:  cannot read the file
  184: # === NOTE:   big files will hog computer memory
  185: sub readfile ($)
  186:   {
  187:     my ($filename) = @_;
  188:     my $contents = '';
  189:     open(IN,'<'.$filename) or die ('Cannot read '.$filename."\n");
  190:     while(<IN>) {$contents .= $_;}
  191:     close(IN);
  192:     return($contents);
  193:   }
  194: 
  195: =pod
  196: 
  197: =head1 NAME
  198: 
  199: B<loncaparestoreconfigurations> - restore data to new LON-CAPA conf files
  200: 
  201: =head1 SYNOPSIS
  202: 
  203:  perl loncaparestoreconfigurations suffix .lpmlnew
  204: 
  205: =head1 DESCRIPTION
  206: 
  207: During software upgrades, it is possible that configuration files will change.
  208: It is important to "intelligently" preserve the machine-specific configuration
  209: data.  This script is meant to run B<after> the software upgrade.
  210: 
  211: For example, consider the configuration file F<loncapa.conf>.
  212: During the software upgrade (not performed by by F<loncapa.conf>),
  213: the following happens:
  214: 
  215:  loncapa.conf is NOT overwritten
  216: 
  217: rather,
  218: 
  219:  a NEW file B<loncapa.conf.lpmlnew> is GENERATED
  220:  (cp UPGRADEDIR/loncapa.conf SYSTEMDIR/loncapa.conf.lpmlnew)
  221: 
  222: This script can be described as:
  223: 
  224: =over 4
  225: 
  226: =item *
  227: 
  228: modifying SYSTEMDIR/loncapa.conf.lpmlnew, and
  229: 
  230: =item *
  231: 
  232: the modification consists of reading values from the old loncapa.conf and
  233: placing them in loncapa.conf.lpmlnew.
  234: 
  235: =back
  236: 
  237: Regarding F<loncapa.conf>, for backwards compatibility, this script tries
  238: to read values out of F<access.conf>.
  239: 
  240: This script also currently works with F<smb.conf> (a standard Linux
  241: configuration file associated with sharing the Linux filesystem with
  242: Windows machines).
  243: 
  244: =head2 Working with the file suffix
  245: 
  246: The script is designed to work according to two strategies.
  247: 
  248: =over 4
  249: 
  250: =item * B<aggressive update>
  251: 
  252: In the aggressive update strategy, two things should happen:
  253: 
  254: =over 4
  255: 
  256: =item * The configuration file should be replaced
  257: 
  258: Therefore, the system administrator "trusts" the software update process
  259: and this script to handle everything correctly.
  260: 
  261: =item * Information should never be lost
  262: 
  263: Therefore, a backup copy should be made that is unique to the time
  264: the action is taken and is never overwritten or destroyed by the
  265: automated process.
  266: 
  267: =back
  268: 
  269: =item * B<passive assistance>
  270: 
  271: =over 4
  272: 
  273: =item * The configuration file should not be replaced
  274: 
  275: The system administrator does not trust the software update process.
  276: She would rather have a new file "intelligently" generated, and, only
  277: by her direct approval, have the new file substitute the contents
  278: of the current configuration file.
  279: 
  280: =item * The script should try to help the system administrator
  281: 
  282: Therefore, a new copy is made with the suffix ".lpmlnew".  This
  283: new copy is modified with data from the existing configuration file.
  284: The system administrator is prompted (by the rest of the software
  285: upgrade process) to resolve the new changes to the configuration
  286: file.
  287: 
  288: =back
  289: 
  290: =back
  291: 
  292: Correspondingly,
  293: 
  294:  perl loncaparestoreconfigurations suffix .lpmlnew
  295: 
  296: invokes this script in B<passive assistance> mode; whereas
  297: 
  298:  perl loncaparestoreconfigurations lasttimestamp
  299: 
  300: invokes this script in B<aggressive update> mode.
  301: 
  302: =head1 AUTHORS
  303: 
  304: Scott Harrison
  305: 
  306: This script is free software; you can redistribute it
  307: and/or modify it under the same terms as LON-CAPA itself.
  308: 
  309: =cut

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>