<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
name="viewport">
<link rel="stylesheet"
- href="/static/AdminLTE-2.3.7/bootstrap/css/bootstrap.min.css">
+ href="{{ url_prefix }}/static/AdminLTE-2.3.7/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet"
- href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
+ href="{{ url_prefix }}/static/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet"
- href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css">
+ href="{{ url_prefix }}/static/AdminLTE-2.3.7/dist/css/AdminLTE.min.css">
<link rel="stylesheet"
- href="/static/AdminLTE-2.3.7/dist/css/AdminLTE.min.css">
+ href="{{ url_prefix }}/static/AdminLTE-2.3.7/dist/css/skins/skin-blue.min.css">
<link rel="stylesheet"
- href="/static/AdminLTE-2.3.7/dist/css/skins/skin-blue.min.css">
+ href="{{ url_prefix }}/static/AdminLTE-2.3.7/plugins/datatables/jquery.dataTables.min.css">
- <script src="/static/AdminLTE-2.3.7/plugins/jQuery/jquery-2.2.3.min.js"></script>
+ <script src="{{ url_prefix }}/static/AdminLTE-2.3.7/plugins/jQuery/jquery-2.2.3.min.js"></script>
+ <script src="{{ url_prefix }}/static/AdminLTE-2.3.7/plugins/sparkline/jquery.sparkline.min.js"></script>
- <script src="/static/rivets.bundled.min.js"></script>
- <script src="/static/underscore-min.js"></script>
-
- <script src="/static/AdminLTE-2.3.7/bootstrap/js/bootstrap.min.js"></script>
- <script src="/static/AdminLTE-2.3.7/dist/js/app.min.js"></script>
-
- <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script>
+ <script src="{{ url_prefix }}/static/libs/rivets/0.9.6/rivets.bundled.min.js"></script>
+ <script src="{{ url_prefix }}/static/libs/underscore.js/1.8.3/underscore-min.js"></script>
+ <script src="{{ url_prefix }}/static/AdminLTE-2.3.7/bootstrap/js/bootstrap.min.js"></script>
+ <script src="{{ url_prefix }}/static/AdminLTE-2.3.7/dist/js/app.min.js"></script>
+ <script src="{{ url_prefix }}/static/AdminLTE-2.3.7/plugins/datatables/jquery.dataTables.min.js"></script>
+ <script src="{{ url_prefix }}/static/libs/moment.js/2.17.1/moment.min.js"></script>
+ <script src="{{ url_prefix }}/static/libs/Chart.js/2.4.0/Chart.min.js"></script>
<script>
$(document).ready(function(){
var refresh_interval = 5000;
var refresh = function() {
- $.get("/toplevel_data", function(data) {
- _.extend(toplevel_data.health, data.health);
+ $.get("{{ url_prefix }}/toplevel_data", function(data) {
+ _.extend(toplevel_data, data);
setTimeout(refresh, refresh_interval);
});
};
}
}
+ rivets.formatters.health_ok = function(status_str) {
+ if (status_str == "HEALTH_OK") {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
var truncate = function(n, max_width) {
var stringized = n.toString();
var parts = stringized.split(".");
}
}
- rivets.formatters.dimless = function(n){
+ var format_number = function(n, divisor, units) {
var width=4;
- var units = [' ', 'k', 'M', 'G', 'T', 'P'];
var unit = 0;
- while (Math.floor(n / (1000**unit)).toString().length > width - 1) {
+ if (n == null) {
+ // People shouldn't really be passing null, but let's
+ // do something sensible instead of barfing.
+ return "-";
+ }
+
+ while (Math.floor(n / (divisor**unit)).toString().length > width - 1) {
unit = unit + 1;
}
var truncated_float;
if (unit > 0) {
- truncated_float = truncate((n / Math.pow(1000.0, unit)).toString(), width);
+ truncated_float = truncate((n / Math.pow(divisor, unit)).toString(), width);
} else {
truncated_float = truncate(n, width);
}
return truncated_float + units[unit];
+ }
+
+ rivets.formatters.dimless = function(n){
+ return format_number(n, 1000, [' ', 'k', 'M', 'G', 'T', 'P'])
+ };
+ rivets.formatters.dimless_binary = function(n){
+ return format_number(n, 1024, ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB']);
};
- <!--rivet.formatters.mon_summary = function(mon_map) {-->
- <!--}-->
+ rivets.formatters.block_health_color = function(rbd_mirroring) {
+ if (rbd_mirroring.errors > 0) {
+ return "color: #ff0000";
+ } else if (rbd_mirroring.warnings > 0) {
+ return "color: #ffc200";
+ }
+ return "";
+ };
+
+ rivets.formatters.short_version = function(version) {
+ // Expect "ceph version 1.2.3-g9asdasd (as98d7a0s8d7)"
+ var result = /ceph version\s+([^ ]+)\s+\(.+\)/.exec(version);
+ if (result) {
+ // Return the "1.2.3-g9asdasd" part
+ return result[1];
+ } else {
+ // Unexpected format, pass it through
+ return version;
+ }
+ return
+ };
+
+ /* This is useful if you need to display some alternative text
+ * when a collection is empty using rv-hide */
+ rivets.formatters.length = function(val) {
+ return val.length;
+ }
+
+ rivets.formatters.hide_count_box = function(value) {
+ value = +value
+ return (isNaN(value) || value == 0)
+ };
- rivets.bind($("#health"), toplevel_data.health);
+ rivets.bind($("#health"), toplevel_data);
rivets.bind($("section.sidebar"), toplevel_data);
setTimeout(refresh, refresh_interval);
});
</script>
- <link rel="shortcut icon" href="http://ceph.com/wp-content/themes/ceph/favicon.ico">
- <link rel="shortcut icon" href="/static/favicon.ico">
+ <link rel="shortcut icon" href="https://ceph.com/wp-content/themes/cephTheme/Resources/Favicons/favicon-96x96.png">
+ <link rel="shortcut icon" href="{{ url_prefix }}/static/favicon.ico">
+
+ <style>
+ div.box {
+ background-color: #222d32;
+ color: #fff;
+ }
+
+ div.info-box {
+ background-color: #222d32;
+ color: #fff;
+ }
+
+ .box {
+ border-top-color: #b8c7ce;
+ }
+
+ div.box-header {
+ color: #b8c7ce;
+ }
+
+ a.logo {
+ background-color: #222d32;
+ }
+
+ body {
+ background-color: #222d32;
+ }
+
+ .navbar {
+ background-color: #222d32;
+ color: #222d32;
+ }
+
+ div#content {
+ background-color: #424d52;
+ color: #ddd;
+ }
+
+ div.progress-bar {
+ border-width: 1px;
+ border-color: #ddd;
+ }
+
+ .ceph-log {
+ font-family: monospace;
+ background-color: #333;
+ color: #ddd;
+ }
+
+ .nav-tabs>li.active>a {
+ background-color: #424d52;
+ color: #ddd;
+ }
+
+ .navbar a {
+ color: #b8c7ce;
+ }
+
+ .ceph-none-found {
+ color: #8aa4af;
+ font-style: italic;
+ padding-left: 15px;
+ padding-right: 5px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+ }
+
+ table.ceph-chartbox {
+ margin-left: 40px;
+ }
+
+ .ceph-chartbox td {
+ padding-left: 35px;
+ text-align: center;
+ font-weight: bold;
+ }
+
+ .chart-container {
+ width: 100%;
+ height: 100%;
+ }
+
+ .dataTables_wrapper .dataTables_filter {
+ color: #ddd
+ }
+
+ .dataTables_wrapper .dataTables_filter input {
+ color: #222d32
+ }
+
+ .dataTables_wrapper tbody td {
+ background-color: #424d52;
+ color: #ddd;
+ }
+
+ .dataTables_wrapper .dataTables_paginate .ellipsis {
+ color: #ddd !important
+ }
+
+ .dataTables_wrapper .dataTables_paginate .paginate_button {
+ color: #ddd !important
+ }
+
+ .dataTables_wrapper .dataTables_paginate .paginate_button.disabled {
+ color: #424d52 !important
+ }
+
+ .nav-tabs-custom {
+ background-color: #222d32;
+ color: #ddd;
+ }
+ .nav-tabs-custom>.nav-tabs>li{
+ margin-right: 0;
+ }
+ .nav-tabs-custom>.nav-tabs>li>a{
+ border-bottom-color: transparent;
+ color: #aaa;
+ }
+ .nav-tabs-custom>.nav-tabs>li.active>a{
+ background-color: #424d52;
+ color: #eee;
+ }
+ .nav-tabs-custom>.nav-tabs>li.active:hover>a{
+ background-color: #66777f;
+ color: #eee;
+ }
+ .nav-tabs-custom>.tab-content {
+ background-color: #424d52;
+ color: #eee;
+ }
+
+ </style>
+
</head>
-<body class="hold-transition skin-blue sidebar-mini">
+<body class="hold-transition sidebar-mini sidebar-collapse">
<div class="wrapper">
- <!-- Main Header -->
+ <!-- Main Header -->
<header class="main-header">
<!-- Logo -->
- <a href="/" class="logo">
- <!--
- <span class="logo-mini"><b>A</b>LT</span>
- <span class="logo-lg"><b>Admin</b>LTE</span> -->
+ <a href="{{ url_prefix }}/" class="logo">
<span class="logo-lg">
- <img src="/static/Ceph_Logo_Standard_RGB_White_120411_fa.png"
+ <img src="{{ url_prefix }}/static/Ceph_Logo_Standard_RGB_White_120411_fa.png"
width="123px" height="34px"/>
</span>
+ <span class="logo-mini">
+ <img src="{{ url_prefix }}/static/logo-mini.png"
+ width="34px" height="34px"/>
+ </span>
</a>
<!-- Header Navbar -->
<span class="sr-only">Toggle navigation</span>
</a>
- <div id="health" style="font-size: 20px; padding: 12px 12px;">
- Health:
- <span rv-style="overall_status | health_color">
- {overall_status}
+ <div id="health" style="font-size: 18px; padding: 12px 12px;">
+ <span rv-hide="health_status | health_ok" >
+ <span rv-style="health_status | health_color">
+ {health_status}
+ </span>
</span>
</div>
</nav>
</header>
<!-- Left side column. contains the logo and sidebar -->
- <aside class="main-sidebar">
+ <aside class="main-sidebar skin-blue">
<!-- sidebar: style can be found in sidebar.less -->
<section class="sidebar">
<!-- Sidebar Menu -->
<ul class="sidebar-menu">
<!-- Optionally, you can add icons to the links -->
- <li><a href="/health"><i class="fa fa-heart"></i>
+ <li class="{%if path_info=='/' or path_info.startswith('/health')%}active{%endif%}">
+ <a href="{{ url_prefix }}/health">
+ <i class="fa fa-heartbeat" rv-style="health_status | health_color"></i>
<span>Cluster health</span></a>
</li>
- <li><a href="/servers"><i class="fa fa-server"></i>
- <span>Servers</span></a>
+ <li class="treeview{%if path_info.startswith(('/server', '/osd'))%} active{%endif%}">
+ <a href="#"><i class="fa fa-server"></i> <span>Cluster</span>
+ <span class="pull-right-container">
+ <i class="fa fa-angle-left pull-right"></i>
+ </span>
+ </a>
+ <ul class="treeview-menu menu-open">
+ <li>
+ <a href="{{ url_prefix }}/servers">Servers</a>
+ </li>
+ <li>
+ <a href="{{ url_prefix }}/osd">OSDs</a>
+ </li>
+ </ul>
+ </li>
+ <li class="treeview{%if path_info.startswith('/rbd')%} active{%endif%}">
+ <a href="#">
+ <i class="fa fa-hdd-o" rv-style="rbd_mirroring | block_health_color"></i> <span>Block</span>
+ <span class="pull-right-container">
+ <i class="fa fa-angle-left pull-right"></i>
+ </span>
+ </a>
+ <ul class="treeview-menu menu-open">
+ <li>
+ <a href="{{ url_prefix }}/rbd_mirroring">
+ <i class="fa fa-exchange"></i> Mirroring
+ <span class="pull-right-container">
+ <small rv-hide="rbd_mirroring.warnings | hide_count_box" class="label pull-right bg-yellow">{rbd_mirroring.warnings}</small>
+ <small rv-hide="rbd_mirroring.errors | hide_count_box" class="label pull-right bg-red">{rbd_mirroring.errors}</small>
+ </span>
+ </a>
+ </li>
+ <li>
+ <a href="{{ url_prefix }}/rbd_iscsi">
+ <i class="fa fa-upload"></i> iSCSI
+ <span class="pull-right-container" />
+ </a>
+ </li>
+ <li class="treeview{%if path_info.startswith('/rbd_pool')%} active menu-open{%endif%}">
+ <a href="#">
+ <i class="fa fa-dot-circle-o"></i> <span>Pools</span>
+ <span class="pull-right-container">
+ <i class="fa fa-angle-left pull-right"></i>
+ </span>
+ </a>
+ <ul class="treeview-menu">
+ <li rv-each-pool="rbd_pools">
+ <a rv-href="pool.url"><i class="fa fa-circle-o"></i> {pool.name}</a>
+ </li>
+ <li class="ceph-none-found" rv-hide="rbd_pools | length">None found</li>
+ </ul>
+ </li>
+ </ul>
</li>
- <li class="treeview active">
+ <li class="treeview{%if path_info.startswith(('/filesystem/', '/clients/'))%} active{%endif%}">
<a href="#"><i class="fa fa-folder"></i> <span>Filesystems</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
<li rv-each-filesystem="filesystems">
<a rv-href="filesystem.url">{filesystem.name}</a>
</li>
+ <li class="ceph-none-found" rv-hide="filesystems | length">None found</li>
</ul>
</li>
</ul>
<strong>Copyright © 2016 by Ceph Contributors.</strong> Free software (LGPL 2.1)
</footer>
- <!-- Control Sidebar -->
- <aside class="control-sidebar control-sidebar-dark">
- <!-- Create the tabs -->
- <ul class="nav nav-tabs nav-justified control-sidebar-tabs">
- <li class="active"><a href="#control-sidebar-home-tab" data-toggle="tab"><i class="fa fa-home"></i></a></li>
- <li><a href="#control-sidebar-settings-tab" data-toggle="tab"><i class="fa fa-gears"></i></a></li>
- </ul>
- <!-- Tab panes -->
- <div class="tab-content">
- <!-- Home tab content -->
- <div class="tab-pane active" id="control-sidebar-home-tab">
- <h3 class="control-sidebar-heading">Recent Activity</h3>
- <ul class="control-sidebar-menu">
- <li>
- <a href="javascript::;">
- <i class="menu-icon fa fa-birthday-cake bg-red"></i>
-
- <div class="menu-info">
- <h4 class="control-sidebar-subheading">Langdon's Birthday</h4>
-
- <p>Will be 23 on April 24th</p>
- </div>
- </a>
- </li>
- </ul>
- <!-- /.control-sidebar-menu -->
-
- <h3 class="control-sidebar-heading">Tasks Progress</h3>
- <ul class="control-sidebar-menu">
- <li>
- <a href="javascript::;">
- <h4 class="control-sidebar-subheading">
- Custom Template Design
- <span class="pull-right-container">
- <span class="label label-danger pull-right">70%</span>
- </span>
- </h4>
-
- <div class="progress progress-xxs">
- <div class="progress-bar progress-bar-danger" style="width: 70%"></div>
- </div>
- </a>
- </li>
- </ul>
- <!-- /.control-sidebar-menu -->
-
- </div>
- <!-- /.tab-pane -->
- <!-- Stats tab content -->
- <div class="tab-pane" id="control-sidebar-stats-tab">Stats Tab Content</div>
- <!-- /.tab-pane -->
- <!-- Settings tab content -->
- <div class="tab-pane" id="control-sidebar-settings-tab">
- <form method="post">
- <h3 class="control-sidebar-heading">General Settings</h3>
-
- <div class="form-group">
- <label class="control-sidebar-subheading">
- Report panel usage
- <input type="checkbox" class="pull-right" checked>
- </label>
-
- <p>
- Some information about this general settings option
- </p>
- </div>
- <!-- /.form-group -->
- </form>
- </div>
- <!-- /.tab-pane -->
- </div>
- </aside>
- <!-- /.control-sidebar -->
- <!-- Add the sidebar's background. This div must be placed
- immediately after the control sidebar -->
- <div class="control-sidebar-bg"></div>
-
</div>
<!--