I am using Fedora 10, I have created an rpm file for my software. It removes all the files from the installed directory. If i use yum remove command or rpm -e command. but after installation my application automatically creates some extra folders in home directory. If I uninstall my application then file from home directories do not get removed. So what I have to do. Is there anything that I have to write in my spec file?
You need to create a post-uninstall script inside your rpm.
The %postun Script
The %postun script executes after the package has been removed. It is the last chance for a package to clean up after itself. Quite often, %postun scripts are used to run ldconfig to remove newly erased shared libraries from ld.so.cache.
See: Maximum RPM: Taking the Red Hat Package Manager to the Limit
Related
I have a rpm created for dev environment and CONTAINS a configuration file that points to dev. Now I have to create the rpm for another environment for which I need to replace just one file in the SOURCES folder and update the reference in .spec and rebuild it. Issue is that I don't have the .spec file that I used to create the rpm for dev.
So upon searching, came across rpmrebuild and I was able to see the .spec file in the editor.
When I give rpmrebuild command, the spec file opens in the editor.
Here's the small snippet from the file
/root/rpmbuild/SOURCES /root/rpmbuild/SOURCES
%files
%attr(0755, root, root) "/opt/**{replace/with/newfile/path**}"
But updating that that gives me - File not found: /root/.tmp/rpmrebuild.2345/work/root/opt/{path/to/newfile}
I don't know if I have to use rpmrebuild command with any --params in order to replace the file in the SOURCES and its reference in the .spec. There are no other changes to be made.
Please guide.
Note: I am a unix novice
I presume you do not have the src.rpm for this package. If you do, then it's very easy, simply install that with rpm -ihv /path/to/src/rpm as you would do with any RPM file. The contents, unless specified otherwise, will be extracted to ~/rpmbuild. The spec will be under ~/rpmbuild/SPECS, the sources under ~/rpmbuild/SOURCES, etc.
If you do not have the src.rpm but only the RPM itself, install the rpmrebuild package from the EPEL repos and then:
$ rpmrebuild -e -p /path/to/package
It will open the spec in your default editor. Edit it and save the spec wherever you want.
Then, assuming you have all the needed source files (declared in the spec using the SourceN directives), you can call:
$ rpmbuild -bb /path/to/spec
To rebuild the RPM from the edited spec.
I have a recipe to compile a printer driver and have a few simple lines to run in do_install.
do_install() {
install -d ${D}${libdir}/cups/filter
install -m 755 ${B}/src/rastertoprinter ${D}${libdir}/cups/filter/
install -d ${D}${sysconfdir}/cups/ppd
install -m 755 ${B}/../rastertoprinter/printer_name.ppd ${D}${sysconfdir}/cups/ppd/
}
To compile the source I have a DEPENDS on cups and also an RDEPENDS on cups as the OS needs cups installed to print of course.
The printer driver is not publicly available so as such I've renamed it to rastertoprinter and changed my path names.
Essentially I need to simply create or ensure the directory /usr/lib/cups/filter exists, and copy the rastertoprinter program there. I also need to create or ensure the directory /etc/cups/ppd exists and copy the .ppd file into that directory.
The first two lines run fine but the 3rd throws the following errors:
file /etc/cups conflicts between attempted installs of printername-r0.corei7_64 and cups-2.2.2-r0.corei7_64
file /etc/cups/ppd conflicts between attempted installs of printername-r0.corei7_64 and cups-2.2.2-r0.corei7_64
I don't understand why both recipes can't create this directory and put stuff in it? Strangely I'm able to do the first /usr/lib/cups/filter directory though fine.
Turns out the issue is that each file to be packaged in Yocto will also generate a %dir for each parent of each file. We don't want to own a directory that is owned by another package, so if you add this to your recipe:
DIRFILES = "1"
It will cause your package to not own parent directories of the files you package.
This will generate an rpm spec file without the %dir entries.
I created a binary package with this command:
dpkg-deb --build -z9 -Zlzma $(DEB_SRC_DIR) $(DEB_DEST_DIR)
and install it on my Ubuntu 12.04 with this command:
sudo dpkg -i /path/to/package
The contents of the package I think are irrelevant.
Despite the sudo command the files in the installation directory belong to the current user and not to root as I expected.
How can I fix that?
Try to run the dpkg-deb command with fakeroot:
`fakeroot dpkg-deb ...`
(This will only help if the files in the source directory already have the correct ownership, which they probably dont. The problem you're actually trying to solve here, is to create an archive with files in it that belong to user root, which is where fakeroot theoretically helps.)
Let me say though, that what you are doing is not the best way for creating a binary package (far from it).
Instead, create a debian/ directory with dh_make (from the dh-make package), and edit the control file and changelog accordingly. You also need a file debian/install that lists what files you are installing and where they should go. There are various guides on the net (and on Stack Overflow) that explain this process. For example, look at the Debian New Maintainers' Guide.
You can then use dpkg-buildpackage to create a real, standard-conforming Debian package with your files in a reproducible way.
dpkg-deb is a low-level tool for manipulating existing deb files; it's not meant to be used for package creation.
I have a debian package that I built that contains a tar ball of the files, a control file, and a postinst file. Its built using dpkg-deb and it installs properly using dpkg.
The modification I would like to make is to have the installation directory of the files be determined at runtime based on an environment variable that will be set when dpkg -i is run on the deb file. I echo out the environment variable in the postinst script and I can see that its set properly.
My questions:
1) Is it possible to dynamically determine the installation directory at runtime?
2) If its possible how would I go about this? I have read about the rules file and the mypackage.install files but I don't know if either of these would allow me to accomplish this.
I could hack it by copying the files to the target location in the posinst script but I would prefer to do it the right way if possible.
Thanks in advance!
So this is what I found out about this problem over the past couple of weeks.
With prepackaged binaries you can't build a debian package with a destination directory dynamicall determined at runtime. I believe that this might be possible if installing a package that is built from source where you can set the install directory using configure. But in this case since these are embedded Ubuntu machines they don't have make so I didn't pursue such an option. I did work out a non traditional method (hack) for installing that did work. Since debian packages simply contain a tar ball relative to / simply build your package relative to a directory under /tmp. In the postinst script you can then determine where to copy the files from the archive into a permanent location.
I expected that after rebooting and the automatic deletion of the subdirectory under /tmp that dpkg might not know that the file package existed. This wasn't a problem. When I ran 'dpkg -l myapp' it showed as still installed. Updating the package using dpkg/apt-get also worked without a hitch.
What I did find is that if you attempted to remove the package using 'dpkg -r myapp' that dpkg would try and remove /tmp which wasn't good. However /tmp isn't easily removed so it never succeeded. Plus in our situation we never remove packages but instead simply upgrade them.
I eventually had to abandon the universal package due to code differences in the sources resulting in having to recompile per platform but I would have left it this way and it did work.
I tried using --instdir to change the install directory of the package and it does relocate the files but dpkg fails since the dpkg file can't be found relative to the new instdir. Using --instdir is sort of like a chroot. I also tried --admindir and --root in various combinations to see if I could use the dpkg system relative to / but install relocate the files but they didn't work. I guess rpm has a relocate option that works but not Ubuntu.
You can also write a script that runs dpkg-deb with a different environment for 6 times, generating 6 different packages. When you make a modification, you simply have to run your script, and all 6 packages gets generated and you can install them on your machines avoiding postinst hacking!
Why not install to a standard location, and simply use a postinst script to create symbolic links to the desired location? This is much cleaner, and shouldn't break anything in dpk -I.
In the process of building an RPM package, I have to specify the BuildRoot and later will be used in %install which invovles $RPM_BUILD_ROOT. I always think that $RPM_BUILD_ROOT is the fake installation for RPM to perform packaging. Then, at install time using the RPM package, it will install into actual location. For example:
$RPM_BUILD_ROOT/usr/bin
I thought that $RPM_BUILD_ROOT is for the packaging process only, and in some ways RPM can distinguish the $RPM_BUILD_ROOT and the actual install location when the user performs "rpm -ivh package.rpm" will be /usr/bin.
But recently upon reading some documents, it is suggested that $RPM_BUILD_ROOT is the actual location which will be installed, and the $RPM_BUILD_ROOT is specified by user with the setting of environment variable $RPM_BUILD_ROOT in order to let the users install the package in their desire locations. Otherwise, $RPM_BUILD_ROOT will be null and it will install into the default location. In the above case, it is /usr/bin . Thus, $RPM_BUILD_ROOT is not just for packaging or "fake installation" process, but is a way for user to define install location, similar to select folder location in Windows.
I don't know my thinking is correct or not. Can someone please verify? Thanks in advance.
$RPM_BUILD_ROOT (or the equivalent %{buildroot} SPEC file macro) always holds the directory under which RPM will look for any files to package. The RPM scripts (e.g. the script that compresses the manual pages) will also use that value to know where to look for the files that were just installed. Normally, this value will be non-empty and contain a location away from the system directories - usually somewhere under /tmp or /var/tmp.
The author of the SPEC file is expected to make sure that make install (or whatever installer the software in question is using) will place any files under $RPM_BUILD_ROOT, with the same hierarchy that should be used when the software is finally installed. E.g. to have RPM install ls in /bin/ls, the %install SPEC file section should make sure that ls is placed in $RPM_BUILD_ROOT/bin/ls.
The author of the SPEC file is also expected to use the BuildRoot: tag to specify a proper location. Alternatively, the build system could have an rpmrc RPM configuration file with a proper entry. In any case the build root should be set, so that:
Normal users will be able to build the source package.
Should the superuser ever build the source package, the build process will not clobber any system files, unless the superuser installs the resulting binary package. And yes, there may be a good reason to build some packages as root - for example, running the full glibc testsuite requires root privileges for some tests.
That said, RPM can and will build a package with an empty build root variable. In that case both the build install and the final destination locations will coincide. A potential call to e.g. make install will use the default locations, thus clobbering the system files under e.g. /usr/lib if run with sufficient privileges. Additionally, having /usr/bin/* in your %files section will happily pull the whole contents of the build host /usr/bin/ directory into your binary package.
Bottom line:
Never use an empty build root.
Do not build packages as root unless there is absolutely no other way.
the file ~/.rpmmacros defines the paths per user:
%_topdir %(echo $HOME)/rpmbuild
%_tmppath %{_topdir}/tmp
and one can also define them with rpmbuild command line parameters:
rpmbuild --define '_topdir /home/username/rpmbuild'