Fix ACME write when traefik is shutting down
This commit is contained in:
parent
c20af070e3
commit
86315e0f18
3 changed files with 33 additions and 17 deletions
|
@ -188,7 +188,7 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
acmeProviders := initACMEProvider(staticConfiguration, providerAggregator, tlsManager, httpChallengeProvider, tlsChallengeProvider)
|
acmeProviders := initACMEProvider(staticConfiguration, providerAggregator, tlsManager, httpChallengeProvider, tlsChallengeProvider, routinesPool)
|
||||||
|
|
||||||
// Entrypoints
|
// Entrypoints
|
||||||
|
|
||||||
|
@ -366,7 +366,7 @@ func switchRouter(routerFactory *server.RouterFactory, serverEntryPointsTCP serv
|
||||||
}
|
}
|
||||||
|
|
||||||
// initACMEProvider creates an acme provider from the ACME part of globalConfiguration.
|
// initACMEProvider creates an acme provider from the ACME part of globalConfiguration.
|
||||||
func initACMEProvider(c *static.Configuration, providerAggregator *aggregator.ProviderAggregator, tlsManager *traefiktls.Manager, httpChallengeProvider, tlsChallengeProvider challenge.Provider) []*acme.Provider {
|
func initACMEProvider(c *static.Configuration, providerAggregator *aggregator.ProviderAggregator, tlsManager *traefiktls.Manager, httpChallengeProvider, tlsChallengeProvider challenge.Provider, routinesPool *safe.Pool) []*acme.Provider {
|
||||||
localStores := map[string]*acme.LocalStore{}
|
localStores := map[string]*acme.LocalStore{}
|
||||||
|
|
||||||
var resolvers []*acme.Provider
|
var resolvers []*acme.Provider
|
||||||
|
@ -376,7 +376,7 @@ func initACMEProvider(c *static.Configuration, providerAggregator *aggregator.Pr
|
||||||
}
|
}
|
||||||
|
|
||||||
if localStores[resolver.ACME.Storage] == nil {
|
if localStores[resolver.ACME.Storage] == nil {
|
||||||
localStores[resolver.ACME.Storage] = acme.NewLocalStore(resolver.ACME.Storage)
|
localStores[resolver.ACME.Storage] = acme.NewLocalStore(resolver.ACME.Storage, routinesPool)
|
||||||
}
|
}
|
||||||
|
|
||||||
p := &acme.Provider{
|
p := &acme.Provider{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package acme
|
package acme
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -22,9 +23,9 @@ type LocalStore struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLocalStore initializes a new LocalStore with a file name.
|
// NewLocalStore initializes a new LocalStore with a file name.
|
||||||
func NewLocalStore(filename string) *LocalStore {
|
func NewLocalStore(filename string, routinesPool *safe.Pool) *LocalStore {
|
||||||
store := &LocalStore{filename: filename, saveDataChan: make(chan map[string]*StoredData)}
|
store := &LocalStore{filename: filename, saveDataChan: make(chan map[string]*StoredData)}
|
||||||
store.listenSaveAction()
|
store.listenSaveAction(routinesPool)
|
||||||
return store
|
return store
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,18 +100,31 @@ func (s *LocalStore) get(resolverName string) (*StoredData, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// listenSaveAction listens to a chan to store ACME data in json format into `LocalStore.filename`.
|
// listenSaveAction listens to a chan to store ACME data in json format into `LocalStore.filename`.
|
||||||
func (s *LocalStore) listenSaveAction() {
|
func (s *LocalStore) listenSaveAction(routinesPool *safe.Pool) {
|
||||||
safe.Go(func() {
|
routinesPool.GoCtx(func(ctx context.Context) {
|
||||||
logger := log.WithoutContext().WithField(log.ProviderName, "acme")
|
logger := log.WithoutContext().WithField(log.ProviderName, "acme")
|
||||||
for object := range s.saveDataChan {
|
for {
|
||||||
data, err := json.MarshalIndent(object, "", " ")
|
select {
|
||||||
if err != nil {
|
case <-ctx.Done():
|
||||||
logger.Error(err)
|
return
|
||||||
}
|
|
||||||
|
|
||||||
err = os.WriteFile(s.filename, data, 0o600)
|
case object := <-s.saveDataChan:
|
||||||
if err != nil {
|
select {
|
||||||
logger.Error(err)
|
case <-ctx.Done():
|
||||||
|
// Stop handling events because Traefik is shutting down.
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := json.MarshalIndent(object, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(s.filename, data, 0o600)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package acme
|
package acme
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -9,6 +10,7 @@ import (
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/safe"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLocalStore_GetAccount(t *testing.T) {
|
func TestLocalStore_GetAccount(t *testing.T) {
|
||||||
|
@ -45,7 +47,7 @@ func TestLocalStore_GetAccount(t *testing.T) {
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
s := NewLocalStore(test.filename)
|
s := NewLocalStore(test.filename, safe.NewPool(context.Background()))
|
||||||
|
|
||||||
account, err := s.GetAccount("test")
|
account, err := s.GetAccount("test")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -58,7 +60,7 @@ func TestLocalStore_GetAccount(t *testing.T) {
|
||||||
func TestLocalStore_SaveAccount(t *testing.T) {
|
func TestLocalStore_SaveAccount(t *testing.T) {
|
||||||
acmeFile := filepath.Join(t.TempDir(), "acme.json")
|
acmeFile := filepath.Join(t.TempDir(), "acme.json")
|
||||||
|
|
||||||
s := NewLocalStore(acmeFile)
|
s := NewLocalStore(acmeFile, safe.NewPool(context.Background()))
|
||||||
|
|
||||||
email := "some@email.com"
|
email := "some@email.com"
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue