updated from server

This commit is contained in:
cutemeli
2026-01-07 20:30:10 +01:00
parent fd9a994ceb
commit e9ed1b266b
121 changed files with 32219 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
#!/bin/bash
### Copyright 1999-2025. WebPros International GmbH. All rights reserved.
out()
{
echo -e "\t$*" >&2
}
print_urls()
{
plesk login 2>/dev/null | sed -e $'s|^|\t * |' >&2
}
print_congratulations()
{
local mode="$1" # 'install' or 'upgrade'
local process=
[ "$mode" = "install" ] && process="installation" || process="upgrade"
out
out " Congratulations!"
out
out "The $process has been finished. Plesk is now running on your server."
out
if [ "$mode" = "install" ]; then
out "To complete the configuration process, browse either of URLs:"
print_urls
out
fi
out "Use the username 'admin' to log in. To log in as 'admin', use the 'plesk login' command."
out "You can also log in as 'root' using your 'root' password."
out
out "Use the 'plesk' command to manage the server. Run 'plesk help' for more info."
out
out "Use the following commands to start and stop the Plesk web interface:"
out "'systemctl start psa.service' and 'systemctl stop psa.service' respectively."
out
if [ "$mode" = "install" ]; then
out "If you would like to migrate your subscriptions from other hosting panel"
out "or older Plesk version to this server, please check out our assistance"
out "options: https://www.plesk.com/professional-services/"
out
fi
}
unset GREP_OPTIONS
print_congratulations "$1"
# Force showing text when used as AI post-examiner
exit 1

View File

