Files

159 lines
3.6 KiB
Bash
Executable File

#!/usr/bin/env bash
download_ram() {
local requested_size="$1"
echo "Downloading $requested_size GiB of RAM"
local total_needed=$(( requested_size + 4 ))
if check_root_space "$total_needed"; then
echo ""
else
exit 1
fi
if actually_download_the_ram "$requested_size"; then
echo "Done, run (sudo) swapon --show to see your new RAM"
else
echo "Failed"
exit 1
fi
}
actually_download_the_ram() {
local size_gb="$1"
local dir="/var/swap"
# Create directory to save swapfiles
mkdir -p "$dir" || {
echo "Failed to create $dir" >&2; return 1;
}
# Find the next available swapfile name
local i=0
local swapfile
while :; do
swapfile="$dir/swapfile$i"
[ -e "$swapfile" ] || break
i=$((i + 1))
done
echo "Downloading $swapfile (${size_gb}G) of RAM"
# Use fallocate (or dd in case no fallocate is installed) to create swapfile
if ! fallocate -l "${size_gb}G" "$swapfile" 2>/dev/null; then
echo "fallocate failed, falling back to dd (this may take a while)..."
if ! dd if=/dev/zero of="$swapfile" bs=1G count="$size_gb" status=progress; then
echo "fallocate/dd failed in creating swapfile" >&2
rm -f "$swapfile"
return 1
fi
fi
# Set file to read and write
chmod 600 "$swapfile" || {
echo "chmod failed" >&2;
rm -f "$swapfile"; return 1;
}
# Turn the file to swap type
if ! mkswap "$swapfile"; then
echo "mkswap failed" >&2
rm -f "$swapfile"
return 1
fi
# Run swapon to enable swap
if ! swapon "$swapfile"; then
echo "swapon failed" >&2
return 1
fi
# Check if swap is running and write into fstab file
if swapon --show | awk 'NR>1 {print $1}' | grep -qx "$swapfile"; then
echo "Successfully 'downloaded' ${size_gb}G of RAM into: $swapfile"
if ! grep -q -E "^[[:space:]]*${swapfile}[[:space:]]" /etc/fstab; then
printf "%s\n" "${swapfile} none swap defaults 0 0" >> /etc/fstab
else
echo "Entry for $swapfile already exists in /etc/fstab, not adding duplicate"
fi
return 0
else
echo "Swapfile created but not active. Check 'swapon --show'" >&2
return 1
fi
}
check_root_space() {
local need_gib=$1
local free_gib
free_gib=$(df -B1G --output=avail / | tail -n1 | tr -d ' ')
if (( free_gib >= need_gib )); then
return 0
else
echo "Your system does not have enough space to download the RAM"
echo "Need at least ${need_gib}GiB free, but only ${free_gib}GiB is available." >&2
return 1
fi
}
# -- Start of Script --
# Check if ran as sudo
if [[ "$EUID" -ne 0 ]]; then
echo "This script must be run as root (try: sudo $0)" >&2
exit 1
fi
# Check if system is mounted on a ext4 filesystem
fs_type=$(findmnt -no FSTYPE / 2>/dev/null)
if [[ "$fs_type" != "ext4" ]]; then
echo "Error: /var is on '$fs_type'. This script only supports systems mounted on ext4." >&2
exit 1
fi
# Message + handle input
echo "Please select how much RAM you want to download:"
echo "1) 4GiB of RAM"
echo "2) 8GiB of RAM"
echo "3) 16GiB of RAM"
echo "4) Custom amount"
echo "Plese note you need at least the chosen amount of space on your drive + 4GiB"
echo ""
read -r -p "Enter your choice (1-4): " choice
case "$choice" in
1)
value=4
;;
2)
value=8
;;
3)
value=16
;;
4)
read -r -p "Enter a custom amount in GiB (1-16): " custom
if [[ ! "$custom" =~ ^[0-9]+$ ]] || (( custom < 1 || custom > 16 )); then
echo "Invalid amount. Please enter a whole number between 1 and 16."
exit 1
fi
value=$custom
;;
*)
echo "Invalid choice."
exit 1
;;
esac
download_ram "$value"