-
-
Notifications
You must be signed in to change notification settings - Fork 24
/
setup-linux
executable file
Β·430 lines (356 loc) Β· 11.3 KB
/
setup-linux
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
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
#!/usr/bin/env bash
function setup_linux() (
source "$DOROTHY/sources/bash.bash"
__require_array 'mapfile'
source "$(type -P eval-helper)"
# =====================================
# Arguments
function help {
cat <<-EOF >/dev/stderr
ABOUT:
Configure Linux to our expectations.
USAGE:
setup-linux <install|update|clean>
EOF
if test "$#" -ne 0; then
echo-error "$@"
fi
return 22 # EINVAL 22 Invalid argument
}
# process
local item action=''
while test "$#" -ne 0; do
item="$1"
shift
case "$item" in
'--help' | '-h') help ;;
'--'*) help "An unrecognised flag was provided: $item" ;;
*)
if test -z "$action"; then
action="$item"
else
help "An unrecognised argument was provided: $item"
fi
;;
esac
done
# assert compatibility
if ! is-linux; then
help 'This command is only purposeful on Linux systems, which you are not running.'
fi
# assert action
if test -z "$action"; then
help "No action provided."
fi
# generate log title
local title
title="$(__uppercase_first_letter -- "$action") Linux"
# =====================================
# Configuration
source "$DOROTHY/sources/config.sh"
# setup.bash provides:
local APK_INSTALL=()
local APT_INSTALL=()
local APT_UNINSTALL=()
local AUR_INSTALL=()
local FLATPAK_INSTALL=()
local RPM_INSTALL=()
local SNAP_INSTALL=()
local ZYPPER_INSTALL=()
local APT_ADD=() # deprecated, use APT_INSTALL
local APT_REMOVE=() # deprecated, use APT_UNINSTALL
load_dorothy_config 'setup.bash'
# deprecations
if test "${#APT_ADD[@]}" -ne 0; then
APT_INSTALL+=("${APT_ADD[@]}")
dorothy-config 'setup.bash' -- \
--field='APT_ADD' --replace= \
--field='APT_INSTALL' --array="$(__print_lines "${APT_INSTALL[@]}" | sort --ignore-case | uniq)"
fi
if test "${#APT_REMOVE[@]}" -ne 0; then
APT_UNINSTALL+=("${APT_REMOVE[@]}")
dorothy-config 'setup.bash' -- \
--field='APT_REMOVE' --replace= \
--field='APT_UNINSTALL' --array="$(__print_lines "${APT_UNINSTALL[@]}" | sort --ignore-case | uniq)"
fi
# adjustments
mapfile -t APK_INSTALL < <(dorothy-config --packages-var='APK_INSTALL' -- "${APK_INSTALL[@]}")
mapfile -t APT_INSTALL < <(dorothy-config --packages-var='APT_INSTALL' -- "${APT_INSTALL[@]}")
mapfile -t APT_UNINSTALL < <(dorothy-config --packages-var='APT_UNINSTALL' -- "${APT_UNINSTALL[@]}")
mapfile -t AUR_INSTALL < <(dorothy-config --packages-var='AUR_INSTALL' -- "${AUR_INSTALL[@]}")
mapfile -t FLATPAK_INSTALL < <(dorothy-config --packages-var='FLATPAK_INSTALL' -- "${FLATPAK_INSTALL[@]}")
mapfile -t RPM_INSTALL < <(dorothy-config --packages-var='RPM_INSTALL' -- "${RPM_INSTALL[@]}")
mapfile -t SNAP_INSTALL < <(dorothy-config --packages-var='SNAP_INSTALL' -- "${SNAP_INSTALL[@]}")
mapfile -t ZYPPER_INSTALL < <(dorothy-config --packages-var='ZYPPER_INSTALL' -- "${ZYPPER_INSTALL[@]}")
# =====================================
# Helpers
# APK
# https://wiki.alpinelinux.org/wiki/Package_management#Upgrade_a_Running_System
# DNF
# https://linuxcommandlibrary.com/man/dnf.html
# Flatpak
# https://manpages.org/flatpak/1
# https://manpages.org/flatpak-update
# `full-upgrade` is the same as `dist-upgrade` apparently, which is a more automatic/comprehensive upgrader compared to `apt-get upgrade`
# Pacman
# https://archlinux.org/pacman/pacman.8.html
# Pamac
# https://linuxcommandlibrary.com/man/pamac
# Snap
# https://manpages.org/snap
# Zypper
# https://www.mankier.com/8/zypper
# -------------------------------------
# Update References
# pamac/flatpak do not have update without upgrade
local updates=(
'apk'
'apk'
'dnf'
'pacman'
'urpmi'
'yum'
'zypper'
)
function do_apk_update {
apk update
}
function do_apt_update {
sudo-helper -- apt-get update -y
}
function do_dnf_update {
sudo-helper -- dnf check-update --assumeyes
}
function do_pacman_update {
# init the local database
# this is needed on systems which pacman was installed
sudo-helper -- pacman-key --init
# refresh the local database
sudo-helper -- pacman --noconfirm --refresh --sync
}
function do_urpmi_update {
# https://wiki.mageia.org/en/URPMI#Basic_commands:_Install.2C_remove.2C_update
sudo-helper -- urpmi.update -a
}
function do_yum_update {
sudo-helper -- yum check-update -y || :
# ^ it always returns exit code 100
}
function do_zypper_update {
sudo-helper -- zypper --non-interactive --gpg-auto-import-keys refresh
}
# -------------------------------------
# Upgrade Packages
# pacman can only upgrade specific packages, not all packages
local upgrades=(
'apk'
'apt'
'dnf'
'flatpak'
'pamac'
'snap'
'urpmi'
'yum'
'zypper'
)
function do_apk_upgrade {
apk upgrade
}
function do_apt_upgrade {
sudo-helper -- apt-get full-upgrade -y
}
function do_urpmi_upgrade {
sudo-helper -- urpmi --auto-update --auto
}
function do_dnf_upgrade {
# --refresh Set metadata as expired before running the command.
# -y, --assumeyes Automatically answer yes for all questions.
# -b, --best Try the best available package versions in transactions. Specifically during dnf upgrade, which by default skips over updates that can not be installed for dependency reasons, the switch forces DNF to only consider the latest packages. When running into packages with broken dependencies, DNF will fail giving a reason why the latest version can not be installed. Note that the use of the newest available version is only guaranteed for the packages directly requested (e.g. as a command line arguments), and the solver may use older
# --allowerasing Allow erasing of installed packages to resolve dependencies. This option could be used as an alternative to the yum swap command where packages to remove are not explicitly defined.
sudo-helper -- dnf upgrade --assumeyes --refresh --best --allowerasing
}
function do_flatpak_upgrade {
sudo-helper -- flatpak update -y
# ^ sudo with flatpak avoids gui sudo prompt
}
function do_pamac_upgrade {
sudo-helper -- pamac upgrade --no-confirm
# ^ sudo with pamac avoids gui sudo prompt
# ^ `pamac update` is an alias for `pamac upgrade`
}
function do_snap_upgrade {
if ! is-snap; then
return 0
fi
sudo-helper -- snap refresh || : # if snap was just installed on fedora, this can fail initially
}
function do_yum_upgrade {
sudo-helper -- yum upgrade -y --best
}
function do_zypper_upgrade {
sudo-helper -- zypper --non-interactive --gpg-auto-import-keys update --no-confirm --best-effort
}
# -------------------------------------
# Install Packages
local packages=(
'apk'
'apt'
'aur'
'flatpak'
'rpm'
'snap'
'zypper'
)
function do_apk_packages {
setup-util --installer=APK -- "${APK_INSTALL[@]}"
}
function do_apt_packages {
# apt uninstall
setup-util --installer=APT --uninstall -- "${APT_UNINSTALL[@]}"
# apt install
setup-util --installer=APT -- "${APT_INSTALL[@]}"
}
function do_aur_packages {
setup-util --installer=AUR -- "${AUR_INSTALL[@]}"
}
function do_flatpak_packages {
setup-util --installer=FLATPAK -- "${FLATPAK_INSTALL[@]}"
}
function do_rpm_packages {
setup-util --installer=RPM -- "${RPM_INSTALL[@]}"
}
function do_snap_packages {
if ! is-snap; then
return 0
fi
setup-util --installer=SNAP -- "${SNAP_INSTALL[@]}"
# configure with
# snap list --color=never | "$bin_gsed" '1d' | cut -d' ' -f1 | grep --invert-match --extended-regexp --regexp='^(core|snapd)'
}
function do_zypper_packages {
setup-util --installer=ZYPPER -- "${ZYPPER_INSTALL[@]}"
}
# -------------------------------------
# Clean System
local clean=(
'apt'
'dnf'
'pacman'
'pamac'
'yum'
'zypper'
)
function do_apt_clean {
sudo-helper -- apt-get autoremove -y --purge
sudo-helper -- apt-get autoclean -y
sudo-helper -- apt-get clean -y
}
function do_dnf_clean {
sudo-helper -- dnf clean all
}
function do_pamac_clean {
sudo-helper -- pamac clean --no-confirm
# ^ sudo with pamac avoids gui sudo prompt
}
function do_pacman_clean {
# -c, --clean
# Remove packages that are no longer installed from the cache as well as currently unused sync databases to free up disk space.
sudo-helper -- pacman --sync --noconfirm --clean
}
function do_yum_clean {
sudo-helper -- yum clean all
}
function do_zypper_clean {
sudo-helper -- zypper --non-interactive --gpg-auto-import-keys clean --all
}
# -------------------------------------
# Upgrade System
function do_apt_system {
if __command_missing -- do-release-upgrade; then
return 0
fi
# check for a new distro release
if do-release-upgrade -c; then
# if there is one, then ask the user if they want to upgrade to it
if confirm --linger --negative --ppid=$$ -- 'Upgrade the distribtion release?'; then
sudo-helper -- do-release-upgrade
fi
fi
}
# =====================================
# Action
# prepare
local item
# action
if test "$action" = 'clean'; then
# clean ecosystems
for item in "${clean[@]}"; do
if __command_exists -- "$item"; then
eval_helper --shapeshifter --no-wrap \
--pending="$(echo-style --bold="Cleaning $item...")" \
--success="$(echo-style --success="Cleaned $item.")" \
--failure="$(echo-style --error="Failed to clean $item.")" \
-- "do_${item}_clean"
fi
done
elif test "$action" = 'install' -o "$action" = 'update'; then
# log
echo-style --h1="$title"
# update references
for item in "${updates[@]}"; do
if __command_exists -- "$item"; then
eval_helper --shapeshifter --no-wrap \
--pending="$(echo-style --bold="Updating references of $item...")" \
--success="$(echo-style --success="Updated references of $item.")" \
--failure="$(echo-style --error="Failed to update references of $item.")" \
-- "do_${item}_update"
fi
done
# setup essential system utilities
setup-util-devel
setup-linux-raspi "$action"
setup-linux-recovery
# install package managers
if test "$action" = 'install'; then
# in this order, based on dependency relationships
setup-util-pamac --optional --confirm
setup-util-snap --optional --confirm
setup-util-flatpak --optional --confirm
setup-util-gnome-software --optional --confirm
fi
# upgrade all packages
# ask, because manjaro and other rolling releases can demand over 40GB for initial upgrades
if confirm --linger --positive --ppid=$$ -- 'Upgrade existing packages?'; then
for item in "${upgrades[@]}"; do
if __command_exists -- "$item"; then
eval_helper --shapeshifter --no-wrap \
--pending="$(echo-style --bold="Upgrading packages of $item...")" \
--success="$(echo-style --success="Upgraded packages of $item.")" \
--failure="$(echo-style --error="Failed to upgrade packages of $item.")" \
-- "do_${item}_upgrade"
fi
done
fi
# upgrade the entire system
do_apt_system
# setup user packages
for item in "${packages[@]}"; do
if __command_exists -- "$item"; then
eval_helper --shapeshifter --no-wrap \
--pending="$(echo-style --bold="Installing packages of $item...")" \
--success="$(echo-style --success="Installed packages of $item.")" \
--failure="$(echo-style --error="Failed to install packages of $item.")" \
-- "do_${item}_packages"
fi
done
# log
echo-style --g1="$title"
else
# unknown action
help "An unrecognised action was provided: $action"
fi
)
# fire if invoked standalone
if test "$0" = "${BASH_SOURCE[0]}"; then
setup_linux "$@"
fi