-
Notifications
You must be signed in to change notification settings - Fork 0
/
updater.sh
executable file
·322 lines (277 loc) · 10.2 KB
/
updater.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
#!/usr/bin/env bash
# shellcheck disable=SC2034,SC1091,SC2086,SC2320
# Basic semi-automatic update/upgrade script
# Made by Jiab77 / 2022 - 2024
#
# Supported distro:
# - Debian / Ubuntu
# - RHEL / CentOS / Rocky Linux
# - Arch Linux / CachyOS
# - Termux (experimental)
#
# This version contains an experimental features:
# - ZFS Snapshots
# - FlatPak support
#
# Breaking changes:
# - As of version 0.8.0, you must use 'sudo' except for Termux.
#
# Version 0.8.1
# Options
[[ -r $HOME/.debug ]] && set -o xtrace || set +o xtrace
# Colors
NC="\033[0m"
NL="\n"
BLUE="\033[1;34m"
YELLOW="\033[1;33m"
GREEN="\033[1;32m"
RED="\033[1;31m"
WHITE="\033[1;37m"
PURPLE="\033[1;35m"
# Config
USE_PARU=true # Only for Arch Linux based distros
ENABLE_FLATPAK=true
ENABLE_ZFS_SNAPSHOTS=true
CREATE_SNAPSHOT_FILE=true
# Internals
BIN_FLATPAK=$(command -v flatpak 2>/dev/null)
BIN_ZFS=$(command -v zfs-snap-mgr 2>/dev/null)
# Overrides
[[ -z $BIN_FLATPAK ]] && ENABLE_FLATPAK=false
[[ -z $BIN_ZFS ]] && ENABLE_ZFS_SNAPSHOTS=false
# Functions
function get_version() {
grep -m1 "# Version" $0 | awk '{ print $3 }'
}
function die() {
echo -e "${NL}${WHITE}Error: ${RED}$*${NC}${NL}" >&2
exit 255
}
function print_usage() {
echo -e "${NL}Usage: $(basename "$0") [flags] - Automatically download and install latest updates."
echo -e "${NL}Flags:"
echo -e " -h | --help\t\tPrint this message and exit"
echo -e " -v | --version\tPrint version and exit"
echo
exit
}
function print_version() {
echo -e "\nVersion: $(get_version)\n"
exit
}
function create_pre_update_snapshot() {
if [[ $ENABLE_ZFS_SNAPSHOTS == true && ! -r /tmp/.before-update-snapshot-done ]]; then
echo -e "${NL}${YELLOW}Making a snapshot of the system before updating...${NC}${NL}"
zfs-snap-mgr create --debug --recursive --name="before-update" --no-header && touch /tmp/.before-update-snapshot-done
if [[ $CREATE_SNAPSHOT_FILE == true ]]; then
echo -e "${NL}${YELLOW}Writing snapshot file...${NC}${NL}"
zfs-snap-mgr send --debug --recursive --incremental --no-header
fi
fi
}
function create_post_update_snapshot() {
if [[ $ENABLE_ZFS_SNAPSHOTS == true && ! -r /tmp/.after-update-snapshot-done ]]; then
echo -e "${NL}${YELLOW}Making a snapshot of the system after updating...${NC}${NL}"
zfs-snap-mgr create --debug --recursive --name="after-update" --no-header && touch /tmp/.after-update-snapshot-done
if [[ $CREATE_SNAPSHOT_FILE == true ]]; then
echo -e "${NL}${YELLOW}Writing snapshot file...${NC}${NL}"
zfs-snap-mgr send --debug --recursive --incremental --no-header
fi
fi
}
function update_flatpak() {
local STD_USER ; STD_USER="$(id -u 1000 -n)" # Assuming that standard user has UID 1000
if [[ $ENABLE_FLATPAK == true ]]; then
echo -e "${NL}${BLUE}Updating FlatPak installed applications...${NC}${NL}"
sudo -u $STD_USER $BIN_FLATPAK update -y
fi
}
function update_ubuntu() {
BIN=$(command -v apt 2>/dev/null)
[[ -z $BIN ]] && die "You must have 'apt' installed to run this script."
echo -e "${NL}${BLUE}Refresh package cache...${NC}${NL}"
$BIN update --fix-missing -y
echo -e "${NL}${BLUE}Display available updates...${NC}${NL}"
$BIN list --upgradable
echo -e "${NL}${BLUE}Initializing update process...${NC}${NL}"
for I in {5..1} ; do echo "Start in $I seconds..." ; sleep 1 ; done
echo -e "${NL}${BLUE}Applying updates...${NC}${NL}"
$BIN dist-upgrade -y --allow-downgrades
echo -e "${NL}${BLUE}Removing old packages...${NC}${NL}"
$BIN autoremove --purge -y
}
function update_redhat() {
BIN_DNF=$(command -v dnf 2>/dev/null)
BIN_YUM=$(command -v yum 2>/dev/null)
[[ -z $BIN_DNF && -n $BIN_YUM ]] && BIN=$BIN_YUM || BIN=$BIN_DNF
[[ -z $BIN ]] && die "You must have at least 'yum' or 'dnf' installed to run this script."
echo -e "${NL}${BLUE}Refresh package cache...${NC}${NL}"
$BIN makecache
echo -e "${NL}${BLUE}Display available updates...${NC}${NL}"
$BIN check-update
echo -e "${NL}${BLUE}Initializing update process...${NC}${NL}"
for I in {5..1} ; do echo "Start in $I seconds..." ; sleep 1 ; done
echo -e "${NL}${BLUE}Applying updates...${NC}${NL}"
$BIN update -y
}
function update_archlinux() {
local STD_USER ; STD_USER="$(id -u 1000 -n)"
BIN_PARU=$(command -v paru 2>/dev/null)
BIN_PACMAN=$(command -v pacman 2>/dev/null)
[[ -z $BIN_PARU || $USE_PARU == false ]] && BIN=$BIN_PACMAN || BIN=$BIN_PARU
[[ -z $BIN ]] && die "You must have at least 'pacman' or 'paru' installed to run this script."
echo -e "${NL}${BLUE}Cleaning package cache...${NC}"
if [[ $USE_PARU == true ]]; then
sudo -u $STD_USER $BIN -Scc --color always --noconfirm
else
$BIN -Scc --color always --noconfirm
fi
echo -e "${NL}${BLUE}Refresh package cache...${NC}${NL}"
if [[ $USE_PARU == true ]]; then
sudo -u $STD_USER $BIN -Sy --color always
else
$BIN -Sy --color always
fi
echo -e "${NL}${BLUE}Display available updates...${NC}${NL}"
if [[ $USE_PARU == true ]]; then
sudo -u $STD_USER $BIN -Qu --color always
else
$BIN -Qu --color always
fi
RET_CODE_CHECK=$?
if [[ $RET_CODE_CHECK -ne 0 ]]; then
echo -e "${NL}User cancelled update process, leaving...${NL}"
exit $RET_CODE_CHECK
fi
echo -e "${NL}${BLUE}Initializing update process...${NC}${NL}"
for I in {5..1} ; do echo "Start in $I seconds..." ; sleep 1 ; done
create_pre_update_snapshot
echo -e "${NL}${BLUE}Applying updates...${NC}${NL}"
if [[ $USE_PARU == true ]]; then
sudo -u $STD_USER $BIN -Syuu --color always --noconfirm
else
$BIN -Syuu --color always --noconfirm
fi
RET_CODE_UPDATE=$?
if [[ $RET_CODE_UPDATE -ne 0 ]]; then
echo -e "${NL}${YELLOW}Something wrong happened, retrying with confirmations enabled...${NC}${NL}"
if [[ $USE_PARU == true ]]; then
sudo -u $STD_USER $BIN -Syuu --color always
else
$BIN -Syuu --color always
fi
RET_CODE_UPDATE_RETRY=$?
fi
if [[ $RET_CODE_UPDATE_RETRY -ne 0 ]]; then
die "Something is blocking the update process, please run it manually."
fi
update_flatpak
create_post_update_snapshot
}
function update_termux() {
BIN=$(command -v apt 2>/dev/null)
[[ -z $BIN ]] && die "You must have 'apt' installed to run this script."
echo -e "${NL}${BLUE}Refresh package cache...${NC}${NL}"
pkg update -y
echo -e "${NL}${BLUE}Display available updates...${NC}${NL}"
$BIN list --upgradable
echo -e "${NL}${BLUE}Initializing update process...${NC}${NL}"
for I in {5..1} ; do echo "Start in $I seconds..." ; sleep 1 ; done
echo -e "${NL}${BLUE}Applying updates...${NC}${NL}"
pkg upgrade -y
echo -e "${NL}${BLUE}Removing old packages...${NC}${NL}"
$BIN autoremove --purge -y
echo -e "${NL}${BLUE}Cleaning packages cache...${NC}${NL}"
pkg autoclean
}
function check_reboot() {
# Check if reboot is required
echo -e "${NL}${BLUE}Checking if reboot is required...${NC}${NL}"
# Select proper reboot check
case $DISTRO in
"debian"|"ubuntu"|"ubuntu debian")
# Reboot test for debian / ubuntu based hosts
if [[ -s /var/run/reboot-required ]]; then
cat /var/run/reboot-required
# Reboot test for pop_os
elif [[ -r /var/run/reboot-required && $(wc -l < /var/run/reboot-required) -eq 0 ]]; then
echo -e "${YELLOW}** Reboot required **${NC}${NL}"
else
echo -e "${WHITE}Nothing to do.${NC}${NL}" ; exit 0
fi
;;
"redhat"|"rhel fedora"|"rhel centos fedora"|"rancheros")
# Reboot test for redhat based hosts
if [[ -n $(command -v needs-restarting 2>/dev/null) ]]; then
needs-restarting -r
else
echo -e "${WHITE}Nothing to do.${NC}${NL}" ; exit 0
fi
;;
"arch"|"cachyos")
# Reboot test for archlinux based hosts
if [[ $(pacman -Q linux-cachyos 2>/dev/null | cut -d " " -f 2) > $(uname -r | sed -e 's/-cachyos//') ]]; then
echo -e "${YELLOW}** Reboot required **${NC}${NL}"
else
echo -e "${WHITE}Nothing to do.${NC}${NL}" ; exit 0
fi
;;
"termux")
echo -e "${YELLOW}** Running on mobile phone **${NC}${NL}${YELLOW}Relaunch the app should be enough.${NC}${NL}"
;;
*) die "Unable to find proper reboot check for '${WHITE}${DISTRO}${RED}'." ;;
esac
}
function init_update() {
# Show machine hostname
echo -e "${NL}${WHITE}Running on ${GREEN}$(hostname -f)${WHITE}...${NC}"
# Show detected system
echo -e "${NL}${WHITE}Operating System: ${YELLOW}${PRETTY_NAME}${WHITE}${NC}"
# Select proper function
case $DISTRO in
"debian"|"ubuntu"|"ubuntu debian")
update_ubuntu
update_flatpak
check_reboot
;;
"redhat"|"rhel fedora"|"rhel centos fedora"|"rancheros")
update_redhat
update_flatpak
check_reboot
;;
"arch"|"cachyos")
update_archlinux
check_reboot
;;
"termux")
update_termux
;;
*) die "OS '${WHITE}${DISTRO}${RED}' not supported." ;;
esac
}
# OS-Release
[[ -r /etc/os-release ]] && source /etc/os-release
# Fix empty 'DISTRO' variable
if [[ -n $ID_LIKE ]]; then
DISTRO=$ID_LIKE
else
DISTRO=$ID
fi
# Add 'termux' support
if [[ -z $DISTRO && $(printenv | grep -ci "termux") -ne 0 ]]; then
DISTRO="termux"
PRETTY_NAME="Termux"
fi
# Script header
echo -e "${NL}${BLUE}Basic ${PURPLE}${PRETTY_NAME}${BLUE} semi-automatic update/upgrade script - ${GREEN}v$(get_version)${NC}"
# Args
[[ $1 == "-h" || $1 == "--help" ]] && print_usage
[[ $1 == "-v" || $1 == "--version" ]] && print_version
# Checks
[[ $# -gt 1 ]] && die "Too many arguments."
[[ -z $DISTRO ]] && die "Unable to detect your operating system."
if [[ ! $DISTRO == "termux" ]]; then
[[ $(id -u) -ne 0 ]] && die "You must run this script as root or with '${YELLOW}sudo${RED}'."
fi
# Main
init_update