diff --git a/requirements.txt b/requirements.txt index 1e3bbf3..98902b3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,8 +2,8 @@ asgiref==3.8.1 certifi==2024.12.14 charset-normalizer==3.4.1 Django==5.1.5 -docker==7.1.0 idna==3.10 +podman==5.2.0 requests==2.32.3 sqlparse==0.5.3 urllib3==2.3.0 diff --git a/webpanel/admin.py b/webpanel/admin.py index 25173ce..b094af1 100644 --- a/webpanel/admin.py +++ b/webpanel/admin.py @@ -1,6 +1,7 @@ from django.contrib import admin from .models import Game, Server -from .utils import launch_docker_container, stop_docker_container, remove_docker_container +from .utils import launch_pod_container, stop_pod_container, remove_pod_container +import podman @admin.register(Game) class GameAdmin(admin.ModelAdmin): @@ -8,32 +9,40 @@ class GameAdmin(admin.ModelAdmin): search_fields = ('name', 'genre') ordering = ('name',) -@admin.action(description='Launch Docker Container') +@admin.action(description='Launch Container') def launch_container(modeladmin, request, queryset): + client = podman.PodmanClient(base_url="unix:///run/user/1000/podman/podman.sock") for server in queryset: container_name = f"{server.game.name}_{server.ip_address}_{server.port}" - result = launch_docker_container( - run_command=server.docker_run_command, - name=container_name, - image=server.docker_image, - ports={f"{server.port}/tcp": server.port}, - ) - server.sync_status() - modeladmin.message_user(request, f"Container launch result for {server}: {result}") + try: + # Ensure the command is passed as a list of strings + command = server.get_docker_run_command().split() if server.docker_run_command else [] + container = client.containers.run( + server.docker_image, + detach=True, + name=container_name, + command=command, + ports={f"{server.port}/tcp": server.port}, + remove=True, # Automatically remove on stop + ) + server.sync_status() + modeladmin.message_user(request, f"Container launched: {container.id}") + except Exception as e: + modeladmin.message_user(request, f"Failed to launch {server}: {e}", level="error") -@admin.action(description='Stop Docker Container') +@admin.action(description='Stop Container') def stop_container(modeladmin, request, queryset): for server in queryset: container_name = f"{server.game.name}_{server.ip_address}_{server.port}" - result = stop_docker_container(container_name) + result = stop_pod_container(container_name) server.sync_status() modeladmin.message_user(request, f"Stop container result for {server}: {result}") -@admin.action(description='Remove Docker Container') +@admin.action(description='Remove Container') def remove_container(modeladmin, request, queryset): for server in queryset: container_name = f"{server.game.name}_{server.ip_address}_{server.port}" - result = remove_docker_container(container_name) + result = remove_pod_container(container_name) server.sync_status() modeladmin.message_user(request, f"Remove container result for {server}: {result}") diff --git a/webpanel/models.py b/webpanel/models.py index 969dd55..4ddc928 100644 --- a/webpanel/models.py +++ b/webpanel/models.py @@ -1,5 +1,5 @@ from django.db import models -import docker +import podman class Game(models.Model): name = models.CharField(max_length=100) @@ -28,7 +28,7 @@ class Server(models.Model): def sync_status(self): """Check the real-time status of the Docker container and update the field.""" - client = docker.from_env() + client = podman.PodmanClient(base_url="unix:///run/user/1000/podman/podman.sock") container_name = f"{self.game.name}_{self.ip_address}_{self.port}" try: container = client.containers.get(container_name) @@ -36,21 +36,20 @@ class Server(models.Model): self.status = "online" else: self.status = "offline" - except docker.errors.NotFound: + except podman.errors.NotFound: self.status = "offline" 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 + """Returns the Podman run command, falling back to default image if not set.""" + if self.docker_run_command: + # Return command as a string to be split later + return self.docker_run_command + else: + # Default command with image and arguments + base_command = f"{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 979ed81..8e8620b 100644 --- a/webpanel/utils.py +++ b/webpanel/utils.py @@ -1,9 +1,9 @@ -import docker +import podman -def launch_docker_container(image, run_command, name, ports): - client = docker.from_env() +def launch_pod_container(image, run_command, name, ports): + client = podman.PodmanClient(base_url="unix:///run/user/1000/podman/podman.sock") try: - container = client.containers.run( + container = client.containers.create( name=name, image=image, # ports=ports, @@ -11,40 +11,41 @@ def launch_docker_container(image, run_command, name, ports): detach=True, network_mode='host' ) + container.start() return f"Container launched successfully: {container.id}" - except docker.errors.APIError as e: + except podman.errors.APIError as e: return f"API Error: {e}" except Exception as e: return f"Error: {e}" -def stop_docker_container(name): - client = docker.from_env() +def stop_pod_container(name): + client = podman.PodmanClient(base_url="unix:///run/user/1000/podman/podman.sock") try: container = client.containers.get(name) container.stop() return f"Container stopped: {name}" - except docker.errors.NotFound: + except podman.errors.NotFound: return f"Container not found: {name}" except Exception as e: return f"Error stopping container {name}: {e}" -def remove_docker_container(name): - client = docker.from_env() +def remove_pod_container(name): + client = podman.PodmanClient(base_url="unix:///run/user/1000/podman/podman.sock") try: container = client.containers.get(name) container.remove(force=True) # Force removal if the container is running return f"Container removed: {name}" - except docker.errors.NotFound: + except podman.errors.NotFound: return f"Container not found: {name}" except Exception as e: return f"Error removing container {name}: {e}" def is_container_running(name): - client = docker.from_env() + client = podman.PodmanClient(base_url="unix:///run/user/1000/podman/podman.sock") try: container = client.containers.get(name) return container.status == "running" - except docker.errors.NotFound: + except podman.errors.NotFound: return False except Exception as e: return f"Error checking container {name}: {e}"