updates 4-6-26

This commit is contained in:
jester 2026-04-07 12:28:22 +00:00
parent c321a8d612
commit bb9b5deb62
23 changed files with 1087 additions and 82 deletions

View File

@ -131,6 +131,12 @@ func HandleGameFilesUpload(w http.ResponseWriter, r *http.Request) {
writeFilesError(w, err) writeFilesError(w, err)
return return
} }
if isVanillaModLocked(cfg) && isModsPath(normalizedPath) {
filesLogf(cfg, "action=upload path=%s overwrite=%t status=denied reason=vanilla_mod_policy", normalizedPath, strings.EqualFold(r.URL.Query().Get("overwrite"), "true"))
log.Printf("[mods] vmid=%d enforcement=vanilla user_mods_blocked=true", cfg.VMID)
writeJSONError(w, http.StatusForbidden, "Vanilla servers do not support user-installed mods")
return
}
overwrite := strings.EqualFold(r.URL.Query().Get("overwrite"), "true") overwrite := strings.EqualFold(r.URL.Query().Get("overwrite"), "true")
mr, err := r.MultipartReader() mr, err := r.MultipartReader()

View File

@ -0,0 +1,28 @@
package handlers
import (
"strings"
"zlh-agent/internal/state"
)
func isVanillaModLocked(cfg *state.Config) bool {
if cfg == nil {
return false
}
if !strings.EqualFold(cfg.ContainerType, "game") {
return false
}
if !strings.EqualFold(cfg.Game, "minecraft") {
return false
}
if strings.EqualFold(cfg.InternalProfile, "vanilla-fabric") {
return true
}
return strings.EqualFold(cfg.Variant, "vanilla")
}
func isModsPath(rel string) bool {
rel = strings.TrimSpace(rel)
return rel == "mods" || strings.HasPrefix(rel, "mods/")
}

View File

