From 10592cb2d2e7fa675a15402353dbff252c353256 Mon Sep 17 00:00:00 2001 From: Pratyush Desai Date: Mon, 20 Jan 2025 22:42:01 +0530 Subject: [PATCH] Configure and test Game Server Launch Connected to hld2m-server successfully. Hardcoded `network_mode='host'` Which isn't viable moving forwards. Current Status: Frontend : Active Servers show Backend: Have configured admin.py utils.py and models.py to grant us the ability to launch a docker image with a command and tested client connection. Server Online status works launch, stop, remove (with force stop) works. Signed-off-by: Pratyush Desai --- webpanel/admin.py | 9 ++++-- ...r_name_alter_server_ip_address_and_more.py | 29 +++++++++++++++++++ ..._command_args_server_docker_run_command.py | 23 +++++++++++++++ webpanel/models.py | 20 +++++++++++-- webpanel/utils.py | 11 +++---- 5 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 webpanel/migrations/0004_server_name_alter_server_ip_address_and_more.py create mode 100644 webpanel/migrations/0005_server_command_args_server_docker_run_command.py diff --git a/webpanel/admin.py b/webpanel/admin.py index de7836a..25173ce 100644 --- a/webpanel/admin.py +++ b/webpanel/admin.py @@ -13,8 +13,9 @@ def launch_container(modeladmin, request, queryset): for server in queryset: container_name = f"{server.game.name}_{server.ip_address}_{server.port}" result = launch_docker_container( - image=server.docker_image, + run_command=server.docker_run_command, name=container_name, + image=server.docker_image, ports={f"{server.port}/tcp": server.port}, ) server.sync_status() @@ -38,7 +39,11 @@ def remove_container(modeladmin, request, queryset): @admin.register(Server) class ServerAdmin(admin.ModelAdmin): - list_display = ('game', 'ip_address', 'port', 'status', 'docker_image') + list_display = ('game', 'name', 'ip_address', 'port', 'status', 'docker_image', 'docker_run_command', 'command_args') + search_fields = ('game__name', 'ip_address', 'port') + + def save_model(self, request, obj, form, change): + super().save_model(request, obj, form, change) def get_queryset(self, request): """Sync status of all servers before rendering the admin list view.""" diff --git a/webpanel/migrations/0004_server_name_alter_server_ip_address_and_more.py b/webpanel/migrations/0004_server_name_alter_server_ip_address_and_more.py new file mode 100644 index 0000000..9d9bf19 --- /dev/null +++ b/webpanel/migrations/0004_server_name_alter_server_ip_address_and_more.py @@ -0,0 +1,29 @@ +# Generated by Django 5.1.5 on 2025-01-20 13:21 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("webpanel", "0003_remove_game_description_alter_server_docker_image_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="server", + name="name", + field=models.CharField(default="hello world", max_length=100), + preserve_default=False, + ), + migrations.AlterField( + model_name="server", + name="ip_address", + field=models.GenericIPAddressField(null=True), + ), + migrations.AlterField( + model_name="server", + name="port", + field=models.PositiveIntegerField(null=True), + ), + ] diff --git a/webpanel/migrations/0005_server_command_args_server_docker_run_command.py b/webpanel/migrations/0005_server_command_args_server_docker_run_command.py new file mode 100644 index 0000000..7a6e8e7 --- /dev/null +++ b/webpanel/migrations/0005_server_command_args_server_docker_run_command.py @@ -0,0 +1,23 @@ +# Generated by Django 5.1.5 on 2025-01-20 15:21 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("webpanel", "0004_server_name_alter_server_ip_address_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="server", + name="command_args", + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name="server", + name="docker_run_command", + field=models.CharField(blank=True, max_length=500, null=True), + ), + ] diff --git a/webpanel/models.py b/webpanel/models.py index 2feff3d..969dd55 100644 --- a/webpanel/models.py +++ b/webpanel/models.py @@ -15,9 +15,12 @@ class Server(models.Model): ] game = models.ForeignKey(Game, on_delete=models.CASCADE) - ip_address = models.GenericIPAddressField() - port = models.PositiveIntegerField() + name = models.CharField(max_length=100) + ip_address = models.GenericIPAddressField(null=True) + port = models.PositiveIntegerField(null=True) docker_image = models.CharField(max_length=200, null=True) + docker_run_command = models.CharField(max_length=500, blank=True, null=True) + command_args = models.TextField(blank=True, null=True) status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='offline') def __str__(self): @@ -38,3 +41,16 @@ class Server(models.Model): except Exception as e: self.status = "offline" # Fallback in case of unexpected errors self.save() + + def get_docker_run_command(self): + """Returns the docker run command, falling back to default image if not set.""" + if self.docker_run_command: + # If a custom command is provided, use it + return self.docker_run_command + else: + # Otherwise, use the default image with any provided args TODO: Fixes reqd + # add ports or remove the else logic. + base_command = f"docker run -d {self.image}" + if self.command_args: + base_command += " " + self.command_args + return base_command \ No newline at end of file diff --git a/webpanel/utils.py b/webpanel/utils.py index 3bbefb8..979ed81 100644 --- a/webpanel/utils.py +++ b/webpanel/utils.py @@ -1,14 +1,15 @@ import docker -def launch_docker_container(image, name, ports=None, environment=None): +def launch_docker_container(image, run_command, name, ports): client = docker.from_env() try: container = client.containers.run( - image, name=name, - ports=ports, - environment=environment, - detach=True + image=image, + # ports=ports, + command=run_command, + detach=True, + network_mode='host' ) return f"Container launched successfully: {container.id}" except docker.errors.APIError as e: