start using ssh pipes

This commit is contained in:
shoopea
2023-08-21 14:37:47 +02:00
parent 1a1713eb14
commit f616c4ccf9
5 changed files with 109 additions and 49 deletions

77
ssh.go
View File

@@ -1,7 +1,7 @@
package main
import (
"bytes"
"io"
"os"
"time"
@@ -14,10 +14,14 @@ const SshDialTimeout = time.Duration(10 * time.Second)
const SshInactivityTimeout = time.Duration(time.Minute)
type Ssh struct {
name string
signer ssh.Signer
config *ssh.ClientConfig
client *ssh.Client
name string
signer ssh.Signer
config *ssh.ClientConfig
client *ssh.Client
session *ssh.Session
in io.WriteCloser
out io.Reader
err io.Reader
}
func NewSsh(name, addr, user, key string) (*Ssh, error) {
@@ -101,27 +105,66 @@ func (s *Ssh) Exec(cmd string) (string, error) {
log.WithFields(log.Fields{"name": s.name, "cmd": cmd}).Debugf("starting")
defer log.WithFields(log.Fields{"name": s.name, "cmd": cmd}).Debugf("done")
session, err := s.client.NewSession()
if err != nil {
log.WithFields(log.Fields{"name": s.name, "cmd": cmd, "call": "client.NewSession", "error": err}).Errorf("")
if err := s.ExecPipe(cmd); err != nil {
log.WithFields(log.Fields{"name": s.name, "cmd": cmd, "call": "ssh.ExecPipe", "error": err}).Errorf("")
return "", err
}
defer session.Close()
defer s.session.Close()
if session.Setenv("TZ", cfg.Timezone); err != nil {
if err := s.session.Wait(); err != nil {
log.WithFields(log.Fields{"name": s.name, "cmd": cmd, "call": "session.Setenv", "error": err}).Errorf("")
return "", err
}
var bufout, buferr bytes.Buffer
session.Stdout = &bufout
session.Stderr = &buferr
err = session.Run(cmd)
buf, err := io.ReadAll(s.out)
if err != nil {
log.WithFields(log.Fields{"name": s.name, "cmd": cmd, "call": "session.Run", "error": err, "stderr": buferr.String()}).Errorf("")
log.WithFields(log.Fields{"name": s.name, "cmd": cmd, "call": "io.ReadAll", "error": err}).Errorf("")
return "", err
}
return bufout.String(), nil
return string(buf), nil
}
func (s *Ssh) ExecPipe(cmd string) error {
log.WithFields(log.Fields{"name": s.name, "cmd": cmd}).Debugf("starting")
defer log.WithFields(log.Fields{"name": s.name, "cmd": cmd}).Debugf("done")
session, err := s.client.NewSession()
if err != nil {
log.WithFields(log.Fields{"name": s.name, "cmd": cmd, "call": "client.NewSession", "error": err}).Errorf("")
return err
}
s.session = session
if s.session.Setenv("TZ", cfg.Timezone); err != nil {
log.WithFields(log.Fields{"name": s.name, "cmd": cmd, "call": "session.Setenv", "error": err}).Errorf("")
return err
}
if s.in, err = s.session.StdinPipe(); err != nil {
log.WithFields(log.Fields{"name": s.name, "cmd": cmd, "call": "session.StdinPipe", "error": err}).Errorf("")
s.session.Close()
return err
}
if s.out, err = s.session.StdoutPipe(); err != nil {
log.WithFields(log.Fields{"name": s.name, "cmd": cmd, "call": "session.StdoutPipe", "error": err}).Errorf("")
s.session.Close()
return err
}
if s.err, err = s.session.StderrPipe(); err != nil {
log.WithFields(log.Fields{"name": s.name, "cmd": cmd, "call": "session.StderrPipe", "error": err}).Errorf("")
s.session.Close()
return err
}
if err = s.session.Start(cmd); err != nil {
log.WithFields(log.Fields{"name": s.name, "cmd": cmd, "call": "session.Start", "error": err}).Errorf("")
s.session.Close()
return err
}
return nil
}