Skip to content

Commit 2645de9

Browse files
committed
Make uninstall way more fault tolerant, and report better errors
1 parent fcedcd4 commit 2645de9

File tree

1 file changed

+94
-27
lines changed

1 file changed

+94
-27
lines changed

package/toltec-bootstrap/toltecctl

Lines changed: 94 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
set -euo pipefail
66

7+
# Path to this script
8+
toltecctl_path=$(realpath "$0")
9+
710
# Path where Toltec resides (will be mounted to $toltec_dest)
811
toltec_src=/home/root/.entware
912

@@ -15,7 +18,7 @@ toltec_share=/home/root/.local/share/toltec
1518
# Path to static opkg build
1619
opkg_path=/home/root/.local/bin/opkg
1720
# Path to opkg install status file
18-
opkg_status="/opt/lib/opkg/status"
21+
opkg_status="$toltec_dest/lib/opkg/status"
1922

2023
# Path to Opkg configuration
2124
opkg_conf="$toltec_src"/etc/opkg.conf
@@ -123,7 +126,7 @@ get-release-version() {
123126
# 3 - unable to install standalone wget
124127
check-version() {
125128
local wget
126-
if [[ "$(install-state)" != "yes" ]] || [[ "$(command -v wget)" != "/opt/bin/wget" ]]; then
129+
if [[ "$(install-state)" != "yes" ]] || [[ "$(command -v wget)" != "$toltec_dest/bin/wget" ]]; then
127130
if ! install-standalone-wget; then
128131
return 2
129132
fi
@@ -197,9 +200,9 @@ add-bind-mount() {
197200
unit_name="$(basename "$unit_path")"
198201

199202
if [[ -e $unit_path ]]; then
200-
echo "Bind mount configuration for '$2' already exists, updating"
203+
log INFO "Bind mount configuration for '$2' already exists, updating"
201204
else
202-
echo "Mounting '$1' over '$2'"
205+
log INFO "Mounting '$1' over '$2'"
203206
fi
204207

205208
cat > "$unit_path" << UNIT
@@ -234,11 +237,11 @@ remove-bind-mount() {
234237
unit_name="$(basename "$unit_path")"
235238

236239
if [[ ! -e $unit_path ]]; then
237-
echo "No existing bind mount for '$1'"
240+
log INFO "No existing bind mount for '$1'"
238241
return
239242
fi
240243

241-
echo "Removing mount over '$1'"
244+
log INFO "Removing mount over '$1'"
242245
systemctl disable "$unit_name"
243246
systemctl stop "$unit_name"
244247
if mountpoint -q "$1"; then
@@ -460,7 +463,7 @@ reinstall-root() {
460463
if [[ -v "on_root_packages[$pkgname]" ]]; then
461464
reinstall_packages[$pkgname]=1
462465
fi
463-
done < <(gunzip -c /opt/var/opkg-lists/* | grep "^Package:" | awk '{print $2}')
466+
done < <(gunzip -c $toltec_dest/var/opkg-lists/* | grep "^Package:" | awk '{print $2}')
464467

465468
# Workaround: Checking the size of an empty array when the nounset option
466469
# is active may throw an error on some Bash versions, so we disable it
@@ -480,6 +483,7 @@ clean-path() {
480483
sed -i "/^$bashrc_start_marker\$/,/^$bashrc_end_marker\$/d" "$bashrc_path"
481484
sed -i "/^$bashrc_old_start_marker\$/!b;n;d" "$bashrc_path"
482485
sed -i "/^$bashrc_old_start_marker\$/d" "$bashrc_path"
486+
# TODO - rewrite this to use $toltec_dest instead of /opt
483487
sed -i '/^\(export \)\?PATH="\?\.*\/opt\/bin:\/opt\/sbin.*"\?$/d' "$bashrc_path"
484488
fi
485489
}
@@ -492,7 +496,7 @@ set-path() {
492496
clean-path
493497
cat >> "$bashrc_path" << SHELL
494498
$bashrc_start_marker
495-
PATH="/opt/bin:/opt/sbin:/home/root/.local/bin:\$PATH"
499+
PATH="$toltec_dest/bin:$toltec_dest/sbin:/home/root/.local/bin:\$PATH"
496500
$bashrc_end_marker
497501
SHELL
498502

@@ -541,9 +545,9 @@ generate-opkg-conf() {
541545
# then run \`toltecctl generate-opkg-conf\` to regenerate this file
542546
543547
dest root /
544-
dest ram /opt/tmp
545-
lists_dir ext /opt/var/opkg-lists
546-
option tmp_dir /opt/tmp
548+
dest ram $toltec_dest/tmp
549+
lists_dir ext $toltec_dest/var/opkg-lists
550+
option tmp_dir $toltec_dest/tmp
547551
548552
CONF
549553

@@ -672,23 +676,23 @@ CONF
672676

673677
# Re-enable Toltec install after system update
674678
reenable() {
675-
log INFO "Mounting /opt"
679+
log INFO "Mounting $toltec_dest"
676680
add-bind-mount "$toltec_src" "$toltec_dest"
677681
switch-branch "$(get-branch)"
678-
log INFO "Generating /opt/etc/opkg.conf"
682+
log INFO "Generating $toltec_dest/etc/opkg.conf"
679683
generate-opkg-conf || true
680684
log INFO "Opkg update"
681685
opkg update
682686
log INFO "Reinsalling base packages"
683687
reinstall-base
684688
log INFO "Reinstalling packages with files on the root partition"
685689
reinstall-root
686-
if [ -d /opt/share/toltec/reenable.d ]; then
687-
find /opt/share/toltec/reenable.d -maxdepth 1 -mindepth 1 -print0 \
690+
if [ -d $toltec_dest/share/toltec/reenable.d ]; then
691+
find $toltec_dest/share/toltec/reenable.d -maxdepth 1 -mindepth 1 -print0 \
688692
| xargs -0rn1 basename \
689693
| while read -r pkg; do
690694
local script
691-
script="/opt/lib/opkg/info/${pkg}.postinst"
695+
script="$toltec_dest/lib/opkg/info/${pkg}.postinst"
692696
if [ -f "$script" ]; then
693697
log INFO "Reconfiguring ${pkg}"
694698
"$script" configure || true
@@ -720,7 +724,7 @@ list-installed-ordered() {
720724
# Install standalone opkg binary
721725
install-standalone-opkg() {
722726
local wget
723-
if [[ "$(install-state)" != "yes" ]] || [[ "$(command -v wget)" != "/opt/bin/wget" ]]; then
727+
if [[ "$(install-state)" != "yes" ]] || [[ "$(command -v wget)" != "$toltec_dest/bin/wget" ]]; then
724728
if ! install-standalone-wget; then
725729
return 2
726730
fi
@@ -775,12 +779,49 @@ install-standalone-wget() {
775779

776780
# Remove Toltec completely
777781
uninstall() {
782+
if ! [ -d "$toltec_src" ] && ! [ -d "$toltec_dest" ]; then
783+
log INFO "Toltec does not appear to be installed"
784+
exit 0
785+
fi
786+
778787
# Fetch standalone opkg used to uninstall packages
779788
if ! install-standalone-opkg; then
780789
return 1
781790
fi
782-
783791
local clean=true
792+
local success=true
793+
794+
broken-state() {
795+
echo " Your system may be in a broken state. Please review the logs"
796+
echo " before rebooting your device. If you need assistance, you can"
797+
echo " get help on the community discord channel."
798+
}
799+
800+
cleanup() {
801+
local error_code=$?
802+
log ERROR "$BASH_LINENO: $BASH_COMMAND"
803+
log ERROR "Uninstall did not complete properly"
804+
broken-state
805+
exit $error_code
806+
}
807+
trap cleanup ERR
808+
809+
if [[ "$toltecctl_path" != *_backup ]]; then
810+
log INFO "Creating backup of toltecctl at ${toltecctl_path}_backup"
811+
rm -f "${toltecctl_path}_backup"
812+
cp "$toltecctl_path" "${toltecctl_path}_backup"
813+
fi
814+
815+
if ! [ -f "$toltec_dest"/etc/opkg.conf ]; then
816+
if [ -f "$toltec_src"/etc/opkg.conf ] && ! mountpoint -q "$toltec_dest"; then
817+
log INFO "Mounting $toltec_dest"
818+
add-bind-mount "$toltec_src" "$toltec_dest"
819+
fi
820+
log ERROR "Current install seems to be partially removed, unable to automatically removed."
821+
broken-state
822+
exit 1
823+
fi
824+
784825
# Remove installed packages in reverse dependency order
785826
while read -r pkgname; do
786827
if ! "$opkg_path" remove --force-depends "$pkgname"; then
@@ -792,28 +833,54 @@ uninstall() {
792833
$(list-installed-ordered)
793834
EOF
794835

795-
systemctl daemon-reload
836+
if ! systemctl daemon-reload; then
837+
log WARN "Failed to reload systemd state"
838+
fi
796839
rm -f "$opkg_path"
797840

798841
# Remove mount point
799842
remove-bind-mount "$toltec_dest"
800-
rmdir "$toltec_dest"
843+
844+
case "$(install-state)" in
845+
no) ;;
846+
*)
847+
log ERROR "$toltec_dest bind mount still is active"
848+
success=false
849+
;;
850+
esac
851+
852+
if ! rmdir "$toltec_dest"; then
853+
log ERROR "Failed to remove mount point"
854+
success=false
855+
fi
801856

802857
# Unset PATH
803858
clean-path
804859

805860
# Remove Toltec data
806-
rm -r "$toltec_src"
861+
if ! rm -r "$toltec_src"; then
862+
log ERROR "Failed to remove toltec data directory"
863+
success=false
864+
fi
807865

808866
# Re-enable xochitl if needed
809-
systemctl enable xochitl
810-
867+
if ! systemctl enable xochitl; then
868+
log ERROR "Failed to enable the user interface."
869+
success=false
870+
fi
811871
if ! $clean; then
812-
echo "Warning: There were errors removing some of the toltec packages."
813-
echo " Your system may be in a broken state. Please review the logs"
814-
echo " before rebooting your device. If you need assistance, you can"
815-
echo " get help on the community discord channel."
872+
log ERROR "There were errors removing some of the toltec packages."
873+
success=false
874+
fi
875+
if ! $success; then
876+
log ERROR "Uninstall failed"
877+
broken-state
878+
exit 1
879+
fi
880+
if [[ "$toltecctl_path" != *_backup ]]; then
881+
rm -f "$toltecctl_path"
816882
fi
883+
rm -f "${toltecctl_path}_backup"
817884
}
818885

819886
# The current toltec install state

0 commit comments

Comments
 (0)