Implements async ssh commands
This commit is contained in:
parent
335fb038a4
commit
6670cd544b
@ -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, ":")
|
||||||
|
@ -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))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user