From 38ab8369cb26b758dadf3d1916e1b27bbaf94745 Mon Sep 17 00:00:00 2001 From: Magnus Root Date: Tue, 5 May 2026 13:08:22 +0300 Subject: [PATCH] Remove check ports for new containers --- containers_part1.go | 46 ++------------------------------------------- main.go | 30 ++++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 47 deletions(-) diff --git a/containers_part1.go b/containers_part1.go index 82870fe..82656b5 100644 --- a/containers_part1.go +++ b/containers_part1.go @@ -194,6 +194,7 @@ func setupContainers(config Config, clientTitle string, clientInfo *ClientInfo, if containerExists { if composeChanges[containerNum] { + updateLockStatus(fmt.Sprintf("recreating container: %s", containerFullName)) success := recreateContainer(containerFullName, composeFile, containerDir, clientTitle, resources, resourcePortMap, containerNum) if success { if err := saveContainerPorts(containerDir, containerNum, resources, containerPorts); err != nil { @@ -263,50 +264,7 @@ func setupContainers(config Config, clientTitle string, clientInfo *ClientInfo, } } else { log.Printf(" Запуск нового контейнера %s", containerName) - - // Собираем порты которые должен занять контейнер - portsToCheck := []int{} - for _, res := range resources { - ports, ok := resourcePortMap[res.L7ResourceID] - if !ok || containerNum-1 >= len(ports) { - continue - } - pm := ports[containerNum-1] - for _, dockerPort := range pm.HTTPPorts { - portsToCheck = append(portsToCheck, dockerPort) - } - for _, dockerPort := range pm.HTTPSPorts { - portsToCheck = append(portsToCheck, dockerPort) - } - } - - // Ждём освобождения портов перед запуском - if len(portsToCheck) > 0 { - portsReady := false - for attempt := 0; attempt < 30; attempt++ { - busy := false - for _, port := range portsToCheck { - if isPortBusyByAnyProcess(port) { - if attempt == 0 { - log.Printf(" → Порт %d занят, ожидаем освобождения...", port) - } - busy = true - break - } - } - if !busy { - portsReady = true - if attempt > 0 { - log.Printf(" ✓ Порты освободились (попытка %d)", attempt+1) - } - break - } - time.Sleep(1 * time.Second) - } - if !portsReady { - log.Printf(" ⚠ Порты не освободились за 30 секунд, пробуем запустить всё равно") - } - } + updateLockStatus(fmt.Sprintf("starting container: %s", containerFullName)) const maxRetries = 3 started := false diff --git a/main.go b/main.go index ae8fdc3..fabf315 100644 --- a/main.go +++ b/main.go @@ -14,6 +14,18 @@ import ( "time" ) +var lockStatusFile *os.File + +// updateLockStatus обновляет статус в lock-файле для диагностики зависаний +func updateLockStatus(status string) { + if lockStatusFile == nil { + return + } + lockStatusFile.Seek(0, 0) + lockStatusFile.Truncate(0) + lockStatusFile.WriteString(fmt.Sprintf("%d\n%s\n", os.Getpid(), status)) +} + func main() { // ════════════════════════════════════════════════════════════ // Lock-файл для предотвращения параллельного запуска @@ -26,8 +38,9 @@ func main() { if os.IsExist(err) { data, readErr := os.ReadFile(lockFile) if readErr == nil { + lines := strings.SplitN(strings.TrimSpace(string(data)), "\n", 2) var existingPID int - if _, parseErr := fmt.Sscanf(strings.TrimSpace(string(data)), "%d", &existingPID); parseErr == nil && existingPID > 0 { + if _, parseErr := fmt.Sscanf(lines[0], "%d", &existingPID); parseErr == nil && existingPID > 0 { // Проверяем существует ли процесс if _, procErr := os.Stat(fmt.Sprintf("/proc/%d", existingPID)); os.IsNotExist(procErr) { log.Printf("⚠ Lock файл найден но процесс PID %d не существует — удаляем устаревший lock", existingPID) @@ -37,15 +50,22 @@ func main() { log.Fatal("❌ Не удалось создать lock файл после очистки: ", err) } } else { - // Процесс существует — проверяем возраст lock-файла + // Процесс существует — проверяем возраст и показываем статус + status := "unknown" + if len(lines) > 1 && lines[1] != "" { + status = lines[1] + } if info, statErr := os.Stat(lockFile); statErr == nil { age := time.Since(info.ModTime()) if age > maxLockAge { log.Printf("⚠ Программа уже запущена (PID %d) но работает более %.0f минут — возможно зависла", existingPID, age.Minutes()) + log.Printf(" Текущий статус: %s", status) log.Printf(" Если утилита зависла, выполните: kill %d && rm %s", existingPID, lockFile) + } else { + log.Printf(" Текущий статус: %s", status) } } - log.Fatalf("❌ Программа уже запущена! PID: %d, Lock файл: %s", existingPID, lockFile) + log.Fatalf("❌ Программа уже запущена! PID: %d, статус: %s, Lock файл: %s", existingPID, status, lockFile) } } else { log.Fatal("❌ Программа уже запущена! Lock файл существует: ", lockFile) @@ -60,14 +80,17 @@ func main() { pid := os.Getpid() f.WriteString(fmt.Sprintf("%d\n", pid)) + lockStatusFile = f defer func() { + lockStatusFile = nil f.Close() os.Remove(lockFile) log.Printf("✓ Lock файл удален") }() log.Printf("✓ Lock файл создан: %s (PID: %d)", lockFile, pid) + updateLockStatus("init") // ════════════════════════════════════════════════════════════ log.Println("=== Запуск программы управления конфигурациями PTAF ===") @@ -293,6 +316,7 @@ func processInstance(db *sql.DB, config Config, hostname, instanceName string, p // Роутер по waf_vendor: направляет клиента в PTAF или SW процессор. func processClient(db *sql.DB, config Config, hostname, instanceName string, clientInfo ClientInfo, portAllocator *PortAllocator) bool { log.Printf("\n--- Обработка клиента: %s (instance: %s) ---", clientInfo.ClientTitle, instanceName) + updateLockStatus(fmt.Sprintf("processing client: %s", clientInfo.ClientTitle)) appsSettingsList, err := getAppsSettingsByClientTitle(db, clientInfo.ClientTitle) if err != nil {