aboutsummaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorXe Iaso <me@xeiaso.net>2024-11-09 10:50:59 -0500
committerGitHub <noreply@github.com>2024-11-09 10:50:59 -0500
commit20d07c7005665f8e2001b4cbd24e15ec589d9882 (patch)
tree8b98d1446c6d9e42bc2621e633543e0420f43541 /cmd
parent2b349f56cb20420dd153f40f22b3654b5079100f (diff)
downloadxesite-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.go125
-rw-r--r--cmd/hydrate/templates/blog.tmpl10
-rw-r--r--cmd/hydrate/templates/linkpost.tmpl5
-rw-r--r--cmd/hydrate/templates/note.tmpl5
-rw-r--r--cmd/hydrate/templates/talk.tmpl0
-rw-r--r--cmd/hydrate/templates/xecast.tmpl0
-rw-r--r--cmd/patreon-saasproxy/main.go47
-rw-r--r--cmd/xesite/internalapi.go4
-rw-r--r--cmd/xesite/main.go1
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))