#! /usr/bin/perl -w
##**************************************************************
##
## Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
## University of Wisconsin-Madison, WI.
## 
## Licensed under the Apache License, Version 2.0 (the "License"); you
## may not use this file except in compliance with the License.  You may
## obtain a copy of the License at
## 
##    http://www.apache.org/licenses/LICENSE-2.0
## 
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
##**************************************************************


##*******************************************************************
## Stops a cold started condor installation and optionally 
## uninstalls the installation.
##
## Author: Joe Meehean
## Date: 7/15/05
##*******************************************************************

##*******************************************************************
## Note 1: The configfile paramters are interpreted. It should be the
## same exact value that was passed to cold_start.  The file name is
## extracted from the path, and then this program checks the location
## that cold_start would have put the installed version of the config.
## If it cannot find the installed version it falls back on using the
## original (note this will not currenly work with config files
## specified as http urls).
##*******************************************************************

#***
# Uses
#***
use strict;
use FindBin;
use Getopt::Long;
use File::Spec;
use File::Basename;
use Cwd;

#***
# Constant Static Variables
#***
my $USAGE = 
    "Usage: condor_cold_stop [-force] <-configfile condor_config_file>\n".
    "[-basedir base_dir]\n".
    "[-localdir local_dir] [-runlocalconfig config_file]\n".
    "[-cleaninstall] [-cleanlocal] [-stop]\n".
    "[-logarchive archive] [-spoolarchive archive] [-execarchive archive]\n".
    "[-filelock] [-pid] [-artifact artifact_file]\n".
    "[-log install_log]\n".
    "[-nogurl] [-globuslocation globus_location]\n".
    "[-help]\n";

my $INSTALL_LOG_DEFAULT = 'install.log';

my $LOCAL_STOP_PROGRAM = 'condor_local_stop';
my $FORCE_OPT = '-f';
my $BASE_DIR_OPT = '-basedir';
my $CONFIG_OPT = '-configfile';
my $LOCAL_DIR_OPT = '-localdir';
my $LOCAL_CONFIG_OPT = '-localconfig';
my $INSTALL_CONFIG_OPT = '-installconfig';
my $FG_OPT = '-fg';
my $FILELOCK_OPT = '-filelock';
my $PID_OPT = '-pid';
my $ARTIFACT_OPT ='-artifact';


my $INSTALL_CLEANUP_PROGRAM = 'cleanup_release';


my $LOCAL_CLEANUP_PROGRAM = 'condor_cleanup_local';
my $LOCALDIR_OPT          = '-localdir';
my $ARCHIVEONLY_OPT       = '-archiveonly';
my $LOGARCHIVE_OPT        = '-logarchive';
my $SPOOLARCHIVE_OPT      = '-spoolarchive';
my $EXECARCHIVE_OPT       = '-execarchive';
my $GLOBUS_LOC_OPT        = '-globuslocation';
my $NO_GURL_OPT           = '-nogurl';
my $CONDOR_LOCAL_INSTALL_CONFIG = 'condor_config.local_install';


#***
# Non-Constant Static Variables
#***
my $force = 0;
my $clean_install_flag = 0;
my $clean_local_flag = 0;
my $stop_flag = 0;
my $log_archive = 0;
my $spool_archive = 0;
my $exec_archive = 0;
my $local_dir = cwd;
my $base_dir = cwd;
my $global_config_file = 0;
my $local_config_file = 0; 
my $install_log_path = 0;
my $filelock_flag = 0;
my $pid_flag = 0;
my $midwife_artifact = 0;
my $no_gurl_flag = 0;
my $globus_location = '/opt/globus';
my $help_flag = 0;

#***
# Main Function
#***

#Process command-line arguments
GetOptions( 'force'=>\$force,
	    'configfile=s'=>\$global_config_file,
	    'basedir=s'=>\$base_dir,
	    'localdir=s'=>\$local_dir,
	    'runlocalconfig=s'=>\$local_config_file,
	    'cleaninstall'=>\$clean_install_flag,
	    'cleanlocal'=>\$clean_local_flag,
	    'stop'=>\$stop_flag,
	    'logarchive=s'=>\$log_archive,
	    'spoolarchive=s'=>\$spool_archive,
	    'execarchive=s'=>\$exec_archive,
	    'log=s'=>\$install_log_path,
	    'filelock'=>\$filelock_flag,
	    'pid'=>\$pid_flag,
	    'artifact=s'=>\$midwife_artifact,
	    'nogurl'=>\$no_gurl_flag,
	    'globuslocation=s'=>\$globus_location,
	    'help'=>\$help_flag,
	    );

# If none of the options are set, then all of them are
if( !$clean_install_flag && !$clean_local_flag && !$stop_flag ){
    $clean_install_flag = 1;
    $clean_local_flag = 1;
    $stop_flag = 1;
}

# Required Stop Arguments
my $missing_stop_requirements = $stop_flag && !$global_config_file;

