2015-11-01 16:35:01 +01:00
package provider
2015-09-07 15:25:13 +02:00
import (
2015-09-07 17:39:22 +02:00
"os"
"path/filepath"
"strings"
2015-09-24 17:16:13 +02:00
"github.com/BurntSushi/toml"
log "github.com/Sirupsen/logrus"
2015-11-01 16:35:01 +01:00
"github.com/emilevauge/traefik/types"
2015-09-24 17:16:13 +02:00
"gopkg.in/fsnotify.v1"
2015-09-07 15:25:13 +02:00
)
2015-11-01 19:29:47 +01:00
// File holds configurations of the File provider.
2015-11-02 19:48:34 +01:00
type File struct {
2016-01-13 22:46:44 +01:00
BaseProvider ` mapstructure:",squash" `
2015-09-07 15:25:13 +02:00
}
2015-11-01 19:29:47 +01:00
// Provide allows the provider to provide configurations to traefik
// using the given configuration channel.
2015-11-02 19:48:34 +01:00
func ( provider * File ) Provide ( configurationChan chan <- types . ConfigMessage ) error {
2015-09-07 15:25:13 +02:00
watcher , err := fsnotify . NewWatcher ( )
if err != nil {
2015-09-11 16:37:13 +02:00
log . Error ( "Error creating file watcher" , err )
2015-10-01 12:04:25 +02:00
return err
2015-09-07 15:25:13 +02:00
}
2015-09-07 17:39:22 +02:00
file , err := os . Open ( provider . Filename )
2015-09-07 15:25:13 +02:00
if err != nil {
2015-09-11 16:37:13 +02:00
log . Error ( "Error opening file" , err )
2015-10-01 12:04:25 +02:00
return err
2015-09-07 15:25:13 +02:00
}
2015-09-07 17:39:22 +02:00
defer file . Close ( )
2015-09-07 15:25:13 +02:00
2015-10-03 16:50:53 +02:00
if provider . Watch {
// Process events
go func ( ) {
defer watcher . Close ( )
for {
select {
case event := <- watcher . Events :
if strings . Contains ( event . Name , file . Name ( ) ) {
log . Debug ( "File event:" , event )
2015-11-01 19:29:47 +01:00
configuration := provider . loadFileConfig ( file . Name ( ) )
2015-10-03 16:50:53 +02:00
if configuration != nil {
2015-11-13 11:50:32 +01:00
configurationChan <- types . ConfigMessage {
ProviderName : "file" ,
Configuration : configuration ,
}
2015-10-03 16:50:53 +02:00
}
2015-09-07 23:25:07 +02:00
}
2015-10-03 16:50:53 +02:00
case error := <- watcher . Errors :
log . Error ( "Watcher event error" , error )
2015-09-07 17:39:22 +02:00
}
2015-09-07 15:25:13 +02:00
}
2015-10-03 16:50:53 +02:00
} ( )
2015-09-07 18:10:33 +02:00
err = watcher . Add ( filepath . Dir ( file . Name ( ) ) )
2015-10-03 16:50:53 +02:00
if err != nil {
log . Error ( "Error adding file watcher" , err )
return err
}
2015-09-07 17:39:22 +02:00
}
2015-09-07 15:25:13 +02:00
2015-11-01 19:29:47 +01:00
configuration := provider . loadFileConfig ( file . Name ( ) )
2015-11-13 11:50:32 +01:00
configurationChan <- types . ConfigMessage {
ProviderName : "file" ,
Configuration : configuration ,
}
2015-10-01 12:04:25 +02:00
return nil
2015-09-07 15:25:13 +02:00
}
2015-11-01 19:29:47 +01:00
func ( provider * File ) loadFileConfig ( filename string ) * types . Configuration {
2015-11-01 16:35:01 +01:00
configuration := new ( types . Configuration )
2015-09-08 00:15:14 +02:00
if _ , err := toml . DecodeFile ( filename , configuration ) ; err != nil {
2015-09-11 16:37:13 +02:00
log . Error ( "Error reading file:" , err )
2015-09-07 15:25:13 +02:00
return nil
}
2015-09-08 00:15:14 +02:00
return configuration
2015-09-12 15:10:03 +02:00
}