Spade
Mini Shell
#!/bin/sh
# /********************************************
# LiteSpeed Cache Management Script
#
# @author Michael Alegre
# @copyright (c) 2017-2023 LiteSpeed Technologies, Inc.
# *********************************************/
VERSION='1.12.3'
OS=$(uname -s)
SCRIPT_DIR=$(cd "$(dirname "${0}")" && pwd)
cd "${SCRIPT_DIR}" || { echo "Unable to cd to script dir
${SCRIPT_DIR}"; exit 1; }
LSWS_DIR=$(cd "${SCRIPT_DIR}/../.." && pwd)
PHP_SCRIPT="${LSWS_DIR}/add-ons/webcachemgr/bootstrap_cli.php"
SHARED_API_VERSION_FILE="${LSWS_DIR}/add-ons/webcachemgr/VERSION"
SHARED_API_MIN_VER_FILE="${LSWS_DIR}/add-ons/webcachemgr/MIN_VER"
YELLOW='\e[33m'
CYAN='\e[36m'
GREEN='\e[32m'
L_GRAY='\e[37m'
END_COLOR='\e[0m'
printHeader()
{
# $1 title , $2 descr
printf "\n${YELLOW}%s${END_COLOR}\n%s\n" "${1}"
"${2}"
}
printLabelDesc()
{
printf "\n${YELLOW}%s${END_COLOR} %s\n\n" "${1}"
"${2}"
}
printCmdOption()
{
printf "${CYAN}%s${END_COLOR} ${GREEN}%s${END_COLOR}\n"
"${1}" "${2}"
printf " %s\n\n" "${3}" | fold -sw 80
}
printExample()
{
printf " ${L_GRAY}%s:${END_COLOR}\n" "${1}"
printf " ./lscmctl %s\n\n" "${2}"
}
printHelp()
{
printHeader "LiteSpeed Cache Manager CLI Tool v${VERSION}"
printLabelDesc 'Usage:' './lscmctl [-php path/to/php]
command [flag/parameter]'
printLabelDesc 'Possible Commands:'
# shellcheck disable=SC2016
printCmdOption 'setcacheroot' '[-svr <cache root>]
[-vh <cache root>]' 'List/Set server and/or virtual host
cache roots. This command will list the current server and virtual host
cache roots when no additional input is given. Use -svr and -vh to set
those cache roots. The
'"'"'$'"'"' character is
not allowed when setting virtual host cache root. Virtual host cache root
values starting with a
'"'"'/'"'"' will
automatically have
'"'"'/$vh_user'"'"'
appended to the end (this format was chosen to maintain compatibility with
CageFS).'
printCmdOption 'setversion' '[{--list | --latest |
<version>}]' 'List/Set active LSCWP version. This command
will list the currently active version when no additional input is given.
Use --list to show available versions or --latest to switch to the latest
available version. A valid version number can also be provided to switch to
that version specifically. This must be set before performing other lscmctl
operations.'
printCmdOption 'scan' '[-n] [-e]' 'Scan for all
WordPress installations. This command will create an lscm.data file under
the "lsws/admin/lscdata" directory. Add the -n flag to only
discover new installations. By adding the -e flag, LSCWP will be enabled on
all known installations after scanning is complete.'
printCmdOption 'scannew' '[-en] ' 'Scan for
WordPress installations not already discovered in a previous scan. This
command will create an lscm.data file under the
"lsws/admin/lscdata" directory. By adding the -en flag, LSCWP
will be enabled only on newly discovered installations after scanning is
complete. If you would rather enable LSCWP for all known installations,
after scanning for previously undiscovered installations, please use
command '"'"'scan -n
-e'"'"' instead.'
printCmdOption 'enable' '{-m | <wp path>}'
'Enables LSCWP for all discovered WordPress installations with the -m
parameter or a single installation by providing the path to the WordPress
installation directory.'
printCmdOption 'disable' '{-m | <wp path>}'
'Disables LSCWP for all discovered WordPress installations with the -m
parameter or a single installation by providing the path to the WordPress
installation directory.'
printCmdOption 'upgrade' '{-m | <wp path>}'
'Upgrade LSCWP for all discovered WordPress installations to the
current active version with the -m parameter or a single installation by
providing the path to the WordPress installation directory.'
printCmdOption 'flag' '<wp path>' 'Flag
a single WordPress installation. Flagged installations will be skipped
during mass operations.'
printCmdOption 'unflag' '{-m | <wp path>}'
'Unflag all discovered WordPress installations with the -m parameter
or a single installation by providing the path to the WordPress
installation directory. Flagged installations will be skipped during mass
operations.'
printCmdOption 'status' '<wp path>' 'Get
the most up to date LSCWP status for the provided WordPress
installation.'
printCmdOption 'dashnotify' '{-m | -wppath <wp
path>} [-plugin <plugin slug>] {-msgfile <message file path>
| -msg <message>}' 'Notify all discovered WordPress
installations with the provided message (plain text or HTML) using the Dash
Notifier WordPress plugin with the -m parameter or a single installation by
providing the path to the WordPress installation directory. A plugin slug
can be included to have an install/activate button for that plugin added to
the message as well. Installations containing a
'"'"'.dash_notifier_bypass'"'"'
file will not be notified.'
printCmdOption 'dashnotifyremove' '{-m | <wp
path>}' 'Remove Dash Notifier plugin (and notification
messages) from all discovered WordPress installations with the -m parameter
or a single installation by providing the path to the WordPress
installation directory.'
printCmdOption 'cpanelplugin' '{--install | --uninstall
| -autoinstall [{0 | 1}] | --fixconf}' '[cPanel/WHM Environment
Only] Install or uninstall the LiteSpeed user-end plugin for cPanel for all
cPanel accounts using the
'"'"'--install'"'"' and
'"'"'--uninstall'"'"'
input flags. The plugin will appear as "LiteSpeed Web Cache
Manager" under
'"'"'Advanced'"'"' in the
user'"'"'s cPanel dashboard. The
'"'"'-autoinstall'"'"'
input param can be used to check the current auto install status. When
turned on, the cPanel plugin will be automatically installed when
installing/updating the WHM plugin. Use
'"'"'-autoinstall {0 |
1}'"'"' to manually turn this off and on
respectively. The
'"'"'--fixConf'"'"' input
param can be used to re-populate the cPanel
plugin'"'"'s configuration file values in case of
an issue.'
printCmdOption 'addinstalls' '{-wpinstall <wp
path> <docroot> <server name> <site url>} |
-wpinstallsfile <installs file path>}' 'Add a WordPress
installation to existing scan data. This "custom" data will be
stored in it'"'"'s own lscm.data.cust data file
under the "lsws/admin/lscdata" directory. A single installation
can be added using the -wpinstall parameter with space separated list of
installation info in the required order (<wp path> <docroot>
<server name> <site url>). Multiple installations can be added
at once using the -wpinstallsfile parameter to provide the path to an
installs file containing a newline separated list of installation info in
the expected format.'
printCmdOption '--update-lib' '' 'Update the
lscmctl script and the required shared library to their latest versions
only if the currently installed versions are no longer supported.'
printCmdOption '--force-update-lib' '' 'Force
update the lscmctl script and the required shared library to their latest
versions. It is not recommended that this command be included in any cron
jobs, use command
'"'"'--update-lib'"'"'
instead.'
printHeader "Example Usage:"
printExample 'List server and virtual host cache roots'
'setcacheroot'
printExample 'Set virtual host cache root' 'setcacheroot
-vh /path/to/ssd/lscache'
printExample 'Display currently active LSCWP version'
'setversion'
printExample 'Display selectable LSCWP versions'
'setversion --list'
printExample 'Set active LSCWP version to latest available'
'setversion --latest'
printExample 'Set active LSCWP version to v1.5'
'setversion 1.5'
printExample 'Discover all installations' 'scan'
printExample 'Discover new installations only, passing in path to
PHP binary' '-php /path/to/php/ scannew'
printExample 'Enable LSCWP on all discovered installations'
'enable -m'
printExample 'Disable LSCWP for a single installation'
'disable /home/user/public_html/wp'
printExample 'Get LSCWP status for a single installation'
'status /home/user/public_html/wp'
printExample 'Send a simple dashboard message to a single
discovered WordPress installation' 'dashnotify -wppath
/path/to/wp/install -msg "Hello World!"'
printExample 'Broadcast a dashboard message recommending the
LiteSpeed Cache for WordPress plugin to all discovered WordPress
installations' 'dashnotify -m -plugin litespeed-cache -msgfile
/path/to/msg/file'
printExample 'Remove dashboard notifications (and Dash Notifier
plugin) from all discovered WordPress installations'
'dashnotifyremove -m'
printExample '[cPanel/WHM Environment Only] Install the LiteSpeed
user-end plugin for cPanel for all cPanel accounts' 'cpanelplugin
--install'
printExample '[cPanel/WHM Environment Only] Turn off auto install
for the LiteSpeed user-end plugin for cPanel' 'cpanelplugin
-autoinstall 0'
printExample 'Add a single WordPress Installations to custom data
file.' 'addinstalls -wpinstall /home/user/public_html/wp
/home/user/public_html user.com user.com/wp'
printExample 'Add multiple WordPress Installations to custom data
file using an installs file.' 'addinstalls -wpinstallsfile
/path/to/installs/file'
}
updateMinAPIVerFile()
{
MIN_VER=$(wget -q https://www.litespeed.sh/sub/shared/MIN_VER -O -)
RET=$?
if [ "${RET}" = "127" ] ; then
errorExit "Required command 'wget' not found with
exit code 127."
elif [ "$RET" != "0" ] ; then
errorExit "Failed to download latest MIN_VER file with wget
exit status ${RET}."
fi
echo "${MIN_VER}" > "${SHARED_API_MIN_VER_FILE}"
}
apiNeedsUpdate()
{
UPDATE_MIN_VER=1
if [ -f "${SHARED_API_VERSION_FILE}" ] ; then
test "$(find "${SHARED_API_VERSION_FILE}" -mmin
-1440)"
# shellcheck disable=SC2181
if [ "${?}" = "0" ] ; then
UPDATE_MIN_VER=0
fi
fi
if [ ! -f "${SHARED_API_MIN_VER_FILE}" ] || [ $UPDATE_MIN_VER
] ; then
updateMinAPIVerFile
fi
CURR_VER=$(cat "${SHARED_API_VERSION_FILE}")
MIN_VER=$(cat "${SHARED_API_MIN_VER_FILE}")
CURR_MAJOR=$(echo "${CURR_VER}" | awk -F"."
'{print $1}')
MIN_MAJOR=$(echo "${MIN_VER}" | awk -F"."
'{print $1}')
if [ "${CURR_MAJOR}" -lt "${MIN_MAJOR}" ] ; then
return 0
elif [ "${CURR_MAJOR}" -gt "${MIN_MAJOR}" ] ; then
return 1
fi
CURR_MINOR=$(echo "${CURR_VER}" | awk -F"."
'{print $2}')
MIN_MINOR=$(echo "${MIN_VER}" | awk -F"."
'{print $2}')
if [ "${CURR_MINOR}" -lt "${MIN_MINOR}" ] ; then
return 0
elif [ "${CURR_MINOR}" -gt "${MIN_MINOR}" ] ; then
return 1
fi
CURR_IMPROVEMENT=$(echo "${CURR_VER}" | awk -F"."
'{print match($3, /[^ ]/) ? $3 : 0}')
MIN_IMPROVEMENT=$(echo "${MIN_VER}" | awk -F"."
'{print match($3, /[^ ]/) ? $3 : 0}')
if [ "${CURR_IMPROVEMENT}" -lt "${MIN_IMPROVEMENT}"
] ; then
return 0
elif [ "${CURR_IMPROVEMENT}" -gt
"${MIN_IMPROVEMENT}" ] ; then
return 1
fi
CURR_PATCH=$(echo "${CURR_VER}" | awk -F"."
'{print match($4, /[^ ]/) ? $4 : 0}')
MIN_PATCH=$(echo "${MIN_VER}" | awk -F"."
'{print match($4, /[^ ]/) ? $4 : 0}')
if [ "${CURR_PATCH}" -lt "${MIN_PATCH}" ] ; then
return 0
elif [ "${CURR_PATCH}" -gt "${MIN_PATCH}" ] ; then
return 1
fi
return 1
}
enforceMinAPIVer()
{
if apiNeedsUpdate ; then
echo "Automatically updating lscmctl script and required
shared library"
runUpdate
fi
}
runUpdate()
{
if [ "${1}" = "--update-lib" ] && !
apiNeedsUpdate ; then
echo "Shared code library already meets minimum API version
requirements."
echo "Done!"
return
fi
ADDONS_DIR=$(cd "${LSWS_DIR}/add-ons" && pwd)
LOCAL_TAR_FILE="${ADDONS_DIR}/shared_latest.tar.gz"
URL="https://shared.litespeed.sh/latest"
echo "Downloading latest shared code tar file..."
wget -q --tries=1 --no-check-certificate "${URL}" -O
"${LOCAL_TAR_FILE}"
RET=$?
if [ "${RET}" != "0" ] ; then
if [ -f "${LOCAL_TAR_FILE}" ] ; then
/bin/rm -f "${LOCAL_TAR_FILE}"
fi
if [ "${RET}" = "127" ] ; then
errorExit "Required command 'wget' not found
with exit code 127."
else
errorExit "Failed to download latest shared code with wget
exit status ${RET}."
fi
fi
MD5_VALUE=$(wget -q https://shared.litespeed.sh/latest/md5 -O -)
if [ "${MD5_VALUE}" = "" ] ; then
/bin/rm -f "${LOCAL_TAR_FILE}"
errorExit "Failed to wget latest shared code md5 value."
fi
if [ "x${OS}" = "xFreeBSD" ] ; then
LOCAL_MD5_VAL=$(md5 "${LOCAL_TAR_FILE}" | awk '{
print $4 }')
else
LOCAL_MD5_VAL=$(md5sum "${LOCAL_TAR_FILE}" | awk '{
print $1 }')
fi
echo "Checking tar file md5..."
if [ "${MD5_VALUE}" != "${LOCAL_MD5_VAL}" ] ; then
/bin/rm -f "${LOCAL_TAR_FILE}"
errorExit "Md5 mismatch for shared code! Aborting."
fi
SHARED_CODE_DIR="${ADDONS_DIR}/webcachemgr"
if [ -d "${SHARED_CODE_DIR}" ] ; then
echo "Removing existing shared code directory..."
/bin/rm -rf "${SHARED_CODE_DIR}"
fi
echo "Extracting downloaded shared code..."
tar -xzf "${LOCAL_TAR_FILE}" -C "${ADDONS_DIR}"
RET=$?
if [ "${RET}" != "0" ] ; then
/bin/rm -f "${LOCAL_TAR_FILE}"
errorExit "Failed to extract tar.gz file with tar exit status
${RET}."
fi
echo "Removing local shared code tar file..."
/bin/rm -f "${LOCAL_TAR_FILE}"
echo "Updating lscmctl script..."
/bin/mv -f "${ADDONS_DIR}/lscmctl"
"${ADDONS_DIR}/../admin/misc/lscmctl"
echo "Done!"
}
errorExit()
{
printf "${YELLOW}ERROR:${END_COLOR} %s\n\n" "${1}"
>&2
exit 1
}
setPanelClassName()
{
PANEL_CLASS_NAME=''
x=$(/usr/local/cpanel/cpanel -V 2>/dev/null)
if [ "${x}" ]; then
PANEL_CLASS_NAME='\Lsc\Wp\Panel\CPanel'
return
fi
x=$(/usr/sbin/plesk version 2>/dev/null)
if [ "${x}" ]; then
PANEL_CLASS_NAME='\Lsc\Wp\Panel\Plesk'
return
fi
x=$(/usr/local/directadmin/directadmin v 2>/dev/null)
if [ "${x}" ]; then
PANEL_CLASS_NAME='\Lsc\Wp\Panel\DirectAdmin'
return
fi
if [ -e "${LSWS_DIR}/admin/lscdata/custom" ]; then
PANEL_CLASS_NAME='custom'
return
fi
}
selectPHP()
{
if [ "${1}" = "-php" ]
then
if [ -x "${2}" ] ; then
PHP_BIN="${2} -d disable_functions="
return 2
else
errorExit "${2} not detected as a valid php binary."
fi
else
#Use default admin php binary
DEFAULT_PHP_BIN="${LSWS_DIR}/admin/fcgi-bin/admin_php5"
OLS_DA_PHP_BIN="${LSWS_DIR}/admin/fcgi-bin/admin_php"
if [ ! -x "${DEFAULT_PHP_BIN}" ] ; then
if [ -x "${OLS_DA_PHP_BIN}" ] ; then
DEFAULT_PHP_BIN="${OLS_DA_PHP_BIN}"
else
errorExit "Could not find default admin PHP
binary."
fi
fi
PHP_BIN="${DEFAULT_PHP_BIN} -c
${LSWS_DIR}/add-ons/webcachemgr/shared/webcachemgr.ini"
fi
}
if [ "${1}" = "--help" ]
then
printHelp
exit 0
fi
if [ "${1}" = "--update-lib" ] || [ "${1}" =
"--force-update-lib" ]
then
runUpdate "${1}"
exit 0;
fi
enforceMinAPIVer
setPanelClassName
if [ "${PANEL_CLASS_NAME}" = '' ] ; then
errorExit 'Supported Control Panel not detected. Aborting!'
fi
selectPHP "${1}" "${2}"
if [ $? = 2 ] ; then
shift 2
fi
if [ $# = 0 ] ; then
errorExit "Missing input command. Try --help for a full list of
available commands with examples."
fi
$PHP_BIN "${PHP_SCRIPT}" "${PANEL_CLASS_NAME}"
"${@}"