/
process.go
66 lines (58 loc) 路 1.46 KB
/
process.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package ssh
import (
"bytes"
"fmt"
"io"
"os"
"github.com/willfantom/nescript"
"golang.org/x/crypto/ssh"
)
// Process represents a single instance of the script running or completed on
// the local device.
type SSHProcess struct {
sshSession *ssh.Session
sshClient *ssh.Client
stdin io.Writer
stdoutBytes bytes.Buffer
stderrBytes bytes.Buffer
}
func (p *SSHProcess) Kill() error {
if err := p.sshSession.Signal(ssh.SIGKILL); err != nil {
return fmt.Errorf("failed to kill process: %w", err)
}
return nil
}
func (p *SSHProcess) Signal(s os.Signal) error {
if err := p.sshSession.Signal(ssh.Signal(s.String())); err != nil {
return fmt.Errorf("failed to send signal to process: %w", err)
}
return nil
}
func (p *SSHProcess) Write(input string) error {
if _, err := io.WriteString(p.stdin, input); err != nil {
return fmt.Errorf("failed to write to stdin: %w", err)
}
return nil
}
func (p *SSHProcess) Result() (*nescript.Result, error) {
defer p.sshSession.Close()
defer p.sshClient.Close()
exitCode := 0
if err := p.sshSession.Wait(); err != nil {
if eerr, ok := err.(*ssh.ExitError); !ok {
return nil, fmt.Errorf("failed to wait for ssh process: %w", err)
} else {
exitCode = eerr.ExitStatus()
}
}
result := nescript.Result{
StdOut: string(p.stdoutBytes.String()),
StdErr: string(p.stderrBytes.String()),
}
result.ExitCode = exitCode
return &result, nil
}
func (p *SSHProcess) Close() {
p.sshSession.Close()
p.sshClient.Close()
}