I wrote a custom Action to get the next available SCSI BUS/Unit Number combo.
I have VMs that have multiple SCSI controllers. Some of those controllers have only RDM or physical drives connected. Others have only flat files connected. I think this is likely standard, but a controller only has 16 available unit numbers, 0-15.
My goal was to loop through the current controllers, find one that does not have RDMs, check to see if there is an available Unit Number, and then return the Bus number and Unit number. This is to be used inside a workflow that will add a disk to a VM. My goal there is to have the user provide as little input as possible about the the drive they want - just the VM name, the drive letter, and the size of the drive they want. The drive letter will be assigned in the VM via a Powershell script using a Powershell Host. I also have a workflow that enumerates the current datastores a VM is in, and finds the best available datastore (datastore that has enough free space with reserve to house the new drive) out of the current datastores - and if the current datastores don't meet that need, it will enumerate all DSs in the DS cluster/StoragePod and find the best match there.
This is the code for the action for the SCSI Bus and Unit number, and I'm looking for feedback as to what I can change or improve:
var MAX_UNIT_NUMBER = 15;
var vmname = vm.name;
Server.log("Finding next available SCSI Bus and Unit number for " + vm.name );
var busNumbers = {};
var devices = vm.config.hardware.device;
if ( devices = null ) {
return null;
}
// enumerate all the controller devices, and generate an associative array with key = busNumber
for ( var i in devices ) {
if ( devices[i] instanceof VcVirtualBusLogicController || devices[i] instanceof VcVirtualLsiLogicController
|| devices[i] instanceof VcParaVirtualSCSIController || devices[i] instanceof VcVirtualLsiLogicSASController ) {
scsiControllerKey = devices[i].key;
bus = devices[i];
busNumber = devices[i].busNumber;
Server.log( "SCSI controller found. (Key: " + scsiControllerKey + ") Bus Number: " + busNumber );
busNumbers[scsiControllerKey] = busNumber;
}
}
controllers: for (var key in busNumbers) {
// this is an array of Unit Numbers that are in use on a particular controller.
var usedUnitNumbers = [];
for (var i in devices) {
if ((devices[i] instanceof VcVirtualDisk) && (devices[i].controllerKey == key)) {
var disk = devices[i];
var type = disk.backing.compatibilityMode
if ( type == 'physicalMode' ) {
// we aren't interested in the RDM SCSI Bus - skip this iteration of controllers
Server.log("Controller " + key + " has RDMs attached - skipping.");
continue controllers;
}
var unitNumber = disk.unitNumber;
Server.log("Found virtual disk at unitNumber " + unitNumber);
usedUnitNumbers.push(unitNumber);
}
}
// if we made it here, it has disks that are not physicalMode
var nextUnitNumber = Math.max.apply(Math,usedUnitNumbers) + 1;
if (nextUnitNumber > MAX_UNIT_NUMBER) {
Server.log("All units are occupied on Bus " + busNumber);
nextUnitNumber = null;
continue;
}
var busNumber = busNumbers[key];
// we have a controller we can use, and we have available units.
// Return the Bus number and the next Unit number
Server.log(busNumber + ":" + nextUnitNumber);
BusAndUnit = new Properties();
BusAndUnit.put("Bus",busNumber);
BusAndUnit.put("UnitNumber",nextUnitNumber);
return BusAndUnit;
break;
}
Hi,
Oh thank you.
On line 10, you are doing assignment instead of comparison.
Oops, yeah, I had the next for loop inside that if statement initially, and the comparison was !=. I had just changed it and missed that. The problem was it was getting to the second for loop (controllers) regardless of the if logic, so I just had it break out.
Fixed that, and the extraneous break.
The Server.log is a work-around right now, as the System.log is not working on my VRO system at the moment (unsure why). I will keep some of these though, as I scrape my workflows when they are finished into a database from the VRO API, and also pull in the events associated with them. Then we display these on our Service Catalog, so people can see what steps were taken in regard to their request. We don't use the VRA SC yet, because we have only just purchased it and have not yet started implementation.
For the issue with non-working logs, is your vRO deployment an upgrade from earlier vRO version? If yes, check in the server.log file if you are hitting the issue discussed in https://communities.vmware.com/thread/586365
Basically, it is caused by an incompatibility issue of log file indices from previous vRO version, so after upgrade you may need to delete these indices manually.
It wasn't in relation to an upgrade. I think we have upgraded, but it just kind of stopped working one day, mid-day. I'm curious if a reboot will fix the issue, as I don't think that has been tried yet. If that doesn't work, I will try the solution mentioned there.