fix install v2.15.X
This commit is contained in:
+130
-26
@@ -1074,6 +1074,79 @@ def _detect_certbot_version(certbot_path: Path) -> str:
|
||||
return m.group(1)
|
||||
|
||||
|
||||
def certbot_version_for_npm() -> str:
|
||||
"""Return the certbot version that NPM must expose as CERTBOT_VERSION.
|
||||
|
||||
NPM v2.15.x replaces {{certbot-version}} in dns-plugins.json from the
|
||||
CERTBOT_VERSION environment variable. If it is missing, Node turns it into
|
||||
"undefined" and pip receives invalid requirements such as acme==undefined.
|
||||
"""
|
||||
candidates = [
|
||||
Path("/opt/certbot/bin/certbot"),
|
||||
Path("/usr/local/bin/certbot"),
|
||||
]
|
||||
|
||||
for certbot_path in candidates:
|
||||
if certbot_path.exists():
|
||||
try:
|
||||
return _detect_certbot_version(certbot_path)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if shutil.which("certbot"):
|
||||
try:
|
||||
out = run_out(["certbot", "--version"], check=False).strip()
|
||||
m = re.search(r"(\d+\.\d+\.\d+)", out)
|
||||
if m:
|
||||
return m.group(1)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return ""
|
||||
|
||||
|
||||
def patch_npm_certbot_plugins_config() -> str:
|
||||
"""Patch NPM DNS plugin metadata with a concrete certbot version.
|
||||
|
||||
This is a non-docker install. NPM normally expects CERTBOT_VERSION in the
|
||||
container environment. We set the env in systemd and also replace the JSON
|
||||
placeholders after every install/update so startup cannot generate
|
||||
acme==undefined even if the process environment is incomplete.
|
||||
"""
|
||||
certbot_ver = certbot_version_for_npm()
|
||||
if not certbot_ver:
|
||||
print("⚠ Could not detect Certbot version for NPM DNS plugin metadata")
|
||||
return ""
|
||||
|
||||
os.environ["CERTBOT_VERSION"] = certbot_ver
|
||||
patched = []
|
||||
for path in [
|
||||
Path("/opt/npm/certbot/dns-plugins.json"),
|
||||
Path("/opt/npm/backend/certbot/dns-plugins.json"),
|
||||
]:
|
||||
if not path.exists():
|
||||
continue
|
||||
try:
|
||||
txt = path.read_text(encoding="utf-8")
|
||||
new = txt.replace("{{certbot-version}}", certbot_ver)
|
||||
new = new.replace("acme==undefined", f"acme=={certbot_ver}")
|
||||
if new != txt:
|
||||
path.write_text(new, encoding="utf-8")
|
||||
patched.append(str(path))
|
||||
except Exception as e:
|
||||
print(f"⚠ Could not patch {path}: {e}")
|
||||
|
||||
if patched:
|
||||
print(f"✔ Patched NPM Certbot plugin metadata: Certbot {certbot_ver}")
|
||||
if DEBUG:
|
||||
for path in patched:
|
||||
print(f" - {path}")
|
||||
else:
|
||||
print(f"✔ NPM Certbot plugin metadata ready: Certbot {certbot_ver}")
|
||||
|
||||
return certbot_ver
|
||||
|
||||
|
||||
|
||||
def run_logged(cmd, log_path: Path, timeout=1200, check=True, env=None):
|
||||
"""Run command with stdout/stderr saved to a log file.
|
||||
@@ -3123,6 +3196,59 @@ exec /usr/sbin/logrotate -s {state_file} "$@"
|
||||
print(f"⚠ Warning: could not fix {logrotate_dir} permissions: {e}")
|
||||
|
||||
|
||||
|
||||
def write_npm_service_unit(ipv6_enabled: bool, include_certbot_version: bool = True):
|
||||
"""Write npm.service.
|
||||
|
||||
During update this refreshes an older unit so NPM receives
|
||||
CERTBOT_VERSION and does not expand DNS plugin requirements to
|
||||
acme==undefined. Fresh installs also use this helper when creating
|
||||
the service from scratch.
|
||||
"""
|
||||
certbot_ver = ""
|
||||
if include_certbot_version:
|
||||
certbot_ver = patch_npm_certbot_plugins_config()
|
||||
|
||||
unit_lines = [
|
||||
"[Unit]",
|
||||
"Description=Nginx Proxy Manager (backend)",
|
||||
"After=network.target angie.service",
|
||||
"Wants=angie.service",
|
||||
"",
|
||||
"[Service]",
|
||||
"User=npm",
|
||||
"Group=npm",
|
||||
"WorkingDirectory=/opt/npm",
|
||||
"Environment=NODE_ENV=production",
|
||||
"Environment=PATH=/opt/certbot/bin:/usr/local/bin:/usr/bin:/bin",
|
||||
]
|
||||
if certbot_ver:
|
||||
unit_lines.append(f"Environment=CERTBOT_VERSION={certbot_ver}")
|
||||
if not ipv6_enabled:
|
||||
unit_lines.append("Environment=DISABLE_IPV6=true")
|
||||
unit_lines += [
|
||||
"ExecStart=/usr/bin/node /opt/npm/index.js",
|
||||
"Restart=on-failure",
|
||||
"RestartSec=5",
|
||||
"",
|
||||
"[Install]",
|
||||
"WantedBy=multi-user.target",
|
||||
"",
|
||||
]
|
||||
|
||||
write_file(Path("/etc/systemd/system/npm.service"), "\n".join(unit_lines), 0o644)
|
||||
subprocess.run(["systemctl", "daemon-reload"], check=False)
|
||||
if certbot_ver:
|
||||
print(f"✔ npm.service updated with CERTBOT_VERSION={certbot_ver}")
|
||||
else:
|
||||
print("✔ npm.service updated")
|
||||
return certbot_ver
|
||||
|
||||
|
||||
def refresh_npm_service_for_update(ipv6_enabled: bool):
|
||||
with step("Updating npm.service for update (CERTBOT_VERSION)"):
|
||||
return write_npm_service_unit(ipv6_enabled=ipv6_enabled, include_certbot_version=True)
|
||||
|
||||
def create_systemd_units(ipv6_enabled: bool):
|
||||
with step("Creating and starting systemd services (angie, npm)"):
|
||||
# Some configs may already reference the admin/metrics SSL certificate.
|
||||
@@ -3130,32 +3256,7 @@ def create_systemd_units(ipv6_enabled: bool):
|
||||
if NPM_ADMIN_ENABLE_SSL:
|
||||
generate_selfsigned_cert()
|
||||
|
||||
unit_lines = [
|
||||
"[Unit]",
|
||||
"Description=Nginx Proxy Manager (backend)",
|
||||
"After=network.target angie.service",
|
||||
"Wants=angie.service",
|
||||
"",
|
||||
"[Service]",
|
||||
"User=npm",
|
||||
"Group=npm",
|
||||
"WorkingDirectory=/opt/npm",
|
||||
"Environment=NODE_ENV=production",
|
||||
"Environment=PATH=/opt/certbot/bin:/usr/local/bin:/usr/bin:/bin",
|
||||
]
|
||||
if not ipv6_enabled:
|
||||
unit_lines.append("Environment=DISABLE_IPV6=true")
|
||||
unit_lines += [
|
||||
"ExecStart=/usr/bin/node /opt/npm/index.js",
|
||||
"Restart=on-failure",
|
||||
"RestartSec=5",
|
||||
"",
|
||||
"[Install]",
|
||||
"WantedBy=multi-user.target",
|
||||
"",
|
||||
]
|
||||
|
||||
write_file(Path("/etc/systemd/system/npm.service"), "\n".join(unit_lines), 0o644)
|
||||
write_npm_service_unit(ipv6_enabled=ipv6_enabled, include_certbot_version=True)
|
||||
write_file(Path("/etc/systemd/system/angie.service"), ANGIE_UNIT, 0o644)
|
||||
subprocess.run(["systemctl", "daemon-reload"], check=False)
|
||||
ensure_angie_log_include_files()
|
||||
@@ -4098,6 +4199,8 @@ def update_only(
|
||||
|
||||
patch_npm_backend_commands()
|
||||
ensure_certbot_venv_ready()
|
||||
patch_npm_certbot_plugins_config()
|
||||
refresh_npm_service_for_update(ipv6_enabled=ipv6_enabled)
|
||||
configure_letsencrypt()
|
||||
create_systemd_units(ipv6_enabled=ipv6_enabled)
|
||||
|
||||
@@ -4415,6 +4518,7 @@ def main():
|
||||
"branch": args.branch if installed_from_branch else None,
|
||||
})
|
||||
|
||||
patch_npm_certbot_plugins_config()
|
||||
create_systemd_units(ipv6_enabled=args.enable_ipv6)
|
||||
|
||||
ensure_nginx_symlink()
|
||||
|
||||
Reference in New Issue
Block a user