Cloning a Virtual Machine in VMWare VI3 without Virtual Server

I, like many other people working in a small company, have to fix problems and come up with solutions with cost at the forefront. I had to make many virtual machines appear from nowhere to create an environment in virtually no time at all. Since all I had was VMWare Server (for Linux), I started there. When I realized that those didn’t translate to ESX, I had to come up with another solution. I created a single template guest OS (of Gentoo 2006.1 which is our primary server OS here) and decided to clone that. How did I do it…well, I am glad you asked.

The key here was to figure out what the VI3 (Virtual Infrastructure 3) client did and mimic it. In order to figure this out, I copied the entire /etc directory to a place where I could later diff it. I created 3 VM (virtual machines) with nothing on them to discern the patterns that the client made in its files. I then diff’d the 2 version of the /etc directory and now I knew the main changes that had to be made. It also should be noted that the Temple VM should be powered off before creating the Clone VM.

I also kept a pristine copy of the template VM so I would always have something to copy from when creating a new VM. For the sake of argument, let’s go with the following names and terminology so we can all stay on the same page. The template VM is going to be named Template. The cloned VM is going to be named Clone. I am going to assume that the template VM that you are using is already fully created, configured, and installed. I am also assuming that you either have console or SSH access to the host since you will need to have access to the commands on the computer itself.

The first step is to copy the template directory. My volume is named Array1, so the command looks like this (Note: I add the & to put the command in the background since it takes a while):

[root@vm1 ~]# cp -arp /vmfs/volumes/Array1/Template /vmfs/volumes/Array1/Clone &

Now its time to get started on the file editing. The first group of files we have to mess with are in the /etc/vmware/hostd/.

vmInventory.xml:
Assuming the only virtual machines you have are going to be Template and his buddy Clone, the following is what your vmInventory.xml should look like:

<ConfigRoot>
  <ConfigEntry id="0001">
    <objID>32</objID>
    <vmxCfgPath>/vmfs/volumes/4725ae82-4e276b80-4c76-001c23c38d80/Template/Template.vmx</vmxCfgPath>
  </ConfigEntry>
  <ConfigEntry id="0002">
    <objID>48</objID>
    <vmxCfgPath>/vmfs/volumes/4725ae82-4e276b80-4c76-001c23c38d80/Clone/Clone.vmx</vmxCfgPath>
  </ConfigEntry>
</ConfigRoot>

The 3 items that you have to note here are:

  1. id: This is a 4 digit zero-padded number going up in increments of 1
  2. objID: This is a number going up in increments of 16
  3. vmxCfgPath: Here you need to ensure that you have the proper hard path (not sym-linked)

pools.xml:
Using the same assumption as before, the only 2 VMs are Template and Clone

<ConfigRoot>
  <resourcePool id="0000">
    <name>Resources</name>
    <objID>ha-root-pool</objID>
    <path>host/user</path>
  </resourcePool>
  <vm id="0001">
    <lastModified>2007-10-30T16:23:57.618151Z</lastModified>
    <objID>32</objID>
    <resourcePool>ha-root-pool</resourcePool>
    <shares>
      <cpu>normal</cpu>
      <mem>normal</mem>
    </shares>
  </vm>
  <vm id="0002">
    <lastModified>2007-10-30T16:23:57.618151Z</lastModified>
    <objID>48</objID>
    <resourcePool>ha-root-pool</resourcePool>
    <shares>
      <cpu>normal</cpu>
      <mem>normal</mem>
    </shares>
  </vm>
</ConfigRoot>

