mirror of
https://github.com/Dvorinka/Containr.git
synced 2026-10-28 15:51:26 +00:00
services.builder picks the build strategy per service: auto detects from repo contents (Dockerfile → railpack → nixpacks), explicit overrides force a builder, and static builds assets in a node stage then serves them from an nginx image (static_build_cmd/static_dir, port 80 default). - cpu_reserve/memory_reserve → Docker CPU shares + MemoryReservation; cpu/memory stay hard caps (NanoCPUs/Memory). Empty string clears. - app_settings.default_cpu/default_memory override service-create fallbacks; capacity_policy=block fails deploys whose requested memory exceeds node capacity (default warn logs via slog). - Resource specs are validated — "512mb" fails instead of silently dropping the limit. - Fixes: deployments.go hardcoded nixpacks (auto-detect was dead code); DockerfileBuilder passed the Dockerfile *path* as build-context content; BuildImage never drained the daemon stream so builds could abort and errors went unseen — stream is now consumed and errorDetail surfaced. - CLI: --builder/--cpu-reserve/--memory-reserve/--static-cmd/--static-dir on create+update; MCP args on services create/update; UI Build & Resources card; OpenAPI + llms.txt + CLI.md. Verified live: static build of a real repo → nginx image → deployed; reserves reach HostConfig (shares=256, MemoryReservation=128Mi); validation rejects bad specs; builder persists + clears. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
49 lines
1.2 KiB
Go
49 lines
1.2 KiB
Go
package api
|
|
|
|
import "testing"
|
|
|
|
func TestParseCPUReserveShares(t *testing.T) {
|
|
cases := map[string]int64{
|
|
"": 0,
|
|
"0": 0,
|
|
"-1": 0,
|
|
"abc": 0,
|
|
"0.25": 256,
|
|
"1": 1024,
|
|
"2.5": 2560,
|
|
" 0.5 ": 512,
|
|
}
|
|
for in, want := range cases {
|
|
if got := parseCPUReserveShares(in); got != want {
|
|
t.Errorf("parseCPUReserveShares(%q) = %d, want %d", in, got, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestValidateResourceSpecs(t *testing.T) {
|
|
if err := validateCPUSpec(""); err != nil {
|
|
t.Error("empty cpu should pass")
|
|
}
|
|
if err := validateCPUSpec("0.5"); err != nil {
|
|
t.Error("0.5 should be valid cpu")
|
|
}
|
|
if err := validateCPUSpec("512mb"); err == nil {
|
|
t.Error("512mb should fail cpu validation")
|
|
}
|
|
if err := validateMemorySpec(""); err != nil {
|
|
t.Error("empty memory should pass")
|
|
}
|
|
if err := validateMemorySpec("512Mi"); err != nil {
|
|
t.Error("512Mi should be valid memory")
|
|
}
|
|
if err := validateMemorySpec("1g"); err != nil {
|
|
t.Error("1g should be valid memory")
|
|
}
|
|
if err := validateMemorySpec("0.5"); err == nil {
|
|
t.Error("0.5 should fail memory validation (parses to <1 byte)")
|
|
}
|
|
if err := validateMemorySpec("lots"); err == nil {
|
|
t.Error("'lots' should fail memory validation")
|
|
}
|
|
}
|