Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

A free and open-source forge that lives in your Git repo.

Expand the admin status page into an operational dashboard

4506a4d3d279556435fdd414265e7499c3dada16 · Keenan Nemetz · 14d ago · parent 2e024cc9

server/server.go +29−20

@@ -18,6 +18,7 @@ import (
18 18 "github.com/rodent-software/vole/forge/config"
19 19 "github.com/rodent-software/vole/forge/identity"
20 20 "github.com/rodent-software/vole/forge/index"
21 "github.com/rodent-software/vole/forge/pageview"
21 22 "github.com/rodent-software/vole/forge/repo"
22 23 "github.com/rodent-software/vole/forge/session"
23 24 "github.com/rodent-software/vole/server/githttp"
@@ -27,23 +28,24 @@ import (
27 28 )
28 29
29 30 type Server struct {
30 ctx context.Context
31 cancel context.CancelFunc
32 Cfg *config.Config
33 Repos *repo.Store
34 Identity *identity.Store
35 Sessions *session.Store
36 Runs *runs.Store
37 Index *index.Store
38 LFS *lfs.Store
39 Locks *lfs.LockStore
40 Pages *pages.Server
41 Proxy *githttp.Proxy
42 SSH *ssh.Server
43 Web *web.Web
44 Log *slog.Logger
45 mux *http.ServeMux
46 acme *acmeSetup
31 ctx context.Context
32 cancel context.CancelFunc
33 Cfg *config.Config
34 Repos *repo.Store
35 Identity *identity.Store
36 Sessions *session.Store
37 Runs *runs.Store
38 Index *index.Store
39 LFS *lfs.Store
40 Locks *lfs.LockStore
41 PageViews *pageview.Store
42 Pages *pages.Server
43 Proxy *githttp.Proxy
44 SSH *ssh.Server
45 Web *web.Web
46 Log *slog.Logger
47 mux *http.ServeMux
48 acme *acmeSetup
47 49 }
48 50
49 51 func New(cfg *config.Config, binPath string, log *slog.Logger) (*Server, error) {
@@ -109,6 +111,7 @@ func New(cfg *config.Config, binPath string, log *slog.Logger) (*Server, error)
109 111 wp.LFS = inst.LFS
110 112 wp.Locks = inst.Locks
111 113 wp.Sessions = inst.Sessions
114 wp.PageViews = inst.PageViews
112 115 wp.Logger = func(format string, args ...any) { log.Warn(fmt.Sprintf(format, args...)) }
113 116 if cfg.DevLogin != "" {
114 117 log.Warn("development login enabled", "account", cfg.DevLogin, "http_addr", cfg.HTTPAddr)
@@ -122,7 +125,8 @@ func New(cfg *config.Config, binPath string, log *slog.Logger) (*Server, error)
122 125 s := &Server{
123 126 Cfg: cfg, Repos: inst.Repos, Identity: inst.Identity, Sessions: inst.Sessions,
124 127 Runs: inst.Runs, Index: inst.Index, acme: acme,
125 LFS: inst.LFS, Locks: inst.Locks, Proxy: proxy, SSH: ssh, Web: wp, Log: log,
128 LFS: inst.LFS, Locks: inst.Locks, PageViews: inst.PageViews,
129 Proxy: proxy, SSH: ssh, Web: wp, Log: log,
126 130 }
127 131 wp.AllowCI = s.allowContributorCI
128 132 wp.RenameRepo = inst.RenameRepo
@@ -177,7 +181,9 @@ func (s *Server) routes() *http.ServeMux {
177 181 mux.HandleFunc("POST /account/passkeys/begin", w.AddPasskeyBegin)
178 182 mux.HandleFunc("POST /account/passkeys/finish", w.AddPasskeyFinish)
179 183 mux.HandleFunc("GET /auth.js", w.AuthJS)
180 mux.HandleFunc("GET /runners", w.RunnersPage)
184 mux.HandleFunc("GET /runners", func(rw http.ResponseWriter, r *http.Request) {
185 http.Redirect(rw, r, "/status?tab=runners", http.StatusMovedPermanently)
186 })
181 187 mux.HandleFunc("GET /repos/new", w.AdminNewRepoPage)
182 188 mux.HandleFunc("POST /repos", w.CreateAdminRepo)
183 189 mux.HandleFunc("GET /users", w.AdminUsersPage)
@@ -259,7 +265,7 @@ func (s *Server) routes() *http.ServeMux {
259 265 mux.HandleFunc("GET /status", w.StatusPage)
260 266 mux.HandleFunc("GET /healthz", func(rw http.ResponseWriter, r *http.Request) {
261 267 rw.Header().Set("Content-Type", "text/plain")
262 fmt.Fprintf(rw, "ok\nusers=%d\n", s.Identity.Snapshot().Count)
268 fmt.Fprint(rw, "ok\n")
263 269 })
264 270
265 271 // Anonymous, read-only git. Registered without a method so git's POSTs reach it.
@@ -405,6 +411,9 @@ func (s *Server) Close() error {
405 411 if s.Locks != nil {
406 412 _ = s.Locks.Close()
407 413 }
414 if s.PageViews != nil {
415 _ = s.PageViews.Close()
416 }
408 417 if s.Index != nil {
409 418 if err := s.Index.Close(); err != nil {
410 419 return err