From 20d07c7005665f8e2001b4cbd24e15ec589d9882 Mon Sep 17 00:00:00 2001 From: Xe Iaso Date: Sat, 9 Nov 2024 10:50:59 -0500 Subject: Move to Kubernetes (#853) * start to lift-and-shift to k8s Signed-off-by: Xe Iaso * manifest/xesite: properly configure pod disruption budget, hostmount for xesite as a hack Signed-off-by: Xe Iaso * properly slonk readiness Signed-off-by: Xe Iaso * manifest: move to aeacus Signed-off-by: Xe Iaso * internal: add OnionLocation middleware Signed-off-by: Xe Iaso * internal/lume: jettison serving from the zipfile Signed-off-by: Xe Iaso * yolo deploy to prod Signed-off-by: Xe Iaso * okay use a machineproxy here Signed-off-by: Xe Iaso * test CI/CD Signed-off-by: Xe Iaso * try civo route Signed-off-by: Xe Iaso * lol Signed-off-by: Xe Iaso * plan c? Signed-off-by: Xe Iaso * specify the region Signed-off-by: Xe Iaso * lol Signed-off-by: Xe Iaso * blog: hello again kubernetes! Signed-off-by: Xe Iaso --------- Signed-off-by: Xe Iaso --- cmd/hydrate/main.go | 125 ++++++++++++++++++++++++++++++++++++ cmd/hydrate/templates/blog.tmpl | 10 +++ cmd/hydrate/templates/linkpost.tmpl | 5 ++ cmd/hydrate/templates/note.tmpl | 5 ++ cmd/hydrate/templates/talk.tmpl | 0 cmd/hydrate/templates/xecast.tmpl | 0 cmd/patreon-saasproxy/main.go | 47 ++++---------- cmd/xesite/internalapi.go | 4 ++ cmd/xesite/main.go | 1 + 9 files changed, 164 insertions(+), 33 deletions(-) create mode 100644 cmd/hydrate/main.go create mode 100644 cmd/hydrate/templates/blog.tmpl create mode 100644 cmd/hydrate/templates/linkpost.tmpl create mode 100644 cmd/hydrate/templates/note.tmpl create mode 100644 cmd/hydrate/templates/talk.tmpl create mode 100644 cmd/hydrate/templates/xecast.tmpl (limited to 'cmd') 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 + +func init() { + flag.Usage = func() { + fmt.Fprintf(os.Stderr, "Usage: %s [flags] \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 diff --git a/cmd/hydrate/templates/xecast.tmpl b/cmd/hydrate/templates/xecast.tmpl new file mode 100644 index 0000000..e69de29 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)) -- cgit v1.2.3