I've been giving Bug 459 (No unistall script) some thought. And I've come up 
with what might well be a solution. I'd be interested to hear thoughts on the 
matter.



*

[1] I've taken Galen's suggestion and added support for multiple machine 
architectures. 
Ostensibly this is to support unixes and variants who do not use /usr/sbin to 
store userdel & groupdel commands.

[2] I've removed comments about the install logfile holding misleading 
information. I believe those comments were probably mistaken and am 
investigating the matter further.


** help wanted:
I'd like suggestions of Perl Interpreter Machine Type Operating System 
Classifications for any machines which do not use the /usr/sbin directory for 
the commands userdel and groupdel

with the exception of FreeBSD (or BSDs in general) if they do not have a 
groupdel command of some kind. (Not a procedure for editing the group file, and 
so forth. It must be one single command.) (**Please do not send instructions 
for procedures for editing users and groups.)

Patrick Mackeown
#!/usr/bin/perl -w # please develop with -w
#
# chances are you'll need to install CPAN IO::Tee
# perl -MCPAN -e'install "IO::Tee"'
#
# written @ Mon Jul 06 13:40:53 EDT 2009  patc...@koha.org
#

use strict;    # please develop with the strict pragma
use Config;
use IO::Tee;
use diagnostics;
use DBI;
use File::Copy;
use File::Path; 

###################################################################
#                  Global Assignments
#               (You may edit these values)
###################################################################

my $LOGDIR="/var/log/koha";
my $ETCDIR="/etc/koha";
my $DROPMODE="";
my $DELCOMPLETE="";
my $MODE="SAFE";
my $KOHAROOT="";
my $CONFIGFILE="";
my $TEE_DUAL_OUTPUT;
my @kohausers =qw(koha kohaadmin kohauser);
my @kohagroups =qw(koha kohaadmin kohauser);

###################################################################
# Support Multiple Machine Architectures
###################################################################
my $deluser;
my $delgroup;
for ($Config{myarchname}) {
      if (/i686-linux/) { 
            $deluser= "/usr/sbin/userdel"; 
            $delgroup= "/usr/sbin/groupdel"; 
      }elsif (/i86pc-solaris/){
            $deluser= "/usr/sbin/userdel"; 
            $delgroup= "/usr/sbin/groupdel"; 
      }elsif (/sun4-solaris/){
            $deluser= "/usr/sbin/userdel"; 
            $delgroup= "/usr/sbin/groupdel"; 
       }else { 
            $deluser= "/usr/sbin/userdel"; 
            $delgroup= "/usr/sbin/groupdel"; }
} 

###################################################################
#   Program Main
#   (Do not edit)
###################################################################
#[1] Open an uninstall logfile
     & open_logfile;

#[2] Ask for deletion info. But, only do this as an input flag
#    or if you cannot locate any del info 
    if ($ARGV[0]){
       if ($ARGV[0] =~ /-user/){
           & user_input;
       }else{
           if ($ARGV[0] =~ /-h\b|-help\b/i){
                  & printhelp;
                  exit 0;
           }else{
               if ($ARGV[0] =~ /-dropdb\b/i){
                      & drop_the_koha_db;
                      exit 0;
               }
           }
       }
    }else{
                & printhelpshort;
    }
#    Search for ENV variables
     & locate_env_variables;
###################################################################
#                 The Unix Help Documentation 
###################################################################

