Skip to content

Commit

Permalink
Merge pull request hashicorp#1543 from hashicorp/f-ui-static
Browse files Browse the repository at this point in the history
Static asset compilation for Consul UI
  • Loading branch information
ryanuber committed Dec 25, 2015
2 parents 14922b5 + 87c1283 commit 63706d5
Show file tree
Hide file tree
Showing 10 changed files with 521 additions and 11 deletions.
12 changes: 10 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
GOTOOLS = github.com/mitchellh/gox golang.org/x/tools/cmd/stringer
GOTOOLS = github.com/mitchellh/gox golang.org/x/tools/cmd/stringer \
github.com/jteeuwen/go-bindata/... github.com/elazarl/go-bindata-assetfs/...
DEPS = $(shell go list -f '{{range .TestImports}}{{.}} {{end}}' ./...)
PACKAGES = $(shell go list ./...)
VETARGS?=-asmdecl -atomic -bool -buildtags -copylocks -methods \
Expand Down Expand Up @@ -68,10 +69,17 @@ generate: deps
find . -type f -name '.DS_Store' -delete
go generate ./...

# generates the static web ui
static-assets: deps
@echo "--> Generating static assets"
@go-bindata-assetfs -pkg agent -prefix ui ./ui/dist/...
@mv bindata_assetfs.go command/agent
$(MAKE) format

web:
./scripts/website_run.sh

web-push:
./scripts/website_push.sh

