
# This is the Vagrantfile template for the default virtualbox provider
# Requires: VAGRANT_EXPERIMENTAL="disks" for disk provisioning to work

# read ssh key from current user's ~/.ssh
ssh_prv_key = File.read(File.join(ENV['HOME'], '.ssh', 'id_rsa'))
ssh_pub_key = File.readlines(File.join(ENV['HOME'], '.ssh', 'id_rsa.pub')).first.strip

Vagrant.configure("2") do |config|
    config.ssh.insert_key = false
    config.vm.box_check_update = false
    config.vm.synced_folder ".", "/vagrant", disabled: true
    config.vm.provision "shell" do |s|
      s.inline = <<-SHELL
        if grep -sq "#{ssh_pub_key}" /home/vagrant/.ssh/authorized_keys; then
          echo "SSH keys already provisioned." ; exit 0;
        fi
        echo "SSH key provisioning."
        sshd=/home/vagrant/.ssh
        mkdir -p ${sshd}; touch ${sshd}/{authorized_keys,config}
        echo #{ssh_pub_key}   >> ${sshd}/authorized_keys
        echo #{ssh_pub_key}   >  ${sshd}/id_rsa.pub      ; chmod 644 ${sshd}/id_rsa.pub
        echo "#{ssh_prv_key}" >  ${sshd}/id_rsa          ; chmod 600 ${sshd}/id_rsa
        if ! grep -q "StrictHostKeyChecking" ${sshd}/config; then
            echo 'StrictHostKeyChecking=no' >> ${sshd}/config
        fi
        chown -R vagrant:vagrant /home/vagrant
        exit 0
      SHELL
    end

    Specs.each_with_index do |spec, index|
        config.vm.define spec["name"] do |node|
            node.vm.box = spec["image"]
            node.vm.network "private_network", ip: spec["ip"]
            node.vm.hostname = spec["name"]
            disk_size = spec["disk"] || 128

            node.vm.provider "virtualbox" do |v|
                v.linked_clone = true
                v.customize ["modifyvm", :id, "--cpus", spec["cpu"], "--memory", spec["mem"], "--nictype1", "virtio", "--nictype2", "virtio"]
                v.customize ["guestproperty", "set", :id, "/VirtualBox/GuestAdd/VBoxService/--timesync-set-threshold", 1000]
            end

            # provision additional disks using vagrant experimental disk feature
            # requires: VAGRANT_EXPERIMENTAL="disks"
            if spec["name"].start_with?("minio")
                node.vm.disk :disk, name: "data1", size: "32GB"
                node.vm.disk :disk, name: "data2", size: "32GB"
                node.vm.disk :disk, name: "data3", size: "32GB"
                node.vm.disk :disk, name: "data4", size: "32GB"
            else
                node.vm.disk :disk, name: "data", size: "#{disk_size}GB"
            end

            # format and mount disks - detect the actual device dynamically
            if spec["name"].start_with?("minio")
                node.vm.provision "shell" do |s|
                  s.inline = <<-SHELL
                    # find unformatted disks (exclude the root disk)
                    ROOT_DISK=$(lsblk -no PKNAME $(findmnt -n -o SOURCE /) | head -1)
                    DISKS=($(lsblk -dpno NAME | grep -v "/dev/${ROOT_DISK}" | sort))
                    if [ ${#DISKS[@]} -lt 4 ]; then
                      echo "Warning: Expected 4 data disks, found ${#DISKS[@]}"
                      exit 0
                    fi
                    for i in 1 2 3 4; do
                      DISK=${DISKS[$((i-1))]}
                      MOUNT="/data${i}"
                      mkdir -p ${MOUNT}
                      if [ -b "${DISK}" ] && ! blkid "${DISK}" | grep -q xfs; then
                        mkfs.xfs -f "${DISK}"
                      fi
                      if ! grep -q "${DISK}" /etc/fstab; then
                        echo "${DISK} ${MOUNT} xfs defaults,noatime,nodiratime 0 0" >> /etc/fstab
                      fi
                    done
                    mount -a
                  SHELL
                end
            else
                node.vm.provision "shell" do |s|
                  s.inline = <<-SHELL
                    # find the first non-root disk
                    ROOT_DISK=$(lsblk -no PKNAME $(findmnt -n -o SOURCE /) | head -1)
                    DATA_DISK=$(lsblk -dpno NAME | grep -v "/dev/${ROOT_DISK}" | head -1)
                    if [ -z "${DATA_DISK}" ]; then
                      echo "No additional data disk found, skipping..."
                      exit 0
                    fi
                    if [ -b "${DATA_DISK}" ] && ! blkid "${DATA_DISK}" | grep -q xfs; then
                      mkfs.xfs -f "${DATA_DISK}"
                    fi
                    mkdir -p /data
                    if ! grep -q "${DATA_DISK}" /etc/fstab; then
                      echo "${DATA_DISK} /data xfs defaults,noatime,nodiratime 0 0" >> /etc/fstab
                    fi
                    mount -a
                  SHELL
                end
            end

        end
    end
end
