Make change script more robust

This commit is contained in:
Ana Custura 2026-03-06 15:58:08 +00:00
parent 46ad2eff41
commit 4c51b1bd0a

View file

@ -5,7 +5,7 @@ from datetime import datetime
from subprocess import run from subprocess import run
import json import json
CHANGES_REQUIRING_RESTART = ['wifi_password', 'ssid', 'enable_access_point', 'enable_chat', 'enable_delta_chat', 'butterbox_hostname', 'ssh_access_settings', 'root_account_settings'] CHANGES_REQUIRING_RESTART = ['wifi_password', 'ssid', 'enable_access_point', 'enable_chat', 'enable_deltachat', 'butterbox_hostname', 'ssh_access_settings', 'root_account_settings']
def lock_root_account(): def lock_root_account():
result = run(["sudo", "passwd", "-l", "root"]) result = run(["sudo", "passwd", "-l", "root"])
@ -15,50 +15,81 @@ def lock_root_account():
def enable_service(service: str): def enable_service(service: str):
is_enabled = run(["sudo", "systemctl", "is-enabled", service], capture_output = True, text = True) is_enabled = run(["sudo", "systemctl", "is-enabled", service], capture_output = True, text = True)
if 'not_found' in is_enabled.stdout: if 'found' in is_enabled.stdout:
print(f"Service {service} not found")
return False return False
if 'disabled' in is_enabled.stdout: if 'disabled' in is_enabled.stdout:
enable = run(["sudo", "systemctl", "enable", service], capture_output = True, text = True) enable = run(["sudo", "systemctl", "enable", service], capture_output = True, text = True)
if enable.returncode != 0: if enable.returncode != 0:
print(f"Issue enabling service {service}:")
print(enable)
return False return False
else:
print(f"Service {service} already enabled")
return True return True
def disable_service(service: str): def disable_service(service: str):
is_enabled = run(["sudo", "systemctl", "is-enabled", service], capture_output = True, text = True) is_enabled = run(["sudo", "systemctl", "is-enabled", service], capture_output = True, text = True)
if 'not_found' in is_enabled.stdout: if 'found' in is_enabled.stdout:
print(f"Service {service} not found")
return False return False
if 'enabled' in is_enabled.stdout: if 'enabled' in is_enabled.stdout:
result = run(["sudo", "systemctl", "disable", service]) enable = run(["sudo", "systemctl", "disable", service])
if result.returncode != 0: if enable.returncode != 0:
print(f"issue disabling service {service}:")
print(enable)
return False return False
else:
print(f"Service {service} already enabled")
return True return True
def load_setting(setting): def load_setting(setting):
with open("./app/settings.txt", "r") as f: with open("./settings.txt", "r") as f:
settings = json.load(f) settings = json.load(f)
return settings[setting] return settings[setting]
def change_service_status(setting, service): def change_service_status(setting, service):
if load_setting(setting) == "true": if load_setting(setting) == "true":
enable_service(service) return(enable_service(service))
else: else:
disable_service(service) return(disable_service(service))
def change_keanu_weblite_config(new_hostname): def change_keanu_weblite_config(new_hostname):
regex = re.compile('qdt ?= ?"([^"]*)"') regex = re.compile('aut ?= ?"([^"]*)"')
target_file = "/var/www/html/chat/assets/index-CD0QtET8.js" target_file = "/var/www/html/chat/assets/index-xXHv_nhZ.js"
match_changed = False
with open(target_file, "r") as f: with open(target_file, "r") as f:
lines = f.readlines() lines = f.readlines()
for line in enumerate(lines): match_exists = False
try:
for i,line in enumerate(lines):
match = regex.search(line) match = regex.search(line)
if match: if match:
match_exists = True
old_hostname = match.group(1) old_hostname = match.group(1)
print(f"Old ostname {old_hostname}, new is {new_hostname}")
if old_hostname != new_hostname: if old_hostname != new_hostname:
re.sub(old_hostname, new_hostname, lines[line]) lines[i] = re.sub(old_hostname, new_hostname, lines[i])
match_changed = True
break
else:
print(f"Old hostname same as new, not changing Keanu config")
if not match_exists:
print("Keanu weblite match not found!")
return False
except Exception as e:
print(e)
print(line)
if match_changed and lines:
new_lines = "".join(lines)
with open(target_file, "w") as f:
print(f"Writing changed file {target_file}.")
f.write(new_lines)
return True
return False
def change_line_in_file(target_file: str, regex: str, replacement: str): def change_line_in_file(target_file: str, regex: str, replacement: str):
print(f"Changing line in file {target_file}")
regex = re.compile(regex) regex = re.compile(regex)
if not os.path.isfile(target_file): if not os.path.isfile(target_file):
raise FileNotFoundError(f"File {target_file} does not exist") raise FileNotFoundError(f"File {target_file} does not exist")
@ -68,8 +99,8 @@ def change_line_in_file(target_file: str, regex: str, replacement: str):
for i, line in enumerate(lines): for i, line in enumerate(lines):
match = re.fullmatch(replacement, line) match = re.fullmatch(replacement, line)
if match: if match:
print("Line already exists!") print(f"Line already exists, not changing.")
return return False
for i, line in enumerate(lines): for i, line in enumerate(lines):
match = re.fullmatch(regex, line) match = re.fullmatch(regex, line)
if match: if match:
@ -79,9 +110,12 @@ def change_line_in_file(target_file: str, regex: str, replacement: str):
lines.append(replacement) lines.append(replacement)
except NameError: except NameError:
raise NameError(f"File {target_file} is empty.") raise NameError(f"File {target_file} is empty.")
return False
new_lines = "".join(lines) new_lines = "".join(lines)
with open(target_file, "w") as f: with open(target_file, "w") as f:
print(f"Writing changed line to file {target_file}.")
f.write(new_lines) f.write(new_lines)
return True
def check_settings(raspap_installed: bool): def check_settings(raspap_installed: bool):
@ -91,6 +125,7 @@ def check_settings(raspap_installed: bool):
diff_in_minutes = (datetime.now().timestamp() - last_modified)/60 diff_in_minutes = (datetime.now().timestamp() - last_modified)/60
if diff_in_minutes < 2: if diff_in_minutes < 2:
for s in CHANGES_REQUIRING_RESTART: for s in CHANGES_REQUIRING_RESTART:
print(f"Now at setting: {s}")
if s == "wifi_password" and raspap_installed: if s == "wifi_password" and raspap_installed:
regex_wpa_method = "wpa=.*?\n" regex_wpa_method = "wpa=.*?\n"
if load_setting("wifi_password") == "": if load_setting("wifi_password") == "":
@ -108,36 +143,39 @@ def check_settings(raspap_installed: bool):
change_service_status("enable_chat", "dendrite") change_service_status("enable_chat", "dendrite")
if s == "enable_access_point" and raspap_installed: if s == "enable_access_point" and raspap_installed:
change_service_status("enable_access_point", "raspapd") change_service_status("enable_access_point", "raspapd")
if s == "enable_delta_chat": if s == "enable_deltachat":
change_service_status("enable_delta_chat", "madmail") change_service_status("enable_deltachat", "madmail")
if s == "butterbox_hostname": if s == "butterbox_hostname":
pass # change in keanu-weblite compiled assets
new_hostname=f"{load_setting('butterbox_hostname')}.local"
print(f"Changing keanu weblite assets {change_keanu_weblite_config(new_hostname)}")
# change in butterbox-dendrite.conf # change in butterbox-dendrite.conf
regex_matrix_server = "server_name:.*?.local\n" regex_matrix_server = "server_name:.*?.local\n"
change_line_in_file("../dendrite/butterbox-dendrite.conf", regex_matrix_server, result = change_line_in_file("../dendrite/butterbox-dendrite.conf", regex_matrix_server,
f"server_name: {load_setting("butterbox_hostname")}.local\n") f"server_name: {load_setting("butterbox_hostname")}.local\n")
print(f"Changing dendrite config: {result}")
# change in butterbox-dnsmasq.conf # change in butterbox-dnsmasq.conf
if raspap_installed: if raspap_installed:
regex_dns = "address=/.*?.local/10.3.141.1\n" regex_dns = "address=/.*?.local/10.3.141.1\n"
change_line_in_file("/etc/dnsmasq.d/butterbox-dnsmasq.conf", regex_dns, result = change_line_in_file("/etc/dnsmasq.d/butterbox-dnsmasq.conf", regex_dns,
f"address=/{load_setting("butterbox_hostname")}.local/10.3.141.1\n") f"address=/{load_setting("butterbox_hostname")}.local/10.3.141.1\n")
# change in keanu-weblite compiled assets print(f"Changing dnsmasq config: {result}")
change_keanu_weblite_config(load_setting("butterbox_hostname"))
if s == "ssh_access_settings": if s == "ssh_access_settings":
change_service_status("ssh_enabled", "ssh") if load_setting("ssh_access_settings") == "ssh_disabled":
disable_service('ssh')
if load_setting("ssh_access_settings") == "enable_ssh_with_password": if load_setting("ssh_access_settings") == "enable_ssh_with_password":
regex_password_auth = "PasswordAuthentication.*?\n" regex_password_auth = "PasswordAuthentication.*?\n"
change_line_in_file("test/sshd/sshd.conf", regex_password_auth, change_line_in_file("/etc/ssh/sshd_config", regex_password_auth,
f"PasswordAuthentication yes\n") f"PasswordAuthentication yes\n")
regex_root_login = "PermitRootLogin.*?\n" regex_root_login = "PermitRootLogin.*?\n"
change_line_in_file("test/sshd/sshd.conf", regex_root_login, change_line_in_file("/etc/ssh/sshd_config", regex_root_login,
f"PermitRootLogin yes\n") f"PermitRootLogin yes\n")
elif load_setting("ssh_access_settings") == "enable_ssh_with_public_key": elif load_setting("ssh_access_settings") == "enable_ssh_with_public_key":
regex_password_auth = "PasswordAuthentication.*?\n" regex_password_auth = "PasswordAuthentication.*?\n"
change_line_in_file("test/sshd/sshd.conf", regex_password_auth, change_line_in_file("/etc/ssh/sshd_config", regex_password_auth,
f"PasswordAuthentication no\n") f"PasswordAuthentication no\n")
regex_root_login = "PermitRootLogin.*?\n" regex_root_login = "PermitRootLogin.*?\n"
change_line_in_file("test/sshd/sshd.conf", regex_root_login, change_line_in_file("/etc/ssh/sshd_config", regex_root_login,
f"PermitRootLogin prohibit-password\n") f"PermitRootLogin prohibit-password\n")
# append here new key!!! # append here new key!!!
if s == "root_account_settings": if s == "root_account_settings":
@ -151,6 +189,7 @@ def check_settings(raspap_installed: bool):
if __name__ == "__main__": if __name__ == "__main__":
raspap_installed = os.path.exists("/var/www/html/raspapd") raspap_installed = os.path.exists("/var/www/html/raspapd")
while True: while True:
print("sleep 10 sec")
check_settings(raspap_installed) check_settings(raspap_installed)
time.sleep(30) time.sleep(10)