mirror of
https://github.com/m1k1o/neko-rooms.git
synced 2026-11-02 22:51:34 -06:00
name + port allocation.
This commit is contained in:
@@ -15,6 +15,7 @@ import (
|
||||
|
||||
"m1k1o/neko_rooms/internal/config"
|
||||
"m1k1o/neko_rooms/internal/types"
|
||||
"m1k1o/neko_rooms/internal/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -63,17 +64,27 @@ func (manager *RoomManagerCtx) List() ([]types.RoomData, error) {
|
||||
return result, nil
|
||||
}
|
||||
func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (*types.RoomData, error) {
|
||||
// configs
|
||||
pathName := "foobar"
|
||||
eprMin := uint(52135)
|
||||
eprMax := uint(52145)
|
||||
// TODO: Check if path name exists.
|
||||
pathName := settings.Name
|
||||
if pathName == "" {
|
||||
var err error
|
||||
pathName, err = utils.NewUID(32)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
epr, err := manager.allocatePorts(settings.MaxConnections)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
portBindings := nat.PortMap{}
|
||||
exposedPorts := nat.PortSet{
|
||||
nat.Port(fmt.Sprintf("%d/udp", frontendPort)): struct{}{},
|
||||
}
|
||||
|
||||
for port := eprMin; port <= eprMax; port++ {
|
||||
for port := epr.Min; port <= epr.Max; port++ {
|
||||
portKey := nat.Port(fmt.Sprintf("%d/udp", port))
|
||||
|
||||
portBindings[portKey] = []nat.PortBinding{
|
||||
@@ -91,8 +102,8 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (*types.RoomD
|
||||
labels := map[string]string{
|
||||
// Set internal labels
|
||||
"m1k1o.neko_rooms.canary": labelCanary,
|
||||
"m1k1o.neko_rooms.epr.min": fmt.Sprintf("%d", eprMin),
|
||||
"m1k1o.neko_rooms.epr.max": fmt.Sprintf("%d", eprMax),
|
||||
"m1k1o.neko_rooms.epr.min": fmt.Sprintf("%d", epr.Min),
|
||||
"m1k1o.neko_rooms.epr.max": fmt.Sprintf("%d", epr.Max),
|
||||
|
||||
// Set traefik labels
|
||||
"traefik.enable": "true",
|
||||
@@ -121,7 +132,7 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (*types.RoomD
|
||||
// List of environment variable to set in the container
|
||||
Env: append([]string{
|
||||
fmt.Sprintf("NEKO_BIND=%d", frontendPort),
|
||||
}, settings.Env(eprMin, eprMax, manager.config.NAT1To1IPs)...),
|
||||
}, settings.Env(epr.Min, epr.Max, manager.config.NAT1To1IPs)...),
|
||||
// Name of the image as it was passed by the operator (e.g. could be symbolic)
|
||||
Image: nekoImage,
|
||||
// List of labels set to this container
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
package room
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type EprPorts struct {
|
||||
Min uint16
|
||||
Max uint16
|
||||
}
|
||||
|
||||
func (manager *RoomManagerCtx) allocatePorts(sum uint16) (EprPorts, error) {
|
||||
min := manager.config.EprMin
|
||||
max := manager.config.EprMax
|
||||
|
||||
epr := EprPorts{
|
||||
Min: min,
|
||||
Max: min + sum,
|
||||
}
|
||||
|
||||
ports, err := manager.getUsedPorts()
|
||||
if err != nil {
|
||||
return epr, err
|
||||
}
|
||||
|
||||
for _, port := range ports {
|
||||
if (epr.Min >= port.Min && epr.Min <= port.Max) || (epr.Max >= port.Min && epr.Max <= port.Max) {
|
||||
epr.Min = port.Max + 1
|
||||
epr.Max = port.Max + 1 + sum
|
||||
}
|
||||
}
|
||||
|
||||
if epr.Min > max || epr.Max > max {
|
||||
return epr, fmt.Errorf("Unable to allocate ports: not enough ports.")
|
||||
}
|
||||
|
||||
return epr, nil
|
||||
}
|
||||
|
||||
func (manager *RoomManagerCtx) getUsedPorts() ([]EprPorts, error) {
|
||||
containers, err := manager.listContainers()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := []EprPorts{}
|
||||
for _, container := range containers {
|
||||
epr, err := manager.getEprFromLabels(container.Labels)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result = append(result, epr)
|
||||
}
|
||||
|
||||
sort.SliceStable(result, func(i, j int) bool {
|
||||
return result[i].Min < result[j].Min
|
||||
})
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (manager *RoomManagerCtx) getEprFromLabels(labels map[string]string) (EprPorts, error) {
|
||||
var err error
|
||||
epr := EprPorts{}
|
||||
|
||||
eprMinStr, ok := labels["m1k1o.neko_rooms.epr.min"]
|
||||
if !ok {
|
||||
return epr, fmt.Errorf("Damaged container labels: epr.min not found.")
|
||||
}
|
||||
|
||||
eprMin, err := strconv.ParseUint(eprMinStr, 10, 16)
|
||||
if err != nil {
|
||||
return epr, err
|
||||
}
|
||||
|
||||
eprMaxStr, ok := labels["m1k1o.neko_rooms.epr.max"]
|
||||
if !ok {
|
||||
return epr, fmt.Errorf("Damaged container labels: epr.max not found.")
|
||||
}
|
||||
|
||||
eprMax, err := strconv.ParseUint(eprMaxStr, 10, 16)
|
||||
if err != nil {
|
||||
return epr, err
|
||||
}
|
||||
|
||||
epr.Min = uint16(eprMin)
|
||||
epr.Max = uint16(eprMax)
|
||||
return epr, nil
|
||||
}
|
||||
@@ -6,7 +6,9 @@ import (
|
||||
)
|
||||
|
||||
type RoomSettings struct {
|
||||
MaxConnections uint `json:"max_connections"`
|
||||
Name string `json:"name"`
|
||||
|
||||
MaxConnections uint16 `json:"max_connections"`
|
||||
UserPass string `json:"user_pass"`
|
||||
AdminPass string `json:"admin_pass"`
|
||||
|
||||
@@ -23,7 +25,7 @@ type RoomSettings struct {
|
||||
AudioPipeline string `json:"audio_pipeline"`
|
||||
}
|
||||
|
||||
func (settings *RoomSettings) Env(eprMin uint, eprMax uint, nat1to1 []string) []string {
|
||||
func (settings *RoomSettings) Env(eprMin uint16, eprMax uint16, nat1to1 []string) []string {
|
||||
env := []string{
|
||||
fmt.Sprintf("NEKO_EPR=%d-%d", eprMin, eprMax),
|
||||
fmt.Sprintf("NEKO_NAT1TO1=%s", strings.Join(nat1to1, ",")),
|
||||
|
||||
Reference in New Issue
Block a user