From 5fcfd7906c0c5dec0b1aa558cd0c496c31db87a9 Mon Sep 17 00:00:00 2001 From: master3395 Date: Tue, 17 Feb 2026 00:39:39 +0100 Subject: [PATCH] Fix HTTP 500 on /docker/containers: add error handling and auto-migrate --- dockerManager/container.py | 88 ++++++++++++++++++++++++-------------- dockerManager/views.py | 17 ++++++-- 2 files changed, 71 insertions(+), 34 deletions(-) diff --git a/dockerManager/container.py b/dockerManager/container.py index 46cebe40c..028f2edc2 100644 --- a/dockerManager/container.py +++ b/dockerManager/container.py @@ -16,6 +16,7 @@ import plogical.CyberCPLogFileWriter as logging from plogical.errorSanitizer import secure_error_response, secure_log_error from django.shortcuts import HttpResponse, render, redirect from django.urls import reverse +from django.db.utils import OperationalError from loginSystem.models import Administrator import subprocess import shlex @@ -217,47 +218,72 @@ class ContainerManager(multi.Thread): return HttpResponse('Operation failed') def listContainers(self, request=None, userID=None, data=None): - client = docker.from_env() - dockerAPI = docker.APIClient() + def _render_list(): + client = docker.from_env() + docker.APIClient() # ensure API is usable - currentACL = ACLManager.loadedACL(userID) - containers = ACLManager.findAllContainers(currentACL, userID) + currentACL = ACLManager.loadedACL(userID) + containers = ACLManager.findAllContainers(currentACL, userID) - allContainers = client.containers.list() - containersList = [] - showUnlistedContainer = True + allContainers = client.containers.list() + showUnlistedContainer = True - # TODO: Add condition to show unlisted Containers only if user has admin level access + unlistedContainers = [] + for container in allContainers: + if container.name not in containers: + unlistedContainers.append(container) - unlistedContainers = [] - for container in allContainers: - if container.name not in containers: - unlistedContainers.append(container) + if not unlistedContainers: + showUnlistedContainer = False - if not unlistedContainers: - showUnlistedContainer = False + adminNames = ACLManager.loadAllUsers(userID) - adminNames = ACLManager.loadAllUsers(userID) + pages = float(len(containers)) / float(10) + pagination = [] - pages = float(len(containers)) / float(10) - pagination = [] + if pages <= 1.0: + pages = 1 + pagination.append('
  • ') + else: + pages = ceil(pages) + finalPages = int(pages) + 1 - if pages <= 1.0: - pages = 1 - pagination.append('
  • ') - else: - pages = ceil(pages) - finalPages = int(pages) + 1 + for i in range(1, finalPages): + pagination.append('
  • ' + str(i) + '
  • ') - for i in range(1, finalPages): - pagination.append('
  • ' + str(i) + '
  • ') + template = 'dockerManager/listContainers.html' + proc = httpProc(request, template, {"pagination": pagination, + "unlistedContainers": unlistedContainers, + "adminNames": adminNames, + "showUnlistedContainer": showUnlistedContainer}, 'admin') + return proc.render() - template = 'dockerManager/listContainers.html' - proc = httpProc(request, template, {"pagination": pagination, - "unlistedContainers": unlistedContainers, - "adminNames": adminNames, - "showUnlistedContainer": showUnlistedContainer}, 'admin') - return proc.render() + try: + return _render_list() + except OperationalError as e: + logging.writeToFile( + "Docker containers list: DB error (table may be missing). Running migrations. Error: %s" % str(e) + ) + try: + from django.core.management import call_command + call_command('migrate', 'dockerManager', verbosity=0) + return _render_list() + except Exception as migrate_err: + logging.writeToFile( + "Docker containers list: migrate failed. Error: %s" % str(migrate_err) + ) + return render( + request, + 'baseTemplate/error.html', + {'error_message': 'Docker Manager database not ready. Please run upgrade or: manage.py migrate dockerManager'} + ) + except Exception as e: + secure_log_error(e, 'docker_list_containers') + return render( + request, + 'baseTemplate/error.html', + {'error_message': 'Containers list could not be loaded. Check error logs.'} + ) def getContainerLogs(self, userID=None, data=None): try: diff --git a/dockerManager/views.py b/dockerManager/views.py index 356fa353c..5d8755632 100644 --- a/dockerManager/views.py +++ b/dockerManager/views.py @@ -188,12 +188,23 @@ def listContainersPage(request): userID = request.session['userID'] cm = ContainerManager() resp = cm.listContainers(request, userID) - resp['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0' - resp['Pragma'] = 'no-cache' - resp['Expires'] = '0' + if hasattr(resp, '__setitem__'): + resp['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0' + resp['Pragma'] = 'no-cache' + resp['Expires'] = '0' return resp except KeyError: return redirect(loadLoginPage) + except Exception as e: + from django.shortcuts import render + from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging + logging.writeToFile("listContainersPage error: %s" % str(e)) + return render( + request, + 'baseTemplate/error.html', + {'error_message': 'Containers page could not be loaded. Check error logs.'}, + status=500 + ) @preDockerRun