Added locking mechanism to logparser command

see #2754
This commit is contained in:
Antoine Nguyen
2023-01-25 17:20:20 +01:00
parent 354ab68840
commit 5aa1886ad3
4 changed files with 36 additions and 0 deletions
@@ -230,6 +230,8 @@ MODOBOA_API_URL = 'https://api.modoboa.org/1/'
DISABLE_DASHBOARD_EXTERNAL_QUERIES = False
PID_FILE_STORAGE_PATH = '/var/run'
# REDIS
REDIS_HOST = 'localhost'
@@ -27,6 +27,7 @@ import time
import rrdtool
from django.conf import settings
from django.core.management.base import BaseCommand
from django.db.models import Q
from django.utils import timezone
@@ -619,7 +620,27 @@ class Command(BaseCommand):
"--debug", default=False, action="store_true",
help="Set debug mode")
def can_start(self):
"""Check if another process is already running or not."""
pidfile = f"{settings.PID_FILE_STORAGE_PATH}/modoboa_logparser.pid"
if os.path.exists(pidfile):
with open(pidfile) as fp:
pid = fp.read()
pid = int(pid.strip())
try:
os.kill(pid, 0)
except OSError:
pass
else:
return False
with open(pidfile, "w") as fp:
fp.write(f"{os.getpid()}\n")
return True
def handle(self, *args, **options):
if not self.can_start():
print("Another process is already running, cannot start")
sys.exit(2)
if options["logfile"] is None:
options["logfile"] = param_tools.get_global_parameter(
"logfile", app="maillog")
+11
View File
@@ -5,6 +5,7 @@ import os
import shutil
import tempfile
from django.conf import settings
from django.core.management import call_command
from django.urls import reverse
from django.test import override_settings
@@ -24,6 +25,9 @@ class RunCommandsMixin(object):
def tearDown(self):
shutil.rmtree(self.workdir)
pid_file = f"{settings.PID_FILE_STORAGE_PATH}/modoboa_logparser.pid"
if os.path.exists(pid_file):
os.remove(pid_file)
def run_logparser(self):
"""Run logparser command."""
@@ -166,3 +170,10 @@ class ManagementCommandsTestCase(RunCommandsMixin, ModoTestCase):
self.assertTrue(os.path.exists(path))
self.run_update_statistics(rebuild=True)
self.assertTrue(os.path.exists(path))
def test_locking(self):
with open(f"{settings.PID_FILE_STORAGE_PATH}/modoboa_logparser.pid", "w") as fp:
fp.write(f"{os.getpid()}\n")
with self.assertRaises(SystemExit) as inst:
self.run_logparser()
self.assertEqual(inst.exception.code, 2)
+2
View File
@@ -212,6 +212,8 @@ SPECTACULAR_SETTINGS = {
MODOBOA_API_URL = 'https://api.modoboa.org/1/'
PID_FILE_STORAGE_PATH = '/tmp'
# REDIS
REDIS_HOST = 'localhost'