sub printhelp{
        print $TEE_DUAL_OUTPUT <<DOCUHELP;

ENV VARS
========
When not run with user input [-user] firstly the program tries 
to find out what your environment variables for PERL5LIB and 
KOHA_CONF are. This isn't conclusive proof that they're the 
ones we're after. But it's a start. Be warned, there could be 
multiple koha installations on this machine (for any number of 
reasons.) 

If for whatever reason you have neither of these environment
variables set, then you'll have to try to find their values.


CONFIGS
=======
Then the program tries to locate and read koha-conf.xml files.

By default the program is configured to search for /etc/koha
and /var/log/koha. These files are set within the parameters 
at the top of the program and can be edited by hand. 

APACHE & Other Web Servers
==========================
The program makes no attempt (in any mode) to deal with virtual
webservers in Apache (or any other type of webserver.) Although 
a koha installation requires these. They'll need removing by hand. 

SAFE mode
=========

By default this installer runs in SAFE mode. Therefore it
deletes nothing. This is because, theoretically, you could
install koha in your root directory, (in single install mode,)
and then ask an installer file to remove the root directory!
Or any other directory that you chose to! What it does is inspect
(and validate your koha directory) & your koha installation and
compiles a set of instructions for you to run (if you want to,)
which would result in the de-installation of koha. What [you]
choose to do then, is up to you. There is a way of editing the
script to automate the de-installation, simply for completeness'
sake. But it's not advisable to automate it.

You could try running either the installer or the uninstaller
as the user koha, But, unless you do this in a directory owned
and accessible by the user koha, then it won't work properly.
Because, (with standard koha installation,) when you run the
installer/uninstaller as the user koha. You will get "permission 
denied" in most directories. Even the dev and single installations 
try to log into /var/log/koha which is not a directory that the 
user koha can create. (And koha will not run unless it can write 
to its logfiles.) You could make directories by hand and then 
assign them to root:koha or koha:koha, or somesuch. But this 
would be messy and confusing.

KOHA DATABASE & UNIX USERS
===========================
The database is assumed to be mysql. The mysql database user
able to drop databases is assumed to be called root (mysqluser)
and the koha database is called koha.

There is an implied assumption here that the koha database and
the unix groups and users are either all to be left in tact or
all to be deleted. And the default assumption is that because
you want to uninstall koha, it doesn't mean that you want to
delete the db & users. (There could be multiple installations.)
But, it's to be noted that if you want to remove any of them
using standard admin commands, it's a simple procedure.
 
By default the program makes no attempt to drop the database or
remove koha's users and groups. You can run it with a [-dropdb]
option. And then it will question you about databases and users
before going on to perform admin commands according to your input
instructions. But it makes just as much sense to run a mysql
command to drop the database & to use standard unix admin commands
to remove users and groups, instead. However, for the sake of
completeness, the utility is provided here, regardless. The
program doesn't have any method of swiftly and silently removing
the koha database, nor will it include one. As much as possible
is done to keep the database in tact, unless removing it is
absolutely necessary. (If you do want one you can edit the script.)

DOCUHELP
}

sub printhelpshort{
        print $TEE_DUAL_OUTPUT <<SHORT;

                Koha Uninstall Info

                Default is SAFE mode no files are deleted.

                (i) long help file 
                uninstall_koha.pl -help
                (ii) enter koha directory to uninstall  
                uninstall_koha.pl -user
                (iii) delete database & unix users
                uninstall_koha.pl -dropdb

                logs to /tmp/koha_uninstall_history.log
                
SHORT
}

sub badinstallinfo{

        print $TEE_DUAL_OUTPUT <<BADINSTALLINFO;

Because theorectically you can install koha anywhere, you need
to check that the directory that you've been told is a koha 
directory actually is one! Let's face it, it could be anything! So 
you define a koharoot by what it contains. And if you're not happy 
that this is one you refuse flat-out to deal with it. (End of story.)

You can remove all genuine koha files in koharoot & /etc/koha & 
then test for an empty dir. If files exist there's something wrong.

Now, in theory, if we fail to validate the koharoot we will set 
BADINSTALLINFO to "True" and you can believe that if we never did set 
BADINSTALLINFO to true then we validated all of the directories in 
koharoot, (unless a bug in the script prevented us from setting the 
flag.) So, you might want to take the failure to set the flag as a 
confirmation that the directory $KOHAROOT is a valid koharoot
(Personally I'd still check it by hand and see if I wanted to 
delete it, or not.  But for automation purposes, that's what you 
could do.


There are a number of places that $KOHAROOT can be generated.
      (a) the logfilereading subroutine can guess it.
      (b) the user can type it in.
      (c) it can be hardcoded into the program
      (d) Calculated from the ENV variables.

BADINSTALLINFO
}


sub warnaboutroot{
              print $TEE_DUAL_OUTPUT <<WARNBADROOT;

Koha Uninstallation Warning:

The file path: $KOHAROOT
was determined to be the location of a koha installation on your 
machine. But, because $KOHAROOT/$_ does not exist. $KOHAROOT will 
not be treated as an authentic koha root. And it will not be 
automatically deleted. You'll probably want to visit $KOHAROOT 
and determine for yourself whether or not you wish to keep it or 
delete it.


WARNBADROOT
}


sub okibelieve{
            print $TEE_DUAL_OUTPUT <<OKIBELIEVE;

I've verified all of the koha installation subdirectories. So, 
I can say to the best of my ability that I think $KOHAROOT is 
a genuine koha installation.

OKIBELIEVE
}


sub printenvfound{
         print $TEE_DUAL_OUTPUT <<ENVFOUND;

I've found the ENV Variables $ENV{PERL5LIB} & $ENV{KOHA_CONF}
This isn't conclusive proof that they point to a koha installation.
The environment variables might be faulty, they could be too old or
left over from another previous koha installation, or just mistaken.
But I'm going to test them to see if I can locate a koha installation.

>From the location of the koha Perl library at: $ENV{PERL5LIB}
I make an educated guess that there is a koha installation at: $KOHAROOT

At the moment $KOHAROOT is KOHAROOT

ENVFOUND
}

sub noguarantee{
          print $TEE_DUAL_OUTPUT <<NOGUARANTEE;

No guarantee that either /etc/koha-conf.xml or /etc/koha/koha-conf.xml
exists. (They may both exist or not, or niether.) And, even if one, or both, 
does exist, there's no guarantee that either contains what you need (or is 
current.)


NOGUARANTEE
}

