Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var ( // Command is the serve command. Command = &cobra.Command{ Use: "serve", Short: "Start the server", Args: cobra.NoArgs, PersistentPreRunE: cmd.InitBackendContext, PersistentPostRunE: cmd.CloseDBContext, RunE: func(c *cobra.Command, _ []string) error { ctx := c.Context() cfg := config.DefaultConfig() if cfg.Exist() { if err := cfg.ParseFile(); err != nil { return fmt.Errorf("parse config file: %w", err) } } else { if err := cfg.WriteConfig(); err != nil { return fmt.Errorf("write config file: %w", err) } } if err := cfg.ParseEnv(); err != nil { return fmt.Errorf("parse environment variables: %w", err) } customHooksPath := filepath.Join(cfg.DataPath, "hooks") if _, err := os.Stat(customHooksPath); err != nil && os.IsNotExist(err) { os.MkdirAll(customHooksPath, os.ModePerm) hookPath := filepath.Join(customHooksPath, "update.sample") if err := os.WriteFile(hookPath, []byte(updateHookExample), 0o744); err != nil { return fmt.Errorf("failed to generate update hook example: %w", err) } } logPath := filepath.Join(cfg.DataPath, "log") if _, err := os.Stat(logPath); err != nil && os.IsNotExist(err) { os.MkdirAll(logPath, os.ModePerm) } db := db.FromContext(ctx) if err := migrate.Migrate(ctx, db); err != nil { return fmt.Errorf("migration error: %w", err) } s, err := NewServer(ctx) if err != nil { return fmt.Errorf("start server: %w", err) } if syncHooks { be := backend.FromContext(ctx) if err := cmd.InitializeHooks(ctx, cfg, be); err != nil { return fmt.Errorf("initialize hooks: %w", err) } } lch := make(chan error, 1) done := make(chan os.Signal, 1) doneOnce := sync.OnceFunc(func() { close(done) }) signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP) if testRun, _ := strconv.ParseBool(os.Getenv("SOFT_SERVE_TESTRUN")); testRun { h := s.HTTPServer.Server.Handler s.HTTPServer.Server.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/__stop" && r.Method == http.MethodHead { doneOnce() return } h.ServeHTTP(w, r) }) } go func() { lch <- s.Start() doneOnce() }() for { select { case err := <-lch: if err != nil { return fmt.Errorf("server error: %w", err) } case sig := <-done: if sig == syscall.SIGHUP { s.logger.Info("received SIGHUP signal, reloading TLS certificates if enabled") if err := s.ReloadCertificates(); err != nil { s.logger.Error("failed to reload TLS certificates", "err", err) } continue } } break } ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() if err := s.Shutdown(ctx); err != nil { return err } return nil }, } )
Functions ¶
This section is empty.
Types ¶
type CertReloader ¶
type CertReloader struct {
// contains filtered or unexported fields
}
CertReloader is responsible for reloading TLS certificates when a SIGHUP signal is received.
func NewCertReloader ¶
func NewCertReloader(certPath, keyPath string, logger *log.Logger) (*CertReloader, error)
NewCertReloader creates a new CertReloader that watches for SIGHUP signals.
func (*CertReloader) GetCertificateFunc ¶
func (cr *CertReloader) GetCertificateFunc() func(*tls.ClientHelloInfo) (*tls.Certificate, error)
GetCertificateFunc returns a function that can be used with tls.Config.GetCertificate.
func (*CertReloader) Reload ¶
func (cr *CertReloader) Reload() error
Reload attempts to reload the certificate and key.
type Server ¶
type Server struct {
SSHServer *sshsrv.SSHServer
GitDaemon *daemon.GitDaemon
HTTPServer *web.HTTPServer
StatsServer *stats.StatsServer
CertLoader *CertReloader
Cron *cron.Scheduler
Config *config.Config
Backend *backend.Backend
DB *db.DB
// contains filtered or unexported fields
}
Server is the Soft Serve server.
func NewServer ¶
NewServer returns a new *Server configured to serve Soft Serve. The SSH server key-pair will be created if none exists. It expects a context with *backend.Backend, *db.DB, *log.Logger, and *config.Config attached.
func (*Server) ReloadCertificates ¶
ReloadCertificates reloads the TLS certificates for the HTTP server.
Click to show internal directories.
Click to hide internal directories.