[pacman-dev] [PATCH] [WIP] Extend database upgrade script to handle alpm db version 9
Allan McRae
allan at archlinux.org
Sat Aug 9 23:16:50 EDT 2014
On 03/08/14 15:31, Andrew Gregory wrote:
> Original-work-by: Allan McRae <allan at archlinux.org>
> Signed-off-by: Andrew Gregory <andrew.gregory.8 at gmail.com>
> ---
>
Big thanks for doing this!
> Changes:
> * set alternate root with PACROOT environment variable
As you have pointed out, that needs to be a -r/--root flag and not an
environmental variable
> * filter results through grep and sort to remove empty lines and duplicates
> * add parent directories (duplicates filtered out by sort)
> * verify that the resolved directory is inside our root
> * replace longer symlinks first
> * handle conflict between resolved directory and existing filelist entry
>
> scripts/pacman-db-upgrade.sh.in | 92 ++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 82 insertions(+), 10 deletions(-)
>
> diff --git a/scripts/pacman-db-upgrade.sh.in b/scripts/pacman-db-upgrade.sh.in
> index b0b0ac8..7ea4077 100644
> --- a/scripts/pacman-db-upgrade.sh.in
> +++ b/scripts/pacman-db-upgrade.sh.in
> @@ -25,9 +25,17 @@ export TEXTDOMAINDIR='@localedir@'
>
> declare -r myver='@PACKAGE_VERSION@'
>
> +resolve_dir() {
> + local d="$(cd "$1"; pwd -P)"
> + [[ $d == */ ]] || d+=/
> + printf "%s" "$d"
> +}
> +
OK
> eval $(awk '/DBPath/ {print $1$2$3}' @sysconfdir@/pacman.conf)
> dbroot="${DBPath:- at localstatedir@/lib/pacman/}"
>
> +pacroot="$(resolve_dir "${PACROOT:-/}")"
> +
> USE_COLOR='y'
>
> m4_include(library/output_format.sh)
> @@ -112,18 +120,82 @@ fi
> # do not let pacman run while we do this
> touch "$lockfile"
>
> -# pacman-3.4 to 3.5 upgrade - merge depends into desc
> -if [[ $(find "$dbroot"/local -name depends) ]]; then
> - msg "$(gettext "Pre-3.5 database format detected - upgrading...")"
> - for i in "$dbroot"/local/*; do
> - if [[ -f "$i"/depends ]]; then
> - cat "$i"/depends >> "$i"/desc
> - rm "$i"/depends
> - fi
> - done
> - msg "$(gettext "Done.")"
> +if [[ -f "${dbroot}"/local/.alpm_db_version ]]; then
> + db_version=$(cat "${dbroot}"/local/.alpm_db_version)
> fi
>
OK.
> +if [[ -z "$db_version" ]]; then
> + # pacman-3.4 to 3.5 upgrade - merge depends into desc
> + if [[ $(find "$dbroot"/local -name depends) ]]; then
> + msg "$(gettext "Pre-3.5 database format detected - upgrading...")"
> + for i in "$dbroot"/local/*; do
> + if [[ -f "$i"/depends ]]; then
> + cat "$i"/depends >> "$i"/desc
> + rm "$i"/depends
> + fi
> + done
> + msg "$(gettext "Done.")"
> + fi
> +
OK
> + # pacman 4.1 to 4.2 upgrade - remove directory symlink support
> + dirlist=()
> +
> + unset GREP_OPTIONS
> + while IFS= read -r dir; do
> + dirlist+=("${pacroot}${dir%/}")
> + done < <(grep -h '/$' "$dbroot"/local/*/files | sort -ru)
> +
OK
> + mapfile -t dirlist < <(find "${dirlist[@]}" -maxdepth 0 -type l)
> +
OK
> + if [[ ${#dirlist[@]} != 0 ]]; then
if (( ${#dirlist[@]} ))
> + msg "$(gettext "Pre-4.2 database format detected - upgrading...")"
> + for dir in "${dirlist[@]}"; do
> + realdir="$(resolve_dir "$(cd $dir; pwd -P)")"
> +
> + # verify realdir is inside root
> + if [[ ${realdir:0:${#pacroot}} != $pacroot ]]; then
> + warning "$(gettext "symlink '%s' points outside pacman root, manual repair required")" "$dir"
> + continue
> + fi
OK.
> +
> + # convert to an appropriate form for the replacement
> + olddir="${dir:${#pacroot}}/"
> + newdir="${realdir:${#pacroot}}"
> +
OK
> + # construct the parents of the new directory
> + parents=""
> + parent="$(dirname "$newdir")"
use bash: parent=${newdir%/*}
> + while [[ $parent != "." ]]; do
Should that be != '/' ?
$ dirname /usr
/
Anyway, using the bash above this becomes
while [[ -n "$parent" ]]; do
> + parents+="$parent/\n"
> + parent="$(dirname "$parent")"
> + done
> +
My awk is suboptimal... So I'll comment my understanding as I go...
> + for f in "$dbroot"/local/*/files; do
> + awk -v "olddir=$olddir" -v "newdir=$newdir" -v "parents=$parents" '
"parents=${parents[@]}"
> + BEGIN {
> + i = length(olddir) + 1
> + file = substr(newdir, 0, length(newdir) - 1)
> + }
> + {
> + if ($0 == olddir) {
> + printf("%s", parents)
> + printf("%s\n", newdir)
OK (replacing old dir with newdir and its parents)
> + } else if ($0 == file) {
> + # skip
I do not understand what this bit is achieving!
> + } else if (index($0, olddir) == 1) {
> + printf("%s%s\n", newdir, substr($0, i))
OK ("moving" file in olddir to "newdir")
> + } else {
> + print
OK (not touching files outside of olddir)
> + }
> + }' "$f" | grep . | LC_ALL=C sort -u > "$f.tmp"
Why the grep?
> + mv "$f.tmp" "$f"
> + done
> + done
> + fi
> +fi
> +
> +echo "9" > "$dbroot"/local/.alpm_db_version
> +
OK
> # remove the lock file
> rm -f "$lockfile"
>
>
More information about the pacman-dev
mailing list