1
0

Implements async ssh commands

This commit is contained in:
dump_stack() 2018-10-06 14:00:31 +00:00
parent 335fb038a4
commit 6670cd544b
2 changed files with 62 additions and 10 deletions

View File

@ -5,6 +5,7 @@
package qemukernel package qemukernel
import ( import (
"bytes"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -237,14 +238,19 @@ func (q *QemuSystem) Stop() {
} }
} }
// Command executes shell commands on qemu system func (q QemuSystem) ssh(user string) (client *ssh.Client, err error) {
func (q *QemuSystem) Command(user, cmd string) (output string, err error) {
cfg := &ssh.ClientConfig{ cfg := &ssh.ClientConfig{
User: user, User: user,
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
} }
cfg.HostKeyCallback = ssh.InsecureIgnoreHostKey()
client, err := ssh.Dial("tcp", q.sshAddrPort, cfg) client, err = ssh.Dial("tcp", q.sshAddrPort, cfg)
return
}
// Command executes shell commands on qemu system
func (q QemuSystem) Command(user, cmd string) (output string, err error) {
client, err := q.ssh(user)
if err != nil { if err != nil {
return return
} }
@ -260,6 +266,23 @@ func (q *QemuSystem) Command(user, cmd string) (output string, err error) {
return return
} }
// AsyncCommand executes command on qemu system but does not wait for exit
func (q QemuSystem) AsyncCommand(user, cmd string) (err error) {
client, err := q.ssh(user)
if err != nil {
return
}
defer client.Close()
session, err := client.NewSession()
if err != nil {
return
}
return session.Run(fmt.Sprintf(
"nohup sh -c '%s' > /dev/null 2> /dev/null < /dev/null &", cmd))
}
// CopyFile is copy file from local machine to remote through ssh/scp // CopyFile is copy file from local machine to remote through ssh/scp
func (q *QemuSystem) CopyFile(user, localPath, remotePath string) (err error) { func (q *QemuSystem) CopyFile(user, localPath, remotePath string) (err error) {
addrPort := strings.Split(q.sshAddrPort, ":") addrPort := strings.Split(q.sshAddrPort, ":")

View File

@ -96,7 +96,7 @@ func TestQemuSystemStart_Timeout(t *testing.T) {
} }
} }
func startTestQemu(t *testing.T) (q *QemuSystem, err error) { func startTestQemu(t *testing.T, timeout time.Duration) (q *QemuSystem, err error) {
t.Parallel() t.Parallel()
kernel := Kernel{ kernel := Kernel{
Name: "Test kernel", Name: "Test kernel",
@ -108,6 +108,10 @@ func startTestQemu(t *testing.T) (q *QemuSystem, err error) {
return return
} }
if timeout != 0 {
q.Timeout = timeout
}
if err = q.Start(); err != nil { if err = q.Start(); err != nil {
return return
} }
@ -116,7 +120,7 @@ func startTestQemu(t *testing.T) (q *QemuSystem, err error) {
} }
func TestQemuSystemCommand(t *testing.T) { func TestQemuSystemCommand(t *testing.T) {
qemu, err := startTestQemu(t) qemu, err := startTestQemu(t, 0)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -145,7 +149,7 @@ func TestQemuSystemCommand(t *testing.T) {
} }
func TestQemuSystemCopyFile(t *testing.T) { func TestQemuSystemCopyFile(t *testing.T) {
qemu, err := startTestQemu(t) qemu, err := startTestQemu(t, 0)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -177,7 +181,7 @@ func TestQemuSystemCopyFile(t *testing.T) {
} }
func TestQemuSystemCopyAndRun(t *testing.T) { func TestQemuSystemCopyAndRun(t *testing.T) {
qemu, err := startTestQemu(t) qemu, err := startTestQemu(t, 0)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -210,7 +214,7 @@ func TestQemuSystemCopyAndRun(t *testing.T) {
} }
func TestQemuSystemCopyAndInsmod(t *testing.T) { func TestQemuSystemCopyAndInsmod(t *testing.T) {
qemu, err := startTestQemu(t) qemu, err := startTestQemu(t, 0)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -235,3 +239,28 @@ func TestQemuSystemCopyAndInsmod(t *testing.T) {
t.Fatal("insmod returns ok but there is no new kernel modules") t.Fatal("insmod returns ok but there is no new kernel modules")
} }
} }
func TestQemuSystemRun(t *testing.T) {
qemu, err := startTestQemu(t, 0)
if err != nil {
t.Fatal(err)
}
defer qemu.Stop()
for {
_, err := qemu.Command("root", "echo")
if err == nil {
break
}
}
start := time.Now()
err = qemu.AsyncCommand("root", "sleep 10s")
if err != nil {
t.Fatal(err)
}
if time.Since(start) > time.Second {
t.Fatalf("qemu.Run does not async (waited %s)", +time.Since(start))
}
}