This commit is contained in:
Mikan
2025-11-21 15:52:02 +03:00
parent 013df5dcad
commit 3acf2c35fc
6 changed files with 305 additions and 0 deletions

View File

@@ -0,0 +1,113 @@
# cert_renew_restart.py
def generate_mkcert_command():
"""Генерирует команду для mkcert с указанием всех доменов"""
services = read_services_config()
domains = [f"{service['name']}.local" for service in services['services']]
domains.append("*.local")
# Создаем PowerShell команду
domains_str = " ".join([f'"{domain}"' for domain in domains])
powershell_cmd = f'mkcert {domains_str}'
return powershell_cmd
def copy_and_rename_certificates():
"""Копирует и переименовывает сертификаты из Windows в WSL"""
# Определяем пути
windows_certs_path = Path("C:/store/certs")
wsl_certs_path = Path.home() / "projects" / "docker" / "network" / "certs"
# Создаем директорию для сертификатов в WSL
wsl_certs_path.mkdir(parents=True, exist_ok=True)
# Находим сгенерированные mkcert файлы
cert_files = list(windows_certs_path.glob("_wildcard.local+*.pem"))
if not cert_files:
print("Сертификаты не найдены в C:/store/certs")
return False
# Предполагаем, что mkcert генерирует файлы в формате _wildcard.domain+N.pem
cert_file = cert_files[0]
key_file = cert_files[0].with_name(cert_file.name.replace(".pem", "-key.pem"))
if not key_file.exists():
print(f"Файл ключа не найден: {key_file}")
return False
# Копируем и переименовываем
target_cert = wsl_certs_path / "wildcard.local.pem"
target_key = wsl_certs_path / "wildcard.local.key"
shutil.copy2(cert_file, target_cert)
shutil.copy2(key_file, target_key)
# Создаем копии для default
default_cert = wsl_certs_path / "default.crt"
default_key = wsl_certs_path / "default.key"
shutil.copy2(target_cert, default_cert)
shutil.copy2(target_key, default_key)
print(f"Сертификаты скопированы в {wsl_certs_path}")
return True
def run_docker_command(cmd):
"""Выполняет команду Docker и возвращает результат"""
try:
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
if result.returncode != 0:
print(f"Ошибка выполнения команды: {cmd}")
print(f"Ошибка: {result.stderr}")
return False
return True
except Exception as e:
print(f"Ошибка выполнения команды: {e}")
return False
def main():
print("Обновление сертификатов и перезапуск сервисов...")
# Получаем имя директории проекта (предполагаем, что это "network")
project_name = "network"
# Генерируем конфигурационный файл dnsmasq
generate_dnsmasq_config()
# Выводим команду для генерации сертификатов
mkcert_cmd = generate_mkcert_command()
print("\nДля генерации сертификатов выполните в PowerShell (от администратора):")
print(f"cd C:\\store\\certs")
print(mkcert_cmd)
print()
# Ждем подтверждения пользователя
input("Нажмите Enter после генерации сертификатов в PowerShell...")
# Копируем сертификаты
if not copy_and_rename_certificates():
print("Не удалось скопировать сертификаты")
sys.exit(1)
# Переходим в директорию проекта
project_path = Path.home() / "projects" / "docker" / project_name
if not project_path.exists():
print(f"Директория проекта не найдена: {project_path}")
sys.exit(1)
os.chdir(project_path)
# Перезапускаем nginx-proxy для загрузки новых сертификатов
print("Перезапуск nginx-proxy...")
if not run_docker_command("docker-compose restart nginx-proxy"):
print("Не удалось перезапустить nginx-proxy")
# Если restart не сработал, пробуем поднять контейнеры
if not run_docker_command("docker-compose up -d"):
print("Не удалось поднять контейнеры")
sys.exit(1)
print("Сертификаты обновлены и сервисы перезапущены!")
if __name__ == "__main__":
main()

112
scripts/common.py Normal file
View File

@@ -0,0 +1,112 @@
# common.py
import subprocess
import sys
import os
import platform
import json
from pathlib import Path
def get_host_ip():
"""Получает IP-адрес хоста в локальной сети"""
try:
# Для WSL2 получаем IP хоста (Windows)
if 'microsoft' in platform.uname().release.lower():
# В WSL2 получаем IP хоста из файла resolv.conf
with open('/etc/resolv.conf', 'r') as f:
for line in f:
if line.startswith('nameserver'):
return line.split()[1]
# Для других систем используем подключение к внешнему серверу
else:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
ip = s.getsockname()[0]
s.close()
return ip
except Exception as e:
print(f"Не удалось получить IP-адрес хоста: {e}")
# Возвращаем IP по умолчанию, если не удалось получить
return "192.168.31.60"
def read_services_config():
"""Читает конфигурацию сервисов из файла"""
config_path = Path.home() / "projects" / "docker" / "network" / "services.json"
default_config = {
"services": [
{"name": "gitea", "port": 3000},
{"name": "youtrack", "port": 8080},
{"name": "n8n", "port": 5678}
]
}
if config_path.exists():
with open(config_path, 'r', encoding='utf-8') as f:
return json.load(f)
else:
# Создаем файл конфигурации по умолчанию
config_path.parent.mkdir(parents=True, exist_ok=True)
with open(config_path, 'w', encoding='utf-8') as f:
json.dump(default_config, f, indent=2, ensure_ascii=False)
return default_config
def generate_dnsmasq_config():
"""Генерирует конфигурационный файл dnsmasq"""
host_ip = get_host_ip()
services = read_services_config()
config_content = f"""# Локальные домены → твой ПК
"""
for service in services['services']:
config_content += f"address=/{service['name']}.local/{host_ip}\n"
config_content += f"""address=/.local/{host_ip}
# Кэш DNS
cache-size=500
# Лог (опционально)
log-queries
log-facility=/var/log/dnsmasq.log
# Не перехватывать внешние запросы — делегируем
no-resolv
server=8.8.8.8
server=1.1.1.1
"""
# Путь к конфигурационному файлу
config_path = Path.home() / "projects" / "docker" / "network" / "dnsmasq.conf"
config_path.parent.mkdir(parents=True, exist_ok=True)
with open(config_path, 'w', encoding='utf-8') as f:
f.write(config_content.strip())
print(f"Конфигурационный файл dnsmasq обновлен: {config_path}")
def run_docker_command(cmd):
"""Выполняет команду Docker и возвращает результат"""
try:
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
if result.returncode != 0:
print(f"Ошибка выполнения команды: {cmd}")
print(f"Ошибка: {result.stderr}")
return False
return True
except Exception as e:
print(f"Ошибка выполнения команды: {e}")
return False
def setup_project():
"""Настройка проекта: генерация конфигов и переход в директорию"""
# Генерируем конфигурационный файл dnsmasq
generate_dnsmasq_config()
# Переходим в директорию проекта
project_path = Path.home() / "projects" / "docker" / "network"
if not project_path.exists():
print(f"Директория проекта не найдена: {project_path}")
sys.exit(1)
os.chdir(project_path)
return project_path

View File

@@ -0,0 +1,22 @@
# restart_services.py
from common import *
def main():
print("Перезапуск сервисов...")
# Настройка проекта
setup_project()
# Перезапускаем контейнеры
print("Перезапуск контейнеров...")
if not run_docker_command("docker-compose restart"):
print("Не удалось перезапустить контейнеры")
# Если restart не сработал, пробуем поднять контейнеры
if not run_docker_command("docker-compose up -d"):
print("Не удалось поднять контейнеры")
sys.exit(1)
print("Сервисы перезапущены!")
if __name__ == "__main__":
main()