#!/usr/bin/env python3 """ Delete BIRCH directories, remove BIRCH access for BIRCH Administrator Synopsis: UNINSTALL-birch.py [-Qn] [-P] [-d=] -Q Quiet option. Do not prompt user to continue. -P Permanent uninstall. This will set up $BIRCH/admin. with scripts that will remove the birch access lines from users' .rc files (eg. .bashrc, .profile, .cshrc) the next time they start a shell. These are lines containing the string '#_BIRCH'. -n do NOT delete the binaries and libraries directories -d specify the directory location to perform the uninstallation process If the path of BIRCH contains the string 'BIRCHDEV', this script will abort. If the path of BIRCH contains the string 'BIRCHBINDEV', binaries will not be deleted. Testing: UNINSTAL-birch.py must work in the following conditions: o manual uninstall before update o after failure of a fresh install or update o during permanent uninstall ie. -P o after a permanent install, if a new install is being done o For a permanent uninstall, UNINSTALL-birch.py calls nobirch.py. UNINSTALL-birch.py should still work if nobirch.py fails at 1 or more steps, or even if nobirch.py isn't found. @modified: May 15, 2023 @author: Brian Fristensky @contact: frist@cc.umanitoba.ca """ # Automatically converted to Python3 using 2to3. Compliant with Python 2 and 3. import sys, re, os, os.path, shutil, subprocess # - - - - - - - - - - - - File lists - - - - - - - - - - FRAMEWORK = ["acedb", "acedb4.9l", "admin", "dat", "doc", "java", "labace", "local-generic", "manl", "ncbi", "pkg", "python", "public_html", "script", "tutorials", "birchconfig.homedir.target.html"] BINARIES = ["bin-solaris-sparc", "bin-solaris-amd64", "bin-linux-x86_64", "bin-osx-x86_64", "bin-macos-arm64", "bin-linux-intel", "lib-solaris-sparc", "lib-solaris-amd64", "lib-linux-intel", "lib-linux-x86_64", "lib-osx-x86_64", "lib-macos-arm64", "bin-winxp-32", "bin-win7-64", "lib-winxp-32", "lib-win7-64"] INSTALLDIRS = ["install-birch", "install-scripts"] # - - - - - - - - Delete a file or directory - - - - - - - - def delfile(filename): if os.path.isdir(filename): shutil.rmtree(filename) else: if os.path.islink(filename) : os.unlink(filename) else : os.remove(filename) #========================= UNINSTALLbirch ==================================== def UNINSTALLbirch(BIRCH, PrintMsg = True, DelBinaries = True, Permanent = False): #--------------------------------------------------------------- # Make sure that this script doesn't run in BIRCHDEV, which # would clobber the master copy of BIRCH. if "BIRCHDEV" in BIRCH: print ('>>> UNINSTALL-birch.py cannot be run in BIRCHDEV') print ('>>> Doing so would clobber the master copy of BIRCH') sys.exit(1) #--------------------------------------------------------------- else: # Ask user if binaries should be deleted if PrintMsg: print('>>> To delete the existing binaries and libraries, type y') print('>>> If you are installing the BIRCH framework, but wish to') print('>>> keep the existing binaries, type n') # The Python 2.x way to read terminal input would be: #choice = raw_input(">>> Type y to continue, n to exit\n") # # However, raw_input will not be available in Python 3.0. # Here's a workaround found at http://python3porting.com/differences.html # This will work in Python 2.x and 3.x # Thanks guys :-< try: input = raw_input except NameError: pass choice = eval(input(">>> Enter Y or N\n")) if choice in ['Y','y'] : DelBinaries = True else: DelBinaries = False # Binaries will not be deleted if this is a BIRCHBINDEV installation. if BIRCH.find("BIRCHBINDEV") > -1 : DelBinaries = False if PrintMsg : print('>>> This copy of BIRCH is installed in BIRCHBINDEV') print('>>> Binaries will not be deleted.') #------------------ Delete files and directories from lists ---------------- #-------- Prompt the user to begin deleting files ------------------ if PrintMsg : try: input = raw_input except NameError: pass choice = eval(input(">>> Type Y to begin deleting BIRCH:\n")) else : choice = "Y" #============== BEGIN DELETING FILES ====================== if choice in ['Y','y'] : if os.path.isdir(BIRCH): if Permanent : os.chdir(os.path.join(BIRCH, 'admin')) # Remove lines form .rc files (eg. .profile) that # call setup scripts in $BIRCH/admin p = subprocess.Popen(['python3', 'nobirch.py', '-Q', '-P']) p.wait() os.chdir(BIRCH) # Delete Framework files for file in FRAMEWORK : if os.path.exists(file): # if PrintMsg: if True : print("Deleting " + file) delfile(file) if Permanent : # Safer to do this separately, after the framework files # have been deleted. # Create dummy admin directory to remove these lines when # other users login. Eventually, all rc files should be # cleaned up. if os.path.isdir('admin.uninstall'): shutil.move('admin.uninstall','admin') # Delete binaries and libraries if DelBinaries: for file in BINARIES : if os.path.exists(file): # if PrintMsg: if True: print ("Deleting " + file) delfile(file) # Delete install directories, including this one for file in INSTALLDIRS : if os.path.exists(file): # if PrintMsg: if True: print("Deleting " + file) delfile(file) else: if PrintMsg: print('>>> exiting program. No files deleted.') ############################################################# #-------------------- MAIN --------------------------------- if __name__=="__main__": # set the default options PrintMsg = True DelBinaries = True Permanent = False BIRCH = os.path.realpath("..") if "BIRCH" in os.environ: BIRCH = os.environ.get("BIRCH") # - - - - - - - - - - Command line options - - - - - - - - - - for a in sys.argv[1:]: if str(a) == "-Q": PrintMsg = False elif str(a) == "-P": Permanent = True elif str(a) == "-n": DelBinaries = False elif str(a).startswith('-d='): BIRCH = str(a)[3:] elif not str(a).rstrip(" ") == "": print("UNINSTALL-birch.py: Invalid command line arguments!") print("USAGE: UNINSTALL-birch.py [-Q -n] [-d=directory]") sys.exit(1) UNINSTALLbirch(BIRCH, PrintMsg, DelBinaries, Permanent)