@@ -0,0 +1,532 @@
#!/bin/bash
### Copyright 1999-2025. WebPros International GmbH. All rights reserved.
[ -z "$PLESK_INSTALLER_DEBUG" ] || set -x
[ -z "$PLESK_INSTALLER_STRICT_MODE" ] || set -e
export LC_ALL=C
unset GREP_OPTIONS
RET_SUCCESS=0
RET_WARN=1
RET_FATAL=2
is_function_defined()
{
local fn="$1"
case "$(type $fn 2>/dev/null)" in
*function*)
return 0
;;
esac
return 1
}
# @params are tags in format "key=value"
# Report body (human readable information) is read from stdin
# and copied to stderr.
make_error_report()
{
local report_file="${PLESK_INSTALLER_ERROR_REPORT:-}"
local python_bin=
for bin in "/opt/psa/bin/python" "/usr/local/psa/bin/python" "/usr/bin/python2" "/opt/psa/bin/py3-python" "/usr/local/psa/bin/py3-python" "/usr/libexec/platform-python" "/usr/bin/python3"; do
if [ -x "$bin" ]; then
python_bin="$bin"
break
fi
done
if [ -n "$report_file" -a -x "$python_bin" ]; then
"$python_bin" -c 'import sys, json
report_file = sys.argv[1]
error = sys.stdin.read()
sys.stderr.write(error)
data = {
"error": error,
}
for tag in sys.argv[2:]:
k, v = tag.split("=", 1)
data[k] = v
with open(report_file, "a") as f:
json.dump(data, f)
f.write("\n")
' "$report_file" "date=$(date --utc --iso-8601=ns)" "$@"
else
cat - >&2
fi
}
detect_platform()
{
. /etc/os-release
os_name="$ID"
os_version="${VERSION_ID%%.*}"
os_arch="$(uname -m)"
if [ -e /etc/debian_version ]; then
case "$os_arch" in
x86_64) pkg_arch="amd64" ;;
aarch64) pkg_arch="arm64" ;;
esac
if [ -n "$VERSION_CODENAME" ]; then
os_codename="$VERSION_CODENAME"
else
case "$os_name$os_version" in
debian10) os_codename="buster" ;;
debian11) os_codename="bullseye" ;;
debian12) os_codename="bookworm" ;;
ubuntu18) os_codename="bionic" ;;
ubuntu20) os_codename="focal" ;;
ubuntu22) os_codename="jammy" ;;
ubuntu24) os_codename="noble" ;;
esac
fi
fi
case "$os_name$os_version" in
rhel7|centos7|cloudlinux7|virtuozzo7)
package_manager="yum"
;;
rhel*|centos*|cloudlinux*|almalinux*|rocky*)
package_manager="dnf"
;;
debian*|ubuntu*)
package_manager="apt"
;;
esac
if [ "$os_name" = "ubuntu" -o "$os_name" = "debian" ]; then
PRODUCT_ROOT_D="/opt/psa"
else
PRODUCT_ROOT_D="/usr/local/psa"
fi
}
has_os_impl_function()
{
local prefix="$1"
local fn="${prefix}_${os_name}${os_version}"
is_function_defined "$fn"
}
call_os_impl_function()
{
local prefix="$1"
shift
local fn="${prefix}_${os_name}${os_version}"
"$fn" "$@"
}
skip_checker_on_flag()
{
local name="$1"
local flag="$2"
if [ -f "$flag" ]; then
echo "$name was skipped due to flag file." >&2
exit $RET_SUCCESS
fi
}
skip_checker_on_env()
{
local name="$1"
local env="$2"
if [ -n "$env" ]; then
echo "$name was skipped due to environment variable." >&2
exit $RET_SUCCESS
fi
}
checker_main()
{
local fnprefix="$1"
shift
detect_platform
# try to execute checker only if all attributes are detected
[ -n "$os_name" -a -n "$os_version" ] || return $RET_SUCCESS
for checker in "${fnprefix}_${os_name}${os_version}" "${fnprefix}_${os_name}" "${fnprefix}"; do
if is_function_defined "$checker"; then
local rc=$RET_SUCCESS
"$checker" "$@" || rc=$?
[ "$(( $rc & $RET_FATAL ))" = "0" ] || return $RET_FATAL
[ "$(( $rc & $RET_WARN ))" = "0" ] || return $RET_WARN
return $rc
fi
done
return $RET_SUCCESS
}
#!/bin/sh
### Copyright 1999-2025. WebPros International GmbH. All rights reserved.
# If env variable PLESK_INSTALLER_ERROR_REPORT=path_to_file is specified then in case of error
# disk_space_check.sh writes single line json report into it with the following fields:
# - "stage": "diskspacecheck"
# - "level": "error"
# - "errtype": "notenoughdiskspace"
# - "volume": volume with not enough diskspace (e.g. "/")
# - "required": required diskspace on the volume, human readable (e.g. "600 MB")
# - "available": available diskspace on the volume, human readable (e.g. "255 MB")
# - "needtofree": amount of diskspace which should be freed on the volume, human readable (e.g. "345 MB")
# - "date": time of error occurance ("2020-03-24T06:59:43,127545441+0000")
# - "error": human readable error message ("There is not enough disk space available in the / directory.")
# Required values below for Full installation are in MB. See 'du -cs -BM /*' and 'df -Pm'.
required_disk_space_cloudlinux7()
{
case "$1" in
/opt) echo 900 ;;
/usr) echo 4400 ;;
/var) echo 600 ;;
/tmp) echo 100 ;;
esac
}
required_disk_space_cloudlinux8()
{
case "$1" in
/opt) echo 1200 ;;
/usr) echo 4400 ;;
/var) echo 700 ;;
/tmp) echo 100 ;;
esac
}
required_disk_space_centos7()
{
case "$1" in
/opt) echo 900 ;;
/usr) echo 4100 ;;
/var) echo 600 ;;
/tmp) echo 100 ;;
esac
}
required_disk_space_centos8()
{
case "$1" in
/opt) echo 900 ;;
/usr) echo 4500 ;;
/var) echo 800 ;;
/tmp) echo 100 ;;
esac
}
required_disk_space_virtuozzo7()
{
required_disk_space_centos7 "$1"
}
required_disk_space_rhel7()
{
required_disk_space_centos7 "$1"
}
required_disk_space_rhel8()
{
required_disk_space_centos8 "$1"
}
required_disk_space_almalinux8()
{
required_disk_space_centos8 "$1"
}
required_disk_space_rocky8()
{
required_disk_space_centos8 "$1"
}
required_disk_space_rhel9()
{
case "$1" in
/opt) echo 500 ;;
/usr) echo 4000 ;;
/var) echo 800 ;;
/tmp) echo 100 ;;
esac
}
required_disk_space_almalinux9()
{
required_disk_space_rhel9 "$1"
}
required_disk_space_almalinux10()
{
required_disk_space_almalinux9 "$1"
}
required_disk_space_cloudlinux9()
{
required_disk_space_rhel9 "$1"
}
required_disk_space_debian10()
{
case "$1" in
/opt) echo 1800 ;;
/usr) echo 2300 ;;
/var) echo 1700 ;;
/tmp) echo 100 ;;
esac
}
required_disk_space_debian11()
{
case "$1" in
/opt) echo 1500 ;;
/usr) echo 3100 ;;
/var) echo 1800 ;;
/tmp) echo 100 ;;
esac
}
required_disk_space_debian12()
{
case "$1" in
/opt) echo 2700 ;;
/usr) echo 2500 ;;
/var) echo 2200 ;;
/tmp) echo 100 ;;
esac
}
required_disk_space_ubuntu18()
{
case "$1" in
/opt) echo 900 ;;
/usr) echo 1800 ;;
/var) echo 600 ;;
/tmp) echo 100 ;;
esac
}
required_disk_space_ubuntu20()
{
case "$1" in
/opt) echo 1800 ;;
/usr) echo 2900 ;;
/var) echo 1600 ;;
/tmp) echo 100 ;;
esac
}
required_disk_space_ubuntu22()
{
case "$1" in
/opt) echo 1800 ;;
/usr) echo 3900 ;;
/var) echo 1900 ;;
/tmp) echo 100 ;;
esac
}
required_disk_space_ubuntu24()
{
case "$1" in
/opt) echo 3200 ;;
/usr) echo 1800 ;;
/var) echo 2400 ;;
/tmp) echo 100 ;;
esac
}
required_update_upgrade_disk_space()
{
case "$1" in
/opt) echo 100 ;;
/usr) echo 300 ;;
/var) echo 600 ;;
/tmp) echo 100 ;;
esac
}
clean_tmp()
{
local volume="$1"
local path="/tmp"
is_path_on_volume "$path" "$volume" || return 0
echo "Cleaning $path via 'systemd-tmpfiles --clean --prefix $path'"
systemd-tmpfiles --clean --prefix "$path" 2>&1
}
clean_yum()
{
local volume="$1"
local path="/var/cache/yum"
is_path_on_volume "$path" "$volume" || return 0
echo "Cleaning $path via 'yum clean all'"
yum clean all 2>&1
# The command above doesn't clean untracked repos (missing in configuration), clean if left > 2 Mb
[ "`du -sm "$path" | awk '{ print $1 }'`" -gt 2 ] || return 0
echo "Cleaning $path via 'rm -rf $path/*'"
rm -rf "$path"/* 2>&1
}
clean_dnf()
{
local volume="$1"
local path="/var/cache/dnf"
is_path_on_volume "$path" "$volume" || return 0
echo "Cleaning $path via 'dnf clean all'"
dnf clean all 2>&1
}
clean_apt()
{
local volume="$1"
local path="/var/cache/apt"
is_path_on_volume "$path" "$volume" || return 0
echo "Cleaning $path via 'apt-get clean'"
apt-get clean 2>&1
}
clean_journal()
{
local volume="$1"
local path="/var/log/journal"
is_path_on_volume "$path" "$volume" || return 0
# Note that --rotate may cause more space to be freed, but may also cause more space to be used
echo "Cleaning $path via 'journalctl --vacuum-time 1d'"
journalctl --vacuum-time 1d 2>&1
}
clean_ext_packages()
{
local volume="$1"
local path="$PRODUCT_ROOT_D/var/modules-packages"
is_path_on_volume "$path" "$volume" || return 0
echo "Cleaning $path via 'rm -rf $path/*'"
rm -rf "$path"/* 2>&1
}
# @param $1 target directory
mount_point()
{
df -Pm $1 | awk 'NR==2 { print $6 }'
}
# @param $1 target directory
available_disk_space()
{
df -Pm $1 | awk 'NR==2 { print $4 }'
}
is_path_on_volume()
{
local path="$1"
local volume="$2"
[ -d "$path" ] && [ "`mount_point "$path"`" = "$volume" ]
}
# @param $1 target directory
# @param $2 mode (install/upgrade/update)
req_disk_space()
{
if [ "$2" != "install" ]; then
required_update_upgrade_disk_space "$1"
return
fi
has_os_impl_function "required_disk_space" || {
echo "There are no requirements defined for $os_name$os_version." >&2
echo "Disk space check cannot be performed." >&2
exit $RET_WARN
}
call_os_impl_function "required_disk_space" "$1"
}
human_readable_size()
{
echo "$1" | awk '
function human(x) {
s = "MGTEPYZ";
while (x >= 1000 && length(s) > 1) {
x /= 1024; s = substr(s, 2);
}
# 0.05 below will make sure the value is rounded up
return sprintf("%.1f %sB", x + 0.05, substr(s, 1, 1));
}
{ print human($1); }'
}
# @param $1 target directory
# @param $2 required disk space
# @param $3 check only flag (don't emit errors)
check_available_disk_space()
{
local volume="$1"
local required="$2"
local check_only="${3:-}"
local available="$(available_disk_space "$volume")"
if [ "$available" -lt "$required" ]; then
local needtofree
needtofree="`human_readable_size $((required - available))`"
[ -n "$check_only" ] ||
make_error_report 'stage=diskspacecheck' 'level=error' 'errtype=notenoughdiskspace' \
"volume=$volume" "required=$required MB" "available=$available MB" "needtofree=$needtofree" \
<<-EOL
There is not enough disk space available in the $1 directory.
You need to free up $needtofree.
EOL
return "$RET_FATAL"
fi
}
# @param $1 target directory
# @param $2 required disk space
clean_and_check_available_disk_space()
{
if [ -n "$PLESK_INSTALLER_FORCE_CLEAN_DISK_SPACE" ] || ! check_available_disk_space "$@" --check-only; then
clean_disk_space "$1"
check_available_disk_space "$@"
fi
}
# Cleans up disk space on the volume
clean_disk_space()
{
local volume="$1"
for cleanup_func in clean_tmp clean_yum clean_dnf clean_apt clean_journal clean_ext_packages; do
"$cleanup_func" "$volume"
done
}
# @param $1 mode (install/upgrade/update)
clean_and_check_disk_space()
{
local mode="$1"
local shared=0
for target_directory in /opt /usr /var /tmp; do
local required=$(req_disk_space "$target_directory" "$mode")
[ -n "$required" ] || return "$RET_WARN"
if is_path_on_volume "$target_directory" "/"; then
shared="$((shared + required))"
else
clean_and_check_available_disk_space "$target_directory" "$required" || return $?
fi
done
clean_and_check_available_disk_space "/" "$shared" || return $?
}
checker_main 'clean_and_check_disk_space' "$1"

View File

@@ -0,0 +1,224 @@
#!/bin/bash
### Copyright 1999-2025. WebPros International GmbH. All rights reserved.
[ -z "$PLESK_INSTALLER_DEBUG" ] || set -x
[ -z "$PLESK_INSTALLER_STRICT_MODE" ] || set -e
export LC_ALL=C
unset GREP_OPTIONS
RET_SUCCESS=0
RET_WARN=1
RET_FATAL=2
is_function_defined()
{
local fn="$1"
case "$(type $fn 2>/dev/null)" in
*function*)
return 0
;;
esac
return 1
}
# @params are tags in format "key=value"
# Report body (human readable information) is read from stdin
# and copied to stderr.
make_error_report()
{
local report_file="${PLESK_INSTALLER_ERROR_REPORT:-}"
local python_bin=
for bin in "/opt/psa/bin/python" "/usr/local/psa/bin/python" "/usr/bin/python2" "/opt/psa/bin/py3-python" "/usr/local/psa/bin/py3-python" "/usr/libexec/platform-python" "/usr/bin/python3"; do
if [ -x "$bin" ]; then
python_bin="$bin"
break
fi
done
if [ -n "$report_file" -a -x "$python_bin" ]; then
"$python_bin" -c 'import sys, json
report_file = sys.argv[1]
error = sys.stdin.read()
sys.stderr.write(error)
data = {
"error": error,
}
for tag in sys.argv[2:]:
k, v = tag.split("=", 1)
data[k] = v
with open(report_file, "a") as f:
json.dump(data, f)
f.write("\n")
' "$report_file" "date=$(date --utc --iso-8601=ns)" "$@"
else
cat - >&2
fi
}
detect_platform()
{
. /etc/os-release
os_name="$ID"
os_version="${VERSION_ID%%.*}"
os_arch="$(uname -m)"
if [ -e /etc/debian_version ]; then
case "$os_arch" in
x86_64) pkg_arch="amd64" ;;
aarch64) pkg_arch="arm64" ;;
esac
if [ -n "$VERSION_CODENAME" ]; then
os_codename="$VERSION_CODENAME"
else
case "$os_name$os_version" in
debian10) os_codename="buster" ;;
debian11) os_codename="bullseye" ;;
debian12) os_codename="bookworm" ;;
ubuntu18) os_codename="bionic" ;;
ubuntu20) os_codename="focal" ;;
ubuntu22) os_codename="jammy" ;;
ubuntu24) os_codename="noble" ;;
esac
fi
fi
case "$os_name$os_version" in
rhel7|centos7|cloudlinux7|virtuozzo7)
package_manager="yum"
;;
rhel*|centos*|cloudlinux*|almalinux*|rocky*)
package_manager="dnf"
;;
debian*|ubuntu*)
package_manager="apt"
;;
esac
if [ "$os_name" = "ubuntu" -o "$os_name" = "debian" ]; then
PRODUCT_ROOT_D="/opt/psa"
else
PRODUCT_ROOT_D="/usr/local/psa"
fi
}
has_os_impl_function()
{
local prefix="$1"
local fn="${prefix}_${os_name}${os_version}"
is_function_defined "$fn"
}
call_os_impl_function()
{
local prefix="$1"
shift
local fn="${prefix}_${os_name}${os_version}"
"$fn" "$@"
}
skip_checker_on_flag()
{
local name="$1"
local flag="$2"
if [ -f "$flag" ]; then
echo "$name was skipped due to flag file." >&2
exit $RET_SUCCESS
fi
}
skip_checker_on_env()
{
local name="$1"
local env="$2"
if [ -n "$env" ]; then
echo "$name was skipped due to environment variable." >&2
exit $RET_SUCCESS
fi
}
checker_main()
{
local fnprefix="$1"
shift
detect_platform
# try to execute checker only if all attributes are detected
[ -n "$os_name" -a -n "$os_version" ] || return $RET_SUCCESS
for checker in "${fnprefix}_${os_name}${os_version}" "${fnprefix}_${os_name}" "${fnprefix}"; do
if is_function_defined "$checker"; then
local rc=$RET_SUCCESS
"$checker" "$@" || rc=$?
[ "$(( $rc & $RET_FATAL ))" = "0" ] || return $RET_FATAL
[ "$(( $rc & $RET_WARN ))" = "0" ] || return $RET_WARN
return $rc
fi
done
return $RET_SUCCESS
}
#!/bin/sh
### Copyright 1999-2025. WebPros International GmbH. All rights reserved.
check_package_manager_deb_based()
{
local output=
output="`dpkg --audit 2>&1`" || output="$output"$'\n'"'dpkg --audit' finished with error code $?."
if [ -n "$output" ]; then
make_error_report 'stage=packagemanagercheck' 'level=error' 'errtype=brokenpackages' <<-EOL
The system package manager reports the following problems:
$output
To continue with the installation, you need to resolve these issues
using the procedure below:
1. Make sure you have a full server snapshot. Although the
following steps are usually safe, they can still cause
data loss or irreversible changes.
2. Run 'dpkg --configure -a'. This command can fix some of the
issues. However, it may fail. Regardless if it fails or not,
proceed with the following steps.
3. Run 'PLESK_INSTALLER_SKIP_PACKAGE_MANAGER_CHECK=1 plesk installer update --skip-cleanup'.
Instead of 'update', you may need to use the command you used
previously (for example, 'upgrade' or 'install').
4. The next step depends on the outcome of the previous one:
- If step 3 was completed with the "You already have the latest
version of product(s) and all the selected components installed.
Installation will not continue." message,
run 'plesk repair installation'.
- If step 3 failed, run 'dpkg --audit'. This command can show you
packages that need to be reinstalled. To reinstall them, run
'apt-get install --reinstall <packages>'.
5. Run 'plesk installer update' to revert temporary changes and
validate that the issues are resolved. If the command fails or
triggers this check again, contact Plesk support.
For more information, see
https://support.plesk.com/hc/en-us/articles/12871173047447-Plesk-update-on-Debian-Ubuntu-fails-dpkg-was-interrupted-you-must-manually-run-dpkg-configure-a-to-correct-the-problem
EOL
return "$RET_FATAL"
fi
}
check_package_manager_debian()
{
check_package_manager_deb_based
}
check_package_manager_ubuntu()
{
check_package_manager_deb_based
}
skip_checker_on_env "Package manager check" "$PLESK_INSTALLER_SKIP_PACKAGE_MANAGER_CHECK"
skip_checker_on_flag "Package manager check" "/tmp/plesk-installer-skip-package-manager-check.flag"
checker_main 'check_package_manager' "$@"

View File

@@ -0,0 +1,38 @@
#!/bin/sh
### Copyright 1999-2025. WebPros International GmbH. All rights reserved.
die()
{
echo $*
exit 1
}
[ -n "$1" ] || die "Usage: $0 php_script [args...]"
[ "X${PLESK_INSTALLER_DEBUG}" = "X" ] || set -x
[ "X${PLESK_INSTALLER_STRICT_MODE}" = "X" ] || set -e
php_bin=
lookup()
{
[ -z "$php_bin" ] || return
local paths="$1"
local name="$2"
for path in $paths; do
if [ -x "$path/$name" ]; then
php_bin="$path/$name"
break
fi
done
}
lookup "/usr/local/psa/admin/bin /opt/psa/admin/bin" "php"
lookup "/usr/local/psa/bin /opt/psa/bin" "sw-engine-pleskrun"
[ -n "$php_bin" ] || \
die "Unable to locate the sw-engine PHP interpreter to execute the script. Make sure that Parallels Plesk Panel is installed on this server."
exec "${php_bin}" "$@"

View File

@@ -0,0 +1,30 @@
#!/bin/sh
### Copyright 1999-2025. WebPros International GmbH. All rights reserved.
die()
{
echo "$*"
exit 1
}
[ -f "$1" ] || die "Usage: $0 PEX [args...]"
[ "X${PLESK_INSTALLER_DEBUG}" = "X" ] || set -x
[ "X${PLESK_INSTALLER_STRICT_MODE}" = "X" ] || set -e
find_python_bin()
{
local bin
for bin in "/opt/psa/bin/py3-python" "/usr/local/psa/bin/py3-python" "/usr/libexec/platform-python" "/usr/bin/python3" "/opt/psa/bin/python" "/usr/local/psa/bin/python" "/usr/bin/python2"; do
[ -x "$bin" ] || continue
python_bin="$bin"
return 0
done
return 1
}
find_python_bin ||
die "Unable to locate Python interpreter to execute the script."
exec "$python_bin" "$@"

View File

@@ -0,0 +1,782 @@
#!/bin/bash
### Copyright 1999-2025. WebPros International GmbH. All rights reserved.
[ -z "$PLESK_INSTALLER_DEBUG" ] || set -x
[ -z "$PLESK_INSTALLER_STRICT_MODE" ] || set -e
export LC_ALL=C
unset GREP_OPTIONS
RET_SUCCESS=0
RET_WARN=1
RET_FATAL=2
is_function_defined()
{
local fn="$1"
case "$(type $fn 2>/dev/null)" in
*function*)
return 0
;;
esac
return 1
}
# @params are tags in format "key=value"
# Report body (human readable information) is read from stdin
# and copied to stderr.
make_error_report()
{
local report_file="${PLESK_INSTALLER_ERROR_REPORT:-}"
local python_bin=
for bin in "/opt/psa/bin/python" "/usr/local/psa/bin/python" "/usr/bin/python2" "/opt/psa/bin/py3-python" "/usr/local/psa/bin/py3-python" "/usr/libexec/platform-python" "/usr/bin/python3"; do
if [ -x "$bin" ]; then
python_bin="$bin"
break
fi
done
if [ -n "$report_file" -a -x "$python_bin" ]; then
"$python_bin" -c 'import sys, json
report_file = sys.argv[1]
error = sys.stdin.read()
sys.stderr.write(error)
data = {
"error": error,
}
for tag in sys.argv[2:]:
k, v = tag.split("=", 1)
data[k] = v
with open(report_file, "a") as f:
json.dump(data, f)
f.write("\n")
' "$report_file" "date=$(date --utc --iso-8601=ns)" "$@"
else
cat - >&2
fi
}
detect_platform()
{
. /etc/os-release
os_name="$ID"
os_version="${VERSION_ID%%.*}"
os_arch="$(uname -m)"
if [ -e /etc/debian_version ]; then
case "$os_arch" in
x86_64) pkg_arch="amd64" ;;
aarch64) pkg_arch="arm64" ;;
esac
if [ -n "$VERSION_CODENAME" ]; then
os_codename="$VERSION_CODENAME"
else
case "$os_name$os_version" in
debian10) os_codename="buster" ;;
debian11) os_codename="bullseye" ;;
debian12) os_codename="bookworm" ;;
ubuntu18) os_codename="bionic" ;;
ubuntu20) os_codename="focal" ;;
ubuntu22) os_codename="jammy" ;;
ubuntu24) os_codename="noble" ;;
esac
fi
fi
case "$os_name$os_version" in
rhel7|centos7|cloudlinux7|virtuozzo7)
package_manager="yum"
;;
rhel*|centos*|cloudlinux*|almalinux*|rocky*)
package_manager="dnf"
;;
debian*|ubuntu*)
package_manager="apt"
;;
esac
if [ "$os_name" = "ubuntu" -o "$os_name" = "debian" ]; then
PRODUCT_ROOT_D="/opt/psa"
else
PRODUCT_ROOT_D="/usr/local/psa"
fi
}
has_os_impl_function()
{
local prefix="$1"
local fn="${prefix}_${os_name}${os_version}"
is_function_defined "$fn"
}
call_os_impl_function()
{
local prefix="$1"
shift
local fn="${prefix}_${os_name}${os_version}"
"$fn" "$@"
}
skip_checker_on_flag()
{
local name="$1"
local flag="$2"
if [ -f "$flag" ]; then
echo "$name was skipped due to flag file." >&2
exit $RET_SUCCESS
fi
}
skip_checker_on_env()
{
local name="$1"
local env="$2"
if [ -n "$env" ]; then
echo "$name was skipped due to environment variable." >&2
exit $RET_SUCCESS
fi
}
checker_main()
{
local fnprefix="$1"
shift
detect_platform
# try to execute checker only if all attributes are detected
[ -n "$os_name" -a -n "$os_version" ] || return $RET_SUCCESS
for checker in "${fnprefix}_${os_name}${os_version}" "${fnprefix}_${os_name}" "${fnprefix}"; do
if is_function_defined "$checker"; then
local rc=$RET_SUCCESS
"$checker" "$@" || rc=$?
[ "$(( $rc & $RET_FATAL ))" = "0" ] || return $RET_FATAL
[ "$(( $rc & $RET_WARN ))" = "0" ] || return $RET_WARN
return $rc
fi
done
return $RET_SUCCESS
}
#!/bin/sh
### Copyright 1999-2025. WebPros International GmbH. All rights reserved.
# If env variable PLESK_INSTALLER_ERROR_REPORT=path_to_file is specified then in case of error
# repository_check.sh writes single line json report into it with the following fields:
# - "stage": "repositorycheck"
# - "level": "error"
# - "errtype" is one of the following:
# * "reponotcached" - repository is not cached (mostly due to unavailability).
# * "reponotenabled" - required repository is not enabled.
# * "reponotsupported" - unsupported repository is enabled.
# * "configmanagernotinstalled" - dnf config-manager is disabled.
# - "repo": repository name.
# - "date": time of error occurance ("2020-03-24T06:59:43,127545441+0000")
# - "error": human readable error message.
report_no_repo()
{
local repo="$1"
make_error_report 'stage=repositorycheck' 'level=error' 'errtype=reponotenabled' "repo=$repo" <<-EOL
Plesk installation requires '$repo' OS repository to be enabled.
Make sure it is available and enabled, then try again.
EOL
}
report_no_repo_cache()
{
local repo="$1"
make_error_report 'stage=repositorycheck' 'level=error' 'errtype=reponotcached' "repo=$repo" <<-EOL
Unable to create $package_manager cache for '$repo' OS repository.
Make sure the repository is available, otherwise either disable it or fix its configuration, then try again.
EOL
}
report_unsupported_repo()
{
local repo="$1"
make_error_report 'stage=repositorycheck' 'level=error' 'errtype=reponotsupported' "repo=$repo" <<-EOL
Plesk installation doesn't support '$repo' OS repository.
Make sure it is disabled, then try again.
EOL
}
report_rh_no_config_manager()
{
local target
case "$package_manager" in
yum)
target="yum-utils package"
;;
dnf)
target="config-manager dnf plugin"
;;
esac
make_error_report 'stage=repositorycheck' 'level=error' 'errtype=configmanagernotinstalled' <<-EOL
Failed to install $target.
Make sure repositories configuration of $package_manager package manager is correct
(use '$package_manager repolist --verbose' to get its actual state), then try again.
EOL
}
check_rh_broken_repos()
{
local rh_enabled_repos rh_available_repos
# 1. `yum repolist` and `dnf repolist` list all repos
# which were enabled before last cache creation
# even if cache for them was not created.
# If some repo is misconfigured and cache was created with `skip_if_unavailable=1`
# then such repo will be listed anyway despite on cache state.
# If some repo was enabled after last cache creation
# then `repolist --cacheonly` will fail.
# 2. `yum repolist --verbose` and `dnf repoinfo` list only repos
# which were successfully cached before.
# These commands fail if at least one repo is not available
# and the 'skip_if_unavailable' flag is not set.
case "$package_manager" in
yum)
rh_enabled_repos="$(
{
yum repolist enabled --cacheonly -q 2>/dev/null \
|| yum repolist enabled -q --setopt='*.skip_if_unavailable=1'
} | sed -n -e '1d' -e 's/^\*\?!\?\([^/[:space:]]\+\).*/\1/p'
)" || return $RET_FATAL
rh_available_repos="$(
yum repolist enabled --verbose --cacheonly -q --setopt='*.skip_if_unavailable=1' \
| sed -n -e 's/^Repo-id\s*:\s*\([^/[:space:]]\+\).*/\1/p'
)" || return $RET_FATAL
;;
dnf)
rh_enabled_repos="$(
{
dnf repolist --enabled --cacheonly -q 2>/dev/null \
|| dnf repolist --enabled -q --setopt='*.skip_if_unavailable=1'
} | sed -n -e '1d' -e 's/^!\?\(\S\+\).*/\1/p'
)" || return $RET_FATAL
rh_available_repos="$( \
dnf repoinfo --enabled --cacheonly -q --setopt='*.skip_if_unavailable=1' \
| sed -n -e 's|^Repo-id\s*:\s*\(\S\+\)\s*$|\1|p'
)" || return $RET_FATAL
;;
esac
local rh_enabled_repos_f="$(mktemp /tmp/plesk-installer.preupgrade_checker.XXXXXX)"
echo "$rh_enabled_repos" | sort > "$rh_enabled_repos_f"
local rh_available_repos_f="$(mktemp /tmp/plesk-installer.preupgrade_checker.XXXXXX)"
echo "$rh_available_repos" | sort > "$rh_available_repos_f"
local repo rc=0
for repo in $(comm -23 "$rh_enabled_repos_f" "$rh_available_repos_f"); do
report_no_repo_cache "$repo"
rc=$RET_WARN
done
rm -f "$rh_enabled_repos_f" "$rh_available_repos_f"
return $rc
}
has_rh_enabled_repo()
{
local repo="$1"
# Try to get list of repos from cache first.
# If some repo was enabled after last cache creation
# or some repo is unavailable the query from cache will fail.
# Try to fetch actual metadata in this case.
case "$package_manager" in
yum)
# Repo-id may end with OS version and/or architecture
# if baseurl of the repo refers to $releasever and/or $basearch variables
# eg 'epel/7/x86_64', 'epel/7', 'epel/x86_64'
{
yum repolist enabled --verbose --cacheonly -q 2>/dev/null \
|| yum repolist enabled --verbose -q --setopt='*.skip_if_unavailable=1'
} | grep -E -q "^Repo-id\s*: $repo(/.+)?\s*$"
;;
dnf)
# note: --noplugins may cause failure and empty output on RedHat
{
dnf repoinfo --enabled --cacheonly -q 2>/dev/null \
|| dnf repoinfo --enabled -q --setopt='*.skip_if_unavailable=1'
} | grep -E -q "^Repo-id\s*: $repo\s*$"
;;
esac
}
has_rh_config_manager()
{
case "$package_manager" in
yum) yum-config-manager --help >/dev/null 2>&1 ;;
dnf) dnf config-manager --help >/dev/null 2>&1 ;;
esac
}
install_rh_config_manager()
{
case "$package_manager" in
yum) yum install --disablerepo 'PLESK_*' -q -y 'yum-utils' --setopt='*.skip_if_unavailable=1' ;;
dnf) dnf install --disablerepo 'PLESK_*' -q -y 'dnf-command(config-manager)' --setopt='*.skip_if_unavailable=1' ;;
esac
}
check_rh_config_manager()
{
if ! has_rh_config_manager && ! install_rh_config_manager; then
report_rh_no_config_manager
return $RET_FATAL
fi
}
enable_rh_repo()
{
case "$package_manager" in
yum) yum-config-manager --enable "$@" && has_rh_enabled_repo "$@" ;;
dnf) dnf config-manager --set-enabled "$@" && has_rh_enabled_repo "$@" ;;
esac
}
enable_sm_repo()
{
! has_rh_enabled_repo "$@" || return 0
subscription-manager repos --enable "$@" || return $?
# On RedHat 8 above command may return 0 on failure with "Repositories disabled by configuration."
has_rh_enabled_repo "$@"
}
check_epel()
{
! enable_rh_repo "epel" || return 0
# try to install epel-release from centos/extras or plesk/thirdparty repo
# and then try to update it to last version shipped by epel itself
# to make package upgradable with pum
"$package_manager" install --disablerepo 'PLESK_*' -q -y 'epel-release' --setopt='*.skip_if_unavailable=1' 2>/dev/null \
|| "$package_manager" install --disablerepo='*' --enablerepo 'PLESK_18_*-thirdparty' -q -y 'epel-release' \
|| "$package_manager" install -q -y "https://dl.fedoraproject.org/pub/epel/epel-release-latest-$os_version.noarch.rpm" \
&& "$package_manager" update -q -y 'epel-release' --setopt='*.skip_if_unavailable=1' 2>/dev/null
# Ensure any other EPEL repos have cache for subsequent check for broken repos (AL9)
local epel_repos="$(
[ "$package_manager" != "dnf" ] || {
dnf repolist --enabled --cacheonly -q 2>/dev/null ||
dnf repolist --enabled -q --setopt='*.skip_if_unavailable=1'
} | sed -n -e '1d' -e 's/^!\?\(epel\S\+\).*/\1/p'
)"
for repo in $epel_repos; do
"$package_manager" makecache --repo "$repo" -q
done
! has_rh_enabled_repo "epel" || return 0
report_no_repo "epel"
return $RET_FATAL
}
check_codeready()
{
local repo_rhel="codeready-builder-for-rhel-$os_version-$os_arch-rpms"
local repo_rhui="codeready-builder-for-rhel-$os_version-rhui-rpms"
local repo_rhui_alt="codeready-builder-for-rhel-$os_version-$os_arch-rhui-rpms"
local repo_rhui_alt2="rhui-codeready-builder-for-rhel-$os_version-$os_arch-rhui-rpms"
! enable_sm_repo "$repo_rhel" || return 0
! enable_rh_repo "$repo_rhui" || return 0
! enable_rh_repo "$repo_rhui_alt" || return 0
! enable_rh_repo "$repo_rhui_alt2" || return 0
report_no_repo "$repo_rhel"
return $RET_FATAL
}
check_optional()
{
local repo_rhel="rhel-$os_version-server-optional-rpms"
local repo_rhui="rhel-$os_version-server-rhui-optional-rpms"
! enable_sm_repo "$repo_rhel" || return 0
! enable_rh_repo "$repo_rhui" || return 0
report_no_repo "$repo_rhel"
return $RET_FATAL
}
check_repos_rhel9()
{
check_rh_config_manager || return $?
local rc=0
check_epel || rc="$(( $rc | $? ))"
check_codeready || rc="$(( $rc | $? ))"
check_rh_broken_repos || rc="$(( $rc | $? ))"
return $rc
}
check_repos_almalinux9()
{
check_rh_config_manager || return $?
local rc=0
check_epel || rc="$(( $rc | $? ))"
check_rh_broken_repos || rc="$(( $rc | $? ))"
# powertools is renamed to crb since AlmaLinux 9
! enable_rh_repo "crb" || return $rc
report_no_repo "crb"
return $RET_FATAL
}
check_repos_cloudlinux9()
{
check_repos_almalinux9 "$@"
}
check_repos_almalinux10()
{
check_repos_almalinux9 "$@"
}
check_repos_centos8()
{
check_rh_config_manager || return $?
local rc=0
check_epel || rc="$(( $rc | $? ))"
check_rh_broken_repos || rc="$(( $rc | $? ))"
# names of repos are lowercased since 8.3
! enable_rh_repo "powertools" || return $rc
! enable_rh_repo "PowerTools" || return $rc
report_no_repo "powertools"
return $RET_FATAL
}
check_repos_cloudlinux8()
{
check_rh_config_manager || return $?
local rc=0
check_epel || rc="$(( $rc | $? ))"
check_rh_broken_repos || rc="$(( $rc | $? ))"
# names of repos are changed since 8.5
! enable_rh_repo "powertools" || return $rc
! enable_rh_repo "cloudlinux-PowerTools" || return $rc
report_no_repo "powertools"
return $RET_FATAL
}
check_repos_rhel8()
{
check_rh_config_manager || return $?
local rc=0
check_epel || rc="$(( $rc | $? ))"
check_rh_broken_repos || rc="$(( $rc | $? ))"
[ "$1" = "install" ] || return $rc
check_codeready || rc="$(( $rc | $? ))"
return $rc
}
check_repos_almalinux8()
{
check_repos_centos8 "$@"
}
check_repos_rocky8()
{
check_repos_centos8 "$@"
}
check_repos_rhel7()
{
check_rh_config_manager || return $?
local rc=0
check_epel || rc="$(( $rc | $? ))"
check_optional || rc="$(( $rc | $? ))"
check_rh_broken_repos || rc="$(( $rc | $? ))"
return $rc
}
check_repos_centos7_based()
{
check_rh_config_manager || return $?
local rc=0
check_epel || rc="$(( $rc | $? ))"
check_rh_broken_repos || rc="$(( $rc | $? ))"
return $rc
}
sed_escape()
{
# Note: this is not a full implementation
echo -n "$1" | sed -e 's|\.|\\.|g'
}
switch_eol_centos_repos()
{
local old_mirrorlist_host="mirrorlist.centos.org"
local old_host="mirror.centos.org"
local new_host="vault.centos.org"
grep -qFw "$old_host" /etc/yum.repos.d/CentOS-*.repo 2>/dev/null || return 0
local backup="`mktemp -d "/tmp/yum.repos.d-$(date --rfc-3339=date)-XXXXXX"`"
! [ -d "$backup" ] || cp -raT /etc/yum.repos.d "$backup" || :
sed -i \
-e "s|^\s*\(mirrorlist\b[^/]*//`sed_escape "$old_mirrorlist_host"`/.*\)$|#\1|" \
-e "s|^#*\s*baseurl\b\([^/]*\)//`sed_escape "$old_host"`/\(.*\)$|baseurl\1//$new_host/\2|" \
/etc/yum.repos.d/CentOS-*.repo
echo "YUM package manager repositories were backed up to '$backup' and switched from $old_host to $new_host ." >&2
}
check_repos_centos7()
{
switch_eol_centos_repos
check_repos_centos7_based "$@"
}
check_repos_cloudlinux7()
{
check_repos_centos7_based "$@"
}
check_repos_virtuozzo7()
{
check_repos_centos7_based "$@"
}
find_apt_repo()
{
local repo="$1"
local dist_tag=
! [ "$os_name" = "ubuntu" ] || dist_tag="a"
! [ "$os_name" = "debian" ] || dist_tag="n"
if [ -z "$_apt_cache_policy" ]; then
# extract info of each available release as a string which consists of 'tag=value'
# filter out releases with priority less or equal to 100
_apt_cache_policy="$(
apt-cache policy \
| grep "b=$pkg_arch" \
| grep -Eo '([a-z]=[^,]+,?)*' \
)"
fi
local l="$(echo "$repo" | cut -f1 -d'/')"
local d="$(echo "$repo" | cut -f2 -d'/')"
local c="$(echo "$repo" | cut -f3 -d'/')"
# try to find releases by distribution and component
echo "$_apt_cache_policy" \
| grep -E "(^|,)l=$l(,|$)" \
| grep -E "(^|,)$dist_tag=$d(,|$)" \
| grep -E "(^|,)c=$c(,|$)" \
| while IFS="$(printf '\n')" read rel && [ -n "$rel" ]; do
l="$(echo "$rel" | grep -Eo "(^|,)l=[^,]+" | cut -f2 -d"=")"
d="$(echo "$rel" | grep -Eo "(^|,)$dist_tag=[^,]+" | cut -f2 -d"=")"
c="$(echo "$rel" | grep -Eo "(^|,)c=[^,]+" | cut -f2 -d"=")"
echo "$l/$d/$c"
done
}
apt_install_packages()
{
DEBIAN_FRONTEND=noninteractive LANG=C PATH=/usr/sbin:/usr/bin:/sbin:/bin \
apt-get -qq --assume-yes -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold -o APT::Install-Recommends=no \
install "$@"
}
# Takes a list of suites and disables them in APT sources.
# Multiline deb822 format is supported.
disable_apt_suites_deb822()
{
local python3=/usr/bin/python3
"$python3" -c 'import aptsources.sourceslist' 2>/dev/null ||
apt_install_packages python3-apt
"$python3" -c '
import sys
from aptsources.sourceslist import SourcesList
suites_to_disable=set(sys.argv[1:])
sources_list = SourcesList(deb822=True)
sources_changed = False
for src in sources_list:
if src.invalid:
continue
suites = getattr(src, "suites", ())
if not suites:
continue
new_suites = [s for s in suites if s not in suites_to_disable]
if len(new_suites) != len(suites):
sources_changed = True
if len(new_suites) == 0:
src.disabled = True
else:
src.suites = new_suites
if sources_changed:
sources_list.save()
' "$@"
# Since we have changed the repositories list, we should re-read _apt_cache_policy on a next call
# of the find_apt_repo function. Hence we have to reset the value of the variable
_apt_cache_policy=""
}
disable_apt_repo()
{
local repos_to_disable="$(find_apt_repo "$1" | cut -d '/' -f 2,3 | sort | uniq)"
if [ -z "$repos_to_disable" ]; then
return 0
fi
echo "$repos_to_disable" \
| while IFS= read -r repo_to_disable && [ -n "$repo_to_disable" ]; do
local distrib=${repo_to_disable%%/*}
local component=${repo_to_disable##*/}
find /etc/apt -name "*.list" -exec \
sed -i -e "/^\s*#/! s/.*\s$distrib\s\+$component\b/# &/" {} +
done
# Since we have changed the repositories list, we should re-read _apt_cache_policy on a next call
# of the find_apt_repo function. Hence we have to reset the value of the variable
_apt_cache_policy=""
return 0
}
check_required_apt_repo()
{
local repo="$1"
[ -z "$(find_apt_repo "$repo")" ] || return 0
report_no_repo "$repo"
return $RET_FATAL
}
check_unsupported_apt_repos_ubuntu()
{
[ -n "$os_codename" ] || return 0
local mode="$1"
local repos="$(
find_apt_repo "Ubuntu/[^,]+/[^,]+" | grep -v "Ubuntu/$os_codename.*/.*"
find_apt_repo "Debian[^,]*/[^,]+/[^,]+"
)"
[ -n "$repos" ] || return 0
echo "$repos" | while IFS="$(printf '\n')" read repo; do
report_unsupported_repo "$repo"
done
[ "$mode" = "install" ] || return $RET_WARN
return $RET_FATAL
}
check_repos_ubuntu18()
{
[ -n "$os_codename" ] || return 0
local mode="$1"
local rc=0
check_required_apt_repo "Ubuntu/$os_codename/main" || rc="$(( $rc | $? ))"
check_required_apt_repo "Ubuntu/$os_codename/universe" || rc="$(( $rc | $? ))"
check_required_apt_repo "Ubuntu/$os_codename-updates/main" || rc="$(( $rc | $? ))"
check_required_apt_repo "Ubuntu/$os_codename-updates/universe" || rc="$(( $rc | $? ))"
check_unsupported_apt_repos_ubuntu "$mode" || rc="$(( $rc | $? ))"
return $rc
}
check_repos_ubuntu()
{
[ -n "$os_codename" ] || return 0
local mode="$1"
local rc=0
check_required_apt_repo "Ubuntu/$os_codename/main" || rc="$(( $rc | $? ))"
check_required_apt_repo "Ubuntu/$os_codename/universe" || rc="$(( $rc | $? ))"
check_unsupported_apt_repos_ubuntu "$mode" || rc="$(( $rc | $? ))"
return $rc
}
check_unsupported_apt_repos_debian()
{
[ -n "$os_codename" ] || return 0
local mode="$1"
local repos="$(
find_apt_repo "Debian Backports/$os_codename-backports/[^,]+"
find_apt_repo "Debian[^,]*/[^,]+/[^,]+" | grep -v "Debian.*/$os_codename.*/.*"
find_apt_repo "Ubuntu/[^,]+/[^,]+"
)"
[ -n "$repos" ] || return 0
echo "$repos" | while IFS="$(printf '\n')" read repo; do
report_unsupported_repo "$repo"
done
[ "$mode" = "install" ] || return $RET_WARN
return $RET_FATAL
}
check_repos_debian()
{
[ -n "$os_codename" ] || return 0
local mode="$1"
local rc=0
if [ "$os_name" = "debian" -a "$os_version" -ge 12 ]; then
disable_apt_suites_deb822 "$os_codename-backports"
else
disable_apt_repo "Debian Backports/$os_codename-backports/[^,]+"
fi
check_required_apt_repo "Debian/$os_codename/main" || rc="$(( $rc | $? ))"
check_unsupported_apt_repos_debian "$mode" || rc="$(( $rc | $? ))"
return $rc
}
# ---
skip_checker_on_flag "Repository check" "/tmp/plesk-installer-skip-repository-check.flag"
checker_main 'check_repos' "$1"

