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  }