Старый postinstall

This commit is contained in:
commit 4337a3f94e
349 changed files with 21945 additions and 0 deletions

880
documentation.md Normal file
View file

@ -0,0 +1,880 @@
# Описание
Программа `postinstall` предназначен для автоматизации различных задач по настройке и конфигурации системы после установки. Он предоставляет интерфейс для управления настройками сети, обновлениями системы, установкой программного обеспечения, настройкой SSH, изменением доменного имени и многими другими функциями.
# Основные директории и файлы
- **`postinstall/`**: Главная директория проекта.
- **`__init__.py`**: Инициализирует пакет `postinstall`.
- **`logger.py`**: Определяет функции для ведения логов.
- **`__main__.py`**: Главный исполняемый скрипт, запускающий основные функции проекта.
- **`root.py`**: Сценарий для управления правами суперпользователя.
- **`option/`**: Поддиректория, содержащая скрипты для различных опций настройки и установки.
## postinstall/__init__.py
Этот скрипт представляет собой основную точку входа для выполнения конфигурационных задач системы. Он использует библиотеку `dialog` для взаимодействия с пользователем через текстовые диалоговые окна и выполняет различные конфигурационные задачи, такие как обновление системы, настройка сети, добавление пользователей, установка пакетов и другие. Скрипт включает в себя функции для чтения и изменения системных конфигураций и резервного копирования.
### Импортируемые модули и функции
- `os`, `subprocess`, `sys`, `signal`: Стандартные модули Python для работы с операционной системой, выполнения команд и обработки сигналов.
- `Dialog` из `dialog`: Для создания текстовых диалоговых окон.
- `check_root` из `postinstall.root`: Проверка прав суперпользователя.
- Модули из `postinstall.option`:
- `network`: Настройка сетевых параметров.
- `update`: Обновление системы.
- `add_user`: Добавление пользователя.
- `install_packages`: Установка программ.
- `ssh`: Настройка SSH.
- `hostname`: Изменение имени хоста.
- `shell`: Выбор оболочки.
- `database`: Настройка базы данных.
- `docker`: Настройка Docker.
- `json`: Для работы с JSON-данными.
- `logger` из `postinstall.logger`: Для ведения логов.
### Константы
- `SSH_CONFIG_PATH`: Путь к конфигурационному файлу SSH.
- `HOSTNAME_FILE`: Путь к файлу с именем хоста.
- `AUTOSTART_FILE`: Путь к файлу автозапуска.
- `BACKUPS_FILE`: Путь к файлу резервных копий.
- `UFW_OPENSSH_CONFIG_PATH`: Путь к конфигурации UFW для OpenSSH.
### Классы и методы
#### `MenuScreen`
- **Методы:**
- `__init__(self)`: Инициализация меню, получение текущих значений конфигурации (SSH порт, имя хоста, автозапуск и т.д.).
- `show_menu(self)`: Отображение главного меню и обработка выбора пользователя.
- `set_temp_network(self, settings)`: Установка временных сетевых настроек.
- `check_auto_start(self)`: Проверка состояния автозапуска.
- `set_auto_start(self, enable: bool)`: Включение или отключение автозапуска.
- `update_ssh_port(self, new_port)`: Обновление порта SSH.
- `update_hostname(self, new_hostname)`: Обновление имени хоста.
- `update_autostart(self, new_state)`: Обновление состояния автозапуска.
### Функции
#### `choose(option, menu)`
- **Описание:** Обработка выбранной пользователем опции из меню.
- **Аргументы:**
- `option`: Выбранная опция меню.
- `menu`: Объект класса `MenuScreen`.
- **Возвращаемое значение:**
- `False`, если произошла ошибка или требуется завершение работы.
#### `signal_handler(sig, frame)`
- **Описание:** Обработчик сигналов для корректного завершения работы приложения.
- **Аргументы:**
- `sig`: Сигнал.
- `frame`: Контекст сигнала.
#### `main()`
- **Описание:** Основная функция, которая запускает приложение, обрабатывает сигналы и отображает меню.
### Примечания
- Скрипт требует прав суперпользователя для выполнения некоторых команд.
- Перед сохранением изменений в системных файлах скрипт делает резервные копии, что позволяет восстановить предыдущие состояния конфигураций при необходимости.
## postinstall/logger.py
Модуль `logger.py` предназначен для настройки и управления логированием в приложении. Он обеспечивает запись логов в файл и добавление информации о текущем пользователе в каждый лог-запись.
### Импортируемые модули
- `logging`: Стандартный модуль для ведения логов в Python.
- `getpass`: Модуль для получения имени текущего пользователя.
### Функции
#### `setup_logger()`
Настраивает логирование для приложения.
**Возвращаемое значение:**
- `logging.Logger` - Настроенный экземпляр логирования.
**Подробности:**
1. **Создание логов:**
- `logger = logging.getLogger()`
- Устанавливается уровень логирования на `INFO`.
2. **Настройка формата:**
- Формат лог-сообщений: `%(asctime)s - User: %(user)s - %(message)s`
- `%(asctime)s` - Время записи.
- `%(user)s` - Имя пользователя, делавшего запись.
- `%(message)s` - Сообщение лога.
3. **Создание и настройка обработчика файла:**
- `file_handler = logging.FileHandler("/var/log/postinstall.log")`
- Обработчик записывает логи в файл `/var/log/postinstall.log`.
- Форматтер применяет формат к записям.
4. **Создание и применение фильтра:**
- `UserFilter` - Класс фильтра, добавляющий имя пользователя к каждой записи лога.
- Фильтр используется для добавления пользовательской информации к записям.
5. **Добавление обработчика и фильтра к логам:**
- Обработчик и фильтр добавляются к логам.
**Примечание:**
- Файл журнала будет создан в `/var/log/`.
### Переменные
#### `logger`
- Настроенный экземпляр логгера, возвращаемый функцией `setup_logger()`.
## postinstall/root.py
Модуль `root.py` предназначен для проверки, что скрипт запущен с правами суперпользователя (root). Это важно для обеспечения выполнения программы. Postinstall работает только с правами суперпользователя для обеспечения успешной работы всех модулей и функций.
### Импортируемые модули
- `os`: Модуль для взаимодействия с операционной системой.
- `sys`: Модуль для работы с параметрами и функциями интерпретатора Python.
### Функции
#### `check_root()`
Проверяет, что скрипт запущен от имени суперпользователя.
**Возвращаемое значение:**
- Нет (в случае успеха) - Если скрипт запущен с правами суперпользователя, функция просто завершает выполнение без ошибок.
- `sys.exit(1)` - Если скрипт не запущен с правами суперпользователя, функция завершает выполнение скрипта с кодом ошибки `1`.
**Подробности:**
1. **Получение идентификатора пользователя:**
- `os.geteuid()` - Возвращает идентификатор эффективного пользователя текущего процесса.
2. **Проверка прав:**
- Если идентификатор эффективного пользователя не равен `0` (что соответствует root), выводится сообщение об ошибке: `"Запустите скрипт с правами суперпользователя"`.
- Скрипт завершается с кодом ошибки `1` с помощью `sys.exit(1)`.
## option/add_user.py
Скрипт `add_user.py` предназначен для добавления нового пользователя в систему Linux через текстовый интерфейс. Также предоставляет возможность скрывать или показывать вводимый пароль и проверяет, существует ли уже пользователь в системе.
### Импортируемые модули
- `subprocess`: Для выполнения команд в командной строке и взаимодействия с процессами.
- `dialog.Dialog`: Для создания текстовых диалогов.
- `pwd`: Для проверки существования пользователя в системе.
- `postinstall.logger`: Для ведения логов, импортирован как `logger`.
### Функции
#### `get_password_with_toggle(d, title)`
Функция для ввода пароля с возможностью переключения видимости пароля (показ/скрытие).
**Параметры:**
- `d` (Dialog): Объект `Dialog`, используемый для создания диалоговых окон.
- `title` (str): Заголовок диалогового окна.
**Процесс:**
1. Функция отображает диалоговое окно для ввода пароля с возможностью переключения между скрытым и открытым отображением пароля.
2. Пользователь может нажать кнопку "Показать пароль" или "Скрыть пароль" для изменения состояния видимости пароля.
3. Если пользователь нажимает "Отмена", функция возвращает `None`.
4. Возвращает введённый пароль, если пользователь подтверждает ввод.
#### `add_user()`
Основная функция для добавления нового пользователя в систему.
**Процесс:**
1. **Создание формы для ввода данных:**
- Поля формы включают имя пользователя, полное имя, мобильный телефон, городской телефон и кабинет.
- После ввода данных в форму, проверяется, существует ли уже пользователь с таким именем.
2. **Проверка существования пользователя:**
- Используется модуль `pwd` для проверки существования пользователя.
- Если пользователь уже существует, выводится сообщение об ошибке.
3. **Запрос пароля:**
- Используется `get_password_with_toggle` для ввода пароля с возможностью его показать/скрыть.
- Пароль также проверяется на совпадение с подтверждением пароля.
4. **Запрос прав администратора:**
- Диалоговое окно спрашивает, нужно ли сделать пользователя администратором.
5. **Создание пользователя:**
- Выполняется команда `useradd` для создания пользователя с указанными параметрами.
- Устанавливается пароль для нового пользователя с помощью команды `passwd`.
- Если пользователь назначается администратором, добавляется в группу `sudo`.
6. **Логирование и сообщение:**
- Записывается информация о созданном пользователе в журнал.
- Отображается сообщение об успешном добавлении пользователя или об ошибке.
#### `run_add_user()`
Функция-обёртка для вызова функции `add_user`.
### Запуск скрипта
При запуске скрипта напрямую (`if __name__ == "__main__":`), вызывается функция `run_add_user`, которая в свою очередь вызывает `add_user`.
### Обработка ошибок
- **`subprocess.CalledProcessError`**: Ловит ошибки выполнения команд в командной строке и записывает их в журнал.
- Сообщения об ошибках также отображаются в диалоговом окне для пользователя.
## option/autostart.py
Скрипт `autostart.py` отвечает за управление настройками автозапуска при следующем запуске системы. Скрипт использует файл в файловой системе для хранения состояния автозапуска.
### Импортируемые модули
- `os`: Для работы с файловой системой (проверка наличия файлов, создание и удаление файлов).
- `dialog.Dialog`: Для создания текстовых диалогов.
- `postinstall.logger`: Для ведения логов, импортирован как `logger`.
### Константы
- `AUTOSTART_FILE`: Путь к файлу, который указывает на состояние автозапуска. Если файл существует, автозапуск отключен. Если файл отсутствует, автозапуск включен.
### Классы и методы
#### Класс `AutoStartScreen`
##### Методы
- **`__init__()`**
Конструктор класса `AutoStartScreen`. Инициализирует объект `Dialog` для создания текстовых диалогов.
- **`check_auto_start() -> bool`**
Проверяет текущее состояние автозапуска. Возвращает `True`, если автозапуск включен (файл `AUTOSTART_FILE` отсутствует), и `False`, если автозапуск отключен (файл присутствует).
- **`set_auto_start(enable: bool) -> None`**
Изменяет состояние автозапуска в зависимости от значения `enable`.
- **Если `enable` равно `True`:** Удаляет файл `AUTOSTART_FILE`, если он существует. Это включает автозапуск.
- **Если `enable` равно `False`:** Создаёт файл `AUTOSTART_FILE`, чтобы отключить автозапуск. В файл записывается комментарий.
В случае ошибок при удалении или создании файла записываются сообщения об ошибках в журнал.
- **`show_screen()`**
Отображает диалоговое окно для выбора действия по настройке автозапуска. Используется `checklist` для отображения опций и состояния текущего автозапуска.
- Если пользователь выбирает опцию "Автозапуск при следующем запуске", состояние автозапуска изменяется в соответствии с выбором.
- После применения изменений отображается сообщение об успешном сохранении изменений.
- Если пользователь отменяет изменения, в журнал записывается информация об отмене.
### Функция `main()`
Создаёт экземпляр `AutoStartScreen` и вызывает метод `show_screen()` для отображения диалогового окна с настройками автозапуска.
### Запуск скрипта
При запуске скрипта напрямую (`if __name__ == "__main__":`), вызывается функция `main`, которая инициирует работу с настройками автозапуска.
## option/install_packages.py
Скрипт `install_packages.py` предназначен для установки пакетов на систему Linux. Он предоставляет пользователю интерфейс для выбора базы данных и установки связанных с ней пакетов, а также возможности установки Webmin и дополнительных компонентов.
### Импортируемые модули
- `subprocess`: Для выполнения команд оболочки и обработки их вывода.
- `dialog.Dialog`: Для создания текстовых диалогов.
### Функции
#### `main()`
Основная функция, которая управляет процессом установки:
1. Создаёт объект `Dialog` для создания текстовых диалогов.
2. Отображает диалоговое окно для выбора базы данных (PostgreSQL или MariaDB).
- Если пользователь выбирает PostgreSQL или MariaDB, вызываются соответствующие функции для установки пакетов.
- Независимо от выбранной базы данных, предлагается установка Webmin.
- Если пользователь соглашается на установку Webmin, вызывается функция `install_webmin`.
#### `is_installed(package_name)`
Проверяет, установлен ли пакет с именем `package_name`:
- Выполняет команду `dpkg-query -W -f=${Status} package_name` для получения статуса пакета.
- Если вывод команды содержит строку `'install ok installed'`, возвращает `True`.
- В случае ошибки возвращает `False`.
#### `run_command_with_log(dialog, command, title)`
Запускает команду и выводит лог её выполнения в диалоговое окно:
- Создаёт процесс для выполнения команды с помощью `subprocess.Popen`.
- Читает стандартный вывод и стандартный ошибки процесса, собирая их в список `log_output`.
- Отображает результат в диалоговом окне с заголовком `title`.
- Возвращает `True`, если команда выполнена успешно, иначе `False`.
#### `install_package(dialog, package_name)`
Устанавливает указанный пакет с выводом лога:
- Отображает сообщение о начале установки пакета.
- Обновляет список пакетов с помощью команды `apt-get update`.
- Устанавливает пакет с помощью `apt-get install -y package_name`.
- Отображает сообщение об успешной установке или ошибке.
#### `install_postgresql(dialog)`
Устанавливает PostgreSQL и связанный пакет Harlequin:
- Проверяет и устанавливает пакеты `postgresql-16`, `python3-harlequin`, и `python3-harlequin-postgres`, если они не установлены.
#### `install_mariadb(dialog)`
Устанавливает MariaDB:
- Проверяет и устанавливает пакеты `mariadb-server` и `python3-harlequin`, если они не установлены.
#### `install_webmin(dialog)`
Устанавливает Webmin и связанные пакеты:
- Проверяет, установлен ли Webmin. Если нет, выполняет установку:
- Устанавливает Webmin и дополнительные пакеты (`postgresql-server-dev-16` и `cpanminus`).
- Разрешает порт `10000/tcp` в `ufw` (брандмауэр).
- Устанавливает Perl-модули `DBI` и `DBD::Pg` через `cpanm`.
- Перезагружает Webmin.
- Отображает сообщения о каждом шаге процесса установки.
### Запуск скрипта
При запуске скрипта напрямую (`if __name__ == "__main__":`), вызывается функция `main`, которая инициирует процесс установки пакетов.
## option/docker.py
Скрипт `docker_config.py` управляет установкой и удалением Docker и Portainer. Логирование выполняется через модуль `logger` из `postinstall.logger`.
### Импортируемые модули
- `subprocess`: Для выполнения команд оболочки и обработки их вывода.
- `os`: Для работы с файловой системой.
- `re`: Для работы с регулярными выражениями.
- `shlex`: Для безопасного разбора команд.
- `abc`, `abstractmethod`: Для создания абстрактных базовых классов и методов.
- `Optional`, `List`, `Callable`: Для аннотаций типов.
- `Dialog`: Для создания текстовых диалогов.
- `logger`: Для логирования.
### Константы
- `REGISTRY_URL`: URL Docker registry.
- `REGISTRY_LOGIN`: Логин для Docker registry.
- `REGISTRY_PASSWORD`: Пароль для Docker registry.
- `DOCKER_COMPOSE_FILE_PATH`: Путь к файлу `docker-compose.yml`.
### Классы и их методы
#### `CommandExecutor`
- **Методы:**
- `run_command(command: str, shell: bool = False, input_data: Optional[str] = None, ignore_errors: List[int] = []) -> subprocess.CompletedProcess`: Выполняет команду и возвращает результат выполнения. Обрабатывает ошибки и логирует их.
#### `SystemChecker`
- **Методы:**
- `is_command_installed(command: str) -> bool`: Проверяет, установлен ли командный инструмент.
#### `ProgressGauge`
- **Методы:**
- `__init__(self, dialog: Dialog, title: str, total_steps: int)`: Инициализирует объект с диалогом и настройками для отображения индикатора выполнения.
- `update(self, step: int, message: str)`: Обновляет индикатор выполнения.
- `__enter__(self)`: Запускает индикатор выполнения.
- `__exit__(self, exc_type, exc_val, exc_tb)`: Останавливает индикатор выполнения.
#### `DockerManager`
- **Методы:**
- `install(progress_callback: Callable[[int, str], None])`: Устанавливает Docker и Docker Compose.
- `uninstall(progress_callback: Callable[[int, str], None])`: Удаляет Docker и Docker Compose.
- `login_to_registry()`: Выполняет вход в Docker registry.
#### `UFWManager`
- **Методы:**
- `add_rule(port: str)`: Добавляет правило для открытия порта в UFW.
- `remove_rule(port: str)`: Удаляет правило для порта в UFW.
#### `PortainerManager`
- **Методы:**
- `install(port: str, password: str, ip: str, progress_callback: Callable[[int, str], None])`: Устанавливает Portainer с указанными параметрами.
- `uninstall(progress_callback: Callable[[int, str], None])`: Удаляет Portainer.
- `_generate_password_hash(password: str) -> str`: Генерирует хеш пароля для Portainer.
- `_create_docker_compose_file(port: str, password_hash: str, ip: str)`: Создаёт файл `docker-compose.yml` для Portainer.
#### `InputValidator`
- **Методы:**
- `validate(value: str, pattern: str) -> bool`: Проверяет значение на соответствие регулярному выражению.
#### `UIElement`
- **Методы:**
- `__init__(self, dialog: Dialog)`: Инициализирует элемент пользовательского интерфейса.
- `show(self)`: Абстрактный метод для отображения UI элемента.
#### `Menu`
- **Методы:**
- `show(self)`: Отображает меню для выбора действия (установка или удаление Docker).
#### `YesNoUI`
- **Методы:**
- `show(self, text: str)`: Отображает диалоговое окно с вопросом и возвращает ответ пользователя.
#### `PasswordInput`
- **Методы:**
- `show(self)`: Отображает диалоговое окно для ввода пароля и возвращает его, если пароль соответствует требованиям.
#### `PortInput`
- **Методы:**
- `show(self)`: Отображает диалоговое окно для ввода порта и возвращает его, если порт корректен.
#### `IPInput`
- **Методы:**
- `show(self)`: Отображает диалоговое окно для ввода IP-адреса и возвращает его, если IP корректен.
#### `DockerConfigUI`
- **Методы:**
- `__init__(self)`: Инициализирует UI для конфигурации Docker.
- `run(self)`: Запускает основной цикл работы UI.
- `_handle_docker(self)`: Обрабатывает установку или удаление Docker.
- `handle_portainer(self)`: Обрабатывает установку или удаление Portainer.
- `_install_portainer(self)`: Устанавливает Portainer с запросом необходимых данных у пользователя.
### Запуск скрипта
При запуске скрипта напрямую вызывается функция `run`, которая создаёт объект `DockerConfigUI` и запускает его метод `run`, инициируя процесс конфигурации Docker и Portainer.
## option/hostname.py
Скрипт `change_hostname.py` предназначен для изменения доменного имени (hostname) системы. Скрипт читает текущее доменное имя, позволяет пользователю ввести новое доменное имя, проверяет его валидность и применяет изменения.
### Импортируемые модули
- `subprocess`: Для выполнения команд оболочки.
- `Dialog`: Для создания текстовых диалогов.
- `os`: Для работы с файловой системой.
### Константы
- `HOSTNAME_FILE`: Путь к файлу, содержащему текущее доменное имя.
- `HOSTS_FILE`: Путь к файлу `hosts`, где также может быть указано доменное имя.
### Функции и их назначения
#### `get_current_hostname()`
- **Описание:** Читает текущее доменное имя из файла `/etc/hostname`.
- **Возвращаемое значение:** Возвращает текущее доменное имя или `"localhost"` в случае ошибки.
#### `change_hostname()`
- **Описание:** Отображает диалоговые окна для ввода нового доменного имени. Проверяет, совпадает ли новое имя с текущим, и если нет, проверяет его валидность. Запрашивает подтверждение изменения.
- **Возвращаемое значение:** Возвращает новое доменное имя, если изменения подтверждены, или `None`, если изменения отменены или имя недопустимо.
#### `is_valid_hostname(hostname)`
- **Описание:** Проверяет, соответствует ли введённое доменное имя требованиям.
- **Параметры:**
- `hostname`: Проверяемое доменное имя.
- **Возвращаемое значение:** Возвращает `True`, если имя допустимо, и `False` в противном случае.
#### `apply_hostname_change(new_hostname)`
- **Описание:** Применяет изменение доменного имени, обновляя файлы `/etc/hostname` и `/etc/hosts`.
- **Параметры:**
- `new_hostname`: Новое доменное имя.
- **Возвращаемое значение:** Возвращает `True`, если изменения применены успешно, и `False` в случае ошибки.
#### `run_change_hostname()`
- **Описание:** Вызывает функцию `change_hostname` и возвращает результат её выполнения.
- **Возвращаемое значение:** Возвращает результат выполнения `change_hostname`.
### Основной блок выполнения
- При запуске скрипта напрямую вызывается функция `run_change_hostname()`, которая запускает процесс изменения доменного имени.
- Если новое доменное имя получено и изменения подтверждены, оно будет выведено на экран. В противном случае будет выведено сообщение об отмене изменения.
### Логирование и ошибки
- Ошибки при чтении файлов или выполнении команд оболочки обрабатываются и выводятся пользователю через диалоговые окна.
- Успешное изменение доменного имени или отмена изменений также сообщаются пользователю через диалоговые окна.
## option/network.py
Скрипт `network.py` предназначен для настройки сетевых интерфейсов в системе. Скрипт позволяет пользователю выбирать сетевой интерфейс и конфигурировать его для работы с DHCP, статическим IP или CIDR. После настройки, скрипт применяет изменения и обновляет конфигурационные файлы.
### Импортируемые модули
- `subprocess`: Для выполнения команд оболочки.
- `ipaddress`: Для работы с IP-адресами и сетями.
- `Dialog`: Для создания текстовых диалогов.
### Класс `NetworkConfig`
#### Метод `__init__(self)`
- **Описание:** Инициализирует объект `NetworkConfig`. Создает объект `Dialog` и пустой словарь для хранения временных сетевых настроек.
#### Метод `select_interface(self)`
- **Описание:**
1. Получает список доступных сетевых интерфейсов.
2. Позволяет пользователю выбрать интерфейс из списка.
3. Показывает текущие настройки выбранного интерфейса.
- **Возвращаемое значение:** Имя выбранного интерфейса или `None`, если интерфейс не выбран.
#### Метод `get_network_interfaces()`
- **Описание:** Получает список доступных сетевых интерфейсов.
- **Возвращаемое значение:** Список имен интерфейсов или пустой список в случае ошибки.
#### Метод `show_current_settings(self, interface)`
- **Описание:**
1. Получает текущие настройки для указанного интерфейса.
2. Показывает информацию о типе настройки (DHCP или Static) и текущем IP-адресе.
- **Возвращаемое значение:** Нет.
#### Метод `configure_dhcp(self, interface)`
- **Описание:**
1. Позволяет пользователю ввести настройки для DHCP (опционально DNS).
2. Сохраняет настройки в временный словарь.
- **Возвращаемое значение:** Нет.
#### Метод `configure_static(self, interface)`
- **Описание:**
1. Позволяет пользователю ввести настройки для статического IP (IP-адрес, маска подсети, шлюз и опционально DNS).
2. Сохраняет настройки в временный словарь.
- **Возвращаемое значение:** Нет.
#### Метод `configure_cidr(self, interface)`
- **Описание:**
1. Позволяет пользователю ввести CIDR, шлюз и опционально DNS.
2. Распознает IP-адрес и маску из CIDR и сохраняет настройки в временный словарь.
- **Возвращаемое значение:** Нет.
#### Метод `run(self)`
- **Описание:**
1. Позволяет пользователю выбрать интерфейс и действия для его настройки.
2. Запускает соответствующие методы для настройки (DHCP, статический IP, CIDR).
3. Возвращает словарь временных сетевых настроек.
- **Возвращаемое значение:** Словарь временных сетевых настроек.
#### Метод `save_and_apply_network_settings(self)`
- **Описание:**
1. Сохраняет и применяет временные сетевые настройки.
2. Обновляет файл конфигурации интерфейсов и файл DNS.
3. Перезапускает сетевую службу.
- **Возвращаемое значение:** `True` при успешном применении настроек и `False` в случае ошибки.
#### Метод `save_dhcp(self, interface, settings)`
- **Описание:** Сохраняет настройки DHCP для указанного интерфейса в конфигурационный файл.
- **Возвращаемое значение:** Нет.
#### Метод `save_static(self, interface, settings)`
- **Описание:** Сохраняет статические настройки IP для указанного интерфейса в конфигурационный файл.
- **Возвращаемое значение:** Нет.
#### Метод `update_interface_config(self, interface, interface_config)`
- **Описание:** Обновляет конфигурационный файл `/etc/network/interfaces` с учетом новых настроек интерфейса.
- **Возвращаемое значение:** Нет.
#### Метод `update_resolv_conf(self, dns)`
- **Описание:** Обновляет файл `/etc/resolv.conf` с новым DNS-сервером.
- **Возвращаемое значение:** Нет.
### Основной блок выполнения
- При запуске скрипта напрямую создается объект `NetworkConfig` и вызывается метод `run()`, который запускает процесс настройки сетевых интерфейсов.
### Примечания
- Скрипт требует прав суперпользователя для внесения изменений в конфигурационные файлы и перезапуска сетевой службы.
- Для корректной работы необходимо наличие утилиты `dialog` и доступа к командам `ip` и `systemctl`.
- При использовании CIDR, маска подсети автоматически рассчитывается на основе IP-адреса и CIDR.
## option/shell.py
Скрипт `shell.py` предназначен для изменения командной оболочки для пользователей системы. Скрипт позволяет выбирать между установкой `zsh` (или другой оболочки) и изменением оболочки для всех пользователей системы или для конкретных пользователей.
### Импортируемые модули
- `subprocess`: Для выполнения команд оболочки.
- `Dialog`: Для создания текстовых диалогов.
- `pwd`: Для получения информации о пользователях.
- `os`: Для проверки существования файлов и путей.
- `logger` из `postinstall.logger`: Для ведения логов.
### Функции
#### Функция `get_users()`
- **Описание:** Получает список пользователей системы с UID >= 1000 и добавляет "root" в список, если его нет.
- **Возвращаемое значение:** Список имен пользователей.
#### Функция `install_zsh()`
- **Описание:**
1. Обновляет список пакетов.
2. Устанавливает `zsh`.
- **Возвращаемое значение:** `True` при успешной установке и `False` в случае ошибки.
#### Функция `change_shell()`
- **Описание:** Основная функция для изменения оболочки.
1. Создает объект `Dialog`.
2. Получает список пользователей с помощью `get_users()`.
3. Позволяет пользователю выбрать способ изменения оболочки (для всех пользователей или для конкретных).
4. Позволяет выбрать новую оболочку (bash или zsh).
5. Если выбран `zsh` и он не установлен, вызывает `install_zsh()` для его установки.
6. Применяет изменения: изменяет оболочку для всех или выбранных пользователей с помощью команды `chsh`.
- **Возвращаемое значение:** Нет.
#### Функция `run_change_shell()`
- **Описание:** Запускает функцию `change_shell()`.
- **Возвращаемое значение:** Нет.
### Основной блок выполнения
- При запуске скрипта напрямую вызывается функция `run_change_shell()`, которая запускает процесс изменения оболочки.
### Примечания
- Установка `zsh` происходит только если выбранная оболочка `zsh` не установлена на системе.
- Логи об ошибках и успешных действиях сохраняются с помощью объекта `logger`.
## option/ssh.py
Скрипт `ssh.py` предназначен для управления конфигурацией SSH-сервиса на системе. Он позволяет:
1. Управлять состоянием службы SSH (запуск, остановка).
2. Изменять порт SSH.
3. Изменять метод аутентификации SSH.
### Константы
- `SSH_CONFIG_PATH`: Путь к конфигурационному файлу SSH (`/etc/ssh/sshd_config`).
- `SSH_AUTH_CONFIG_PATH`: Путь к файлу конфигурации аутентификации SSH (`/etc/ssh/sshd_config.d/auth.conf`).
- `UFW_OPENSSH_CONFIG_PATH`: Путь к файлу конфигурации UFW для OpenSSH (`/etc/ufw/applications.d/openssh-server`).
### Класс `SSHConfig`
#### Методы
##### `__init__(self)`
- **Описание:** Инициализация класса. Создает объект `Dialog` и получает текущие настройки порта и метода аутентификации SSH.
- **Возвращаемое значение:** Нет.
##### `get_sshd_status(self)`
- **Описание:** Получает статус службы SSH.
- **Возвращаемое значение:** Строка, представляющая статус службы (`active`, `inactive`, или `unknown`).
##### `toggle_sshd_service(self, action)`
- **Описание:** Запускает или останавливает службу SSH в зависимости от переданного действия (`start` или `stop`).
- **Возвращаемое значение:** Нет.
##### `get_current_ssh_port(self)`
- **Описание:** Получает текущий порт SSH из конфигурационного файла.
- **Возвращаемое значение:** Текущий порт SSH (или "22", если порт не найден).
##### `change_ssh_port(self)`
- **Описание:** Позволяет пользователю ввести новый порт SSH и подтверждает изменение.
- **Возвращаемое значение:** Нет.
##### `get_current_auth_method(self)`
- **Описание:** Получает текущий метод аутентификации SSH из конфигурационного файла.
- **Возвращаемое значение:** Строка, представляющая метод аутентификации (`"По ключу и паролю"`, `"Только по ключу"`, или `"Только по паролю"`).
##### `change_auth_method(self)`
- **Описание:** Позволяет пользователю выбрать метод аутентификации SSH.
- **Возвращаемое значение:** Нет.
##### `apply_changes(self)`
- **Описание:** Применяет изменения порта и/или метода аутентификации, если они были сделаны.
- **Возвращаемое значение:** Нет.
##### `main_menu(self)`
- **Описание:** Основное меню, которое позволяет пользователю выбрать действие: включение/выключение службы SSH, изменение порта SSH, изменение метода аутентификации.
- **Возвращаемое значение:** `True`, если были внесены изменения, иначе `False`.
### Функция `run_ssh_config()`
- **Описание:** Создает экземпляр `SSHConfig`, запускает основное меню и возвращает объект конфигурации и флаг, указывающий на наличие изменений.
- **Возвращаемое значение:** Кортеж `(SSHConfig, changes_made)`.
### Основной блок выполнения
- При запуске скрипта напрямую вызывается функция `run_ssh_config()`. Она запускает основной процесс управления конфигурацией SSH и применяет изменения, если они были внесены.
### Примечания
- Используются команды `sed` и `ufw` для обновления конфигураций, а также перезапуск службы SSH для применения изменений.
- Логи об ошибках и успешных действиях сохраняются с помощью модуля `logging`.
## option/update.py
Скрипт `update.py` предназначен для обновления системы. Он выполняет обновление списка пакетов и обновление установленных пакетов до последних доступных версий.
### Функции
#### `run_update()`
- **Описание:** Выполняет обновление системы. Запрашивает подтверждение у пользователя, выполняет команды обновления через `apt`, и отображает процесс обновления с помощью индикатора `gauge` библиотеки `dialog`.
- **Шаги выполнения:**
1. **Запрос подтверждения:** Появляется диалоговое окно с запросом на подтверждение обновления системы. Если пользователь не подтверждает, функция завершает выполнение.
2. **Инициализация индикатора прогресса:** Запускается индикатор прогресса с начальным значением 0%.
3. **Выполнение команд обновления:**
- Выполняются команды `apt update` и `apt upgrade -y` с обновлением индикатора прогресса в зависимости от выполнения команд.
- Вывод команд отображается в диалоговом окне.
- Если команда завершается с ошибкой, возникает исключение `subprocess.CalledProcessError`, и выводится сообщение об ошибке.
4. **Обработка ошибок:**
- Если происходит ошибка при выполнении команды, логируется ошибка, и отображается сообщение об ошибке.
- Если возникает неожиданная ошибка, также логируется и отображается соответствующее сообщение.
5. **Завершение обновления:** Обновление системы завершено, отображается сообщение об успешном завершении.
### Основной блок выполнения
- При запуске скрипта напрямую вызывается функция `run_update()`.
## option/database.py
Скрипт `database.py` предназначен для установки и настройки баз данных PostgreSQL и MariaDB, а также для установки Webmin и необходимых дополнительных пакетов.
### Основные функции
1. **Выбор базы данных для установки:**
- Пользователь может выбрать установку PostgreSQL или MariaDB через диалоговое окно.
2. **Установка PostgreSQL:**
- Проверка и установка PostgreSQL и сопутствующих пакетов, включая `python3-harlequin` и `python3-harlequin-postgres`.
3. **Установка MariaDB:**
- Проверка и установка MariaDB и `python3-harlequin`.
4. **Установка Webmin:**
- Проверка и установка Webmin, разрешение порта 10000/tcp в ufw, установка модулей DBI и DBD::Pg через `cpanminus`, и перезагрузка Webmin.
### Основные функции и методы
#### `main()`
Основная функция, которая запускает диалоговый интерфейс для выбора базы данных и выполнения соответствующих установок.
#### `is_installed(package_name: str) -> bool`
Проверяет, установлен ли указанный пакет.
**Параметры:**
- `package_name`: Название пакета для проверки.
**Возвращает:**
- `True`, если пакет установлен, иначе `False`.
#### `run_command_with_log(dialog: Dialog, command: list[str], title: str) -> bool`
Запускает указанную команду и отображает лог выполнения в диалоговом окне.
**Параметры:**
- `dialog`: Экземпляр диалогового окна для отображения логов.
- `command`: Список команд и параметров для выполнения.
- `title`: Заголовок диалогового окна.
**Возвращает:**
- `True`, если команда выполнена успешно, иначе `False`.
#### `install_package(dialog: Dialog, package_name: str)`
Устанавливает указанный пакет и отображает статус установки в диалоговом окне.
**Параметры:**
- `dialog`: Экземпляр диалогового окна.
- `package_name`: Название пакета для установки.
#### `install_postgresql(dialog: Dialog)`
Устанавливает PostgreSQL и сопутствующие пакеты.
**Параметры:**
- `dialog`: Экземпляр диалогового окна.
#### `install_mariadb(dialog: Dialog)`
Устанавливает MariaDB и `python3-harlequin`.
**Параметры:**
- `dialog`: Экземпляр диалогового окна.
#### `install_webmin(dialog: Dialog)`
Устанавливает Webmin и выполняет дополнительные настройки, такие как разрешение порта в ufw, установка модулей через `cpanminus`, и перезагрузка Webmin.
**Параметры:**
- `dialog`: Экземпляр диалогового окна.