VMware Cloud Community
richi666
Contributor
Contributor

Setting the boot order does not work

Hi all,

I'm trying to set the boot order of a VM with the help of a perl script. (VSphere 5.0.0) What I would like to achive is, that the VM tries to boot from network first and then from the first harddisk. (So that I can PXE boot it....)

I'm using the same method like mentioned in this community post: http://communities.vmware.com/message/1889377, so I'm actually setting new boot options with a ReconfigureVM task. At the end, the VM configuration looks like this:

'bootOptions' => bless( {

         'bootDelay' => '3000',

         'bootOrder' => [

                     bless( {}, 'VirtualMachineBootOptionsBootableCdromDevice' ),

                     bless( {

                                'deviceKey' => '4000'

                            }, 'VirtualMachineBootOptionsBootableEthernetDevice' ),

                     bless( {

                                'deviceKey' => '2000'

                            }, 'VirtualMachineBootOptionsBootableDiskDevice' )

                     ],

         'bootRetryDelay' => '20000',

         'bootRetryEnabled' => '1',

         'enterBIOSSetup' => '0'

      }, 'VirtualMachineBootOptions' ),

So the boot order seems to be CDROM, network, hard disk, which is what I want it to be.

However, on the BIOS screen, the boot order is different and it also does not boot from network. So instead of “CDROM, Network, Disk” as the supposed config, it is using the displayed boot order in the BIOS, so “CDROM, Disk, Network”.

screenshot_bios_screen_vmware.png

Does anybody know how to solve this? Is this propably a known bug?

Richard

0 Kudos
5 Replies
lamw
Community Manager
Community Manager

Take a look at this article towards the bottom with a fully working vSphere SDK for Perl script http://www.virtuallyghetto.com/2011/07/2-hidden-virtual-machine-gems-in.html

0 Kudos
richi666
Contributor
Contributor

Hi William,

I just had a look at your perl script, which does basically the same as mine. The only difference is, that I'm trying to set the order of all devices, whereas you are just setting the first boot device.

When I'm using your script, it actually sets the first boot device, so that helps a little bit. However I would like to set the order of the following devices as well. Does that work for you?

I can see in my tests, that I'm able to change the position of the CDROM or hard disk in the boot order, but regardless what I'm doing, the network interface is always at the very end of the list.

Here is my script:

-----------------------

#!/usr/bin/perl

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

my %opts = ( vmname =>     { type => "=s",
                             help => "Name of virtual machine",
                             required => 1},
             bootoption => { type => "=s",
                             help => "Boot order ('default', 'hdfirst')",
                             required => 1},
           );

# parse options
Opts::add_options(%opts);
Opts::parse();
Opts::validate();


my $vmname = Opts::get_option('vmname');
my $bootoption = Opts::get_option('bootoption');

if ($bootoption ne 'default' and $bootoption ne 'hdfirst' and $bootoption ne 'unset')
{
    print "Error. Bootoption has to be 'default', 'hdfirst' or 'unset'\n\n";
    exit 1;
}


# connect to the server
Util::connect();

# do action
my $shortname = (split(/\./,$vmname,2))[0];
my $vm_view = Vim::find_entity_view(view_type => "VirtualMachine",
                                    filter => { 'name' => qr/^$shortname/i });

if (defined $vm_view)
{
    # get NIC, CDROM, DISK object
    my $bootdevice = '';
    my @boot_order_objects = ();
    my $net_device = undef;
    my $cdrom_device = undef;
    my $disk_device = undef;

    my $devices = $vm_view->config->hardware->device;
    foreach my $device (@$devices)
    {
        #print $device->deviceInfo->label.' '.ref($device)."\n";
        # first network adapter
        if ($device->deviceInfo->label eq 'Network adapter 1')
        {
            print "Found network: ".ref($device)."\n";
            $net_device = VirtualMachineBootOptionsBootableEthernetDevice->new( 'deviceKey' => ($device->key));
        }

        # first hard drive
        if ($device->deviceInfo->label eq 'Hard disk 1')
        {
            print "Found first harddisk: ".ref($device)."\n";
            $disk_device = VirtualMachineBootOptionsBootableDiskDevice->new( 'deviceKey' => ($device->key));
        }

        # first CDROM
        if ($device->deviceInfo->label eq 'CD/DVD drive 1')
        {
            print "Found first CDROM: ".ref($device)."\n";
            $cdrom_device = VirtualMachineBootOptionsBootableCdromDevice->new();
        }
    }

    if ($bootoption eq 'default')
    {
        @boot_order_objects = ($cdrom_device,$net_device,$disk_device);
        print "Setting bootorder: CDROM, network, hard disk\n";
    }
    elsif ($bootoption eq 'hdfirst')
    {
        @boot_order_objects = ($disk_device,$cdrom_device,$net_device);
        print "Setting bootorder: Hard disk, CDROM, network\n";
    }
    else
    {
        print "Un-setting bootorder.\n";
    }


    my $bootOptions = VirtualMachineBootOptions->new(bootOrder => \@boot_order_objects);
    my $configspec = VirtualMachineConfigSpec->new ( bootOptions => $bootOptions );
    $vm_view->ReconfigVM_Task(spec => $configspec);

}
else
{
    print "\nERROR. Virtual machine $vmname not found.\n\n";
    Util::disconnect();
    exit 1;
}

# disconnect
Util::disconnect();
exit 0;

------------------------

0 Kudos
lamw
Community Manager
Community Manager

If you want ethernet to be first, then you just need to specify "ethernet" key first in the --bootoption parameter and also provide the matching NIC deviceKey

0 Kudos
richi666
Contributor
Contributor

I did a little bit more testing...

I'm sure that there is a bug on the VMware side. You can set the first boot device, when you just specify a single device in the list, e.g. an ethernet device with its corresponding deviceKey. But when you specify a list of devices it doesn't work as it's supposed to. It just ignores some devices or there might be a problem with the order of the "Removable devices", that you cannot set at all. 

In my case, I want the boot order to be 'CDROM, network, hard disk'. By doing that in one ReconfigureVM Task, it doesn't work. As a workaround, you can do that by using three ReconfigureVM tasks, where you enter the devices in a reverse order. (So 'hard disk' first, then you put 'network' on top and last, but not least the CDROM on top of that.

0 Kudos
lamw
Community Manager
Community Manager

Using my script, I'm able to achieve the results you wanted:

Listing the NIC deviceKey

vi-admin@vMA51:~> ./updateVMBootOrder.pl --vmname TESTVM --operation listnic
Network adapter 1       4000

Listing the DISK deviceKey

vi-admin@vMA51:~> ./updateVMBootOrder.pl --vmname TESTVM --operation listdisk
Hard disk 1     2000

Set the bootOrder CDROM,NIC and DISK

vi-admin@vMA51:~> ./updateVMBootOrder.pl --vmname TESTVM --operation update --bootorder cdrom,ethernet,disk --diskkey 2000 --nickey 4000
Reconfiguring VM Boot Options ...
Successfully updated VM Boot Options

Listing the bootOrder and can see that reflected

vi-admin@vMA51:~> ./updateVMBootOrder.pl --vmname TESTVM --operation list
$VAR1 = [
          bless( {}, 'VirtualMachineBootOptionsBootableCdromDevice' ),
          bless( {
                   'deviceKey' => '4000'
                 }, 'VirtualMachineBootOptionsBootableEthernetDevice' ),
          bless( {
                   'deviceKey' => '2000'
                 }, 'VirtualMachineBootOptionsBootableDiskDevice' )
        ];

If you're still running into issues and you believe you're hitting a bug, please file an SR with VMware

0 Kudos