2018-04-20 14:12:01 -04:00
#!/bin/bash
2020-05-11 13:36:57 -04:00
required_bins = ( ip sudo debconf-set-selections )
2018-04-20 14:12:01 -04:00
check_bins( ) {
# Append any needed binaries we need to check for, to our list
if [ [ $1 ] ] ; then
required_bins += ( " $1 " )
fi
2020-05-11 13:36:57 -04:00
2018-04-20 14:12:01 -04:00
for binary in " ${ required_bins [@] } " ; do
if ! [ -x " $( command -v " $binary " ) " ] ; then
printf "Error: Necessary program '%s' is not installed. Please fix, aborting now.\n\n" " $binary " >& 2
exit 1
fi
done
}
2020-05-07 11:50:58 -04:00
read_config( ) {
2020-05-11 13:21:06 -04:00
if [ ! -f maas.config ] ; then
printf "Error: missing config file. Please create the file 'maas.config'.\n"
exit 1
else
shopt -s extglob
maas_config = "maas.config"
source " $maas_config "
fi
if [ ! -f maas.debconf ] ; then
printf "Error: missing debconf file. Please create the file 'maas.debconf'.\n"
exit 1
fi
2020-05-07 11:50:58 -04:00
}
2018-04-20 14:12:01 -04:00
# Initialize some vars we'll reuse later in the build, bootstrap
init_variables( ) {
2019-03-01 21:11:47 +00:00
echo " MAAS Endpoint: $maas_endpoint "
echo " MAAS Proxy: $maas_local_proxy "
2018-04-20 14:12:01 -04:00
2020-05-12 10:10:17 -04:00
core_packages = ( jq moreutils uuid )
maas_packages = ( maas maas-cli maas-proxy maas-dhcp maas-dns maas-rack-controller maas-region-api maas-common )
pg_packages = ( postgresql-10 postgresql-client postgresql-client-common postgresql-common )
2018-04-20 14:12:01 -04:00
}
remove_maas( ) {
# Drop the MAAS db ("maasdb"), so we don't risk reusing it
sudo -u postgres psql -c "select pg_terminate_backend(pid) from pg_stat_activity where datname='maasdb'"
sudo -u postgres psql -c "drop database maasdb"
# Remove everything, start clean and clear from the top
2020-05-07 11:50:58 -04:00
sudo DEBIAN_FRONTEND = noninteractive apt-get -y remove --purge " ${ maas_packages [@] } " " ${ pg_packages [@] } " && \
sudo apt-get -fuy autoremove
2018-04-20 14:12:01 -04:00
# Yes, they're removed but we want them PURGED, so this becomes idempotent
for package in " ${ maas_packages [@] } " " ${ pg_packages [@] } " ; do
sudo dpkg -P " $package "
done
}
install_maas( ) {
# This is separate from the removal, so we can handle them atomically
2020-05-12 10:10:17 -04:00
sudo apt-get -fuy --reinstall install " ${ core_packages } " " ${ maas_packages [@] } " " ${ pg_packages [@] } "
2020-04-29 16:11:40 -04:00
sudo sed -i 's/DISPLAY_LIMIT=5/DISPLAY_LIMIT=100/' /usr/share/maas/web/static/js/bundle/maas-min.js
2018-04-20 14:12:01 -04:00
}
purge_admin_user( ) {
read -r -d '' purgeadmin <<EOF
with deleted_user as ( delete from auth_user where username = '$maas_profile' returning id) ,
deleted_token as ( delete from piston3_token where user_id = ( select id from deleted_user) ) ,
deleted_ssh_id as ( delete from maasserver_sshkey where user_id = ( select id from deleted_user) ) ,
deleted_userprofile as ( delete from maasserver_userprofile where user_id = ( select id from deleted_user) )
delete from piston3_consumer where user_id = ( select id from deleted_user) ;
EOF
sudo -u postgres psql -c " $purgeadmin " maasdb
}
build_maas( ) {
# Create the initial 'admin' user of MAAS, purge first!
purge_admin_user
sudo maas createadmin --username " $maas_profile " --password " $maas_pass " --email " $maas_profile " @" $maas_pass " --ssh-import lp:" $launchpad_user "
2019-03-01 21:11:47 +00:00
sudo chsh -s /bin/bash maas
sudo chown -R maas:maas /var/lib/maas
2020-05-11 13:36:57 -04:00
if [ -f ~/.maas-api.key ] ; then
2020-05-07 11:50:58 -04:00
rm ~/.maas-api.key
maas_api_key = " $( sudo maas-region apikey --username= $maas_profile | tee ~/.maas-api.key) "
fi ;
2018-04-20 14:12:01 -04:00
# Fetch the MAAS API key, store to a file for later reuse, also set this var to that value
2020-05-11 13:36:57 -04:00
maas login " $maas_profile " " $maas_endpoint " " $maas_api_key "
2018-04-20 14:12:01 -04:00
maas_system_id = " $( maas $maas_profile nodes read hostname = " $HOSTNAME " | jq -r '.[].interface_set[0].system_id' ) "
# Inject the maas SSH key
2020-05-07 11:50:58 -04:00
maas_ssh_key = $( <~/.ssh/maas_rsa.pub)
2018-04-20 14:12:01 -04:00
maas $maas_profile sshkeys create " key= $maas_ssh_key "
# Update settings to match our needs
2020-04-29 16:11:40 -04:00
maas $maas_profile maas set-config name = default_storage_layout value = lvm
2018-04-20 14:12:01 -04:00
maas $maas_profile maas set-config name = network_discovery value = disabled
maas $maas_profile maas set-config name = active_discovery_interval value = 0
2020-05-06 23:25:47 -04:00
maas $maas_profile maas set-config name = kernel_opts value = "console=ttyS0,115200 console=tty0,115200 elevator=noop zswap.enabled=1 zswap.compressor=lz4 zswap.max_pool_percent=20 zswap.zpool=z3fold intel_iommu=on iommu=pt debug nosplash scsi_mod.use_blk_mq=1 dm_mod.use_blk_mq=1 enable_mtrr_cleanup mtrr_spare_reg_nr=1 systemd.log_level=debug"
2018-04-20 14:12:01 -04:00
maas $maas_profile maas set-config name = maas_name value = us-east
maas $maas_profile maas set-config name = upstream_dns value = " $maas_upstream_dns "
2019-03-11 04:53:49 +00:00
maas $maas_profile maas set-config name = dnssec_validation value = no
2018-04-20 14:12:01 -04:00
maas $maas_profile maas set-config name = enable_analytics value = false
maas $maas_profile maas set-config name = enable_http_proxy value = true
2020-04-29 16:11:40 -04:00
# maas $maas_profile maas set-config name=http_proxy value="$squid_proxy"
2018-04-20 14:12:01 -04:00
maas $maas_profile maas set-config name = enable_third_party_drivers value = false
2019-03-01 21:11:47 +00:00
maas $maas_profile maas set-config name = curtin_verbose value = true
2019-03-26 16:12:00 +00:00
2020-05-07 11:50:58 -04:00
maas $maas_profile boot-source update 1 url = " $maas_boot_source "
# maas $maas_profile boot-source update 1 url=http://"$maas_bridge_ip":8765/maas/images/ephemeral-v3/daily/
2020-05-16 20:59:56 -04:00
maas $maas_profile package-repository update 1 name = 'main_archive' url = " $package_repository "
2019-03-26 16:12:00 +00:00
2020-04-29 16:11:40 -04:00
# This is hacky, but it's the only way I could find to reliably get the
# correct subnet for the maas bridge interface
2020-05-06 23:25:47 -04:00
maas $maas_profile subnet update " $( maas $maas_profile subnets read | jq -rc --arg maas_ip " $maas_ip_range " '.[] | select(.name | contains($maas_ip)) | "\(.id)"' ) " gateway_ip = " $maas_bridge_ip "
2019-03-01 21:11:47 +00:00
sleep 3
2020-05-06 23:25:47 -04:00
2020-05-11 13:38:57 -04:00
maas $maas_profile ipranges create type = dynamic start_ip = " $maas_subnet_start " end_ip = " $maas_subnet_end " comment = 'This is the reserved range for MAAS nodes'
2020-05-06 23:25:47 -04:00
2019-03-26 16:12:00 +00:00
sleep 3
2020-04-29 16:11:40 -04:00
maas $maas_profile vlan update fabric-1 0 dhcp_on = True primary_rack = " $maas_system_id "
2018-04-20 14:12:01 -04:00
# This is needed, because it points to localhost by default and will fail to
# commission/deploy in this state
2019-03-11 04:53:49 +00:00
echo " DEBUG: http:// $maas_bridge_ip :5240/MAAS/ "
2020-05-11 13:36:57 -04:00
2020-04-29 16:11:40 -04:00
sudo debconf-set-selections maas.debconf
sleep 2
# sudo maas-rack config --region-url "http://$maas_bridge_ip:5240/MAAS/" && sudo service maas-rackd restart
sudo DEBIAN_FRONTEND = noninteractive dpkg-reconfigure maas-rack-controller
sleep 2
2020-05-11 13:36:57 -04:00
2020-04-29 16:11:40 -04:00
sudo DEBIAN_FRONTEND = noninteractive dpkg-reconfigure maas-region-controller
sudo service maas-rackd restart
2020-05-06 23:25:47 -04:00
sleep 5
2018-04-20 14:12:01 -04:00
}
bootstrap_maas( ) {
# Import the base images; this can take some time
echo "Importing boot images, please be patient, this may take some time..."
maas $maas_profile boot-resources import
until [ " $( maas $maas_profile boot-resources is-importing) " = false ] ; do sleep 3; done ;
# Add a chassis with nodes we want to build against
maas $maas_profile machines add-chassis chassis_type = virsh prefix_filter = maas-node hostname = " $virsh_chassis "
# This is necessary to allow MAAS to quiesce the imported chassis
echo "Pausing while chassis is imported..."
sleep 10
# Commission those nodes (requires that image import step has completed)
2020-04-29 16:11:40 -04:00
maas $maas_profile machines accept-all
2018-04-20 14:12:01 -04:00
# Grab the first node in the chassis and commission it
# maas_node=$(maas $maas_profile machines read | jq -r '.[0].system_id')
# maas "$maas_profile" machine commission -d "$maas_node"
# Acquire all images marked "Ready"
2020-05-11 13:36:57 -04:00
maas $maas_profile machines allocate
2018-04-20 14:12:01 -04:00
# Deploy the node you just commissioned and acquired
# maas "$maas_profile" machine deploy $maas_node
}
# These are for juju, adding a cloud matching the customer/reproducer we need
add_cloud( ) {
2020-05-07 11:50:58 -04:00
if ! [ -x " $( command -v juju) " ] ; then
sudo snap install juju --channel " $juju_version "
fi
2018-04-20 14:12:01 -04:00
rand_uuid = $( uuid -F siv)
cloud_name = " $1 "
2020-05-07 11:50:58 -04:00
maas_api_key = $( <~/.maas-api.key)
2018-04-20 14:12:01 -04:00
cat > clouds-" $rand_uuid " .yaml <<EOF
clouds:
$cloud_name :
type: maas
auth-types: [ oauth1 ]
description: MAAS cloud for $cloud_name
# endpoint: ${maas_endpoint:0:-8}
endpoint: $maas_endpoint
2019-03-26 16:12:00 +00:00
config:
2020-05-16 20:59:56 -04:00
apt-mirror: $package_repository
2020-04-29 16:11:40 -04:00
apt-http-proxy: $squid_proxy
apt-https-proxy: $squid_proxy
snap-http-proxy: $squid_proxy
snap-https-proxy: $squid_proxy
2020-05-11 14:02:38 -04:00
# snap-store-proxy: $snap_store_proxy
2019-03-26 16:12:00 +00:00
enable-os-refresh-update: true
enable-os-upgrade: false
logging-config: <root>= DEBUG
2018-04-20 14:12:01 -04:00
EOF
cat > credentials-" $rand_uuid " .yaml <<EOF
credentials:
$cloud_name :
$cloud_name -auth:
auth-type: oauth1
2020-05-11 13:36:57 -04:00
maas-oauth: $maas_api_key
2018-04-20 14:12:01 -04:00
EOF
cat > config-" $rand_uuid " .yaml <<EOF
automatically-retry-hooks: true
2020-04-29 16:11:40 -04:00
mongo-memory-profile: default
2019-03-01 21:11:47 +00:00
default-series: bionic
2020-04-29 16:11:40 -04:00
juju-ftp-proxy: $squid_proxy
juju-http-proxy: $squid_proxy
juju-https-proxy: $squid_proxy
2020-05-11 13:16:40 -04:00
juju-no-proxy: $no_proxy
2020-04-29 16:11:40 -04:00
apt-http-proxy: $squid_proxy
apt-https-proxy: $squid_proxy
transmit-vendor-metrics: false
2018-04-20 14:12:01 -04:00
EOF
2020-05-11 13:36:57 -04:00
echo " Adding cloud............: $cloud_name "
2020-04-29 16:11:40 -04:00
# juju add-cloud --replace "$cloud_name" clouds-"$rand_uuid".yaml
juju update-cloud " $cloud_name " -f clouds-" $rand_uuid " .yaml
2018-04-20 14:12:01 -04:00
echo " Adding credentials for..: $cloud_name "
2020-04-29 16:11:40 -04:00
#juju add-credential --replace "$cloud_name" -f credentials-"$rand_uuid".yaml
juju add-credential " $cloud_name " -f credentials-" $rand_uuid " .yaml
2018-04-20 14:12:01 -04:00
echo " Details for cloud.......: $cloud_name ... "
juju clouds --format json | jq --arg cloud " $cloud_name " '.[$cloud]'
juju bootstrap " $cloud_name " --debug --config= config-" $rand_uuid " .yaml
2020-05-11 13:36:57 -04:00
2018-04-20 14:12:01 -04:00
# Since we created ephemeral files, let's wipe them out. Comment if you want to keep them around
if [ [ $? = 0 ] ] ; then
rm -f clouds-" $rand_uuid " .yaml credentials-" $rand_uuid " .yaml config-" $rand_uuid " .yaml
fi
2020-04-29 16:11:40 -04:00
juju enable-ha
juju machines -m controller
2018-04-20 14:12:01 -04:00
}
# Let's get rid of that cloud and clean up after ourselves
destroy_cloud( ) {
cloud_name = " $1 "
2020-04-29 16:11:40 -04:00
juju --debug clouds --format json | jq --arg cloud " $cloud_name " '.[$cloud]'
juju --debug remove-cloud " $cloud_name "
2018-04-20 14:12:01 -04:00
}
show_help( ) {
echo "
-a <cloud_name> Do EVERYTHING ( maas, juju cloud, juju bootstrap)
-b Build out and bootstrap a new MAAS
-c <cloud_name> Add a new cloud + credentials
-i Just install the dependencies and exit
-j <name> Bootstrap the Juju controller called <name>
-n Create MAAS kvm nodes ( to be imported into chassis)
-r Remove the entire MAAS server + dependencies
-t <cloud_name> Tear down the cloud named <cloud_name>
"
}
if [ $# -eq 0 ] ; then
printf "%s needs options to function correctly. Valid options are:" " $0 "
show_help
exit 0
fi
2020-05-11 13:41:33 -04:00
# Load up some initial variables from the config and package arrays
2018-04-20 14:12:01 -04:00
init_variables
2020-05-07 11:50:58 -04:00
read_config
2018-04-20 14:12:01 -04:00
2020-05-11 13:16:40 -04:00
# This is the proxy that MAAS itself uses (the "internal" MAAS proxy)
no_proxy = " localhost,127.0.0.1, $maas_system_ip , $( echo $maas_ip_range .{ 100..200} | sed 's/ /,/g' ) "
2018-04-20 14:12:01 -04:00
while getopts ":a:bc:ij:nt:r" opt; do
case $opt in
a )
check_bins
remove_maas
install_maas
build_maas
bootstrap_maas
add_cloud " $OPTARG "
; ;
b )
echo "Building out a new MAAS server"
2020-04-29 16:11:40 -04:00
check_bins
2018-04-20 14:12:01 -04:00
install_maas
build_maas
bootstrap_maas
exit 0
; ;
c )
check_bins maas
init_variables
add_cloud " $OPTARG "
; ;
i )
echo "Installing MAAS and PostgreSQL dependencies"
install_maas
exit 0
; ;
j )
echo " Bootstrapping Juju controller $OPTARG "
add_cloud " $OPTARG "
exit 0
; ;
r )
remove_maas
exit 0
; ;
t )
destroy_cloud " $OPTARG "
exit 0
; ;
\? )
printf "Unrecognized option: -%s. Valid options are:" " $OPTARG " >& 2
show_help
exit 1
; ;
: )
printf "Option -%s needs an argument.\n" " $OPTARG " >& 2
show_help
echo ""
exit 1
; ;
esac
done