- commit
- dfcdebc
- parent
- dfcdebc
- author
- Eric Bower
- date
- 2024-03-19 21:17:20 -0400 EDT
feat: init
4 files changed,
+216,
-0
+15,
-0
1@@ -0,0 +1,15 @@
2+*.log
3+*.swp
4+.env
5+.envrc
6+.env.prod
7+build/*
8+!build/.gitkeep
9+*.bak
10+data/*
11+!data/.gitkeep
12+ssh_data
13+.storage
14+__debug_bin
15+.bin
16+/public/
A
go.mod
+38,
-0
1@@ -0,0 +1,38 @@
2+module github.com/picosh/pico-git
3+
4+go 1.22.1
5+
6+require (
7+ github.com/charmbracelet/ssh v0.0.0-20240301204039-e79ff702f5b3
8+ github.com/charmbracelet/wish v1.3.2
9+ github.com/picosh/ptun v0.0.0-20240313192814-d0ca401937fe
10+)
11+
12+require (
13+ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
14+ github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
15+ github.com/charmbracelet/bubbletea v0.25.0 // indirect
16+ github.com/charmbracelet/keygen v0.5.0 // indirect
17+ github.com/charmbracelet/lipgloss v0.10.0 // indirect
18+ github.com/charmbracelet/log v0.3.1 // indirect
19+ github.com/charmbracelet/x/errors v0.0.0-20240117030013-d31dba354651 // indirect
20+ github.com/charmbracelet/x/exp/term v0.0.0-20240229115032-4b79243a3516 // indirect
21+ github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
22+ github.com/creack/pty v1.1.21 // indirect
23+ github.com/go-logfmt/logfmt v0.6.0 // indirect
24+ github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
25+ github.com/mattn/go-isatty v0.0.20 // indirect
26+ github.com/mattn/go-localereader v0.0.1 // indirect
27+ github.com/mattn/go-runewidth v0.0.15 // indirect
28+ github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
29+ github.com/muesli/cancelreader v0.2.2 // indirect
30+ github.com/muesli/reflow v0.3.0 // indirect
31+ github.com/muesli/termenv v0.15.2 // indirect
32+ github.com/rivo/uniseg v0.4.7 // indirect
33+ golang.org/x/crypto v0.21.0 // indirect
34+ golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // indirect
35+ golang.org/x/sync v0.6.0 // indirect
36+ golang.org/x/sys v0.18.0 // indirect
37+ golang.org/x/term v0.18.0 // indirect
38+ golang.org/x/text v0.14.0 // indirect
39+)
A
go.sum
+71,
-0
1@@ -0,0 +1,71 @@
2+github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
3+github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
4+github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
5+github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
6+github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM=
7+github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg=
8+github.com/charmbracelet/keygen v0.5.0 h1:XY0fsoYiCSM9axkrU+2ziE6u6YjJulo/b9Dghnw6MZc=
9+github.com/charmbracelet/keygen v0.5.0/go.mod h1:DfvCgLHxZ9rJxdK0DGw3C/LkV4SgdGbnliHcObV3L+8=
10+github.com/charmbracelet/lipgloss v0.10.0 h1:KWeXFSexGcfahHX+54URiZGkBFazf70JNMtwg/AFW3s=
11+github.com/charmbracelet/lipgloss v0.10.0/go.mod h1:Wig9DSfvANsxqkRsqj6x87irdy123SR4dOXlKa91ciE=
12+github.com/charmbracelet/log v0.3.1 h1:TjuY4OBNbxmHWSwO3tosgqs5I3biyY8sQPny/eCMTYw=
13+github.com/charmbracelet/log v0.3.1/go.mod h1:OR4E1hutLsax3ZKpXbgUqPtTjQfrh1pG3zwHGWuuq8g=
14+github.com/charmbracelet/ssh v0.0.0-20240301204039-e79ff702f5b3 h1:BI6Vno579jK/NKUwrvboHtMfF2On6kh6mU1cguf5+vQ=
15+github.com/charmbracelet/ssh v0.0.0-20240301204039-e79ff702f5b3/go.mod h1:wUZ0VTrLI5ixIbYOSRHrqrZnfj8EXgLZOOvQYAQ2f18=
16+github.com/charmbracelet/wish v1.3.2 h1:9+32OZnfebIw59Mcx0Yhsj6uke727bJVGJb6WolxsxQ=
17+github.com/charmbracelet/wish v1.3.2/go.mod h1:aulqcv2nEoW14yC3tlkrmIbVN7qDjeH+pzIO239VGTA=
18+github.com/charmbracelet/x/errors v0.0.0-20240117030013-d31dba354651 h1:3RXpZWGWTOeVXCTv0Dnzxdv/MhNUkBfEcbaTY0zrTQI=
19+github.com/charmbracelet/x/errors v0.0.0-20240117030013-d31dba354651/go.mod h1:2P0UgXMEa6TsToMSuFqKFQR+fZTO9CNGUNokkPatT/0=
20+github.com/charmbracelet/x/exp/term v0.0.0-20240229115032-4b79243a3516 h1:wL/PiybPudKHv/LDgAUqS9eoPQr3pOAmzShMPG99cXA=
21+github.com/charmbracelet/x/exp/term v0.0.0-20240229115032-4b79243a3516/go.mod h1:ntNL6rRIDmBHKUmo6ZKt344wCTcrPsSrfVj72qT8A5U=
22+github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
23+github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
24+github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
25+github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
26+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
27+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
28+github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
29+github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
30+github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
31+github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
32+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
33+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
34+github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
35+github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
36+github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
37+github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
38+github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
39+github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
40+github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
41+github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
42+github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
43+github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
44+github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
45+github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
46+github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
47+github.com/picosh/ptun v0.0.0-20240313192814-d0ca401937fe h1:FmDSB2z/4iQ1m1WEVWQaDEwXiXlehd9Csqb8evWCMpY=
48+github.com/picosh/ptun v0.0.0-20240313192814-d0ca401937fe/go.mod h1:uQfDebjN3JJPsI3PAx8T5rmJwdpfmjvdRe7fXY33Kbw=
49+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
50+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
51+github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
52+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
53+github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
54+github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
55+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
56+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
57+golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
58+golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
59+golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 h1:mchzmB1XO2pMaKFRqk/+MV3mgGG96aqaPXaMifQU47w=
60+golang.org/x/exp v0.0.0-20231108232855-2478ac86f678/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
61+golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
62+golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
63+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
64+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
65+golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
66+golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
67+golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
68+golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
69+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
70+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
71+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
72+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
A
main.go
+92,
-0
1@@ -0,0 +1,92 @@
2+package main
3+
4+import (
5+ "context"
6+ "fmt"
7+ "log/slog"
8+ "net/http"
9+ "os"
10+ "os/signal"
11+ "syscall"
12+ "time"
13+
14+ "github.com/charmbracelet/ssh"
15+ "github.com/charmbracelet/wish"
16+ "github.com/picosh/ptun"
17+)
18+
19+func authHandler(ctx ssh.Context, key ssh.PublicKey) bool {
20+ return true
21+}
22+
23+func serveMux(ctx ssh.Context) http.Handler {
24+ clientName := ctx.User()
25+ router := http.NewServeMux()
26+
27+ router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
28+ _, err := w.Write([]byte(fmt.Sprintf("Hello %s!", clientName)))
29+ if err != nil {
30+ fmt.Println(err)
31+ }
32+ })
33+
34+ return router
35+}
36+
37+func GitServerMiddleware() wish.Middleware {
38+ return func(next ssh.Handler) ssh.Handler {
39+ return func(sesh ssh.Session) {
40+ _, _, activePty := sesh.Pty()
41+ if activePty {
42+ next(sesh)
43+ return
44+ }
45+
46+ args := sesh.Command()
47+ fmt.Println(args)
48+ }
49+ }
50+}
51+
52+func main() {
53+ host := os.Getenv("SSH_HOST")
54+ if host == "" {
55+ host = "0.0.0.0"
56+ }
57+ port := os.Getenv("SSH_PORT")
58+ if port == "" {
59+ port = "2222"
60+ }
61+
62+ logger := slog.Default()
63+ s, err := wish.NewServer(
64+ wish.WithAddress(fmt.Sprintf("%s:%s", host, port)),
65+ wish.WithHostKeyPath("ssh_data/term_info_ed25519"),
66+ wish.WithPublicKeyAuth(authHandler),
67+ ptun.WithWebTunnel(ptun.NewWebTunnelHandler(serveMux, logger)),
68+ wish.WithMiddleware(GitServerMiddleware()),
69+ )
70+
71+ if err != nil {
72+ logger.Error("could not create server", "err", err)
73+ }
74+
75+ done := make(chan os.Signal, 1)
76+ signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
77+ logger.Info("starting SSH server", "host", host, "port", port)
78+ go func() {
79+ if err = s.ListenAndServe(); err != nil {
80+ logger.Error("serve error", "err", err)
81+ os.Exit(1)
82+ }
83+ }()
84+
85+ <-done
86+ logger.Info("stopping SSH server")
87+ ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
88+ defer func() { cancel() }()
89+ if err := s.Shutdown(ctx); err != nil {
90+ logger.Error("shutdown", "err", err)
91+ os.Exit(1)
92+ }
93+}