MCPanel/app/docker_utils.py

164 lines
4.6 KiB
Python

import json
import shutil
import docker
import os
from docker.errors import NotFound
from .port_utils import assign_ports
client = docker.from_env()
DEFAULT_CONFIG = {
"max-players": 20,
"pvp": True,
"difficulty": "easy",
"online-mode": True,
"spawn-monsters": True,
"spawn-animals": True,
"allow-nether": True,
"max-build-height": 256,
"view-distance": 10
}
def get_server_config(username):
server_info_path = f"./servers/mc-{username}/server_info.json"
if not os.path.exists(server_info_path):
server_info = {
"type": "paper",
"version": "latest",
"config": DEFAULT_CONFIG.copy()
}
os.makedirs(os.path.dirname(server_info_path), exist_ok=True)
with open(server_info_path, "w") as f:
json.dump(server_info, f, indent=4)
return DEFAULT_CONFIG.copy(), "paper", "latest"
with open(server_info_path, "r") as f:
server_info = json.load(f)
server_type = server_info.get("type", "paper")
server_version = server_info.get("version", "latest")
server_config = server_info.get("config", DEFAULT_CONFIG.copy())
updated = False
for key, default_value in DEFAULT_CONFIG.items():
if key not in server_config:
server_config[key] = default_value
updated = True
if updated:
server_info["config"] = server_config
with open(server_info_path, "w") as f:
json.dump(server_info, f, indent=4)
return server_config, server_type, server_version
def save_server_info(username, server_type, server_version):
server_info_path = f"./servers/mc-{username}/server_info.json"
server_info = {
"type": server_type,
"version": server_version,
"config": DEFAULT_CONFIG.copy()
}
os.makedirs(os.path.dirname(server_info_path), exist_ok=True)
with open(server_info_path, "w") as f:
json.dump(server_info, f)
assign_ports(username)
def get_server_info(username):
server_info_path = f"./servers/mc-{username}/server_info.json"
if os.path.exists(server_info_path):
with open(server_info_path, "r") as f:
return json.load(f)
return None
def start_server(username):
name = f"mc-{username}"
ports = assign_ports(username)
path = f"./servers/{name}"
os.makedirs(path, exist_ok=True)
server_config, server_type, server_version = get_server_config(username)
environment = {
"EULA": "TRUE",
"SERVER_PORT": ports[0],
"ENABLE_RCON": "TRUE",
"MOTD": f"Serwer użytkownika §9{username}",
"TYPE": server_type,
"VERSION": server_version,
"MAX_PLAYERS": server_config["max-players"],
"PVP": "TRUE" if server_config["pvp"] else "FALSE",
"DIFFICULTY": server_config["difficulty"],
"SPAWN_MONSTERS": "TRUE" if server_config["spawn-monsters"] else "FALSE",
"SPAWN_ANIMALS": "TRUE" if server_config["spawn-animals"] else "FALSE",
"ALLOW_NETHER": "TRUE" if server_config["allow-nether"] else "FALSE",
"MAX_BUILD_HEIGHT": server_config["max-build-height"],
"VIEW_DISTANCE": server_config["view-distance"],
"ONLINE_MODE": "TRUE" if server_config["online-mode"] else "FALSE",
"INIT_MEMORY": "1G",
"MAX_MEMORY": "4G"
}
client.containers.run(
"itzg/minecraft-server",
detach=True,
name=f"mc-{username}",
ports={
f"{ports[0]}/tcp": ports[0],
f"{ports[1]}/tcp": ports[1],
f"{ports[2]}/tcp": ports[2],
},
volumes={
os.path.abspath(path): {'bind': '/data', 'mode': 'rw'}
},
environment=environment,
restart_policy={"Name": "unless-stopped"}
)
def stop_server(username):
name = f"mc-{username}"
container = client.containers.get(name)
container.stop()
container.remove()
def restart_server(username):
name = f"mc-{username}"
container = client.containers.get(name)
container.stop()
container.remove()
start_server(username)
def delete_server(username):
container_name = f"mc-{username}"
server_path = f"./servers/{container_name}"
try:
container = client.containers.get(container_name)
container.stop()
container.remove()
except NotFound:
pass
if os.path.exists(server_path):
shutil.rmtree(server_path)
from .port_utils import free_ports_for_user
free_ports_for_user(username)
return f"Serwer {container_name} został usunięty."
def get_logs(username):
name = f"mc-{username}"
container = client.containers.get(name)
return container.logs(tail=100).decode()