die $USAGE if( $help_flag || $missing_stop_requirements );

# Perform the stop
&StopIt() if( $stop_flag );

# Archive and cleanup the local_dir if neccessary
if( $clean_local_flag || $log_archive || 
    $spool_archive || $exec_archive){
    &CleanUpLocal() 
}
   
# Perform install cleanup
&CleanUpInstall() if ( $clean_install_flag );



#*********************************************************************
# Perform the Shutdown Operation
#*********************************************************************
sub StopIt(){
    # Find the global configuration file
    my $global_config_path = &FindConfigFilePath($global_config_file);
    
    # Construct the basic arguments to local_stop
    my @args = ($CONFIG_OPT, $global_config_path, 
		$BASE_DIR_OPT, $base_dir);

    # Add the local config if nessecary
    if( $local_config_file ){
	my $local_config_path = &FindConfigFilePath($local_config_file);
	push @args, $LOCAL_CONFIG_OPT, $local_config_path;
    }

    # Add the install configuration
    my $local_install_config = 
	File::Spec->catpath(0, 
			    $local_dir, 
			    $CONDOR_LOCAL_INSTALL_CONFIG);
    push @args, $INSTALL_CONFIG_OPT,  $local_install_config if( -e $local_install_config );

    # Add the local directory
    push @args, $LOCAL_DIR_OPT, $local_dir;

    # Add the force option if neccessary
    push @args, $FORCE_OPT if( $force );

     # midwife args
    push @args, $FILELOCK_OPT if( $filelock_flag );
    push @args, $PID_OPT if( $pid_flag );
    push @args, ($ARTIFACT_OPT, $midwife_artifact) if( $midwife_artifact);

    # Execute local_stop
    my $local_stop_path = File::Spec->catpath(0, $FindBin::Bin, $LOCAL_STOP_PROGRAM);
    !system $local_stop_path, @args
	or die "FAILED: Failed to stop the local condor installation";
}

#*********************************************************************
# Searches the installation directory and then the original location
# for the given configuration file, in that order.  Returns a path to 
# the configuration file that exists.
#*********************************************************************
sub FindConfigFilePath(){
    my ($config_file) = @_;  #Name the parameters
    
    # Extract just the file name
    my $config_name = basename $config_file;

    # Check the installation directory for the installed version
    my $config_path = 
	File::Spec->catpath(0, $base_dir, $config_name);

    # If not in the installation directory
    # Try using the original version
    if( !-e $config_path ){
	$config_path = $config_file;
    } 

    # If the original version is missing as well
    # Fail
    if( !-e $config_path ){
	die "FAILED: Cannot find the installed version of configuration file".
	    "[$config_file] in the installation directory [$config_path]";
    }

    return $config_path;
}

#*********************************************************************
# Cleans and archives the local_dir.
#*********************************************************************
sub CleanUpLocal(){
    
    # Construct the basic arguments to condor_cleanup_local
    my @args = ($LOCALDIR_OPT, $local_dir,
		$BASE_DIR_OPT, $base_dir);

    # Remove the local install configuration
    my $local_install_config = File::Spec->catpath(0, 
						   $local_dir, 
						   $CONDOR_LOCAL_INSTALL_CONFIG);
    push @args, ($CONFIG_OPT, $local_install_config);

    # Archive only if required
    push @args, $ARCHIVEONLY_OPT if( !$clean_local_flag );

    # Archive the log dir if required
    push @args, ($LOGARCHIVE_OPT, $log_archive) if ($log_archive);

    # Archive the spool dir if required
    push @args, ($SPOOLARCHIVE_OPT, $spool_archive) if ($spool_archive);

    # Archive the exec dir if required
    push @args, ($EXECARCHIVE_OPT, $exec_archive) if ($exec_archive);

    # File transfer options
    push @args, ($GLOBUS_LOC_OPT, $globus_location) if ($globus_location);
    push @args, ($NO_GURL_OPT) if ($no_gurl_flag);

    # Find the cleanup_local executable
    my $local_cleanup_path = 
	File::Spec->catpath(0, $FindBin::Bin, $LOCAL_CLEANUP_PROGRAM);

    # condor_cleanup_local -localdir $local_dir 
    !system $local_cleanup_path, @args
	or die "FAILED: Failed to cleanup local_dir";


}

#*********************************************************************
# Unistall the condor installation
#*********************************************************************
sub CleanUpInstall(){
    # Determine the location of the install log
    if( !$install_log_path ){
	$install_log_path = File::Spec->catpath(0, $base_dir, $INSTALL_LOG_DEFAULT);
    }

    # Construct the basic arguments to install_cleanup
    my @args = ($install_log_path);
    
    # Execute the cleanup
    my $install_cleanup_path = 
	File::Spec->catpath(0, $FindBin::Bin, $INSTALL_CLEANUP_PROGRAM);
    !system $install_cleanup_path, @args
	or die "FAILED: Failed to cleanup local condor installation: $!";
}
