fork of indigo with slightly nicer lexgen
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

relay pull-hosts command (for public bootstrapping) (#1047)

This helper command queries an existing relay instance for known hosts,
and adds them to the local instance (if they aren't already). The
intention is to make bootstrapping a new full-network relay easier (eg,
avoid wrangling bash script pipelines and admin API requests).

It does some filtering and checks to try and skip inactive/stale hosts:
only "active" (or "idle") hosts which have seen at least one event
remotely (aka, `seq` is positive), and does an (optional) HTTP request
to `describeServer` on the host to check it is live.

This command should only be run if the overall relay isn't already
running as a daemon. It is safe to run it multiple times, or after the
relay has been running for some time.

(this code is pretty off-the-cuff; I've run it a few times to test, and
it isn't critical to our prod use, but could definitely use eyes)

authored by bnewbold.net and committed by

GitHub 57d5c7ba 75944060

+164
+2
cmd/relay/main.go
··· 178 178 }, 179 179 }, 180 180 }, 181 + // additional commands defined in pull.go 182 + cmdPullHosts, 181 183 } 182 184 return app.Run(os.Args) 183 185
+162
cmd/relay/pull.go
··· 1 + package main 2 + 3 + import ( 4 + "errors" 5 + "fmt" 6 + 7 + comatproto "github.com/bluesky-social/indigo/api/atproto" 8 + "github.com/bluesky-social/indigo/atproto/identity" 9 + "github.com/bluesky-social/indigo/cmd/relay/relay" 10 + "github.com/bluesky-social/indigo/cmd/relay/relay/models" 11 + "github.com/bluesky-social/indigo/util/cliutil" 12 + "github.com/bluesky-social/indigo/xrpc" 13 + 14 + "github.com/urfave/cli/v2" 15 + ) 16 + 17 + var cmdPullHosts = &cli.Command{ 18 + Name: "pull-hosts", 19 + Usage: "initializes or updates host list from an existing relay (public API)", 20 + Action: runPullHosts, 21 + Flags: []cli.Flag{ 22 + &cli.StringFlag{ 23 + Name: "relay-host", 24 + Usage: "method, hostname, and port of relay to pull from", 25 + Value: "https://bsky.network", 26 + EnvVars: []string{"RELAY_HOST"}, 27 + }, 28 + &cli.StringFlag{ 29 + Name: "db-url", 30 + Usage: "database connection string for relay database", 31 + Value: "sqlite://data/relay/relay.sqlite", 32 + EnvVars: []string{"DATABASE_URL"}, 33 + }, 34 + &cli.IntFlag{ 35 + Name: "default-account-limit", 36 + Value: 100, 37 + Usage: "max number of active accounts for new upstream hosts", 38 + EnvVars: []string{"RELAY_DEFAULT_ACCOUNT_LIMIT", "RELAY_DEFAULT_REPO_LIMIT"}, 39 + }, 40 + &cli.IntFlag{ 41 + Name: "batch-size", 42 + Value: 500, 43 + Usage: "host many hosts to pull at a time", 44 + EnvVars: []string{"RELAY_PULL_HOSTS_BATCH_SIZE"}, 45 + }, 46 + &cli.StringSliceFlag{ 47 + Name: "trusted-domains", 48 + Usage: "domain names which mark trusted hosts; use wildcard prefix to match suffixes", 49 + Value: cli.NewStringSlice("*.host.bsky.network"), 50 + EnvVars: []string{"RELAY_TRUSTED_DOMAINS"}, 51 + }, 52 + &cli.BoolFlag{ 53 + Name: "skip-host-checks", 54 + Usage: "don't run describeServer requests to see if host is a PDS before adding", 55 + EnvVars: []string{"RELAY_SKIP_HOST_CHECKS"}, 56 + }, 57 + }, 58 + } 59 + 60 + func runPullHosts(cctx *cli.Context) error { 61 + ctx := cctx.Context 62 + 63 + if cctx.Args().Len() > 0 { 64 + return fmt.Errorf("unexpected arguments") 65 + } 66 + 67 + client := xrpc.Client{ 68 + Host: cctx.String("relay-host"), 69 + } 70 + 71 + skipHostChecks := cctx.Bool("skip-host-checks") 72 + 73 + dir := identity.DefaultDirectory() 74 + 75 + dburl := cctx.String("db-url") 76 + db, err := cliutil.SetupDatabase(dburl, 10) 77 + if err != nil { 78 + return err 79 + } 80 + 81 + relayConfig := relay.DefaultRelayConfig() 82 + relayConfig.DefaultRepoLimit = cctx.Int64("default-account-limit") 83 + relayConfig.TrustedDomains = cctx.StringSlice("trusted-domains") 84 + 85 + // NOTE: setting evtmgr to nil 86 + r, err := relay.NewRelay(db, nil, dir, relayConfig) 87 + if err != nil { 88 + return err 89 + } 90 + 91 + checker := relay.NewHostClient(relayConfig.UserAgent) 92 + 93 + cursor := "" 94 + size := cctx.Int64("batch-size") 95 + for { 96 + resp, err := comatproto.SyncListHosts(ctx, &client, cursor, size) 97 + if err != nil { 98 + return err 99 + } 100 + for _, h := range resp.Hosts { 101 + if h.Status == nil { 102 + fmt.Printf("%s: status=unknown\n", h.Hostname) 103 + continue 104 + } 105 + if !(models.HostStatus(*h.Status) == models.HostStatusActive || models.HostStatus(*h.Status) == models.HostStatusIdle) { 106 + fmt.Printf("%s: status=%s\n", h.Hostname, *h.Status) 107 + continue 108 + } 109 + if h.Seq == nil || *h.Seq <= 0 { 110 + fmt.Printf("%s: no-cursor\n", h.Hostname) 111 + continue 112 + } 113 + existing, err := r.GetHost(ctx, h.Hostname) 114 + if err != nil && !errors.Is(err, relay.ErrHostNotFound) { 115 + return err 116 + } 117 + if existing != nil { 118 + fmt.Printf("%s: exists\n", h.Hostname) 119 + continue 120 + } 121 + hostname, noSSL, err := relay.ParseHostname(h.Hostname) 122 + if err != nil { 123 + return fmt.Errorf("%w: %s", err, h.Hostname) 124 + } 125 + if noSSL { 126 + // skip "localhost" and non-SSL hosts (this is for public PDS instances) 127 + fmt.Printf("%s: non-public\n", h.Hostname) 128 + continue 129 + } 130 + 131 + accountLimit := r.Config.DefaultRepoLimit 132 + trusted := relay.IsTrustedHostname(hostname, r.Config.TrustedDomains) 133 + if trusted { 134 + accountLimit = r.Config.TrustedRepoLimit 135 + } 136 + 137 + if !skipHostChecks { 138 + if err := checker.CheckHost(ctx, "https://"+hostname); err != nil { 139 + fmt.Printf("%s: checking host: %s\n", h.Hostname, err) 140 + continue 141 + } 142 + } 143 + 144 + host := models.Host{ 145 + Hostname: hostname, 146 + NoSSL: noSSL, 147 + Status: models.HostStatusActive, 148 + Trusted: trusted, 149 + AccountLimit: accountLimit, 150 + } 151 + if err := db.Create(&host).Error; err != nil { 152 + return err 153 + } 154 + fmt.Printf("%s: added\n", h.Hostname) 155 + } 156 + if resp.Cursor == nil || *resp.Cursor == "" { 157 + break 158 + } 159 + cursor = *resp.Cursor 160 + } 161 + return nil 162 + }