#!/bin/bash
# ENSAIO Veeam->WCI: converte os discos exportados de UMA VM. uso: convert.sh <VM>   (roda como root)
# Saida: /NFS01/migrate/ENSAIO/<VM>/<VM>-disk-N.qcow2 (publicado em transfer.cloudax.cloud/ENSAIO/<VM>/...)
set -o pipefail
VM=$1; SRC=/mnt/veeam-export/$VM; W=/NFS01/migrate/ENSAIO/work-$VM; OUT=/NFS01/migrate/ENSAIO/$VM
export LIBGUESTFS_BACKEND=direct TMPDIR=/NFS01/migrate/.guestfs-tmp LIBGUESTFS_CACHEDIR=/NFS01/migrate/.guestfs-tmp VIRTIO_WIN=/tmp/virtio-win.iso
t(){ date +%s; }; T0=$(t); log(){ echo "$(date +%T) $*"; }
mkdir -p $W $OUT; rm -f $OUT/*.qcow2
mapfile -t FL < <(ls $SRC/*-flat.vmdk | awk "{n=\$0; m=0; if (match(n,/_([0-9]+)-flat\.vmdk$/,a)) m=a[1]; print m\"\t\"n}" | sort -n | cut -f2)
[ ${#FL[@]} -eq 0 ] && { log "ERRO sem discos em $SRC"; exit 1; }
log "discos: ${#FL[@]}"; for f in "${FL[@]}"; do log "  $(basename $f) $(du -h --apparent-size "$f" | cut -f1) (usado $(du -h "$f" | cut -f1))"; done
BOOT=${FL[0]}
FW=BIOS; sgdisk -p "$BOOT" 2>/dev/null | grep -qE "EF00|EFI system" && FW=UEFI
OSN=$(virt-inspector --format=raw -a "$BOOT" --no-icon 2>/dev/null | grep -oE "<product_name>[^<]+" | head -1 | cut -d">" -f2)
log "firmware=$FW os=\"$OSN\""
T1=$(t); qemu-img convert -f raw -O qcow2 "$BOOT" $W/boot.qcow2 || { log "ERRO qemu-img boot"; exit 1; }
log "raw->qcow2 boot: $(( $(t)-T1 ))s"
if [[ "$OSN" == *Windows* ]]; then
  P=$(virt-filesystems --long -a $W/boot.qcow2 | awk "\$3==\"ntfs\" {print \$1, \$NF}" | sort -k2 -n | tail -1 | cut -d" " -f1)
  guestfish --rw -a $W/boot.qcow2 <<<"run
ntfsfix $P clearbadsectors:false" >/dev/null 2>&1 && log "ntfsfix $P ok"
  guestfish --rw -a $W/boot.qcow2 -m $P:/:remove_hiberfile:ntfs-3g <<<"-rm-f /hiberfil.sys" >/dev/null 2>&1
fi
# libvirt xml com todos os discos (boot qcow2 local, dados raw direto do SMB)
X=$W/$VM.xml; { echo "<domain type=\"kvm\"><name>$VM</name><memory unit=\"GiB\">4</memory><vcpu>2</vcpu><os>"; [ $FW = UEFI ] && echo "<type arch=\"x86_64\">hvm</type><loader readonly=\"yes\" type=\"pflash\">/usr/share/OVMF/OVMF_CODE_4M.fd</loader>" || echo "<type arch=\"x86_64\">hvm</type>"; echo "</os><devices>"
  i=0; for f in $W/boot.qcow2 "${FL[@]:1}"; do fmt=raw; [ $i -eq 0 ] && fmt=qcow2; dev=sd$(printf "\\x$(printf %x $((97+i)))"); echo "<disk type=\"file\" device=\"disk\"><driver name=\"qemu\" type=\"$fmt\"/><source file=\"$f\"/><target dev=\"$dev\" bus=\"scsi\"/></disk>"; i=$((i+1)); done
  echo "</devices></domain>"; } > $X
T2=$(t); VW=/tmp/virtio-win.iso; [[ "$OSN" == *2012* ]] && VW=/NFS01/migrate/virtio-win-0.1.171.iso
log "INICIO virt-v2v (VIRTIO_WIN=$(basename $VW))"
VIRTIO_WIN=$VW virt-v2v -i libvirtxml $X -o local -of qcow2 -os $W -on $VM > $W/v2v.log 2>&1; RC=$?
grep -E "warning|error|Converting|requires" $W/v2v.log | sed "s/^/  v2v: /" | head -8
log "virt-v2v rc=$RC $(( $(t)-T2 ))s"; [ $RC -ne 0 ] && { tail -5 $W/v2v.log; exit 1; }
if false; then  # troca manual do .sys desativada: ISO 0.1.171 inteira via VIRTIO_WIN
  D=2k12; [[ "$OSN" == *R2* ]] && D=2k12R2; mkdir -p /mnt/vold171; mountpoint -q /mnt/vold171 || mount -o loop,ro /NFS01/migrate/virtio-win-0.1.171.iso /mnt/vold171
  guestfish --rw -a $W/$VM-sda -i <<<"upload /mnt/vold171/viostor/$D/amd64/viostor.sys /Windows/System32/drivers/viostor.sys
-upload /mnt/vold171/NetKVM/$D/amd64/netkvm.sys /Windows/System32/drivers/netkvm.sys
-upload /mnt/vold171/NetKVM/$D/amd64/netkvm.sys /Windows/Drivers/VirtIO/netkvm.sys" > $W/virtio171.log 2>&1 && log "virtio 0.1.171 ($D) aplicado" || log "AVISO virtio171: $(tail -2 $W/virtio171.log)"
fi
if [[ "$OSN" == *2012* ]]; then  # Win2012: publicador Red Hat nao confiavel -> driver de rede fica sem instalar (prompt invisivel)
  virt-customize -a $W/$VM-sda --upload /NFS01/migrate/ENSAIO/fb2012.ps1:/Windows/Temp/fb2012.ps1 \
    --firstboot-command "powershell -NoProfile -ExecutionPolicy Bypass -File C:\\Windows\\Temp\\fb2012.ps1" > $W/fb.log 2>&1 \
    && log "firstboot 2012 (trust Red Hat + pnputil) injetado" || log "AVISO firstboot 2012 falhou: $(tail -2 $W/fb.log)"
fi
if [[ "$OSN" == *Linux* ]]; then  # Linux: ifcfg preso ao nome da placa VMware (ens192) -> eth0 estavel
  virt-customize $(for d in $(ls $W/$VM-sd? | sort); do echo -a $d; done) --run /NFS01/migrate/ENSAIO/fixnet_linux.sh > $W/fixnet.log 2>&1 \
    && log "fixnet linux: $(grep -h fixnet: $W/fixnet.log | tail -1)" || log "AVISO fixnet linux falhou: $(tail -2 $W/fixnet.log)"
fi
n=0; for d in $(ls $W/$VM-sd? | sort); do mv $d $OUT/$VM-disk-$n.qcow2; n=$((n+1)); done
chmod 644 $OUT/*.qcow2; chown -R inovatech:inovatech $OUT; rm -rf $W
for q in $OUT/*.qcow2; do log "  OUT $(basename $q) $(du -h $q | cut -f1)"; done
R="RESULT|$VM|fw=$FW|os=$OSN|discos=$n|total=$(( $(t)-T0 ))s"; log "$R"; echo "$R" > /NFS01/migrate/ENSAIO/logs/$VM.result
