1b2d29daeSVladimir Kotal#!/usr/bin/env python3 2b2d29daeSVladimir Kotal 3b2d29daeSVladimir Kotal# CDDL HEADER START 4b2d29daeSVladimir Kotal# 5b2d29daeSVladimir Kotal# The contents of this file are subject to the terms of the 6b2d29daeSVladimir Kotal# Common Development and Distribution License (the "License"). 7b2d29daeSVladimir Kotal# You may not use this file except in compliance with the License. 8b2d29daeSVladimir Kotal# 9b2d29daeSVladimir Kotal# See LICENSE.txt included in this distribution for the specific 10b2d29daeSVladimir Kotal# language governing permissions and limitations under the License. 11b2d29daeSVladimir Kotal# 12b2d29daeSVladimir Kotal# When distributing Covered Code, include this CDDL HEADER in each 13b2d29daeSVladimir Kotal# file and include the License file at LICENSE.txt. 14b2d29daeSVladimir Kotal# If applicable, add the following below this CDDL HEADER, with the 15b2d29daeSVladimir Kotal# fields enclosed by brackets "[]" replaced with your own identifying 16b2d29daeSVladimir Kotal# information: Portions Copyright [yyyy] [name of copyright owner] 17b2d29daeSVladimir Kotal# 18b2d29daeSVladimir Kotal# CDDL HEADER END 19b2d29daeSVladimir Kotal 20b2d29daeSVladimir Kotal# 21b2d29daeSVladimir Kotal# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. 22b2d29daeSVladimir Kotal# 23b2d29daeSVladimir Kotal 24b2d29daeSVladimir Kotalimport os 25b2d29daeSVladimir Kotalimport logging 26b2d29daeSVladimir Kotalimport multiprocessing 27b2d29daeSVladimir Kotalimport shutil 28b2d29daeSVladimir Kotalimport subprocess 29b2d29daeSVladimir Kotalimport threading 30b2d29daeSVladimir Kotalimport time 31d44cbea0SVladimir Kotalfrom pathlib import Path 32d44cbea0SVladimir Kotalfrom requests import get, ConnectionError 33b2d29daeSVladimir Kotal 34b2d29daeSVladimir Kotalfrom opengrok_tools.utils.log import get_console_logger, \ 35b2d29daeSVladimir Kotal get_log_level, get_class_basename 36b2d29daeSVladimir Kotalfrom opengrok_tools.deploy import deploy_war 37b2d29daeSVladimir Kotalfrom opengrok_tools.utils.indexer import Indexer 38b2d29daeSVladimir Kotalfrom opengrok_tools.sync import do_sync 39b2d29daeSVladimir Kotalfrom opengrok_tools.utils.opengrok import list_projects, \ 401822b591SVladimir Kotal add_project, delete_project, get_configuration, set_config_value 41b2d29daeSVladimir Kotalfrom opengrok_tools.utils.readconfig import read_config 42b2d29daeSVladimir Kotalfrom opengrok_tools.utils.exitvals import SUCCESS_EXITVAL 43b2d29daeSVladimir Kotal 44b2d29daeSVladimir Kotal 45b2d29daeSVladimir Kotalfs_root = os.path.abspath('.').split(os.path.sep)[0] + os.path.sep 46b2d29daeSVladimir Kotalif os.environ.get('OPENGROK_TOMCAT_ROOT'): # debug only 47b2d29daeSVladimir Kotal tomcat_root = os.environ.get('OPENGROK_TOMCAT_ROOT') 48b2d29daeSVladimir Kotalelse: 49b2d29daeSVladimir Kotal tomcat_root = os.path.join(fs_root, "usr", "local", "tomcat") 50b2d29daeSVladimir Kotal 51b2d29daeSVladimir Kotalif os.environ.get('OPENGROK_ROOT'): # debug only 52b2d29daeSVladimir Kotal OPENGROK_BASE_DIR = os.environ.get('OPENGROK_ROOT') 53b2d29daeSVladimir Kotalelse: 54b2d29daeSVladimir Kotal OPENGROK_BASE_DIR = os.path.join(fs_root, "opengrok") 55b2d29daeSVladimir Kotal 56b2d29daeSVladimir KotalOPENGROK_LIB_DIR = os.path.join(OPENGROK_BASE_DIR, "lib") 57b2d29daeSVladimir KotalOPENGROK_DATA_ROOT = os.path.join(OPENGROK_BASE_DIR, "data") 58b2d29daeSVladimir KotalOPENGROK_SRC_ROOT = os.path.join(OPENGROK_BASE_DIR, "src") 59b2d29daeSVladimir KotalBODY_INCLUDE_FILE = os.path.join(OPENGROK_DATA_ROOT, "body_include") 60b2d29daeSVladimir KotalOPENGROK_CONFIG_FILE = os.path.join(OPENGROK_BASE_DIR, "etc", 61b2d29daeSVladimir Kotal "configuration.xml") 62b2d29daeSVladimir KotalOPENGROK_WEBAPPS_DIR = os.path.join(tomcat_root, "webapps") 634810eb96SVladimir KotalOPENGROK_JAR = os.path.join(OPENGROK_LIB_DIR, 'opengrok.jar') 64b2d29daeSVladimir Kotal 65b2d29daeSVladimir Kotal 66f7d6d77cSVladimir Kotaldef set_url_root(logger, url_root): 67b2d29daeSVladimir Kotal """ 68b2d29daeSVladimir Kotal Set URL root and URI based on input 69788f14d3SVladimir Kotal :param logger: logger instance 70b2d29daeSVladimir Kotal :param url_root: input 71b2d29daeSVladimir Kotal :return: URI and URL root 72b2d29daeSVladimir Kotal """ 73b2d29daeSVladimir Kotal if not url_root: 74b2d29daeSVladimir Kotal url_root = '/' 75b2d29daeSVladimir Kotal 76b2d29daeSVladimir Kotal if ' ' in url_root: 77b2d29daeSVladimir Kotal logger.warn('Deployment path contains spaces. Deploying to root') 78b2d29daeSVladimir Kotal url_root = '/' 79b2d29daeSVladimir Kotal 80b2d29daeSVladimir Kotal # Remove leading and trailing slashes 81b2d29daeSVladimir Kotal if url_root.startswith('/'): 82b2d29daeSVladimir Kotal url_root = url_root[1:] 83b2d29daeSVladimir Kotal if url_root.endswith('/'): 84b2d29daeSVladimir Kotal url_root = url_root[:-1] 85b2d29daeSVladimir Kotal 86b2d29daeSVladimir Kotal uri = "http://localhost:8080/" + url_root 87b2d29daeSVladimir Kotal # 88b2d29daeSVladimir Kotal # Make sure URI ends with slash. This is important for the various API 89b2d29daeSVladimir Kotal # calls, notably for those that check the HTTP error code. 90b2d29daeSVladimir Kotal # Normally accessing the URI without the terminating slash results in 91b2d29daeSVladimir Kotal # HTTP redirect (code 302) instead of success (200). 92b2d29daeSVladimir Kotal # 93b2d29daeSVladimir Kotal if not uri.endswith('/'): 94b2d29daeSVladimir Kotal uri = uri + '/' 95b2d29daeSVladimir Kotal 96b2d29daeSVladimir Kotal return uri, url_root 97b2d29daeSVladimir Kotal 98b2d29daeSVladimir Kotal 99b2d29daeSVladimir Kotaldef get_war_name(url_root): 100d44cbea0SVladimir Kotal """ 101d44cbea0SVladimir Kotal :param url_root: web app URL root 102d44cbea0SVladimir Kotal :return: filename of the WAR file 103d44cbea0SVladimir Kotal """ 104b2d29daeSVladimir Kotal if len(url_root) == 0: 105b2d29daeSVladimir Kotal return "ROOT.war" 106f7d6d77cSVladimir Kotal 107b2d29daeSVladimir Kotal return url_root + ".war" 108b2d29daeSVladimir Kotal 109b2d29daeSVladimir Kotal 110f7d6d77cSVladimir Kotaldef deploy(logger, url_root): 111b2d29daeSVladimir Kotal """ 112b2d29daeSVladimir Kotal Deploy the web application 113788f14d3SVladimir Kotal :param logger: logger instance 114b2d29daeSVladimir Kotal :param url_root: web app URL root 115b2d29daeSVladimir Kotal """ 116b2d29daeSVladimir Kotal 117b2d29daeSVladimir Kotal logger.info('Deploying web application') 118b2d29daeSVladimir Kotal webapps_dir = os.path.join(tomcat_root, 'webapps') 119b2d29daeSVladimir Kotal if not os.path.isdir(webapps_dir): 120b2d29daeSVladimir Kotal raise Exception("{} is not a directory".format(webapps_dir)) 121b2d29daeSVladimir Kotal 122b2d29daeSVladimir Kotal for item in os.listdir(webapps_dir): 123b2d29daeSVladimir Kotal subdir = os.path.join(webapps_dir, item) 124b2d29daeSVladimir Kotal if os.path.isdir(subdir): 125b2d29daeSVladimir Kotal logger.debug("Removing '{}' directory recursively".format(subdir)) 126b2d29daeSVladimir Kotal shutil.rmtree(subdir) 127b2d29daeSVladimir Kotal 128b2d29daeSVladimir Kotal deploy_war(logger, os.path.join(OPENGROK_LIB_DIR, "source.war"), 129b2d29daeSVladimir Kotal os.path.join(OPENGROK_WEBAPPS_DIR, get_war_name(url_root)), 130b2d29daeSVladimir Kotal OPENGROK_CONFIG_FILE, None) 131b2d29daeSVladimir Kotal 132b2d29daeSVladimir Kotal 133f7d6d77cSVladimir Kotaldef setup_redirect_source(logger, url_root): 134b2d29daeSVladimir Kotal """ 135b2d29daeSVladimir Kotal Set up redirect from /source 136b2d29daeSVladimir Kotal """ 137b2d29daeSVladimir Kotal logger.debug("Setting up redirect from /source to '{}'".format(url_root)) 138b2d29daeSVladimir Kotal source_dir = os.path.join(OPENGROK_WEBAPPS_DIR, "source") 139b2d29daeSVladimir Kotal if not os.path.isdir(source_dir): 140b2d29daeSVladimir Kotal os.makedirs(source_dir) 141b2d29daeSVladimir Kotal 142b2d29daeSVladimir Kotal with open(os.path.join(source_dir, "index.jsp"), "w+") as index: 143b2d29daeSVladimir Kotal index.write("<% response.sendRedirect(\"/{}\"); %>".format(url_root)) 144b2d29daeSVladimir Kotal 145b2d29daeSVladimir Kotal 146f7d6d77cSVladimir Kotaldef wait_for_tomcat(logger, uri): 147b2d29daeSVladimir Kotal """ 148b2d29daeSVladimir Kotal Active/busy waiting for Tomcat to come up. 149b2d29daeSVladimir Kotal Currently there is no upper time bound. 150b2d29daeSVladimir Kotal """ 151b2d29daeSVladimir Kotal logger.info("Waiting for Tomcat to start") 152b2d29daeSVladimir Kotal 153b2d29daeSVladimir Kotal while True: 154b2d29daeSVladimir Kotal try: 155d44cbea0SVladimir Kotal ret = get(uri) 156d44cbea0SVladimir Kotal status = ret.status_code 157b2d29daeSVladimir Kotal except ConnectionError: 158b2d29daeSVladimir Kotal status = 0 159b2d29daeSVladimir Kotal 160b2d29daeSVladimir Kotal if status != 200: 161b2d29daeSVladimir Kotal logger.debug("Got status {} for {}, sleeping for 1 second". 162b2d29daeSVladimir Kotal format(status, uri)) 163b2d29daeSVladimir Kotal time.sleep(1) 164b2d29daeSVladimir Kotal else: 165b2d29daeSVladimir Kotal break 166b2d29daeSVladimir Kotal 167b2d29daeSVladimir Kotal logger.info("Tomcat is ready") 168b2d29daeSVladimir Kotal 169b2d29daeSVladimir Kotal 170f7d6d77cSVladimir Kotaldef refresh_projects(logger, uri): 171b2d29daeSVladimir Kotal """ 172b2d29daeSVladimir Kotal Ensure each immediate source root subdirectory is a project. 173b2d29daeSVladimir Kotal """ 174b2d29daeSVladimir Kotal webapp_projects = list_projects(logger, uri) 175b2d29daeSVladimir Kotal logger.debug('Projects from the web app: {}'.format(webapp_projects)) 176b2d29daeSVladimir Kotal src_root = OPENGROK_SRC_ROOT 177b2d29daeSVladimir Kotal 178b2d29daeSVladimir Kotal # Add projects. 179b2d29daeSVladimir Kotal for item in os.listdir(src_root): 180b2d29daeSVladimir Kotal logger.debug('Got item {}'.format(item)) 181b2d29daeSVladimir Kotal if os.path.isdir(os.path.join(src_root, item)): 182b2d29daeSVladimir Kotal if item not in webapp_projects: 183b2d29daeSVladimir Kotal logger.info("Adding project {}".format(item)) 184b2d29daeSVladimir Kotal add_project(logger, item, uri) 185b2d29daeSVladimir Kotal 186b2d29daeSVladimir Kotal # Remove projects 187b2d29daeSVladimir Kotal for item in webapp_projects: 188b2d29daeSVladimir Kotal if not os.path.isdir(os.path.join(src_root, item)): 189b2d29daeSVladimir Kotal logger.info("Deleting project {}".format(item)) 190b2d29daeSVladimir Kotal delete_project(logger, item, uri) 191b2d29daeSVladimir Kotal 192b2d29daeSVladimir Kotal 193f7d6d77cSVladimir Kotaldef save_config(logger, uri, config_path): 194b2d29daeSVladimir Kotal """ 195b2d29daeSVladimir Kotal Retrieve configuration from the web app and write it to file. 196788f14d3SVladimir Kotal :param logger: logger instance 197b2d29daeSVladimir Kotal :param uri: web app URI 198b2d29daeSVladimir Kotal :param config_path: file path 199b2d29daeSVladimir Kotal """ 200b2d29daeSVladimir Kotal 201b2d29daeSVladimir Kotal logger.info('Saving configuration to {}'.format(config_path)) 202b2d29daeSVladimir Kotal config = get_configuration(logger, uri) 203b2d29daeSVladimir Kotal with open(config_path, "w+") as config_file: 204b2d29daeSVladimir Kotal config_file.write(config) 205b2d29daeSVladimir Kotal 206b2d29daeSVladimir Kotal 207b2d29daeSVladimir Kotaldef merge_commands_env(commands, env): 208b2d29daeSVladimir Kotal """ 209b2d29daeSVladimir Kotal Merge environment into command structure. If any of the commands has 210b2d29daeSVladimir Kotal an environment already set, the env is merged in. 211b2d29daeSVladimir Kotal :param commands: commands structure 212b2d29daeSVladimir Kotal :param env: environment dictionary 213b2d29daeSVladimir Kotal :return: updated commands structure 214b2d29daeSVladimir Kotal """ 215b2d29daeSVladimir Kotal for cmd in commands: 216b2d29daeSVladimir Kotal cmd_env = cmd.get('env') 217b2d29daeSVladimir Kotal if cmd_env: 218b2d29daeSVladimir Kotal cmd.env.update(env) 219b2d29daeSVladimir Kotal else: 220b2d29daeSVladimir Kotal cmd['env'] = env 221b2d29daeSVladimir Kotal 222b2d29daeSVladimir Kotal return commands 223b2d29daeSVladimir Kotal 224b2d29daeSVladimir Kotal 2254810eb96SVladimir Kotaldef indexer_no_projects(logger, uri, config_path, sync_period, 2264810eb96SVladimir Kotal extra_indexer_options): 2274810eb96SVladimir Kotal """ 2284810eb96SVladimir Kotal Project less indexer 2294810eb96SVladimir Kotal """ 2304810eb96SVladimir Kotal 2314810eb96SVladimir Kotal wait_for_tomcat(logger, uri) 2324810eb96SVladimir Kotal 2334810eb96SVladimir Kotal while True: 2344810eb96SVladimir Kotal indexer_options = ['-s', OPENGROK_SRC_ROOT, 2354810eb96SVladimir Kotal '-d', OPENGROK_DATA_ROOT, 2364810eb96SVladimir Kotal '-c', '/usr/local/bin/ctags', 2374810eb96SVladimir Kotal '--remote', 'on', 2384810eb96SVladimir Kotal '-H', 2394810eb96SVladimir Kotal '-W', config_path, 2404810eb96SVladimir Kotal '-U', uri] 2414810eb96SVladimir Kotal if extra_indexer_options: 2424810eb96SVladimir Kotal logger.debug("Adding extra indexer options: {}". 2434810eb96SVladimir Kotal format(extra_indexer_options)) 2444810eb96SVladimir Kotal indexer_options.extend(extra_indexer_options.split()) 2454810eb96SVladimir Kotal indexer = Indexer(indexer_options, logger=logger, 246d2f093daSVladimir Kotal jar=OPENGROK_JAR, doprint=True) 2474810eb96SVladimir Kotal indexer.execute() 2484810eb96SVladimir Kotal 2494810eb96SVladimir Kotal sleep_seconds = sync_period * 60 2504810eb96SVladimir Kotal logger.info("Sleeping for {} seconds".format(sleep_seconds)) 2514810eb96SVladimir Kotal time.sleep(sleep_seconds) 2524810eb96SVladimir Kotal 2534810eb96SVladimir Kotal 2544810eb96SVladimir Kotaldef project_syncer(logger, loglevel, uri, config_path, sync_period, 2554810eb96SVladimir Kotal numworkers, env): 256b2d29daeSVladimir Kotal """ 257b2d29daeSVladimir Kotal Wrapper for running opengrok-sync. 258b2d29daeSVladimir Kotal To be run in a thread/process in the background. 259b2d29daeSVladimir Kotal """ 260b2d29daeSVladimir Kotal 261f7d6d77cSVladimir Kotal wait_for_tomcat(logger, uri) 262b2d29daeSVladimir Kotal 2631822b591SVladimir Kotal set_config_value(logger, 'projectsEnabled', 'true', uri) 2641822b591SVladimir Kotal 265b2d29daeSVladimir Kotal while True: 266f7d6d77cSVladimir Kotal refresh_projects(logger, uri) 267b2d29daeSVladimir Kotal 268b2d29daeSVladimir Kotal if os.environ.get('OPENGROK_SYNC_YML'): # debug only 269b2d29daeSVladimir Kotal config_file = os.environ.get('OPENGROK_SYNC_YML') 270b2d29daeSVladimir Kotal else: 271b2d29daeSVladimir Kotal config_file = os.path.join(fs_root, 'scripts', 'sync.yml') 272b2d29daeSVladimir Kotal config = read_config(logger, config_file) 273b2d29daeSVladimir Kotal if config is None: 274b2d29daeSVladimir Kotal logger.error("Cannot read config file from {}".format(config_file)) 275b2d29daeSVladimir Kotal raise Exception("no sync config") 276b2d29daeSVladimir Kotal 277b2d29daeSVladimir Kotal projects = list_projects(logger, uri) 278b2d29daeSVladimir Kotal # 279b2d29daeSVladimir Kotal # The driveon=True is needed for the initial indexing of newly 280b2d29daeSVladimir Kotal # added project, otherwise the incoming check in the opengrok-mirror 2813d5852a4SVladimir Kotal # program would short circuit it. 282b2d29daeSVladimir Kotal # 283b2d29daeSVladimir Kotal if env: 284b2d29daeSVladimir Kotal logger.info('Merging commands with environment') 285b2d29daeSVladimir Kotal commands = merge_commands_env(config["commands"], env) 286b2d29daeSVladimir Kotal logger.debug(config['commands']) 287b2d29daeSVladimir Kotal else: 288b2d29daeSVladimir Kotal commands = config["commands"] 289b2d29daeSVladimir Kotal 290b2d29daeSVladimir Kotal logger.info("Sync starting") 291b2d29daeSVladimir Kotal do_sync(loglevel, commands, config.get('cleanup'), 292b2d29daeSVladimir Kotal projects, config.get("ignore_errors"), uri, 293b2d29daeSVladimir Kotal numworkers, driveon=True, logger=logger, print_output=True) 294b2d29daeSVladimir Kotal logger.info("Sync done") 295b2d29daeSVladimir Kotal 296b2d29daeSVladimir Kotal # Workaround for https://github.com/oracle/opengrok/issues/1670 297b2d29daeSVladimir Kotal Path(os.path.join(OPENGROK_DATA_ROOT, 'timestamp')).touch() 298b2d29daeSVladimir Kotal 299f7d6d77cSVladimir Kotal save_config(logger, uri, config_path) 300b2d29daeSVladimir Kotal 3013d5852a4SVladimir Kotal sleep_seconds = sync_period * 60 302b2d29daeSVladimir Kotal logger.info("Sleeping for {} seconds".format(sleep_seconds)) 303b2d29daeSVladimir Kotal time.sleep(sleep_seconds) 304b2d29daeSVladimir Kotal 305b2d29daeSVladimir Kotal 3069d6d7c28SVladimir Kotaldef create_bare_config(logger, extra_indexer_options=None): 307b2d29daeSVladimir Kotal """ 308b2d29daeSVladimir Kotal Create bare configuration file with a few basic settings. 309b2d29daeSVladimir Kotal """ 310b2d29daeSVladimir Kotal 311b2d29daeSVladimir Kotal logger.info('Creating bare configuration in {}'. 312b2d29daeSVladimir Kotal format(OPENGROK_CONFIG_FILE)) 3134810eb96SVladimir Kotal indexer_options = ['-s', OPENGROK_SRC_ROOT, 314b2d29daeSVladimir Kotal '-d', OPENGROK_DATA_ROOT, 315b2d29daeSVladimir Kotal '-c', '/usr/local/bin/ctags', 316b2d29daeSVladimir Kotal '--remote', 'on', 3174810eb96SVladimir Kotal '-H', 318b2d29daeSVladimir Kotal '-W', OPENGROK_CONFIG_FILE, 3194810eb96SVladimir Kotal '--noIndex'] 3204810eb96SVladimir Kotal 3219d6d7c28SVladimir Kotal if extra_indexer_options: 3225b279385SVladimir Kotal if type(extra_indexer_options) is not list: 3235b279385SVladimir Kotal raise Exception("extra_indexer_options has to be a list") 3249d6d7c28SVladimir Kotal indexer_options.extend(extra_indexer_options) 3254810eb96SVladimir Kotal indexer = Indexer(indexer_options, 3264810eb96SVladimir Kotal jar=OPENGROK_JAR, 327b2d29daeSVladimir Kotal logger=logger, doprint=True) 328b2d29daeSVladimir Kotal indexer.execute() 329b2d29daeSVladimir Kotal ret = indexer.getretcode() 330b2d29daeSVladimir Kotal if ret != SUCCESS_EXITVAL: 331b2d29daeSVladimir Kotal logger.error('Command returned {}'.format(ret)) 332b2d29daeSVladimir Kotal logger.error(indexer.geterroutput()) 333b2d29daeSVladimir Kotal raise Exception("Failed to create bare configuration") 334b2d29daeSVladimir Kotal 335b2d29daeSVladimir Kotal 336f7d6d77cSVladimir Kotaldef main(): 337b2d29daeSVladimir Kotal log_level = os.environ.get('OPENGROK_LOG_LEVEL') 338b2d29daeSVladimir Kotal if log_level: 339b2d29daeSVladimir Kotal log_level = get_log_level(log_level) 340b2d29daeSVladimir Kotal else: 341b2d29daeSVladimir Kotal log_level = logging.INFO 342b2d29daeSVladimir Kotal 343b2d29daeSVladimir Kotal logger = get_console_logger(get_class_basename(), log_level) 344b2d29daeSVladimir Kotal 345f7d6d77cSVladimir Kotal uri, url_root = set_url_root(logger, os.environ.get('URL_ROOT')) 346f7d6d77cSVladimir Kotal logger.debug("URL_ROOT = {}".format(url_root)) 347f7d6d77cSVladimir Kotal logger.debug("URI = {}".format(uri)) 348b2d29daeSVladimir Kotal 3493d5852a4SVladimir Kotal # default period for syncing (in minutes) 3503d5852a4SVladimir Kotal sync_period = 10 3513d5852a4SVladimir Kotal sync_env = os.environ.get('SYNC_TIME_MINUTES') 3523d5852a4SVladimir Kotal if sync_env: 3533d5852a4SVladimir Kotal try: 3543d5852a4SVladimir Kotal n = int(sync_env) 3553d5852a4SVladimir Kotal if n >= 0: 3563d5852a4SVladimir Kotal sync_period = n 3573d5852a4SVladimir Kotal except ValueError: 3583d5852a4SVladimir Kotal logger.error("SYNC_TIME_MINUTES is not a number: {}". 3593d5852a4SVladimir Kotal format(sync_env)) 3603d5852a4SVladimir Kotal 3613d5852a4SVladimir Kotal if sync_period == 0: 3623d5852a4SVladimir Kotal logger.info("synchronization disabled") 363b2d29daeSVladimir Kotal else: 3643d5852a4SVladimir Kotal logger.info("synchronization period = {} minutes".format(sync_period)) 365b2d29daeSVladimir Kotal 366b2d29daeSVladimir Kotal # Note that deploy is done before Tomcat is started. 367f7d6d77cSVladimir Kotal deploy(logger, url_root) 368b2d29daeSVladimir Kotal 369f7d6d77cSVladimir Kotal if url_root != '/source': 370f7d6d77cSVladimir Kotal setup_redirect_source(logger, url_root) 371b2d29daeSVladimir Kotal 372b2d29daeSVladimir Kotal env = {} 373*dadacd3dSAdam Hornacek extra_indexer_options = os.environ.get('INDEXER_OPT', '') 3744810eb96SVladimir Kotal if extra_indexer_options: 3754810eb96SVladimir Kotal logger.info("extra indexer options: {}".format(extra_indexer_options)) 3764810eb96SVladimir Kotal env['OPENGROK_INDEXER_OPTIONAL_ARGS'] = extra_indexer_options 377b2d29daeSVladimir Kotal if os.environ.get('NOMIRROR'): 378b2d29daeSVladimir Kotal env['OPENGROK_NO_MIRROR'] = os.environ.get('NOMIRROR') 379b2d29daeSVladimir Kotal logger.debug('Extra environment: {}'.format(env)) 380b2d29daeSVladimir Kotal 3814810eb96SVladimir Kotal use_projects = True 3824810eb96SVladimir Kotal if os.environ.get('AVOID_PROJECTS'): 3834810eb96SVladimir Kotal use_projects = False 3844810eb96SVladimir Kotal 385b2d29daeSVladimir Kotal # 386b2d29daeSVladimir Kotal # Create empty configuration to avoid the non existent file exception 387b2d29daeSVladimir Kotal # in the web app during the first web app startup. 388b2d29daeSVladimir Kotal # 389b2d29daeSVladimir Kotal if not os.path.exists(OPENGROK_CONFIG_FILE) or \ 390b2d29daeSVladimir Kotal os.path.getsize(OPENGROK_CONFIG_FILE) == 0: 391c6f6c3d1SVladimir Kotal create_bare_config(logger, extra_indexer_options.split()) 392b2d29daeSVladimir Kotal 3933d5852a4SVladimir Kotal if sync_period > 0: 3944810eb96SVladimir Kotal if use_projects: 395b2d29daeSVladimir Kotal num_workers = multiprocessing.cpu_count() 3963d5852a4SVladimir Kotal workers_env = os.environ.get('WORKERS') 3973d5852a4SVladimir Kotal if workers_env: 3983d5852a4SVladimir Kotal try: 3993d5852a4SVladimir Kotal n = int(workers_env) 4003d5852a4SVladimir Kotal if n > 0: 4013d5852a4SVladimir Kotal num_workers = n 4023d5852a4SVladimir Kotal except ValueError: 4034810eb96SVladimir Kotal logger.error("WORKERS is not a number: {}". 4044810eb96SVladimir Kotal format(workers_env)) 4053d5852a4SVladimir Kotal 406b2d29daeSVladimir Kotal logger.info('Number of sync workers: {}'.format(num_workers)) 407b2d29daeSVladimir Kotal 4084810eb96SVladimir Kotal worker_function = project_syncer 4094810eb96SVladimir Kotal syncer_args = (logger, log_level, uri, 410f7d6d77cSVladimir Kotal OPENGROK_CONFIG_FILE, 4114810eb96SVladimir Kotal sync_period, num_workers, env) 4124810eb96SVladimir Kotal else: 4134810eb96SVladimir Kotal worker_function = indexer_no_projects 4144810eb96SVladimir Kotal syncer_args = (logger, uri, OPENGROK_CONFIG_FILE, sync_period, 4154810eb96SVladimir Kotal extra_indexer_options) 4164810eb96SVladimir Kotal 4174810eb96SVladimir Kotal logger.debug("Starting sync thread") 4184810eb96SVladimir Kotal thread = threading.Thread(target=worker_function, name="Sync thread", 4194810eb96SVladimir Kotal args=syncer_args) 420f7d6d77cSVladimir Kotal thread.start() 421b2d29daeSVladimir Kotal 422b2d29daeSVladimir Kotal # Start Tomcat last. It will be the foreground process. 423b2d29daeSVladimir Kotal logger.info("Starting Tomcat") 424b2d29daeSVladimir Kotal subprocess.run([os.path.join(tomcat_root, 'bin', 'catalina.sh'), 'run']) 425f7d6d77cSVladimir Kotal 426f7d6d77cSVladimir Kotal 427f7d6d77cSVladimir Kotalif __name__ == "__main__": 428f7d6d77cSVladimir Kotal main() 429