updates 4-19-26

This commit is contained in:
jester 2026-04-19 21:51:00 +00:00
parent 08aba389e4
commit 2517a41ddf
12 changed files with 42 additions and 108 deletions

View File

@ -717,13 +717,6 @@ func sourceForPath(root, rel string) *string {
return &source return &source
} }
func min(a, b int) int {
if a < b {
return a
}
return b
}
func normalizeAndCheckVisibleRel(rel string) (string, error) { func normalizeAndCheckVisibleRel(rel string) (string, error) {
normalizedRel, err := normalizeRelativePath(rel) normalizedRel, err := normalizeRelativePath(rel)
if err != nil { if err != nil {

View File

@ -8,7 +8,6 @@ import (
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
"strconv"
"strings" "strings"
"time" "time"
@ -293,7 +292,7 @@ func ensureProvisioned(cfg *state.Config) error {
} }
func ensureDevCodeServer(cfg *state.Config) error { func ensureDevCodeServer(cfg *state.Config) error {
if cfg == nil || !devCodeServerRequested(*cfg) { if cfg == nil || !provision.CodeServerRequested(*cfg) {
return nil return nil
} }
@ -316,18 +315,6 @@ func ensureDevCodeServer(cfg *state.Config) error {
return nil return nil
} }
func devCodeServerRequested(cfg state.Config) bool {
if cfg.EnableCodeServer {
return true
}
for _, addon := range cfg.Addons {
if strings.EqualFold(addon, "codeserver") {
return true
}
}
return false
}
/* /*
-------------------------------------------------------------------------- --------------------------------------------------------------------------
/config the REAL provisioning trigger (async) /config the REAL provisioning trigger (async)
@ -864,49 +851,13 @@ func handleGamePlayers(w http.ResponseWriter, r *http.Request) {
return return
} }
ports := make([]int, 0, 3) ports := mcstatus.CandidatePorts(*cfg)
propsPath := filepath.Join(provision.ServerDir(*cfg), "server.properties") protocols := mcstatus.CandidateProtocols(cfg.Version)
if b, err := os.ReadFile(propsPath); err == nil {
lines := strings.Split(string(b), "\n")
for _, l := range lines {
if strings.HasPrefix(l, "server-port=") {
if p, err := strconv.Atoi(strings.TrimPrefix(l, "server-port=")); err == nil && p > 0 {
ports = append(ports, p)
}
break
}
}
}
if len(cfg.Ports) > 0 && cfg.Ports[0] > 0 {
ports = append(ports, cfg.Ports[0])
}
ports = append(ports, 25565)
seenPorts := make(map[int]struct{}, len(ports))
uniqPorts := make([]int, 0, len(ports))
for _, p := range ports {
if _, ok := seenPorts[p]; ok {
continue
}
seenPorts[p] = struct{}{}
uniqPorts = append(uniqPorts, p)
}
protocols := []int{mcstatus.ProtocolForVersion(cfg.Version), 767, 765, 763, 762, 754}
seenProtocols := make(map[int]struct{}, len(protocols))
uniqProtocols := make([]int, 0, len(protocols))
for _, pr := range protocols {
if _, ok := seenProtocols[pr]; ok {
continue
}
seenProtocols[pr] = struct{}{}
uniqProtocols = append(uniqProtocols, pr)
}
var status mcstatus.StatusResponse var status mcstatus.StatusResponse
var lastErr error var lastErr error
for _, port := range uniqPorts { for _, port := range ports {
for _, protocol := range uniqProtocols { for _, protocol := range protocols {
s, err := mcstatus.QueryStatus("127.0.0.1", port, protocol) s, err := mcstatus.QueryStatus("127.0.0.1", port, protocol)
if err != nil { if err != nil {
lastErr = err lastErr = err

View File

@ -15,9 +15,8 @@ import (
func WaitUntilReady(cfg state.Config, timeout, interval time.Duration) error { func WaitUntilReady(cfg state.Config, timeout, interval time.Duration) error {
start := time.Now() start := time.Now()
ports := candidatePorts(cfg) ports := CandidatePorts(cfg)
protocols := []int{ProtocolForVersion(cfg.Version), 767, 765, 763, 762, 754} protocols := CandidateProtocols(cfg.Version)
protocols = dedupeInts(protocols)
attempt := 0 attempt := 0
deadline := start.Add(timeout) deadline := start.Add(timeout)
@ -50,14 +49,14 @@ func WaitUntilReady(cfg state.Config, timeout, interval time.Duration) error {
} }
} }
func candidatePorts(cfg state.Config) []int { func CandidatePorts(cfg state.Config) []int {
ports := make([]int, 0, 3) ports := make([]int, 0, 3)
propsPath := filepath.Join(provision.ServerDir(cfg), "server.properties") propsPath := filepath.Join(provision.ServerDir(cfg), "server.properties")
if b, err := os.ReadFile(propsPath); err == nil { if b, err := os.ReadFile(propsPath); err == nil {
lines := strings.Split(string(b), "\n") lines := strings.SplitSeq(string(b), "\n")
for _, l := range lines { for l := range lines {
if strings.HasPrefix(l, "server-port=") { if after, ok := strings.CutPrefix(l, "server-port="); ok {
if p, err := strconv.Atoi(strings.TrimPrefix(l, "server-port=")); err == nil && p > 0 { if p, err := strconv.Atoi(after); err == nil && p > 0 {
ports = append(ports, p) ports = append(ports, p)
} }
break break
@ -71,6 +70,10 @@ func candidatePorts(cfg state.Config) []int {
return dedupeInts(ports) return dedupeInts(ports)
} }
func CandidateProtocols(version string) []int {
return dedupeInts([]int{ProtocolForVersion(version), 767, 765, 763, 762, 754})
}
func dedupeInts(in []int) []int { func dedupeInts(in []int) []int {
seen := make(map[int]struct{}, len(in)) seen := make(map[int]struct{}, len(in))
out := make([]int, 0, len(in)) out := make([]int, 0, len(in))

View File

@ -45,7 +45,7 @@ func ProtocolForVersion(version string) int {
} }
func QueryStatus(host string, port int, protocol int) (StatusResponse, error) { func QueryStatus(host string, port int, protocol int) (StatusResponse, error) {
addr := fmt.Sprintf("%s:%d", host, port) addr := net.JoinHostPort(host, fmt.Sprintf("%d", port))
conn, err := net.DialTimeout("tcp", addr, 3*time.Second) conn, err := net.DialTimeout("tcp", addr, 3*time.Second)
if err != nil { if err != nil {
return StatusResponse{}, err return StatusResponse{}, err

View File

@ -307,8 +307,8 @@ func validateExpectedHash(v string) error {
func normalizeExpectedHash(raw string, expectedLen int, prefix string) (string, error) { func normalizeExpectedHash(raw string, expectedLen int, prefix string) (string, error) {
v := strings.TrimSpace(strings.ToLower(raw)) v := strings.TrimSpace(strings.ToLower(raw))
if strings.HasPrefix(v, prefix+":") { if after, ok := strings.CutPrefix(v, prefix+":"); ok {
v = strings.TrimPrefix(v, prefix+":") v = after
} }
if len(v) != expectedLen { if len(v) != expectedLen {
return "", fmt.Errorf("%s must include %d hex characters", prefix, expectedLen) return "", fmt.Errorf("%s must include %d hex characters", prefix, expectedLen)
@ -407,12 +407,12 @@ func uniqueRemovedPath(dir, filename string) string {
} }
base := filename base := filename
ext := "" ext := ""
if strings.HasSuffix(filename, ".disabled") { if before, ok := strings.CutSuffix(filename, ".disabled"); ok {
base = strings.TrimSuffix(filename, ".disabled") base = before
ext = ".disabled" ext = ".disabled"
} }
if strings.HasSuffix(base, ".jar") { if before, ok := strings.CutSuffix(base, ".jar"); ok {
base = strings.TrimSuffix(base, ".jar") base = before
ext = ".jar" + ext ext = ".jar" + ext
} }
ts := time.Now().UTC().Format("20060102T150405") ts := time.Now().UTC().Format("20060102T150405")

View File

@ -123,8 +123,8 @@ func mergeFabricMetadata(out *jarMetadata, b []byte) {
} }
func mergeModsTOMLMetadata(out *jarMetadata, b []byte) { func mergeModsTOMLMetadata(out *jarMetadata, b []byte) {
lines := strings.Split(string(b), "\n") lines := strings.SplitSeq(string(b), "\n")
for _, raw := range lines { for raw := range lines {
line := strings.TrimSpace(raw) line := strings.TrimSpace(raw)
if line == "" || strings.HasPrefix(line, "#") { if line == "" || strings.HasPrefix(line, "#") {
continue continue
@ -182,8 +182,8 @@ func mergeModInfoMap(out *jarMetadata, obj map[string]any) {
} }
func mergePluginYAMLMetadata(out *jarMetadata, b []byte) { func mergePluginYAMLMetadata(out *jarMetadata, b []byte) {
lines := strings.Split(string(b), "\n") lines := strings.SplitSeq(string(b), "\n")
for _, raw := range lines { for raw := range lines {
line := strings.TrimSpace(raw) line := strings.TrimSpace(raw)
if line == "" || strings.HasPrefix(line, "#") { if line == "" || strings.HasPrefix(line, "#") {
continue continue

View File

@ -10,6 +10,7 @@ import (
"os/exec" "os/exec"
"os/user" "os/user"
"path/filepath" "path/filepath"
"slices"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -154,11 +155,9 @@ func ValidateRuntimeSelection(cfg state.Config) error {
for _, runtime := range catalog.Runtimes { for _, runtime := range catalog.Runtimes {
if strings.EqualFold(runtime.ID, runtimeID) { if strings.EqualFold(runtime.ID, runtimeID) {
for _, candidate := range runtime.Versions { if slices.Contains(runtime.Versions, version) {
if candidate == version { log.Printf("[provision] action=validate_runtime runtime=%s version=%s status=ok", runtimeID, version)
log.Printf("[provision] action=validate_runtime runtime=%s version=%s status=ok", runtimeID, version) return nil
return nil
}
} }
return fmt.Errorf("unsupported %s version: %s", runtimeID, version) return fmt.Errorf("unsupported %s version: %s", runtimeID, version)
} }

View File

@ -95,10 +95,7 @@ func WriteStartScript(cfg state.Config) error {
} }
xmx := mem xmx := mem
xms := mem / 2 xms := max(mem/2, 512)
if xms < 512 {
xms = 512
}
if xms > xmx { if xms > xmx {
xms = xmx xms = xmx
} }

View File

@ -300,10 +300,7 @@ func parseVersion(raw string) ([]int, error) {
} }
func compareVersionSlices(a, b []int) int { func compareVersionSlices(a, b []int) int {
maxLen := len(a) maxLen := max(len(b), len(a))
if len(b) > maxLen {
maxLen = len(b)
}
for i := 0; i < maxLen; i++ { for i := 0; i < maxLen; i++ {
ai := 0 ai := 0

View File

@ -151,7 +151,7 @@ func ProvisionAll(cfg state.Config) error {
/* --------------------------------------------------------- /* ---------------------------------------------------------
ADDONS (OPTIONAL, ROLE-AGNOSTIC) ADDONS (OPTIONAL, ROLE-AGNOSTIC)
--------------------------------------------------------- */ --------------------------------------------------------- */
if strings.EqualFold(cfg.ContainerType, "dev") && codeServerRequested(cfg) { if strings.EqualFold(cfg.ContainerType, "dev") && CodeServerRequested(cfg) {
seen := false seen := false
for _, addon := range cfg.Addons { for _, addon := range cfg.Addons {
if strings.EqualFold(addon, "codeserver") { if strings.EqualFold(addon, "codeserver") {
@ -173,7 +173,7 @@ func ProvisionAll(cfg state.Config) error {
return nil return nil
} }
func codeServerRequested(cfg state.Config) bool { func CodeServerRequested(cfg state.Config) bool {
if cfg.EnableCodeServer { if cfg.EnableCodeServer {
return true return true
} }

View File

@ -182,10 +182,7 @@ func minecraftHeap(memoryMB int) (xms int, xmx int) {
mem = 2048 mem = 2048
} }
xmx = mem xmx = mem
xms = mem / 2 xms = max(mem/2, 512)
if xms < 512 {
xms = 512
}
if xms > xmx { if xms > xmx {
xms = xmx xms = xmx
} }
@ -411,8 +408,8 @@ func GetConsolePTY(cfg *state.Config) (*os.File, error) {
} }
func WriteConsoleInput(cfg *state.Config, input string) error { func WriteConsoleInput(cfg *state.Config, input string) error {
if strings.HasSuffix(input, "\n") { if before, ok := strings.CutSuffix(input, "\n"); ok {
input = strings.TrimSuffix(input, "\n") input = before
} }
payload := []byte(input + "\n") payload := []byte(input + "\n")
@ -469,10 +466,7 @@ func buildCrashInfo(cfg *state.Config, waitErr error, startedAt time.Time) *stat
exitCode, signal := extractExitDetails(waitErr) exitCode, signal := extractExitDetails(waitErr)
uptime := int64(0) uptime := int64(0)
if !startedAt.IsZero() { if !startedAt.IsZero() {
uptime = int64(time.Since(startedAt).Seconds()) uptime = max(int64(time.Since(startedAt).Seconds()), 0)
if uptime < 0 {
uptime = 0
}
} }
logTail := tailLogLines(cfg, 40) logTail := tailLogLines(cfg, 40)

View File

@ -1,6 +1,6 @@
{ {
"status": "error", "status": "available",
"current": "0.0.0-dev", "current": "0.0.0-dev",
"error": "Get \"http://zlh-artifacts.internal.zlh:8080/agents/manifest.json\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)", "target": "1.0.68",
"checked_at_utc": "2026-04-19T11:18:03Z" "checked_at_utc": "2026-04-19T21:48:03Z"
} }