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
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:
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.