diff --git a/qemu-kernel.go b/qemu-kernel.go index bc18ac2..68628b2 100644 --- a/qemu-kernel.go +++ b/qemu-kernel.go @@ -279,3 +279,14 @@ func (q *QemuSystem) CopyFile(user, localPath, remotePath string) (err error) { return } + +// CopyAndRun is copy local file to qemu vm then run it +func (q *QemuSystem) 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 { + return + } + + return q.Command(user, "chmod +x "+remotePath+" && "+remotePath) +} diff --git a/qemu-kernel_test.go b/qemu-kernel_test.go index f7fa3fb..40332c3 100644 --- a/qemu-kernel_test.go +++ b/qemu-kernel_test.go @@ -8,12 +8,18 @@ import ( "crypto/sha512" "fmt" "io/ioutil" + "math/rand" "net" + "os" "strings" "testing" "time" ) +func init() { + rand.Seed(time.Now().UnixNano()) +} + func TestQemuSystemNew_InvalidKernelPath(t *testing.T) { kernel := Kernel{Name: "Invalid", KernelPath: "/invalid/path"} if _, err := NewQemuSystem(X86_64, kernel, "/bin/sh"); err == nil { @@ -172,3 +178,36 @@ func TestQemuSystemCopyFile(t *testing.T) { t.Fatal(fmt.Sprintf("Broken file (%s instead of %s)", sha_remote, sha_local)) } } + +func TestQemuSystemCopyAndRun(t *testing.T) { + qemu, err := startTestQemu() + if err != nil { + t.Fatal(err) + } + defer qemu.Stop() + + randStr := fmt.Sprintf("%d", rand.Int()) + content := []byte("#!/bin/sh\n echo -n " + randStr + "\n") + + tmpfile, err := ioutil.TempFile("", "executable") + if err != nil { + t.Fatal(err) + } + defer os.Remove(tmpfile.Name()) + + if _, err := tmpfile.Write(content); err != nil { + t.Fatal(err) + } + if err := tmpfile.Close(); err != nil { + t.Fatal(err) + } + + output, err := qemu.CopyAndRun("user", tmpfile.Name()) + if err != nil { + t.Fatal(err) + } + + if output != randStr { + t.Fatal("Wrong output from copyied executable (" + output + "," + randStr + ")") + } +}