import docker import os import socket import inspect import shutil import requests from flask import current_app from game_table_model import GameTable from key_model import TableKey from time import sleep def build_container_routing_labels(prefix: str, strip_prefix=True): host_name = os.environ.get("API_HOST_NAME") or "localhost" router_key = "traefik.http.routers.{prefix}.rule".format(prefix=prefix) middleware_key = ( "traefik.http.middlewares.{prefix}-stripprefix.stripprefix.prefixes".format( prefix=prefix ) ) middleware_router_key = "traefik.http.routers.{prefix}.middlewares".format( prefix=prefix ) labels = {} labels[router_key] = "Host(`{host_name}`) && PathPrefix(`/{prefix}`)".format( host_name=host_name, prefix=prefix ) if strip_prefix: labels[middleware_key] = "/{prefix}".format(prefix=prefix) labels[middleware_router_key] = "{prefix}-stripprefix".format(prefix=prefix) return labels def delete_file_package(table: GameTable) -> bool: if table.active: return False if not os.path.exists("/data/{prefix}".format(prefix=table.game_table_link)): return False shutil.rmtree("/data/{prefix}".format(prefix=table.game_table_link)) os.removedirs("/data/{prefix}") return True def delete_container(table: GameTable) -> bool: if not table.docker_id: return False try: client = docker.from_env() container = client.containers.get(table.docker_id) container.remove() return True except (docker.errors.NotFound, docker.errors.APIError): return False def stop_container(docker_id) -> bool: try: client = docker.from_env() container = client.containers.get(docker_id) container.stop() return True except (docker.errors.NotFound, docker.errors.APIError): return False def start_foundry_container(table: GameTable, key: TableKey): client = docker.from_env() container = None networkName = client.containers.get(socket.gethostname()).attrs["HostConfig"][ "NetworkMode" ] data_bind = os.environ.get("FOUNDRY_DATA_BIND") data_volume = os.environ.get("FOUNDRY_DATA_VOL") if table.docker_id != None and table.docker_id != 0: try: container = client.containers.get(table.docker_id) except (docker.errors.NotFound, docker.errors.NullResource): container = None if container: container.start() else: environment = [ "FOUNDRY_ROUTE_PREFIX={prefix}".format(prefix=table.game_table_link), "FOUNDRY_TELEMETRY=FALSE", "FOUNDRY_LICENSE_KEY={key_value}".format(key_value=key.key), ] ports = {"30000": str(30000 + table.game_table_id)} image = "felddy/foundryvtt:{version}".format(version=table.version) labels = build_container_routing_labels(table.game_table_link, False) if data_volume: os.makedirs( "/data/{prefix}".format(prefix=table.game_table_link), exist_ok=True ) mounts = [ docker.types.Mount( target="/data", source=data_volume, type="volume", subpath=table.game_table_link, ), docker.types.Mount( target="/data/container_cache", source=data_volume, type="volume", subpath="container_cache", ), ] container = client.containers.run( image=image, labels=labels, mounts=mounts, environment=environment, ports=ports, detach=True, network=networkName, ) else: volumes = { "{data_bind}/{prefix}".format( data_bind=os.environ.get("FOUNDRY_DATA_BIND"), prefix=table.game_table_link, ): {"bind": "/data", "mode": "rw"}, "{data_bind}/container_cache".format( data_bind=os.environ.get("FOUNDRY_DATA_BIND") ): {"bind": "/data/container_cache", "mode": "rw"}, } container = client.containers.run( image=image, labels=labels, volumes=volumes, environment=environment, ports=ports, detach=True, network=networkName, ) current_app.logger.info(container.attrs) count = 0 current_app.logger.info("Here:") container.reload() current_app.logger.info(container.status) sleep(2) while(container.status == "running" and count < 10): current_app.logger.info(count) current_app.logger.info(requests.get("http://proxy:8080/api/http/routers").json()) container.reload() count = count + 1 sleep(1) container.reload() if (container.status != "running"): raise "Fuck" return container.id