9 <meta content=
"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
11 <link rel=
"stylesheet"
12 href=
"{{ url_prefix }}/static/AdminLTE-2.3.7/bootstrap/css/bootstrap.min.css">
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"
18 href=
"{{ url_prefix }}/static/AdminLTE-2.3.7/dist/css/AdminLTE.min.css">
19 <link rel=
"stylesheet"
20 href=
"{{ url_prefix }}/static/AdminLTE-2.3.7/dist/css/skins/skin-blue.min.css">
21 <link rel=
"stylesheet"
22 href=
"{{ url_prefix }}/static/AdminLTE-2.3.7/plugins/datatables/jquery.dataTables.css">
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>
27 <script src=
"{{ url_prefix }}/static/rivets.bundled.min.js"></script>
28 <script src=
"{{ url_prefix }}/static/underscore-min.js"></script>
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>
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>
40 $(document).ready(function(){
41 var toplevel_data = {{ toplevel_data }};
42 var refresh_interval =
5000;
44 var refresh = function() {
45 $.get(
"{{ url_prefix }}/toplevel_data", function(data) {
46 _.extend(toplevel_data, data);
47 setTimeout(refresh, refresh_interval);
54 templateDelimiters: [
"{",
"}"]
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;"
67 rivets.formatters.health_ok = function(status_str) {
68 if (status_str ==
"HEALTH_OK") {
75 var truncate = function(n, max_width) {
76 var stringized = n.toString();
77 var parts = stringized.split(
".");
78 if (parts.length ==
1) {
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
88 return stringized.substring(
0, max_width);
93 var format_number = function(n, divisor, units) {
98 // People shouldn't really be passing null, but let's
99 // do something sensible instead of barfing.
103 while (Math.floor(n / (divisor**unit)).toString().length
> width -
1) {
109 truncated_float = truncate((n / Math.pow(divisor, unit)).toString(), width);
111 truncated_float = truncate(n, width);
114 return truncated_float + units[unit];
117 rivets.formatters.dimless = function(n){
118 return format_number(n,
1000, [' ', 'k', 'M', 'G', 'T', 'P'])
120 rivets.formatters.dimless_binary = function(n){
121 return format_number(n,
1024, ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB']);
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";
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);
137 // Return the
"1.2.3-g9asdasd" part
140 // Unexpected format, pass it through
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) {
152 rivets.formatters.hide_count_box = function(value) {
154 return (isNaN(value) || value ==
0)
157 rivets.bind($(
"#health"), toplevel_data);
158 rivets.bind($(
"section.sidebar"), toplevel_data);
159 setTimeout(refresh, refresh_interval);
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">
168 background-color: #
222d32;
173 background-color: #
222d32;
178 border-top-color: #b8c7ce;
186 background-color: #
222d32;
190 background-color: #
222d32;
194 background-color: #
222d32;
199 background-color: #
424d52;
209 font-family: monospace;
210 background-color: #
333;
214 .nav-tabs
>li.active
>a {
215 background-color: #
424d52;
232 table.ceph-chartbox {
247 .dataTables_wrapper .dataTables_filter {
251 .dataTables_wrapper .dataTables_filter input {
255 .dataTables_wrapper tbody td {
256 background-color: #
424d52;
260 .dataTables_wrapper .dataTables_paginate .ellipsis {
261 color: #ddd !important
264 .dataTables_wrapper .dataTables_paginate .paginate_button {
265 color: #ddd !important
268 .dataTables_wrapper .dataTables_paginate .paginate_button.disabled {
269 color: #
424d52 !important
273 background-color: #
222d32;
276 .nav-tabs-custom
>.nav-tabs
>li{
279 .nav-tabs-custom
>.nav-tabs
>li
>a{
280 border-bottom-color: transparent;
283 .nav-tabs-custom
>.nav-tabs
>li.active
>a{
284 background-color: #
424d52;
287 .nav-tabs-custom
>.nav-tabs
>li.active:hover
>a{
288 background-color: #
66777f;
291 .nav-tabs-custom
>.tab-content {
292 background-color: #
424d52;
300 <body class=
"hold-transition sidebar-mini sidebar-collapse">
301 <div class=
"wrapper">
304 <header class=
"main-header">
306 <a href=
"{{ url_prefix }}/" class=
"logo">
307 <span class=
"logo-lg">
308 <img src=
"{{ url_prefix }}/static/Ceph_Logo_Standard_RGB_White_120411_fa.png"
309 width=
"123px" height=
"34px"/>
311 <span class=
"logo-mini">
312 <img src=
"{{ url_prefix }}/static/logo-mini.png"
313 width=
"34px" height=
"34px"/>
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"
322 <span class=
"sr-only">Toggle navigation
</span>
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">
333 <!-- Navbar Right Menu -->
334 <div class=
"navbar-custom-menu">
335 <ul class=
"nav navbar-nav">
341 <!-- Left side column. contains the logo and sidebar -->
342 <aside class=
"main-sidebar skin-blue">
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 -->
349 <li class=
"{%if path_info=='/' or path_info.startswith('/health')%}active{%endif%}">
350 <a href=
"{{ url_prefix }}/health">
351 <i class=
"fa fa-heartbeat" rv-style=
"health_status | health_color"></i>
352 <span>Cluster health
</span></a>
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>
360 <ul class=
"treeview-menu menu-open">
362 <a href=
"{{ url_prefix }}/servers">Servers
</a>
365 <a href=
"{{ url_prefix }}/osd">OSDs
</a>
369 <li class=
"treeview{%if path_info.startswith('/rbd')%} active{%endif%}">
371 <i class=
"fa fa-hdd-o" rv-style=
"rbd_mirroring | block_health_color"></i> <span>Block
</span>
372 <span class=
"pull-right-container">
373 <i class=
"fa fa-angle-left pull-right"></i>
376 <ul class=
"treeview-menu menu-open">
378 <a href=
"{{ url_prefix }}/rbd_mirroring">
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>
387 <a href=
"{{ url_prefix }}/rbd_iscsi">
388 <i class=
"fa fa-upload"></i> iSCSI
389 <span class=
"pull-right-container" />
392 <li class=
"treeview{%if path_info.startswith('/rbd_pool')%} active menu-open{%endif%}">
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>
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>
403 <li class=
"ceph-none-found" rv-hide=
"rbd_pools | length">None found
</li>
408 <li class=
"treeview{%if path_info.startswith(('/filesystem/', '/clients/'))%} active{%endif%}">
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>
414 <ul class=
"treeview-menu menu-open">
415 <li rv-each-filesystem=
"filesystems">
416 <a rv-href=
"filesystem.url">{filesystem.name}
</a>
418 <li class=
"ceph-none-found" rv-hide=
"filesystems | length">None found
</li>
422 <!-- /.sidebar-menu -->
427 <div id=
"content" class=
"content-wrapper">
429 {% block content %}{% endblock %}
432 <!-- /.content-wrapper -->
435 <footer class=
"main-footer">
436 <!-- To the right -->
437 <div class=
"pull-right hidden-xs">
440 <!-- Default to the left -->
441 <strong>Copyright
© 2016 by Ceph Contributors.
</strong> Free software (LGPL
2.1)
452 <!-- Bootstrap 3.3.6 -->
454 <!-- AdminLTE App -->