fix(agent): v0.3.10 cleanup orphan instance dirs on startup
- Add cleanupOrphanInstanceDirs() to remove leftover instance directories after failed deletes (common on Windows when compose.log is locked) - Log RemoveAll errors in dockerComposeRm for better visibility - Bump version to 0.3.10 and rebuild binaries
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
||||
0.3.9
|
||||
0.3.10
|
||||
|
||||
+6
-1
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
@@ -92,7 +93,11 @@ func dockerComposeRm(dataDir, instanceID string) error {
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
return os.RemoveAll(dir)
|
||||
if err := os.RemoveAll(dir); err != nil {
|
||||
log.Printf("dockerComposeRm: failed to remove %s: %v (will retry on next startup)", dir, err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// extractPublicURL tries to find the public URL from a WordPress compose config.
|
||||
|
||||
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
@@ -130,3 +131,34 @@ func getInstanceStatus(dataDir, instanceID string) string {
|
||||
}
|
||||
return "stopped"
|
||||
}
|
||||
|
||||
// cleanupOrphanInstanceDirs removes instance directories that have no entry in
|
||||
// instances.json. This typically happens on Windows when a delete operation
|
||||
// could not fully remove the directory because compose.log was locked.
|
||||
func cleanupOrphanInstanceDirs(dataDir string) {
|
||||
instancesDir := filepath.Join(dataDir, "instances")
|
||||
inst, err := loadInstances(dataDir)
|
||||
if err != nil {
|
||||
log.Printf("cleanupOrphanInstanceDirs: loadInstances error: %v", err)
|
||||
return
|
||||
}
|
||||
entries, err := os.ReadDir(instancesDir)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
log.Printf("cleanupOrphanInstanceDirs: ReadDir error: %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
for _, entry := range entries {
|
||||
if !entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
if _, ok := inst[entry.Name()]; !ok {
|
||||
dir := filepath.Join(instancesDir, entry.Name())
|
||||
log.Printf("cleanupOrphanInstanceDirs: removing orphan directory %s", dir)
|
||||
if err := os.RemoveAll(dir); err != nil {
|
||||
log.Printf("cleanupOrphanInstanceDirs: RemoveAll error for %s: %v", dir, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,10 @@ func main() {
|
||||
|
||||
log.Printf("[%s Agent] version=%s node=%s data-dir=%s server=%s", APP_NAME, version, cfg.NodeID, *dataDir, cfg.Server)
|
||||
|
||||
// Clean up instance directories left behind by failed deletes (common on
|
||||
// Windows when compose.log is locked during removal).
|
||||
cleanupOrphanInstanceDirs(*dataDir)
|
||||
|
||||
// Ensure Podman machine DNS is configured on Windows/macOS so images can be
|
||||
// pulled and containers can reach the internet.
|
||||
ensurePodmanMachineDNS()
|
||||
|
||||
Reference in New Issue
Block a user