-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgentoo-update
executable file
·322 lines (292 loc) · 10.2 KB
/
gentoo-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
#!/usr/bin/env bash
# Gentoo system upgrade script, upgrades gentoo by syncing the portage tree,
# upgrades any layman repositories, cleans up after any prior emerge history,
# updates portage and does a complete system upgrade, then it runs a depclean
# and rebuilds any dependencies if needed, then rebuilds stale libraries and
# kernel modules! I use this script to upgrade my daily Gentoo system, if anything
# goes wrong feel free to contact me, or open a GitHub issue!
#
# Copyright (c) 2020-2021 quarkyalice ([email protected])
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# === Variables ===
PROGNAME="$(basename "${0}")"
VERSION="1.4" # If you're using 9999 this will be whatever the next version of the script is
CONFIG_FILE="/etc/gentoo-update.conf" # Configuration file
SCRIPTPATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")" # Store canonical path of script
ARGS="${@}" # Store copy of command line arguments
# Color variables
red="\e[0;91m"
blue="\e[0;94m"
green="\e[0;92m"
white="\e[0;97m"
bold="\e[1m"
uline="\e[4m"
reset="\e[0m"
# === End of Variables ===
# force TERM if none found (e.g. when running from cron)
# otherwise mach builds (firefox etc.) will fail
if ! tty -s; then
export TERM="dumb"
fi
# === Prerun tasks ===
prerun_checks() {
# Check for root by checking the UID of the running user
if [ "$EUID" -ne 0 ]; then
echo -e "${red}Please run as root${reset}"
error
# Check if the config file exists
elif [[ ! -f ${CONFIG_FILE} ]]; then
echo -e "${red}No config file found!${reset}"
echo -e "${red}Using defaults!${reset}"
kernel_build="NO"
use_running_config="NO"
reboot="YES"
else
source $CONFIG_FILE
fi
}
# === End of prerun tasks ===
restart() {
exec "${SCRIPTPATH}" ${ARGS}
}
error() {
echo -e "${red}Error: exiting${reset}" >&2
exit 1
}
successful_quit() {
exit 0
}
sync_portage_tree() {
# Sync the portage tree, using webrsync and eix-sync
if [[ "$SKIP_SYNC_TREE" == "1" ]]; then
echo -e "${red}Skipping sync...${reset}"
elif [[ "$WEBRSYNC" == "1" ]]; then
echo -e "${green}Running emerge-webrsync...${reset}"
emerge-webrsync
else
# Using emerge-webrsync to bring portage tree up to a recent snapshot
echo -e "${green}Upgrading portage tree with webrsync before doing a sync...${reset}"
emerge-webrsync
# Using emerge --sync to bring the portage tree up to the very latest snapshot
echo -e "${green}Syncing portage...${reset}"
eix-sync
echo
fi
}
update_layman_repos() {
# Layman is obsolete, so it's not recommended to use it, however I'll leave this for the people still using it
if [[ "$SKIP_LAYMAN_SYNC" == "1" ]]; then
echo -e "${red}Skipping layman sync...${reset}"
elif [ -f /usr/bin/layman ]; then
echo -e "${green}Updating layman repos...${reset}"
layman -S
echo
fi
}
clean_prior_history() {
if [[ "$SKIP_CLEAN_HISTORY" == "1" ]]; then
echo -e "${red}Skipping cleaning any prior emerge resume history...${reset}"
else
echo -e "${green}Cleaning any prior emerge resume history...${reset}"
emaint --fix cleanresume
echo
fi
}
update_portage() {
if [[ "$SKIP_PORTAGE_UPDATE" == "1" ]]; then
echo -e "${red}Skipping portage update...${reset}"
else
echo -e "${green}Updating portage...${reset}"
emerge --oneshot --update portage
echo
fi
}
update_gentoo_update() {
echo -e "${green}Ensuring ${PROGNAME} is up to date...${reset}"
emerge --oneshot --update app-portage/gentoo-update
# If gentoo-update version changed, restart
if [[ $("${SCRIPTPATH}" -v) != "${VERSION}" ]]; then
echo "${red}${PROGNAME} has changed, restarting...${reset}"
restart
fi
}
do_the_complete_system_upgrade() {
echo -e "${green}Running a complete system upgrade...${reset}"
echo -e "${red}This process could fail and require manual intervention!${reset}"
echo -e "${blue}Running emerge --deep --with-bdeps=y --changed-use --update @world${reset}"
# Check if user changes are required to percede
if grep -qi "The following \(keyword\|mask\|USE\|license\) changes are necessary to proceed" \
<(emerge --pretend --deep --with-bdeps=y --changed-use --update --backtrack=50 @world 2>&1 || true); then
# Silently note this and fail later
USER_CHANGES_REQUIRED="YES"
fi
# Actually do the system upgrade
START=`date`
emerge --deep --with-bdeps=y --changed-use --update @world
STOP=`date`
if [[ "$USER_CHANGES_REQUIRED" == "YES" ]]; then
echo -e "${red}User changes are required! Attempt to fix it in another console window then return here${reset}"
read -p "Press enter to continue"
do_the_complete_system_upgrade
fi
echo -e "${blue}Start : ${reset}" $START
echo -e "${blue}End : ${reset}" $STOP
echo
}
process_dependencies() {
echo -e "${green}Cleaning up dependencies...${reset}"
emerge --depclean
echo
echo -e "${green}Checking and rebuilding dependencies...${reset}"
revdep-rebuild
echo
echo -e "${green}Rebuilding any packages that depend on stale libraries...${reset}"
emerge @preserved-rebuild
echo
echo -e "${green}Updating environmental settings${reset}"
env-update
echo
}
update_old_perl_modules() {
# perl modules need to be updated as they are built for a particular perl target but not automatically
# rebuilt when perl gets upgraded
if [[ "$NO_PERL_REBUILD" == "YES" ]]; then
echo -e "${red}Skipping Perl module rebuild...${reset}"
else
echo -e "${green}Rebuilding old perl modules...${reset}"
perl-cleaner --all
fi
}
clean_python_config() {
# Remove uninstalled versions of python from /etc/python-exec/python-exec.conf
if [ -f /usr/share/eselect/modules/python.eselect ]; then
eselect python cleanup
fi
}
build_kernel() {
# Eventually this may be it 's own script altogether, pulled in as a dependency but for now it's a part of this script.
if [[ "$kernel_build" == "YES" ]]; then
echo -e "${green}Upgrading kernel...${reset}"
if [[ $(findmnt -M "$FOLDER") ]]; then
echo -e "${green}/boot is mounted! continuing${reset}"
else
echo -e "${green}Mounting /boot!${reset}"
mount /boot
fi
if [[ $use_running_config == YES ]]; then
# Building kernel with config in /proc/config.gz
echo -e "${green}Using current running config in /proc/config.gz...${reset}"
genkernel --kernel-config=/proc/config.gz all
else
genkernel all
fi
fi
}
rebuild_modules() {
echo -e "${green}Rebuilding any external kernel modules (example virtualbox or vmware)${reset}"
emerge @module-rebuild --exclude '*-bin'
echo
}
env_update() {
# Update the environment
env-update
}
reboot() {
echo -e "${green}Upgrade completed!${reset}"
if [[ $reboot == YES ]]; then
# Prompt asking if you want to reboot the computer
read -r -p "Reboot? [Y/n] " input
case $input in
[yY][eE][sS]|[yY])
echo "Rebooting"
reboot
;;
[nN][oO]|[nN])
;;
*)
echo -e "${red}Invalid input...${reset}"
exit 1
;;
esac
fi
}
usage() {
cat << EOF
USAGE: ${PROGNAME} [options]
Options:
-s, --skip-sync Skip the portage tree sync
-r, --webrsync Webrsync only, but don't emerge --sync
-l, --layman-skip-sync Skip layman sync, if you have layman installed, otherwise this is useless
-p, --skip-portage Skip portage upgrade before upgrading world (bad idea unless you know what you're doing)
-v, --version Script version number
-h, --help Usage prompt
-m, --module-rebuild Rebuild kernel modules and do nothing else
-k, --kernel-rebuild Rebuild kernel, override config
EOF
}
version() {
echo "${VERSION}"
}
process_command_line_arguments() {
local TEMP
declare -i RC
set +e
TEMP="$(getopt -n "${PROGNAME}" -o vsrlphmk --long version,skip-sync,webrsync,layman-skip-sync,skip-portage,help,module-rebuild,kernel-rebuild: -- "${@}")"
RC="${?}"
set -e
if ((RC!=0)); then
error
fi
eval set -- "${TEMP}"
while true; do
case "${1}" in
-v|--version) PRINT_VERSION=1; shift ;;
-s|--skip-sync) SKIP_SYNC_TREE=1; shift ;;
-r|--webrsync) WEBRSYNC=1; shift ;;
-l|--layman-skip-sync) SKIP_LAYMAN_SYNC=1; shift ;;
-p|--skip-portage) SKIP_PORTAGE_UPDATE=1; shift ;;
-h|--help) USAGE=1; shift ;;
-m|--module-rebuild) MOD_REBUILD=1; shift ;;
-k|--kernel-rebuild) kernel_build=YES; shift ;;
--) shift; break ;;
*) error "Internal error!" ;;
esac
done
if [[ $USAGE == 1 ]]; then
usage; successful_quit
elif [[ $PRINT_VERSION == 1 ]]; then
version; successful_quit
elif [[ $MOD_REBUILD == 1 ]]; then
rebuild_modules; successful_quit
fi
}
# === Do the script ===
prerun_checks
process_command_line_arguments "${@}"
sync_portage_tree
update_layman_repos
clean_prior_history
update_portage
update_gentoo_update
do_the_complete_system_upgrade
process_dependencies
update_old_perl_modules
clean_python_config
build_kernel
rebuild_modules
env_update
reboot
successful_quit
# === End of script ===