-1

Goal

Use Golang's crypto/ssh to run iperf3 on two VMs to measure throughput.

The manual process

Here is a description of the manual process that works. I am trying to do the same thing in golang.

Manual Approach: From a jumpbox, connect to VM1 and run iperf as server

# Login to VM1
ssh testadmin@168.61.222.12
# Run iperf server on VM1
iperf3 -s -p 5001

enter image description here

You can see from the image above that the server is sitting there listening. The same command hangs the golang code as explained below.

Manual Approach: From a jumpbox, connect to VM2 and run iperf as client

# Login to VM2
ssh testadmin@23.101.124.159

# Run client tests on VM2
iperf3 -c 168.61.222.12 -p 5001 -i 1 -t 3

All of it works great from the command line. Below is an explanation on using Golang but the code hangs.

Problem: The golang code hangs

The golang code hangs on the line below. See the function:

putVM1IntoServerMode()

The code hangs on:

putVM1IntoServerMode() {}
    # Code hangs here
    out, err := 
      VMConnectServer.hostSession.CombinedOutput(VMConnectServer.commands[0])
      ...
}

That is kind of expected because of what you see in the manual process:

enter image description here

Main Code

type VMCONNECT struct {
    hostConnection *ssh.Client
    hostSession    *ssh.Session
    user           string
    hostPort       string
    commands       []string
    password       string
}

var VMConnectServer = VMCONNECT{
    nil,
    nil,
    "testadmin",
    "169.61.222.12:22",
    []string{"iperf3 -s -p 5001"},
    "????",
}
/*************************************
Logic
  connect to server
  put vm into server mode
  connect to client
  run iperf3 tests
  close client
  close server
**************************************/

func main() {

    connectToServer()
    putVM1IntoServerMode()
    // other code ommitted for brevity
}    

# This works fine, no issues
func connectToServer() {
    var err error
    VMConnectServer.hostConnection, VMConnectServer.hostSession, err = connectToHost(VMConnectServer.user, VMConnectServer.hostPort)
    if err != nil {
        panic(err)
    }
}

# Code hangs here
func putVM1IntoServerMode() {
    # Code hangs here
    out, err := VMConnectServer.hostSession.CombinedOutput(VMConnectServer.commands[0])
    if err != nil {
        panic(err)
    }
    fmt.Println(string(out))
}

How to solve

Do I run code async using a channel? What is the best way to solve this issue?

Any guidance is appreciated.

Bruno
  • 498
  • 1
  • 4
  • 9

1 Answers1

0

Success!

When running on the server side of iperf, it is very tricky.

func runIperfTestsFromVM2() string {
    fmt.Println(VMConnectClient.commands[0])
    out, err := VMConnectClient.hostSession.CombinedOutput("sh -c 'nohup iperf3 -s -p 5001 > /dev/null 2>&1 &'")
    if err != nil {
        panic(err)
    }
    fmt.Println(string(out))
    return string(out)
}
Bruno
  • 498
  • 1
  • 4
  • 9