linux-server-tools/swap-management/autoswap.sh

198 lines
6.9 KiB
Bash

#!/bin/bash
## autoswap.sh
## version 1.0
## Automatically add and remove SWAP files based on system load.
## Author: Ze'ev Schurmann
## License: GPL3.0 or later
## Git Repo: https://git.zaks.web.za/thisiszeev/linux-server-tools
## Usage:
##
## 1. Copy the file autoswap.conf to /etc/autoswap/autoswap.conf
## 2. Set owner and group to root and edit the contents of the file to fit your
## your use case.
## 3. Copy the file autoswap.service to /etc/systemd/system/autoswap.service
## 4. Set owner and group to root
## 5. Copy autoswap.sh, addswap.sh and remswap.sh to the / folder.
## 6. Set owner and group to root and make executable for root only (744)
##
## (as root)
## systemctl daemon-reload
## systemctl start autoswap.service
## systemctl enable autoswap.service
##
## (with sudo)
## sudo systemctl daemon-reload
## sudo systemctl start autoswap.service
## sudo systemctl enable autoswap.service
##
## The script will monitor your available memory and SWAP resources and use
## addswap.sh and remswap.sh to add and remove SWAP fles depending on your
## requirements and settings in /etc/autoswap/autoswap.conf.
##
## If you make changes to /etc/autoswap/autoswap.conf then you need to restart the
## autoswap.service using:
##
## (as root)
## systemctl restart autoswap.service
##
## (with sudo)
## sudo systemctl restart autoswap.service
##
## A log file can be found at /var/log/swapmanagement.log
## Why did I make these two scripts?
##
## I use Debian as my daily driver (I've been using Linux in some for or the other
## as my daily driver since 2006). I also us Debian for all my servers. I also
## running a webhosting business (https://www.zaks.web.za) and in my 20+ years in
## the game, I have learned that... 1. VPS's do not come with SWAP, but sometimes
## you need a bit of SWAP to handle heavy load. 2. SWAP files can be added and
## removed on the fly (no reboot required), however a SWAP partition, not so simple.
##
## On my daily driver machine, I also create a lot of digital artwork. I recently
## found myself rendering a finished artfile that was 9.5GB (24000px by 13700px)
## in Gimp, and half way through I started running out of RAM and SWAP. So I
## quickly created the needed SWAP file, and Gimp was able to finish the render
## without crashing.
## Plans for the future:
##
## I am planning to make a configurable service file that can be run in the
## background to automatically create more SWAP files when your server/computer is
## under load, and remove excess SWAP files when the server/computer is no longer
## under load.
## Do you have a script idea?
## If you have an idea for a useful server script for selfhost/homelab environments,
## please start a chat with me on Reddit /u/thisiszeev and share your idea. I might
## just make it a reality, and give you credit in the relevant README.md file.
## Donations
##
## Please consider making me small donation. Even though my scripts are open source
## and free to use, I still need to eat. And the occasional bottle of wine also goes
## down well.
##
## $5 buys me a cup of coffee
## $10 buys me a nice burger
## $20 buys me a bottle of wine
## Anything above that will be awesome as well.
##
## You can send me a donation via Paypal https://www.paypal.com/paypalme/thisiszeev
##
## Drop me a message on Reddit if you do make a donation. u/thisiszeev
##
## Support is only offered freely to those who donate $20 or more.
##
## Your donation contributes to further development.
##
## If you need a custom script, contact me on Reddit for pricing.
function echolog {
echo "$1"
echo "$(date) > autoswap > $1" >> /var/log/swapmanagement.log
if [[ $(wc -l < /var/log/swapmanagement.log) -gt 300 ]]; then
cat /var/log/swapmanagement.log | tail -n 250 > /var/log/swapmanagement.temp && mv /var/log/swapmanagement.temp /var/log/swapmanagement.log
fi
}
echolog "Initializing..."
threshold_minimum=512
swap_file_size=2048
required_swap_files=1
minimum_free_storage=4096
check_interval=30
if [[ -f /etc/autoswap/autoswap.conf ]]; then
source /etc/autoswap/autoswap.conf
echolog "/etc/autoswap/autoswap.conf found... settings applied."
else
echolog "/etc/autoswap/autoswap.conf not found... default settings applied."
fi
swap_file_size_gb=$(($swap_file_size/1024))
if [[ $(($swap_file_size%1024)) -eq 0 ]]; then
echolog "Converting {swap_file_size} from MB to GB, rounding up..."
((swap_file_size_gb++))
swap_file_size=$(($swap_file_size_gb*1014))
fi
echolog "{threshold_minimum} = ${threshold_minimum}MB"
echolog "{swap_file_size} = ${swap_file_size}MB"
echolog "{required_swap_files} = ${required_swap_files}"
echolog "{minimum_free_storage} = ${minimum_free_storage}MB"
echolog "{check_interval} = ${check_interval}s"
swap_file_size_gb=$(($swap_file_size/1024))
interval=$check_interval
while true; do
#echo "Doing checks..."
ram_array=($(free | grep "^Mem:"))
swap_array=($(free | grep "^Swap:"))
root_drive_array=($(df | grep "/$"))
free_ram=$((${ram_array[6]}/1024))
free_swap=$((${swap_array[3]}/1024))
free_combined=$(($free_ram+$free_swap))
free_root_drive=$((${root_drive_array[3]}/1024))
total_ram=${ram_array[1]}
total_swap=${swap_array[1]}
required_free_root_drive=$(($swap_file_size+$minimum_free_storage))
swap_files=$(swapon --show | grep "file" | wc -l)
#echo "Root Drive Free Space : ${free_root_drive}MB"
#echo "Req. Space for more SWAP : ${required_free_root_drive}MB"
#echo "RAM Memory Free Space : ${free_ram}MB"
#echo "SWAP Memory Free Space : ${free_swap}MB"
#echo "Total Combined Free Mem : ${free_combined}MB"
#echo "No. of Active SWAP Files : $swap_files"
#echo "Threshold Minimum Space : ${threshold_minimum}MB"
#echo "SWAP File Allocation Size : ${swap_file_size}MB"
if [[ $swap_files -lt $required_swap_files ]]; then
echolog "Number of active SWAP files is less than required minimum..."
bash addswap.sh $swap_file_size_gb
interval=1
elif [[ $free_combined -lt $threshold_minimum ]] && [[ $free_root_drive -gt $required_free_root_drive ]] && [[ $swap_files -ge $required_swap_files ]]; then
echolog "System Memory and SWAP resources running below ${threshold_minimum}MB..."
bash addswap.sh $swap_file_size_gb
interval=$check_interval
elif [[ $free_combined -lt $threshold_minimum ]] && [[ $free_root_drive -le $required_free_root_drive ]] && [[ $swap_files -ge $required_swap_files ]]; then
echolog "CRITICAL > System Memory and SWAP resources running below ${threshold_minimum}MB but insufficient free space on root drive. [${free_root_drive}MB - requires $(($swap_file_size+$minimum_free_storage))MB]"
interval=$(($check_interval*10))
elif [[ $free_combined -gt $(($threshold_minimum+$swap_file_size)) ]] && [[ $swap_files -gt $required_swap_files ]]; then
echolog "System Memory and SWAP resource have improved."
bash remswap.sh
interval=1
else
interval=$check_interval
fi
#echo "Check Interval : ${interval}s"
sleep ${interval}s
done