tazpkg annotate modules/remove @ rev 929

modules/install and modules/remove: auto-update /ets/filesystems for the FS Kernel modules
author Aleksej Bobylev <al.bobylev@gmail.com>
date Sun Jan 01 23:01:52 2017 +0200 (2017-01-01)
parents 688515d746e1
children 45d90da42ede
rev   line source
al@840 1 #!/bin/sh
al@840 2 # TazPkg - Tiny autonomous zone packages manager, hg.slitaz.org/tazpkg
al@840 3 # remove - TazPkg module
al@840 4 # Remove packages
al@840 5
al@840 6
al@840 7 # Connect function libraries
al@840 8 . /lib/libtaz.sh
al@840 9
al@840 10 # Get TazPkg working environment
al@840 11 . @@MODULES@@/getenv
al@840 12
al@840 13
al@840 14
al@840 15
al@840 16 # Log activity
al@840 17
al@840 18 log_pkg() {
al@840 19 [ -w "$LOG" ] &&
al@840 20 echo "$(date +'%F %T') - $1 - $PACKAGE ($VERSION$EXTRAVERSION)" >> "$LOG"
al@840 21 }
al@840 22
al@840 23
al@840 24 # Interactive mode
al@840 25
al@840 26 im() { tty -s; }
al@840 27
al@840 28
al@844 29 # Block of receipt function callers
al@844 30 # Why? "Bad" receipt sourcing can redefine some vital TazPkg variables.
al@844 31 # Few receipts function should be patched now.
al@844 32
al@844 33 # Input: $1 = path to the receipt to be processed
al@844 34
al@844 35 call_pre_remove() {
al@844 36 local tmp
al@844 37 if grep -q '^pre_remove()' "$1"; then
al@844 38 action 'Execute pre-remove commands...'
al@844 39 tmp="$(mktemp)"
al@844 40 cp "$1" "$tmp"
al@844 41 sed -i 's|$1/*$INSTALLED|$INSTALLED|g' "$tmp"
al@844 42 ( . "$tmp"; pre_remove "$root" )
al@844 43 status
al@844 44 rm "$tmp"
al@844 45 fi
al@844 46 }
al@844 47
al@844 48 call_post_remove() {
al@844 49 local tmp
al@844 50 if grep -q '^post_remove()' "$1"; then
al@844 51 action 'Execute post-remove commands...'
al@844 52 tmp="$(mktemp)"
al@844 53 cp "$1" "$tmp"
al@844 54 sed -i 's|$1/*$INSTALLED|$INSTALLED|g' "$tmp"
al@844 55 ( . "$tmp"; post_remove "$root" )
al@844 56 status
al@844 57 rm "$tmp"
al@844 58 fi
al@844 59 }
al@844 60
al@844 61
al@887 62 # return possible name for a virtual package name
al@840 63
al@887 64 virtual_pkg() {
al@887 65 # input: $1 virtual package name
al@887 66 # $2 repository db directory
al@887 67 # output: display possible package name
al@840 68
al@887 69 debug "\nvirtual_pkg('$1', '$2')"
al@887 70 local i
al@887 71 unset IFS
al@887 72 for i in $(grep -hs "^$1=" "$2/packages.equiv" | sed "s/^$1=//"); do
al@887 73 if echo $i | fgrep -q : ; then
al@887 74 # format 'alternative:newname'
al@887 75 # if alternative is installed then substitute newname
al@887 76 if [ -f $INSTALLED/${i%:*}/receipt ]; then
al@887 77 # substitute package dependency
al@887 78 echo ${i#*:}
al@887 79 return
al@887 80 fi
al@887 81 elif ! grep -q "^$1 " "$2/packages.info" || [ -f "$INSTALLED/$i/receipt" ]; then
al@887 82 # unconditional substitution
al@887 83 echo $i
al@887 84 return
al@887 85 fi
al@887 86 done
al@887 87 # the real package name
al@887 88 echo $1
al@887 89 }
al@887 90
al@887 91
al@887 92
al@887 93
al@887 94 for rep in $PRIORITY; do
al@887 95 [ ! -f "$rep/packages.info" ] && continue
al@887 96 PACKAGE="$(virtual_pkg "$1" "$rep")"
al@887 97 [ "$PACKAGE" != "$1" ] && break
al@887 98 done
al@840 99
al@840 100 if [ ! -f "$INSTALLED/$PACKAGE/receipt" ]; then
al@840 101 newline; _ 'Package "%s" is not installed.' "$PACKAGE"
al@840 102 exit 1
al@840 103 fi
al@840 104
al@840 105 . "$INSTALLED/$PACKAGE/receipt"
al@840 106
al@840 107 # Info #1: dependent packages (to be processed later)
al@840 108 ALTERED="$(awk -F$'\t' -vp=" $PACKAGE " 'index(" " $8 " ", p) { printf " %s\n", $1 }' "$PKGS_DB/installed.info")"
al@840 109
al@840 110 if [ -n "$ALTERED" ]; then
al@840 111 _ 'The following packages depend on package "%s":' "$PACKAGE"
al@840 112 echo "$ALTERED"
al@840 113 fi
al@840 114
al@840 115 # Info #2: changed packages (to be processed later)
al@840 116 REFRESH=$(cd "$INSTALLED"; grep -sl "^$PACKAGE$" */modifiers)
al@840 117
al@840 118 if [ -n "$REFRESH" ]; then
al@840 119 _ 'The following packages have been modified by package "%s":' "$PACKAGE"
al@840 120 for i in $REFRESH; do
al@840 121 echo " ${i%/modifiers}"
al@840 122 done
al@840 123 fi
al@840 124
al@840 125 # Confirmation
pascal@916 126 if [ -n "$noconfirm" ] || im && [ -z "$auto" ]; then
al@840 127 confirm "$(_ 'Remove package "%s" (%s)? (y/N)' "$PACKAGE" "$VERSION$EXTRAVERSION")"
al@840 128 if [ "$?" -ne 0 ]; then
al@840 129 newline; _ 'Uninstallation of package "%s" cancelled.' "$PACKAGE"
al@840 130 exit 0
al@840 131 fi
al@840 132 fi
al@913 133 # We are here: non-interactive mode, or --auto, or --yes, or answer 'y'
al@840 134
al@840 135 # Removing package
al@840 136 title 'Removing package "%s"' "$PACKAGE"
al@840 137
al@926 138 # Unblock package quietly; otherwise:
al@926 139 # 1. We can no longer install the package one more time - because it is blocked
al@926 140 # 2. We can no longer unblock the package - because it is not installed
al@926 141 tazpkg -u "$PACKAGE" --nowarning | grep -v '^$'
al@926 142
al@887 143 # [1/5] Pre-remove commands
al@844 144 call_pre_remove "$INSTALLED/$PACKAGE/receipt"
al@844 145
al@840 146
al@887 147 # [2/5] Removing files
al@840 148 action 'Removing all files installed...'
al@857 149
al@857 150 # NOTE: package 'faenza-icon-theme' install time: 12s; removing time ~ 11min on my system o_O
al@860 151 # After optimization: 3s! (Long) for-loops are (big) evil ;)
al@857 152
al@857 153 # NOTE: many packages contains filenames with spaces:
al@857 154 # lzcat /var/lib/tazpkg/files.list.lzma | awk -F" " '{if(NF>2)print $1}' | sed 's|:$||' | uniq
al@857 155 # Redefine IFS to only-new-line field separator:
al@857 156 IFS=$'\n'
al@857 157
al@857 158 files2remove="$(mktemp)"
al@857 159
al@857 160 debug '\nDetermine which files to remove...'
al@840 161 if [ -f "$INSTALLED/$PACKAGE/modifiers" ]; then
al@857 162 debug ' (modifiers detected)'
al@857 163
al@857 164 mods="$(mktemp)"
al@857 165 for mod in $(cat "$INSTALLED/$PACKAGE/modifiers"); do
al@857 166 cat "$INSTALLED/$mod/files.list" >> "$mods" 2>/dev/null
al@840 167 done
al@857 168
al@857 169 awk -vroot="$root" -vfl="$INSTALLED/$PACKAGE/files.list" '
al@857 170 {
al@857 171 if (FILENAME == fl)
al@857 172 f[$0] = 1;
al@857 173 else
al@857 174 f[$0] = "";
al@857 175 }
al@857 176 END {
al@857 177 for (i in f) {
al@857 178 if (f[i] == 1) printf "%s%s\n", root, i;
al@857 179 }
al@857 180 }' "$INSTALLED/$PACKAGE/files.list" "$mods" > "$files2remove"
al@857 181 rm "$mods"
al@840 182 else
al@857 183 debug ' (modifiers not detected)'
al@857 184
al@857 185 awk -vroot="$root" '{ printf "%s%s\n", root, $0; }' \
al@857 186 "$INSTALLED/$PACKAGE/files.list" > "$files2remove"
al@857 187 fi
al@857 188
al@857 189 debug 'Removing files...'
al@857 190 xargs rm -f < "$files2remove"
al@857 191
al@860 192 debug 'Removing folders...'
al@857 193 awk '
al@857 194 BEGIN {
al@857 195 FS = "/"; OFS = "/";
al@857 196 }
al@857 197 {
al@857 198 # removing filename beyond the last "/"
al@857 199 $NF = "";
al@857 200 if (! a[$0]) {
al@857 201 a[$0] = 1; print;
al@857 202 }
al@860 203 }' "$files2remove" | xargs rmdir -p 2>/dev/null
al@857 204
al@860 205 rm "$files2remove"
al@857 206 unset IFS
al@857 207
al@840 208 status
al@840 209
al@887 210 # [3/5] Post-remove commands
al@844 211 call_post_remove "$INSTALLED/$PACKAGE/receipt"
al@840 212
al@887 213 # [4/5] Update system databases
al@920 214 fl="$INSTALLED/$PACKAGE/files.list"; upd=0
al@887 215
al@929 216 fgrep /usr/share/applications/ "$fl" | fgrep -q .desktop && udesk='yes'
al@929 217 fgrep -q /usr/share/mime "$fl" && umime='yes'
al@929 218 fgrep -q /usr/share/icon/hicolor "$fl" && uicon='yes'
al@929 219 fgrep /usr/share/glib-2.0/schemas "$fl" | fgrep -q .xml && uschm='yes'
al@929 220 fgrep /usr/lib/gdk-pixbuf "$fl" | fgrep -q .so && upixb='yes'
al@929 221 if fgrep -q /lib/modules "$fl"; then
al@929 222 ukrnl='yes'
al@929 223 if fgrep -q /kernel/fs/ "$fl"; then
al@929 224 ukrnlfs='yes'
al@929 225 fi
al@929 226 fi
al@887 227
al@887 228 if [ -n "$udesk$umime$uicon$uschm$upixb$ukrnl" ]; then
al@887 229 action 'Update system databases...'
al@887 230 upd=1
al@887 231 fi
al@887 232
al@887 233 # package 'desktop-file-utils'
al@887 234 [ -n "$udesk" ] && chroot "$root/" /usr/bin/update-desktop-database /usr/share/applications 2>/dev/null
al@887 235 # package 'shared-mime-info'
al@887 236 [ -n "$umime" ] && chroot "$root/" /usr/bin/update-mime-database /usr/share/mime
al@887 237 # packages 'gtk+', 'gtk+3'
al@887 238 [ -n "$uicon" ] && chroot "$root/" /usr/bin/gtk-update-icon-cache /usr/share/icons/hicolor
al@887 239 # package 'glib'
al@897 240 # hide messages like next because they are unresolved (we may to patch glib to hide them, almost the same)
al@897 241 # warning: Schema '*' has path '*'. Paths starting with '/apps/', '/desktop/' or '/system/' are deprecated.
al@897 242 [ -n "$uschm" ] && chroot "$root/" /usr/bin/glib-compile-schemas /usr/share/glib-2.0/schemas 2>&1 | fgrep -v '/apps/'
al@887 243 # package 'gdk-pixbuf'
al@887 244 [ -n "$upixb" ] && chroot "$root/" /usr/bin/gdk-pixbuf-query-loaders --update-cache
al@929 245
al@929 246 if [ -n "$ukrnlfs" ]; then
al@929 247 for i in $(awk -F/ '{if($6=="fs" && $8~$7)print $7}' "$fl" | sort -u); do
al@929 248 grep -i "/^$i\$/d" "$root/etc/filesystems"
al@929 249 done
al@929 250 fi
al@887 251 # packages 'busybox', 'kmod', 'depmod'
al@887 252 [ -n "$ukrnl" ] && grep '/lib/modules' "$fl" | cut -d'/' -f4 | uniq | xargs chroot "$root/" /sbin/depmod -a
al@887 253
al@887 254 [ "$upd" -eq 1 ] && status
al@887 255
al@887 256
al@887 257 # [5/5] Remove package receipt and remove it from databases
al@840 258 action 'Removing package receipt...'
al@840 259 rm -rf "$INSTALLED/$PACKAGE"
al@840 260 sed -i "/ $PACKAGE-$VERSION$EXTRAVERSION.tazpkg$/d" "$PKGS_DB/installed.$SUM"
al@840 261 sed -i "/^$PACKAGE /d" "$PKGS_DB/installed.info"
al@840 262 status
al@840 263
al@840 264 footer "$(_ 'Package "%s" (%s) removed.' "$PACKAGE" "$VERSION$EXTRAVERSION")"
al@840 265
al@840 266 # Log this activity
al@840 267 log_pkg Removed
al@840 268
al@840 269 # Stop if non-interactive mode and no --auto option
al@840 270 if ! im && [ -z "$auto" ]; then exit 0; fi
al@840 271
al@840 272 # Process dependent packages
al@840 273 if [ -n "$ALTERED" ]; then
al@840 274 if [ -n "$auto" ]; then
al@840 275 answer=0
al@840 276 else
al@840 277 confirm "$(_ 'Remove packages depending on package "%s"? (y/N)' "$PACKAGE")"
al@840 278 answer=$?
al@840 279 fi
al@840 280 if [ "$answer" -eq 0 ]; then
al@840 281 for i in $ALTERED; do
al@840 282 if [ -d "$INSTALLED/$i" ]; then
al@840 283 tazpkg remove $i
al@840 284 fi
al@840 285 done
al@840 286 fi
al@840 287 fi
al@840 288
al@840 289 # Process changed packages
al@840 290 if [ -n "$REFRESH" ]; then
al@840 291 if [ -n "$auto" ]; then
al@840 292 answer=0
al@840 293 else
al@840 294 confirm "$(_ 'Reinstall packages modified by package "%s"? (y/N)' "$PACKAGE")"
al@840 295 answer=$?
al@840 296 fi
al@840 297 if [ "$answer" -eq 0 ]; then
al@840 298 for i in $REFRESH; do
al@840 299 if [ "$(wc -l < "$INSTALLED/$i")" -gt 1 ]; then
al@849 300 _ 'Package "%s" was modified by "%s" and other packages. It will not be reinstalled.' \
al@849 301 "${i%/modifiers}" "$PACKAGE"
al@849 302 _ 'Check "%s" for reinstallation.' "$INSTALLED/$i"
al@849 303
al@840 304 continue
al@840 305 fi
al@840 306 rm -r "$INSTALLED/$i"
al@840 307 tazpkg get-install ${i%/modifiers} --forced
al@840 308 done
al@840 309 fi
al@840 310 fi
al@840 311