import docker import os import socket import inspect import shutil from flask import current_app from game_table_model import GameTable from key_model import TableKey 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(`{prefix}.{host_name}`)".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.removedir("/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.kill() 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, ) return container.id