sub mode{
        if ($MODE =~ /SAFE/){
        print $TEE_DUAL_OUTPUT <<SAFE;

Program mode is: SAFE. No files will be deleted. And the koha database will 
not be dropped. A logfile was created at

 /tmp/koha_uninstall_history.log


SAFE
       }else{
         print $TEE_DUAL_OUTPUT <<RISK;


It is not advisble to run the program in any mode other than SAFE mode.
=======================================================

YOU are responsible for ensuring that it is instructed to delete 
the correct files.

RISK
       }
}
###################################################################
# The Basement: This is where the code is.
###################################################################

sub open_logfile{ #Preserve the old one, (if it exists.)
      if ( -f "/tmp/koha_uninstall_history.log"){
         copy( "/tmp/koha_uninstall_history.log", 
"/tmp/koha_uninstall_history.log.$$") 
             or warn "Cannot preserve old koha uninstall history log.";
             if ( -f "/tmp/koha_uninstall_history.log.$$"){
                   unlink "/tmp/koha_uninstall_history.log";
             }
      }
      $TEE_DUAL_OUTPUT = IO::Tee->new(">> /tmp/koha_uninstall_history.log", 
\*STDOUT);
}


sub is_this_authentic_koha_root{

   my $BADUNINSTALLINFO="";
   my $manyerrors="0";
   my @KOHAFILES=qw( bin  doc  intranet  lib  man  misc  opac );
   foreach (@KOHAFILES) {
      if ($manyerrors < 3){
           if ( !-d "$KOHAROOT/$_"){
              ++$manyerrors;
              $BADUNINSTALLINFO="True";
              & warnaboutroot;
       }
              # Bailout of uninstall. You've been given bad uninstall info.
           } else {
                  if ($manyerrors < 3){;
                     if ( -f "$KOHAROOT/$_"){
                         print $TEE_DUAL_OUTPUT "Validating $KOHAROOT [Found] 
$_\n";
                     }
                  }
           }
   } 
        if ( "$BADUNINSTALLINFO" !~ /True/){
             & okibelieve;
             & prep_genuine_root_del;
        }
}



sub locate_env_variables{
      #  The first thing we need to do is test for ENV variables
      if ($ENV{KOHA_CONF}){
             print $TEE_DUAL_OUTPUT "\n [Found] ENV Variable $ENV{KOHA_CONF}  
\n";
             & try_etc_koha_conf_xml;
      }
      if (!$ENV{PERL5LIB}){
             if (!$ENV{KOHA_CONF}){
                  print $TEE_DUAL_OUTPUT "\nWARNING PERL5LIB & KOHA_CONF ENV 
VARS missing!\n";
                  & try_etc_koha_conf_xml;
                  & user_input;
             }
      }else{
             if (!$ENV{KOHA_CONF}){
                  print $TEE_DUAL_OUTPUT "\nWARNING KOHA_CONF ENV VAR 
missing!\n";
             }else{
                    print $TEE_DUAL_OUTPUT "\n [Found] ENV Variable 
$ENV{KOHA_CONF}  \n";
                    & try_etc_koha_conf_xml;
             }


         # Env variables are present.
         $KOHAROOT=$ENV{PERL5LIB};
         if ( $ENV{PERL5LIB} =~ /lib\// ){      
              $KOHAROOT =~ s/lib\///; 
         }else{
              $KOHAROOT =~ s/lib//;
         }                                      
         $KOHAROOT =~ s/koha\//koha/;            
         & printenvfound; 
         & is_this_authentic_koha_root;
      }
}

