Minor changes
This commit is contained in:
parent
bb14ec70bd
commit
17ad5153b8
38 changed files with 93 additions and 182 deletions
|
@ -152,7 +152,7 @@ func (d *Datastore) Begin() (Transaction, Object, error) {
|
||||||
operation := func() error {
|
operation := func() error {
|
||||||
meta := d.get()
|
meta := d.get()
|
||||||
if meta.Lock != id {
|
if meta.Lock != id {
|
||||||
return fmt.Errorf("Object lock value: expected %s, got %s", id, meta.Lock)
|
return fmt.Errorf("object lock value: expected %s, got %s", id, meta.Lock)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ func (d *Datastore) Begin() (Transaction, Object, error) {
|
||||||
ebo.MaxElapsedTime = 60 * time.Second
|
ebo.MaxElapsedTime = 60 * time.Second
|
||||||
err = backoff.RetryNotify(safe.OperationWithRecover(operation), ebo, notify)
|
err = backoff.RetryNotify(safe.OperationWithRecover(operation), ebo, notify)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("Datastore cannot sync: %v", err)
|
return nil, nil, fmt.Errorf("datastore cannot sync: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// we synced with KV store, we can now return Setter
|
// we synced with KV store, we can now return Setter
|
||||||
|
@ -224,12 +224,12 @@ func (s *datastoreTransaction) Commit(object Object) error {
|
||||||
s.localLock.Lock()
|
s.localLock.Lock()
|
||||||
defer s.localLock.Unlock()
|
defer s.localLock.Unlock()
|
||||||
if s.dirty {
|
if s.dirty {
|
||||||
return fmt.Errorf("Transaction already used, please begin a new one")
|
return fmt.Errorf("transaction already used, please begin a new one")
|
||||||
}
|
}
|
||||||
s.Datastore.meta.object = object
|
s.Datastore.meta.object = object
|
||||||
err := s.Datastore.meta.Marshall()
|
err := s.Datastore.meta.Marshall()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Marshall error: %s", err)
|
return fmt.Errorf("marshall error: %s", err)
|
||||||
}
|
}
|
||||||
err = s.kv.StoreConfig(s.Datastore.meta)
|
err = s.kv.StoreConfig(s.Datastore.meta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -238,7 +238,7 @@ func (s *datastoreTransaction) Commit(object Object) error {
|
||||||
|
|
||||||
err = s.remoteLock.Unlock()
|
err = s.remoteLock.Unlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Unlock error: %s", err)
|
return fmt.Errorf("unlock error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.dirty = true
|
s.dirty = true
|
||||||
|
|
|
@ -88,7 +88,7 @@ Add more configuration information here.
|
||||||
// NewCmd builds a new Bug command
|
// NewCmd builds a new Bug command
|
||||||
func NewCmd(traefikConfiguration *cmd.TraefikConfiguration, traefikPointersConfiguration *cmd.TraefikConfiguration) *flaeg.Command {
|
func NewCmd(traefikConfiguration *cmd.TraefikConfiguration, traefikPointersConfiguration *cmd.TraefikConfiguration) *flaeg.Command {
|
||||||
|
|
||||||
//version Command init
|
// version Command init
|
||||||
return &flaeg.Command{
|
return &flaeg.Command{
|
||||||
Name: "bug",
|
Name: "bug",
|
||||||
Description: `Report an issue on Traefik bugtracker`,
|
Description: `Report an issue on Traefik bugtracker`,
|
||||||
|
|
|
@ -288,7 +288,7 @@ func TestWithMiddleware(t *testing.T) {
|
||||||
request := httptest.NewRequest(http.MethodGet, "/test", nil)
|
request := httptest.NewRequest(http.MethodGet, "/test", nil)
|
||||||
internalMuxRouter.ServeHTTP(recorder, request)
|
internalMuxRouter.ServeHTTP(recorder, request)
|
||||||
|
|
||||||
obtained := string(recorder.Body.Bytes())
|
obtained := recorder.Body.String()
|
||||||
|
|
||||||
assert.Equal(t, "before middleware1|before middleware2|router|after middleware2|after middleware1", obtained)
|
assert.Equal(t, "before middleware1|before middleware2|router|after middleware2|after middleware1", obtained)
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ Træfik can be configured with a file.
|
||||||
trustForwardHeader = true
|
trustForwardHeader = true
|
||||||
authResponseHeaders = ["X-Auth-User"]
|
authResponseHeaders = ["X-Auth-User"]
|
||||||
[frontends.frontend1.auth.forward.tls]
|
[frontends.frontend1.auth.forward.tls]
|
||||||
ca = [ "path/to/local.crt"]
|
ca = "path/to/local.crt"
|
||||||
caOptional = true
|
caOptional = true
|
||||||
cert = "path/to/foo.cert"
|
cert = "path/to/foo.cert"
|
||||||
key = "path/to/foo.key"
|
key = "path/to/foo.key"
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
trustForwardHeader = true
|
trustForwardHeader = true
|
||||||
authResponseHeaders = ["X-Auth-User"]
|
authResponseHeaders = ["X-Auth-User"]
|
||||||
[entryPoints.http.auth.forward.tls]
|
[entryPoints.http.auth.forward.tls]
|
||||||
ca = [ "path/to/local.crt"]
|
ca = "path/to/local.crt"
|
||||||
caOptional = true
|
caOptional = true
|
||||||
cert = "path/to/foo.cert"
|
cert = "path/to/foo.cert"
|
||||||
key = "path/to/foo.key"
|
key = "path/to/foo.key"
|
||||||
|
@ -347,7 +347,7 @@ Otherwise, the response from the authentication server is returned.
|
||||||
# Optional
|
# Optional
|
||||||
#
|
#
|
||||||
[entryPoints.http.auth.forward.tls]
|
[entryPoints.http.auth.forward.tls]
|
||||||
ca = [ "path/to/local.crt"]
|
ca = "path/to/local.crt"
|
||||||
caOptional = true
|
caOptional = true
|
||||||
cert = "path/to/foo.cert"
|
cert = "path/to/foo.cert"
|
||||||
key = "path/to/foo.key"
|
key = "path/to/foo.key"
|
||||||
|
|
|
@ -45,7 +45,6 @@ func init() {
|
||||||
// to provide an http.Server.
|
// to provide an http.Server.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
*http.Server
|
*http.Server
|
||||||
originalHandler http.Handler
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serve Put a middleware around the original handler to handle h2c
|
// Serve Put a middleware around the original handler to handle h2c
|
||||||
|
@ -101,6 +100,9 @@ func initH2CWithPriorKnowledge(w http.ResponseWriter) (net.Conn, error) {
|
||||||
|
|
||||||
buf := make([]byte, len(expectedBody))
|
buf := make([]byte, len(expectedBody))
|
||||||
n, err := io.ReadFull(rw, buf)
|
n, err := io.ReadFull(rw, buf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("fail to read body: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
if bytes.Equal(buf[0:n], []byte(expectedBody)) {
|
if bytes.Equal(buf[0:n], []byte(expectedBody)) {
|
||||||
c := &rwConn{
|
c := &rwConn{
|
||||||
|
@ -132,7 +134,7 @@ func drainClientPreface(r io.Reader) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if n != prefaceLen || buf.String() != http2.ClientPreface {
|
if n != prefaceLen || buf.String() != http2.ClientPreface {
|
||||||
return fmt.Errorf("Client never sent: %s", http2.ClientPreface)
|
return fmt.Errorf("client never sent: %s", http2.ClientPreface)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -363,7 +365,7 @@ func getH2Settings(h http.Header) ([]http2.Setting, error) {
|
||||||
}
|
}
|
||||||
settings, err := decodeSettings(vals[0])
|
settings, err := decodeSettings(vals[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Invalid HTTP2-Settings: %q", vals[0])
|
return nil, fmt.Errorf("invalid HTTP2-Settings: %q", vals[0])
|
||||||
}
|
}
|
||||||
return settings, nil
|
return settings, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ func (s *SimpleSuite) TestInvalidConfigShouldFail(c *check.C) {
|
||||||
actual := output.String()
|
actual := output.String()
|
||||||
|
|
||||||
if !strings.Contains(actual, expected) {
|
if !strings.Contains(actual, expected) {
|
||||||
return fmt.Errorf("Got %s, wanted %s", actual, expected)
|
return fmt.Errorf("got %s, wanted %s", actual, expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -72,7 +72,7 @@ func (s *SimpleSuite) TestDefaultEntryPoints(c *check.C) {
|
||||||
actual := output.String()
|
actual := output.String()
|
||||||
|
|
||||||
if !strings.Contains(actual, expected) {
|
if !strings.Contains(actual, expected) {
|
||||||
return fmt.Errorf("Got %s, wanted %s", actual, expected)
|
return fmt.Errorf("got %s, wanted %s", actual, expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -93,10 +93,10 @@ func (s *SimpleSuite) TestPrintHelp(c *check.C) {
|
||||||
actual := output.String()
|
actual := output.String()
|
||||||
|
|
||||||
if strings.Contains(actual, notExpected) {
|
if strings.Contains(actual, notExpected) {
|
||||||
return fmt.Errorf("Got %s", actual)
|
return fmt.Errorf("got %s", actual)
|
||||||
}
|
}
|
||||||
if !strings.Contains(actual, expected) {
|
if !strings.Contains(actual, expected) {
|
||||||
return fmt.Errorf("Got %s, wanted %s", actual, expected)
|
return fmt.Errorf("got %s, wanted %s", actual, expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -501,7 +501,7 @@ func (s *ConsulCatalogSuite) TestRefreshConfigPortChange(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ConsulCatalogSuite) TestRetryWithConsulServer(c *check.C) {
|
func (s *ConsulCatalogSuite) TestRetryWithConsulServer(c *check.C) {
|
||||||
//Scale consul to 0 to be able to start traefik before and test retry
|
// Scale consul to 0 to be able to start traefik before and test retry
|
||||||
s.composeProject.Scale(c, "consul", 0)
|
s.composeProject.Scale(c, "consul", 0)
|
||||||
|
|
||||||
cmd, display := s.traefikCmd(
|
cmd, display := s.traefikCmd(
|
||||||
|
@ -547,7 +547,7 @@ func (s *ConsulCatalogSuite) TestRetryWithConsulServer(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ConsulCatalogSuite) TestServiceWithMultipleHealthCheck(c *check.C) {
|
func (s *ConsulCatalogSuite) TestServiceWithMultipleHealthCheck(c *check.C) {
|
||||||
//Scale consul to 0 to be able to start traefik before and test retry
|
// Scale consul to 0 to be able to start traefik before and test retry
|
||||||
s.composeProject.Scale(c, "consul", 0)
|
s.composeProject.Scale(c, "consul", 0)
|
||||||
|
|
||||||
cmd, display := s.traefikCmd(
|
cmd, display := s.traefikCmd(
|
||||||
|
|
|
@ -282,7 +282,7 @@ func (s *ConsulSuite) TestGlobalConfiguration(c *check.C) {
|
||||||
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 60*time.Second, try.BodyContains("Path:/test"))
|
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 60*time.Second, try.BodyContains("Path:/test"))
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
//check
|
// check
|
||||||
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8001/", nil)
|
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8001/", nil)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
req.Host = "test.localhost"
|
req.Host = "test.localhost"
|
||||||
|
@ -469,7 +469,7 @@ func datastoreContains(datastore *cluster.Datastore, expectedValue string) func(
|
||||||
return func() error {
|
return func() error {
|
||||||
kvStruct := datastore.Get().(*TestStruct)
|
kvStruct := datastore.Get().(*TestStruct)
|
||||||
if kvStruct.String != expectedValue {
|
if kvStruct.String != expectedValue {
|
||||||
return fmt.Errorf("Got %s, wanted %s", kvStruct.String, expectedValue)
|
return fmt.Errorf("got %s, wanted %s", kvStruct.String, expectedValue)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ func (s *DockerComposeSuite) TestComposeScale(c *check.C) {
|
||||||
|
|
||||||
s.composeProject.Scale(c, composeService, serviceCount)
|
s.composeProject.Scale(c, composeService, serviceCount)
|
||||||
|
|
||||||
file := s.adaptFileForHost(c, "fixtures/docker/simple.toml")
|
file := s.adaptFileForHost(c, "fixtures/docker/minimal.toml")
|
||||||
defer os.Remove(file)
|
defer os.Remove(file)
|
||||||
|
|
||||||
cmd, display := s.traefikCmd(withConfigFile(file))
|
cmd, display := s.traefikCmd(withConfigFile(file))
|
||||||
|
|
|
@ -49,7 +49,7 @@ func (s *ErrorPagesSuite) TestSimpleConfiguration(c *check.C) {
|
||||||
|
|
||||||
func (s *ErrorPagesSuite) TestErrorPage(c *check.C) {
|
func (s *ErrorPagesSuite) TestErrorPage(c *check.C) {
|
||||||
|
|
||||||
//error.toml contains a mis-configuration of the backend host
|
// error.toml contains a mis-configuration of the backend host
|
||||||
file := s.adaptFile(c, "fixtures/error_pages/error.toml", struct {
|
file := s.adaptFile(c, "fixtures/error_pages/error.toml", struct {
|
||||||
Server1 string
|
Server1 string
|
||||||
Server2 string
|
Server2 string
|
||||||
|
|
|
@ -280,7 +280,7 @@ func (s *Etcd3Suite) TestGlobalConfiguration(c *check.C) {
|
||||||
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 60*time.Second, try.BodyContains("Path:/test"))
|
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 60*time.Second, try.BodyContains("Path:/test"))
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
//check
|
// check
|
||||||
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8001/", nil)
|
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8001/", nil)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
req.Host = "test.localhost"
|
req.Host = "test.localhost"
|
||||||
|
@ -298,7 +298,7 @@ func (s *Etcd3Suite) TestCertificatesContentWithSNIConfigHandshake(c *check.C) {
|
||||||
"--etcd.useAPIV3=true")
|
"--etcd.useAPIV3=true")
|
||||||
defer display(c)
|
defer display(c)
|
||||||
|
|
||||||
//Copy the contents of the certificate files into ETCD
|
// Copy the contents of the certificate files into ETCD
|
||||||
snitestComCert, err := ioutil.ReadFile("fixtures/https/snitest.com.cert")
|
snitestComCert, err := ioutil.ReadFile("fixtures/https/snitest.com.cert")
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
snitestComKey, err := ioutil.ReadFile("fixtures/https/snitest.com.key")
|
snitestComKey, err := ioutil.ReadFile("fixtures/https/snitest.com.key")
|
||||||
|
@ -376,7 +376,7 @@ func (s *Etcd3Suite) TestCertificatesContentWithSNIConfigHandshake(c *check.C) {
|
||||||
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 60*time.Second, try.BodyContains("Host:snitest.org"))
|
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 60*time.Second, try.BodyContains("Host:snitest.org"))
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
//check
|
// check
|
||||||
tlsConfig := &tls.Config{
|
tlsConfig := &tls.Config{
|
||||||
InsecureSkipVerify: true,
|
InsecureSkipVerify: true,
|
||||||
ServerName: "snitest.com",
|
ServerName: "snitest.com",
|
||||||
|
@ -406,7 +406,7 @@ func (s *Etcd3Suite) TestCommandStoreConfig(c *check.C) {
|
||||||
// wait for traefik finish without error
|
// wait for traefik finish without error
|
||||||
cmd.Wait()
|
cmd.Wait()
|
||||||
|
|
||||||
//CHECK
|
// CHECK
|
||||||
checkmap := map[string]string{
|
checkmap := map[string]string{
|
||||||
"/traefik/loglevel": "DEBUG",
|
"/traefik/loglevel": "DEBUG",
|
||||||
"/traefik/defaultentrypoints/0": "http",
|
"/traefik/defaultentrypoints/0": "http",
|
||||||
|
|
14
integration/fixtures/docker/minimal.toml
Normal file
14
integration/fixtures/docker/minimal.toml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
defaultEntryPoints = ["http"]
|
||||||
|
|
||||||
|
logLevel = "DEBUG"
|
||||||
|
|
||||||
|
[entryPoints]
|
||||||
|
[entryPoints.http]
|
||||||
|
address = ":8000"
|
||||||
|
|
||||||
|
[api]
|
||||||
|
|
||||||
|
[docker]
|
||||||
|
endpoint = "{{.DockerHost}}"
|
||||||
|
domain = "docker.localhost"
|
||||||
|
exposedByDefault = false
|
|
@ -9,9 +9,6 @@ logLevel = "DEBUG"
|
||||||
[api]
|
[api]
|
||||||
|
|
||||||
[docker]
|
[docker]
|
||||||
|
|
||||||
# It's dynamagic !
|
|
||||||
endpoint = "{{.DockerHost}}"
|
endpoint = "{{.DockerHost}}"
|
||||||
|
|
||||||
domain = "docker.localhost"
|
domain = "docker.localhost"
|
||||||
exposedByDefault = true
|
exposedByDefault = true
|
||||||
|
|
|
@ -194,7 +194,7 @@ func (s *HealthCheckSuite) TestPortOverload(c *check.C) {
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
frontendHealthReq.Host = "test.localhost"
|
frontendHealthReq.Host = "test.localhost"
|
||||||
|
|
||||||
//We test bad gateway because we use an invalid port for the backend
|
// We test bad gateway because we use an invalid port for the backend
|
||||||
err = try.Request(frontendHealthReq, 500*time.Millisecond, try.StatusCodeIs(http.StatusBadGateway))
|
err = try.Request(frontendHealthReq, 500*time.Millisecond, try.StatusCodeIs(http.StatusBadGateway))
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ func (s *LogRotationSuite) TestTraefikLogRotation(c *check.C) {
|
||||||
// If more log entries are output on startup
|
// If more log entries are output on startup
|
||||||
c.Assert(lineCount, checker.GreaterOrEqualThan, 5)
|
c.Assert(lineCount, checker.GreaterOrEqualThan, 5)
|
||||||
|
|
||||||
//Verify traefik.log output as expected
|
// Verify traefik.log output as expected
|
||||||
lineCount = verifyLogLines(c, traefikTestLogFile, lineCount, false)
|
lineCount = verifyLogLines(c, traefikTestLogFile, lineCount, false)
|
||||||
c.Assert(lineCount, checker.GreaterOrEqualThan, 7)
|
c.Assert(lineCount, checker.GreaterOrEqualThan, 7)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/containous/traefik/integration/try"
|
"github.com/containous/traefik/integration/try"
|
||||||
"github.com/containous/traefik/provider/label"
|
"github.com/containous/traefik/provider/label"
|
||||||
marathon "github.com/gambol99/go-marathon"
|
"github.com/gambol99/go-marathon"
|
||||||
"github.com/go-check/check"
|
"github.com/go-check/check"
|
||||||
checker "github.com/vdemeester/shakers"
|
checker "github.com/vdemeester/shakers"
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,3 +2,4 @@ whoami1:
|
||||||
image: emilevauge/whoami
|
image: emilevauge/whoami
|
||||||
labels:
|
labels:
|
||||||
- traefik.frontend.rule=PathPrefix:/whoami
|
- traefik.frontend.rule=PathPrefix:/whoami
|
||||||
|
- traefik.enable=true
|
|
@ -82,7 +82,7 @@ func HasBody() ResponseCondition {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(body) == 0 {
|
if len(body) == 0 {
|
||||||
return errors.New("Response doesn't have body content")
|
return errors.New("response doesn't have body content")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,7 +279,7 @@ func (s *WebsocketSuite) TestSSLTermination(c *check.C) {
|
||||||
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 10*time.Second, try.BodyContains("127.0.0.1"))
|
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 10*time.Second, try.BodyContains("127.0.0.1"))
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
//Add client self-signed cert
|
// Add client self-signed cert
|
||||||
roots := x509.NewCertPool()
|
roots := x509.NewCertPool()
|
||||||
certContent, err := ioutil.ReadFile("./resources/tls/local.cert")
|
certContent, err := ioutil.ReadFile("./resources/tls/local.cert")
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
@ -487,7 +487,7 @@ func (s *WebsocketSuite) TestSSLhttp2(c *check.C) {
|
||||||
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 10*time.Second, try.BodyContains("127.0.0.1"))
|
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 10*time.Second, try.BodyContains("127.0.0.1"))
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
//Add client self-signed cert
|
// Add client self-signed cert
|
||||||
roots := x509.NewCertPool()
|
roots := x509.NewCertPool()
|
||||||
certContent, err := ioutil.ReadFile("./resources/tls/local.cert")
|
certContent, err := ioutil.ReadFile("./resources/tls/local.cert")
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
|
@ -154,17 +154,16 @@ func (w *influxDBWriter) Write(bp influxdb.BatchPoints) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *influxDBWriter) initWriteClient() (c influxdb.Client, err error) {
|
func (w *influxDBWriter) initWriteClient() (influxdb.Client, error) {
|
||||||
if w.config.Protocol == "http" {
|
if w.config.Protocol == "http" {
|
||||||
c, err = influxdb.NewHTTPClient(influxdb.HTTPConfig{
|
return influxdb.NewHTTPClient(influxdb.HTTPConfig{
|
||||||
Addr: w.config.Address,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
c, err = influxdb.NewUDPClient(influxdb.UDPConfig{
|
|
||||||
Addr: w.config.Address,
|
Addr: w.config.Address,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return
|
|
||||||
|
return influxdb.NewUDPClient(influxdb.UDPConfig{
|
||||||
|
Addr: w.config.Address,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *influxDBWriter) handleWriteError(c influxdb.Client, writeErr error) error {
|
func (w *influxDBWriter) handleWriteError(c influxdb.Client, writeErr error) error {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
type Registry interface {
|
type Registry interface {
|
||||||
// IsEnabled shows whether metrics instrumentation is enabled.
|
// IsEnabled shows whether metrics instrumentation is enabled.
|
||||||
IsEnabled() bool
|
IsEnabled() bool
|
||||||
|
|
||||||
// server metrics
|
// server metrics
|
||||||
ConfigReloadsCounter() metrics.Counter
|
ConfigReloadsCounter() metrics.Counter
|
||||||
ConfigReloadsFailureCounter() metrics.Counter
|
ConfigReloadsFailureCounter() metrics.Counter
|
||||||
|
@ -38,18 +39,18 @@ func NewVoidRegistry() Registry {
|
||||||
// It handles the case when a registry hasn't registered some metric and returns nil.
|
// It handles the case when a registry hasn't registered some metric and returns nil.
|
||||||
// This allows for feature imparity between the different metric implementations.
|
// This allows for feature imparity between the different metric implementations.
|
||||||
func NewMultiRegistry(registries []Registry) Registry {
|
func NewMultiRegistry(registries []Registry) Registry {
|
||||||
configReloadsCounter := []metrics.Counter{}
|
var configReloadsCounter []metrics.Counter
|
||||||
configReloadsFailureCounter := []metrics.Counter{}
|
var configReloadsFailureCounter []metrics.Counter
|
||||||
lastConfigReloadSuccessGauge := []metrics.Gauge{}
|
var lastConfigReloadSuccessGauge []metrics.Gauge
|
||||||
lastConfigReloadFailureGauge := []metrics.Gauge{}
|
var lastConfigReloadFailureGauge []metrics.Gauge
|
||||||
entrypointReqsCounter := []metrics.Counter{}
|
var entrypointReqsCounter []metrics.Counter
|
||||||
entrypointReqDurationHistogram := []metrics.Histogram{}
|
var entrypointReqDurationHistogram []metrics.Histogram
|
||||||
entrypointOpenConnsGauge := []metrics.Gauge{}
|
var entrypointOpenConnsGauge []metrics.Gauge
|
||||||
backendReqsCounter := []metrics.Counter{}
|
var backendReqsCounter []metrics.Counter
|
||||||
backendReqDurationHistogram := []metrics.Histogram{}
|
var backendReqDurationHistogram []metrics.Histogram
|
||||||
backendOpenConnsGauge := []metrics.Gauge{}
|
var backendOpenConnsGauge []metrics.Gauge
|
||||||
backendRetriesCounter := []metrics.Counter{}
|
var backendRetriesCounter []metrics.Counter
|
||||||
backendServerUpGauge := []metrics.Gauge{}
|
var backendServerUpGauge []metrics.Gauge
|
||||||
|
|
||||||
for _, r := range registries {
|
for _, r := range registries {
|
||||||
if r.ConfigReloadsCounter() != nil {
|
if r.ConfigReloadsCounter() != nil {
|
||||||
|
|
|
@ -49,7 +49,7 @@ func (crw *captureResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error)
|
||||||
if h, ok := crw.rw.(http.Hijacker); ok {
|
if h, ok := crw.rw.(http.Hijacker); ok {
|
||||||
return h.Hijack()
|
return h.Hijack()
|
||||||
}
|
}
|
||||||
return nil, nil, fmt.Errorf("Not a hijacker: %T", crw.rw)
|
return nil, nil, fmt.Errorf("not a hijacker: %T", crw.rw)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (crw *captureResponseWriter) CloseNotify() <-chan bool {
|
func (crw *captureResponseWriter) CloseNotify() <-chan bool {
|
||||||
|
|
|
@ -72,7 +72,7 @@ func TestBasicAuthFail(t *testing.T) {
|
||||||
Users: []string{"test"},
|
Users: []string{"test"},
|
||||||
},
|
},
|
||||||
}, &tracing.Tracing{})
|
}, &tracing.Tracing{})
|
||||||
assert.Contains(t, err.Error(), "Error parsing Authenticator user", "should contains")
|
assert.Contains(t, err.Error(), "error parsing Authenticator user", "should contains")
|
||||||
|
|
||||||
authMiddleware, err := NewAuthenticator(&types.Auth{
|
authMiddleware, err := NewAuthenticator(&types.Auth{
|
||||||
Basic: &types.Basic{
|
Basic: &types.Basic{
|
||||||
|
@ -131,7 +131,7 @@ func TestDigestAuthFail(t *testing.T) {
|
||||||
Users: []string{"test"},
|
Users: []string{"test"},
|
||||||
},
|
},
|
||||||
}, &tracing.Tracing{})
|
}, &tracing.Tracing{})
|
||||||
assert.Contains(t, err.Error(), "Error parsing Authenticator user", "should contains")
|
assert.Contains(t, err.Error(), "error parsing Authenticator user", "should contains")
|
||||||
|
|
||||||
authMiddleware, err := NewAuthenticator(&types.Auth{
|
authMiddleware, err := NewAuthenticator(&types.Auth{
|
||||||
Digest: &types.Digest{
|
Digest: &types.Digest{
|
||||||
|
|
|
@ -20,7 +20,7 @@ func parserBasicUsers(basic *types.Basic) (map[string]string, error) {
|
||||||
for _, user := range userStrs {
|
for _, user := range userStrs {
|
||||||
split := strings.Split(user, ":")
|
split := strings.Split(user, ":")
|
||||||
if len(split) != 2 {
|
if len(split) != 2 {
|
||||||
return nil, fmt.Errorf("Error parsing Authenticator user: %v", user)
|
return nil, fmt.Errorf("error parsing Authenticator user: %v", user)
|
||||||
}
|
}
|
||||||
userMap[split[0]] = split[1]
|
userMap[split[0]] = split[1]
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ func parserDigestUsers(digest *types.Digest) (map[string]string, error) {
|
||||||
for _, user := range userStrs {
|
for _, user := range userStrs {
|
||||||
split := strings.Split(user, ":")
|
split := strings.Split(user, ":")
|
||||||
if len(split) != 3 {
|
if len(split) != 3 {
|
||||||
return nil, fmt.Errorf("Error parsing Authenticator user: %v", user)
|
return nil, fmt.Errorf("error parsing Authenticator user: %v", user)
|
||||||
}
|
}
|
||||||
userMap[split[0]+":"+split[1]] = split[2]
|
userMap[split[0]+":"+split[1]] = split[2]
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
// Compress is a middleware that allows redirection
|
// Compress is a middleware that allows redirection
|
||||||
type Compress struct{}
|
type Compress struct{}
|
||||||
|
|
||||||
// ServerHTTP is a function used by Negroni
|
// ServeHTTP is a function used by Negroni
|
||||||
func (c *Compress) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
|
func (c *Compress) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
|
||||||
contentType := r.Header.Get("Content-Type")
|
contentType := r.Header.Get("Content-Type")
|
||||||
if strings.HasPrefix(contentType, "application/grpc") {
|
if strings.HasPrefix(contentType, "application/grpc") {
|
||||||
|
|
|
@ -21,8 +21,8 @@ func NewRoutes(router *mux.Router) *Routes {
|
||||||
func (router *Routes) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
|
func (router *Routes) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
|
||||||
routeMatch := mux.RouteMatch{}
|
routeMatch := mux.RouteMatch{}
|
||||||
if router.router.Match(r, &routeMatch) {
|
if router.router.Match(r, &routeMatch) {
|
||||||
json, _ := json.Marshal(routeMatch.Handler)
|
rt, _ := json.Marshal(routeMatch.Handler)
|
||||||
log.Println("Request match route ", json)
|
log.Println("Request match route ", rt)
|
||||||
}
|
}
|
||||||
next(rw, r)
|
next(rw, r)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/containous/traefik/log"
|
"github.com/containous/traefik/log"
|
||||||
opentracing "github.com/opentracing/opentracing-go"
|
"github.com/opentracing/opentracing-go"
|
||||||
zipkin "github.com/openzipkin/zipkin-go-opentracing"
|
zipkin "github.com/openzipkin/zipkin-go-opentracing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -4,5 +4,5 @@ package docker
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// DockerAPIVersion is a constant holding the version of the Provider API traefik will use
|
// DockerAPIVersion is a constant holding the version of the Provider API traefik will use
|
||||||
DockerAPIVersion string = "1.21"
|
DockerAPIVersion = "1.21"
|
||||||
)
|
)
|
||||||
|
|
|
@ -496,87 +496,6 @@ func TestFilterInstance(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChunkedTaskArns(t *testing.T) {
|
|
||||||
testVal := "a"
|
|
||||||
testCases := []struct {
|
|
||||||
desc string
|
|
||||||
count int
|
|
||||||
expectedLengths []int
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
desc: "0 parameter should return nil",
|
|
||||||
count: 0,
|
|
||||||
expectedLengths: []int(nil),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "1 parameter should return 1 array of 1 element",
|
|
||||||
count: 1,
|
|
||||||
expectedLengths: []int{1},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "99 parameters should return 1 array of 99 elements",
|
|
||||||
count: 99,
|
|
||||||
expectedLengths: []int{99},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "100 parameters should return 1 array of 100 elements",
|
|
||||||
count: 100,
|
|
||||||
expectedLengths: []int{100},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "101 parameters should return 1 array of 100 elements and 1 array of 1 element",
|
|
||||||
count: 101,
|
|
||||||
expectedLengths: []int{100, 1},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "199 parameters should return 1 array of 100 elements and 1 array of 99 elements",
|
|
||||||
count: 199,
|
|
||||||
expectedLengths: []int{100, 99},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "200 parameters should return 2 arrays of 100 elements each",
|
|
||||||
count: 200,
|
|
||||||
expectedLengths: []int{100, 100},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "201 parameters should return 2 arrays of 100 elements each and 1 array of 1 element",
|
|
||||||
count: 201,
|
|
||||||
expectedLengths: []int{100, 100, 1},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "555 parameters should return 5 arrays of 100 elements each and 1 array of 55 elements",
|
|
||||||
count: 555,
|
|
||||||
expectedLengths: []int{100, 100, 100, 100, 100, 55},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "1001 parameters should return 10 arrays of 100 elements each and 1 array of 1 element",
|
|
||||||
count: 1001,
|
|
||||||
expectedLengths: []int{100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 1},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range testCases {
|
|
||||||
test := test
|
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
var tasks []*string
|
|
||||||
for v := 0; v < test.count; v++ {
|
|
||||||
tasks = append(tasks, &testVal)
|
|
||||||
}
|
|
||||||
|
|
||||||
out := chunkedTaskArns(tasks)
|
|
||||||
var outCount []int
|
|
||||||
|
|
||||||
for _, el := range out {
|
|
||||||
outCount = append(outCount, len(el))
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Equal(t, test.expectedLengths, outCount, "Chunking %d elements", test.count)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetHost(t *testing.T) {
|
func TestGetHost(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
|
|
|
@ -227,7 +227,7 @@ func (p *Provider) listInstances(ctx context.Context, client *awsClient) ([]ecsI
|
||||||
Cluster: &c,
|
Cluster: &c,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Unable to describe tasks for %s", page.TaskArns)
|
log.Errorf("Unable to describe tasks for %v", page.TaskArns)
|
||||||
} else {
|
} else {
|
||||||
for _, t := range resp.Tasks {
|
for _, t := range resp.Tasks {
|
||||||
tasks[aws.StringValue(t.TaskArn)] = t
|
tasks[aws.StringValue(t.TaskArn)] = t
|
||||||
|
@ -396,19 +396,3 @@ func (p *Provider) loadECSConfig(ctx context.Context, client *awsClient) (*types
|
||||||
|
|
||||||
return p.buildConfiguration(instances)
|
return p.buildConfiguration(instances)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Provider expects no more than 100 parameters be passed to a DescribeTask call; thus, pack
|
|
||||||
// each string into an array capped at 100 elements
|
|
||||||
func chunkedTaskArns(tasks []*string) [][]*string {
|
|
||||||
var chunkedTasks [][]*string
|
|
||||||
for i := 0; i < len(tasks); i += 100 {
|
|
||||||
var sliceEnd int
|
|
||||||
if i+100 < len(tasks) {
|
|
||||||
sliceEnd = i + 100
|
|
||||||
} else {
|
|
||||||
sliceEnd = len(tasks)
|
|
||||||
}
|
|
||||||
chunkedTasks = append(chunkedTasks, tasks[i:sliceEnd])
|
|
||||||
}
|
|
||||||
return chunkedTasks
|
|
||||||
}
|
|
||||||
|
|
|
@ -2165,7 +2165,7 @@ func TestTLSSecretLoad(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
endpoints := []*corev1.Endpoints{}
|
var endpoints []*corev1.Endpoints
|
||||||
watchChan := make(chan interface{})
|
watchChan := make(chan interface{})
|
||||||
client := clientMock{
|
client := clientMock{
|
||||||
ingresses: ingresses,
|
ingresses: ingresses,
|
||||||
|
|
|
@ -8,8 +8,8 @@ import (
|
||||||
// Namespaces holds kubernetes namespaces
|
// Namespaces holds kubernetes namespaces
|
||||||
type Namespaces []string
|
type Namespaces []string
|
||||||
|
|
||||||
//Set adds strings elem into the the parser
|
// Set adds strings elem into the the parser
|
||||||
//it splits str on , and ;
|
// it splits str on , and ;
|
||||||
func (ns *Namespaces) Set(str string) error {
|
func (ns *Namespaces) Set(str string) error {
|
||||||
fargs := func(c rune) bool {
|
fargs := func(c rune) bool {
|
||||||
return c == ',' || c == ';'
|
return c == ',' || c == ';'
|
||||||
|
@ -20,13 +20,13 @@ func (ns *Namespaces) Set(str string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get []string
|
// Get []string
|
||||||
func (ns *Namespaces) Get() interface{} { return *ns }
|
func (ns *Namespaces) Get() interface{} { return *ns }
|
||||||
|
|
||||||
//String return slice in a string
|
// String return slice in a string
|
||||||
func (ns *Namespaces) String() string { return fmt.Sprintf("%v", *ns) }
|
func (ns *Namespaces) String() string { return fmt.Sprintf("%v", *ns) }
|
||||||
|
|
||||||
//SetValue sets []string into the parser
|
// SetValue sets []string into the parser
|
||||||
func (ns *Namespaces) SetValue(val interface{}) {
|
func (ns *Namespaces) SetValue(val interface{}) {
|
||||||
*ns = val.(Namespaces)
|
*ns = val.(Namespaces)
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,15 +30,9 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// RegexpBaseFrontendErrorPage used to extract error pages from service's label
|
|
||||||
RegexpBaseFrontendErrorPage = regexp.MustCompile(`^frontend\.errors\.(?P<name>[^ .]+)\.(?P<field>[^ .]+)$`)
|
|
||||||
|
|
||||||
// RegexpFrontendErrorPage used to extract error pages from label
|
// RegexpFrontendErrorPage used to extract error pages from label
|
||||||
RegexpFrontendErrorPage = regexp.MustCompile(`^traefik\.frontend\.errors\.(?P<name>[^ .]+)\.(?P<field>[^ .]+)$`)
|
RegexpFrontendErrorPage = regexp.MustCompile(`^traefik\.frontend\.errors\.(?P<name>[^ .]+)\.(?P<field>[^ .]+)$`)
|
||||||
|
|
||||||
// RegexpBaseFrontendRateLimit used to extract rate limits from service's label
|
|
||||||
RegexpBaseFrontendRateLimit = regexp.MustCompile(`^frontend\.rateLimit\.rateSet\.(?P<name>[^ .]+)\.(?P<field>[^ .]+)$`)
|
|
||||||
|
|
||||||
// RegexpFrontendRateLimit used to extract rate limits from label
|
// RegexpFrontendRateLimit used to extract rate limits from label
|
||||||
RegexpFrontendRateLimit = regexp.MustCompile(`^traefik\.frontend\.rateLimit\.rateSet\.(?P<name>[^ .]+)\.(?P<field>[^ .]+)$`)
|
RegexpFrontendRateLimit = regexp.MustCompile(`^traefik\.frontend\.rateLimit\.rateSet\.(?P<name>[^ .]+)\.(?P<field>[^ .]+)$`)
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containous/traefik/log"
|
"github.com/containous/traefik/log"
|
||||||
marathon "github.com/gambol99/go-marathon"
|
"github.com/gambol99/go-marathon"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -24,7 +24,7 @@ import (
|
||||||
|
|
||||||
var _ provider.Provider = (*Provider)(nil)
|
var _ provider.Provider = (*Provider)(nil)
|
||||||
|
|
||||||
//Provider holds configuration of the provider.
|
// Provider holds configuration of the provider.
|
||||||
type Provider struct {
|
type Provider struct {
|
||||||
provider.BaseProvider
|
provider.BaseProvider
|
||||||
Endpoint string `description:"Mesos server endpoint. You can also specify multiple endpoint for Mesos"`
|
Endpoint string `description:"Mesos server endpoint. You can also specify multiple endpoint for Mesos"`
|
||||||
|
|
|
@ -37,7 +37,7 @@ func TestBuilder(t *testing.T) {
|
||||||
DiscoveryInfo: state.DiscoveryInfo{
|
DiscoveryInfo: state.DiscoveryInfo{
|
||||||
Name: "name1",
|
Name: "name1",
|
||||||
Labels: struct {
|
Labels: struct {
|
||||||
Labels []state.Label "json:\"labels\""
|
Labels []state.Label `json:"labels"`
|
||||||
}{},
|
}{},
|
||||||
Ports: state.Ports{DiscoveryPorts: []state.DiscoveryPort{
|
Ports: state.Ports{DiscoveryPorts: []state.DiscoveryPort{
|
||||||
{Protocol: "TCP", Number: 80, Name: "p"},
|
{Protocol: "TCP", Number: 80, Name: "p"},
|
||||||
|
@ -63,7 +63,7 @@ func aTaskData(id, segment string, ops ...func(*state.Task)) taskData {
|
||||||
}
|
}
|
||||||
|
|
||||||
func segmentedTaskData(segments []string, ts state.Task) []taskData {
|
func segmentedTaskData(segments []string, ts state.Task) []taskData {
|
||||||
td := []taskData{}
|
var td []taskData
|
||||||
lbls := label.ExtractTraefikLabels(extractLabels(ts))
|
lbls := label.ExtractTraefikLabels(extractLabels(ts))
|
||||||
for _, s := range segments {
|
for _, s := range segments {
|
||||||
if l, ok := lbls[s]; !ok {
|
if l, ok := lbls[s]; !ok {
|
||||||
|
|
|
@ -46,14 +46,14 @@ func (p *Pool) Ctx() context.Context {
|
||||||
return p.baseCtx
|
return p.baseCtx
|
||||||
}
|
}
|
||||||
|
|
||||||
//AddGoCtx adds a recoverable goroutine with a context without starting it
|
// AddGoCtx adds a recoverable goroutine with a context without starting it
|
||||||
func (p *Pool) AddGoCtx(goroutine routineCtx) {
|
func (p *Pool) AddGoCtx(goroutine routineCtx) {
|
||||||
p.lock.Lock()
|
p.lock.Lock()
|
||||||
p.routinesCtx = append(p.routinesCtx, goroutine)
|
p.routinesCtx = append(p.routinesCtx, goroutine)
|
||||||
p.lock.Unlock()
|
p.lock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
//GoCtx starts a recoverable goroutine with a context
|
// GoCtx starts a recoverable goroutine with a context
|
||||||
func (p *Pool) GoCtx(goroutine routineCtx) {
|
func (p *Pool) GoCtx(goroutine routineCtx) {
|
||||||
p.lock.Lock()
|
p.lock.Lock()
|
||||||
p.routinesCtx = append(p.routinesCtx, goroutine)
|
p.routinesCtx = append(p.routinesCtx, goroutine)
|
||||||
|
@ -154,7 +154,7 @@ func OperationWithRecover(operation backoff.Operation) backoff.Operation {
|
||||||
defer func() {
|
defer func() {
|
||||||
if res := recover(); res != nil {
|
if res := recover(); res != nil {
|
||||||
defaultRecoverGoroutine(res)
|
defaultRecoverGoroutine(res)
|
||||||
err = fmt.Errorf("Panic in operation: %s", err)
|
err = fmt.Errorf("panic in operation: %s", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
return operation()
|
return operation()
|
||||||
|
|
Loading…
Reference in a new issue