Browse Source

En cours de développement

master
mls-361 4 months ago
parent
commit
5294ae6d49
  1. 1
      Taskfile.yml
  2. 2
      client.go
  3. 91
      connection.go
  4. 6
      go.mod
  5. 19
      go.sum
  6. 49
      session.go
  7. 96
      stream.go

1
Taskfile.yml

@ -6,7 +6,6 @@ version: '3'
tasks:
update:
cmds:
- go get -u forge.chapril.org/mls-361/crypto
- go get -u forge.chapril.org/mls-361/errors
- go get -u forge.chapril.org/mls-361/logger
- go mod tidy

2
client.go

@ -7,7 +7,7 @@
package ssh
import (
"github.com/mls-361/logger"
"forge.chapril.org/mls-361/logger"
"golang.org/x/crypto/ssh"
)

91
connection.go

@ -6,6 +6,97 @@
package ssh
import (
"bufio"
"io"
"time"
"forge.chapril.org/mls-361/logger"
"golang.org/x/crypto/ssh"
)
// Connection AFAIRE.
type Connection struct {
client *Client
logger logger.Logger
ssh *ssh.Client
}
// Host AFAIRE.
func (conn *Connection) Host() string {
return conn.client.host
}
// Port AFAIRE.
func (conn *Connection) Port() int {
return conn.client.port
}
// Username AFAIRE.
func (conn *Connection) Username() string {
return conn.client.username
}
// NewSession AFAIRE.
func (conn *Connection) NewSession() (*Session, error) {
s, err := conn.ssh.NewSession()
if err != nil {
return nil, err
}
session := &Session{
Session: s,
client: conn.client,
logger: conn.logger,
}
return session, nil
}
// ReadStream AFAIRE.
func (conn *Connection) ReadStream(cmd string, timeout time.Duration) (*Stream, error) {
session, err := conn.NewSession()
if err != nil {
return nil, err
}
s := &Stream{
session: session,
stderr: make(chan string),
stdout: make(chan string),
done: make(chan bool),
}
stdoutReader, err := session.StdoutPipe()
if err != nil {
s.Close()
return nil, err
}
stderrReader, err := session.StderrPipe()
if err != nil {
s.Close()
return nil, err
}
stderrScanner := bufio.NewScanner(io.MultiReader(stderrReader))
stdoutScanner := bufio.NewScanner(io.MultiReader(stdoutReader))
if err := session.Start(cmd); err != nil {
s.Close()
return nil, err
}
go s.readData(timeout, stderrScanner, stdoutScanner) //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
return s, nil
}
// Disconnect AFAIRE.
func (conn *Connection) Disconnect() {
conn.ssh.Close()
}
/*
######################################################################################################## @(°_°)@ #######
*/

6
go.mod

@ -1,3 +1,9 @@
module forge.chapril.org/mls-361/ssh
go 1.16
require (
forge.chapril.org/mls-361/errors v0.0.0-20210507222244-6017b9315140
forge.chapril.org/mls-361/logger v0.0.0-20210511132528-884fa4c98c68
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
)

19
go.sum

