Skip to content

Commit

Permalink
fixed tcp/udp I/O, deadlock, nil dereference; improved docker watcher…
Browse files Browse the repository at this point in the history
…, idlewatcher, loading page
  • Loading branch information
yusing committed Sep 22, 2024
1 parent 96bce79 commit 090b73d
Show file tree
Hide file tree
Showing 31 changed files with 682 additions and 463 deletions.
1 change: 0 additions & 1 deletion docs/docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,6 @@ services:
ports:
- 25565
labels:
- proxy.mc.scheme=tcp
- proxy.mc.port=20001:25565
environment:
- EULA=TRUE
Expand Down
71 changes: 26 additions & 45 deletions docs/docker_socket_proxy.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,37 @@ For docker client on other machine, set this up, then add `name: tcp://<machine_

```yml
# compose.yml on remote machine (e.g. server1)
services:
docker-proxy:
container_name: docker-proxy
image: ghcr.io/linuxserver/socket-proxy
environment:
- ALLOW_START=1 #optional
- ALLOW_STOP=1 #optional
- ALLOW_RESTARTS=0 #optional
- AUTH=0 #optional
- BUILD=0 #optional
- COMMIT=0 #optional
- CONFIGS=0 #optional
- CONTAINERS=1 #optional
- DISABLE_IPV6=1 #optional
- DISTRIBUTION=0 #optional
- EVENTS=1 #optional
- EXEC=0 #optional
- IMAGES=0 #optional
- INFO=0 #optional
- NETWORKS=0 #optional
- NODES=0 #optional
- PING=1 #optional
- POST=1 #optional
- PLUGINS=0 #optional
- SECRETS=0 #optional
- SERVICES=0 #optional
- SESSION=0 #optional
- SWARM=0 #optional
- SYSTEM=0 #optional
- TASKS=0 #optional
- VERSION=1 #optional
- VOLUMES=0 #optional
volumes:
- /var/run/docker.sock:/var/run/docker.sock
restart: always
tmpfs:
- /run
ports:
- 2375:2375
docker-proxy:
container_name: docker-proxy
image: tecnativa/docker-socket-proxy
privileged: true
environment:
- ALLOW_START=1
- ALLOW_STOP=1
- ALLOW_RESTARTS=1
- CONTAINERS=1
- EVENTS=1
- PING=1
- POST=1
- VERSION=1
volumes:
- /var/run/docker.sock:/var/run/docker.sock
restart: always
ports:
- 2375:2375
# or more secure
- <machine_ip>:2375:2375
```
```yml
# config.yml on go-proxy machine
autocert:
... # your config
... # your config

