Files
cloudron-box/dashboard/public/views/volumes.js

369 lines
12 KiB
JavaScript
Raw Normal View History

2020-10-28 16:14:32 -07:00
'use strict';
/* global angular */
/* global $ */
/* global async */
2020-10-28 16:14:32 -07:00
angular.module('Application').controller('VolumesController', ['$scope', '$location', '$timeout', 'Client', function ($scope, $location, $timeout, Client) {
Client.onReady(function () { if (!Client.getUserInfo().isAtLeastAdmin) $location.path('/'); });
2020-10-28 16:14:32 -07:00
var refreshVolumesTimerId = null;
2020-10-28 16:14:32 -07:00
$scope.config = Client.getConfig();
$scope.volumes = [];
2023-01-23 18:43:54 +01:00
$scope.devices = [];
2020-10-28 16:14:32 -07:00
$scope.ready = false;
2021-05-12 21:40:30 -07:00
$scope.mountTypes = [
{ name: 'CIFS', value: 'cifs' },
{ name: 'EXT4', value: 'ext4' },
2021-06-24 23:01:35 -07:00
{ name: 'Filesystem', value: 'filesystem' },
{ name: 'Filesystem (Mountpoint)', value: 'mountpoint' },
2021-05-12 21:40:30 -07:00
{ name: 'NFS', value: 'nfs' },
{ name: 'SSHFS', value: 'sshfs' },
2022-06-08 10:38:54 -07:00
{ name: 'XFS', value: 'xfs' },
2021-05-12 21:40:30 -07:00
];
2020-10-28 16:14:32 -07:00
function refreshVolumes(callback) {
let refreshAgain = false;
2020-10-28 16:14:32 -07:00
Client.getVolumes(function (error, results) {
if (error) return console.error(error);
$scope.volumes = results;
2021-05-13 15:33:07 -07:00
async.eachSeries($scope.volumes, function (volume, iteratorDone) {
2021-05-13 15:33:07 -07:00
Client.getVolumeStatus(volume.id, function (error, result) {
if (error) {
console.error('Failed to fetch volume status', volume.name, error);
iteratorDone();
}
2021-05-13 15:33:07 -07:00
volume.status = result;
if (volume.status.state === 'activating') refreshAgain = true;
iteratorDone();
2021-05-13 15:33:07 -07:00
});
}, function () {
if (!refreshAgain) {
clearTimeout(refreshVolumesTimerId);
refreshVolumesTimerId = null;
} else if (!refreshVolumesTimerId) {
refreshVolumesTimerId = setTimeout(refreshVolumes, 5000);
}
2021-05-13 15:33:07 -07:00
if (callback) callback();
});
2020-10-28 16:14:32 -07:00
});
}
2021-10-11 15:51:26 +02:00
// same as box/mounts.js
$scope.isMountProvider = function (provider) {
2022-06-08 10:38:54 -07:00
return provider === 'sshfs' || provider === 'cifs' || provider === 'nfs' || provider === 'ext4' || provider === 'xfs';
2021-10-11 15:51:26 +02:00
};
$scope.isNetworkProvider = function (provider) {
return provider === 'sshfs' || provider === 'cifs' || provider === 'nfs';
};
2021-10-11 15:51:26 +02:00
$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);
2021-10-11 15:51:26 +02:00
});
};
2021-06-21 16:23:34 -07:00
$scope.volumeAdd = {
2020-10-28 16:14:32 -07:00
error: null,
busy: false,
name: '',
hostPath: '',
2021-06-24 23:01:35 -07:00
mountType: 'mountpoint',
2021-05-12 21:40:30 -07:00
host: '',
remoteDir: '',
username: '',
password: '',
ext4Disk: null, // { path, type }
xfsDisk: null, // { path, type }
2021-05-18 17:20:59 +02:00
user: '',
2024-04-15 21:54:40 +02:00
seal: true,
2021-05-18 17:20:59 +02:00
port: 22,
privateKey: '',
2020-10-28 16:14:32 -07:00
reset: function () {
2021-06-21 16:23:34 -07:00
$scope.volumeAdd.error = null;
$scope.volumeAdd.busy = false;
$scope.volumeAdd.name = '';
$scope.volumeAdd.hostPath = '';
2021-06-24 23:01:35 -07:00
$scope.volumeAdd.mountType = 'mountpoint';
2021-06-21 16:23:34 -07:00
$scope.volumeAdd.host = '';
$scope.volumeAdd.remoteDir = '';
$scope.volumeAdd.username = '';
$scope.volumeAdd.password = '';
$scope.volumeAdd.ext4Disk = null;
$scope.volumeAdd.xfsDisk = null;
2021-06-21 16:23:34 -07:00
$scope.volumeAdd.user = '';
2024-04-15 21:54:40 +02:00
$scope.volumeAdd.seal = true;
2021-06-21 16:23:34 -07:00
$scope.volumeAdd.port = 22;
$scope.volumeAdd.privateKey = '';
$scope.volumeAddForm.$setPristine();
$scope.volumeAddForm.$setUntouched();
2020-10-28 16:14:32 -07:00
},
2021-06-21 16:23:34 -07:00
show: function () {
$scope.volumeAdd.reset();
2020-10-28 16:14:32 -07:00
$scope.ext4BlockDevices = [];
$scope.xfsBlockDevices = [];
2023-01-23 18:43:54 +01:00
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; });
$scope.ext4BlockDevices = result.filter(function (d) { return d.type === 'ext4'; });
$scope.xfsBlockDevices = result.filter(function (d) { return d.type === 'xfs'; });
2023-01-23 18:43:54 +01:00
$('#volumeAddModal').modal('show');
});
2020-10-28 16:14:32 -07:00
},
submit: function () {
2021-06-21 16:23:34 -07:00
$scope.volumeAdd.busy = true;
$scope.volumeAdd.error = null;
2020-10-28 16:14:32 -07:00
2021-05-12 21:40:30 -07:00
var mountOptions = null;
2021-06-21 16:23:34 -07:00
if ($scope.volumeAdd.mountType === 'cifs') {
2021-05-12 21:40:30 -07:00
mountOptions = {
2021-06-21 16:23:34 -07:00
host: $scope.volumeAdd.host,
remoteDir: $scope.volumeAdd.remoteDir,
username: $scope.volumeAdd.username,
2022-01-10 16:45:58 +01:00
password: $scope.volumeAdd.password,
seal: $scope.volumeAdd.seal
2021-05-12 21:40:30 -07:00
};
2021-06-21 16:23:34 -07:00
} else if ($scope.volumeAdd.mountType === 'nfs') {
2021-05-12 21:40:30 -07:00
mountOptions = {
2021-06-21 16:23:34 -07:00
host: $scope.volumeAdd.host,
remoteDir: $scope.volumeAdd.remoteDir,
2021-05-12 21:40:30 -07:00
};
2021-06-21 16:23:34 -07:00
} else if ($scope.volumeAdd.mountType === 'sshfs') {
2021-05-18 17:20:59 +02:00
mountOptions = {
2021-06-21 16:23:34 -07:00
host: $scope.volumeAdd.host,
port: $scope.volumeAdd.port,
remoteDir: $scope.volumeAdd.remoteDir,
user: $scope.volumeAdd.user,
privateKey: $scope.volumeAdd.privateKey,
2021-05-18 17:20:59 +02:00
};
} else if ($scope.volumeAdd.mountType === 'ext4') {
mountOptions = {
diskPath: $scope.volumeAdd.ext4Disk.path
};
} else if ($scope.volumeAdd.mountType === 'xfs') {
2021-05-12 21:40:30 -07:00
mountOptions = {
diskPath: $scope.volumeAdd.xfsDisk.path
2021-05-12 21:40:30 -07:00
};
} else if ($scope.volumeAdd.mountType === 'mountpoint' || $scope.volumeAdd.mountType === 'filesystem') {
mountOptions = {
hostPath: $scope.volumeAdd.hostPath
};
2021-05-12 21:40:30 -07:00
}
Client.addVolume($scope.volumeAdd.name, $scope.volumeAdd.mountType, mountOptions, function (error) {
2021-06-21 16:23:34 -07:00
$scope.volumeAdd.busy = false;
2020-10-28 16:14:32 -07:00
if (error) {
2021-06-21 16:23:34 -07:00
$scope.volumeAdd.error = error.message;
2020-10-28 16:14:32 -07:00
return;
}
2021-06-21 16:23:34 -07:00
$('#volumeAddModal').modal('hide');
$scope.volumeAdd.reset();
2020-10-28 16:14:32 -07:00
refreshVolumes();
});
}
};
$scope.volumeEdit = {
error: null,
busy: false,
// cannot be changed
volume: '',
name: '',
mountType: 'mountpoint',
// can be changed
host: '',
remoteDir: '',
username: '',
password: '',
user: '',
2024-04-15 21:54:40 +02:00
seal: true,
port: 22,
privateKey: '',
reset: function () {
$scope.volumeEdit.error = null;
$scope.volumeEdit.busy = false;
$scope.volumeEdit.volume = null;
$scope.volumeEdit.name = '';
$scope.volumeEdit.mountType = '';
$scope.volumeEdit.host = '';
2024-04-15 21:54:40 +02:00
$scope.volumeEdit.seal = true;
$scope.volumeEdit.port = '';
$scope.volumeEdit.remoteDir = '';
$scope.volumeEdit.username = '';
$scope.volumeEdit.password = '';
$scope.volumeEdit.user = '';
$scope.volumeEdit.privateKey = '';
$scope.volumeEditForm.$setPristine();
$scope.volumeEditForm.$setUntouched();
},
show: function (volume) {
$scope.volumeEdit.reset();
Client.getVolume(volume.id, function (error, result) {
if (error) console.error('Failed to get volume:', error);
$scope.volumeEdit.volume = volume;
$scope.volumeEdit.mountType = result.mountType;
2023-09-28 09:43:48 +02:00
$scope.volumeEdit.name = result.name;
$scope.volumeEdit.host = result.mountOptions.host;
$scope.volumeEdit.seal = result.mountOptions.seal;
$scope.volumeEdit.port = result.mountOptions.port;
$scope.volumeEdit.remoteDir = result.mountOptions.remoteDir;
$scope.volumeEdit.username = result.mountOptions.username;
$scope.volumeEdit.password = result.mountOptions.password;
$scope.volumeEdit.user = result.mountOptions.user;
$scope.volumeEdit.privateKey = result.mountOptions.privateKey;
$('#volumeEditModal').modal('show');
});
},
submit: function () {
$scope.volumeEdit.busy = true;
$scope.volumeEdit.error = null;
var mountOptions = null;
if ($scope.volumeEdit.mountType === 'cifs') {
mountOptions = {
host: $scope.volumeEdit.host,
remoteDir: $scope.volumeEdit.remoteDir,
username: $scope.volumeEdit.username,
password: $scope.volumeEdit.password,
seal: $scope.volumeEdit.seal
};
} else if ($scope.volumeEdit.mountType === 'nfs') {
mountOptions = {
host: $scope.volumeEdit.host,
remoteDir: $scope.volumeEdit.remoteDir,
};
} else if ($scope.volumeEdit.mountType === 'sshfs') {
mountOptions = {
host: $scope.volumeEdit.host,
port: $scope.volumeEdit.port,
remoteDir: $scope.volumeEdit.remoteDir,
user: $scope.volumeEdit.user,
privateKey: $scope.volumeEdit.privateKey,
};
} else {
console.error('Should not come here. Only network volumes can be edited');
$('#volumeEditModal').modal('hide');
$scope.volumeEdit.reset();
return;
}
Client.updateVolume($scope.volumeEdit.volume.id, mountOptions, function (error) {
$scope.volumeEdit.busy = false;
if (error) {
$scope.volumeEdit.error = error.message;
return;
}
$('#volumeEditModal').modal('hide');
$scope.volumeEdit.reset();
refreshVolumes();
});
}
};
2020-10-28 16:14:32 -07:00
$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
2021-06-21 16:23:34 -07:00
['volumeAddModal', 'volumeRemoveModal'].forEach(function (id) {
2020-10-28 16:14:32 -07:00
$('#' + id).on('shown.bs.modal', function () {
$(this).find('[autofocus]:first').focus();
});
});
$('.modal-backdrop').remove();
}]);