Correct qemu arguments
This commit is contained in:
		@@ -8,6 +8,8 @@ import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"math/rand"
 | 
			
		||||
	"net"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"syscall"
 | 
			
		||||
@@ -58,8 +60,12 @@ type Kernel struct {
 | 
			
		||||
 | 
			
		||||
// QemuSystem describe qemu parameters and runned process
 | 
			
		||||
type QemuSystem struct {
 | 
			
		||||
	arch   arch
 | 
			
		||||
	kernel Kernel
 | 
			
		||||
	arch      arch
 | 
			
		||||
	kernel    Kernel
 | 
			
		||||
	drivePath string
 | 
			
		||||
 | 
			
		||||
	Cpus   int
 | 
			
		||||
	Memory int
 | 
			
		||||
 | 
			
		||||
	// accessible while qemu is runned
 | 
			
		||||
	cmd  *exec.Cmd
 | 
			
		||||
@@ -76,7 +82,7 @@ type QemuSystem struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewQemuSystem constructor
 | 
			
		||||
func NewQemuSystem(arch arch, kernel Kernel) (q QemuSystem, err error) {
 | 
			
		||||
func NewQemuSystem(arch arch, kernel Kernel, drivePath string) (q QemuSystem, err error) {
 | 
			
		||||
	if _, err = exec.LookPath("qemu-system-" + string(arch)); err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
@@ -87,15 +93,63 @@ func NewQemuSystem(arch arch, kernel Kernel) (q QemuSystem, err error) {
 | 
			
		||||
	}
 | 
			
		||||
	q.kernel = kernel
 | 
			
		||||
 | 
			
		||||
	if _, err = os.Stat(drivePath); err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	q.drivePath = drivePath
 | 
			
		||||
 | 
			
		||||
	// Default values
 | 
			
		||||
	q.Cpus = 2
 | 
			
		||||
	q.Memory = 512 // megabytes
 | 
			
		||||
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getRandomAddrPort() (addr string) {
 | 
			
		||||
	// 127.1-255.0-255.0-255:10000-50000
 | 
			
		||||
	ip := fmt.Sprintf("127.%d.%d.%d",
 | 
			
		||||
		rand.Int()%254+1, rand.Int()%255, rand.Int()%254)
 | 
			
		||||
	port := rand.Int()%40000 + 10000
 | 
			
		||||
	return fmt.Sprintf("%s:%d", ip, port)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getFreeAddrPort() (addrPort string) {
 | 
			
		||||
	for {
 | 
			
		||||
		addrPort = getRandomAddrPort()
 | 
			
		||||
		ln, err := net.Listen("tcp", addrPort)
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			ln.Close()
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func kvmExists() bool {
 | 
			
		||||
	if _, err := os.Stat("/dev/kvm"); err != nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Start qemu process
 | 
			
		||||
func (q *QemuSystem) Start() (err error) {
 | 
			
		||||
	q.cmd = exec.Command("qemu-system-"+string(q.arch),
 | 
			
		||||
		// TODO
 | 
			
		||||
		"-snapshot",
 | 
			
		||||
		"-nographic")
 | 
			
		||||
	rand.Seed(time.Now().UnixNano()) // Are you sure?
 | 
			
		||||
	hostfwd := fmt.Sprintf("hostfwd=tcp:%s-:22", getFreeAddrPort())
 | 
			
		||||
	qemuArgs := []string{"-snapshot", "-nographic",
 | 
			
		||||
		"-hda", q.drivePath,
 | 
			
		||||
		"-kernel", q.kernel.Path,
 | 
			
		||||
		"-append", "root=/dev/sda console=ttyS0 rw",
 | 
			
		||||
		"-smp", fmt.Sprintf("%d", q.Cpus),
 | 
			
		||||
		"-m", fmt.Sprintf("%d", q.Memory),
 | 
			
		||||
		"-device", "e1000,netdev=n1",
 | 
			
		||||
		"-netdev", "user,id=n1," + hostfwd,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (q.arch == X86_64 || q.arch == I386) && kvmExists() {
 | 
			
		||||
		qemuArgs = append(qemuArgs, "-enable-kvm")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	q.cmd = exec.Command("qemu-system-"+string(q.arch), qemuArgs...)
 | 
			
		||||
 | 
			
		||||
	if q.pipe.stdin, err = q.cmd.StdinPipe(); err != nil {
 | 
			
		||||
		return
 | 
			
		||||
 
 | 
			
		||||
@@ -5,12 +5,13 @@
 | 
			
		||||
package qemukernel
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net"
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestQemuSystemNew_InvalidKernelPath(t *testing.T) {
 | 
			
		||||
	kernel := Kernel{Name: "Invalid", Path: "/invalid/path"}
 | 
			
		||||
	if _, err := NewQemuSystem(X86_64, kernel); err == nil {
 | 
			
		||||
	if _, err := NewQemuSystem(X86_64, kernel, "/bin/sh"); err == nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -18,7 +19,15 @@ func TestQemuSystemNew_InvalidKernelPath(t *testing.T) {
 | 
			
		||||
func TestQemuSystemNew_InvalidQemuArch(t *testing.T) {
 | 
			
		||||
	// FIXME put kernel image to path not just "any valid path"
 | 
			
		||||
	kernel := Kernel{Name: "Valid path", Path: "/bin/sh"}
 | 
			
		||||
	if _, err := NewQemuSystem(unsupported, kernel); err == nil {
 | 
			
		||||
	if _, err := NewQemuSystem(unsupported, kernel, "/bin/sh"); err == nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestQemuSystemNew_InvalidQemuDrivePath(t *testing.T) {
 | 
			
		||||
	// FIXME put kernel image to path not just "any valid path"
 | 
			
		||||
	kernel := Kernel{Name: "Valid path", Path: "/bin/sh"}
 | 
			
		||||
	if _, err := NewQemuSystem(X86_64, kernel, "/invalid/path"); err == nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -26,7 +35,7 @@ func TestQemuSystemNew_InvalidQemuArch(t *testing.T) {
 | 
			
		||||
func TestQemuSystemNew(t *testing.T) {
 | 
			
		||||
	// FIXME put kernel image to path not just "any valid path"
 | 
			
		||||
	kernel := Kernel{Name: "Valid path", Path: "/bin/sh"}
 | 
			
		||||
	if _, err := NewQemuSystem(X86_64, kernel); err != nil {
 | 
			
		||||
	if _, err := NewQemuSystem(X86_64, kernel, "/bin/sh"); err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -34,7 +43,7 @@ func TestQemuSystemNew(t *testing.T) {
 | 
			
		||||
func TestQemuSystemStart(t *testing.T) {
 | 
			
		||||
	// TODO check kernel path on other distros than gentoo
 | 
			
		||||
	kernel := Kernel{Name: "Host kernel", Path: "/boot/vmlinuz-4.18.8"}
 | 
			
		||||
	qemu, err := NewQemuSystem(X86_64, kernel)
 | 
			
		||||
	qemu, err := NewQemuSystem(X86_64, kernel, "/bin/sh")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
@@ -45,3 +54,12 @@ func TestQemuSystemStart(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
	qemu.Stop()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetFreeAddrPort(t *testing.T) {
 | 
			
		||||
	addrPort := getFreeAddrPort()
 | 
			
		||||
	ln, err := net.Listen("tcp", addrPort)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	ln.Close()
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user