This commit is contained in:
Alexey Berezhok
2026-07-19 01:18:52 +03:00
parent 49812505b2
commit e85d945984
4 changed files with 118 additions and 3 deletions

View File

@@ -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

View File

@@ -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: