Инициализация проекта

Всем привет :)
This commit is contained in:
2025-10-16 16:27:36 +07:00
commit 0e93af1d8c
23 changed files with 4058 additions and 0 deletions

View File

@@ -0,0 +1,121 @@
package database
import (
"fmt"
"log"
"os"
"os/exec"
"strconv"
"strings"
"syscall"
)
const pidFile = "/opt/wg_serf/wg_serf.pid"
// CheckAndKillOldProcess проверяет и завершает старый процесс
func CheckAndKillOldProcess() error {
// Проверяем существует ли PID файл
if _, err := os.Stat(pidFile); os.IsNotExist(err) {
// Файла нет - это первый запуск
return nil
}
// Читаем PID из файла
data, err := os.ReadFile(pidFile)
if err != nil {
log.Println("⚠️ Не удалось прочитать PID файл:", err)
return nil
}
oldPID, err := strconv.Atoi(strings.TrimSpace(string(data)))
if err != nil {
log.Println("⚠️ Некорректный PID в файле:", err)
os.Remove(pidFile)
return nil
}
// Проверяем существует ли процесс
if !processExists(oldPID) {
log.Println("📝 Старый процесс не найден, очищаю PID файл")
os.Remove(pidFile)
return nil
}
// Проверяем что это действительно wg-panel
if !isWGPanelProcess(oldPID) {
log.Println("⚠️ PID принадлежит другому процессу, очищаю файл")
os.Remove(pidFile)
return nil
}
// Завершаем старый процесс
log.Printf("🔄 Обнаружена запущенная версия (PID: %d), завершаю...", oldPID)
if err := killProcess(oldPID); err != nil {
return fmt.Errorf("не удалось завершить старый процесс: %v", err)
}
log.Println("✅ Старый процесс завершен")
os.Remove(pidFile)
return nil
}
// WritePIDFile записывает PID текущего процесса в файл
func WritePIDFile() error {
pid := os.Getpid()
return os.WriteFile(pidFile, []byte(fmt.Sprintf("%d", pid)), 0644)
}
// RemovePIDFile удаляет PID файл
func RemovePIDFile() {
os.Remove(pidFile)
}
// processExists проверяет существует ли процесс с данным PID
func processExists(pid int) bool {
process, err := os.FindProcess(pid)
if err != nil {
return false
}
// Отправляем сигнал 0 для проверки существования процесса
err = process.Signal(syscall.Signal(0))
return err == nil
}
// isWGPanelProcess проверяет что процесс действительно wg-panel
func isWGPanelProcess(pid int) bool {
// Читаем командную строку процесса
cmdline, err := os.ReadFile(fmt.Sprintf("/proc/%d/cmdline", pid))
if err != nil {
return false
}
// Проверяем что в командной строке есть wg-panel
return strings.Contains(string(cmdline), "wg-panel")
}
// killProcess завершает процесс
func killProcess(pid int) error {
process, err := os.FindProcess(pid)
if err != nil {
return err
}
// Сначала пробуем мягко (SIGTERM)
if err := process.Signal(syscall.SIGTERM); err != nil {
return err
}
// Ждем немного
cmd := exec.Command("sleep", "1")
cmd.Run()
// Проверяем завершился ли процесс
if processExists(pid) {
// Если нет - убиваем принудительно (SIGKILL)
log.Println("⚠️ Процесс не завершился, использую SIGKILL")
return process.Signal(syscall.SIGKILL)
}
return nil
}