Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 67 additions & 95 deletions lib/jobs/secure-erase-drive.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ function secureEraseJobFactory(

this.commandUtil = new CommandUtil(this.context.target);
this.nodeId = this.context.target;
this.eraseSettings = [];
this.eraseSettings = this.options.eraseSettings;
this.commands = [];
this.hasSentCommands = false;
}
Expand All @@ -53,7 +53,7 @@ function secureEraseJobFactory(

SecureEraseJob.prototype.driveConst = Object.freeze({
hdparm: {
protocol: ['SATADOM', 'SATA'],
protocol: ['SATA'],
args: ['security-erase', 'secure-erase-enhanced']
},
sg_sanitize: { //jshint ignore:line
Expand Down Expand Up @@ -129,27 +129,18 @@ function secureEraseJobFactory(
*/
SecureEraseJob.prototype._validateOptions = function() {
var self = this;

return _.transform(self.options.eraseSettings, function(result, entry) {

return _.transform(self.eraseSettings, function(result, entry) {
assert.array(entry.disks, 'disks');
if (entry.disks.length === 0) {
throw new Error('disks should not be empty');
}

if (entry.hasOwnProperty('arg')) {

assert.string(entry.arg, 'arg');

// Make sure "tool" is assigned when "arg" is specified
assert.string(entry.tool, 'tool');

var match = true;

// Verify the arg is supported in the specified tool
if (!_.includes(self.driveConst[entry.tool].args, entry.arg)) {
match = false;

_.forEach(self.driveConst[entry.tool].args, function(arg) {
if (util.isRegExp(arg) && (entry.arg.match(arg))) {
match = true;
Expand All @@ -158,14 +149,11 @@ function secureEraseJobFactory(
}
});
}

if (match === false) {
throw new Error(entry.tool + " doesn't support arg " + entry.arg);
}
}

result.push(entry);

}, []);
};

Expand All @@ -176,13 +164,11 @@ function secureEraseJobFactory(
*/
SecureEraseJob.prototype._collectDisks = function() {
var self = this;

return _.transform(self.eraseSettings, function(result, entry) {

_.forEach(entry.disks, function(disk) {
result[disk] = 1;
result.push(disk);
});
}, {});
}, []);
};

/**
Expand All @@ -191,7 +177,7 @@ function secureEraseJobFactory(
* @description Use info from catalogSearch to form the parameters
* in json format for secure_erase.py running on node
*/
/* diskInfo example:
/* driveIdExt example:
[
{
"devName": "sdg",
Expand Down Expand Up @@ -247,7 +233,7 @@ function secureEraseJobFactory(
The output parameter will be:
[
{
"disks": [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

miss "["?

"disks":
{
"diskName": "/dev/sda",
"virtualDisk": "/c0/v0",
Expand All @@ -264,7 +250,7 @@ function secureEraseJobFactory(
...
]
*/
SecureEraseJob.prototype._marshalParams = function(diskInfo) {
SecureEraseJob.prototype._marshalParams = function(driveIdExt) {
var self = this;
return _.transform(self.eraseSettings, function(result, entry) {
/* entry ex:
Expand All @@ -274,76 +260,30 @@ function secureEraseJobFactory(
'arg': 'secure-erase'
}
*/

_.forEach(entry.disks, function(disk, idx) {
// disk ex: 'sda'

var match = false;

_.forEach(diskInfo, function(info) {


// Find out the matched entry from catalogSearch
if ((info.devName === disk) ||
(info.identifier === disk)) {

match = true;

// Verify the specified tool (except scrub, which supports all protocols)
// supports the disk's protocol
if (entry.hasOwnProperty('tool') && (entry.tool !== 'scrub')) {

// Get the disk protocol
var protocols = [undefined];
if (info.esxiWwid.indexOf('SATADOM') > 0) {
protocols[0] = 'SATADOM';
}
else if (info.hasOwnProperty('physicalDisks')) {
protocols = [];
_.forEach(info.physicalDisks, function(pd) {
protocols.push(pd.protocol);
});
}

_.forEach(protocols, function(protocol){
if (!_.contains(self.driveConst[entry.tool].protocol, protocol)) {
throw new Error(entry.tool + " doesn't support disk " + disk +
' (' + protocol + ')');
}
});
}
else {
entry.tool = 'scrub';
}

// Marshal the disk parameter
entry.disks[idx] = {
'diskName': '/dev/' + info.devName,
'virtualDisk': info.virtualDisk,
'scsiId': info.scsiId,
};

// Add virtual disk info if any
if (info.virtualDisk !== "") {
entry.disks[idx].deviceIds = info.deviceIds;
entry.disks[idx].slotIds = info.slotIds;
}

if (info.hasOwnProperty('controllerVendor')) {
entry.vendor = info.controllerVendor;
}

return false;
}

if (!entry.tool) { entry.tool = "scrub"; }
_.forEach(entry.disks, function(disk, index) {
// disk ex: 'sda'
var diskCatalog = _.find(driveIdExt, function(info){
return info.devName === disk || info.identifier ===disk;
});

if (match === false) {
if (!diskCatalog) {
throw new Error("Cannot find info in catalogs for drive " + disk);
}

self._validateDiskProtocol(entry.tool, diskCatalog, disk);
entry.disks[index] = {
'diskName': '/dev/' + diskCatalog.devName,
'virtualDisk': diskCatalog.virtualDisk,
'scsiId': diskCatalog.scsiId,
};
// Add virtual disk info if any
if (diskCatalog.virtualDisk !== "") {
entry.disks[index].deviceIds = diskCatalog.deviceIds;
entry.disks[index].slotIds = diskCatalog.slotIds;
}
if (diskCatalog.hasOwnProperty('controllerVendor') && !entry.vendor) {
entry.vendor = diskCatalog.controllerVendor;
}
});

result.push(entry);
}, []);
};
Expand Down Expand Up @@ -387,24 +327,20 @@ function secureEraseJobFactory(
SecureEraseJob.prototype._formatCommands = function(params) {
var self = this;
this.commands = _.transform(params, function(result, param) {

var formatCmd = {cmd: "sudo python secure_erase.py"};
var notificationUrl = self.options.baseUri + '/api/current/notification/progress';
formatCmd.cmd += ' -i ' + self.taskId + ' -s ' + notificationUrl;
formatCmd.cmd += ' -i ' + self.taskId + ' -s ' + notificationUrl + ' -t ' + param.tool;
_.forEach(param.disks, function(disk) {
formatCmd.cmd += ' -d ' + '\'' + JSON.stringify(disk) + '\'';
});

formatCmd.cmd += ' -t ' + param.tool;

if (param.hasOwnProperty('arg')) {
formatCmd.cmd += ' -o ' + param.arg;
}

if (param.hasOwnProperty('vendor')) {
formatCmd.cmd += ' -v ' + param.vendor;
}

result.push(formatCmd);

}, []);
Expand Down Expand Up @@ -441,12 +377,48 @@ function secureEraseJobFactory(
};
};

/**
* @memberOf SecureEraseJob
* @function _validateDiskProtocol
* @description validate protocol against erase tool for a disk.
*/
SecureEraseJob.prototype._validateDiskProtocol= function(tool, diskInfo, disk) {
// Verify the specified tool (except scrub, which supports all protocols)
// supports the disk's protocol
var protocols = [undefined];
var self = this;
if (tool === "scrub") { return; }
if (diskInfo.hasOwnProperty('physicalDisks')) {
protocols = [];
_.forEach(diskInfo.physicalDisks, function(pd) {
protocols.push(pd.protocol);
});
} else {
if (diskInfo.linuxWwid.indexOf('ata') > 0 ||
diskInfo.linuxWwid.indexOf('wwwn') >0) {
protocols[0] = 'SATA';
} else if (diskInfo.linuxWwid.indexOf('scsi') > 0) {
protocols[0] = 'SAS';
} else if (diskInfo.linuxWwid.indexOf('nvme') > 0) {
protocols[0] = 'NVME';
} else if (diskInfo.linuxWwid.indexOf('usb') > 0) {
protocols[0] = 'USB';
}
}
_.forEach(protocols, function(protocol){
if (!_.contains(self.driveConst[tool].protocol, protocol)) {
throw new Error(tool + " doesn't support disk " + disk +
' (' + protocol + ')');
}
});
};

/**
* @memberOf SecureEraseJob
* @function _validateDiskWwid
* @description validate extended disk esxiWwid information against cached driveId catalogs
*/
SecureEraseJob.prototype._validateDiskEsxiWwid= function(diskInfo) {
SecureEraseJob.prototype._validateDiskEsxiWwid= function(driveIdExt) {
//driveId catalog will be refresh before secure erase job
//driveId catalog will be cached in graph context before refreshing
//cached catalog and refreshed driveId catalogs are compared on esxiWwid to make sure
Expand All @@ -459,7 +431,7 @@ function secureEraseJobFactory(
_.forEach(driveIdCache, function(disk){
driveWwidCache[disk.devName] = disk.esxiWwid;
});
_.forEach(diskInfo, function(disk){
_.forEach(driveIdExt, function(disk){
if (driveWwidCache[disk.devName] !== disk.esxiWwid) {
throw new Error("Drive id catalog does not match user input data, " +
"drive re-cataloging is required");
Expand Down
Loading