diff --git a/Makefile b/Makefile index b1b545042..8fdbcea3d 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: dep docker pilosa release-build prerelease-build release prerelease prerelease-upload install generate statik test cover cover-pkg cover-viz clean docker-build docker-test +.PHONY: dep docker pilosa release-build prerelease-build release prerelease prerelease-upload install generate generate-statik generate-protoc statik test cover cover-pkg cover-viz clean docker-build docker-test DEP := $(shell command -v dep 2>/dev/null) STATIK := $(shell command -v statik 2>/dev/null) @@ -103,7 +103,7 @@ generate-protoc: .protoc-gen-gofast go generate github.com/pilosa/pilosa/internal generate-statik: statik - go generate github.com/pilosa/pilosa + go generate github.com/pilosa/pilosa/statik generate: generate-protoc generate-statik diff --git a/filesystem.go b/filesystem.go new file mode 100644 index 000000000..5664f0987 --- /dev/null +++ b/filesystem.go @@ -0,0 +1,42 @@ +// Copyright 2017 Pilosa Corp. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package pilosa + +import ( + "fmt" + "net/http" +) + +// Ensure nopFileSystem implements interface. +var _ FileSystem = &nopFileSystem{} + +// FileSystem represents an interface for a WebUI file system. +type FileSystem interface { + New() (http.FileSystem, error) +} + +func init() { + NopFileSystem = &nopFileSystem{} +} + +// NopFileSystem represents a FileSystem that returns an error if called. +var NopFileSystem FileSystem + +type nopFileSystem struct{} + +// New is a no-op implementation of FileSystem New method. +func (n *nopFileSystem) New() (http.FileSystem, error) { + return nil, fmt.Errorf("file system not implemented") +} diff --git a/handler.go b/handler.go index cea42e6ac..a23b2e5ac 100644 --- a/handler.go +++ b/handler.go @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:generate statik -src=./webui - package pilosa import ( @@ -44,10 +42,6 @@ import ( "github.com/pilosa/pilosa/pql" "unicode" - - // Allow building Pilosa without the web UI. - _ "github.com/pilosa/pilosa/statik" - "github.com/rakyll/statik/fs" ) // Handler represents an HTTP handler. @@ -57,6 +51,8 @@ type Handler struct { BroadcastHandler BroadcastHandler StatusHandler StatusHandler + FileSystem FileSystem + // Local hostname & cluster configuration. Node *Node Cluster *Cluster @@ -98,6 +94,11 @@ type errorResponse struct { // NewHandler returns a new instance of Handler with a default logger. func NewHandler() *Handler { handler := &Handler{ + Broadcaster: NopBroadcaster, + //BroadcastHandler: NopBroadcastHandler, // TODO: implement the nop + //StatusHandler: NopStatusHandler, // TODO: implement the nop + FileSystem: NopFileSystem, + LogOutput: os.Stderr, } BuildRouters(handler) @@ -285,13 +286,13 @@ func (h *Handler) handleWebUI(w http.ResponseWriter, r *http.Request) { http.Error(w, "Welcome. Pilosa is running. Visit https://www.pilosa.com/docs/ for more information or try the WebUI by visiting this URL in your browser.", http.StatusNotFound) return } - statikFS, err := fs.New() + filesystem, err := h.FileSystem.New() if err != nil { h.writeQueryResponse(w, r, &QueryResponse{Err: err}) h.logger().Println("Pilosa WebUI is not available. Please run `make generate-statik` before building Pilosa with `make install`.") return } - http.FileServer(statikFS).ServeHTTP(w, r) + http.FileServer(filesystem).ServeHTTP(w, r) } // handleGetSchema handles GET /schema requests. diff --git a/handler_test.go b/handler_test.go index 0f527514d..551c81d66 100644 --- a/handler_test.go +++ b/handler_test.go @@ -31,6 +31,7 @@ import ( "github.com/pilosa/pilosa" "github.com/pilosa/pilosa/internal" "github.com/pilosa/pilosa/pql" + "github.com/pilosa/pilosa/statik" "github.com/pilosa/pilosa/test" ) @@ -1853,6 +1854,7 @@ func TestHandler_WebUI(t *testing.T) { h := test.NewHandler() h.Holder = hldr.Holder h.Cluster = test.NewCluster(1) + h.FileSystem = &statik.FileSystem{} w := httptest.NewRecorder() h.ServeHTTP(w, test.MustNewHTTPRequest("GET", "/", nil)) diff --git a/server/server.go b/server/server.go index eac98121d..7b2353cdc 100644 --- a/server/server.go +++ b/server/server.go @@ -36,6 +36,7 @@ import ( "github.com/pilosa/pilosa/gcnotify" "github.com/pilosa/pilosa/gopsutil" "github.com/pilosa/pilosa/gossip" + "github.com/pilosa/pilosa/statik" "github.com/pilosa/pilosa/statsd" ) @@ -190,6 +191,9 @@ func (m *Command) SetupServer() error { m.Server.Handler.RemoteClient = c m.Server.Cluster.RemoteClient = c + // Statik file system. + m.Server.Handler.FileSystem = &statik.FileSystem{} + // Set configuration options. m.Server.AntiEntropyInterval = time.Duration(m.Config.AntiEntropy.Interval) m.Server.Cluster.LongQueryTime = time.Duration(m.Config.Cluster.LongQueryTime) diff --git a/statik/.gitignore b/statik/.gitignore index 514ee40a1..485c0c57d 100644 --- a/statik/.gitignore +++ b/statik/.gitignore @@ -1 +1 @@ -statik.go +/statik.go diff --git a/statik/doc.go b/statik/filesystem.go similarity index 56% rename from statik/doc.go rename to statik/filesystem.go index e9ca40ffd..e3bf95cb1 100644 --- a/statik/doc.go +++ b/statik/filesystem.go @@ -11,7 +11,27 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - -// Package statik contains static assets for the Web UI. `go generate` will -// produce statik.go, which is ignored by git. +// +//go:generate statik -src=../webui -dest=.. +// +// Package statik contains static assets for the Web UI. `go generate` or +// `make generate-statik` will produce statik.go, which is ignored by git. package statik + +import ( + "net/http" + + "github.com/pilosa/pilosa" + "github.com/rakyll/statik/fs" +) + +// Ensure nopFileSystem implements interface. +var _ pilosa.FileSystem = &FileSystem{} + +// FileSystem represents a static FileSystem. +type FileSystem struct{} + +// New is a statik implementation of FileSystem New method. +func (s *FileSystem) New() (http.FileSystem, error) { + return fs.New() +}