Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions roverctl/src/commands/prechecks/prechecks.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package command_prechecks

import (
"fmt"
"strings"

"github.com/VU-ASE/rover/roverctl/src/configuration"
"github.com/VU-ASE/rover/roverctl/src/utils"
view_incompatible "github.com/VU-ASE/rover/roverctl/src/views/incompatible"

"github.com/spf13/cobra"
Expand All @@ -28,6 +30,12 @@ func Perform(cmd *cobra.Command, args []string, roverIndex int, roverdHost strin
// Pad number to two digits and use mDNS to resolve the rover's hostname
host = fmt.Sprintf("rover%02d.local", roverIndex)
// host = fmt.Sprintf("192.168.0.%d", roverIndex+100)

if strings.HasSuffix(host, ".local") {
if ip, err := utils.ResolveHostWithPing(host); err == nil {
host = ip
}
}
}

// Create connection
Expand Down
60 changes: 60 additions & 0 deletions roverctl/src/utils/mdns.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package utils

import (
"bytes"
"context"
"fmt"
"os/exec"
"regexp"
"time"
"runtime"
)

// A regular expression to match IPv4 addresses in ping output
var theIPv4Regex = regexp.MustCompile(`\((\d+\.\d+\.\d+\.\d+)\)`)

func ResolveHostWithPing(host string) (string, error) {
// We use a context with timeout to avoid hanging indefinitely on the ping command
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()

// We prepare the ping command based on what OS is currently running roverctl
args := pingArgs(host)
cmd := exec.CommandContext(ctx, "ping", args...)

// Capture the output
var out bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &out

// Run the ping command, but do not return an error yet
// Since ping might fail even if mDNS resolution worked
// We will check the output for an IP address, and if we cannot find one, we return an error
if err := cmd.Run(); err != nil {
_ = err
}

// Search the output for an IPv4 address
matches := theIPv4Regex.FindStringSubmatch(out.String())
if len(matches) >= 2 {
return matches[1], nil
}

// If we reach here, we could not find an IP address in the ping output
return "", fmt.Errorf("could not resolve host %s via ping, output: %s", host, out.String())
}

func pingArgs(host string) []string {
// Different OSes have different arguments for ping
switch runtime.GOOS {
// MacOS
case "darwin":
return []string{"-c", "1", "-W", "1000", host}
// Linux
default:
return []string{"-c", "1", "-w", "1", host}
}
}



Loading