forked from tangled.org/core
Monorepo for Tangled — https://tangled.org
1package knotserver 2 3import ( 4 "context" 5 "fmt" 6 "net/http" 7 8 "github.com/urfave/cli/v3" 9 "tangled.sh/tangled.sh/core/api/tangled" 10 "tangled.sh/tangled.sh/core/jetstream" 11 "tangled.sh/tangled.sh/core/knotserver/config" 12 "tangled.sh/tangled.sh/core/knotserver/db" 13 "tangled.sh/tangled.sh/core/log" 14 "tangled.sh/tangled.sh/core/rbac" 15) 16 17func Command() *cli.Command { 18 return &cli.Command{ 19 Name: "server", 20 Usage: "run a knot server", 21 Action: Run, 22 Description: ` 23Environment variables: 24 KNOT_SERVER_SECRET (required) 25 KNOT_SERVER_HOSTNAME (required) 26 KNOT_SERVER_LISTEN_ADDR (default: 0.0.0.0:5555) 27 KNOT_SERVER_INTERNAL_LISTEN_ADDR (default: 127.0.0.1:5444) 28 KNOT_SERVER_DB_PATH (default: knotserver.db) 29 KNOT_SERVER_JETSTREAM_ENDPOINT (default: wss://jetstream1.us-west.bsky.network/subscribe) 30 KNOT_SERVER_DEV (default: false) 31 KNOT_REPO_SCAN_PATH (default: /home/git) 32 KNOT_REPO_README (comma-separated list) 33 KNOT_REPO_MAIN_BRANCH (default: main) 34 APPVIEW_ENDPOINT (default: https://tangled.sh) 35`, 36 } 37} 38 39func Run(ctx context.Context, cmd *cli.Command) error { 40 l := log.FromContext(ctx) 41 42 c, err := config.Load(ctx) 43 if err != nil { 44 return fmt.Errorf("failed to load config: %w", err) 45 } 46 47 if c.Server.Dev { 48 l.Info("running in dev mode, signature verification is disabled") 49 } 50 51 db, err := db.Setup(c.Server.DBPath) 52 if err != nil { 53 return fmt.Errorf("failed to load db: %w", err) 54 } 55 56 e, err := rbac.NewEnforcer(c.Server.DBPath) 57 if err != nil { 58 return fmt.Errorf("failed to setup rbac enforcer: %w", err) 59 } 60 61 e.E.EnableAutoSave(true) 62 63 jc, err := jetstream.NewJetstreamClient(c.Server.JetstreamEndpoint, "knotserver", []string{ 64 tangled.PublicKeyNSID, 65 tangled.KnotMemberNSID, 66 }, nil, l, db, true) 67 if err != nil { 68 l.Error("failed to setup jetstream", "error", err) 69 } 70 71 mux, err := Setup(ctx, c, db, e, jc, l) 72 if err != nil { 73 return fmt.Errorf("failed to setup server: %w", err) 74 } 75 imux := Internal(ctx, db, e) 76 77 l.Info("starting internal server", "address", c.Server.InternalListenAddr) 78 go http.ListenAndServe(c.Server.InternalListenAddr, imux) 79 80 l.Info("starting main server", "address", c.Server.ListenAddr) 81 l.Error("server error", "error", http.ListenAndServe(c.Server.ListenAddr, mux)) 82 83 return nil 84}