mirror of
https://github.com/m1k1o/neko-rooms.git
synced 2026-11-03 07:01:35 -06:00
Merge branch 'master' into policies
This commit is contained in:
@@ -13,34 +13,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (manager *RoomManagerCtx) containerToEntry(container dockerTypes.Container) (*types.RoomEntry, error) {
|
func (manager *RoomManagerCtx) containerToEntry(container dockerTypes.Container) (*types.RoomEntry, error) {
|
||||||
roomName, ok := container.Labels["m1k1o.neko_rooms.name"]
|
labels, err := manager.extractLabels(container.Labels)
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("damaged container labels: name not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
nekoImage, ok := container.Labels["m1k1o.neko_rooms.neko_image"]
|
|
||||||
if !ok {
|
|
||||||
// Backward compatibility.
|
|
||||||
nekoImage = container.Image
|
|
||||||
//return nil, fmt.Errorf("Damaged container labels: neko_image not found.")
|
|
||||||
}
|
|
||||||
|
|
||||||
URL, ok := container.Labels["m1k1o.neko_rooms.url"]
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("damaged container labels: url not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
epr, err := manager.getEprFromLabels(container.Labels)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &types.RoomEntry{
|
return &types.RoomEntry{
|
||||||
ID: container.ID,
|
ID: container.ID,
|
||||||
URL: URL,
|
URL: labels.URL,
|
||||||
Name: roomName,
|
Name: labels.Name,
|
||||||
NekoImage: nekoImage,
|
NekoImage: labels.NekoImage,
|
||||||
MaxConnections: epr.Max - epr.Min + 1,
|
MaxConnections: labels.Epr.Max - labels.Epr.Min + 1,
|
||||||
Running: container.State == "running",
|
Running: container.State == "running",
|
||||||
Status: container.Status,
|
Status: container.Status,
|
||||||
Created: time.Unix(container.Created, 0),
|
Created: time.Unix(container.Created, 0),
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package room
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RoomLabels struct {
|
||||||
|
Name string
|
||||||
|
URL string
|
||||||
|
Epr EprPorts
|
||||||
|
NekoImage string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (manager *RoomManagerCtx) extractLabels(labels map[string]string) (*RoomLabels, error) {
|
||||||
|
name, ok := labels["m1k1o.neko_rooms.name"]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("damaged container labels: name not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
url, ok := labels["m1k1o.neko_rooms.url"]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("damaged container labels: url not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
nekoImage, ok := labels["m1k1o.neko_rooms.neko_image"]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("damaged container labels: neko_image not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
eprMinStr, ok := labels["m1k1o.neko_rooms.epr.min"]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("damaged container labels: epr.min not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
eprMin, err := strconv.ParseUint(eprMinStr, 10, 16)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
eprMaxStr, ok := labels["m1k1o.neko_rooms.epr.max"]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("damaged container labels: epr.max not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
eprMax, err := strconv.ParseUint(eprMaxStr, 10, 16)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &RoomLabels{
|
||||||
|
Name: name,
|
||||||
|
URL: url,
|
||||||
|
NekoImage: nekoImage,
|
||||||
|
Epr: EprPorts{
|
||||||
|
Min: uint16(eprMin),
|
||||||
|
Max: uint16(eprMax),
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (manager *RoomManagerCtx) serializeLabels(labels RoomLabels) map[string]string {
|
||||||
|
return map[string]string{
|
||||||
|
"m1k1o.neko_rooms.name": labels.Name,
|
||||||
|
"m1k1o.neko_rooms.url": labels.URL,
|
||||||
|
"m1k1o.neko_rooms.instance": manager.config.InstanceName,
|
||||||
|
"m1k1o.neko_rooms.epr.min": fmt.Sprintf("%d", labels.Epr.Min),
|
||||||
|
"m1k1o.neko_rooms.epr.max": fmt.Sprintf("%d", labels.Epr.Max),
|
||||||
|
"m1k1o.neko_rooms.neko_image": labels.NekoImage,
|
||||||
|
}
|
||||||
|
}
|
||||||
+54
-38
@@ -115,6 +115,10 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allocate ports
|
||||||
|
//
|
||||||
|
|
||||||
epr, err := manager.allocatePorts(settings.MaxConnections)
|
epr, err := manager.allocatePorts(settings.MaxConnections)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@@ -138,8 +142,33 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
|
|||||||
exposedPorts[portKey] = struct{}{}
|
exposedPorts[portKey] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set traefik labels
|
||||||
|
//
|
||||||
|
|
||||||
containerName := manager.config.InstanceName + "-" + roomName
|
containerName := manager.config.InstanceName + "-" + roomName
|
||||||
|
|
||||||
|
traefikLabels := map[string]string{
|
||||||
|
"traefik.enable": "true",
|
||||||
|
"traefik.http.services." + containerName + "-frontend.loadbalancer.server.port": fmt.Sprintf("%d", frontendPort),
|
||||||
|
"traefik.http.routers." + containerName + ".entrypoints": manager.config.TraefikEntrypoint,
|
||||||
|
"traefik.http.routers." + containerName + ".rule": "Host(`" + manager.config.TraefikDomain + "`) && PathPrefix(`/" + roomName + "`)",
|
||||||
|
"traefik.http.middlewares." + containerName + "-rdr.redirectregex.regex": "/" + roomName + "$$",
|
||||||
|
"traefik.http.middlewares." + containerName + "-rdr.redirectregex.replacement": "/" + roomName + "/",
|
||||||
|
"traefik.http.middlewares." + containerName + "-prf.stripprefix.prefixes": "/" + roomName + "/",
|
||||||
|
"traefik.http.routers." + containerName + ".middlewares": containerName + "-rdr," + containerName + "-prf",
|
||||||
|
}
|
||||||
|
|
||||||
|
// optional HTTPS
|
||||||
|
if manager.config.TraefikCertresolver != "" {
|
||||||
|
traefikLabels["traefik.http.routers."+containerName+".tls"] = "true"
|
||||||
|
traefikLabels["traefik.http.routers."+containerName+".tls.certresolver"] = manager.config.TraefikCertresolver
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set internal labels
|
||||||
|
//
|
||||||
|
|
||||||
instanceUrl := manager.config.InstanceUrl
|
instanceUrl := manager.config.InstanceUrl
|
||||||
if instanceUrl == "" {
|
if instanceUrl == "" {
|
||||||
urlProto := "http"
|
urlProto := "http"
|
||||||
@@ -158,31 +187,20 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
|
|||||||
instanceUrl = instanceUrl + "/"
|
instanceUrl = instanceUrl + "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
labels := map[string]string{
|
labels := manager.serializeLabels(RoomLabels{
|
||||||
// Set internal labels
|
Name: roomName,
|
||||||
"m1k1o.neko_rooms.name": roomName,
|
URL: instanceUrl + roomName + "/",
|
||||||
"m1k1o.neko_rooms.url": instanceUrl + roomName + "/",
|
Epr: epr,
|
||||||
"m1k1o.neko_rooms.instance": manager.config.InstanceName,
|
NekoImage: settings.NekoImage,
|
||||||
"m1k1o.neko_rooms.epr.min": fmt.Sprintf("%d", epr.Min),
|
})
|
||||||
"m1k1o.neko_rooms.epr.max": fmt.Sprintf("%d", epr.Max),
|
|
||||||
"m1k1o.neko_rooms.neko_image": settings.NekoImage,
|
|
||||||
|
|
||||||
// Set traefik labels
|
for k, v := range traefikLabels {
|
||||||
"traefik.enable": "true",
|
labels[k] = v
|
||||||
"traefik.http.services." + containerName + "-frontend.loadbalancer.server.port": fmt.Sprintf("%d", frontendPort),
|
|
||||||
"traefik.http.routers." + containerName + ".entrypoints": manager.config.TraefikEntrypoint,
|
|
||||||
"traefik.http.routers." + containerName + ".rule": "Host(`" + manager.config.TraefikDomain + "`) && PathPrefix(`/" + roomName + "`)",
|
|
||||||
"traefik.http.middlewares." + containerName + "-rdr.redirectregex.regex": "/" + roomName + "$$",
|
|
||||||
"traefik.http.middlewares." + containerName + "-rdr.redirectregex.replacement": "/" + roomName + "/",
|
|
||||||
"traefik.http.middlewares." + containerName + "-prf.stripprefix.prefixes": "/" + roomName + "/",
|
|
||||||
"traefik.http.routers." + containerName + ".middlewares": containerName + "-rdr," + containerName + "-prf",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// optional HTTPS
|
//
|
||||||
if manager.config.TraefikCertresolver != "" {
|
// Set environment variables
|
||||||
labels["traefik.http.routers."+containerName+".tls"] = "true"
|
//
|
||||||
labels["traefik.http.routers."+containerName+".tls.certresolver"] = manager.config.TraefikCertresolver
|
|
||||||
}
|
|
||||||
|
|
||||||
env := []string{
|
env := []string{
|
||||||
fmt.Sprintf("NEKO_BIND=:%d", frontendPort),
|
fmt.Sprintf("NEKO_BIND=:%d", frontendPort),
|
||||||
@@ -245,6 +263,10 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set container mounts
|
||||||
|
//
|
||||||
|
|
||||||
paths := map[string]bool{}
|
paths := map[string]bool{}
|
||||||
mounts := []dockerMount.Mount{}
|
mounts := []dockerMount.Mount{}
|
||||||
for _, mount := range settings.Mounts {
|
for _, mount := range settings.Mounts {
|
||||||
@@ -319,6 +341,10 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
|
|||||||
paths[mount.ContainerPath] = true
|
paths[mount.ContainerPath] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set container configs
|
||||||
|
//
|
||||||
|
|
||||||
config := &container.Config{
|
config := &container.Config{
|
||||||
// Hostname
|
// Hostname
|
||||||
Hostname: containerName,
|
Hostname: containerName,
|
||||||
@@ -417,22 +443,12 @@ func (manager *RoomManagerCtx) GetSettings(id string) (*types.RoomSettings, erro
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
roomName, ok := container.Config.Labels["m1k1o.neko_rooms.name"]
|
labels, err := manager.extractLabels(container.Config.Labels)
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("damaged container labels: name not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
nekoImage, ok := container.Config.Labels["m1k1o.neko_rooms.neko_image"]
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("damaged container labels: neko_image not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
epr, err := manager.getEprFromLabels(container.Config.Labels)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
privateStorageRoot := path.Join(manager.config.StorageExternal, privateStoragePath, roomName)
|
privateStorageRoot := path.Join(manager.config.StorageExternal, privateStoragePath, labels.Name)
|
||||||
templateStorageRoot := path.Join(manager.config.StorageExternal, templateStoragePath)
|
templateStorageRoot := path.Join(manager.config.StorageExternal, templateStoragePath)
|
||||||
|
|
||||||
mounts := []types.RoomMount{}
|
mounts := []types.RoomMount{}
|
||||||
@@ -456,7 +472,7 @@ func (manager *RoomManagerCtx) GetSettings(id string) (*types.RoomSettings, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
var policiesData *types.Policies
|
var policiesData *types.Policies
|
||||||
policyConfig := policies.GetConfig(nekoImage)
|
policyConfig := policies.GetConfig(labels.NekoImage)
|
||||||
if policyConfig != nil {
|
if policyConfig != nil {
|
||||||
var policyMount *types.RoomMount
|
var policyMount *types.RoomMount
|
||||||
for _, mount := range mounts {
|
for _, mount := range mounts {
|
||||||
@@ -480,9 +496,9 @@ func (manager *RoomManagerCtx) GetSettings(id string) (*types.RoomSettings, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
settings := types.RoomSettings{
|
settings := types.RoomSettings{
|
||||||
Name: roomName,
|
Name: labels.Name,
|
||||||
NekoImage: nekoImage,
|
NekoImage: labels.NekoImage,
|
||||||
MaxConnections: epr.Max - epr.Min + 1,
|
MaxConnections: labels.Epr.Max - labels.Epr.Min + 1,
|
||||||
Mounts: mounts,
|
Mounts: mounts,
|
||||||
Policies: policiesData,
|
Policies: policiesData,
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-32
@@ -3,7 +3,6 @@ package room
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type EprPorts struct {
|
type EprPorts struct {
|
||||||
@@ -51,12 +50,12 @@ func (manager *RoomManagerCtx) getUsedPorts() ([]EprPorts, error) {
|
|||||||
|
|
||||||
result := []EprPorts{}
|
result := []EprPorts{}
|
||||||
for _, container := range containers {
|
for _, container := range containers {
|
||||||
epr, err := manager.getEprFromLabels(container.Labels)
|
labels, err := manager.extractLabels(container.Labels)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result = append(result, epr)
|
result = append(result, labels.Epr)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.SliceStable(result, func(i, j int) bool {
|
sort.SliceStable(result, func(i, j int) bool {
|
||||||
@@ -65,32 +64,3 @@ func (manager *RoomManagerCtx) getUsedPorts() ([]EprPorts, error) {
|
|||||||
|
|
||||||
return result, nil
|
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
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user