diff --git a/app/app.py b/app/app.py index 0f91fe4..a07fe15 100644 --- a/app/app.py +++ b/app/app.py @@ -1,27 +1,35 @@ +import logging from requestHandler import RequestHandler from utils import docker_container_mapping from dockerHandler import DockerHandler from nginxHandler import NginxHandler +logging.basicConfig(level=logging.INFO) + def main(): - port_ip_map = docker_container_mapping() + try: + port_ip_map = docker_container_mapping() - # Create a DockerHandler instance - docker_handler = DockerHandler( - 'unix://var/run/docker.sock', port_ip_map) + # Create a DockerHandler instance + docker_handler = DockerHandler( + 'unix://var/run/docker.sock', port_ip_map) - # Create an NginxHandler instance - nginx_handler = NginxHandler('/etc/nginx/nginx.conf') - nginx_handler.setup_config_file( - docker_container_mapping(), docker_handler.get_current_container_ip()) - nginx_handler.print_config() + # Create an NginxHandler instance + nginx_handler = NginxHandler('/etc/nginx/nginx.conf') + nginx_handler.setup_config_file( + docker_container_mapping(), docker_handler.get_current_container_ip()) + nginx_handler.print_config() - # Create a RequestHandler instance for each port - for port in port_ip_map.keys(): - print(f'Creating request handler for port {port}') - request_handler = RequestHandler(int(port), docker_handler) - request_handler.start() + # Create a RequestHandler instance for each port + for port in port_ip_map.keys(): + logging.info(f'Creating request handler for port {port}') + request_handler = RequestHandler(int(port), docker_handler) + request_handler.start() + + except Exception as e: + logging.error(f'An error occurred: {e}') -main() +if __name__ == "__main__": + main() diff --git a/app/dockerHandler.py b/app/dockerHandler.py index b244c65..a5388f0 100644 --- a/app/dockerHandler.py +++ b/app/dockerHandler.py @@ -1,45 +1,60 @@ import docker import os +import logging class DockerHandler: def __init__(self, base_url, port_ip_map): - print( + logging.info( f'Initializing docker handler with base url {base_url} and port ip map: {port_ip_map}') self.base_url = base_url self.client = docker.DockerClient(base_url=base_url) self.port_ip_map = port_ip_map self.current_network = self.get_current_network() + def get_current_container(self): + current_container_name = os.environ.get('HOSTNAME') + try: + return self.client.containers.get(current_container_name) + except docker.errors.NotFound: + logging.error(f'Container {current_container_name} not found') + return None + def get_current_container_ip(self): # Get IP of current container - current_container_name = os.environ.get('HOSTNAME') - current_container = self.client.containers.get(current_container_name) - networks = current_container.attrs['NetworkSettings']['Networks'] - current_network = list(networks.keys())[0] - current_container_ip = networks[current_network]['IPAddress'] - return current_container_ip + current_container = self.get_current_container() + if current_container: + networks = current_container.attrs['NetworkSettings']['Networks'] + current_network = list(networks.keys())[0] + return networks[current_network]['IPAddress'] + return None def get_current_network(self): # Get network of current container - current_container_name = os.environ.get('HOSTNAME') - current_container = self.client.containers.get(current_container_name) - networks = current_container.attrs['NetworkSettings']['Networks'] - current_network = list(networks.keys())[0] - return current_network + current_container = self.get_current_container() + if current_container: + networks = current_container.attrs['NetworkSettings']['Networks'] + return list(networks.keys())[0] + return None def get_container_by_ip(self, ip): - containers = self.client.containers.list(all=True) + try: + containers = self.client.containers.list(all=True) + except docker.errors.APIError as e: + logging.error(f'Error getting container list: {e}') + return None for container in containers: networks = container.attrs['NetworkSettings']['Networks'] if self.current_network in networks and networks[self.current_network]['IPAMConfig']['IPv4Address'] == ip: - print( + logging.info( f'Found container {container.name} with ip {ip} in network {self.current_network}') return container - print( + logging.info( f'No docker container found with ip {ip} in network {self.current_network}') return None def is_container_starting(self, container): - return container.attrs['State']['Health']['Status'] == 'starting' + if container: + return container.attrs['State']['Health']['Status'] == 'starting' + return False diff --git a/app/nginxHandler.py b/app/nginxHandler.py index c0527e9..cc92201 100644 --- a/app/nginxHandler.py +++ b/app/nginxHandler.py @@ -1,4 +1,5 @@ import os +import logging class NginxHandler: @@ -6,14 +7,14 @@ class NginxHandler: self.config_path = config_path def start(self): - print('Starting NGINX...') + logging.info('Starting NGINX...') os.system('nginx > /dev/null 2>&1 &') - print('NGINX started') + logging.info('NGINX started') def stop(self): - print('Stopping NGINX...') + logging.info('Stopping NGINX...') os.system('nginx -s stop') - print('NGINX stopped') + logging.info('NGINX stopped') def restart(self): self.stop() @@ -21,13 +22,13 @@ class NginxHandler: def print_config(self): with open(self.config_path, 'r') as f: - print(f.read()) + logging.info(f.read()) def setup_config_file(self, port_ip_map, current_container_ip): proxy_timeout = "5s" self.stop() - print('Setting up NGINX config file...') - print('port_ip_map: {}'.format(port_ip_map)) + logging.info('Setting up NGINX config file...') + logging.info('port_ip_map: {}'.format(port_ip_map)) nginx_conf = open(self.config_path, 'w+') nginx_conf.truncate() nginx_conf.write('worker_processes 5;\n') @@ -57,5 +58,5 @@ class NginxHandler: nginx_conf.write(' }\n') nginx_conf.write('}\n') nginx_conf.close() - print('NGINX config file setup complete') + logging.info('NGINX config file setup complete') self.start() diff --git a/app/requestHandler.py b/app/requestHandler.py index 44d4814..9a83059 100644 --- a/app/requestHandler.py +++ b/app/requestHandler.py @@ -1,5 +1,6 @@ import os import socket +import logging import threading from utils import docker_container_mapping @@ -12,81 +13,86 @@ class RequestHandler(threading.Thread): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_address = ('localhost', self.port) - print(f'Starting up on {server_address[0]} port {server_address[1]}') + logging.info( + f'Starting up on {server_address[0]} port {server_address[1]}') self.sock.bind(server_address) self.sock.listen(1) def restart(self): - print(f'Restarting request handler for port {self.port}') + logging.info(f'Restarting request handler for port {self.port}') self.sock.close() self.__init__(self.port, self.docker_handler) def run(self): while True: try: - print(f'Waiting for a connection on port {self.port}') + logging.info(f'Waiting for a connection on port {self.port}') self.connection, self.client_address = self.sock.accept() try: - print('Connection from', self.client_address) + logging.info('Connection from', self.client_address) self.handle_request() except Exception as e: - print( + logging.info( f'Error in request handler for port {self.port}: {e}') - print('Restarting request handler...') + logging.info('Restarting request handler...') self.restart() finally: self.connection.close() self.restart() except Exception as e: - print(f'Error in request handler for port {self.port}: {e}') - print('Restarting request handler...') + logging.info( + f'Error in request handler for port {self.port}: {e}') + logging.info('Restarting request handler...') self.restart() def handle_request(self): - print(f'Handling request on port {self.port}') + logging.info(f'Handling request on port {self.port}') container_ip = docker_container_mapping().get(str(self.port)) if container_ip: container = self.docker_handler.get_container_by_ip( container_ip) isStarting = self.docker_handler.is_container_starting(container) request = self.connection.recv(1024) - print(f'Received request: {request}') + logging.info(f'Received request: {request}') # b'\x1b\x00\xfb\x05\x14mc.tealfire.de\x00FML3\x00c\xa0\x02\x1a\x00\x07DerTyp7\x01\xf2]\x9a\x18*\xeaJ\xed\xbe0g\x9c\x8aT\xa9t' if request[0] == 0x10 or request[0] == 0x15 or request[0] == 0x1b: if b'\x02' in request: - print(f'Detected join/login request for {container_ip}') + logging.info( + f'Detected join/login request for {container_ip}') if isStarting: - print( + logging.info( f'Container {container_ip} is already starting...') self.forward_request_to_placeholder( request, isStarting) else: - print(f'Starting container {container_ip}') + logging.info(f'Starting container {container_ip}') container.start() elif b'\x01' in request: - print(f'Detected ping request for {container_ip}') + logging.info(f'Detected ping request for {container_ip}') self.forward_request_to_placeholder(request, isStarting) elif request[0] == 0xFE: - print(f'Detected legacy ping request for {container_ip}') + logging.info( + f'Detected legacy ping request for {container_ip}') self.forward_request_to_placeholder(request, isStarting) else: - print(f'Detected unknown request for {container_ip}') + logging.info(f'Detected unknown request for {container_ip}') self.forward_request_to_placeholder(request, isStarting) else: - print(f'No container mapped to port {self.port}') + logging.info(f'No container mapped to port {self.port}') def forward_request_to_placeholder(self, request, isStarting=False): - print('Forwarding request to placeholder server') + logging.info('Forwarding request to placeholder server') with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket: ip = os.environ.get('PLACEHOLDER_SERVER_SLEEPING_IP') if isStarting: - print('Container is starting. Using starting placeholder IP') + logging.info( + 'Container is starting. Using starting placeholder IP') ip = os.environ.get('PLACEHOLDER_SERVER_STARTING_IP') if not ip: - print('No placeholder server IP found') + logging.info('No placeholder server IP found') return try: server_socket.connect((ip, 25565)) @@ -94,5 +100,6 @@ class RequestHandler(threading.Thread): response = server_socket.recv(1024) self.connection.sendall(response) except Exception as e: - print(f'Error while handling request on port {self.port}: {e}') + logging.info( + f'Error while handling request on port {self.port}: {e}') self.restart() diff --git a/app/requirements.txt b/app/requirements.txt index 6d0eac4..cc0d25a 100644 --- a/app/requirements.txt +++ b/app/requirements.txt @@ -1 +1 @@ -docker \ No newline at end of file +docker==6.1.3 \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..8986ecd --- /dev/null +++ b/build.sh @@ -0,0 +1 @@ +docker build -t dertyp7/minecraft_server_auto_starter:latest . \ No newline at end of file diff --git a/start.sh b/start.sh index b318b27..e92332e 100644 --- a/start.sh +++ b/start.sh @@ -1 +1 @@ -docker compose up -d --build \ No newline at end of file +docker compose up -d \ No newline at end of file