poolList.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <link rel="stylesheet" href="../../script/semantic/semantic.min.css">
  6. <script type="text/javascript" src="../../script/jquery.min.js"></script>
  7. <script type="text/javascript" src="../../script/semantic/semantic.min.js"></script>
  8. <title>Storage Pool Manager</title>
  9. <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  10. <style>
  11. .svg-icon {
  12. display: inline-flex;
  13. align-self: center;
  14. }.svg-icon svg {
  15. height:1em;
  16. width:1em;
  17. }
  18. </style>
  19. </head>
  20. <body>
  21. <div class="ui container">
  22. <div class="ui basic segment">
  23. <h3 class="ui header">
  24. Storage Pools
  25. <div class="sub header">Manage system and permission group storage pools</div>
  26. </h3>
  27. </div>
  28. <div class="ui stackable grid">
  29. <div class="six wide column">
  30. <p>Select a Storage Pool to edit</p>
  31. <select id="poolNameList" class="ui search fluid dropdown" onchange="updatePoolSelection(this.value)">
  32. <option value="">Storage Pool</option>
  33. </select>
  34. <div class="ui divider"></div>
  35. <div id="poolStorageList">
  36. </div>
  37. <button class="ui green fluid disabled button selectedOnly" onclick="editSelectedPool();"><i class="edit icon"></i> Edit Storage Pool</button>
  38. <div class="ui divider"></div>
  39. <div class="ui red segment">
  40. <h4>Danger Zone</h4>
  41. <p>The following buttons will unmount storage pool and remount them from configuration file.</p>
  42. <button class="ui red basic fluid disabled button selectedOnly" style="margin-top: 8px;" onclick="reloadSelectedStoragePool();"><i class="refresh icon"></i> Reload Selected Pool</button>
  43. <button class="ui red basic fluid button" style="margin-top: 8px;" onclick="reloadAllStoragePool();"><i class="refresh icon"></i> Reload All Storage Pool</button>
  44. </div>
  45. </div>
  46. <div class="ten wide column">
  47. <p>Current Storage Pool Structure</p>
  48. <div id="poolList" class="ui list">
  49. <div class="item">
  50. <i class="spinner icon"></i>
  51. <div class="content">
  52. <div class="header">Loading</div>
  53. <div class="description"></div>
  54. </div>
  55. </div>
  56. </div>
  57. </div>
  58. </div>
  59. </div>
  60. <div id="ok" class="ui basic modal">
  61. <div class="ui icon header">
  62. <i class="green checkmark icon"></i>
  63. Storage Pool Reloaded
  64. </div>
  65. <div class="content" align="center">
  66. <p>Storage Pool has successfully reloaded.</p>
  67. </div>
  68. <div class="actions">
  69. <div class="ui green ok inverted button">
  70. <i class="checkmark icon"></i>
  71. OK
  72. </div>
  73. </div>
  74. </div>
  75. <script>
  76. var selectedStoragePool = "";
  77. var storagePoolList = [];
  78. //Create all elements
  79. $(".ui.dropdown").dropdown();
  80. //Render the poollist
  81. loadStoragePoolList();
  82. function loadStoragePoolList(){
  83. $("#poolList").html("");
  84. $.get("../../system/storage/pool/list", function(data){
  85. if (data.error !== undefined){
  86. $("#poolList").html("<p>" + data.error + "</p>");
  87. }else{
  88. $("#poolNameList").html(`<option value="">Storage Pools</option>`);
  89. storagePoolList = data;
  90. data.forEach(storagePool => {
  91. //Add Options
  92. $("#poolNameList").append(`<option value="${storagePool.Owner}">${storagePool.Owner}</option>`);
  93. //Render the pool diagram
  94. let desc = "";
  95. if (storagePool.Owner == "system"){
  96. desc = " (Base Pool)"
  97. }
  98. let spHTML = `<div class="item">
  99. <i class="server icon"></i>
  100. <div class="content">
  101. <div class="header">${storagePool.Owner + desc}</div>
  102. <div class="description">Other's Permission: ${storagePool.OtherPermission}</div>
  103. <div class="list">`;
  104. if (storagePool.Storages !== null && storagePool.Storages.length > 0){
  105. storagePool.Storages.forEach(fsh => {
  106. var diskIcon = `grey disk icon`;
  107. if (fsh.Hierarchy == "backup"){
  108. diskIcon = `green refresh icon`
  109. }else if (fsh.Hierarchy == "user"){
  110. diskIcon = `blue disk icon`;
  111. }
  112. spHTML += (`<div class="item">
  113. <i class="${diskIcon}"></i>
  114. <div class="content">
  115. <div class="header">${fsh.Name} (${fsh.UUID}:/)</div>
  116. <div class="description">
  117. <div class="ui breadcrumb">
  118. Mount Point: ${fsh.Path}
  119. <span class="divider">|</span>
  120. Hierarchy: ${fsh.Hierarchy}
  121. <span class="divider">|</span>
  122. ReadOnly: ${fsh.ReadOnly}
  123. </div>
  124. </div>
  125. </div>
  126. </div>`);
  127. });
  128. }else{
  129. spHTML += `<div class="item">
  130. <i class="remove icon"></i>
  131. <div class="content">No storage found under this Storage Pool</div>`;
  132. }
  133. spHTML += (`
  134. </div>
  135. </div>
  136. </div>`);
  137. $("#poolList").append(spHTML);
  138. });
  139. }
  140. });
  141. }
  142. function updatePoolSelection(value){
  143. $("#poolStorageList").html("");
  144. $.get("../../system/storage/pool/list", function(data){
  145. if (data.error !== undefined){
  146. $("#poolList").html("<p>" + data.error + "</p>");
  147. }else{
  148. //List the fshandlers inside this storage pool
  149. var targetStoragePool = undefined;
  150. storagePoolList = data;
  151. data.forEach(sp => {
  152. if (sp.Owner == value){
  153. targetStoragePool = sp;
  154. }
  155. });
  156. if (targetStoragePool == undefined){
  157. $("#poolStorageList").html(`
  158. <div class="ui red inverted segment">
  159. <i class="remove icon"></i>Selected Storage Pool Not Found
  160. </div>
  161. `);
  162. $(".selectedOnly").addClass('disabled');
  163. return
  164. }
  165. selectedStoragePool = value;
  166. $(".selectedOnly").removeClass('disabled');
  167. }
  168. });
  169. }
  170. function editSelectedPool(){
  171. if (selectedStoragePool == ""){
  172. console.log("Pool not selected: ", selectedStoragePool)
  173. return
  174. }
  175. ao_module_newfw({
  176. url:"SystemAO/storage/poolEditor.html#" + encodeURIComponent(selectedStoragePool),
  177. width: 530,
  178. height: 740,
  179. appicon: "SystemAO/storage/img/icon.png",
  180. title: "Edit Storage Pool",
  181. callback: "finishCreateHandler",
  182. parent: ao_module_windowID
  183. });
  184. }
  185. function finishCreateHandler(state){
  186. //Reload the list
  187. loadStoragePoolList();
  188. }
  189. function reloadAllStoragePool(){
  190. if (confirm("THIS WILL CRASH THE SYSTEM IF YOUR CONFIG IS INVALID. CONFIRM?")){
  191. //OK. Reload storage pool for this pool
  192. $.ajax({
  193. url: "../../system/storage/pool/reload?pool=1eb201a3-d0f6-6630-5e6d-2f40480115c5",
  194. success: function(data){
  195. console.log(data);
  196. loadStoragePoolList();
  197. $("#ok").modal("show");
  198. },
  199. error: function(){
  200. loadStoragePoolList();
  201. }
  202. });
  203. }
  204. }
  205. function reloadSelectedStoragePool(){
  206. if (selectedStoragePool != ""){
  207. if (confirm("Confirm reloading " + selectedStoragePool + " storage pool?")){
  208. //OK. Reload storage pool for this pool
  209. $.ajax({
  210. url: "../../system/storage/pool/reload",
  211. data: {pool: selectedStoragePool},
  212. success: function(data){
  213. console.log(data);
  214. loadStoragePoolList();
  215. $("#ok").modal("show");
  216. },
  217. error: function(){
  218. loadStoragePoolList();
  219. }
  220. });
  221. }
  222. }
  223. }
  224. </script>
  225. </body>
  226. </html>