File:  [LON-CAPA] / loncom / build / loncaparestoreconfigurations
Revision 1.16: download - view: text, annotated - select for diffs
Mon Feb 3 18:03:52 2003 UTC (21 years, 10 months ago) by harris41
Branches: MAIN
CVS tags: version_2_9_X, version_2_9_99_0, version_2_9_1, version_2_9_0, version_2_8_X, version_2_8_99_1, version_2_8_99_0, version_2_8_2, version_2_8_1, version_2_8_0, version_2_7_X, version_2_7_99_1, version_2_7_99_0, version_2_7_1, version_2_7_0, version_2_6_X, version_2_6_99_1, version_2_6_99_0, version_2_6_3, version_2_6_2, version_2_6_1, version_2_6_0, version_2_5_X, version_2_5_99_1, version_2_5_99_0, version_2_5_2, version_2_5_1, version_2_5_0, version_2_4_X, version_2_4_99_0, version_2_4_2, version_2_4_1, version_2_4_0, version_2_3_X, version_2_3_99_0, version_2_3_2, version_2_3_1, version_2_3_0, version_2_2_X, version_2_2_99_1, version_2_2_99_0, version_2_2_2, version_2_2_1, version_2_2_0, version_2_1_X, version_2_1_99_3, version_2_1_99_2, version_2_1_99_1, version_2_1_99_0, version_2_1_3, version_2_1_2, version_2_1_1, version_2_1_0, version_2_12_X, version_2_11_X, version_2_11_5_msu, version_2_11_5, version_2_11_4_uiuc, version_2_11_4_msu, version_2_11_4, version_2_11_3_uiuc, version_2_11_3_msu, version_2_11_3, version_2_11_2_uiuc, version_2_11_2_msu, version_2_11_2_educog, version_2_11_2, version_2_11_1, version_2_11_0_RC3, version_2_11_0_RC2, version_2_11_0_RC1, version_2_11_0, version_2_10_X, version_2_10_1, version_2_10_0_RC2, version_2_10_0_RC1, version_2_10_0, version_2_0_X, version_2_0_99_1, version_2_0_2, version_2_0_1, version_2_0_0, version_1_99_3, version_1_99_2, version_1_99_1_tmcc, version_1_99_1, version_1_99_0_tmcc, version_1_99_0, version_1_3_X, version_1_3_3, version_1_3_2, version_1_3_1, version_1_3_0, version_1_2_X, version_1_2_99_1, version_1_2_99_0, version_1_2_1, version_1_2_0, version_1_1_X, version_1_1_99_5, version_1_1_99_4, version_1_1_99_3, version_1_1_99_2, version_1_1_99_1, version_1_1_99_0, version_1_1_3, version_1_1_2, version_1_1_1, version_1_1_0, version_1_0_99_3, version_1_0_99_2, version_1_0_99_1, version_1_0_99, version_1_0_3, version_1_0_2, version_1_0_1, version_1_0_0, version_0_99_5, version_0_99_4, version_0_99_3, version_0_99_2, version_0_99_1, version_0_99_0, loncapaMITrelate_1, language_hyphenation_merge, language_hyphenation, conference_2003, bz6209-base, bz6209, bz5969, bz5610, bz2851, PRINT_INCOMPLETE_base, PRINT_INCOMPLETE, HEAD, GCI_3, GCI_2, GCI_1, BZ5971-printing-apage, BZ5434-fox, BZ4492-merge, BZ4492-feature_horizontal_radioresponse, BZ4492-feature_Support_horizontal_radioresponse, BZ4492-Support_horizontal_radioresponse
best wishes to all.

#!/usr/bin/perl

# loncaparestoreconfigurations - restore data to new LON-CAPA conf files
#
# $Id: loncaparestoreconfigurations,v 1.16 2003/02/03 18:03:52 harris41 Exp $
#
###

# This tool helps in updating a system.  It restores information for
# configuration files (.lpmlnew or other backup notations).

# By default, the .lpmlsave suffix is used.
# Alternatively, there can be two other invocations
# Invocation #1:
#   ARGV[0]=suffix
#   ARGV[1]=.bak
# Invocation #2:
#   ARGV[0]=lasttimestamp

# The criteria for the lasttimestamp is that the 
# file suffix is a '.' followed by a 14-digit
# time-stamp (YYYYMMDDhhmmss).
# The time-stamp with the greatest value is
# taken as the backup file.

# --------------------------------------------- Define program version variable
$VERSION = sprintf("%d.%02d", q$Revision: 1.16 $ =~ /(\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';
}

use strict; # restrict unsafe and poorly coded constructs

# ------------------------------------ Configuration files to be concerned with
my @special_conf_files=(
			'/etc/httpd/conf/loncapa.conf',
			);

my %pvar; # store the PerlSetVar variable key/value combinations

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

# ---------------------------------------------------------------- loncapa.conf
    if (/^\/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/;
	  }
	open(OUT,'>'.$lpmlnew_file) or
	    die('Cannot open '.$lpmlnew_file.' for output'."\n");
	print(OUT $lpmlnew);
	close(OUT);
      }

# ---------------------- smb.conf (probably will be deprecated in 2004 or 2005)
    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);
      }
    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");
    my $dir = $file; $dir =~ s/([^\/]+)$//;
    my $filename = $1;
    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);
  }

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


This script is free software; you can redistribute it
and/or modify it under the same terms as LON-CAPA itself.

=cut

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>