VAGRANTFILE_API_VERSION = "2"
ENV['VAGRANT_DEFAULT_PROVIDER'] = "vmware_esxi"

BRANCH=ENV['BRANCH'] || "main"
BRANCH_EXTRA=ENV['BRANCH_EXTRA'] || BRANCH

OGAGENTVERSION="1.1.2"

LANGUAGE = "es_ES"
ENV['LC_ALL'] = LANGUAGE + ".UTF-8"

NCLIENTS = ENV['NUMBER_OF_CLIENTS']|| 4
NCLIENTS = NCLIENTS.to_i

SERVERMEM = 2048	# Minimum: 512
CLIENTMEM = 512		# Minimum: 256

MACPREFIX = ENV['OGN_MAC_PREFIX'] || '00:50:56:aa:aa'
NETPREFIX = ENV['OGN_NET_PREFIX'] || "192.168.2"
DHCPNET   = ENV['DHCPNET'] || "192.168.2.0"

SERVERIP = "#{NETPREFIX}.10"

LOCALWEBPORT = 8443

ESXIPASSWORD = ENV['ESXI_PASSWORD'] || 'prompt:'

GITEA_TOKEN = ENV['GITEA_TOKEN']
GITEA_USER = ENV['GITEA_USER'] || 'unizar'
SSH_GIT_KEY_PASS = ENV['SSH_GIT_KEY_PASS'] || ''


OGSERVERSCRIPT = <<EOT
echo -n 'hostname: '; hostname -f
echo env vars beginning with OG:
env |grep OG
ip address show eth0

# Fix problem with gitea host
grep -q '^150\.214\.58\.246' /etc/hosts || echo "150.214.58.246 ognproject.evlt.uma.es" >> /etc/hosts

echo Setting up SSH config and agent
mkdir -p /root/.ssh/
cp /vagrant/config/id_rsa /root/.ssh/id_rsa
chown root:root /root/.ssh/id_rsa
chmod 0400 /root/.ssh/id_rsa
cp /vagrant/config/ssh_config /root/.ssh/config
chown root:root /root/.ssh/config
chmod 0400 /root/.ssh/config
cp /vagrant/config/ask_pass.sh /root/ask_pass.sh
chmod 755 /root/ask_pass.sh

eval `ssh-agent`
export DISPLAY=:0
export SSH_ASKPASS=/root/ask_pass.sh
ssh-add /root/.ssh/id_rsa <<< $SSH_GIT_KEY_PASS


echo Setting up language and locales
export LANG="#{LANGUAGE}.UTF-8"
echo "LANG=\\\"$LANG\\\"" > /etc/default/locale
echo "LANG=\\\"$LANG\\\"" >> /etc/environment
locale-gen --lang #{LANGUAGE}
sed -i "s/XKBLAYOUT=.*/XKBLAYOUT=\\\"${LANG%_*}\\\"/" /etc/default/keyboard
dpkg-reconfigure -fnoninteractive console-setup


# Exit if OpenGnsys is installed.
[ -f /opt/opengnsys/doc/VERSION.json ] && echo "Cannot provision, OpenGnsys is already installed." && exit 1


echo Creating a repository disk
if [ -z "$(blkid /dev/mapper/og-images | grep ext4)" ]; then
    pvcreate /dev/sdb
    vgcreate og /dev/sdb
    vgchange -ay
    lvcreate -ay -n images -l 100%VG og
    mkfs -t ext4 /dev/mapper/og-images
    mkdir -p /opt/opengnsys/images
    echo "/dev/mapper/og-images  /opt/opengnsys/images  ext4  defaults  0  0" >> /etc/fstab
    mount -a
fi


if [ -f /etc/netplan/01-eth1.yaml ]; then
    echo "Network configured, skipping"
else
    echo "Configuring eth1"
    sed -i "s/##ADDRESS##/${NETPREFIX}.1/g" /tmp/01-eth1.yaml
    mv /tmp/01-eth1.yaml /etc/netplan
    chown root:root /etc/netplan/01-eth1.yaml
    netplan apply
    while ! ip address show eth0 |grep -qw inet; do
        echo eth0 has no IPv4, waiting...
        sleep 1
    done
fi


# Download installer
echo Downloading https://ognproject.evlt.uma.es/gitea/opengnsys/opengnsys/raw/branch/${BRANCH}/installer/opengnsys_installer_devel_esxi.sh
curl --retry 5 --stderr - --insecure --location --output opengnsys_installer_devel_esxi.sh https://$GITEA_USER:$GITEA_TOKEN@ognproject.evlt.uma.es/gitea/opengnsys/opengnsys/raw/branch/${BRANCH}/installer/opengnsys_installer_devel_esxi.sh
chmod 755 opengnsys_installer_devel_esxi.sh && ./opengnsys_installer_devel_esxi.sh $BRANCH

