info_distro.sh 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. #!/bin/bash
  2. # LinuxGSM info_distro.sh module
  3. # Author: Daniel Gibbs
  4. # Contributors: http://linuxgsm.com/contrib
  5. # Website: https://linuxgsm.com
  6. # Description: Variables providing useful info on the Operating System such as disk and performace info.
  7. # Used for command_details.sh, command_debug.sh and alert.sh.
  8. functionselfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
  9. ### Game Server pid
  10. if [ "${status}" == "1" ]; then
  11. gameserverpid="$(tmux list-sessions -F "#{session_name} #{pane_pid}" | grep "^${sessionname} " | awk '{print $NF}')"
  12. if [ "${engine}" == "source" ]; then
  13. srcdslinuxpid="$(ps -ef | grep -v grep | grep "${gameserverpid}" | grep srcds_linux | awk '{print $2}')"
  14. elif [ "${engine}" == "goldsrc" ]; then
  15. hldslinuxpid="$(ps -ef | grep -v grep | grep "${gameserverpid}" | grep hlds_linux | awk '{print $2}')"
  16. fi
  17. fi
  18. ### Distro information
  19. ## Distro
  20. # Returns architecture, kernel and distro/os.
  21. arch="$(uname -m)"
  22. kernel="$(uname -r)"
  23. # Distro Name - Ubuntu 16.04 LTS
  24. # Distro Version - 16.04
  25. # Distro ID - ubuntu
  26. # Distro Codename - xenial
  27. # Gathers distro info from various sources filling in missing gaps.
  28. distro_info_array=( os-release lsb_release hostnamectl debian_version redhat-release )
  29. for distro_info in "${distro_info_array[@]}"; do
  30. if [ -f "/etc/os-release" ]&&[ "${distro_info}" == "os-release" ]; then
  31. distroname="$(grep "PRETTY_NAME" /etc/os-release | awk -F\= '{gsub(/"/,"",$2);print $2}')"
  32. distroversion="$(grep "VERSION_ID" /etc/os-release | awk -F\= '{gsub(/"/,"",$2);print $2}')"
  33. # Special var for rhel like distros to removed point in number e.g 8.4 to just 8.
  34. distroversionrh="$(sed -nr 's/^VERSION_ID="([0-9]*).+?"/\1/p' /etc/os-release)"
  35. distroid="$(grep "ID=" /etc/os-release | grep -v _ID | awk -F\= '{gsub(/"/,"",$2);print $2}')"
  36. distroidlike="$(grep "ID_LIKE=" /etc/os-release | grep -v _ID | awk -F\= '{gsub(/"/,"",$2);print $2}')"
  37. distrocodename="$(grep "VERSION_CODENAME" /etc/os-release | awk -F\= '{gsub(/"/,"",$2);print $2}')"
  38. elif [ "$(command -v lsb_release 2>/dev/null)" ]&&[ "${distro_info}" == "lsb_release" ]; then
  39. if [ -z "${distroname}" ];then
  40. distroname="$(lsb_release -sd)"
  41. elif [ -z "${distroversion}" ]; then
  42. distroversion="$(lsb_release -sr)"
  43. elif [ -z "${distroid}" ]; then
  44. distroid="$(lsb_release -si)"
  45. elif [ -z "${distrocodename}" ]; then
  46. distrocodename="$(lsb_release -sc)"
  47. fi
  48. elif [ "$(command -v hostnamectl 2>/dev/null)" ]&&[ "${distro_info}" == "hostnamectl" ]; then
  49. if [ -z "${distroname}" ];then
  50. distroname="$(hostnamectl | grep "Operating System" | sed 's/Operating System: //g')"
  51. fi
  52. elif [ -f "/etc/debian_version" ]&&[ "${distro_info}" == "debian_version" ]; then
  53. if [ -z "${distroname}" ]; then
  54. distroname="Debian $(cat /etc/debian_version)"
  55. elif [ -z "${distroversion}" ]; then
  56. distroversion="$(cat /etc/debian_version)"
  57. elif [ -z "${distroid}" ]; then
  58. distroid="debian"
  59. fi
  60. elif [ -f "/etc/redhat-release" ]&&[ "${distro_info}" == "redhat-release" ]; then
  61. if [ -z "${distroname}" ]; then
  62. distroname="$(cat /etc/redhat-release)"
  63. elif [ -z "${distroversion}" ]; then
  64. distroversion="$(rpm -qa \*-release | grep -Ei "oracle|redhat|centos|fedora" | cut -d"-" -f3)"
  65. elif [ -z "${distroid}" ]; then
  66. distroid="$(awk '{print $1}' /etc/redhat-release)"
  67. fi
  68. fi
  69. done
  70. # some RHEL based distros use 8.4 instead of just 8.
  71. if [[ "${distroidlike}" == *"rhel"* ]]||[ "${distroid}" == "rhel" ]; then
  72. distroversioncsv="${distroversionrh}"
  73. else
  74. distroversioncsv="${distroversion}"
  75. fi
  76. # Check if distro supported by distro vendor.
  77. if [ "$(command -v distro-info 2>/dev/null)" ]; then
  78. distrosunsupported="$(distro-info --unsupported)"
  79. distrosunsupported_array=( "${distrosunsupported}" )
  80. for distrounsupported in "${distrosunsupported_array[@]}"; do
  81. if [ "${distrounsupported}" == "${distrocodename}" ]; then
  82. distrosupport=unsupported
  83. break
  84. else
  85. distrosupport=supported
  86. fi
  87. done
  88. else
  89. distrosupport=unknown
  90. fi
  91. echo "${distrosupport}"
  92. ## Glibc version
  93. # e.g: 1.17
  94. glibcversion="$(ldd --version | sed -n '1s/.* //p')"
  95. ## tmux version
  96. # e.g: tmux 1.6
  97. if [ ! "$(command -V tmux 2>/dev/null)" ]; then
  98. tmuxv="${red}NOT INSTALLED!${default}"
  99. tmuxvdigit="0"
  100. else
  101. tmuxvdigit="$(tmux -V | sed "s/tmux //" | sed -n '1 p' | tr -cd '[:digit:]')"
  102. if [ "${tmuxvdigit}" -lt "16" ]; then
  103. tmuxv="$(tmux -V) (>= 1.6 required for console log)"
  104. else
  105. tmuxv="$(tmux -V)"
  106. fi
  107. fi
  108. if [ "$(command -V java 2>/dev/null)" ]; then
  109. javaversion="$(java -version 2>&1 | grep "version")"
  110. fi
  111. if [ "$(command -v mono 2>/dev/null)" ]; then
  112. monoversion="$(mono --version 2>&1 | grep -Po '(?<=version )\d')"
  113. fi
  114. ## Uptime
  115. uptime="$(</proc/uptime)"
  116. uptime=${uptime/[. ]*/}
  117. minutes="$(( uptime/60%60 ))"
  118. hours="$(( uptime/60/60%24 ))"
  119. days="$(( uptime/60/60/24 ))"
  120. ### Performance information
  121. ## Average server load
  122. load="$(uptime|awk -F 'load average: ' '{ print $2 }')"
  123. ## CPU information
  124. cpumodel="$(awk -F: '/model name/ {name=$2} END {print name}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//')"
  125. cpucores="$(awk -F: '/model name/ {core++} END {print core}' /proc/cpuinfo)"
  126. cpufreqency="$(awk -F: '/cpu MHz/ {freq=$2} END {print freq}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//')"
  127. # CPU usage of the game server pid
  128. if [ -n "${gameserverpid}" ]; then
  129. cpuused="$(ps --forest -o pcpu -g "${gameserverpid}"|awk '{s+=$1} END {print s}')"
  130. cpuusedmhz="$(echo "${cpufreqency} * ${cpuused} / 100" | bc)"
  131. fi
  132. ## Memory information
  133. # Available RAM and swap.
  134. # Newer distros can use numfmt to give more accurate results.
  135. if [ "$(command -v numfmt 2>/dev/null)" ]; then
  136. # Issue #2005 - Kernel 3.14+ contains MemAvailable which should be used. All others will be calculated.
  137. # get the raw KB values of these fields.
  138. physmemtotalkb="$(grep MemTotal /proc/meminfo | awk '{print $2}')"
  139. physmemfreekb="$(grep ^MemFree /proc/meminfo | awk '{print $2}')"
  140. physmembufferskb="$(grep ^Buffers /proc/meminfo | awk '{print $2}')"
  141. physmemcachedkb="$(grep ^Cached /proc/meminfo | awk '{print $2}')"
  142. physmemreclaimablekb="$(grep ^SReclaimable /proc/meminfo | awk '{print $2}')"
  143. # check if MemAvailable Exists.
  144. if grep -q ^MemAvailable /proc/meminfo; then
  145. physmemactualfreekb="$(grep ^MemAvailable /proc/meminfo | awk '{print $2}')"
  146. else
  147. physmemactualfreekb="$((physmemfreekb+physmembufferskb+physmemcachedkb))"
  148. fi
  149. # Available RAM and swap.
  150. physmemtotalmb="$((physmemtotalkb/1024))"
  151. physmemtotal="$(numfmt --to=iec --from=iec --suffix=B "${physmemtotalkb}K")"
  152. physmemfree="$(numfmt --to=iec --from=iec --suffix=B "${physmemactualfreekb}K")"
  153. physmemused="$(numfmt --to=iec --from=iec --suffix=B "$((physmemtotalkb-physmemfreekb-physmembufferskb-physmemcachedkb-physmemreclaimablekb))K")"
  154. physmemavailable="$(numfmt --to=iec --from=iec --suffix=B "${physmemactualfreekb}K")"
  155. physmemcached="$(numfmt --to=iec --from=iec --suffix=B "$((physmemcachedkb+physmemreclaimablekb))K")"
  156. swaptotal="$(numfmt --to=iec --from=iec --suffix=B "$(grep ^SwapTotal /proc/meminfo | awk '{print $2}')K")"
  157. swapfree="$(numfmt --to=iec --from=iec --suffix=B "$(grep ^SwapFree /proc/meminfo | awk '{print $2}')K")"
  158. swapused="$(numfmt --to=iec --from=iec --suffix=B "$(($(grep ^SwapTotal /proc/meminfo | awk '{print $2}')-$(grep ^SwapFree /proc/meminfo | awk '{print $2}')))K")"
  159. # RAM usage of the game server pid
  160. # MB
  161. if [ "${gameserverpid}" ]; then
  162. memused="$(ps --forest -o rss -g "${gameserverpid}" | awk '{s+=$1} END {print s}'| awk '{$1/=1024;printf "%.0f",$1}{print $2}')"
  163. # %
  164. pmemused="$(ps --forest -o %mem -g "${gameserverpid}" | awk '{s+=$1} END {print s}')"
  165. fi
  166. else
  167. # Older distros will need to use free.
  168. # Older versions of free do not support -h option.
  169. if [ "$(free -h > /dev/null 2>&1; echo $?)" -ne "0" ]; then
  170. humanreadable="-m"
  171. else
  172. humanreadable="-h"
  173. fi
  174. physmemtotalmb="$(free -m | awk '/Mem:/ {print $2}')"
  175. physmemtotal="$(free ${humanreadable} | awk '/Mem:/ {print $2}')"
  176. physmemfree="$(free ${humanreadable} | awk '/Mem:/ {print $4}')"
  177. physmemused="$(free ${humanreadable} | awk '/Mem:/ {print $3}')"
  178. oldfree="$(free ${humanreadable} | awk '/cache:/')"
  179. if [ "${oldfree}" ]; then
  180. physmemavailable="n/a"
  181. physmemcached="n/a"
  182. else
  183. physmemavailable="$(free ${humanreadable} | awk '/Mem:/ {print $7}')"
  184. physmemcached="$(free ${humanreadable} | awk '/Mem:/ {print $6}')"
  185. fi
  186. swaptotal="$(free ${humanreadable} | awk '/Swap:/ {print $2}')"
  187. swapused="$(free ${humanreadable} | awk '/Swap:/ {print $3}')"
  188. swapfree="$(free ${humanreadable} | awk '/Swap:/ {print $4}')"
  189. fi
  190. ### Disk information
  191. ## Available disk space on the partition.
  192. filesystem="$(LC_ALL=C df -hP "${rootdir}" | tail -n 1 | awk '{print $1}')"
  193. totalspace="$(LC_ALL=C df -hP "${rootdir}" | tail -n 1 | awk '{print $2}')"
  194. usedspace="$(LC_ALL=C df -hP "${rootdir}" | tail -n 1 | awk '{print $3}')"
  195. availspace="$(LC_ALL=C df -hP "${rootdir}" | tail -n 1 | awk '{print $4}')"
  196. ## LinuxGSM used space total.
  197. rootdirdu="$(du -sh "${rootdir}" 2> /dev/null | awk '{print $1}')"
  198. if [ -z "${rootdirdu}" ]; then
  199. rootdirdu="0M"
  200. fi
  201. ## LinuxGSM used space in serverfiles dir.
  202. serverfilesdu="$(du -sh "${serverfiles}" 2> /dev/null | awk '{print $1}')"
  203. if [ -z "${serverfilesdu}" ]; then
  204. serverfilesdu="0M"
  205. fi
  206. ## LinuxGSM used space total minus backup dir.
  207. rootdirduexbackup="$(du -sh --exclude="${backupdir}" "${serverfiles}" 2> /dev/null | awk '{print $1}')"
  208. if [ -z "${rootdirduexbackup}" ]; then
  209. rootdirduexbackup="0M"
  210. fi
  211. ## Backup info
  212. if [ -d "${backupdir}" ]; then
  213. # Used space in backups dir.
  214. backupdirdu="$(du -sh "${backupdir}" | awk '{print $1}')"
  215. # If no backup dir, size is 0M.
  216. if [ -z "${backupdirdu}" ]; then
  217. backupdirdu="0M"
  218. fi
  219. # number of backups set to 0 by default.
  220. backupcount=0
  221. # If there are backups in backup dir.
  222. if [ "$(find "${backupdir}" -name "*.tar.gz" | wc -l)" -ne "0" ]; then
  223. # number of backups.
  224. backupcount="$(find "${backupdir}"/*.tar.gz | wc -l)"
  225. # most recent backup.
  226. lastbackup="$(ls -1t "${backupdir}"/*.tar.gz | head -1)"
  227. # date of most recent backup.
  228. lastbackupdate="$(date -r "${lastbackup}")"
  229. # no of days since last backup.
  230. lastbackupdaysago="$(( ( $(date +'%s') - $(date -r "${lastbackup}" +'%s') )/60/60/24 ))"
  231. # size of most recent backup.
  232. lastbackupsize="$(du -h "${lastbackup}" | awk '{print $1}')"
  233. fi
  234. fi
  235. # Network Interface name
  236. netint=$(${ipcommand} -o addr | grep "${ip}" | awk '{print $2}')
  237. netlink=$(${ethtoolcommand} "${netint}" 2>/dev/null| grep Speed | awk '{print $2}')
  238. # External IP address
  239. if [ -z "${extip}" ]; then
  240. extip="$(curl --connect-timeout 10 -s https://api.ipify.org 2>/dev/null)"
  241. exitcode=$?
  242. # Should ifconfig.co return an error will use last known IP.
  243. if [ ${exitcode} -eq 0 ]; then
  244. if [[ "${extip}" != *"DOCTYPE"* ]]; then
  245. echo -e "${extip}" > "${tmpdir}/extip.txt"
  246. else
  247. if [ -f "${tmpdir}/extip.txt" ]; then
  248. extip="$(cat "${tmpdir}/extip.txt")"
  249. else
  250. fn_print_error_nl "Unable to get external IP"
  251. fi
  252. fi
  253. else
  254. if [ -f "${tmpdir}/extip.txt" ]; then
  255. extip="$(cat "${tmpdir}/extip.txt")"
  256. else
  257. fn_print_error_nl "Unable to get external IP"
  258. fi
  259. fi
  260. fi
  261. # Alert IP address
  262. if [ "${displayip}" ]; then
  263. alertip="${displayip}"
  264. elif [ "${extip}" ]; then
  265. alertip="${extip}"
  266. else
  267. alertip="${ip}"
  268. fi
  269. # Steam Master Server - checks if detected by master server.
  270. if [ -z "${displaymasterserver}" ]; then
  271. if [ "$(command -v jq 2>/dev/null)" ]; then
  272. if [ "${ip}" ]&&[ "${port}" ]; then
  273. if [ "${steammaster}" == "true" ]||[ "${commandname}" == "DEV-QUERY-RAW" ]; then
  274. # Will query server IP addresses first.
  275. for queryip in "${queryips[@]}"; do
  276. masterserver="$(curl --connect-timeout 10 -m 3 -s "https://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr=${queryip}&format=json" | jq --arg port "${port}" --arg queryport "${queryport}" '.response.servers[] | select((.gameport == ($port|tonumber) or (.gameport == ($queryport|tonumber)))) | .addr' | wc -l 2>/dev/null)"
  277. done
  278. # Should that not work it will try the external IP.
  279. if [ "${masterserver}" == "0" ]; then
  280. masterserver="$(curl --connect-timeout 10 -m 3 -s "https://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr=${extip}&format=json" | jq --arg port "${port}" --arg queryport "${queryport}" '.response.servers[] | select((.gameport == ($port|tonumber) or (.gameport == ($queryport|tonumber)))) | .addr' | wc -l 2>/dev/null)"
  281. fi
  282. if [ "${masterserver}" == "0" ]; then
  283. displaymasterserver="false"
  284. else
  285. displaymasterserver="true"
  286. fi
  287. fi
  288. fi
  289. fi
  290. fi
  291. # Sets the SteamCMD glibc requirement if the game server requirement is less or not required.
  292. if [ "${appid}" ]; then
  293. if [ "${glibc}" = "null" ]||[ -z "${glibc}" ]||[ "$(printf '%s\n'${glibc}'\n' "2.14" | sort -V | head -n 1)" != "2.14" ]; then
  294. glibc="2.14"
  295. fi
  296. fi
  297. # Gather Port Info using ss
  298. ssinfo="$(ss -tuplwn)"