Annotation of loncom/build/loncaparestoreconfigurations, revision 1.14

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

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