@ -51,6 +51,11 @@ func HandleGameModsInstall(w http.ResponseWriter, r *http.Request) {
if !ok { if !ok {
return return
} }
if isVanillaModLocked(cfg) {
modsLogf(cfg, "enforcement=vanilla user_mods_blocked=true action=install status=denied")
writeJSONError(w, http.StatusForbidden, "Vanilla servers do not support user-installed mods")
return
}
var req mods.InstallRequest var req mods.InstallRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil { if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
@ -148,6 +153,11 @@ func HandleGameModByID(w http.ResponseWriter, r *http.Request) {
if !ok { if !ok {
return return
} }
if isVanillaModLocked(cfg) {
modsLogf(cfg, "enforcement=vanilla user_mods_blocked=true action=%s status=denied", strings.ToLower(r.Method))
writeJSONError(w, http.StatusForbidden, "Vanilla servers do not support user-installed mods")
return
}
modID := strings.TrimPrefix(r.URL.Path, "/game/mods/") modID := strings.TrimPrefix(r.URL.Path, "/game/mods/")
if modID == "" || strings.Contains(modID, "/") || !mods.IsValidModID(modID) { if modID == "" || strings.Contains(modID, "/") || !mods.IsValidModID(modID) {

View File

@ -179,7 +179,7 @@ func ensureProvisioned(cfg *state.Config) error {
return runProvisionPipeline(cfg) return runProvisionPipeline(cfg)
} }
jar := filepath.Join(dir, "server.jar") jar := filepath.Join(dir, provision.ExpectedMinecraftJar(*cfg))
if fileExists(jar) { if fileExists(jar) {
return nil return nil
} }

View File

@ -58,7 +58,7 @@ func BuildArtifactURL(path string) string {
base := os.Getenv("ZLH_ARTIFACT_BASE_URL") base := os.Getenv("ZLH_ARTIFACT_BASE_URL")
if base == "" { if base == "" {
base = "http://10.60.0.251:8080/" base = "http://zlh-artifacts.internal.zlh:8080/"
} }
return strings.TrimRight(base, "/") + "/" + strings.TrimLeft(path, "/") return strings.TrimRight(base, "/") + "/" + strings.TrimLeft(path, "/")

View File

@ -10,7 +10,7 @@ import (
func launchEnv(cfg state.Config) []string { func launchEnv(cfg state.Config) []string {
extraEnv := []string{ extraEnv := []string{
"CODE_SERVER_PORT=8080", "CODE_SERVER_PORT=6000",
"CODE_SERVER_WORKSPACE=/home/dev/workspace", "CODE_SERVER_WORKSPACE=/home/dev/workspace",
} }
if cfg.VMID != 0 { if cfg.VMID != 0 {

View File

@ -79,7 +79,7 @@ func findRunningPID() (int, error) {
if !strings.Contains(cmdline, "code-server") { if !strings.Contains(cmdline, "code-server") {
continue continue
} }
if !strings.Contains(cmdline, "--bind-addr 0.0.0.0:8080") { if !strings.Contains(cmdline, "--bind-addr 0.0.0.0:6000") {
continue continue
} }

View File

@ -26,6 +26,17 @@ func BuildArtifactURL(path string) string {
return provcommon.BuildArtifactURL(path) return provcommon.BuildArtifactURL(path)
} }
func ExpectedMinecraftJar(cfg state.Config) string {
return "server.jar"
}
func MinecraftRuntime(cfg state.Config) string {
if runtime := strings.ToLower(strings.TrimSpace(cfg.Runtime)); runtime != "" {
return runtime
}
return strings.ToLower(strings.TrimSpace(cfg.Variant))
}
// Local fallback used ONLY inside this package — NOT exported. // Local fallback used ONLY inside this package — NOT exported.
func buildArtifactURL(path string) string { func buildArtifactURL(path string) string {
if strings.HasPrefix(path, "http://") || strings.HasPrefix(path, "https://") { if strings.HasPrefix(path, "http://") || strings.HasPrefix(path, "https://") {
@ -34,7 +45,7 @@ func buildArtifactURL(path string) string {
base := os.Getenv("ZLH_ARTIFACT_BASE_URL") base := os.Getenv("ZLH_ARTIFACT_BASE_URL")
if base == "" { if base == "" {
base = "http://10.60.0.251:8080/" // fallback base = "http://zlh-artifacts.internal.zlh:8080/" // fallback
} }
return strings.TrimRight(base, "/") + "/" + strings.TrimLeft(path, "/") return strings.TrimRight(base, "/") + "/" + strings.TrimLeft(path, "/")

View File

@ -10,7 +10,7 @@ import (
) )
/* /*
WriteEula writes eula.txt for all Minecraft variants. WriteEula writes eula.txt for all Minecraft variants.
*/ */
func WriteEula(cfg state.Config) error { func WriteEula(cfg state.Config) error {
dir := ServerDir(cfg) dir := ServerDir(cfg)
@ -23,9 +23,9 @@ func WriteEula(cfg state.Config) error {
} }
/* /*
WriteServerProperties writes server.properties for jar-based Minecraft servers. WriteServerProperties writes server.properties for jar-based Minecraft servers.
Forge/NeoForge generate their own, so they are skipped. Forge/NeoForge generate their own, so they are skipped.
*/ */
func WriteServerProperties(cfg state.Config) error { func WriteServerProperties(cfg state.Config) error {
variant := strings.ToLower(cfg.Variant) variant := strings.ToLower(cfg.Variant)
@ -68,9 +68,9 @@ max-players=20
} }
/* /*
WriteStartScript creates start.sh for all supported games. WriteStartScript creates start.sh for all supported games.
- Vanilla/Paper/Purpur/Fabric: exec java -jar server.jar - Vanilla/Paper/Purpur/Fabric: exec java -jar server.jar
- Forge/NeoForge: use JAVA_TOOL_OPTIONS and run.sh - Forge/NeoForge: use JAVA_TOOL_OPTIONS and run.sh
*/ */
func WriteStartScript(cfg state.Config) error { func WriteStartScript(cfg state.Config) error {
dir := ServerDir(cfg) dir := ServerDir(cfg)

View File

@ -0,0 +1,417 @@
package minecraft
import (
"crypto/sha256"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
"syscall"
"zlh-agent/internal/provcommon"
"zlh-agent/internal/state"
)
var (
fabricProxyArtifactRoot = "minecraft/fabric/fabric-proxy-lite"
fabricAPIArtifactPath = "minecraft/fabric/fabric-api/fabric-api.jar"
fabricProxyConfigPath = "minecraft/fabric/FabricProxy-Lite.toml"
)
var (
fabricProxyMapOnce sync.Once
fabricProxyMap map[string]string
fabricProxyMapErr error
)
func resolveProxyVersion(mcVersion string) (string, error) {
mappings, err := loadFabricProxyMap()
if err != nil {
return "", err
}
mcVersion = strings.TrimSpace(mcVersion)
if mcVersion == "" {
return "", fmt.Errorf("empty minecraft version")
}
compareVersion, err := parseVersion(mcVersion)
if err != nil {
return "", fmt.Errorf("invalid minecraft version %q: %w", mcVersion, err)
}
if version, ok := mappings[mcVersion]; ok {
return version, nil
}
for spec, version := range mappings {
start, end, ok := parseVersionRange(spec)
if !ok {
continue
}
if compareVersionSlices(compareVersion, start) >= 0 && compareVersionSlices(compareVersion, end) <= 0 {
return version, nil
}
}
return "", fmt.Errorf("no fabricproxy-lite mapping for minecraft version %q", mcVersion)
}
func InjectFabricProxyLite(cfg state.Config) error {
if !shouldInjectFabricProxyLite(cfg) {
return nil
}
modsDir, targetPath, err := ensureSystemModsDir(cfg)
if err != nil {
log.Printf("[mods] vmid=%d type=system name=fabricproxy-lite error=%v", cfg.VMID, err)
return err
}
version, err := resolveProxyVersion(cfg.Version)
if err != nil {
log.Printf("[mods] vmid=%d type=system name=fabricproxy-lite error=%v", cfg.VMID, err)
return err
}
source := proxyArtifactURL(version)
log.Printf("[mods] vmid=%d type=system name=fabricproxy-lite source=artifact version=%s", cfg.VMID, version)
if err := installSystemMod(source, targetPath, modsDir); err != nil {
err = fmt.Errorf("install fabricproxy-lite: %w", err)
log.Printf("[mods] vmid=%d type=system name=fabricproxy-lite error=%v", cfg.VMID, err)
return err
}
log.Printf("[mods] vmid=%d type=system name=fabricproxy-lite installed=true", cfg.VMID)
fabricAPIPath := filepath.Join(modsDir, "fabric-api.jar")
log.Printf("[mods] vmid=%d type=system name=fabric-api source=artifact", cfg.VMID)
if err := installSystemMod(provcommon.BuildArtifactURL(fabricAPIArtifactPath), fabricAPIPath, modsDir); err != nil {
err = fmt.Errorf("install fabric-api: %w", err)
log.Printf("[mods] vmid=%d type=system name=fabric-api error=%v", cfg.VMID, err)
return err
}
log.Printf("[mods] vmid=%d type=system name=fabric-api installed=true", cfg.VMID)
if err := installFabricProxyConfig(cfg); err != nil {
log.Printf("[mods] vmid=%d type=system name=fabricproxy-lite-config error=%v", cfg.VMID, err)
return err
}
return nil
}
func shouldInjectFabricProxyLite(cfg state.Config) bool {
if !strings.EqualFold(cfg.ContainerType, "game") {
return false
}
if !strings.EqualFold(cfg.Game, "minecraft") {
return false
}
return strings.EqualFold(cfg.InternalProfile, "vanilla-fabric")
}
func loadFabricProxyMap() (map[string]string, error) {
fabricProxyMapOnce.Do(func() {
raw, err := fetchArtifact(proxyMapURL())
if err != nil {
fabricProxyMapErr = fmt.Errorf("read fabricproxy-lite map: %w", err)
return
}
var mappings map[string]string
if err := json.Unmarshal(raw, &mappings); err != nil {
fabricProxyMapErr = fmt.Errorf("parse fabricproxy-lite map: %w", err)
return
}
if len(mappings) == 0 {
fabricProxyMapErr = fmt.Errorf("fabricproxy-lite map is empty")
return
}
for spec, version := range mappings {
spec = strings.TrimSpace(spec)
version = strings.TrimSpace(version)
if spec == "" || version == "" {
fabricProxyMapErr = fmt.Errorf("fabricproxy-lite map contains empty key or value")
return
}
if start, end, ok := parseVersionRange(spec); ok {
if compareVersionSlices(start, end) > 0 {
fabricProxyMapErr = fmt.Errorf("invalid fabricproxy-lite range %q", spec)
return
}
continue
}
if _, err := parseVersion(spec); err != nil {
fabricProxyMapErr = fmt.Errorf("invalid fabricproxy-lite version key %q: %w", spec, err)
return
}
}
fabricProxyMap = mappings
})
if fabricProxyMapErr != nil {
return nil, fabricProxyMapErr
}
return fabricProxyMap, nil
}
func proxyMapURL() string {
return provcommon.BuildArtifactURL(filepath.ToSlash(filepath.Join(fabricProxyArtifactRoot, "map.json")))
}
func proxyArtifactURL(version string) string {
rel := filepath.ToSlash(filepath.Join(
fabricProxyArtifactRoot,
version,
fmt.Sprintf("FabricProxy-Lite-%s.jar", version),
))
return provcommon.BuildArtifactURL(rel)
}
func ensureSystemModsDir(cfg state.Config) (string, string, error) {
serverDir := provcommon.ServerDir(cfg)
info, err := os.Stat(serverDir)
if err != nil {
return "", "", fmt.Errorf("stat server dir: %w", err)
}
modsDir := filepath.Join(serverDir, "mods")
created := false
if _, err := os.Stat(modsDir); err != nil {
if !os.IsNotExist(err) {
return "", "", fmt.Errorf("stat mods dir: %w", err)
}
created = true
}
if err := os.MkdirAll(modsDir, info.Mode().Perm()); err != nil {
return "", "", fmt.Errorf("create mods dir: %w", err)
}
if err := syncOwnershipAndPerms(modsDir, info); err != nil {
return "", "", fmt.Errorf("sync mods dir ownership: %w", err)
}
log.Printf("[provision] vmid=%d profile=vanilla-fabric step=mods_dir created=%t", cfg.VMID, created)
return modsDir, filepath.Join(modsDir, "fabricproxy-lite.jar"), nil
}
func installFabricProxyConfig(cfg state.Config) error {
serverDir := provcommon.ServerDir(cfg)
info, err := os.Stat(serverDir)
if err != nil {
return fmt.Errorf("stat server dir: %w", err)
}
configDir := filepath.Join(serverDir, "config")
created := false
if _, err := os.Stat(configDir); err != nil {
if !os.IsNotExist(err) {
return fmt.Errorf("stat config dir: %w", err)
}
created = true
}
if err := os.MkdirAll(configDir, info.Mode().Perm()); err != nil {
return fmt.Errorf("create config dir: %w", err)
}
if err := syncOwnershipAndPerms(configDir, info); err != nil {
return fmt.Errorf("sync config dir ownership: %w", err)
}
targetPath := filepath.Join(configDir, "FabricProxy-Lite.toml")
if err := installSystemFile(provcommon.BuildArtifactURL(fabricProxyConfigPath), targetPath, configDir, 0o644); err != nil {
return fmt.Errorf("install FabricProxy-Lite.toml: %w", err)
}
log.Printf("[provision] vmid=%d profile=vanilla-fabric step=config_dir created=%t", cfg.VMID, created)
log.Printf("[mods] vmid=%d type=system name=FabricProxy-Lite.toml installed=true", cfg.VMID)
return nil
}
func parseVersionRange(spec string) ([]int, []int, bool) {
parts := strings.Split(spec, "-")
if len(parts) != 2 {
return nil, nil, false
}
start, err := parseVersion(parts[0])
if err != nil {
return nil, nil, false
}
end, err := parseVersion(parts[1])
if err != nil {
return nil, nil, false
}
return start, end, true
}
func parseVersion(raw string) ([]int, error) {
raw = strings.TrimSpace(raw)
if raw == "" {
return nil, fmt.Errorf("empty version")
}
parts := strings.Split(raw, ".")
out := make([]int, 0, len(parts))
for _, part := range parts {
part = strings.TrimSpace(part)
if part == "" {
return nil, fmt.Errorf("invalid version %q", raw)
}
n, err := strconv.Atoi(part)
if err != nil {
return nil, fmt.Errorf("invalid version segment %q", part)
}
out = append(out, n)
}
return out, nil
}
func compareVersionSlices(a, b []int) int {
maxLen := len(a)
if len(b) > maxLen {
maxLen = len(b)
}
for i := 0; i < maxLen; i++ {
ai := 0
if i < len(a) {
ai = a[i]
}
bi := 0
if i < len(b) {
bi = b[i]
}
switch {
case ai < bi:
return -1
case ai > bi:
return 1
}
}
return 0
}
func fetchArtifact(url string) ([]byte, error) {
client := &http.Client{}
resp, err := client.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("status %d", resp.StatusCode)
}
return io.ReadAll(resp.Body)
}
func installSystemMod(url, dst, modsDir string) error {
payload, err := fetchArtifact(url)
if err != nil {
return err
}
if same, err := sameFileChecksum(dst, payload); err == nil && same {
return syncFileOwnership(dst, modsDir)
}
tmp, err := os.CreateTemp(filepath.Dir(dst), "fabricproxy-lite-*.jar")
if err != nil {
return err
}
tmpPath := tmp.Name()
defer func() {
_ = os.Remove(tmpPath)
}()
if _, err := tmp.Write(payload); err != nil {
_ = tmp.Close()
return err
}
if err := tmp.Close(); err != nil {
return err
}
if err := os.Rename(tmpPath, dst); err != nil {
return err
}
return syncFileOwnership(dst, modsDir)
}
func installSystemFile(url, dst, referenceDir string, mode os.FileMode) error {
payload, err := fetchArtifact(url)
if err != nil {
return err
}
if same, err := sameFileChecksum(dst, payload); err == nil && same {
return syncFileOwnershipWithMode(dst, referenceDir, mode)
}
tmp, err := os.CreateTemp(filepath.Dir(dst), "zlh-system-file-*")
if err != nil {
return err
}
tmpPath := tmp.Name()
defer func() {
_ = os.Remove(tmpPath)
}()
if _, err := tmp.Write(payload); err != nil {
_ = tmp.Close()
return err
}
if err := tmp.Close(); err != nil {
return err
}
if err := os.Rename(tmpPath, dst); err != nil {
return err
}
return syncFileOwnershipWithMode(dst, referenceDir, mode)
}
func sameFileChecksum(path string, payload []byte) (bool, error) {
current, err := os.ReadFile(path)
if err != nil {
return false, err
}
currentSum := sha256.Sum256(current)
newSum := sha256.Sum256(payload)
return currentSum == newSum, nil
}
func syncOwnershipAndPerms(path string, info os.FileInfo) error {
if err := os.Chmod(path, info.Mode().Perm()); err != nil {
return err
}
stat, ok := info.Sys().(*syscall.Stat_t)
if !ok {
return nil
}
return os.Chown(path, int(stat.Uid), int(stat.Gid))
}
func syncFileOwnership(path, referenceDir string) error {
return syncFileOwnershipWithMode(path, referenceDir, 0o644)
}
func syncFileOwnershipWithMode(path, referenceDir string, mode os.FileMode) error {
info, err := os.Stat(referenceDir)
if err != nil {
return err
}
if err := os.Chmod(path, mode); err != nil {
return err
}
stat, ok := info.Sys().(*syscall.Stat_t)
if !ok {
return nil
}
return os.Chown(path, int(stat.Uid), int(stat.Gid))
}

View File

@ -0,0 +1,78 @@
package minecraft
import (
"net/http"
"net/http/httptest"
"strings"
"sync"
"testing"
)
func TestResolveProxyVersion(t *testing.T) {
data := `{
"1.20.1": "2.6.0",
"1.20.2-1.20.4": "2.7.0",
"1.20.5": "2.8.0",
"1.21.0-1.21.8": "2.9.0"
}`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/zpacks/minecraft/fabric/fabric-proxy-lite/map.json" {
http.NotFound(w, r)
return
}
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(data))
}))
defer server.Close()
t.Setenv("ZLH_ARTIFACT_BASE_URL", server.URL)
origRoot := fabricProxyArtifactRoot
origMap := fabricProxyMap
origErr := fabricProxyMapErr
origOnce := fabricProxyMapOnce
fabricProxyArtifactRoot = "zpacks/minecraft/fabric/fabric-proxy-lite"
fabricProxyMap = nil
fabricProxyMapErr = nil
fabricProxyMapOnce = sync.Once{}
t.Cleanup(func() {
fabricProxyArtifactRoot = origRoot
fabricProxyMap = origMap
fabricProxyMapErr = origErr
fabricProxyMapOnce = origOnce
})
tests := []struct {
name string
version string
want string
wantErr string
}{
{name: "exact match", version: "1.20.1", want: "2.6.0"},
{name: "range lower bound", version: "1.20.2", want: "2.7.0"},
{name: "range middle", version: "1.20.3", want: "2.7.0"},
{name: "range upper bound", version: "1.21.8", want: "2.9.0"},
{name: "missing", version: "1.19.4", wantErr: "no fabricproxy-lite mapping"},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
fabricProxyMap = nil
fabricProxyMapErr = nil
fabricProxyMapOnce = sync.Once{}
got, err := resolveProxyVersion(tc.version)
if tc.wantErr != "" {
if err == nil || !strings.Contains(err.Error(), tc.wantErr) {
t.Fatalf("expected error containing %q, got %v", tc.wantErr, err)
}
return
}
if err != nil {
t.Fatalf("resolveProxyVersion(%q) error = %v", tc.version, err)
}
if got != tc.want {
t.Fatalf("resolveProxyVersion(%q) = %q, want %q", tc.version, got, tc.want)
}
})
}
}

View File

@ -7,11 +7,11 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"zlh-agent/internal/state"
"zlh-agent/internal/provcommon" "zlh-agent/internal/provcommon"
"zlh-agent/internal/state"
) )
func InstallMinecraftVanilla(cfg state.Config) error { func InstallMinecraftJar(cfg state.Config) error {
dir := provcommon.ServerDir(cfg) dir := provcommon.ServerDir(cfg)
if err := os.MkdirAll(dir, 0o755); err != nil { if err := os.MkdirAll(dir, 0o755); err != nil {
return fmt.Errorf("mkdir server dir: %w", err) return fmt.Errorf("mkdir server dir: %w", err)
@ -22,7 +22,7 @@ func InstallMinecraftVanilla(cfg state.Config) error {
resp, err := http.Get(url) resp, err := http.Get(url)
if err != nil { if err != nil {
return fmt.Errorf("download vanilla: %w", err) return fmt.Errorf("download server jar: %w", err)
} }
defer resp.Body.Close() defer resp.Body.Close()
@ -40,11 +40,16 @@ func InstallMinecraftVanilla(cfg state.Config) error {
return fmt.Errorf("write server.jar: %w", err) return fmt.Errorf("write server.jar: %w", err)
} }
// 🔹 NEW: verify + self-repair (java, server.jar, start.sh, etc.)
if err := VerifyMinecraftInstallWithRepair(cfg); err != nil { if err := VerifyMinecraftInstallWithRepair(cfg); err != nil {
return fmt.Errorf("vanilla install verification failed: %w", err) return fmt.Errorf("jar install verification failed: %w", err)
} }
return nil return nil
} }
func InstallFabric(cfg state.Config) error {
if err := InstallMinecraftJar(cfg); err != nil {
return fmt.Errorf("fabric install failed: %w", err)
}
return nil
}

View File

@ -64,12 +64,24 @@ func VerifyMinecraftInstallWithRepair(cfg state.Config) error {
func verifyMinecraftInstallOnce(cfg state.Config) error { func verifyMinecraftInstallOnce(cfg state.Config) error {
dir := provcommon.ServerDir(cfg) dir := provcommon.ServerDir(cfg)
variant := strings.ToLower(cfg.Variant) variant := strings.ToLower(cfg.Variant)
runtime := strings.ToLower(strings.TrimSpace(cfg.Runtime))
if runtime == "" {
runtime = variant
}
fmt.Printf("[verify] runtime=%s\n", runtime)
// Java symlink must exist // Java symlink must exist
if err := verifyJavaSymlink(); err != nil { if err := verifyJavaSymlink(); err != nil {
return err return err
} }
if runtime == "fabric" {
if err := verifyServerJar(cfg, dir); err != nil {
return err
}
return nil
}
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// VANILLA / PAPER / PURPUR / FABRIC / QUILT → *ONLY REQUIRE server.jar* // VANILLA / PAPER / PURPUR / FABRIC / QUILT → *ONLY REQUIRE server.jar*
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@ -79,7 +91,7 @@ func verifyMinecraftInstallOnce(cfg state.Config) error {
variant == "fabric" || variant == "fabric" ||
variant == "quilt" { variant == "quilt" {
if err := verifyServerJar(dir); err != nil { if err := verifyServerJar(cfg, dir); err != nil {
return err return err
} }
@ -137,11 +149,13 @@ func verifyJavaSymlink() error {
// Vanilla-like variants: require ONLY server.jar // Vanilla-like variants: require ONLY server.jar
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
func verifyServerJar(dir string) error { func verifyServerJar(cfg state.Config, dir string) error {
jar := filepath.Join(dir, "server.jar") jarName := "server.jar"
jar := filepath.Join(dir, jarName)
if _, err := os.Stat(jar); err != nil { if _, err := os.Stat(jar); err != nil {
return fmt.Errorf("server.jar missing in %s: %w", dir, err) return fmt.Errorf("%s missing in %s: %w", jarName, dir, err)
} }
fmt.Printf("[verify] found=%s\n", jarName)
return nil return nil
} }

View File

@ -2,6 +2,7 @@ package provision
import ( import (
"fmt" "fmt"
"log"
"strings" "strings"
"zlh-agent/internal/provision/addons" "zlh-agent/internal/provision/addons"
@ -19,6 +20,7 @@ IMPORTANT:
- state.Config is treated as immutable desired state. - state.Config is treated as immutable desired state.
*/ */
func ProvisionAll(cfg state.Config) error { func ProvisionAll(cfg state.Config) error {
normalizeMinecraftConfig(&cfg)
/* --------------------------------------------------------- /* ---------------------------------------------------------
BASE ROLE PROVISIONING BASE ROLE PROVISIONING
@ -34,6 +36,7 @@ func ProvisionAll(cfg state.Config) error {
// Legacy / default behavior assumes game containers // Legacy / default behavior assumes game containers
game := strings.ToLower(cfg.Game) game := strings.ToLower(cfg.Game)
variant := strings.ToLower(cfg.Variant) variant := strings.ToLower(cfg.Variant)
runtime := strings.ToLower(cfg.Runtime)
/* --------------------------------------------------------- /* ---------------------------------------------------------
MINECRAFT MINECRAFT
@ -47,10 +50,25 @@ func ProvisionAll(cfg state.Config) error {
// 2. Game variant install // 2. Game variant install
switch variant { switch variant {
case "vanilla":
if runtime != "fabric" {
return fmt.Errorf("unsupported runtime: %s", cfg.Runtime)
}
if err := minecraft.InstallFabric(cfg); err != nil {
return err
}
if err := minecraft.InjectFabricProxyLite(cfg); err != nil {
return fmt.Errorf("fabricproxy-lite injection failed: %w", err)
}
case "vanilla", "paper", "purpur", "fabric", "quilt": case "fabric":
if err := minecraft.InstallMinecraftVanilla(cfg); err != nil { if err := minecraft.InstallFabric(cfg); err != nil {
return fmt.Errorf("minecraft vanilla install failed: %w", err) return err
}
case "paper", "purpur", "quilt":
if err := minecraft.InstallMinecraftJar(cfg); err != nil {
return fmt.Errorf("minecraft jar install failed: %w", err)
} }
case "forge": case "forge":
@ -154,3 +172,25 @@ func ProvisionAll(cfg state.Config) error {
return nil return nil
} }
func normalizeMinecraftConfig(cfg *state.Config) {
if cfg == nil {
return
}
if !strings.EqualFold(cfg.ContainerType, "game") {
return
}
if !strings.EqualFold(cfg.Game, "minecraft") {
return
}
if !strings.EqualFold(cfg.Variant, "vanilla") {
return
}
cfg.Runtime = "fabric"
cfg.InternalProfile = "vanilla-fabric"
cfg.ArtifactPath = fmt.Sprintf("minecraft/fabric/%s/server.jar", strings.TrimSpace(cfg.Version))
log.Printf("[provision] vmid=%d action=normalize original_variant=vanilla runtime=fabric profile=vanilla-fabric", cfg.VMID)
log.Printf("[provision] vmid=%d variant=vanilla normalized_runtime=fabric", cfg.VMID)
log.Printf("[provision] vmid=%d artifact_override=true source=fabric path=%s", cfg.VMID, cfg.ArtifactPath)
}

View File

@ -22,6 +22,7 @@ type Config struct {
// Dev runtime (only for dev containers) // Dev runtime (only for dev containers)
Runtime string `json:"runtime,omitempty"` Runtime string `json:"runtime,omitempty"`
InternalProfile string `json:"internal_profile,omitempty"`
Version string `json:"version"` Version string `json:"version"`
// OPTIONAL addons (role-agnostic) // OPTIONAL addons (role-agnostic)

View File

@ -9,6 +9,7 @@ import (
"os/exec" "os/exec"
"os/user" "os/user"
"path/filepath" "path/filepath"
"sort"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -62,8 +63,10 @@ func StartServer(cfg *state.Config) error {
startScript := filepath.Join(dir, "start.sh") startScript := filepath.Join(dir, "start.sh")
log.Printf("[process] vmid=%d server start requested dir=%s", cfg.VMID, dir) log.Printf("[process] vmid=%d server start requested dir=%s", cfg.VMID, dir)
cmd := exec.Command("/bin/bash", startScript) cmd, err := buildServerCommand(cfg, dir, startScript)
cmd.Dir = dir if err != nil {
return err
}
ptmx, err := runtime.CreatePTY(cmd) ptmx, err := runtime.CreatePTY(cmd)
if err != nil { if err != nil {
@ -88,6 +91,73 @@ func StartServer(cfg *state.Config) error {
return nil return nil
} }
func buildServerCommand(cfg *state.Config, dir, startScript string) (*exec.Cmd, error) {
variant := strings.ToLower(strings.TrimSpace(cfg.Variant))
if variant == "forge" || variant == "neoforge" {
cmd := exec.Command("/bin/bash", startScript)
cmd.Dir = dir
return cmd, nil
}
if strings.EqualFold(cfg.Game, "minecraft") {
runtimeType := provision.MinecraftRuntime(*cfg)
jarPath, err := resolveMinecraftRuntimeJar(runtimeType, dir)
if err != nil {
return nil, err
}
xms, xmx := minecraftHeap(cfg.MemoryMB)
javaBin := filepath.Join(provision.JavaRoot, "java")
cmd := exec.Command(javaBin,
fmt.Sprintf("-Xms%dM", xms),
fmt.Sprintf("-Xmx%dM", xmx),
"-jar", jarPath, "nogui",
)
cmd.Dir = dir
return cmd, nil
}
cmd := exec.Command("/bin/bash", startScript)
cmd.Dir = dir
return cmd, nil
}
func resolveMinecraftRuntimeJar(runtimeType, dir string) (string, error) {
if runtimeType == "fabric" {
matches, err := filepath.Glob(filepath.Join(dir, ".fabric", "server", "fabric-loader-server-*.jar"))
if err != nil {
return "", fmt.Errorf("fabric runtime selected but loader scan failed: %w", err)
}
if len(matches) == 0 {
log.Printf("[runtime] ERROR missing fabric loader jar")
return "", fmt.Errorf("fabric runtime selected but no fabric loader jar found")
}
sort.Strings(matches)
loader := matches[len(matches)-1]
log.Printf("[runtime] type=fabric loader=%s", loader)
return loader, nil
}
log.Printf("[runtime] type=%s jar=server.jar", runtimeType)
return filepath.Join(dir, "server.jar"), nil
}
func minecraftHeap(memoryMB int) (xms int, xmx int) {
mem := memoryMB
if mem <= 0 {
mem = 2048
}
xmx = mem
xms = mem / 2
if xms < 512 {
xms = 512
}
if xms > xmx {
xms = xmx
}
return xms, xmx
}
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
StopServer StopServer
----------------------------------------------------------------------------*/ ----------------------------------------------------------------------------*/

View File

@ -20,7 +20,7 @@ import (
) )
const ( const (
artifactBaseURL = "http://10.60.0.251:8080/agents/" defaultArtifactBaseURL = "http://zlh-artifacts.internal.zlh:8080"
releasesDir = "/opt/zlh-agent/releases" releasesDir = "/opt/zlh-agent/releases"
currentLink = "/opt/zlh-agent/current" currentLink = "/opt/zlh-agent/current"
previousLink = "/opt/zlh-agent/previous" previousLink = "/opt/zlh-agent/previous"
@ -54,6 +54,14 @@ type Result struct {
CheckedAtUTC string `json:"checked_at_utc,omitempty"` CheckedAtUTC string `json:"checked_at_utc,omitempty"`
} }
func artifactBaseURL() string {
base := strings.TrimSpace(os.Getenv("ZLH_ARTIFACT_BASE_URL"))
if base == "" {
base = defaultArtifactBaseURL
}
return strings.TrimRight(base, "/") + "/agents/"
}
func CheckAvailable(currentVersion string) Result { func CheckAvailable(currentVersion string) Result {
currentVersion = normalizeVersion(currentVersion) currentVersion = normalizeVersion(currentVersion)
result := Result{ result := Result{
@ -248,8 +256,9 @@ func CheckAndUpdate(currentVersion string) Result {
tmpPath := filepath.Join(releasesDir, target, "zlh-agent.new") tmpPath := filepath.Join(releasesDir, target, "zlh-agent.new")
finalPath := filepath.Join(releasesDir, target, "zlh-agent") finalPath := filepath.Join(releasesDir, target, "zlh-agent")
binURL := artifactBaseURL + binPath baseURL := artifactBaseURL()
shaURL := artifactBaseURL + shaPath binURL := baseURL + binPath
shaURL := baseURL + shaPath
if err := downloadFile(binURL, tmpPath); err != nil { if err := downloadFile(binURL, tmpPath); err != nil {
result.Error = fmt.Sprintf("download binary: %v", err) result.Error = fmt.Sprintf("download binary: %v", err)
@ -326,7 +335,7 @@ func CheckAndUpdate(currentVersion string) Result {
} }
func fetchManifest() (Manifest, error) { func fetchManifest() (Manifest, error) {
url := artifactBaseURL + "manifest.json" url := artifactBaseURL() + "manifest.json"
client := &http.Client{Timeout: 10 * time.Second} client := &http.Client{Timeout: 10 * time.Second}
resp, err := client.Get(url) resp, err := client.Get(url)
if err != nil { if err != nil {

View File

@ -0,0 +1,310 @@
2026/04/01 12:50:51 [agent] file logging enabled
2026/04/01 12:50:51 [agent] lifecycle logging enabled
2026/04/01 12:50:51 [agent] routes registered
2026/04/01 12:50:51 [autostart] disabled (ok)
2026/04/01 12:50:51 [update] periodic checks enabled (mode=notify interval=30m0s)
2026/04/01 12:50:51 [agent] listening on :18888
2026/04/01 12:51:04 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 13:21:07 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 13:51:08 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 14:02:16 [agent] shutdown signal received
2026/04/01 14:02:16 [agent] http server stopped gracefully
2026/04/01 14:02:16 [agent] exiting
2026/04/01 14:02:26 [agent] file logging enabled
2026/04/01 14:02:26 [agent] lifecycle logging enabled
2026/04/01 14:02:26 [agent] routes registered
2026/04/01 14:02:26 [autostart] disabled (ok)
2026/04/01 14:02:26 [update] periodic checks enabled (mode=notify interval=30m0s)
2026/04/01 14:02:26 [agent] listening on :18888
2026/04/01 14:02:39 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 14:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 15:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 15:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 16:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 16:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 17:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 17:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 18:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 18:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 19:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 19:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 20:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 20:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 21:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 21:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 22:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 22:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 23:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/01 23:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 00:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 00:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 01:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 01:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 02:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 02:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 03:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 03:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 04:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 04:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 05:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 05:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 06:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 06:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 07:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 07:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 08:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 08:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 09:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 09:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 10:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 10:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 11:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 11:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 12:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 12:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 13:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 13:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 14:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 14:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 15:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 15:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 16:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 16:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 17:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 17:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 18:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 18:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 19:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 19:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 20:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 20:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 21:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 21:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 22:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 22:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 23:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/02 23:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 00:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 00:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 01:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 01:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 02:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 02:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 03:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 03:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 04:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 04:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 05:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 05:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 06:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 06:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 07:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 07:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 08:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 08:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 09:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 09:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 10:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 10:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 11:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 11:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 12:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 12:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 13:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 13:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 14:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 14:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 15:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 15:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 16:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 16:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 17:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 17:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 18:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 18:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 19:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 19:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 20:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 20:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 21:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 21:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 22:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 22:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 23:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/03 23:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 00:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 00:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 01:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 01:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 02:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 02:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 03:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 03:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 04:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 04:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 05:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 05:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 06:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 06:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 07:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 07:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 08:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 08:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 09:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 09:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 10:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 10:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 11:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 11:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 12:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 12:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 13:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 13:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 14:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 14:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 15:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 15:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 16:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 16:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 17:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 17:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 18:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 18:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 19:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 19:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 20:02:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 20:32:42 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 21:02:43 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 21:23:54 [agent] file logging enabled
2026/04/04 21:23:54 [agent] lifecycle logging enabled
2026/04/04 21:23:54 [agent] routes registered
2026/04/04 21:23:54 [autostart] disabled (ok)
2026/04/04 21:23:54 [update] periodic checks enabled (mode=notify interval=30m0s)
2026/04/04 21:23:54 [agent] listening on :18888
2026/04/04 21:24:07 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 21:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 22:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 22:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 23:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/04 23:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 00:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 00:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 01:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 01:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 02:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 02:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 03:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 03:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 04:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 04:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 05:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 05:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 06:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 06:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 07:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 07:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 08:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 08:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 09:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 09:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 10:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 10:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 11:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 11:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 12:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 12:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 13:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 13:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 14:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 14:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 15:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 15:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 16:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 16:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 17:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 17:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 18:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 18:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 19:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 19:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 20:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 20:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 21:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 21:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 22:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 22:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 23:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/05 23:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 00:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 00:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 01:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 01:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 02:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 02:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 03:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 03:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 04:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 04:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 05:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 05:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 06:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 06:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 07:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 07:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 08:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 08:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 09:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 09:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 10:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 10:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 11:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 11:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 12:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 12:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 13:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 13:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 14:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 14:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 15:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 15:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 16:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 16:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 17:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 17:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 18:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 18:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 19:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 19:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 20:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 20:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 21:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 21:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 22:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 22:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 23:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/06 23:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 00:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 00:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 01:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 01:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 02:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 02:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 03:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 03:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 04:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 04:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 05:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 05:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 06:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 06:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 07:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 07:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 08:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 08:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 09:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 09:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 10:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 10:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 11:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 11:54:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host
2026/04/07 12:24:10 [update] notify check failed status=error current=0.0.0-dev target= err=Get "http://10.60.0.251:8080/agents/manifest.json": dial tcp 10.60.0.251:8080: connect: no route to host

0
logs/lifecycle.log Normal file
View File

View File

@ -7,7 +7,7 @@ echo "[code-server] starting install"
# Config # Config
# ---------------------------------------------------------- # ----------------------------------------------------------
SERVICE_ROOT="/opt/zlh/services/code-server" SERVICE_ROOT="/opt/zlh/services/code-server"
ZLH_ARTIFACT_BASE_URL="${ZLH_ARTIFACT_BASE_URL:-http://10.60.0.251:8080}" ZLH_ARTIFACT_BASE_URL="${ZLH_ARTIFACT_BASE_URL:-http://zlh-artifacts.internal.zlh:8080}"
ARTIFACT_NAME="${ZLH_CODESERVER_ARTIFACT:-code-server.tar.gz}" ARTIFACT_NAME="${ZLH_CODESERVER_ARTIFACT:-code-server.tar.gz}"
ARTIFACT_URL="${ZLH_ARTIFACT_BASE_URL%/}/addons/code-server/${ARTIFACT_NAME}" ARTIFACT_URL="${ZLH_ARTIFACT_BASE_URL%/}/addons/code-server/${ARTIFACT_NAME}"
ARTIFACT_TMP="/tmp/${ARTIFACT_NAME}" ARTIFACT_TMP="/tmp/${ARTIFACT_NAME}"
@ -15,7 +15,7 @@ MARKER="/opt/zlh/.zlh/addons/code-server.installed"
PID_FILE="/opt/zlh/.zlh/addons/code-server.pid" PID_FILE="/opt/zlh/.zlh/addons/code-server.pid"
LOG_FILE="/opt/zlh/logs/code-server.log" LOG_FILE="/opt/zlh/logs/code-server.log"
WORKSPACE_DIR="${CODE_SERVER_WORKSPACE:-/home/dev/workspace}" WORKSPACE_DIR="${CODE_SERVER_WORKSPACE:-/home/dev/workspace}"
PORT="${CODE_SERVER_PORT:-8080}" PORT="${CODE_SERVER_PORT:-6000}"
BIN="${SERVICE_ROOT}/bin/code-server" BIN="${SERVICE_ROOT}/bin/code-server"
LINK_PATH="/usr/local/bin/code-server" LINK_PATH="/usr/local/bin/code-server"
CONFIG_DIR="/home/dev/.config/code-server" CONFIG_DIR="/home/dev/.config/code-server"

View File

@ -7,7 +7,7 @@ RUNTIME="dotnet"
RUNTIME_ROOT="/opt/zlh/runtimes/${RUNTIME}" RUNTIME_ROOT="/opt/zlh/runtimes/${RUNTIME}"
DEST_DIR="${RUNTIME_ROOT}/${RUNTIME_VERSION}" DEST_DIR="${RUNTIME_ROOT}/${RUNTIME_VERSION}"
CURRENT_LINK="${RUNTIME_ROOT}/current" CURRENT_LINK="${RUNTIME_ROOT}/current"
ZLH_ARTIFACT_BASE_URL="${ZLH_ARTIFACT_BASE_URL:-http://10.60.0.251:8080}" ZLH_ARTIFACT_BASE_URL="${ZLH_ARTIFACT_BASE_URL:-http://zlh-artifacts.internal.zlh:8080}"
INSTALLER_URL="${ZLH_ARTIFACT_BASE_URL%/}/devcontainer/dotnet/dotnet-install.sh" INSTALLER_URL="${ZLH_ARTIFACT_BASE_URL%/}/devcontainer/dotnet/dotnet-install.sh"
INSTALLER_TMP="/tmp/dotnet-install.sh" INSTALLER_TMP="/tmp/dotnet-install.sh"

View File

@ -13,7 +13,7 @@ set -euo pipefail
# Optional env # Optional env
############################################ ############################################
ZLH_ARTIFACT_BASE_URL="${ZLH_ARTIFACT_BASE_URL:-http://10.60.0.251:8080}" ZLH_ARTIFACT_BASE_URL="${ZLH_ARTIFACT_BASE_URL:-http://zlh-artifacts.internal.zlh:8080}"
ZLH_RUNTIME_ROOT="${ZLH_RUNTIME_ROOT:-/opt/zlh/runtimes}" ZLH_RUNTIME_ROOT="${ZLH_RUNTIME_ROOT:-/opt/zlh/runtimes}"
ARCHIVE_PREFIX="${ARCHIVE_PREFIX:-${RUNTIME}}" ARCHIVE_PREFIX="${ARCHIVE_PREFIX:-${RUNTIME}}"

6
state/update.json Normal file
View File

@ -0,0 +1,6 @@
{
"status": "error",
"current": "0.0.0-dev",
"error": "Get \"http://10.60.0.251:8080/agents/manifest.json\": dial tcp 10.60.0.251:8080: connect: no route to host",
"checked_at_utc": "2026-04-07T12:24:07Z"
}