Skip to content

Instantly share code, notes, and snippets.

@stachjankowski
Created March 7, 2025 12:28
Show Gist options
  • Save stachjankowski/52d1d6da71b7f249512a8e0eb025e6e2 to your computer and use it in GitHub Desktop.
Save stachjankowski/52d1d6da71b7f249512a8e0eb025e6e2 to your computer and use it in GitHub Desktop.
Program to test the time it takes to start a virtual machine.
/*
Program to test the time it takes to start a virtual machine.
USAGE:
./main -vm vm-name -address 192.168.120.150:22 -user username -key ~/.ssh/id_rsa
*/
package main
import (
"flag"
"fmt"
"os"
"os/exec"
"time"
"golang.org/x/crypto/ssh"
)
func startVM(vmName string) error {
cmd := exec.Command("virsh", "start", vmName)
return cmd.Run()
}
func waitForSSH(address, user, keyPath string) (time.Duration, error) {
start := time.Now()
for {
key, err := os.ReadFile(keyPath)
if err != nil {
return 0, fmt.Errorf("failed to read SSH key: %v", err)
}
signer, err := ssh.ParsePrivateKey(key)
if err != nil {
return 0, fmt.Errorf("failed to parse SSH key: %v", err)
}
config := &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
conn, err := ssh.Dial("tcp", address, config)
if err == nil {
conn.Close()
break
}
time.Sleep(1 * time.Millisecond)
}
return time.Since(start), nil
}
func main() {
vmName := flag.String("vm", "", "Name of the VM")
sshAddress := flag.String("address", "", "SSH address in format host:port")
sshUser := flag.String("user", "", "SSH user")
sshKeyPath := flag.String("key", "", "Path to SSH key")
flag.Parse()
if *vmName == "" || *sshAddress == "" || *sshUser == "" || *sshKeyPath == "" {
fmt.Println("Missing required flags")
fmt.Println("USAGE:")
fmt.Println(" ./main -vm vm-name -address 192.168.120.150:22 -user username -key ~/.ssh/id_rsa")
return
}
fmt.Println("Starting VM...")
if err := startVM(*vmName); err != nil {
fmt.Printf("Failed to start VM: %v\n", err)
return
}
fmt.Println("Waiting for SSH...")
duration, err := waitForSSH(*sshAddress, *sshUser, *sshKeyPath)
if err != nil {
fmt.Printf("Error waiting for SSH: %v\n", err)
return
}
fmt.Printf("SSH is ready after %v seconds\n", duration.Seconds())
}
@stachjankowski
Copy link
Author

stachjankowski commented Mar 7, 2025

OS HOST RAM CPU Time
Debian 12.9 AMD Ryzen 9 7950X, QEMU/KVM 8GB 4 cores 4.08s
Ubuntu 24.04 AMD Ryzen 9 7950X, QEMU/KVM 8GB 4 cores 4.58s
CentOS Stream 10 AMD Ryzen 9 7950X, QEMU/KVM 8GB 4 cores 7.20s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment