#!/usr/bin/env bash # ╭────────────────────────────────────────────────────╮ # │ _ _ _ _ owo │ # │ | |__ ___| |_ __ ___ _ __| |__ ___ | |_ │ # │ | '_ \ / _ \ | '_ \ / _ \ '__| '_ \ / _ \| __| │ # │ | | | | __/ | |_) | __/ | | |_) | (_) | |_ │ # │ |_| |_|\___|_| .__/ \___|_| |_.__/ \___/ \__| │ # │ |_| │ # ╰────────────────────────────────────────────────────╯ # helperbot - synth.download's all in one script for managing everything. beep! # ============================================================================= # ╭─────────────────────────╮ # │ functions and variables │ # ╰─────────────────────────╯ # unset everything - ensure we're working with a clean state unset synth_help && unset synth_upgrade && unset synth_backup && unset synth_vacuum && unset synth_invalid && unset synth_current_system # exit immediately if an error occurs somewhere to prevent Fucked Up Shit set -e # defining colors for text output if [[ -t 1 ]]; then red=$( tput setaf 1 ); green=$( tput setaf 2 ); yellow=$( tput setaf 3 ); blue=$( tput setaf 4 ); pink=$( tput setaf 5 ); cyan=$( tput setaf 6 ); gray=$( tput setaf 8 ); normal=$( tput sgr 0 ); fi # attempt to detect the system based on hostname function detect_system { if [ "$(hostname)" = "phosphorus" ]; then synth_current_system=phosphorus echo "Detected ${blue}phosphorus${normal}." elif [ "$(hostname)" = "neptunium" ]; then synth_current_system=neptunium echo "Detected ${blue}neptunium${normal}." elif [ "$(hostname)" = "cerium" ]; then synth_current_system=cerium echo "Detected ${blue}cerium${normal}." elif [ "$(hostname)" = "synthnix" ]; then synth_current_system=synthnix echo "Detected ${blue}synthnix${normal}." else echo "${red}Failed to detect system.${normal}" echo "We're most likely being run in an environment we don't know of." echo "Exiting..." exit 1 fi } # base system upgrade - generic steps for debian/ubuntu based systems function base_system_upgrade { echo "${cyan}Upgrading base system.${normal}" echo "${blue}Doing standard apt upgrade...${normal}" apt update apt upgrade -y echo "${blue}Try upgrading distro base...${normal}" apt dist-upgrade -y echo "${blue}Apt cleanup...${normal}" apt clean echo "${green}Base system upgraded!.${normal}" } # docker container updates # reusable steps to update containers - upgrade_docker_container [/srv/docker] [name_of_service_or_folder] [compose.yaml] function upgrade_docker_container { if [ -d "$1/$2" ]; then # pull the container cd "$1"/"$2" && docker compose -f "$1/$2/$3" pull docker compose -f "$1/$2/$3" down && docker compose -f "$1/$2/$3" up -d else echo "${red}docker:${normal} Folder $1/$2 does not exist." fi } # psql vacuuming # reusable step to vacuum databases - postgres_vacuum [postgres-db-1] [user_and_db_name] [password] function postgres_vacuum { docker exec -it "$1" /bin/bash -c "POSTGRES_PASSWORD="$3" psql -U "$2" -d "$2" -c 'VACUUM ANALYZE;'" } # postgres_vacuum_self [postgres-db-1] function postgres_vacuum_self { docker exec -it "$1" /bin/bash -c "psql -U postgres -c 'VACUUM ANALYZE;'" } # psql backup # reusable step to backup databases - postgres_backup [postgres-db-1] [user_and_db_name] [output_name] [$backup_working_directory] function postgres_backup { docker exec "$1" /bin/bash -c "pg_dump "$2" --username "$2" > "$3".sql" docker cp "$1":/$3.sql $4/$3/$3.sql docker exec "$1" /bin/bash -c "rm "$3".sql" } # redis snapshot # tells redis to make a snapshot - redis_snapshot [whatever-redis-1] function redis_snapshot { docker exec $1 redis-cli SAVE } # backup - create folder and copy # step that combines the process of making folders and copying files for backup # backup_create_copy ["source files"] [subpath/to/folder] [$backup_working_directory] function backup_create_copy { mkdir -p $3/$2 cp -r $1 $3/$2 } # ╭───────────────────╮ # │ defining messages │ # ╰───────────────────╯ # header function header { echo "╭────────────────╮" echo "│ helperbot! owo │" echo "╰────────────────╯" echo sleep 1 # grace period } # help info function info_help { echo "${blue}Usage:${normal} helperbot [-h|-u|-b|-v]" echo echo "${green}Options:${normal}" echo "-h, --help Print this help page." echo "-u, --upgrade Update the system." echo "-b, --backup Backup the system." echo "-v, --vacuum Vacuum the postgresql databases." echo echo "helperbot automatically knows what to do based on this system's hostname! Beep!" echo echo "${yellow}This script is still generally a work-in-progress.${normal}" echo "Report breakage or suggestions or improvments or whatever to here:" echo "https://forged.synth.download/synth.download/synth.download" echo } # ============================================================================= # ╭──────────────╮ # │ main program │ # ╰──────────────╯ # check to see if we're running as root #if [[ ${UID} != 0 ]]; then # echo "${red}helperbot must be run as root or with sudo permissions!${normal} thanks!" # exit 1 #fi # display the header header # evaluate arguments and set environment variables to enable each command and see what should be executed while [ -n "$1" ]; do case "$1" in -h | --help) # display help info synth_help=1;; -u | --upgrade) # upgrade system synth_upgrade=1 if [ ! -v synth_current_system ]; then detect_system fi;; -b | --backup) # backup system synth_backup=1 if [ ! -v synth_current_system ]; then detect_system fi;; -v | --vacuum) # vacuum database synth_vacuum=1 if [ ! -v synth_current_system ]; then detect_system fi;; *) # invalid option was given synth_invalid=1;; esac shift 1 done # say invalid option if we get an invalid option (duh) if [ -v synth_invalid ]; then echo "${red}Error:${normal} Invalid option." echo "\"helperbot is very confused... >~<\"" echo echo "Run with --help to see all options." exit 1 fi # runs if no option was specified; throw up the help menu # otherwise: also run if specified if [[ ! -v synth_args_exist || -v synth_help ]]; then info_help exit 0 fi # ╭──────────────╮ # │ upgrade step │ # ╰──────────────╯ if [ -v synth_upgrade ]; then #timestamp=$(date +'%Y%m%d%H%M%S') #synth_upgrade_log=/tmp/upgrade-output-${timestamp}.txt echo "${blue}upgrade:${normal} Running full system upgrade for ${green}${synth_current_system}${normal}." #echo "Upgrade will be logged into ${yellow}${synth_upgrade_log}${normal} if needed." # logging doesn't work properly - check on later if [ "$synth_current_system" = "phosphorus" ]; then # phosphorus # apt/system related upgrade base_system_upgrade # docker upgrade_docker_container "/srv/docker" "sharkey" "compose.yaml" upgrade_docker_container "/srv/docker" "iceshrimp" "compose.yaml" upgrade_docker_container "/srv/docker" "mastodon" "compose.yaml" upgrade_docker_container "/srv/docker" "pds" "compose.yaml" # done echo "${green}System upgrade finished! beep!~${normal}" elif [ "$synth_current_system" = "neptunium" ]; then # neptunium # apt/system related upgrade base_system_upgrade # docker upgrade_docker_container "/srv/docker" "mailserver" "compose.yaml" upgrade_docker_container "/srv/docker" "ejabberd" "compose.yaml" upgrade_docker_container "/srv/docker" "zitadel" "compose.yaml" upgrade_docker_container "/srv/docker" "forgejo" "compose.yaml" upgrade_docker_container "/srv/docker" "forgejo" "compose-runner.yaml" upgrade_docker_container "/srv/docker" "freshrss" "compose.yaml" upgrade_docker_container "/srv/docker" "vaultwarden" "compose-runner.yaml" upgrade_docker_container "/srv/docker" "ask-js" "compose.yaml" # done echo "${green}System upgrade finished! beep!~${normal}" elif [ "$synth_current_system" = "cerium" ]; then # cerium # apt/system related upgrade base_system_upgrade # docker upgrade_docker_container "/srv/docker" "redlib" "compose.yaml" upgrade_docker_container "/srv/docker" "safetwitch" "compose.yaml" # done echo "${green}System upgrade finished! beep!~${normal}" echo "${red}Rebooting system.${normal}" sleep 1 && systemctl reboot elif [ "$synth_current_system" = "synthnix" ]; then # synthnix # apt/system related upgrade base_system_upgrade # done echo "${green}System upgrade finished! beep!~${normal}" fi fi # ╭─────────────╮ # │ backup step │ # ╰─────────────╯ if [ -v synth_backup ]; then if [ -v synth_vacuum ]; then echo "${yellow}NOTICE:${normal} You've also passed in the --vacuum command. Note that upgrading also automatically vacuums the databases beforehand." sleep 1 fi echo "${blue}backup:${normal} Running full system backup for ${green}${synth_current_system}${normal}." if [ "$synth_current_system" = "phosphorus" ]; then # phosphorus # variables backup_local_folder=/srv/docker backup_working_directory=/var/backups/phosphorus backup_output_tar=phosphorus.tar backup_media_output_tar=media_backups.tar # refers to the old local fedi media before s3 migration # external files containing secrets export $(grep -v '^#' /etc/secrets/b2.env | xargs) export $(grep -v '^#' /etc/secrets/postgres.env | xargs) # initial mkdir -p $backup_working_directory # database vacuuming echo "${blue}Vacuuming postgres databases...${normal}" postgres_vacuum_self postgres-db-1 postgres_vacuum postgres-db-1 misskey ${SHARKEY_POSTGRES_PASSWORD} postgres_vacuum postgres-db-1 iceshrimp ${ICESHRIMP_POSTGRES_PASSWORD} postgres_vacuum postgres-db-1 mastodon ${MASTODON_POSTGRES_PASSWORD} # ============================================================================= # backup files - sharkey echo "${blue}Pulling in Sharkey...${normal}" mkdir -p $backup_working_directory/sharkey/.config # database postgres_backup postgres-db-1 misskey sharkey $backup_working_directory # redis redis_snapshot sharkey-redis-1 cp -r $backup_local_folder/sharkey/redis $backup_working_directory/sharkey # configs, extra cp -r $backup_local_folder/sharkey/compose.yaml $backup_working_directory/sharkey cp -r $backup_local_folder/sharkey/.config $backup_working_directory/sharkey # ============================================================================= # iceshrimp echo "${blue}Pulling in Iceshrimp...${normal}" mkdir -p $backup_working_directory/iceshrimp/config # database postgres_backup postgres-db-1 iceshrimp iceshrimp $backup_working_directory # configs, extra cp -r $backup_local_folder/iceshrimp/compose.yaml $backup_working_directory/iceshrimp cp -r $backup_local_folder/iceshrimp/config $backup_working_directory/iceshrimp # ============================================================================= # mastodon echo "${blue}Pulling in Mastodon...${normal}" mkdir -p $backup_working_directory/mastodon/.config # database postgres_backup postgres-db-1 mastodon mastodon $backup_working_directory # redis redis_snapshot mastodon-redis-1 cp -r $backup_local_folder/mastodon/redis $backup_working_directory/mastodon # configs, extra cp -r $backup_local_folder/mastodon/compose.yaml $backup_working_directory/mastodon cp -r $backup_local_folder/mastodon/.config $backup_working_directory/mastodon # ============================================================================= # pds echo "${blue}Pulling in PDS...${normal}" mkdir -p $backup_working_directory/pds # there isn't a native way to "backup" the pds, so we shut it off and copy it docker compose -f $backup_local_folder/pds/compose.yaml down cp -r $backup_local_folder/pds/pds $backup_working_directory/pds docker compose -f $backup_local_folder/pds/compose.yaml up -d # configs, extra cp -r $backup_local_folder/pds/compose.yaml $backup_working_directory/pds # ============================================================================= # unset secrets unset $(grep -v '^#' /etc/secrets/b2.env | sed -E 's/(.*)=.*/\1/' | xargs) unset $(grep -v '^#' /etc/secrets/postgres.env | sed -E 's/(.*)=.*/\1/' | xargs) elif [ "$synth_current_system" = "neptunium" ]; then # neptunium postgres_vacuum_self postgres-db-1 elif [ "$synth_current_system" = "cerium" ]; then # cerium postgres_vacuum_self postgres-db-1 elif [ "$synth_current_system" = "synthnix" ]; then # synthnix # as synthnix doesn't really include much and serves as a place for members # we just need to back up the home directory here # # WIP fi echo "${green}System backup finished! beep!~${normal}" fi #if [[ -v system_vacuum ]]; then # echo "${yellow}NOTICE:${normal} You've also passed in the --vacuum command. Note that upgrading also automatically vacuums the databases beforehand." # sleep 1 #fi # unset everything unset synth_help && unset synth_upgrade && unset synth_backup && unset synth_vacuum && unset synth_invalid && unset synth_current_system