From e85d945984ba6aee9e4ca63b5740825909a27996 Mon Sep 17 00:00:00 2001
From: Alexey Berezhok
Date: Sun, 19 Jul 2026 01:18:52 +0300
Subject: [PATCH] Fixes
---
README.ru.md | 2 +-
...nager-plugin-nginx_mod_rewrite_plugin.spec | 7 +-
.../mgr5/addon/nginx_form_rewrite_plugin.py | 107 +++++++++++++++++-
.../mgr5/addon/nginx_mod_rewrite_plugin.py | 5 +
4 files changed, 118 insertions(+), 3 deletions(-)
diff --git a/README.ru.md b/README.ru.md
index 16152b0..498e30c 100644
--- a/README.ru.md
+++ b/README.ru.md
@@ -67,7 +67,7 @@ _packages/ispmanager-plugin-nginx_mod_rewrite_plugin-0.0.1-1.el9.x86_64.rpm
Для установки нужно установить собранный в предыдущем пункте пакет:
```
-sudo rpm -ihv _packages/ispmanager-plugin-nginx_mod_rewrite_plugin-0.0.1-1.el9.x86_64.rpm
+sudo dnf install _packages/ispmanager-plugin-nginx_mod_rewrite_plugin-0.0.1-1.el9.x86_64.rpm
```
Если вдруг установка провалилась, лог установки можно изучить здесь - `/usr/local/mgr5/var/nginx-mod-rewrite-plugin.log`
diff --git a/ispmanager-plugin-nginx_mod_rewrite_plugin.spec b/ispmanager-plugin-nginx_mod_rewrite_plugin.spec
index ad3e113..033f2ca 100644
--- a/ispmanager-plugin-nginx_mod_rewrite_plugin.spec
+++ b/ispmanager-plugin-nginx_mod_rewrite_plugin.spec
@@ -32,11 +32,14 @@ mkdir -p %{buildroot}/usr/local/ispmanager-mod_rewrite/utils
wget -O %{buildroot}/usr/local/ispmanager-mod_rewrite/mod_rewrite.zip https://github.com/bayrepo/ngx_http_apache_rewrite_module/archive/refs/heads/main.zip
cp utils/build_mod_rewrite.py %{buildroot}/usr/local/ispmanager-mod_rewrite/utils
mkdir -p %{buildroot}/usr/local/ispmanager-mod_rewrite/settings
+touch %{buildroot}/usr/local/ispmanager-mod_rewrite/.lock
mkdir -p %{buildroot}/usr/local/ispmanager-mod_rewrite/patches
cp payload/* %{buildroot}/usr/local/ispmanager-mod_rewrite/patches/
%triggerin -- nginx
-/usr/local/ispmanager-mod_rewrite/utils/build_mod_rewrite.py --nodeps
+if [ -e /usr/local/ispmanager-mod_rewrite/settings/installed.cfg ]; then
+ /usr/local/ispmanager-mod_rewrite/utils/build_mod_rewrite.py --nodeps
+fi
%posttrans
killall core
@@ -53,6 +56,7 @@ fi
if [ "$1" == "0" ]; then
rm -f /usr/share/nginx/modules/ngx_http_apache_rewrite_module.conf
rm -f /usr/lib64/nginx/modules/ngx_http_apache_rewrite_module.so
+ rm -f /usr/local/ispmanager-mod_rewrite/settings/installed.cfg
systemctl restart nginx
fi
@@ -69,6 +73,7 @@ fi
%attr(644, root, root) /usr/local/mgr5/skins/common/plugin-logo/ispmanager-plugin-nginx_mod_rewrite_plugin.png
%attr(600, root, root) /usr/local/ispmanager-mod_rewrite/patches/nginx-vhosts.template.patch
%attr(600, root, root) /usr/local/ispmanager-mod_rewrite/patches/nginx-vhosts-ssl.template.patch
+%attr(600, root, root) /usr/local/ispmanager-mod_rewrite/.lock
%changelog
* Mon Jun 29 2026 Alexey BayRepo - 0.0.1-1
diff --git a/usr/local/mgr5/addon/nginx_form_rewrite_plugin.py b/usr/local/mgr5/addon/nginx_form_rewrite_plugin.py
index 6044d37..1bb27d1 100755
--- a/usr/local/mgr5/addon/nginx_form_rewrite_plugin.py
+++ b/usr/local/mgr5/addon/nginx_form_rewrite_plugin.py
@@ -8,6 +8,7 @@ import datetime
from xml.dom import minidom
import shutil
import subprocess
+import fcntl
CONFIG_PATH = "/usr/share/nginx/modules/ngx_http_apache_rewrite_module.conf"
MODULE_LINE = 'load_module "/usr/lib64/nginx/modules/ngx_http_apache_rewrite_module.so";'
@@ -58,6 +59,74 @@ def dump_all_to_log(root):
except Exception:
pass
+def unlock_plugin():
+ """
+ Release the lock on the plugin lock file.
+
+ Returns:
+ bool: True if lock was successfully released, False otherwise (e.g., no lock held)
+ """
+ lock_path = '/usr/local/ispmanager-mod_rewrite/.lock'
+
+ try:
+ if not os.path.exists(lock_path):
+ return False
+
+ with open(lock_path, 'r+') as lock_file:
+ fcntl.flock(lock_file, fcntl.LOCK_UN)
+ lock_file.truncate(0)
+ lock_file.seek(0)
+ return True
+ except Exception:
+ return False
+
+
+def lock_plugin_with_to():
+ """
+ Acquire an exclusive (write) lock on the plugin lock file.
+
+ Returns:
+ bool: True if lock was successfully acquired, False otherwise
+ """
+ lock_path = '/usr/local/ispmanager-mod_rewrite/.lock'
+
+ try:
+ if not os.path.exists(lock_path):
+ return False
+
+ with open(lock_path, 'r+') as lock_file:
+ fcntl.flock(lock_file, fcntl.LOCK_EX)
+ # Add timestamp and PID to indicate this process holds the lock
+ lock_file.write(f'Locked by PID {os.getpid()} at {datetime.datetime.now()}\n')
+ lock_file.truncate(0)
+ return True
+ except Exception:
+ return False
+
+
+def lock_plugin_with_to_read():
+ """
+ Acquire a shared (read) lock on the plugin lock file.
+ Allows multiple readers but prevents writers from acquiring exclusive lock.
+
+ Returns:
+ bool: True if lock was successfully acquired, False otherwise
+ """
+ lock_path = '/usr/local/ispmanager-mod_rewrite/.lock'
+
+ try:
+ if not os.path.exists(lock_path):
+ return False
+
+ with open(lock_path, 'r+') as lock_file:
+ fcntl.flock(lock_file, fcntl.LOCK_SH)
+ # Add timestamp to indicate this reader holds a shared lock
+ lock_file.write(f'Read lock by PID {os.getpid()} at {datetime.datetime.now()}\n')
+ lock_file.truncate(0)
+ return True
+ except Exception:
+ return False
+
def site_state(param):
"""
Get or set the state of a site in sites_settings.cfg.
@@ -67,8 +136,10 @@ def site_state(param):
config_path = "/usr/local/ispmanager-mod_rewrite/settings/sites_settings.cfg"
if isinstance(param, str):
+ lock_plugin_with_to_read()
param_name = param
if not os.path.exists(config_path):
+ unlock_plugin()
return "off"
try:
with open(config_path, 'r', encoding='utf-8') as f:
@@ -79,17 +150,22 @@ def site_state(param):
pattern = rf'^\s*{re.escape(param_name)}\s*=\s*(.*)$'
m = re.match(pattern, line)
if m:
+ unlock_plugin()
return m.group(1).strip()
except Exception:
+ unlock_plugin()
return "off"
+ unlock_plugin()
return "off"
elif isinstance(param, dict):
# Write mode
+ lock_plugin_with_to()
dir_path = os.path.dirname(config_path)
try:
os.makedirs(dir_path, exist_ok=True)
except Exception:
+ unlock_plugin()
return None
lines = []
if os.path.exists(config_path):
@@ -97,6 +173,7 @@ def site_state(param):
with open(config_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
except Exception:
+ unlock_plugin()
return None
for key, val in param.items():
actual_value = 'on' if val == 'on' else 'off'
@@ -116,7 +193,9 @@ def site_state(param):
with open(config_path, 'w', encoding='utf-8') as f:
f.writelines(lines)
except Exception:
+ unlock_plugin()
return None
+ unlock_plugin()
return None
else:
return None
@@ -133,9 +212,12 @@ def read_global_config(params):
param_value = params.get('param_value')
config_path = "/usr/local/ispmanager-mod_rewrite/settings/global_settings.cfg"
+
if param_value is None:
+ lock_plugin_with_to_read()
# Read mode
if not os.path.exists(config_path):
+ unlock_plugin()
return None
try:
with open(config_path, 'r', encoding='utf-8') as f:
@@ -146,16 +228,21 @@ def read_global_config(params):
pattern = rf'^\s*{re.escape(param_name)}\s*=\s*(.*)$'
m = re.match(pattern, line)
if m:
+ unlock_plugin()
return m.group(1).strip()
except Exception:
+ unlock_plugin()
return None
+ unlock_plugin()
return None
else:
+ lock_plugin_with_to()
# Write mode
dir_path = os.path.dirname(config_path)
try:
os.makedirs(dir_path, exist_ok=True)
except Exception:
+ unlock_plugin()
return None
lines = []
found = False
@@ -164,6 +251,7 @@ def read_global_config(params):
with open(config_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
except Exception:
+ unlock_plugin()
return None
for idx, line in enumerate(lines):
stripped = line.strip()
@@ -180,7 +268,9 @@ def read_global_config(params):
with open(config_path, 'w', encoding='utf-8') as f:
f.writelines(lines)
except Exception:
+ unlock_plugin()
return None
+ unlock_plugin()
return None
def check_nginx_rewrite_module():
@@ -188,6 +278,7 @@ def check_nginx_rewrite_module():
if not os.path.exists(CONFIG_PATH):
_log(f"Config file {CONFIG_PATH} does not exist")
return False
+ lock_plugin_with_to_read()
try:
with open(CONFIG_PATH, 'r') as f:
for line in f:
@@ -196,15 +287,19 @@ def check_nginx_rewrite_module():
continue
if MODULE_PATTERN.match(line):
_log("Module found and enabled in config")
+ unlock_plugin()
return True
_log("Module not found in config")
+ unlock_plugin()
return False
except Exception as e:
_log(f"Error reading config file {CONFIG_PATH}: {e}")
+ unlock_plugin()
return False
def set_nginx_rewrite_module(enable: bool):
_log(f"set_nginx_rewrite_module called with enable={enable}")
+ lock_plugin_with_to()
if enable:
if not os.path.exists(CONFIG_PATH):
try:
@@ -266,6 +361,7 @@ def set_nginx_rewrite_module(enable: bool):
_log("No uncommented module line found to disable")
except Exception as e:
_log(f"Error disabling module in config file {CONFIG_PATH}: {e}")
+ unlock_plugin()
def make_nginx_custom_template() -> bool:
tmpl = "/usr/local/mgr5/etc/templates/nginx-vhosts.template"
@@ -281,6 +377,8 @@ def make_nginx_custom_template() -> bool:
default_ssl_tmpl = os.path.join(default_dir, "nginx-vhosts-ssl.template")
target_dir = "/usr/local/mgr5/etc/templates"
+ lock_plugin_with_to()
+
# Copy default templates if they exist
try:
if os.path.exists(default_tmpl):
@@ -296,6 +394,7 @@ def make_nginx_custom_template() -> bool:
os.remove(f)
except Exception:
pass
+ unlock_plugin()
return False
# Ensure copied files exist
@@ -307,6 +406,7 @@ def make_nginx_custom_template() -> bool:
os.remove(f)
except Exception:
pass
+ unlock_plugin()
return False
patches_dir = "/usr/local/ispmanager-mod_rewrite/patches"
@@ -316,6 +416,7 @@ def make_nginx_custom_template() -> bool:
def apply_patch(target, patch_file):
if not os.path.exists(patch_file):
_log(f"Patch file {patch_file} does not exist.")
+ unlock_plugin()
return False
try:
result = subprocess.run(
@@ -326,10 +427,13 @@ def make_nginx_custom_template() -> bool:
)
if result.returncode != 0:
_log(f"Patch failed for {target}: {result.stderr.decode(errors='ignore')}")
+ unlock_plugin()
return False
+ unlock_plugin()
return True
except Exception as e:
_log(f"Exception applying patch to {target}: {e}")
+ unlock_plugin()
return False
patch_success = True
@@ -346,8 +450,9 @@ def make_nginx_custom_template() -> bool:
os.remove(f)
except Exception:
pass
+ unlock_plugin()
return False
-
+ unlock_plugin()
read_global_config({'param_name': 'templates_created', 'param_value': 'on'})
_log("Success: Custom Nginx templates created and patched successfully.")
return True
diff --git a/usr/local/mgr5/addon/nginx_mod_rewrite_plugin.py b/usr/local/mgr5/addon/nginx_mod_rewrite_plugin.py
index 6b9a355..5fedbb5 100755
--- a/usr/local/mgr5/addon/nginx_mod_rewrite_plugin.py
+++ b/usr/local/mgr5/addon/nginx_mod_rewrite_plugin.py
@@ -44,6 +44,11 @@ def BuildModule():
if result.returncode != 0:
# Extract error message from stderr (already captured in stdout due to redirect)
return f'Build utility failed with exit code {result.returncode}'
+
+ installed_cfg_path = '/usr/local/ispmanager-mod_rewrite/settings/installed.cfg'
+ with open(installed_cfg_path, 'w') as cfg_file:
+ cfg_file.write('')
+ os.chmod(installed_cfg_path, 0o600)
except Exception as exc:
log_path_error = os.path.join(os.path.dirname(log_path), 'error.log')
with open(log_path_error, 'a') as error_file: