Skip to content

Fix #699 Fixes for handling file query arguments in rpm v4.14.0+ - #702

Merged
robnagler merged 4 commits into
masterfrom
699-fix-almalinux-install-perl-rpm
Sep 20, 2026
Merged

robnagler merged 4 commits into
masterfrom
699-fix-almalinux-install-perl-rpm

Conversation

@schellj

@schellj schellj commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

@schellj
schellj requested a review from robnagler September 2, 2026 19:09
Comment thread rsconf/package_data/rsconf/rsconf.sh Outdated
# --nomanifest prevents a non-rpm file from being treated as a list of file names.
name=$(rpm --query --package --nomanifest "$name" 2>/dev/null)
if [[ ! $name ]]; then
install_err "$1: not found or not a valid RPM"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's always better to use a temporary for this so you don't have to do this ($1).

declare n=$(rpm --query --package --nomanifest "$name")
if [[ ! $n ]]; then
     install_err "not found or invalid rpm=$name (see previous error)"    
fi
name=$n

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll update.

However, not sure if we want the --nomanifest flag here after all. With it no errors seem to get printed at all, whether the file contains an html (not found) response or a corrupted rpm, etc. So there won't be an error for "see previous error". Without --nomanifest we get the weird errors that the previous code was complaining about, e.g.:

[py3;@... rpmtest]# cat > foo.rpm
<html>not found</html>
[py3;@... rpmtest]# rpm --query --package foo.rpm
error: open of <html>not failed: No such file or directory
error: open of found</html> failed: No such file or directory

@robnagler robnagler Sep 4, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This case is a bug in install_download (or whatever is called). It should check the output for this. install_script_eval validates the result before executing. We should validate the rpm downloaded is an rpm instead of just jumping to installing it.

@schellj schellj Sep 8, 2026 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if I'm following exactly what you're saying.

Maybe this is what you mean regarding the specific "not found" example in my comment -- I could see install_download verifying the response status, but it doesn't seem like it should be the responsibility of that function to validate the contents, unless we specifically add an install_download_rpm function.

We can validate the rpm downloaded here in rsconf.sh, but the code is already doing that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In rsconf_install_file there's code like this:

    install_download "$path" > "$tmp"
    # Unlikely we are downloading HTML so this is a sanity check on SimpleHTTPServer
    # returning something that's a directory listing or not found
    if grep -s -q -i '^<title>' "$tmp"; then
        install_err "$path: unexpected HTML file (directory listing?)"
    fi

This probably should be in install_download. To avoid a broad change, rsconf.sh should have a wrapper that does this. If it really is an html file downloaded, it'll end in "html". Perhaps the above test is too loose and should look for <html> or whatever too. There may be scripts that output HTML, but I don't think that's true in rsconf.

For now just leave it as you have it.

Comment thread rsconf/package_data/rsconf/rsconf.sh Outdated
_rsconf_need_yum_install() {
declare name=$1
if [[ -e $name ]]; then
# in rpm v4.14.0+, rpm -q treats an extant file arg as installed; query version instead.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to read why "extant" vs "existing". I believe it's an "overuse" of the word, because it implies something about it having "survived". That's irrelevant to this check, which is really existing. I prefer simpler language in comments except when they are necessary. I'm not sure what "query version" means here. You are querying "$name", not the version so I don't understand that part of the comment. I think the interesting bit is that "--package" is superfluous in 4.14.0+, that is, it always checks for a file on disk.

Go simpler:

# before rpm 4.14 --package was required to validate an rpm file.
# --nomanifest prevents a non-rpm file from being treated as a list of file names.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

before rpm 4.14 --package was required to validate an rpm file.

But we're doing this command for two reasons; to validate the rpm file, and to get something that we can use with rpm --query at the end of the function to tell us if the package is installed. So, this comment misses the second part, which isn't obvious (at least to me) and why I said "query version instead" in my comment (though mine didn't talk about the first part).

How about this?

    # --package is required to validate a file before rpm 4.14; after, querying an existing file
    # doesn't tell us if it's installed, so we need to query with the file's package version.
    # --nomanifest keeps a non-rpm from being read as a list of names.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I understand the comment you wrote. :) I think this is better (combining below's code):

declare n=$(rpm --query --package --nomanifest "$name")
if [[ ! $n ]]; then
     install_err "not found or invalid rpm=$name (see previous error)"    
fi
# rpm --query returns version-qualified package, which is a better value to check than the file
name=$n

Comment thread tests/rsconf_sh_test.py Outdated
@@ -0,0 +1,24 @@
"""test rsconf.sh

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a lot of code to test something that depends on semantics of actual rpms and the rpm command. This type of testing is not very useful imho. Rather, if you really wanted to stub this out, you could create a github workflow that uses a centos & alma image with an integration test of actually installing or not installing an rpm. I don't think that's very useful either.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, but I was trying to validate the changes since I was both modifying the code and there was at least one bug before (i.e., with Centos 7, the existing todo filter in rsconf_yum_install would have never removed an rpm file argument). It seems like there should be a test for this logic, but I can remove it if you don't think it's useful and there isn't a better way.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These type of stub tests are too specific to a few lines of code and they give a false sense of "working". Yes, they'll test the new code, and they'll be brittle. The number of cases alone was way too long to be useful.

Realistic tests are always better even though they take longer. One option is to create tests that call docker and run inside them with "file:///" urls for the install. These tests would take longer to run, but they are "correct" in that they test the semantics e2e. The tests wouldn't need to run on CI, or these could be special tests that run inside a CI that's got multiple environments configured.

All this is doable, and it takes time.

with Centos 7, the existing todo filter in rsconf_yum_install would have never removed an rpm file argument

Aside: we should probably put those files in install_tmp and then they would get deleted on exit. Not sure why they wouldn't be there now. The removal inline is a good idea to not clutter the machine, and removal at the end is a good backup.

Finally, you could ask copilot to do a review. I wonder if it would have caught this bug.

Comment thread rsconf/package_data/rsconf/rsconf.sh Outdated
# --nomanifest prevents a non-rpm file from being treated as a list of file names.
name=$(rpm --query --package --nomanifest "$name" 2>/dev/null)
if [[ ! $name ]]; then
install_err "$1: not found or not a valid RPM"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In rsconf_install_file there's code like this:

    install_download "$path" > "$tmp"
    # Unlikely we are downloading HTML so this is a sanity check on SimpleHTTPServer
    # returning something that's a directory listing or not found
    if grep -s -q -i '^<title>' "$tmp"; then
        install_err "$path: unexpected HTML file (directory listing?)"
    fi

This probably should be in install_download. To avoid a broad change, rsconf.sh should have a wrapper that does this. If it really is an html file downloaded, it'll end in "html". Perhaps the above test is too loose and should look for <html> or whatever too. There may be scripts that output HTML, but I don't think that's true in rsconf.

For now just leave it as you have it.

@schellj
schellj force-pushed the 699-fix-almalinux-install-perl-rpm branch from 5b871e9 to 32de2a8 Compare September 19, 2026 18:39
@robnagler
robnagler merged commit 772a302 into master Sep 20, 2026
2 checks passed
@robnagler
robnagler deleted the 699-fix-almalinux-install-perl-rpm branch September 20, 2026 12:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants