7

I deliver an application via an RPM.

This application delivers various directories and files.
E.g. under /opt/internal/com
a file structure is being copied.

I was expecting that on rpm -e all the file structure delivered under /opt/internal/com will be removed.
But it does not.
There are directories in the file structure that are non-empty.

Is this the reason? But these (non-empty) directories were created by the RPM installation. So I would expect that they would be "owned" by RPM and removed automatically.

Is this wrong? Am I supposed to remove them manually?

masegaloeh
  • 17,978
  • 9
  • 56
  • 104
Jim
  • 305
  • 2
  • 4
  • 8

2 Answers2

7

RPM won't delete any files it doesn't know about, so if new files have been created in a directory that are not part of a package, RPM won't remove them, or the directories.

It will delete the directories if they are empty and it knows about them. It depends how the spec file was written.

James O'Gorman
  • 5,249
  • 2
  • 23
  • 28
  • 1
    Will it delete directories that are NOT empty and DOES know about them? (the rpm delivered them) – Jim Apr 06 '12 at 11:05
  • `It depends how the spec file was written.` Do you mean I should have removed them in a `%postun` section? – Jim Apr 06 '12 at 11:11
  • 1
    Jim, James is saying that it wont remove directories that are non-empty because they contain *files* it is not aware of. If you feel that you need to remove these directories during uninstall a `%postun` is appropriate, but know that this is how most RPMs work. – Kyle Smith Apr 06 '12 at 11:14
  • @Jim You could use a %postun to `rm -rf` the directories, but ordinarily RPM doesn't do this because it's not safe to do so. You might lose data that you didn't intend to just because you removed a package (e.g. config file modifications). – James O'Gorman Apr 06 '12 at 11:28
  • So basically if my rpm spec has in the `%files` section the hierarchy `/opt/internal/com` and it delivers that hierarchy, on uninstall it will nor remove everything under `com` if there are other files dirs even if it delivered them? It delivers them recursively from `/opt/internal/com` but knows only about `/opt/internal/com` and not the containing files/folders? – Jim Apr 06 '12 at 11:34
  • @JamesO'Gorman:Did I get this? – Jim Apr 06 '12 at 11:40
  • @Jim RPM will _only_ remove files and dirs that were specified in the `%files` section of the spec. If you install dir `/opt/internal/com` and under that a file `foo`, `rpm -e` will remove `foo`, but will **only** remove `/opt/internal/com` if there are no other files. If you created a file `bar`, then the directory will remain. – James O'Gorman Apr 06 '12 at 11:56
  • @JamesO'Gorman:I specified `/opt/internal/com` in the `%files`. Under com is `foo/bar/stuff/file1.txt`. The RPM installs `/opt/internal/com/foo/bar/stuff/file1.txt`. But you are saying that it will now not remove `com` because of `foo/bar/stuff/file1.txt`? Even though the RPM delivered this hierarchy?This part I don't get – Jim Apr 06 '12 at 12:07
  • This is really confusing for me. – Jim Apr 06 '12 at 12:23
  • 1
    @Jim Was `foo/bar/stuff/file1.txt` installed by the RPM and specified in `%files`? If so, `rpm -e` will remove is _as long as_ it has not been modified. If it wasn't installed by the RPM, then it will not be removed. – James O'Gorman Apr 06 '12 at 13:01
  • @JamesO'Gorman:In the `%files` I specified ONLY `/opt/internal/com` which contained `/opt/internal/com/foo/bar/stuff/file1.txt`. So the interal files were delivered as well. Will this mean that RPM knows about `stuff` dir or not? – Jim Apr 06 '12 at 13:10
  • The best way is to check what the RPM delivers with `rpm -qpl package.rpm`. – James O'Gorman Apr 06 '12 at 14:54
  • @JamesO'Gorman, "_If so, rpm -e will remove is **as long as it has not been modified.**_" This was key for me understanding why some files were not removed on RPM upgrade for a package I'm building. – CivFan Jun 23 '16 at 19:38
2

Answer from James O'Gorman is absolutely right.

One more scenario to add, which I recently encountered, is you need to tell directories owned by RPM package in %files section with a line "%dir /dir/path", so that it will remember all files and directories in RPM database when installed and can be removed (unless contents of the dir not own by that package) during RPM erase.

More care should be taken while specifying owned directories as there is different methods to process RPM erase on different distros.

e.g. if your package contains following files & directories:

**DIR:** /opt/dir1/empty_dir **FILE:** /opt/dir1/file1 **FILE:** /opt/dir1/dir2/file2

then your %files section should look like

%files
%dir /opt/dir1
%dir /opt/dir1/empty_dir
%dir /opt/dir1/dir2
/opt/dir1/file1
/opt/dir1/dir2/file2

Tricky part is, you might miss %dir /opt/dir1 and it won't be removed even if it is empty on some distros.

avg598
  • 121
  • 2
  • This is not correct. "_...if a directory is specified in the %files list, the contents of that directory, and the contents of every directory under it, will automatically be included in the package._" [See the %dir section in this rpm.org doc](http://www.rpm.org/max-rpm/s1-rpm-inside-files-list-directives.html) – CivFan Jun 23 '16 at 19:36