Diff for /loncom/build/loncaparestoreconfigurations between versions 1.12 and 1.13

version 1.12, 2002/03/03 00:21:23 version 1.13, 2002/05/16 00:20:30
Line 1 Line 1
 #!/usr/bin/perl  #!/usr/bin/perl
   
 # loncaparestoreconfigurations  # loncaparestoreconfigurations - restore data to new LON-CAPA conf files
   #
   # $Id$
   #
   # YEAR=2000
   # 10/25, 12/14 Scott Harrison
   # YEAR=2002
   # Scott Harrison, 05/15
   #
   ###
   
 # Scott Harrison, 10/25/2000  # This tool helps in updating a system.  It restores information for
 # Scott Harrison, 12/14/2000  # configuration files (.lpmlsave or other backup notations).
   
 # This tool helps in updating a system.  It restores backed-up  # By default, the .lpmlsave suffix is used.
 # configuration files (.rpmsave or other backup notations).  
   
 # By default, the .rpmsave suffix is used.  
 # Alternatively, there can be two other invocations  # Alternatively, there can be two other invocations
 # Invocation #1:  # Invocation #1:
 #   ARGV[0]=suffix  #   ARGV[0]=suffix
Line 22 Line 28
 # The time-stamp with the greatest value is  # The time-stamp with the greatest value is
 # taken as the backup file.  # taken as the backup file.
   
 my $suffix=".rpmsave";  # --------------------------------------------- Define program version variable
 my $suffixpragma="";  $VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
   
   # ---------------------------------------------- Process command-line arguments
   my $suffix='.lpmlsave';
   my $suffixpragma='';
 if ($ARGV[0] eq 'suffix') {  if ($ARGV[0] eq 'suffix') {
     $suffix=$ARGV[1] if $ARGV[1]=~/^[\.\w]+$/;      $suffix=$ARGV[1] if $ARGV[1]=~/^[\.\w]+$/;
 }  }
 elsif ($ARGV[0] eq 'lasttimestamp') {  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=(  my @special_conf_files=(
  "/etc/httpd/conf/access.conf",   '/etc/httpd/conf/loncapa.conf',
  "/etc/smb.conf",   '/etc/httpd/conf/access.conf',
  "/etc/samba/smb.conf"   '/etc/smb.conf',
    '/etc/samba/smb.conf'
  );   );
   
 my @generic_conf_files=(  my %pvar; # store the PerlSetVar variable key/value combinations
  "/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 @perlsetvars=("lonHostID","lonRole","lonAdmEMail","lonDefDomain","lonLoadLim","lonExpire","lonReceipt","lonSqlAccess");  # --------------------------------------------- Process the configuration files
 my %pvar;  # NOTE that I have structured this processing to make NO assumptions
 foreach (@special_conf_files) {  # about the processing of each configuration file.  So, in terms
     if (/^\/etc\/httpd\/conf\/access.conf$/) {  # of keeping each file's processing algorithms self-contained, I am not
  if ($suffixpragma eq 'lasttimestamp') {  # modularizing things (where it is obvious that they might be modularized.)
     $suffix=getsuffix('/etc/httpd/conf/access.conf');  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`;   else {
  my $lpmlnew=`/bin/cat /etc/httpd/conf/access.conf$suffix`;      $lpmlold="\n".&readfile('/etc/httpd/conf/access.conf');
 # `/bin/mv /etc/httpd/conf/access.conf /etc/httpd/conf/access.conf.template`;      $lpmlnew_file='/etc/httpd/conf/access.conf'.$suffix;
  foreach my $psv (@perlsetvars) {      unless (-e $lpmlnew_file) {
     if ($template=~/\nPerlSetVar\s+$psv\s+(\S+)/) {   next CONFLOOP;
  my $pval=$1;  
  $lpmlnew=~s/(\nPerlSetVar\s+$psv\s+)\S+/$1$pval/;  
  $pvar{$psv}=$pval;  
     }      }
       $lpmlnew=&readfile($lpmlnew_file);
  }   }
  open OUT,">/etc/httpd/conf/access.conf$suffix";   while($lpmlold=~/\n\s*PerlSetVar\s+(\S+)\s+(\S+)/mcg) {
  print OUT $lpmlnew;      my $pkey=$1; my $pval=$2;
  close OUT;      $lpmlnew=~s/(\n\s*PerlSetVar\s+$pkey\s+)\S+/$1$pval/;
     }      $pvar{$pkey}=$pval;
     if (/^\/etc\/smb.conf$/ and -e "/etc/smb.conf$suffix") {  
  if ($suffixpragma eq 'lasttimestamp') {  
     $suffix=getsuffix('/etc/smb.conf');  
  }   }
  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') {  # ---------------------------------------------------------------- loncapa.conf
     $suffix=getsuffix('/etc/samba/smb.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`;   open(OUT,'>'.$lpmlnew_file) or
  foreach my $psv (@perlsetvars) {      die('Cannot open '.$lpmlnew_file.' for output'."\n");
     $template=~s/\{\{\{\{\[(.*?)\]\}\}\}\}/$pvar{$1}/ge;   print(OUT $lpmlnew);
  }   close(OUT);
  open OUT,">/etc/samba/smb.conf$suffix";  
  print OUT $template;  
  close OUT;  
     }      }
 }  
   
 exit; # Just because this is only about restoring configuration to  
       # new files  
   
 foreach (@generic_conf_files) {  # -------------------------------------------------------------------- smb.conf
     my $file=$_;      elsif (/^\/etc\/smb.conf$/ and -e "/etc/smb.conf$suffix") {
     if ($suffixpragma eq 'lasttimestamp') {   if ($suffixpragma eq 'lasttimestamp') {
  $suffix=getsuffix($file);      $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") {      elsif (/^\/etc\/samba\/smb.conf$/ and -e "/etc/samba/smb.conf$suffix") {
  `/bin/mv $file $_.template`;   if ($suffixpragma eq 'lasttimestamp') {
  `/bin/cp $file$suffix $file`;      $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 {  sub getsuffix {
     my ($file)=@_;      my ($file)=@_;
     print "$file\n";      print("$file\n");
     my $dir=$file; $dir=~s/([^\/]+)$//;      my $dir=$file; $dir=~s/([^\/]+)$//;
     my $filename=$1;      my $filename=$1;
     opendir(DIR,$dir);      opendir(DIR,$dir) or
     my @a=grep {/$filename\.\d{14}/} readdir DIR;   die('Cannot open directory '.$dir.' for viewing'."\n");
     closedir DIR;      my @a=grep {/$filename\.\d{14}/} readdir(DIR);
       closedir(DIR);
     map {s/$filename\.//;} @a;      map {s/$filename\.//;} @a;
     my @b=sort {$a<=>$b} @a;      my @b=sort {$a<=>$b} @a;
     my $suffix='.'.$b[$#b];      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

Removed from v.1.12  
changed lines
  Added in v.1.13


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