wish/main.go (view raw)
1package main
2
3import (
4 "context"
5 "errors"
6 "net"
7 "os"
8 "os/signal"
9 "syscall"
10 "time"
11
12 "github.com/charmbracelet/log"
13 "github.com/charmbracelet/ssh"
14 "github.com/charmbracelet/wish"
15 "github.com/charmbracelet/wish/activeterm"
16 "github.com/charmbracelet/wish/logging"
17)
18
19const (
20 host = "localhost"
21 port = "23234"
22)
23
24func main() {
25 s, err := wish.NewServer(
26 wish.WithAddress(net.JoinHostPort(host, port)),
27
28 // Allocate a pty.
29 // This creates a pseudoconsole on windows, compatibility is limited in
30 // that case, see the open issues for more details.
31 ssh.AllocatePty(),
32 wish.WithMiddleware(
33 func(next ssh.Handler) ssh.Handler {
34 return func(s ssh.Session) {
35 cmd := wish.Command(s, "../glog", "-path", "..")
36 if err := cmd.Run(); err != nil {
37 wish.Fatalln(s, err)
38 }
39 next(s)
40 }
41 },
42 // ensure the user has requested a tty
43 activeterm.Middleware(),
44 logging.Middleware(),
45 ),
46 )
47 if err != nil {
48 log.Error("Could not start server", "error", err)
49 }
50
51 done := make(chan os.Signal, 1)
52 signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
53 log.Info("Starting SSH server", "host", host, "port", port)
54 go func() {
55 if err = s.ListenAndServe(); err != nil && !errors.Is(err, ssh.ErrServerClosed) {
56 log.Error("Could not start server", "error", err)
57 done <- nil
58 }
59 }()
60
61 <-done
62 log.Info("Stopping SSH server")
63 ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
64 defer func() { cancel() }()
65 if err := s.Shutdown(ctx); err != nil && !errors.Is(err, ssh.ErrServerClosed) {
66 log.Error("Could not stop server", "error", err)
67 }
68}