feat(setup): use sudo for writing proxy configs to system directories
This commit is contained in:
76
setup.py
76
setup.py
@@ -537,6 +537,46 @@ def _get_host_ip() -> str:
|
|||||||
return "127.0.0.1"
|
return "127.0.0.1"
|
||||||
|
|
||||||
|
|
||||||
|
def _write_system_file(path: pathlib.Path, content: str) -> bool:
|
||||||
|
"""Write a file, using sudo tee if direct write fails with permission error."""
|
||||||
|
# Try direct write first
|
||||||
|
try:
|
||||||
|
path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
path.write_text(content)
|
||||||
|
return True
|
||||||
|
except PermissionError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Fall back to sudo
|
||||||
|
info(f"Need elevated permissions to write to {path.parent}")
|
||||||
|
if not ask_yes_no("Use sudo?", default=True):
|
||||||
|
warn("Skipped. You can copy the config manually later.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Ensure parent directory exists
|
||||||
|
subprocess.run(
|
||||||
|
["sudo", "mkdir", "-p", str(path.parent)],
|
||||||
|
check=True, timeout=30,
|
||||||
|
)
|
||||||
|
# Write via sudo tee
|
||||||
|
result = subprocess.run(
|
||||||
|
["sudo", "tee", str(path)],
|
||||||
|
input=content, text=True,
|
||||||
|
capture_output=True, timeout=30,
|
||||||
|
)
|
||||||
|
if result.returncode != 0:
|
||||||
|
fail(f"sudo tee failed: {result.stderr.strip()}")
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
fail(f"sudo failed: {e}")
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
fail(f"Failed to write config: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def wizard_reverse_proxy(config: dict) -> None:
|
def wizard_reverse_proxy(config: dict) -> None:
|
||||||
section("Reverse Proxy")
|
section("Reverse Proxy")
|
||||||
info("TOD needs a reverse proxy for HTTPS termination.")
|
info("TOD needs a reverse proxy for HTTPS termination.")
|
||||||
@@ -647,9 +687,12 @@ def wizard_reverse_proxy(config: dict) -> None:
|
|||||||
config["proxy_configured"] = False
|
config["proxy_configured"] = False
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
written = _write_system_file(out_path, output)
|
||||||
out_path.parent.mkdir(parents=True, exist_ok=True)
|
|
||||||
out_path.write_text(output)
|
if not written:
|
||||||
|
config["proxy_configured"] = False
|
||||||
|
return
|
||||||
|
|
||||||
ok(f"Wrote {cfg['label']} config to {out_path}")
|
ok(f"Wrote {cfg['label']} config to {out_path}")
|
||||||
config["proxy_configured"] = True
|
config["proxy_configured"] = True
|
||||||
config["proxy_type"] = cfg["label"]
|
config["proxy_type"] = cfg["label"]
|
||||||
@@ -658,33 +701,24 @@ def wizard_reverse_proxy(config: dict) -> None:
|
|||||||
# Post-install hints
|
# Post-install hints
|
||||||
print()
|
print()
|
||||||
if selected == "caddy":
|
if selected == "caddy":
|
||||||
info("Reload Caddy: systemctl reload caddy")
|
info("Reload Caddy: sudo systemctl reload caddy")
|
||||||
elif selected == "nginx":
|
elif selected == "nginx":
|
||||||
if "/sites-available/" in str(out_path):
|
if "/sites-available/" in str(out_path):
|
||||||
sites_enabled = out_path.parent.parent / "sites-enabled" / out_path.name
|
sites_enabled = out_path.parent.parent / "sites-enabled" / out_path.name
|
||||||
info(f"Enable site: ln -s {out_path} {sites_enabled}")
|
info(f"Enable site: sudo ln -s {out_path} {sites_enabled}")
|
||||||
info("Test config: nginx -t")
|
info("Test config: sudo nginx -t")
|
||||||
info("Reload nginx: systemctl reload nginx")
|
info("Reload nginx: sudo systemctl reload nginx")
|
||||||
elif selected == "apache":
|
elif selected == "apache":
|
||||||
if "/sites-available/" in str(out_path):
|
if "/sites-available/" in str(out_path):
|
||||||
info(f"Enable site: a2ensite {out_path.stem}")
|
info(f"Enable site: sudo a2ensite {out_path.stem}")
|
||||||
info("Test config: apachectl configtest")
|
info("Test config: sudo apachectl configtest")
|
||||||
info("Reload Apache: systemctl reload apache2")
|
info("Reload Apache: sudo systemctl reload apache2")
|
||||||
elif selected == "haproxy":
|
elif selected == "haproxy":
|
||||||
info("Test config: haproxy -c -f /etc/haproxy/haproxy.cfg")
|
info("Test config: sudo haproxy -c -f /etc/haproxy/haproxy.cfg")
|
||||||
info("Reload: systemctl reload haproxy")
|
info("Reload: sudo systemctl reload haproxy")
|
||||||
elif selected == "traefik":
|
elif selected == "traefik":
|
||||||
info("Traefik watches for file changes — no reload needed.")
|
info("Traefik watches for file changes — no reload needed.")
|
||||||
|
|
||||||
except PermissionError:
|
|
||||||
fail(f"Permission denied writing to {out_path}")
|
|
||||||
warn(f"Try running with sudo, or copy manually:")
|
|
||||||
info(f" The config has been printed above.")
|
|
||||||
config["proxy_configured"] = False
|
|
||||||
except Exception as e:
|
|
||||||
fail(f"Failed to write config: {e}")
|
|
||||||
config["proxy_configured"] = False
|
|
||||||
|
|
||||||
|
|
||||||
# ── Summary ──────────────────────────────────────────────────────────────────
|
# ── Summary ──────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user