View File

@@ -0,0 +1,61 @@
<?php
// Copyright 1999-2025. WebPros International GmbH. All rights reserved.
require_once('api-common/cu.php');
require_once('api-common/cuApp.php');
cu::initCLI();
class InstallationInfo extends cuApp
{
protected $_needToCheckPsaConfigured = false;
public function __construct()
{
parent::__construct();
$this->allowed_commands = [
[
CU_OPT_LONG => 'save',
CU_OPT_PARAM => false,
CU_OPT_DESC => 'Save info about Plesk installation',
],
];
$this->allowed_options = [
[
CU_OPT_LONG => 'mode',
CU_OPT_PARAM => true,
],
[
CU_OPT_LONG => 'preset',
CU_OPT_PARAM => true,
],
[
CU_OPT_LONG => 'arguments',
CU_OPT_PARAM => true,
],
];
}
protected function _saveCommand($mode, $preset, $arguments)
{
put_param('installation_mode', $this->getMode($mode));
put_param('installation_preset', $preset);
put_param('installation_arguments', $arguments);
put_param('installation_finish', time());
}
private function getMode($mode)
{
if (!$this->os->isUnix()) {
return $mode;
}
if (empty(getenv('PLESK_ONE_CLICK_INSTALLER'))) {
return $mode;
}
return 'ONE_CLICK';
}
}
$app = new InstallationInfo();
$app->runFromCli();