[ -e /opt/opengnsys/log/bash.log ] && mv /opt/opengnsys/log/bash.log /opt/opengnsys/log/opengnsys_installer.log

echo y | /opt/opengnsys/bin/setserveraddr $(ip -o link show | tail -1 | cut -d: -f2)

# Insert DHCP data.
sed -i "/^}$/ i host modelo { hardware ethernet #{MACPREFIX}:FF; fixed-address #{NETPREFIX}.199; }" /etc/dhcp/dhcpd.conf
for ((i=#{NCLIENTS+10}; i>10; i--)); do
    sed -i "/^}$/ i host pc${i} { hardware ethernet #{MACPREFIX}:${i}; fixed-address #{NETPREFIX}.${i}; }" /etc/dhcp/dhcpd.conf
done
service isc-dhcp-server restart

echo Creating an aula and some clients
SQL="INSERT INTO aulas (nombreaula, idcentro, urlfoto, grupoid, ubicacion, puestos, modomul, ipmul, pormul, velmul, router, netmask, ntp, dns, proxy, modp2p, timep2p)"\
"VALUES  ('Aula virtual', 1, 'aula.jpg', 0, 'Despliegue virtual con Vagrant.', 5, 2, '239.194.2.11', 9000, 70, '#{NETPREFIX}.1', '255.255.255.0', '', '', '', 'peer', 30); "\
"INSERT INTO ordenadores (nombreordenador, ip, mac, idaula, idrepositorio, idperfilhard, idmenu, idproautoexec, grupoid, router, mascara, arranque, netiface, netdriver, fotoord) VALUES "\
"('modelo', '#{NETPREFIX}.199', REPLACE('#{MACPREFIX}FF',':',''), 1, 1, 0, 0, 0, 0, '#{NETPREFIX}.1', '255.255.255.0', '00unknown', 'eth0', 'generic', 'fotoordenador.gif'),"
for ((i=11; i<=#{NCLIENTS+10}; i++)); do
    SQL="$SQL ('pc$i', '#{NETPREFIX}.$i', REPLACE('#{MACPREFIX}$i',':',''), 1, 1, 0, 0, 0, 0, '#{NETPREFIX}.1', '255.255.255.0', '00unknown', 'eth0', 'generic', 'fotoordenador.gif'),"
done
mysql -u usuog -ppassusuog -D ogAdmBD -e "${SQL%,}"
/opt/opengnsys/bin/setclientmode ogLiveAdmin modelo PERM
/opt/opengnsys/bin/setclientmode ogLiveAdmin pc11 PERM
for ((i=12; i<=#{NCLIENTS+10}; i++)); do
    /opt/opengnsys/bin/setclientmode ogLive pc$i PERM
done

echo "Notes:"
echo "- OpenGnsys Server URL: https://localhost:${LOCALWEBPORT}/opengnsys/"
exit 0
EOT


OGDHCPSCRIPT = <<EOT
echo in ogdhcp script
echo -n 'hostname: '; hostname -f
echo env vars beginning with OG:
env |grep OG
ip address show eth0
echo "OGDHCP_BRANCH ($OGDHCP_BRANCH)"
EOT


OGBOOTSCRIPT = <<EOT
echo in ogboot script
echo -n 'hostname: '; hostname -f
echo env vars beginning with OG:
env |grep OG
ip address show eth0
echo "OGBOOT_BRANCH ($OGBOOT_BRANCH)"
echo "OGSERVER_IP ($OGSERVER_IP)"
#curl --retry 5 --stderr - --insecure --location --output installer.py https://$GITEA_USER:$GITEA_TOKEN@ognproject.evlt.uma.es/gitea/opengnsys/ogboot/raw/branch/ ${OGBOOT_BRANCH}/installer.py
#python3 /install.py
EOT


OGREPOSCRIPT = <<EOT
echo in ogrepo script
echo -n 'hostname: '; hostname -f
echo env vars beginning with OG:
env |grep OG
ip address show eth0
echo "OGREPO_BRANCH ($OGREPO_BRANCH)"
EOT


OGLOGSCRIPT = <<EOT
echo in oglog script
echo -n 'hostname: '; hostname -f
echo env vars beginning with OG:
env |grep OG
ip address show eth0
echo "OGLOG_BRANCH ($OGLOG_BRANCH)"
EOT


Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
    require 'pp'

    def do_debug(msg)
        if ENV.has_key?("DEBUG_VAGRANT") and ENV["DEBUG_VAGRANT"] == "true" then
            if msg.class == Array then
                #PP.pp(msg, STDERR)        ## doesn't actually pretty print to the jenkins log
                STDERR.puts msg.pretty_inspect
            else
                STDERR.puts msg
            end
        end
    end

    provisioners_env = {
        "NETPREFIX"                 => NETPREFIX,
        "BRANCH"                    => BRANCH,
        "OGDHCP_BRANCH"             => ENV['OGDHCP_BRANCH'],
        "OGBOOT_BRANCH"             => ENV['OGBOOT_BRANCH'],
        "OGREPO_BRANCH"             => ENV['OGREPO_BRANCH'],
        "OGLOG_BRANCH"              => ENV['OGLOG_BRANCH'],
        "GITEA_TOKEN"               => GITEA_TOKEN,
        "GITEA_USER"                => GITEA_USER,
        "DHCPNET"                   => DHCPNET,
        "SSH_GIT_KEY_PASS"          => SSH_GIT_KEY_PASS,
        "LOCALWEBPORT"              => LOCALWEBPORT,
        "DEFAULT_UDS_REST_URL"      => ENV['DEFAULT_UDS_REST_URL'],
        "DEFAULT_UDS_AUTHENTICATOR" => ENV['DEFAULT_UDS_AUTHENTICATOR'],
        "DEFAULT_UDS_USER"          => ENV['DEFAULT_UDS_USER'],
        "DEFAULT_UDS_PASS"          => ENV['DEFAULT_UDS_PASS'],
        "OGLOG_IP"                  => ENV['OGLOG_IP'],
        "OGSERVER_IP"               => ENV['OGSERVER_IP'],
    }
    app_servers = {
        'vm1' => {
            :name               => "og-#{BRANCH_EXTRA}-server",
            :memsize            => SERVERMEM,
            :clone_from         => 'Ubuntu-18-template-image',
            :networks           => [ 'vLan_742', BRANCH_EXTRA ],
            :macs               => [ "#{MACPREFIX}:00", "#{MACPREFIX}:01" ],
            :file_provisioner   => {
                :src => "config/01-eth1.yaml",
                :dst => "/tmp/",
            },
            :shell_provisioners => [ OGSERVERSCRIPT ],
        },
    }

    vm1_components = vm2_components = []

    if ENV.has_key?("VM1_COMPONENTS") then
        vm1_components = ENV["VM1_COMPONENTS"].split(" ")
    end

    if ENV.has_key?("VM2_COMPONENTS") then
        vm2_components = ENV["VM2_COMPONENTS"].split(" ")
        if vm2_components.size > 0 then
            app_servers['vm2'] = {
                :name               => "og-#{BRANCH_EXTRA}",
                :memsize            => SERVERMEM,
                :clone_from         => 'Ubuntu-18-template-image',
                :networks           => [ 'vLan_742' ],
                :macs               => [ "#{MACPREFIX}:02" ],
                :shell_provisioners => [],
            }
        end
    end
    do_debug ("VM1_COMPONENTS: " + vm1_components.to_s)
    do_debug ("VM2_COMPONENTS: " + vm2_components.to_s)

    vms_loop = [
        { "components" => vm1_components, "key" => "vm1" },
        { "components" => vm2_components, "key" => "vm2" },
    ]
    all_components = [
        { "name" => "oglog",  "hostname_suffix" => "-log",  "script" => OGLOGSCRIPT  },
        { "name" => "ogdhcp", "hostname_suffix" => "-dhcp", "script" => OGDHCPSCRIPT },
        { "name" => "ogboot", "hostname_suffix" => "-boot", "script" => OGBOOTSCRIPT },
        { "name" => "ogrepo", "hostname_suffix" => "-repo", "script" => OGREPOSCRIPT },
    ]

    ## foreach VM, foreach OG component: edit hostname and add provisioning script
    vms_loop.each do |vm|
        components = vm['components']
        key = vm['key']
        all_components.each do |c|
            if components.include?(c['name']) then
                app_servers[key][:name] += c['hostname_suffix']
                app_servers[key][:shell_provisioners].push (c['script'])
            end
        end
    end

    do_debug (app_servers)

    app_servers.each do |machine,data|
        boxname = data[:name]
        config.vm.define boxname do |og|
            og.vm.provider :vmware_esxi do |esxi|
                esxi.guest_name = boxname
                esxi.guest_memsize = data[:memsize]
                esxi.esxi_username = 'root'
                esxi.esxi_password = ESXIPASSWORD
                esxi.esxi_hostname = 'esxi-jenkins.evlt.uma.es'
                esxi.clone_from_vm = data[:clone_from]
                esxi.esxi_resource_pool = "/"
                esxi.local_allow_overwrite = 'True'
                esxi.guest_custom_vmx_settings = [['monitor.allowLegacyCPU', 'TRUE']]
                esxi.guest_storage = [ 10 ]
                esxi.esxi_virtual_network = data[:networks]
                esxi.guest_mac_address = data[:macs]
                esxi.guest_nic_type = 'e1000'
            end
            og.vm.box = "esxi_clone/dummy"
            og.vm.hostname = boxname
            if data.key?(:file_provisioner)
                og.vm.provision "file", source: data[:file_provisioner][:src], destination: data[:file_provisioner][:dst]
            end
            data[:shell_provisioners].each do |script|
                og.vm.provision "shell", inline: script, env: provisioners_env
            end
        end
    end
end
