";
- var diskSummary = formStyle + "
";
- var grandTotal = 0;
- for (var key in diskObj) {
- var readableCapacity = humanize.filesize(key);
- var totalCapacity = key * diskObj[key];
- diskSummary += "";
- diskSummary += "| " + diskObj[key] + " X " + readableCapacity + " | ";
- diskSummary += "" + humanize.filesize(totalCapacity) + " | ";
- diskSummary += "
";
- grandTotal += totalCapacity;
+ submit: function() {
+ var button = $('#create_pool');
+ if (buttonDisabled(button))
+ return false;
+ disableButton(button);
+ var compression = $('#compression').val();
+ if (compression == 'no') {
+ compression = null;
}
- var diskUsableCapacity = this.getUsableCapacity(diskObj, humanize.filesize(grandTotal));
- diskSummary += "| Total Raw Capacity | " + humanize.filesize(grandTotal) + " |
";
- diskSummary += "| Total Usable Capacity | " + "" + diskUsableCapacity + " |
";
- diskSummary += "
";
- return diskSummary;
- },
-
- getUsableCapacity: function (diskObject, rawCapacity) {
- var raidConfig = $('#raid_level').val();
-
- //get all the keys and convert them to numbers to get the disk size correctly.
- var keysArr = Object.keys(diskObject);
- var numericKeysArr = keysArr.map(function (key) {
- return Number(key);
- });
- //calculate least disk size from all the keys.
- var minDiskSize = Math.min.apply(Math, numericKeysArr);
-
- var totalSelectedDisks = 0;
- for (var key in diskObject) {
- totalSelectedDisks += diskObject[key];
- }
-
- var usableCapacity;
- switch (raidConfig) {
- case "single":
- usableCapacity = rawCapacity;
- break;
- case "raid0":
- usableCapacity = humanize.filesize(minDiskSize * totalSelectedDisks);
- break;
- case "raid1":
- usableCapacity = humanize.filesize(minDiskSize * totalSelectedDisks / 2);
- break;
- case "raid5":
- usableCapacity = humanize.filesize(minDiskSize * (totalSelectedDisks - 1));
- break;
- case "raid6":
- usableCapacity = humanize.filesize(minDiskSize * (totalSelectedDisks - 2));
- break;
- case "raid10":
- usableCapacity = humanize.filesize(minDiskSize * totalSelectedDisks / 2);
- break;
+ var mnt_options = $('#mnt_options').val();
+ if (mnt_options == '') {
+ mnt_options = null;
}
+ $.ajax({
+ url: '/api/pools',
+ type: 'POST',
+ dataType: 'json',
+ contentType: 'application/json',
+ data: JSON.stringify({
+ disks: this.selectedDisks.pluck('name'),
+ raid_level: $('#raid_level').val(),
+ pname: $('#pool_name').val(),
+ compression: compression,
+ mnt_options: mnt_options
+ })
+ })
+ .done(function() {
+ enableButton(button);
+ $('#add-pool-form input').tooltip('hide');
+ app_router.navigate('pools', {trigger: true})
+ })
+ .fail(function() {
+ enableButton(button);
+ });
+ },
- return usableCapacity;
+ cancel: function (event) {
+ event.preventDefault();
+ this.$('#add-pool-form :input').tooltip('hide');
+ app_router.navigate('pools', {trigger: true});
+ },
+ selectAllCheckboxes: function(event) {
+ $('input:checkbox').prop('checked', $('#checkAll').prop('checked'));
+ this.updateSelection(event);
},
initHandlebarHelpers: function () {
@@ -352,7 +290,6 @@ AddPoolView = Backbone.View.extend({
return humanize.filesize(diskSize * 1024);
});
}
-
});
//Add pagination
diff --git a/src/rockstor/storageadmin/templates/storageadmin/base.html b/src/rockstor/storageadmin/templates/storageadmin/base.html
index 145133602..d3f79f906 100644
--- a/src/rockstor/storageadmin/templates/storageadmin/base.html
+++ b/src/rockstor/storageadmin/templates/storageadmin/base.html
@@ -79,7 +79,7 @@
-
+
diff --git a/src/rockstor/storageadmin/urls/pools.py b/src/rockstor/storageadmin/urls/pools.py
index 256787a6e..cf1ef9ff5 100644
--- a/src/rockstor/storageadmin/urls/pools.py
+++ b/src/rockstor/storageadmin/urls/pools.py
@@ -18,7 +18,7 @@
from django.conf.urls import patterns, url
from storageadmin.views import (PoolListView, PoolDetailView, PoolScrubView,
- PoolBalanceView)
+ PoolBalanceView, get_usage_bound)
from django.conf import settings
pool_regex = settings.POOL_REGEX
@@ -26,6 +26,7 @@
urlpatterns = patterns(
'',
url(r'^$', PoolListView.as_view(), name='pool-view'),
+ url(r'^/usage_bound$', get_usage_bound),
url(r'^/(?P
%s)$' % pool_regex, PoolDetailView.as_view(),),
url(r'^/(?P%s)/balance$' % pool_regex, PoolBalanceView.as_view(),),
url(r'^/(?P%s)/balance/(?P.*)$' % pool_regex,
@@ -33,5 +34,6 @@
url(r'^/(?P%s)/scrub$' % pool_regex, PoolScrubView.as_view(),),
url(r'^/(?P%s)/scrub/(?P.*)$' % pool_regex,
PoolScrubView.as_view(),),
- url(r'^/(?P%s)/(?P.*)$' % pool_regex, PoolDetailView.as_view(),),
+ url(r'^/(?P%s)/(?P.*)$' % pool_regex,
+ PoolDetailView.as_view(),)
)
diff --git a/src/rockstor/storageadmin/views/__init__.py b/src/rockstor/storageadmin/views/__init__.py
index d32d5e226..3d3024edf 100644
--- a/src/rockstor/storageadmin/views/__init__.py
+++ b/src/rockstor/storageadmin/views/__init__.py
@@ -21,7 +21,7 @@
from snapshot import SnapshotView
from share import (ShareListView, ShareDetailView)
from disk import (DiskMixin, DiskListView, DiskDetailView)
-from pool import (PoolListView, PoolDetailView)
+from pool import (PoolListView, PoolDetailView, get_usage_bound)
from command import CommandView
from appliances import (ApplianceListView, ApplianceDetailView)
from login import LoginView
diff --git a/src/rockstor/storageadmin/views/command.py b/src/rockstor/storageadmin/views/command.py
index 48aa3cd89..01c0a10b1 100644
--- a/src/rockstor/storageadmin/views/command.py
+++ b/src/rockstor/storageadmin/views/command.py
@@ -67,7 +67,7 @@ def _refresh_pool_state():
pool_info = get_pool_info(fd.name)
p.name = pool_info['label']
p.raid = pool_raid('%s%s' % (settings.MNT_PT, p.name))['data']
- p.size = pool_usage('%s%s' % (settings.MNT_PT, p.name))[0]
+ p.size = p.usage_bound()
p.save()
except Exception, e:
logger.error('Exception while refreshing state for '
diff --git a/src/rockstor/storageadmin/views/disk.py b/src/rockstor/storageadmin/views/disk.py
index 5df5c492e..f0a3c0db8 100644
--- a/src/rockstor/storageadmin/views/disk.py
+++ b/src/rockstor/storageadmin/views/disk.py
@@ -213,7 +213,7 @@ def _update_disk_state():
# update disk db object to reflect special root pool status
dob.pool = p
dob.save()
- p.size = pool_usage(mount_root(p))[0]
+ p.size = p.usage_bound()
enable_quota(p)
p.uuid = btrfs_uuid(dob.name)
p.save()
@@ -379,7 +379,7 @@ def _btrfs_disk_import(self, dname, request):
do.save()
mount_root(po)
po.raid = pool_raid('%s%s' % (settings.MNT_PT, po.name))['data']
- po.size = pool_usage('%s%s' % (settings.MNT_PT, po.name))[0]
+ po.size = po.usage_bound()
po.save()
enable_quota(po)
import_shares(po, request)
diff --git a/src/rockstor/storageadmin/views/pool.py b/src/rockstor/storageadmin/views/pool.py
index 28491229a..228a1af62 100644
--- a/src/rockstor/storageadmin/views/pool.py
+++ b/src/rockstor/storageadmin/views/pool.py
@@ -24,12 +24,13 @@
import time
from rest_framework.response import Response
from rest_framework import status
+from rest_framework.decorators import api_view
from django.db import transaction
from storageadmin.serializers import PoolInfoSerializer
from storageadmin.models import (Disk, Pool, Share, PoolBalance)
from storageadmin.views import DiskMixin
from fs.btrfs import (add_pool, pool_usage, resize_pool, umount_root,
- btrfs_uuid, mount_root, start_balance)
+ btrfs_uuid, mount_root, start_balance, usage_bound)
from system.osi import remount
from storageadmin.util import handle_exception
from django.conf import settings
@@ -162,7 +163,7 @@ def _remount(cls, request, pool):
for m in mount_map[share]:
try:
remount(m, mnt_options)
- except Exception, e:
+ except Exception as e:
logger.exception(e)
failed_remounts.append(m)
if (len(failed_remounts) > 0):
@@ -272,7 +273,7 @@ def post(self, request):
d.pool = p
d.save()
add_pool(p, dnames)
- p.size = pool_usage(mount_root(p))[0]
+ p.size = p.usage_bound()
p.uuid = btrfs_uuid(dnames[0])
p.save()
return Response(PoolInfoSerializer(p).data)
@@ -415,11 +416,11 @@ def put(self, request, pname, command):
size_cut = 0
for d in disks:
size_cut += d.size
- if (size_cut >= usage[2]):
+ if (size_cut >= usage):
e_msg = ('Removing these(%s) disks may shrink the pool by '
'%dKB, which is greater than available free space'
' %dKB. This is not supported.' %
- (dnames, size_cut, usage[2]))
+ (dnames, size_cut, usage))
handle_exception(Exception(e_msg), request)
resize_pool(pool, dnames, add=False)
@@ -434,8 +435,7 @@ def put(self, request, pname, command):
else:
e_msg = ('command(%s) is not supported.' % command)
handle_exception(Exception(e_msg), request)
- usage = pool_usage('/%s/%s' % (settings.MNT_PT, pool.name))
- pool.size = usage[0]
+ pool.size = pool.usage_bound()
pool.save()
return Response(PoolInfoSerializer(pool).data)
@@ -462,6 +462,15 @@ def delete(self, request, pname):
pool.delete()
try:
self._update_disk_state()
- except Exception, e:
+ except Exception as e:
logger.error('Exception while updating disk state: %s' % e.__str__())
return Response()
+
+
+@api_view()
+def get_usage_bound(request):
+ """Simple view to relay the computed usage bound to the front end."""
+ disk_sizes = [int(size) for size in
+ request.query_params.getlist('disk_sizes[]')]
+ raid_level = request.query_params.get('raid_level', 'single')
+ return Response(usage_bound(disk_sizes, len(disk_sizes), raid_level))