194 lines
8.2 KiB
Go
194 lines
8.2 KiB
Go
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"log"
|
||
"os"
|
||
"os/exec"
|
||
"path/filepath"
|
||
"time"
|
||
)
|
||
|
||
func setupContainers(config Config, clientTitle string, clientInfo *ClientInfo, resources []ResourceData, resourcePortMap map[int][]PortMapping) error {
|
||
log.Printf("Настройка контейнеров для %s", clientTitle)
|
||
baseDir := filepath.Join("/home/install/ptaf", clientTitle)
|
||
containerChanges := make(map[int]bool)
|
||
composeChanges := make(map[int]bool)
|
||
|
||
for containerNum := 1; containerNum <= clientInfo.ContainersCount; containerNum++ {
|
||
containerName := fmt.Sprintf("%s-ptaf-agent%03d", clientTitle, containerNum)
|
||
containerDir := filepath.Join(baseDir, containerName)
|
||
log.Printf(" Обработка контейнера: %s", containerName)
|
||
|
||
dirs := []string{
|
||
containerDir,
|
||
filepath.Join("/home/install/conf/ptaf-nginx", clientTitle, fmt.Sprintf("ptaf-agent%03d", containerNum), "conf.d"),
|
||
}
|
||
for _, dir := range dirs {
|
||
existed := false
|
||
if _, err := os.Stat(dir); err == nil {
|
||
existed = true
|
||
}
|
||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||
return fmt.Errorf("ошибка создания директории %s: %w", dir, err)
|
||
}
|
||
if !existed {
|
||
log.Printf(" ✓ Создана директория: %s", dir)
|
||
}
|
||
}
|
||
|
||
logDir := filepath.Join("/var/log/ptaf_nginx", clientTitle, fmt.Sprintf("ptaf-agent%03d", containerNum))
|
||
logDirExisted := false
|
||
if _, err := os.Stat(logDir); err == nil {
|
||
logDirExisted = true
|
||
}
|
||
if err := os.MkdirAll(logDir, 0777); err != nil {
|
||
return fmt.Errorf("ошибка создания директории логов %s: %w", logDir, err)
|
||
}
|
||
if err := os.Chmod(logDir, 0777); err != nil {
|
||
return fmt.Errorf("ошибка установки прав для директории логов %s: %w", logDir, err)
|
||
}
|
||
if !logDirExisted {
|
||
log.Printf(" ✓ Создана директория логов: %s (права: 0777)", logDir)
|
||
}
|
||
|
||
nginxConfPath := filepath.Join("/home/install/conf/ptaf-nginx", clientTitle, fmt.Sprintf("ptaf-agent%03d", containerNum), "nginx.conf")
|
||
existingPodIP := ""
|
||
if info, err := os.Stat(nginxConfPath); err == nil {
|
||
if info.IsDir() {
|
||
log.Printf(" ⚠ nginx.conf является директорией, удаляем...")
|
||
os.RemoveAll(nginxConfPath)
|
||
} else {
|
||
existingPodIP = extractPodIPFromConfig(nginxConfPath)
|
||
}
|
||
}
|
||
|
||
ptafConfig := ""
|
||
if clientInfo.PTAFConfig.Valid {
|
||
ptafConfig = clientInfo.PTAFConfig.String
|
||
}
|
||
|
||
changed, err := generateNginxConf(nginxConfPath, config, ptafConfig, existingPodIP)
|
||
if err != nil {
|
||
return fmt.Errorf("ошибка генерации nginx.conf: %w", err)
|
||
}
|
||
if changed {
|
||
log.Printf(" ✓ nginx.conf изменен: %s", nginxConfPath)
|
||
containerChanges[containerNum] = true
|
||
} else {
|
||
log.Printf(" ○ nginx.conf не изменился: %s", nginxConfPath)
|
||
}
|
||
|
||
mimeTypesPath := filepath.Join("/home/install/conf/ptaf-nginx", clientTitle, fmt.Sprintf("ptaf-agent%03d", containerNum), "mime.types")
|
||
if info, err := os.Stat(mimeTypesPath); err == nil {
|
||
if info.IsDir() {
|
||
log.Printf(" ⚠ mime.types является директорией, удаляем...")
|
||
os.RemoveAll(mimeTypesPath)
|
||
}
|
||
}
|
||
changed, err = generateMimeTypes(mimeTypesPath)
|
||
if err != nil {
|
||
return fmt.Errorf("ошибка генерации mime.types: %w", err)
|
||
}
|
||
if changed {
|
||
log.Printf(" ✓ mime.types изменен: %s", mimeTypesPath)
|
||
containerChanges[containerNum] = true
|
||
}
|
||
|
||
confDPath := filepath.Join("/home/install/conf/ptaf-nginx", clientTitle, fmt.Sprintf("ptaf-agent%03d", containerNum), "conf.d")
|
||
containerPorts := []PortMapping{}
|
||
for _, res := range resources {
|
||
ports, ok := resourcePortMap[res.L7ResourceID]
|
||
if !ok || containerNum-1 >= len(ports) {
|
||
return fmt.Errorf("не найдены порты для l7ResourceID %d контейнер %d", res.L7ResourceID, containerNum)
|
||
}
|
||
containerPorts = append(containerPorts, ports[containerNum-1])
|
||
confFile := filepath.Join(confDPath, fmt.Sprintf("%s_%d.conf", clientTitle, res.L7ResourceID))
|
||
oldHash := ""
|
||
if _, err := os.Stat(confFile); err == nil {
|
||
oldHash, _ = getFileHash(confFile)
|
||
}
|
||
err := generateNginxResourceConfig(confFile, config, res, ports[containerNum-1])
|
||
if err != nil {
|
||
return fmt.Errorf("ошибка генерации конфига для ресурса: %w", err)
|
||
}
|
||
newHash, _ := getFileHash(confFile)
|
||
if oldHash != "" && oldHash != newHash {
|
||
log.Printf(" ✓ Конфиг ресурса изменен: %s", confFile)
|
||
containerChanges[containerNum] = true
|
||
} else if oldHash == "" {
|
||
log.Printf(" ✓ Создан конфиг ресурса: %s", confFile)
|
||
containerChanges[containerNum] = true
|
||
} else {
|
||
log.Printf(" ○ Конфиг ресурса не изменился: %s", confFile)
|
||
}
|
||
}
|
||
|
||
composeFile := filepath.Join(containerDir, "docker-compose.yml")
|
||
log.Printf(" → DEBUG порты контейнера %d:", containerNum)
|
||
for idx, pm := range containerPorts {
|
||
log.Printf(" PortMapping[%d]: HTTP=%v, HTTPS=%v", idx, pm.HTTPPorts, pm.HTTPSPorts)
|
||
}
|
||
changed, err = generateDockerCompose(composeFile, config, clientTitle, clientInfo, containerNum, resources, containerPorts)
|
||
if err != nil {
|
||
return fmt.Errorf("ошибка генерации docker-compose.yml: %w", err)
|
||
}
|
||
if changed {
|
||
log.Printf(" ✓ docker-compose.yml изменен: %s", composeFile)
|
||
composeChanges[containerNum] = true
|
||
}
|
||
if err := saveContainerPorts(containerDir, containerNum, resources, containerPorts); err != nil {
|
||
log.Printf(" ⚠ Ошибка сохранения портов: %v", err)
|
||
}
|
||
}
|
||
|
||
log.Printf(" Запуск и обновление контейнеров для %s", clientTitle)
|
||
for containerNum := 1; containerNum <= clientInfo.ContainersCount; containerNum++ {
|
||
containerName := fmt.Sprintf("%s-ptaf-agent%03d", clientTitle, containerNum)
|
||
containerDir := filepath.Join(baseDir, containerName)
|
||
composeFile := filepath.Join(containerDir, "docker-compose.yml")
|
||
containerFullName := fmt.Sprintf("ptaf_%s_%03d", clientTitle, containerNum)
|
||
containerExists, containerRunning := checkContainerStatus(containerFullName)
|
||
|
||
if containerExists {
|
||
if composeChanges[containerNum] {
|
||
recreateContainer(containerFullName, composeFile, containerDir, clientTitle, resources, resourcePortMap, containerNum)
|
||
continue
|
||
}
|
||
if !containerRunning {
|
||
startContainer(containerFullName, composeFile, containerDir)
|
||
}
|
||
if containerChanges[containerNum] {
|
||
log.Printf(" Конфигурация изменилась, проверяем и перезагружаем nginx в %s", containerFullName)
|
||
if err := testNginxConfig(containerFullName); err != nil {
|
||
log.Printf(" ⚠ Ошибка проверки конфигурации в %s: %v", containerFullName, err)
|
||
continue
|
||
}
|
||
if err := reloadNginx(containerFullName); err != nil {
|
||
log.Printf(" ⚠ Ошибка перезагрузки nginx в %s: %v", containerFullName, err)
|
||
continue
|
||
}
|
||
log.Printf(" ✓ Nginx успешно перезагружен в контейнере %s", containerFullName)
|
||
} else {
|
||
log.Printf(" ○ Конфигурация не изменилась, проверка и перезагрузка не требуются для %s", containerFullName)
|
||
}
|
||
} else {
|
||
log.Printf(" Запуск нового контейнера %s", containerName)
|
||
cmd := exec.Command("docker-compose", "-f", composeFile, "up", "-d")
|
||
cmd.Dir = containerDir
|
||
output, _ := cmd.CombinedOutput()
|
||
log.Printf(" → Вывод docker-compose: %s", string(output))
|
||
time.Sleep(5 * time.Second)
|
||
_, isRunning := checkContainerStatus(containerFullName)
|
||
if !isRunning {
|
||
log.Printf(" ⚠ Контейнер %s не запустился. Попробуйте вручную: cd %s && docker-compose up -d", containerFullName, containerDir)
|
||
continue
|
||
}
|
||
log.Printf(" ✓ Контейнер %s успешно запущен", containerName)
|
||
}
|
||
}
|
||
|
||
log.Printf(" Проверка лишних контейнеров для %s", clientTitle)
|
||
processDrainingContainers(clientTitle, clientInfo.ContainersCount)
|
||
return nil
|
||
}
|