From b5bad4defc6c75b9b969658229ce5fd2f3a46107 Mon Sep 17 00:00:00 2001 From: Ben Busby Date: Tue, 21 Jan 2025 13:46:29 -0700 Subject: Rewrite project, add daily update of services list The project was rewritten from Elixir to Go, primarily because: - I don't write Elixir anymore and don't want to maintain a project in a language I no longer write - I already write Go for other projects, including my day job, so it's a safer bet for a project that I want to maintain long term - Go allows me to build portable executables that will make it easier for others to run farside on their own machines The Go version of Farsside also has a built in task to fetch the latest services{-full}.json file from the repo and ingest it, which makes running a farside server a lot simpler. It also automatically fetches the latest instance state from https://farside.link unless configured as a primary farside node, which will allow others to use farside without increasing traffic to all instances that are queried by farside (just to the farside node itself). --- services/services.go | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 services/services.go (limited to 'services/services.go') diff --git a/services/services.go b/services/services.go new file mode 100644 index 0000000..b9e5693 --- /dev/null +++ b/services/services.go @@ -0,0 +1,93 @@ +package services + +import ( + "encoding/json" + "io" + "net/http" + "os" +) + +var ( + ServiceList []Service + FallbackMap map[string]string +) + +const ( + baseRepoLink = "https://git.sr.ht/~benbusby/farside/blob/main/" + + noCFServicesJSON = "services.json" + fullServicesJSON = "services-full.json" +) + +type Service struct { + Type string `json:"type"` + TestURL string `json:"test_url,omitempty"` + Fallback string `json:"fallback,omimtempty"` + Instances []string `json:"instances"` +} + +func ingestServicesList(servicesBytes []byte) error { + err := json.Unmarshal(servicesBytes, &ServiceList) + return err +} + +func GetServicesFileName() string { + cloudflareEnabled := false + + cfEnabledVar := os.Getenv("FARSIDE_CF_ENABLED") + if len(cfEnabledVar) > 0 && cfEnabledVar == "1" { + cloudflareEnabled = true + } + + serviceJSON := noCFServicesJSON + if cloudflareEnabled { + serviceJSON = fullServicesJSON + } + + return serviceJSON +} + + +func FetchServicesFile(serviceJSON string) ([]byte, error) { + resp, err := http.Get(baseRepoLink + serviceJSON) + if err != nil { + return nil, err + } + + defer resp.Body.Close() + + bodyBytes, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + err = os.WriteFile(serviceJSON, bodyBytes, 0666) + if err != nil { + return nil, err + } + + return bodyBytes, nil +} + +func InitializeServices() error { + serviceJSON := GetServicesFileName() + fileBytes, err := os.ReadFile(serviceJSON) + if err != nil { + fileBytes, err = FetchServicesFile(serviceJSON) + if err != nil { + return err + } + } + + err = ingestServicesList(fileBytes) + if err != nil { + return err + } + + FallbackMap = make(map[string]string) + for _, serviceElement := range ServiceList { + FallbackMap[serviceElement.Type] = serviceElement.Fallback + } + + return nil +} -- cgit v1.2.3