disk_detail.html 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864
  1. {% extends "layout.html" %}
  2. {% block head %}
  3. {{ super() }}
  4. <style type="text/css">
  5. @media (min-width: 768px) {
  6. .form-horizontal .control-label {
  7. text-align: left;
  8. }
  9. }
  10. label>span {
  11. color: deepskyblue;
  12. }
  13. #change_disk_quota_form label {
  14. padding-left: 0;
  15. padding-right: 0;
  16. }
  17. .btn,
  18. .form-group>div>div,
  19. .form-control {
  20. border-radius: 0;
  21. }
  22. .table {
  23. font-size: 12px;
  24. border-width: 1px;
  25. line-height: 22px;
  26. }
  27. .table > tbody > tr > td {
  28. color: #424547;
  29. }
  30. .table-bordered > tbody > tr {
  31. padding-top: 10px;
  32. padding-bottom: 10px;
  33. }
  34. .table-bordered > thead > tr > th,
  35. .table-bordered > tbody > tr > th,
  36. .table-bordered > tfoot > tr > th,
  37. .table-bordered > thead > tr > td,
  38. .table-bordered > tbody > tr > td,
  39. .table-bordered > tfoot > tr > td {
  40. border-style: solid;
  41. border-width: 1px 0 0 0;
  42. }
  43. .guest-label {
  44. color: #999999;
  45. }
  46. .guest-desc {
  47. color: #333333;
  48. }
  49. </style>
  50. {% endblock head %}
  51. {% block body %}
  52. <script>
  53. var resource_path = window.location.pathname;
  54. var resource_path_array = resource_path.split('/');
  55. var uuid = resource_path_array[resource_path_array.length - 1];
  56. var datetime_format_type = 'time';
  57. function format_time(timestamp, i) {
  58. if (datetime_format_type === 'time') {
  59. return new Date(timestamp).format('HH:MM');
  60. } else {
  61. return new Date(timestamp).format('mm-dd');
  62. }
  63. }
  64. function render_disk_throughput_chart(disk_uuid, granularity, dev_id, dev_name) {
  65. var url = '/api/guest_performance/disk_io/last_hour/' + disk_uuid;
  66. if (granularity === 'hour') {
  67. url = '/api/guest_performance/disk_io/last_hour/' + disk_uuid
  68. } else if (granularity === 'six_hours') {
  69. url = '/api/guest_performance/disk_io/last_six_hours/' + disk_uuid
  70. } else if (granularity === 'day') {
  71. url = '/api/guest_performance/disk_io/last_day/' + disk_uuid
  72. } else {
  73. url = '/api/guest_performance/disk_io/last_seven_days/' + disk_uuid
  74. }
  75. $.ajax({
  76. url : url,
  77. type : 'GET',
  78. contentType: "application/json; charset=utf-8",
  79. dataType: 'json',
  80. error : function() {
  81. alter_danger('获取图表数据失败失败!');
  82. },
  83. success : function(data, textStatus, xhr) {
  84. if (data.data.length > 1) {
  85. if ((data.data[data.data.length - 1]['timestamp'] - data.data[0]['timestamp']) >= 86400) {
  86. datetime_format_type = 'date';
  87. }
  88. }
  89. var option = {
  90. color: ['#3BC0FF', '#FAB406'],
  91. title: {
  92. text: '磁盘吞吐量 - ' + dev_name
  93. },
  94. legend: {
  95. data:['读(MBps)', '写(MBps)'],
  96. bottom: 5
  97. },
  98. toolbox: {
  99. feature: {
  100. dataZoom: {
  101. yAxisIndex: 'none'
  102. },
  103. magicType: {type: ['line', 'bar']},
  104. saveAsImage: {
  105. show: true,
  106. pixelRatio: 4
  107. }
  108. }
  109. },
  110. tooltip: {
  111. show: true,
  112. trigger: 'axis',
  113. formatter: (function (params, ticket, callback) {
  114. var readSeriesName = params[0].seriesName;
  115. var writeSeriesName = params[1].seriesName;
  116. var read = params[0].data[1];
  117. var write = params[1].data[1];
  118. var readMarker = params[0].marker;
  119. var writeMarker = params[1].marker;
  120. var datetime = new Date(params[0].data[0]).format('yyyy-mm-dd HH:MM:ss');
  121. if (read === null) {
  122. read = '无数据';
  123. }
  124. if (write === null) {
  125. write = '无数据';
  126. }
  127. return datetime + '<br />' + [readMarker, readSeriesName, read].join(' ') +
  128. '<br />' + [writeMarker, writeSeriesName, write].join(' ')
  129. })
  130. },
  131. xAxis: {
  132. type: 'time',
  133. axisTick: {
  134. show: false
  135. },
  136. axisLine: {
  137. lineStyle: {
  138. opacity: 0.1,
  139. color: '#3d4245'
  140. }
  141. },
  142. splitLine: {
  143. show: false
  144. },
  145. axisLabel: {
  146. formatter: format_time
  147. }
  148. },
  149. yAxis: {
  150. min: 0,
  151. max: 'dataMax',
  152. minInterval: 2,
  153. axisTick: {
  154. show: false
  155. },
  156. axisLine: {
  157. lineStyle: {
  158. opacity: 0,
  159. color: '#8c8f91'
  160. }
  161. },
  162. splitLine: {
  163. show: true,
  164. lineStyle: {
  165. width: 1,
  166. opacity: 0.5
  167. }
  168. }
  169. },
  170. series: [{
  171. name: '读(MBps)',
  172. type: 'line',
  173. showSymbol: false,
  174. smooth: true,
  175. lineStyle: {
  176. normal: {
  177. width: 1
  178. }
  179. },
  180. data: (function () {
  181. var d = [];
  182. $.each(data.data, function(i, ele) {
  183. d.push([
  184. ele['timestamp'] * 1000,
  185. ele['rd_bytes'] !== null ? Math.floor(ele['rd_bytes'] / 1024 / 1024 * 1000) / 1000 : null
  186. ])
  187. });
  188. return d;
  189. })()
  190. },{
  191. name: '写(MBps)',
  192. type: 'line',
  193. showSymbol: false,
  194. smooth: true,
  195. lineStyle: {
  196. normal: {
  197. width: 1
  198. }
  199. },
  200. data: (function () {
  201. var d = [];
  202. $.each(data.data, function(i, ele) {
  203. d.push([
  204. ele['timestamp'] * 1000,
  205. ele['wr_bytes'] !== null ? Math.floor(ele['wr_bytes'] / 1024 / 1024 * 1000) / 1000 : null
  206. ])
  207. });
  208. return d;
  209. })()
  210. }]
  211. };
  212. var disk_chart = echarts.init(document.getElementById(dev_id));
  213. disk_chart.setOption(option);
  214. }
  215. });
  216. }
  217. function render_disk_iops_chart(disk_uuid, granularity, dev_id, dev_name) {
  218. var url = '/api/guest_performance/disk_io/last_hour/' + disk_uuid;
  219. if (granularity === 'hour') {
  220. url = '/api/guest_performance/disk_io/last_hour/' + disk_uuid
  221. } else if (granularity === 'six_hours') {
  222. url = '/api/guest_performance/disk_io/last_six_hours/' + disk_uuid
  223. } else if (granularity === 'day') {
  224. url = '/api/guest_performance/disk_io/last_day/' + disk_uuid
  225. } else {
  226. url = '/api/guest_performance/disk_io/last_seven_days/' + disk_uuid
  227. }
  228. $.ajax({
  229. url : url,
  230. type : 'GET',
  231. contentType: "application/json; charset=utf-8",
  232. dataType: 'json',
  233. error : function() {
  234. alter_danger('获取图表数据失败失败!');
  235. },
  236. success : function(data, textStatus, xhr) {
  237. if (data.data.length > 1) {
  238. if ((data.data[data.data.length - 1]['timestamp'] - data.data[0]['timestamp']) >= 86400) {
  239. datetime_format_type = 'date';
  240. }
  241. }
  242. var option = {
  243. color: ['#3BC0FF', '#FAB406'],
  244. title: {
  245. text: '磁盘IOPS - ' + dev_name
  246. },
  247. legend: {
  248. data:['读(IOPS)', '写(IOPS)'],
  249. bottom: 5
  250. },
  251. toolbox: {
  252. feature: {
  253. dataZoom: {
  254. yAxisIndex: 'none'
  255. },
  256. magicType: {type: ['line', 'bar']},
  257. saveAsImage: {
  258. show: true,
  259. pixelRatio: 4
  260. }
  261. }
  262. },
  263. tooltip: {
  264. show: true,
  265. trigger: 'axis',
  266. formatter: (function (params, ticket, callback) {
  267. var readSeriesName = params[0].seriesName;
  268. var writeSeriesName = params[1].seriesName;
  269. var read = params[0].data[1];
  270. var write = params[1].data[1];
  271. var readMarker = params[0].marker;
  272. var writeMarker = params[1].marker;
  273. var datetime = new Date(params[0].data[0]).format('yyyy-mm-dd HH:MM:ss');
  274. if (read === null) {
  275. read = '无数据';
  276. }
  277. if (write === null) {
  278. write = '无数据';
  279. }
  280. return datetime + '<br />' + [readMarker, readSeriesName, read].join(' ') +
  281. '<br />' + [writeMarker, writeSeriesName, write].join(' ')
  282. })
  283. },
  284. xAxis: {
  285. type: 'time',
  286. axisTick: {
  287. show: false
  288. },
  289. axisLine: {
  290. lineStyle: {
  291. opacity: 0.1,
  292. color: '#3d4245'
  293. }
  294. },
  295. splitLine: {
  296. show: false
  297. },
  298. axisLabel: {
  299. formatter: format_time
  300. }
  301. },
  302. yAxis: {
  303. min: 0,
  304. max: 'dataMax',
  305. minInterval: 2,
  306. axisTick: {
  307. show: false
  308. },
  309. axisLine: {
  310. lineStyle: {
  311. opacity: 0,
  312. color: '#8c8f91'
  313. }
  314. },
  315. splitLine: {
  316. show: true,
  317. lineStyle: {
  318. width: 1,
  319. opacity: 0.5
  320. }
  321. }
  322. },
  323. series: [{
  324. name: '读(IOPS)',
  325. type: 'line',
  326. showSymbol: false,
  327. smooth: true,
  328. lineStyle: {
  329. normal: {
  330. width: 1
  331. }
  332. },
  333. data: (function () {
  334. var d = [];
  335. $.each(data.data, function(i, ele) {
  336. d.push([
  337. ele['timestamp'] * 1000,
  338. ele['rd_req'] !== null ? ele['rd_req'] : null
  339. ])
  340. });
  341. return d;
  342. })()
  343. },{
  344. name: '写(IOPS)',
  345. type: 'line',
  346. showSymbol: false,
  347. smooth: true,
  348. lineStyle: {
  349. normal: {
  350. width: 1
  351. }
  352. },
  353. data: (function () {
  354. var d = [];
  355. $.each(data.data, function(i, ele) {
  356. d.push([
  357. ele['timestamp'] * 1000,
  358. ele['wr_req'] !== null ? ele['wr_req'] : null
  359. ])
  360. });
  361. return d;
  362. })()
  363. }]
  364. };
  365. var disk_chart = echarts.init(document.getElementById(dev_id));
  366. disk_chart.setOption(option);
  367. }
  368. });
  369. }
  370. function render_disks_chart(uuid, granularity) {
  371. var dev_name = '{{ disk_ret.data.device }}';
  372. var dev_id_throughput = 'disk_throughput_chart';
  373. var dev_id_iops = 'disk_iops_chart';
  374. render_disk_throughput_chart(uuid, granularity, dev_id_throughput, dev_name);
  375. render_disk_iops_chart(uuid, granularity, dev_id_iops, dev_name);
  376. }
  377. $(document).ready(function() {
  378. $('body').addClass('add-transition');
  379. $('.add-page-transition').on('click', function(){
  380. var transAttr = $(this).attr('data-transition');
  381. $('.add-transition').attr('class', 'add-transition');
  382. $('.add-transition').addClass(transAttr);
  383. });
  384. render_disks_chart(uuid, 'hour');
  385. register_iops_bps_event();
  386. });
  387. function refresh_render_with_specify_granularity(granularity) {
  388. render_disks_chart(uuid, granularity)
  389. }
  390. function refresh() {
  391. window.location.href=window.location.pathname;
  392. }
  393. function update_disk_quota(uuids) {
  394. $.ajax({
  395. url : '/api/disks/' + uuids.join(','),
  396. type : 'PATCH',
  397. contentType: "application/json; charset=utf-8",
  398. data : JSON.stringify({
  399. iops: parseInt($('#iops').val()),
  400. iops_rd: parseInt($('#iops_rd').val()),
  401. iops_wr: parseInt($('#iops_wr').val()),
  402. iops_max: parseInt($('#iops_max').val()),
  403. iops_max_length: parseInt($('#iops_max_length').val()),
  404. bps: parseInt($('#bps').val()) * 1024 * 1024,
  405. bps_rd: parseInt($('#bps_rd').val()) * 1024 * 1024,
  406. bps_wr: parseInt($('#bps_wr').val()) * 1024 * 1024,
  407. bps_max: parseInt($('#bps_max').val()) * 1024 * 1024,
  408. bps_max_length: parseInt($('#bps_max_length').val())
  409. }),
  410. error : function() {
  411. alter_danger('变更磁盘性能配额指令发送失败!');
  412. },
  413. success : function() {
  414. alter_success('变更磁盘性能配额指令发送成功!');
  415. refresh();
  416. }
  417. });
  418. }
  419. function change_disk_quota() {
  420. var uuids = [uuid];
  421. if (uuids) {
  422. update_disk_quota(uuids);
  423. }
  424. $('#change_disk_quota_modal').modal('hide');
  425. }
  426. $(function() { "use strict";
  427. $("#iops").TouchSpin({
  428. max: {{ config_ret.data.iops_cap }},
  429. min: 0,
  430. verticalbuttons: true,
  431. verticalupclass: 'glyph-icon icon-plus',
  432. verticaldownclass: 'glyph-icon icon-minus'
  433. });
  434. });
  435. $(function() { "use strict";
  436. $("#iops_rd").TouchSpin({
  437. max: {{ config_ret.data.iops_cap - disk_ret.data.iops_wr }},
  438. min: 0,
  439. verticalbuttons: true,
  440. verticalupclass: 'glyph-icon icon-plus',
  441. verticaldownclass: 'glyph-icon icon-minus'
  442. });
  443. });
  444. $(function() { "use strict";
  445. $("#iops_wr").TouchSpin({
  446. max: {{ config_ret.data.iops_cap - disk_ret.data.iops_rd }},
  447. min: 0,
  448. verticalbuttons: true,
  449. verticalupclass: 'glyph-icon icon-plus',
  450. verticaldownclass: 'glyph-icon icon-minus'
  451. });
  452. });
  453. $(function() { "use strict";
  454. $("#iops_max").TouchSpin({
  455. max: {{ config_ret.data.iops_max }},
  456. min: 0,
  457. verticalbuttons: true,
  458. verticalupclass: 'glyph-icon icon-plus',
  459. verticaldownclass: 'glyph-icon icon-minus'
  460. });
  461. });
  462. $(function() { "use strict";
  463. $("#iops_max_length").TouchSpin({
  464. max: {{ config_ret.data.iops_max_length }},
  465. min: 0,
  466. postfix: '秒',
  467. verticalbuttons: true,
  468. verticalupclass: 'glyph-icon icon-plus',
  469. verticaldownclass: 'glyph-icon icon-minus'
  470. });
  471. });
  472. $(function() { "use strict";
  473. $("#bps").TouchSpin({
  474. max: {{ (config_ret.data.bps_cap / 1024 / 1024) | int }},
  475. min: 0,
  476. postfix: 'MiB',
  477. verticalbuttons: true,
  478. verticalupclass: 'glyph-icon icon-plus',
  479. verticaldownclass: 'glyph-icon icon-minus'
  480. });
  481. });
  482. $(function() { "use strict";
  483. $("#bps_rd").TouchSpin({
  484. max: {{ ((config_ret.data.bps_cap - disk_ret.data.bps_wr) / 1024 / 1024) | int }},
  485. min: 0,
  486. postfix: 'MiB',
  487. verticalbuttons: true,
  488. verticalupclass: 'glyph-icon icon-plus',
  489. verticaldownclass: 'glyph-icon icon-minus'
  490. });
  491. });
  492. $(function() { "use strict";
  493. $("#bps_wr").TouchSpin({
  494. max: {{ ((config_ret.data.bps_cap - disk_ret.data.bps_rd) / 1024 / 1024) | int }},
  495. min: 0,
  496. postfix: 'MiB',
  497. verticalbuttons: true,
  498. verticalupclass: 'glyph-icon icon-plus',
  499. verticaldownclass: 'glyph-icon icon-minus'
  500. });
  501. });
  502. $(function() { "use strict";
  503. $("#bps_max").TouchSpin({
  504. max: {{ (config_ret.data.bps_max / 1024 / 1024) | int }},
  505. min: 0,
  506. postfix: 'MiB',
  507. verticalbuttons: true,
  508. verticalupclass: 'glyph-icon icon-plus',
  509. verticaldownclass: 'glyph-icon icon-minus'
  510. });
  511. });
  512. $(function() { "use strict";
  513. $("#bps_max_length").TouchSpin({
  514. max: {{ config_ret.data.bps_max_length }},
  515. min: 0,
  516. postfix: '秒',
  517. verticalbuttons: true,
  518. verticalupclass: 'glyph-icon icon-plus',
  519. verticaldownclass: 'glyph-icon icon-minus'
  520. });
  521. });
  522. function register_iops_bps_event() {
  523. $('#iops').on('change', function(){
  524. $("#iops_rd").trigger("touchspin.updatesettings", {max: $('#iops').val() - $('#iops_wr').val()});
  525. $("#iops_wr").trigger("touchspin.updatesettings", {max: $('#iops').val() - $('#iops_rd').val()});
  526. });
  527. $('#iops_rd').on('change', function(){
  528. $("#iops_wr").trigger("touchspin.updatesettings", {max: $('#iops').val() - $('#iops_rd').val()});
  529. });
  530. $('#iops_wr').on('change', function(){
  531. $("#iops_rd").trigger("touchspin.updatesettings", {max: $('#iops').val() - $('#iops_wr').val()});
  532. });
  533. $('#bps').on('change', function(){
  534. $("#bps_rd").trigger("touchspin.updatesettings", {max: $('#bps').val() - $('#bps_wr').val()});
  535. $("#bps_wr").trigger("touchspin.updatesettings", {max: $('#bps').val() - $('#bps_rd').val()});
  536. });
  537. $('#bps_rd').on('change', function(){
  538. $("#bps_wr").trigger("touchspin.updatesettings", {max: $('#bps').val() - $('#bps_rd').val()});
  539. });
  540. $('#bps_wr').on('change', function(){
  541. $("#bps_rd").trigger("touchspin.updatesettings", {max: $('#bps').val() - $('#bps_wr').val()});
  542. });
  543. }
  544. </script>
  545. <div class="container" style="padding-top: 100px; width: 90%; max-width: 100%;">
  546. <div class="panel">
  547. <div class="panel-body">
  548. <a href="javascript:history.go(-1)" class="btn btn-xs btn-default add-page-transition" data-transition="pt-page-moveFromLeft-init" style="margin-bottom: 4px; margin-left: 10px;">
  549. <span class="glyph-icon icon-separator" style="transform: rotateY(-180deg);">
  550. <i class="glyph-icon icon-level-up"></i>
  551. </span>
  552. <span class="button-content">
  553. 返回
  554. </span>
  555. </a>
  556. <div class="row" style="margin-top: 10px;">
  557. <div class="col-xs-4">
  558. <div style="background: #F5f6FA; border: 1px solid #e1e6eb; padding: 10px; font-size: 14px; width: 100%;">
  559. <span>
  560. 磁盘信息
  561. </span>
  562. </div>
  563. <table class="table table-bordered">
  564. <tbody>
  565. <tr>
  566. <td>
  567. <span class="guest-label">UUID:&nbsp;&nbsp;&nbsp;&nbsp;</span>
  568. <span class="guest-desc">
  569. {{ disk_ret.data.uuid }}
  570. </span>
  571. </td>
  572. </tr>
  573. <tr>
  574. <td>
  575. <span class="guest-label">名称:&nbsp;&nbsp;&nbsp;&nbsp;</span>
  576. <span class="guest-desc">
  577. {{ disk_ret.data.remark }}
  578. </span>
  579. </td>
  580. </tr>
  581. <tr>
  582. <td>
  583. <span class="guest-label">状态:&nbsp;&nbsp;&nbsp;&nbsp;</span>
  584. <span class="guest-desc">
  585. {{ format_disk_state(disk_ret.data.state)|safe }}
  586. </span>
  587. </td>
  588. </tr>
  589. <tr>
  590. <td>
  591. <span class="guest-label">磁盘性别:&nbsp;&nbsp;&nbsp;&nbsp;</span>
  592. <span class="guest-desc">
  593. {% if disk_ret.data.sequence == 0 %}
  594. 系统盘
  595. {% else %}
  596. 数据盘
  597. {% endif %}
  598. </span>
  599. </td>
  600. </tr>
  601. <tr>
  602. <td>
  603. <span class="guest-label">磁盘容量:&nbsp;&nbsp;&nbsp;&nbsp;</span>
  604. <span class="guest-desc">
  605. {{ disk_ret.data.size }} GB
  606. </span>
  607. </td>
  608. </tr>
  609. <tr>
  610. <td>
  611. <span class="guest-label">所属虚拟机:&nbsp;&nbsp;&nbsp;&nbsp;</span>
  612. <span class="guest-desc">
  613. {% if disk_ret.data.sequence != -1 %}
  614. <a href="/guest/detail/{{ disk_ret.data.guest_uuid }}">{{ guest_ret.data.label }}/{{ guest_ret.data.remark }}</a>
  615. {% else %}
  616. {% endif %}
  617. </span>
  618. </td>
  619. </tr>
  620. <tr>
  621. <td>
  622. <span class="guest-label">设备路径:&nbsp;&nbsp;&nbsp;&nbsp;</span>
  623. <span class="guest-desc">
  624. {% if disk_ret.data.sequence >= 0 %}
  625. {{ disk_ret.data.device }}
  626. {% endif %}
  627. </span>
  628. </td>
  629. </tr>
  630. <tr>
  631. <td style="padding: 0;">
  632. <table style="width: 100%;">
  633. <thead>
  634. <tr class="guest-label">
  635. <th width="100%" colspan="5" style="padding: 0 9px;">
  636. <span style="position: absolute; left: 41.2%;">
  637. 磁盘性能配额
  638. </span>
  639. <button class="btn btn-xs btn-default btn-shortcut" style="float: right;" data-toggle="modal" data-target="#change_disk_quota_modal">变更配额</button>
  640. </th>
  641. </tr>
  642. <tr class="guest-label">
  643. <th width="20%" style="padding: 0 9px; text-align: center;">IOPS</th>
  644. <th width="20%" style="padding: 0 9px; text-align: center;">IOPS 读</th>
  645. <th width="20%" style="padding: 0 9px; text-align: center;">IOPS 写</th>
  646. <th width="20%" style="padding: 0 9px; text-align: center;">IOPS 桶宽</th>
  647. <th width="20%" style="padding: 0 9px; text-align: center;">IOPS 桶高</th>
  648. </tr>
  649. </thead>
  650. <tbody>
  651. <tr class="guest-desc">
  652. <th style="text-align: center;">{{ disk_ret.data.iops }}</th>
  653. <th style="text-align: center;">{{ disk_ret.data.iops_rd }}</th>
  654. <th style="text-align: center;">{{ disk_ret.data.iops_wr }}</th>
  655. <th style="text-align: center;">{{ disk_ret.data.iops_max }}</th>
  656. <th style="text-align: center;">{{ disk_ret.data.iops_max_length }} 秒</th>
  657. </tr>
  658. </tbody>
  659. <thead>
  660. <tr class="guest-label">
  661. <th width="20%" style="padding: 0 9px; text-align: center;">BPS</th>
  662. <th width="20%" style="padding: 0 9px; text-align: center;">BPS 读</th>
  663. <th width="20%" style="padding: 0 9px; text-align: center;">BPS 写</th>
  664. <th width="20%" style="padding: 0 9px; text-align: center;">BPS 桶宽</th>
  665. <th width="20%" style="padding: 0 9px; text-align: center;">BPS 桶高</th>
  666. </tr>
  667. </thead>
  668. <tbody>
  669. <tr class="guest-desc">
  670. <th style="text-align: center;">{{ (disk_ret.data.bps / 1024 / 1024) | int }} MiB</th>
  671. <th style="text-align: center;">{{ (disk_ret.data.bps_rd / 1024 / 1024) | int }} MiB</th>
  672. <th style="text-align: center;">{{ (disk_ret.data.bps_wr / 1024 / 1024) | int }} MiB</th>
  673. <th style="text-align: center;">{{ (disk_ret.data.bps_max / 1024 / 1024) | int }} MiB</th>
  674. <th style="text-align: center;">{{ disk_ret.data.bps_max_length }} 秒</th>
  675. </tr>
  676. </tbody>
  677. </table>
  678. </td>
  679. </tr>
  680. <tr>
  681. <td>
  682. <span class="guest-label">创建时间:&nbsp;&nbsp;&nbsp;&nbsp;</span>
  683. <span class="guest-desc">
  684. {{ format_datetime_by_tus(disk_ret.data.create_time) }}
  685. </span>
  686. </td>
  687. </tr>
  688. </tbody>
  689. </table>
  690. </div>
  691. <div class="col-xs-8">
  692. <div class="row" style="margin-bottom: 20px;">
  693. <div class="col-xs-8"></div>
  694. <div class="col-xs-4">
  695. <div class="btn-group btn-group-justified btn-group-xs">
  696. <a class="btn btn-default" role="button" onclick="refresh_render_with_specify_granularity('hour');">1小时</a>
  697. <a class="btn btn-default" role="button" onclick="refresh_render_with_specify_granularity('six_hours');">6小时</a>
  698. <a class="btn btn-default" role="button" onclick="refresh_render_with_specify_granularity('day');">1天</a>
  699. <a class="btn btn-default" role="button" onclick="refresh_render_with_specify_granularity('seven_days');">7天</a>
  700. </div>
  701. </div>
  702. </div>
  703. <div>
  704. <div id="disk_throughput_chart" style="width: 800px;height:280px;"></div>
  705. <div id="disk_iops_chart" style="width: 800px;height:280px;"></div>
  706. </div>
  707. <div id="disks_chart"></div>
  708. </div>
  709. </div>
  710. </div>
  711. </div>
  712. </div>
  713. <div class="modal" id="change_disk_quota_modal" tabindex="-1" role="dialog" style="margin-top: 100px;">
  714. <div class="modal-dialog modal-lg">
  715. <div class="modal-content">
  716. <div class="modal-header">
  717. <h4 class="modal-title">变更磁盘配额:</h4>
  718. </div>
  719. <div class="modal-body" style="padding-left: 8%;">
  720. <form id="change_disk_quota_form" class="form-horizontal bordered-row">
  721. <div class="form-group" style="margin-bottom: 0;">
  722. <label class="col-sm-2 control-label">
  723. <span class="glyph-icon icon-exchange" style="transform: rotate(90deg); display: inline-flex;"></span>
  724. &nbsp;&nbsp;IOPS
  725. </label>
  726. <div class="col-sm-3">
  727. <input id="iops" title="IOPS" class="form-control" type="text" value="{{ disk_ret.data.iops }}" name="iops">
  728. </div>
  729. <span class="col-sm-1"></span>
  730. <label class="col-sm-2 control-label"><span class="glyph-icon icon-openid"></span>&nbsp;&nbsp;BPS</label>
  731. <div class="col-sm-3">
  732. <input id="bps" title="BPS" class="form-control" type="text" value="{{ (disk_ret.data.bps / 1024 / 1024) | int }}" name="bps">
  733. </div>
  734. <span class="col-sm-1"></span>
  735. </div>
  736. <div class="form-group" style="margin-bottom: 0;">
  737. <label class="col-sm-2 control-label">
  738. <span class="glyph-icon icon-exchange" style="transform: rotate(90deg); display: inline-flex;"></span>
  739. &nbsp;&nbsp;IOPS 读
  740. </label>
  741. <div class="col-sm-3">
  742. <input id="iops_rd" title="IOPS 读" class="form-control" type="text" value="{{ disk_ret.data.iops_rd }}" name="iops_rd">
  743. </div>
  744. <span class="col-sm-1"></span>
  745. <label class="col-sm-2 control-label"><span class="glyph-icon icon-openid"></span>&nbsp;&nbsp;BPS 读</label>
  746. <div class="col-sm-3">
  747. <input id="bps_rd" title="BPS 读" class="form-control" type="text" value="{{ (disk_ret.data.bps_rd / 1024 / 1024) | int }}" name="bps_rd">
  748. </div>
  749. <span class="col-sm-1"></span>
  750. </div>
  751. <div class="form-group" style="margin-bottom: 0;">
  752. <label class="col-sm-2 control-label">
  753. <span class="glyph-icon icon-exchange" style="transform: rotate(90deg); display: inline-flex;"></span>
  754. &nbsp;&nbsp;IOPS 写
  755. </label>
  756. <div class="col-sm-3">
  757. <input id="iops_wr" title="IOPS 写" class="form-control" type="text" value="{{ disk_ret.data.iops_wr }}" name="iops_wr">
  758. </div>
  759. <span class="col-sm-1"></span>
  760. <label class="col-sm-2 control-label"><span class="glyph-icon icon-openid"></span>&nbsp;&nbsp;BPS 写</label>
  761. <div class="col-sm-3">
  762. <input id="bps_wr" title="BPS 写" class="form-control" type="text" value="{{ (disk_ret.data.bps_wr / 1024 / 1024) | int }}" name="bps_wr">
  763. </div>
  764. <span class="col-sm-1"></span>
  765. </div>
  766. <div class="form-group" style="margin-bottom: 0;">
  767. <label class="col-sm-2 control-label">
  768. <span class="glyph-icon icon-exchange" style="transform: rotate(90deg); display: inline-flex;"></span>
  769. <span class="glyph-icon icon-bitbucket" style="margin-left: -4px;"></span>
  770. &nbsp;&nbsp;IOPS 桶宽
  771. </label>
  772. <div class="col-sm-3">
  773. <input id="iops_max" title="IOPS 桶宽" class="form-control" type="text" value="{{ disk_ret.data.iops_max }}" name="iops_max">
  774. </div>
  775. <span class="col-sm-1"></span>
  776. <label class="col-sm-2 control-label"><span class="glyph-icon icon-openid"></span><span class="glyph-icon icon-bitbucket"></span>&nbsp;&nbsp;BPS 桶宽</label>
  777. <div class="col-sm-3">
  778. <input id="bps_max" title="BPS 桶宽" class="form-control" type="text" value="{{ (disk_ret.data.bps_max / 1024 / 1024) | int }}" name="bps_max">
  779. </div>
  780. <span class="col-sm-1"></span>
  781. </div>
  782. <div class="form-group" style="margin-bottom: 0;">
  783. <label class="col-sm-2 control-label">
  784. <span class="glyph-icon icon-exchange" style="transform: rotate(90deg); display: inline-flex;"></span>
  785. <span class="glyph-icon icon-bitbucket" style="margin-left: -4px;"></span>
  786. &nbsp;&nbsp;IOPS 桶高
  787. </label>
  788. <div class="col-sm-3">
  789. <input id="iops_max_length" title="IOPS 桶高" class="form-control" type="text" value="{{ disk_ret.data.iops_max_length }}" name="iops_max_length">
  790. </div>
  791. <span class="col-sm-1"></span>
  792. <label class="col-sm-2 control-label"><span class="glyph-icon icon-openid"></span><span class="glyph-icon icon-bitbucket"></span>&nbsp;&nbsp;BPS 桶高</label>
  793. <div class="col-sm-3">
  794. <input id="bps_max_length" title="BPS 桶高" class="form-control" type="text" value="{{ disk_ret.data.bps_max_length }}" name="bps_max_length">
  795. </div>
  796. <span class="col-sm-1"></span>
  797. </div>
  798. </form>
  799. </div>
  800. <div class="modal-footer">
  801. <button type="button" class="btn btn-sm btn-primary" onclick="change_disk_quota();">确定</button>
  802. <button type="button" class="btn btn-sm btn-default" data-dismiss="modal">取消</button>
  803. </div>
  804. </div>
  805. </div>
  806. </div>
  807. {% endblock body %}