[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--