mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-19 20:32:35 +02:00
fixed issue for container not being excluded on restart
This commit is contained in:
parent
860e914b90
commit
b38d7595a7
16 changed files with 67 additions and 52 deletions
2
Makefile
2
Makefile
|
@ -27,7 +27,7 @@ logs:
|
|||
docker compose logs -f
|
||||
|
||||
get:
|
||||
cd cmd && go get -u && go mod tidy && cd ..
|
||||
go get -u ./cmd && go mod tidy
|
||||
|
||||
debug:
|
||||
make BUILD_FLAG="" build && sudo GOPROXY_DEBUG=1 bin/go-proxy
|
||||
|
|
|
@ -17,6 +17,8 @@ const (
|
|||
ConfigFileName = "config.yml"
|
||||
ConfigExampleFileName = "config.example.yml"
|
||||
ConfigPath = ConfigBasePath + "/" + ConfigFileName
|
||||
|
||||
MiddlewareDefsBasePath = ConfigBasePath + "/middlewares"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -20,6 +20,7 @@ func FromDocker(c *types.Container, dockerHost string) (res Container) {
|
|||
res.ProxyProperties = &ProxyProperties{
|
||||
DockerHost: dockerHost,
|
||||
ContainerName: res.getName(),
|
||||
ContainerID: c.ID,
|
||||
ImageName: res.getImageName(),
|
||||
PublicPortMapping: res.getPublicPortMapping(),
|
||||
PrivatePortMapping: res.getPrivatePortMapping(),
|
||||
|
|
|
@ -63,7 +63,9 @@ func Register(entry *P.ReverseProxyEntry) (*watcher, E.NestedError) {
|
|||
watcherMapMu.Lock()
|
||||
defer watcherMapMu.Unlock()
|
||||
|
||||
if w, ok := watcherMap[entry.ContainerName]; ok {
|
||||
key := entry.ContainerID
|
||||
|
||||
if w, ok := watcherMap[key]; ok {
|
||||
w.refCount.Add(1)
|
||||
w.ReverseProxyEntry = entry
|
||||
return w, nil
|
||||
|
@ -85,7 +87,7 @@ func Register(entry *P.ReverseProxyEntry) (*watcher, E.NestedError) {
|
|||
w.refCount.Add(1)
|
||||
w.stopByMethod = w.getStopCallback()
|
||||
|
||||
watcherMap[w.ContainerName] = w
|
||||
watcherMap[key] = w
|
||||
|
||||
go func() {
|
||||
newWatcherCh <- w
|
||||
|
@ -94,8 +96,8 @@ func Register(entry *P.ReverseProxyEntry) (*watcher, E.NestedError) {
|
|||
return w, nil
|
||||
}
|
||||
|
||||
func Unregister(containerName string) {
|
||||
if w, ok := watcherMap[containerName]; ok {
|
||||
func Unregister(entry *P.ReverseProxyEntry) {
|
||||
if w, ok := watcherMap[entry.ContainerID]; ok {
|
||||
w.refCount.Add(-1)
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +120,7 @@ func Start() {
|
|||
w.refCount.Wait() // wait for 0 ref count
|
||||
|
||||
w.client.Close()
|
||||
delete(watcherMap, w.ContainerName)
|
||||
delete(watcherMap, w.ContainerID)
|
||||
w.l.Debug("unregistered")
|
||||
mainLoopWg.Done()
|
||||
}()
|
||||
|
@ -138,29 +140,29 @@ func (w *watcher) PatchRoundTripper(rtp http.RoundTripper) roundTripper {
|
|||
}
|
||||
|
||||
func (w *watcher) containerStop() error {
|
||||
return w.client.ContainerStop(w.ctx, w.ContainerName, container.StopOptions{
|
||||
return w.client.ContainerStop(w.ctx, w.ContainerID, container.StopOptions{
|
||||
Signal: string(w.StopSignal),
|
||||
Timeout: &w.StopTimeout})
|
||||
}
|
||||
|
||||
func (w *watcher) containerPause() error {
|
||||
return w.client.ContainerPause(w.ctx, w.ContainerName)
|
||||
return w.client.ContainerPause(w.ctx, w.ContainerID)
|
||||
}
|
||||
|
||||
func (w *watcher) containerKill() error {
|
||||
return w.client.ContainerKill(w.ctx, w.ContainerName, string(w.StopSignal))
|
||||
return w.client.ContainerKill(w.ctx, w.ContainerID, string(w.StopSignal))
|
||||
}
|
||||
|
||||
func (w *watcher) containerUnpause() error {
|
||||
return w.client.ContainerUnpause(w.ctx, w.ContainerName)
|
||||
return w.client.ContainerUnpause(w.ctx, w.ContainerID)
|
||||
}
|
||||
|
||||
func (w *watcher) containerStart() error {
|
||||
return w.client.ContainerStart(w.ctx, w.ContainerName, container.StartOptions{})
|
||||
return w.client.ContainerStart(w.ctx, w.ContainerID, container.StartOptions{})
|
||||
}
|
||||
|
||||
func (w *watcher) containerStatus() (string, E.NestedError) {
|
||||
json, err := w.client.ContainerInspect(w.ctx, w.ContainerName)
|
||||
json, err := w.client.ContainerInspect(w.ctx, w.ContainerID)
|
||||
if err != nil {
|
||||
return "", E.FailWith("inspect container", err)
|
||||
}
|
||||
|
@ -219,7 +221,7 @@ func (w *watcher) watchUntilCancel() {
|
|||
dockerEventCh, dockerEventErrCh := dockerWatcher.EventsWithOptions(w.ctx, W.DockerListOptions{
|
||||
Filters: W.NewDockerFilter(
|
||||
W.DockerFilterContainer,
|
||||
W.DockerrFilterContainerName(w.ContainerName),
|
||||
W.DockerrFilterContainer(w.ContainerID),
|
||||
W.DockerFilterStart,
|
||||
W.DockerFilterStop,
|
||||
W.DockerFilterDie,
|
||||
|
|
|
@ -6,6 +6,7 @@ type PortMapping = map[string]types.Port
|
|||
type ProxyProperties struct {
|
||||
DockerHost string `yaml:"-" json:"docker_host"`
|
||||
ContainerName string `yaml:"-" json:"container_name"`
|
||||
ContainerID string `yaml:"-" json:"container_id"`
|
||||
ImageName string `yaml:"-" json:"image_name"`
|
||||
PublicPortMapping PortMapping `yaml:"-" json:"public_port_mapping"` // non-zero publicPort:types.Port
|
||||
PrivatePortMapping PortMapping `yaml:"-" json:"private_port_mapping"` // privatePort:types.Port
|
||||
|
|
|
@ -49,8 +49,6 @@ func (b Builder) Addf(format string, args ...any) Builder {
|
|||
func (b Builder) Build() NestedError {
|
||||
if len(b.errors) == 0 {
|
||||
return nil
|
||||
} else if len(b.errors) == 1 {
|
||||
return b.errors[0].Subjectf("%s", b.message)
|
||||
}
|
||||
return Join(b.message, b.errors...)
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ var CloudflareRealIP = &realIP{
|
|||
},
|
||||
}
|
||||
|
||||
func NewCloudflareRealIP(_ OptionsRaw, _ *ReverseProxy) (*Middleware, E.NestedError) {
|
||||
func NewCloudflareRealIP(_ OptionsRaw) (*Middleware, E.NestedError) {
|
||||
cri := new(realIP)
|
||||
cri.m = &Middleware{
|
||||
impl: cri,
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/yusing/go-proxy/internal/common"
|
||||
D "github.com/yusing/go-proxy/internal/docker"
|
||||
E "github.com/yusing/go-proxy/internal/error"
|
||||
gpHTTP "github.com/yusing/go-proxy/internal/net/http"
|
||||
|
@ -31,6 +30,7 @@ type (
|
|||
TrustForwardHeader bool
|
||||
AuthResponseHeaders []string
|
||||
AddAuthCookiesToResponse []string
|
||||
transport http.RoundTripper
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -56,16 +56,29 @@ var ForwardAuth = func() *forwardAuth {
|
|||
}()
|
||||
var faLogger = logrus.WithField("middleware", "ForwardAuth")
|
||||
|
||||
func NewForwardAuthfunc(optsRaw OptionsRaw, rp *ReverseProxy) (*Middleware, E.NestedError) {
|
||||
tr, ok := rp.Transport.(*http.Transport)
|
||||
if ok {
|
||||
tr = tr.Clone()
|
||||
} else {
|
||||
tr = common.DefaultTransport.Clone()
|
||||
}
|
||||
|
||||
func NewForwardAuthfunc(optsRaw OptionsRaw) (*Middleware, E.NestedError) {
|
||||
faWithOpts := new(forwardAuth)
|
||||
faWithOpts.forwardAuthOpts = new(forwardAuthOpts)
|
||||
err := Deserialize(optsRaw, faWithOpts.forwardAuthOpts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = E.Check(url.Parse(faWithOpts.Address))
|
||||
if err != nil {
|
||||
return nil, E.Invalid("address", faWithOpts.Address)
|
||||
}
|
||||
|
||||
faWithOpts.m = &Middleware{
|
||||
impl: faWithOpts,
|
||||
before: faWithOpts.forward,
|
||||
}
|
||||
|
||||
// TODO: use tr from reverse proxy
|
||||
tr, ok := faWithOpts.forwardAuthOpts.transport.(*http.Transport)
|
||||
if ok {
|
||||
tr = tr.Clone()
|
||||
}
|
||||
|
||||
faWithOpts.client = http.Client{
|
||||
CheckRedirect: func(r *Request, via []*Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
|
@ -73,19 +86,6 @@ func NewForwardAuthfunc(optsRaw OptionsRaw, rp *ReverseProxy) (*Middleware, E.Ne
|
|||
Timeout: 30 * time.Second,
|
||||
Transport: tr,
|
||||
}
|
||||
faWithOpts.m = &Middleware{
|
||||
impl: faWithOpts,
|
||||
before: faWithOpts.forward,
|
||||
}
|
||||
|
||||
err := Deserialize(optsRaw, faWithOpts.forwardAuthOpts)
|
||||
if err != nil {
|
||||
return nil, E.FailWith("set options", err)
|
||||
}
|
||||
_, err = E.Check(url.Parse(faWithOpts.Address))
|
||||
if err != nil {
|
||||
return nil, E.Invalid("address", faWithOpts.Address)
|
||||
}
|
||||
return faWithOpts.m, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ type (
|
|||
BeforeFunc func(next http.Handler, w ResponseWriter, r *Request)
|
||||
RewriteFunc func(req *Request)
|
||||
ModifyResponseFunc func(resp *Response) error
|
||||
CloneWithOptFunc func(opts OptionsRaw, rp *ReverseProxy) (*Middleware, E.NestedError)
|
||||
CloneWithOptFunc func(opts OptionsRaw) (*Middleware, E.NestedError)
|
||||
|
||||
OptionsRaw = map[string]any
|
||||
Options any
|
||||
|
@ -55,7 +55,7 @@ func (m *Middleware) String() string {
|
|||
|
||||
func (m *Middleware) WithOptionsClone(optsRaw OptionsRaw, rp *ReverseProxy) (*Middleware, E.NestedError) {
|
||||
if len(optsRaw) != 0 && m.withOptions != nil {
|
||||
if mWithOpt, err := m.withOptions(optsRaw, rp); err != nil {
|
||||
if mWithOpt, err := m.withOptions(optsRaw); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return mWithOpt, nil
|
||||
|
|
|
@ -30,7 +30,7 @@ var ModifyRequest = func() *modifyRequest {
|
|||
return mr
|
||||
}()
|
||||
|
||||
func NewModifyRequest(optsRaw OptionsRaw, _ *ReverseProxy) (*Middleware, E.NestedError) {
|
||||
func NewModifyRequest(optsRaw OptionsRaw) (*Middleware, E.NestedError) {
|
||||
mr := new(modifyRequest)
|
||||
mr.m = &Middleware{
|
||||
impl: mr,
|
||||
|
@ -39,7 +39,7 @@ func NewModifyRequest(optsRaw OptionsRaw, _ *ReverseProxy) (*Middleware, E.Neste
|
|||
mr.modifyRequestOpts = new(modifyRequestOpts)
|
||||
err := Deserialize(optsRaw, mr.modifyRequestOpts)
|
||||
if err != nil {
|
||||
return nil, E.FailWith("set options", err)
|
||||
return nil, err
|
||||
}
|
||||
return mr.m, nil
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ var ModifyResponse = func() (mr *modifyResponse) {
|
|||
return
|
||||
}()
|
||||
|
||||
func NewModifyResponse(optsRaw OptionsRaw, _ *ReverseProxy) (*Middleware, E.NestedError) {
|
||||
func NewModifyResponse(optsRaw OptionsRaw) (*Middleware, E.NestedError) {
|
||||
mr := new(modifyResponse)
|
||||
mr.m = &Middleware{
|
||||
impl: mr,
|
||||
|
@ -41,7 +41,7 @@ func NewModifyResponse(optsRaw OptionsRaw, _ *ReverseProxy) (*Middleware, E.Nest
|
|||
mr.modifyResponseOpts = new(modifyResponseOpts)
|
||||
err := Deserialize(optsRaw, mr.modifyResponseOpts)
|
||||
if err != nil {
|
||||
return nil, E.FailWith("set options", err)
|
||||
return nil, err
|
||||
}
|
||||
return mr.m, nil
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ var realIPOptsDefault = func() *realIPOpts {
|
|||
|
||||
var realIPLogger = logrus.WithField("middleware", "RealIP")
|
||||
|
||||
func NewRealIP(opts OptionsRaw, _ *ReverseProxy) (*Middleware, E.NestedError) {
|
||||
func NewRealIP(opts OptionsRaw) (*Middleware, E.NestedError) {
|
||||
riWithOpts := new(realIP)
|
||||
riWithOpts.m = &Middleware{
|
||||
impl: riWithOpts,
|
||||
|
@ -67,7 +67,7 @@ func NewRealIP(opts OptionsRaw, _ *ReverseProxy) (*Middleware, E.NestedError) {
|
|||
riWithOpts.realIPOpts = realIPOptsDefault()
|
||||
err := Deserialize(opts, riWithOpts.realIPOpts)
|
||||
if err != nil {
|
||||
return nil, E.FailWith("set options", err)
|
||||
return nil, err
|
||||
}
|
||||
return riWithOpts.m, nil
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ type (
|
|||
StopSignal T.Signal
|
||||
DockerHost string
|
||||
ContainerName string
|
||||
ContainerID string
|
||||
ContainerRunning bool
|
||||
}
|
||||
StreamEntry struct {
|
||||
|
@ -115,6 +116,7 @@ func validateRPEntry(m *M.RawEntry, s T.Scheme, b E.Builder) *ReverseProxyEntry
|
|||
StopSignal: stopSignal,
|
||||
DockerHost: m.DockerHost,
|
||||
ContainerName: m.ContainerName,
|
||||
ContainerID: m.ContainerID,
|
||||
ContainerRunning: m.Running,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,12 +78,17 @@ func (p *DockerProvider) LoadRoutesImpl() (routes R.Routes, err E.NestedError) {
|
|||
return routes, errors.Build()
|
||||
}
|
||||
|
||||
func (p *DockerProvider) shouldIgnore(container D.Container) bool {
|
||||
return container.IsExcluded ||
|
||||
!container.IsExplicit && p.ExplicitOnly
|
||||
}
|
||||
|
||||
func (p *DockerProvider) OnEvent(event W.Event, routes R.Routes) (res EventResult) {
|
||||
b := E.NewBuilder("event %s error", event)
|
||||
defer b.To(&res.err)
|
||||
|
||||
routes.RangeAll(func(k string, v R.Route) {
|
||||
if v.Entry().ContainerName == event.ActorName {
|
||||
if v.Entry().ContainerID == event.ActorID {
|
||||
b.Add(v.Stop())
|
||||
routes.Delete(k)
|
||||
res.nRemoved++
|
||||
|
@ -101,6 +106,11 @@ func (p *DockerProvider) OnEvent(event W.Event, routes R.Routes) (res EventResul
|
|||
b.Add(E.FailWith("inspect container", err))
|
||||
return
|
||||
}
|
||||
|
||||
if p.shouldIgnore(cont) {
|
||||
return
|
||||
}
|
||||
|
||||
entries, err := p.entriesFromContainerLabels(cont)
|
||||
b.Add(err)
|
||||
|
||||
|
@ -126,8 +136,7 @@ func (p *DockerProvider) OnEvent(event W.Event, routes R.Routes) (res EventResul
|
|||
func (p *DockerProvider) entriesFromContainerLabels(container D.Container) (entries M.RawEntries, _ E.NestedError) {
|
||||
entries = M.NewProxyEntries()
|
||||
|
||||
if container.IsExcluded ||
|
||||
!container.IsExplicit && p.ExplicitOnly {
|
||||
if p.shouldIgnore(container) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ func NewHTTPRoute(entry *P.ReverseProxyEntry) (*HTTPRoute, E.NestedError) {
|
|||
return nil
|
||||
}
|
||||
unregIdleWatcher = func() {
|
||||
idlewatcher.Unregister(entry.ContainerName)
|
||||
idlewatcher.Unregister(entry)
|
||||
rp.Transport = trans
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,8 +37,8 @@ var (
|
|||
dockerWatcherRetryInterval = 3 * time.Second
|
||||
)
|
||||
|
||||
func DockerrFilterContainerName(name string) filters.KeyValuePair {
|
||||
return filters.Arg("container", name)
|
||||
func DockerrFilterContainer(nameOrID string) filters.KeyValuePair {
|
||||
return filters.Arg("container", nameOrID)
|
||||
}
|
||||
|
||||
func NewDockerWatcher(host string) DockerWatcher {
|
||||
|
|
Loading…
Add table
Reference in a new issue