# Cloning a Ganeti VM

Given a Ganeti VM previously built and customized, how might one clone it?  Oddly, there is no `gnt-instance clone`, one has to use export and import from `gnt-backup`.

### Some definitions

*src.instance* is the Ganeti instance name of the existing VM to be cloned
 *dest.instance* is the Ganeti instance name of the resulting new VM clone
 *src.node* is the name of the Ganeti node which will hold the (intermediate) exported image
 *dest.node* the Ganeti node where the resulting new clone will go

### Free Advice

The src.node may be any node in the cluster.  It does not have to be the node where the src.instance resides or the node where the dest.instance will reside. It's merely an intermediate Ganeti node where the VM image that is  exported and then imported is stored.

If your disk performance is mediocre and your inter-node net performance is good, it may be faster to do the export to a src.node which is  neither where the src.instance nor dest.instance VMs reside.

As operational process may take time to propagate, it is advisable to  set up DNS and IP addressing for the new, dest.instance, clone early in  the process.

Before starting the cloning, it is wise to have the src.instance VM up to date.

```
apt-get update
apt-get upgrade
apt-get dist-upgrade
```

## Exporting the Instance

Note that exporting VMx will delete any previous export of VMx (by name) in the cluster.  I.e. a VM may only have one export image.

### If You are a Risk Taker

If you are a risk-taker, you can add the `--noshutdown`  option to the export.  The src.instance will not be shut down before  being exported.  File systems, databases, etc. will be in an  unsynchronized state, and will all need to be able to recover when the  clone is booted.  Also, as the src.instance will still be running,  assumptions below about the dest.instance safely booting with the  src.instance's IP address will not hold.  Basically, do not do this  unless you **really** have to keep the src.instance running.

### Do the Export on the Ganeti Master Node

First, be sure to check you have enough disk space on /var to hold the full src.instance.

To export src.instance to `src.node:/var/lib/ganeti/export/src.instance`, enter the command

```
gnt-backup export -n src.node src.instance
```

Which should produce output similar to

```
# gnt-backup export -n src.node src.instance
Fri May 22 19:12:20 2015 Shutting down instance src.instance
Fri May 22 19:12:26 2015 Creating a snapshot of disk/0 on node src.node
Fri May 22 19:12:27 2015 Starting instance src.instance
Fri May 22 19:12:29 2015 Exporting snapshot/0 from src.node to src.node
Fri May 22 19:12:33 2015 snapshot/0 is now listening, starting export
Fri May 22 19:12:35 2015 snapshot/0 is receiving data on src.node
Fri May 22 19:12:35 2015 snapshot/0 is sending data on src.node
Fri May 22 19:12:40 2015 snapshot/0 sent 197M, 25.2 MiB/s, 0%, ETA 21m 34s
Fri May 22 19:13:42 2015 snapshot/0 sent 1.1G, 15.3 MiB/s, 3%, ETA 34m 35s
...
Fri May 22 19:21:26 2015 snapshot/0 finished receiving data
Fri May 22 19:21:26 2015 snapshot/0 finished sending data
Fri May 22 19:21:26 2015 Removing snapshot of disk/0 on node src.node
Fri May 22 19:21:27 2015 Finalizing export on src.node
Fri May 22 19:21:27 2015 Removing old exports for instance src.instance
```

### Show Exported VMs

You can see the export with

```
# gnt-backup list
Node           Export
src.node src.instance
```

on the master node.

## Importing the Image

### On the Master Node

```
# gnt-backup import \
  --src-node src.node \
  --src-dir /var/lib/ganeti/export/src.instance \
  -t plain \
  -s 32G \
  -n dest.node \
  --no-name-check \
  --no-ip-check \
  --net 0:mac=generate \
  dest.instance
```

Which will produce output similar to

```
# gnt-backup import \
>   --src-node src.node \
>   --src-dir /var/lib/ganeti/export/src.instance \
>   -t plain \
>   -s 32G \
>   -n dest.node \
>   --no-name-check \
>   --no-ip-check \
>   --net 0:mac=generate \
>   dest.instance
Fri May 22 19:40:30 2015 * disk 0, size 32.0G
Fri May 22 19:40:30 2015 * creating instance disks...
Fri May 22 19:40:31 2015 adding instance dest.instance to cluster config
Fri May 22 19:40:32 2015  - INFO: Waiting for instance dest.instance to sync disks
Fri May 22 19:40:32 2015  - INFO: Instance dest.instance's disks are in sync
Fri May 22 19:40:32 2015 * running the instance OS import scripts...
Fri May 22 19:40:32 2015 Exporting disk/0 from src.node to dest.node
Fri May 22 19:40:35 2015 disk/0 is now listening, starting export
Fri May 22 19:40:38 2015 disk/0 is receiving data on dest.src.node
Fri May 22 19:40:38 2015 disk/0 is sending data on src.node
Fri May 22 19:40:43 2015 disk/0 sent 97M, 11.8 MiB/s, 0%, ETA 46m 10s
...
Fri May 22 20:23:00 2015 disk/0 sent 31.4G, 12.8 MiB/s, 98%, ETA 47s
Fri May 22 20:24:01 2015 disk/0 finished sending data
Fri May 22 20:24:07 2015 disk/0 finished receiving data
Fri May 22 20:24:07 2015 Running rename script for dest.instance
```

## Clean Up

After the export/import, the cloned image is in shutdown state, but the source has been restarted.

### Check the VMs

```
# gnt-instance list
Instance              Hypervisor OS   Primary_node      Status     Memory
dest.instance          kvm    noop       dest.node     ADMIN_down      -
src.instance           kvm    noop       dest.node     ADMIN_down      -
```

### Start the Clone VM

```
gnt-instance start dest.instance
```

### Clean up Clone VM

If you are not in a DCHP world, but use configured static addressing, the dest.instance will have its IP address configured in `/etc/network/interfaces` as the src.instance does.  So you will want to reconfigure the  dest.instance's IP addressing before restarting the src.instance.  So  edit the dest.instance's `/etc/network/interfaces`

It would also be wise to generate new host ssh keys and fix the host's name.

```
rm /etc/ssh/ssh_host*
ssh-keygen -A
echo dest.instance > /etc/hostname
```

You will also want to reconfigure exim for the new hostname

```
dpkg-reconfigure exim4-config
```

Fix up /etc/hosts

And reboot. 