Annotation of loncom/build/loncaparestoreconfigurations, revision 1.13

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

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