add hostname provisioning step
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import ipaddress, os, re, subprocess, tempfile, json, datetime
|
import ipaddress, os, re, subprocess, tempfile, json, datetime, shlex
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
@@ -111,13 +111,66 @@ def step_wireguard_provision(iot_host: str, client_name: str):
|
|||||||
return {"wg_name": name, "wg_iface": iface}
|
return {"wg_name": name, "wg_iface": iface}
|
||||||
|
|
||||||
def step_set_hostname(iot_host: str, hostname: str | None):
|
def step_set_hostname(iot_host: str, hostname: str | None):
|
||||||
"""Placeholder: set hostname on the device via custom script under /home/caster/bumble-auracast/src/server.
|
"""Set hostname on the device by running the project's provision script over SSH.
|
||||||
|
|
||||||
Intention: SSH into device and run a script, e.g. /home/caster/bumble-auracast/src/server/set-hostname <hostname>.
|
Executes: /home/caster/bumble-auracast/src/auracast/server/provision_domain_hostname.sh <hostname> <domain>
|
||||||
Currently does nothing.
|
Domain is always 'local'. Returns a dict including whether the hostname appears changed.
|
||||||
"""
|
"""
|
||||||
print("⏭️ [placeholder] Skipping hostname change (no-op). Intended hostname:", hostname)
|
if not hostname:
|
||||||
return {"hostname": hostname}
|
print("⏭️ hostname: no hostname provided, skipping")
|
||||||
|
return {"hostname": None, "changed": False}
|
||||||
|
|
||||||
|
# Known locations where the script might live on the device
|
||||||
|
candidates = [
|
||||||
|
"/home/caster/bumble-auracast/src/auracast/server/provision_domain_hostname.sh",
|
||||||
|
"/home/caster/bumble-auracast/src/server/provision_domain_hostname.sh",
|
||||||
|
]
|
||||||
|
domain = "local"
|
||||||
|
|
||||||
|
# Build remote command. Use sudo since hostname changes typically require elevated privileges.
|
||||||
|
quoted_name = shlex.quote(hostname)
|
||||||
|
quoted_domain = shlex.quote(domain)
|
||||||
|
# Build a remote snippet that picks the first existing candidate and runs it via bash
|
||||||
|
# Using bash avoids executable-bit/shebang issues.
|
||||||
|
remote_candidates = " ".join(shlex.quote(c) for c in candidates)
|
||||||
|
remote = (
|
||||||
|
"set -e\n"
|
||||||
|
f"for p in {remote_candidates}; do\n"
|
||||||
|
" if [ -f \"$p\" ]; then sp=\"$p\"; break; fi\n"
|
||||||
|
"done\n"
|
||||||
|
"if [ -z \"${sp:-}\" ]; then echo 'script not found in any candidate path' >&2; exit 1; fi\n"
|
||||||
|
f"sudo bash \"$sp\" {quoted_name} {quoted_domain}\n"
|
||||||
|
"hostname 2>/dev/null || true\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
ssh_cmd = ["ssh", "-p", str(SSH_PORT)]
|
||||||
|
if SSH_KEY:
|
||||||
|
ssh_cmd += ["-i", SSH_KEY]
|
||||||
|
ssh_cmd += [f"{SSH_USER}@{iot_host}", remote]
|
||||||
|
|
||||||
|
proc = subprocess.run(ssh_cmd, check=False, capture_output=True, text=True)
|
||||||
|
stdout = (proc.stdout or "").strip()
|
||||||
|
stderr = (proc.stderr or "").strip()
|
||||||
|
|
||||||
|
# After running the script, re-check the hostname from the device
|
||||||
|
facts_post = get_device_facts(iot_host)
|
||||||
|
new_hostname = facts_post.get("hostname")
|
||||||
|
|
||||||
|
changed = bool(new_hostname) and (new_hostname == hostname)
|
||||||
|
if proc.returncode != 0:
|
||||||
|
print(f"❌ hostname: remote script failed rc={proc.returncode}: {stderr}")
|
||||||
|
else:
|
||||||
|
print(f"✅ hostname: script executed. device hostname now '{new_hostname}' (rc={proc.returncode})")
|
||||||
|
|
||||||
|
return {
|
||||||
|
"hostname": hostname,
|
||||||
|
"domain": domain,
|
||||||
|
"device_hostname": new_hostname,
|
||||||
|
"changed": changed,
|
||||||
|
"rc": proc.returncode,
|
||||||
|
"out": stdout[-500:], # tail to keep logs compact
|
||||||
|
"err": stderr[-500:],
|
||||||
|
}
|
||||||
|
|
||||||
def step_update_app(iot_host: str, services: list[str] | None = None):
|
def step_update_app(iot_host: str, services: list[str] | None = None):
|
||||||
"""Placeholder: start/enable required system services on the device.
|
"""Placeholder: start/enable required system services on the device.
|
||||||
|
|||||||
Reference in New Issue
Block a user