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"
|
||||
)
|
||||
|
||||
var version string = "develop"
|
||||
|
||||
type ConfigDef struct {
|
||||
Key string
|
||||
Env string
|
||||
@ -102,6 +104,10 @@ func GetConfigDefs[T ServerConfig | ClientConfig]() []ConfigDef {
|
||||
return defs
|
||||
}
|
||||
|
||||
func GetVersion() string {
|
||||
return version
|
||||
}
|
||||
|
||||
func getConfigValue(cmdFlags *pflag.FlagSet, def ConfigDef) string {
|
||||
// 1. Get Flags First
|
||||
if cmdFlags != nil {
|
||||
|
@ -3,6 +3,7 @@ package server
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -19,6 +20,16 @@ import (
|
||||
"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 {
|
||||
*websocket.Conn
|
||||
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()
|
||||
count := len(s.tunnels)
|
||||
for t, c := range s.tunnels {
|
||||
allTunnels = append(allTunnels, TunnelInfo{
|
||||
Name: t,
|
||||
Target: c.RemoteAddr().String(),
|
||||
})
|
||||
}
|
||||
s.mu.RUnlock()
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(200)
|
||||
// Create Response
|
||||
d, err := json.MarshalIndent(InfoResponse{
|
||||
Tunnels: allTunnels,
|
||||
Version: config.GetVersion(),
|
||||
}, "", " ")
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
response := fmt.Sprintf(`{"tunnels": %d}`, count)
|
||||
_, _ = w.Write([]byte(response))
|
||||
// Send Response
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write(d)
|
||||
}
|
||||
|
||||
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 {
|
||||
case "/_conduit/tunnel":
|
||||
s.createTunnel(w, r)
|
||||
case "/_conduit/status":
|
||||
s.getStatus(w, r)
|
||||
case "/_conduit/info":
|
||||
s.getInfo(w, r)
|
||||
default:
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user