build stuff
This commit is contained in:
parent
d2b9f273e0
commit
516427dcda
35
.drone.yml
Normal file
35
.drone.yml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: default
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
branch:
|
||||||
|
- master
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# Unit Tests
|
||||||
|
- name: tests
|
||||||
|
image: golang
|
||||||
|
commands:
|
||||||
|
- make tests
|
||||||
|
|
||||||
|
# Fetch tags
|
||||||
|
- name: fetch tags
|
||||||
|
image: alpine/git
|
||||||
|
commands:
|
||||||
|
- git fetch --tags
|
||||||
|
|
||||||
|
# Publish docker image
|
||||||
|
- name: publish docker
|
||||||
|
image: plugins/docker
|
||||||
|
settings:
|
||||||
|
repo: gitea.va.reichard.io/evan/conduit
|
||||||
|
registry: gitea.va.reichard.io
|
||||||
|
tags:
|
||||||
|
- dev
|
||||||
|
custom_dns:
|
||||||
|
- 8.8.8.8
|
||||||
|
username:
|
||||||
|
from_secret: docker_username
|
||||||
|
password:
|
||||||
|
from_secret: docker_password
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
cover.html
|
27
Dockerfile
Normal file
27
Dockerfile
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# Certificates & Timezones
|
||||||
|
FROM alpine AS alpine
|
||||||
|
RUN apk update && apk add --no-cache ca-certificates tzdata
|
||||||
|
|
||||||
|
# Build Image
|
||||||
|
FROM golang:1.24 AS build
|
||||||
|
|
||||||
|
# Create Package Directory
|
||||||
|
RUN mkdir -p /opt/conduit
|
||||||
|
|
||||||
|
# Copy Source
|
||||||
|
WORKDIR /src
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Compile
|
||||||
|
RUN go build \
|
||||||
|
-ldflags "-X reichard.io/conduit/config.version=`git describe --tags`" \
|
||||||
|
-o /opt/conduit/conduit
|
||||||
|
|
||||||
|
# Create Image
|
||||||
|
FROM busybox:1.36
|
||||||
|
COPY --from=alpine /etc/ssl/certs /etc/ssl/certs
|
||||||
|
COPY --from=alpine /usr/share/zoneinfo /usr/share/zoneinfo
|
||||||
|
COPY --from=build /opt/conduit /opt/conduit
|
||||||
|
WORKDIR /opt/conduit
|
||||||
|
EXPOSE 8080
|
||||||
|
ENTRYPOINT ["/opt/conduit/conduit", "serve"]
|
29
Dockerfile-BuildKit
Normal file
29
Dockerfile-BuildKit
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Certificates & Timezones
|
||||||
|
FROM alpine AS alpine
|
||||||
|
RUN apk update && apk add --no-cache ca-certificates tzdata
|
||||||
|
|
||||||
|
# Build Image
|
||||||
|
FROM --platform=$BUILDPLATFORM golang:1.24 AS build
|
||||||
|
|
||||||
|
# Create Package Directory
|
||||||
|
WORKDIR /src
|
||||||
|
RUN mkdir -p /opt/conduit
|
||||||
|
|
||||||
|
# Cache Dependencies & Compile
|
||||||
|
ARG TARGETOS
|
||||||
|
ARG TARGETARCH
|
||||||
|
RUN --mount=target=. \
|
||||||
|
--mount=type=cache,target=/root/.cache/go-build \
|
||||||
|
--mount=type=cache,target=/go/pkg \
|
||||||
|
GOOS=$TARGETOS GOARCH=$TARGETARCH go build \
|
||||||
|
-ldflags "-X reichard.io/conduit/config.version=`git describe --tags`" \
|
||||||
|
-o /opt/conduit/conduit
|
||||||
|
|
||||||
|
# Create Image
|
||||||
|
FROM busybox:1.36
|
||||||
|
COPY --from=alpine /etc/ssl/certs /etc/ssl/certs
|
||||||
|
COPY --from=alpine /usr/share/zoneinfo /usr/share/zoneinfo
|
||||||
|
COPY --from=build /opt/conduit /opt/conduit
|
||||||
|
WORKDIR /opt/conduit
|
||||||
|
EXPOSE 8080
|
||||||
|
ENTRYPOINT ["/opt/conduit/conduit", "serve"]
|
35
Makefile
Normal file
35
Makefile
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
build_local:
|
||||||
|
go mod download
|
||||||
|
rm -r ./build || true
|
||||||
|
mkdir -p ./build
|
||||||
|
|
||||||
|
env GOOS=linux GOARCH=amd64 go build -ldflags "-X reichard.io/conduit/config.version=`git describe --tags`" -o ./build/server_linux_amd64
|
||||||
|
env GOOS=linux GOARCH=arm64 go build -ldflags "-X reichard.io/conduit/config.version=`git describe --tags`" -o ./build/server_linux_arm64
|
||||||
|
env GOOS=darwin GOARCH=arm64 go build -ldflags "-X reichard.io/conduit/config.version=`git describe --tags`" -o ./build/server_darwin_arm64
|
||||||
|
env GOOS=darwin GOARCH=amd64 go build -ldflags "-X reichard.io/conduit/config.version=`git describe --tags`" -o ./build/server_darwin_amd64
|
||||||
|
|
||||||
|
docker_build_local:
|
||||||
|
docker build -t conduit:latest .
|
||||||
|
|
||||||
|
docker_build_release_dev:
|
||||||
|
docker buildx build \
|
||||||
|
--platform linux/amd64,linux/arm64 \
|
||||||
|
-t gitea.va.reichard.io/evan/conduit:dev \
|
||||||
|
-f Dockerfile-BuildKit \
|
||||||
|
--push .
|
||||||
|
|
||||||
|
docker_build_release_latest:
|
||||||
|
docker buildx build \
|
||||||
|
--platform linux/amd64,linux/arm64 \
|
||||||
|
-t gitea.va.reichard.io/evan/conduit:latest \
|
||||||
|
-t gitea.va.reichard.io/evan/conduit:`git describe --tags` \
|
||||||
|
-f Dockerfile-BuildKit \
|
||||||
|
--push .
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf ./build
|
||||||
|
|
||||||
|
tests:
|
||||||
|
SET_TEST=set_val go test -coverpkg=./... ./... -coverprofile=./cover.out
|
||||||
|
go tool cover -html=./cover.out -o ./cover.html
|
||||||
|
rm ./cover.out
|
39
cmd/tunnel.go
Normal file
39
cmd/tunnel.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"reichard.io/conduit/client"
|
||||||
|
"reichard.io/conduit/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
var tunnelCmd = &cobra.Command{
|
||||||
|
Use: "tunnel <name> <host:port>",
|
||||||
|
Short: "Create a conduit tunnel",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
// Get Client Config
|
||||||
|
cfg, err := config.GetClientConfig(cmd.Flags())
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("failed to get client config:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Tunnel
|
||||||
|
tunnel, err := client.NewTunnel(cfg)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("failed to create tunnel:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start Tunnel
|
||||||
|
log.Infof("creating TCP tunnel: %s -> %s", cfg.TunnelName, cfg.TunnelTarget)
|
||||||
|
if err := tunnel.Start(); err != nil {
|
||||||
|
log.Fatal("failed to start tunnel:", err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
configDefs := config.GetConfigDefs[config.ClientConfig]()
|
||||||
|
for _, d := range configDefs {
|
||||||
|
tunnelCmd.Flags().String(d.Key, d.Default, d.Description)
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,8 @@ import (
|
|||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var version string = "develop"
|
||||||
|
|
||||||
type ConfigDef struct {
|
type ConfigDef struct {
|
||||||
Key string
|
Key string
|
||||||
Env string
|
Env string
|
||||||
@ -102,6 +104,10 @@ func GetConfigDefs[T ServerConfig | ClientConfig]() []ConfigDef {
|
|||||||
return defs
|
return defs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetVersion() string {
|
||||||
|
return version
|
||||||
|
}
|
||||||
|
|
||||||
func getConfigValue(cmdFlags *pflag.FlagSet, def ConfigDef) string {
|
func getConfigValue(cmdFlags *pflag.FlagSet, def ConfigDef) string {
|
||||||
// 1. Get Flags First
|
// 1. Get Flags First
|
||||||
if cmdFlags != nil {
|
if cmdFlags != nil {
|
||||||
|
@ -3,6 +3,7 @@ package server
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@ -19,6 +20,16 @@ import (
|
|||||||
"reichard.io/conduit/types"
|
"reichard.io/conduit/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type InfoResponse struct {
|
||||||
|
Tunnels []TunnelInfo `json:"tunnels"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TunnelInfo struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Target string `json:"target"`
|
||||||
|
}
|
||||||
|
|
||||||
type TunnelConnection struct {
|
type TunnelConnection struct {
|
||||||
*websocket.Conn
|
*websocket.Conn
|
||||||
name string
|
name string
|
||||||
@ -76,16 +87,31 @@ func (s *Server) Start() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) getStatus(w http.ResponseWriter, _ *http.Request) {
|
func (s *Server) getInfo(w http.ResponseWriter, _ *http.Request) {
|
||||||
|
// Get Tunnels
|
||||||
|
var allTunnels []TunnelInfo
|
||||||
s.mu.RLock()
|
s.mu.RLock()
|
||||||
count := len(s.tunnels)
|
for t, c := range s.tunnels {
|
||||||
|
allTunnels = append(allTunnels, TunnelInfo{
|
||||||
|
Name: t,
|
||||||
|
Target: c.RemoteAddr().String(),
|
||||||
|
})
|
||||||
|
}
|
||||||
s.mu.RUnlock()
|
s.mu.RUnlock()
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
// Create Response
|
||||||
w.WriteHeader(200)
|
d, err := json.MarshalIndent(InfoResponse{
|
||||||
|
Tunnels: allTunnels,
|
||||||
|
Version: config.GetVersion(),
|
||||||
|
}, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
response := fmt.Sprintf(`{"tunnels": %d}`, count)
|
// Send Response
|
||||||
_, _ = w.Write([]byte(response))
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
_, _ = w.Write(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) proxyRawConnection(clientConn net.Conn, tunnelConn *TunnelConnection, dataReader io.Reader) {
|
func (s *Server) proxyRawConnection(clientConn net.Conn, tunnelConn *TunnelConnection, dataReader io.Reader) {
|
||||||
@ -212,8 +238,8 @@ func (s *Server) handleAsHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
switch r.URL.Path {
|
switch r.URL.Path {
|
||||||
case "/_conduit/tunnel":
|
case "/_conduit/tunnel":
|
||||||
s.createTunnel(w, r)
|
s.createTunnel(w, r)
|
||||||
case "/_conduit/status":
|
case "/_conduit/info":
|
||||||
s.getStatus(w, r)
|
s.getInfo(w, r)
|
||||||
default:
|
default:
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user