vRO: Workflow to add an existent disk to a virtual machine

In this post I’m going to expose how to deploy a custom workflow to add an existing virtual disk to virtual machine. I had to improve a workflow that we had for deploy virtual machines massive way. We had this need to add an existing disk to specific virtual machines. Now I am going to detail the process.

First, we are going to duplicate the original workflow “Add Disk”

2018-09-18 10_55_12-172.16.98.23 - Conexión a Escritorio remotoNow we are going to review the Input Parameters and the defined Attributes. After that we had duplicated the Workflow, we have obtained the next schema.

2018-09-18 11_14_11-172.16.98.23 - Conexión a Escritorio remoto

Now we have these input parameters. These parameters, we can use them or not depends on our need. After we’ll see because these input parameters are not strictly necessary.

2018-09-18 11_25_54-172.16.98.23 - Conexión a Escritorio remoto

And this default attributes.

2018-09-18 11_26_45-172.16.98.23 - Conexión a Escritorio remoto

Ok, let’s go!!! We are going to modify the scripting task.2018-09-18 11_41_52-172.16.98.23 - Conexión a Escritorio remoto

Like we have copied the workflow, we should have the original js code for the Scriptable Task “Add Disk”. We are going to delete all code and we are going to implement a new js script.

2018-09-18 11_59_54-172.16.98.23 - Conexión a Escritorio remoto

We need the parameters “vm”, “datastore”, “thinProvisioned” (if we want to add a thin virtual disk). The rest of the parameters are optional to use.

Ok! The first step is we get the Filepath of the vmdk file for add.

<script type="text/javascript">
// Get the vmdk filepath for add to the vm
 var vm_name = vm.name;
 var diskPath = System.getModule("com.vmware.library.vc.datastore.files").getAllVmdkFile(datastore)
 var diskPathLength = diskPath.length;
 var count_path = 0
 while (count_path < diskPathLength)
 {
 var vmdk = diskPath[count_path];
 var existe = vmdk.indexOf(vm_name);
 if (existe !== -1)
 {
 System.log("FilePath found:")
 System.log(vmdk);
 var filevmdkPath = vmdk;
 break;
 }
 count_path++;
 }
System.log("Attempting to attach " + filevmdkPath + " to " + vm.name);
</script>

The next step is finding all scsi controllers associated to the vm and get a list of free diskIndex for each scsi controller.

<script type="text/javascript">
// Max number of vmdks attached to a single scsi controller is 15
var MAX_VMDKS = 15;
// Get list all devices for the object vm
var devices = vm.config.hardware.device;
var diskFilePath = filevmdkPath;
var controllerKey;
var unitNumber;
var usedUnitNumbers = [];
 
for each (controller in devices) 
{
// For each device we look for scsi controller device only. We look for all type of scsi 
// controller (LSI, Paravirtual,Bus Logic,etc).
 var isScsi = controller instanceof VcVirtualBusLogicController || controller instanceof VcVirtualLsiLogicController
 || controller instanceof VcParaVirtualSCSIController || controller instanceof VcVirtualLsiLogicSASController;
   if (!isScsi) 
   {
     continue;
   }
   System.log("SCSI controller found: " + controller.deviceInfo.label);
   //For each device in the list of devices, we look into scsi controller the bus number and     
   //the diskIndex.
   for each (device in devices) 
   {
      if (device.controllerKey == controller.key)
      {
         System.log("Device found: '" + device.deviceInfo.label + "' 'SCSI (" +     controller.busNumber + ":" + device.unitNumber + ")'");
         //When we found a bus scsi number, we save the bus scsi number in a var.
         controllerKey = controller.key; // We can use the input "scsiBusNumber"
 // We save the diskIndex numbers in a array "usedUnitNumbers[]" usedUnitNumbers.push(device.unitNumber); } } break; } // If the number of used diskIndex is the same than the max number of disk for scsi 
// controller, the script . if (usedUnitNumbers.length >= MAX_NUMBER_ATTACHED_VMDKS) { throw "SCSI controller is full, the VMDK can not be attached!"; } </script>

Now, we must find the next diskIndex for our vdisk.

<script type="text/javascript">

// Find the first available SCSI id in the list of usedUnitNumber[]
for (i = 0; i < MAX_VMDKS; i++) {
   if (usedUnitNumbers.indexOf(i) == -1) 
  {
     unitNumber = i; // We can use the input "diskIndex"
     System.log("Found available SCSI unit numebr '" + unitNumber + "'");
     break;
 }
}

</script>

OK! Now we are going to start to configure the specs for config the vm.

<script type="text/javascript">

// Configure the backing virtual disk to add
var backing = new VcVirtualDiskFlatVer2BackingInfo();
backing.fileName = diskFilePath;
backing.diskMode = VcVirtualDiskMode.persistent;
backing.thinProvisioned = true; // We can use the input thinProvioned

var connectable = new VcVirtualDeviceConnectInfo();
connectable.startConnected = true;
connectable.allowGuestControl = false; // We can use the input diskMode
connectable.connected = true;

// We customize the virtual disk to add, we specify the backing file, 
// scsiNumber,diskIndex,etc.

var device = new VcVirtualDisk();
device.backing = backing;
device.connectable = connectable;
device.controllerKey = controllerKey;
device.unitNumber = unitNumber;

// We customize the config operation that we apply to the vm config.

var deviceChange = new VcVirtualDeviceConfigSpec();
deviceChange.operation = VcVirtualDeviceConfigSpecOperation.add;
deviceChange.device = device;
var deviceChangeArray = [deviceChange];

// We save the config operation in a config Spec()

var spec = new VcVirtualMachineConfigSpec();
spec.deviceChange = deviceChangeArray;

</script>

The last step is run a config task against the virtual machine.

<script type="text/javascript">

// We run the config task and we save the task info for waittaskend()
task = vm.reconfigVM_Task(spec);
System.log("Initiating reconfigure...");
System.getModule("com.vmware.library.vc.basic").vim3WaitTaskEnd(task,true,3);
System.log("Reconfigure of VM '" + vm.name + "' successful.");

</script>
And with this we have finished our Workflow customization! We can execute it and try it!
I hope this post has been helpful. Thank you very much for sharing!!! 😉

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *