Change docker restart
This commit is contained in:
parent
38ab8369cb
commit
853ada564b
1 changed files with 38 additions and 41 deletions
|
|
@ -14,28 +14,51 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// isAngieEstabOnPort проверяет есть ли активные ESTAB соединения Angie на данном порту
|
||||
func isAngieEstabOnPort(port int) bool {
|
||||
// getBusyPortsFromList проверяет список портов одним вызовом ss и возвращает занятые
|
||||
func getBusyPortsFromList(ports []int) []int {
|
||||
cmd := exec.Command("ss", "-tnap")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return false
|
||||
return nil
|
||||
}
|
||||
portStr := fmt.Sprintf(":%d", port)
|
||||
|
||||
// Строим set портов для быстрого поиска
|
||||
portSet := make(map[int]bool, len(ports))
|
||||
for _, p := range ports {
|
||||
portSet[p] = true
|
||||
}
|
||||
|
||||
busy := make(map[int]bool)
|
||||
for _, line := range strings.Split(string(output), "\n") {
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) < 4 {
|
||||
continue
|
||||
}
|
||||
if fields[0] != "ESTAB" {
|
||||
localAddr := fields[3]
|
||||
lastColon := strings.LastIndex(localAddr, ":")
|
||||
if lastColon < 0 {
|
||||
continue
|
||||
}
|
||||
localAddr := fields[3]
|
||||
if strings.HasSuffix(localAddr, portStr) && strings.Contains(line, "angie") {
|
||||
return true
|
||||
var port int
|
||||
if _, err := fmt.Sscanf(localAddr[lastColon+1:], "%d", &port); err != nil {
|
||||
continue
|
||||
}
|
||||
if !portSet[port] {
|
||||
continue
|
||||
}
|
||||
state := fields[0]
|
||||
if state == "LISTEN" {
|
||||
busy[port] = true
|
||||
} else if state == "ESTAB" && strings.Contains(line, "docker-proxy") {
|
||||
busy[port] = true
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
||||
result := make([]int, 0, len(busy))
|
||||
for p := range busy {
|
||||
result = append(result, p)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// isPortBusyByAnyProcess проверяет занят ли порт процессом который мешает биндингу.
|
||||
|
|
@ -115,50 +138,24 @@ func recreateContainer(containerFullName, composeFile, containerDir, clientTitle
|
|||
}
|
||||
}
|
||||
|
||||
// Reload Angie после остановки контейнера чтобы закрыть keepalive ESTAB соединения
|
||||
// Reload Angie после остановки контейнера чтобы закрыть keepalive соединения
|
||||
log.Printf(" → Reload Angie для закрытия keepalive соединений к остановленному контейнеру...")
|
||||
reloadAngie()
|
||||
|
||||
// Ждём пока Angie закроет ESTAB соединения к портам старого контейнера
|
||||
log.Printf(" → Ожидаем закрытия ESTAB соединений Angie на портах %v...", portsToFree)
|
||||
for attempt := 0; attempt < 30; attempt++ {
|
||||
angieEstab := false
|
||||
for _, port := range portsToFree {
|
||||
if isAngieEstabOnPort(port) {
|
||||
angieEstab = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !angieEstab {
|
||||
log.Printf(" ✓ Все ESTAB соединения Angie закрыты (попытка %d)", attempt+1)
|
||||
break
|
||||
}
|
||||
if attempt%5 == 0 && attempt > 0 {
|
||||
log.Printf(" → Angie ещё держит соединения (попытка %d/30)...", attempt+1)
|
||||
}
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
if len(portsToFree) > 0 {
|
||||
log.Printf(" → Ожидаем освобождения %d портов...", len(portsToFree))
|
||||
allPortsFree := false
|
||||
for attempt := 0; attempt < 180; attempt++ {
|
||||
portsBusy := 0
|
||||
busyPortsList := make([]int, 0)
|
||||
for _, port := range portsToFree {
|
||||
if isPortBusyByAnyProcess(port) {
|
||||
portsBusy++
|
||||
busyPortsList = append(busyPortsList, port)
|
||||
}
|
||||
}
|
||||
if portsBusy == 0 {
|
||||
// Один вызов ss для всех портов сразу
|
||||
busyPortsList := getBusyPortsFromList(portsToFree)
|
||||
if len(busyPortsList) == 0 {
|
||||
allPortsFree = true
|
||||
log.Printf(" ✓ Все порты освобождены (попытка %d)", attempt+1)
|
||||
break
|
||||
}
|
||||
if attempt%5 == 0 && attempt > 0 {
|
||||
log.Printf(" → Ещё заняты %d портов: %v (попытка %d/180)", portsBusy, busyPortsList, attempt+1)
|
||||
if attempt%10 == 0 {
|
||||
log.Printf(" → Ещё заняты %d портов: %v (попытка %d/180)", len(busyPortsList), busyPortsList, attempt+1)
|
||||
}
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue