Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

query: --web.route-prefix makes UI inaccessible #2581

Closed
GiedriusS opened this issue May 10, 2020 · 1 comment · Fixed by #2714
Closed

query: --web.route-prefix makes UI inaccessible #2581

GiedriusS opened this issue May 10, 2020 · 1 comment · Fixed by #2714

Comments

@GiedriusS
Copy link
Member

Thanos, Prometheus and Golang version used:

./thanos --version                                                                                                                
thanos, version 0.12.2 (branch: master, revision: 060ad9552dbcce9ea50218025a913ad8e99b4471)
  build user:       gstatkevicius@gstatkevicius-desktop
  build date:       20200510-20:54:11
  go version:       go1.14.2

Object Storage Provider:

N/A

What happened:

I have specified --web.route-prefix as FOO by: --web.route-prefix=FOO. Then, I went to http://localhost:10902/FOO.

What you expected to happen:

Expected the user interface to load. Instead, I got a 404.

How to reproduce it (as minimally and precisely as possible):

Run ./thanos query --web.route-prefix="test". Go to http://localhost:10902/test.

Full logs to relevant components:

N/A

Anything else we need to know:

ATM when you specify FOO as --web.route-prefix then:

  • A permanent redirect is registered on / to /FOO
  • On /FOO a permanent redirect is registered via q.root to /graph
  • And /graph is actually registered on /FOO/graph

Making an ad-hoc change to q.root like this:

// Root redirects "/" requests to "/graph", taking into account the path prefix value.
func (q *Query) root(w http.ResponseWriter, r *http.Request) {
	prefix := GetWebPrefix(q.logger, q.externalPrefix, q.prefixHeader, r)

	http.Redirect(w, r, path.Join(prefix, "/test", "/graph"), http.StatusFound)
}

Makes the UI available on http://localhost:10902/test again to some degree.

The assets are still being loaded from /static, not /test/static but that's another problem. I'd expect to see a fully functional UI but that hasn't worked on 0.11.x as well. To get a fully functional UI, you also need to specify --web.external-prefix="/test". But maybe that's by design.

@onprem
Copy link
Member

onprem commented May 24, 2020

Okay so I tried looking into this and I have got some observations that can help us.

Setting the --web.route-prefix="test" results in everything getting served /test. So now the graph page accessible at /test/graph, assets are getting served from /test/static/ and the API is accessible from /test/api

Setting the --web.external-prefix="ext" results in each link on webUI converting to {{ external-prefix }}/actual-link/..., it also appends the external prefix to every http redirection. This is useful when we want to use Thanos behind a reverse proxy on a sub path like example.com/thanos, the reverse proxy would strip /thanos from the url for us during requests but we still need to append /thanos to links and redirections, and that's exactly what --web.external-prefix does.

So going back to route prefix, if we use --web.route-prefix=test and open localhost:10902/test/graph we should be able to use the UI but that's not the case because all requests for the static assets gets 404 Not Found error. This is because the WebUI is trying to load the assets from /static/*, while the assets are getting served on /test/static/*.

The bug lies in the templates we use for the WebUI. For example in graph.html

<link type="text/css" rel="stylesheet" href="{{ pathPrefix }}/static/css/graph.css?v={{ buildVersion }}">

pathPrefix is the external prefix defined by --web.external-prefix and in this case it isn't set so the value of href attribute becomes /static/css/.... which is going to get 404 Not Found because we need /test/static/.. here. This can be easily solved by using a relative url here.

A simple workaround is setting --web.external-prefix=".". So if you run Thanos with --web.route-prefix="test" --web.external-prefix="." everything works on localhost:10902/test/graph.

For a proper solution we can remove the forward slash after {{ pathPrefix }} from html templates, and passing the pathPrefix with / (if defined). This way if we don't have external-prefix the urls would remain relative and work.

/* graph.html */
<link type="text/css" rel="stylesheet" href="{{ pathPrefix }}static/css/graph.css?v={{ buildVersion }}">
// pkg/ui/query.go
func (q *Query) graph(w http.ResponseWriter, r *http.Request) {
	prefix := GetWebPrefix(q.logger, q.externalPrefix, q.prefixHeader, r)
	if prefix != "" {
		prefix := prefix + "/"
	}

	q.executeTemplate(w, "graph.html", prefix, nil)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants