tlu/update.sh
2021-11-23 16:43:55 +01:00

480 lines
16 KiB
Bash
Executable File

#!/bin/bash
set -aeou pipefail
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
function printHelp(){
cat << EOF
Usage ${0##*/} [options..]
-h,-?, --help Show help and exit
-s, --salt run a masterless salt-call
-y, --yes answer 'yes' on all questions
-t, --tools Install/update tools (kubectl, helm, etc)
-r, --rancher Install rancher server VM
--rmt-sync Sync database with SUSE Customer Center
--rmt-enable-products Enable all preconfigured repositories
--rmt-mirror Mirror repositories
EOF
}
function asktobreak(){
if [[ "$ANSWER_YES" == true ]];then
printf "\n"
return 1
fi
printf "Do you want to run this step (y/n)"
while read -r -n 1 -s answer; do
if [[ $answer == [YyNn] ]];then
[[ $answer == [Yy] ]] && return_value=1
[[ $answer == [Nn] ]] && return_value=0
printf "\n"
break;
fi
done
return $return_value
}
function new_log(){
# script output
printf "\n**** [%s] ***\n" "$*"
}
function log(){
printf "%s\n" "$*"
}
function parse_yaml() {
# ripped from https://gist.github.com/pkuczynski/8665367#gistcomment-2174214
local yaml_file=$1
local prefix=$2
local s
local w
local fs
s='[[:space:]]*'
w='[a-zA-Z0-9_]*'
fs="$(echo @|tr @ '\034')"
(
sed -ne 's/--//g; s/\"/\\\"/g; s/\#.*//g; s/\s*$//g;' \
-e "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
-e "s|^\($s\)\($w\)$s[:-]$s\(.*\)$s\$|\1$fs\2$fs\3|p" |
awk -F"$fs" '{
indent = length($1)/2;
if (length($2) == 0) { conj[indent]="+";} else {conj[indent]="";}
vname[indent] = $2;
for (i in vname) {if (i > indent) {delete vname[i]}}
if (length($3) > 0) {
vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
printf("%s%s%s%s=(\"%s\")\n", "'"$prefix"'",vn, $2, conj[indent-1],$3);
}
}' |
sed 's/_=/+=/g'
) < "$yaml_file"
}
function check_prerequisites(){
set +e
local answer
type "$1" > /dev/null 2>&1
RESULT=$?
if [[ $RESULT != 0 ]];then
printf "$1 is not installed, do your want to install it [y/N]?"
read -r -n 1 -s answer;
printf "\n"
if [[ $answer == [yY] ]];then
sudo zypper --non-interactive install "$1"
fi
fi
set -e
}
function do_salt_call(){
local salt="sudo salt-call --local --file-root $SCRIPTDIR/salt/states --pillar-root $SCRIPTDIR/salt/pillars --module-dirs=$SCRIPTDIR/salt/modules"
new_log "Running salt high state"
if asktobreak;then
return
fi
$salt state.apply pillar="{username: $USER}"
}
function rmt_sync(){
new_log "Sync RMT Database with SUSE Customer Center"
if asktobreak; then
return
fi
sudo rmt-cli sync
}
function rmt_enable_products(){
new_log "Enable the following products in RMT?"
eval $(parse_yaml $SCRIPTDIR/salt/pillars/rmt.sls "SALT_")
if [[ -f salt/pillars/local.sls ]];then
eval $(parse_yaml $SCRIPTDIR/salt/pillars/local.sls "SALT_")
fi
for name in "${SALT_rmt_products__name[@]}"; do
echo " * $name"
done
if asktobreak; then
return
fi
sudo rmt-cli products enable "${SALT_rmt_products__id[*]}"
}
function rmt_mirror(){
new_log "Mirror all repositories"
if asktobreak; then
return
fi
sudo rmt-cli mirror all
}
function install_tools(){
new_log "Install client tools"
echo "- kubectl"
echo "- helm"
echo "- stern"
echo "- virtctl"
if asktobreak; then
return
fi
set +e
echo "---- kubectl ----"
cd $HOME/bin
if [[ -f kubectl ]]; then
KUBECTL_CURRENT=$(./kubectl version --client 2> /dev/null| sed -n 's/.* GitVersion:"\(v[0-9]*\.[0-9]*\.[0-9]*\)".*/\1/p')
else
KUBECTL_CURRENT="N/A"
fi
KUBECTL_STABLE="$(curl -L -s https://dl.k8s.io/release/stable.txt)"
echo "Installed version: $KUBECTL_CURRENT"
echo "Latest stable version: $KUBECTL_STABLE"
if [[ "$KUBECTL_CURRENT" != "$KUBECTL_STABLE" ]]; then
echo "updating to $KUBECTL_STABLE"
curl -LO https://dl.k8s.io/release/$KUBECTL_STABLE/bin/linux/amd64/kubectl
chmod +x kubectl
fi
echo ""
echo "---- helm ----"
if [[ -f helm ]]; then
HELM_CURRENT=$(./helm version | sed -n 's/.*Version:"\(v[0-9]*\.[0-9]*\.[0-9]*\)".*/\1/p')
else
HELM_CURRENT="N/A"
fi
HELM_STABLE="$(curl -Ls https://github.com/helm/helm/releases | egrep 'href="/helm/helm/releases/tag/v[0-9]+.[0-9]+.[0-9]+\"' | head -n 1 | sed -n 's/.*tag\/\(v.*\)" data.*/\1/p')"
echo "Installed version: $HELM_CURRENT"
echo "Latest stable version: $HELM_STABLE"
if [[ "$HELM_CURRENT" != "$HELM_STABLE" ]]; then
echo "updating to $HELM_STABLE"
curl -LO https://get.helm.sh/helm-$HELM_STABLE-linux-amd64.tar.gz
tar xvzf helm-$HELM_STABLE-linux-amd64.tar.gz --strip-components=1 linux-amd64/helm
rm helm-$HELM_STABLE-linux-amd64.tar.gz
fi
echo ""
echo "---- stern ----"
if [[ -f stern ]]; then
STERN_CURRENT="v$(./stern -v | head -n1 | cut -d " " -f2)"
else
STERN_CURRENT="N/A"
fi
STERN_STABLE="$(curl -Ls https://github.com/stern/stern/releases | egrep 'href="/stern/stern/releases/tag/v[0-9]+.[0-9]+.[0-9]+*\"' | head -n 1 | sed -n 's/.*tag\/\(v.*\)" data.*/\1/p')"
echo "Installed version: $STERN_CURRENT"
echo "Latest stable version: $STERN_STABLE"
if [[ "$STERN_CURRENT" != "$STERN_STABLE" ]]; then
echo "updating to $STERN_STABLE"
curl -LO https://github.com/stern/stern/releases/download/$STERN_STABLE/stern_${STERN_STABLE:1}_linux_amd64.tar.gz
tar xvzf stern_${STERN_STABLE:1}_linux_amd64.tar.gz --strip-components=1 stern_${STERN_STABLE:1}_linux_amd64/stern
rm stern_${STERN_STABLE:1}_linux_amd64.tar.gz
fi
echo ""
echo "---- virtctl ----"
if [[ -f stern ]]; then
VIRTCTL_CURRENT="$(./virtctl version --client 2> /dev/null| sed -n 's/.*GitVersion:"\(v[0-9]*\.[0-9]*\.[0-9]*\)".*/\1/p')"
else
VIRTCTL_CURRENT="N/A"
fi
VIRTCTL_STABLE="$(curl -Ls https://github.com/kubevirt/kubevirt/releases | egrep 'href="/kubevirt/kubevirt/releases/tag/v[0-9]+.[0-9]+.[0-9]+*\"' | head -n 1 | sed -n 's/.*tag\/\(v.*\)" data.*/\1/p')"
echo "Installed version: $VIRTCTL_CURRENT"
echo "Latest stable version: $VIRTCTL_STABLE"
if [[ "$VIRTCTL_CURRENT" != "$VIRTCTL_STABLE" ]]; then
echo "updating to $VIRTCTL_STABLE"
curl -Lo virtctl https://github.com/kubevirt/kubevirt/releases/download/$VIRTCTL_STABLE/virtctl-$VIRTCTL_STABLE-linux-amd64
chmod +x ./virtctl
fi
echo ""
set -e
}
function install_rancher_vm(){
new_log "Install rancher vm"
if asktobreak; then
return
fi
systemctl is-active libvirtd --quiet || ( echo "libvirtd is not running...."; return 1)
if sudo virsh list --all | grep -q "rancher";then
echo "rancher VM already installed..."
return 0
fi
eval $(parse_yaml $SCRIPTDIR/salt/pillars/network.sls "SALT_")
eval $(parse_yaml $SCRIPTDIR/salt/pillars/rancher.sls "SALT_")
eval $(parse_yaml $SCRIPTDIR/salt/pillars/ssh.sls "SALT_")
eval $(parse_yaml $SCRIPTDIR/salt/pillars/local.sls "SALT_")
# Download openSUSE MicroOS image
if sudo test ! -f /var/lib/libvirt/images/openSUSE-MicroOS.x86_64-ContainerHost-kvm-and-xen.qcow2;then
echo "Downloading MicroOS"
curl -Lo /tmp/openSUSE-MicroOS.x86_64-ContainerHost-kvm-and-xen.qcow2 http://download.opensuse.org/tumbleweed/appliances/openSUSE-MicroOS.x86_64-ContainerHost-kvm-and-xen.qcow2
curl -Lo /tmp/openSUSE-MicroOS.x86_64-ContainerHost-kvm-and-xen.qcow2.sha256 http://download.opensuse.org/tumbleweed/appliances/openSUSE-MicroOS.x86_64-ContainerHost-kvm-and-xen.qcow2.sha256
cd /tmp/
echo "checking sha256sum"
if ! echo "$(cat /tmp/openSUSE-MicroOS.x86_64-ContainerHost-kvm-and-xen.qcow2.sha256 | cut -f 1 -d " ") openSUSE-MicroOS.x86_64-ContainerHost-kvm-and-xen.qcow2" | sudo sha256sum --check --status;then
echo "sha256sum doesn't match on openSUSE-MicroOS.x86_64-ContainerHost-kvm-and-xen.qcow2"
exit 1
fi
echo "Moving image file to /var/lib/libvirt/images"
sudo mv /tmp/openSUSE-MicroOS.x86_64-ContainerHost-kvm-and-xen.qcow2 /var/lib/libvirt/images/
fi
# Create the Butane config file
if [[ -f $HOME/rancherVM.yaml ]]; then
echo "rancher butane file already exists"
else
echo "creating the butane file"
SSH_PUB_KEYS=""
for i in "${SALT_ssh_user_pub_keys[@]}"; do
if [[ "$i" != "[]" ]];then
SSH_PUB_KEYS="$SSH_PUB_KEYS - $i\n"
fi
done
cat << EOF >> $HOME/rancherVM.yaml
variant: fcos
version: 1.0.0
passwd:
users:
- name: root
ssh_authorized_keys:
$(echo -e "$SSH_PUB_KEYS")
password_hash: "$(echo ${SALT_rancher_bootstrapPassword} | mkpasswd --method=SHA-512 --stdin)"
storage:
files:
- path: /etc/sysconfig/network/ifcfg-eth0
mode: 0600
overwrite: true
contents:
inline: |
BOOTPROTO='static'
STARTMODE='auto'
BROADCAST=''
ETHTOOL_OPTIONS=''
IPADDR='${SALT_network_ip%.*}.${SALT_network_hosts_rancher}/24'
MTU=''
NAME=''
NETWORK=''
REMOTE_IPADDR=''
ZONE=internal
- path: /etc/sysconfig/network/routes
mode: 0644
overwrite: true
contents:
inline: |
default ${SALT_network_ip} - -
- path: /etc/rancher/k3s/registries.yaml
mode: 0600
contents:
inline: |
mirrors:
docker.io:
endpoint:
- "http://${SALT_network_ip}:5000"
- path: /etc/hostname
mode: 0644
overwrite: true
contents:
inline: |
rancher.${SALT_network_domain}
- path: /root/rancher_install.sh
mode: 0700
overwrite: true
contents:
inline: |
#!/bin/bash
# Fix DNS to point to admin server
sed -i 's/^NETCONFIG_DNS_STATIC_SERVERS=""/NETCONFIG_DNS_STATIC_SERVERS="172.18.0.1"/' /etc/sysconfig/network/config
netconfig update -f
echo "Installing k3s"
curl -sfL https://get.k3s.io | sh -
echo "Waiting for k3s to be healthy"
while ! kubectl get cs &> /dev/null;do sleep 1; done
echo "fetching Helm"
cd /root/bin
if [[ -f helm ]]; then
HELM_CURRENT=\$(./helm version | sed -n 's/.*Version:"\(v[0-9]*\.[0-9]*\.[0-9]*\)".*/\1/p')
else
HELM_CURRENT="N/A"
fi
HELM_STABLE="\$(curl -Ls https://github.com/helm/helm/releases | egrep 'href="/helm/helm/releases/tag/v[0-9]+.[0-9]+.[0-9]+\"' | head -n 1 | sed -n 's/.*tag\/\(v.*\)" data.*/\1/p')"
echo "Installed version: \$HELM_CURRENT"
echo "Latest stable version: \$HELM_STABLE"
if [[ "\$HELM_CURRENT" != "\$HELM_STABLE" ]]; then
echo "updating to \$HELM_STABLE"
curl -LO https://get.helm.sh/helm-\$HELM_STABLE-linux-amd64.tar.gz
tar xvzf helm-\$HELM_STABLE-linux-amd64.tar.gz --strip-components=1 linux-amd64/helm
rm helm-\$HELM_STABLE-linux-amd64.tar.gz
fi
echo ""
echo "installing cert-manager"
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm --kubeconfig /etc/rancher/k3s/k3s.yaml install cert-manager jetstack/cert-manager \\
--namespace cert-manager \\
--create-namespace \\
--set installCRDs=true \\
--version v1.5.1
kubectl wait --for=condition=available --timeout=600s deployment/cert-manager --namespace cert-manager
echo "installing rancher"
helm repo add rancher-latest https://releases.rancher.com/server-charts/latest
helm repo update
kubectl create namespace cattle-system
helm --kubeconfig /etc/rancher/k3s/k3s.yaml install rancher rancher-latest/rancher \\
--namespace cattle-system \\
--set hostname=rancher.${SALT_network_domain} \\
--set bootstrapPassword=${SALT_rancher_bootstrapPassword} \\
--set replicas=1
EOF
# Create the ignition file
fi
if [[ -f $HOME/rancherVM.ign ]];then
echo "rancher ignition file already exists"
else
echo "creating the ignition file"
sudo podman run -i --rm quay.io/coreos/fcct:release --pretty --strict < $HOME/rancherVM.yaml > $HOME/rancherVM.ign
fi
[[ -d "$HOME"/.kube ]] || mkdir "$HOME"/.kube
#create the rancher VM
sudo virt-install --import --connect qemu:///system \
--name rancher \
--ram "${SALT_rancher_ram}" \
--vcpus "$SALT_rancher_vcpus" \
--disk size=20,backing_store=/var/lib/libvirt/images/openSUSE-MicroOS.x86_64-ContainerHost-kvm-and-xen.qcow2,bus=virtio \
--os-variant=opensusetumbleweed \
--network bridge=br0,model=virtio \
--noautoconsole \
--graphics spice,listen=127.0.0.1 \
--qemu-commandline="-fw_cfg name=opt/com.coreos/config,file=$HOME/rancherVM.ign"
printf "%s" "Waiting for rancher VM ssh to come up"
while ! nc -z rancher."${SALT_network_domain}" 22 &> /dev/null; do
printf "%c" "."
sleep 1
done
printf "\nAdding rancher VM into ssh known_hosts\n"
ssh-keyscan -H "rancher.${SALT_network_domain}" >> $HOME/.ssh/known_hosts
ssh-keyscan -H "${SALT_network_ip%.*}.${SALT_network_hosts_rancher}" >> $HOME/.ssh/known_hosts
ssh root@rancher."${SALT_network_domain}" /root/rancher_install.sh
ssh root@rancher."${SALT_network_domain}" cat /etc/rancher/k3s/k3s.yaml > $HOME/.kube/rancher.yaml
sed -i "s/127.0.0.1/${SALT_network_ip%.*}.${SALT_network_hosts_rancher}/g" $HOME/.kube/rancher.yaml
sed -i 's/default/rancher/g' $HOME/.kube/rancher.yaml
}
#########################
#
# Main Script
#
########################
#initialize all options
ALL=true
SALT=false
ANSWER_YES=false
RMT_SYNC=false
RMT_MIRROR=false
RMT_ENABLE_PRODUCTS=false
INSTALL_TOOLS=false
RANCHER=false
while :; do
case ${1-noop} in
-h|-\?|--help)
printHelp
exit
;;
-s|--salt)
SALT=true
ALL=false
;;
-y|--yes)
ANSWER_YES=true
;;
-r|--rancher)
RANCHER=true
ALL=false
;;
--rmt-sync)
RMT_SYNC=true
ALL=false
;;
--rmt-mirror)
RMT_MIRROR=true
ALL=false
;;
--rmt-enable-products)
RMT_ENABLE_PRODUCTS=true
ALL=false
;;
-t|--tools)
INSTALL_TOOLS=true
ALL=false
;;
--) #End of all options
shift
break
;;
-?*)
printf "'%s' is not a valid option\n" "$1" >&2
exit 1
;;
*) #Break out of case, no more options
break
esac
shift
done
for cmd in git salt-minion curl;do
check_prerequisites "$cmd"
done
[[ $ALL == true ]] || [[ $SALT == true ]] && do_salt_call
[[ $ALL == true ]] || [[ $RMT_SYNC == true ]] && rmt_sync
[[ $ALL == true ]] || [[ $RMT_ENABLE_PRODUCTS == true ]] && rmt_enable_products
[[ $ALL == true ]] || [[ $RMT_MIRROR == true ]] && rmt_mirror
[[ $ALL == true ]] || [[ $INSTALL_TOOLS == true ]] && install_tools
[[ $ALL == true ]] || [[ $RANCHER == true ]] && install_rancher_vm
printf "\n DONE!!!!!!!\n"