Source code for schrodinger.utils.postinstall
"""
This file contains post-installation steps common to all platforms.
This allows post installation steps to be tested and used in and outside
the installers. Migrate more post-installation steps here in the future.
"""
import argparse
import glob
import os
import pathlib
import shutil
from enum import Enum
from enum import unique
import pymmlibs
pymmlibs.mmerr_set_mmlibs()
# isort: split
from schrodinger.utils import mmutil
from schrodinger.utils.fileutils import get_mmshare_data_dir
[docs]@unique
class CustomConfigFiles(str, Enum):
"""
Customized configuration files used during the postinstall stage of an
installation. These files are optional during the installation, but may be
required depending on the environment.
featureflags.json global and product settings for the suite
server.json required for queuing system installation on Linux
suitepref.xml required for local installation on Windows
"""
FEATURE_FLAGS = 'featureflags.json'
SERVER = 'server.json'
PREFERENCES = 'suitepref.xml'
CONFIG_DIRECTORY = pathlib.Path(os.environ['SCHRODINGER']) / 'config'
MMSHARE_DATA_DIRECTORY = pathlib.Path(get_mmshare_data_dir())
[docs]def copy_customized_files(customized_files_dir: pathlib.Path):
"""
Checks the specified directory for a customized configuration file and
deploys it to $SCHRODINGER/config.
NOTE: suitepref.xml is the only exception, this file is copied to
$SCHRODINGER/mmshare-v*/data/ - SHARED-8207
The custom configuration file types are stored in the global variable
CUSTOMIZED_CONFIGURATION_FILES.
:type customized_files_dir: pathlib.Path
:param featureflags_dir: path to the directory where the customized config
file(s) is located.
"""
for expected_config_filename in CustomConfigFiles:
source_file = customized_files_dir / expected_config_filename.value
if not custom_config_file_exists(customized_files_dir, source_file):
continue
if CustomConfigFiles.PREFERENCES.value in str(source_file):
dest_file = MMSHARE_DATA_DIRECTORY / expected_config_filename.value
else:
dest_file = CONFIG_DIRECTORY / expected_config_filename.value
print(
f'Copying custom configuration file {source_file=} to {dest_file=}')
copy_custom_config_file(source_file, dest_file)
[docs]def custom_config_file_exists(customized_files_dir: pathlib.Path,
source_file: pathlib.Path) -> bool:
"""
Check if source_file exists on file system, return boolean.
"""
if not source_file.exists():
print(
f'Customized configuration file {source_file.name} not found in '
f'{customized_files_dir}. Using default settings for installation.')
return False
return True
[docs]def copy_custom_config_file(source_file: pathlib.Path, dest_file: pathlib.Path):
"""
Copy customized configuration file to the specified destination.
Ensure the destination directory (e.g. $SCHRODINGER/config) exists
before copying.
"""
os.makedirs(os.path.dirname(dest_file), exist_ok=True)
shutil.copy(source_file, dest_file)
[docs]def get_lib_dir():
"""
Don't use hunt because we are getting rid of and it requires feature
flags which requires licenses.
"""
return glob.glob(os.environ["SCHRODINGER"] + "/mmshare-v*/lib/*")[0]
[docs]def create_config_dir():
"""
Create $SCHRODINGER/config
"""
target_directory = mmutil.mmfile_get_config_dir()
os.makedirs(target_directory, exist_ok=True)
[docs]def get_disabled_lib_dir():
lib_directory = get_lib_dir()
deconstructed_path = lib_directory.split(os.path.sep)
deconstructed_path[-2] = "disabled_lib"
disabled_lib_directory = os.path.sep.join(deconstructed_path)
return disabled_lib_directory
[docs]def parse_args(argv=None):
parser = argparse.ArgumentParser(__doc__)
parser.add_argument(
'--customized-files-dir',
type=pathlib.Path,
help='Path to customized configuration files. These files will be '
'copied to $SCHRODINGER/config directory.')
return parser.parse_args(argv)
[docs]def main(argv=None):
args = parse_args(argv)
create_config_dir()
if args.customized_files_dir:
copy_customized_files(args.customized_files_dir)
return args
if __name__ == '__main__':
main()