github.com/Cloud-Foundations/Dominator@v0.3.4/lib/filegen/template.go (about) 1 package filegen 2 3 import ( 4 "bytes" 5 "errors" 6 "io" 7 "io/ioutil" 8 "os" 9 "text/template" 10 "time" 11 12 "github.com/Cloud-Foundations/Dominator/lib/fsutil" 13 "github.com/Cloud-Foundations/Dominator/lib/hash" 14 "github.com/Cloud-Foundations/Dominator/lib/log" 15 "github.com/Cloud-Foundations/Dominator/lib/mdb" 16 "github.com/Cloud-Foundations/Dominator/lib/objectserver/memory" 17 ) 18 19 type templateGenerator struct { 20 objectServer *memory.ObjectServer 21 logger log.Logger 22 template *template.Template 23 notifierChannel chan<- string 24 } 25 26 func (m *Manager) registerTemplateFileForPath(pathname string, 27 templateFile string, watchForUpdates bool) error { 28 tgen := &templateGenerator{ 29 objectServer: m.objectServer, 30 logger: m.logger} 31 tgen.notifierChannel = m.registerHashGeneratorForPath(pathname, tgen) 32 if watchForUpdates { 33 readCloserChannel := fsutil.WatchFile(templateFile, m.logger) 34 go tgen.handleReadClosers(readCloserChannel) 35 } else { 36 file, err := os.Open(templateFile) 37 if err != nil { 38 return err 39 } 40 if err := tgen.handleReadCloser(file); err != nil { 41 return err 42 } 43 } 44 return nil 45 } 46 47 func (tgen *templateGenerator) generate(machine mdb.Machine, 48 logger log.Logger) ( 49 hash.Hash, uint64, time.Time, error) { 50 if tgen.template == nil { 51 return hash.Hash{}, 0, time.Time{}, errors.New("no template data yet") 52 } 53 buffer := new(bytes.Buffer) 54 if err := tgen.template.Execute(buffer, machine); err != nil { 55 return hash.Hash{}, 0, time.Time{}, err 56 } 57 length := uint64(buffer.Len()) 58 hashVal, _, err := tgen.objectServer.AddObject(buffer, length, nil) 59 return hashVal, length, time.Time{}, err 60 } 61 62 func (tgen *templateGenerator) handleReadClosers( 63 readCloserChannel <-chan io.ReadCloser) { 64 for readCloser := range readCloserChannel { 65 if err := tgen.handleReadCloser(readCloser); err != nil { 66 tgen.logger.Println(err) 67 } 68 } 69 } 70 71 func (tgen *templateGenerator) handleReadCloser( 72 readCloser io.ReadCloser) error { 73 data, err := ioutil.ReadAll(readCloser) 74 readCloser.Close() 75 if err != nil { 76 return err 77 } 78 tmpl, err := template.New("generatorTemplate").Parse(string(data)) 79 if err != nil { 80 return err 81 } 82 tgen.template = tmpl 83 tgen.notifierChannel <- "" 84 return nil 85 }