
- Add a shellcheck linter for the scripts in the multinode framework - Update all scripting to comply with shellcheck - Move linting job to Ubuntu Bionic as the multinode gate now requires Bionic versions of libvirt Change-Id: Ibee645331421e1e6cecd4e3daa8e9c321dce5523
515 lines
12 KiB
Bash
515 lines
12 KiB
Bash
#!/bin/bash
|
|
export TEMP_DIR=${TEMP_DIR:-$(mktemp -d)}
|
|
export NAMEKEY_FILE=${NAMEKEY_FILE:-"$HOME/.airship_key"}
|
|
export DEFINITION_DEPOT="${TEMP_DIR}/site_yaml/"
|
|
export RENDERED_DEPOT="${TEMP_DIR}/rendered_yaml/"
|
|
export CERT_DEPOT="${TEMP_DIR}/cert_yaml/"
|
|
export GATE_DEPOT="${TEMP_DIR}/gate_yaml/"
|
|
export SCRIPT_DEPOT="${TEMP_DIR}/scripts/"
|
|
export BUILD_WORK_DIR=${BUILD_WORK_DIR:-/work}
|
|
export BASE_IMAGE_SIZE=${BASE_IMAGE_SIZE:-68719476736}
|
|
export BASE_IMAGE_URL=${BASE_IMAGE_URL:-https://cloud-images.ubuntu.com/releases/xenial/release/ubuntu-16.04-server-cloudimg-amd64-disk1.img}
|
|
export IMAGE_PROMENADE_CLI=${IMAGE_PROMENADE_CLI:-quay.io/airshipit/promenade:cfb8aa498c294c2adbc369ba5aaee19b49550d22}
|
|
export IMAGE_PEGLEG_CLI=${IMAGE_PEGLEG_CLI:-quay.io/airshipit/pegleg:50ce7a02e08a0a5277c2fbda96ece6eb5782407a}
|
|
export IMAGE_SHIPYARD_CLI=${IMAGE_SHIPYARD_CLI:-quay.io/airshipit/shipyard:4dd6b484d11e86ad51da733841b9ef137421d461}
|
|
export IMAGE_COREDNS=${IMAGE_COREDNS:-docker.io/coredns/coredns:1.2.2}
|
|
export IMAGE_QUAGGA=${IMAGE_QUAGGA:-docker.io/cumulusnetworks/quagga:CL3.3.2}
|
|
export IMAGE_DRYDOCK_CLI=${IMAGE_DRYDOCK_CLI:-quay.io/airshipit/drydock:d93d6d5a0a370ced536180612d1ade708e29cd47}
|
|
export IMAGE_DOCKER_REGISTRY=${IMAGE_DOCKER_REGISTRY:-"docker.io/registry:2"}
|
|
export IMAGE_HYPERKUBE=${IMAGE_HYPERKUBE:-gcr.io/google_containers/hyperkube-amd64:v1.12.9}
|
|
export PROMENADE_DEBUG=${PROMENADE_DEBUG:-0}
|
|
export PROMENADE_TMP_LOCAL=${PROMENADE_TMP_LOCAL:-cache}
|
|
export REGISTRY_DATA_DIR=${REGISTRY_DATA_DIR:-/mnt/registry}
|
|
export VIRSH_POOL=${VIRSH_POOL:-airship}
|
|
export VIRSH_POOL_PATH=${VIRSH_POOL_PATH:-/var/lib/libvirt/airship}
|
|
export VIRSH_CPU_OPTS=${VIRSH_CPU_OPTS:-host}
|
|
export UPSTREAM_DNS=${UPSTREAM_DNS:-"8.8.8.8 8.8.4.4"}
|
|
export NTP_POOLS=${NTP_POOLS:-"0.ubuntu.pool.ntp.org 1.ubuntu.pool.ntp.org"}
|
|
export NTP_SERVERS=${NTP_SERVERS:-""}
|
|
export PROMENADE_ENCRYPTION_KEY=${PROMENADE_ENCRYPTION_KEY:-MjI1N2ZiMjMzYjI0ZmVkZDU4}
|
|
|
|
# key-pair used for drydock/maas auth towards libvirt and access to
|
|
# the virtual nodes; auto-generated if no value provided
|
|
export GATE_SSH_KEY=${GATE_SSH_KEY:-""}
|
|
|
|
# skip generation of certificates, and other security manifests
|
|
# auto-generated by default
|
|
export USE_EXISTING_SECRETS=${USE_EXISTING_SECRETS:-""}
|
|
|
|
export SHIPYARD_PASSWORD=${SHIPYARD_OS_PASSWORD:-'password18'}
|
|
export AIRSHIP_KEYSTONE_URL=${AIRSHIP_KEYSTONE_URL:-'http://keystone.gate.local:80/v3'}
|
|
|
|
config_vm_memory() {
|
|
nodename=${1}
|
|
jq -cr ".vm.${nodename}.memory" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_vm_names() {
|
|
jq -cr '.vm | keys | join(" ")' < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_vm_iface_list() {
|
|
nodename="$1"
|
|
jq -cr ".vm.${nodename}.networking | del(.addresses) | keys | .[]" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_vm_iface_mac() {
|
|
nodename="$1"
|
|
interface="$2"
|
|
jq -cr ".vm.${nodename}.networking.${interface}.mac" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
# What network this VM interface should be attached to
|
|
config_vm_iface_network() {
|
|
nodename="$1"
|
|
interface="$2"
|
|
jq -cr ".vm.${nodename}.networking.${interface}.attachment.network" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
# What VLANs on a network should be attached to this node
|
|
config_vm_iface_vlans() {
|
|
nodename="$1"
|
|
interface="$2"
|
|
jq -cr ".vm.${nodename}.networking.${interface}.attachment.vlans | select(.!=null)" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
# PCI slot for this VM interface
|
|
config_vm_iface_slot() {
|
|
nodename="$1"
|
|
interface="$2"
|
|
jq -cr ".vm.${nodename}.networking.${interface}.pci.slot" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
# PCI card port for this VM interface
|
|
config_vm_iface_port() {
|
|
nodename="$1"
|
|
interface="$2"
|
|
jq -cr ".vm.${nodename}.networking.${interface}.pci.port" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
# The IP address for the VM for a network. If vlan is also specified, the VLAN
|
|
# on the network
|
|
config_vm_net_ip() {
|
|
nodename="$1"
|
|
network="$2"
|
|
vlan="$3"
|
|
|
|
if is_netspec "$network"
|
|
then
|
|
vlan=$(netspec_vlan "$network")
|
|
network=$(netspec_netname "$network")
|
|
fi
|
|
|
|
if [[ -z "$vlan" ]]
|
|
then
|
|
query=".vm.${nodename}.networking.addresses.${network}.ip"
|
|
else
|
|
query=".vm.${nodename}.networking.addresses.${network}.vlans.${vlan}.ip"
|
|
fi
|
|
|
|
jq -cr "$query" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_vm_vcpus() {
|
|
nodename=${1}
|
|
jq -cr ".vm.${nodename}.vcpus" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_vm_bootstrap() {
|
|
nodename=${1}
|
|
val=$(jq -cr ".vm.${nodename}.bootstrap" < "${GATE_MANIFEST}")
|
|
if [[ "${val}" == "true" ]]
|
|
then
|
|
echo "true"
|
|
else
|
|
echo "false"
|
|
fi
|
|
}
|
|
|
|
config_disk_list() {
|
|
layout_name="${1}"
|
|
jq -cr ".disk_layouts.${layout_name} | keys | join(\" \")" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_disk_details() {
|
|
layout_name="${1}"
|
|
disk_device="${2}"
|
|
jq -cr ".disk_layouts.${layout_name}.${disk_device}" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_disk_size() {
|
|
layout_name="$1"
|
|
disk_device="$2"
|
|
jq -cr ".disk_layouts.${layout_name}.${disk_device}.size" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_disk_format() {
|
|
layout_name="$1"
|
|
disk_device="$2"
|
|
do_format=$(jq -cr ".disk_layouts.${layout_name}.${disk_device} | has(\"format\")")
|
|
|
|
if [[ "$do_format" == "true" && "$disk_device" != "$(config_layout_bootstrap "$layout_name")" ]]
|
|
then
|
|
jq -cr ".disk_layouts.${layout_name}.${disk_device}.format" < "${GATE_MANIFEST}"
|
|
else
|
|
echo ""
|
|
fi
|
|
}
|
|
|
|
config_format_type() {
|
|
JSON="$1"
|
|
echo "$JSON" | jq -cr '.type'
|
|
}
|
|
|
|
config_format_mount() {
|
|
JSON="$1"
|
|
echo "$JSON" | jq -cr '.mountpoint'
|
|
}
|
|
|
|
config_disk_ioprofile() {
|
|
layout_name="$1"
|
|
disk_device="$2"
|
|
jq -cr ".disk_layouts.${layout_name}.${disk_device}.io_profile"
|
|
}
|
|
|
|
# Find which disk in a layout should
|
|
# get the bootstrap image
|
|
config_layout_bootstrap() {
|
|
layout_name="${1}"
|
|
jq -cr ".disk_layouts.${layout_name} | keys[] as \$k | {device: (\$k)} + (.[\$k]) | select(.bootstrap) | .device " < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_vm_disk_layout() {
|
|
nodename=${1}
|
|
jq -cr ".vm.${nodename}.disk_layout" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_vm_userdata() {
|
|
nodename=${1}
|
|
val=$(jq -cr ".vm.${nodename}.userdata" < "${GATE_MANIFEST}")
|
|
|
|
if [[ "${val}" != "null" ]]
|
|
then
|
|
echo "${val}"
|
|
fi
|
|
}
|
|
|
|
config_bgp_as() {
|
|
as_number=${1}
|
|
jq -cr ".bgp.${as_number}" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_net_list() {
|
|
jq -cr '.networking | keys | .[]' < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_net_vlan_list() {
|
|
network="$1"
|
|
|
|
jq -cr ".networking.${network}.layer2.vlans // {} | keys | .[]" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_net_cidr() {
|
|
network="$1"
|
|
vlan="$2"
|
|
|
|
if is_netspec "$network"
|
|
then
|
|
vlan=$(netspec_vlan "$network")
|
|
network=$(netspec_netname "$network")
|
|
fi
|
|
|
|
if [[ -z "$vlan" ]]
|
|
then
|
|
query=".networking.${network}.layer3.cidr"
|
|
else
|
|
query=".networking.${network}.vlans.${vlan}.layer3.cidr"
|
|
fi
|
|
|
|
jq -cr "$query" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_net_is_layer3() {
|
|
network="$1"
|
|
vlan="$2"
|
|
|
|
if is_netspec "$network"
|
|
then
|
|
vlan=$(netspec_vlan "$network")
|
|
network=$(netspec_netname "$network")
|
|
fi
|
|
|
|
if [[ -z "$vlan" ]]
|
|
then
|
|
query=".networking.${network} | has(\"layer3\")"
|
|
else
|
|
query=".network.${network}.vlans.${vlan} | has(\"layer3\")"
|
|
fi
|
|
|
|
jq -cr "$query" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
# Find the layer 3 network tagged for a particular
|
|
# role - this can be either a native or vlan network
|
|
# If multiple networks have a role, the results is
|
|
# undefined
|
|
config_netspec_for_role() {
|
|
role="$1"
|
|
|
|
set -x
|
|
|
|
for net in $(config_net_list)
|
|
do
|
|
if config_net_has_role "$net" "$role"
|
|
then
|
|
netspec="$net"
|
|
fi
|
|
|
|
for vlan in $(config_net_vlan_list "$net")
|
|
do
|
|
if config_vlan_has_role "$net" "$vlan" "$role"
|
|
then
|
|
netspec="${vlan}@${net}"
|
|
fi
|
|
done
|
|
done
|
|
|
|
echo -n "$netspec"
|
|
}
|
|
|
|
config_net_has_role() {
|
|
netname="$1"
|
|
role="$2"
|
|
|
|
value="$(jq -cr ".networking.${netname}.roles | contains([\"${role}\"])" < "$GATE_MANIFEST")"
|
|
|
|
if [ "$value" == "true" ]
|
|
then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
config_vlan_has_role() {
|
|
netname="$1"
|
|
vlan="$2"
|
|
role="$3"
|
|
|
|
value="$(jq -cr " .networking.${netname}.vlans.${vlan}.roles | contains([\"${role}\"])" < "$GATE_MANIFEST")"
|
|
|
|
if [ "$value" == "true" ]
|
|
then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
config_net_selfip() {
|
|
network="$1"
|
|
vlan="$2"
|
|
|
|
if [[ -z "$vlan" ]]
|
|
then
|
|
query=".networking.${network}.layer3.address"
|
|
else
|
|
query=".networking.${network}.vlans.${vlan}.layer3.address"
|
|
fi
|
|
|
|
jq -cr "$query" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_net_selfip_cidr() {
|
|
network="$1"
|
|
vlan="$2"
|
|
|
|
if is_netspec "$network"
|
|
then
|
|
vlan=$(netspec_vlan "$network")
|
|
network=$(netspec_netname "$network")
|
|
fi
|
|
|
|
selfip=$(config_net_selfip "$network" "$vlan")
|
|
netcidr=$(config_net_cidr "$network" "$vlan")
|
|
netbits=$(echo "$netcidr" | awk -F '/' '{print $2}')
|
|
|
|
printf "%s/%s" "$selfip" "$netbits"
|
|
}
|
|
|
|
config_net_gateway() {
|
|
network="$1"
|
|
vlan="$2"
|
|
|
|
if is_netspec "$network"
|
|
then
|
|
vlan=$(netspec_vlan "$network")
|
|
network=$(netspec_netname "$network")
|
|
fi
|
|
|
|
if [[ -z "$vlan" ]]
|
|
then
|
|
query=".networking.${network}.layer3.gateway"
|
|
else
|
|
query=".networking.${network}.vlans.${vlan}.layer3.gateway"
|
|
fi
|
|
|
|
jq -cr "$query" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_net_routemode() {
|
|
network="$1"
|
|
vlan="$2"
|
|
|
|
if is_netspec "$network"
|
|
then
|
|
vlan=$(netspec_vlan "$network")
|
|
network=$(netspec_netname "$network")
|
|
fi
|
|
|
|
if [[ -z "$vlan" ]]
|
|
then
|
|
query=".networking.${network}.layer3.routing.mode"
|
|
else
|
|
query=".networking.${network}.vlans.${vlan}.layer3.routing.mode"
|
|
fi
|
|
|
|
jq -cr "$query" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_net_mtu() {
|
|
network="$1"
|
|
vlan="$2"
|
|
|
|
if is_netspec "$network"
|
|
then
|
|
vlan=$(netspec_vlan "$network")
|
|
network=$(netspec_netname "$network")
|
|
fi
|
|
|
|
if [[ -z "$vlan" ]]
|
|
then
|
|
query=".networking.${network}.layer2.mtu // 1500"
|
|
else
|
|
query=".networking.${network}.vlans.${vlan}.layer2.mtu // 1500"
|
|
fi
|
|
|
|
jq -cr "$query" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_net_mac() {
|
|
network="$1"
|
|
vlan="$2"
|
|
|
|
if is_netspec "$network"
|
|
then
|
|
vlan=$(netspec_vlan "$network")
|
|
network=$(netspec_netname "$network")
|
|
fi
|
|
|
|
if [[ -z "$vlan" ]]
|
|
then
|
|
query=".networking.${network}.layer2.address"
|
|
else
|
|
query=".networking.${network}.vlans.${vlan}.layer2.address"
|
|
fi
|
|
|
|
jq -cr "$query" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_ingress_domain() {
|
|
jq -cr '.ingress.domain' < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_ingress_ca() {
|
|
if [[ ! -z "$GATE_MANIFEST" ]]
|
|
then
|
|
jq -cr '.ingress.ca' < "${GATE_MANIFEST}"
|
|
fi
|
|
}
|
|
|
|
config_ingress_ips() {
|
|
jq -cr '.ingress | keys | map(select(test("([0-9]{1,3}.?){4}"))) | join(" ")' < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_ingress_entries() {
|
|
IP=$1
|
|
jq -cr ".ingress[\"${IP}\"] | join(\" \")" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_pegleg_primary_repo() {
|
|
jq -cr ".configuration.primary_repo" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_pegleg_sitename() {
|
|
jq -cr ".configuration.site" < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
config_pegleg_aux_repos() {
|
|
jq -cr '.configuration.aux_repos | join(" ")' < "${GATE_MANIFEST}"
|
|
}
|
|
|
|
join_array() {
|
|
local IFS=$1
|
|
shift
|
|
echo "$*"
|
|
}
|
|
|
|
besteffort() {
|
|
set +e
|
|
"$@"
|
|
set -e
|
|
}
|
|
|
|
get_namekey() {
|
|
if [[ -r "$NAMEKEY_FILE" ]]
|
|
then
|
|
key=$(cat "$NAMEKEY_FILE")
|
|
else
|
|
key=$(openssl rand -hex 4)
|
|
echo -n "$key" > "$NAMEKEY_FILE"
|
|
fi
|
|
|
|
echo -n "$key"
|
|
}
|
|
|
|
is_netspec(){
|
|
value="$1"
|
|
|
|
if echo -n "$value" | grep -q "[0-9]+@.+"
|
|
then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
netspec_netname(){
|
|
netspec="$1"
|
|
|
|
echo -n "$netspec" | awk -F'@' '{print $2}'
|
|
}
|
|
|
|
netspec_vlan(){
|
|
netspec="$1"
|
|
|
|
echo -n "$netspec" | awk -F'@' '{print $1}'
|
|
}
|
|
|
|
# We'll just add the conversions as needed
|
|
cidr_to_netmask() {
|
|
cidr="$1"
|
|
netbits="$(echo "$cidr" | awk -F'/' '{print $2}')"
|
|
|
|
case "$netbits" in
|
|
32)
|
|
netmask="255.255.255.255"
|
|
;;
|
|
24)
|
|
netmask="255.255.255.0"
|
|
;;
|
|
esac
|
|
|
|
echo "$netmask"
|
|
}
|