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>