Allow cancelling of node discovery.
This commit is contained in:
100
cmd/node.go
100
cmd/node.go
@@ -1,7 +1,11 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
@@ -24,6 +28,19 @@ var nodeDiscoverCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
// Check if --cancel flag is set
|
||||
shouldCancel, _ := cmd.Flags().GetBool("cancel")
|
||||
if shouldCancel {
|
||||
// Cancel any running discovery first
|
||||
_, err := apiClient.Post(fmt.Sprintf("/api/v1/instances/%s/discovery/cancel", inst), nil)
|
||||
if err != nil {
|
||||
// Ignore error if no discovery is running
|
||||
fmt.Println("No active discovery to cancel, starting new discovery...")
|
||||
} else {
|
||||
fmt.Println("Cancelled previous discovery, starting new discovery...")
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("Starting discovery for %d IP(s)...\n", len(args))
|
||||
_, err = apiClient.Post(fmt.Sprintf("/api/v1/instances/%s/nodes/discover", inst), map[string]interface{}{
|
||||
"ip_list": args,
|
||||
@@ -32,9 +49,39 @@ var nodeDiscoverCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
// Set up signal handling for Ctrl-C
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
|
||||
|
||||
// Handle signals in a goroutine
|
||||
go func() {
|
||||
<-sigChan
|
||||
fmt.Println("\n\nCancelling discovery...")
|
||||
cancel()
|
||||
|
||||
// Call cancel API
|
||||
_, err := apiClient.Post(fmt.Sprintf("/api/v1/instances/%s/discovery/cancel", inst), nil)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to cancel discovery: %v\n", err)
|
||||
} else {
|
||||
fmt.Println("Discovery cancelled successfully")
|
||||
}
|
||||
os.Exit(0)
|
||||
}()
|
||||
|
||||
// Poll for completion
|
||||
fmt.Println("Scanning nodes...")
|
||||
fmt.Println("Scanning nodes... (Press Ctrl-C to cancel)")
|
||||
ticker := time.NewTicker(500 * time.Millisecond)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
case <-ticker.C:
|
||||
resp, err := apiClient.Get(fmt.Sprintf("/api/v1/instances/%s/discovery", inst))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -49,21 +96,29 @@ var nodeDiscoverCmd = &cobra.Command{
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Printf("\nFound %d node(s):\n\n", len(nodesFound))
|
||||
fmt.Printf("%-15s %-12s %-10s\n", "IP", "INTERFACE", "VERSION")
|
||||
fmt.Println("-----------------------------------------------")
|
||||
fmt.Printf("\nFound %d node(s) in maintenance mode:\n\n", len(nodesFound))
|
||||
fmt.Printf("%-15s %-15s %-15s\n", "IP", "VERSION", "HOSTNAME")
|
||||
fmt.Println("-----------------------------------------------------")
|
||||
for _, node := range nodesFound {
|
||||
if m, ok := node.(map[string]interface{}); ok {
|
||||
fmt.Printf("%-15s %-12s %-10s\n",
|
||||
m["ip"], m["interface"], m["version"])
|
||||
version := m["version"]
|
||||
if version == nil {
|
||||
version = ""
|
||||
}
|
||||
hostname := m["hostname"]
|
||||
if hostname == nil {
|
||||
hostname = ""
|
||||
}
|
||||
fmt.Printf("%-15s %-15s %-15s\n",
|
||||
m["ip"], version, hostname)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Still running, wait a bit
|
||||
// Still running, show progress
|
||||
fmt.Print(".")
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -431,6 +486,31 @@ You can use it manually to update templates.`,
|
||||
},
|
||||
}
|
||||
|
||||
var nodeCancelDiscoveryCmd = &cobra.Command{
|
||||
Use: "cancel-discovery",
|
||||
Short: "Cancel active node discovery",
|
||||
Long: `Cancel an active node discovery operation.
|
||||
|
||||
Use this if discovery gets stuck or you want to stop a running scan.
|
||||
|
||||
Example:
|
||||
wild node cancel-discovery`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
inst, err := getInstanceName()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = apiClient.Post(fmt.Sprintf("/api/v1/instances/%s/discovery/cancel", inst), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("Discovery cancelled successfully")
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var nodeDeleteCmd = &cobra.Command{
|
||||
Use: "delete <hostname>",
|
||||
Short: "Delete a node",
|
||||
@@ -453,6 +533,7 @@ var nodeDeleteCmd = &cobra.Command{
|
||||
|
||||
func init() {
|
||||
nodeCmd.AddCommand(nodeDiscoverCmd)
|
||||
nodeCmd.AddCommand(nodeCancelDiscoveryCmd)
|
||||
nodeCmd.AddCommand(nodeDetectCmd)
|
||||
nodeCmd.AddCommand(nodeListCmd)
|
||||
nodeCmd.AddCommand(nodeShowCmd)
|
||||
@@ -462,6 +543,9 @@ func init() {
|
||||
nodeCmd.AddCommand(nodeFetchTemplatesCmd)
|
||||
nodeCmd.AddCommand(nodeDeleteCmd)
|
||||
|
||||
// Add flags to node discover command
|
||||
nodeDiscoverCmd.Flags().Bool("cancel", false, "Cancel any running discovery before starting")
|
||||
|
||||
// Add flags to node add command
|
||||
nodeAddCmd.Flags().String("target-ip", "", "Target IP address for production")
|
||||
nodeAddCmd.Flags().String("current-ip", "", "Current IP address (for maintenance mode)")
|
||||
|
||||
Reference in New Issue
Block a user