123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- package file
- import (
- "fmt"
- "io/ioutil"
- "strings"
- "time"
- "github.com/docker/docker/pkg/discovery"
- )
- // Discovery is exported
- type Discovery struct {
- heartbeat time.Duration
- path string
- }
- func init() {
- Init()
- }
- // Init is exported
- func Init() {
- discovery.Register("file", &Discovery{})
- }
- // Initialize is exported
- func (s *Discovery) Initialize(path string, heartbeat time.Duration, ttl time.Duration, _ map[string]string) error {
- s.path = path
- s.heartbeat = heartbeat
- return nil
- }
- func parseFileContent(content []byte) []string {
- var result []string
- for _, line := range strings.Split(strings.TrimSpace(string(content)), "\n") {
- line = strings.TrimSpace(line)
- // Ignoring line starts with #
- if strings.HasPrefix(line, "#") {
- continue
- }
- // Inlined # comment also ignored.
- if strings.Contains(line, "#") {
- line = line[0:strings.Index(line, "#")]
- // Trim additional spaces caused by above stripping.
- line = strings.TrimSpace(line)
- }
- result = append(result, discovery.Generate(line)...)
- }
- return result
- }
- func (s *Discovery) fetch() (discovery.Entries, error) {
- fileContent, err := ioutil.ReadFile(s.path)
- if err != nil {
- return nil, fmt.Errorf("failed to read '%s': %v", s.path, err)
- }
- return discovery.CreateEntries(parseFileContent(fileContent))
- }
- // Watch is exported
- func (s *Discovery) Watch(stopCh <-chan struct{}) (<-chan discovery.Entries, <-chan error) {
- ch := make(chan discovery.Entries)
- errCh := make(chan error)
- ticker := time.NewTicker(s.heartbeat)
- go func() {
- defer close(errCh)
- defer close(ch)
- // Send the initial entries if available.
- currentEntries, err := s.fetch()
- if err != nil {
- errCh <- err
- } else {
- ch <- currentEntries
- }
- // Periodically send updates.
- for {
- select {
- case <-ticker.C:
- newEntries, err := s.fetch()
- if err != nil {
- errCh <- err
- continue
- }
- // Check if the file has really changed.
- if !newEntries.Equals(currentEntries) {
- ch <- newEntries
- }
- currentEntries = newEntries
- case <-stopCh:
- ticker.Stop()
- return
- }
- }
- }()
- return ch, errCh
- }
- // Register is exported
- func (s *Discovery) Register(addr string) error {
- return discovery.ErrNotImplemented
- }
|