* [PATCH] Correct sorting of kernel names containing '_'
@ 2022-01-18 17:29 Robbie Harwood
2022-01-18 17:56 ` Robbie Harwood
0 siblings, 1 reply; 7+ messages in thread
From: Robbie Harwood @ 2022-01-18 17:29 UTC (permalink / raw)
To: grub-devel; +Cc: Robbie Harwood
sort(1) from GNU coreutils does not treat underscore as part of a
version number for `sort -V. This causes misorderings on x86_64, where
e.g. kernel-core-3.17.6-300.11.fc21.x86_64 will incorrectly sort
*before* kernel-core-3.17.6-300.fc21.x86_64.
To cope with this behavior, replace underscores with dashes in order to
approximate their intended meaning as version component separators.
Fixes: https://savannah.gnu.org/bugs/?42844
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
---
util/grub-mkconfig_lib.in | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in
index 301d1ac22..23d41475f 100644
--- a/util/grub-mkconfig_lib.in
+++ b/util/grub-mkconfig_lib.in
@@ -243,8 +243,8 @@ version_test_numeric ()
version_test_gt ()
{
- version_test_gt_a="`echo "$1" | sed -e "s/[^-]*-//"`"
- version_test_gt_b="`echo "$2" | sed -e "s/[^-]*-//"`"
+ version_test_gt_a="`echo "$1" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
+ version_test_gt_b="`echo "$2" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
version_test_gt_cmp=gt
if [ "x$version_test_gt_b" = "x" ] ; then
return 0
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] Correct sorting of kernel names containing '_'
2022-01-18 17:29 [PATCH] Correct sorting of kernel names containing '_' Robbie Harwood
@ 2022-01-18 17:56 ` Robbie Harwood
2022-01-18 21:57 ` Glenn Washburn
0 siblings, 1 reply; 7+ messages in thread
From: Robbie Harwood @ 2022-01-18 17:56 UTC (permalink / raw)
To: grub-devel
[-- Attachment #1: Type: text/plain, Size: 2869 bytes --]
Robbie Harwood <rharwood@redhat.com> writes:
> sort(1) from GNU coreutils does not treat underscore as part of a
> version number for `sort -V. This causes misorderings on x86_64, where
> e.g. kernel-core-3.17.6-300.11.fc21.x86_64 will incorrectly sort
> *before* kernel-core-3.17.6-300.fc21.x86_64.
>
> To cope with this behavior, replace underscores with dashes in order to
> approximate their intended meaning as version component separators.
>
> Fixes: https://savannah.gnu.org/bugs/?42844
> Signed-off-by: Robbie Harwood <rharwood@redhat.com>
> ---
> util/grub-mkconfig_lib.in | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in
> index 301d1ac22..23d41475f 100644
> --- a/util/grub-mkconfig_lib.in
> +++ b/util/grub-mkconfig_lib.in
> @@ -243,8 +243,8 @@ version_test_numeric ()
>
> version_test_gt ()
> {
> - version_test_gt_a="`echo "$1" | sed -e "s/[^-]*-//"`"
> - version_test_gt_b="`echo "$2" | sed -e "s/[^-]*-//"`"
> + version_test_gt_a="`echo "$1" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
> + version_test_gt_b="`echo "$2" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
> version_test_gt_cmp=gt
> if [ "x$version_test_gt_b" = "x" ] ; then
> return 0
> --
> 2.34.1
Before yinz bikeshed this into the ground, here are some other
approaches I considered:
- Use a C program to invoke librpm. This has the advantage of being
already written - it's what we currently do downstream:
https://github.com/rhboot/grub2/commit/81e155df39c9fbc97803cf9032f4138f5d9a0310
I dislike the approach regardless because it's heavyweight and doesn't
generalize to non-RPM distros (especially since e.g. Debian can
install a /usr/bin/rpm & co.). But it is "more correct", so if you
want to merge that instead, there's the patch :)
- Invoke rpmdev-vercmp if available. Problem here is that it may not be
(it's not part of the rpm package itself on Fedora, but rather
rpmdev-tools), and again, won't generalize to non-RPM distros.
- Strip out any dot-delimited section that contains non-numerics. This
has also been written and is the attached solution to
https://savannah.gnu.org/bugs/?42844 - but since it hasn't been merged
in the six years since posting, I have to assume it's been rejected.
It also would not correctly handle the case of
e.g. kernel-core-2.6.32-1_test2.x86_64 vs kernel-core-2.6.32-1.x86_64
- Strip underscore entirely, either with sed or tr. This has the same
problem as the previous one in my mind - underscore is intended as a
separator, and this causes it to not be treated as one.
- Ignore the sorting problem and keep the status quo as it is in
upstream. Attractive, but my bugzilla mailbox has plenty of angry
people in it already :)
Be well,
--Robbie
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 861 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Correct sorting of kernel names containing '_'
2022-01-18 17:56 ` Robbie Harwood
@ 2022-01-18 21:57 ` Glenn Washburn
2022-01-19 18:52 ` Robbie Harwood
2022-01-19 21:33 ` [PATCH] mkconfig: use distro sorts when available Robbie Harwood
0 siblings, 2 replies; 7+ messages in thread
From: Glenn Washburn @ 2022-01-18 21:57 UTC (permalink / raw)
To: Robbie Harwood; +Cc: The development of GNU GRUB
On Tue, 18 Jan 2022 12:56:34 -0500
Robbie Harwood <rharwood@redhat.com> wrote:
> Robbie Harwood <rharwood@redhat.com> writes:
>
> > sort(1) from GNU coreutils does not treat underscore as part of a
> > version number for `sort -V. This causes misorderings on x86_64, where
> > e.g. kernel-core-3.17.6-300.11.fc21.x86_64 will incorrectly sort
> > *before* kernel-core-3.17.6-300.fc21.x86_64.
> >
> > To cope with this behavior, replace underscores with dashes in order to
> > approximate their intended meaning as version component separators.
> >
> > Fixes: https://savannah.gnu.org/bugs/?42844
> > Signed-off-by: Robbie Harwood <rharwood@redhat.com>
> > ---
> > util/grub-mkconfig_lib.in | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in
> > index 301d1ac22..23d41475f 100644
> > --- a/util/grub-mkconfig_lib.in
> > +++ b/util/grub-mkconfig_lib.in
> > @@ -243,8 +243,8 @@ version_test_numeric ()
> >
> > version_test_gt ()
> > {
> > - version_test_gt_a="`echo "$1" | sed -e "s/[^-]*-//"`"
> > - version_test_gt_b="`echo "$2" | sed -e "s/[^-]*-//"`"
> > + version_test_gt_a="`echo "$1" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
> > + version_test_gt_b="`echo "$2" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
> > version_test_gt_cmp=gt
> > if [ "x$version_test_gt_b" = "x" ] ; then
> > return 0
> > --
> > 2.34.1
>
> Before yinz bikeshed this into the ground, here are some other
> approaches I considered:
Let the bikeshedding begin! Just kidding :)
This seems like a simple solution. Not being in the weeds on this, can
you comment on the short coming of changing the '_' to '-'? Are there
any known version string formats where this would be worse? At the
moment, it seems like a good incremental solution.
>
> - Use a C program to invoke librpm. This has the advantage of being
> already written - it's what we currently do downstream:
> https://github.com/rhboot/grub2/commit/81e155df39c9fbc97803cf9032f4138f5d9a0310
> I dislike the approach regardless because it's heavyweight and doesn't
> generalize to non-RPM distros (especially since e.g. Debian can
> install a /usr/bin/rpm & co.). But it is "more correct", so if you
> want to merge that instead, there's the patch :)
Agreed, not a fan of this approach.
> - Invoke rpmdev-vercmp if available. Problem here is that it may not be
> (it's not part of the rpm package itself on Fedora, but rather
> rpmdev-tools), and again, won't generalize to non-RPM distros.
I like this as a supplement to this patch. I'm thinking first identify
the distro (using /etc/os-release?), if known RPM distro look for
rpmdev-vercmp, else look for dpkg (to use dpkg --compare-versions), and
if neither is found fall back to this approach. This could be extended
to other package manager compare logic as desired.
> - Strip out any dot-delimited section that contains non-numerics. This
> has also been written and is the attached solution to
> https://savannah.gnu.org/bugs/?42844 - but since it hasn't been merged
> in the six years since posting, I have to assume it's been rejected.
> It also would not correctly handle the case of
> e.g. kernel-core-2.6.32-1_test2.x86_64 vs kernel-core-2.6.32-1.x86_64
This patch actually removes the last part of the version string
starting with the first dot segment whose first character is
non-numeric. Regardless, this doesn't seem like a great approach.
> - Strip underscore entirely, either with sed or tr. This has the same
> problem as the previous one in my mind - underscore is intended as a
> separator, and this causes it to not be treated as one.
Agreed.
> - Ignore the sorting problem and keep the status quo as it is in
> upstream. Attractive, but my bugzilla mailbox has plenty of angry
> people in it already :)
I think at a minimum this patch seems like a step in the right
direction. It would be nice to have it accompanied by my suggestions
above, but also recognize its a non-insignificant amount of effort.
Glenn
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Correct sorting of kernel names containing '_'
2022-01-18 21:57 ` Glenn Washburn
@ 2022-01-19 18:52 ` Robbie Harwood
2022-01-19 21:33 ` [PATCH] mkconfig: use distro sorts when available Robbie Harwood
1 sibling, 0 replies; 7+ messages in thread
From: Robbie Harwood @ 2022-01-19 18:52 UTC (permalink / raw)
To: development; +Cc: The development of GNU GRUB
[-- Attachment #1: Type: text/plain, Size: 2745 bytes --]
Glenn Washburn <development@efficientek.com> writes:
> This seems like a simple solution. Not being in the weeds on this, can
> you comment on the short coming of changing the '_' to '-'? Are there
> any known version string formats where this would be worse? At the
> moment, it seems like a good incremental solution.
I think in order for it to be a problem, someone / some packaging system
would have to be relying on '_' to not be part of the version. All
package managers I'm aware of have the version at the end - i.e., after
the package name.[1]
The only real "drawback" I'm aware of is that this still leaves
https://savannah.gnu.org/bugs/?42921 (and any other inconsistencies
between distro sort and `sort -V`) unaddressed - but none of the other
proposals listed would help with that either. (Fedora avoids this
particular issue by mandating prerelease versions start with 0 - for
instance, rather than making the 3.16.0-rc6 as gentoo did in that bug,
we make 3.16.0-0.rc6 .)
>> - Invoke rpmdev-vercmp if available. Problem here is that it may not be
>> (it's not part of the rpm package itself on Fedora, but rather
>> rpmdev-tools), and again, won't generalize to non-RPM distros.
>
> I like this as a supplement to this patch. I'm thinking first identify
> the distro (using /etc/os-release?), if known RPM distro look for
> rpmdev-vercmp, else look for dpkg (to use dpkg --compare-versions), and
> if neither is found fall back to this approach. This could be extended
> to other package manager compare logic as desired.
Interesting. Doing this for rpmdev-vercmp alone still doesn't seem
worth the effort to me, but dpkg --compare-versions is more attractive
since it'll be installed for sure. I'll see if I can make something
tolerable.
>> - Strip out any dot-delimited section that contains non-numerics.
>> This has also been written and is the attached solution to
>> https://savannah.gnu.org/bugs/?42844 - but since it hasn't been
>> merged in the six years since posting, I have to assume it's been
>> rejected. It also would not correctly handle the case of
>> e.g. kernel-core-2.6.32-1_test2.x86_64 vs kernel-core-2.6.32-1.x86_64
>
> This patch actually removes the last part of the version string
> starting with the first dot segment whose first character is
> non-numeric. Regardless, this doesn't seem like a great approach.
Oops, yes.
Be well,
--Robbie
1: This ignores things like epoch, but I'm not aware of any distro using
an epoch-like versioning for the kernel, nor does it seem likely that
Linux will change its versioning scheme in a way that breaks "normal"
version sorting. It would also be broken right now, though, which is
why I've buried mention of it it in a footnote :)
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 861 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] mkconfig: use distro sorts when available
2022-01-18 21:57 ` Glenn Washburn
2022-01-19 18:52 ` Robbie Harwood
@ 2022-01-19 21:33 ` Robbie Harwood
2022-01-20 0:36 ` Glenn Washburn
2022-01-20 1:17 ` Glenn Washburn
1 sibling, 2 replies; 7+ messages in thread
From: Robbie Harwood @ 2022-01-19 21:33 UTC (permalink / raw)
To: grub-devel; +Cc: Robbie Harwood
For Debian-likes and Fedora-likes, use the distribution's sorting tools
to determine the latest package before falling back to sort(1). While
Fedora's rpmdev-vercmp(1) is likely unavailable, Debian's is built into
dpkg itself, and hence likely present.
Refactor to remove unused code and make it easy to add other package
managers as needed.
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
---
util/grub-mkconfig_lib.in | 90 +++++++++++++++++++++------------------
1 file changed, 49 insertions(+), 41 deletions(-)
diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in
index 23d41475f..6b0d0327b 100644
--- a/util/grub-mkconfig_lib.in
+++ b/util/grub-mkconfig_lib.in
@@ -200,62 +200,70 @@ grub_file_is_not_garbage ()
return 0
}
-version_sort ()
+# A $SORT function returns 0 if $1 is newer than $2, and 1 otherwise. Other
+# package managers can be plugged in here as needed with their own functions.
+sort_dpkg ()
{
- case $version_sort_sort_has_v in
- yes)
- LC_ALL=C sort -V;;
- no)
- LC_ALL=C sort -n;;
- *)
- if sort -V </dev/null > /dev/null 2>&1; then
- version_sort_sort_has_v=yes
- LC_ALL=C sort -V
- else
- version_sort_sort_has_v=no
- LC_ALL=C sort -n
- fi;;
- esac
+ left="`echo "$1" | sed -e "s/^[^0-9]*//"`"
+ right="`echo "$2" | sed -e "s/^[^0-9]*//"`"
+ dpkg --compare-versions "$left" gt "$right"
}
-version_test_numeric ()
+sort_rpm ()
{
- version_test_numeric_a="$1"
- version_test_numeric_cmp="$2"
- version_test_numeric_b="$3"
- if [ "$version_test_numeric_a" = "$version_test_numeric_b" ] ; then
- case "$version_test_numeric_cmp" in
- ge|eq|le) return 0 ;;
- gt|lt) return 1 ;;
- esac
- fi
- if [ "$version_test_numeric_cmp" = "lt" ] ; then
- version_test_numeric_c="$version_test_numeric_a"
- version_test_numeric_a="$version_test_numeric_b"
- version_test_numeric_b="$version_test_numeric_c"
- fi
- if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | version_sort | head -n 1 | grep -qx "$version_test_numeric_b" ; then
- return 0
- else
- return 1
+ left="`echo "$1" | sed -e "s/^[^0-9]*//"`"
+ right="`echo "$2" | sed -e "s/^[^0-9]*//"`"
+ rpmdev-vercmp "$left" "$right" >/dev/null
+ if [ $? -eq 12 ]; then
+ return 0;
fi
+ return 1;
+}
+
+sort_V ()
+{
+ left="`echo "$1" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
+ right="`echo "$2" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
+ printf "$left\n$right\n" | LC_ALL=C sort -V | head -n1 | grep -qx "$right"
+}
+
+sort_n ()
+{
+ left="`echo "$1" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
+ right="`echo "$2" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
+ printf "$left\n$right\n" | LC_ALL=C sort -n | head -n1 | grep -qx "$right"
}
version_test_gt ()
{
- version_test_gt_a="`echo "$1" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
- version_test_gt_b="`echo "$2" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
- version_test_gt_cmp=gt
+ version_test_gt_a="$1"
+ version_test_gt_b="$2"
+
if [ "x$version_test_gt_b" = "x" ] ; then
return 0
fi
case "$version_test_gt_a:$version_test_gt_b" in
*.old:*.old) ;;
- *.old:*) version_test_gt_a="`echo "$version_test_gt_a" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=gt ;;
- *:*.old) version_test_gt_b="`echo "$version_test_gt_b" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=ge ;;
+ *.old:*) version_test_gt_a="`echo "$version_test_gt_a" | sed -e 's/\.old$//'`" ;;
+ *:*.old) version_test_gt_b="`echo "$version_test_gt_b" | sed -e 's/\.old$//'`" ;;
esac
- version_test_numeric "$version_test_gt_a" "$version_test_gt_cmp" "$version_test_gt_b"
- return "$?"
+
+ if [ "$version_test_gt_a" = "$version_test_gt_b" ]; then
+ return 1;
+ fi
+
+ if [ x"$SORT" = x ]; then
+ if [ -f /etc/debian_version -a -f /usr/bin/dpkg ]; then
+ SORT=sort_dpkg
+ elif [ -f /etc/redhat-release -a -f /usr/bin/rpmdev-vercmp ]; then
+ SORT=sort_rpm
+ elif sort -V </dev/null > /dev/null 2>&1; then
+ SORT=sort_V
+ else
+ SORT=sort_n
+ fi
+ fi
+ $SORT "$version_test_gt_a" "$version_test_gt_b"
}
version_find_latest ()
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] mkconfig: use distro sorts when available
2022-01-19 21:33 ` [PATCH] mkconfig: use distro sorts when available Robbie Harwood
@ 2022-01-20 0:36 ` Glenn Washburn
2022-01-20 1:17 ` Glenn Washburn
1 sibling, 0 replies; 7+ messages in thread
From: Glenn Washburn @ 2022-01-20 0:36 UTC (permalink / raw)
To: Robbie Harwood; +Cc: The development of GNU GRUB
On Wed, 19 Jan 2022 16:33:57 -0500
Robbie Harwood <rharwood@redhat.com> wrote:
> For Debian-likes and Fedora-likes, use the distribution's sorting tools
> to determine the latest package before falling back to sort(1). While
> Fedora's rpmdev-vercmp(1) is likely unavailable, Debian's is built into
> dpkg itself, and hence likely present.
>
> Refactor to remove unused code and make it easy to add other package
> managers as needed.
>
> Signed-off-by: Robbie Harwood <rharwood@redhat.com>
> ---
> util/grub-mkconfig_lib.in | 90 +++++++++++++++++++++------------------
> 1 file changed, 49 insertions(+), 41 deletions(-)
>
> diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in
> index 23d41475f..6b0d0327b 100644
> --- a/util/grub-mkconfig_lib.in
> +++ b/util/grub-mkconfig_lib.in
> @@ -200,62 +200,70 @@ grub_file_is_not_garbage ()
> return 0
> }
>
> -version_sort ()
> +# A $SORT function returns 0 if $1 is newer than $2, and 1 otherwise. Other
> +# package managers can be plugged in here as needed with their own functions.
> +sort_dpkg ()
> {
> - case $version_sort_sort_has_v in
> - yes)
> - LC_ALL=C sort -V;;
> - no)
> - LC_ALL=C sort -n;;
> - *)
> - if sort -V </dev/null > /dev/null 2>&1; then
> - version_sort_sort_has_v=yes
> - LC_ALL=C sort -V
> - else
> - version_sort_sort_has_v=no
> - LC_ALL=C sort -n
> - fi;;
> - esac
> + left="`echo "$1" | sed -e "s/^[^0-9]*//"`"
> + right="`echo "$2" | sed -e "s/^[^0-9]*//"`"
> + dpkg --compare-versions "$left" gt "$right"
> }
>
> -version_test_numeric ()
> +sort_rpm ()
> {
> - version_test_numeric_a="$1"
> - version_test_numeric_cmp="$2"
> - version_test_numeric_b="$3"
> - if [ "$version_test_numeric_a" = "$version_test_numeric_b" ] ; then
> - case "$version_test_numeric_cmp" in
> - ge|eq|le) return 0 ;;
> - gt|lt) return 1 ;;
> - esac
> - fi
> - if [ "$version_test_numeric_cmp" = "lt" ] ; then
> - version_test_numeric_c="$version_test_numeric_a"
> - version_test_numeric_a="$version_test_numeric_b"
> - version_test_numeric_b="$version_test_numeric_c"
> - fi
> - if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | version_sort | head -n 1 | grep -qx "$version_test_numeric_b" ; then
> - return 0
> - else
> - return 1
> + left="`echo "$1" | sed -e "s/^[^0-9]*//"`"
> + right="`echo "$2" | sed -e "s/^[^0-9]*//"`"
> + rpmdev-vercmp "$left" "$right" >/dev/null
> + if [ $? -eq 12 ]; then
> + return 0;
> fi
> + return 1;
> +}
> +
> +sort_V ()
> +{
> + left="`echo "$1" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
> + right="`echo "$2" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
> + printf "$left\n$right\n" | LC_ALL=C sort -V | head -n1 | grep -qx "$right"
> +}
> +
> +sort_n ()
> +{
> + left="`echo "$1" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
> + right="`echo "$2" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
> + printf "$left\n$right\n" | LC_ALL=C sort -n | head -n1 | grep -qx "$right"
> }
>
> version_test_gt ()
> {
> - version_test_gt_a="`echo "$1" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
> - version_test_gt_b="`echo "$2" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
> - version_test_gt_cmp=gt
> + version_test_gt_a="$1"
> + version_test_gt_b="$2"
> +
> if [ "x$version_test_gt_b" = "x" ] ; then
> return 0
> fi
> case "$version_test_gt_a:$version_test_gt_b" in
> *.old:*.old) ;;
> - *.old:*) version_test_gt_a="`echo "$version_test_gt_a" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=gt ;;
> - *:*.old) version_test_gt_b="`echo "$version_test_gt_b" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=ge ;;
> + *.old:*) version_test_gt_a="`echo "$version_test_gt_a" | sed -e 's/\.old$//'`" ;;
> + *:*.old) version_test_gt_b="`echo "$version_test_gt_b" | sed -e 's/\.old$//'`" ;;
> esac
> - version_test_numeric "$version_test_gt_a" "$version_test_gt_cmp" "$version_test_gt_b"
> - return "$?"
> +
> + if [ "$version_test_gt_a" = "$version_test_gt_b" ]; then
> + return 1;
> + fi
> +
> + if [ x"$SORT" = x ]; then
> + if [ -f /etc/debian_version -a -f /usr/bin/dpkg ]; then
> + SORT=sort_dpkg
> + elif [ -f /etc/redhat-release -a -f /usr/bin/rpmdev-vercmp ]; then
> + SORT=sort_rpm
> + elif sort -V </dev/null > /dev/null 2>&1; then
> + SORT=sort_V
> + else
> + SORT=sort_n
> + fi
> + fi
> + $SORT "$version_test_gt_a" "$version_test_gt_b"
> }
>
> version_find_latest ()
I like that this makes the previous implementation simpler too. Thanks
Robbie, LGTM.
Reviewed-by: Glenn Washburn <development@efficientek.com>
Glenn
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] mkconfig: use distro sorts when available
2022-01-19 21:33 ` [PATCH] mkconfig: use distro sorts when available Robbie Harwood
2022-01-20 0:36 ` Glenn Washburn
@ 2022-01-20 1:17 ` Glenn Washburn
1 sibling, 0 replies; 7+ messages in thread
From: Glenn Washburn @ 2022-01-20 1:17 UTC (permalink / raw)
To: Robbie Harwood; +Cc: The development of GNU GRUB
Hi Robbie,
Looks like I sent my first response a tad too soon.
On Wed, 19 Jan 2022 16:33:57 -0500
Robbie Harwood <rharwood@redhat.com> wrote:
> For Debian-likes and Fedora-likes, use the distribution's sorting tools
> to determine the latest package before falling back to sort(1). While
> Fedora's rpmdev-vercmp(1) is likely unavailable, Debian's is built into
> dpkg itself, and hence likely present.
>
> Refactor to remove unused code and make it easy to add other package
> managers as needed.
>
> Signed-off-by: Robbie Harwood <rharwood@redhat.com>
> ---
> util/grub-mkconfig_lib.in | 90 +++++++++++++++++++++------------------
> 1 file changed, 49 insertions(+), 41 deletions(-)
>
> diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in
> index 23d41475f..6b0d0327b 100644
> --- a/util/grub-mkconfig_lib.in
> +++ b/util/grub-mkconfig_lib.in
> @@ -200,62 +200,70 @@ grub_file_is_not_garbage ()
> return 0
> }
>
> -version_sort ()
> +# A $SORT function returns 0 if $1 is newer than $2, and 1 otherwise. Other
> +# package managers can be plugged in here as needed with their own functions.
> +sort_dpkg ()
> {
> - case $version_sort_sort_has_v in
> - yes)
> - LC_ALL=C sort -V;;
> - no)
> - LC_ALL=C sort -n;;
> - *)
> - if sort -V </dev/null > /dev/null 2>&1; then
> - version_sort_sort_has_v=yes
> - LC_ALL=C sort -V
> - else
> - version_sort_sort_has_v=no
> - LC_ALL=C sort -n
> - fi;;
> - esac
> + left="`echo "$1" | sed -e "s/^[^0-9]*//"`"
> + right="`echo "$2" | sed -e "s/^[^0-9]*//"`"
> + dpkg --compare-versions "$left" gt "$right"
> }
>
> -version_test_numeric ()
> +sort_rpm ()
> {
> - version_test_numeric_a="$1"
> - version_test_numeric_cmp="$2"
> - version_test_numeric_b="$3"
> - if [ "$version_test_numeric_a" = "$version_test_numeric_b" ] ; then
> - case "$version_test_numeric_cmp" in
> - ge|eq|le) return 0 ;;
> - gt|lt) return 1 ;;
> - esac
> - fi
> - if [ "$version_test_numeric_cmp" = "lt" ] ; then
> - version_test_numeric_c="$version_test_numeric_a"
> - version_test_numeric_a="$version_test_numeric_b"
> - version_test_numeric_b="$version_test_numeric_c"
> - fi
> - if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | version_sort | head -n 1 | grep -qx "$version_test_numeric_b" ; then
> - return 0
> - else
> - return 1
> + left="`echo "$1" | sed -e "s/^[^0-9]*//"`"
> + right="`echo "$2" | sed -e "s/^[^0-9]*//"`"
> + rpmdev-vercmp "$left" "$right" >/dev/null
> + if [ $? -eq 12 ]; then
> + return 0;
> fi
> + return 1;
> +}
> +
> +sort_V ()
> +{
> + left="`echo "$1" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
> + right="`echo "$2" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
> + printf "$left\n$right\n" | LC_ALL=C sort -V | head -n1 | grep -qx "$right"
> +}
> +
> +sort_n ()
> +{
> + left="`echo "$1" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
> + right="`echo "$2" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
> + printf "$left\n$right\n" | LC_ALL=C sort -n | head -n1 | grep -qx "$right"
> }
>
> version_test_gt ()
> {
> - version_test_gt_a="`echo "$1" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
> - version_test_gt_b="`echo "$2" | sed -e "s/[^-]*-//" -e "s/_/-/g"`"
> - version_test_gt_cmp=gt
> + version_test_gt_a="$1"
> + version_test_gt_b="$2"
> +
> if [ "x$version_test_gt_b" = "x" ] ; then
> return 0
> fi
> case "$version_test_gt_a:$version_test_gt_b" in
> *.old:*.old) ;;
> - *.old:*) version_test_gt_a="`echo "$version_test_gt_a" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=gt ;;
> - *:*.old) version_test_gt_b="`echo "$version_test_gt_b" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=ge ;;
> + *.old:*) version_test_gt_a="`echo "$version_test_gt_a" | sed -e 's/\.old$//'`" ;;
> + *:*.old) version_test_gt_b="`echo "$version_test_gt_b" | sed -e 's/\.old$//'`" ;;
> esac
> - version_test_numeric "$version_test_gt_a" "$version_test_gt_cmp" "$version_test_gt_b"
> - return "$?"
> +
> + if [ "$version_test_gt_a" = "$version_test_gt_b" ]; then
> + return 1;
> + fi
> +
> + if [ x"$SORT" = x ]; then
> + if [ -f /etc/debian_version -a -f /usr/bin/dpkg ]; then
I think we should be checking for binary presence using "comamnd -v
dpkg >/dev/null". This way dpkg only needs to be in PATH, not some
specific directory. This construct works in bash, sh, and dash. Same for
the rpmdev-vercmp.
> + SORT=sort_dpkg
> + elif [ -f /etc/redhat-release -a -f /usr/bin/rpmdev-vercmp ]; then
> + SORT=sort_rpm
I was thinking about this some more and I'm thinking there might be
distros out there that have dpkg or rpmdev-vercmp (Slack or SuSE?) but
not the etc files. Perhaps we should add two more elif clauses.
elif command -v rpmdev-vercmp >/dev/null; then
SORT=sort_rpm
elif command -v dpkg >/dev/null; then
SORT=sort_dpkg
I suggest checking for rpmdev-vercmp first because its less commonly
installed and it seems more likely to me that an RPM based distro
(where you want to prefer using rpmdev-vercmp) has dpkg installed than
a DEB distro having rpmdev-vercmp installed.
Glenn
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2022-01-20 1:20 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-01-18 17:29 [PATCH] Correct sorting of kernel names containing '_' Robbie Harwood
2022-01-18 17:56 ` Robbie Harwood
2022-01-18 21:57 ` Glenn Washburn
2022-01-19 18:52 ` Robbie Harwood
2022-01-19 21:33 ` [PATCH] mkconfig: use distro sorts when available Robbie Harwood
2022-01-20 0:36 ` Glenn Washburn
2022-01-20 1:17 ` Glenn Washburn
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.