#!/bin/bash

# This script is used to prepare a new Ubuntu node for a Kubernetes installation.
# It will install the required components for the latest version of Kubernetes.
# No cluster configuration will be run, this is left to the user.

set -e

upgrade_system() {
  apt-get update
  apt-get upgrade -y
}

install_jq() {
  apt-get install -y jq
}

get_latest_version() {
  local owner="$1"
  local repo="$2"
  local version=$(curl -s https://api.github.com/repos/$owner/$repo/releases/latest | jq -r '.tag_name')
  echo "${version:1}"
}

get_latest_versions() {
  echo "Getting latest versions..."

  conatinerd_version=$(get_latest_version "containerd" "containerd")
  runc_version=$(get_latest_version "opencontainers" "runc")
  cni_plugins_version=$(get_latest_version "containernetworking" "plugins")

  echo "containerd: $conatinerd_version"
  echo "runc: $runc_version"
  echo "cni-plugins: $cni_plugins_version"
}

configure_kernal_modules() {
  echo 'overlay' > /etc/modules-load.d/k8s.conf
  echo 'br_netfilter' >> /etc/modules-load.d/k8s.conf
  modprobe overlay
  modprobe br_netfilter

  echo 'net.bridge.bridge-nf-call-iptables = 1' > /etc/sysctl.d/k8s.conf
  echo 'net.bridge.bridge-nf-call-ip6tables = 1' >> /etc/sysctl.d/k8s.conf
  echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.d/k8s.conf
  sysctl --system
}

install_containerd() {
  cd /tmp
  wget https://github.com/containerd/containerd/releases/download/v$conatinerd_version/containerd-$conatinerd_version-linux-amd64.tar.gz
  tar Cxzvf /usr/local containerd-$conatinerd_version-linux-amd64.tar.gz
  wget https://raw.githubusercontent.com/containerd/containerd/main/containerd.service
  mv containerd.service /etc/systemd/system/containerd.service
  mkdir -p /etc/containerd
  containerd config default > /etc/containerd/config.toml
  sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
  systemctl daemon-reload
  systemctl enable --now containerd
  rm containerd-$conatinerd_version-linux-amd64.tar.gz
}

install_runc() {
  cd /tmp
  wget https://github.com/opencontainers/runc/releases/download/v$runc_version/runc.amd64
  install -m 755 runc.amd64 /usr/local/sbin/runc
  rm runc.amd64
}

install_cni_plugins() {
  cd /tmp
  wget https://github.com/containernetworking/plugins/releases/download/v$cni_plugins_version/cni-plugins-linux-amd64-v$cni_plugins_version.tgz
  mkdir -p /opt/cni/bin
  tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v$cni_plugins_version.tgz
  rm cni-plugins-linux-amd64-v$cni_plugins_version.tgz
}

setup_kubernetes_repo() {
  apt-get install -y apt-transport-https ca-certificates curl
  curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg
  echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | tee /etc/apt/sources.list.d/kubernetes.list
  apt-get update
}

install_kubernetes() {
  apt-get install -y kubelet kubeadm kubectl
  apt-mark hold kubelet kubeadm kubectl
}

main() {
  upgrade_system
  install_jq
  get_latest_versions
  configure_kernal_modules
  install_containerd
  install_runc
  install_cni_plugins
  setup_kubernetes_repo
  install_kubernetes
}

main
