Refactor [2]
This commit is contained in:
@ -52,7 +52,7 @@ Minimal example:
|
||||
KernelPath: "/path/to/vmlinuz",
|
||||
InitrdPath: "/path/to/initrd", // if required
|
||||
}
|
||||
q, err := qemu.NewQemuSystem(qemu.X86_64, kernel, "/path/to/qcow2")
|
||||
q, err := qemu.NewSystem(qemu.X86_64, kernel, "/path/to/qcow2")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -44,9 +44,10 @@ func readUntilEOF(pipe io.ReadCloser, buf *[]byte) (err error) {
|
||||
type arch string
|
||||
|
||||
const (
|
||||
// X86_64 must be exactly same as in qemu-system-${HERE}
|
||||
X86_64 arch = "x86_64"
|
||||
I386 = "i386"
|
||||
// X86x64 is the qemu-system-x86_64
|
||||
X86x64 arch = "x86_64"
|
||||
// X86x32 is the qemu-system-i386
|
||||
X86x32 = "i386"
|
||||
// TODO add other
|
||||
|
||||
unsupported = "unsupported" // for test purposes
|
||||
@ -59,8 +60,8 @@ type Kernel struct {
|
||||
InitrdPath string
|
||||
}
|
||||
|
||||
// QemuSystem describe qemu parameters and runned process
|
||||
type QemuSystem struct {
|
||||
// System describe qemu parameters and runned process
|
||||
type System struct {
|
||||
arch arch
|
||||
kernel Kernel
|
||||
drivePath string
|
||||
@ -98,12 +99,12 @@ type QemuSystem struct {
|
||||
exitErr error
|
||||
}
|
||||
|
||||
// NewQemuSystem constructor
|
||||
func NewQemuSystem(arch arch, kernel Kernel, drivePath string) (q *QemuSystem, err error) {
|
||||
// NewSystem constructor
|
||||
func NewSystem(arch arch, kernel Kernel, drivePath string) (q *System, err error) {
|
||||
if _, err = exec.LookPath("qemu-system-" + string(arch)); err != nil {
|
||||
return
|
||||
}
|
||||
q = &QemuSystem{}
|
||||
q = &System{}
|
||||
q.arch = arch
|
||||
|
||||
if _, err = os.Stat(kernel.KernelPath); err != nil {
|
||||
@ -164,7 +165,7 @@ func kvmExists() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (q *QemuSystem) panicWatcher() {
|
||||
func (q *System) panicWatcher() {
|
||||
for {
|
||||
time.Sleep(time.Second)
|
||||
if bytes.Contains(q.Stdout, []byte("Kernel panic")) {
|
||||
@ -178,7 +179,7 @@ func (q *QemuSystem) panicWatcher() {
|
||||
}
|
||||
|
||||
// Start qemu process
|
||||
func (q *QemuSystem) Start() (err error) {
|
||||
func (q *System) Start() (err error) {
|
||||
rand.Seed(time.Now().UnixNano()) // Are you sure?
|
||||
q.sshAddrPort = getFreeAddrPort()
|
||||
hostfwd := fmt.Sprintf("hostfwd=tcp:%s-:22", q.sshAddrPort)
|
||||
@ -213,11 +214,11 @@ func (q *QemuSystem) Start() (err error) {
|
||||
qemuArgs = append(qemuArgs, "-initrd", q.kernel.InitrdPath)
|
||||
}
|
||||
|
||||
if (q.arch == X86_64 || q.arch == I386) && kvmExists() {
|
||||
if (q.arch == X86x64 || q.arch == X86x32) && kvmExists() {
|
||||
qemuArgs = append(qemuArgs, "-enable-kvm")
|
||||
}
|
||||
|
||||
if q.arch == X86_64 && runtime.GOOS == "darwin" {
|
||||
if q.arch == X86x64 && runtime.GOOS == "darwin" {
|
||||
qemuArgs = append(qemuArgs, "-accel", "hvf", "-cpu", "host")
|
||||
}
|
||||
|
||||
@ -270,7 +271,7 @@ func (q *QemuSystem) Start() (err error) {
|
||||
}
|
||||
|
||||
// Stop qemu process
|
||||
func (q *QemuSystem) Stop() {
|
||||
func (q *System) Stop() {
|
||||
// 1 00/01 01 01 SOH (Ctrl-A) START OF HEADING
|
||||
fmt.Fprintf(q.pipe.stdin, "%cx", 1)
|
||||
// wait for die
|
||||
@ -282,7 +283,7 @@ func (q *QemuSystem) Stop() {
|
||||
}
|
||||
}
|
||||
|
||||
func (q QemuSystem) ssh(user string) (client *ssh.Client, err error) {
|
||||
func (q System) ssh(user string) (client *ssh.Client, err error) {
|
||||
cfg := &ssh.ClientConfig{
|
||||
User: user,
|
||||
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
|
||||
@ -293,7 +294,7 @@ func (q QemuSystem) ssh(user string) (client *ssh.Client, err error) {
|
||||
}
|
||||
|
||||
// Command executes shell commands on qemu system
|
||||
func (q QemuSystem) Command(user, cmd string) (output string, err error) {
|
||||
func (q System) Command(user, cmd string) (output string, err error) {
|
||||
client, err := q.ssh(user)
|
||||
if err != nil {
|
||||
return
|
||||
@ -311,7 +312,7 @@ func (q QemuSystem) Command(user, cmd string) (output string, err error) {
|
||||
}
|
||||
|
||||
// AsyncCommand executes command on qemu system but does not wait for exit
|
||||
func (q QemuSystem) AsyncCommand(user, cmd string) (err error) {
|
||||
func (q System) AsyncCommand(user, cmd string) (err error) {
|
||||
client, err := q.ssh(user)
|
||||
if err != nil {
|
||||
return
|
||||
@ -328,7 +329,7 @@ func (q QemuSystem) AsyncCommand(user, cmd string) (err error) {
|
||||
}
|
||||
|
||||
// CopyFile is copy file from local machine to remote through ssh/scp
|
||||
func (q *QemuSystem) CopyFile(user, localPath, remotePath string) (err error) {
|
||||
func (q *System) CopyFile(user, localPath, remotePath string) (err error) {
|
||||
addrPort := strings.Split(q.sshAddrPort, ":")
|
||||
addr := addrPort[0]
|
||||
port := addrPort[1]
|
||||
@ -346,7 +347,7 @@ func (q *QemuSystem) CopyFile(user, localPath, remotePath string) (err error) {
|
||||
}
|
||||
|
||||
// CopyAndInsmod copy kernel module to temporary file on qemu then insmod it
|
||||
func (q *QemuSystem) CopyAndInsmod(localKoPath string) (output string, err error) {
|
||||
func (q *System) CopyAndInsmod(localKoPath string) (output string, err error) {
|
||||
remoteKoPath := fmt.Sprintf("/tmp/module_%d.ko", rand.Int())
|
||||
err = q.CopyFile("root", localKoPath, remoteKoPath)
|
||||
if err != nil {
|
||||
@ -357,7 +358,7 @@ func (q *QemuSystem) CopyAndInsmod(localKoPath string) (output string, err error
|
||||
}
|
||||
|
||||
// CopyAndRun is copy local file to qemu vm then run it
|
||||
func (q *QemuSystem) CopyAndRun(user, path string) (output string, err error) {
|
||||
func (q *System) CopyAndRun(user, path string) (output string, err error) {
|
||||
remotePath := fmt.Sprintf("/tmp/executable_%d", rand.Int())
|
||||
err = q.CopyFile(user, path, remotePath)
|
||||
if err != nil {
|
||||
@ -368,28 +369,28 @@ func (q *QemuSystem) CopyAndRun(user, path string) (output string, err error) {
|
||||
}
|
||||
|
||||
// Debug is for enable qemu debug and set hostname and port for listen
|
||||
func (q *QemuSystem) Debug(conn string) {
|
||||
func (q *System) Debug(conn string) {
|
||||
q.debug = true
|
||||
q.gdb = conn
|
||||
}
|
||||
|
||||
// SetKASLR is changing KASLR state through kernel boot args
|
||||
func (q *QemuSystem) SetKASLR(state bool) {
|
||||
func (q *System) SetKASLR(state bool) {
|
||||
q.noKASLR = !state
|
||||
}
|
||||
|
||||
// SetSMEP is changing SMEP state through kernel boot args
|
||||
func (q *QemuSystem) SetSMEP(state bool) {
|
||||
func (q *System) SetSMEP(state bool) {
|
||||
q.noSMEP = !state
|
||||
}
|
||||
|
||||
// SetSMAP is changing SMAP state through kernel boot args
|
||||
func (q *QemuSystem) SetSMAP(state bool) {
|
||||
func (q *System) SetSMAP(state bool) {
|
||||
q.noSMAP = !state
|
||||
}
|
||||
|
||||
// GetSshCommand returns command for connect to qemu machine over ssh
|
||||
func (q QemuSystem) GetSshCommand() (cmd string) {
|
||||
// GetSSHCommand returns command for connect to qemu machine over ssh
|
||||
func (q System) GetSSHCommand() (cmd string) {
|
||||
addrPort := strings.Split(q.sshAddrPort, ":")
|
||||
addr := addrPort[0]
|
||||
port := addrPort[1]
|
||||
|
@ -20,37 +20,37 @@ func init() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
}
|
||||
|
||||
func TestQemuSystemNew_InvalidKernelPath(t *testing.T) {
|
||||
func TestSystemNew_InvalidKernelPath(t *testing.T) {
|
||||
kernel := Kernel{Name: "Invalid", KernelPath: "/invalid/path"}
|
||||
if _, err := NewQemuSystem(X86_64, kernel, "/bin/sh"); err == nil {
|
||||
if _, err := NewSystem(X86_64, kernel, "/bin/sh"); err == nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestQemuSystemNew_InvalidQemuArch(t *testing.T) {
|
||||
func TestSystemNew_InvalidQemuArch(t *testing.T) {
|
||||
kernel := Kernel{Name: "Valid path", KernelPath: testConfigVmlinuz}
|
||||
if _, err := NewQemuSystem(unsupported, kernel, "/bin/sh"); err == nil {
|
||||
if _, err := NewSystem(unsupported, kernel, "/bin/sh"); err == nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestQemuSystemNew_InvalidQemuDrivePath(t *testing.T) {
|
||||
func TestSystemNew_InvalidQemuDrivePath(t *testing.T) {
|
||||
kernel := Kernel{Name: "Valid path", KernelPath: testConfigVmlinuz}
|
||||
if _, err := NewQemuSystem(X86_64, kernel, "/invalid/path"); err == nil {
|
||||
if _, err := NewSystem(X86_64, kernel, "/invalid/path"); err == nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestQemuSystemNew(t *testing.T) {
|
||||
func TestSystemNew(t *testing.T) {
|
||||
kernel := Kernel{Name: "Valid path", KernelPath: testConfigVmlinuz}
|
||||
if _, err := NewQemuSystem(X86_64, kernel, "/bin/sh"); err != nil {
|
||||
if _, err := NewSystem(X86_64, kernel, "/bin/sh"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestQemuSystemStart(t *testing.T) {
|
||||
func TestSystemStart(t *testing.T) {
|
||||
kernel := Kernel{Name: "Test kernel", KernelPath: testConfigVmlinuz}
|
||||
q, err := NewQemuSystem(X86_64, kernel, "/bin/sh")
|
||||
q, err := NewSystem(X86_64, kernel, "/bin/sh")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -71,10 +71,10 @@ func TestGetFreeAddrPort(t *testing.T) {
|
||||
ln.Close()
|
||||
}
|
||||
|
||||
func TestQemuSystemStart_Timeout(t *testing.T) {
|
||||
func TestSystemStart_Timeout(t *testing.T) {
|
||||
t.Parallel()
|
||||
kernel := Kernel{Name: "Test kernel", KernelPath: testConfigVmlinuz}
|
||||
q, err := NewQemuSystem(X86_64, kernel, "/bin/sh")
|
||||
q, err := NewSystem(X86_64, kernel, "/bin/sh")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -96,14 +96,14 @@ func TestQemuSystemStart_Timeout(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func startTestQemu(t *testing.T, timeout time.Duration) (q *QemuSystem, err error) {
|
||||
func startTestQemu(t *testing.T, timeout time.Duration) (q *System, err error) {
|
||||
t.Parallel()
|
||||
kernel := Kernel{
|
||||
Name: "Test kernel",
|
||||
KernelPath: testConfigVmlinuz,
|
||||
InitrdPath: testConfigInitrd,
|
||||
}
|
||||
q, err = NewQemuSystem(X86_64, kernel, testConfigRootfs)
|
||||
q, err = NewSystem(X86_64, kernel, testConfigRootfs)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -119,7 +119,7 @@ func startTestQemu(t *testing.T, timeout time.Duration) (q *QemuSystem, err erro
|
||||
return
|
||||
}
|
||||
|
||||
func TestQemuSystemCommand(t *testing.T) {
|
||||
func TestSystemCommand(t *testing.T) {
|
||||
q, err := startTestQemu(t, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -149,7 +149,7 @@ func TestQemuSystemCommand(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestQemuSystemCopyFile(t *testing.T) {
|
||||
func TestSystemCopyFile(t *testing.T) {
|
||||
q, err := startTestQemu(t, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -182,7 +182,7 @@ func TestQemuSystemCopyFile(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestQemuSystemCopyAndRun(t *testing.T) {
|
||||
func TestSystemCopyAndRun(t *testing.T) {
|
||||
q, err := startTestQemu(t, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -216,7 +216,7 @@ func TestQemuSystemCopyAndRun(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestQemuSystemCopyAndInsmod(t *testing.T) {
|
||||
func TestSystemCopyAndInsmod(t *testing.T) {
|
||||
q, err := startTestQemu(t, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -243,7 +243,7 @@ func TestQemuSystemCopyAndInsmod(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestQemuSystemKernelPanic(t *testing.T) {
|
||||
func TestSystemKernelPanic(t *testing.T) {
|
||||
q, err := startTestQemu(t, 5*time.Minute)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -278,7 +278,7 @@ func TestQemuSystemKernelPanic(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestQemuSystemRun(t *testing.T) {
|
||||
func TestSystemRun(t *testing.T) {
|
||||
q, err := startTestQemu(t, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -313,13 +313,13 @@ func openedPort(port int) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func TestQemuSystemDebug(t *testing.T) {
|
||||
func TestSystemDebug(t *testing.T) {
|
||||
t.Parallel()
|
||||
kernel := Kernel{
|
||||
KernelPath: testConfigVmlinuz,
|
||||
InitrdPath: testConfigInitrd,
|
||||
}
|
||||
q, err := NewQemuSystem(X86_64, kernel, testConfigRootfs)
|
||||
q, err := NewSystem(X86_64, kernel, testConfigRootfs)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
Reference in New Issue
Block a user