VMware Virtual Machine Reconfiguration Webinar Sample Code

VMware Virtual Machine Reconfiguration Webinar Sample Code

exaddvirtualdisk.pl

Copyright © 2008 VMware, Inc. All rights reserved.

#!/usr/bin/perl -w

#######################################################################################
# DISCLAIMER. THIS SCRIPT IS PROVIDED TO YOU "AS IS" WITHOUT WARRANTIES OR CONDITIONS 
# OF ANY KIND, WHETHER ORAL OR WRITTEN, EXPRESS OR IMPLIED. THE AUTHOR SPECIFICALLY 
# DISCLAIMS ANY IMPLIED WARRANTIES OR CONDITIONS OF MERCHANTABILITY, SATISFACTORY 
# QUALITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. 
#######################################################################################

use strict;
use warnings;
use Getopt::Long;
use VMware::VIRuntime;
use VMware::VILib;

#######################################################################################
#
# exaddvirtualdisk.pl
#	Example script to add a virtual disk to a virtual machine
#	Parameters:
#		-- server 		server name (either VC or ESX dns or ip address)
#		-- username 	credentials
#		-- password 		
#		-- vm  		name of virtual machine to query
#		-- name 	      name of the virtual disk to create
#		-- size 		size of virtual disk to create in MB (default is 10)
#           --persistent            (if selected, specify that virtual disk should be persistent)
#           --independent           (if selected, specify that virtual disk is independent of the vm)
#######################################################################################

my %opts = (
   vm  => {
      type     => "=s",
      variable => "vmName",
      help     => "Virtual Machine Name",
      required => 1},
   name  => {
      type     => "=s",
      variable => "devName",
      help     => "Device Name"},
   size  => {
      type     => "=i",
      variable => "size",
      help     => "Size in MB",
      required => 0,
      default  => 10},
   nopersist  => {
      type     => "",
      variable => "no persist",
      help     => "Define whether device is non-persistent",
      required => 0},
   independent  => {
      type     => "",
      variable => "independent",
      help     => "Define whether device is independent",
      required => 0});

# validate options, and connect to the server
Opts::add_options(%opts);
Opts::parse();
Opts::validate();
Util::connect();

#######################################################################################
#
#	Collect the information about the virtual machine
#		... information about the 'SCSI Controller 0' to retrieve it's controller key and number of attached devices
#######################################################################################
my $vm_name = Opts::get_option ('vm');
my $vm_view = Vim::find_entity_view(view_type => 'VirtualMachine', filter => {'name' => "^$vm_name\$"});
Fail ("Virtual Machine $vm_name was not found.\n") unless ($vm_view);

#
#	find the information for the owning SCSI Controller, assume that it's SCSI Controller 0
#
my $controller = FindDevice ($vm_view, 'SCSI Controller 0');
Fail ("SCSI Controller not found.\n") unless (defined $controller);
my $controllerKey = $controller->key;		# need the controller key
my $unitNumber = $#{$controller->device} + 1;		# assume that units are contiguous

my $size = Opts::get_option ('size') * 1024;		# convert size to MB
my $nonPersistent = Opts::option_is_set ('nopersist');
#
# valid combinations are 'persistent', 'independent_persistent', and 'independent_nonpersistent'
my $diskMode = (Opts::option_is_set ('independent')) ? 'independent' : '';	
if ($diskMode eq 'independent') {
    $diskMode .= ($nonPersistent) ? '_nonpersistent' : '_persistent';
    }
else {
    $diskMode = 'persistent';		# simply assume persistent.    
    }

#
#  use either the default name or the user specified name
#
my $fileName = '';						
if (Opts::option_is_set ('name')) {
    my $name = Opts::get_option('name');
    my $path = $vm_view->config->files->vmPathName;		# use the file object to get the datastore name
    $path =~ /^(\[.*\])/;		# just use the header ([ds name]
    $fileName = "$1/$name";
    $fileName .= ".vmdk" unless ($fileName =~ /\.vmdk$/);		# set the extension to vmdk
    }

#######################################################################################
#
#	Create the specification for ReconfigVM
#		... Backing Info (VirtualDiskFlatVer2BackingInfo) specifies the name and type of the backing file
#		... specifying a blank filename ... the virtual disk will be created in the VirtualMachine folder in the 
#		    base datastore
#		... VirtualDisk selects the owning controller, a unit number, the capacity, and the backing file
#		... VirtualDeviceConfigSpec specifies the operation (add), the file operation (create), and the device
#######################################################################################

# Create disk VirtualDeviceConfigSpec
my $disk_backing_info = VirtualDiskFlatVer2BackingInfo->new(
                                                            diskMode => $diskMode,
                                                            fileName => $fileName,
                                                            );

my $disk = VirtualDisk->new( controllerKey => $controllerKey,
                             unitNumber => $unitNumber,
                             key => -1,		# specifying a negative key makes it unique
                             backing => $disk_backing_info,
                             capacityInKB => $size);

my $devspec = VirtualDeviceConfigSpec->new(
                                           operation => VirtualDeviceConfigSpecOperation->new('add'),
                                           device => $disk,
                                           fileOperation => VirtualDeviceConfigSpecFileOperation->new('create'));

my $vmspec = VirtualMachineConfigSpec->new( deviceChange => [$devspec] );
print "Adding Virtual Disk on $vm_name\n";
eval {
    $vm_view->ReconfigVM( spec => $vmspec );
    };
if ($@) {
    print "Reconfiguration failed.\n $@";
    }
else {
    print "Virtual Disk created.\n";
    }

# logout
Util::disconnect();


sub Fail {
    my ($msg) = @_;
    Util::disconnect();
    die ($msg);
    exit ();
}

sub FindDevice {
    my ($vm, $name) = @_;
    my $devices = $vm->config->hardware->device;
    foreach my $device (@$devices) {
        return $device if ($device->deviceInfo->label eq $name);
        }
    return undef;
}

The sample code is provided "AS-IS" for use, modification, and redistribution in source and binary forms, provided that the copyright notice and this following list of conditions are retained and/or reproduced in your distribution. To the maximum extent permitted by law, VMware, Inc., its subsidiaries and affiliates hereby disclaim all express, implied and/or statutory warranties, including duties or conditions of merchantability, fitness for a particular purpose, and non-infringement of intellectual property rights. IN NO EVENT WILL VMWARE, ITS SUBSIDIARIES OR AFFILIATES BE LIABLE TO ANY OTHER PARTY FOR THE COST OF PROCURING SUBSTITUTE GOODS OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA, OR ANY INCIDENTAL, CONSEQUENTIAL, DIRECT, INDIRECT, OR SPECIAL DAMAGES, ARISING OUT OF THIS OR ANY OTHER AGREEMENT RELATING TO THE SAMPLE CODE.

You agree to defend, indemnify and hold harmless VMware, and any of its directors, officers, employees, agents, affiliates, or subsidiaries from and against all losses, damages, costs and liabilities arising from your use, modification and distribution of the sample code.

VMware does not certify or endorse your use of the sample code, nor is any support or other service provided in connection with the sample code.