#!/bin/bash

# Author: Benyu Xu, xubenyu@hygon.cn



#set -x
set -e

export KATA_REPO_URL=https://mirrors.openanolis.org/inclavare-containers/anolis8.4
export KATA_REPO_KEY=https://mirrors.openanolis.org/inclavare-containers/anolis8.4/RPM-GPG-KEY-rpm-sign
export K8S_REPO_URL=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
export K8S_REPO_KEY="https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg"
export POD_NET_START=10.244.0
export POD_IMG_REGISTRY=registry.aliyuncs.com/google_containers
export FLANNEL_CONF_URL=https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
export TEST_IMG_NAME=busybox
export TEST_IMG_SUFFIX=sig-test
export OPA_URL=https://openpolicyagent.org/downloads/v0.30.1/opa_linux_amd64_static
export VERDICTD_GIT=https://github.com/inclavare-containers/verdictd.git
export SIG_INITRD_URL=http://mirrors.openanolis.cn/inclavare-containers/confidential-containers-demo/bin/ccv1-csv/initrd.sig.img
EMAIL_ADDR=""
USER_NM=""

check_succeed()
{
    if [ $? -eq 0 ];then
        echo "Succeed!"
	echo ""
    else
        echo "Faild!"
	echo ""
        exit
    fi
}

# disable firewalld
disable_firewall()
{
    echo "disable firewalld ..."
    sudo service firewalld stop
    check_succeed
}

# disable selinux
disable_selinux()
{
    echo "disable selinux ..."
    sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
    check_succeed
}

# check mirror reachable
check_mirror_reachable()
{
    echo "check mirror reachable ..."
    wget ${KATA_REPO_KEY}
    check_succeed
}

# install dependency
install_deps()
{
    echo "install dependency packages ..."
    sudo yum install -y yum-utils iproute-tc git cmake gcc-c++ openssl-devel
    check_succeed
}

# install go-lang
install_go()
{
    echo "install go-lang ..."
    cd $HOME
    wget https://golang.google.cn/dl/go1.17.2.linux-amd64.tar.gz
    tar zxvf go1.17.2.linux-amd64.tar.gz
    sudo ln -s $HOME/go/bin/go /usr/bin/
    export GOPROXY="https://mirrors.aliyun.com/goproxy,direct"
    mkdir -p go-path
    check_succeed
}

# install cargo
install_cargo()
{
    echo "install cargo ..."
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path
    source $HOME/.cargo/env
    check_succeed
}

# install kata
install_kata()
{
    echo "install kata-container ..."
    sudo yum-config-manager --add-repo ${KATA_REPO_URL} && \
        sudo rpm --import ${KATA_REPO_KEY} && \
        sudo yum install -y kata-static
    check_succeed
}

# install qemu-system-x86_64
install_qemu-system-x86_64()
{
    echo "install qemu-system-x86_64 ..."
    sudo yum install -y qemu-system-x86_64
    check_succeed
}

# install guest dependency
install_guest_deps()
{
    echo "install guest dependency ..."
    sudo yum install -y ccv0-guest
    check_succeed
}

# install kata-runtime
install_kata-runtime()
{
    echo "install kata-runtime ..."
    sudo yum -y install kata-runtime
    check_succeed
}

# configure kata-runtime
configure_kata-runtime()
{
    echo "configure kata-runtime ..."
    sudo mkdir -p /etc/kata-containers/
    sudo cp /opt/kata/share/defaults/kata-containers/configuration.toml /etc/kata-containers/ && \
        cd /etc/kata-containers/ && \
        sudo sed -i 's/opt\/kata\/bin\/qemu-system-x86_64/opt\/qemu\/bin\/qemu-system-x86_64/' configuration.toml && \
        sudo sed -i 's/kata\/share\/kata-containers\/vmlinux.container/csv\/ccv0-guest\/vmlinuz-5.15.0-rc5+/' configuration.toml && \
        #sed -i 's/image = \"\/opt\/kata\/share\/kata-containers\/kata-containers/initrd = \"\/opt\/csv\/ccv0-guest\/initrd.run/' configuration.toml && \
        sudo sed -i 's/\# confidential_guest/confidential_guest/' configuration.toml && \
        sudo sed -i 's/kernel_params = \"\"/kernel_params = \"agent.config_file=\/etc\/agent-config.toml\"/' configuration.toml && \
        sudo sed -i 's/firmware = \"\"/firmware = \"\/opt\/csv\/ccv0-guest\/OVMF.fd\"/' configuration.toml && \
        sudo sed -i 's/default_memory = 2048/default_memory = 8000/' configuration.toml && \
        sudo sed -i 's/shared_fs = \"virtio-fs\"/shared_fs = \"virtio-9p\"/' configuration.toml && \
        sudo sed -i 's/\#service_offload/service_offload/' configuration.toml
    check_succeed
}