View File

@@ -0,0 +1,7 @@
#!/bin/sh
### Copyright 1999-2025. WebPros International GmbH. All rights reserved.
[ "X${PLESK_INSTALLER_DEBUG}" = "X" ] || set -x
[ "X${PLESK_INSTALLER_STRICT_MODE}" = "X" ] || set -e
exec "$@"

View File

@@ -0,0 +1,287 @@
#!/bin/bash
### Copyright 1999-2025. WebPros International GmbH. All rights reserved.
[ -z "$PLESK_INSTALLER_DEBUG" ] || set -x
[ -z "$PLESK_INSTALLER_STRICT_MODE" ] || set -e
export LC_ALL=C
unset GREP_OPTIONS
RET_SUCCESS=0
RET_WARN=1
RET_FATAL=2
is_function_defined()
{
local fn="$1"
case "$(type $fn 2>/dev/null)" in
*function*)
return 0
;;
esac
return 1
}
detect_platform()
{
. /etc/os-release
os_name="$ID"
os_version="${VERSION_ID%%.*}"
os_arch="$(uname -m)"
if [ -e /etc/debian_version ]; then
case "$os_arch" in
x86_64) pkg_arch="amd64" ;;
aarch64) pkg_arch="arm64" ;;
esac
if [ -n "$VERSION_CODENAME" ]; then
os_codename="$VERSION_CODENAME"
else
case "$os_name$os_version" in
debian10) os_codename="buster" ;;
debian11) os_codename="bullseye" ;;
debian12) os_codename="bookworm" ;;
ubuntu18) os_codename="bionic" ;;
ubuntu20) os_codename="focal" ;;
ubuntu22) os_codename="jammy" ;;
ubuntu24) os_codename="noble" ;;
esac
fi
fi
case "$os_name$os_version" in
rhel7|centos7|cloudlinux7|virtuozzo7)
package_manager="yum"
;;
rhel*|centos*|cloudlinux*|almalinux*|rocky*)
package_manager="dnf"
;;
debian*|ubuntu*)
package_manager="apt"
;;
esac
if [ "$os_name" = "ubuntu" -o "$os_name" = "debian" ]; then
PRODUCT_ROOT_D="/opt/psa"
else
PRODUCT_ROOT_D="/usr/local/psa"
fi
}
checker_main()
{
local fnprefix="$1"
shift
detect_platform
# try to execute checker only if all attributes are detected
[ -n "$os_name" -a -n "$os_version" ] || return $RET_SUCCESS
for checker in "${fnprefix}_${os_name}${os_version}" "${fnprefix}_${os_name}" "${fnprefix}"; do
if is_function_defined "$checker"; then
local rc=$RET_SUCCESS
"$checker" "$@" || rc=$?
[ "$(( $rc & $RET_FATAL ))" = "0" ] || return $RET_FATAL
[ "$(( $rc & $RET_WARN ))" = "0" ] || return $RET_WARN
return $rc
fi
done
return $RET_SUCCESS
}
### Copyright 1999-2025. WebPros International GmbH. All rights reserved.
# echo message to product log and console (always visible)
pp_echo()
{
if [ -n "$product_log" ] ; then
echo "$@" >> "$product_log" 2>&1
fi
echo "$@" >&2
}
detect_vz()
{
[ -z "$PLESK_VZ_RESULT" ] || return $PLESK_VZ_RESULT
PLESK_VZ_RESULT=1
PLESK_VZ=0
PLESK_VE_HW_NODE=0
PLESK_VZ_TYPE=
local issue_file="/etc/issue"
local vzcheck_file="/proc/self/status"
[ -f "$vzcheck_file" ] || return 1
local env_id=`sed -ne 's|^envID\:[[:space:]]*\([[:digit:]]\+\)$|\1|p' "$vzcheck_file"`
[ -n "$env_id" ] || return 1
if [ "$env_id" = "0" ]; then
# Either VZ/OpenVZ HW node or unjailed CloudLinux
PLESK_VE_HW_NODE=1
return 1
fi
if grep -q "CloudLinux" "$issue_file" >/dev/null 2>&1 ; then
return 1
fi
if [ -f "/proc/vz/veredir" ]; then
PLESK_VZ_TYPE="vz"
elif [ -d "/proc/vz" ]; then
PLESK_VZ_TYPE="openvz"
fi
PLESK_VZ=1
PLESK_VZ_RESULT=0
return 0
}
# detects lxc and docker containers
detect_lxc()
{
[ -z "$PLESK_LXC_RESULT" ] || return $PLESK_LXC_RESULT
PLESK_LXC_RESULT=1
PLESK_LXC=0
if { [ -f /proc/1/cgroup ] && grep -q 'docker\|lxc' /proc/1/cgroup; } || \
{ [ -f /proc/1/environ ] && cat /proc/1/environ | tr \\0 \\n | grep -q "container=lxc"; };
then
PLESK_LXC_RESULT=0
PLESK_LXC=1
fi
return "$PLESK_LXC_RESULT"
}
### Copyright 1999-2025. WebPros International GmbH. All rights reserved.
# vim:ft=sh
set_file_swap_params()
{
local pleskswaprc='/etc/pleskswaprc'
[ ! -f "$pleskswaprc" ] || . /etc/pleskswaprc
[ -n "$PLESK_SWAP_PATH" ] || PLESK_SWAP_PATH='/pleskswap'
[ -n "$PLESK_SWAP_SIZE" ] || PLESK_SWAP_SIZE='1G'
[ -n "$PLESK_REQUIRED_MEMORY" ] || PLESK_REQUIRED_MEMORY='1G'
FSTAB='/etc/fstab'
}
file_swap_is_required()
{
local total_mem_mib=$(LC_ALL=C LANG=C free -m -t | awk '/^Total:/ { print $2 }')
local required_mem_mib="`units2units $PLESK_REQUIRED_MEMORY M`"
[ "$total_mem_mib" -lt "$required_mem_mib" ] || return 1
pp_echo "Total amount of memory is less than minimal required size (${total_mem_mib}M < ${required_mem_mib}M)"
return 0
}
file_swap_is_switched_off()
{
case "${PLESK_SWAP:-}" in
0|false|disable)
pp_echo "Swapfile creation is disabled: envirinment vaiable \$PLESK_SWAP='$PLESK_SWAP'."
return 0
;;
esac
if [ -f "/etc/pleskswapdisable" ]; then
pp_echo "Swapfile creation is disabled: file '/etc/pleskswapdisable' is present."
return 0
fi
detect_vz
if [ "$PLESK_VZ" = "1" ]; then
pp_echo "Swapfile creation is disabled: installation into Virtuozzo container."
return 0
fi
detect_lxc
if [ "$PLESK_LXC" = "1" ]; then
pp_echo "Swapfile creation is disabled: installation into Docker/LXC container."
return 0
fi
return 1
}
file_swap_enable()
{
if file_swap_status; then
echo "Error: Plesk swapfile is already enabled." >&2
return 1
fi
local swap_size_mb="`units2units $PLESK_SWAP_SIZE M`"
pp_echo "===> Enable swapfile in $PLESK_SWAP_PATH"
dd if=/dev/zero of="$PLESK_SWAP_PATH" bs=1M count="$swap_size_mb" status=none || return 1
chmod 0600 "$PLESK_SWAP_PATH" || return 1
mkswap "$PLESK_SWAP_PATH" || return 1
if ! grep -qw "^$PLESK_SWAP_PATH" "${FSTAB}"; then
cp -f "${FSTAB}" "${FSTAB}.saved_by_plesk"
echo "$PLESK_SWAP_PATH none swap sw 0 0" >> "${FSTAB}"
fi
if swapon "$PLESK_SWAP_PATH"; then
rm -f "${FSTAB}.saved_by_plesk"
return 0
else
[ ! -f "${FSTAB}.saved_by_plesk" ] || mv -f "${FSTAB}.saved_by_plesk" "${FSTAB}"
return 1
fi
}
file_swap_status()
{
[ -f "$PLESK_SWAP_PATH" ] || return 1
grep -qw "^$PLESK_SWAP_PATH" "${FSTAB}" || return 1
return 0
}
### Copyright 1999-2025. WebPros International GmbH. All rights reserved.
units2units() {
local bytes
local n="${1%%[^0-9]*}"
case "${1,,}" in
*[0-9]) bytes="$1" ;;
*k|*kib) bytes="$(( $n * 1024 ** 1 ))" ;;
*m|*mib) bytes="$(( $n * 1024 ** 2 ))" ;;
*g|*gib) bytes="$(( $n * 1024 ** 3 ))" ;;
*t|*tib) bytes="$(( $n * 1024 ** 4 ))" ;;
*kb) bytes="$(( $n * 1000 ** 1 ))" ;;
*mb) bytes="$(( $n * 1000 ** 2 ))" ;;
*gb) bytes="$(( $n * 1000 ** 3 ))" ;;
*tb) bytes="$(( $n * 1000 ** 4 ))" ;;
*) echo "units2units: incorrect value '$1'" >&2; exit 1 ;;
esac
case "${2,,}" in
k|kib) echo $(( $bytes / 1024 ** 1 )) ;;
m|mib) echo $(( $bytes / 1024 ** 2 )) ;;
g|gib) echo $(( $bytes / 1024 ** 3 )) ;;
t|tib) echo $(( $bytes / 1024 ** 4 )) ;;
kb) echo $(( $bytes / 1000 ** 1 )) ;;
mb) echo $(( $bytes / 1000 ** 2 )) ;;
gb) echo $(( $bytes / 1000 ** 3 )) ;;
tb) echo $(( $bytes / 1000 ** 4 )) ;;
"") echo $bytes ;;
*) echo "Unknown unit: $2" >&2; exit 1 ;;
esac
}
#!/bin/sh
### Copyright 1999-2025. WebPros International GmbH. All rights reserved.
tune_memory_swap()
{
local mode="$1"
[ "$mode" = 'install' ] || return 0 # clean install only
set_file_swap_params
file_swap_is_required || return 0
! file_swap_is_switched_off || return 0 # disabled by admin
! file_swap_status || return 0 # already enabled
if ! file_swap_enable; then
pp_echo "Failed to enable swapfile. Installation may fail or freeze due to insufficient memory."
return "$RET_WARN"
fi
}
product_log=
product_problems_log=
checker_main 'tune_memory_swap' "$1"