diff options
| author | Xe Iaso <me@xeiaso.net> | 2024-11-09 10:50:59 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-09 10:50:59 -0500 |
| commit | 20d07c7005665f8e2001b4cbd24e15ec589d9882 (patch) | |
| tree | 8b98d1446c6d9e42bc2621e633543e0420f43541 /cmd | |
| parent | 2b349f56cb20420dd153f40f22b3654b5079100f (diff) | |
| download | xesite-20d07c7005665f8e2001b4cbd24e15ec589d9882.tar.xz xesite-20d07c7005665f8e2001b4cbd24e15ec589d9882.zip | |
Move to Kubernetes (#853)
* start to lift-and-shift to k8s
Signed-off-by: Xe Iaso <me@xeiaso.net>
* manifest/xesite: properly configure pod disruption budget, hostmount for xesite as a hack
Signed-off-by: Xe Iaso <me@xeiaso.net>
* properly slonk readiness
Signed-off-by: Xe Iaso <me@xeiaso.net>
* manifest: move to aeacus
Signed-off-by: Xe Iaso <me@xeiaso.net>
* internal: add OnionLocation middleware
Signed-off-by: Xe Iaso <me@xeiaso.net>
* internal/lume: jettison serving from the zipfile
Signed-off-by: Xe Iaso <me@xeiaso.net>
* yolo deploy to prod
Signed-off-by: Xe Iaso <me@xeiaso.net>
* okay use a machineproxy here
Signed-off-by: Xe Iaso <me@xeiaso.net>
* test CI/CD
Signed-off-by: Xe Iaso <me@xeiaso.net>
* try civo route
Signed-off-by: Xe Iaso <me@xeiaso.net>
* lol
Signed-off-by: Xe Iaso <me@xeiaso.net>
* plan c?
Signed-off-by: Xe Iaso <me@xeiaso.net>
* specify the region
Signed-off-by: Xe Iaso <me@xeiaso.net>
* lol
Signed-off-by: Xe Iaso <me@xeiaso.net>
* blog: hello again kubernetes!
Signed-off-by: Xe Iaso <me@xeiaso.net>
---------
Signed-off-by: Xe Iaso <me@xeiaso.net>
Diffstat (limited to 'cmd')
| -rw-r--r-- | cmd/hydrate/main.go | 125 | ||||
| -rw-r--r-- | cmd/hydrate/templates/blog.tmpl | 10 | ||||
| -rw-r--r-- | cmd/hydrate/templates/linkpost.tmpl | 5 | ||||
| -rw-r--r-- | cmd/hydrate/templates/note.tmpl | 5 | ||||
| -rw-r--r-- | cmd/hydrate/templates/talk.tmpl | 0 | ||||
| -rw-r--r-- | cmd/hydrate/templates/xecast.tmpl | 0 | ||||
| -rw-r--r-- | cmd/patreon-saasproxy/main.go | 47 | ||||
| -rw-r--r-- | cmd/xesite/internalapi.go | 4 | ||||
| -rw-r--r-- | cmd/xesite/main.go | 1 |
9 files changed, 164 insertions, 33 deletions
diff --git a/cmd/hydrate/main.go b/cmd/hydrate/main.go new file mode 100644 index 0000000..ced069c --- /dev/null +++ b/cmd/hydrate/main.go @@ -0,0 +1,125 @@ +package main + +import ( + "embed" + "flag" + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "strconv" + "strings" + "text/template" + "time" +) + +var ( + //go:embed templates/*.tmpl + templates embed.FS + + date = flag.String("date", time.Now().Format(time.DateOnly), "Publication date of the post") + + routing = map[string]string{ + "blog": "lume/src/blog", + "linkpost": "lume/src/blog", + "note": "lume/src/notes", + "talk": "lume/src/talks", + "xecast": "lume/src/xecast", + } +) + +// go run ./cmd/hydrate <kind> <slug> + +func init() { + flag.Usage = func() { + fmt.Fprintf(os.Stderr, "Usage: %s [flags] <kind> <slug>\n\n", filepath.Base(os.Args[0])) + fmt.Fprintln(os.Stderr, "Available kinds:") + + templs, err := templates.ReadDir("templates") + if err != nil { + log.Panicf("can't read templates: %v", err) + } + + for _, tmpl := range templs { + kind, ok := strings.CutSuffix(tmpl.Name(), filepath.Ext(tmpl.Name())) + if !ok { + log.Panicf("can't cut extension from %q", tmpl.Name()) + } + fmt.Fprintln(os.Stderr, " *", kind) + } + + fmt.Fprintln(os.Stderr) + fmt.Fprintln(os.Stderr, "Flags:") + + flag.PrintDefaults() + + os.Exit(2) + } +} + +func main() { + tmpl, err := template.ParseFS(templates, "templates/*.tmpl") + if err != nil { + log.Fatalf("can't parse templates: %v", err) + } + + flag.Parse() + + if flag.NArg() != 2 { + flag.Usage() + } + + kind := flag.Arg(0) + slug := flag.Arg(1) + + year, err := yearOf(*date) + if err != nil { + log.Fatalf("can't parse year in %s: %v", *date, year) + } + + foutName := filepath.Join(routing[kind], year, slug+".mdx") + + if _, err := os.Stat(foutName); !os.IsNotExist(err) { + log.Printf("Potential error when trying to verify %s doesn't exist: %v", foutName, err) + log.Println("Does the file already exist?") + os.Exit(1) + } + + fout, err := os.Create(foutName) + if err != nil { + log.Fatalf("can't create %s: %v", foutName, err) + } + + if err := tmpl.ExecuteTemplate(fout, kind+".tmpl", struct { + Date string + }{ + Date: *date, + }); err != nil { + log.Fatalf("error writing template: %v", err) + } + + if err := fout.Close(); err != nil { + log.Fatalf("error closing output file: %v", err) + } + + codePath, err := exec.LookPath("code") + if err != nil { + log.Println("hint: control shift p -> install code command") + log.Fatalf("can't find code command in $PATH: %v", err) + } + + if err := exec.Command(codePath, foutName).Run(); err != nil { + log.Fatalf("can't open %s in VS Code: %v", foutName, err) + } + +} + +func yearOf(date string) (string, error) { + t, err := time.Parse(time.DateOnly, date) + if err != nil { + return "", err + } + + return strconv.Itoa(t.Year()), nil +} diff --git a/cmd/hydrate/templates/blog.tmpl b/cmd/hydrate/templates/blog.tmpl new file mode 100644 index 0000000..6d9edde --- /dev/null +++ b/cmd/hydrate/templates/blog.tmpl @@ -0,0 +1,10 @@ +--- +title: "" +desc: "" +date: {{.Date}} +hero: + ai: "" + file: "" + prompt: "" + social: false +---
\ No newline at end of file diff --git a/cmd/hydrate/templates/linkpost.tmpl b/cmd/hydrate/templates/linkpost.tmpl new file mode 100644 index 0000000..9afcc71 --- /dev/null +++ b/cmd/hydrate/templates/linkpost.tmpl @@ -0,0 +1,5 @@ +--- +title: "" +date: {{.Date}} +redirect_to: "" +---
\ No newline at end of file diff --git a/cmd/hydrate/templates/note.tmpl b/cmd/hydrate/templates/note.tmpl new file mode 100644 index 0000000..2e510a5 --- /dev/null +++ b/cmd/hydrate/templates/note.tmpl @@ -0,0 +1,5 @@ +--- +title: "" +desc: "" +date: {{.Date}} +---
\ No newline at end of file diff --git a/cmd/hydrate/templates/talk.tmpl b/cmd/hydrate/templates/talk.tmpl new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/cmd/hydrate/templates/talk.tmpl diff --git a/cmd/hydrate/templates/xecast.tmpl b/cmd/hydrate/templates/xecast.tmpl new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/cmd/hydrate/templates/xecast.tmpl diff --git a/cmd/patreon-saasproxy/main.go b/cmd/patreon-saasproxy/main.go index 6901ee3..363fa80 100644 --- a/cmd/patreon-saasproxy/main.go +++ b/cmd/patreon-saasproxy/main.go @@ -2,14 +2,13 @@ package main import ( "context" - "encoding/base64" "flag" + "fmt" "log" "log/slog" "net" "net/http" "os" - "path/filepath" "github.com/facebookgo/flagenv" _ "github.com/joho/godotenv/autoload" @@ -20,13 +19,16 @@ import ( "gopkg.in/mxpv/patreon-go.v1" "xeiaso.net/v4/internal" "xeiaso.net/v4/internal/adminpb" + "xeiaso.net/v4/internal/k8s" ) var ( - bind = flag.String("bind", ":80", "HTTP bind addr") - clientID = flag.String("client-id", "", "Patreon client ID") - clientSecret = flag.String("client-secret", "", "Patreon client secret") - dataDir = flag.String("data-dir", "./var", "Directory to store data in") + bind = flag.String("bind", ":80", "HTTP bind addr") + clientID = flag.String("client-id", "", "Patreon client ID") + clientSecret = flag.String("client-secret", "", "Patreon client secret") + dataDir = flag.String("data-dir", "./var", "Directory to store data in") + k8sNamespace = flag.String("kubernetes-namespace", "default", "Kubernetes namespace this app is running in") + k8sSecretName = flag.String("kubernetes-secret-name", "xesite-patreon-saasproxy-state", "Kubernetes secret to store state data in") ) func main() { @@ -46,36 +48,11 @@ func main() { Scopes: []string{"users", "pledges-to-me", "my-campaign"}, } - if !internal.FileExists(filepath.Join(*dataDir, "patreon-token.json")) { - val, ok := os.LookupEnv("PATREON_TOKEN_JSON_B64") - if !ok { - log.Fatal("PATREON_TOKEN_JSON_B64 not set") - } - - fout, err := os.Create(filepath.Join(*dataDir, "patreon-token.json")) - if err != nil { - log.Fatal(err) - } - defer fout.Close() - - decoded, err := base64.StdEncoding.DecodeString(val) - if err != nil { - slog.Error("can't decode token", "err", err, "val", val) - log.Fatal(err) - } - - if _, err := fout.Write(decoded); err != nil { - log.Fatal(err) - } - } - - token, err := internal.ReadToken(filepath.Join(*dataDir, "patreon-token.json")) + cts, err := k8s.TokenSource(*k8sNamespace, *k8sSecretName, &config) if err != nil { - log.Fatalf("error reading token: %v", err) + log.Fatalf("error making token source: %v", err) } - cts := internal.CachingTokenSource(filepath.Join(*dataDir, "patreon-token.json"), &config, token) - s := &Server{ cts: cts, } @@ -83,6 +60,10 @@ func main() { ph := adminpb.NewPatreonServer(s) http.Handle(adminpb.PatreonPathPrefix, ph) + http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "OK") + }) + ln, err := net.Listen("tcp", *bind) if err != nil { log.Fatalf("can't listen over TCP: %v", err) diff --git a/cmd/xesite/internalapi.go b/cmd/xesite/internalapi.go index c0dfa9c..615af72 100644 --- a/cmd/xesite/internalapi.go +++ b/cmd/xesite/internalapi.go @@ -3,6 +3,7 @@ package main import ( "context" "expvar" + "fmt" "log" "net" "net/http" @@ -23,6 +24,9 @@ func internalAPI(fs *lume.FS) { mux := http.NewServeMux() mux.Handle("/debug/vars", expvar.Handler()) + mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "OK") + }) mux.HandleFunc("/rebuild", func(w http.ResponseWriter, r *http.Request) { go fs.Update(context.Background()) diff --git a/cmd/xesite/main.go b/cmd/xesite/main.go index 0062086..bef58e7 100644 --- a/cmd/xesite/main.go +++ b/cmd/xesite/main.go @@ -126,6 +126,7 @@ func main() { h = internal.AcceptEncodingMiddleware(h) h = internal.RefererMiddleware(h) h = internal.DomainRedirect(h, *devel) + h = internal.OnionLocation(h) slog.Info("starting server", "bind", *bind) log.Fatal(http.Serve(ln, h)) |