# install containerd
install_containerd()
{
    echo "install containerd ..."
    sudo yum install -y containerd
    check_succeed
}

# start containerd service
start_containerd_service()
{
    echo "start containerd service ..."
	sudo systemctl enable /etc/systemd/system/containerd.service
    sudo systemctl daemon-reload
    sudo service containerd restart
    check_succeed
}

# install module br_netfilter
install_module_br_netfilter()
{
    echo "install module br_netfilter ..."
    sudo modprobe br_netfilter
    check_succeed
}

# enable iptables check the net bridge traffic
enable_check_br_traffic()
{
echo "enable iptables check the net bridge traffic ..."
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
check_succeed

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
check_succeed

sudo sysctl --system
check_succeed
}

# disable swap
disable_swap()
{
    echo "disable swap ..."
    sudo swapoff -a
    check_succeed
}

# install K8S
install_K8S()
{
echo "install K8S ..."
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=${K8S_REPO_URL}
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=${K8S_REPO_KEY}
EOF

check_succeed

sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
#sudo yum -y install kubelet-1.24.0-0.x86_64 kubectl-1.24.0-0.x86_64 kubeadm-1.24.0-0.x86_64
check_succeed
}

# configure K8S
configure_K8S()
{
echo "configure K8S ..."
sudo mkdir -p  /etc/systemd/system/kubelet.service.d/
cat <<EOF | sudo tee  /etc/systemd/system/kubelet.service.d/0-containerd.conf
[Service]
Environment="KUBELET_EXTRA_ARGS=--container-runtime=remote --runtime-request-timeout=15m --container-runtime-endpoint=unix:///run/containerd/containerd.sock"
EOF
check_succeed

cat << EOF | sudo tee /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"

#This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically

EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env

#This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use

#the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.

EnvironmentFile=-/etc/sysconfig/kubelet
ExecStart=
ExecStart=/usr/bin/kubelet \$KUBELET_KUBECONFIG_ARGS \$KUBELET_CONFIG_ARGS \$KUBELET_KUBEADM_ARGS \$KUBELET_EXTRA_ARGS
EOF
check_succeed
}

# initialize K8S
init_K8S()
{
    echo "initialize K8S ..."
    echo 1 > /proc/sys/net/ipv4/ip_forward
    sudo kubeadm init --cri-socket /run/containerd/containerd.sock --pod-network-cidr=${POD_NET_START}.0/16 --image-repository ${POD_IMG_REGISTRY}
    rm -rf $HOME/.kube
    mkdir -p $HOME/.kube
    sudo /bin/cp -f /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
    check_succeed
}

# enable master node
enable_master_node()
{
    echo "enable master node ..."
    su -c \
    'export KUBECONFIG=/etc/kubernetes/admin.conf
    kubectl taint nodes --all node-role.kubernetes.io/master-'
    check_succeed
}

# install flannel
install_flannel()
{
    echo "get flannel config"
    su -c \
    "wget --no-check-certificate --retry-connrefused --waitretry=1 --read-timeout=20 --timeout=15 --tries=0 ${FLANNEL_CONF_URL}  -O kube-flannel.yml"
    check_succeed

    echo "install flannel ..."
    su -c \
        "export KUBECONFIG=/etc/kubernetes/admin.conf
        kubectl apply -f ./kube-flannel.yml"
    check_succeed

    # wait the flannel ready
    sleep 10
}



# create kata RuntimeClass
create_kata_RuntimeClass()
{
echo "create kata RuntimeClass ..."
su -c \
"export KUBECONFIG=/etc/kubernetes/admin.conf
cat <<-EOF | kubectl apply -f -
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: kata
handler: kata
EOF"
check_succeed
}

# gen gpg key pair
gen_gpg_key_pair()
{
    echo "gen GPG key pair ..."
    echo "please follow the instruction to type in the user name, email, password"
    sudo gpg2 --gen-key
    check_succeed
}

# export pubring.gpg
export_pubring()
{
    echo "export pubring.gpg ..."
    read -p "please type in the email address: " EMAIL_ADDR
    cd /root/.gnupg/
    sudo gpg2 --armor --export --output pubring.gpg  ${EMAIL_ADDR}
    check_succeed
}

# sign the container image
sign_container_image()
{
echo "sign the container image ..."
su -c \
"
mkdir -p /etc/containers/registries.d/
cat>/etc/containers/registries.d/default.yaml <<EOF
default-docker:
 sigstore-staging: file:///var/lib/containers/sigstore
EOF
"

read -p "please type in your docker.io username: " USER_NM


if [ "$(id -u)" != "0" ]; then
    echo "please type in superuser password "
fi

su -c \
"
echo \"skopeo login docker.io ...\"
echo \"  please type in your docker.io password\"
skopeo login docker.io --username ${USER_NM}

skopeo copy --remove-signatures --sign-by ${EMAIL_ADDR} \
 docker://docker.io/${TEST_IMG_NAME}:latest \
 docker://docker.io/${USER_NM}/${TEST_IMG_NAME}:${TEST_IMG_SUFFIX}

skopeo logout docker.io
"
check_succeed
}

