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"
2016-03-31 18:57:08 +02:00
"github.com/containous/traefik/safe"
2016-02-24 16:43:39 +01:00
"github.com/containous/traefik/types"
2015-09-24 17:16:13 +02:00
"gopkg.in/fsnotify.v1"
2015-09-07 15:25:13 +02:00
)
2016-08-16 19:13:18 +02:00
var _ Provider = ( * File ) ( nil )
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-06-24 09:58:42 +02: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.
2016-05-31 09:54:42 +02:00
func ( provider * File ) Provide ( configurationChan chan <- types . ConfigMessage , pool * safe . Pool , _ [ ] types . Constraint ) 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
2016-04-13 20:36:23 +02:00
pool . Go ( func ( stop chan bool ) {
2015-10-03 16:50:53 +02:00
defer watcher . Close ( )
for {
select {
2016-04-13 20:36:23 +02:00
case <- stop :
return
2015-10-03 16:50:53 +02:00
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
}
2016-03-31 18:57:08 +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
}