218 lines
6.9 KiB
Bash
Executable File
218 lines
6.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# PVC Bootstrap system installer
|
|
|
|
echo "Welcome to the PVC bootstrap installer. This will guide you through the setup process."
|
|
echo
|
|
echo "Please enter the bootstrap root directory; all components will be installed here:"
|
|
echo -n "[/srv/pvc] > "
|
|
read root_directory
|
|
if [[ -z ${root_directory} ]]; then
|
|
root_directory="/srv/pvc"
|
|
fi
|
|
echo
|
|
|
|
echo "Please enter the IP network for the Bootstrap network (MUST be an RFC1918 /24):"
|
|
echo -n "[10.255.255.0/24] > "
|
|
read bootstrap_network
|
|
if [[ -z ${bootstrap_network} ]]; then
|
|
bootstrap_network="10.255.255.0/24"
|
|
fi
|
|
echo
|
|
|
|
echo "Will the bootstrap interface be a vLAN? Note: It should not be configured yet if so!"
|
|
echo -n "[y/N] > "
|
|
read is_bootstrap_interface_vlan
|
|
case ${is_bootstrap_interface_vlan} in
|
|
y|Y|yes|Yes|YES) is_bootstrap_interface_vlan="yes" ;;
|
|
*) is_bootstrap_interface_vlan="no" ;;
|
|
esac
|
|
echo
|
|
|
|
all_interfaces=( $(
|
|
ip address | grep '^[0-9]' | grep 'bond\|eth\|eno\|enp\|ens\|wlan\|wlp' | awk '{ print $2 }' | tr -d ':'
|
|
) )
|
|
if [[ "${is_bootstrap_interface_vlan}" == "yes" ]]; then
|
|
echo "Please enter the underlying device for the Bootstrap network vLAN:"
|
|
else
|
|
echo "Please enter the Bootstrap network interface:"
|
|
fi
|
|
echo "Available interfaces: ${all_interfaces[@]}"
|
|
bootstrap_interface=""
|
|
while true; do
|
|
echo -n "> "
|
|
read bootstrap_interface
|
|
if [[ -n ${bootstrap_interface} && "${all_interfaces[@]}" =~ "${bootstrap_interface}" ]]; then
|
|
break
|
|
fi
|
|
done
|
|
echo
|
|
|
|
if [[ "${is_bootstrap_interface_vlan}" == "yes" ]]; then
|
|
echo "Please enter the Bootstrap network vLAN ID:"
|
|
echo -n "> "
|
|
read bootstrap_vlan
|
|
echo
|
|
fi
|
|
|
|
echo "Please enter the Git remote (SSH-only) for your local PVC repository:"
|
|
while [[ -z ${git_remote} ]]; do
|
|
echo -n "> "
|
|
read git_remote
|
|
done
|
|
echo
|
|
|
|
echo "Please enter the branch to use from the local PVC repository:"
|
|
echo -n "[master] > "
|
|
read git_branch
|
|
if [[ -z ${git_branch} ]]; then
|
|
git_branch="master"
|
|
fi
|
|
echo
|
|
|
|
echo "Please enter a username for Ansible management of the cluster:"
|
|
echo -n "[deploy] > "
|
|
read deploy_username
|
|
if [[ -z ${deploy_username} ]]; then
|
|
deploy_username="deploy"
|
|
fi
|
|
echo
|
|
|
|
echo "Proceeding with setup!"
|
|
echo
|
|
|
|
echo "Installing dependencies..."
|
|
sudo apt-get update
|
|
sudo apt-get install --yes vlan iptables redis python3 python3-pip python3-virtualenv virtualenv
|
|
|
|
echo "Creating root directory..."
|
|
sudo mkdir -p ${root_directory}
|
|
sudo chown $USER ${root_directory}
|
|
|
|
echo "Creating virtualenv..."
|
|
virtualenv --python python3 ${root_directory}/venv
|
|
|
|
echo "Installing pvcbootstrapd..."
|
|
cp -a bootstrap-daemon ${root_directory}/pvcbootstrapd
|
|
|
|
echo "Installing dependencies..."
|
|
. ${root_directory}/venv/bin/activate
|
|
pip3 install -r ${root_directory}/pvcbootstrapd/requirements.txt
|
|
deactivate
|
|
|
|
echo "Determining IP addresses..."
|
|
bootstrap_address="$( awk -F'.' '{ print $1"."$2"."$3".1" }' <<<"${bootstrap_network}" )"
|
|
bootstrap_dhcpstart="$( awk -F'.' '{ print $1"."$2"."$3".100" }' <<<"${bootstrap_network}" )"
|
|
bootstrap_dhcpend="$( awk -F'.' '{ print $1"."$2"."$3".199" }' <<<"${bootstrap_network}" )"
|
|
|
|
echo "Creating configuration..."
|
|
cp ${root_directory}/pvcbootstrapd/pvcbootstrapd.yaml.template ${root_directory}/pvcbootstrapd/pvcbootstrapd.yaml
|
|
sed -i "s|DEPLOY_USERNAME|${deploy_username}|" ${root_directory}/pvcbootstrapd/pvcbootstrapd.yaml
|
|
sed -i "s|ROOT_DIRECTORY|${root_directory}|" ${root_directory}/pvcbootstrapd/pvcbootstrapd.yaml
|
|
sed -i "s|BOOTSTRAP_ADDRESS|${bootstrap_address}|" ${root_directory}/pvcbootstrapd/pvcbootstrapd.yaml
|
|
sed -i "s|BOOTSTRAP_DHCPSTART|${bootstrap_dhcpstart}|" ${root_directory}/pvcbootstrapd/pvcbootstrapd.yaml
|
|
sed -i "s|BOOTSTRAP_DHCPEND|${bootstrap_dhcpend}|" ${root_directory}/pvcbootstrapd/pvcbootstrapd.yaml
|
|
sed -i "s|GIT_REMOTE|${git_remote}|" ${root_directory}/pvcbootstrapd/pvcbootstrapd.yaml
|
|
sed -i "s|GIT_BRANCH|${git_branch}|" ${root_directory}/pvcbootstrapd/pvcbootstrapd.yaml
|
|
|
|
echo "Creating network configuration for interface ${bootstrap_interface} (is vLAN? ${is_bootstrap_interface_vlan})..."
|
|
if [[ "${is_bootstrap_interface_vlan}" == "yes" ]]; then
|
|
cat <<EOF | sudo tee /etc/network/interfaces.d/bootstrapnet
|
|
auto vlan${bootstrap_vlan}
|
|
iface vlan${bootstrap_vlan} inet static
|
|
vlan_raw_device ${bootstrap_interface}
|
|
address ${bootstrap_address}
|
|
netmask 255.255.255.0
|
|
post-up echo 1 > /proc/sys/net/ipv4/ip_forward
|
|
post-up iptables -A FORWARD -i $IFACE -j ACCEPT
|
|
post-up iptables -A FORWARD -o $IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
|
|
post-up iptables -t nat -A POSTROUTING -i $IFACE -j MASQUERADE
|
|
EOF
|
|
else
|
|
cat <<EOF | sudo tee /etc/network/interfaces.d/bootstrapnet
|
|
auto ${bootstrap_interface}
|
|
iface ${bootstrap_interface} inet static
|
|
address ${bootstrap_address}
|
|
netmask 255.255.255.0
|
|
post-up echo 1 > /proc/sys/net/ipv4/ip_forward
|
|
post-up iptables -A FORWARD -i $IFACE -j ACCEPT
|
|
post-up iptables -A FORWARD -o $IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
|
|
post-up iptables -t nat -A POSTROUTING -i $IFACE -j MASQUERADE
|
|
EOF
|
|
fi
|
|
|
|
echo "Installing service units..."
|
|
cat <<EOF | sudo tee /etc/systemd/system/pvcbootstrapd.service
|
|
# Parallel Virtual Cluster Bootstrap API daemon unit file
|
|
|
|
[Unit]
|
|
Description = Parallel Virtual Cluster Bootstrap API daemon
|
|
After = network-online.target
|
|
|
|
[Service]
|
|
Type = simple
|
|
WorkingDirectory = ${root_directory}/pvcbootstrapd
|
|
Environment = PYTHONUNBUFFERED=true
|
|
Environment = PVC_CONFIG_FILE=${root_directory}/pvcbootstrapd/pvcbootstrapd.yaml
|
|
ExecStart = ${root_directory}/venv/bin/python3 ${root_directory}/pvcbootstrapd/pvcbootstrapd.py
|
|
Restart = on-failure
|
|
|
|
[Install]
|
|
WantedBy = multi-user.target
|
|
EOF
|
|
sudo systemctl enable pvcbootstrapd.service
|
|
|
|
cat <<EOF | sudo tee /etc/systemd/system/pvcbootstrapd-worker.service
|
|
# Parallel Virtual Cluster Provisioner API provisioner worker unit file
|
|
|
|
[Unit]
|
|
Description = Parallel Virtual Cluster Bootstrap API worker
|
|
After = network-online.target
|
|
|
|
[Service]
|
|
Type = simple
|
|
WorkingDirectory = ${root_directory}/pvcbootstrapd
|
|
Environment = PYTHONUNBUFFERED=true
|
|
Environment = PVC_CONFIG_FILE=${root_directory}/pvcbootstrapd/pvcbootstrapd.yaml
|
|
ExecStart = ${root_directory}/pvcbootstrapd/pvcbootstrapd-worker.sh
|
|
Restart = on-failure
|
|
|
|
[Install]
|
|
WantedBy = multi-user.target
|
|
EOF
|
|
sudo systemctl enable pvcbootstrapd-worker.service
|
|
|
|
echo "Generating SSH keypair..."
|
|
ssh-keygen -t ed25519 -C "pvcbootstrapd@$(hostname)" -N "" -f ${root_directory}/id_ed25519
|
|
echo
|
|
echo "NOTE: The PVC Bootstrap system will automatically commit first-run Ansible changes."
|
|
echo "Add the following as a writeable deploy key for your repository to allow push!"
|
|
echo -n " "
|
|
cat ${root_directory}/id_ed25519.pub
|
|
echo
|
|
|
|
echo "Edit configuration before proceeding?"
|
|
echo -n "[y/N] > "
|
|
read edit_flag
|
|
case ${edit_flag} in
|
|
y|Y|yes|Yes|YES)
|
|
vim ${root_directory}/pvcbootstrapd/pvcbootstrapd.yaml
|
|
;;
|
|
*)
|
|
true
|
|
;;
|
|
esac
|
|
echo
|
|
|
|
echo "Restart system to activate?"
|
|
echo -n "[y/N] > "
|
|
read reboot_flag
|
|
case ${reboot_flag} in
|
|
y/Y/yes/Yes/YES)
|
|
sudo reboot
|
|
;;
|
|
*)
|
|
true
|
|
;;
|
|
esac
|