Annotation of loncom/build/loncaparestoreconfigurations, revision 1.15

1.1       harris41    1: #!/usr/bin/perl
                      2: 
1.13      harris41    3: # loncaparestoreconfigurations - restore data to new LON-CAPA conf files
                      4: #
1.15    ! harris41    5: # $Id: loncaparestoreconfigurations,v 1.14 2002/07/27 22:39:56 harris41 Exp $
1.13      harris41    6: #
                      7: # YEAR=2000
1.15    ! harris41    8: # Scott Harrison 10/25, 11/02, 12/14
        !             9: # YEAR=2001
        !            10: # Scott Harrison 05/09, 06/01, 11/27
1.13      harris41   11: # YEAR=2002
1.15    ! harris41   12: # Scott Harrison 03/03, 05/15, 7/27
        !            13: # YEAR=2003
        !            14: # Scott Harrison 01/21
1.13      harris41   15: #
                     16: ###
1.1       harris41   17: 
1.13      harris41   18: # This tool helps in updating a system.  It restores information for
1.15    ! harris41   19: # configuration files (.lpmlnew or other backup notations).
1.8       harris41   20: 
1.13      harris41   21: # By default, the .lpmlsave suffix is used.
1.8       harris41   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: 
1.13      harris41   35: # --------------------------------------------- Define program version variable
1.15    ! harris41   36: $VERSION = sprintf("%d.%02d", q$Revision: 1.14 $ =~ /(\d+)\.(\d+)/);
1.13      harris41   37: 
                     38: # ---------------------------------------------- Process command-line arguments
                     39: my $suffix='.lpmlsave';
                     40: my $suffixpragma='';
1.8       harris41   41: if ($ARGV[0] eq 'suffix') {
1.11      harris41   42:     $suffix=$ARGV[1] if $ARGV[1]=~/^[\.\w]+$/;
1.8       harris41   43: }
                     44: elsif ($ARGV[0] eq 'lasttimestamp') {
1.13      harris41   45:     $suffixpragma='lasttimestamp';
1.8       harris41   46: }
1.1       harris41   47: 
1.13      harris41   48: use strict; # restrict unsafe and poorly coded constructs
1.1       harris41   49: 
1.13      harris41   50: # ------------------------------------ Configuration files to be concerned with
1.1       harris41   51: my @special_conf_files=(
1.13      harris41   52: 			'/etc/httpd/conf/loncapa.conf',
1.1       harris41   53: 			);
                     54: 
