1
1
sovereign-stack/deployment/remote.sh

242 lines
8.1 KiB
Bash
Raw Normal View History

#!/bin/bash
2023-11-30 21:34:44 +00:00
set -exu
2022-07-27 16:38:33 +00:00
cd "$(dirname "$0")"
# This script is meant to be executed on the management machine.
# it reaches out to an SSH endpoint and provisions that machine
2023-11-29 19:04:24 +00:00
# to use incus.
DATA_PLANE_MACVLAN_INTERFACE=
2023-03-02 14:46:17 +00:00
DISK_TO_USE=
2023-03-09 14:55:40 +00:00
# override the remote name.
REMOTE_NAME="${1:-}"
if [ -z "$REMOTE_NAME" ]; then
2023-09-06 02:01:57 +00:00
echo "ERROR: The remote name was not provided. Syntax is: 'ss-remote <remote_name> <remote01.domain.tld>'"
echo " for example: 'ss-remote development clusterhost00.domain.tld"
2022-10-10 00:35:02 +00:00
exit 1
fi
2023-04-12 14:07:41 +00:00
. ./deployment_defaults.sh
. ./base.sh
2023-04-02 13:42:55 +00:00
export REMOTE_PATH="$REMOTES_PATH/$REMOTE_NAME"
2023-03-13 17:40:47 +00:00
REMOTE_DEFINITION="$REMOTE_PATH/remote.conf"
2023-03-09 14:55:40 +00:00
export REMOTE_DEFINITION="$REMOTE_DEFINITION"
2023-03-09 14:55:40 +00:00
mkdir -p "$REMOTE_PATH"
if [ ! -f "$REMOTE_DEFINITION" ]; then
2023-03-13 17:40:47 +00:00
# stub out a remote.conf.
2023-03-09 14:55:40 +00:00
cat >"$REMOTE_DEFINITION" <<EOL
2023-03-13 17:40:47 +00:00
# https://www.sovereign-stack.org/ss-remote
2023-03-13 17:40:47 +00:00
# REGISTRY_URL=http://registry.domain.tld:5000
EOL
2023-03-09 14:55:40 +00:00
chmod 0744 "$REMOTE_DEFINITION"
echo "We stubbed out a '$REMOTE_DEFINITION' file for you."
echo "Use this file to customize your remote deployment;"
2023-03-13 17:40:47 +00:00
echo "Check out 'https://www.sovereign-stack.org/ss-remote' for more information."
2022-10-10 00:35:02 +00:00
exit 1
fi
2023-03-09 14:55:40 +00:00
source "$REMOTE_DEFINITION"
2023-09-22 23:46:07 +00:00
if ! incus remote list | grep -q "$REMOTE_NAME"; then
2022-10-10 00:35:02 +00:00
FQDN="${2:-}"
2023-02-01 19:44:05 +00:00
if [ -z "$FQDN" ]; then
2023-03-09 14:55:40 +00:00
echo "ERROR: You MUST provide the FQDN of the remote host."
2023-02-01 19:44:05 +00:00
exit
fi
2022-10-10 00:35:02 +00:00
shift
2022-10-10 00:35:02 +00:00
if [ -z "$FQDN" ]; then
2023-03-09 14:55:40 +00:00
echo "ERROR: The Fully Qualified Domain Name of the new remote member was not set."
2022-10-10 00:35:02 +00:00
exit 1
fi
2022-10-10 00:35:02 +00:00
# let's check to ensure we have SSH access to the specified host.
if ! wait-for-it -t 5 "$FQDN:22"; then
echo "ERROR: We can't get an SSH connection to '$FQDN:22'. Ensure you have the host set up correctly."
exit 1
fi
2022-10-10 00:35:02 +00:00
# grab any modifications from the command line.
for i in "$@"; do
case $i in
--data-plane-interface=*)
DATA_PLANE_MACVLAN_INTERFACE="${i#*=}"
shift
;;
--disk=*)
DISK_TO_USE="${i#*=}"
shift
;;
*)
2022-10-10 00:35:02 +00:00
;;
esac
done
2023-03-03 13:59:52 +00:00
# first let's copy our ssh pubkey to the remote server so we don't have to login constantly.
ssh-copy-id -i "$HOME/.ssh/id_rsa.pub" "ubuntu@$FQDN"
2022-10-31 02:09:44 +00:00
if [ -z "$DISK_TO_USE" ]; then
2023-09-22 23:46:07 +00:00
if ! ssh "ubuntu@$FQDN" incus storage list -q | grep -q ss-base; then
2023-04-04 15:34:20 +00:00
echo "INFO: It looks like the DISK_TO_USE has not been set. Enter it now."
echo ""
2023-04-04 15:34:20 +00:00
ssh "ubuntu@$FQDN" lsblk --paths
2023-04-04 15:34:20 +00:00
echo "Please enter the disk or partition that Sovereign Stack will use to store data: "
read -r DISK_TO_USE
fi
2022-10-31 02:09:44 +00:00
fi
2022-10-10 00:35:02 +00:00
else
2023-11-30 02:33:45 +00:00
echo "ERROR: the remote already exists! You need to go delete your incus remote if you want to re-create your remote."
2023-03-09 14:55:40 +00:00
echo " It's may also be helpful to reset/rename your remote path."
2022-10-10 00:35:02 +00:00
exit 1
fi
2023-03-09 14:55:40 +00:00
#ssh "ubuntu@$FQDN" 'sudo echo "ubuntu ALL=(ALL) NOPASSWD: /bin/su - a" >> /etc/sudoers'
2022-11-05 23:51:58 +00:00
# if the disk is loop-based, then we assume the / path exists.
if [ "$DISK_TO_USE" != loop ]; then
# ensure we actually have that disk/partition on the system.
2023-02-01 19:44:05 +00:00
if ! ssh "ubuntu@$FQDN" lsblk --paths | grep -q "$DISK_TO_USE"; then
echo "ERROR: We could not findthe disk you specified. Please run this command again and supply a different disk."
2022-11-05 23:51:58 +00:00
echo "NOTE: You can always specify on the command line by adding the '--disk=/dev/sdd', for example."
exit 1
fi
fi
2023-09-22 23:46:07 +00:00
if ! command -v incus >/dev/null 2>&1; then
if incus profile list --format csv | grep -q "$BASE_IMAGE_VM_NAME"; then
incus profile delete "$BASE_IMAGE_VM_NAME"
2022-10-10 00:35:02 +00:00
sleep 1
fi
2023-09-23 16:26:51 +00:00
if incus network list --format csv -q --project default | grep -q incusbr0; then
incus network delete incusbr0 --project default
2023-02-01 19:44:05 +00:00
sleep 1
fi
2023-03-09 14:58:16 +00:00
2023-11-30 02:33:45 +00:00
if incus network list --format csv -q project default | grep -q incusbr1; then
incus network delete incusbr1 --project default
2023-03-09 14:58:16 +00:00
sleep 1
fi
2022-10-10 00:35:02 +00:00
fi
2023-03-05 16:49:53 +00:00
# install dependencies.
2023-03-09 14:58:16 +00:00
ssh -t "ubuntu@$FQDN" 'sudo apt update && sudo apt upgrade -y && sudo apt install htop dnsutils nano -y'
2023-11-30 02:33:45 +00:00
2023-11-30 21:34:44 +00:00
REMOTE_SCRIPT_PATH="$REMOTE_HOME/install_incus.sh"
scp ../install_incus.sh "ubuntu@$FQDN:$REMOTE_SCRIPT_PATH"
ssh -t "ubuntu@$FQDN" "chmod +x $REMOTE_SCRIPT_PATH"
ssh -t "ubuntu@$FQDN" "sudo bash -c $REMOTE_SCRIPT_PATH"
2022-11-05 23:51:58 +00:00
2023-03-09 14:58:16 +00:00
# install OVN for the project-specific bridge networks
2023-04-04 15:34:20 +00:00
ssh -t "ubuntu@$FQDN" "sudo apt-get install -y ovn-host ovn-central && sudo ovs-vsctl set open_vswitch . external_ids:ovn-remote=unix:/var/run/ovn/ovnsb_db.sock external_ids:ovn-encap-type=geneve external_ids:ovn-encap-ip=127.0.0.1"
2023-03-09 14:58:16 +00:00
2023-03-18 15:14:01 +00:00
# if the user did not specify the interface, we just use whatever is used for the default route.
2022-10-10 00:35:02 +00:00
if [ -z "$DATA_PLANE_MACVLAN_INTERFACE" ]; then
2023-03-18 15:14:01 +00:00
DATA_PLANE_MACVLAN_INTERFACE="$(ssh ubuntu@"$FQDN" ip route | grep "default via" | awk '{print $5}')"
2022-10-10 00:35:02 +00:00
fi
2023-03-02 14:46:17 +00:00
export DATA_PLANE_MACVLAN_INTERFACE="$DATA_PLANE_MACVLAN_INTERFACE"
2023-03-18 15:14:36 +00:00
MGMT_PLANE_IP="$(ssh ubuntu@"$FQDN" env | grep SSH_CONNECTION | cut -d " " -f 3)"
IP_OF_MGMT_MACHINE="$(ssh ubuntu@"$FQDN" env | grep SSH_CLIENT | cut -d " " -f 1 )"
IP_OF_MGMT_MACHINE="${IP_OF_MGMT_MACHINE#*=}"
IP_OF_MGMT_MACHINE="$(echo "$IP_OF_MGMT_MACHINE" | cut -d: -f1)"
2023-11-30 02:33:45 +00:00
# run incus admin init on the remote server.
cat <<EOF | ssh ubuntu@"$FQDN" incus admin init --preseed
config:
core.https_address: ${MGMT_PLANE_IP}:8443
2023-02-01 19:44:05 +00:00
core.dns_address: ${MGMT_PLANE_IP}
images.auto_update_interval: 15
2023-03-02 14:46:17 +00:00
networks:
2023-09-23 16:26:51 +00:00
- name: incusbr0
2023-03-02 14:46:17 +00:00
description: "ss-config,${DATA_PLANE_MACVLAN_INTERFACE:-error}"
2022-08-15 13:35:01 +00:00
type: bridge
config:
2023-03-09 14:58:16 +00:00
ipv4.address: 10.9.9.1/24
ipv4.dhcp.ranges: 10.9.9.10-10.9.9.127
2023-03-02 14:46:17 +00:00
ipv4.nat: true
2023-02-01 19:44:05 +00:00
ipv6.address: none
dns.mode: managed
2023-11-30 02:33:45 +00:00
- name: incusbr1
2023-03-16 19:50:02 +00:00
description: "Non-natting bridge needed for ovn networks."
2023-03-09 14:58:16 +00:00
type: bridge
config:
ipv4.address: 10.10.10.1/24
ipv4.dhcp.ranges: 10.10.10.10-10.10.10.63
ipv4.ovn.ranges: 10.10.10.64-10.10.10.254
ipv4.nat: false
ipv6.address: none
2023-02-01 19:44:05 +00:00
profiles:
- config: {}
description: "default profile for sovereign-stack instances."
devices:
root:
path: /
pool: ss-base
type: disk
name: default
EOF
2023-11-30 02:33:45 +00:00
# ensure the incus service is available over the network, then add a incus remote, then switch the active remote to it.
2022-10-10 00:35:02 +00:00
if wait-for-it -t 20 "$FQDN:8443"; then
2023-11-30 21:34:44 +00:00
# before we add the remote, we need a trust token from the incus server
INCUS_CERT_TRUST_TOKEN=$(ssh ubuntu@"$FQDN" incus config trust add ss-mgmt | tail -n 1)
2023-09-22 23:46:07 +00:00
# now create a remote on your local incus client and switch to it.
2023-03-09 14:55:40 +00:00
# the software will now target the new remote.
2023-11-30 21:34:44 +00:00
incus remote add "$REMOTE_NAME" "$FQDN" --auth-type=tls --accept-certificate --token="$INCUS_CERT_TRUST_TOKEN"
2023-09-22 23:46:07 +00:00
incus remote switch "$REMOTE_NAME"
2023-09-22 23:46:07 +00:00
echo "INFO: A new remote named '$REMOTE_NAME' has been created. Your incus client has been switched to it."
else
2023-11-29 19:04:24 +00:00
echo "ERROR: Could not detect the incus endpoint. Something went wrong."
2022-10-10 00:35:02 +00:00
exit 1
fi
2022-10-10 00:35:02 +00:00
2023-02-01 19:44:05 +00:00
# create the default storage pool if necessary
2023-09-22 23:46:07 +00:00
if ! incus storage list --format csv | grep -q ss-base; then
2023-02-01 19:44:05 +00:00
if [ "$DISK_TO_USE" != loop ]; then
2023-11-29 19:04:24 +00:00
# we omit putting a size here so, so incus will consume the entire disk if '/dev/sdb' or partition if '/dev/sdb1'.
2023-02-01 19:44:05 +00:00
# TODO do some sanity/resource checking on DISK_TO_USE. Impelment full-disk encryption?
2023-09-22 23:46:07 +00:00
incus storage create ss-base zfs source="$DISK_TO_USE"
2023-02-01 19:44:05 +00:00
else
# if a disk is the default 'loop', then we create a zfs storage pool
2023-11-29 19:04:24 +00:00
# on top of the existing filesystem using a loop device, per incus docs
2023-09-22 23:46:07 +00:00
incus storage create ss-base zfs
2023-02-01 19:44:05 +00:00
fi
2023-03-16 19:50:02 +00:00
# # create the testnet/mainnet blocks/chainstate subvolumes.
# for CHAIN in mainnet testnet; do
# for DATA in blocks chainstate; do
2023-09-22 23:46:07 +00:00
# if ! incus storage volume list ss-base | grep -q "$CHAIN-$DATA"; then
# incus storage volume create ss-base "$CHAIN-$DATA" --type=filesystem
# fi
# done
# done
2023-03-19 17:48:26 +00:00
else
2023-04-12 14:09:47 +00:00
echo "WARNING! The host '$FQDN' appears to have Sovereign Stack worksloads already provisioned."
echo "INFO: Here are your current Deployments."
2023-09-22 23:46:07 +00:00
incus project list -q
2023-03-19 17:48:26 +00:00
fi