rpm-software-management/yum

install command will return error code 1 if package is already installed

0x7162 opened this issue ยท 13 comments

A lot of installation scripts rely on exit code of commands, and it will exit if any of subcommands has non-zero exit code.
Yum may return error code (1) in case package is already installed
(imho it is not an error)

Example:

Step 1 (first install):

yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm; echo $?
...
Installed:
  epel-release.noarch 0:7-11                                                                                                                                                                                                               

Complete!
0

Step 2 (install the same package):

yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm; echo $?
...
/var/tmp/yum-root-dE0FBq/epel-release-latest-7.noarch.rpm: does not update installed package.
Error: Nothing to do
1

Step3 (wrong path):

yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch__BUG__.rpm; echo $?
Loaded plugins: fastestmirror
Cannot open: https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch__BUG__.rpm. Skipping.
Error: Nothing to do
1

Suggestion:

A) return 0 exit code (no_error) in _already_installed_case
or
B) use different error exit code

Alt solutions I found:

1. use localinstall:

will return 0, but it also will return 0 in wrong cases,
like:
yum -y localinstall https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch_BUG.rpm || echo $?
Loaded plugins: fastestmirror, versionlock
Cannot open: https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch_BUG.rpm. Skipping.
Nothing to do
0

2. use reinstall:

works fine, but it will REINSTALL it every time (trade off: at least time)

Reference:

https://github.com/rpm-software-management/yum/blob/master/yum/__init__.py#L5654

nothing?

I would at least change the Error into a Warning (and possibly return 0).

Is this really about yum? Aren't you using dnf nowadays?

yum development has stopped and nobody will change the code unless it's a serious bugfix, which this issue is not. While I agree the behaviour isn't right, we don't want to be changing it at this stage.

I'll just go ahead and close this, please reopen only if this is a serious issue for you (and then still I don't see the changes high).

Then please put a big sign on the description and/or the README stating so.

And possibly a template for new issues warning about that too. Frankly, GH should have project flags for such things :-|

What exactly is it that you would like a big sign for? That development has stopped and dnf has superseded yum? Yes, we should do that... (though I'd guess it's common knowledge in the Fedora community at least for the people savvy enough to report issues on GH?) Anything else?

I'm not a Fedora user, I'm a Centos User. Centos still distributes and uses yum.

I agree with the need to get this fixed. The VFX community is still using CentOS 7.7, which is using yum as its package manager. I have a Salt state that attempts to install a package and it gets an exit code of 1 because it is already installed. I can tell the state 1 is a success, however Salt requisites fail even if I designate 1 is success. What is really needed is for 'yum install' to return 0 if the package is already installed. That would be in line with least surprise.

+1 here, Amazon Elastic Map Reduce (EMR) will fail on bootstrap scripts that fail due to yum.

Sorry about this, I understand the frustration, but CentOS reflects what is in RHEL, and this isn't going to be fixed in RHEL (as far as I know, as of now). Only important bug fixes go there (YMMV on this of course). It's been that way for a long time and it seems to unfortunately be staying that way in RHEL 7. It's fixed in RHEL 8.

I just got bitten by this too, very weird to return the same error code as other failures... ๐Ÿค”

Ok, so ... the yum in el7 is pretty old. It doesn't even have "fail-or-install-n" which is one of the last changes/workarounds I put in for this kind of problem.

I understand everyone here is approaching the problem from "I want FOO installed when command finishes, it is already installed, therefore that is a success" but the cli has always come from the POV "I want you to do operation FOO, I did nothing therefore I did not do what you asked."

This becomes much more complicated when there are multiple packages and/or wildcards.

Traditional workaround is something like:

if ! yum list installed zsh; then
    yum install zsh
fi

...but, again, what people expect either of those to do when zsh is "zsh vim*" will be different, sometimes people even expect different things in different situations.

It was on the TODO list a long time ago to have more than just a "we failed" error code, but how expectations differ from reality is very big and it was never a high enough priority, we didn't have as many people working on it as do now and we never got patches (although, TBF, that would have been big/messy). If that's still something you want maybe you can get it into dnf.

A long time ago I hoped people would use the API when doing API like things, but that is long past.

For less hacky solutions to this problem on el7:

  • On your test machine test and create a transaction file and then on your production server use yum load-transaction
  • Use yum-debug-dump/yum-debug-restore
  • Use ansible to specify a list of packages that should be present.
  • Use "gold" repos. and yum distro-sync full and/or metapackages.