feat(storidge): snapshots, profile and nodes evolution

storidge-standalone
baron_l 2019-03-27 19:44:38 +01:00
parent 77d51a8465
commit f8610c5480
16 changed files with 142 additions and 130 deletions

View File

@ -22,7 +22,7 @@ function ($scope, $state, $transition$, $q, ModalService, VolumeService, Contain
StoridgeSnapshotService.remove(item.Id)
.then(function success() {
Notifications.success('Snapshot successfully removed', item.Id);
var index = $scope.containerGroups.indexOf(item);
var index = $scope.storidgeSnapshots.indexOf(item);
$scope.storidgeSnapshots.splice(index, 1);
})
.catch(function error(err) {

View File

@ -71,7 +71,7 @@
<td>{{ item.IP }}</td>
<td>{{ item.Role }}</td>
<td>
<i class="fa fa-heartbeat space-right {{ item.Status | nodeStatusBadge }}"></i>
<i class="fa fa-heartbeat space-right {{ item.Status | storidgeNodeStatusBadge }}"></i>
{{ item.Status }}
</td>
</tr>

View File

@ -4,9 +4,9 @@
<rd-widget-body>
<form class="form-horizontal">
<div class="form-group">
<label for="comment" class="col-sm-3 col-lg-2 control-label text-left">Description</label>
<label for="description" class="col-sm-3 col-lg-2 control-label text-left">Description</label>
<div class="col-sm-9 col-lg-10">
<input type="text" class="form-control" id="comment" ng-model="$ctrl.formValues.Comment">
<input type="text" class="form-control" id="description" ng-model="$ctrl.formValues.Description">
</div>
</div>
<div class="form-group">

View File

@ -10,7 +10,7 @@ function (StoridgeSnapshotService, Notifications, $state) {
this.createSnapshot = function () {
ctrl.state.actionInProgress = true;
StoridgeSnapshotService.create(ctrl.volumeId, ctrl.formValues.Comment)
StoridgeSnapshotService.create(ctrl.volumeId, ctrl.formValues.Description)
.then(function success() {
Notifications.success('Success', 'Snapshot successfully created');
$state.reload();

View File

@ -8,7 +8,7 @@
</div>
<div class="actionBar">
<button type="button" class="btn btn-sm btn-danger"
ng-disabled="$ctrl.state.selectedItemCount === 0" ng-click="$ctrl.removeSnapshot($ctrl.state.selectedItems)">
ng-disabled="$ctrl.state.selectedItemCount === 0" ng-click="$ctrl.removeAction($ctrl.state.selectedItems)">
<i class="fa fa-trash-alt space-right" aria-hidden="true"></i>Remove
</button>
</div>
@ -54,7 +54,7 @@
<input id="select_{{ $index }}" type="checkbox" ng-model="item.Checked" ng-change="$ctrl.selectItem(item)" ng-disabled="item.Status === 'normal'"/>
<label for="select_{{ $index }}"></label>
</span>
<!-- <a ui-sref="storidge.drives.drive({id: item.Id})"> {{ item.Id }}</a> -->
<a ui-sref="docker.volumes.volume.snapshot({snapshotId: item.Id})"> {{ item.Id }}</a>
</td>
<td>{{ item.Date }}</td>
<td>{{ item.Description }}</td>

View File

@ -96,7 +96,7 @@
</tr>
<tr>
<td>Snapshot Interval</td>
<td>{{ $ctrl.volume.SnapshotInterval}}</td>
<td>{{ $ctrl.volume.SnapshotInterval}} minute(s)</td>
</tr>
<tr>
<td>Max Snapshots</td>

View File

@ -21,12 +21,14 @@ angular.module('extension.storidge')
return 'info';
};
})
.filter('nodeStatusBadge', function () {
.filter('storidgeNodeStatusBadge', function () {
'use strict';
return function (text) {
var status = text ? _.toLower(text) : '';
if (status === 'maintenance') {
if (status === 'cordoned') {
return 'orange-icon';
} else if (status === 'alert') {
return 'red-icon'
}
return 'green-icon';
};

View File

@ -10,8 +10,8 @@ export function StoridgeProfileDefaultModel() {
this.MaxBandwidth = 100;
this.Filesystem = 'btrfs';
this.SnapshotEnabled = false;
this.SnapshotInterval = 0;
this.SnapshotMax = 0;
this.SnapshotInterval = 1440;
this.SnapshotMax = 1;
this.EncryptionEnabled = false;
this.InterfaceType = 'nfs';
this.InterfaceDriver = '';

View File

@ -16,7 +16,13 @@ angular.module('extension.storidge')
Storidge.querySnapshots({id: volumeId}).$promise
.then(function success(data) {
var snapshotsData = data.snapshots;
var snapshots = snapshotsData.map(function (snapshot) {
let snapshotsArray = [];
for (const key in snapshotsData) {
if (snapshotsData.hasOwnProperty(key)) {
snapshotsArray.push(snapshotsData[key]);
}
}
var snapshots = snapshotsArray.map(function (snapshot) {
return new StoridgeSnapshotModel(snapshot);
});
deferred.resolve(snapshots);
@ -43,9 +49,9 @@ angular.module('extension.storidge')
return deferred.promise;
}
function create(volumeId, comment) {
function create(volumeId, description) {
var deferred = $q.defer();
Storidge.createSnapshot({id: volumeId, comment: comment}).$promise
Storidge.createSnapshot({id: volumeId, description: description}).$promise
.then(function success(data) {
deferred.resolve(data);
})

View File

@ -19,7 +19,7 @@ function ($q, $scope, $state, Notifications, ModalService, StoridgeDriveService)
return item.Status === 'faulty';
});
angular.forEach(selectedItems, function (drive) {
StoridgeDriveService.delete(drive.Id)
StoridgeDriveService.remove(drive.Id)
.then(function success() {
Notifications.success('Drive successfully removed', drive.Id);
})

View File

@ -10,15 +10,16 @@
<div class="col-lg-12 col-md-12 col-xs-12">
<rd-widget>
<rd-widget-header icon="fa-object-group" title-text="Node details">
<button type="button" class="btn btn-sm btn-danger" ng-click="removeNodeAction()">
<button type="button" class="btn btn-sm btn-danger"
ng-disabled="node.Status === 'cordoned'" ng-click="removeNodeAction()">
<i class="fa fa-trash-alt space-right" aria-hidden="true"></i>Remove node
</button>
<button type="button" class="btn btn-sm btn-primary"
ng-disabled="node.Status === 'maintenance'" ng-click="cordonNodeAction()">
ng-disabled="node.Status === 'cordoned'" ng-click="cordonNodeAction()">
<i class="fas fa-wrench space-right" aria-hidden="true"></i>Enter maintenance mode
</button>
<button type="button" class="btn btn-sm btn-primary"
ng-disabled="node.Status !== 'maintenance'" ng-click="uncordonNodeAction()">
ng-disabled="node.Status !== 'cordoned'" ng-click="uncordonNodeAction()">
<i class="fa fa-power-off space-right" aria-hidden="true"></i>Exit maintenance mode
</button>
</rd-widget-header>

View File

@ -52,15 +52,19 @@ function ($scope, $state, $transition$, Notifications, StoridgeProfileService) {
delete profile.MaxBandwidth;
}
if (profile.SnapshotEnabled && $scope.state.RecurringSnapshotEnabled) {
if (!profile.SnapshotInterval) {
profile.SnapshotInterval = 1;
if (profile.SnapshotEnabled) {
if (!profile.SnapshotMax || profile.SnapshotMax <= 0) {
profile.SnapshotMax = 1;
}
profile.SnapshotInterval *= 60;
}
if (!$scope.state.RecurringSnapshotEnabled) {
profile.SnapshotInterval = 0;
if (!$scope.state.RecurringSnapshotEnabled) {
delete profile.SnapshotInterval;
}
if ($scope.state.RecurringSnapshotEnabled && (!profile.SnapshotInterval || profile.SnapshotInterval <= 0)) {
profile.SnapshotInterval = 1440;
}
} else {
delete profile.SnapshotMax;
delete profile.SnapshotInterval;
}
prepareLabels(profile);

View File

@ -105,31 +105,49 @@
<!-- !Filesystem -->
<!-- snapshotEnabled -->
<div class="form-group">
<div class="col-sm-6">
<label for="profile_snapshotEnabled" class="control-label text-left">
Enable snapshots
</label>
<label class="switch" style="margin-left: 20px;">
<input name="profile_snapshotEnabled" type="checkbox" ng-model="model.SnapshotEnabled"><i></i>
</label>
<label for="profile_snapshotEnabled" class="col-sm-2 col-lg-1 control-label text-left">
Enable snapshots
</label>
<label class="switch" style="margin-left: 20px;">
<input name="profile_snapshotEnabled" type="checkbox" ng-model="model.SnapshotEnabled"><i></i>
</label>
</div>
<!-- !snapshotEnabled -->
<!-- snapshotMax -->
<div class="form-group" ng-if="model.SnapshotEnabled">
<label for="profile_snapshotMax" class="col-sm-2 col-lg-1 control-label text-left" style="margin-top: 20px;">
Snapshot max
</label>
<div class="col-sm-4">
<slider model="model.SnapshotMax" floor="1" ceil="100" step="1"></slider>
</div>
<div class="col-sm-6">
<label for="profile_recurringSnapshotEnabled" class="control-label text-left">
Enable periodic snapshots
</label>
<label class="switch" style="margin-left: 20px;">
<input name="profile_recurringSnapshotEnabled" type="checkbox" ng-model="state.RecurringSnapshotEnabled"><i></i>
</label>
<div class="col-sm-2">
<input type="number" min="1" class="form-control" ng-model="model.SnapshotMax" id="profile_snapshotMax">
</div>
<div class="col-sm-4">
<p class="small text-muted" style="margin-top: 7px;">
Snapshot max (<b>count</b>)
</p>
</div>
</div>
<!-- !snapshotMax -->
<!-- snapshotEnabled -->
<div class="form-group" ng-if="model.SnapshotEnabled">
<label for="profile_recurringSnapshotEnabled" class="col-sm-2 col-lg-1 control-label text-left">
Enable periodic snapshots
</label>
<label class="switch" style="margin-left: 20px;">
<input name="profile_recurringSnapshotEnabled" type="checkbox" ng-model="state.RecurringSnapshotEnabled"><i></i>
</label>
</div>
<!-- !snapshotEnabled -->
<!-- snapshotInterval -->
<div class="form-group" ng-if="state.RecurringSnapshotEnabled">
<div class="form-group" ng-if="model.SnapshotEnabled && state.RecurringSnapshotEnabled">
<label for="profile_snapshotInterval" class="col-sm-2 col-lg-1 control-label text-left" style="margin-top: 20px;">
Snapshot interval
</label>
<div class="col-sm-4">
<slider model="model.SnapshotInterval" floor="1" ceil="750" step="1"></slider>
<slider model="model.SnapshotInterval" floor="1" ceil="2880" step="1"></slider>
</div>
<div class="col-sm-2">
<input type="number" min="1" class="form-control" ng-model="model.SnapshotInterval" id="profile_snapshotInterval">
@ -141,34 +159,14 @@
</div>
</div>
<!-- !snapshotInterval -->
<!-- snapshotMax -->
<div class="form-group" ng-if="state.RecurringSnapshotEnabled">
<label for="profile_snapshotMax" class="col-sm-2 col-lg-1 control-label text-left" style="margin-top: 20px;">
Snapshot max
</label>
<div class="col-sm-4">
<slider model="model.SnapshotMax" floor="1" ceil="100" step="1"></slider>
</div>
<div class="col-sm-2">
<input type="number" min="1" class="form-control" ng-model="model.SnapshotMax" id="profile_snapshotMax">
</div>
<div class="col-sm-4">
<p class="small text-muted" style="margin-top: 7px;">
Snapshot max (<b>count</b>)
</p>
</div>
</div>
<!-- snapshotMax -->
<!-- encryptionEnabled -->
<div class="form-group">
<div class="col-sm-12">
<label for="profile_encryptionEnabled" class="control-label text-left">
Enable encryption
</label>
<label class="switch" style="margin-left: 20px;">
<input name="profile_encryptionEnabled" type="checkbox" ng-model="model.EncryptionEnabled"><i></i>
</label>
</div>
<label for="profile_encryptionEnabled" class="col-sm-2 col-lg-1 control-label text-left">
Enable encryption
</label>
<label class="switch" style="margin-left: 20px;">
<input name="profile_encryptionEnabled" type="checkbox" ng-model="model.EncryptionEnabled"><i></i>
</label>
</div>
<!-- !encryptionEnabled -->
<!-- interfaceType -->
@ -239,14 +237,14 @@
IOPS
</div>
<div class="form-group">
<div class="col-sm-12">
<div class="col-md-1 col-sm-2">
<label for="permissions" class="control-label text-left">
Limit IOPS
</label>
<label class="switch" style="margin-left: 20px;">
<input type="checkbox" ng-model="state.LimitIOPS" ng-change="state.NoLimit = (!state.LimitBandwidth && !state.LimitIOPS)"><i></i>
</label>
</div>
<label class="switch" style="margin-left: 20px;">
<input type="checkbox" ng-model="state.LimitIOPS" ng-change="state.NoLimit = (!state.LimitBandwidth && !state.LimitIOPS)"><i></i>
</label>
</div>
<div class="form-group" ng-if="state.LimitIOPS">
<label for="min_iops" class="col-sm-1 control-label text-left">Min</label>
@ -284,14 +282,14 @@
Bandwidth
</div>
<div class="form-group">
<div class="col-sm-12">
<div class="col-md-1 col-sm-2">
<label for="permissions" class="control-label text-left">
Limit bandwidth
</label>
<label class="switch" style="margin-left: 20px;">
<input type="checkbox" ng-model="state.LimitBandwidth" ng-change="state.NoLimit = (!state.LimitBandwidth && !state.LimitIOPS)"><i></i>
</label>
</div>
<label class="switch" style="margin-left: 20px;">
<input type="checkbox" ng-model="state.LimitBandwidth" ng-change="state.NoLimit = (!state.LimitBandwidth && !state.LimitIOPS)"><i></i>
</label>
</div>
<div class="form-group" ng-if="state.LimitBandwidth">
<label for="min_bandwidth" class="col-sm-1 control-label text-left">Min</label>

View File

@ -98,31 +98,49 @@
<!-- !Filesystem -->
<!-- snapshotEnabled -->
<div class="form-group">
<div class="col-sm-6">
<label for="profile_snapshotEnabled" class="control-label text-left">
Enable snapshots
</label>
<label class="switch" style="margin-left: 20px;">
<input name="profile_snapshotEnabled" type="checkbox" ng-model="profile.SnapshotEnabled"><i></i>
</label>
<label for="profile_snapshotEnabled" class="col-sm-2 col-lg-1 control-label text-left">
Enable snapshots
</label>
<label class="switch" style="margin-left: 20px;">
<input name="profile_snapshotEnabled" type="checkbox" ng-model="profile.SnapshotEnabled"><i></i>
</label>
</div>
<!-- !snapshotEnabled -->
<!-- snapshotMax -->
<div class="form-group" ng-if="profile.SnapshotEnabled">
<label for="profile_snapshotMax" class="col-sm-2 col-lg-1 control-label text-left" style="margin-top: 20px;">
Snapshot max
</label>
<div class="col-sm-4">
<slider model="profile.SnapshotMax" floor="1" ceil="100" step="1"></slider>
</div>
<div class="col-sm-6">
<label for="profile_recurringSnapshotEnabled" class="control-label text-left">
Enable periodic snapshots
</label>
<label class="switch" style="margin-left: 20px;">
<input name="profile_recurringSnapshotEnabled" type="checkbox" ng-model="state.RecurringSnapshotEnabled"><i></i>
</label>
<div class="col-sm-2">
<input type="number" min="1" class="form-control" ng-model="profile.SnapshotMax" id="profile_snapshotMax">
</div>
<div class="col-sm-4">
<p class="small text-muted" style="margin-top: 7px;">
Snapshot max (<b>count</b>)
</p>
</div>
</div>
<!-- !snapshotMax -->
<!-- snapshotEnabled -->
<div class="form-group" ng-if="profile.SnapshotEnabled">
<label for="profile_recurringSnapshotEnabled" class="col-sm-2 col-lg-1 control-label text-left">
Enable periodic snapshots
</label>
<label class="switch" style="margin-left: 20px;">
<input name="profile_recurringSnapshotEnabled" type="checkbox" ng-model="state.RecurringSnapshotEnabled"><i></i>
</label>
</div>
<!-- !snapshotEnabled -->
<!-- snapshotInterval -->
<div class="form-group" ng-if="state.RecurringSnapshotEnabled">
<div class="form-group" ng-if="profile.SnapshotEnabled && state.RecurringSnapshotEnabled">
<label for="profile_snapshotInterval" class="col-sm-2 col-lg-1 control-label text-left" style="margin-top: 20px;">
Snapshot interval
</label>
<div class="col-sm-4">
<slider model="profile.SnapshotInterval" floor="1" ceil="750" step="1"></slider>
<slider model="profile.SnapshotInterval" floor="1" ceil="2880" step="1"></slider>
</div>
<div class="col-sm-2">
<input type="number" min="1" class="form-control" ng-model="profile.SnapshotInterval" id="profile_snapshotInterval">
@ -134,34 +152,14 @@
</div>
</div>
<!-- !snapshotInterval -->
<!-- snapshotMax -->
<div class="form-group" ng-if="state.RecurringSnapshotEnabled">
<label for="profile_snapshotMax" class="col-sm-2 col-lg-1 control-label text-left" style="margin-top: 20px;">
Snapshot max
</label>
<div class="col-sm-4">
<slider model="profile.SnapshotMax" floor="1" ceil="100" step="1"></slider>
</div>
<div class="col-sm-2">
<input type="number" min="1" class="form-control" ng-model="profile.SnapshotMax" id="profile_snapshotMax">
</div>
<div class="col-sm-4">
<p class="small text-muted" style="margin-top: 7px;">
Snapshot max (<b>count</b>)
</p>
</div>
</div>
<!-- snapshotMax -->
<!-- encryptionEnabled -->
<div class="form-group">
<div class="col-sm-12">
<label for="profile_encryptionEnabled" class="control-label text-left">
Enable encryption
</label>
<label class="switch" style="margin-left: 20px;">
<input name="profile_encryptionEnabled" type="checkbox" ng-model="profile.EncryptionEnabled"><i></i>
</label>
</div>
<label for="profile_encryptionEnabled" class="col-sm-2 col-lg-1 control-label text-left">
Enable encryption
</label>
<label class="switch" style="margin-left: 20px;">
<input name="profile_encryptionEnabled" type="checkbox" ng-model="profile.EncryptionEnabled"><i></i>
</label>
</div>
<!-- !encryptionEnabled -->
<!-- interfaceType -->

View File

@ -45,7 +45,6 @@ function ($scope, $state, $transition$, Notifications, StoridgeProfileService, M
];
$scope.update = function() {
var profile = $scope.profile;
if (!$scope.state.LimitIOPS) {
@ -58,15 +57,19 @@ function ($scope, $state, $transition$, Notifications, StoridgeProfileService, M
delete profile.MaxBandwidth;
}
if (profile.SnapshotEnabled && $scope.state.RecurringSnapshotEnabled) {
if (!profile.SnapshotInterval) {
profile.SnapshotInterval = 1;
if (profile.SnapshotEnabled) {
if (!profile.SnapshotMax || profile.SnapshotMax <= 0) {
profile.SnapshotMax = 1;
}
profile.SnapshotInterval *= 60;
}
if (!$scope.state.RecurringSnapshotEnabled) {
profile.SnapshotInterval = 0;
if (!$scope.state.RecurringSnapshotEnabled) {
delete profile.SnapshotInterval;
}
if ($scope.state.RecurringSnapshotEnabled && (!profile.SnapshotInterval || profile.SnapshotInterval <= 0)) {
profile.SnapshotInterval = 1440;
}
} else {
delete profile.SnapshotMax;
delete profile.SnapshotInterval;
}
prepareLabels(profile);
@ -123,9 +126,8 @@ function ($scope, $state, $transition$, Notifications, StoridgeProfileService, M
} else {
$scope.state.NoLimit = true;
}
if (profile.SnapshotEnabled && profile.SnapshotInterval) {
if (profile.SnapshotEnabled && profile.SnapshotInterval !== 0) {
$scope.state.RecurringSnapshotEnabled = true;
profile.SnapshotInterval /= 60;
}
initLabels(profile.Labels);
$scope.profile = profile;

View File

@ -35,6 +35,7 @@ function ($q, $scope, $state, Notifications, StoridgeProfileService) {
$scope.create = function() {
var model = new StoridgeProfileDefaultModel();
model.Labels = {};
model.Name = $scope.formValues.Name;
model.Directory = model.Directory + model.Name;