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