]>
Commit | Line | Data |
---|---|---|
31f18b77 FG |
1 | |
2 | <!DOCTYPE html> | |
3 | ||
4 | <html> | |
5 | ||
6 | <head> | |
7 | <title>Ceph</title> | |
8 | ||
9 | <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" | |
10 | name="viewport"> | |
11 | <link rel="stylesheet" | |
3efd9988 | 12 | href="{{ url_prefix }}/static/AdminLTE-2.3.7/bootstrap/css/bootstrap.min.css"> |
31f18b77 | 13 | <link rel="stylesheet" |
b32b8144 | 14 | href="{{ url_prefix }}/static/libs/font-awesome/4.7.0/css/font-awesome.min.css"> |
31f18b77 | 15 | <link rel="stylesheet" |
3efd9988 | 16 | href="{{ url_prefix }}/static/AdminLTE-2.3.7/dist/css/AdminLTE.min.css"> |
31f18b77 | 17 | <link rel="stylesheet" |
3efd9988 | 18 | href="{{ url_prefix }}/static/AdminLTE-2.3.7/dist/css/skins/skin-blue.min.css"> |
c07f9fc5 | 19 | <link rel="stylesheet" |
b32b8144 | 20 | href="{{ url_prefix }}/static/AdminLTE-2.3.7/plugins/datatables/jquery.dataTables.min.css"> |
31f18b77 | 21 | |
3efd9988 FG |
22 | <script src="{{ url_prefix }}/static/AdminLTE-2.3.7/plugins/jQuery/jquery-2.2.3.min.js"></script> |
23 | <script src="{{ url_prefix }}/static/AdminLTE-2.3.7/plugins/sparkline/jquery.sparkline.min.js"></script> | |
31f18b77 | 24 | |
b32b8144 FG |
25 | <script src="{{ url_prefix }}/static/libs/rivets/0.9.6/rivets.bundled.min.js"></script> |
26 | <script src="{{ url_prefix }}/static/libs/underscore.js/1.8.3/underscore-min.js"></script> | |
31f18b77 | 27 | |
3efd9988 FG |
28 | <script src="{{ url_prefix }}/static/AdminLTE-2.3.7/bootstrap/js/bootstrap.min.js"></script> |
29 | <script src="{{ url_prefix }}/static/AdminLTE-2.3.7/dist/js/app.min.js"></script> | |
30 | <script src="{{ url_prefix }}/static/AdminLTE-2.3.7/plugins/datatables/jquery.dataTables.min.js"></script> | |
31f18b77 | 31 | |
b32b8144 FG |
32 | <script src="{{ url_prefix }}/static/libs/moment.js/2.17.1/moment.min.js"></script> |
33 | <script src="{{ url_prefix }}/static/libs/Chart.js/2.4.0/Chart.min.js"></script> | |
31f18b77 FG |
34 | |
35 | <script> | |
36 | $(document).ready(function(){ | |
37 | var toplevel_data = {{ toplevel_data }}; | |
38 | var refresh_interval = 5000; | |
39 | ||
40 | var refresh = function() { | |
3efd9988 | 41 | $.get("{{ url_prefix }}/toplevel_data", function(data) { |
224ce89b | 42 | _.extend(toplevel_data, data); |
31f18b77 FG |
43 | setTimeout(refresh, refresh_interval); |
44 | }); | |
45 | }; | |
46 | ||
47 | rivets.configure({ | |
48 | preloadData: true, | |
49 | prefix: "rv", | |
50 | templateDelimiters: ["{", "}"] | |
51 | }); | |
52 | ||
53 | rivets.formatters.health_color = function(status_str) { | |
54 | if (status_str == "HEALTH_OK") { | |
55 | return "color: #00bb00;"; | |
56 | } else if (status_str == "HEALTH_WARN") { | |
57 | return "color: #FFC200;"; | |
58 | } else if (status_str == "HEALTH_ERR") { | |
59 | return "color: #ff0000;" | |
60 | } | |
61 | } | |
62 | ||
224ce89b WB |
63 | rivets.formatters.health_ok = function(status_str) { |
64 | if (status_str == "HEALTH_OK") { | |
65 | return true; | |
66 | } else { | |
67 | return false; | |
68 | } | |
69 | } | |
70 | ||
31f18b77 FG |
71 | var truncate = function(n, max_width) { |
72 | var stringized = n.toString(); | |
73 | var parts = stringized.split("."); | |
74 | if (parts.length == 1) { | |
75 | // Just an int | |
76 | return stringized; | |
77 | } else { | |
78 | var fractional_digits = max_width - parts[0].length - 1; | |
79 | if (fractional_digits <= 0) { | |
80 | // No width available for the fractional part, drop | |
81 | // it and the decimal point | |
82 | return parts[0]; | |
83 | } else { | |
84 | return stringized.substring(0, max_width); | |
85 | } | |
86 | } | |
87 | } | |
88 | ||
224ce89b | 89 | var format_number = function(n, divisor, units) { |
31f18b77 | 90 | var width=4; |
31f18b77 FG |
91 | var unit = 0; |
92 | ||
3efd9988 FG |
93 | if (n == null) { |
94 | // People shouldn't really be passing null, but let's | |
95 | // do something sensible instead of barfing. | |
96 | return "-"; | |
97 | } | |
98 | ||
224ce89b | 99 | while (Math.floor(n / (divisor**unit)).toString().length > width - 1) { |
31f18b77 FG |
100 | unit = unit + 1; |
101 | } | |
102 | ||
103 | var truncated_float; | |
104 | if (unit > 0) { | |
224ce89b | 105 | truncated_float = truncate((n / Math.pow(divisor, unit)).toString(), width); |
31f18b77 FG |
106 | } else { |
107 | truncated_float = truncate(n, width); | |
108 | } | |
109 | ||
110 | return truncated_float + units[unit]; | |
224ce89b WB |
111 | } |
112 | ||
113 | rivets.formatters.dimless = function(n){ | |
114 | return format_number(n, 1000, [' ', 'k', 'M', 'G', 'T', 'P']) | |
115 | }; | |
116 | rivets.formatters.dimless_binary = function(n){ | |
117 | return format_number(n, 1024, ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB']); | |
31f18b77 FG |
118 | }; |
119 | ||
c07f9fc5 FG |
120 | rivets.formatters.block_health_color = function(rbd_mirroring) { |
121 | if (rbd_mirroring.errors > 0) { | |
122 | return "color: #ff0000"; | |
123 | } else if (rbd_mirroring.warnings > 0) { | |
124 | return "color: #ffc200"; | |
125 | } | |
126 | return ""; | |
127 | }; | |
128 | ||
129 | rivets.formatters.short_version = function(version) { | |
130 | // Expect "ceph version 1.2.3-g9asdasd (as98d7a0s8d7)" | |
131 | var result = /ceph version\s+([^ ]+)\s+\(.+\)/.exec(version); | |
132 | if (result) { | |
133 | // Return the "1.2.3-g9asdasd" part | |
134 | return result[1]; | |
135 | } else { | |
136 | // Unexpected format, pass it through | |
137 | return version; | |
138 | } | |
139 | return | |
140 | }; | |
141 | ||
224ce89b WB |
142 | /* This is useful if you need to display some alternative text |
143 | * when a collection is empty using rv-hide */ | |
144 | rivets.formatters.length = function(val) { | |
145 | return val.length; | |
146 | } | |
31f18b77 | 147 | |
c07f9fc5 FG |
148 | rivets.formatters.hide_count_box = function(value) { |
149 | value = +value | |
150 | return (isNaN(value) || value == 0) | |
151 | }; | |
152 | ||
224ce89b | 153 | rivets.bind($("#health"), toplevel_data); |
31f18b77 FG |
154 | rivets.bind($("section.sidebar"), toplevel_data); |
155 | setTimeout(refresh, refresh_interval); | |
156 | }); | |
157 | </script> | |
158 | ||
3efd9988 FG |
159 | <link rel="shortcut icon" href="https://ceph.com/wp-content/themes/cephTheme/Resources/Favicons/favicon-96x96.png"> |
160 | <link rel="shortcut icon" href="{{ url_prefix }}/static/favicon.ico"> | |
224ce89b WB |
161 | |
162 | <style> | |
163 | div.box { | |
164 | background-color: #222d32; | |
165 | color: #fff; | |
166 | } | |
167 | ||
168 | div.info-box { | |
169 | background-color: #222d32; | |
170 | color: #fff; | |
171 | } | |
172 | ||
173 | .box { | |
174 | border-top-color: #b8c7ce; | |
175 | } | |
176 | ||
177 | div.box-header { | |
178 | color: #b8c7ce; | |
179 | } | |
180 | ||
181 | a.logo { | |
182 | background-color: #222d32; | |
183 | } | |
184 | ||
185 | body { | |
186 | background-color: #222d32; | |
187 | } | |
188 | ||
189 | .navbar { | |
190 | background-color: #222d32; | |
191 | color: #222d32; | |
192 | } | |
193 | ||
194 | div#content { | |
195 | background-color: #424d52; | |
196 | color: #ddd; | |
197 | } | |
198 | ||
199 | div.progress-bar { | |
200 | border-width: 1px; | |
201 | border-color: #ddd; | |
202 | } | |
203 | ||
204 | .ceph-log { | |
205 | font-family: monospace; | |
206 | background-color: #333; | |
207 | color: #ddd; | |
208 | } | |
209 | ||
210 | .nav-tabs>li.active>a { | |
211 | background-color: #424d52; | |
212 | color: #ddd; | |
213 | } | |
214 | ||
215 | .navbar a { | |
216 | color: #b8c7ce; | |
217 | } | |
218 | ||
219 | .ceph-none-found { | |
220 | color: #8aa4af; | |
221 | font-style: italic; | |
222 | padding-left: 15px; | |
223 | padding-right: 5px; | |
224 | padding-top: 5px; | |
225 | padding-bottom: 5px; | |
226 | } | |
227 | ||
228 | table.ceph-chartbox { | |
229 | margin-left: 40px; | |
230 | } | |
231 | ||
232 | .ceph-chartbox td { | |
233 | padding-left: 35px; | |
234 | text-align: center; | |
235 | font-weight: bold; | |
236 | } | |
237 | ||
181888fb FG |
238 | .chart-container { |
239 | width: 100%; | |
240 | height: 100%; | |
241 | } | |
242 | ||
c07f9fc5 FG |
243 | .dataTables_wrapper .dataTables_filter { |
244 | color: #ddd | |
245 | } | |
246 | ||
247 | .dataTables_wrapper .dataTables_filter input { | |
248 | color: #222d32 | |
249 | } | |
250 | ||
251 | .dataTables_wrapper tbody td { | |
252 | background-color: #424d52; | |
253 | color: #ddd; | |
254 | } | |
255 | ||
256 | .dataTables_wrapper .dataTables_paginate .ellipsis { | |
257 | color: #ddd !important | |
258 | } | |
259 | ||
260 | .dataTables_wrapper .dataTables_paginate .paginate_button { | |
261 | color: #ddd !important | |
262 | } | |
263 | ||
264 | .dataTables_wrapper .dataTables_paginate .paginate_button.disabled { | |
265 | color: #424d52 !important | |
266 | } | |
267 | ||
268 | .nav-tabs-custom { | |
269 | background-color: #222d32; | |
270 | color: #ddd; | |
271 | } | |
272 | .nav-tabs-custom>.nav-tabs>li{ | |
273 | margin-right: 0; | |
274 | } | |
275 | .nav-tabs-custom>.nav-tabs>li>a{ | |
276 | border-bottom-color: transparent; | |
277 | color: #aaa; | |
278 | } | |
279 | .nav-tabs-custom>.nav-tabs>li.active>a{ | |
280 | background-color: #424d52; | |
281 | color: #eee; | |
282 | } | |
283 | .nav-tabs-custom>.nav-tabs>li.active:hover>a{ | |
284 | background-color: #66777f; | |
285 | color: #eee; | |
286 | } | |
287 | .nav-tabs-custom>.tab-content { | |
288 | background-color: #424d52; | |
289 | color: #eee; | |
290 | } | |
291 | ||
224ce89b WB |
292 | </style> |
293 | ||
31f18b77 FG |
294 | </head> |
295 | ||
224ce89b | 296 | <body class="hold-transition sidebar-mini sidebar-collapse"> |
31f18b77 FG |
297 | <div class="wrapper"> |
298 | ||
224ce89b | 299 | <!-- Main Header --> |
31f18b77 FG |
300 | <header class="main-header"> |
301 | <!-- Logo --> | |
3efd9988 | 302 | <a href="{{ url_prefix }}/" class="logo"> |
31f18b77 | 303 | <span class="logo-lg"> |
3efd9988 | 304 | <img src="{{ url_prefix }}/static/Ceph_Logo_Standard_RGB_White_120411_fa.png" |
31f18b77 FG |
305 | width="123px" height="34px"/> |
306 | </span> | |
224ce89b | 307 | <span class="logo-mini"> |
3efd9988 | 308 | <img src="{{ url_prefix }}/static/logo-mini.png" |
224ce89b WB |
309 | width="34px" height="34px"/> |
310 | </span> | |
31f18b77 FG |
311 | </a> |
312 | ||
313 | <!-- Header Navbar --> | |
314 | <nav class="navbar navbar-static-top" role="navigation"> | |
315 | <!-- Sidebar toggle button--> | |
316 | <a href="#" class="sidebar-toggle" data-toggle="offcanvas" | |
317 | role="button"> | |
318 | <span class="sr-only">Toggle navigation</span> | |
319 | </a> | |
320 | ||
224ce89b WB |
321 | <div id="health" style="font-size: 18px; padding: 12px 12px;"> |
322 | <span rv-hide="health_status | health_ok" > | |
323 | <span rv-style="health_status | health_color"> | |
324 | {health_status} | |
325 | </span> | |
31f18b77 FG |
326 | </span> |
327 | </div> | |
328 | ||
329 | <!-- Navbar Right Menu --> | |
330 | <div class="navbar-custom-menu"> | |
331 | <ul class="nav navbar-nav"> | |
332 | ||
333 | </ul> | |
334 | </div> | |
335 | </nav> | |
336 | </header> | |
337 | <!-- Left side column. contains the logo and sidebar --> | |
224ce89b | 338 | <aside class="main-sidebar skin-blue"> |
31f18b77 FG |
339 | |
340 | <!-- sidebar: style can be found in sidebar.less --> | |
341 | <section class="sidebar"> | |
342 | <!-- Sidebar Menu --> | |
343 | <ul class="sidebar-menu"> | |
344 | <!-- Optionally, you can add icons to the links --> | |
c07f9fc5 | 345 | <li class="{%if path_info=='/' or path_info.startswith('/health')%}active{%endif%}"> |
3efd9988 | 346 | <a href="{{ url_prefix }}/health"> |
224ce89b | 347 | <i class="fa fa-heartbeat" rv-style="health_status | health_color"></i> |
31f18b77 FG |
348 | <span>Cluster health</span></a> |
349 | </li> | |
1adf2230 | 350 | <li class="treeview{%if path_info.startswith(('/server', '/osd','/config_options'))%} active{%endif%}"> |
c07f9fc5 FG |
351 | <a href="#"><i class="fa fa-server"></i> <span>Cluster</span> |
352 | <span class="pull-right-container"> | |
353 | <i class="fa fa-angle-left pull-right"></i> | |
354 | </span> | |
355 | </a> | |
356 | <ul class="treeview-menu menu-open"> | |
357 | <li> | |
3efd9988 | 358 | <a href="{{ url_prefix }}/servers">Servers</a> |
c07f9fc5 FG |
359 | </li> |
360 | <li> | |
3efd9988 | 361 | <a href="{{ url_prefix }}/osd">OSDs</a> |
c07f9fc5 | 362 | </li> |
1adf2230 AA |
363 | <li> |
364 | <a href="{{ url_prefix }}/config_options">Configuration</a> | |
365 | </li> | |
c07f9fc5 | 366 | </ul> |
31f18b77 | 367 | </li> |
c07f9fc5 FG |
368 | <li class="treeview{%if path_info.startswith('/rbd')%} active{%endif%}"> |
369 | <a href="#"> | |
370 | <i class="fa fa-hdd-o" rv-style="rbd_mirroring | block_health_color"></i> <span>Block</span> | |
224ce89b WB |
371 | <span class="pull-right-container"> |
372 | <i class="fa fa-angle-left pull-right"></i> | |
373 | </span> | |
374 | </a> | |
375 | <ul class="treeview-menu menu-open"> | |
c07f9fc5 | 376 | <li> |
3efd9988 | 377 | <a href="{{ url_prefix }}/rbd_mirroring"> |
c07f9fc5 FG |
378 | <i class="fa fa-exchange"></i> Mirroring |
379 | <span class="pull-right-container"> | |
380 | <small rv-hide="rbd_mirroring.warnings | hide_count_box" class="label pull-right bg-yellow">{rbd_mirroring.warnings}</small> | |
381 | <small rv-hide="rbd_mirroring.errors | hide_count_box" class="label pull-right bg-red">{rbd_mirroring.errors}</small> | |
382 | </span> | |
383 | </a> | |
384 | </li> | |
385 | <li> | |
3efd9988 | 386 | <a href="{{ url_prefix }}/rbd_iscsi"> |
c07f9fc5 FG |
387 | <i class="fa fa-upload"></i> iSCSI |
388 | <span class="pull-right-container" /> | |
389 | </a> | |
390 | </li> | |
391 | <li class="treeview{%if path_info.startswith('/rbd_pool')%} active menu-open{%endif%}"> | |
392 | <a href="#"> | |
393 | <i class="fa fa-dot-circle-o"></i> <span>Pools</span> | |
394 | <span class="pull-right-container"> | |
395 | <i class="fa fa-angle-left pull-right"></i> | |
396 | </span> | |
397 | </a> | |
398 | <ul class="treeview-menu"> | |
399 | <li rv-each-pool="rbd_pools"> | |
400 | <a rv-href="pool.url"><i class="fa fa-circle-o"></i> {pool.name}</a> | |
401 | </li> | |
181888fb | 402 | <li class="ceph-none-found" rv-hide="rbd_pools | length">None found</li> |
c07f9fc5 | 403 | </ul> |
224ce89b | 404 | </li> |
224ce89b WB |
405 | </ul> |
406 | </li> | |
c07f9fc5 | 407 | <li class="treeview{%if path_info.startswith(('/filesystem/', '/clients/'))%} active{%endif%}"> |
31f18b77 FG |
408 | <a href="#"><i class="fa fa-folder"></i> <span>Filesystems</span> |
409 | <span class="pull-right-container"> | |
410 | <i class="fa fa-angle-left pull-right"></i> | |
411 | </span> | |
412 | </a> | |
413 | <ul class="treeview-menu menu-open"> | |
414 | <li rv-each-filesystem="filesystems"> | |
415 | <a rv-href="filesystem.url">{filesystem.name}</a> | |
416 | </li> | |
224ce89b | 417 | <li class="ceph-none-found" rv-hide="filesystems | length">None found</li> |
31f18b77 FG |
418 | </ul> |
419 | </li> | |
420 | </ul> | |
421 | <!-- /.sidebar-menu --> | |
422 | </section> | |
423 | <!-- /.sidebar --> | |
424 | </aside> | |
425 | ||
426 | <div id="content" class="content-wrapper"> | |
427 | ||
428 | {% block content %}{% endblock %} | |
429 | ||
430 | </div> | |
431 | <!-- /.content-wrapper --> | |
432 | ||
433 | <!-- Main Footer --> | |
434 | <footer class="main-footer"> | |
435 | <!-- To the right --> | |
436 | <div class="pull-right hidden-xs"> | |
437 | {{ ceph_version }} | |
438 | </div> | |
439 | <!-- Default to the left --> | |
440 | <strong>Copyright © 2016 by Ceph Contributors.</strong> Free software (LGPL 2.1) | |
441 | </footer> | |
442 | ||
31f18b77 FG |
443 | </div> |
444 | ||
445 | <!-- | |
446 | <pre> | |
447 | {{ data }} | |
448 | </pre> | |
449 | --> | |
450 | ||
451 | <!-- Bootstrap 3.3.6 --> | |
452 | ||
453 | <!-- AdminLTE App --> | |
454 | ||
455 | ||
456 | </body> | |
457 | </html> |