118 lines
4.2 KiB
Go
118 lines
4.2 KiB
Go
package agent
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"net"
|
|
"net/http"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.zaynet.fr/DoGaMa/DoGaMa-serv/internal/agentwire"
|
|
)
|
|
|
|
func TestDockerPingerUsesConfiguredUnixSocket(t *testing.T) {
|
|
socket := filepath.Join(t.TempDir(), "docker.sock")
|
|
listener, err := net.Listen("unix", socket)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
server := &http.Server{Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path != "/_ping" {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
_, _ = w.Write([]byte("OK"))
|
|
})}
|
|
go func() { _ = server.Serve(listener) }()
|
|
t.Cleanup(func() { _ = server.Shutdown(context.Background()) })
|
|
pinger, err := NewDockerRuntime(socket, "dogama-games")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := pinger.Ping(context.Background()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestDockerRuntimeCreatesFixedSecurityBaseline(t *testing.T) {
|
|
socket := filepath.Join(t.TempDir(), "docker.sock")
|
|
listener, err := net.Listen("unix", socket)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
createdBodies := make(chan []byte, 1)
|
|
server := &http.Server{Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch {
|
|
case r.URL.Path == "/v1.41/images/create":
|
|
_, _ = w.Write([]byte("{}\n"))
|
|
case r.URL.Path == "/v1.41/containers/json":
|
|
_, _ = w.Write([]byte("[]"))
|
|
case r.URL.Path == "/v1.41/containers/create":
|
|
body, _ := io.ReadAll(r.Body)
|
|
createdBodies <- body
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusCreated)
|
|
_, _ = w.Write([]byte(`{"Id":"container-1"}`))
|
|
default:
|
|
http.NotFound(w, r)
|
|
}
|
|
})}
|
|
go func() { _ = server.Serve(listener) }()
|
|
t.Cleanup(func() { _ = server.Shutdown(context.Background()) })
|
|
runtime, err := NewDockerRuntime(socket, "dogama-games")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
plan := agentwire.DeploymentPlan{
|
|
InstanceID: "abcdefghijklmnopqrstuvwx", TemplateID: "palworld-official", TemplateVersion: "1.0.0", PlanDigest: strings.Repeat("a", 64), Image: "example.invalid/game:1",
|
|
Ports: []agentwire.PlanPort{{ID: "game", Protocol: "udp", ContainerPort: 8211, HostPort: 38211, Publish: true}},
|
|
Mounts: []agentwire.PlanMount{{ID: "saved", HostPath: "/srv/games/saved", ContainerPath: "/game/saved"}}, Resources: agentwire.PlanResource{CPUCores: 2, MemoryMB: 1024, StorageGB: 10}, Labels: map[string]string{"dashboard.name": "Summer"}, User: "1000:1001",
|
|
}
|
|
if err := runtime.CheckPorts(context.Background(), plan.Ports); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
id, err := runtime.Create(context.Background(), plan, []AssetMount{{HostPath: "/srv/games/.dogama/helper", ContainerPath: "/pal/helper.sh"}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if id != "container-1" {
|
|
t.Fatalf("container ID = %q", id)
|
|
}
|
|
var payload struct {
|
|
User string `json:"User"`
|
|
Labels map[string]string `json:"Labels"`
|
|
HostConfig struct {
|
|
NetworkMode string `json:"NetworkMode"`
|
|
CapDrop []string `json:"CapDrop"`
|
|
SecurityOpt []string `json:"SecurityOpt"`
|
|
Memory int64 `json:"Memory"`
|
|
NanoCPUs int64 `json:"NanoCpus"`
|
|
} `json:"HostConfig"`
|
|
}
|
|
if err := json.Unmarshal(<-createdBodies, &payload); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if payload.HostConfig.NetworkMode != "dogama-games" || len(payload.HostConfig.CapDrop) != 1 || payload.HostConfig.CapDrop[0] != "ALL" || len(payload.HostConfig.SecurityOpt) != 1 || payload.HostConfig.Memory <= 0 || payload.HostConfig.NanoCPUs <= 0 {
|
|
t.Fatalf("insecure Docker host config: %#v", payload.HostConfig)
|
|
}
|
|
if payload.Labels["io.dogama.instance-id"] != plan.InstanceID || payload.Labels["io.dogama.plan-digest"] != plan.PlanDigest {
|
|
t.Fatalf("binding labels = %#v", payload.Labels)
|
|
}
|
|
if payload.Labels["dashboard.name"] != "Summer" || payload.User != "1000:1001" {
|
|
t.Fatalf("custom Docker configuration = %#v user=%q", payload.Labels, payload.User)
|
|
}
|
|
}
|
|
|
|
func TestDockerPingerDoesNotExposeConnectionDetails(t *testing.T) {
|
|
pinger, err := NewDockerRuntime(filepath.Join(t.TempDir(), "missing.sock"), "dogama-games")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := pinger.Ping(context.Background()); err == nil || err.Error() != "docker daemon is unavailable" {
|
|
t.Fatalf("Ping error = %v", err)
|
|
}
|
|
}
|