Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Two new functions: "Backup" and "Recover" #57

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ functions:
unused packages. Does not accept <input>, but has
a confirmation prompt.

backup: Creates a backup of all installed packages' names. Does not
accept <input>, but includes a confirmation prompt.
You can choose the location of the backup file or use the
default location generated by the script.

recover: Recovers packages from a backup file and replicate
the same environment on another device. Reads each line
of the file and installs the packages listed. Accepts the
backup file as <input>. Includes a confirmation prompt.
You can choose to run an update and a cleaup afterwards.

flags:
--help/-h: Display this page

Expand Down
221 changes: 221 additions & 0 deletions rhino-pkg
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ functions:
unused packages. Does not accept <input>, but has
a confirmation prompt.

backup: Creates a backup of all installed packages' names. Does not
accept <input>, but includes a confirmation prompt.
You can choose the location of the backup file or use the
default location generated by the script.

recover: Recovers packages from a backup file and replicate
the same environment on another device. Reads each line
of the file and installs the packages listed. Accepts the
backup file as <input>. Includes a confirmation prompt.
You can choose to run an update and a cleaup afterwards.


flags:
--help/-h: Display this page

Expand Down Expand Up @@ -96,6 +108,181 @@ function msg() {
echo -e "$input"
}

function back_up() {
local back_up_path=$1
echo -e "${BGreen}Backup location: $back_up_path${NC}"
echo -e "${BGreen}Starting backup process...${NC}"
echo -e "${BGreen}Collecting installed package names...${NC}"
{
echo "[dpkg/apt]"
dpkg-query -f '${Package}\n' -W
echo "[Snap]"
snap list --all | awk 'NR>1 {print $1}'
echo "[Flatpak]"
flatpak list --app --columns=application
echo "[Pacstall]"
pacstall -L
} > "$back_up_path"
echo -e "${BGreen}Backup completed successfully!${NC}"
echo -e "${BGreen}Backup saved to: $back_up_path${NC}"
sha256sum_of_backup=$(sha256sum "$back_up_path" | awk '{print $1}')
echo -e "${BGreen}SHA256: $sha256sum_of_backup${NC}"
}

function back_up_file_check() {
local custom_file_path=$1
if [ -f "$custom_file_path" ]; then
if [[ "$custom_file_path" =~ \.txt$ ]]; then
if [ -w "$custom_file_path" ]; then
echo -e "${BGreen}Using the file: $custom_file_path${NC}"
else
echo -e "${BRed}Error: '$custom_file_path' is not writable. Exiting.${NC}"
exit 1
fi
else
echo -e "${BRed}Error: '$custom_file_path' is not a .txt file. Exiting.${NC}"
exit 1
fi
else
echo -e "${BRed}Error: '$custom_file_path' is not a valid file. Exiting.${NC}"
exit 1
fi
}

function recover_file_check() {
local custom_file_path=$1
if [ -f "$custom_file_path" ]; then
if [[ "$custom_file_path" =~ \.txt$ ]]; then
echo -e "${BGreen}Using the file: $custom_file_path${NC}"
else
echo -e "${BRed}Error: '$custom_file_path' is not a .txt file. Exiting.${NC}"
exit 1
fi
else
echo -e "${BRed}Error: '$custom_file_path' is not a valid file. Exiting.${NC}"
exit 1
fi
}

