#!/bin/bash
# Ubuntu base build

# vim: ts=4 sw=4 sts=4 et tw=72 :

# force any errors to cause the script and job to end in failure
set -xeu -o pipefail

rh_systems() {
    echo 'No changes to apply'
}

ubuntu_systems() {
    DISTRO=$(lsb_release -cs)

    # get prereqs for PPA and apt-over-HTTPS support
    apt-get clean
    apt-get update
    apt-get install -y apt-transport-https software-properties-common

    # set up git backports repo
    add-apt-repository -y  ppa:git-core/ppa

    # set up docker repo
    cat << EOF | base64 -d > /tmp/docker-apt-key.gpg

aAotLS0tLUVORCBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCg==
EOF

    apt-key add /tmp/docker-apt-key.gpg
    add-apt-repository -y \
        "deb [arch=amd64] https://download.docker.com/linux/ubuntu $DISTRO stable"

    # set up golang repo
    # docs: https://github.com/golang/go/wiki/Ubuntu
    add-apt-repository -y ppa:longsleep/golang-backports

    # set up kubernetes repo
    cat << EOF | base64 -d > /tmp/k8s-apt-key.gpg
xsBNBFrBaNsBCADrF18KCbsZlo4NjAvVecTBCnp6WcBQJ5oSh7+E98jX9YznUCrNrgmeCc
CMUvTDRDxfTaDJybaHugfba43nqhkbNpJ47YXsIa+YL6eEE9emSmQtjrSWIiY+2YJYwsDg
sgckF3duqkb02OdBQlh6IbHPoXB6H//b1PgZYsomB+841XW1LSJPYlYbIrWfwDfQvtkFQI
90r6NknVTQlpqQh5GLNWNYqRNrGQPmsB+NrUYrkl1nUt1LRGu+rCe4bSaSmNbwKMQKkROE
4kTiB72DPk7zH4Lm0uo0YFFWG4qsMIuqEihJ/9KNX8GYBr+tWgyLooLlsdK3l+4dVqd8cj
kJM1ExABEBAAHNQEdvb2dsZSBDbG91ZCBQYWNrYWdlcyBBdXRvbWF0aWMgU2lnbmluZyBL
ZXkgPGdjLXRlYW1AZ29vZ2xlLmNvbT7CwHgEEwECACwFAlrBaNsJEGoDCyG6B/T7AhsPBQ
kFo5qABgsJCAcDAgYVCAIJCgsEFgIDAQAAJr4IAM5lgJ2CTkTRu2iw+tFwb90viLR6W0N1
CiSPUwi1gjEKMr5r0aimBi6FXiHTuX7RIldSNynkypkZrNAmTMM8SU+sri7R68CFTpSgAv
W8qlnlv2iwrEApd/UxxzjYaq8ANcpWAOpDsHeDGYLCEmXOhu8LmmpY4QqBuOCM40kuTDRd
52PCJE6b0V1t5zUqdKeKZCPQPhsS/9rdYP9yEEGdsx0V/Vt3C8hjv4Uwgl8Fa3s/4ag6lg
If+4SlkBAdfl/MTuXu/aOhAWQih444igB+rvFaDYIhYosVhCxP4EUAfGZk+qfo2mCY3w1p
te31My+vVNceEZSUpMetSfwit3QA8EE=
EOF

    apt-key add /tmp/k8s-apt-key.gpg
    add-apt-repository -y "deb http://apt.kubernetes.io/ kubernetes-xenial main"

    # set up NodeJS repo
    # Instructions: https://github.com/nodesource/distributions/blob/master/README.md#manual-installation
    cat << EOF | base64 -d > /tmp/nodejs-apt-key.gpg

1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLQo=
EOF

    apt-key add /tmp/nodejs-apt-key.gpg
    NODE_VERSION=node_7.x
    add-apt-repository -y "deb [arch=amd64] https://deb.nodesource.com/$NODE_VERSION $DISTRO main"

    # update after adding apt repos to sources
    apt-get update

    # install basic sofware requirements
    apt-get install -y \
        "docker-ce=5:19.03*" \
        apt-transport-https \
        build-essential \
        bzip2 \
        cloud-init \
        curl \
        ebtables \
        enchant \
        ethtool \
        git \
        golang-1.12-go \
        graphviz \
        jq \
        kafkacat \
        "kubeadm=1.18*" \
        "kubelet=1.18*" \
        "kubectl=1.18*" \
        "kubernetes-cni=0.8.7*" \
        less \
        libmysqlclient-dev \
        libpcap-dev \
        libxml2-utils \
        maven \
        nodejs \
        python \
        python-dev \
        python-pip \
        python3-dev \
        python3-pip \
        ruby \
        screen \
        socat \
        ssh \
        sshpass \
        zip
        # end of apt-get install list

    # remove apt installed incompatible python tools
    # NOTE: Python3 versions are not removed, as cloud-init depends on them
    apt-get -y remove \
      python-enum34 \
      python-cryptography \
      python-openssl \
      python-ndg-httpsclient \
      python-requests \
      python-six \
      python-urllib3

    # install python3 modules
    # upgrade pip or other installations may fail in unusual ways
    pip3 install --upgrade pip
    pip3 install \
        ansible \
        ansible-lint \
        docker \
        docker-compose \
        git-review \
        httpie \
        netaddr \
        pylint \
        tox \
        twine \
        virtualenv \
        yamllint
        # end of pip3 install list

    # install python2 modules
    # upgrade pip or other installations may fail in unusual ways
    python -m pip install --upgrade pip
    python -m pip install \
        Jinja2 \
        coverage \
        certifi \
        cryptography \
        git+https://github.com/linkchecker/linkchecker.git@v9.4.0 \
        graphviz \
        grpcio-tools \
        isort \
        more-itertools==5.0.0 \
        mock==2.0.* \
        ndg-httpsclient \
        nose2==0.9.* \
        pyopenssl \
        pexpect \
        pyyaml==3.10.* \
        requests==2.14.* \
        robotframework \
        robotframework-httplibrary \
        robotframework-kafkalibrary \
        robotframework-lint \
        robotframework-requests \
        robotframework-sshlibrary \
        six \
        urllib3
        # end of pip install list

    # install ruby gems
    gem install \
        mdl -v 0.5.0
        # end of gem install list

    # install npm modules
    npm install -g \
        gitbook-cli \
        markdownlint \
        typings

    # install golang packages in /usr/local/go
    # Set PATH=$PATH:/usr/local/go/bin` to use these
    export GOPATH=/usr/local/go
    mkdir -p $GOPATH
    export PATH=$PATH:/usr/lib/go-1.12/bin:$GOPATH/bin

    # converters for unit/coverage tests
    go get -v github.com/t-yuki/gocover-cobertura
    go get -v github.com/jstemmer/go-junit-report

    # github-release - uploader for github artifacts
    go get -v github.com/github-release/github-release

    # dep for go package dependencies w/versioning, version 0.5.2, adapted from:
    #  https://golang.github.io/dep/docs/installation.html#install-from-source
    go get -d -u github.com/golang/dep
    pushd "$(go env GOPATH)/src/github.com/golang/dep"
      git checkout "0.5.2"
      go install -ldflags="-X main.version=0.5.2" ./cmd/dep
    popd

    # golangci-lint for testing
    #  https://github.com/golangci/golangci-lint#local-installation
    GO111MODULE=on go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.17.1

    # protoc-gen-go - Golang protbuf compiler extension for protoc (installed
    # below)
    go get -d -u github.com/golang/protobuf/protoc-gen-go
    pushd "$(go env GOPATH)/src/github.com/golang/protobuf"
      git checkout "v1.3.1"
      go install ./protoc-gen-go
    popd

    # install repo launcher v2.9
    REPO_B64_SHA256SUM="da4a14be94382f7ecdb22fef4f554eb0ffcf09a0d8c352667beae4a1794ad666"
    curl -o /tmp/repo.b64 'https://gerrit.googlesource.com/git-repo/+/refs/tags/v2.9/repo?format=TEXT'
    echo "$REPO_B64_SHA256SUM  /tmp/repo.b64" | sha256sum -c -
    base64 --decode /tmp/repo.b64 > /tmp/repo
    mv /tmp/repo /usr/local/bin/repo
    chmod a+x /usr/local/bin/repo

    # add host entries to /etc/hosts to allow resolving the virtual hosts
    # used to expose the voltha api (voltha.voltha.local) and etcd
    # (voltha-infra.local) inside of k8s via ingress to localhost
    for INGRESS_HOST in voltha.voltha.local voltha-infra.local; do
      echo "adding host entry for $INGRESS_HOST"
      sed -i "s/^127.0.0.1[[:blank:]]\+localhost/& $INGRESS_HOST/" /etc/hosts
    done

    # install helm
    HELM_VERSION="3.4.2"
    HELM_SHA256SUM="cacde7768420dd41111a4630e047c231afa01f67e49cc0c6429563e024da4b98"
    HELM_PLATFORM="linux-amd64"
    curl -L -o /tmp/helm.tgz "https://get.helm.sh/helm-v${HELM_VERSION}-${HELM_PLATFORM}.tar.gz"
    echo "$HELM_SHA256SUM  /tmp/helm.tgz" | sha256sum -c -
    pushd /tmp
    tar -xzvf helm.tgz
    mv ${HELM_PLATFORM}/helm /usr/local/bin/helm
    chmod a+x /usr/local/bin/helm
    rm -rf helm.tgz ${HELM_PLATFORM}
    popd

    # install minikube
    MINIKUBE_VERSION="1.13.1"
    MINIKUBE_SHA256SUM="ac6cd65568f1fdab13207aaed3903037b07bd660a7d0eb4331a2a4198890de39"
    curl -L -o /tmp/minikube.deb "https://github.com/kubernetes/minikube/releases/download/v${MINIKUBE_VERSION}/minikube_${MINIKUBE_VERSION}-0_amd64.deb"
    echo "$MINIKUBE_SHA256SUM  /tmp/minikube.deb" | sha256sum -c -
    pushd /tmp
    dpkg -i minikube.deb
    rm -f minikube.deb
    popd

    # install protobufs
    PROTOC_VERSION="3.7.0"
    PROTOC_SHA256SUM="a1b8ed22d6dc53c5b8680a6f1760a305b33ef471bece482e92728f00ba2a2969"
    curl -L -o /tmp/protoc-${PROTOC_VERSION}-linux-x86_64.zip https://github.com/google/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-x86_64.zip
    echo "$PROTOC_SHA256SUM  /tmp/protoc-${PROTOC_VERSION}-linux-x86_64.zip" | sha256sum -c -
    unzip /tmp/protoc-${PROTOC_VERSION}-linux-x86_64.zip -d /tmp/protoc3
    mv /tmp/protoc3/bin/* /usr/local/bin/
    mv /tmp/protoc3/include/* /usr/local/include/
    # fix permissions on files
    chmod -R a+rx /usr/local/bin/*
    chmod -R a+rX /usr/local/include/

    # give sudo permissions on minikube and protoc to jenkins user
    cat << EOF > /etc/sudoers.d/88-jenkins-minikube-protoc
Cmnd_Alias CMDS = /usr/local/bin/protoc, /usr/bin/minikube
Defaults:jenkins !requiretty
jenkins ALL=(ALL) NOPASSWD:SETENV: CMDS
EOF

    # install hadolint (Dockerfile checker)
    HADOLINT_VERSION="1.18.0"
    HADOLINT_SHA256SUM="f9bc9de12438b463ca84e77fde70b07b155d4da07ca21bc3f4354a62c6199db4"
    curl -L -o /tmp/hadolint https://github.com/hadolint/hadolint/releases/download/v${HADOLINT_VERSION}/hadolint-Linux-x86_64
    echo "$HADOLINT_SHA256SUM  /tmp/hadolint" | sha256sum -c -
    mv /tmp/hadolint /usr/local/bin/hadolint
    chmod -R a+rx /usr/local/bin/hadolint

    # install pandoc (document converter)
    PANDOC_VERSION="2.10.1"
    PANDOC_SHA256SUM="4515d6fe2bf8b82765d8dfa1e1b63ccb0ff3332d60389f948672eaa37932e936"
    curl -L -o /tmp/pandoc.deb "https://github.com/jgm/pandoc/releases/download/${PANDOC_VERSION}/pandoc-${PANDOC_VERSION}-1-amd64.deb"
    echo "$PANDOC_SHA256SUM  /tmp/pandoc.deb" | sha256sum -c -
    dpkg -i /tmp/pandoc.deb
    rm -f /tmp/pandoc.deb

    # install yq (YAML query)
    YQ_VERSION="3.4.0"
    YQ_SHA256SUM="f6bd1536a743ab170b35c94ed4c7c4479763356bd543af5d391122f4af852460"
    curl -L -o /tmp/yq https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_amd64
    echo "$YQ_SHA256SUM  /tmp/yq" | sha256sum -c -
    mv /tmp/yq /usr/local/bin/yq
    chmod -R a+rx /usr/local/bin/yq

    # add docker cache
    cat << EOF > /etc/docker/daemon.json
{
    "registry-mirrors":["https://mirror.registry.opennetworking.org"]
}
EOF
    service docker restart

    # remove apparmor
    service apparmor stop
    update-rc.d -f apparmor remove
    apt-get remove apparmor-utils libapparmor-perl apparmor
    update-grub

    # clean up
    apt-get clean
    apt-get purge -y
    apt-get autoremove -y
    rm -rf /var/lib/apt/lists/*
}

all_systems() {
    echo 'No common distribution configuration to perform'
}

echo "---> Detecting OS"
ORIGIN=$(facter operatingsystem | tr '[:upper:]' '[:lower:]')

case "${ORIGIN}" in
    fedora|centos|redhat)
        echo "---> RH type system detected"
        rh_systems
    ;;
    ubuntu)
        echo "---> Ubuntu system detected"
        ubuntu_systems
    ;;
    *)
        echo "---> Unknown operating system"
    ;;
esac

# execute steps for all systems
all_systems

# [EOF]
