Files
cloudron-box/src/views/volumes.js
2023-01-26 14:20:11 +01:00

254 lines
8.2 KiB
JavaScript

'use strict';
/* global angular */
/* global $ */
/* global async */
angular.module('Application').controller('VolumesController', ['$scope', '$location', '$timeout', 'Client', function ($scope, $location, $timeout, Client) {
Client.onReady(function () { if (!Client.getUserInfo().isAtLeastUserManager) $location.path('/'); });
var refreshVolumesTimerId = null;
$scope.config = Client.getConfig();
$scope.volumes = [];
$scope.devices = [];
$scope.ready = false;
$scope.mountTypes = [
{ name: 'CIFS', value: 'cifs' },
{ name: 'EXT4', value: 'ext4' },
{ name: 'Filesystem', value: 'filesystem' },
{ name: 'Filesystem (Mountpoint)', value: 'mountpoint' },
{ name: 'NFS', value: 'nfs' },
{ name: 'SSHFS', value: 'sshfs' },
{ name: 'XFS', value: 'xfs' },
];
function refreshVolumes(callback) {
let refreshAgain = false;
Client.getVolumes(function (error, results) {
if (error) return console.error(error);
$scope.volumes = results;
async.eachSeries($scope.volumes, function (volume, iteratorDone) {
Client.getVolumeStatus(volume.id, function (error, result) {
if (error) {
console.error('Failed to fetch volume status', volume.name, error);
iteratorDone();
}
volume.status = result;
if (volume.status.state === 'activating') refreshAgain = true;
iteratorDone();
});
}, function () {
if (!refreshAgain) {
clearTimeout(refreshVolumesTimerId);
refreshVolumesTimerId = null;
} else if (!refreshVolumesTimerId) {
refreshVolumesTimerId = setTimeout(refreshVolumes, 5000);
}
if (callback) callback();
});
});
}
// same as box/mounts.js
$scope.isMountProvider = function (provider) {
return provider === 'sshfs' || provider === 'cifs' || provider === 'nfs' || provider === 'ext4' || provider === 'xfs';
};
$scope.remount = function (volume) {
volume.remounting = true;
Client.remountVolume(volume.id, function (error) {
if (error) console.error(error);
// give the backend some time
$timeout(function () {
volume.remounting = false;
refreshVolumes(function (error) { if (error) console.error('Failed to refresh volume states.', error); });
}, 2000);
});
};
$scope.volumeAdd = {
error: null,
busy: false,
name: '',
hostPath: '',
mountType: 'mountpoint',
host: '',
remoteDir: '',
username: '',
password: '',
diskPath: '',
user: '',
seal: false,
port: 22,
privateKey: '',
reset: function () {
$scope.volumeAdd.error = null;
$scope.volumeAdd.busy = false;
$scope.volumeAdd.name = '';
$scope.volumeAdd.hostPath = '';
$scope.volumeAdd.mountType = 'mountpoint';
$scope.volumeAdd.host = '';
$scope.volumeAdd.remoteDir = '';
$scope.volumeAdd.username = '';
$scope.volumeAdd.password = '';
$scope.volumeAdd.diskPath = '';
$scope.volumeAdd.customDiskPath = '';
$scope.volumeAdd.user = '';
$scope.volumeAdd.seal = false;
$scope.volumeAdd.port = 22;
$scope.volumeAdd.privateKey = '';
$scope.volumeAddForm.$setPristine();
$scope.volumeAddForm.$setUntouched();
},
show: function () {
$scope.volumeAdd.reset();
$scope.blockDevices = [];
Client.getBlockDevices(function (error, result) {
if (error) console.error('Failed to list blockdevices:', error);
// only offer unmounted disks
result = result.filter(function (d) { return !d.mountpoint; });
// amend label for UI
result.forEach(function (d) { d.label = d.path; });
// add custom fake option
result.push({ path: 'custom', label: 'Custom' });
$scope.blockDevices = result;
$scope.volumeAdd.diskPath = $scope.blockDevices[0];
$('#volumeAddModal').modal('show');
});
},
submit: function () {
$scope.volumeAdd.busy = true;
$scope.volumeAdd.error = null;
var mountOptions = null;
if ($scope.volumeAdd.mountType === 'cifs') {
mountOptions = {
host: $scope.volumeAdd.host,
remoteDir: $scope.volumeAdd.remoteDir,
username: $scope.volumeAdd.username,
password: $scope.volumeAdd.password,
seal: $scope.volumeAdd.seal
};
} else if ($scope.volumeAdd.mountType === 'nfs') {
mountOptions = {
host: $scope.volumeAdd.host,
remoteDir: $scope.volumeAdd.remoteDir,
};
} else if ($scope.volumeAdd.mountType === 'sshfs') {
mountOptions = {
host: $scope.volumeAdd.host,
port: $scope.volumeAdd.port,
remoteDir: $scope.volumeAdd.remoteDir,
user: $scope.volumeAdd.user,
privateKey: $scope.volumeAdd.privateKey,
};
} else if ($scope.volumeAdd.mountType === 'ext4' || $scope.volumeAdd.mountType === 'xfs') {
mountOptions = {
diskPath: $scope.volumeAdd.diskPath === 'custom' ? $scope.volumeAdd.customDiskPath : $scope.volumeAdd.diskPath
};
}
var hostPath;
if ($scope.volumeAdd.mountType === 'mountpoint' || $scope.volumeAdd.mountType === 'filesystem') {
hostPath = $scope.volumeAdd.hostPath;
} else {
hostPath = null;
}
Client.addVolume($scope.volumeAdd.name, $scope.volumeAdd.mountType, hostPath, mountOptions, function (error) {
$scope.volumeAdd.busy = false;
if (error) {
$scope.volumeAdd.error = error.message;
return;
}
$('#volumeAddModal').modal('hide');
$scope.volumeAdd.reset();
refreshVolumes();
});
}
};
$scope.volumeRemove = {
busy: false,
error: null,
volume: null,
reset: function () {
$scope.volumeRemove.busy = false;
$scope.volumeRemove.error = null;
$scope.volumeRemove.volume = null;
},
show: function (volume) {
$scope.volumeRemove.reset();
$scope.volumeRemove.volume = volume;
$('#volumeRemoveModal').modal('show');
},
submit: function () {
$scope.volumeRemove.busy = true;
$scope.volumeRemove.error = null;
Client.removeVolume($scope.volumeRemove.volume.id, function (error) {
if (error && (error.statusCode === 403 || error.statusCode === 409)) {
$scope.volumeRemove.error = error.message;
} else if (error) {
Client.error(error);
} else {
$('#volumeRemoveModal').modal('hide');
$scope.volumeRemove.reset();
refreshVolumes();
}
$scope.volumeRemove.busy = false;
});
},
};
Client.onReady(function () {
refreshVolumes(function (error) {
if (error) return console.error(error);
$scope.ready = true;
});
});
// setup all the dialog focus handling
['volumeAddModal', 'volumeRemoveModal'].forEach(function (id) {
$('#' + id).on('shown.bs.modal', function () {
$(this).find('[autofocus]:first').focus();
});
});
$('.modal-backdrop').remove();
}]);