mirror of
https://github.com/rocky-linux/rocky-tools.git
synced 2024-11-25 14:41:25 +00:00
Fix rpm and dnf package spec issues
When attempting to check if a package exists for a particular provide string what happened is if an older version of the package was on the system but a newer version in the repositories then the older (system) version would be returned by dnf provides, but this could not be translated into a package name with dnf repoquery because that specific version could not be found in the repos. The solution was to check rpm first to translate the package name on the system and then dnf repoquery if rpm doesn't find it. This brought to light issues when passing arrays of package names to rpm and dnf which might happen to contain an empty element. In this case rpm and dnf would consider the empty arg an indicator that it should match all packages on the system, or all available packages. While we should try to avoid passing arrays with empty elements, this highlighed a need to make rpm and dnf safer in this regard, and so there are now saferpm and sfednf functions which simply strip any empty args before calling the appropriate command with the rest of the args untouched. This commit also fixes an issue with output column formatting.
This commit is contained in:
parent
ef1cfd1fb9
commit
844896ad6b
@ -228,11 +228,36 @@ provides_pkg () (
|
|||||||
provides=$(dnf -q provides "$1" | awk '{print $1; nextfile}') ||
|
provides=$(dnf -q provides "$1" | awk '{print $1; nextfile}') ||
|
||||||
return 1
|
return 1
|
||||||
set +o pipefail
|
set +o pipefail
|
||||||
pkg=$(dnf -q repoquery --queryformat '%{NAME}' "$provides") ||
|
pkg=$(rpm -q --queryformat '%{NAME}\n' "$provides") ||
|
||||||
|
pkg=$(dnf -q repoquery --queryformat '%{NAME}\n' "$provides") ||
|
||||||
exit_message "Can't get package name for $provides."
|
exit_message "Can't get package name for $provides."
|
||||||
printf '%s\n' "$pkg"
|
printf '%s\n' "$pkg"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# If you pass an empty arg as one of the package specs to rpm it will match
|
||||||
|
# every package on the system. This funtion simply strips out any empty args
|
||||||
|
# and passes the rest to rpm to avoid this side-effect.
|
||||||
|
saferpm () (
|
||||||
|
args=()
|
||||||
|
for a in "$@"; do
|
||||||
|
if [[ $a ]]; then
|
||||||
|
args+=("$a")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
rpm "${args[@]}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# And a similar function for dnf
|
||||||
|
safednf () (
|
||||||
|
args=()
|
||||||
|
for a in "$@"; do
|
||||||
|
if [[ $a ]]; then
|
||||||
|
args+=("$a")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
dnf "${args[@]}"
|
||||||
|
)
|
||||||
|
|
||||||
collect_system_info () {
|
collect_system_info () {
|
||||||
# Check the efi mount first, so we can bail before wasting time on all these
|
# Check the efi mount first, so we can bail before wasting time on all these
|
||||||
# other checks if it's not there.
|
# other checks if it's not there.
|
||||||
@ -285,8 +310,8 @@ collect_system_info () {
|
|||||||
done
|
done
|
||||||
|
|
||||||
printf '%s\n' '' '' "Found the following repositories which map from $PRETTY_NAME to Rocky Linux 8:"
|
printf '%s\n' '' '' "Found the following repositories which map from $PRETTY_NAME to Rocky Linux 8:"
|
||||||
column -t -N "$PRETTY_NAME,Rocky Linux 8" < <(for r in "${!repo_map[@]}"; do
|
column -t -s $'\t' -N "$PRETTY_NAME,Rocky Linux 8" < <(for r in "${!repo_map[@]}"; do
|
||||||
printf '%s %s\n' "${repo_map[$r]}" "$r"
|
printf '%s\t%s\n' "${repo_map[$r]}" "$r"
|
||||||
done)
|
done)
|
||||||
|
|
||||||
printf '\n%s' "${blue}Getting system package names for $PRETTY_NAME$nocolor."
|
printf '\n%s' "${blue}Getting system package names for $PRETTY_NAME$nocolor."
|
||||||
@ -344,26 +369,27 @@ collect_system_info () {
|
|||||||
done
|
done
|
||||||
|
|
||||||
printf '%s\n' '' '' "Found the following system packages which map from $PRETTY_NAME to Rocky Linux 8:"
|
printf '%s\n' '' '' "Found the following system packages which map from $PRETTY_NAME to Rocky Linux 8:"
|
||||||
column -t -N "$PRETTY_NAME,Rocky Linux 8" < <(for p in "${!pkg_map[@]}"; do
|
column -t -s $'\t' -N "$PRETTY_NAME,Rocky Linux 8" < <(for p in "${!pkg_map[@]}"; do
|
||||||
printf '%s %s\n' "${pkg_map[$p]}" "$p"
|
printf '%s\t%s\n' "${pkg_map[$p]}" "$p"
|
||||||
done)
|
done)
|
||||||
|
|
||||||
printf '%s\n' '' "${blue}Getting list of installed system packages$nocolor."
|
printf '%s\n' '' "${blue}Getting list of installed system packages$nocolor."
|
||||||
readarray -t installed_packages < <(rpm -qa --queryformat="%{NAME}\n" "${pkg_map[@]}")
|
|
||||||
|
readarray -t installed_packages < <(saferpm -qa --queryformat="%{NAME}\n" "${pkg_map[@]}")
|
||||||
declare -g -A installed_pkg_check installed_pkg_map
|
declare -g -A installed_pkg_check installed_pkg_map
|
||||||
for p in "${installed_packages[@]}"; do
|
for p in "${installed_packages[@]}"; do
|
||||||
installed_pkg_check[$p]=1
|
installed_pkg_check[$p]=1
|
||||||
done
|
done
|
||||||
for p in "${!pkg_map[@]}"; do
|
for p in "${!pkg_map[@]}"; do
|
||||||
if [[ ${installed_pkg_check[${pkg_map[$p]}]} ]]; then
|
if [[ ${pkg_map[$p]} && ${installed_pkg_check[${pkg_map[$p]}]} ]]; then
|
||||||
installed_pkg_map[$p]=${pkg_map[$p]}
|
installed_pkg_map[$p]=${pkg_map[$p]}
|
||||||
fi
|
fi
|
||||||
done;
|
done;
|
||||||
|
|
||||||
printf '%s\n' '' "We will replace the following $PRETTY_NAME packages with their Rocky Linux 8 equivalents"
|
printf '%s\n' '' "We will replace the following $PRETTY_NAME packages with their Rocky Linux 8 equivalents"
|
||||||
column -t -N "Packages to be Removed,Packages to be Installed" < <(
|
column -t -s $'\t' -N "Packages to be Removed,Packages to be Installed" < <(
|
||||||
for p in "${!installed_pkg_map[@]}"; do
|
for p in "${!installed_pkg_map[@]}"; do
|
||||||
printf '%s %s\n' "${installed_pkg_map[$p]}" "$p"
|
printf '%s\t%s\n' "${installed_pkg_map[$p]}" "$p"
|
||||||
done
|
done
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -383,7 +409,7 @@ collect_system_info () {
|
|||||||
# Get a list of system enabled modules.
|
# Get a list of system enabled modules.
|
||||||
readarray -t enabled_modules < <(
|
readarray -t enabled_modules < <(
|
||||||
set -e -o pipefail
|
set -e -o pipefail
|
||||||
dnf -q "${repo_map[@]/#/--repo=}" module list --enabled |
|
safednf -q "${repo_map[@]/#/--repo=}" module list --enabled |
|
||||||
awk '
|
awk '
|
||||||
$1 == "@modulefailsafe", /^$/ {next}
|
$1 == "@modulefailsafe", /^$/ {next}
|
||||||
$1 == "Name", /^$/ {if ($1!="Name" && !/^$/) print $1":"$2}
|
$1 == "Name", /^$/ {if ($1!="Name" && !/^$/) print $1":"$2}
|
||||||
@ -448,7 +474,7 @@ package_swaps() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
# Use dnf shell to swap the system packages out.
|
# Use dnf shell to swap the system packages out.
|
||||||
dnf -y shell --disablerepo=\* --noautoremove \
|
safednf -y shell --disablerepo=\* --noautoremove \
|
||||||
--setopt=protected_packages= --setopt=keepcache=True \
|
--setopt=protected_packages= --setopt=keepcache=True \
|
||||||
"${dnfparameters[@]}" \
|
"${dnfparameters[@]}" \
|
||||||
<<EOF
|
<<EOF
|
||||||
@ -470,7 +496,7 @@ EOF
|
|||||||
# linux package will be removed and then installed again.
|
# linux package will be removed and then installed again.
|
||||||
local -a check_removed check_installed
|
local -a check_removed check_installed
|
||||||
readarray -t check_removed < <(
|
readarray -t check_removed < <(
|
||||||
rpm -qa --qf '%{NAME}\n' "${installed_pkg_map[@]}" \
|
saferpm -qa --qf '%{NAME}\n' "${installed_pkg_map[@]}" \
|
||||||
"${addl_pkg_removes[@]}" | sort -u
|
"${addl_pkg_removes[@]}" | sort -u
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -478,9 +504,13 @@ EOF
|
|||||||
printf '%s\n' '' "${blue}Packages found on system that should still be removed. Forcibly removing them with rpm:$nocolor"
|
printf '%s\n' '' "${blue}Packages found on system that should still be removed. Forcibly removing them with rpm:$nocolor"
|
||||||
# Removed packages still found on the system. Forcibly remove them.
|
# Removed packages still found on the system. Forcibly remove them.
|
||||||
for pkg in "${check_removed[@]}"; do
|
for pkg in "${check_removed[@]}"; do
|
||||||
|
# Extra safety measure, skip if empty string
|
||||||
|
if [[ -z $pkg ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
printf '%s\n' "$pkg"
|
printf '%s\n' "$pkg"
|
||||||
rpm -e --allmatches --nodeps "${check_removed[@]}" ||
|
saferpm -e --allmatches --nodeps "$pkg" ||
|
||||||
rpm -e --allmatches --nodeps --noscripts --notriggers "$pkg"
|
saferpm -e --allmatches --nodeps --noscripts --notriggers "$pkg"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -488,7 +518,7 @@ EOF
|
|||||||
readarray -t check_installed < <(
|
readarray -t check_installed < <(
|
||||||
{
|
{
|
||||||
printf '%s\n' "${!installed_pkg_map[@]}" | sort -u
|
printf '%s\n' "${!installed_pkg_map[@]}" | sort -u
|
||||||
rpm -qa --qf '%{NAME}\n' "${!installed_pkg_map[@]}" | sort -u
|
saferpm -qa --qf '%{NAME}\n' "${!installed_pkg_map[@]}" | sort -u
|
||||||
} | sort | uniq -u
|
} | sort | uniq -u
|
||||||
)
|
)
|
||||||
if (( ${#check_installed[@]} )); then
|
if (( ${#check_installed[@]} )); then
|
||||||
@ -537,7 +567,7 @@ EOF
|
|||||||
printf '%s\n' '' "${blue}Removing dnf cache$nocolor"
|
printf '%s\n' '' "${blue}Removing dnf cache$nocolor"
|
||||||
rm -rf /var/cache/{yum,dnf}
|
rm -rf /var/cache/{yum,dnf}
|
||||||
printf '%s\n' "${blue}Ensuring repos are enabled before the package swap$nocolor"
|
printf '%s\n' "${blue}Ensuring repos are enabled before the package swap$nocolor"
|
||||||
dnf -y config-manager --set-enabled "${!repo_map[@]}" || {
|
safednf -y config-manager --set-enabled "${!repo_map[@]}" || {
|
||||||
printf '%s\n' 'Repo name missing?'
|
printf '%s\n' 'Repo name missing?'
|
||||||
exit 25
|
exit 25
|
||||||
}
|
}
|
||||||
@ -545,24 +575,24 @@ EOF
|
|||||||
if (( ${#managed_repos[@]} )); then
|
if (( ${#managed_repos[@]} )); then
|
||||||
# Filter the managed repos for ones still in the system.
|
# Filter the managed repos for ones still in the system.
|
||||||
readarray -t managed_repos < <(
|
readarray -t managed_repos < <(
|
||||||
dnf -q repolist "${managed_repos[@]}" | awk '$1!="repo" {print $1}'
|
safednf -q repolist "${managed_repos[@]}" | awk '$1!="repo" {print $1}'
|
||||||
)
|
)
|
||||||
|
|
||||||
if (( ${#managed_repos[@]} )); then
|
if (( ${#managed_repos[@]} )); then
|
||||||
printf '%s\n' '' "${blue}Disabling subscription managed repos$nocolor."
|
printf '%s\n' '' "${blue}Disabling subscription managed repos$nocolor."
|
||||||
dnf -y config-manager --disable "${managed_repos[@]}"
|
safednf -y config-manager --disable "${managed_repos[@]}"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if (( ${#enabled_modules[@]} )); then
|
if (( ${#enabled_modules[@]} )); then
|
||||||
printf '%s\n' "${blue}Enabling modules$nocolor" ''
|
printf '%s\n' "${blue}Enabling modules$nocolor" ''
|
||||||
dnf -y module enable "${enabled_modules[@]}" ||
|
safednf -y module enable "${enabled_modules[@]}" ||
|
||||||
exit_message "Can't enable modules ${enabled_modules[*]}"
|
exit_message "Can't enable modules ${enabled_modules[*]}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Make sure that excluded repos are disabled.
|
# Make sure that excluded repos are disabled.
|
||||||
printf '%s\n' "${blue}Disabling excluded modules$nocolor" ''
|
printf '%s\n' "${blue}Disabling excluded modules$nocolor" ''
|
||||||
dnf -y module disable "${module_excludes[@]}" ||
|
safednf -y module disable "${module_excludes[@]}" ||
|
||||||
exit_message "Can't disable modules ${module_excludes[*]}"
|
exit_message "Can't disable modules ${module_excludes[*]}"
|
||||||
|
|
||||||
printf '%s\n' '' "${blue}Syncing packages$nocolor" ''
|
printf '%s\n' '' "${blue}Syncing packages$nocolor" ''
|
||||||
|
Loading…
Reference in New Issue
Block a user