aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXe <me@christine.website>2022-12-29 15:11:17 -0500
committerXe <me@christine.website>2022-12-29 15:11:17 -0500
commitfeb3e3d732ac238c5f8a358aeac36237db71060d (patch)
tree264c07197f181056a9941e1fff6771c361414169
parent23751f755b0eeba2588d029aefe32810369faac1 (diff)
downloadx-feb3e3d732ac238c5f8a358aeac36237db71060d.tar.xz
x-feb3e3d732ac238c5f8a358aeac36237db71060d.zip
add aegis
Signed-off-by: Xe <me@christine.website>
-rw-r--r--cmd/aegis/aegis.txt26
-rw-r--r--cmd/aegis/main.go63
-rw-r--r--cmd/within.website/assets_vfsdata.go186
-rw-r--r--cmd/within.website/dev.go7
-rw-r--r--cmd/within.website/main.go9
-rw-r--r--flake.lock35
-rw-r--r--flake.nix242
-rw-r--r--mastodon/robocadey/gpt2/.gitignore1
-rwxr-xr-xmastodon/robocadey/gpt2/main.py34
-rw-r--r--mastodon/robocadey/main.go134
10 files changed, 262 insertions, 475 deletions
diff --git a/cmd/aegis/aegis.txt b/cmd/aegis/aegis.txt
new file mode 100644
index 0000000..24624ab
--- /dev/null
+++ b/cmd/aegis/aegis.txt
@@ -0,0 +1,26 @@
+ =:::::::::~~~=
+ :,:::::::,,::=
+ = +++++ + ++=
+ :~+~~~~~~~====
+ :=+=~~~~~~=~~=
+ =~:===~~~~~=~~!=
+ =::~====~~~~=::::=
+ =: ++====~~~~==::=
+ =: -=+====~~~~~=~=
+ =~= ~++===~~~~=,~=
+ =~ +++==~~=:=~+=
+ ,= +++==~~=~++
+ := +++=+=~=~++
+ ,= ++++==~==++
+ ,~ ++++==~=+++
+ ,~ +++===~~==+
+ ,= ++====~~=++
+ ,= +==~===~==+
+ ,=+======~~==+
+ :=+=~~~~~~~=++
+ :===~~~~~~~+==
+ :~===~~~~~~=+=
+ ,~=~~~~~~~~===
+ ,~=~~~~~~~~+=~
+ ::+========+~=
+ +=~~~~~~~~~~~=
diff --git a/cmd/aegis/main.go b/cmd/aegis/main.go
new file mode 100644
index 0000000..a6a2005
--- /dev/null
+++ b/cmd/aegis/main.go
@@ -0,0 +1,63 @@
+package main
+
+import (
+ _ "embed"
+ "flag"
+ "fmt"
+ "log"
+ "net"
+ "net/http"
+ "net/http/httputil"
+ "os"
+ "path"
+ "path/filepath"
+)
+
+var (
+ hostport = flag.String("hostport", "[::]:31337", "TCP host:port to listen on")
+ sockdir = flag.String("sockdir", "./run", "directory full of unix sockets to monitor")
+)
+
+//go:embed "aegis.txt"
+var core string
+
+func main() {
+ flag.Parse()
+
+ fmt.Print(core)
+ log.SetFlags(0)
+ log.Printf("%s -> %s", *hostport, *sockdir)
+
+ http.DefaultServeMux.HandleFunc("/", proxyToUnixSocket)
+
+ log.Fatal(http.ListenAndServe(*hostport, nil))
+}
+
+func proxyToUnixSocket(w http.ResponseWriter, r *http.Request) {
+ name := path.Base(r.URL.Path)
+
+ fname := filepath.Join(*sockdir, name+".sock")
+ _, err := os.Stat(fname)
+ if os.IsNotExist(err) {
+ http.NotFound(w, r)
+ return
+ }
+
+ ts := &http.Transport{
+ Dial: func(_, _ string) (net.Conn, error) {
+ return net.Dial("unix", fname)
+ },
+ DisableKeepAlives: true,
+ }
+
+ rp := httputil.ReverseProxy{
+ Director: func(req *http.Request) {
+ req.URL.Scheme = "http"
+ req.URL.Host = "aegis"
+ req.URL.Path = "/metrics"
+ req.URL.RawPath = "/metrics"
+ },
+ Transport: ts,
+ }
+ rp.ServeHTTP(w, r)
+}
diff --git a/cmd/within.website/assets_vfsdata.go b/cmd/within.website/assets_vfsdata.go
deleted file mode 100644
index e01db6b..0000000
--- a/cmd/within.website/assets_vfsdata.go
+++ /dev/null
@@ -1,186 +0,0 @@
-// Code generated by vfsgen; DO NOT EDIT.
-
-// +build !dev
-
-package main
-
-import (
- "bytes"
- "compress/gzip"
- "fmt"
- "io"
- "io/ioutil"
- "net/http"
- "os"
- pathpkg "path"
- "time"
-)
-
-// assets statically implements the virtual filesystem provided to vfsgen.
-var assets = func() http.FileSystem {
- fs := vfsgen۰FS{
- "/": &vfsgen۰DirInfo{
- name: "/",
- modTime: time.Date(2019, 6, 8, 23, 10, 54, 920411817, time.UTC),
- },
- "/gruvbox.css": &vfsgen۰CompressedFileInfo{
- name: "gruvbox.css",
- modTime: time.Date(2019, 6, 8, 23, 10, 54, 844411817, time.UTC),
- uncompressedSize: 968,
-
- compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\x91\xcf\x6e\xa3\x30\x10\xc6\xef\x7e\x8a\x91\x72\xd9\x95\xa0\x8a\xa1\xa4\xc4\xb9\xec\xab\xf8\xcf\x10\x5b\xc5\x98\x35\x4e\x37\xd5\x8a\x77\x5f\x61\xa0\x01\xb7\x5d\x73\xc0\x1a\xcf\x7c\x33\xf3\xfd\x2c\x37\x1d\xfc\x25\x00\x8d\xeb\x42\xde\x70\x6b\xda\x77\x06\xd6\x75\x6e\xe8\xb9\xc4\xec\x71\xbd\x10\x00\xcb\xef\xf9\x1f\xa3\x82\x66\x50\xd6\x1e\xed\x14\xeb\xb9\x52\xa6\xbb\x32\x28\x96\x80\xe5\xfe\x6a\x3a\x06\xfc\x16\xdc\x85\x8c\x84\x30\x36\x60\x8b\x32\x18\x37\xb7\x12\x5c\xbe\x5e\xbd\xbb\x75\x8a\xc1\x41\x95\xf5\xe9\x2c\x62\x9e\x70\xea\xfd\x73\x42\x51\x4f\xdf\x24\x2c\x5d\xeb\x3c\x83\x78\x0e\x28\x94\x10\x45\xac\xeb\x3d\x26\x65\xf9\x92\x7a\x28\x65\x59\x97\xa7\xdd\x98\x74\x9e\x52\x38\xaf\xd0\x33\x38\x46\x09\x9e\x01\x67\x5c\x06\xf3\x86\xd3\xed\xcd\x0c\x26\xa0\x8a\xaa\xab\x94\xa0\xa7\xa2\x8e\x52\x5f\xf4\xa1\xaa\x38\x16\x34\x4a\x69\x9a\x81\x2e\x32\xd0\x65\x06\xfa\x39\x03\x5d\x45\x99\xd9\x95\x5c\xb8\x10\x9c\x65\xf0\x44\xa3\x5b\xd3\xd6\xad\x93\xaf\xbf\x6f\x2e\x2c\x4b\xc4\xb9\xf2\x16\x9b\xc0\x80\xf6\x77\x18\x5c\x6b\x14\x1c\x84\xe2\x78\x2e\xb7\xfe\x1e\x9f\x2a\xb4\x40\x8f\xfd\x7d\xb7\xdf\x36\x3c\x12\xf2\xcb\xa2\x32\x1c\x7e\xf4\x1e\x1b\xf4\xc3\x3c\x71\x3e\x48\x8d\x16\x19\xb4\xe6\xaa\xc3\xcf\xd8\x78\x6a\xbd\xf8\x3f\x9f\x1d\x85\x46\x34\x54\xbe\x5c\x3e\x1e\x77\x2c\x1e\x2e\x03\x8c\x24\xfe\x56\x26\xa9\xd4\x87\x63\x2b\xbf\x35\x25\xe5\xb3\x14\x3e\x28\x6d\xc4\xff\x43\x6b\x37\xdd\x86\xd9\xb7\x73\x34\xe7\xa6\x52\x2f\x3b\xf9\x6f\x08\xce\xe7\x6b\x8e\x9b\xea\x84\xe7\x76\x8f\xcf\x54\x4f\x55\x25\xab\xe7\x4b\xa2\x9e\xb2\x4d\x1c\x4a\x1f\x47\x32\x92\x7f\x01\x00\x00\xff\xff\xab\xef\x35\x5a\xc8\x03\x00\x00"),
- },
- }
- fs["/"].(*vfsgen۰DirInfo).entries = []os.FileInfo{
- fs["/gruvbox.css"].(os.FileInfo),
- }
-
- return fs
-}()
-
-type vfsgen۰FS map[string]interface{}
-
-func (fs vfsgen۰FS) Open(path string) (http.File, error) {
- path = pathpkg.Clean("/" + path)
- f, ok := fs[path]
- if !ok {
- return nil, &os.PathError{Op: "open", Path: path, Err: os.ErrNotExist}
- }
-
- switch f := f.(type) {
- case *vfsgen۰CompressedFileInfo:
- gr, err := gzip.NewReader(bytes.NewReader(f.compressedContent))
- if err != nil {
- // This should never happen because we generate the gzip bytes such that they are always valid.
- panic("unexpected error reading own gzip compressed bytes: " + err.Error())
- }
- return &vfsgen۰CompressedFile{
- vfsgen۰CompressedFileInfo: f,
- gr: gr,
- }, nil
- case *vfsgen۰DirInfo:
- return &vfsgen۰Dir{
- vfsgen۰DirInfo: f,
- }, nil
- default:
- // This should never happen because we generate only the above types.
- panic(fmt.Sprintf("unexpected type %T", f))
- }
-}
-
-// vfsgen۰CompressedFileInfo is a static definition of a gzip compressed file.
-type vfsgen۰CompressedFileInfo struct {
- name string
- modTime time.Time
- compressedContent []byte
- uncompressedSize int64
-}
-
-func (f *vfsgen۰CompressedFileInfo) Readdir(count int) ([]os.FileInfo, error) {
- return nil, fmt.Errorf("cannot Readdir from file %s", f.name)
-}
-func (f *vfsgen۰CompressedFileInfo) Stat() (os.FileInfo, error) { return f, nil }
-
-func (f *vfsgen۰CompressedFileInfo) GzipBytes() []byte {
- return f.compressedContent
-}
-
-func (f *vfsgen۰CompressedFileInfo) Name() string { return f.name }
-func (f *vfsgen۰CompressedFileInfo) Size() int64 { return f.uncompressedSize }
-func (f *vfsgen۰CompressedFileInfo) Mode() os.FileMode { return 0444 }
-func (f *vfsgen۰CompressedFileInfo) ModTime() time.Time { return f.modTime }
-func (f *vfsgen۰CompressedFileInfo) IsDir() bool { return false }
-func (f *vfsgen۰CompressedFileInfo) Sys() interface{} { return nil }
-
-// vfsgen۰CompressedFile is an opened compressedFile instance.
-type vfsgen۰CompressedFile struct {
- *vfsgen۰CompressedFileInfo
- gr *gzip.Reader
- grPos int64 // Actual gr uncompressed position.
- seekPos int64 // Seek uncompressed position.
-}
-
-func (f *vfsgen۰CompressedFile) Read(p []byte) (n int, err error) {
- if f.grPos > f.seekPos {
- // Rewind to beginning.
- err = f.gr.Reset(bytes.NewReader(f.compressedContent))
- if err != nil {
- return 0, err
- }
- f.grPos = 0
- }
- if f.grPos < f.seekPos {
- // Fast-forward.
- _, err = io.CopyN(ioutil.Discard, f.gr, f.seekPos-f.grPos)
- if err != nil {
- return 0, err
- }
- f.grPos = f.seekPos
- }
- n, err = f.gr.Read(p)
- f.grPos += int64(n)
- f.seekPos = f.grPos
- return n, err
-}
-func (f *vfsgen۰CompressedFile) Seek(offset int64, whence int) (int64, error) {
- switch whence {
- case io.SeekStart:
- f.seekPos = 0 + offset
- case io.SeekCurrent:
- f.seekPos += offset
- case io.SeekEnd:
- f.seekPos = f.uncompressedSize + offset
- default:
- panic(fmt.Errorf("invalid whence value: %v", whence))
- }
- return f.seekPos, nil
-}
-func (f *vfsgen۰CompressedFile) Close() error {
- return f.gr.Close()
-}
-
-// vfsgen۰DirInfo is a static definition of a directory.
-type vfsgen۰DirInfo struct {
- name string
- modTime time.Time
- entries []os.FileInfo
-}
-
-func (d *vfsgen۰DirInfo) Read([]byte) (int, error) {
- return 0, fmt.Errorf("cannot Read from directory %s", d.name)
-}
-func (d *vfsgen۰DirInfo) Close() error { return nil }
-func (d *vfsgen۰DirInfo) Stat() (os.FileInfo, error) { return d, nil }
-
-func (d *vfsgen۰DirInfo) Name() string { return d.name }
-func (d *vfsgen۰DirInfo) Size() int64 { return 0 }
-func (d *vfsgen۰DirInfo) Mode() os.FileMode { return 0755 | os.ModeDir }
-func (d *vfsgen۰DirInfo) ModTime() time.Time { return d.modTime }
-func (d *vfsgen۰DirInfo) IsDir() bool { return true }
-func (d *vfsgen۰DirInfo) Sys() interface{} { return nil }
-
-// vfsgen۰Dir is an opened dir instance.
-type vfsgen۰Dir struct {
- *vfsgen۰DirInfo
- pos int // Position within entries for Seek and Readdir.
-}
-
-func (d *vfsgen۰Dir) Seek(offset int64, whence int) (int64, error) {
- if offset == 0 && whence == io.SeekStart {
- d.pos = 0
- return 0, nil
- }
- return 0, fmt.Errorf("unsupported Seek in directory %s", d.name)
-}
-
-func (d *vfsgen۰Dir) Readdir(count int) ([]os.FileInfo, error) {
- if d.pos >= len(d.entries) && count > 0 {
- return nil, io.EOF
- }
- if count <= 0 || count > len(d.entries)-d.pos {
- count = len(d.entries) - d.pos
- }
- e := d.entries[d.pos : d.pos+count]
- d.pos += count
- return e, nil
-}
diff --git a/cmd/within.website/dev.go b/cmd/within.website/dev.go
deleted file mode 100644
index 1417c41..0000000
--- a/cmd/within.website/dev.go
+++ /dev/null
@@ -1,7 +0,0 @@
-//+build dev
-
-package main
-
-import "net/http"
-
-var assets http.FileSystem = http.Dir("./static")
diff --git a/cmd/within.website/main.go b/cmd/within.website/main.go
index 9b04a19..c95da9a 100644
--- a/cmd/within.website/main.go
+++ b/cmd/within.website/main.go
@@ -3,6 +3,7 @@ package main
import (
"context"
+ "embed"
"flag"
"net/http"
@@ -28,6 +29,11 @@ var (
gogsRepos = stringlist.Flag("gogs-repo", "list of Gogs repositories to use")
)
+var (
+ //go:embed static
+ staticFS embed.FS
+)
+
var githubReposDefault = []string{
"ln",
"x",
@@ -76,7 +82,7 @@ func main() {
ln.Log(ctx, ln.F{"gogs_domain": *gogsDomain, "gogs_username": *gogsUsername, "gogs_repo": repo}, ln.Info("adding gogs repo"))
}
- http.Handle("/static/", http.StripPrefix("/static", http.FileServer(assets)))
+ http.Handle("/static/", http.FileServer(http.FS(staticFS)))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
@@ -118,7 +124,6 @@ const indexTemplate = `<!DOCTYPE html>
<li><a href="https://within.website/gorqlite">gorqlite</a> - A driver for <a href="https://github.com/rqlite/rqlite">rqlite</a></li>
<li><a href="https://within.website/johaus">johaus</a> - <a href="http://lojban.org">Lojban</a> parsing</li>
<li><a href="https://within.website/ln">ln</a> - Key->value based logging made context-aware and simple</li>
- <li><a href="https://within.website/mi">mi</a> - A personal API </li>
<li><a href="https://within.website/olin">olin</a> - WebAssembly on the server</li>
<li><a href="https://within.website/x">x</a> - Experiments, toys and tinkering (many subpackages)</li>
</ul>
diff --git a/flake.lock b/flake.lock
index 7eee2be..f58ea2c 100644
--- a/flake.lock
+++ b/flake.lock
@@ -54,46 +54,11 @@
"type": "indirect"
}
},
- "nixpkgs_2": {
- "locked": {
- "lastModified": 1662019588,
- "narHash": "sha256-oPEjHKGGVbBXqwwL+UjsveJzghWiWV0n9ogo1X6l4cw=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "2da64a81275b68fdad38af669afeda43d401e94b",
- "type": "github"
- },
- "original": {
- "id": "nixpkgs",
- "ref": "nixos-unstable",
- "type": "indirect"
- }
- },
- "portable-svc": {
- "inputs": {
- "nixpkgs": "nixpkgs_2"
- },
- "locked": {
- "lastModified": 1662398951,
- "narHash": "sha256-E6kcB8SZQB+N37/AVxmMrUXzt/i/Herqp8DH7pBAmWw=",
- "ref": "main",
- "rev": "e2683a1c4ca5c42f47956c0ab46331d8a0f3be3d",
- "revCount": 7,
- "type": "git",
- "url": "https://tulpa.dev/cadey/portable-svc.git"
- },
- "original": {
- "ref": "main",
- "type": "git",
- "url": "https://tulpa.dev/cadey/portable-svc.git"
- }
- },
"root": {
"inputs": {
"ckiee": "ckiee",
"gomod2nix": "gomod2nix",
"nixpkgs": "nixpkgs",
- "portable-svc": "portable-svc",
"rust-overlay": "rust-overlay",
"utils": "utils"
}
diff --git a/flake.nix b/flake.nix
index 8f6cd33..4219fc3 100644
--- a/flake.nix
+++ b/flake.nix
@@ -4,7 +4,6 @@
inputs = {
nixpkgs.url = "nixpkgs/nixos-unstable";
utils.url = "github:numtide/flake-utils";
- portable-svc.url = "git+https://tulpa.dev/cadey/portable-svc.git?ref=main";
ckiee.url = "github:ckiee/nixpkgs?ref=gpt2simple-py-init";
rust-overlay = {
@@ -20,7 +19,7 @@
};
};
- outputs = { self, nixpkgs, utils, gomod2nix, portable-svc, ckiee, rust-overlay
+ outputs = { self, nixpkgs, utils, gomod2nix, ckiee, rust-overlay
}@attrs:
utils.lib.eachSystem [
"x86_64-linux"
@@ -37,7 +36,6 @@
buildGoModule = prev.buildGo118Module;
})
gomod2nix.overlays.default
- portable-svc.overlay
rust-overlay.overlays.default
#(final: prev: self.packages.${system})
];
@@ -83,6 +81,7 @@
pname = "mkapp";
path = "make-mastodon-app";
};
+ aegis = copyFile { pname = "aegis"; };
prefix = copyFile { pname = "prefix"; };
quickserv = copyFile { pname = "quickserv"; };
within-website = copyFile { pname = "within.website"; };
@@ -94,95 +93,186 @@
pname = "importer";
path = "cadeybot-importer";
};
-
- robocadey = copyFile { pname = "robocadey"; };
- robocadey-gpt2 = pkgs.writeShellScriptBin "robocadey-gpt2" ''
- ${python}/bin/python3 ${./mastodon/robocadey/gpt2/main.py}
- '';
- robocadey-psvc = let
- service = pkgs.substituteAll {
- name = "robocadey.service";
- src = ./run/robocadey.service.in;
- robocadey = self.packages.${system}.robocadey;
- };
- gpt2-service = pkgs.substituteAll {
- name = "robocadey-gpt2.service";
- src = ./run/robocadey-gpt2.service.in;
- inherit python;
- main = ./mastodon/robocadey/gpt2/main.py;
- };
- in pkgs.portableService {
- inherit (self.packages.${system}.robocadey) version;
- name = "robocadey";
- description = "Robotic twitter shitposting bot";
- units = [ service gpt2-service ./run/robocadey-gpt2.socket ];
- symlinks = [{
- object = "${pkgs.cacert}/etc/ssl";
- symlink = "/etc/ssl";
- }];
- };
};
- nixosModules.robocadey = { config, lib, pkgs, ... }:
- with lib;
- let
- system = pkgs.system;
- cfg = config.xeserv.services.robocadey;
- selfpkgs = self.packages.${system};
- in {
- options.xeserv.services.robocadey = {
- enable = mkEnableOption "Activates the printerfacts server";
-
- pathToModel = mkOption {
- type = types.str;
- default = "/srv/models/robocadey_gpt2.raw";
- description = "model squashfs volume location";
+ nixosModules = {
+ aegis = { config, lib, pkgs, ... }:
+ with lib;
+ let
+ system = pkgs.system;
+ cfg = config.xeserv.services.robocadey;
+ selfpkgs = self.packages.${system};
+ in {
+ options.within.services.aegis = {
+ enable = mkEnableOption
+ "Activates Aegis (unix socket prometheus proxy)";
+
+ hostport = mkOption {
+ type = types.str;
+ default = "[::1]:31337";
+ description =
+ "The host:port that aegis should listen for traffic on";
+ };
+
+ sockdir = mkOption {
+ type = types.str;
+ default = "/srv/within/run";
+ example = "/srv/within/run";
+ description = "The folder that aegis will read from";
+ };
};
- };
- config = mkIf cfg.enable {
- systemd.mounts = [{
- type = "squashfs";
- what = cfg.pathToModel;
- where = "/var/lib/private/xeserv.robocadey-gpt2/checkpoint";
- options = "ro,relatime,errors=continue";
- }];
- systemd.services = {
- "robocadey" = {
+ config = mkIf cfg.enable {
+ users.users.aegis = {
+ createHome = true;
+ description = "tulpa.dev/cadey/aegis";
+ isSystemUser = true;
+ group = "within";
+ home = "/srv/within/aegis";
+ };
+
+ systemd.services.aegis = {
wantedBy = [ "multi-user.target" ];
- description = "RoboCadey";
- after = [ "robocadey-gpt2.socket" ];
serviceConfig = {
- Restart = "always";
- DynamicUser = "true";
- ExecStart = "${selfpkgs.robocadey}/bin/robocadey";
- WorkingDirectory = "/var/lib/private/xeserv.robocadey";
- StateDirectory = "xeserv.robocadey";
- CacheDirectory = "xeserv.robocadey";
+ User = "aegis";
+ Group = "within";
+ Restart = "on-failure";
+ WorkingDirectory = "/srv/within/aegis";
+ RestartSec = "30s";
};
+
+ script = let aegis = selfpkgs.aegis;
+ in ''
+ exec ${aegis}/bin/aegis -sockdir="${cfg.sockdir}" -hostport="${cfg.hostport}"
+ '';
};
- "robocadey-gpt2" = {
- wantedBy = [ "multi-user.target" ];
- description = "RoboCadey GPT2 sidecar";
+ };
+ };
+
+ robocadey = { config, lib, pkgs, ... }:
+ with lib;
+ let
+ system = pkgs.system;
+ cfg = config.xeserv.services.robocadey;
+ selfpkgs = self.packages.${system};
+ in {
+ options.xeserv.services.robocadey = {
+ enable = mkEnableOption "Activates the printerfacts server";
+
+ pathToModel = mkOption {
+ type = types.str;
+ default = "/srv/models/robocadey_gpt2.raw";
+ description = "model squashfs volume location";
+ };
+ };
+
+ config = mkIf cfg.enable {
+ systemd.mounts = [{
+ type = "squashfs";
+ what = cfg.pathToModel;
+ where = "/var/lib/private/xeserv.robocadey-gpt2/checkpoint";
+ options = "ro,relatime,errors=continue";
+ }];
+ systemd.services = {
+ "robocadey" = {
+ wantedBy = [ "multi-user.target" ];
+ description = "RoboCadey";
+ after = [ "robocadey-gpt2.socket" ];
+ serviceConfig = {
+ Restart = "always";
+ DynamicUser = "true";
+ ExecStart = "${selfpkgs.robocadey}/bin/robocadey";
+ WorkingDirectory = "/var/lib/private/xeserv.robocadey";
+ StateDirectory = "xeserv.robocadey";
+ CacheDirectory = "xeserv.robocadey";
+ };
+ };
+ "robocadey-gpt2" = {
+ wantedBy = [ "multi-user.target" ];
+ description = "RoboCadey GPT2 sidecar";
+
+ serviceConfig = {
+ Restart = "always";
+ DynamicUser = "true";
+ ExecStart =
+ "${selfpkgs.robocadey-gpt2}/bin/robocadey-gpt2";
+ WorkingDirectory =
+ "/var/lib/private/xeserv.robocadey-gpt2";
+ StateDirectory = "xeserv.robocadey-gpt2";
+ CacheDirectory = "xeserv.robocadey-gpt2";
+ };
+ };
+ };
+ systemd.sockets."robocadey-gpt2" = {
+ description = "RoboCadey GPT-2 activation socket";
+ partOf = [ "robocadey-gpt2.service" ];
+ listenStreams = [ "/run/robocadey-gpt2.sock" ];
+ };
+ };
+ };
+
+ "within.website" = { config, lib, pkgs, ... }:
+ with lib;
+ let
+ system = pkgs.system;
+ cfg = config.xeserv.services.within-website;
+ selfpkgs = self.packages.${system};
+ in {
+ options.xeserv.services.withinwebsite = {
+ enable =
+ mkEnableOption "Enables the within.website import redirector";
+
+ domain = mkOption {
+ type = types.str;
+ default = "within.website";
+ example = "within.website";
+ description =
+ "The domain name that nginx should check against for HTTP hostnames";
+ };
+
+ port = mkOption {
+ type = types.int;
+ default = 52838;
+ example = 9001;
+ description =
+ "The port number withinwebsite should listen on for HTTP traffic";
+ };
+
+ package = mkOption {
+ type = types.package;
+ default = selfpkgs.within-website;
+ description =
+ "the package containing the within.website binary";
+ };
+ };
+ config = mkIf cfg.enable {
+ systemd.services.within-website = {
serviceConfig = {
- Restart = "always";
DynamicUser = "true";
- ExecStart = "${selfpkgs.robocadey-gpt2}/bin/robocadey-gpt2";
- WorkingDirectory = "/var/lib/private/xeserv.robocadey-gpt2";
- StateDirectory = "xeserv.robocadey-gpt2";
- CacheDirectory = "xeserv.robocadey-gpt2";
+ DynamicGroup = "true";
+ Restart = "always";
+ RestartSec = "30s";
+ ExecStart = "${cfg.package}/bin/within.website --port=${
+ toString cfg.port
+ }";
};
};
- };
- systemd.sockets."robocadey-gpt2" = {
- description = "RoboCadey GPT-2 activation socket";
- partOf = [ "robocadey-gpt2.service" ];
- listenStreams = [ "/run/robocadey-gpt2.sock" ];
+
+ services.nginx.virtualHosts."withinwebsite" = {
+ serverName = "${cfg.domain}";
+ locations."/".proxyPass =
+ "http://127.0.0.1:${toString cfg.port}";
+ forceSSL = true;
+ useACMEHost = "${cfg.domain}";
+ extraConfig = ''
+ access_log /var/log/nginx/withinwebsite.access.log;
+ '';
+ };
};
};
- };
+ };
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
diff --git a/mastodon/robocadey/gpt2/.gitignore b/mastodon/robocadey/gpt2/.gitignore
deleted file mode 100644
index 92b189f..0000000
--- a/mastodon/robocadey/gpt2/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-checkpoint
diff --git a/mastodon/robocadey/gpt2/main.py b/mastodon/robocadey/gpt2/main.py
deleted file mode 100755
index 4bb0ef2..0000000
--- a/mastodon/robocadey/gpt2/main.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env python3
-
-import gpt_2_simple as gpt2
-import json
-import os
-import socket
-import sys
-from datetime import datetime
-
-sess = gpt2.start_tf_sess()
-gpt2.load_gpt2(sess, run_name='run1')
-
-SYSTEMD_FIRST_SOCKET_FD = 3
-sock = socket.fromfd(SYSTEMD_FIRST_SOCKET_FD, socket.AF_UNIX, socket.SOCK_STREAM)
-
-sock.listen(1)
-
-while True:
- connection, client_address = sock.accept()
- print("generating shitpost")
- result = gpt2.generate(sess,
- length=512,
- temperature=0.8,
- nsamples=1,
- batch_size=1,
- return_as_list=True,
- top_p=0.9,
- )[0].split("\n")[1:][:-1]
- print("shitpost generated")
- print(json.dumps(result))
- connection.send(json.dumps(result).encode())
- connection.close()
-
-sock.close()
diff --git a/mastodon/robocadey/main.go b/mastodon/robocadey/main.go
deleted file mode 100644
index d78eb16..0000000
--- a/mastodon/robocadey/main.go
+++ /dev/null
@@ -1,134 +0,0 @@
-package main
-
-import (
- "context"
- "encoding/json"
- "flag"
- "math/rand"
- "net"
- "time"
-
- "github.com/McKael/madon/v2"
- "within.website/ln"
- "within.website/x/internal"
-)
-
-var (
- instance = flag.String("instance", "", "mastodon instance")
- appID = flag.String("app-id", "", "oauth2 app id")
- appSecret = flag.String("app-secret", "", "oauth2 app secret")
- token = flag.String("token", "", "oauth2 token")
- sockPath = flag.String("gpt2-sock", "/run/robocadey-gpt2.sock", "path to unix socket for robocadey-gpt2")
-)
-
-var scopes = []string{"read", "write", "follow"}
-
-func getShitposts(sockPath string) ([]string, error) {
- var conn net.Conn
- var err error
- if sockPath != "" {
- conn, err = net.Dial("unix", sockPath)
- } else {
- conn, err = net.Dial("tcp", "[::1]:9999")
- }
-
- if err != nil {
- return nil, err
- }
- defer conn.Close()
- var result []string
- err = json.NewDecoder(conn).Decode(&result)
- if err != nil {
- return nil, err
- }
-
- return result, nil
-}
-
-func getShitpost(ctx context.Context) string {
- shitposts, err := getShitposts(*sockPath)
- if err != nil {
- ln.FatalErr(ctx, err)
- }
-
- return shitposts[rand.Intn(len(shitposts))]
-}
-
-func main() {
- internal.HandleStartup()
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- c, err := madon.RestoreApp("furry boost bot", *instance, *appID, *appSecret, &madon.UserToken{AccessToken: *token})
- if err != nil {
- ln.FatalErr(ctx, err, ln.Action("madon.RestoreApp"))
- }
- _ = c
-
- rand.Seed(time.Now().UnixMicro())
- time.Sleep(5 * time.Second)
-
- if _, err := c.PostStatus(madon.PostStatusParams{
- Text: getShitpost(ctx),
- }); err != nil {
- ln.FatalErr(ctx, err)
- }
-
- t := time.Tick(4 * time.Hour)
-
- for {
- evChan := make(chan madon.StreamEvent, 10)
- stop := make(chan bool)
- done := make(chan bool)
-
- err = c.StreamListener("user", "", evChan, stop, done)
- if err != nil {
- ln.FatalErr(ctx, err)
- }
-
- ln.Log(ctx, ln.F{
- "action": "streaming.toots",
- })
-
- outer:
- for {
- select {
- case _, ok := <-done:
- if !ok {
- ln.Fatal(ctx, ln.F{"action": "stream.dead"})
- }
-
- case <-t:
- if _, err := c.PostStatus(madon.PostStatusParams{
- Text: getShitpost(ctx),
- }); err != nil {
- }
-
- case ev := <-evChan:
- switch ev.Event {
- case "error":
- ln.Log(ctx, ln.F{"err": ev.Error, "action": "processing.event"})
- stop <- true
- break outer
- case "notification":
- n := ev.Data.(madon.Notification)
-
- if n.Type == "mention" {
- ln.Log(ctx, ln.F{
- "target": n.Account.Acct,
- "link": n.Status.URL,
- "privacy": n.Status.Visibility,
- })
- if _, err := c.PostStatus(madon.PostStatusParams{
- Text: "@" + n.Account.Acct + " " + getShitpost(ctx),
- InReplyTo: n.Status.ID,
- Visibility: n.Status.Visibility,
- }); err != nil {
- ln.FatalErr(ctx, err)
- }
- }
- }
- }
- }
- }
-}