diff --git a/Makefile b/Makefile index 3069ae29..0cddd3de 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ +all: templates.go + go build -all: status.html.go +templates.go: templates/*.html monitor.go + go generate -status.html.go: templates/*.html - go-bindata -o status.html.go.tmp templates/ - @echo "// +build !devel\n" > status.html.go - @cat status.html.go.tmp >> status.html.go - @rm status.html.go.tmp +devel: + go build -tags devel diff --git a/geodns.go b/geodns.go index 9c754838..45f2792a 100644 --- a/geodns.go +++ b/geodns.go @@ -35,6 +35,10 @@ var VERSION string = "2.4.4" var buildTime string var gitVersion string +// Set development with the 'devel' build flag to load +// templates from disk instead of from the binary. +var development bool + var serverID string var serverIP string var serverGroups []string diff --git a/monitor.go b/monitor.go index e84ffc1d..bf14d3b4 100644 --- a/monitor.go +++ b/monitor.go @@ -1,5 +1,7 @@ package main +//go:generate esc -o templates.go templates/ + import ( "encoding/json" "fmt" @@ -281,13 +283,13 @@ func StatusServer(zones Zones) func(http.ResponseWriter, *http.Request) { } } - statusTemplate, err := templates_status_html() + statusTemplate, err := FSString(development, "/templates/status.html") if err != nil { - log.Println("Could not read template", err) + log.Println("Could not read template:", err) w.WriteHeader(500) return } - tmpl, err := template.New("status_html").Parse(string(statusTemplate)) + tmpl, err := template.New("status_html").Parse(statusTemplate) if err != nil { str := fmt.Sprintf("Could not parse template: %s", err) diff --git a/status.html.go b/status.html.go deleted file mode 100644 index 52e39320..00000000 --- a/status.html.go +++ /dev/null @@ -1,128 +0,0 @@ -// +build !devel - -package main - -import ( - "bytes" - "compress/gzip" - "fmt" - "io" - "strings" -) - -func bindata_read(data []byte, name string) ([]byte, error) { - gz, err := gzip.NewReader(bytes.NewBuffer(data)) - if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) - } - - var buf bytes.Buffer - _, err = io.Copy(&buf, gz) - gz.Close() - - if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) - } - - return buf.Bytes(), nil -} - -func templates_status_html() ([]byte, error) { - return bindata_read([]byte{ - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x00, 0xff, 0xb4, 0x57, - 0x4d, 0x53, 0xeb, 0x36, 0x14, 0x5d, 0x27, 0xbf, 0x42, 0xe3, 0x29, 0xbb, - 0x22, 0x13, 0x4a, 0x66, 0x1a, 0xea, 0x78, 0x03, 0x0c, 0x5d, 0x34, 0x14, - 0x9a, 0xb6, 0x8b, 0xb7, 0x53, 0xac, 0x9b, 0xd8, 0xf3, 0x1c, 0x29, 0x4f, - 0x52, 0x08, 0xbc, 0x4c, 0xfe, 0xfb, 0xbb, 0x92, 0x3f, 0x62, 0x3b, 0x26, - 0x04, 0xbf, 0x61, 0x83, 0xe5, 0x23, 0x9d, 0x2b, 0x9d, 0x7b, 0x4f, 0xae, - 0x4c, 0x10, 0x9b, 0x65, 0x1a, 0x06, 0x31, 0x30, 0x1e, 0x06, 0x26, 0x31, - 0x29, 0x84, 0xf7, 0x20, 0x6f, 0x1f, 0xa6, 0x64, 0xbb, 0x25, 0xf4, 0x7f, - 0x50, 0x3a, 0x91, 0x82, 0xec, 0x76, 0x81, 0x9f, 0x4d, 0xf6, 0x83, 0x34, - 0x11, 0x5f, 0x49, 0xac, 0x60, 0x3e, 0xf6, 0x7c, 0x5f, 0x80, 0xe1, 0x82, - 0xd1, 0x99, 0x94, 0x46, 0x1b, 0xc5, 0x56, 0x11, 0x17, 0x34, 0x92, 0x4b, - 0xdf, 0x6c, 0x12, 0x63, 0x40, 0x9d, 0x97, 0x13, 0xfe, 0x25, 0xfd, 0x8d, - 0x0e, 0xfc, 0x48, 0x6b, 0xbf, 0xc4, 0xce, 0x71, 0xe5, 0x2c, 0x11, 0xc0, - 0xe9, 0x32, 0x41, 0x9a, 0xd6, 0x1e, 0x51, 0x90, 0x8e, 0x3d, 0x6d, 0x5e, - 0x53, 0xd0, 0x31, 0x80, 0xf1, 0x4e, 0xdd, 0xcf, 0x01, 0x1b, 0x66, 0xa2, - 0xb8, 0xd8, 0x08, 0xd4, 0x3a, 0x05, 0x26, 0xf6, 0xbb, 0x1d, 0xdd, 0xc4, - 0xbd, 0x85, 0xfd, 0x9e, 0xe1, 0xf4, 0xbb, 0x14, 0x20, 0xd8, 0x12, 0x7e, - 0xc5, 0xb1, 0x4d, 0x0b, 0x28, 0xb2, 0x25, 0x73, 0x29, 0xcc, 0xf9, 0x06, - 0x92, 0x45, 0x6c, 0xae, 0xc9, 0x4c, 0xa6, 0xfc, 0x0f, 0xb2, 0xeb, 0x07, - 0x7e, 0x4e, 0x0b, 0x66, 0x92, 0xbf, 0x86, 0xfd, 0x7e, 0xc0, 0x93, 0x67, - 0x12, 0xa5, 0x4c, 0xeb, 0xb1, 0x17, 0x21, 0x83, 0xa1, 0x38, 0xe5, 0xd9, - 0x89, 0x78, 0x10, 0xde, 0xa7, 0x72, 0xc6, 0xd2, 0xc0, 0xc7, 0x61, 0x7d, - 0xa5, 0x92, 0x1b, 0xbb, 0xa6, 0x57, 0xc5, 0xf4, 0x8a, 0x89, 0xdf, 0x1d, - 0xda, 0x0b, 0x0c, 0x9b, 0xa5, 0x50, 0x4c, 0x64, 0x2f, 0xee, 0x2f, 0x26, - 0x57, 0xe1, 0xe9, 0x80, 0xe7, 0xaf, 0xb8, 0x23, 0x07, 0xa1, 0x81, 0x23, - 0xaf, 0x67, 0x79, 0xca, 0x3d, 0x71, 0xc0, 0x0b, 0x76, 0x22, 0xe6, 0x92, - 0x64, 0xa2, 0xbc, 0xfc, 0x40, 0x44, 0x1b, 0x66, 0x34, 0x96, 0x97, 0x97, - 0xab, 0xc3, 0x01, 0xc1, 0x5c, 0xd5, 0xa1, 0xe1, 0x21, 0x34, 0x68, 0xc1, - 0x26, 0x98, 0xf2, 0x12, 0xc1, 0x81, 0x72, 0x12, 0x6a, 0x67, 0x09, 0x9f, - 0xd6, 0xa0, 0x12, 0x68, 0x6c, 0xb9, 0xdd, 0xae, 0x54, 0x22, 0xcc, 0x9c, - 0x78, 0x67, 0xf4, 0x72, 0xee, 0x11, 0x9a, 0x9d, 0x8e, 0xe6, 0x8b, 0xe9, - 0x3f, 0xcc, 0xc0, 0xc0, 0xd9, 0xf0, 0x83, 0xa4, 0x61, 0x17, 0xd2, 0xa0, - 0x13, 0xcb, 0x8a, 0xaf, 0xf0, 0x32, 0xf9, 0xee, 0x69, 0xeb, 0xf3, 0xb9, - 0xc5, 0xfc, 0x33, 0xd1, 0x46, 0x2e, 0x14, 0x5b, 0x36, 0xf2, 0x3a, 0x39, - 0x5a, 0x21, 0x87, 0x8c, 0x2e, 0xce, 0x1a, 0xc0, 0xe8, 0x00, 0xa0, 0x4d, - 0x68, 0xc2, 0x5e, 0xea, 0xc0, 0xd4, 0xf0, 0x5b, 0x78, 0x7e, 0xaf, 0xf6, - 0xb9, 0xe7, 0xbe, 0xbd, 0x63, 0x01, 0xee, 0x11, 0x52, 0xa6, 0xb8, 0x94, - 0x46, 0x51, 0xcc, 0xa9, 0x75, 0xa9, 0x90, 0xea, 0x55, 0x39, 0x91, 0xf5, - 0x18, 0x99, 0xd1, 0x05, 0xe9, 0xc6, 0x1b, 0x75, 0xe5, 0x1d, 0x25, 0xbe, - 0x95, 0x13, 0xf6, 0xf2, 0xf1, 0xdd, 0xb2, 0x62, 0x91, 0x03, 0xb3, 0xd6, - 0xdd, 0x1a, 0xf8, 0xd8, 0x91, 0xda, 0x3a, 0xd3, 0xd5, 0x4f, 0x75, 0xa6, - 0xc2, 0x10, 0x15, 0x2b, 0x17, 0x2e, 0xfe, 0x6f, 0x65, 0x92, 0x25, 0xec, - 0x0f, 0xe5, 0xc4, 0xd0, 0x0c, 0xa5, 0xb7, 0xec, 0x75, 0x6a, 0x50, 0xd8, - 0x62, 0x7f, 0xec, 0xf2, 0x27, 0xf6, 0x76, 0xc8, 0xc7, 0x94, 0x99, 0xb9, - 0x54, 0xcb, 0x66, 0xd0, 0x02, 0x6f, 0x09, 0x76, 0x98, 0x81, 0xf2, 0x89, - 0xcd, 0xfb, 0x0b, 0xde, 0x0f, 0x3a, 0x6b, 0xe3, 0x9d, 0x12, 0xe0, 0xce, - 0x1a, 0x98, 0x38, 0xc4, 0x7d, 0xe2, 0x6c, 0xe4, 0xfa, 0xed, 0xda, 0xc0, - 0x1e, 0x19, 0xe6, 0x88, 0xae, 0x2c, 0x6a, 0xc1, 0xac, 0xb7, 0xc9, 0xd3, - 0xe3, 0x34, 0x47, 0xb2, 0x1a, 0xe2, 0xc5, 0xfd, 0x8b, 0x91, 0xab, 0xbf, - 0x31, 0x6b, 0x78, 0x75, 0x5f, 0x8f, 0x09, 0xfd, 0xb7, 0x78, 0xdb, 0xed, - 0xec, 0xb4, 0x62, 0x62, 0x01, 0xe8, 0x25, 0xa7, 0x84, 0x58, 0xcc, 0x26, - 0xb0, 0xda, 0x56, 0xf2, 0x3a, 0x61, 0x32, 0x65, 0x6a, 0x0b, 0x3e, 0x1e, - 0x16, 0xb3, 0xc5, 0xed, 0xe8, 0xd9, 0x1c, 0x3e, 0xe0, 0xa0, 0xcc, 0x5f, - 0xe1, 0xa0, 0xa0, 0x28, 0xc9, 0x41, 0xa7, 0x6f, 0xf5, 0xe6, 0x04, 0xb0, - 0xa6, 0x91, 0x7e, 0xab, 0xd1, 0x9f, 0xcc, 0x19, 0x76, 0xe0, 0x0c, 0xba, - 0x90, 0x6a, 0xfd, 0xa4, 0x45, 0xf4, 0x9d, 0xfd, 0x78, 0xfa, 0x88, 0xf2, - 0x3b, 0x2e, 0x74, 0x17, 0xf5, 0x4d, 0xde, 0xa9, 0x62, 0x0e, 0xf6, 0xeb, - 0x4a, 0x6c, 0xcd, 0x84, 0x75, 0x5f, 0x24, 0xd7, 0xc2, 0x68, 0x67, 0xbd, - 0x82, 0xfb, 0x17, 0x9b, 0x41, 0x3a, 0xb5, 0x9f, 0x1a, 0xd6, 0x8d, 0x37, - 0xd9, 0x82, 0x8a, 0x4d, 0x9d, 0x0b, 0x91, 0x9b, 0xcc, 0x4b, 0x3a, 0x42, - 0xbd, 0x56, 0x63, 0xd6, 0x9d, 0x19, 0xba, 0xd0, 0xba, 0xf9, 0x2b, 0x2e, - 0x6c, 0x5e, 0x8b, 0xd6, 0xb8, 0x47, 0xf3, 0x10, 0x57, 0xd6, 0xcb, 0x2e, - 0x4a, 0xae, 0x26, 0x6f, 0x11, 0xee, 0x94, 0x2d, 0x17, 0xfa, 0x76, 0x0b, - 0x82, 0xdb, 0x78, 0xc5, 0x20, 0x57, 0x9d, 0x26, 0xd0, 0x94, 0x7d, 0xe3, - 0xb0, 0x53, 0x75, 0xe7, 0x01, 0x4e, 0x15, 0x9e, 0x05, 0x3f, 0xa2, 0xbc, - 0x1a, 0xef, 0xb3, 0xa4, 0xf7, 0xcb, 0xd1, 0xbe, 0x6f, 0xee, 0xdb, 0x66, - 0xf6, 0x61, 0x8c, 0xdd, 0xd2, 0xfe, 0x97, 0xd1, 0xff, 0x11, 0x00, 0x00, - 0xff, 0xff, 0xb0, 0x9d, 0x52, 0xc9, 0x6d, 0x0c, 0x00, 0x00, - }, - "templates/status.html", - ) -} - -// Asset loads and returns the asset for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func Asset(name string) ([]byte, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - return f() - } - return nil, fmt.Errorf("Asset %s not found", name) -} - -// AssetNames returns the names of the assets. -func AssetNames() []string { - names := make([]string, 0, len(_bindata)) - for name := range _bindata { - names = append(names, name) - } - return names -} - -// _bindata is a table, holding each asset generator, mapped to its name. -var _bindata = map[string]func() ([]byte, error){ - "templates/status.html": templates_status_html, -} diff --git a/templates.go b/templates.go new file mode 100644 index 00000000..219e1704 --- /dev/null +++ b/templates.go @@ -0,0 +1,192 @@ +package main + +import ( + "bytes" + "compress/gzip" + "io/ioutil" + "net/http" + "os" + "path" + "sync" + "time" +) + +type _escLocalFS struct{} + +var _escLocal _escLocalFS + +type _escStaticFS struct{} + +var _escStatic _escStaticFS + +type _escFile struct { + compressed string + size int64 + local string + isDir bool + + data []byte + once sync.Once + name string +} + +func (_escLocalFS) Open(name string) (http.File, error) { + f, present := _escData[path.Clean(name)] + if !present { + return nil, os.ErrNotExist + } + return os.Open(f.local) +} + +func (_escStaticFS) prepare(name string) (*_escFile, error) { + f, present := _escData[path.Clean(name)] + if !present { + return nil, os.ErrNotExist + } + var err error + f.once.Do(func() { + f.name = path.Base(name) + if f.size == 0 { + return + } + var gr *gzip.Reader + gr, err = gzip.NewReader(bytes.NewBufferString(f.compressed)) + if err != nil { + return + } + f.data, err = ioutil.ReadAll(gr) + }) + if err != nil { + return nil, err + } + return f, nil +} + +func (fs _escStaticFS) Open(name string) (http.File, error) { + f, err := fs.prepare(name) + if err != nil { + return nil, err + } + return f.File() +} + +func (f *_escFile) File() (http.File, error) { + type httpFile struct { + *bytes.Reader + *_escFile + } + return &httpFile{ + Reader: bytes.NewReader(f.data), + _escFile: f, + }, nil +} + +func (f *_escFile) Close() error { + return nil +} + +func (f *_escFile) Readdir(count int) ([]os.FileInfo, error) { + return nil, nil +} + +func (f *_escFile) Stat() (os.FileInfo, error) { + return f, nil +} + +func (f *_escFile) Name() string { + return f.name +} + +func (f *_escFile) Size() int64 { + return f.size +} + +func (f *_escFile) Mode() os.FileMode { + return 0 +} + +func (f *_escFile) ModTime() time.Time { + return time.Time{} +} + +func (f *_escFile) IsDir() bool { + return f.isDir +} + +func (f *_escFile) Sys() interface{} { + return f +} + +// FS returns a http.Filesystem for the embedded assets. If useLocal is true, +// the filesystem's contents are instead used. +func FS(useLocal bool) http.FileSystem { + if useLocal { + return _escLocal + } + return _escStatic +} + +// FSByte returns the named file from the embedded assets. If useLocal is +// true, the filesystem's contents are instead used. +func FSByte(useLocal bool, name string) ([]byte, error) { + if useLocal { + f, err := _escLocal.Open(name) + if err != nil { + return nil, err + } + return ioutil.ReadAll(f) + } + f, err := _escStatic.prepare(name) + if err != nil { + return nil, err + } + return f.data, nil +} + +// FSMustByte is the same as FSByte, but panics if name is not present. +func FSMustByte(useLocal bool, name string) []byte { + b, err := FSByte(useLocal, name) + if err != nil { + panic(err) + } + return b +} + +// FSString is the string version of FSByte. +func FSString(useLocal bool, name string) (string, error) { + b, err := FSByte(useLocal, name) + return string(b), err +} + +// FSMustString is the string version of FSMustByte. +func FSMustString(useLocal bool, name string) string { + return string(FSMustByte(useLocal, name)) +} + +var _escData = map[string]*_escFile{ + + "/templates/status.html": { + local: "templates/status.html", + size: 3181, + compressed: "" + + "\x1f\x8b\b\x00\x00\tn\x88\x00\xff\xb4WMS\xeb6\x14]'\xbfB\xe3)\xbb\"\x13Jf\x1a\xeax\x03\f]4\x14\x9a\xb6\x8b\xb7S\xac\x9b\xd8\xf3\x1c)OR\b\xbcL\xfe\xfb\xbb\x92?b;&\x04\xbfa\x83\xe5#\x9d+\x9d{O\xaeL\x10\x9be\x1a\x0610\x1e\x06&1)\x84\xf7 o\x1f\xa6d\xbb%\xf4\u007fP:\x91\x82" + + "\xecv\x81\x9fM\xf6\x834\x11_I\xac`>\xf6|_\x80\xe1\x82љ\x94F\x1b\xc5V\x11\x174\x92K\xdfl\x12c@\x9d\x97\x13\xfe%\xfd\x8d\x0e\xfcHk\xbf\xc4\xceq\xe5,\x11\xc0\xe92A\x9a\xd6\x1eQ\x90\x8e=m^S\xd01\x80\xf1N\xdd\xcf\x01\x1bf\xa2\xb8\xd8\b\xd4:\x05&\xf6\xbb\x1d\xddĽ\x85\xfd\x9e\xe1\xf4\xbb\x14" + + " \xd8\x12~űM\v(\xb2%s)\xcc\xf9\x06\x92El\xae\xc9L\xa6\xfc\x0f\xb2\xeb\a~N\vf\x92\xbf\x86\xfd~\xc0\x93g\x12\xa5L\xeb\xb1\x17!\x83\xa18\xe5ىx\x10ާr\xc6\xd2\xc0\xc7a}\xa5\x92\x1b\xbb\xa6W\xc5\xf4\x8a\x89\xdf\x1d\xda\v\f\x9b\xa5PLd/\xee/&W\xe1\xe9\x80篸#\a\xa1\x81#" + + "\xafgy\xca=q\xc0\vv\"\xe6\x92d\xa2\xbc\xfc@D\x1bf4\x96\x97\x97\xab\xc3\x01\xc1\\ա\xe1!4h\xc1&\x98\xf2\x12\xc1\x81r\x12jg\t\x9f֠\x12hl\xb9ݮT\"̜xg\xf4r\xee\x11\x9a\x9d\x8e\xe6\x8b\xe9?\xcc\xc0\xc0\xd9\xf0\x83\xa4a\x17Ҡ\x13ˊ\xaf\xf02\xf9\xeei\xeb\xf3\xb9\xc5\xfc3\xd1" + + "F.\x14[6\xf2:9Z!\x87\x8c.\xce\x1a\xc0\xe8\x00\xa0Mh\xc2^\xea\xc0\xd4\xf0[x~\xaf\xf6\xb9羽c\x01\xee\x11R\xa6\xb8\x94FQ̩u\xa9\x90\xeaU9\x91\xf5\x18\x99\xd1\x05\xe9\xc6\x1bu\xe5\x1d%\xbe\x95\x13\xf6\xf2\xf1ݲb\x91\x03\xb3\xd6\xdd\x1a\xf8ؑ\xda:\xd3\xd5Ou\xa6\xc2\x10\x15+\x17.\xfeo" + + "e\x92%\xec\x0f\xe5\xc4\xd0\f\xa5\xb7\xecujP\xd8b\u007f\xec\xf2'\xf6v\xc8ǔ\x99\xb9T\xcbf\xd0\x02o\tv\x98\x81\xf2\x89\xcd\xfb\v\xde\x0f:k\xe3\x9d\x12\xe0\xce\x1a\x988\xc4}\xe2l\xe4\xfa\xed\xda\xc0\x1e\x19戮,j\xc1\xac\xb7\xc9\xd3\xe34G\xb2\x1a\xe2\xc5\xfd\x8b\x91\xab\xbf1kxu_\x8f\t\xfd\xb7x\xdb\xed" + + "\xec\xb4bb\x01\xe8%\xa7\x84X\xcc&\xb0\xdaV\xf2:a2ej\v>\x1e\x16\xb3\xc5\xed\xe8\xd9\x1c>\xe0\xa0\xcc_ᠠ(\xc9A\xa7o\xf5\xe6\x04\xb0\xa6\x91~\xabџ\xcc\x19v\xe0\f\xba\x90j\xfd\xa4E\xf4\x9d\xfdx\xfa\x88\xf2;.t\x17\xf5Mީb\x0e\xf6\xebJl̈́u_$\xd7\xc2hg\xbd\x82\xfb\x17\x9b" + + "A:\xb5\x9f\x1a֍7ق\x8aM\x9d\v\x91\x9b\xccK:B\xbdVc֝\x19\xbaк\xf9+.l^\x8bָG\xf3\x10W\xd6\xcb.J\xae&o\x11\xee\x94-\x17\xfav\v\x82\xdbx\xc5 W\x9d&Д}\xe3\xb0Su\xe7\x01N\x15\x9e\x05?\xa2\xbc\x1aﳤ\xf7\xcbѾo\xee\xdbf\xf6a\x8c\xdd\xd2\xfe\x97\xd1" + + "\xff\x11\x00\x00\xff\xff\xb0\x9dR\xc9m\f\x00\x00", + }, + + "/": { + isDir: true, + local: "/", + }, + + "/templates": { + isDir: true, + local: "/templates", + }, +} diff --git a/templates_devel.go b/templates_devel.go index ccd9aeea..5c226cff 100644 --- a/templates_devel.go +++ b/templates_devel.go @@ -2,16 +2,7 @@ package main -import ( - "io/ioutil" - "log" -) - -func templates_status_html() ([]byte, error) { - data, err := ioutil.ReadFile("templates/status.html") - if err != nil { - log.Println("Could not open status.html", err) - return nil, err - } - return data, nil +func init() { + // load templates from disk + development = true }