function recover() {
local local back_up_path=$1
recover_file_check "$back_up_path"

echo -n "Do you want to recover files by downloading packages again (${BRed}WARNING: YOU CANNOT CANCEL THE OPERATION! Internet bandwidth usage warning!${NC})? (${BGreen}y${NC}/${BRed}N${NC}) "
read recover_choice

if [[ "$recover_choice" =~ ^[Yy]$ ]]; then
echo -e "${BGreen}Starting recovery...${NC}"
else
echo -e "${BRed}The operation was cancelled.${NC}"
exit 1
fi

echo -n "Do you want to update first? (${BGreen}y${NC}/${BRed}N${NC}) "
read update_choice

if [[ "$update_choice" =~ ^[Yy]$ ]]; then
echo -e "${BGreen}Starting update...${NC}"
sudo rpk update -y
echo -e "${BGreen}Update completed.${NC}"
else
echo -e "${BRed}Skipping update.${NC}"
fi

mapfile -t lines < "$back_up_path"

failed_dpkg_apt=()
failed_snap=()
failed_flatpak=()
failed_pacstall=()

for line in "${lines[@]}"; do
case "$line" in
"[dpkg/apt]")
echo -e "${BGreen}Recovering dpkg/apt packages...${NC}"
;;
"[Snap]")
echo -e "${BGreen}Recovering Snap packages...${NC}"
;;
"[Flatpak]")
echo -e "${BGreen}Recovering Flatpak packages...${NC}"
;;
"[Pacstall]")
echo -e "${BGreen}Recovering Pacstall packages...${NC}"
;;
*)
if [[ "$line" == *flatpak* ]]; then
if ! sudo flatpak install "$line" -y; then
failed_flatpak+=("$line")
echo -e "${BRed}Failed to install '$line'.${NC}"
else
echo -e "${BGreen}'$line' is installed successfully.${NC}"
fi
elif [[ "$line" == *snap* ]]; then
if ! sudo snap install "$line"; then
echo -e "${BRed}Failed to install '$line'.${NC}"
failed_snap+=("$line")
else
echo -e "${BGreen}'$line' is installed successfully.${NC}"
fi
elif [[ "$line" == *pacstall* ]]; then
if ! pacstall -PI "$line"; then
echo -e "${BRed}Failed to install '$line'.${NC}"
failed_pacstall+=("$line")
else
echo -e "${BGreen}'$line' is installed successfully.${NC}"
fi
else
if ! sudo apt install "$line" -y; then
echo -e "${BRed}Failed to install '$line'.${NC}"
failed_dpkg_apt+=("$line")
else
echo -e "${BGreen}'$line' is installed successfully.${NC}"
fi
fi
;;
esac
done

if [ ${#failed_dpkg_apt[@]} -ne 0 ]; then
echo -e "${BRed}Failed to install the following dpkg/apt packages:${NC}"
for pkg in "${failed_dpkg_apt[@]}"; do
echo -e "${BRed}- $pkg${NC}"
done
fi
if [ ${#failed_snap[@]} -ne 0 ]; then
echo -e "${BRed}Failed to install the following Snap packages:${NC}"
for pkg in "${failed_snap[@]}"; do
echo -e "${BRed}- $pkg${NC}"
done
fi
if [ ${#failed_flatpak[@]} -ne 0 ]; then
echo -e "${BRed}Failed to install the following Flatpak packages:${NC}"
for pkg in "${failed_flatpak[@]}"; do
echo -e "${BRed}- $pkg${NC}"
done
fi
if [ ${#failed_pacstall[@]} -ne 0 ]; then
echo -e "${BRed}Failed to install the following Pacstall packages:${NC}"
for pkg in "${failed_pacstall[@]}"; do
echo -e "${BRed}- $pkg${NC}"
done
fi
echo -n "Do you want to update and cleanup? (${BGreen}y${NC}/${BRed}N${NC}) "
read cleanup_choice
if [[ "$cleanup_choice" =~ ^[Yy]$ ]]; then
echo -e "${BGreen}Starting cleanup...${NC}"
sudo rpk update -y
sudo rpk cleanup
echo -e "${BGreen}Cleanup completed.${NC}"
else
echo -e "${BRed}Skipping cleanup.${NC}"
fi

echo -e "${BGreen}Recovery completed successfully!${NC}"
}


function prompt() {
local input="$1"
local index="$2"
Expand Down Expand Up @@ -193,6 +380,40 @@ case "${1}" in
shift
fi
;;
backup)
if [ "$EUID" -ne 0 ]; then
echo -e "${BRed}The root privileges are required to create the add and to give it the writing permission. Please run with sudo.${NC}"
echo -e "${BGreen}Restarting...$back_up_path${NC}"
exec sudo "$0" "$@"
exit
fi
back_up_path="/rhino-pkg_backup_$(date +%Y%m%d_%H%M%S).txt"
echo -n "The backup file's location: '$back_up_path'
Continue (${BGreen}y${NC}), or choose your own .txt file (${BRed}S${NC})? (${BGreen}y${NC}/${BRed}S${NC}) "
read user_choice
if [[ "$user_choice" =~ ^[Yy]$ ]]; then
echo -e "${BGreen}Creating the file: $back_up_path${NC}"
touch "$back_up_path"
chmod +w "$back_up_path"
back_up_file_check "$back_up_path"
elif [[ "$user_choice" =~ ^[Ss]$ ]]; then
echo -n "Enter your desired file path: "
read custom_file_path
back_up_file_check "$custom_file_path"
back_up_path="$custom_file_path"
else
echo -e "${BRed}Invalid choice.${NC}"
echo "$help_flag"
exit 1
fi
back_up "$back_up_path"
exit 0
;;
recover)
shift
recover "$1"
exit 0
;;
-h | --help)
echo "$help_flag"
exit 0
Expand Down