Speed matchchecker
This commit is contained in:
parent
a658bf8c05
commit
8a37c62e63
1 changed files with 89 additions and 20 deletions
109
matchcheck.go
109
matchcheck.go
|
|
@ -9,6 +9,7 @@ import (
|
|||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// ── Типы ─────────────────────────────────────────────────────────────────────
|
||||
|
|
@ -173,7 +174,7 @@ func mcCheckClient(client, hostname string) mcClientCheck {
|
|||
|
||||
func mcCheckContainer(client string, num int, angiePorts []int, hostname string) mcContainerCheck {
|
||||
result := mcContainerCheck{Number: num}
|
||||
fullName := fmt.Sprintf("ptaf_%s_%03d", client, num)
|
||||
fullName := mcBuildContainerName(client, hostname, num)
|
||||
label := fmt.Sprintf("контейнер %03d", num)
|
||||
|
||||
fmt.Printf(" ┌─ Контейнер %03d\n", num)
|
||||
|
|
@ -365,31 +366,99 @@ func mcIsValidJSON(filePath string) bool {
|
|||
return json.Unmarshal(data, &js) == nil
|
||||
}
|
||||
|
||||
func mcIsContainerRunning(name string) bool {
|
||||
cmd := exec.Command("docker", "ps", "--format", "{{.Names}}")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return false
|
||||
// mcBuildContainerName строит имя Docker-контейнера по новому формату:
|
||||
// {ClientTitle}_{AZN}_{prefix}{nodeN}_a{agentN}
|
||||
//
|
||||
// Пример:
|
||||
//
|
||||
// hostname: PTAF-TB-docker-AZ3-HW-node01, client: PSB_CFA, agent: 1
|
||||
// → PSB_CFA_AZ3_hn01_a001
|
||||
//
|
||||
// hostname: PTAF-TB-docker-AZ1-node04, client: ITAR-TASS, agent: 1
|
||||
// → ITAR-TASS_AZ1_n04_a001
|
||||
func mcBuildContainerName(client, hostname string, agentNum int) string {
|
||||
// Извлекаем AZN: ищем AZ + цифры в hostname
|
||||
azRe := regexp.MustCompile(`AZ(\d+)`)
|
||||
azMatch := azRe.FindStringSubmatch(hostname)
|
||||
azPart := "AZ0"
|
||||
if len(azMatch) > 1 {
|
||||
azPart = "AZ" + azMatch[1]
|
||||
}
|
||||
for _, line := range strings.Split(string(output), "\n") {
|
||||
if strings.TrimSpace(line) == name {
|
||||
return true
|
||||
|
||||
// Определяем префикс ноды: HW → hn, иначе n
|
||||
nodePrefix := "n"
|
||||
if strings.Contains(hostname, "-HW-") {
|
||||
nodePrefix = "hn"
|
||||
}
|
||||
|
||||
// Извлекаем номер ноды: цифры после "node"
|
||||
nodeRe := regexp.MustCompile(`node(\d+)`)
|
||||
nodeMatch := nodeRe.FindStringSubmatch(hostname)
|
||||
nodePart := "00"
|
||||
if len(nodeMatch) > 1 {
|
||||
// Берём последние 2 цифры с ведущим нулём
|
||||
num := nodeMatch[1]
|
||||
if len(num) >= 2 {
|
||||
nodePart = num[len(num)-2:]
|
||||
} else {
|
||||
nodePart = fmt.Sprintf("%02s", num)
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
||||
return fmt.Sprintf("%s_%s_%s%s_a%03d", client, azPart, nodePrefix, nodePart, agentNum)
|
||||
}
|
||||
|
||||
// ── Кэш системных вызовов ────────────────────────────────────────────────────
|
||||
// docker ps и ss вызываются один раз на всё выполнение и кэшируются.
|
||||
// Это критично при большом количестве контейнеров и портов (51+ портов на контейнер).
|
||||
|
||||
var (
|
||||
mcRunningContainers map[string]bool // имя контейнера → запущен
|
||||
mcListeningPorts map[int]bool // порт → слушается
|
||||
mcCacheOnce sync.Once
|
||||
)
|
||||
|
||||
func mcInitCache() {
|
||||
mcCacheOnce.Do(func() {
|
||||
mcRunningContainers = make(map[string]bool)
|
||||
mcListeningPorts = make(map[int]bool)
|
||||
|
||||
// Один вызов docker ps — все запущенные контейнеры
|
||||
if out, err := exec.Command("docker", "ps", "--format", "{{.Names}}").Output(); err == nil {
|
||||
for _, line := range strings.Split(string(out), "\n") {
|
||||
name := strings.TrimSpace(line)
|
||||
if name != "" {
|
||||
mcRunningContainers[name] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Один вызов ss — все слушающие порты
|
||||
out, err := exec.Command("ss", "-tlnp").Output()
|
||||
if err != nil {
|
||||
out, err = exec.Command("netstat", "-tlnp").Output()
|
||||
}
|
||||
if err == nil {
|
||||
re := regexp.MustCompile(`127\.0\.0\.1:(\d+)`)
|
||||
for _, m := range re.FindAllStringSubmatch(string(out), -1) {
|
||||
if len(m) > 1 {
|
||||
var p int
|
||||
fmt.Sscanf(m[1], "%d", &p)
|
||||
mcListeningPorts[p] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func mcIsContainerRunning(name string) bool {
|
||||
mcInitCache()
|
||||
return mcRunningContainers[name]
|
||||
}
|
||||
|
||||
func mcIsPortListening(port int) bool {
|
||||
cmd := exec.Command("ss", "-tlnp")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
cmd = exec.Command("netstat", "-tlnp")
|
||||
output, err = cmd.Output()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return strings.Contains(string(output), fmt.Sprintf("127.0.0.1:%d", port))
|
||||
mcInitCache()
|
||||
return mcListeningPorts[port]
|
||||
}
|
||||
|
||||
func mcContainsInt(slice []int, val int) bool {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue