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>