sub try_etc_koha_conf_xml{
       if ( -f "/etc/koha-conf.xml" ){
             $CONFIGFILE="/etc/koha-conf.xml";
             & read_config_file;
             & del_conf;
       }else{
             if ( -f "/etc/koha/koha-conf.xml" ){
                   $CONFIGFILE="/etc/koha/koha-conf.xml";
                   & read_config_file;
                   & del_conf;
             }else{
                    if ( -f "$ENV{KOHA_CONF}" ){
                          $CONFIGFILE="$ENV{KOHA_CONF}";
                          & read_config_file;
                          & del_conf;
                    }
             }

           sub read_config_file{
                      my $etc_conf_log;
                      print $TEE_DUAL_OUTPUT "\n\n [Found] Config at loc 
$CONFIGFILE \n";
                      open(CONFIG_FILE, "<$CONFIGFILE");
                      while (<CONFIG_FILE>){
                         if ($_ =~ /install_log/){
                             s/\<install_log\>//;  # config is XML trim this 
off  
                             s/\<\/install_log\>//;
                             s/\s+//g;
                             chomp;    
                             $etc_conf_log = $_; 
                             if ( -f "$etc_conf_log" ){
                                   $KOHAROOT=$etc_conf_log;
                                   $KOHAROOT =~ s/koha-install-log//;
                                   $KOHAROOT =~ s/misc\///;
                                   print $TEE_DUAL_OUTPUT <<EOF2;

   I have located a koha installation log file history at $etc_conf_log
   However, there is no guarantee that the logfile is either current or 
accurate.

   From the location of the koha logfile at: $etc_conf_log
   I make an educated guess that there is a koha installation at: $KOHAROOT

EOF2
                             & is_this_authentic_koha_root;
                             }
                         }
                      }
           }
       }
}


sub user_input{
      if ($DELCOMPLETE !~ /True/){
          print $TEE_DUAL_OUTPUT "Enter location of your koha installation\n";
            my $kohainstallation=(<STDIN>);
            chop $kohainstallation;
            if ( -d $kohainstallation ){
                 $KOHAROOT = "$kohainstallation";
                 print " [Found] $KOHAROOT Do you want to delete it? Yes or 
No?\n";
                 my $continue2=(<STDIN>);
                 chop $continue2;
                 if ($continue2 =~ /^Y\b|^yes|^y\b|^Yes/i) { # Uninstall 
user-specified koharoot
                       & is_this_authentic_koha_root;
                 }
            }else{
                 print <<EOF1;

                 The user-specified directory $kohainstallation does not exist. 
Please locate
                 your koha installation and rerun the script.
EOF1
                 exit 0; 
            }
        }

}

