D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
opt
/
psa
/
admin
/
bin
/
Filename :
collect
back
Copy
#!/bin/bash ### Copyright 1999-2025. WebPros International GmbH. All rights reserved. export LANG="C" export LC_ALL="C" set -u # Here you can define checking routines list for every mode brief_list=" get_sysinfo get_common_info get_common_logs get_ipconfig get_mounts_info get_last get_selinux_info get_pkglist get_components get_system_users get_system_services get_ai_log get_apache_info get_nginx_info get_cpserver_info get_php_info get_psa_conf get_plesk_repair_status " # removed from brief: get_history middle_list=" $brief_list get_db_misc get_db_eventhandlers get_maillog get_mail_handlers_list get_vhost_conf get_php_conf get_pmm_info get_webmail_conf " full_list=" $middle_list get_db_dumps " MYSQL_BIN_D="/usr/bin" # common options curdir="`dirname $0`" tmp_d="/usr/local/psa/var" infodir="$tmp_d/collect" info_plesk="$infodir/plesk" info_system="$infodir/system" info_db="$infodir/db" my_access="-uadmin -p`cat /etc/psa/.psa.shadow`" # global options pkgtype='' # defined in get_sysinfo os_descr='' # defined in get_sysinfo root_d='' # defined in get_sysinfo # Common functions # --------------------------------------------------------------------------------------- help() { cat <<-EOT USAGE: $progname [--quiet] [--output FILE] [--mode [brief|middle|full]] $progname --help OPTIONS: --mode Set required verbosity level. See MODES section to get an additional info. --quiet Do not output any info on stdout. --output Specify file where data will be saved. --sanitizer Specify path to sanitizer unitity. --tail-size Number of lines collected from logfiles. --help Show this message MODES: brief Short basic info. middle Detailed info about system and product. This is default. full Includes detailed info, product logs and database dumps. EOT } parse_options() { local count="$#" # global params: progname="`basename $0`" mode="" quiet="" output="" sanitize_bin="/usr/local/psa/admin/sbin/sanitize" tail_size=1000 actions_list="" local TEMP TEMP=`getopt -o m:qo:S:t:h --long mode:,quiet,output:,sanitizer:,tail-size:,actions:,help -n "$progname" -- "$@"` if [ $? != 0 ]; then echo "Internal error in parsing options" >&2 exit 1 fi eval set -- "$TEMP" while true; do case "$1" in -m|--mode) case "$2" in brief) actions_list="$brief_list" ;; middle) actions_list="$middle_list" ;; full) actions_list="$full_list" ;; *) help && exit 1 ;; esac shift 2 ;; -q|--quiet) quiet=1; exec >/dev/null shift ;; -o|--output) output="$2"; shift 2;; -h|--help) help && exit 0;; -S|--sanitizer) sanitize_bin="$2"; shift 2;; -t|--tail-size) tail_size="$2"; shift 2;; --actions) actions_list="$2"; shift 2;; --) shift; break;; *) echo "Internal error in processing options: '$1'"; exit 1;; esac done # allow relative path for $output: if [ -n "$output" ]; then expr match "$output" "/" >/dev/null || output="`pwd`/$output" fi # allow relative path for $sanitize_bin if [ -n "$sanitize_bin" ]; then expr match "$sanitize_bin" "/" >/dev/null || sanitize_bin="`pwd`/$sanitize_bin" fi # default mode is middle: [ -n "$actions_list" ] || actions_list="$middle_list" } ok() { [ ! -z "$quiet" ] || echo "ok" } info() { [ ! -z "$quiet" ] || echo "$*" } try() { [ ! -z "$quiet" ] || echo -n "Trying to $*... " } fail() { [ ! -z "$quiet" ] || echo "failed" } die() { echo "ERROR: $*.. exiting..." >&2 exit 1 } is_function() { local type_output=$(type -t "$1") test "X${type_output}" = "Xfunction" } cleanup() { rm -rf $infodir >/dev/null 2>&1 rm -f $tmp_d/collect.zip } cp_tail() { local src="$1" local dest="$2" expr match "$dest" / > /dev/null || dest="`pwd`/$dest" if [ -d "$dest" ]; then dest="$dest/`basename $src`" fi if [ -d "$src" ]; then [ -e "$dest" ] || mkdir "$dest" pushd "$src" > /dev/null find -type d -exec mkdir -p "$dest/{}" \; for i in `find -type f`; do tail -n "$tail_size" "$i" > "$dest/$i" done popd > /dev/null else tail -n "$tail_size" "$src" > "$dest" fi } db_do() { local query="$*" local mysql_client="$MYSQL_BIN_D/mysql" if [ -f "$MYSQL_BIN_D/mariadb" ]; then mysql_client="$MYSQL_BIN_D/mariadb" fi echo "$query" | "$mysql_client" -n -N $my_access psa } db_dump() { local database="$1" local table where my_opts local dump_client="$MYSQL_BIN_D/mysqldump" [ -f "$MYSQL_BIN_D/mariadb-dump" ] && dump_client="$MYSQL_BIN_D/mariadb-dump" my_opts="--skip-extended-insert --skip-quick --skip-lock-tables --databases $1" shift [ ! "$#" -ge 1 ] || my_opts+=" --tables $1" "$dump_client" $my_access $my_opts } collect() { local functions="$1" for func in $functions; do if is_function $func; then $func continue fi echo "Internal error: Unable to find a function '$func'. Skipping..." done } sanitize() { try "filter out user private data" [ -x "$sanitize_bin" ] || die "$sanitize_bin not found" "$sanitize_bin" "$tmp_d/collect" ok } pack() { local output_path="$1" [ -n "$output_path" ] || output_path="$tmp_d/collect.zip" try "pack gathered info to '$output_path'" local zip_bin="`which zip 2>/dev/null`" [ -z "$zip_bin" ] && die "ZIP archiver didn't find" pushd "$(dirname "$infodir")" > /dev/null local include_list="$(mktemp "$tmp_d/include.lst.XXXXXX")" find "$(basename "$infodir")" -type f > "$include_list" # prevent zip from adding .zip to output_path $zip_bin -r -q -b . - "$(basename "$infodir")" --include @"$include_list" > "$output_path" popd > /dev/null rm -f "$include_list" rm -rf "$infodir" ok } # Routines # --------------------------------------------------------------------------------------- get_sysinfo() { try "collect system info" res="`/bin/uname -m`" [ "$res" = "amd64" -o "$res" = "x86_64" ] && arch="x86_64" || arch="i386" found_file="" for f in redhat-release SuSE-release lsb-release debian_version; do [ -f "/etc/$f" ] && found_file="$f" && break done case $found_file in redhat-release) pkgtype="rpm" os_descr="`cat /etc/$found_file` $arch" root_d="/usr/local/psa" ;; SuSE-release) pkgtype="rpm" os_descr="`cat /etc/$found_file | head -n 1` $arch" root_d="/usr/local/psa" ;; lsb-release) pkgtype="deb" os_descr="`awk -F '=' '/DISTRIB_DESCRIPTION/ {print $2}' < /etc/$found_file | tr -d '"'` $arch" root_d="/opt/psa" ;; debian_version) pkgtype="deb" os_descr="Debian `cat /etc/$found_file` $arch" root_d="/opt/psa" ;; *) fail die "Unsupported os has been detected" ;; esac ok } get_ipconfig() { try "collect IP configuration" mkdir -p $info_system ifconfig > $info_system/ipconfig.txt 2>&1 ok } get_mounts_info() { try "get mountpoints and volumes info" mkdir -p $info_system mount > $info_system/mounts.txt echo "" >> $info_system/mounts.txt df -h >> $info_system/mounts.txt ok } get_last() { try "get last events" mkdir -p $info_system last > $info_system/last.txt ok } get_db_misc() { try "collect info from psa.misc database table" mkdir -p $info_db db_dump "psa" "misc" > $info_db/misc.sql ok } get_db_eventhandlers() { try "collect info from psa.event_handlers" mkdir -p $info_db db_dump "psa" "event_handlers" > $info_db/event_handlers.sql ok } get_selinux_info() { try "get selinux status" enforced="`getenforce 2>/dev/null`" [ "$pkgtype" != "rpm" -o -z "$enforced" ] \ && info "not installed" \ && return mkdir -p $info_system echo -e "SELinux mode:\n $enforced" > $info_system/selinux.txt ok } get_common_info() { try "collect Plesk common info" [ ! -f "$root_d/version" ] && fail && return || info="`cat $root_d/version`" up_hist="`db_do "select * from upgrade_history"`" domains="`db_do "select count(*) from domains"`" case $pkgtype in rpm) nginx_str="`head -1 /etc/sysconfig/nginx`" ;; deb) nginx_str="`head -1 /etc/default/nginx`" ;; *) die "Unsupported OS" ;; esac nginx_status="`echo $nginx_str | awk -F '=' '{print $2}' | tr -d '"'`" vz_env_id="`awk '/envID/ {print $2}' /proc/self/status`" if [ -z "$vz_env_id" -o "$vz_env_id" = "0" ]; then vz_status="Nope. Is not VZ." counters="Not found." else vz_status="Yep. Is VZ." counters="`cat /proc/user_beancounters`" fi mkdir -p $infodir out="$infodir/common_info.txt" echo "OS:" > $out echo " $os_descr" >> $out echo "" >> $out echo "Is virtuozzo container?:" >> $out echo " $vz_status" >> $out echo "" >> $out echo "Product:" >> $out echo " $info" >> $out echo "" >> $out echo "Upgrade history:" >> $out if [ -z "$up_hist" ]; then echo " Clean installation." >> $out else IFS_OLD="$IFS" IFS=$'\n' for str in $up_hist; do echo " $str" >> $out done IFS="$IFS_OLD" fi echo "" >> $out echo "Count of domains:" >> $out echo " $domains" >> $out echo "" >> $out echo "Nginx enabled:" >> $out echo " $nginx_status" >> $out echo "" >> $out echo "Collected info date:" >> $out echo " `date +%s` (`date -u`)" >> $out echo "" >> $out echo "User Beancounters:" >> $out echo " $counters" >> $out echo "" >> $out cp -f /etc/sw/keys/registry.xml $infodir/ ok } get_common_logs() { try "collect common system logs" dstdir="$info_system/var_log" mkdir -p $dstdir for entry in cron mail.info syslog maillog messages mysqld.log secure yum.log audit dmesg; do [ -e "/var/log/$entry" ] && cp_tail /var/log/$entry $dstdir/ done ok } get_pkglist() { try "get packages list" mkdir -p $info_system case $pkgtype in rpm) rpm -qa >$info_system/pkglist.txt 2>&1 ;; deb) dpkg --list > $info_system/pkglist.txt 2>&1 ;; *) die "Unknown packages type." ;; esac ok } get_components() { try "get Plesk components list" mkdir -p $info_plesk $root_d/admin/sbin/packagemng --list > $info_plesk/components.txt 2>&1 ok } get_history() { try "get shell history" history > $info_system/history.txt 2>&1 ok } get_system_users() { try "get system users and groups" mkdir -p $info_system cp -f /etc/passwd $info_system/sysusers.txt cp -f /etc/group $info_system/sysgroups.txt ok } get_system_services() { try "get system active services list" mkdir -p $info_system if [ -x "/bin/systemctl" ]; then echo >> "$info_system/services.txt" /bin/systemctl list-unit-files >> "$info_system/services.txt" fi top -b -n 1 > $info_system/top.txt 2>&1 ps auxwww > $info_system/ps.txt 2>&1 ok } get_ai_log() { try "get autoinstaller logs" mkdir -p "$info_plesk" local latest_ai_log="`ls -t /var/log/plesk/install/autoinstaller3*.log 2>/dev/null | head -n 1`" [ -z "$latest_ai_log" ] || cp_tail "$latest_ai_log" "$info_plesk/" ok } get_mail_handlers_list() { try "get mail handlers info" mkdir -p $info_plesk $root_d/admin/sbin/mail_handlers_control --list > $info_plesk/mhandlers.txt echo "" >> $info_plesk/mhandlers.txt $root_d/admin/sbin/mail_handlers_control --list --extent >> $info_plesk/mhandlers.txt ok } get_apache_info() { try "collect customer's web server configuration" local cmd local out local subdir mkdir -p $info_plesk/apache/logs out="$info_plesk/apache/common.txt" cmd="`which httpd 2>/dev/null`" [ -z "$cmd" ] && cmd="`which apache 2>/dev/null`" [ -z "$cmd" ] && cmd="`which apache2 2>/dev/null`" [ -z "$cmd" ] && echo "apache not found.. " && fail && return [ "$pkgtype" = "rpm" ] && cmd_bin="$cmd" || cmd_bin="apachectl" $cmd_bin -t >> $out 2>&1 echo "" >> $out $cmd_bin -V >> $out 2>&1 echo "" >> $out $cmd_bin -M >> $out 2>&1 echo "" >> $out $cmd_bin -S > $info_plesk/apache/vhosts.txt 2>&1 subdir="`basename $cmd`" [ ! -s "/var/log/$subdir/error_log" ] || cp_tail /var/log/$subdir/error_log $info_plesk/apache/logs/ cp -fR /etc/$subdir $info_plesk/apache/conf ok } get_nginx_info() { try "collect nginx web server info" mkdir -p $info_plesk/nginx cp -fR /etc/nginx/* $info_plesk/nginx/ ok } get_cpserver_info() { try "collect cp-server info" dstdir="$info_plesk/cp-server" mkdir -p $dstdir/etc/conf $dstdir/var_logs cp -fR /etc/sw-cp-server/* $dstdir/etc/ for l in error_log sw-engine.log; do [ ! -s "/var/log/sw-cp-server/$l" ] || cp_tail "/var/log/sw-cp-server/$l" "$dstdir/var_logs/" done mkdir -p $dstdir/admin cp -fR $root_d/admin/conf $dstdir/admin/ for l in panel.log sitebuilder.log; do [ ! -s "/var/log/plesk/$l" ] || cp_tail "/var/log/plesk/$l" "$dstdir/admin/" done # Remove pem files that store private key to avoid leakage of them rm -f $dstdir/admin/conf/*.pem* ok } get_php_info() { try "collect info about installed php" mkdir -p $info_plesk php -r "@phpinfo();" < /dev/null > $info_plesk/phpinfo.txt ok } get_psa_conf() { try "get psa common configuration" mkdir -p $info_plesk/etc_psa for l in psa.conf php_versions.json; do [ ! -s "/etc/psa/$l" ] || cp -f /etc/psa/$l $info_plesk/etc_psa/ done ok } get_webmail_conf() { try "get webmails configuration" mkdir -p $info_plesk/webmails cp -fR /etc/psa-webmail/* $info_plesk/webmails/ ok } get_maillog() { try "collect mail logs" mkdir -p $info_plesk cp_tail $root_d/var/log $info_plesk/maillog ok } get_vhost_conf() { try "collect info from virtual domains" local vhosts_d vhosts_d="`awk '/^HTTPD_VHOSTS_D/ {print $2}' /etc/psa/psa.conf`" is_new_vhost="`which plesk 2>/dev/null`" count=0 for domain in `db_do "select name from domains"`; do [ $count -eq 100 ] && echo -n "." && count=0 [ -n "$is_new_vhost" ] \ && srcdir="$vhosts_d/system/$domain" \ || srcdir="$vhosts_d/$domain" mkdir -p $info_plesk/vhosts/$domain/logs for l in error_log proxy_error_log; do [ ! -s "$srcdir/logs/$l" ] || cp_tail $srcdir/logs/$l $info_plesk/vhosts/$domain/logs done cp -fR $srcdir/conf $info_plesk/vhosts/$domain/ 2>/dev/null count=$(expr $count + 1) done ok } get_php_conf() { try "collect php configs" mkdir -p $info_plesk/php find /etc -maxdepth 1 -type f -name "*php*" -exec cp -f {} $info_plesk/php/ \; for p in $(find /etc -maxdepth 1 -type d -name "*php*"); do pushd "$p" >/dev/null find . -type d -exec mkdir -p $info_plesk/php/$(basename $p)/{} \; find . -type f -name "*.ini" -exec cp -f {} $info_plesk/php/$(basename $p)/{} \; find . -type f -name "*.conf" -exec cp -f {} $info_plesk/php/$(basename $p)/{} \; popd >/dev/null done ok } get_plesk_perms() { try "collect plesk permissions" mkdir -p $info_plesk find $root_d -type d -exec ls -ld {} \; \ | awk '{print $1" "$3" "$4" "$5" "$6" "$7" "$8" "$9" "$10" "$11}' \ > $info_plesk/permissions.txt ok } get_pmm_info() { try "collect backup/migration logs" local pmmd='/var/log/plesk/PMM' [ -d "$pmmd" ] || { ok; return; } local dstdir local srcdir dstdir="$info_plesk/PMM" mkdir -p $dstdir local cur_month=`date +"%Y-%m"` local prev_month=`date +"%Y-%m" --date='last month'` pushd "$pmmd" > /dev/null for f in `ls -d *.log *$cur_month* *$prev_month* 2>/dev/null | sort -u`; do cp_tail "$f" "$dstdir" done popd > /dev/null ok } get_db_dumps() { mkdir -p $info_db try "get psa database dump" db_dump psa > $info_db/psa.sql ok try "get apsc database dump" db_dump apsc > $info_db/apsc.sql ok } get_plesk_repair_status() { mkdir -p "$info_plesk" "$root_d/bin/repair" --all -n >"$info_plesk/repair_status.txt" 2> "$info_plesk/repair_status.stderr.txt" } # -------------------------------------------------------------------------------------------- if [ "`id -u`" -ne 0 ]; then echo "$0: This script must be run as root" >&2 echo "Log in as root then run this script again." >&2 echo >&2 exit 1 fi parse_options "$@" cleanup collect "$actions_list" sanitize pack "$output"