add docker specific columns to server table
This commit is contained in:
64
local/utl/env/env.go
vendored
Normal file → Executable file
64
local/utl/env/env.go
vendored
Normal file → Executable file
@@ -6,10 +6,26 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultSteamCMDPath = "c:\\steamcmd\\steamcmd.exe"
|
||||
DefaultNSSMPath = ".\\nssm.exe"
|
||||
DefaultSteamCMDPath = "c:\\steamcmd\\steamcmd.exe"
|
||||
DefaultNSSMPath = ".\\nssm.exe"
|
||||
DefaultPlatform = "windows"
|
||||
DefaultACCImage = "acc-wine:latest"
|
||||
DefaultACCGameVolume = "/data/acc-game"
|
||||
DefaultACCConfigBasePath = "/data/configs"
|
||||
DefaultLinuxSteamCMDPath = "/usr/games/steamcmd"
|
||||
)
|
||||
|
||||
func GetPlatform() string {
|
||||
if p := os.Getenv("PLATFORM"); p != "" {
|
||||
return p
|
||||
}
|
||||
return DefaultPlatform
|
||||
}
|
||||
|
||||
func IsDockerPlatform() bool {
|
||||
return GetPlatform() == "docker"
|
||||
}
|
||||
|
||||
func GetSteamCMDPath() string {
|
||||
if path := os.Getenv("STEAMCMD_PATH"); path != "" {
|
||||
return path
|
||||
@@ -17,6 +33,13 @@ func GetSteamCMDPath() string {
|
||||
return DefaultSteamCMDPath
|
||||
}
|
||||
|
||||
func GetLinuxSteamCMDPath() string {
|
||||
if path := os.Getenv("STEAMCMD_LINUX_PATH"); path != "" {
|
||||
return path
|
||||
}
|
||||
return DefaultLinuxSteamCMDPath
|
||||
}
|
||||
|
||||
func GetSteamCMDDirPath() string {
|
||||
steamCMDPath := GetSteamCMDPath()
|
||||
return filepath.Dir(steamCMDPath)
|
||||
@@ -29,17 +52,40 @@ func GetNSSMPath() string {
|
||||
return DefaultNSSMPath
|
||||
}
|
||||
|
||||
func GetACCImage() string {
|
||||
if img := os.Getenv("ACC_IMAGE"); img != "" {
|
||||
return img
|
||||
}
|
||||
return DefaultACCImage
|
||||
}
|
||||
|
||||
func GetACCGameVolume() string {
|
||||
if v := os.Getenv("ACC_GAME_VOLUME"); v != "" {
|
||||
return v
|
||||
}
|
||||
return DefaultACCGameVolume
|
||||
}
|
||||
|
||||
func GetACCConfigBasePath() string {
|
||||
if p := os.Getenv("ACC_CONFIG_BASE_PATH"); p != "" {
|
||||
return p
|
||||
}
|
||||
return DefaultACCConfigBasePath
|
||||
}
|
||||
|
||||
func ValidatePaths() map[string]error {
|
||||
errors := make(map[string]error)
|
||||
|
||||
steamCMDPath := GetSteamCMDPath()
|
||||
if _, err := os.Stat(steamCMDPath); os.IsNotExist(err) {
|
||||
errors["STEAMCMD_PATH"] = err
|
||||
}
|
||||
if !IsDockerPlatform() {
|
||||
steamCMDPath := GetSteamCMDPath()
|
||||
if _, err := os.Stat(steamCMDPath); os.IsNotExist(err) {
|
||||
errors["STEAMCMD_PATH"] = err
|
||||
}
|
||||
|
||||
nssmPath := GetNSSMPath()
|
||||
if _, err := os.Stat(nssmPath); os.IsNotExist(err) {
|
||||
errors["NSSM_PATH"] = err
|
||||
nssmPath := GetNSSMPath()
|
||||
if _, err := os.Stat(nssmPath); os.IsNotExist(err) {
|
||||
errors["NSSM_PATH"] = err
|
||||
}
|
||||
}
|
||||
|
||||
return errors
|
||||
|
||||
72
local/utl/network/port_pool.go
Normal file
72
local/utl/network/port_pool.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultPortPoolMin = 9600
|
||||
defaultPortPoolMax = 9700
|
||||
)
|
||||
|
||||
type PortPoolManager struct {
|
||||
mu sync.Mutex
|
||||
min int
|
||||
max int
|
||||
inUse map[int]struct{}
|
||||
}
|
||||
|
||||
func NewPortPoolManager(db *gorm.DB) (*PortPoolManager, error) {
|
||||
min := portEnvInt("PORT_POOL_MIN", defaultPortPoolMin)
|
||||
max := portEnvInt("PORT_POOL_MAX", defaultPortPoolMax)
|
||||
|
||||
var ports []int
|
||||
if err := db.Raw("SELECT port FROM servers WHERE platform = 'docker' AND port > 0").Scan(&ports).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to seed port pool from database: %v", err)
|
||||
}
|
||||
|
||||
inUse := make(map[int]struct{}, len(ports))
|
||||
for _, p := range ports {
|
||||
inUse[p] = struct{}{}
|
||||
}
|
||||
|
||||
return &PortPoolManager{
|
||||
min: min,
|
||||
max: max,
|
||||
inUse: inUse,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *PortPoolManager) Acquire(_ context.Context) (int, error) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
|
||||
for port := p.min; port <= p.max; port++ {
|
||||
if _, used := p.inUse[port]; !used {
|
||||
p.inUse[port] = struct{}{}
|
||||
return port, nil
|
||||
}
|
||||
}
|
||||
return 0, fmt.Errorf("no available ports in pool [%d-%d]", p.min, p.max)
|
||||
}
|
||||
|
||||
func (p *PortPoolManager) Release(_ context.Context, port int) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
delete(p.inUse, port)
|
||||
}
|
||||
|
||||
func portEnvInt(key string, defaultVal int) int {
|
||||
if v := os.Getenv(key); v != "" {
|
||||
if n, err := strconv.Atoi(v); err == nil {
|
||||
return n
|
||||
}
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
@@ -44,7 +44,7 @@ func Start(di *dig.Container) *fiber.App {
|
||||
|
||||
app.Use(cors.New(cors.Config{
|
||||
AllowOrigins: allowedOrigin,
|
||||
AllowHeaders: "Origin, Content-Type, Accept, Authorization, Access-Token",
|
||||
AllowHeaders: "Origin, Content-Type, Accept, Authorization, Access-Key",
|
||||
AllowMethods: "GET, POST, PUT, DELETE, OPTIONS",
|
||||
AllowCredentials: true,
|
||||
MaxAge: 86400, // 24 hours
|
||||
|
||||
Reference in New Issue
Block a user