@ -0,0 +1,19 @@
forge.chapril.org/mls-361/buffer v0.0.0-20210410182428-5dc7a7b2ae79 h1:Lh+y98uVFC7btl5FdxKNtokzHD2j14R4ZIgJECao6r4=
forge.chapril.org/mls-361/buffer v0.0.0-20210410182428-5dc7a7b2ae79/go.mod h1:JnOkXF+AEkQ4mv65rzW9eVLsauGzOYIUBQB0zUb5NGE=
forge.chapril.org/mls-361/errors v0.0.0-20210507222244-6017b9315140 h1:uBp4Uz62/2Yq1yjRRtNaUXoZLQB84vbHf19TTbOfT1Y=
forge.chapril.org/mls-361/errors v0.0.0-20210507222244-6017b9315140/go.mod h1:GBBbrcpLm0Hww05AoFQJY3tTXbNBOQPqV+qTFEWpL20=
forge.chapril.org/mls-361/kvfmt v0.0.0-20210507213839-4f18d8b29e73 h1:OKwxmpmkdhy9SWwZcJrz7Fp57LWpY/PNloHdFiDc4Ek=
forge.chapril.org/mls-361/kvfmt v0.0.0-20210507213839-4f18d8b29e73/go.mod h1:bv44R0CAd8lQV4ub1hjLE3kWYwpfsW4Ro9zRnD4YOMU=
forge.chapril.org/mls-361/logger v0.0.0-20210511132528-884fa4c98c68 h1:n5qBjDnfCFOb3LWJj/ySg7wsJe6IISeOm5dlILfzLUg=
forge.chapril.org/mls-361/logger v0.0.0-20210511132528-884fa4c98c68/go.mod h1:R/JAwND755VIZ+uTkwqtgY3GmPzS+Nn8NKXPXBr2JwQ=
forge.chapril.org/mls-361/uuid v0.0.0-20210511091055-533cd6b13c6f h1:ycJeyJjfkgEaiiNmOKd74Jir+qtlGlB17Dstvi1KekQ=
forge.chapril.org/mls-361/uuid v0.0.0-20210511091055-533cd6b13c6f/go.mod h1:OAYM+f6ErfC4jbruuG2crA5W7YSpr7+wEs2MrxIzR3Q=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

49
session.go

@ -6,6 +6,55 @@
package ssh
import (
"forge.chapril.org/mls-361/logger"
"golang.org/x/crypto/ssh"
)
type (
// Session AFAIRE.
Session struct {
*ssh.Session
client *Client
logger logger.Logger
}
)
func (s *Session) trace(cmd string) {
if s.logger != nil {
s.logger.Debug( //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
"SSH",
"server", s.client.host,
"username", s.client.username,
"cmd", cmd,
)
}
}
// CombinedOutput AFAIRE.
func (s *Session) CombinedOutput(cmd string) ([]byte, error) {
s.trace(cmd)
return s.Session.CombinedOutput(cmd)
}
// Output AFAIRE.
func (s *Session) Output(cmd string) ([]byte, error) {
s.trace(cmd)
return s.Session.Output(cmd)
}
// Run AFAIRE.
func (s *Session) Run(cmd string) error {
s.trace(cmd)
return s.Session.Run(cmd)
}
// Start AFAIRE.
func (s *Session) Start(cmd string) error {
s.trace(cmd)
return s.Session.Start(cmd)
}
/*
######################################################################################################## @(°_°)@ #######
*/

96
stream.go

@ -6,6 +6,102 @@
package ssh
import (
"bufio"
"sync"
"time"
)
// Stream AFAIRE.
type Stream struct {
session *Session
stderr chan string
stdout chan string
done chan bool
err error
}
func (s *Stream) readData(timeout time.Duration, stderrScanner, stdoutScanner *bufio.Scanner) {
stop := make(chan struct{}, 1)
defer close(stop)
group := sync.WaitGroup{}
group.Add(2)
go func() { //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
for stderrScanner.Scan() {
s.stderr <- stderrScanner.Text()
}
group.Done()
}()
go func() { //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
for stdoutScanner.Scan() {
s.stdout <- stdoutScanner.Text()
}
group.Done()
}()
go func() { //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
group.Wait()
stop <- struct{}{}
}()
select {
case <-stop:
s.err = s.session.Wait()
s.done <- true
case <-time.After(timeout):
s.done <- false
}
}
// Stderr AFAIRE.
func (s *Stream) Stderr() <-chan string {
return s.stderr
}
// Stdout AFAIRE.
func (s *Stream) Stdout() <-chan string {
return s.stdout
}
// Done AFAIRE.
func (s *Stream) Done() <-chan bool {
return s.done
}
// Err AFAIRE.
func (s *Stream) Err() error {
return s.err
}
// Close AFAIRE.
func (s *Stream) Close() {
if s.done != nil {
close(s.done)
s.done = nil
}
if s.stdout != nil {
close(s.stdout)
s.stdout = nil
}
if s.stderr != nil {
close(s.stderr)
s.stderr = nil
}
if s.session != nil {
s.session.Close()
s.session = nil
}
}
/*
######################################################################################################## @(°_°)@ #######
*/

Loading…
Cancel
Save