mirror of
https://github.com/mail-in-a-box/mailinabox.git
synced 2025-04-01 23:57:05 +00:00
252 lines
6.8 KiB
Bash
252 lines
6.8 KiB
Bash
#!/bin/bash
|
|
#####
|
|
##### This file is part of Mail-in-a-Box-LDAP which is released under the
|
|
##### terms of the GNU Affero General Public License as published by the
|
|
##### Free Software Foundation, either version 3 of the License, or (at
|
|
##### your option) any later version. See file LICENSE or go to
|
|
##### https://github.com/downtownallday/mailinabox-ldap for full license
|
|
##### details.
|
|
#####
|
|
|
|
|
|
# source this file
|
|
|
|
lx_project_root_dir() {
|
|
local d="$PWD"
|
|
while [ ${#d} -gt 1 ]; do
|
|
if [ -e "$d/setup" ]; then
|
|
echo "$d"
|
|
return 0
|
|
fi
|
|
d="$(dirname "$d")"
|
|
done
|
|
return 1
|
|
}
|
|
|
|
lx_guess_project_name() {
|
|
local d
|
|
d="$(lx_project_root_dir)"
|
|
[ $? -ne 0 ] && return 1
|
|
if [ -e "$d/setup/redis.sh" ]; then
|
|
echo "ciab"
|
|
else
|
|
echo "miab"
|
|
fi
|
|
}
|
|
|
|
|
|
# get the interface with the default route (first one)
|
|
get_system_default_network_interface() {
|
|
ip route | awk '/^default/ {printf "%s", $5; exit 0}'
|
|
}
|
|
|
|
isa_bridge_interface() {
|
|
local interface="$1"
|
|
if ip --oneline link show type bridge | awk -F: '{print $2}' | grep -q "^ *$interface *\$"; then
|
|
echo "yes"
|
|
else
|
|
echo "no"
|
|
fi
|
|
}
|
|
|
|
isa_wifi_device() {
|
|
local interface="$1"
|
|
local type
|
|
type="$(nmcli d show "$interface" | awk '$1=="GENERAL.TYPE:" {print $2}')"
|
|
if [ "$type" = "wifi" ]; then
|
|
echo "yes"
|
|
else
|
|
echo "no"
|
|
fi
|
|
}
|
|
|
|
# delete an instance
|
|
lx_delete() {
|
|
local project="${1:-default}"
|
|
local inst="$2"
|
|
local interactive="${3:-interactive}"
|
|
|
|
local xargs=""
|
|
if [ "$interactive" = "interactive" ]; then
|
|
xargs="-i"
|
|
fi
|
|
|
|
# only delete instance if the instance exists
|
|
if [ "$(lxc --project "$project" list name="$inst" -c n -f csv)" = "$inst" ]; then
|
|
lxc --project "$project" delete "$inst" -f $xargs
|
|
fi
|
|
}
|
|
|
|
|
|
# create a virtual-machine instance and start it
|
|
lx_launch_vm() {
|
|
local project="${1:-default}"
|
|
local inst_name="$2"
|
|
lx_init_vm "$@" || return 1
|
|
lxc --project "$project" start "$inst_name" || return 1
|
|
}
|
|
|
|
|
|
# create a virtual-machine instance (stopped)
|
|
lx_init_vm() {
|
|
local project="${1:-default}"
|
|
local inst_name="$2"
|
|
local image="$3"
|
|
local mount_host="$4" # path that you want available in guest
|
|
local mount_guest="$5" # mountpoint in guest
|
|
shift; shift; shift; shift; shift;
|
|
|
|
# a storage named the same as project must exist
|
|
# e.g. "lxc storage create $project dir" was executed prior.
|
|
|
|
case "${@}" in
|
|
*bridgenet* )
|
|
echo "Using network 'bridgenet'"
|
|
lxc --project "$project" profile show bridgenet | sed 's/^/ /' || return 1
|
|
;;
|
|
esac
|
|
|
|
lxc --project "$project" init "$image" "$inst_name" --vm --storage "$project" "$@" || return 1
|
|
|
|
if [ ! -z "$mount_host" -a ! -z "$mount_guest" ]; then
|
|
echo "adding $mount_guest on $inst_name to refer to $mount_host on host as device '${project}root'"
|
|
if [ $EUID -ne 0 ]; then
|
|
# so that files created by root on the mount inside the
|
|
# guest have the permissions of the current host user and
|
|
# not root:root
|
|
# see: https://documentation.ubuntu.com/lxd/en/latest/userns-idmap/
|
|
local egid="$(id --group)"
|
|
local idmap="uid $EUID 0
|
|
gid $egid 0"
|
|
lxc --project "$project" config set "$inst_name" raw.idmap="$idmap"
|
|
fi
|
|
lxc --project "$project" config device add "$inst_name" "${project}root" disk source="$(realpath "$mount_host")" path="$mount_guest" || return 1
|
|
fi
|
|
}
|
|
|
|
lx_launch_vm_and_wait() {
|
|
local project="$1"
|
|
local inst="$2"
|
|
local base_image="$3"
|
|
local mount_project_root_to="$4"
|
|
shift; shift; shift; shift;
|
|
|
|
# Delete existing instance, if it exists
|
|
lx_delete "$project" "$inst" interactive || return 1
|
|
|
|
# Create the instance (started)
|
|
lx_launch_vm "$project" "$inst" "$base_image" "$(lx_project_root_dir)" "$mount_project_root_to" "$@" || return 1
|
|
|
|
lx_wait_for_boot "$project" "$inst" || return 1
|
|
}
|
|
|
|
|
|
lx_output_inst_list() {
|
|
# Pre-defined column shorthand chars:
|
|
# 4 - IPv4 address
|
|
# 6 - IPv6 address
|
|
# a - Architecture
|
|
# b - Storage pool
|
|
# c - Creation date
|
|
# d - Description
|
|
# D - disk usage
|
|
# e - Project name
|
|
# l - Last used date
|
|
# m - Memory usage
|
|
# M - Memory usage (%)
|
|
# n - Name
|
|
# N - Number of Processes
|
|
# p - PID of the instance's init process
|
|
# P - Profiles
|
|
# s - State
|
|
# S - Number of snapshots
|
|
# t - Type (persistent or ephemeral)
|
|
# u - CPU usage (in seconds)
|
|
# L - Location of the instance (e.g. its cluster member)
|
|
# f - Base Image Fingerprint (short)
|
|
# F - Base Image Fingerprint (long)
|
|
local project="$1"
|
|
local columns="${2:-ns46tSL}"
|
|
local format="${3:-table}" # csv|json|table|yaml|compact
|
|
lxc --project "$project" list -c "$columns" -f "$format"
|
|
}
|
|
|
|
lx_output_image_list() {
|
|
# Column shorthand chars:
|
|
# l - Shortest image alias (and optionally number of other aliases)
|
|
# L - Newline-separated list of all image aliases
|
|
# f - Fingerprint (short)
|
|
# F - Fingerprint (long)
|
|
# p - Whether image is public
|
|
# d - Description
|
|
# a - Architecture
|
|
# s - Size
|
|
# u - Upload date
|
|
# t - Type
|
|
local project="$1"
|
|
local columns="${2:-lfpdatsu}"
|
|
local format="${3:-table}" # csv|json|table|yaml|compact
|
|
lxc --project "$project" image list -c "$columns" -f "$format"
|
|
}
|
|
|
|
lx_wait_for_boot() {
|
|
local project="$1"
|
|
local inst="$2"
|
|
|
|
echo -n "Wait for boot "
|
|
while ! lxc --project "$project" exec "$inst" -- ls >/dev/null 2>&1; do
|
|
echo -n "."
|
|
sleep 1
|
|
done
|
|
echo ""
|
|
echo -n "Wait for cloud-init "
|
|
lxc --project "$project" exec "$inst" -- cloud-init status --wait
|
|
local rc=$?
|
|
|
|
if [ $rc -eq 0 ]; then
|
|
echo "Wait for ip address "
|
|
local ip=""
|
|
local count=0
|
|
while [ $count -lt 10 ]; do
|
|
let count+=1
|
|
ip="$(lxc --project "$project" exec "$inst" -- hostname -I | awk '{print $1}')"
|
|
rc=$?
|
|
echo " [${count}] got: $ip"
|
|
if [ $rc -ne 0 -o "$ip" != "" ];then
|
|
break
|
|
fi
|
|
sleep 5
|
|
done
|
|
fi
|
|
echo ""
|
|
return $rc
|
|
}
|
|
|
|
lx_get_ssh_identity() {
|
|
local keydir="tests/assets/vm_keys"
|
|
if [ "$1" != "relative" ]; then
|
|
keydir="$(lx_project_root_dir)/$keydir"
|
|
fi
|
|
echo "$keydir/id_ed25519"
|
|
}
|
|
|
|
lx_get_ssh_known_hosts() {
|
|
local id="$(lx_get_ssh_identity)"
|
|
local known_hosts="$(dirname "$id")/known_hosts"
|
|
echo "$known_hosts"
|
|
}
|
|
|
|
lx_remove_known_host() {
|
|
local hostname="$1"
|
|
local known_hosts="$(lx_get_ssh_known_hosts)"
|
|
ssh-keygen -f "$known_hosts" -R "$hostname"
|
|
}
|
|
|
|
lx_create_ssh_identity() {
|
|
local id="$(lx_get_ssh_identity)"
|
|
if [ ! -e "$id" ]; then
|
|
mkdir -p "$(dirname "$id")"
|
|
ssh-keygen -f "$id" -C "vm key" -N "" -t ed25519
|
|
fi
|
|
}
|