Skip to content

Commit

Permalink
Rewrite cache_dirs logic
Browse files Browse the repository at this point in the history
* initialize cache_dirs with one of:
 1. value provided in command line -c switch
 2. pacman.conf provided in command line -C switch
 3. container pacman.conf file
* find first writable cache_dir, bind it rw, remove from cache_dirs
* extract host mirrors, find file:// ones, append to cache_dirs
* extract server url, find file:// ones, append to cache_dirs
* concatenate cache_dirs removing duplicates, bind them ro to container
* check if any extra cache_dirs was defined, append to
  container pacman.conf as new [options] section.

Fix #57 archlinux#58 archlinux#59
  • Loading branch information
bartus authored and hexchain committed Sep 4, 2021
1 parent c5c5dbc commit cb35b64
Showing 1 changed file with 40 additions and 22 deletions.
62 changes: 40 additions & 22 deletions arch-nspawn.in
Original file line number Diff line number Diff line change
Expand Up @@ -61,35 +61,48 @@ if (( ${#cache_dirs[@]} == 0 )); then
mapfile -t cache_dirs < <(pacman-conf --config "${pac_conf:-$working_dir/etc/pacman.conf}" CacheDir)
fi

# find first writable cache, bind it to container in rw mode, remove it from cache_dirs
for cache_dir in "${cache_dirs[@]}"; do
if [[ -d "$cache_dir" && -w "$cache_dir" ]]; then
mount_args+=("--bind=$cache_dir")
mapfile -t cache_dirs < <(printf "%s\n" "${cache_dirs[@]}" | grep -vFx "$cache_dir")
break
fi
# this could print an warning to the user that no host caches would be used
done


# shellcheck disable=2016
host_mirrors=($(pacman-conf --repo extra Server 2> /dev/null | sed -r 's#(.*/)extra/os/.*#\1$repo/os/$arch#'))

for host_mirror in "${host_mirrors[@]}"; do
if [[ $host_mirror == *file://* ]]; then
host_mirror=$(echo "$host_mirror" | sed -r 's#file://(/.*)/\$repo/os/\$arch#\1#g')
for m in "$host_mirror"/pool/*/; do
in_array "$m" "${cache_dirs[@]}" || cache_dirs+=("$m")
done
fi
done
# extract local host mirrors (Server=file://...)
mapfile -t host_mirrors_local < <(printf "%s\n" "${host_mirrors[@]}" | grep -Po "(?<=file://).*(?=\/\$repo)")

while read -r line; do
mapfile -t lines < <(pacman-conf --config "${pac_conf:-$working_dir/etc/pacman.conf}" \
--repo $line Server | sed -r 's#(.*/)[^/]+/os/.+#\1#')
for line in "${lines[@]}"; do
if [[ $line = file://* ]]; then
line=${line#file://}
in_array "$line" "${cache_dirs[@]}" || cache_dirs+=("$line")
fi
for host_mirror in "${host_mirrors_local[@]}"; do
for m in "$host_mirror"/pool/*/; do
cache_dirs+=("$m")
done
done < <(pacman-conf --config "${pac_conf:-$working_dir/etc/pacman.conf}" --repo-list)
done

mount_args+=("--bind=${cache_dirs[0]//:/\\:}")
mapfile -t repos < <(pacman-conf --config "${pac_conf:-$working_dir/etc/pacman.conf}" --repo-list)

for cache_dir in "${cache_dirs[@]:1}"; do
mount_args+=("--bind-ro=${cache_dir//:/\\:}")
declare -a servers
for repo in "${repos[@]}"; do
mapfile -t -O "${#servers[@]}" servers < <( \
pacman-conf --config "${pac_conf:-$working_dir/etc/pacman.conf}" --repo "$repo" Server | \
grep -Po "(?<=file://).*$" | sed -r -e "s#\$repo#$repo#" -e 's#/$arch##' )
done

cache_dirs+=("${servers[@]}")

# rest of cache_dirs are getting bind ro therefor we don't care about ordering and can use sort -u for concatenation
if (( ${#cache_dirs[@]} != 0 )); then
mapfile -t cache_dirs < <(printf '%s\n' "${cache_dirs[@]}" | sort -u)
for cache_dir in "${cache_dirs[@]}"; do
mount_args+=("--bind-ro=${cache_dir//:/\\:}")
done
fi

# {{{ functions
copy_hostconf () {
unshare --fork --pid gpg --homedir "$working_dir"/etc/pacman.d/gnupg/ --no-permission-warning --quiet --batch --import --import-options import-local-sigs "$(pacman-conf GpgDir)"/pubring.gpg >/dev/null 2>&1
Expand All @@ -100,13 +113,18 @@ copy_hostconf () {
[[ -n $pac_conf ]] && cp "$pac_conf" "$working_dir/etc/pacman.conf"
[[ -n $makepkg_conf ]] && cp "$makepkg_conf" "$working_dir/etc/makepkg.conf"

# check if any extra cache_dirs was added
mapfile -t container_cache_dirs < <(pacman-conf --config "$working_dir/etc/pacman.conf" CacheDir)
mapfile -t extra_cache_dirs < <(comm -13 <(printf "%s\n" "${container_cache_dirs[@]}"|sort) <(printf "%s\n" "${cache_dirs[@]}"|sort))
if (( ${#extra_cache_dirs[@]} != 0 )); then
echo -e "\n[options]\nCacheDir = ${extra_cache_dirs[*]}" >> "$working_dir/etc/pacman.conf"
fi

local file
for file in "${files[@]}"; do
mkdir -p "$(dirname "$working_dir$file")"
cp -T "$file" "$working_dir$file"
done

sed -r "s|^#?\\s*CacheDir.+|CacheDir = ${cache_dirs[*]}|g" -i "$working_dir/etc/pacman.conf"
}
# }}}

Expand Down

0 comments on commit cb35b64

Please sign in to comment.