383 lines
6.7 KiB
Bash
383 lines
6.7 KiB
Bash
|
#!/bin/sh
|
||
|
# Basic Percona XtraDB Cluster Server installation script
|
||
|
# Intended to be run on openSUSE Leap, but is easily adaptable by changing the package manager call in check_dependencies.
|
||
|
#
|
||
|
# Georg Pfuetzenreuter <georg@lysergic.dev>
|
||
|
# Created and last modified: 30/04/2022
|
||
|
|
||
|
SCRIPT="PXC_Boostrap"
|
||
|
VENDOR="Percona"
|
||
|
VERSION="8.0.27"
|
||
|
PRODUCT="$VENDOR-XtraDB-Cluster_$VERSION-18.1_Linux.x86_64.glibc2.17-minimal"
|
||
|
TARBALL="$PRODUCT.tar.gz"
|
||
|
URL="https://downloads.percona.com/downloads/Percona-XtraDB-Cluster-LATEST/Percona-XtraDB-Cluster-8.0.27/binary/tarball/$TARBALL"
|
||
|
TARGETPREFIX="/opt"
|
||
|
TARGETDIR="$TARGETPREFIX/$VENDOR"
|
||
|
TMPDIR="/tmp"
|
||
|
SHORTY="mysql"
|
||
|
DATADIR="/var/lib/$SHORTY"
|
||
|
HOMEDIR="/var/lib/${SHORTY}_home"
|
||
|
RUNDATE="`date +%m%d%Y-%H%M%S`"
|
||
|
servicefile="/etc/systemd/system/${SHORTY}d.service"
|
||
|
configfile="/etc/opt/my.cnf"
|
||
|
checkfile="/var/adm/pxc.installed"
|
||
|
ARGS="$@"
|
||
|
|
||
|
check_args () {
|
||
|
if [ "$ARGS" = "--debug" ]
|
||
|
then
|
||
|
RUNMODE="debug"
|
||
|
# we do not use this here
|
||
|
echo "Not implemented."
|
||
|
exit 1
|
||
|
fi
|
||
|
if [ ! "$ARGS" = "--debug" ]
|
||
|
then
|
||
|
RUNMODE="normal"
|
||
|
fi
|
||
|
if [ "$ARGS" = "--uninstall" ]
|
||
|
then
|
||
|
RUNMODE="uninstall"
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
check_dependencies () {
|
||
|
if ! command -v ex &>/dev/null
|
||
|
then
|
||
|
if zypper --non-interactive install vim-small
|
||
|
then
|
||
|
log "Satisfied dependencies."
|
||
|
else
|
||
|
log "Could not satisfy dependency \"ex\"."
|
||
|
return 1
|
||
|
fi
|
||
|
fi
|
||
|
if ! command -v systemctl &>/dev/null
|
||
|
then
|
||
|
log "Unsure whether this actually is a systemd based system."
|
||
|
return 1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
init () {
|
||
|
local step="Preparation"
|
||
|
|
||
|
if [ ! "`id -u`" = "0" ]
|
||
|
then
|
||
|
log "Script needs root privileges."
|
||
|
exit 1
|
||
|
fi
|
||
|
log "Initializing $SCRIPT for $PRODUCT"
|
||
|
check_args
|
||
|
if [ "$RUNMODE" = "normal" ]
|
||
|
then
|
||
|
if [ -f "$checkfile" ]
|
||
|
then
|
||
|
log "Existing installation found. Consider --uninstall first."
|
||
|
exit 1
|
||
|
fi
|
||
|
check_dependencies
|
||
|
check "$?" "dependencies"
|
||
|
cd $TMPDIR
|
||
|
download
|
||
|
setup
|
||
|
touch "$checkfile"
|
||
|
fi
|
||
|
if [ "$RUNMODE" = "uninstall" ]
|
||
|
then
|
||
|
uninstall
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
|
||
|
log () {
|
||
|
local printmsg="$1"
|
||
|
local prefix="[$SCRIPT]"
|
||
|
local logmsg="$prefix $printmsg"
|
||
|
local logfile="$TMPDIR/$SCRIPT_$RUNDATE.log"
|
||
|
|
||
|
echo "$printmsg"
|
||
|
echo "$logmsg" >> $logfile
|
||
|
}
|
||
|
|
||
|
check () {
|
||
|
local return="$1"
|
||
|
local action="$2"
|
||
|
|
||
|
if [ "$return" = "0" ]
|
||
|
then
|
||
|
log "$step: Action \"$action\" OK"
|
||
|
else
|
||
|
log "$step: Action \"$action\" failed"
|
||
|
abort
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
abort () {
|
||
|
local trash_link="$TARGETPREFIX/$SHORTY"
|
||
|
local trash_dir="$TARGETDIR/$PRODUCT"
|
||
|
local trash_dl1="$TMPDIR/$TARBALL"
|
||
|
local trash_dl2="$TMPDIR/$checksum"
|
||
|
|
||
|
if [ ! "$RUNMODE" = "uninstall" ]
|
||
|
then
|
||
|
log "Fatal error, aborting script ..."
|
||
|
fi
|
||
|
|
||
|
if [ -h "$trash_link" ]
|
||
|
then
|
||
|
log "Cleaning up installation ..."
|
||
|
rm $trash_link
|
||
|
if [ -d $trash_dir ]
|
||
|
then
|
||
|
rm -r $trash_dir
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
if [ -f "$trash_dl1" ]
|
||
|
then
|
||
|
log "Cleaning up download ..."
|
||
|
rm $trash_dl1
|
||
|
if [ -f $trash_dl2 ]
|
||
|
then
|
||
|
rm $trash_dl2
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
if [ -f "$servicefile" ]
|
||
|
then
|
||
|
log "Removing servicefile ..."
|
||
|
systemctl disable ${SHORTY}d.service &>/dev/null
|
||
|
rm $servicefile
|
||
|
fi
|
||
|
|
||
|
if [ ! "$RUNMODE" = "uninstall" ]
|
||
|
then
|
||
|
log "Exit."
|
||
|
exit 1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
download () {
|
||
|
checksum="$TARBALL.sha256sum"
|
||
|
log "Downloading release tarball ..."
|
||
|
if [ -f $TARBALL ]
|
||
|
then
|
||
|
log "Removing stale files ..."
|
||
|
rm $TARBALL
|
||
|
fi
|
||
|
if [ -f $checksum ]
|
||
|
then
|
||
|
rm $checksum
|
||
|
fi
|
||
|
curl -sSLo $TARBALL $URL
|
||
|
curl -sSLo $checksum $URL.sha256sum
|
||
|
if ! download_verify $checksum
|
||
|
then
|
||
|
log "Corrupted download, verify URL."
|
||
|
exit 1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
download_verify () {
|
||
|
log "Verifying downloaded tarball ..."
|
||
|
sha256sum -c $1
|
||
|
}
|
||
|
|
||
|
setup () {
|
||
|
local step="Setup"
|
||
|
|
||
|
for action in extract prepare install
|
||
|
do
|
||
|
setup_$action
|
||
|
check "$?" "$action"
|
||
|
done
|
||
|
|
||
|
}
|
||
|
|
||
|
setup_extract () {
|
||
|
log "Deflating ..."
|
||
|
if [ ! -d "$TARGETDIR" ]
|
||
|
then
|
||
|
mkdir "$TARGETDIR"
|
||
|
fi
|
||
|
tar -C $TARGETDIR -xzf $TARBALL
|
||
|
}
|
||
|
|
||
|
setup_prepare () {
|
||
|
log "Preparing installation ..."
|
||
|
local target="$TARGETDIR/$PRODUCT"
|
||
|
local target_short="$TARGETPREFIX/$SHORTY"
|
||
|
ln -s $target $target_short
|
||
|
if ! getent group "$SHORTY" &>/dev/null
|
||
|
then
|
||
|
log "Creating group ..."
|
||
|
if ! groupadd -r $SHORTY
|
||
|
then
|
||
|
log "Failed to create group."
|
||
|
return 1
|
||
|
fi
|
||
|
fi
|
||
|
if ! id "$SHORTY" &>/dev/null
|
||
|
then
|
||
|
log "Creating user ..."
|
||
|
if ! useradd -g $SHORTY -d $HOMEDIR -rs /usr/sbin/nologin $SHORTY
|
||
|
then
|
||
|
log "Failed to create user."
|
||
|
return 1
|
||
|
fi
|
||
|
if [ ! -d "$HOMEDIR" ]
|
||
|
then
|
||
|
if mkdir $HOMEDIR
|
||
|
then
|
||
|
if chown $SHORTY:$SHORTY $HOMEDIR
|
||
|
then
|
||
|
if ! chmod 750 $HOMEDIR
|
||
|
then
|
||
|
log "Failed to set homedir permissions."
|
||
|
return 1
|
||
|
fi
|
||
|
else
|
||
|
log "Failed to set homedir ownership."
|
||
|
return 1
|
||
|
fi
|
||
|
else
|
||
|
log "Failed to create home directory."
|
||
|
return 1
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
fi
|
||
|
if ! chown -R $SHORTY:$SHORTY $target
|
||
|
then
|
||
|
log "Failed to change ownership."
|
||
|
return 1
|
||
|
fi
|
||
|
if ! chmod 750 $target
|
||
|
then
|
||
|
log "Failed to change permissions."
|
||
|
return 1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
setup_install () {
|
||
|
log "Placing systemd service ..."
|
||
|
ex - $servicefile <<EOF_SERVICE
|
||
|
insert
|
||
|
[Unit]
|
||
|
Description=Percona XtraDB Cluster Server
|
||
|
After=syslog.target network.target
|
||
|
|
||
|
[Service]
|
||
|
User=$SHORTY
|
||
|
Group=$SHORTY
|
||
|
PIDFile=/run/$SHORTY/${SHORTY}d.pid
|
||
|
ExecStart=$TARGETPREFIX/$SHORTY/bin/mysqld --defaults-file=$configfile
|
||
|
RuntimeDirectory=$SHORTY
|
||
|
ProtectSystem=strict
|
||
|
ProtectHome=yes
|
||
|
PrivateDevices=yes
|
||
|
PrivateTmp=yes
|
||
|
PrivateUsers=yes
|
||
|
ProtectKernelTunables=yes
|
||
|
ProtectKernelLogs=yes
|
||
|
ProtectControlGroups=yes
|
||
|
ReadWritePaths=/var/lib/$SHORTY
|
||
|
ReadWritePaths=/var/log/$SHORTY
|
||
|
|
||
|
[Install]
|
||
|
WantedBy=multi-user.target
|
||
|
.
|
||
|
wq
|
||
|
EOF_SERVICE
|
||
|
if [ ! "$?" = "0" ]
|
||
|
then
|
||
|
log "Failed to create systemd service file."
|
||
|
return 1
|
||
|
fi
|
||
|
|
||
|
log "Placing initial configuration ..."
|
||
|
ex - $configfile <<EOF_CONFIG
|
||
|
insert
|
||
|
[client]
|
||
|
socket=/run/mysql/mysql.sock
|
||
|
|
||
|
[mysqld]
|
||
|
datadir=$DATADIR
|
||
|
socket=/run/$SHORTY/$SHORTY.sock
|
||
|
log-error=/var/log/$SHORTY/${SHORTY}d.log
|
||
|
port=3306
|
||
|
bind-address = ::1
|
||
|
server-id=1
|
||
|
ssl_ca=/etc/pki/trust/anchors/syscid-ca.crt
|
||
|
ssl_cert=/etc/ssl/MySQL/crt
|
||
|
ssl_key=/etc/ssl/MySQL/key
|
||
|
.
|
||
|
wq
|
||
|
EOF_CONFIG
|
||
|
if [ ! "$?" = "0" ]
|
||
|
then
|
||
|
log "Failed to create configfile"
|
||
|
return 1
|
||
|
fi
|
||
|
|
||
|
if [ ! -d "$DATADIR" ]
|
||
|
then
|
||
|
if mkdir $DATADIR
|
||
|
then
|
||
|
if chown $SHORTY:$SHORTY $DATADIR
|
||
|
then
|
||
|
if ! chmod 750 $DATADIR
|
||
|
then
|
||
|
log "Failed to set datadir permissions."
|
||
|
return 1
|
||
|
fi
|
||
|
else
|
||
|
log "Failed to set datadir ownership."
|
||
|
return 1
|
||
|
fi
|
||
|
else
|
||
|
log "Failed to create data directory."
|
||
|
return 1
|
||
|
fi
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
uninstall () {
|
||
|
log "Removing user and group ..."
|
||
|
userdel -f $SHORTY &>/dev/null
|
||
|
groupdel -f $SHORTY &>/dev/null
|
||
|
|
||
|
log "Removing files and directories ..."
|
||
|
abort
|
||
|
|
||
|
echo "Remove data? y/n"
|
||
|
read choice
|
||
|
if [ "$choice" = "y" ]
|
||
|
then
|
||
|
if [ -d "$DATADIR" ]
|
||
|
then
|
||
|
rm -r "$DATADIR"
|
||
|
fi
|
||
|
if [ -d "$HOMEDIR" ]
|
||
|
then
|
||
|
rm -r "$HOMEDIR"
|
||
|
fi
|
||
|
if [ -f "$configfile" ]
|
||
|
then
|
||
|
rm "$configfile"
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
if [ -f "$checkfile" ]
|
||
|
then
|
||
|
rm "$checkfile"
|
||
|
fi
|
||
|
|
||
|
log "OK"
|
||
|
}
|
||
|
|
||
|
# Execute workflow
|
||
|
init
|
||
|
|