Skip to content

Commit ea2e509

Browse files
authored
Rewrite from TypeScript to Go (#211)
Replace TypeScript implementation (rathole + traefik) with a single Go binary using native QUIC tunneling. Zero external runtime dependencies.
1 parent 5c81790 commit ea2e509

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+5341
-9134
lines changed

.dockerignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
/src/managers/*.toml
1+
.git
2+
.github
3+
*.md
Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,38 @@
1-
---
21
name: Quality Assurance
32

43
on:
54
push:
6-
branches: ["main"]
5+
branches: [main]
76
pull_request:
8-
branches: ["main"]
7+
branches: [main]
98

109
jobs:
11-
12-
docker-buildx:
13-
runs-on: ubuntu-latest
10+
lint:
11+
runs-on: ubuntu-24.04
1412
steps:
15-
- uses: actions/checkout@v5
16-
- uses: docker/setup-qemu-action@v3
17-
- uses: docker/setup-buildx-action@v3
18-
id: buildx
13+
- uses: actions/checkout@v4
14+
- uses: actions/setup-go@v5
1915
with:
20-
install: true
21-
- run: docker buildx build --platform linux/amd64 . -t firecow/ratnation --cache-to type=gha --cache-from type=gha,mode=max
16+
go-version: "1.23"
17+
- uses: golangci/golangci-lint-action@v6
18+
with:
19+
version: v1.64.5
2220

23-
eslint:
24-
runs-on: ubuntu-latest
21+
test:
22+
runs-on: ubuntu-24.04
2523
steps:
26-
- uses: actions/checkout@v5
27-
- uses: actions/setup-node@v6
24+
- uses: actions/checkout@v4
25+
- uses: actions/setup-go@v5
2826
with:
29-
node-version: 22
30-
cache: 'npm'
31-
- run: npm ci --no-audit
32-
- run: npx eslint .
27+
go-version: "1.23"
28+
- run: go test -race ./...
3329

34-
jest:
35-
runs-on: ubuntu-latest
30+
docker:
31+
runs-on: ubuntu-24.04
3632
steps:
37-
- uses: actions/checkout@v5
38-
- uses: actions/setup-node@v6
33+
- uses: actions/checkout@v4
34+
- uses: docker/setup-buildx-action@v3
35+
- uses: docker/build-push-action@v6
3936
with:
40-
node-version: 22
41-
cache: 'npm'
42-
- run: npm ci --no-audit
43-
- run: npm run build
44-
- run: npm test
45-
- run: node src/index.js --help
37+
context: .
38+
push: false

.gitignore

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,2 @@
1-
/.cego/
2-
/.idea/
3-
/.gitlab-ci-local/
4-
/coverage/
5-
/node_modules/
6-
/src/king/*.toml
7-
/src/ling/*.toml
8-
**/*.mjs
9-
**/*.js
1+
/burrow
2+
*.exe

.golangci.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
linters:
2+
enable:
3+
- bodyclose
4+
- copyloopvar
5+
- errcheck
6+
- errorlint
7+
- gocognit
8+
- gocritic
9+
- gofmt
10+
- gosec
11+
- govet
12+
- ineffassign
13+
- misspell
14+
- nilerr
15+
- prealloc
16+
- revive
17+
- staticcheck
18+
- unconvert
19+
- unparam
20+
- unused
21+
- wastedassign
22+
23+
linters-settings:
24+
gocognit:
25+
min-complexity: 30
26+
revive:
27+
rules:
28+
- name: blank-imports
29+
- name: context-as-argument
30+
- name: dot-imports
31+
- name: error-return
32+
- name: error-strings
33+
- name: exported
34+
disabled: true
35+
- name: increment-decrement
36+
- name: indent-error-flow
37+
- name: range
38+
- name: receiver-naming
39+
- name: redefines-builtin-id
40+
- name: time-naming
41+
- name: unexported-return
42+
- name: var-declaration
43+
- name: var-naming

Dockerfile

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
FROM traefik:v3.5.0 AS traefik
1+
FROM golang:1.24.4-alpine AS builder
22

3-
FROM alpine:3.22.1 AS rathole
4-
RUN wget -O rathole.zip https://github.com/rapiz1/rathole/releases/download/v0.4.8/rathole-x86_64-unknown-linux-musl.zip && unzip rathole.zip
3+
WORKDIR /build
54

6-
FROM alpine:3.22.1 AS node_modules
7-
RUN apk add nodejs npm
8-
COPY package.json package-lock.json ./
9-
RUN npm install --no-audit --no-progress --omit=dev
5+
COPY go.mod go.sum ./
6+
RUN go mod download
107

11-
FROM alpine:3.22.1
12-
RUN apk add nodejs npm
13-
COPY --from=node_modules /node_modules /node_modules
14-
COPY --from=traefik /usr/local/bin/traefik /usr/local/bin/traefik
15-
COPY --from=rathole /rathole /usr/local/bin/rathole
16-
COPY package.json ./
17-
COPY src src
18-
ENTRYPOINT ["node", "src/index.js"]
8+
COPY . .
9+
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o burrow ./cmd/burrow
10+
11+
FROM alpine:3.21.3
12+
13+
RUN apk add --no-cache ca-certificates
14+
15+
COPY --from=builder /build/burrow /usr/local/bin/burrow
16+
17+
ENTRYPOINT ["burrow"]

cmd/burrow/main.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"log/slog"
6+
"os"
7+
"os/signal"
8+
"syscall"
9+
10+
"github.com/firecow/ratnation/internal/council"
11+
"github.com/firecow/ratnation/internal/debug"
12+
"github.com/firecow/ratnation/internal/king"
13+
"github.com/firecow/ratnation/internal/ling"
14+
"github.com/spf13/cobra"
15+
)
16+
17+
func main() {
18+
os.Exit(run())
19+
}
20+
21+
func run() int {
22+
slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, nil)))
23+
24+
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
25+
defer cancel()
26+
27+
root := &cobra.Command{
28+
Use: "burrow",
29+
Short: "Distributed service mesh with native QUIC tunneling",
30+
}
31+
32+
root.AddCommand(council.Command())
33+
root.AddCommand(king.Command())
34+
root.AddCommand(ling.Command())
35+
root.AddCommand(debug.Command())
36+
37+
root.SetContext(ctx)
38+
39+
if err := root.ExecuteContext(ctx); err != nil {
40+
return 1
41+
}
42+
return 0
43+
}

example_deploy.sh

Lines changed: 0 additions & 10 deletions
This file was deleted.

examples/docker-swarm/stack.yml

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ networks:
1111
attachable: true
1212

1313
services:
14-
ratcouncil:
14+
council:
1515
image: firecow/ratnation:${DOCKER_TAG:-latest}
1616
networks: [host]
1717
command: council --port 8080
1818
ports:
1919
- { target: 8080, published: 8080, protocol: tcp, mode: host }
2020

21-
ratking1:
21+
king1:
2222
image: firecow/ratnation:${DOCKER_TAG:-latest}
2323
networks: [host]
2424
command:
@@ -28,11 +28,11 @@ services:
2828
--rathole="bind_port=2333 ports=5000-5001"
2929
--location=CPH
3030
ports:
31-
- { target: 2333, published: 2333, protocol: tcp, mode: host }
31+
- { target: 2333, published: 2333, protocol: udp, mode: host }
3232
- { target: 5000, published: 5000, protocol: tcp, mode: host }
3333
- { target: 5001, published: 5001, protocol: tcp, mode: host }
3434

35-
ratking2:
35+
king2:
3636
image: firecow/ratnation:${DOCKER_TAG:-latest}
3737
networks: [host]
3838
command:
@@ -43,14 +43,14 @@ services:
4343
--rathole="bind_port=2335 ports=5004-5004"
4444
--location=AMS
4545
ports:
46-
- { target: 2334, published: 2334, protocol: tcp, mode: host }
47-
- { target: 2335, published: 2335, protocol: tcp, mode: host }
46+
- { target: 2334, published: 2334, protocol: udp, mode: host }
47+
- { target: 2335, published: 2335, protocol: udp, mode: host }
4848
- { target: 5002, published: 5002, protocol: tcp, mode: host }
4949
- { target: 5003, published: 5003, protocol: tcp, mode: host }
5050
- { target: 5004, published: 5004, protocol: tcp, mode: host }
5151

52-
# <editor-fold desc="Alpha services">
53-
ratling-alpha:
52+
# Alpha services
53+
ling-alpha:
5454
image: firecow/ratnation:${DOCKER_TAG:-latest}
5555
networks: [alpha]
5656
command:
@@ -60,24 +60,22 @@ services:
6060
deploy: { update_config: { order: start-first, parallelism: 0 } }
6161
echoserver-alpha:
6262
hostname: echoserver-alpha
63-
image: jmalloc/echo-server
63+
image: jmalloc/echo-server:0.3.6
6464
networks: [alpha]
6565
deploy: { update_config: { order: start-first, parallelism: 0 } }
66-
# </editor-fold>
6766

68-
# <editor-fold desc="Beta services">
69-
ratling-beta:
67+
# Beta services
68+
ling-beta:
7069
image: firecow/ratnation:${DOCKER_TAG:-latest}
7170
networks: [beta]
7271
command:
7372
ling
7473
--council-host="http://172.17.0.1:8080"
7574
--proxy="name=alpha bind_port=2184"
7675
deploy: { update_config: { order: start-first, parallelism: 0 } }
77-
# This requester service should be able to reach echoserver-alpha through the ratling-beta on port 2184
76+
# This requester service should be able to reach echoserver-alpha through ling-beta on port 2184
7877
debug-requester-beta:
7978
image: firecow/ratnation:${DOCKER_TAG:-latest}
80-
command: ["debug-requester", "--url=http://ratling-beta:2184"]
79+
command: ["debug-requester", "--url=http://ling-beta:2184"]
8180
networks: [beta]
8281
deploy: { update_config: { order: start-first, parallelism: 0 } }
83-
# </editor-fold>

go.mod

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
module github.com/firecow/ratnation
2+
3+
go 1.24.0
4+
5+
require (
6+
github.com/coder/websocket v1.8.14
7+
github.com/google/uuid v1.6.0
8+
github.com/quic-go/quic-go v0.49.0
9+
github.com/spf13/cobra v1.8.1
10+
github.com/stretchr/testify v1.11.1
11+
github.com/testcontainers/testcontainers-go v0.40.0
12+
)
13+
14+
require (
15+
dario.cat/mergo v1.0.2 // indirect
16+
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
17+
github.com/Microsoft/go-winio v0.6.2 // indirect
18+
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
19+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
20+
github.com/containerd/errdefs v1.0.0 // indirect
21+
github.com/containerd/errdefs/pkg v0.3.0 // indirect
22+
github.com/containerd/log v0.1.0 // indirect
23+
github.com/containerd/platforms v0.2.1 // indirect
24+
github.com/cpuguy83/dockercfg v0.3.2 // indirect
25+
github.com/davecgh/go-spew v1.1.1 // indirect
26+
github.com/distribution/reference v0.6.0 // indirect
27+
github.com/docker/docker v28.5.1+incompatible // indirect
28+
github.com/docker/go-connections v0.6.0 // indirect
29+
github.com/docker/go-units v0.5.0 // indirect
30+
github.com/ebitengine/purego v0.8.4 // indirect
31+
github.com/felixge/httpsnoop v1.0.4 // indirect
32+
github.com/go-logr/logr v1.4.3 // indirect
33+
github.com/go-logr/stdr v1.2.2 // indirect
34+
github.com/go-ole/go-ole v1.2.6 // indirect
35+
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
36+
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
37+
github.com/inconshreveable/mousetrap v1.1.0 // indirect
38+
github.com/klauspost/compress v1.18.0 // indirect
39+
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
40+
github.com/magiconair/properties v1.8.10 // indirect
41+
github.com/moby/docker-image-spec v1.3.1 // indirect
42+
github.com/moby/go-archive v0.1.0 // indirect
43+
github.com/moby/patternmatcher v0.6.0 // indirect
44+
github.com/moby/sys/sequential v0.6.0 // indirect
45+
github.com/moby/sys/user v0.4.0 // indirect
46+
github.com/moby/sys/userns v0.1.0 // indirect
47+
github.com/moby/term v0.5.0 // indirect
48+
github.com/morikuni/aec v1.0.0 // indirect
49+
github.com/onsi/ginkgo/v2 v2.9.5 // indirect
50+
github.com/opencontainers/go-digest v1.0.0 // indirect
51+
github.com/opencontainers/image-spec v1.1.1 // indirect
52+
github.com/pkg/errors v0.9.1 // indirect
53+
github.com/pmezard/go-difflib v1.0.0 // indirect
54+
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
55+
github.com/shirou/gopsutil/v4 v4.25.6 // indirect
56+
github.com/sirupsen/logrus v1.9.3 // indirect
57+
github.com/spf13/pflag v1.0.5 // indirect
58+
github.com/tklauser/go-sysconf v0.3.12 // indirect
59+
github.com/tklauser/numcpus v0.6.1 // indirect
60+
github.com/yusufpapurcu/wmi v1.2.4 // indirect
61+
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
62+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
63+
go.opentelemetry.io/otel v1.40.0 // indirect
64+
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 // indirect
65+
go.opentelemetry.io/otel/metric v1.40.0 // indirect
66+
go.opentelemetry.io/otel/sdk v1.40.0 // indirect
67+
go.opentelemetry.io/otel/trace v1.40.0 // indirect
68+
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
69+
go.uber.org/mock v0.5.0 // indirect
70+
golang.org/x/crypto v0.43.0 // indirect
71+
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
72+
golang.org/x/mod v0.18.0 // indirect
73+
golang.org/x/net v0.45.0 // indirect
74+
golang.org/x/sync v0.8.0 // indirect
75+
golang.org/x/sys v0.40.0 // indirect
76+
golang.org/x/tools v0.22.0 // indirect
77+
google.golang.org/protobuf v1.36.11 // indirect
78+
gopkg.in/yaml.v3 v3.0.1 // indirect
79+
)

0 commit comments

Comments
 (0)