-
Notifications
You must be signed in to change notification settings - Fork 16
/
fedora-upgrade
executable file
·433 lines (381 loc) · 12.9 KB
/
fedora-upgrade
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
431
432
433
#!/bin/bash
# vim: sw=3:ts=3:et
set -e
RAWHIDE_VERSION=39
FEDORA_VERSION=$(rpm -qf --qf '%{version}' /etc/os-release)
TARGET_VERSION=$((FEDORA_VERSION + 1))
UPGRADE_FINISHED=0
TMPFS_MOUNTED=0
DISABLED_PLUGINS="--disableplugin=needs-restarting --disableplugin=tracer"
function check_installation() {
[[ -e /usr/sbin/fedora-upgrade ]]
}
function pause() {
# clear the stdin buffer and pause with question
read -t 1 -n 10000 discard || [ $? -gt 128 ]
read -p "Hit Enter to continue or Ctrl + C to cancel."
}
function continue_or_skip() {
read -t 1 -n 10000 discard || [ $? -gt 128 ]
echo -e $1
echo "This step is highly recommended but can be safely skipped."
ANSWER='XXX'
while [ "$ANSWER" != "" -a "$ANSWER" != "S" ] ; do
read -p "Hit Enter to continue, Ctrl + C to cancel or S + Enter to skip. " ANSWER
ANSWER=$(echo $ANSWER | tr "[:lower:]" "[:upper:]")
done
}
function dnf_install_deps() {
# TODO add -q to all dnf and create some kind of progress meter
# but now be verbose
install_if_missing rpmconf
install_if_missing dnf-plugins-core
}
function install_if_missing() {
echo "Checking if $1 is installed."
rpm -q $1 >/dev/null || dnf install -y -q $1
}
function upgrade_before_upgrade() {
continue_or_skip "\nGoing to run 'dnf upgrade' before upgrading."
if [ "$ANSWER" != "S" ] ; then
dnf upgrade
fi
}
function dnf_upgrade_before_upgrade() {
continue_or_skip "\nGoing to run 'dnf upgrade' before upgrading."
if [ "$ANSWER" != "S" ] ; then
dnf upgrade
fi
}
function rpmconf_before_upgrade() {
continue_or_skip "\nGoing to resolve old .rpmsave and .rpmnew files before upgrading."
if [ "$ANSWER" != "S" ] ; then
rpmconf -fvimdiff -a
fi
}
function import_keys() {
echo "Importing new RPM-GPG keys."
rpm --import /usr/share/distribution-gpg-keys/fedora/RPM-GPG-KEY-fedora-$TARGET_VERSION-primary
if [ -f /etc/yum.repos.d/rpmfusion-free.repo -a -e /usr/share/distribution-gpg-keys/rpmfusion/RPM-GPG-KEY-rpmfusion-free-fedora-$TARGET_VERSION ]; then
rpm --import /usr/share/distribution-gpg-keys/rpmfusion/RPM-GPG-KEY-rpmfusion-free-fedora-$TARGET_VERSION
fi
if [ -f /etc/yum.repos.d/rpmfusion-nonfree.repo -a -e /usr/share/distribution-gpg-keys/rpmfusion/RPM-GPG-KEY-rpmfusion-nonfree-fedora-$TARGET_VERSION ]; then
rpm --import /usr/share/distribution-gpg-keys/rpmfusion/RPM-GPG-KEY-rpmfusion-nonfree-fedora-$TARGET_VERSION
fi
}
function install_base() {
continue_or_skip "\nGoing to install missing packages from group 'Minimal Install'"
if [ "$ANSWER" != "S" ] ; then
dnf group install 'Minimal Install'
fi
}
function dnf_install_base() {
continue_or_skip "\nGoing to install missing packages from group 'Minimal Install'"
if [ "$ANSWER" != "S" ] ; then
dnf groupupdate 'Minimal Install'
fi
}
function rpmconf_after_upgrade() {
continue_or_skip "\nGoing to resolve .rpmsave and .rpmnew files after upgrade."
if [ "$ANSWER" != "S" ] ; then
rpmconf -fvimdiff -a
rpmconf --clean
fi
}
function remove_old_gpg_keys() {
continue_or_skip "\nGoing to remove old GPG keys."
if [ "$ANSWER" != "S" ] ; then
/usr/sbin/fedora-remove-old-gpg-keys || true
fi
}
function reset_service_priorities() {
continue_or_skip "\nGoing to resets all installed unit files to the defaults configured\nin the preset policy file."
if [ "$ANSWER" != "S" ] ; then
systemctl preset-all || true
fi
}
function EXCEPTION_reset_libgit2_module() {
continue_or_skip "\nGoing to reset libgit2, exa, bat Fedora Modules. (dnf module reset libgit2 exa bat)"
if [ "$ANSWER" != "S" ] ; then
dnf module reset libgit2 exa bat
fi
}
function EXCEPTION_reset_modules() {
continue_or_skip "\nGoing to reset Fedora Modules. (dnf module reset '*')"
if [ "$ANSWER" != "S" ] ; then
dnf module reset '*'
fi
}
function cleanup_cache() {
rm -rf /var/cache/yum/* /var/cache/dnf/* /var/cache/PackageKit/*
}
function unwanted_packages() {
LAST=$1
continue_or_skip "\nThere may be some packages which are now orphaned, do you want to see them?"
if [ "$ANSWER" != "S" ] ; then
RESULT=0
package-cleanup --orphans | grep -v kernel && RESULT=1
if [ 0$RESULT -eq 1 ]; then
echo "These packages are very probably orphaned. You may want to remove them."
fi
fi
}
function unwanted_packages2() {
LAST=$1
continue_or_skip "\nThere may be some packages which are now retired, do you want to remove them?\nYou will confirm each removal separately."
if [ "$ANSWER" != "S" ] ; then
remove-retired-packages $LAST
fi
}
function is_prerelease() {
# will print string "--enablerepo=updates-testing" if this is prerelease, "" otherwise
local RELEASE=$1
TEMP=$(mktemp -d)
dnf download -q --destdir "$TEMP" --disablerepo=* --enablerepo=fedora --releasever=$RELEASE fedora-repos
if rpm2cpio "$TEMP"/fedora-repos*.rpm | cpio -i --quiet --to-stdout - ./etc/yum.repos.d/fedora-updates-testing.repo | grep 'enabled=1' >/dev/null ; then
if [ -e /etc/yum.repos.d/fedora-updates-modular.repo ]; then
echo "--enablerepo=updates-testing --enablerepo=updates-testing-modular"
else
echo "--enablerepo=updates-testing"
fi
else
echo ""
fi
rm -rf "$TEMP"
}
function warn_if_graphics_mode() {
if [[ ! "$TERM" =~ "screen".* ]]; then
cat << WARNING
It seems you are running upgrade from graphics mode. You should use "screen" or "tmux".
Are you sure you want to continue?
WARNING
pause
fi
}
function print_exit_banner() {
umount_cache_dnf
if [ $UPGRADE_FINISHED -eq 2 ]; then
echo "Enabling updates repos back"
# upgrade to rawhide failed, restore repos
dnf config-manager --set-enabled fedora updates updates-testing updates-modular
# FIXME we should enable
# rpmfusion-free-updates rpmfusion-nonfree-updates
# but only if we previously disabled it
echo "Disabling rawhide repo."
dnf config-manager --set-disabled rawhide
UPGRADE_FINISHED=0
fi
if [ $UPGRADE_FINISHED -eq 1 ]; then
echo
echo You successfully upgraded to Fedora $TARGET_VERSION
echo Reboot is strongly suggested.
exit 0
else
echo
echo Upgrade to Fedora $TARGET_VERSION was not finished!
echo You can safely re-run fedora-upgrade again to start over with:
echo " fedora-upgrade --upgrade-to=${TARGET_VERSION}"
exit 1
fi
}
function welcome_banner() {
echo "Going to upgrade your Fedora to version $1."
echo "You may want to read Release Notes:"
echo " http://docs.fedoraproject.org/f${TARGET_VERSION}/release-notes/"
echo "and about commond bugs:"
echo " https://fedoraproject.org/wiki/Common_F${TARGET_VERSION}_bugs"
pause
}
function warn_about_online() {
echo "Warning: This is unofficial upgrade path. For official tool see:"
echo " https://fedoraproject.org/wiki/Upgrading"
echo " While author of fedora-upgrade thinks online upgrade is better, it is"
echo " not officially tested by FedoraQA."
pause
}
function going_to_reboot() {
echo ""
echo "********** End of DNF plugin output **********"
echo ""
echo "Download complete! The downloaded packages were saved in cache till the next"
echo "successful transaction. You can remove cached packages by executing"
echo "'dnf clean packages'."
echo "In next step, your computer will be REBOOTED, and packages will be upgraded."
pause
}
function choose_upgrade_method() {
echo "Choose upgrade method"
echo " * offline - this use dnf-plugin-system-upgrade plugin and requires two reboots"
echo " - this is official upgrade method"
echo " * online - this use distro-sync and require only one reboot"
echo " - this is not officially tested by FedoraQA"
echo "For more information see https://fedoraproject.org/wiki/Upgrading"
read -t 1 -n 10000 discard || [ $? -gt 128 ]
}
function mount_cache_dnf() {
if [ -n "$OPTS_TMPFS" ]; then
mount -t tmpfs none -o "size=$OPTS_TMPFS" /var/cache/dnf/
TMPFS_MOUNTED=1
fi
}
function umount_cache_dnf() {
if [ -n "$OPTS_TMPFS" -a 0$TMPFS_MOUNTED -eq 1 ]; then
umount /var/cache/dnf/
TMPFS_MOUNTED=0
fi
}
################################ START OF THE CODE ############################
if ! check_installation; then
echo "Please install fedora-upgrade package using dnf first"
exit 2
fi
if [ 0$UID -ne 0 ]; then
echo "Error: You must be a root."
echo "Run as: sudo fedora-upgrade"
exit 1
fi
# make obvious ending for inexperienced users
trap "print_exit_banner" SIGHUP SIGINT SIGTERM INT ERR
# parse command line options
for i in "$@"; do
case $i in
-u=*|--upgrade-to=*)
OPTS_UPGRADE_TO="${i#*=}"
TARGET_VERSION="$OPTS_UPGRADE_TO"
if [ "$TARGET_VERSION" = "rawhide" ]; then
TARGET_VERSION="$RAWHIDE_VERSION"
fi
shift # past argument=value
;;
--tmpfs=*)
OPTS_TMPFS="${i#*=}"
shift # past argument=value
;;
--help)
OPTS_HELP=YES
shift # past argument
;;
*)
# unknown option
;;
esac
done
if [ -n "$OPTS_HELP" ]; then
man fedora-upgrade | cat
exit 0;
fi
if [ 0$TARGET_VERSION -eq 39 ]; then
# Fedora 38 to 39
warn_if_graphics_mode
welcome_banner $TARGET_VERSION
dnf_install_deps
dnf_upgrade_before_upgrade
rpmconf_before_upgrade
import_keys
dnf clean -q dbcache metadata
enable_updates=""
echo "Checking if this is pre-release"
enable_updates=$(is_prerelease $TARGET_VERSION )
choose_upgrade_method
echo -e $1
ANSWER='XXX'
while [ "$ANSWER" != "offline" -a "$ANSWER" != "online" ] ; do
read -p "What is your choice? (offline/online) " ANSWER
ANSWER=$(echo $ANSWER | tr "[:upper:]" "[:lower:]")
done
if [ "$ANSWER" == "online" ] ; then
mount_cache_dnf
dnf --releasever=$TARGET_VERSION --setopt=deltarpm=false --setopt=module_platform_id=platform:f$TARGET_VERSION $enable_updates $DISABLED_PLUGINS distro-sync
umount_cache_dnf
elif [ "$ANSWER" == "offline" ] ; then
install_if_missing dnf-plugin-system-upgrade
dnf system-upgrade download --setopt=module_platform_id=platform:f$TARGET_VERSION --releasever=$TARGET_VERSION
going_to_reboot
dnf system-upgrade reboot
fi
dnf_install_base
cleanup_cache
rpmconf_after_upgrade
reset_service_priorities
unwanted_packages2 $FEDORA_VERSION
remove_old_gpg_keys
UPGRADE_FINISHED=1
elif [ 0$TARGET_VERSION -eq 40 ]; then
# Fedora 39 to 40
warn_if_graphics_mode
welcome_banner $TARGET_VERSION
dnf_install_deps
dnf_upgrade_before_upgrade
rpmconf_before_upgrade
import_keys
dnf clean -q dbcache metadata
enable_updates=""
echo "Checking if this is pre-release"
enable_updates=$(is_prerelease $TARGET_VERSION )
choose_upgrade_method
echo -e $1
ANSWER='XXX'
while [ "$ANSWER" != "offline" -a "$ANSWER" != "online" ] ; do
read -p "What is your choice? (offline/online) " ANSWER
ANSWER=$(echo $ANSWER | tr "[:upper:]" "[:lower:]")
done
if [ "$ANSWER" == "online" ] ; then
mount_cache_dnf
dnf --releasever=$TARGET_VERSION --setopt=deltarpm=false --setopt=module_platform_id=platform:f$TARGET_VERSION $enable_updates $DISABLED_PLUGINS distro-sync
umount_cache_dnf
elif [ "$ANSWER" == "offline" ] ; then
install_if_missing dnf-plugin-system-upgrade
dnf system-upgrade download --setopt=module_platform_id=platform:f$TARGET_VERSION --releasever=$TARGET_VERSION
going_to_reboot
dnf system-upgrade reboot
fi
dnf_install_base
cleanup_cache
rpmconf_after_upgrade
reset_service_priorities
unwanted_packages2 $FEDORA_VERSION
remove_old_gpg_keys
UPGRADE_FINISHED=1
elif [ 0$TARGET_VERSION -eq 0$RAWHIDE_VERSION ]; then
warn_if_graphics_mode
echo "Going to upgrade your Fedora to rawhide."
echo "Fedora $TARGET_VERSION is currently under development."
echo "Are you sure?"
pause
dnf_install_deps
rpmconf_before_upgrade
install_if_missing fedora-repos-rawhide
dnf config-manager --set-disabled rpmfusion-free-updates rpmfusion-nonfree-updates || true
dnf config-manager --set-disabled fedora updates updates-testing updates-modular
dnf config-manager --set-enabled rawhide
UPGRADE_FINISHED=2
dnf clean -q dbcache metadata
choose_upgrade_method
echo -e $1
ANSWER='XXX'
while [ "$ANSWER" != "offline" -a "$ANSWER" != "online" ] ; do
read -p "What is your choice? (offline/online) " ANSWER
ANSWER=$(echo $ANSWER | tr "[:upper:]" "[:lower:]")
done
if [ "$ANSWER" == "online" ] ; then
mount_cache_dnf
dnf --releasever=rawhide --setopt=deltarpm=false --setopt=module_platform_id=platform:f$TARGET_VERSION $DISABLED_PLUGINS distro-sync --nogpgcheck
umount_cache_dnf
elif [ "$ANSWER" == "offline" ] ; then
install_if_missing dnf-plugin-system-upgrade
dnf system-upgrade download --setopt=module_platform_id=platform:f$TARGET_VERSION --releasever=rawhide --nogpgcheck
going_to_reboot
dnf system-upgrade reboot
fi
dnf_install_base
cleanup_cache
rpmconf_after_upgrade
reset_service_priorities
remove_old_gpg_keys
unwanted_packages
UPGRADE_FINISHED=1
else
echo Upgrading to version $TARGET_VERSION is not supported.
exit 1
fi
print_exit_banner