shell.go

 1package ssh
 2
 3import (
 4	"fmt"
 5	"io"
 6
 7	"github.com/charmbracelet/log"
 8	"github.com/charmbracelet/soft-serve/pkg/shell"
 9	"github.com/charmbracelet/ssh"
10	"github.com/charmbracelet/wish"
11)
12
13// ShellMiddleware is a middleware for the SSH shell.
14func ShellMiddleware(sh ssh.Handler) ssh.Handler {
15	return func(s ssh.Session) {
16		ctx := s.Context()
17		logger := log.FromContext(ctx).WithPrefix("ssh")
18		envs := &sessionEnv{s}
19
20		ppty, _, isInteractive := s.Pty()
21
22		var (
23			in  io.Reader = s
24			out io.Writer = s
25			er  io.Writer = s.Stderr()
26			err error
27		)
28
29		if isInteractive {
30			in, out, er, err = ptyNew(ppty.Pty)
31			if err != nil {
32				logger.Errorf("could not create pty: %v", err)
33				// TODO: replace this err with a declared error
34				wish.Fatalln(s, fmt.Errorf("internal server error"))
35				return
36			}
37		}
38
39		args := s.Command()
40		if len(args) == 0 {
41			// XXX: args cannot be nil, otherwise cobra will use os.Args[1:]
42			args = []string{}
43		}
44
45		cmd := shell.Command(ctx, envs, isInteractive)
46		cmd.SetArgs(args)
47		cmd.SetIn(in)
48		cmd.SetOut(out)
49		cmd.SetErr(er)
50		cmd.SetContext(ctx)
51
52		if err := cmd.ExecuteContext(ctx); err != nil {
53			wish.Fatalln(s, err)
54			return
55		}
56
57		sh(s)
58	}
59}