package main import ( "fmt" "os" "os/exec" "path/filepath" "regexp" "strconv" "strings" "time" ) func main() { if len(os.Args) < 2 { printHelp() return } command := os.Args[1] switch command { case "restart": name := "" if len(os.Args) > 2 { if os.Args[2] == "--sleep" && len(os.Args) > 3 { // Ignora per ora, ma in handleRestart parsare } else { name = os.Args[2] } } handleRestart(name) case "help": printHelp() default: fmt.Printf("Unknown command: %s\n", command) fmt.Println("Use 'duckai help' for usage.") os.Exit(1) } } func handleRestart(name string) { sleepTime := 3 args := os.Args[2:] if len(args) > 0 && args[0] == "--sleep" && len(args) > 1 { if s, err := strconv.Atoi(args[1]); err == nil { sleepTime = s } if len(args) > 2 { name = args[2] } } else if name == "" && len(args) > 0 { name = args[0] } fmt.Println("Reloading systemd user daemon...") runCommand("systemctl", "--user", "daemon-reload") if name != "" { // Riavvia servizio specifico containerFile := findServiceFile("*.container", name) if containerFile != "" { serviceName := strings.TrimSuffix(filepath.Base(containerFile), ".container") fmt.Printf("Restarting container %s...\n", name) if runCommand("systemctl", "--user", "restart", serviceName) { fmt.Printf(" ✓ %s restarted successfully\n", name) } else { fmt.Printf(" ✗ Failed to restart %s\n", name) } } else { networkFile := findServiceFile("*.network", name) if networkFile != "" { serviceName := strings.TrimSuffix(filepath.Base(networkFile), ".network") + "-network" fmt.Printf("Restarting network %s...\n", name) if runCommand("systemctl", "--user", "try-restart", serviceName) || runCommand("systemctl", "--user", "start", serviceName) { fmt.Printf(" ✓ %s restarted successfully\n", name) } else { fmt.Printf(" ✗ Failed to restart %s\n", name) } } else { fmt.Printf("Service %s not found.\n", name) os.Exit(1) } } // Riavvia nginx restartNginx() } else { fmt.Println("Restarting all quadlet networks...") restartNetworks(sleepTime) fmt.Println("Restarting all quadlet containers...") restartContainers(sleepTime) fmt.Println("All services restarted successfully.") } } func findServiceFile(pattern, name string) string { home, _ := os.UserHomeDir() dir := filepath.Join(home, ".config", "containers", "systemd") files, _ := filepath.Glob(filepath.Join(dir, pattern)) re := regexp.MustCompile(`^[0-9]+_`) for _, file := range files { if strings.HasPrefix(filepath.Base(file), "99_") { continue } serviceName := strings.TrimSuffix(filepath.Base(file), filepath.Ext(file)) if pattern == "*.network" { serviceName += "-network" } displayName := re.ReplaceAllString(serviceName, "") if displayName == name { return file } } return "" } home, _ := os.UserHomeDir() dir := filepath.Join(home, ".config", "containers", "systemd") files, _ := filepath.Glob(filepath.Join(dir, pattern)) re := regexp.MustCompile(`^[0-9]+_`) for _, file := range files { if strings.HasPrefix(filepath.Base(file), "99_") { continue } serviceName := strings.TrimSuffix(filepath.Base(file), filepath.Ext(file)) if pattern == "*.network" { serviceName += "-network" } displayName := re.ReplaceAllString(serviceName, "") if displayName == name { return file } } return "" } func restartNetworks(sleepTime int) { home, _ := os.UserHomeDir() dir := filepath.Join(home, ".config", "containers", "systemd") files, _ := filepath.Glob(filepath.Join(dir, "*.network")) re := regexp.MustCompile(`^[0-9]+_`) for _, file := range files { if strings.HasPrefix(filepath.Base(file), "99_") { continue } serviceName := strings.TrimSuffix(filepath.Base(file), ".network") + "-network" displayName := re.ReplaceAllString(serviceName, "") fmt.Printf("Restarting %s...\n", displayName) if runCommand("systemctl", "--user", "try-restart", serviceName) || runCommand("systemctl", "--user", "start", serviceName) { fmt.Printf(" ✓ %s restarted successfully\n", displayName) } else { fmt.Printf(" ✗ Failed to restart %s\n", displayName) } time.Sleep(time.Duration(sleepTime) * time.Second) } } func restartContainers(sleepTime int) { home, _ := os.UserHomeDir() dir := filepath.Join(home, ".config", "containers", "systemd") files, _ := filepath.Glob(filepath.Join(dir, "*.container")) re := regexp.MustCompile(`^[0-9]+_`) for _, file := range files { if strings.HasPrefix(filepath.Base(file), "99_") { continue } serviceName := strings.TrimSuffix(filepath.Base(file), ".container") displayName := re.ReplaceAllString(serviceName, "") fmt.Printf("Restarting %s...\n", displayName) if runCommand("systemctl", "--user", "restart", serviceName) { fmt.Printf(" ✓ %s restarted successfully\n", displayName) } else { fmt.Printf(" ✗ Failed to restart %s\n", displayName) } time.Sleep(time.Duration(sleepTime) * time.Second) } } func restartNginx() { home, _ := os.UserHomeDir() dir := filepath.Join(home, ".config", "containers", "systemd") files, _ := filepath.Glob(filepath.Join(dir, "*nginx*.container")) if len(files) > 0 { serviceName := strings.TrimSuffix(filepath.Base(files[0]), ".container") fmt.Println("Restarting nginx...") if runCommand("systemctl", "--user", "restart", serviceName) { fmt.Println(" ✓ nginx restarted successfully") } else { fmt.Println(" ✗ Failed to restart nginx") } } } func runCommand(name string, args ...string) bool { cmd := exec.Command(name, args...) err := cmd.Run() return err == nil } func printHelp() { fmt.Println(`D U C K A I - C O M M A N D L I N E -------------------------------------------------------------------------------- Usage: duckai [options] Commands: restart [--sleep N] [name] Restart all quadlet containers and networks, or a specific one by name (without prefix), reload systemd user daemon help Show this help message Options: --sleep N Sleep N seconds between restarts (default: 3)`) }