Старый postinstall
This commit is contained in:
commit
4337a3f94e
349 changed files with 21945 additions and 0 deletions
395
deb_dist/postinstall-1.5.0/postinstall/__init__.py
Normal file
395
deb_dist/postinstall-1.5.0/postinstall/__init__.py
Normal file
|
|
@ -0,0 +1,395 @@
|
|||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import signal
|
||||
from dialog import Dialog
|
||||
from postinstall.root import check_root
|
||||
from postinstall.option import (
|
||||
network,
|
||||
update,
|
||||
add_user,
|
||||
install_packages,
|
||||
ssh,
|
||||
hostname,
|
||||
shell,
|
||||
database,
|
||||
docker,
|
||||
)
|
||||
import json
|
||||
|
||||
check_root()
|
||||
|
||||
from postinstall.logger import logger
|
||||
|
||||
# import debugpy
|
||||
|
||||
# debugpy.listen(("0.0.0.0", 5678))
|
||||
# debugpy.wait_for_client()
|
||||
|
||||
|
||||
SSH_CONFIG_PATH = "/etc/ssh/sshd_config"
|
||||
HOSTNAME_FILE = "/etc/hostname"
|
||||
AUTOSTART_FILE = "/usr/share/postinstall/.norestart"
|
||||
BACKUPS_FILE = "/usr/share/postinstall/backups.json"
|
||||
UFW_OPENSSH_CONFIG_PATH = "/etc/ufw/applications.d/openssh-server"
|
||||
|
||||
|
||||
logging = logger
|
||||
|
||||
|
||||
def get_hostname() -> str:
|
||||
try:
|
||||
with open(HOSTNAME_FILE, "r") as f:
|
||||
return f.read().strip()
|
||||
except IOError as e:
|
||||
logging.error(f"Ошибка при чтении hostname: {e}")
|
||||
return "localhost"
|
||||
|
||||
|
||||
def get_ssh_port() -> str:
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["grep", "^#*Port", SSH_CONFIG_PATH],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
port = result.stdout.strip().split()[-1]
|
||||
return port if port.isdigit() else "22"
|
||||
except subprocess.CalledProcessError:
|
||||
logging.warning("Не удалось получить порт SSH, используется порт по умолчанию")
|
||||
return "22"
|
||||
|
||||
|
||||
class MenuScreen:
|
||||
def __init__(self):
|
||||
self.d = Dialog(dialog="dialog")
|
||||
self.ssh_port = get_ssh_port()
|
||||
self.hostname = get_hostname()
|
||||
self.ssh_changes = None
|
||||
self.new_hostname = None
|
||||
self.network = None
|
||||
self.autostart_enabled = self.check_auto_start()
|
||||
self.new_autostart_enabled = self.autostart_enabled
|
||||
|
||||
self.options = [
|
||||
{
|
||||
"name": "Сетевые настройки",
|
||||
"value": "",
|
||||
"tabs": "\t \t",
|
||||
"option": "network",
|
||||
},
|
||||
{
|
||||
"name": "Обновление системы",
|
||||
"value": "",
|
||||
"tabs": "\t \t",
|
||||
"option": "update",
|
||||
},
|
||||
{
|
||||
"name": "Добавить пользователя",
|
||||
"value": "",
|
||||
"tabs": "\t \t",
|
||||
"option": "add_user",
|
||||
},
|
||||
{
|
||||
"name": "Установка программ",
|
||||
"value": "",
|
||||
"tabs": "\t \t",
|
||||
"option": "install_packages",
|
||||
},
|
||||
{
|
||||
"name": "Настройки ssh",
|
||||
"value": "",
|
||||
"tabs": "\t \t",
|
||||
"option": "ssh",
|
||||
},
|
||||
{
|
||||
"name": "Изменить доменное имя ПК",
|
||||
"value": self.hostname,
|
||||
"tabs": "\t \t",
|
||||
"option": "hostname",
|
||||
},
|
||||
{"name": "Выбор оболочки", "value": "", "tabs": "\t \t", "option": "shell"},
|
||||
{
|
||||
"name": "Автозапуск при следующем запуске",
|
||||
"value": "Включен" if self.new_autostart_enabled else "Отключен",
|
||||
"tabs": "\t",
|
||||
"option": "auto_start",
|
||||
},
|
||||
{
|
||||
"name": "Настройка базы данных",
|
||||
"value": "",
|
||||
"tabs": "\t \t",
|
||||
"option": "database",
|
||||
},
|
||||
{
|
||||
"name": "Настройка docker",
|
||||
"value": "",
|
||||
"tabs": "\t \t",
|
||||
"option": "docker",
|
||||
},
|
||||
{
|
||||
"name": "Откат последних изменений",
|
||||
"value": "",
|
||||
"tabs": "\t \t",
|
||||
"option": "rollback",
|
||||
},
|
||||
{
|
||||
"name": "Сохранить и выйти",
|
||||
"value": "",
|
||||
"tabs": "\t \t",
|
||||
"option": "save_and_exit",
|
||||
},
|
||||
]
|
||||
|
||||
os.makedirs(os.path.dirname(AUTOSTART_FILE), exist_ok=True)
|
||||
|
||||
def show_menu(self):
|
||||
choices = []
|
||||
for i, option in enumerate(self.options, 1):
|
||||
value = option["value"]
|
||||
if option["option"] == "hostname":
|
||||
value = (
|
||||
self.new_hostname
|
||||
if self.new_hostname is not None
|
||||
else self.hostname
|
||||
)
|
||||
if self.new_hostname is not None:
|
||||
value = f"{value} (не применено)"
|
||||
elif option["option"] == "network":
|
||||
value = "Изменено (не применено)" if self.network else ""
|
||||
|
||||
choice_text = f"{option['name']}{option['tabs']}{value}"
|
||||
choices.append((str(i), choice_text))
|
||||
|
||||
code, tag = self.d.menu(
|
||||
"Выберите опцию:",
|
||||
choices=choices,
|
||||
title="Главное меню",
|
||||
cancel_label="Выйти без сохранения",
|
||||
width=70,
|
||||
height=15,
|
||||
)
|
||||
|
||||
if code == self.d.OK and tag:
|
||||
return self.options[int(tag) - 1]["option"]
|
||||
return None
|
||||
|
||||
def set_temp_network(self, settings):
|
||||
self.temp_network = settings
|
||||
|
||||
def check_auto_start(self) -> bool:
|
||||
return not os.path.exists(AUTOSTART_FILE)
|
||||
|
||||
def set_auto_start(self, enable: bool) -> None:
|
||||
try:
|
||||
if enable:
|
||||
if os.path.exists(AUTOSTART_FILE):
|
||||
os.remove(AUTOSTART_FILE)
|
||||
logging.info("Автозапуск включен")
|
||||
else:
|
||||
with open(AUTOSTART_FILE, "w") as f:
|
||||
f.write("# Это файл создан для отключения автозапуска\n")
|
||||
logging.info("Автозапуск отключен")
|
||||
except Exception as e:
|
||||
logging.error(f"Ошибка при изменении автозапуска: {e}")
|
||||
|
||||
def update_ssh_port(self, new_port):
|
||||
self.new_ssh_port = new_port
|
||||
|
||||
def update_hostname(self, new_hostname):
|
||||
self.new_hostname = new_hostname
|
||||
|
||||
def update_autostart(self, new_state):
|
||||
self.new_autostart_enabled = new_state
|
||||
|
||||
|
||||
def choose(option, menu):
|
||||
if menu.new_autostart_enabled != menu.autostart_enabled:
|
||||
menu.set_auto_start(menu.new_autostart_enabled)
|
||||
if option == "network":
|
||||
net_config = network.NetworkConfig()
|
||||
if net_config.run():
|
||||
menu.network = net_config
|
||||
elif option == "update":
|
||||
logging.info("Начало обновления системы.")
|
||||
update.run_update()
|
||||
logging.info("Завершено обновление системы.")
|
||||
elif option == "add_user":
|
||||
logging.info("Началось добавления пользователя.")
|
||||
add_user.run_add_user()
|
||||
logging.info("Завершено добавление пользователя.")
|
||||
elif option == "install_packages":
|
||||
logging.info("Начало установки пакетов.")
|
||||
install_packages.run_install_packages()
|
||||
logging.info("Завершена установка пакетов.")
|
||||
elif option == "ssh":
|
||||
ssh_config, changes_made = ssh.run_ssh_config()
|
||||
if changes_made:
|
||||
menu.ssh_changes = ssh_config
|
||||
elif option == "hostname":
|
||||
new_hostname = hostname.run_change_hostname()
|
||||
if new_hostname:
|
||||
menu.new_hostname = new_hostname
|
||||
menu.options[5]["value"] = f"{new_hostname} (не применено)"
|
||||
elif option == "shell":
|
||||
logging.info("Началось изменение shell.")
|
||||
shell.run_change_shell()
|
||||
logging.info("Завершено изменение shell.")
|
||||
elif option == "auto_start":
|
||||
menu.new_autostart_enabled = not menu.new_autostart_enabled
|
||||
menu.options[7]["value"] = (
|
||||
"Включен" if menu.new_autostart_enabled else "Отключен"
|
||||
)
|
||||
logging.info(
|
||||
f"Автозапуск {'включен' if menu.new_autostart_enabled else 'отключен'}"
|
||||
)
|
||||
elif option == "database":
|
||||
logging.info("Запуск настройки базы данных.")
|
||||
|
||||
# Открытие диалогового окна для выбора базы данных
|
||||
code, choice = menu.d.menu("Выберите базу данных для установки:",
|
||||
choices=[("PostgreSQL", "Установить PostgreSQL"),
|
||||
("MariaDB", "Установить MariaDB")])
|
||||
|
||||
if code == menu.d.OK:
|
||||
if choice == "PostgreSQL":
|
||||
if not database.is_installed('postgresql-16'):
|
||||
database.install_postgresql(menu.d)
|
||||
else:
|
||||
menu.d.msgbox("PostgreSQL и Harlequin уже установлены.")
|
||||
|
||||
elif choice == "MariaDB":
|
||||
if not database.is_installed('mariadb-server'):
|
||||
database.install_mariadb(menu.d)
|
||||
else:
|
||||
menu.d.msgbox("MariaDB уже установлена.")
|
||||
|
||||
# Независимо от выбранной базы данных, предложить установку Webmin
|
||||
if not database.is_installed('webmin'):
|
||||
code = menu.d.yesno("Установить Webmin?", yes_label="Да", no_label="Нет")
|
||||
if code == menu.d.OK:
|
||||
database.install_webmin(menu.d)
|
||||
else:
|
||||
menu.d.msgbox("Webmin уже установлен.")
|
||||
|
||||
logging.info("Настройка базы данных завершена.")
|
||||
else:
|
||||
menu.d.msgbox("Выбор базы данных отменён")
|
||||
elif option == "docker":
|
||||
docker.run()
|
||||
|
||||
elif option == "rollback":
|
||||
try:
|
||||
with open(BACKUPS_FILE, "r") as f:
|
||||
backups = json.load(f)
|
||||
f.close()
|
||||
for i in backups:
|
||||
with open(i["file"], "w") as f:
|
||||
f.write(i["content"])
|
||||
f.close()
|
||||
subprocess.run(["systemctl", "restart", "networking"], check=True)
|
||||
subprocess.run(["sudo", "systemctl", "restart", "sshd"], check=True)
|
||||
ssh_port = get_ssh_port()
|
||||
subprocess.run(
|
||||
[
|
||||
"sudo",
|
||||
"sed",
|
||||
"-i",
|
||||
f"s/^ports=.*/ports={ssh_port}\/tcp/",
|
||||
UFW_OPENSSH_CONFIG_PATH,
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
subprocess.run(["sudo", "ufw", "app", "update", "OpenSSH"], check=True)
|
||||
subprocess.run(["sudo", "ufw", "delete", "allow", "OpenSSH"], check=True)
|
||||
subprocess.run(["sudo", "ufw", "allow", "OpenSSH"], check=True)
|
||||
|
||||
menu.d.msgbox("Резервные копии успешно восстановлены")
|
||||
logging.info("Резервные копии успешно восстановлены")
|
||||
except Exception as e:
|
||||
menu.d.msgbox(f"Вы еще не применяли изменения.{e}")
|
||||
return False
|
||||
|
||||
elif option == "save_and_exit":
|
||||
with open("/etc/network/interfaces", "r") as f:
|
||||
interfaces = f.read()
|
||||
f.close()
|
||||
with open("/etc/resolv.conf", "r") as f:
|
||||
dns_settings = f.read()
|
||||
f.close()
|
||||
with open("/etc/ssh/sshd_config", "r") as f:
|
||||
ssh_settings = f.read()
|
||||
f.close()
|
||||
try:
|
||||
with open("/etc/ssh/sshd_config.d/auth.conf", "r") as f:
|
||||
ssh_auth = f.read()
|
||||
except Exception:
|
||||
ssh_auth = ""
|
||||
backup = [
|
||||
{
|
||||
"file": "/etc/network/interfaces",
|
||||
"content": interfaces,
|
||||
},
|
||||
{
|
||||
"file": "/etc/resolv.conf",
|
||||
"content": dns_settings,
|
||||
},
|
||||
{
|
||||
"file": "/etc/ssh/sshd_config",
|
||||
"content": ssh_settings,
|
||||
},
|
||||
{
|
||||
"file": "/etc/ssh/sshd_config.d/auth.conf",
|
||||
"content": ssh_auth,
|
||||
},
|
||||
]
|
||||
|
||||
with open(BACKUPS_FILE, "w") as f:
|
||||
f.write(json.dumps(backup))
|
||||
f.close()
|
||||
|
||||
if menu.ssh_changes:
|
||||
logging.info(
|
||||
f"Применены новые настройки SSH. {'Новый порт SSH: ' + str(menu.ssh_changes.new_port) if menu.ssh_changes.new_port is not None else ''} {'Новый метод авторизации: ' + menu.ssh_changes.new_auth_method if menu.ssh_changes.new_auth_method is not None else ''}"
|
||||
)
|
||||
menu.ssh_changes.apply_changes()
|
||||
if menu.new_hostname:
|
||||
logging.info(f"Применено новое имя хоста: {menu.new_hostname}")
|
||||
if hostname.apply_hostname_change(menu.new_hostname):
|
||||
menu.hostname = menu.new_hostname
|
||||
if menu.network:
|
||||
logging.info(
|
||||
f"Применены новые настройки сети: {menu.network.temp_network_settings}"
|
||||
)
|
||||
if not menu.network.save_and_apply_network_settings():
|
||||
return True
|
||||
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def signal_handler(sig, frame):
|
||||
logging.info("Приложение закрыто")
|
||||
subprocess.run("clear", shell=True)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def main():
|
||||
logging.info("Приложение запущено")
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
signal.signal(signal.SIGTERM, signal_handler)
|
||||
|
||||
menu = MenuScreen()
|
||||
while True:
|
||||
option = menu.show_menu()
|
||||
if option is None:
|
||||
break
|
||||
if not choose(option, menu):
|
||||
break
|
||||
logging.info("Приложение закрыто")
|
||||
subprocess.run("clear", shell=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue