[LON-CAPA-cvs] cvs: loncom /build loncaparestoreconfigurations
harris41
lon-capa-cvs@mail.lon-capa.org
Thu, 16 May 2002 00:20:30 -0000
This is a MIME encoded message
--harris411021508430
Content-Type: text/plain
harris41 Wed May 15 20:20:30 2002 EDT
Modified files:
/loncom/build loncaparestoreconfigurations
Log:
BUG 436; cleaning up code; TESTED; supports loncapa.conf; supports
access.conf backwards; documented; mega-fixed; FIXED
--harris411021508430
Content-Type: text/plain
Content-Disposition: attachment; filename="harris41-20020515202030.txt"
Index: loncom/build/loncaparestoreconfigurations
diff -u loncom/build/loncaparestoreconfigurations:1.12 loncom/build/loncaparestoreconfigurations:1.13
--- loncom/build/loncaparestoreconfigurations:1.12 Sat Mar 2 19:21:23 2002
+++ loncom/build/loncaparestoreconfigurations Wed May 15 20:20:30 2002
@@ -1,14 +1,20 @@
#!/usr/bin/perl
-# loncaparestoreconfigurations
+# loncaparestoreconfigurations - restore data to new LON-CAPA conf files
+#
+# $Id: loncaparestoreconfigurations,v 1.13 2002/05/16 00:20:30 harris41 Exp $
+#
+# YEAR=2000
+# 10/25, 12/14 Scott Harrison
+# YEAR=2002
+# Scott Harrison, 05/15
+#
+###
-# Scott Harrison, 10/25/2000
-# Scott Harrison, 12/14/2000
+# This tool helps in updating a system. It restores information for
+# configuration files (.lpmlsave or other backup notations).
-# This tool helps in updating a system. It restores backed-up
-# configuration files (.rpmsave or other backup notations).
-
-# By default, the .rpmsave suffix is used.
+# By default, the .lpmlsave suffix is used.
# Alternatively, there can be two other invocations
# Invocation #1:
# ARGV[0]=suffix
@@ -22,104 +28,292 @@
# The time-stamp with the greatest value is
# taken as the backup file.
-my $suffix=".rpmsave";
-my $suffixpragma="";
+# --------------------------------------------- Define program version variable
+$VERSION = sprintf("%d.%02d", q$Revision: 1.13 $ =~ /(\d+)\.(\d+)/);
+
+# ---------------------------------------------- Process command-line arguments
+my $suffix='.lpmlsave';
+my $suffixpragma='';
if ($ARGV[0] eq 'suffix') {
$suffix=$ARGV[1] if $ARGV[1]=~/^[\.\w]+$/;
}
elsif ($ARGV[0] eq 'lasttimestamp') {
- $suffixpragma="lasttimestamp";
+ $suffixpragma='lasttimestamp';
}
+use strict; # restrict unsafe and poorly coded constructs
-use strict;
-
+# ------------------------------------ Configuration files to be concerned with
my @special_conf_files=(
- "/etc/httpd/conf/access.conf",
- "/etc/smb.conf",
- "/etc/samba/smb.conf"
+ '/etc/httpd/conf/loncapa.conf',
+ '/etc/httpd/conf/access.conf',
+ '/etc/smb.conf',
+ '/etc/samba/smb.conf'
);
-my @generic_conf_files=(
- "/home/httpd/lonTabs/hosts.tab",
- "/home/httpd/lonTabs/spare.tab",
- "/etc/krb.conf",
- "/etc/ntp.conf",
- "/etc/httpd/conf/srm.conf",
- "/etc/httpd/conf/httpd.conf",
- );
+my %pvar; # store the PerlSetVar variable key/value combinations
-my @perlsetvars=("lonHostID","lonRole","lonAdmEMail","lonDefDomain","lonLoadLim","lonExpire","lonReceipt","lonSqlAccess");
-my %pvar;
-foreach (@special_conf_files) {
- if (/^\/etc\/httpd\/conf\/access.conf$/) {
- if ($suffixpragma eq 'lasttimestamp') {
- $suffix=getsuffix('/etc/httpd/conf/access.conf');
+# --------------------------------------------- Process the configuration files
+# NOTE that I have structured this processing to make NO assumptions
+# about the processing of each configuration file. So, in terms
+# of keeping each file's processing algorithms self-contained, I am not
+# modularizing things (where it is obvious that they might be modularized.)
+CONFLOOP: foreach (@special_conf_files) {
+
+ my $lpmlold; # holds information that needs to be read
+ my $lpmlnew; # holds information that needs to be modified
+
+ my $lpmlnew_file; # file location of information that needs to be modified
+
+# ------------------------------------------- access.conf (becoming deprecated)
+ if (/^\/etc\/httpd\/conf\/access.conf$/ and
+ -e '/etc/httpd/conf/access.conf') {
+ if ($suffixpragma eq 'lasttimestamp' and
+ -e '/etc/httpd/conf/access.conf'.$suffix) {
+ $suffix=&getsuffix('/etc/httpd/conf/access.conf');
+ unless (-e '/etc/httpd/conf/access.conf'.$suffix) {
+ next CONFLOOP;
+ }
+ $lpmlold="\n".&readfile('/etc/httpd/conf/access.conf'.$suffix);
+ $lpmlnew_file='/etc/httpd/conf/access.conf';
+ $lpmlnew=&readfile($lpmlnew_file);
}
- my $template=`/bin/cat /etc/httpd/conf/access.conf`;
- my $lpmlnew=`/bin/cat /etc/httpd/conf/access.conf$suffix`;
-# `/bin/mv /etc/httpd/conf/access.conf /etc/httpd/conf/access.conf.template`;
- foreach my $psv (@perlsetvars) {
- if ($template=~/\nPerlSetVar\s+$psv\s+(\S+)/) {
- my $pval=$1;
- $lpmlnew=~s/(\nPerlSetVar\s+$psv\s+)\S+/$1$pval/;
- $pvar{$psv}=$pval;
+ else {
+ $lpmlold="\n".&readfile('/etc/httpd/conf/access.conf');
+ $lpmlnew_file='/etc/httpd/conf/access.conf'.$suffix;
+ unless (-e $lpmlnew_file) {
+ next CONFLOOP;
}
+ $lpmlnew=&readfile($lpmlnew_file);
}
- open OUT,">/etc/httpd/conf/access.conf$suffix";
- print OUT $lpmlnew;
- close OUT;
- }
- if (/^\/etc\/smb.conf$/ and -e "/etc/smb.conf$suffix") {
- if ($suffixpragma eq 'lasttimestamp') {
- $suffix=getsuffix('/etc/smb.conf');
+ while($lpmlold=~/\n\s*PerlSetVar\s+(\S+)\s+(\S+)/mcg) {
+ my $pkey=$1; my $pval=$2;
+ $lpmlnew=~s/(\n\s*PerlSetVar\s+$pkey\s+)\S+/$1$pval/;
+ $pvar{$pkey}=$pval;
}
- my $template=`/bin/cat /etc/smb.conf$suffix`;
- foreach my $psv (@perlsetvars) {
- $template=~s/\{\{\{\{\[(.*?)\]\}\}\}\}/$pvar{$1}/ge;
- }
- open OUT,">/etc/smb.conf$suffix";
- print OUT $template;
- close OUT;
}
- if (/^\/etc\/samba\/smb.conf$/ and -e "/etc/samba/smb.conf$suffix") {
- if ($suffixpragma eq 'lasttimestamp') {
- $suffix=getsuffix('/etc/samba/smb.conf');
+
+# ---------------------------------------------------------------- loncapa.conf
+ elsif (/^\/etc\/httpd\/conf\/loncapa.conf$/ and
+ -e '/etc/httpd/conf/loncapa.conf') {
+ if ($suffixpragma eq 'lasttimestamp' and
+ -e '/etc/httpd/conf/loncapa.conf') {
+ $suffix=&getsuffix('/etc/httpd/conf/loncapa.conf');
+ unless (-e '/etc/httpd/conf/loncapa.conf'.$suffix) {
+ next CONFLOOP;
+ }
+ $lpmlold="\n".&readfile('/etc/httpd/conf/loncapa.conf'.$suffix);
+ $lpmlnew_file='/etc/httpd/conf/loncapa.conf';
+ $lpmlnew=&readfile($lpmlnew_file);
+ }
+ else {
+ $lpmlold="\n".&readfile('/etc/httpd/conf/loncapa.conf');
+ $lpmlnew_file='/etc/httpd/conf/loncapa.conf'.$suffix;
+ unless (-e $lpmlnew_file) {
+ next CONFLOOP;
+ }
+ $lpmlnew=&readfile($lpmlnew_file);
+ }
+ while($lpmlold=~/\n\s*PerlSetVar\s+(\S+)\s+(\S+)/mcg) {
+ my $pkey=$1; my $pval=$2;
+ $pvar{$pkey}=$pval;
+ }
+ foreach my $pkey (keys %pvar) {
+ my $pval=$pvar{$pkey};
+ $lpmlnew=~s/(\n\s*PerlSetVar\s+$pkey\s+)\S+/$1$pval/;
}
- my $template=`/bin/cat /etc/samba/smb.conf$suffix`;
- foreach my $psv (@perlsetvars) {
- $template=~s/\{\{\{\{\[(.*?)\]\}\}\}\}/$pvar{$1}/ge;
- }
- open OUT,">/etc/samba/smb.conf$suffix";
- print OUT $template;
- close OUT;
+ open(OUT,'>'.$lpmlnew_file) or
+ die('Cannot open '.$lpmlnew_file.' for output'."\n");
+ print(OUT $lpmlnew);
+ close(OUT);
}
-}
-
-exit; # Just because this is only about restoring configuration to
- # new files
-foreach (@generic_conf_files) {
- my $file=$_;
- if ($suffixpragma eq 'lasttimestamp') {
- $suffix=getsuffix($file);
+# -------------------------------------------------------------------- smb.conf
+ elsif (/^\/etc\/smb.conf$/ and -e "/etc/smb.conf$suffix") {
+ if ($suffixpragma eq 'lasttimestamp') {
+ $suffix=&getsuffix('/etc/smb.conf');
+ unless (-e '/etc/httpd/conf/loncapa.conf'.$suffix) {
+ next CONFLOOP;
+ }
+ $lpmlnew=&readfile('/etc/smb.conf');
+ $lpmlnew_file='/etc/smb.conf';
+ }
+ else {
+ $lpmlnew=&readfile('/etc/smb.conf'.$suffix);
+ $lpmlnew_file='/etc/smb.conf'.$suffix;
+ }
+ $lpmlnew=~s/\{\{\{\{\[(.*?)\]\}\}\}\}/$pvar{$1}/ge;
+ open(OUT,'>'.$lpmlnew_file) or
+ die('Cannot open '.$lpmlnew_file.' for output'."\n");
+ print(OUT $lpmlnew);
+ close(OUT);
}
- if (-e "$file$suffix") {
- `/bin/mv $file $_.template`;
- `/bin/cp $file$suffix $file`;
+ elsif (/^\/etc\/samba\/smb.conf$/ and -e "/etc/samba/smb.conf$suffix") {
+ if ($suffixpragma eq 'lasttimestamp') {
+ $suffix=&getsuffix('/etc/samba/smb.conf');
+ unless (-e '/etc/samba/smb.conf'.$suffix) {
+ next CONFLOOP;
+ }
+ $lpmlnew=&readfile('/etc/samba/smb.conf');
+ $lpmlnew_file='/etc/samba/smb.conf';
+ }
+ else {
+ $lpmlnew=&readfile('/etc/samba/smb.conf'.$suffix);
+ $lpmlnew_file='/etc/samba/smb.conf'.$suffix;
+ }
+ $lpmlnew=~s/\{\{\{\{\[(.*?)\]\}\}\}\}/$pvar{$1}/ge;
+ open(OUT,'>'.$lpmlnew_file) or
+ die('Cannot open '.$lpmlnew_file.' for output'."\n");
+ print(OUT $lpmlnew);
+ close(OUT);
}
}
+# --------------------------------- getsuffix: get the latest time stamp suffix
+# === INPUT: filename without suffix
+# === OUTPUT: the latest time stamp suffix; 14 digits YYYYMMDDhhmmss
+# === ERROR: cannot read the directory in which the filenames reside
sub getsuffix {
my ($file)=@_;
- print "$file\n";
+ print("$file\n");
my $dir=$file; $dir=~s/([^\/]+)$//;
my $filename=$1;
- opendir(DIR,$dir);
- my @a=grep {/$filename\.\d{14}/} readdir DIR;
- closedir DIR;
+ opendir(DIR,$dir) or
+ die('Cannot open directory '.$dir.' for viewing'."\n");
+ my @a=grep {/$filename\.\d{14}/} readdir(DIR);
+ closedir(DIR);
map {s/$filename\.//;} @a;
my @b=sort {$a<=>$b} @a;
my $suffix='.'.$b[$#b];
- return $suffix;
+ return($suffix);
+}
+
+# -------------------------- readfile: get the file contents in a scalar string
+# === INPUT: filename
+# === OUTPUT: the filename's contents
+# === ERROR: cannot read the file
+# === NOTE: big files will hog computer memory
+sub readfile {
+ my ($filename)=@_;
+ my $contents='';
+ open(IN,'<'.$filename) or die ('Cannot read '.$filename."\n");
+ while(<IN>) {$contents.=$_;}
+ close(IN);
+ return($contents);
}
+
+=pod
+
+=head1 NAME
+
+B<loncaparestoreconfigurations> - restore data to new LON-CAPA conf files
+
+=head1 SYNOPSIS
+
+ perl loncaparestoreconfigurations suffix .lpmlnew
+
+=head1 DESCRIPTION
+
+During software upgrades, it is possible that configuration files will change.
+It is important to "intelligently" preserve the machine-specific configuration
+data. This script is meant to run B<after> the software upgrade.
+
+For example, consider the configuration file F<loncapa.conf>.
+During the software upgrade (not performed by by F<loncapa.conf>),
+the following happens:
+
+ loncapa.conf is NOT overwritten
+
+rather,
+
+ a NEW file B<loncapa.conf.lpmlnew> is GENERATED
+ (cp UPGRADEDIR/loncapa.conf SYSTEMDIR/loncapa.conf.lpmlnew)
+
+This script can be described as:
+
+=over 4
+
+=item *
+
+modifying SYSTEMDIR/loncapa.conf.lpmlnew, and
+
+=item *
+
+the modification consists of reading values from the old loncapa.conf and
+placing them in loncapa.conf.lpmlnew.
+
+=back
+
+Regarding F<loncapa.conf>, for backwards compatibility, this script tries
+to read values out of F<access.conf>.
+
+This script also currently works with F<smb.conf> (a standard Linux
+configuration file associated with sharing the Linux filesystem with
+Windows machines).
+
+=head2 Working with the file suffix
+
+The script is designed to work according to two strategies.
+
+=over 4
+
+=item * B<aggressive update>
+
+In the aggressive update strategy, two things should happen:
+
+=over 4
+
+=item * The configuration file should be replaced
+
+Therefore, the system administrator "trusts" the software update process
+and this script to handle everything correctly.
+
+=item * Information should never be lost
+
+Therefore, a backup copy should be made that is unique to the time
+the action is taken and is never overwritten or destroyed by the
+automated process.
+
+=back
+
+=item * B<passive assistance>
+
+=over 4
+
+=item * The configuration file should not be replaced
+
+The system administrator does not trust the software update process.
+She would rather have a new file "intelligently" generated, and, only
+by her direct approval, have the new file substitute the contents
+of the current configuration file.
+
+=item * The script should try to help the system administrator
+
+Therefore, a new copy is made with the suffix ".lpmlnew". This
+new copy is modified with data from the existing configuration file.
+The system administrator is prompted (by the rest of the software
+upgrade process) to resolve the new changes to the configuration
+file.
+
+=back
+
+=back
+
+Correspondingly,
+
+ perl loncaparestoreconfigurations suffix .lpmlnew
+
+invokes this script in B<passive assistance> mode; whereas
+
+ perl loncaparestoreconfigurations lasttimestamp
+
+invokes this script in B<aggressive update> mode.
+
+=head1 AUTHORS
+
+Scott Harrison
+
+This module is free software; you can redistribute it
+and/or modify it under the same terms as LON-CAPA itself.
+
+=cut
--harris411021508430--