Created
June 29, 2022 19:26
-
-
Save ThinGuy/9fda64c8bebfe99df06e4a5db97aa762 to your computer and use it in GitHub Desktop.
Updated lxd-maas microcloud
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# vim: set et ts=2 sw=2 filetype=bash : | |
[[ $_ != $0 ]] || { printf "\n\e[2G\e[1mPlease source this script!\e[0m ( e.g. \"source ${BASH_SOURCE[0]}\" )\n\n"; sleep 1;exit; } | |
maas-microcloud-lxd() { | |
[[ -n ${FDEBUG} && ${FDEBUG} = true ]] && { set -x &>/dev/null; } | |
local DESC="${FUNCNAME}: Deploy a LXD Cluster via MAAS command line" | |
local CI_TZ='America/Los_Angeles' | |
local CI_LC='en_US.UTF-8' | |
local CI_TC=${CI_LC:3:2} | |
if [[ -n ${CI_TC} && $(curl -slSL -w %{http_code} -o /dev/null ${CI_TC,,}.archive.ubuntu.com) -eq 200 ]];then | |
local CI_CC=${CI_TC} | |
local CI_APT_MIRROR=${CI_CC,,}.archive.ubuntu.com | |
else | |
local CI_APT_MIRROR=archive.ubuntu.com | |
fi | |
local CI_PKG_UPG=true | |
local CI_PKG_UPD=true | |
local ENABLE_GPU=false | |
local BASE_TAG="microcloud-lxd" | |
local STORAGE_POOL_DEVICE= | |
local STORAGE_POOL_TYPE=file | |
local WAIT=false | |
local -a CI_PKG_LIST=( | |
bridge-utils | |
build-essential | |
jq | |
prips | |
squashfuse | |
unzip | |
zfsutils-linux | |
) | |
maas-microcloud-lxd_usage() { | |
printf "\n\e[2G${DESC}\n\n" | |
printf "\e[2G\e[1mUsage\e[0m: ${FUNCNAME%%_*} [-c <count>] [-t <tag>] [-d <distro>] (-p storage-pool block device)\n\n" | |
printf "\e[4G -c, --count\e[20GNumber of nodes (Min: 3) \n" | |
printf "\e[4G -t, --tag \e[20GExisting tag to use when selecting nodes\n" | |
printf "\e[4G -d, --distro\e[20GName of Ubuntu Distro (Default: bionic)\n" | |
printf "\e[4G -p, --pool-device\e[20GPhysical disk to use for Storage Pool (Optional: default uses file method)\n" | |
printf "\e[4G -m, --mtag\e[20GName of this microcloud (default: \"microcloud-lxd-<random 6 char str>\")\n" | |
printf "\e[4G -w, --wait\e[20GWait for nodes to finish deploying before exiting ${FUNCNAME%%_*}\n" | |
printf "\e[4G -h, --help\e[20GThis message\n" | |
printf "\n\n" | |
} | |
ARGS=$(getopt -o n:c:t:d:p:dhwm: -l count:,tag:,distro:,pool-device:,help,desc,wait,mtag: -n ${FUNCNAME} -- "$@") | |
eval set -- "$ARGS" | |
while true ; do | |
case "$1" in | |
-n|-c|--count) local COUNT=${2};shift 2;; | |
-t|--tag) local TAG=${2};local TAG=${TAG,,};shift 2;; | |
-m|--mtag) export MICROCLOUD_TAG=${2};local TAG=${TAG,,};shift 2;; | |
-d|--distro) local DISTRO=${2};local DISTRO=${DISTRO,,};shift 2;; | |
-p|--pool-device) local STORAGE_POOL_DEVICE=${2};local STORAGE_POOL_DEVICE=${STORAGE_POOL_DEVICE,,};local STORAGE_POOL_TYPE=device;shift 2;; | |
-w|--wait) local WAIT=true;shift 1;; | |
--desc) printf "\n\e[2G${DESC}\n";return 0;; | |
-h|--help) ${FUNCNAME}_usage;return 2;; | |
--) shift;break;; | |
esac | |
done | |
if [[ -f /snap/bin/maas ]];then | |
local MAAS_VER=$(snap info maas|awk '/^installed/{gsub(/~.*/,"",$2);print $2}') | |
else | |
command -v maas &>/dev/null || { printf "\n\n\e[2G\e[2G\e[38;2;255;255;0mSorry! \e[0m\e[38;2;0;255;0m maas-cli \e[0m\e[1m2.5+\e[0m is required for this demo.\n\e[9GPlease install and configure version MAAS 2.5 or later\n\n";return 1; } | |
[[ $(dpkg-query 2>/dev/null -s maas|grep -oP '(?<=Version: )[^?]{3}'|sed 's/\.//') -lt 25 ]] && { printf "\n\n\e[2G\e[2G\e[38;2;255;255;0mSorry! \e[0mMAAS \e[38;2;0;255;0m2.5\e[0m\e[1m+\e[0m is required for this demo.\n\e[9GYou are running version \e[38;2;255;255;0m$(dpkg-query -s maas|grep -oP '(?<=Version: )[^~]+')\e[0m\n\n";return 1; } | |
local MAAS_VER=$(dpkg-query 2>/dev/null -s maas|grep -oP '(?<=Version: )[^?]{3}'|sed 's/\.//') | |
fi | |
command -v jq &>/dev/null || sudo apt install jq -y | |
local OK='\u00A0\e[38;2;0;255;0m\u2713\e[0m\u00A0\n' | |
local FAILED='\u00A0\e[38;2;255;0;0m\u2718\u00A0\n' | |
printf -- "\n\e[1mMicro-cloud Demo - LXD\e[0m\n\n" | |
printf -- " - Powered by \e[1m$(lsb_release -ds)\e[0m${OK}\n" | |
printf -- " - Provisioning by \e[1mMAAS ${MAAS_VER}${OK}\n" | |
printf -- " - Featuring \e[1mLXD $(snap info lxd|awk '/installed:/{print $2}') with clustering\e[0m${OK}\n" | |
[[ -z ${MAAS_PROFILE} ]] && { read -srp "$(printf "Please enter your MAAS profile name: ")" MAAS_PROFILE_INPUT;local MAAS_PROFILE=$MAAS_PROFILE_INPUT; } | |
#Validation and error handling | |
local -a VALID_TAGS=($(maas ${MAAS_PROFILE} tags read|jq -r '.[].name')) | |
local -a VALID_DISTROS=($(maas ${MAAS_PROFILE} boot-resources read|jq -r '.[]|"\(select((.name|startswith("grub")|not) and (.name|startswith("ubuntu")) and (.name|startswith("pxe")|not)).name|sub("ubuntu/"; ""))"'|sort -uV)) | |
# If not a physical disk, set storage pool to use a file | |
[[ ${STORAGE_POOL_TYPE} = device ]] && { printf "\e[3G- Storage Pool on Cluster Hosts will be using block device ${STORAGE_POOL_DEVICE} \n\n"; local STORAGE_POOL_TYPE=device; } || { local STORAGE_POOL_TYPE=file;local STORAGE_POOL_DEVICE="/var/snap/lxd/common/lxd/disks/local.img";printf "\e[3G- Storage Pool on Cluster Hosts will be file-based \n\n"; } | |
[[ ${COUNT} =~ ^[0-9]+$ ]] || { local COUNT=3;printf "\e[3G- Setting Node count to ${COUNT}\n\n"; } | |
[[ ${COUNT} =~ ^[0-9]+$ && ${COUNT} -lt 3 ]] && { local COUNT=3;printf "\e[3G- Minimum LXD Cluster node count is ${COUNT}. Setting Node count to ${COUNT}.\n\n"; } | |
[[ -z ${TAG} ]] && { printf "\e[2GERROR: No tag name given ${TAG}\n\n\e[2GValid tags are:\n";printf "\e[4G- %s\n" ${VALID_TAGS[@]};return 1; } | |
[[ -n ${TAG} && -n $(grep -P '(^|\s)\K'${TAG}'(?=\s|$)' <<< ${VALID_TAGS[@]}) ]] || { printf "\e[2GERROR: No tags exist named ${TAG}\n\n\e[2GValid tags are:\n";printf "\e[4G- %s\n" ${VALID_TAGS[@]};return 1; } | |
[[ -n ${TAG} ]] && { printf "\e[3G- Using tag \"${TAG}\" as primary machine constraint\n\n"; } | |
[[ -n ${DISTRO} ]] || { local DISTRO="bionic"; } | |
[[ -n ${DISTRO} && -n $(grep -P '(^|\s)\K'${DISTRO}'(?=\s|$)' <<< ${VALID_DISTROS[@]}) ]] || { printf "\e[2GERROR: invalid distro: ${DISTRO}\n\n\e[2GValid distros for LXD Clusters are:\n";printf "\e[4G- %s\n" ${VALID_DISTROS[@]};return 1; } | |
[[ -n ${DISTRO} ]] && { printf "\e[3G- Setting distro to ${DISTRO}\n\n"; } | |
printf "\n\e[3G- Gathering values from to use for setting up the lxd-cluster. Please wait..." | |
#Get values we'll be replacing in lxd-cluster script template | |
maas refresh | |
local MAAS_LIST="$(maas list|awk '/'${MAAS_PROFILE}'/')" | |
local MAAS_API=$(awk '{print $3}' <<< "${MAAS_LIST}") | |
local MAAS_IP=$(grep -oP '(?<=http://)[^:|^/]+' <<< "${MAAS_LIST}") | |
local MAAS_URL=$(grep -oP 'http://(?<=http://|https://)[^S]+S/' <<< "${MAAS_LIST}") | |
local MAAS_SUBNET=$(maas ${MAAS_PROFILE} subnets read|jq -r '.[]|select(.vlan.fabric_id==0).cidr') | |
local MAAS_DOMAIN=$(maas ${MAAS_PROFILE} domains read|jq -r '.[]|select((.authoritative==true) and .id==0).name') | |
# IFS=$'\n' && declare -ag MAAS_SSH_HOST_KEYS=($(maas ${MAAS_PROFILE} sshkeys read|jq -r '.[]|"\(.key)"')) | |
if [[ -n ${MAAS_API} && -n ${MAAS_URL} && -n ${MAAS_SUBNET} && -n ${MAAS_IP} && -n ${MAAS_DOMAIN} ]];then | |
printf "${OK}" | |
else | |
printf "${FAILED}\e[2GThere was an issue gathering lxd-cluster values from maas. Make you are running this while logged into the maas-cli. Quitting\n\n" | |
echo | |
for v in API URL SUBNET IP DOMAIN;do eval echo MAAS_$v=\$MAAS_$v;done | |
echo | |
return 1 | |
fi | |
[[ ${COUNT} -eq 1 ]] && W= || W=s | |
if [[ ${STORAGE_POOL_TYPE} = device ]];then | |
printf "\n\e[3G- Finding ${COUNT} machine${W} :\n\e[5G- Marked as \"Ready\"\n\e[5G- Tagged with \"${TAG}\"\n" | |
local READY_TAGGED_MACHINES=($(maas ${MAAS_PROFILE} machines read|jq -r '.[]|select(.physicalblockdevice_set[].name|contains("'${STORAGE_POOL_DEVICE##*/}'"))|select((.tag_names[]|contains("'"${TAG}"'")) and .status == 4)|"\(.hostname):\(.system_id)"'|head -n${COUNT}|sort -V)) | |
[[ ${#READY_TAGGED_MACHINES[@]} -lt 3 ]] && { printf "\e[2G\e[2G\e[38;2;255;255;0mSorry! \e[0mCould not find enough machines to create a LXD Cluster.\n\n\e[9GMachines Required: 3\n\e[9GMachines Found:\e[4C\e[38;2;255;0;0m${#READY_TAGGED_MACHINES[@]}\n\n";return 1; } | |
[[ ${#READY_TAGGED_MACHINES[@]} -lt ${COUNT} && ${#READY_TAGGED_MACHINES[@]} -ge 3 ]] && { read -erp "$(printf "\n\e[2G - Could only find ${#READY_TAGGED_MACHINES[@]} machine${W} with the ${TAG} tag. Continue? [y/n] : ")" CONT; [[ ${CONT,,} =~ y ]] && echo || return 0; } | |
[[ ${#READY_TAGGED_MACHINES[@]} -lt ${COUNT} ]] && { read -erp "$(printf "\n\e[2G - Could only find ${#READY_TAGGED_MACHINES[@]} machines with the ${TAG} tag. Continue? [y/n] : ")" CONT; [[ ${CONT,,} =~ y ]] && echo || return 0; } | |
local COUNT=${#READY_TAGGED_MACHINES[@]} | |
else | |
printf "\n\e[3G- Finding ${COUNT} machine${W} :\n\e[5G- Marked as \"Ready\"\e[5G- Tagged with \"${TAG}\"\n\e[5G- Has physical disk named ${STORAGE_POOL_DEVICE}\n" | |
local -a READY_TAGGED_MACHINES=($(maas ${MAAS_PROFILE} machines read|jq -r '.[]|select((.tag_names[]|contains("'"${TAG}"'")) and .status == 4)|"\(.hostname):\(.system_id)"'|head -n${COUNT}|sort -V)) | |
[[ ${#READY_TAGGED_MACHINES[@]} -lt 3 ]] && { printf "\e[2G\e[2G\e[38;2;255;255;0mSorry! \e[0mCould not find enough machines to create a LXD Cluster.\n\n\e[9GMachines Required: 3\n\e[9GMachines Found:\e[4C\e[38;2;255;0;0m${#READY_TAGGED_MACHINES[@]}\n\n";return 1; } | |
[[ ${#READY_TAGGED_MACHINES[@]} -lt ${COUNT} && ${#READY_TAGGED_MACHINES[@]} -ge 3 ]] && { read -erp "$(printf "\n\e[2G - Could only find ${#READY_TAGGED_MACHINES[@]} machine${W} with the ${TAG} tag. Continue? [y/n] : ")" CONT; [[ ${CONT,,} =~ y ]] && echo || return 0; } | |
[[ ${#READY_TAGGED_MACHINES[@]} -lt ${COUNT} ]] && { read -erp "$(printf "\n\e[2G - Could only find ${#READY_TAGGED_MACHINES[@]} machine${W} with the ${TAG} tag. Continue? [y/n] : ")" CONT; [[ ${CONT,,} =~ y ]] && echo || return 0; } | |
local COUNT=${#READY_TAGGED_MACHINES[@]} | |
fi | |
printf "\n\e[2GAllocating the following Host${W} to the LXD Pods:\n" | |
printf -- "\e[2G - %s\n" ${READY_TAGGED_MACHINES[@]}|sed 's/:/ \(/g;s/.$/&\)/g';echo | |
local -a ALLOCATED_MACHINES=($(printf "%s\n" ${READY_TAGGED_MACHINES[@]##*:}|xargs -I{} -n1 -P0 maas ${MAAS_PROFILE} machines allocate system_id={}|jq -r '"\(.hostname):\(.system_id)"'|sort -uV)) | |
[[ ${#ALLOCATED_MACHINES[@]} -lt 3 ]] && { printf "\e[2G\e[2G\e[38;2;255;255;0mSorry! \e[0mCould not allocate enough machines to create a LXD Cluster.\n\n\e[9GMachines Required: 3\n\e[9GMachines Found:\e[4C\e[38;2;255;0;0m${#ALLOCATED_MACHINES[@]}\n\n";return 1; } | |
[[ ${#ALLOCATED_MACHINES[@]} -lt ${COUNT} && ${#ALLOCATED_MACHINES[@]} -ge 3 ]] && { read -erp "$(printf "\n\e[2G - Could only allocate ${#ALLOCATED_MACHINES[@]} machine${W}. Continue? [y/n] : ")" CONT; [[ ${CONT,,} =~ y ]] && echo || return 0; } | |
[[ ${#ALLOCATED_MACHINES[@]} -lt ${COUNT} ]] && { read -erp "$(printf "\n\e[2G - Could only allocate ${#ALLOCATED_MACHINES[@]} machines. Continue? [y/n] : ")" CONT; [[ ${CONT,,} =~ y ]] && echo || return 0; } | |
local COUNT=${#ALLOCATED_MACHINES[@]} | |
# The first element in the array will be the Cluster Primary | |
local LXD_PRIMARY=${ALLOCATED_MACHINES[0]%%:*} | |
# Preconfigure the system keys in /etc/ssh so we can setup the cluster without any prompts or exchanging ssh keys | |
local -a KEY_TYPES=(rsa dsa ecdsa) | |
xargs -n1 -P0 bash -c 'ssh-keygen &>/dev/null -t $0 -f /tmp/lxd_cluster_ssh_host_$0_key -P ""' <<< ${KEY_TYPES[@]} | |
local SSH_HOST_KEYS="$(printf "\nssh_keys:\n";xargs -n1 -P1 bash -c 'printf " $0_private: |\n$(cat /tmp/lxd_cluster_ssh_host_$0_key|sed '"'"'s/^.*$/ &/g'"'"')\n\n $0_public: $(cat /tmp/lxd_cluster_ssh_host_$0_key.pub)\n\n"' <<< ${KEY_TYPES[@]})" | |
#Remove preseeded ssh keys from local machine | |
rm -rf /tmp/lxd_cluster_ssh_host* /tmp/lxd_cluster_user_ssh* | |
# Get SSH Public keys from local accounts. Remove duplicates | |
local SSH_PUB_KEYS="$((if [[ -n $(find 2>/dev/null ~/.ssh -iname "*.pub") ]];then | |
echo ssh_authorized_keys: | |
find 2>/dev/null ~/.ssh -iname "*.pub"|xargs -n1 -P1 bash -c 'printf -- '"'"' - %s\n'"'"' "$(cat $0)"' | |
fi | |
)|awk '!seen[$0]++')" | |
# Create correct the stanza for disk or file based storage pool | |
[[ ${STORAGE_POOL_DEVICE} =~ dev || ${STORAGE_POOL_DEVICE} =~ sd ]] && local LXD_STORAGE_POOL="$(cat <<EOF | |
storage_pools: | |
- config: | |
source: ${STORAGE_POOL_DEVICE} | |
description: 'Default LXD Storage Pool' | |
name: local | |
driver: zfs | |
EOF | |
)" | |
[[ ! ${STORAGE_POOL_DEVICE} =~ dev && ! ${STORAGE_POOL_DEVICE} =~ sd ]] && local LXD_STORAGE_POOL="$(cat <<EOF | |
storage_pools: | |
- config: | |
size: 100GB | |
source: /var/snap/lxd/common/lxd/disks/local.img | |
zfs.pool_name: local | |
description: "" | |
name: local | |
driver: zfs | |
EOF | |
)" | |
#Indent yaml for use in LXD preeseed yaml | |
local LXD_SSH_PUB_KEYS="$(echo;echo "${SSH_PUB_KEYS}"|sed 's/^/ /g')" | |
# Create a string of the Cluster hosts that we can for SSH config files (thus the added asterisk) | |
# (easier to remove the asterisk in a variable than to add it, so it's added to main variable) | |
local CLUSTER_HOST_LIST=$(printf "%s*\n" ${ALLOCATED_MACHINES[@]%%:*}|paste -sd" "|sort -uV) | |
# Create Package List for Cluster hosts | |
local CI_PACKAGES=$([[ ${#CI_PKG_LIST[@]} -ge 1 ]] && printf "packages: [$(printf '%s\n' ${CI_PKG_LIST[@]}|paste -sd',')]\n") | |
#Make LXD Image Script to preseed LXD Clusters image store | |
local LXD_IMAGE_SCRIPT="$(cat <<EOF|base64 -w0 | |
#!/bin/bash | |
printf "\e[1mLXD Image Copy Tool\e[0m\n" | |
/snap/bin/lxc image copy ubuntu-daily:f local: --copy-aliases --public | |
EOF | |
)" | |
#Make LXD Cluster Script and convert to base64 to include in cloud-init user-data | |
local LXD_CLUSTER_SCRIPT="$(cat <<EOF|base64 -w0 | |
#!/bin/bash | |
if [[ \$(hostname 2>/dev/null -s) = ${LXD_PRIMARY} ]];then | |
cat <<EOT|sudo lxd init --preseed | |
config: | |
core.https_address: \$(dig +short @${MAAS_IP} \$(hostname -f)):8443 | |
core.trust_password: ubuntu | |
maas.api.key: ${MAAS_API} | |
maas.api.url: ${MAAS_URL} | |
networks: | |
- config: | |
ipv4.address: auto | |
ipv4.nat: 'true' | |
ipv6.address: none | |
ipv6.nat: 'false' | |
name: lxdbr0 | |
type: bridge | |
${LXD_STORAGE_POOL} | |
profiles: | |
- name: default | |
description: 'Default LXD Profile' | |
config: | |
user.user-data: | | |
#cloud-config | |
${LXD_SSH_PUB_KEYS} | |
devices: | |
eth0: | |
name: eth0 | |
nictype: bridged | |
parent: lxdbr0 | |
type: nic | |
root: | |
path: / | |
pool: local | |
type: disk | |
- name: privileged | |
description: 'Privileged LXD Profile' | |
config: | |
linux.kernel_modules: ip_tables,ip6_tables,netlink_diag,nf_nat,overlay | |
migration.incremental.memory: 'true' | |
raw.lxc: |- | |
lxc.cgroup.devices.allow = c 10:237 rwm | |
lxc.apparmor.profile = unconfined | |
lxc.cgroup.devices.allow = b 7:* rwm | |
security.nesting: 'true' | |
security.privileged: 'true' | |
user.user-data: | | |
#cloud-config | |
${LXD_SSH_PUB_KEYS} | |
devices: | |
eth0: | |
name: eth0 | |
nictype: bridged | |
parent: lxdbr0 | |
type: nic | |
root: | |
path: / | |
pool: local | |
type: disk | |
kvm: | |
path: /dev/kvm | |
type: unix-char | |
mem: | |
path: /dev/mem | |
type: unix-char | |
loop-control: | |
path: /dev/loop-control | |
type: unix-char | |
loop0: | |
path: /dev/loop0 | |
type: unix-block | |
loop1: | |
path: /dev/loop1 | |
type: unix-block | |
loop2: | |
path: /dev/loop2 | |
type: unix-block | |
loop3: | |
path: /dev/loop3 | |
type: unix-block | |
loop4: | |
path: /dev/loop4 | |
type: unix-block | |
loop5: | |
path: /dev/loop5 | |
type: unix-block | |
loop6: | |
path: /dev/loop6 | |
type: unix-block | |
loop7: | |
path: /dev/loop7 | |
type: unix-block | |
- name: maas | |
description: 'MAAS LXD Profile' | |
config: | |
user.user-data: | | |
#cloud-config | |
${LXD_SSH_PUB_KEYS} | |
devices: | |
eth0: | |
maas.subnet.ipv4: ${MAAS_SUBNET} | |
name: eth0 | |
nictype: bridged | |
parent: br0 | |
type: nic | |
root: | |
path: / | |
pool: local | |
type: disk | |
- name: maas-privileged | |
description: 'MAAS Privileged LXD Profile' | |
config: | |
linux.kernel_modules: ip_tables,ip6_tables,netlink_diag,nf_nat,overlay | |
migration.incremental.memory: 'true' | |
raw.lxc: |- | |
lxc.cgroup.devices.allow = c 10:237 rwm | |
lxc.apparmor.profile = unconfined | |
lxc.cgroup.devices.allow = b 7:* rwm | |
security.nesting: 'true' | |
security.privileged: 'true' | |
user.user-data: | | |
#cloud-config | |
${LXD_SSH_PUB_KEYS} | |
devices: | |
eth0: | |
maas.subnet.ipv4: ${MAAS_SUBNET} | |
name: eth0 | |
nictype: bridged | |
parent: br0 | |
type: nic | |
root: | |
path: / | |
pool: local | |
type: disk | |
kvm: | |
path: /dev/kvm | |
type: unix-char | |
mem: | |
path: /dev/mem | |
type: unix-char | |
loop-control: | |
path: /dev/loop-control | |
type: unix-char | |
loop0: | |
path: /dev/loop0 | |
type: unix-block | |
loop1: | |
path: /dev/loop1 | |
type: unix-block | |
loop2: | |
path: /dev/loop2 | |
type: unix-block | |
loop3: | |
path: /dev/loop3 | |
type: unix-block | |
loop4: | |
path: /dev/loop4 | |
type: unix-block | |
loop5: | |
path: /dev/loop5 | |
type: unix-block | |
loop6: | |
path: /dev/loop6 | |
type: unix-block | |
loop7: | |
path: /dev/loop7 | |
type: unix-block | |
cluster: | |
server_name: \$(hostname 2>/dev/null -s) | |
enabled: true | |
member_config: [] | |
cluster_address: '' | |
cluster_certificate: '' | |
server_address: '' | |
cluster_password: '' | |
EOT | |
elif [[ \$(hostname 2>/dev/null -s) != ${LXD_PRIMARY} ]];then | |
while [[ \$(sudo ssh 2>/dev/null -i /etc/ssh/ssh_host_rsa_key -tt -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ubuntu@${LXD_PRIMARY} 'test -f /var/snap/lxd/common/lxd/server.crt';echo \$?) -ne 0 ]];do sleep 5;done | |
cat <<EOT|sudo lxd init --preseed | |
config: {} | |
networks: [] | |
storage_pools: [] | |
profiles: [] | |
cluster: | |
server_name: \$(hostname -s) | |
enabled: true | |
member_config: | |
- entity: storage-pool | |
name: local | |
key: source | |
value: ${STORAGE_POOL_DEVICE} | |
description: '' | |
- entity: storage-pool | |
name: local | |
key: volatile.initial_source | |
value: ${STORAGE_POOL_DEVICE} | |
description: '' | |
- entity: storage-pool | |
name: local | |
key: zfs.pool_name | |
value: local | |
description: '' | |
cluster_address: ${LXD_PRIMARY}.${MAAS_DOMAIN}:8443 | |
cluster_certificate: | | |
\$(sudo ssh 2>/dev/null -i /etc/ssh/ssh_host_rsa_key -tt -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ubuntu@${LXD_PRIMARY} 'sed -e ":a;N;$!ba;s/\n/\n\n/g" /var/snap/lxd/common/lxd/server.crt'|sed 's/^.*$/ &/g') | |
server_address: \$(dig +short @${MAAS_IP} \$(hostname -f)):8443 | |
cluster_password: ubuntu | |
EOT | |
fi | |
EOF | |
)" | |
local CI_USER_DATA="$(cat <<EOF|tee /tmp/${FUNCNAME}.cloud-init.yaml|base64 -w0 | |
#cloud-config | |
bootcmd: | |
- set -x | |
- export DEBIAN_FRONTEND=noninteractive | |
- cloud-init-per once aupdate apt update -qq | |
- cloud-init-per once isquashfuse apt install squashfuse -yqq | |
- cloud-init-per once rlxd apt purge lxd\\* -yqq | |
- cloud-init-per once aremove apt autoremove -yq | |
final_message: "LXD-Cluster Install Complete" | |
timezone: ${CI_TZ} | |
locale: ${CI_LC} | |
apt: | |
primary: | |
- arches: [amd64] | |
uri: http://us.archive.ubuntu.com/ubuntu} | |
security: | |
- arches: [amd64] | |
uri: http://us.archive.ubuntu.com/ubuntu} | |
sources_list: | | |
deb \$PRIMARY \$RELEASE main universe restricted multiverse | |
deb \$PRIMARY \$RELEASE-updates main universe restricted multiverse | |
deb \$SECURITY \$RELEASE-security main universe restricted multiverse | |
deb \$SECURITY \$RELEASE-backports main universe restricted multiverse | |
package_update: ${CI_PKG_UPD} | |
package_upgrade: ${CI_PKG_UPG} | |
${CI_PACKAGES} | |
write_files: | |
- encoding: b64 | |
content: ${LXD_CLUSTER_SCRIPT} | |
path: /usr/local/bin/lxd-cluster.sh | |
permissions: '755' | |
owner: root:root | |
- encoding: b64 | |
content: ${LXD_IMAGE_SCRIPT} | |
path: /usr/local/bin/lxc-image-copy.sh | |
permissions: '755' | |
owner: root:root | |
runcmd: | |
- set -x | |
- snap install lxd --candidate | |
- adduser \$(id -un 1000) lxd | |
- export PATH="/snap/bin:$PATH" | |
- sed 's|PATH="|PATH="/snap/bin:|g' -i /etc/environment | |
- if [ ! \$(id -un 1000) = ubuntu -a -n \$(id 2>/dev/null -u ubuntu) ];then adduser ubuntu lxd;fi | |
- if [ ! -f \$(awk -F":" '/'\$(id -un 0)'/{print \$6}' /etc/passwd)/.ssh/id_rsa ];then printf "y\n"|ssh-keygen -f ~/.ssh/id_rsa -P "";fi | |
- if [ ! -f \$(awk -F":" '/'\$(id -un 1000)'/{print \$6}' /etc/passwd)/.ssh/id_rsa ];then su - \$(id -un 1000) -c 'printf "y\n"|ssh-keygen -f ~/.ssh/id_rsa -P ""' ;fi | |
- if [ ! \$(id -un 1000) = ubuntu -a -n \$(id 2>/dev/null -u ubuntu) ];then if [ ! -f \$(awk -F":" '/ubuntu/{print \$6}' /etc/passwd)/.ssh/id_rsa ];then su - ubuntu -c 'printf "y\n"|ssh-keygen -f ~/.ssh/id_rsa -P ""' ;fi;fi | |
- cp /etc/ssh/ssh_host_rsa_key* \$(awk -F":" '/'\$(id -un 1000)'/{print \$6}' /etc/passwd)/.ssh/ | |
- chown -R \$(id -un 1000):\$(id -un 1000) \$(awk -F":" '/'\$(id -un 1000)'/{print \$6}' /etc/passwd)/.ssh/ | |
- cat /etc/ssh/ssh_host_rsa_key.pub|tee 1>/dev/null -a \$(awk -F":" '/'\$(id -un 0)'/{print \$6}' /etc/passwd)/.ssh/authorized_keys \$(awk -F":" '/'\$(id -un 1000)'/{print \$6}' /etc/passwd)/.ssh/authorized_keys | |
- printf -- "\nHost ${CLUSTER_HOST_LIST}\n\tAddressFamily inet\n\tCheckHostIP no\n\tForwardX11Trusted yes\n\tForwardX11 yes\n\tIdentityFile /etc/ssh/ssh_host_rsa_key\n LogLevel FATAL\n SendEnv LANG LC_*\n StrictHostKeyChecking no\n UserKnownHostsFile /dev/null\n User ubuntu\n\tXAuthLocation /usr/bin/xauth\n"|tee -a 1>/dev/null /etc/ssh/ssh_config | |
- printf -- "%s\n" ${CLUSTER_HOST_LIST//\*/}|xargs -I{} -n1 -P0 ssh-keyscan 2>/dev/null -H {}|su - \$(id -un 1000) -c "tee -a ~/.ssh/known_hosts" | |
- printf -- "%s\n" ${CLUSTER_HOST_LIST//\*/}|xargs -I{} -n1 -P0 ssh-keyscan 2>/dev/null -H {}|tee -a \$(awk -F":" '/'\$(id -un 1000)'/{print \$6}' /etc/passwd)/.ssh/known_hosts | |
- if [ -f /usr/local/bin/lxd-cluster.sh ];then /usr/local/bin/lxd-cluster.sh;fi | |
- if [ \$(hostname -s) = ${LXD_PRIMARY} -a -f /usr/local/bin/lxc-image-copy.sh ];then /usr/local/bin/lxc-image-copy.sh;fi | |
- lxc 2>/dev/null profile device set maas eth0 parent \$(ip route get ${MAAS_IP}|/bin/grep -oP '(?<=dev )[^ ]+') | |
- lxc 2>/dev/null profile device set maas-privileged eth0 parent \$(ip route get ${MAAS_IP}|/bin/grep -oP '(?<=dev )[^ ]+') | |
- touch /var/tmp/install-complete | |
${SSH_HOST_KEYS} | |
${SSH_PUB_KEYS} | |
EOF | |
)" | |
[[ -n ${MICROCLOUD_TAG} ]] || { local MICROCLOUD_TAG="${BASE_TAG}-$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 6 | head -n 1)"; } | |
printf "\n\e[2GCreating tag \"${MICROCLOUD_TAG}\" for this microcloud...\n" | |
maas ${MAAS_PROFILE} tags create name=${MICROCLOUD_TAG} comment="$(echo -n ${MICROCLOUD_TAG^^}|sed 's/-/_/g')_HOSTS=(`printf '%s\n' ${ALLOCATED_MACHINES[@]##*:}|paste -sd" "` ); $(echo -n ${MICROCLOUD_TAG^^}|sed 's/-/_/g')_BUILD_DATE=$(date --iso-8601=seconds)" &>/dev/null | |
printf "\e[2G- Tagging ${#ALLOCATED_MACHINES[@]} machines with \"${MICROCLOUD_TAG}\"...\n" | |
ADD=$(printf "add=%s\n" ${ALLOCATED_MACHINES[@]##*:}|paste -sd' ') | |
local ADDED=$(eval "maas ${MAAS_PROFILE} tag update-nodes ${MICROCLOUD_TAG} "$ADD""|jq -r .added) | |
[[ ${ADDED} -eq ${#ALLOCATED_MACHINES[@]} ]] && { printf "\e[4G - Successfully tagged ${ADDED}/${#ALLOCATED_MACHINES[@]} machines with the \"${MICROCLOUD_TAG}\" tag ${OK} "; } || { printf "\e[2G - Could only tag ${ADDED}/${#ALLOCATED_MACHINES[@]} machines with ${MICROCLOUD_TAG} ${FAILED} \n"; } | |
echo | |
printf "\n\e[2GDeploying the following hosts to ${MICROCLOUD_TAG} :\n\n" | |
printf -- "\e[2G - %s\n" ${ALLOCATED_MACHINES[@]}|sed 's/:/ \(/g;s/.$/&\)/g';echo | |
local -a DEPLOYED_MACHINES=($(printf "%s\n" ${ALLOCATED_MACHINES[@]##*:}|xargs -I{} -n1 -P1 maas ${MAAS_PROFILE} machine deploy {} distro_series=${DISTRO} user_data="${CI_USER_DATA}"|jq 2>/dev/null -r '"\(.hostname):\(.system_id)"')) | |
printf "\n\e[2G - A copy of the cloud-init used for this deployment can be found at /tmp/${FUNCNAME}.cloud-init.yaml\n\n" | |
printf "\e[0m\n\e[5G\e[38;2;255;255;255mLXD Microcloud Tips:\e[0m\n" | |
printf "\n\e[4G - To run cluster status on all nodes, type:\n\e[7G\e[38;2;255;255;255;3mmaas ${MAAS_PROFILE} tag nodes ${MICROCLOUD_TAG}|jq -r .[].hostname|sort -V|xargs -rn1 -P1 -I{} ssh {} lxc cluster list\n\e[0m" | |
printf "\n\e[4G - To release all machines in cluster, type:\n\e[7G\e[38;2;255;255;255;3mmaas ${MAAS_PROFILE} tag nodes ${MICROCLOUD_TAG}|jq -r .[].system_id|xargs -rn1 -P0 maas ${MAAS_PROFILE} machine release;maas ${MAAS_PROFILE} tag delete ${MICROCLOUD_TAG}\n\e[0m" | |
echo | |
[[ ${WAIT} = true ]] && { tput civis;while [[ $(maas ${MAAS_PROFILE} tag nodes ${MICROCLOUD_TAG}|jq -r '.[]|select(.status_name=="Deploying").name'|wc -l) -ne 0 ]];do printf "\e[2G - Deploying\e[K\r";sleep .25;printf "\e[2G - Deploying .\e[K\r";sleep .25;printf "\e[2G - Deploying . .\e[K\r";sleep .25;printf "\e[2G - Deploying . . .\e[K\r";sleep .25;done;tput cnorm; } | |
[[ -n ${FDEBUG} && ${FDEBUG} = true ]] && { set +x &>/dev/null; } | |
};export -f maas-microcloud-lxd |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment