disaster recovery to Proxmox

disaster recovery to Proxmox

Just to clarify I am doing this as more of a retroactive post to show how I migrated from my xcp-ng server ( I had some weird network sh!t go down...and I honestly didn't probably need to migrate but it happened 😅 ) to proxmox. Just wanted to link to the articles I used and some commands in case it helps others 🙂. Also, sorry but not all of this might be 100% accurate, because I did the transfer last weekend but I remember pretty much everything I did ( I think it was the stress of the situation that burned it into my mind 😅 ).

So, I didn't know this till I actually logged directly into the xcp-ng console, but apparently the version of xcp-ng, I was running, used CentOS 7. So, not my most comfortable OS, but I managed.

First thing that got in  my way was that I had an exFAT external HDD that I was planning to export the VMs to, but whatever version of CentOS I had didn't have builtin support for that. Interestingly almost all the repos were disabled except for the xcp-ng repos, which makes sense but I don't think the exfat utils were in their repos. So, I first enabled the Base, Extras, and Updates repos and installed the epel-release package to enable that repo by following this guide. Afterwards I followed this guide to install the exFAT drivers, and after that everything worked with mounting the external HDD.

Next I needed to figure out how to export the xcp-ng vms from the CLI. One thing I do have to admit is that the xcp-ng has excellent tab completion ( at least for the xe command ). One thing I continued to notice ( while researching how to do this ) is that it seems there is not a very clear/good way to export to .ova for .img formats. Seems like you have to convert to the .xva format and then you can convert to other formats from that one. So, while using a lot of tab completion, used this command: xe vm-export filename=export_filename vm=name_of_vm_to_export to export the vms ( check out here for more info on the reference for the xe command). I actually did it in a for loop, so I didn't have to manually export each one and wait for them to finish individually. Once I finished exporting them to the external HDD I needed to convert them.

Fortunately it seemed pretty straight forward from this blog post using this project. For the most part it was, but one thing that I didn't know about was there were multiple folders when I uncompressed the export... normally there was a smaller one ( based on the file size (i.e. megabytes) ) and a larger one ( normally in the gigabytes ). So, I would imagine the MB folder was a delta backup or something, and I always wanted to get the larger one. So, I made a script ( as I normally do ) which would go and uncompress the file and identify the larger folder, and then use that folder as the basis for recreating the vm to a .qcow2 file. The script is below, feel free to comment asking about different parts but https://explainshell.com is a pretty good tool for exploring how commands are constructed.

#!/usr/bin/env bash

# https://elrey.casa/bash/scripting/harden
set -${-//[sc]/}eu${DEBUG+xv}o pipefail

function calculate_bigger(){
  folder_for_comparison="${1}"
  bigger_folder="$(du -hs "${folder_for_comparison}/"* | sort -h | tail -n 1 | cut -f 2)"
}

function conversion(){
  xva_file="${1}"
  new_base="$(mktemp -d)"
  xva_base_folder_name="${xva_file%.*}"
  xva_base_name="${new_base}/${xva_base_folder_name}"
  bigger_folder=''
  mkdir -p "${xva_base_name}/"
  tar -xf "${xva_file}" -C "${xva_base_name}"
  sudo chmod -R u+rwX "${xva_base_name}"
  calculate_bigger "${xva_base_name}"
  xva-img -p disk-export "${bigger_folder}" "${xva_base_name}/vm.raw"
  qemu-img convert -f raw -O qcow2 "${xva_base_name}/vm.raw"  "${xva_base_name}/vm.qcow2"
  mkdir -p "${xva_base_folder_name}"
  if mv -vf "${xva_base_name}/vm.qcow2" "${xva_base_folder_name}/" ; then
    :
  else
    echo "probably ok..."
  fi
  rm -rf "${new_base}"

}

function main(){
  if [[ -n "${1:-}" ]] ; then
      conversion "${1}"
      # https://elrey.casa/zfs/tricks#cleanupzfsautosnap
      pool_name='rpool'; rm -f ~/"deletion-${pool_name}.log" && zfs list -t snapshot -Ho name | grep "${pool_name}" | grep 'zfs-auto-snap' | xargs -t -n 1 sudo zfs destroy -v  |& tee -a ~/"deletion-${pool_name}.log"
  else
    for xva in ./*.xva ; do
      printf '%s\n' "${xva}"
      conversion "${xva}"
      # https://elrey.casa/zfs/tricks#cleanupzfsautosnap
      pool_name='rpool'; rm -f ~/"deletion-${pool_name}.log" && zfs list -t snapshot -Ho name | grep "${pool_name}" | grep 'zfs-auto-snap' | xargs -t -n 1 sudo zfs destroy -v  |& tee -a ~/"deletion-${pool_name}.log"
      echo "waiting for 3 seconds in case need to cancel"
      sleep 3
    done
  fi
}

# https://elrey.casa/bash/scripting/main
if [[ "${0}" = "${BASH_SOURCE[0]:-bash}" ]] ; then
  main "${@}"
fi

After that I had all the vms convert to .qcow2 format, and I needed to figure out how to get them into proxmox. Fortunetly I found this post which showed a command for how you can import the qcow2 img to a specific vm. One thing that tripped me up doing that is it registered it as an "unused disk", and I didn't know how to make it "used". It took me a bit, but if you click on the edit button and then you hit save it should then "activate" it and attach it to your vm's scsi controller.

Now starts the real journey to try and convert everything to IaC since I have wanted to do that for a while 🙂