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