1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 19:26:48 +00:00
webvirtcloud/dev/libvirt-bootstrap.sh
catborise 2dab23cd9e fix(gstfsd): only the panel, with the host's key, can change a VM's disk
gstfsd, the root service on each compute that rewrites a shut-off VM's
/etc/shadow and authorized_keys, did what any client on its port asked.
Now it needs GSTFSD_KEY (64 hexadecimal characters, in the unit's
/etc/default/webvirt-gstfsd) and does not start without it. Each
connection gets a new challenge; the panel signs its request for it
with HMAC-SHA256 and gstfsd checks the signature before any change, so
a request recorded on one connection is refused on another. gstfsd
signs its reply for the same challenge and the panel's nonce, and the
panel accepts only that reply.

Each compute has a gstfsd key, the host's GSTFSD_KEY: the compute forms
and the API take it and never show it, and an empty value on an edit
keeps it. The bootstrap script makes the key file once, readable by
root only; the README shows how to make it and where the panel takes
it. The traffic is still not encrypted: a remote panel's port stays
open to the panel's address only.
2026-10-31 01:53:43 +03:00

827 lines
32 KiB
Bash

#!/bin/sh -
#===============================================================================
# vim: softtabstop=4 shiftwidth=4 expandtab fenc=utf-8 spell spelllang=en cc=81
#===============================================================================
#
# FILE: libvirt-bootstrap.sh
#
# DESCRIPTION: Bootstrap webvirtcloud installation for various distributions
#
# BUGS: https://github.com/retspen/webvirtcloud/issues
#
# COPYRIGHT: (c) 2015 by the WebVirtCloud Team
#
# LICENSE: Apache 2.0
# ORGANIZATION: WebVirtCloud (webvirtcloud.net)
# CREATED: 11/11/2013 11:00:00 EET
#===============================================================================
#--- FUNCTION ----------------------------------------------------------------
# NAME: echoerr
# DESCRIPTION: Echo errors to stderr.
#-------------------------------------------------------------------------------
echoerror() {
printf "${RC} * ERROR${EC}: %s\n" "$@" 1>&2;
}
#--- FUNCTION ----------------------------------------------------------------
# NAME: echoinfo
# DESCRIPTION: Echo information to stdout.
#-------------------------------------------------------------------------------
echoinfo() {
printf "${GC} * INFO${EC}: %s\n" "$@";
}
#--- FUNCTION ----------------------------------------------------------------
# NAME: echowarn
# DESCRIPTION: Echo warning informations to stdout.
#-------------------------------------------------------------------------------
echowarn() {
printf "${YC} * WARN${EC}: %s\n" "$@";
}
#--- FUNCTION ----------------------------------------------------------------
# NAME: echodebug
# DESCRIPTION: Echo debug information to stdout.
#-------------------------------------------------------------------------------
echodebug() {
if [ "${_ECHO_DEBUG:-0}" = 1 ]; then
printf "${BC} * DEBUG${EC}: %s\n" "$@";
fi
}
#--- FUNCTION ----------------------------------------------------------------
# NAME: __test_distro_arch
# DESCRIPTION: Echo errors to stderr.
#-------------------------------------------------------------------------------
__test_distro_arch() {
ARCH=$(uname -m | sed 's/x86_//;s/i[3-6]86/32/')
if [ "$ARCH" = 32 ]; then
echoerror "32-bit Arch kernel does not support"
exit 1
fi
}
__test_distro_arch
#--- FUNCTION ----------------------------------------------------------------
# NAME: __strip_duplicates
# DESCRIPTION: Strip duplicate strings
#-------------------------------------------------------------------------------
__strip_duplicates() {
echo "$@" | tr -s '[:space:]' '\n' | awk '!x[$0]++'
}
#--- FUNCTION ----------------------------------------------------------------
# NAME: __function_defined
# DESCRIPTION: Checks if a function is defined within this scripts scope
# PARAMETERS: function name
# RETURNS: 0 or 1 as in defined or not defined
#-------------------------------------------------------------------------------
__function_defined() {
FUNC_NAME=$1
if [ "$(command -v "$FUNC_NAME")x" != "x" ]; then
echoinfo "Found function $FUNC_NAME"
return 0
fi
echodebug "$FUNC_NAME not found...."
return 1
}
#--- FUNCTION ----------------------------------------------------------------
# NAME: __parse_version_string
# DESCRIPTION: Parse version strings ignoring the revision.
# MAJOR.MINOR.REVISION becomes MAJOR.MINOR
#-------------------------------------------------------------------------------
__parse_version_string() {
VERSION_STRING="$1"
PARSED_VERSION=$(
echo "$VERSION_STRING" |
sed -e 's/^/#/' \
-e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\)\(\.[0-9][0-9]*\).*$/\1/' \
-e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\).*$/\1/' \
-e 's/^#[^0-9]*\([0-9][0-9]*\).*$/\1/' \
-e 's/^#.*$//'
)
echo "$PARSED_VERSION"
}
#--- FUNCTION ----------------------------------------------------------------
# NAME: __sort_release_files
# DESCRIPTION: Custom sort function. Alphabetical or numerical sort is not
# enough.
#-------------------------------------------------------------------------------
__sort_release_files() {
KNOWN_RELEASE_FILES=$(echo "(arch|centos|almalinux|rocky|debian|ubuntu|fedora|redhat|suse|\
mandrake|mandriva|gentoo|slackware|turbolinux|unitedlinux|lsb|system|\
os)(-|_)(release|version)" | sed -r 's:[[:space:]]::g')
primary_release_files=""
secondary_release_files=""
# Sort know VS un-known files first
for release_file in $(echo "$@" | sed -r 's:[[:space:]]:\n:g' | sort --unique --ignore-case); do
match=$(echo "$release_file" | grep -E -i "${KNOWN_RELEASE_FILES}")
if [ "x${match}" != "x" ]; then
primary_release_files="${primary_release_files} ${release_file}"
else
secondary_release_files="${secondary_release_files} ${release_file}"
fi
done
# Now let's sort by know files importance, max important goes last in the max_prio list
max_prio="redhat-release centos-release"
for entry in $max_prio; do
if [ "x$(echo "${primary_release_files}" | grep "$entry")" != "x" ]; then
primary_release_files=$(echo "${primary_release_files}" | sed -e "s:\(.*\)\($entry\)\(.*\):\2 \1 \3:g")
fi
done
# Now, least important goes last in the min_prio list
min_prio="lsb-release"
for entry in $min_prio; do
if [ "x$(echo "${primary_release_files}" | grep "$entry")" != "x" ]; then
primary_release_files=$(echo "${primary_release_files}" | sed -e "s:\(.*\)\($entry\)\(.*\):\1 \3 \2:g")
fi
done
# Echo the results collapsing multiple white-space into a single white-space
echo "${primary_release_files} ${secondary_release_files}" | sed -r 's:[[:space:]]:\n:g'
}
#--- FUNCTION ----------------------------------------------------------------
# NAME: __gather_linux_system_info
# DESCRIPTION: Discover Linux system information
#-------------------------------------------------------------------------------
__gather_linux_system_info() {
DISTRO_NAME=""
DISTRO_VERSION=""
# Let's test if the lsb_release binary is available
if lsb_release >/dev/null 2>&1; then
DISTRO_NAME=$(lsb_release -si)
if [ "x$(echo "$DISTRO_NAME" | grep RedHat)" != "x" ]; then
# Let's convert CamelCase to Camel Case
DISTRO_NAME=$(__camelcase_split "$DISTRO_NAME")
fi
if [ "${DISTRO_NAME}" = "openSUSE project" ] || [ "${DISTRO_NAME}" = "openSUSE" ] || [ "${DISTRO_NAME}" = "opensuse" ]; then
# lsb_release -si returns "openSUSE project" on openSUSE 12.3
DISTRO_NAME="opensuse"
fi
if [ "${DISTRO_NAME}" = "SUSE LINUX" ] || [ "${DISTRO_NAME}" = "SLES" ] || [ "${DISTRO_NAME}" = "sles" ]; then
# lsb_release -si returns "SUSE LINUX" on SLES 11 SP3
DISTRO_NAME="suse"
fi
rv=$(lsb_release -sr)
[ "${rv}x" != "x" ] && DISTRO_VERSION=$(__parse_version_string "$rv")
elif [ -f /etc/lsb-release ]; then
# We don't have the lsb_release binary, though, we do have the file it parses
DISTRO_NAME=$(grep DISTRIB_ID /etc/lsb-release | sed -e 's/.*=//')
rv=$(grep DISTRIB_RELEASE /etc/lsb-release | sed -e 's/.*=//')
[ "${rv}x" != "x" ] && DISTRO_VERSION=$(__parse_version_string "$rv")
fi
if [ "x$DISTRO_NAME" != "x" ] && [ "x$DISTRO_VERSION" != "x" ]; then
# We already have the distribution name and version
return
fi
for rsource in $(__sort_release_files "$(
cd /etc && find ./*[_-]release ./*[_-]version -printf "%f\n" 2>/dev/null | env -i sort | \
sed -e '/^redhat-release$/d' -e '/^lsb-release$/d'; \
echo redhat-release lsb-release
)"); do
# Don't follow symlinks, except os-release (a link to /usr/lib/os-release, openSUSE's only release file)
[ -L "/etc/${rsource}" ] && [ "${rsource}" != "os-release" ] && continue
[ ! -f "/etc/${rsource}" ] && continue # Does not exist
n=$(echo "${rsource}" | sed -e 's/[_-]release$//' -e 's/[_-]version$//')
rv=$( (grep VERSION /etc/"${rsource}"; cat /etc/"${rsource}") | grep '[0-9]' | sed -e 'q' )
[ "${rv}x" = "x" ] && continue # There's no version information. Continue to next rsource
v=$(__parse_version_string "$rv")
case $(echo "${n}" | tr '[:upper:]' '[:lower:]') in
redhat )
if [ ".$(grep -E 'CentOS' /etc/"${rsource}")" != . ]; then
n="CentOS"
elif [ ".$(grep -E 'Red Hat Enterprise Linux' /etc/"${rsource}")" != . ]; then
n="<R>ed <H>at <E>nterprise <L>inux"
else
n="<R>ed <H>at <L>inux"
fi
;;
arch ) n="Arch Linux" ;;
centos ) n="CentOS" ;;
almalinux ) n="AlmaLinux" ;;
debian ) n="Debian" ;;
ubuntu ) n="Ubuntu" ;;
fedora ) n="Fedora" ;;
suse ) n="SUSE" ;;
system )
while read -r line; do
[ "${n}x" != "systemx" ] && break
case "$line" in
*Amazon*Linux*AMI*)
n="Amazon Linux AMI"
break
esac
done < /etc/"${rsource}"
;;
os )
nn=$(grep '^ID=' /etc/os-release | sed -e 's/^ID=\(.*\)$/\1/g' | tr -d "\"'")
rv=$(grep '^VERSION_ID=' /etc/os-release | sed -e 's/^VERSION_ID=\(.*\)$/\1/g' | tr -d "\"'")
[ "${rv}x" != "x" ] && v=$(__parse_version_string "$rv") || v=""
case $(echo "${nn}" | tr '[:upper:]' '[:lower:]') in
arch )
n="Arch Linux"
v="" # Arch Linux does not provide a version.
;;
debian )
n="Debian"
if [ "${v}x" = "x" ]; then
if [ "$(cat /etc/debian_version)" = "wheezy/sid" ]; then
# I've found an EC2 wheezy image which did not tell its version
v=$(__parse_version_string "7.0")
fi
else
echowarn "Unable to parse the Debian Version"
fi
;;
opensuse* )
n="opensuse"
;;
sles*|sled*|suse* )
n="suse"
;;
* )
n=${nn}
;;
esac
;;
* ) ;;
esac
DISTRO_NAME=$n
DISTRO_VERSION=$v
break
done
}
__gather_linux_system_info
# Simplify distro name naming on functions
DISTRO_NAME_L=$(echo "$DISTRO_NAME" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-zA-Z0-9_ ]//g' | sed -re 's/([[:space:]])+/_/g')
# Rocky Linux and AlmaLinux use the CentOS install functions
case "${DISTRO_NAME_L}" in
rocky|almalinux) DISTRO_NAME_L="centos" ;;
esac
DISTRO_MAJOR_VERSION="$(echo "$DISTRO_VERSION" | sed 's/^\([0-9]*\).*/\1/g')"
DISTRO_MINOR_VERSION="$(echo "$DISTRO_VERSION" | sed 's/^\([0-9]*\).\([0-9]*\).*/\2/g')"
PREFIXED_DISTRO_MAJOR_VERSION="_${DISTRO_MAJOR_VERSION}"
if [ "${PREFIXED_DISTRO_MAJOR_VERSION}" = "_" ]; then
PREFIXED_DISTRO_MAJOR_VERSION=""
fi
PREFIXED_DISTRO_MINOR_VERSION="_${DISTRO_MINOR_VERSION}"
if [ "${PREFIXED_DISTRO_MINOR_VERSION}" = "_" ]; then
PREFIXED_DISTRO_MINOR_VERSION=""
fi
#--- FUNCTION ----------------------------------------------------------------
# NAME: __check_end_of_life_versions
# DESCRIPTION: Check for end of life distribution versions
#-------------------------------------------------------------------------------
__check_end_of_life_versions() {
case "${DISTRO_NAME_L}" in
debian)
# Debian versions bellow 6 are not supported
if [ "$DISTRO_MAJOR_VERSION" -lt 6 ]; then
echoerror "End of life distributions are not supported."
echoerror "Please consider upgrading to the next stable. See:"
echoerror " https://wiki.debian.org/DebianReleases"
exit 1
fi
;;
ubuntu)
# Ubuntu versions not supported
#
# < 10
# = 10.10
# = 11.04
# = 11.10
if { [ "$DISTRO_MAJOR_VERSION" -eq 10 ] && [ "$DISTRO_MINOR_VERSION" -eq 10 ]; } || \
{ [ "$DISTRO_MAJOR_VERSION" -eq 11 ] && [ "$DISTRO_MINOR_VERSION" -eq 04 ]; } || \
{ [ "$DISTRO_MAJOR_VERSION" -eq 11 ] && [ "$DISTRO_MINOR_VERSION" -eq 10 ]; } || \
[ "$DISTRO_MAJOR_VERSION" -lt 10 ]; then
echoerror "End of life distributions are not supported."
echoerror "Please consider upgrading to the next stable. See:"
echoerror " https://wiki.ubuntu.com/Releases"
exit 1
fi
;;
opensuse)
# openSUSE: allow Leap 15.x and Tumbleweed
if [ -n "$DISTRO_MAJOR_VERSION" ] && [ "$DISTRO_MAJOR_VERSION" -lt 12 ]; then
echoerror "End of life distributions are not supported."
echoerror "Please consider upgrading to the next stable. See:"
echoerror " http://en.opensuse.org/Lifetime"
exit 1
fi
;;
suse)
# SLES / SLED
if [ -f /etc/SuSE-release ]; then
SUSE_PATCHLEVEL=$(awk '/PATCHLEVEL/ {print $3}' /etc/SuSE-release )
if [ "x${SUSE_PATCHLEVEL}" = "x" ]; then
SUSE_PATCHLEVEL="00"
fi
if { [ "$DISTRO_MAJOR_VERSION" -eq 11 ] && [ "$SUSE_PATCHLEVEL" -lt 02 ]; } || [ "$DISTRO_MAJOR_VERSION" -lt 11 ]; then
echoerror "Versions lower than SuSE 11 SP2 are not supported."
echoerror "Please consider upgrading to the next stable"
exit 1
fi
elif [ -n "$DISTRO_MAJOR_VERSION" ] && [ "$DISTRO_MAJOR_VERSION" -lt 12 ]; then
echoerror "Versions lower than SUSE 12 are not supported."
exit 1
fi
;;
fedora)
# Fedora lower than 18 are no longer supported
if [ "$DISTRO_MAJOR_VERSION" -lt 18 ]; then
echoerror "End of life distributions are not supported."
echoerror "Please consider upgrading to the next stable. See:"
echoerror " https://fedoraproject.org/wiki/Releases"
exit 1
fi
;;
centos)
# CentOS versions lower than 6 are no longer supported
if { [ "$DISTRO_MAJOR_VERSION" -eq 6 ] && [ "$DISTRO_MINOR_VERSION" -lt 3 ]; } || [ "$DISTRO_MAJOR_VERSION" -lt 5 ]; then
echoerror "End of life distributions are not supported."
echoerror "Please consider upgrading to the next stable. See:"
echoerror " http://wiki.centos.org/Download"
exit 1
fi
;;
red_hat*linux)
# Red Hat (Enterprise) Linux versions lower than 5 are no longer supported
if { [ "$DISTRO_MAJOR_VERSION" -eq 6 ] && [ "$DISTRO_MINOR_VERSION" -lt 3 ]; } || [ "$DISTRO_MAJOR_VERSION" -lt 5 ]; then
echoerror "End of life distributions are not supported."
echoerror "Please consider upgrading to the next stable. See:"
echoerror " https://access.redhat.com/support/policy/updates/errata/"
exit 1
fi
;;
*)
;;
esac
}
# Fail soon for end of life versions
__check_end_of_life_versions
##############################################################################
#
# CentOS Install Functions
#
# gstfsd and its systemd unit, enabled and (re)started: from the clone this
# script runs in, else from GitHub. Its key is made once and kept: the
# panel's copy of it (the host's gstfsd key) stays valid.
install_gstfsd() {
if [ ! -s /etc/default/webvirt-gstfsd ]; then
key="$(python3 -c 'import secrets; print(secrets.token_hex(32))')" || return 1
(umask 077 && printf 'GSTFSD_KEY=%s\n' "$key" > /etc/default/webvirt-gstfsd) || return 1
fi
# only root reads it, also when it was there already
chown root:root /etc/default/webvirt-gstfsd && chmod 600 /etc/default/webvirt-gstfsd || return 1
src="$(dirname "$0")/.."
if [ -f "$src/conf/daemon/gstfsd" ]; then
install -m 755 "$src/conf/daemon/gstfsd" /usr/local/bin/gstfsd &&
install -m 644 "$src/conf/systemd/webvirt-gstfsd.service" /etc/systemd/system/ || return 1
else
curl -fsSL https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/daemon/gstfsd -o /usr/local/bin/gstfsd &&
chmod +x /usr/local/bin/gstfsd &&
curl -fsSL https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/systemd/webvirt-gstfsd.service -o /etc/systemd/system/webvirt-gstfsd.service || return 1
fi
systemctl daemon-reload && systemctl enable webvirt-gstfsd && systemctl restart webvirt-gstfsd || return 1
}
# libvirtd started by systemd sockets ignores libvirtd_opts="-l"; TCP needs its socket
enable_libvirt_tcp() {
systemctl cat libvirtd-tcp.socket > /dev/null 2>&1 || return 0
systemctl stop libvirtd.service && systemctl enable --now libvirtd-tcp.socket && systemctl start libvirtd.service || return 1
}
install_centos() {
yum -y install epel-release || return 1
if [ "$DISTRO_MAJOR_VERSION" -lt 8 ]; then
yum -y install qemu-kvm libvirt bridge-utils python-libguestfs libguestfs-tools cyrus-sasl-md5 || return 1
else
yum -y install qemu-kvm libvirt python3-libguestfs libguestfs-tools cyrus-sasl-md5 || return 1
fi
return 0
}
install_centos_post() {
if [ "$DISTRO_MAJOR_VERSION" -lt 8 ]; then
if [ -f /etc/sysconfig/libvirtd ]; then
sed -i 's/#LIBVIRTD_ARGS/LIBVIRTD_ARGS/g' /etc/sysconfig/libvirtd
else
echoerror "/etc/sysconfig/libvirtd not found. Exiting..."
exit 1
fi
if [ -f /etc/libvirt/libvirtd.conf ]; then
sed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/libvirtd.conf
sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/libvirtd.conf
sed -i 's/#auth_tcp/auth_tcp/g' /etc/libvirt/libvirtd.conf
else
echoerror "/etc/libvirt/libvirtd.conf not found. Exiting..."
exit 1
fi
fi
if [ -f /etc/libvirt/qemu.conf ]; then
sed -i 's/#[ ]*vnc_listen.*/vnc_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf
else
echoerror "/etc/libvirt/qemu.conf not found. Exiting..."
exit 1
fi
if [ -f /etc/sasl2/libvirt.conf ]; then
sed -i 's/: gssapi/: digest-md5/g' /etc/sasl2/libvirt.conf
sed -i 's/#sasldb_path/sasldb_path/g' /etc/sasl2/libvirt.conf
else
echoerror "/etc/sasl2/libvirt.conf not found. Exiting..."
exit 1
fi
install_gstfsd || return 1
return 0
}
daemons_running_centos() {
if [ -f /etc/init.d/libvirtd ]; then
service libvirtd stop > /dev/null 2>&1
service libvirtd start
fi
if [ -f /etc/init.d/libvirt-guests ]; then
service libvirt-guests stop > /dev/null 2>&1
service libvirt-guests start
fi
if [ "$DISTRO_MAJOR_VERSION" -lt 8 ]; then
if [ -f /usr/lib/systemd/system/libvirtd.service ]; then
systemctl stop libvirtd.service > /dev/null 2>&1
systemctl start libvirtd.service
fi
elif [ "$DISTRO_MAJOR_VERSION" -ge 10 ]; then
# EL10 runs the modular daemons, one per driver; virtproxyd serves remote TCP (SASL).
for drv in qemu interface network nodedev nwfilter secret storage proxy; do
systemctl enable --now virt${drv}d.socket || return 1
done
systemctl enable --now virtproxyd-tcp.socket || return 1
# EL10's policy lets virtproxyd read but not map the SASL database, so TCP logins fail
if selinuxenabled 2>/dev/null; then
echo '(allow virtproxyd_t virt_etc_t (file (map)))' > /tmp/wvc-virtproxyd-sasl.cil &&
semodule -i /tmp/wvc-virtproxyd-sasl.cil || return 1
fi
else
if [ -f /usr/lib/systemd/system/libvirtd-tcp.socket ]; then
systemctl stop libvirtd-tcp.socket > /dev/null 2>&1
systemctl start libvirtd-tcp.socket
fi
fi
if [ -f /usr/lib/systemd/system/libvirt-guests.service ]; then
systemctl stop libvirt-guests.service > /dev/null 2>&1
systemctl start libvirt-guests.service
fi
return 0
}
#
# Ended CentOS Install Functions
#
##############################################################################
##############################################################################
#
# Fedora Install Functions
#
install_fedora() {
yum -y install kvm libvirt bridge-utils python3-libguestfs || return 1
return 0
}
install_fedora_post() {
if [ -f /etc/sysconfig/libvirtd ]; then
sed -i 's/#LIBVIRTD_ARGS/LIBVIRTD_ARGS/g' /etc/sysconfig/libvirtd
else
echoerror "/etc/sysconfig/libvirtd not found. Exiting..."
exit 1
fi
if [ -f /etc/libvirt/libvirtd.conf ]; then
sed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/libvirtd.conf
sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/libvirtd.conf
sed -i 's/#auth_tcp/auth_tcp/g' /etc/libvirt/libvirtd.conf
else
echoerror "/etc/libvirt/libvirtd.conf not found. Exiting..."
exit 1
fi
if [ -f /etc/libvirt/qemu.conf ]; then
sed -i 's/#[ ]*vnc_listen.*/vnc_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf
else
echoerror "/etc/libvirt/qemu.conf not found. Exiting..."
exit 1
fi
install_gstfsd || return 1
return 0
}
daemons_running_fedora() {
if [ -f /usr/lib/systemd/system/libvirtd.service ]; then
systemctl stop libvirtd.service > /dev/null 2>&1
systemctl start libvirtd.service
fi
if [ -f /usr/lib/systemd/system/libvirt-guests.service ]; then
systemctl stop libvirt-guests.service > /dev/null 2>&1
systemctl start libvirt-guests.service
fi
return 0
}
#
# Ended Fedora Install Functions
#
##############################################################################
##############################################################################
#
# Opensuse Install Functions
#
install_opensuse() {
zypper -n install -l qemu-kvm libvirt libvirt-daemon-qemu libvirt-client bridge-utils python3-libguestfs || \
zypper -n install -l kvm libvirt bridge-utils python3-libguestfs || return 1
return 0
}
install_opensuse_post() {
if [ -f /etc/sysconfig/libvirtd ]; then
sed -i 's/#LIBVIRTD_ARGS/LIBVIRTD_ARGS/g' /etc/sysconfig/libvirtd
fi
if [ -f /etc/libvirt/libvirtd.conf ]; then
sed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/libvirtd.conf
sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/libvirtd.conf
sed -i 's/#auth_tcp/auth_tcp/g' /etc/libvirt/libvirtd.conf
sed -i 's/#unix_sock_group = "libvirt"/unix_sock_group = "libvirt"/g' /etc/libvirt/libvirtd.conf
sed -i 's/#unix_sock_rw_perms = "0770"/unix_sock_rw_perms = "0770"/g' /etc/libvirt/libvirtd.conf
sed -i 's/#auth_unix_rw = "polkit"/auth_unix_rw = "none"/g' /etc/libvirt/libvirtd.conf
fi
if [ -f /etc/libvirt/virtqemud.conf ]; then
sed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/virtqemud.conf
sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/virtqemud.conf
sed -i 's/#auth_tcp/auth_tcp/g' /etc/libvirt/virtqemud.conf
sed -i 's/#unix_sock_group = "libvirt"/unix_sock_group = "libvirt"/g' /etc/libvirt/virtqemud.conf
sed -i 's/#unix_sock_rw_perms = "0770"/unix_sock_rw_perms = "0770"/g' /etc/libvirt/virtqemud.conf
sed -i 's/#auth_unix_rw = "polkit"/auth_unix_rw = "none"/g' /etc/libvirt/virtqemud.conf
fi
if [ -f /etc/libvirt/qemu.conf ]; then
sed -i 's/#[ ]*vnc_listen.*/vnc_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf
fi
install_gstfsd || return 1
return 0
}
daemons_running_opensuse() {
systemctl enable --now libvirtd.service 2>/dev/null || systemctl enable --now virtqemud.service 2>/dev/null || true
systemctl enable --now libvirt-guests.service 2>/dev/null || true
return 0
}
install_suse() {
install_opensuse "$@"
}
install_suse_post() {
install_opensuse_post "$@"
}
daemons_running_suse() {
daemons_running_opensuse "$@"
}
#
# Ended openSUSE Install Functions
#
##############################################################################
##############################################################################
#
# Ubuntu Install Functions
#
install_ubuntu() {
apt-get update || return 1
if [ "$DISTRO_MAJOR_VERSION" -lt 18 ]; then
apt-get -y install kvm libvirt-bin bridge-utils sasl2-bin python-guestfs || return 1
else
apt install -y qemu-kvm libvirt-clients libvirt-daemon-system bridge-utils virt-manager sasl2-bin python3-guestfs || return 1
fi
return 0
}
install_ubuntu_post() {
if [ -f /etc/default/libvirt-bin ]; then
sed -i 's/libvirtd_opts="-d"/libvirtd_opts="-d -l"/g' /etc/default/libvirt-bin
elif [ -f /etc/default/libvirtd ]; then
sed -i 's/libvirtd_opts="-d"/libvirtd_opts="-d -l"/g' /etc/default/libvirtd
else
echoerror "/etc/default/libvirt-bin or /etc/default/libvirtd not found. Exiting..."
exit 1
fi
if [ -f /etc/libvirt/libvirtd.conf ]; then
sed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/libvirtd.conf
sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/libvirtd.conf
sed -i 's/#auth_tcp/auth_tcp/g' /etc/libvirt/libvirtd.conf
sed -i 's/#auth_unix_rw = "polkit"/auth_unix_rw = "none"/g' /etc/libvirt/libvirtd.conf
else
echoerror "/etc/libvirt/libvirtd.conf not found. Exiting..."
exit 1
fi
if [ -f /etc/libvirt/qemu.conf ]; then
sed -i 's/#[ ]*vnc_listen.*/vnc_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf
else
echoerror "/etc/libvirt/qemu.conf not found. Exiting..."
exit 1
fi
if [ -f /etc/sasl2/libvirt.conf ]; then
sed -i 's/: gssapi/: digest-md5/g' /etc/sasl2/libvirt.conf
sed -i 's/#sasldb_path/sasldb_path/g' /etc/sasl2/libvirt.conf
fi
install_gstfsd || return 1
return 0
}
daemons_running_ubuntu() {
if [ -f /etc/init.d/libvirt-bin ]; then
# Still in SysV init!?
service libvirt-bin stop > /dev/null 2>&1
service libvirt-bin start
fi
enable_libvirt_tcp || return 1
return 0
}
#
# Ended Ubuntu Install Functions
#
##############################################################################
##############################################################################
#
# Debian Install Functions
#
install_debian() {
apt-get update || return 1
if [ "$DISTRO_MAJOR_VERSION" -lt 10 ]; then
apt-get -y install qemu-kvm libvirt-bin bridge-utils sasl2-bin python-guestfs || return 1
elif [ "$DISTRO_MAJOR_VERSION" -lt 12 ]; then
apt-get -y install qemu qemu-kvm qemu-system qemu-utils libvirt-clients libvirt-daemon-system sasl2-bin python3-guestfs virtinst || return 1
else
apt-get -y install qemu-system qemu-utils libvirt-clients libvirt-daemon-system sasl2-bin python3-guestfs virtinst || return 1
fi
return 0
}
install_debian_post() {
if [ "$DISTRO_MAJOR_VERSION" -ge 8 ]; then
LIBVIRTSVC=libvirtd
else
LIBVIRTSVC=libvirt-bin
fi
if [ -f /etc/default/$LIBVIRTSVC ]; then
if [ "$( grep -c '^libvirtd_opts *=' /etc/default/$LIBVIRTSVC )" -gt 0 ]; then
if [ "$( grep -c '^libvirtd_opts *=.*-l' /etc/default/$LIBVIRTSVC )" -eq 0 ]; then
sed -i 's/^libvirtd_opts="\([^"]*\)"/libvirtd_opts="\1 -l"/g' /etc/default/$LIBVIRTSVC
fi
else
sed -i 's/^#libvirtd_opts=.*$/libvirtd_opts="-l"/g' /etc/default/$LIBVIRTSVC
fi
else
echoerror "/etc/default/$LIBVIRTSVC not found. Exiting..."
exit 1
fi
if [ -f /etc/libvirt/libvirtd.conf ]; then
sed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/libvirtd.conf
sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/libvirtd.conf
sed -i 's/#auth_tcp/auth_tcp/g' /etc/libvirt/libvirtd.conf
sed -i 's/#auth_unix_rw = "polkit"/auth_unix_rw = "none"/g' /etc/libvirt/libvirtd.conf
else
echoerror "/etc/libvirt/libvirtd.conf not found. Exiting..."
exit 1
fi
if [ -f /etc/libvirt/qemu.conf ]; then
sed -i 's/#[ ]*vnc_listen.*/vnc_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf
else
echoerror "/etc/libvirt/qemu.conf not found. Exiting..."
exit 1
fi
if [ -f /etc/sasl2/libvirt.conf ]; then
sed -i 's/: gssapi/: digest-md5/g' /etc/sasl2/libvirt.conf
sed -i 's/#sasldb_path/sasldb_path/g' /etc/sasl2/libvirt.conf
else
echoerror "/etc/sasl2/libvirt.conf not found. Exiting..."
exit 1
fi
install_gstfsd || return 1
return 0
}
daemons_running_debian() {
if [ "$DISTRO_MAJOR_VERSION" -ge 8 ]; then
LIBVIRTSVC=libvirtd
else
LIBVIRTSVC=libvirt-bin
fi
if [ -f /etc/init.d/$LIBVIRTSVC ]; then
/etc/init.d/$LIBVIRTSVC stop > /dev/null 2>&1
/etc/init.d/$LIBVIRTSVC start
fi
enable_libvirt_tcp || return 1
return 0
}
#
# Ended Debian Install Functions
#
##############################################################################
#=============================================================================
# INSTALLATION
#=============================================================================
# Let's get the install function
INSTALL_FUNC_NAMES="install_${DISTRO_NAME_L}"
INSTALL_FUNC="null"
for FUNC_NAME in $(__strip_duplicates "$INSTALL_FUNC_NAMES"); do
if __function_defined "$FUNC_NAME"; then
INSTALL_FUNC=$FUNC_NAME
break
fi
done
echodebug "INSTALL_FUNC=${INSTALL_FUNC}"
if [ "$INSTALL_FUNC" = "null" ]; then
echoerror "No installation function found. Exiting..."
exit 1
else
echoinfo "Running ${INSTALL_FUNC}()"
if ! $INSTALL_FUNC; then
echoerror "Failed to run ${INSTALL_FUNC}()!!!"
exit 1
fi
fi
# Let's get the post install function
POST_FUNC_NAMES="install_${DISTRO_NAME_L}_post"
POST_INSTALL_FUNC="null"
for FUNC_NAME in $(__strip_duplicates "$POST_FUNC_NAMES"); do
if __function_defined "$FUNC_NAME"; then
POST_INSTALL_FUNC=$FUNC_NAME
break
fi
done
echodebug "POST_INSTALL_FUNC=${POST_INSTALL_FUNC}"
if [ "$POST_INSTALL_FUNC" = "null" ]; then
echoerror "No installation function found. Exiting..."
exit 1
else
echoinfo "Running ${POST_INSTALL_FUNC}()"
if ! $POST_INSTALL_FUNC; then
echoerror "Failed to run ${POST_INSTALL_FUNC}()!!!"
exit 1
fi
fi
# Let's get the daemons running check function.
DAEMONS_RUNNING_FUNC_NAMES="daemons_running_${DISTRO_NAME_L}"
DAEMONS_RUNNING_FUNC="null"
for FUNC_NAME in $(__strip_duplicates "$DAEMONS_RUNNING_FUNC_NAMES"); do
if __function_defined "$FUNC_NAME"; then
DAEMONS_RUNNING_FUNC=$FUNC_NAME
break
fi
done
echodebug "DAEMONS_RUNNING_FUNC=${DAEMONS_RUNNING_FUNC}"
if [ "$DAEMONS_RUNNING_FUNC" = "null" ]; then
echoerror "No installation function found. Exiting..."
exit 1
else
echoinfo "Running ${DAEMONS_RUNNING_FUNC}()"
if ! $DAEMONS_RUNNING_FUNC; then
echoerror "Failed to run ${DAEMONS_RUNNING_FUNC}()!!!"
exit 1
fi
fi
exit 0