Diff
1diff --git a/cmd/soft/main.go b/cmd/soft/main.go
2index f7ea656fe02c4e946e9a4f6a7943c78af9273726..d15a23bd99a6f1aaec4fc2ea6f7c2c99612f61dc 100644
3--- a/cmd/soft/main.go
4+++ b/cmd/soft/main.go
5@@ -1,10 +1,14 @@
6 package main
7
8 import (
9+ "context"
10 "flag"
11 "fmt"
12 "log"
13 "os"
14+ "os/signal"
15+ "syscall"
16+ "time"
17
18 "github.com/charmbracelet/soft-serve/config"
19 "github.com/charmbracelet/soft-serve/server"
20@@ -49,9 +53,23 @@ func main() {
21
22 cfg := config.DefaultConfig()
23 s := server.NewServer(cfg)
24- log.Printf("Starting SSH server on %s:%d\n", cfg.Host, cfg.Port)
25- err := s.Start()
26- if err != nil {
27+
28+ done := make(chan os.Signal, 1)
29+ signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
30+
31+ log.Printf("Starting SSH server on %s:%d", cfg.Host, cfg.Port)
32+ go func() {
33+ if err := s.Start(); err != nil {
34+ log.Fatalln(err)
35+ }
36+ }()
37+
38+ <-done
39+
40+ log.Printf("Stopping SSH server on %s:%d", cfg.Host, cfg.Port)
41+ ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
42+ defer func() { cancel() }()
43+ if err := s.Shutdown(ctx); err != nil {
44 log.Fatalln(err)
45 }
46 }
47diff --git a/server/server.go b/server/server.go
48index e7ab0cf23e23fd31119af8569ecc473df9c1960a..17a0bd7e0c0f3ca6f07827d6bb93450fb97c77c4 100644
49--- a/server/server.go
50+++ b/server/server.go
51@@ -1,6 +1,7 @@
52 package server
53
54 import (
55+ "context"
56 "fmt"
57 "log"
58
59@@ -63,3 +64,8 @@ func (srv *Server) Reload() error {
60 func (srv *Server) Start() error {
61 return srv.SSHServer.ListenAndServe()
62 }
63+
64+// Shutdown lets the server gracefully shutdown.
65+func (srv *Server) Shutdown(ctx context.Context) error {
66+ return srv.SSHServer.Shutdown(ctx)
67+}