2021-11-29 21:22:46 +00:00
from cmd import Cmd
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
""" Our custom classes / pip packages """
from app . classes . shared . console import console
from app . classes . shared . helpers import helper
2021-09-08 22:01:10 +00:00
from app . classes . shared . main_models import installer , database
2020-08-31 17:46:25 +00:00
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
2020-08-27 22:53:04 +00:00
from app . classes . shared . cmd 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
with open ( logging_config_file , ' rt ' ) as f :
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 )
logging . warning ( " Unable to read logging config from {} " . format ( logging_config_file ) )
console . critical ( " Unable to read logging config from {} " . format ( logging_config_file ) )
""" Our Main Starter """
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 ( )
2021-11-29 21:22:46 +00:00
if helper . check_file_exists ( ' /.dockerenv ' ) :
console . cyan ( " Docker environment detected! " )
else :
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 )
2020-08-12 00:36:09 +00:00
helper . ensure_logging_setup ( )
setup_logging ( debug = args . verbose )
# setting up the logger object
logger = logging . getLogger ( __name__ )
2021-11-29 21:22:46 +00:00
console . cyan ( " Logging set to: {} " . format ( 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
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 " )
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 ( )
2021-09-13 21:08:02 +00:00
logger . info ( " Checking Internet/Port Service. This may take a minute. " )
console . info ( " Checking Internet/Port Service. This may take a minute. " )
2021-09-13 17:10:34 +00:00
if not helper . check_internet ( ) :
2021-11-30 19:37:45 +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
elif not helper . check_port ( helper . get_setting ( ' https_port ' ) ) :
2021-11-30 19:37:45 +00:00
console . warning ( " We have detected Crafty ' s port, {} may not be open on the host network or a firewall is blocking it. Remote client connections to Crafty may be limited. " . format ( helper . get_setting ( ' https_port ' ) ) )
console . help ( " If you are not forwarding ports from your public IP or your router does not support hairpin NAT you can safely disregard the previous message. " )
2021-09-13 17:10:34 +00:00
2021-08-18 16:50:13 +00:00
Crafty = MainPrompt ( tasks_manager , migration_manager )
2021-06-02 18:30:12 +00:00
def sigterm_handler ( signum , current_stack_frame ) :
print ( ) # for newline
logger . info ( " Recieved SIGTERM, stopping Crafty " )
console . info ( " Recieved SIGTERM, 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
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 :
2021-04-03 19:12:03 +00:00
logger . info ( " Recieved SIGINT, stopping Crafty " )
2021-06-02 16:53:01 +00:00
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 ( )