providers:
include:
...
docker:
...
server1: tcp://<machine_ip>:2375
include:
...
docker:
...
server1: tcp://<machine_ip>:2375
```
2 changes: 1 addition & 1 deletion src/autocert/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (p *Provider) ObtainCert() (res E.NestedError) {
defer b.To(&res)

if p.cfg.Provider == ProviderLocal {
b.Addf("provider is set to %q", ProviderLocal)
b.Addf("provider is set to %q", ProviderLocal).WithSeverity(E.SeverityWarning)
return
}

Expand Down
29 changes: 29 additions & 0 deletions src/autocert/setup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package autocert

import (
"context"
"os"

E "github.com/yusing/go-proxy/error"
)

func (p *Provider) Setup(ctx context.Context) (err E.NestedError) {
if err = p.LoadCert(); err != nil {
if !err.Is(os.ErrNotExist) { // ignore if cert doesn't exist
return err
}
logger.Debug("obtaining cert due to error loading cert")
if err = p.ObtainCert(); err != nil {
return err.Warn()
}
}

go p.ScheduleRenewal(ctx)

for _, expiry := range p.GetExpiries() {
logger.Infof("certificate expire on %s", expiry)
break
}

return nil
}
14 changes: 8 additions & 6 deletions src/common/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ type Args struct {
}

const (
CommandStart = ""
CommandValidate = "validate"
CommandListConfigs = "ls-config"
CommandListRoutes = "ls-routes"
CommandReload = "reload"
CommandDebugListEntries = "debug-ls-entries"
CommandStart = ""
CommandValidate = "validate"
CommandListConfigs = "ls-config"
CommandListRoutes = "ls-routes"
CommandReload = "reload"
CommandDebugListEntries = "debug-ls-entries"
CommandDebugListProviders = "debug-ls-providers"
)

var ValidCommands = []string{
Expand All @@ -27,6 +28,7 @@ var ValidCommands = []string{
CommandListRoutes,
CommandReload,
CommandDebugListEntries,
CommandDebugListProviders,
}

func GetArgs() Args {
Expand Down
6 changes: 3 additions & 3 deletions src/common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ const (
)

const (
SchemaBasePath = "schema/"
ConfigSchemaPath = SchemaBasePath + "config.schema.json"
ProvidersSchemaPath = SchemaBasePath + "providers.schema.json"
SchemaBasePath = "schema/"
ConfigSchemaPath = SchemaBasePath + "config.schema.json"
FileProviderSchemaPath = SchemaBasePath + "providers.schema.json"
)

const DockerHostFromEnv = "$DOCKER_HOST"
Expand Down
70 changes: 3 additions & 67 deletions src/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
U "github.com/yusing/go-proxy/utils"
F "github.com/yusing/go-proxy/utils/functional"
W "github.com/yusing/go-proxy/watcher"
"github.com/yusing/go-proxy/watcher/events"
"gopkg.in/yaml.v3"
)

Expand Down Expand Up @@ -94,7 +95,7 @@ func (cfg *Config) WatchChanges() {
case <-cfg.watcherCtx.Done():
return
case event := <-eventCh:
if event.Action.IsDelete() {
if event.Action == events.ActionFileDeleted {
cfg.stopProviders()
} else {
cfg.reloadReq <- struct{}{}
Expand All @@ -107,71 +108,6 @@ func (cfg *Config) WatchChanges() {
}()
}

func (cfg *Config) FindRoute(alias string) R.Route {
return F.MapFind(cfg.proxyProviders,
func(p *PR.Provider) (R.Route, bool) {
if route, ok := p.GetRoute(alias); ok {
return route, true
}
return nil, false
},
)
}

func (cfg *Config) RoutesByAlias() map[string]U.SerializedObject {
routes := make(map[string]U.SerializedObject)
cfg.forEachRoute(func(alias string, r R.Route, p *PR.Provider) {
obj, err := U.Serialize(r)
if err.HasError() {
cfg.l.Error(err)
return
}
obj["provider"] = p.GetName()
obj["type"] = string(r.Type())
routes[alias] = obj
})
return routes
}

func (cfg *Config) Statistics() map[string]any {
nTotalStreams := 0
nTotalRPs := 0
providerStats := make(map[string]any)

cfg.forEachRoute(func(alias string, r R.Route, p *PR.Provider) {
s, ok := providerStats[p.GetName()]
if !ok {
s = make(map[string]int)
}

stats := s.(map[string]int)
switch r.Type() {
case R.RouteTypeStream:
stats["num_streams"]++
nTotalStreams++
case R.RouteTypeReverseProxy:
stats["num_reverse_proxies"]++
nTotalRPs++
default:
panic("bug: should not reach here")
}
})

return map[string]any{
"num_total_streams": nTotalStreams,
"num_total_reverse_proxies": nTotalRPs,
"providers": providerStats,
}
}

func (cfg *Config) DumpEntries() map[string]*M.RawEntry {
entries := make(map[string]*M.RawEntry)
cfg.forEachRoute(func(alias string, r R.Route, p *PR.Provider) {
entries[alias] = r.Entry()
})
return entries
}

func (cfg *Config) forEachRoute(do func(alias string, r R.Route, p *PR.Provider)) {
cfg.proxyProviders.RangeAll(func(_ string, p *PR.Provider) {
p.RangeRoutes(func(a string, r R.Route) {
Expand Down Expand Up @@ -259,7 +195,7 @@ func (cfg *Config) loadProviders(providers *M.ProxyProviders) (res E.NestedError
}

func (cfg *Config) controlProviders(action string, do func(*PR.Provider) E.NestedError) {
errors := E.NewBuilder("cannot %s these providers", action)
errors := E.NewBuilder("errors in %s these providers", action)

cfg.proxyProviders.RangeAll(func(name string, p *PR.Provider) {
if err := do(p); err.HasError() {
Expand Down
82 changes: 82 additions & 0 deletions src/config/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package config

import (
M "github.com/yusing/go-proxy/models"
PR "github.com/yusing/go-proxy/proxy/provider"
R "github.com/yusing/go-proxy/route"
U "github.com/yusing/go-proxy/utils"
F "github.com/yusing/go-proxy/utils/functional"
)

func (cfg *Config) DumpEntries() map[string]*M.RawEntry {
entries := make(map[string]*M.RawEntry)
cfg.forEachRoute(func(alias string, r R.Route, p *PR.Provider) {
entries[alias] = r.Entry()
})
return entries
}

func (cfg *Config) DumpProviders() map[string]*PR.Provider {
entries := make(map[string]*PR.Provider)
cfg.proxyProviders.RangeAll(func(name string, p *PR.Provider) {
entries[name] = p
})
return entries
}

func (cfg *Config) RoutesByAlias() map[string]U.SerializedObject {
routes := make(map[string]U.SerializedObject)
cfg.forEachRoute(func(alias string, r R.Route, p *PR.Provider) {
obj, err := U.Serialize(r)
if err.HasError() {
cfg.l.Error(err)
return
}
obj["provider"] = p.GetName()
obj["type"] = string(r.Type())
routes[alias] = obj
})
return routes
}

func (cfg *Config) Statistics() map[string]any {
nTotalStreams := 0
nTotalRPs := 0
providerStats := make(map[string]any)

cfg.forEachRoute(func(alias string, r R.Route, p *PR.Provider) {
s, ok := providerStats[p.GetName()]
if !ok {
s = make(map[string]int)
}

stats := s.(map[string]int)
switch r.Type() {
case R.RouteTypeStream:
stats["num_streams"]++
nTotalStreams++
case R.RouteTypeReverseProxy:
stats["num_reverse_proxies"]++
nTotalRPs++
default:
panic("bug: should not reach here")
}
})

return map[string]any{
"num_total_streams": nTotalStreams,
"num_total_reverse_proxies": nTotalRPs,
"providers": providerStats,
}
}

func (cfg *Config) FindRoute(alias string) R.Route {
return F.MapFind(cfg.proxyProviders,
func(p *PR.Provider) (R.Route, bool) {
if route, ok := p.GetRoute(alias); ok {
return route, true
}
return nil, false
},
)
}
Loading

0 comments on commit 090b73d

Please sign in to comment.