-
Notifications
You must be signed in to change notification settings - Fork 5
/
eos-update
executable file
·412 lines (358 loc) · 15.3 KB
/
eos-update
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
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
#!/bin/bash
# Package updater for EndeavourOS and Arch.
# Handles db lock file, keyrings, syncing, and optionally AUR with given AUR helper.
echo2() { echo "$@" >&2 ; }
printf2() { printf "$@" >&2 ; }
WARN() { echo2 "==> $progname: warning: $1"; }
DIE() { echo2 "==> $progname: error: $1"; exit 1; }
SetHelper() {
for helper in "$@" "$EOS_AUR_HELPER" "$EOS_AUR_HELPER_OTHER" yay paru pacman ; do
which "${helper%% *}" &>/dev/null && return 0
done
WARN "AUR helper not found"
helper=pacman
}
Cmd() { # Show a command, run it, and exit on issues.
echo2 "==>" "$@"
"$@" || DIE "'$*' failed."
}
MirrorCheckResult() {
local ml="$1"
local ret=0
echo2 "==> $ml contains:"
echo2 " available mirrors: ${#supported[@]}"
echo2 " unavailable mirrors: ${#unsupported[@]}"
[ ${#unsupported[@]} -gt 0 ] && printf "%s\n" "${unsupported[@]}" | sed 's|^[0-9]*:| -> Server = |' >&2
if [ ${#unsupported[@]} -eq 0 ] && [ ${#supported[@]} -gt 0 ] ; then # create the return code, 0=success, 1=fail
return 0
else
if [ ${#unsupported[@]} -gt 0 ] ; then
EditMirrorlist $ml "${unsupported[0]%%:*}" # second parameter is the line number
else
EditMirrorlist $ml
fi
return 1
fi
}
Hardware-x86_64() { [ $(eos_GetArch) = x86_64 ] || DIE "sorry, this implementation supports only x86_64 environment"; }
CheckYourArchMirrorlist() {
Hardware-x86_64
local url="https://archlinux.org/mirrorlist/?use_mirror_status=on"
local lm
local all_working_mirrors
local local_mirrors
local supported=()
local unsupported=()
# get working mirrors from the Arch mirrorlist page
all_working_mirrors=$(curl --fail -Lsm 30 "$url") || DIE "failed to fetch available mirrors (curl code $?)"
[ "$all_working_mirrors" ] || DIE "-> archlinux.org/mirrorlist failed"
readarray -t all_working_mirrors <<< $(echo "$all_working_mirrors" | tail -n +7 | grep "^#Server = " | awk '{print $NF}')
# get mirrors from local mirrorlist
readarray -t local_mirrors <<< $(grep -n "^[ \t]*Server[ \t]*=[ \t]*" $aml | sed 's|[ \t]*Server[ \t]*=[ \t]*||')
for lm in "${local_mirrors[@]}" ; do
if printf "%s\n" "${all_working_mirrors[@]}" | grep "${lm#*:}" >/dev/null ; then
supported+=("${lm#*:}")
else
unsupported+=("$lm") # includes the line number: "nr:https://..."
fi
done
MirrorCheckResult $aml
}
CheckYourEndeavourosMirrorlist() {
Hardware-x86_64
local -r mirrors=( # for downloading the latest endeavouros-mirrorlist package
https://mirror.alpix.eu/endeavouros/repo/endeavouros/x86_64 # Germany
https://mirror.moson.org/endeavouros/repo/endeavouros/x86_64 # Germany
https://mirrors.gigenet.com/endeavouros/repo/endeavouros/x86_64 # United States
)
local url data
local -r tmpfile=/tmp/eos-ml.p
local good_mirrors local_mirrors
local lm
local unsupported=() supported=()
# local continent=""
# [ -x /bin/location ] && continent="$(/bin/location list-countries --show-continent | awk '{print $2}')"
# case "$continent" in
# NA) mirrors=("${mirrors_NA[@]}" "${mirrors_EU[@]}") ;;
# *) mirrors=("${mirrors_EU[@]}" "${mirrors_NA[@]}") ;;
# esac
for url in "${mirrors[@]}" ; do
data=$(curl -Lsm 30 -o- $url)
if [ $? -eq 0 ] && [ "$data" ] ; then
data=$(echo "$data" | grep "endeavouros-mirrorlist.*\.sig") # the line that contains the pkg file name
data=${data#*\"} # skip prefix
data=${data%%\.sig*} # skip suffix
if [ "$data" ] ; then
unsupported=()
supported=()
url+="/$data"
curl -Lsm 30 -o$tmpfile $url
good_mirrors=$(tar xvf $tmpfile ${eml:1} -O 2>/dev/null | grep "^Server = " | sed 's|^Server = ||')
rm -f $tmpfile
local_mirrors=$(grep -n "^[ \t]*Server[ \t]*=[ \t]*" $eml | sed 's|[ \t]*Server[ \t]*=[ \t]*||')
for lm in $local_mirrors ; do
if [ "$(echo "$good_mirrors" | grep "${lm#*:}")" ] ; then
supported+=(${lm#*:})
else
unsupported+=($lm) # includes the line number: "nr:https://..."
fi
done
MirrorCheckResult $eml
return
fi
fi
done
[ "$data" ] || DIE "sorry, cannot fetch the latest EndeavourOS mirrorlist data"
}
EditMirrorlist() {
local list="$1" # arch, endeavouros, or the full path of the mirrorlist
local linenr="$2" # for the editor; may be empty
local editor=/usr/bin/rnano
[ -x $editor ] || { WARN "package 'nano' is required for editing $list"; return 1; }
case "$list" in
arch | $aml) list="$aml" ;;
endeavouros | $eml) list="$eml" ;;
"") DIE "supported mirrorlists: arch, endeavouros" ;;
esac
if [ "$linenr" ] ; then
if [ -z "${linenr//[0-9]/}" ] ; then
linenr="+$linenr"
else
WARN "detected line number '$linenr' in $list is flawed!"
linenr=""
fi
fi
RunInTerminal "echo 'Starting to edit $list:'; sudo $editor $linenr $list"
}
ResetKeyrings() {
Cmd sudo mv /etc/pacman.d/gnupg /root/pacman-key.bak.$(date +%Y%m%d-%H%M).by.$progname
Cmd sudo pacman-key --init
Cmd sudo pacman-key --populate archlinux endeavouros
Cmd sudo pacman -Syy --noconfirm archlinux-keyring endeavouros-keyring
Cmd sudo pacman -Syu
echo2 "Keyrings reset."
exit 0
}
ClearDatabases() {
Cmd sudo rm /var/lib/pacman/sync/*
echo2 "Package databases cleared."
exit 0
}
OptionCheck() {
case "$1" in
--nvidia) IsSupportedOS "$1" || return 1 ;;
esac
return 0
}
Options() {
local opts
local lopts="aur,clear-databases,dump-options,keyrings-reset,nvidia,nvidia-auto,no-keyring,no-sync,helper:"
lopts+=",min-free-bytes:,pacdiff,paru,yay,pacman,help"
lopts+=",show-only-fixed,show-upstream-news,check-mirrors-arch,check-mirrors-eos,check-mirrors,edit-mirrorlist:"
local sopts="h"
opts="$(LANG=C /usr/bin/getopt -o=$sopts --longoptions $lopts --name "$progname" -- "$@")" || {
echo2 "==> more info with command: $progname --help"
exit 1
}
eval set -- "$opts"
local ret=0
while true ; do
case "$1" in
--check-mirrors) CheckYourEndeavourosMirrorlist || ((ret++))
CheckYourArchMirrorlist || ((ret++))
exit $ret
;;
--check-mirrors-arch) CheckYourArchMirrorlist || ((ret++))
exit $ret
;;
--check-mirrors-eos) CheckYourEndeavourosMirrorlist || ((ret++))
exit $ret
;;
--edit-mirrorlist) EditMirrorlist "$2"; exit 0 ;;
--nvidia) OptionCheck "$1" && nvidia=yes ;;
--no-keyring) keyring=no ;;
--no-sync) sync=":" ;;
--keyrings-reset) ResetKeyrings ;;
--clear-databases) ClearDatabases ;;
--min-free-bytes) min_free_bytes="$2" ; shift ;;
--helper) SetHelper "$2" ; shift ;;
--aur) SetHelper ;;
--paru | --yay | --pacman) SetHelper "${1/--/}" ;;
--pacdiff) pacdiffer="$pacdiffer_cmd_default" ;;
--show-only-fixed)
which arch-audit >/dev/null && arch-audit -u
exit
;;
--show-upstream-news)
local br=$(eos_select_browser)
[ "$br" ] && $br https://archlinux.org/news
exit
;;
--dump-options)
lopts="${lopts//:/}"
lopts="--${lopts//,/ --}"
sopts="${sopts//:/}"
sopts="$(echo "$sopts" | sed -E 's|([a-z])| -\1|g')"
echo $lopts $sopts
exit 0
;;
-h | --help) Usage; exit 0 ;;
--) shift ; break ;;
esac
shift
done
}
Usage() {
cat <<EOF
$progname is a package updater for EndeavourOS and Arch.
$progname is implemented as a wrapper around commands pacman and optionally yay/paru.
Essentially runs commands 'pacman -Syu' and optionally 'yay -Sua' or 'paru -Sua'.
$progname includes (by default) special help in the following situations:
- A dangling pacman db lock file (/var/lib/pacman/db.lck).
- Disk space availability for updates (with a configurable minimum space).
- Keyring package updating before updating other packages.
- Running the 'sync' command after update.
Optional help:
- Can clear package databases in case of constant problems with them.
- Can reset keyrings in case of constant problems with them.
- Can check the validity of the locally configured lists of mirrors.
- Updates AUR packages (with option --helper, see Usage below).
- Ad hoc check for Nvidia GPU driver vs. kernel updates (non-dkms only).
Usage: $progname [options]
Options:
--help, -h This help.
--check-mirrors Check files $eml and $aml
for unsupported mirrors.
This may be useful when one or more mirrors start failing unexpectedly.
Note: only x86_64 hardware is supported.
--check-mirrors-eos Check file $eml for unsupported mirrors.
--check-mirrors-arch Check file $aml for unsupported mirrors.
--edit-mirrorlist Edit chosen mirrorlist file. Supported: arch, endeavouros. No default.
--nvidia Check also nvidia driver vs. kernel updates. Useful only with the Nvidia GPU.
--clear-databases Clears package database files.
Use this only if package database issues constantly make system update fail.
--keyrings-reset Resets Arch and EndeavourOS keyrings.
Use this only if keyring issues constantly make system update fail.
--no-keyring Do not try to update keyrings first.
--no-sync Do not run 'sync' after update.
--show-only-fixed Show only packages that have already been fixed (runs: arch-audit -u) and exit.
--show-upstream-news Show the news page of the upstream site and exit.
--pacdiff Run eos-pacdiff in the end of $progname. See also EOS_UPDATE_PACDIFFER
in file /etc/eos-script-lib-yad.conf.
--helper AUR helper name. Supported: yay, paru, pacman.
Default: pacman
Other AUR helpers supporting option -Sua like yay should work as well.
--paru Same as --helper=paru.
--yay Same as --helper=yay.
--aur Uses the AUR helper configured in /etc/eos-script-lib-yad.conf.
--pacman Same as --helper=pacman. Default. (Note: pacman does not support AUR directly).
--min-free-bytes Minimum amount of free space (in bytes) that the root partition should have
before updating. Otherwise a warning message will be displayed.
Default: $min_free_bytes
Tip: create an alias in file ~/.bashrc for $progname to have the options you need, for example:
# Enable Nvidia update check, disable sync execution, use paru for AUR updates.
alias $progname='$progname --nvidia --no-sync --paru'
EOF
}
IsSupportedOS() {
if [ -x /usr/bin/eos-kernel-nvidia-update-check ] ; then
return 0
else
WARN "the Nvidia check requires package 'eos-bash-shared' fully installed, option $1 ignored."
return 1
fi
}
DiskSpace() {
local available=$(findmnt / -nbo avail)
local min=$min_free_bytes
if [ $available -lt $min ] ; then
{
WARN "your root partition (/) has only $available bytes of free space."
if [ $(du -b -d0 /var/cache/pacman/pkg | awk '{print $1}') -gt $min ] ; then
printf "\nFor example, cleaning up the package cache may help.\n"
printf "Command 'sudo paccache -rk1' would do this:"
paccache -dk1
printf "Command 'sudo paccache -ruk0' would do this:"
paccache -duk0
echo ""
fi
} >&2
fi
}
echo2blue() { echo2 "${BLUE}$1${RESET}" ; }
echo2green() { echo2 "${GREEN}$1${RESET}" ; }
Main() {
local progname="${0##*/}"
source /usr/share/endeavouros/scripts/eos-script-lib-yad || return 1
local helper="pacman"
local min_free_bytes=$((1000 * 1000 * 1000)) # default: 1 GB
local lock=/var/lib/pacman/db.lck
local rmopt=f
local pacdiffer="" # default = "" because pacdiff can change critical files
local -r pacdiffer_cmd_default="eos-pacdiff --quiet"
local subopts=()
local afteropts=()
local keyring=yes # user may disable keyring check with --no-keyring
local nvidia=no # user may enable Nvidia check with --nvidia
local nvidia_opt=""
local sync="sync"
local -r eml=/etc/pacman.d/endeavouros-mirrorlist
local -r aml=/etc/pacman.d/mirrorlist
local -r RED=$'\e[0;91m'
local -r GREEN=$'\e[0;92m'
local -r BLUE=$'\e[0;94m'
local -r MAGENTA=$'\e[0;95m'
local -r RESET=$'\e[0m'
Options "$@"
[ "$EOS_UPDATE_PACDIFFER" ] && pacdiffer="$EOS_UPDATE_PACDIFFER"
[ $nvidia = yes ] && subopts+=(--nvidia)
[ $keyring = yes ] && subopts+=(--keyrings)
echo2blue "$progname: package updater with additional features"
DiskSpace
if [ -e $lock ] && fuser $lock &>/dev/null ; then
rmopt=i
fi
local cmdfile=$(mktemp "$HOME/.$progname.helper.XXX")
case "$helper" in
pacman)
echo2green "Updating native apps..."
cat <<EOF > "$cmdfile"
#!/bin/bash
eos_update_sudofunc() {
rm -$rmopt $lock
if [ ! -e $lock ] ; then
pacman -Sy || return
${progname}-extras ${subopts[*]} || return
pacman -Su || return
$pacdiffer
$sync
fi
}
eos_update_sudofunc
EOF
;;
*)
echo2green "Updating native and AUR apps..."
local helper2="/usr/bin/sudo -u $LOGNAME $helper -Sua"
cat <<EOF > "$cmdfile"
#!/bin/bash
eos_update_sudofunc() {
rm -$rmopt $lock
if [ ! -e $lock ] ; then
pacman -Sy || return
${progname}-extras ${subopts[*]} || return
pacman -Su || return
$helper2 || return # Note: 'paru' returns 1 on error, but 'yay' does not!
$pacdiffer
$sync
fi
}
eos_update_sudofunc
EOF
;;
esac
chmod u+x,go-rwx "$cmdfile"
sudo "$cmdfile"
rm -f "$cmdfile"
}
Main "$@"