1.13      harris41   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
1.15    ! harris41   70:     if (/^\/etc\/httpd\/conf\/loncapa.conf$/ and
        !            71: 	-e '/etc/httpd/conf/loncapa.conf')
        !            72:       {
1.13      harris41   73: 	if ($suffixpragma eq 'lasttimestamp' and
1.15    ! harris41   74: 	    -e '/etc/httpd/conf/loncapa.conf')
        !            75: 	  {
1.13      harris41   76: 	    $suffix=&getsuffix('/etc/httpd/conf/loncapa.conf');
1.15    ! harris41   77: 	    unless (-e '/etc/httpd/conf/loncapa.conf'.$suffix)
        !            78: 	      {
1.13      harris41   79: 		next CONFLOOP;
1.15    ! harris41   80: 	      }
1.13      harris41   81: 	    $lpmlold="\n".&readfile('/etc/httpd/conf/loncapa.conf'.$suffix);
                     82: 	    $lpmlnew_file='/etc/httpd/conf/loncapa.conf';
                     83: 	    $lpmlnew=&readfile($lpmlnew_file);
1.15    ! harris41   84: 	  }
        !            85: 	else
        !            86: 	  {
1.13      harris41   87: 	    $lpmlold="\n".&readfile('/etc/httpd/conf/loncapa.conf');
                     88: 	    $lpmlnew_file='/etc/httpd/conf/loncapa.conf'.$suffix;
1.15    ! harris41   89: 	    unless (-e $lpmlnew_file)
        !            90: 	      {
1.13      harris41   91: 		next CONFLOOP;
1.15    ! harris41   92: 	      }
1.13      harris41   93: 	    $lpmlnew=&readfile($lpmlnew_file);
1.15    ! harris41   94: 	  }
        !            95: 	while($lpmlold=~/\n\s*PerlSetVar\s+(\S+)\s+(\S+)/mcg)
        !            96: 	  {
1.13      harris41   97: 	    my $pkey=$1; my $pval=$2;
                     98: 	    $pvar{$pkey}=$pval;
1.15    ! harris41   99: 	  }
        !           100: 	foreach my $pkey (keys %pvar)
        !           101: 	  {
1.13      harris41  102: 	    my $pval=$pvar{$pkey};
                    103: 	    $lpmlnew=~s/(\n\s*PerlSetVar\s+$pkey\s+)\S+/$1$pval/;
1.15    ! harris41  104: 	  }
1.13      harris41  105: 	open(OUT,'>'.$lpmlnew_file) or
                    106: 	    die('Cannot open '.$lpmlnew_file.' for output'."\n");
                    107: 	print(OUT $lpmlnew);
                    108: 	close(OUT);
1.15    ! harris41  109:       }
1.13      harris41  110: 
1.15    ! harris41  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: 	  {
1.13      harris41  116: 	    $suffix=&getsuffix('/etc/smb.conf');
1.15    ! harris41  117: 	    unless (-e '/etc/httpd/conf/loncapa.conf'.$suffix)
        !           118: 	      {
1.13      harris41  119: 		next CONFLOOP;
1.15    ! harris41  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;
1.13      harris41  130: 	open(OUT,'>'.$lpmlnew_file) or
                    131: 	    die('Cannot open '.$lpmlnew_file.' for output'."\n");
                    132: 	print(OUT $lpmlnew);
                    133: 	close(OUT);
1.15    ! harris41  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: 	      {
1.13      harris41  142: 		next CONFLOOP;
1.15    ! harris41  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;
1.13      harris41  153: 	open(OUT,'>'.$lpmlnew_file) or
                    154: 	    die('Cannot open '.$lpmlnew_file.' for output'."\n");
                    155: 	print(OUT $lpmlnew);
                    156: 	close(OUT);
1.15    ! harris41  157:       }
        !           158:   }
1.8       harris41  159: 
1.13      harris41  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
1.15    ! harris41  164: sub getsuffix ($)
        !           165:   {
        !           166:     my ($file) = @_;
1.13      harris41  167:     print("$file\n");
1.15    ! harris41  168:     my $dir = $file; $dir =~ s/([^\/]+)$//;
        !           169:     my $filename = $1;
1.13      harris41  170:     opendir(DIR,$dir) or
                    171: 	die('Cannot open directory '.$dir.' for viewing'."\n");
1.15    ! harris41  172:     my @a = grep {/$filename\.\d{14}/} readdir(DIR);
1.13      harris41  173:     closedir(DIR);
1.8       harris41  174:     map {s/$filename\.//;} @a;
1.15    ! harris41  175:     my @b = sort {$a<=>$b} @a;
        !           176:     my $suffix = '.'.$b[$#b];
1.13      harris41  177:     return($suffix);
1.15    ! harris41  178:   }
1.13      harris41  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
1.15    ! harris41  185: sub readfile ($)
        !           186:   {
        !           187:     my ($filename) = @_;
        !           188:     my $contents = '';
1.13      harris41  189:     open(IN,'<'.$filename) or die ('Cannot read '.$filename."\n");
1.15    ! harris41  190:     while(<IN>) {$contents .= $_;}
1.13      harris41  191:     close(IN);
                    192:     return($contents);
1.15    ! harris41  193:   }
1.13      harris41  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: 
1.15    ! harris41  306: This script is free software; you can redistribute it
1.13      harris41  307: and/or modify it under the same terms as LON-CAPA itself.
                    308: 
                    309: =cut

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