Tip: my procedure for cloning a Fedora VM

Update: New in libguestfs ≥ 1.13.19 is a tool to “sysprep” VMs. See the virt-sysprep manual page

To clone a Fedora VM by hand you need a mixture of host (ie. LVM, libvirt) and guest (ie. libguestfs) operations. This is how I currently do it by hand:

Create new storage and copy the old VM. Because I’m using logical volumes, the size of the new LV must be exactly the same as the size of the old LV:

# lvcreate -L 10G -n FNew vg_host
# dd if=/dev/vg_host/F14 of=/dev/vg_host/FNew bs=1M

Copy and modify the libvirt XML:

# virsh dumpxml F14 > /tmp/fnew.xml
# emacs /tmp/fnew.xml

You need to change the following 4 fields in the XML: <name>, <uuid>, <source dev='/dev/vg_host/...'> and <mac address='...'>. For the UUID and MAC address, just randomly change the last few digits.

Define the new guest, but don’t boot it just yet:

# virsh define /tmp/fnew.xml
Domain FNew defined from /tmp/fnew.xml

There are two files you need to edit inside the guest:

# guestfish -i -d FNew

Welcome to guestfish, the libguestfs filesystem interactive shell for
editing virtual machine filesystems.

Type: 'help' for a list of commands
      'man' to read the manual
      'quit' to quit the shell

Operating system: Fedora release 14 (Laughlin)
/dev/mapper/vg_f13x64-lv_root mounted on /
/dev/vda1 mounted on /boot

><fs> edit /etc/sysconfig/network
(change the hostname)
><fs> edit /etc/udev/rules.d/70-persistent-net.rules
(change the MAC address to the same as the one in the libvirt XML file)
><fs> exit

Now you can go ahead and boot the new, cloned guest.

On the virt tools roadmap is a plan to refresh the old “virt-clone” tool to do all this properly and automatically.

9 Comments

Filed under Uncategorized

9 responses to “Tip: my procedure for cloning a Fedora VM

  1. Yaniv

    Within the guest, don’t you need to run something that will regenerate the private SSH keys and stuff? sys-unconfig or something?

    • rich

      Yes you’re right as always. Of course ssh doesn’t complain because it thinks the hosts are the same …

      Investigation of the sshd init script on Fedora shows that probably just doing this would trigger rekeying, although I have not tried it:

      ><fs> glob rm /etc/ssh/ssh_host_*key*
      

      Edit: sys-unconfig is a little bit different. According to the man page it ” will halt your system, and run the following configuration programs at boot: passwd (to change the root password), netconfig, timeconfig, kbdconfig, authconfig, and ntsysv.” Similar to a first boot after installation. You can get this effect from guestfish by doing:

      ><fs> touch /.unconfigured
      
  2. frankiii

    Great to hear that virt-clone is getting refreshed. Is there any intention to possibly speed up the clone process by operating at the filesystem level? This could turn out to be much faster than the all-purpose dd approach. I wrote up my process here:

    http://virt-notes.blogspot.com/2010/09/quick-provisioning-with-kvm-and-xen.html

    Obviously this would need to be generalized for a larger set of configurations, but I routinely churn out VMs in around 30 seconds and that has become rather addictive. It could be tough to go back. 🙂

    Love your blog.

    • rich

      Yes, although that requires snapshot support in libvirt or for us to munge LVs etc directly.

      Really what I want is a prebuilt distribution tool:

      Prebuilt distributions part 3

      and one day I may get around to writing it. (Not a day when I keep getting bug reports like today …)

      BTW, should be using libguestfs not kpartx there 🙂

      • frankiii

        I actually *did* try to use libguestfs rather than kpartx. I love your work. 🙂

        The first problem (not necessarily related) is that gparted creates the partition device files in /dev/mapper automatically against my will so I still needed some hack to remove those after partitioning.

        The second is that I couldn’t figure out how to do the grub magic via libguestfs. Is that even possible? If so, it would be a major boon!

        On a somewhat related note, one thing I love with Xen is the ability to designate logical volumes as individual partitions in the guest. That way I don’t need to jump through any of the kpartx hoops but can simply create an lv, build a filesystem, and assign it to the guest. Are you aware of any plans to allow for similar functionality under KVM? I suppose this would require some sort of pygrub equivalent, though…

      • rich

        The parted thing is a bit odd, and I haven’t seen that before. The names of the mapper devices look a bit like the ones created by kpartx, are you sure they’re not coming from kpartx?

        For grub, we offer a simple grub-install command. This may or may not be enough to fully install grub. If it isn’t, then it’s very easy to add new API calls to libguestfs, literally 20-30 lines of code (example)

        On the filesystem-per-LV issue: In fact I have set up one of my production servers (on KVM) in exactly this way. (git.annexia.org is a virtual guest set up like this). It’s not quite as straightforward as it might seem, since the kernel and initrd must be external to the guest. I will shortly write a small blog posting describing the setup.

      • frankiii

        “The parted thing is a bit odd, and I haven’t seen that before. The names of the mapper devices look a bit like the ones created by kpartx, are you sure they’re not coming from kpartx?”

        Yeah, here’s output with extra info removed.

        RHEL5.5 and RHEL6b2:
        # lvcreate -L 10g -n /dev/vg_virt/testvol
        # ls /dev/mapper/*testvol*
        /dev/mapper/vg_virt-testvol
        # parted /dev/vg_virt/testvol mktable msdos
        # parted /dev/vg_virt/testvol mkpart primary ext2 0 2048
        # ls /dev/mapper/*testvol*
        /dev/mapper/vg_virt-testvol /dev/mapper/vg_virt-testvolp1

        Looks like RHEL6’s kpartx can handle this better, though.

        RHEL5.5:
        # kpartx -p p -d /dev/vg_virt/testvol
        # ls /dev/mapper/*testvol*
        /dev/mapper/vg_virt-testvol /dev/mapper/vg_virt-testvolp1

        RHEL6b2:
        # kpartx -p p -d /dev/vg_virt/testvol
        # ls /dev/mapper/*testvol*
        /dev/mapper/vg_virt-testvol

        Thanks for the info on the grub-install. I’ll definitely try that in guestfish and I look forward to reading your future blog entry about the kvm lvm->partition usage.

  3. Pingback: Tip: Configure guest with filesystem directly on a host device « Richard WM Jones

  4. Pingback: VM cloning, udev and network interfaces on KVM | recurrent null

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.