.PHONY: all bin dev dist cov deps test vet web web-push generate test-nodep
.PHONY: all bin dev dist cov deps test vet web web-push generate test-nodep static-assets
431 changes: 431 additions & 0 deletions command/agent/bindata_assetfs.go

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions command/agent/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ func (c *Command) readConfig() *Config {
cmdFlags.StringVar(&cmdConfig.NodeName, "node", "", "node name")
cmdFlags.StringVar(&cmdConfig.Datacenter, "dc", "", "node datacenter")
cmdFlags.StringVar(&cmdConfig.DataDir, "data-dir", "", "path to the data directory")
cmdFlags.BoolVar(&cmdConfig.EnableUi, "ui", false, "enable the built-in web UI")
cmdFlags.StringVar(&cmdConfig.UiDir, "ui-dir", "", "path to the web UI directory")
cmdFlags.StringVar(&cmdConfig.PidFile, "pid-file", "", "path to file to store PID")
cmdFlags.StringVar(&cmdConfig.EncryptKey, "encrypt", "", "gossip encryption key")
Expand Down Expand Up @@ -990,6 +991,7 @@ Options:
-rejoin Ignores a previous leave and attempts to rejoin the cluster.
-server Switches agent to server mode.
-syslog Enables logging to syslog
-ui Enables the built-in static web UI server
-ui-dir=path Path to directory containing the Web UI resources
-pid-file=path Path to file to store agent PID
Expand Down
7 changes: 7 additions & 0 deletions command/agent/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,10 @@ type Config struct {
RetryIntervalWan time.Duration `mapstructure:"-" json:"-"`
RetryIntervalWanRaw string `mapstructure:"retry_interval_wan"`

// EnableUi enables the statically-compiled assets for the Consul web UI and
// serves them at the default /ui/ endpoint automatically.
EnableUi bool `mapstructure:"ui"`

// UiDir is the directory containing the Web UI resources.
// If provided, the UI endpoints will be enabled.
UiDir string `mapstructure:"ui_dir"`
Expand Down Expand Up @@ -1004,6 +1008,9 @@ func MergeConfig(a, b *Config) *Config {
if b.Addresses.RPC != "" {
result.Addresses.RPC = b.Addresses.RPC
}
if b.EnableUi {
result.EnableUi = true
}
if b.UiDir != "" {
result.UiDir = b.UiDir
}
Expand Down
12 changes: 12 additions & 0 deletions command/agent/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,17 @@ func TestDecodeConfig(t *testing.T) {
t.Fatalf("bad: %#v", config)
}

// Static UI server
input = `{"ui": true}`
config, err = DecodeConfig(bytes.NewReader([]byte(input)))
if err != nil {
t.Fatalf("err: %s", err)
}

if !config.EnableUi {
t.Fatalf("bad: %#v", config)
}

// UI Dir
input = `{"ui_dir": "/opt/consul-ui"}`
config, err = DecodeConfig(bytes.NewReader([]byte(input)))
Expand Down Expand Up @@ -1230,6 +1241,7 @@ func TestMergeConfig(t *testing.T) {
Services: []*ServiceDefinition{nil},
StartJoin: []string{"1.1.1.1"},
StartJoinWan: []string{"1.1.1.1"},
EnableUi: true,
UiDir: "/opt/consul-ui",
EnableSyslog: true,
RejoinAfterLeave: true,
Expand Down
5 changes: 3 additions & 2 deletions command/agent/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,10 +275,11 @@ func (s *HTTPServer) registerHandlers(enableDebug bool) {
s.mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
}

// Enable the UI + special endpoints
// Use the custom UI dir if provided.
if s.uiDir != "" {
// Static file serving done from /ui/
s.mux.Handle("/ui/", http.StripPrefix("/ui/", http.FileServer(http.Dir(s.uiDir))))
} else if s.agent.config.EnableUi {
s.mux.Handle("/ui/", http.StripPrefix("/ui/", http.FileServer(assetFS())))
}

// API's are under /internal/ui/ to avoid conflict
Expand Down
25 changes: 20 additions & 5 deletions command/agent/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@ func makeHTTPServerWithConfig(t *testing.T, cb func(c *Config)) (string, *HTTPSe
}

dir, agent := makeAgent(t, conf)
uiDir := filepath.Join(dir, "ui")
if err := os.Mkdir(uiDir, 755); err != nil {
t.Fatalf("err: %v", err)
}
conf.UiDir = uiDir
servers, err := NewHTTPServers(agent, conf, agent.logOutput)
if err != nil {
t.Fatalf("err: %v", err)
Expand Down Expand Up @@ -635,6 +630,26 @@ func TestScadaHTTP(t *testing.T) {
scadaHttp.mux.HandleFunc("/debug/pprof/symbol", mockFn)
}

func TestEnableWebUI(t *testing.T) {
httpTestWithConfig(t, func(s *HTTPServer) {
req, err := http.NewRequest("GET", "/ui/", nil)
if err != nil {
t.Fatalf("err: %v", err)
}

// Perform the request
resp := httptest.NewRecorder()
s.mux.ServeHTTP(resp, req)

// Check the result
if resp.Code != 200 {
t.Fatalf("should handle ui")
}
}, func(c *Config) {
c.EnableUi = true
})
}

// assertIndex tests that X-Consul-Index is set and non-zero
func assertIndex(t *testing.T, resp *httptest.ResponseRecorder) {
header := resp.Header().Get("X-Consul-Index")
Expand Down
12 changes: 11 additions & 1 deletion command/agent/ui_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,17 @@ import (
)

func TestUiIndex(t *testing.T) {
dir, srv := makeHTTPServer(t)
// Make a test dir to serve UI files
uiDir, err := ioutil.TempDir("", "consul")
if err != nil {
t.Fatalf("err: %v", err)
}
defer os.RemoveAll(uiDir)

// Make the server
dir, srv := makeHTTPServerWithConfig(t, func(c *Config) {
c.UiDir = uiDir
})
defer os.RemoveAll(dir)
defer srv.Shutdown()
defer srv.agent.Shutdown()
Expand Down
17 changes: 17 additions & 0 deletions ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,20 @@ The `dist` folder will contain the files you should use for deployment.

###Acknowledgements
cog icon by useiconic.com from the [Noun Project](https://thenounproject.com/term/setting/45865/)

### Compiling the UI into the Go binary

The UI is compiled and shipped with the Consul go binary. The generated bindata
file lives in the `command/agent/bindata_assetfs.go` file and is checked into
source control. This is useful so that not every Consul developer needs to set
up bundler etc. To re-generate the file, first follow the compilation steps
above to build the UI assets into the `dist/` folder. With that done, from the
root of the Consul repo, run:

```
$ make static-assets
```

The file will now be refreshed with the current UI data. You can now rebuild the
Consul binary normally with `make bin` or `make dev`, and see the updated UI
after re-launching Consul.
9 changes: 8 additions & 1 deletion website/source/docs/agent/options.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,12 @@ The options below are all specified on the command-line.
* <a name="_syslog"></a><a href="#_syslog">`-syslog`</a> - This flag enables logging to syslog. This
is only supported on Linux and OSX. It will result in an error if provided on Windows.

* <a name="_ui"></a><a href="#_ui">`-ui`</a> - Enables the built-in web UI
server and the required HTTP routes. This eliminates the need to maintain the
Consul web UI files separately from the binary.

* <a name="_ui_dir"></a><a href="#_ui_dir">`-ui-dir`</a> - This flag provides the directory containing
the Web UI resources for Consul. This must be provided to enable the Web UI. The directory must be
the Web UI resources for Consul. This will automatically enable the Web UI. The directory must be
readable to the agent.

## <a name="configuration_files"></a>Configuration Files
Expand Down Expand Up @@ -590,6 +594,9 @@ definitions support being updated during a reload.
[`enable_syslog`](#enable_syslog) is provided, this controls to which
facility messages are sent. By default, `LOCAL0` will be used.

* <a name="ui"></a><a href="#ui">`ui`</a> - Equivalent to the [`-ui`](#_ui)
command-line flag.

* <a name="ui_dir"></a><a href="#ui_dir">`ui_dir`</a> - Equivalent to the
[`-ui-dir`](#_ui_dir) command-line flag.

Expand Down

0 comments on commit 63706d5

Please sign in to comment.