From fdafa6ca866297dbe6c14f03b7d5e352cfb29caa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre?= Date: Wed, 6 Oct 2021 11:42:46 +0200 Subject: [PATCH 1/2] toltecctl: Honour dependencies when uninstalling `toltecctl uninstall` will now try to uninstall packages in the reverse order of their dependencies, so that a package can use binaries it depends on during its removal scripts (see #448). Packages in a dependency cycle are removed in an unspecified order. Test plan: Upgrade `toltec-bootstrap`, install some packages, then run `toltecctl uninstall`. You should see packages removed in reverse dependency order, so for example: * `libc`, `libpthread`, `libgcc` should generally be the last removed packages * graphical apps should get removed before `display` * `toltec-bootstrap` should get removed before `coreutils-tsort` --- package/toltec-bootstrap/package | 5 ++-- package/toltec-bootstrap/toltecctl | 40 ++++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/package/toltec-bootstrap/package b/package/toltec-bootstrap/package index c1ff8453b..6cac9a9df 100644 --- a/package/toltec-bootstrap/package +++ b/package/toltec-bootstrap/package @@ -5,11 +5,12 @@ pkgnames=(toltec-bootstrap) pkgdesc="Manage your Toltec install" url=https://toltec-dev.org/ -pkgver=0.2.0-1 -timestamp=2021-09-25T10:36Z +pkgver=0.2.1-1 +timestamp=2021-10-06T07:51Z section="utils" maintainer="Eeems " license=MIT +installdepends=(coreutils-tsort) source=( toltecctl diff --git a/package/toltec-bootstrap/toltecctl b/package/toltec-bootstrap/toltecctl index e49fbee05..e218d5abf 100644 --- a/package/toltec-bootstrap/toltecctl +++ b/package/toltec-bootstrap/toltecctl @@ -305,10 +305,46 @@ reenable() { set-path } -# Remove all installed packages +# List all installed packages such that any package comes before +# its dependencies. Dependency cycles are broken arbitrarily +list-installed-ordered() { + # shellcheck disable=SC2016 + local awk_trim='NR>1 {print gensub(/^[ \t]+|[ \t]+$/, "", "g", $0);}' + + opkg list-installed | awk -F' - ' '{print $1}' | while read -r srcpkg; do + # Make sure all packages are included even when they don’t have + # any dependencies + echo "$srcpkg $srcpkg" + + # List all dependencies for this package + opkg depends "$srcpkg" | awk "$awk_trim" | while read -r dstpkg; do + echo "$srcpkg $dstpkg" + done + done | tsort 2> /dev/null || true + # tsort reports errors if there are dependency cycles, we ignore them +} + +# Remove Toltec completely uninstall() { - opkg remove --force-depends --force-remove "*" + # Fetch standalone opkg used to uninstall packages + local opkg_path=/home/root/.local/bin/opkg + local opkg_remote=https://bin.entware.net/armv7sf-k3.2/installer/opkg + + if ! wget --no-verbose "$opkg_remote" --output-document "$opkg_path"; then + echo "Unable to fetch standalone opkg, make sure you have a stable Wi-Fi connection" + return 1 + fi + + chmod u+x "$opkg_path" + + # Remove installed packages in reverse dependency order + echo "Collecting installed packages" + list-installed-ordered | while read -r pkgname; do + "$opkg_path" remove --force-depends --force-remove "$pkgname" + done + systemctl daemon-reload + rm -f "$opkg_path" # Remove mount point remove-bind-mount "$toltec_dest" From 5ea4e95b272b9b46f3c9ede38b39f9d9c0ea70ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre?= Date: Wed, 13 Oct 2021 21:21:29 +0200 Subject: [PATCH 2/2] Improve speed of package ordering --- package/toltec-bootstrap/toltecctl | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/package/toltec-bootstrap/toltecctl b/package/toltec-bootstrap/toltecctl index a6069a361..2480d6eee 100644 --- a/package/toltec-bootstrap/toltecctl +++ b/package/toltec-bootstrap/toltecctl @@ -309,18 +309,17 @@ reenable() { # its dependencies. Dependency cycles are broken arbitrarily list-installed-ordered() { # shellcheck disable=SC2016 - local awk_trim='NR>1 {print gensub(/^[ \t]+|[ \t]+$/, "", "g", $0);}' - - opkg list-installed | awk -F' - ' '{print $1}' | while read -r srcpkg; do - # Make sure all packages are included even when they don’t have - # any dependencies - echo "$srcpkg $srcpkg" - - # List all dependencies for this package - opkg depends "$srcpkg" | awk "$awk_trim" | while read -r dstpkg; do - echo "$srcpkg $dstpkg" - done - done | tsort 2> /dev/null || true + local awk_list_to_graph=' + /^.* depends on:$/{ + from=$1; + print from " " from; + } + + /^\t/{ + print from " " $1; + } + ' + opkg depends '*' | awk "$awk_list_to_graph" | tsort 2> /dev/null || true # tsort reports errors if there are dependency cycles, we ignore them } @@ -338,7 +337,6 @@ uninstall() { chmod u+x "$opkg_path" # Remove installed packages in reverse dependency order - echo "Collecting installed packages" list-installed-ordered | while read -r pkgname; do "$opkg_path" remove --force-depends --force-remove "$pkgname" done