Skip to content

Commit

Permalink
Merge pull request #2762 from modoboa/fix/logparser_lock
Browse files Browse the repository at this point in the history
Added locking mechanism to logparser command
  • Loading branch information
tonioo committed Jan 25, 2023
2 parents 717be47 + 5aa1886 commit 718ee43
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 0 deletions.
2 changes: 2 additions & 0 deletions modoboa/core/commands/templates/settings.py.tpl
Expand Up @@ -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'
Expand Down
21 changes: 21 additions & 0 deletions modoboa/maillog/management/commands/logparser.py
Expand Up @@ -27,6 +27,7 @@

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
Expand Down Expand Up @@ -619,7 +620,27 @@ def add_arguments(self, parser):
"--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")
Expand Down
11 changes: 11 additions & 0 deletions modoboa/maillog/tests/test_views.py
Expand Up @@ -5,6 +5,7 @@
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
Expand All @@ -24,6 +25,9 @@ def setUp(self):

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."""
Expand Down Expand Up @@ -166,3 +170,10 @@ def test_update_statistics(self):
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 changes: 2 additions & 0 deletions test_project/test_project/settings.py
Expand Up @@ -212,6 +212,8 @@

MODOBOA_API_URL = 'https://api.modoboa.org/1/'

PID_FILE_STORAGE_PATH = '/tmp'

# REDIS

REDIS_HOST = 'localhost'
Expand Down

0 comments on commit 718ee43

Please sign in to comment.