The 3 items that you have to note here are:

  1. id: This is a 4 digit zero-padded number going up in increments of 1 (and it must match the id from vmInventory.xml
  2. objID: This is a number going up in increments of 16 (and it must match the id from vmInventory.xml
  3. The lastModified item here doesn’t matter as it will be changed when you make a change to VM anyway.

By now, the Template directory should be finished copying itself over to the directory that we will be using as our clone. First thing we have to do is rename all the files in the directory to mimic the name of our VM.

  # mv Template-flat.vmdk Clone-flat.vmdk
  # mv Template.nvram Clone.nvram
  # mv Template.vmdk Clone.vmdk
  # mv Template.vmx Clone.vmx
  # mv Template.vmxf Clone.vmxf

Now we just need to edit some files and we are ready to go. First let’s edit the Template.vmdk file. You need to change the line that reads something similar to (the difference will be in the size of your extents):

# Extent description
RW 20971520 VMFS "Template-flat.vmdk"

to look like:

# Extent description
RW 20971520 VMFS "Clone-flat.vmdk"

Save and exit this file. The next file is Template.vmx. The key here is to change every instance of the word Template to Clone. There should be 4 instances:

  1. nvram
  2. displayName
  3. extendedConfigFile
  4. scsi0:0.fileName

Don’t forget to change the MAC address(es). Their variable name(s) should be something like ethernet0.generateAddress. Delete the line that has the variable title sched.swap.derivedName. It will be regenerated and added to the config file. Lastly, add the following line to the end of the file if it doesn’t already exist elsewhere in the file:

uuid.action = "create"

The final item that needs to be done is the one that got me for such a long time. This is the step that will allow your changes to be seen in the client. (Drum roll …..)

Restart the VMWare management console daemon. So simple. Just run the following command:

  # /etc/init.d/mgmt-vmware restart

Note: This will log you out of the client console. But when you log back in, you will have access to the changes that you have made including the clones.

Good luck, and be careful as XML has a tendency to be easier to break than to fix.

  • http://None Loren E

    Great information, i am looking at doing the same thing.

    However, i tought you should be able to browse the datastore with the VI Client and right click the new directory then select “Add to Inventory” in the menu. I think that simplifies editing the Inventory.xml files and maybe others.

    Did you try this? It took me a while to figure out it was even possible to do this, so maybe you over looked this? Any comments on this vs. you solution would be great.

  • http://www.m3v.us Alex

    Hey man,

    Awesome article :) Helped me a lot.

    There are couple more places where you’ll need to change the name from Template to Clone:

    Clone.vmxf (last line, vmxPathName)

    Also, scsi0:0.fileName parameter in the .vmx file should point to Clone.vmdk (or whatever the virtual disk config file is)… otherwise it fails to power up the machine.

  • Henning

    Just tossing out thoughts here, not tested properly yet.

    After making a virtual machine, sysprep it if its linux so it’s ready for template deployment.

    Afterwards run the following command on your system disk file (as root):

    vmkfstools -i /vmfs/volumes/4725ae82-4e276b80-4c76-001c23c38d80/Source/system.vmdk /vmfs/volumes/4725ae82-4e276b80-4c76-001c23c38d80/Tempalte/system.vmdk -d thin

    This will import the disk, but convert it to a thin format that means it only takes up the diskspace of the actual data and not the empty partition space you probably added in.

    Repeat for additional disk if required, but I usually prefer to make data disk upon deploying the system.

    For deployment for the clone just create a clone directory on the vmfs and run (as root):
    vmkfstools -i /vmfs/volumes/4725ae82-4e276b80-4c76-001c23c38d80/Template/system.vmdk /vmfs/volumes/4725ae82-4e276b80-4c76-001c23c38d80/Clone/system.vmdk

    It will convert the disk to regular thick format. After it’s done just use the esx gui to make a new virtual machine and opt to use existing disk files. Add the file you just imported.

    Feel free to send me a mail telling how it went if you experiement around my solution or simular solutions. Thanks for the post, while not exactly was I was looking for it was educational.

  • http://www.datajini.com Colin ‘t Hart

    It’s much easier to do this using VMware Convertor!

  • darkstar

    A template is nothing but a powered down VM, with the .vmx extension of the config file changed to .vmtx. Any .vmtx file will be seen by the esx gui as a template.

    The solution given by Henning is nicer because you might be able to save some space also for your templates, but other than the extension a template for Virtual center is the same as a normal VM.

    Templates make easier the process of deploying vms and it is equivalent to using vmkfstool -i, ofcourse hostd also changes its inventory.xml file and other files to track the newly created VMs etc.

  • Allen

    Nice tutorial – it came in handy. Rather than changing the MAC Address to something else, you can just blank it out.

    ethernet0.generatedAddress = “”

    I found this by removing the NIC through the GUI and then adding a new one and checking the .vmx file. It will generate a new one when you power it up.

  • mfarney

    Lucky for me there are so many dedicated people out here. I had no idea how to exclude the virtual server and after trying out what you suggested I realized things couldn't be any simpler. Thanks for the article and thanks to all who have replied for their hints.
    Mathew Farney | UK VPS hosting