Annotation of loncom/build/loncaparestoreconfigurations, revision 1.16

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

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