Files
ispmanager-mod_rewrite/utils/build_mod_rewrite.py
Alexey Berezhok ec27eef6b3 Fixes
2026-07-18 11:34:35 +03:00

181 lines
6.2 KiB
Python

#!/usr/bin/env python3
"""
Utility for building and installing nginx mod_rewrite module.
This script handles downloading, extracting, building, and installing the module.
Returns None on success, or error message string on failure.
"""
import os
import sys
import shutil
import subprocess
import zipfile
import datetime
import re
def _get_nginx_version(log_file):
"""
Detect nginx version from /usr/sbin/nginx -V output.
Args:
log_file: File object to write log messages to
Returns:
str or None: Version string (e.g., '1.30.2') if found, None otherwise
"""
nginx_binary = '/usr/sbin/nginx'
if not os.path.exists(nginx_binary):
log_file.write('Nginx binary not found at /usr/sbin/nginx, using default version detection.\n')
return None
try:
result = subprocess.run([nginx_binary, '-V'], capture_output=True, text=True, timeout=30)
if result.returncode != 0:
log_file.write(f'Failed to run nginx -V with exit code {result.returncode}\n')
if result.stderr:
log_file.write(f'nginx stderr: {result.stderr.strip()}\n')
return None
log_file.write(f'nginx stdout:\n{result.stderr.strip()}\n')
# First line contains "nginx version: nginx/X.Y.Z"
first_line = result.stderr.strip().split('\n')[0]
# Parse the version from the first line
# Expected format: "nginx version: nginx/1.30.2 ..."
match = re.search(r'nginx/(\d+\.\d+\.?\d*)', first_line)
if match:
version = match.group(1)
log_file.write(f'Detected nginx version: {version}\n')
return version
else:
log_file.write(f'Could not parse nginx version from: {first_line}\n')
return None
except subprocess.TimeoutExpired:
log_file.write('nginx -V command timed out.\n')
return None
except Exception as e:
log_file.write(f'Error running nginx -V: {e}\n')
return None
def build_mod_rewrite():
"""
Build and install the nginx mod_rewrite module.
Returns:
str: Error message on failure, None on success
"""
tmp_dir = '/tmp/nginx-mod-rewrite'
log_path = '/usr/local/mgr5/var/nginx-mod-rewrite-plugin.log'
# Check for --nodeps argument - skip installdeps stage if provided
nodeps = False
args = sys.argv[1:]
if '--nodeps' in args:
nodeps = True
try:
# Ensure log directory exists
log_dir = os.path.dirname(log_path)
if log_dir and not os.path.exists(log_dir):
os.makedirs(log_dir, exist_ok=True)
# Setup temporary directory: create or clean
if os.path.isdir(tmp_dir):
shutil.rmtree(tmp_dir)
os.makedirs(tmp_dir, exist_ok=True)
with open(log_path, 'a') as log_file:
log_file.write(f'=== Starting module download and install: {datetime.datetime.now()} ===\n')
# Copy the ZIP file into the temporary directory
src_zip = '/usr/local/ispmanager-mod_rewrite/mod_rewrite.zip'
dst_zip = os.path.join(tmp_dir, 'mod_rewrite.zip')
try:
shutil.copy(src_zip, dst_zip)
log_file.write(f'Copied zip to {dst_zip}\n')
except Exception as e:
return f'Failed to copy zip: {e}'
# Extract the ZIP file
try:
with zipfile.ZipFile(dst_zip, 'r') as zip_ref:
zip_ref.extractall(tmp_dir)
log_file.write('Extracted zip contents.\n')
except Exception as e:
return f'Failed to extract zip: {e}'
# Locate the extracted root directory
extracted_root = None
for entry in os.listdir(tmp_dir):
full_path = os.path.join(tmp_dir, entry)
if os.path.isdir(full_path):
extracted_root = full_path
break
if not extracted_root:
return 'Extracted folder not found.'
log_file.write(f'Using extracted root: {extracted_root}\n')
# Define the sequence of commands to run
if nodeps:
commands = []
else:
commands = [['bash', 'package_preparer.sh', 'installdeps']]
# Detect nginx version and decide on download target
nginx_version_to_use = '.' # Default fallback
detected_version = _get_nginx_version(log_file)
if detected_version is not None:
nginx_version_to_use = detected_version
log_file.write(f'Using detected nginx version: {nginx_version_to_use} for download\n')
else:
log_file.write('Nginx version detection failed, using default (.).\n')
if nginx_version_to_use == '.':
commands.extend([
['bash', 'package_preparer.sh', 'download', nginx_version_to_use, 'system']
])
else:
commands.extend([
['bash', 'package_preparer.sh', 'download', nginx_version_to_use]
])
commands.extend([
['bash', 'package_preparer.sh', 'build'],
['bash', 'package_preparer.sh', 'installmod']
])
for cmd in commands:
log_file.write(f'Running command: {" ".join(cmd)}\n')
result = subprocess.run(cmd, cwd=extracted_root, stdout=log_file, stderr=log_file)
if result.returncode != 0:
return f'Command {" ".join(cmd)} failed with exit code {result.returncode}'
log_file.write('All commands executed successfully.\n')
except Exception as exc:
return f'Unexpected error: {exc}'
finally:
# Clean up temporary directory
try:
if os.path.isdir(tmp_dir):
shutil.rmtree(tmp_dir)
except Exception:
pass
return None
if __name__ == '__main__':
# Run the build process and output result to stdout
result = build_mod_rewrite()
if result is not None:
# On error, write error message to stderr
print(result, file=sys.stderr)
sys.exit(1)
else:
# On success, exit with 0 (no output)
sys.exit(0)