# install verdictd
install_verdictd()
{
    #delete old version
    echo "delete old version verdictd ..."
    sudo rm -rf /usr/share/rats-tls /usr/local/lib/rats-tls/ /usr/local/bin/verdict*
    check_succeed

    # install OPA
    echo "install OPA ..."
    cd
    curl -L -o opa ${OPA_URL}
    chmod 755 ./opa
    sudo mv opa /usr/local/bin/opa
    check_succeed

    #install verdictd
    echo "build && install verdictd ..."
    git clone ${VERDICTD_GIT}
    cd verdictd
    su -c \
    "
    export GOPROXY="https://mirrors.aliyun.com/goproxy,direct"
    make
    make install
    "
    check_succeed
}

# configure verdictd
configure_verdictd()
{
echo "configure verdictd"
#read -p "please type in your docker.io username: " USER_NM
su -c \
"
mkdir -p /opt/verdictd/gpg/
mkdir -p /opt/verdictd/image/
cp /root/.gnupg/pubring.gpg  /opt/verdictd/gpg/keyring.gpg
cat>/opt/verdictd/image/policy.json <<EOF
{
  \"default\": [
   {
      \"type\": \"reject\"
   }
 ],
  \"transports\": {
    \"docker\": {
      \"docker.io/${USER_NM}\": [
       {
          \"type\": \"signedBy\",
          \"keyType\": \"GPGKeys\",
          \"keyPath\": \"/run/image-security/simple_signing/pubkey.gpg\"
       }
     ]
   }
 }
}
EOF

cat>/opt/verdictd/image/sigstore.yaml <<EOF
default-docker:
 sigstore: file:///var/lib/containers/sigstore

docker:
 docker.io/${USER_NM}:
   sigstore: file:///var/lib/containers/sigstore
EOF
"
check_succeed
}


# get the initrd.sig.img
get_initrd()
{
    echo "get initrd.sig.img ..."
    sudo mkdir -p /opt/csv/ccv1-guest/
    cd /opt/csv/ccv1-guest/
    sudo wget ${SIG_INITRD_URL}
    check_succeed
}

# unzip the initrd.sig.img
unzip_initrd()
{
    echo "unzip the initrd.sig.img ..."
    cd /opt/csv/ccv1-guest/
    sudo cp initrd.sig.img ./initrd.img.gz
    sudo gunzip initrd.img.gz
    sudo mkdir initrd
    cd initrd/
    sudo cpio -ivmd < ../initrd.img
    check_succeed
}

# modify the initrd.sig.img
modify_initrd()
{
    # modify the initrd/etc/agent-config.toml
    cd /opt/csv/ccv1-guest/initrd/
    sed -i 1c"aa_kbc_params = \"eaa_kbc\:\:${POD_NET_START}.1\:20002\"" ./etc/agent-config.toml

    # configure the initrd.sig.img sigstore
    echo "configure the initrd.sig.img sigstore ..."
    sudo cp -rf /var/lib/containers/sigstore/* ./var/lib/containers/sigstore
    check_succeed
}

# repackage initrd.sig.img
repackage_initrd()
{
    echo "repackage initrd.sig.img ..."

    cd /opt/csv/ccv1-guest/initrd/
    su -c \
    "
    find . | cpio -o -H newc > ../initrd.new.img
    gzip ../initrd.new.img
    cd ../ && mv initrd.new.img.gz initrd.new.img
    cp initrd.new.img initrd.sig.img
    "
    check_succeed
}

# configure kata initrd
configure_kata_initrd()
{
    echo "configure kata initrd ..."
    sudo sed -i 's/image = \"\/opt\/kata\/share\/kata-containers\/kata-containers/initrd = \"\/opt\/csv\/ccv1-guest\/initrd.sig/' /etc/kata-containers/configuration.toml
    check_succeed
}

disable_firewall
disable_selinux
check_mirror_reachable
install_deps
install_go
install_cargo
install_kata
install_qemu-system-x86_64
install_guest_deps
install_kata-runtime
configure_kata-runtime
install_containerd
start_containerd_service
install_module_br_netfilter
enable_check_br_traffic
disable_swap
install_K8S
configure_K8S
init_K8S
enable_master_node
install_flannel
create_kata_RuntimeClass
gen_gpg_key_pair
export_pubring
sign_container_image
install_verdictd
configure_verdictd
get_initrd
unzip_initrd
modify_initrd
repackage_initrd
configure_kata_initrd

echo "The verification environment setting done!"