sub prep_genuine_root_del{
        & mode;
        if ( $MODE =~ /SAFE/){
        }else{
           if ( $MODE =~ /INSECURE/){
                   & deletelogs;
                      if (-d "$ETCDIR"){
                           rmtree($ETCDIR) or warn $!;
                           my @ETCKOHACONTENTS=qw( koha-httpd.conf  pazpar2  
README.txt  zebradb );
                           foreach (@ETCKOHACONTENTS) {
                              if ( -e "$ETCDIR/$_"){
                                     print $TEE_DUAL_OUTPUT "[DELETING] 
$ETCDIR/$_\n";
                                     rmtree("$ETCDIR/$_") or warn $!;
                              }
                           }
                            rmdir ("$ETCDIR/$_") || warn (" [ERROR IN DELETING] 
$ETCDIR/$_ $?");
                        }
                      my @KOHAFILES=qw( bin  doc  intranet  lib  man  misc  
opac );           
                      foreach (@KOHAFILES) {
                            if ( -d "$KOHAROOT/$_"){
                                   rmtree("$KOHAROOT/$_") or warn $!;
                                   print $TEE_DUAL_OUTPUT "[DELETING] 
$KOHAROOT/$_\n";
                                   if ( -d "$KOHAROOT/etc"){
                                         print $TEE_DUAL_OUTPUT "[DELETING] 
$KOHAROOT/etc\n";
                                         rmtree("$KOHAROOT/etc") or warn $!;
                                   }
                                   if ( -d "$KOHAROOT/var"){
                                         print $TEE_DUAL_OUTPUT "[DELETING] 
$KOHAROOT/var\n";
                                         rmtree("$KOHAROOT/var") or warn $!;
                                   }
                            }
                      }
                      if ( -e "$KOHAROOT"){
                            print $TEE_DUAL_OUTPUT "[DELETING] $KOHAROOT\n";
                            rmdir ("$KOHAROOT") || warn (" [ERROR IN DELETING] 
$KOHAROOT $?");
                      }

               print $TEE_DUAL_OUTPUT "[DELETION COMPLETE]\n";
               $DELCOMPLETE="True";

               print $TEE_DUAL_OUTPUT "[DROPPING] the koha database\n";
               & drop_the_koha_db;
           }
        }
}


sub del_conf{
           if ( $MODE =~ /SAFE/){
               print $TEE_DUAL_OUTPUT " Program mode is: SAFE. No files will be 
deleted. \n";
           }else{
                    if ( $MODE =~ /INSECURE/){
                            if ( -e $CONFIGFILE){
                                  print $TEE_DUAL_OUTPUT "\n\n [DELETING] 
Config at loc $CONFIGFILE \n";
                                  unlink $CONFIGFILE;
                            }
                    }

           }
}


sub drop_the_koha_db{
      # You really want to make sure that you really want to do this!
      print "Do you want to drop the koha database? Yes or No?\n";
      my $dropit=(<STDIN>);
      chop $dropit;
         if ($dropit =~ /^Y\b|^yes|^y\b|^Yes/i) { # You have permission to drop 
the database
               print "Are you sure that you want to drop the koha database? Yes 
or No?\n";
               my $sure=(<STDIN>);
               chop $sure;
               if ($sure =~ /^Y\b|^yes|^y\b|^Yes/i) { #How sure does he need to 
be? (Remove it.)
                   & run_drop_db_code;
               }
         }
       print "Do you want to delete koha's users and groups? Yes or No?\n";
       my $people=(<STDIN>);
       chop $people;
       if ($people =~ /^Y\b|^yes|^y\b|^Yes/i) { # del users & groups 
             & del_users_and_groups;
       }

          sub run_drop_db_code{
                 my $DBPASSWD="katikoan";
                 my $DBUSER="root";
             if ( $DROPMODE !~ /SILENT/){
                 print "Please enter [mysql]database username of mysql admin 
user. \n";
                 $DBUSER=(<STDIN>);
                 chop $DBUSER;
                 print "Please enter [mysql]database password for the mysql 
admin user. \n";
                 $DBPASSWD=(<STDIN>);
                 chop $DBPASSWD;
             }

             my 
$dbh=DBI->connect('DBI:mysql:mysql:localhost:port=3306:socket=/tmp/mysqld-new.sock',
 
                $DBUSER, $DBPASSWD) or warn "Cannot connect to database : 
$DBI::errstr\n";
             my $sth = $dbh->prepare('drop database koha')
                or warn "Couldn't prepare statement: " . $dbh->errstr;
             $sth->execute()             # Execute the query
                  or warn "Couldn't execute statement: " . $sth->errstr;
             $sth->finish;
             $dbh->disconnect;
          }

          sub del_users_and_groups{
                 foreach (@kohausers){
                     `$deluser $_`; 
                 }
                 foreach (@kohagroups){
                      `$delgroup $_`;
                 }
          }
}


sub deletelogs{
  if (-d "$LOGDIR") {
          my @KOHALOGS=qw( koha-access_log koha-intranet-rewrite.log
                           koha-opac-error_log README koha-error_log
                           koha-opac-access_log koha-opac-rewrite.log);
                           foreach (@KOHALOGS) {
                           print $TEE_DUAL_OUTPUT "[DELETING] $LOGDIR/$_\n";
                              unlink "$LOGDIR/$_";
                           }
                           rmdir ("$LOGDIR") || warn (" [ERROR IN DELETING] 
$LOGDIR $?");
                        }

}
_______________________________________________
Koha-devel mailing list
Koha-devel@lists.koha.org
http://lists.koha.org/mailman/listinfo/koha-devel

Reply via email to