2020-08-12 00:36:09 +00:00
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import json
|
|
|
|
import time
|
|
|
|
import argparse
|
|
|
|
import logging.config
|
2021-06-02 18:30:12 +00:00
|
|
|
import signal
|
2020-08-12 00:36:09 +00:00
|
|
|
from app.classes.shared.console import console
|
|
|
|
from app.classes.shared.helpers import helper
|
2022-03-02 13:12:03 +00:00
|
|
|
if helper.checkRoot():
|
|
|
|
console.critical("Root detected. Root/Admin access denied. Run Crafty again with non-elevated permissions.")
|
|
|
|
time.sleep(5)
|
|
|
|
console.critical("Crafty shutting down. Root/Admin access denied.")
|
|
|
|
sys.exit(0)
|
2022-01-26 01:45:30 +00:00
|
|
|
# pylint: disable=wrong-import-position
|
2021-09-08 22:01:10 +00:00
|
|
|
from app.classes.shared.main_models import installer, database
|
2021-03-06 20:48:02 +00:00
|
|
|
from app.classes.shared.tasks import TasksManager
|
2021-09-08 22:01:10 +00:00
|
|
|
from app.classes.shared.main_controller import Controller
|
2021-08-18 15:11:53 +00:00
|
|
|
from app.classes.shared.migration import MigrationManager
|
2021-03-22 04:32:48 +00:00
|
|
|
|
2022-01-26 01:45:30 +00:00
|
|
|
from app.classes.shared.command import MainPrompt
|
2020-08-12 00:36:09 +00:00
|
|
|
|
2020-08-19 01:04:43 +00:00
|
|
|
|
2020-08-12 00:36:09 +00:00
|
|
|
def do_intro():
|
2020-08-17 02:47:53 +00:00
|
|
|
logger.info("***** Crafty Controller Started *****")
|
2020-08-12 00:36:09 +00:00
|
|
|
|
2020-08-17 02:47:53 +00:00
|
|
|
version = helper.get_version_string()
|
2020-08-12 00:36:09 +00:00
|
|
|
|
2021-11-02 14:08:27 +00:00
|
|
|
intro = f"""
|
|
|
|
{'/' * 75}
|
|
|
|
#{("Welcome to Crafty Controller - v." + version).center(73, " ")}#
|
|
|
|
{'/' * 75}
|
|
|
|
#{"Server Manager / Web Portal for your Minecraft server".center(73, " ")}#
|
|
|
|
#{"Homepage: www.craftycontrol.com".center(73, " ")}#
|
|
|
|
{'/' * 75}
|
|
|
|
"""
|
2020-08-12 00:36:09 +00:00
|
|
|
|
|
|
|
console.magenta(intro)
|
|
|
|
|
|
|
|
|
2021-03-09 03:01:42 +00:00
|
|
|
def setup_logging(debug=True):
|
2020-08-12 00:36:09 +00:00
|
|
|
logging_config_file = os.path.join(os.path.curdir,
|
|
|
|
'app',
|
|
|
|
'config',
|
|
|
|
'logging.json'
|
|
|
|
)
|
|
|
|
|
|
|
|
if os.path.exists(logging_config_file):
|
|
|
|
# open our logging config file
|
2022-01-26 01:45:30 +00:00
|
|
|
with open(logging_config_file, 'rt', encoding='utf-8') as f:
|
2020-08-12 00:36:09 +00:00
|
|
|
logging_config = json.load(f)
|
|
|
|
if debug:
|
|
|
|
logging_config['loggers']['']['level'] = 'DEBUG'
|
2021-01-19 13:56:00 +00:00
|
|
|
|
2020-08-12 00:36:09 +00:00
|
|
|
logging.config.dictConfig(logging_config)
|
2021-01-19 13:56:00 +00:00
|
|
|
|
2020-08-12 00:36:09 +00:00
|
|
|
else:
|
|
|
|
logging.basicConfig(level=logging.DEBUG)
|
2022-01-26 01:45:30 +00:00
|
|
|
logging.warning(f"Unable to read logging config from {logging_config_file}")
|
|
|
|
console.critical(f"Unable to read logging config from {logging_config_file}")
|
2020-08-12 00:36:09 +00:00
|
|
|
|
|
|
|
|
2022-01-26 01:45:30 +00:00
|
|
|
# Our Main Starter
|
2020-08-12 00:36:09 +00:00
|
|
|
if __name__ == '__main__':
|
2020-08-31 17:46:25 +00:00
|
|
|
parser = argparse.ArgumentParser("Crafty Controller - A Server Management System")
|
2020-08-12 00:36:09 +00:00
|
|
|
|
|
|
|
parser.add_argument('-i', '--ignore',
|
|
|
|
action='store_true',
|
2020-08-19 01:04:43 +00:00
|
|
|
help="Ignore session.lock files"
|
2020-08-12 00:36:09 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
parser.add_argument('-v', '--verbose',
|
|
|
|
action='store_true',
|
|
|
|
help="Sets logging level to debug."
|
|
|
|
)
|
|
|
|
|
2021-03-06 20:48:02 +00:00
|
|
|
parser.add_argument('-d', '--daemon',
|
|
|
|
action='store_true',
|
|
|
|
help="Runs Crafty in daemon mode (no prompt)"
|
|
|
|
)
|
|
|
|
|
2020-08-12 00:36:09 +00:00
|
|
|
args = parser.parse_args()
|
|
|
|
|
2022-01-26 02:00:40 +00:00
|
|
|
helper.ensure_logging_setup()
|
|
|
|
|
2020-08-12 00:36:09 +00:00
|
|
|
setup_logging(debug=args.verbose)
|
|
|
|
|
|
|
|
# setting up the logger object
|
|
|
|
logger = logging.getLogger(__name__)
|
2022-01-26 01:45:30 +00:00
|
|
|
console.cyan(f"Logging set to: {logger.level}")
|
2020-08-12 00:36:09 +00:00
|
|
|
|
|
|
|
# print our pretty start message
|
|
|
|
do_intro()
|
|
|
|
|
2020-08-31 17:46:25 +00:00
|
|
|
# our session file, helps prevent multiple controller agents on the same machine.
|
2020-08-12 00:36:09 +00:00
|
|
|
helper.create_session_file(ignore=args.ignore)
|
|
|
|
|
2021-08-18 15:11:53 +00:00
|
|
|
|
|
|
|
migration_manager = MigrationManager(database)
|
|
|
|
migration_manager.up() # Automatically runs migrations
|
2022-01-26 01:45:30 +00:00
|
|
|
|
2020-08-31 17:46:25 +00:00
|
|
|
# do our installer stuff
|
2020-09-22 19:00:05 +00:00
|
|
|
fresh_install = installer.is_fresh_install()
|
|
|
|
|
|
|
|
if fresh_install:
|
2021-03-22 04:02:18 +00:00
|
|
|
console.debug("Fresh install detected")
|
2022-01-26 01:45:30 +00:00
|
|
|
console.warning("We have detected a fresh install. Please be sure to forward Crafty's port, " +
|
|
|
|
f"{helper.get_setting('https_port')}, through your router/firewall if you would like to be able to access Crafty remotely.")
|
2020-08-31 17:46:25 +00:00
|
|
|
installer.default_settings()
|
2021-03-22 04:02:18 +00:00
|
|
|
else:
|
|
|
|
console.debug("Existing install detected")
|
2020-08-31 17:46:25 +00:00
|
|
|
|
2021-03-22 04:02:18 +00:00
|
|
|
# now the tables are created, we can load the tasks_manger and server controller
|
|
|
|
controller = Controller()
|
|
|
|
tasks_manager = TasksManager(controller)
|
2020-08-12 00:36:09 +00:00
|
|
|
tasks_manager.start_webserver()
|
2020-08-17 02:47:53 +00:00
|
|
|
|
|
|
|
# slowing down reporting just for a 1/2 second so messages look cleaner
|
|
|
|
time.sleep(.5)
|
2020-08-12 00:36:09 +00:00
|
|
|
|
2020-08-24 23:16:33 +00:00
|
|
|
# init servers
|
|
|
|
logger.info("Initializing all servers defined")
|
|
|
|
console.info("Initializing all servers defined")
|
|
|
|
controller.init_all_servers()
|
|
|
|
servers = controller.list_defined_servers()
|
|
|
|
|
2020-08-19 01:04:43 +00:00
|
|
|
# start stats logging
|
|
|
|
tasks_manager.start_stats_recording()
|
|
|
|
|
2021-03-22 04:02:18 +00:00
|
|
|
# once the controller is up and stats are logging, we can kick off the scheduler officially
|
|
|
|
tasks_manager.start_scheduler()
|
|
|
|
|
2020-08-23 22:43:28 +00:00
|
|
|
# refresh our cache and schedule for every 12 hoursour cache refresh for serverjars.com
|
|
|
|
tasks_manager.serverjar_cache_refresher()
|
|
|
|
|
2022-01-14 19:59:06 +00:00
|
|
|
logger.info("Checking Internet. This may take a minute.")
|
|
|
|
console.info("Checking Internet. This may take a minute.")
|
2021-09-13 21:08:02 +00:00
|
|
|
|
2021-09-13 17:10:34 +00:00
|
|
|
if not helper.check_internet():
|
2022-01-26 01:45:30 +00:00
|
|
|
console.warning("We have detected the machine running Crafty has no connection to the internet. " +
|
|
|
|
"Client connections to the server may be limited.")
|
2021-09-13 17:10:34 +00:00
|
|
|
|
2021-12-21 01:17:28 +00:00
|
|
|
if not controller.check_system_user():
|
|
|
|
controller.add_system_user()
|
|
|
|
|
2021-08-18 16:50:13 +00:00
|
|
|
Crafty = MainPrompt(tasks_manager, migration_manager)
|
2021-06-02 18:30:12 +00:00
|
|
|
|
2022-01-14 04:01:18 +00:00
|
|
|
project_root = os.path.dirname(__file__)
|
|
|
|
controller.set_project_root(project_root)
|
2022-03-02 17:55:49 +00:00
|
|
|
controller.clear_unexecuted_commands()
|
2022-03-13 12:29:26 +00:00
|
|
|
controller.clear_support_status()
|
2022-01-14 04:01:18 +00:00
|
|
|
|
2022-03-02 16:50:44 +00:00
|
|
|
def sigterm_handler(*sig):
|
2021-06-02 18:30:12 +00:00
|
|
|
print() # for newline
|
2022-03-08 05:26:13 +00:00
|
|
|
logger.info(f"Recieved {signal.Signals(sig[0]).name} [{sig[0]}], stopping Crafty...")
|
|
|
|
console.info(f"Recieved {signal.Signals(sig[0]).name} [{sig[0]}], stopping Crafty...")
|
2021-12-09 23:35:00 +00:00
|
|
|
tasks_manager._main_graceful_exit()
|
2021-06-02 18:30:12 +00:00
|
|
|
Crafty.universal_exit()
|
|
|
|
|
|
|
|
signal.signal(signal.SIGTERM, sigterm_handler)
|
|
|
|
|
2021-03-06 20:48:02 +00:00
|
|
|
if not args.daemon:
|
2021-06-02 16:53:01 +00:00
|
|
|
try:
|
|
|
|
Crafty.cmdloop()
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
print() # for newline
|
2022-03-02 16:50:44 +00:00
|
|
|
logger.info("Recieved SIGINT, stopping Crafty...")
|
|
|
|
console.info("Recieved SIGINT, stopping Crafty...")
|
2021-12-09 23:35:00 +00:00
|
|
|
tasks_manager._main_graceful_exit()
|
2021-06-02 16:53:01 +00:00
|
|
|
Crafty.universal_exit()
|
2021-03-06 20:48:02 +00:00
|
|
|
else:
|
|
|
|
print("Crafty started in daemon mode, no shell will be printed")
|
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
if tasks_manager.get_main_thread_run_status():
|
|
|
|
break
|
|
|
|
time.sleep(1)
|
|
|
|
except KeyboardInterrupt:
|
2022-03-02 16:50:44 +00:00
|
|
|
logger.info("Recieved SIGINT, stopping Crafty...")
|
|
|
|
console.info("Recieved SIGINT, stopping Crafty...")
|
2021-03-06 20:48:02 +00:00
|
|
|
break
|
2021-12-09 23:35:00 +00:00
|
|
|
tasks_manager._main_graceful_exit()
|
2021-04-17 21:24:54 +00:00
|
|
|
Crafty.universal_exit()
|