Change 0 containers

This commit is contained in:
Magnus Root 2026-03-16 17:43:14 +03:00
parent 7cbc9b181c
commit 417f005e04
4 changed files with 62 additions and 21 deletions

View file

@ -212,22 +212,28 @@ func getContainerDrainInfo(containerName string) (timestamp int64, isMigration b
return ts, migration, true
}
func markAngieConfigForDrain(clientTitle string) error {
func markAngieConfigForDrain(clientTitle string, isMigration bool) error {
markerFile := fmt.Sprintf("/tmp/ptaf-angie-drain-%s", clientTitle)
return os.WriteFile(markerFile, []byte(fmt.Sprintf("%d", time.Now().Unix())), 0644)
content := fmt.Sprintf("%d", time.Now().Unix())
if isMigration {
content += ":migration"
}
return os.WriteFile(markerFile, []byte(content), 0644)
}
func getAngieConfigDrainTimestamp(clientTitle string) (int64, bool) {
func getAngieConfigDrainInfo(clientTitle string) (timestamp int64, isMigration bool, found bool) {
markerFile := fmt.Sprintf("/tmp/ptaf-angie-drain-%s", clientTitle)
data, err := os.ReadFile(markerFile)
if err != nil {
return 0, false
return 0, false, false
}
timestamp, err := strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64)
parts := strings.SplitN(strings.TrimSpace(string(data)), ":", 2)
ts, err := strconv.ParseInt(parts[0], 10, 64)
if err != nil {
return 0, false
return 0, false, false
}
return timestamp, true
migration := len(parts) == 2 && parts[1] == "migration"
return ts, migration, true
}
func stopAndRemoveContainer(containerName, composeFile, containerDir string) error {
@ -635,6 +641,10 @@ func generateDockerCompose(filePath string, config Config, clientTitle string, c
{{- end}}
sysctls:
kernel.sem: "32000 1024000000 500 32000"
ulimits:
nofile:
soft: 1048576
hard: 1048576
ports:
{{- range .SortedHTTPPorts}}
- 127.0.0.1:{{.DockerPort}}:{{.CustomPort}}/tcp

View file

@ -43,7 +43,6 @@ func getActualContainerCount(clientTitle string) int {
func processDrainingAngieConfigs() {
currentTime := time.Now().Unix()
timeout := int64(MigrationDrainTimeout)
hostname, err := os.Hostname()
if err != nil {
log.Printf("⚠ Ошибка получения hostname: %v", err)
@ -65,26 +64,40 @@ func processDrainingAngieConfigs() {
continue
}
clientTitle := strings.Join(parts[3:], "-")
drainTimestamp, found := getAngieConfigDrainTimestamp(clientTitle)
drainTimestamp, isMigration, found := getAngieConfigDrainInfo(clientTitle)
if !found {
continue
}
var timeout int64
timeoutName := "масштабирование"
if isMigration {
timeout = int64(MigrationDrainTimeout)
timeoutName = "миграция"
} else {
timeout = int64(ContainerDrainTimeout)
}
elapsedTime := currentTime - drainTimestamp
remainingTime := timeout - elapsedTime
angieConfigPath := fmt.Sprintf("/etc/angie/http.d/angie-ptaf-%s.conf", clientTitle)
if elapsedTime >= timeout {
log.Printf(" Конфиг Angie для %s завершил drain (прошло %d сек), проверяю актуальность...", clientTitle, elapsedTime)
clientInfo, err := getClientInfoByClientTitle(db, clientTitle)
if err == nil && clientInfo.WAFInstance != "" {
belongsNow, checkErr := checkHostBelongsToInstance(db, hostname, clientInfo.WAFInstance)
if checkErr == nil && belongsNow {
log.Printf(" ⚠ Клиент %s снова принадлежит этому хосту, ОТМЕНЯЮ удаление конфига", clientTitle)
os.Remove(markerFile)
continue
log.Printf(" Конфиг Angie для %s завершил drain [%s] (прошло %d сек), проверяю актуальность...", clientTitle, timeoutName, elapsedTime)
if isMigration {
clientInfo, err := getClientInfoByClientTitle(db, clientTitle)
if err == nil && clientInfo.WAFInstance != "" {
belongsNow, checkErr := checkHostBelongsToInstance(db, hostname, clientInfo.WAFInstance)
if checkErr == nil && belongsNow {
log.Printf(" ⚠ Клиент %s снова принадлежит этому хосту, ОТМЕНЯЮ удаление конфига", clientTitle)
os.Remove(markerFile)
continue
}
}
log.Printf(" → Клиент %s не принадлежит этому хосту, удаляю конфиг", clientTitle)
} else {
log.Printf(" → Удаляю конфиг Angie для %s", clientTitle)
}
log.Printf(" → Клиент %s не принадлежит этому хосту, удаляю конфиг", clientTitle)
if _, err := os.Stat(angieConfigPath); err == nil {
if err := os.Remove(angieConfigPath); err != nil {
log.Printf(" ⚠ Ошибка удаления конфига Angie: %v", err)
@ -98,7 +111,7 @@ func processDrainingAngieConfigs() {
os.Remove(markerFile)
}
} else {
log.Printf(" ○ Конфиг Angie для %s в процессе drain [миграция] (осталось %d сек)", clientTitle, remainingTime)
log.Printf(" ○ Конфиг Angie для %s в процессе drain [%s] (осталось %d сек)", clientTitle, timeoutName, remainingTime)
}
}
}
@ -169,7 +182,7 @@ func processAllDrainingContainersGlobally(db *sql.DB, hostname string) {
}
angieConfigPath := fmt.Sprintf("/etc/angie/http.d/angie-ptaf-%s.conf", clientTitle)
if _, err := os.Stat(angieConfigPath); err == nil {
if err := markAngieConfigForDrain(clientTitle); err != nil {
if err := markAngieConfigForDrain(clientTitle, true); err != nil {
log.Printf(" ⚠ Ошибка пометки Angie конфига: %v", err)
} else {
log.Printf(" ✓ Angie конфиг помечен для удаления")

View file

@ -303,7 +303,7 @@ func handleClientMigration(clientInfo ClientInfo, hostname string) {
angieConfigPath := fmt.Sprintf("/etc/angie/http.d/angie-ptaf-%s.conf", clientInfo.ClientTitle)
if _, err := os.Stat(angieConfigPath); err == nil {
log.Printf(" → Помечаю конфиг Angie для удаления (миграция, таймаут %d сек)", MigrationDrainTimeout)
if err := markAngieConfigForDrain(clientInfo.ClientTitle); err != nil {
if err := markAngieConfigForDrain(clientInfo.ClientTitle, true); err != nil {
log.Printf(" ⚠ Ошибка пометки конфига: %v", err)
} else {
log.Printf(" ✓ Конфиг Angie помечен для удаления")

View file

@ -5,6 +5,7 @@ import (
"fmt"
"log"
"net"
"os"
"strings"
"time"
)
@ -53,6 +54,23 @@ func processPTAFClient(
log.Printf("✓ Клиент %s принадлежит instance '%s', обрабатываю", clientInfo.ClientTitle, clientInfo.WAFInstance)
}
// Если контейнеров 0 — помечаем все существующие для drain и выходим
if clientInfo.ContainersCount == 0 {
log.Printf("⚠ Количество контейнеров равно 0 для %s — помечаю существующие контейнеры для drain", clientInfo.ClientTitle)
processDrainingContainers(clientInfo.ClientTitle, 0)
angieConfigPath := fmt.Sprintf("/etc/angie/http.d/angie-ptaf-%s.conf", clientInfo.ClientTitle)
if _, err := os.Stat(angieConfigPath); err == nil {
log.Printf(" → Помечаю конфиг Angie для удаления (контейнеров 0)")
if err := markAngieConfigForDrain(clientInfo.ClientTitle, false); err != nil {
log.Printf(" ⚠ Ошибка пометки конфига Angie: %v", err)
} else {
log.Printf(" ✓ Конфиг Angie помечен для удаления")
}
}
return false
}
// Автоочистка устаревших маркеров drain
cleanStaleDrainMarkers(clientInfo)