server.go

 1package server
 2
 3import (
 4	"context"
 5	"log"
 6
 7	"github.com/charmbracelet/soft-serve/config"
 8	appCfg "github.com/charmbracelet/soft-serve/internal/config"
 9)
10
11// Server is the Soft Serve server.
12type Server struct {
13	HTTPServer *HTTPServer
14	SSHServer  *SSHServer
15	Cfg        *config.Config
16	ac         *appCfg.Config
17}
18
19// NewServer returns a new *ssh.Server configured to serve Soft Serve. The SSH
20// server key-pair will be created if none exists. An initial admin SSH public
21// key can be provided with authKey. If authKey is provided, access will be
22// restricted to that key. If authKey is not provided, the server will be
23// publicly writable until configured otherwise by cloning the `config` repo.
24func NewServer(cfg *config.Config) *Server {
25	ac, err := appCfg.NewConfig(cfg)
26	if err != nil {
27		log.Fatal(err)
28	}
29	return &Server{
30		HTTPServer: NewHTTPServer(cfg, ac),
31		SSHServer:  NewSSHServer(cfg, ac),
32		Cfg:        cfg,
33		ac:         ac,
34	}
35}
36
37// Reload reloads the server configuration.
38func (srv *Server) Reload() error {
39	return srv.ac.Reload()
40}
41
42func (s *Server) Start() {
43	go func() {
44		log.Printf("Starting HTTP server on %s:%d", s.Cfg.BindAddr, s.Cfg.HTTPPort)
45		if err := s.HTTPServer.Start(); err != nil {
46			log.Fatal(err)
47		}
48	}()
49	log.Printf("Starting SSH server on %s:%d", s.Cfg.BindAddr, s.Cfg.SSHPort)
50	if err := s.SSHServer.Start(); err != nil {
51		log.Fatal(err)
52	}
53}
54
55func (s *Server) Shutdown(ctx context.Context) error {
56	log.Printf("Stopping SSH server on %s:%d", s.Cfg.BindAddr, s.Cfg.SSHPort)
57	err := s.SSHServer.Shutdown(ctx)
58	if err != nil {
59		return err
60	}
61	log.Printf("Stopping HTTP server on %s:%d", s.Cfg.BindAddr, s.Cfg.SSHPort)
62	return s.HTTPServer.Shutdown(ctx)
63}