# ******************************************************************************
# IBM Cloud Kubernetes Service, 5737-D43
# (C) Copyright IBM Corp. 2021 All Rights Reserved.
#
# SPDX-License-Identifier: Apache2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ******************************************************************************
# -*- mode: ruby -*-
# vi: set ft=ruby :

build_steps = ENV.fetch('CLOUD_PROVIDER_IBM_BUILD_STEPS','')

# Inline script to setup Python and pip for the build.
$setup_python_and_pip = <<SCRIPT
function exit_build {
    echo "ERROR: Failed to setup Python and pip"
    exit 1
}

PYTHON3_VERSION=python3.8

apt-get install -y software-properties-common
if [[ $? -ne 0 ]]; then exit_build ; fi
apt-add-repository -y ppa:deadsnakes/ppa
if [[ $? -ne 0 ]]; then exit_build ; fi
apt-get update
apt-get install -y ${PYTHON3_VERSION} ${PYTHON3_VERSION}-dev ${PYTHON3_VERSION}-distutils ${PYTHON3_VERSION}-venv
if [[ $? -ne 0 ]]; then exit_build ; fi

${PYTHON3_VERSION} -m ensurepip --upgrade --default-pip
if [[ $? -ne 0 ]]; then exit_build ; fi
# ensurepip doesn't always get the latest pip installed
pip install --upgrade pip
if [[ $? -ne 0 ]]; then exit_build ; fi
SCRIPT

# Inline script to setup go and docker for the build.
$setup_go_and_docker = <<SCRIPT
function exit_build {
    echo "ERROR: Failed to setup go and docker"
    exit 1
}

apt-get install -y make
if ! hash go 2>/dev/null; then
    # Add apt-repository ppa:ubuntu-lxc/lxd-stable
    curl -O https://dl.google.com/go/go1.17.5.linux-amd64.tar.gz
    if [[ $? -ne 0 ]]; then exit_build ; fi
    tar -C /usr/local -xzf go1.17.5.linux-amd64.tar.gz
    if [[ $? -ne 0 ]]; then exit_build ; fi
    if [ ! -n "$(grep "/usr/local/go/bin" /etc/profile)" ]; then
        echo 'export PATH=$PATH:/usr/local/go/bin' >> /etc/profile
    fi
else
    echo "Go already installed -- skipping install"
fi

# Install keys for docker install
if [ ! -f /etc/apt/sources.list.d/docker.list ]; then
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    echo "deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable" | tee \
         /etc/apt/sources.list.d/docker.list
else
    echo "Docker keys already installed - skipping"
fi

apt-get update
if [[ $? -ne 0 ]]; then exit_build ; fi
apt-get install -y mercurial apt-transport-https ca-certificates \
                   linux-image-extra-virtual \
                   docker.io sshpass gcc
if [[ $? -ne 0 ]]; then exit_build ; fi

echo -e "StrictHostKeyChecking no" >> /etc/ssh/ssh_config

echo 'Starting docker ...'
usermod -a -G docker vagrant
if [[ $? -ne 0 ]]; then exit_build ; fi
service docker start
if [[ $? -ne 0 ]]; then exit_build ; fi

# Add Go binaries to PATH
export PATH=PATH:$GOPATH/bin
SCRIPT

# Inline script to setup the build.
$setup_build = <<SCRIPT
function exit_build {
    echo "ERROR: Failed to setup build dependencies"
    exit 1
}

cd cloud-provider-ibm
if ! make setup-build; then exit_build ; fi
if ! make install-golangci-lint; then exit_build ; fi
SCRIPT

if File.exists?('/var/run/libvirtd.pid')
  PROVIDER = "libvirt"
  BOX_IMAGE = "generic/ubuntu1804"
else
  PROVIDER = "virtualbox"
  BOX_IMAGE = "bento/ubuntu-18.04"
end

# With libvirt, we need to override qemu_use_session on vagrant 2.2 or later
v = `vagrant --version | awk '{print $2}'`
VAGRANT_VERSION = Gem::Version.new(v)
VAGRANT_2_2 = Gem::Version.new('2.2.0')

VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = BOX_IMAGE
  if PROVIDER == "virtualbox"
    # For direct ssh to VM on a known port (convenience method vs vagrant ssh):
    # Use guest port that doesn't conflict with other vagrant environments.
    # Causes vagrant up to hang using libvirt provider (for me)
    config.vm.network "forwarded_port", guest: 22, host: 2210, id: 'ssh', auto_correct: true
    config.ssh.guest_port = 2210
    config.ssh.forward_agent = true
  end
  config.vm.synced_folder File.expand_path(".."), "/home/vagrant/cloud-provider-ibm"

  # Use IP address accessible to other vagrant environments.
  config.vm.define "cloud-provider-ibm-build" do |node|
    node.vm.network "private_network", ip: "192.168.10.10"
    node.vm.hostname = "cloud-provider-ibm-build"
    node.vm.provision "shell", inline: $setup_go_and_docker
    node.vm.provision "shell", inline: $setup_python_and_pip
    node.vm.provision "shell", inline: $setup_build
    node.vm.provision "shell", path: "provisioning/build.sh", privileged: false, args: "#{build_steps}"
    node.vm.provider PROVIDER do |nodeopts|
      nodeopts.memory = "4096"
      nodeopts.cpus = 2
      if PROVIDER == "libvirt" and VAGRANT_VERSION >= VAGRANT_2_2
        nodeopts.qemu_use_session = false
      end
      if PROVIDER == "virtualbox"
        nodeopts.customize ['modifyvm', :id, '--natdnshostresolver1', "on"]
      end
    end
  end
end
