#!/usr/bin/env python3 import os, os.path, sys, shutil, re, getpass, urllib.request, urllib.parse, urllib.error, subprocess import birchhome, customdoc, htmldoc, newuser, setplatform, update_local ''' birch_install.py - Performs the tasks necessary for a complete installation of BIRCH Asumes that framework and binary files have already been downloaded from BIRCH web site. This script is usually run by getbirch.jar, but can be run manually. Synopsis: birch_install.py platform installdir adminemail install minibirch Example: birch_install.py linux-x86_64 /home/rjs/BIRCH rjs@nullmail.com Y N @param installDir the target location to install BIRCH @param logger the output log/console to use to display progress information @param adminEmail the administrator's email address to use for the installation @param install whether to install or update birch (Y = install, N=update) @param minibirch whether to install miniBIRCH, N for full BIRCH install, Y for minibirch @modified: May 16, 2023 @author: Brian Fristensky @contact: brian.fristensky@umanitoba.ca ''' def run_pyinstall (PLATFORM, installDir, adminEmail, install, minibirch): username = getpass.getuser() admindir = os.path.join(installDir, "admin" ) installBIRCH = os.path.join(installDir, "install-scripts" ) local = os.path.join(installDir, "local" ) phtml = os.path.join(installDir, "public_html" ) scriptdir = os.path.join(installDir, "script" ) htmldirParam = os.path.join(installBIRCH, "htmldir.param" ) localgeneric = os.path.join(installDir, "local-generic" ) oldstrParam = os.path.join(installBIRCH, "oldstr.param" ) ladmin = os.path.join(local, "admin" ) pfile = os.path.join(ladmin, "BIRCH.properties" ) paramfile = os.path.join(ladmin, "newstr.param" ) installDirURL = 'file://' + urllib.request.pathname2url(os.path.abspath(installDir)) phtmlDirURL = 'file://' + urllib.request.pathname2url(os.path.abspath(phtml)) if install: # New install only: create a new local directory for BIRCH print ("Moving local-generic to local") shutil.move(localgeneric, local) #---------------------- Steps for both new install and update ---------------------- # configure Birchhome print ('') print ('') print ('') print ("********************Birchhome********************") print ("Running birchhome") # need to update this once default install is using BIRCHDEV # birchhome.main(install_dir,homepath); birchhome.birchhome(installDir) # need to run setplatform print ('') print ("********************Setplatform********************") print("Setting birch platform to " + PLATFORM) print("Using install dir: " + installDir) setplatform.setplatform(installDir) os.chdir(os.path.join(installDir, "install-scripts")) #---------------------- Steps for New Installation only ---------------------- if install: print ('') print ('') print ("---------------------- NEW BIRCH INSTALLATION ----------------------") # write a new BIRCH.properties file print ("Writing BIRCH.properties") props = open (pfile, "w+") props.write("BirchProps.homedir=" + installDir + '\n') props.write("BirchProps.adminUserid=" + username + '\n') props.write("BirchProps.birchURL=" + phtmlDirURL + '\n') props.write("BirchProps.adminEmail=" + adminEmail + '\n') props.write("BirchProps.platform=" + PLATFORM + '\n') # BirchProps.BirchMasterCopy props.write("BirchProps.birchHomeURL=" + installDirURL + '\n') props.write("BirchProps.minibirch=" + str(minibirch) + '\n') props.close() if os.path.exists(pfile): print ("Birch properties file written successfully") else: print ("Error, properties file not written!") #Call BLHelper.py to set default values for BioLegato helper apps. # We BLHelper.py using subprocess.Popen, mainly because I don't know # how to call an imported script that doesn't take a fixed number of arguments. # There probably is a way, but I haven't found it online. print ('') print ("******************** BLHelper.py ********************") print ("Running BLHelper.py") # We need to flush the standard output at this point. If we don't, the # messages from BLHelper.py will appear BEFORE any other install message. sys.stdout.flush() scriptpath = os.path.join(installDir, 'install-scripts', 'BLHelper.py') p = subprocess.Popen(["python3", scriptpath, "--install", "--platform", PLATFORM, "--birchdir", installDir]) p.wait() # Call BIRCHSettings.py to set system-wide default values for BioLegato helper apps. # We call BIRCHSettings.py using subprocess.Popen, mainly because I don't know # how to call an imported script that doesn't take a fixed number of arguments. # There probably is a way, but I haven't found it online. print ('') print ("******************** BIRCHSettings.py ********************") print ("Running BIRCHSettings.py") # We need to flush the standard output at this point. If we don't, the # messages from BIRCHSettings.py will appear BEFORE any other install message. sys.stdout.flush() scriptpath = os.path.join(installDir, 'install-scripts', 'BIRCHSettings.py') p = subprocess.Popen(["python3", scriptpath, "--install", "--birchdir", installDir]) p.wait() # For new install, set BIRCH Administrator's personal BL_EMAIL variable adminEmail. print ('') print ("******************** BIRCHUserSettings.py ********************") print ("Running BIRCHUserSettings.py") # We need to flush the standard output at this point. If we don't, the # messages from BIRCHSettings.py will appear BEFORE any other install message. sys.stdout.flush() scriptpath = os.path.join(installDir, 'install-scripts', 'BIRCHUserSettings.py') p = subprocess.Popen(["python3", scriptpath, "--setvar", "BL_EMAIL="+adminEmail]) p.wait() #Call blastdbkit.py to set BLASTDB environment variable, and to # Set up menus in birchadmin for installing, updating and deleting # local copies of BLAST databases. Also creates menus in bldna and blprotein. # for searching these databases print ('') print ("******************** blastdbkit.py ********************") print ("Running blastdbkit.py") # We need to flush the standard output at this point. If we don't, the # messages from BIRCHSettings.py will appear BEFORE any other install message. sys.stdout.flush() scriptpath = os.path.join(installDir, 'install-scripts', 'blastdbkit.py') blastdbDir = os.path.join(installDir, 'GenBank') p = subprocess.Popen(["python3", scriptpath, "--configure", "--birchdir", installDir, "--blastdb", blastdbDir]) p.wait() #---------------------- Steps for Update only ---------------------- else: # Update an existing installation print ('') print ('') print ("---------------------- UPDATING BIRCH ----------------------") print ("Parsing BIRCH properties file") # These variables will be needed for running customdoc.py props = open (pfile, "r") for line in props: if not (line.startswith('#')) : if '=' in line: fields = line.split('=') if fields[0].lower() == 'birchprops.adminemail': adminEmail = str(fields[1]).rstrip("\n\r") print("Setting the BIRCH administrator's email to: " + adminEmail) elif fields[0].lower() == 'birchprops.birchurl': installDirURL = str(fields[1]).rstrip("\n\r") print("Setting the URL for the local BIRCH web site to: " + installDirURL) elif fields[0].lower() == 'birchprops.birchhomeurl': phtmlDirURL = str(fields[1]).rstrip("\n\r") print("Setting the URL for the local BIRCH documentation to: " + phtmlDirURL) props.close() # Turn off BIRCH access import nobirch nobirch.nobirch(installDir) # copy new files from local-generic to existing local directory print ('') print ("******************** update_local.py ********************") print ("Running update_local.py") update_local.update_local() #Call BLHelper.py to set default values for BioLegato helper apps. # We BLHelper.py using subprocess.Popen, mainly because I don't know # how to call an imported script that doesn't take a fixed number of arguments. # There probably is a way, but I haven't found it online. print ('') print ("******************** BLHelper.py ********************") print ("Running BLHelper.py") # We need to flush the standard output at this point. If we don't, the # messages from BLHelper.py will appear BEFORE any other install message. sys.stdout.flush() scriptpath = os.path.join(installDir, 'install-scripts', 'BLHelper.py') p = subprocess.Popen(["python3", scriptpath, "--update", "--platform", PLATFORM, "--birchdir", installDir]) p.wait() #Call BIRCHSettings.py to set default values for BioLegato helper apps. # We BIRCHSettings.py using subprocess.Popen, mainly because I don't know # how to call an imported script that doesn't take a fixed number of arguments. # There probably is a way, but I haven't found it online. print ('') print ("******************** BIRCHSettings.py ********************") print ("Running BIRCHSettings.py") # We need to flush the standard output at this point. If we don't, the # messages from BIRCHSettings.py will appear BEFORE any other install message. sys.stdout.flush() scriptpath = os.path.join(installDir, 'install-scripts', 'BIRCHSettings.py') p = subprocess.Popen(["python3", scriptpath, "--update", "--birchdir", installDir]) p.wait() # For update, set BIRCH Administrator's personal BL_EMAIL variable adminEmail only if the BIRCH # settings file doesn't exist. HOMEDIR = os.environ.get("HOME") SettingsFile = os.path.join(HOMEDIR, ".config", "BIRCH", "BIRCHsettings.source") if not os.path.exists(SettingsFile) : print ('') print ("******************** BIRCHUserSettings.py ********************") print ("Running BIRCHUserSettings.py") # We need to flush the standard output at this point. If we don't, the # messages from BIRCHUserSettings.py will appear BEFORE any other install message. sys.stdout.flush() scriptpath = os.path.join(installDir, 'install-scripts', 'BIRCHUserSettings.py') p = subprocess.Popen(["python3", scriptpath, "--setvar", "BL_EMAIL="+adminEmail]) p.wait() # Call blastdbkit.py to set BLASTDB environment variable, and to # Set up menus in birchadmin for installing, updating and deleting # local copies of BLAST databases. Also creates menus in bldna and blprotein. # for searching these databases print ('') print ("******************** blastdbkit.py ********************") print ("Running blastdbkit.py") # We need to flush the standard output at this point. If we don't, the # messages from BIRCHSettings.py will appear BEFORE any other install message. sys.stdout.flush() scriptpath = os.path.join(installDir, 'install-scripts', 'blastdbkit.py') p = subprocess.Popen(["python3", scriptpath, "--configure", "--birchdir", installDir]) p.wait() props = None #---------------------- Steps for both new install and update ---------------------- print ('') print ("********************Customdoc********************") print ("Making new paramfile for customdoc") pwriter = open(paramfile, "w+") pwriter.write("~" + '\n') pwriter.write(phtmlDirURL + '\n') pwriter.write(installDirURL + '\n') pwriter.write(adminEmail + '\n') pwriter.write(installDir + '\n') pwriter.write(username + '\n') pwriter.close() print ("Running customdoc.py") customdoc.customdoc(oldstrParam, paramfile, htmldirParam) print ('') print ("********************Htmldoc********************") print ("Running htmldoc.py") # htmldoc.htmldoc(installDir, PLATFORM) htmldoc.main() # RUN THE NEWUSER SCRIPT print ('') print ("********************Newuser********************") print ("Running newuser") newuser.newuser(installDir, PLATFORM) print ("Running newuser") # Get rid of the legacy install-birch directory, if it exists print ('') filename = os.path.join(installDir, "install-birch") if (os.path.exists(filename)) : print("Deleting " + filename) shutil.rmtree(filename) print ('') print ('') print ("********************** birch_install DONE! *******************************") if __name__=="__main__": if len(sys.argv) > 4: PLATFORM = sys.argv[1] installDir = sys.argv[2] adminEmail = sys.argv[3] install = (sys.argv[4].upper() == "Y") minibirch = (sys.argv[5].upper() == "Y") if installDir.find("BIRCHDEV") > -1: print ('>>> birch_install.py cannot be run in BIRCHDEV') print ('>>> Doing so would clobber the master copy of BIRCH') sys.exit(1) else: print ('') print ('===========================================================') print ('| |') print ('| Running birch_install.py |') print ('| |') print ('===========================================================') run_pyinstall (PLATFORM, installDir, adminEmail, install, minibirch) else: print ("ERROR!!! INCORRECT NUMBER OF COMMAND LINE ARGUMENTS SPECIFIED!") print ("Usage: birch_install.py ") sys.exit(1)