Difference between revisions of "RPMS"
(→SPEC: Post/Postun Notes) |
|||
(21 intermediate revisions by one user not shown) | |||
Line 1: | Line 1: | ||
+ | == Abstract == | ||
+ | |||
+ | |||
A src.rpm is completely self contained, it has everything internal to it to archive, patch, build, and install a piece of software. It also contains macros to run actions before, and after the package is installed, and trigger macros to run before/after its installed when it detects other packages. The action of building an RPM will never involve you installing the package as a requirement to build it. | A src.rpm is completely self contained, it has everything internal to it to archive, patch, build, and install a piece of software. It also contains macros to run actions before, and after the package is installed, and trigger macros to run before/after its installed when it detects other packages. The action of building an RPM will never involve you installing the package as a requirement to build it. | ||
− | What makes app vault rpms unique is that you are in effect packaging something for another package management system. That involves more steps, and more changes that have nothing to do with the RPM system. IE, they have their own XML file used to describe the application, and its dependencies. So here are some tips on building a package that is maintainable: | + | |
+ | == PSA App Vault RPMS == | ||
+ | |||
+ | What makes app vault rpms unique is that you are in effect packaging something for another package management system. That involves more steps, and more changes that have nothing to do with the RPM system. IE, they have their own XML file used to describe the application, and its dependencies. | ||
+ | |||
+ | |||
+ | |||
+ | == So here are some tips on building a package that is maintainable: == | ||
+ | |||
1) dont ever modify the application tarball directly. Use patches instead, even if it takes you an extra hour to do it right. When you update your rpm in a few months, its going to save you a lot of time. | 1) dont ever modify the application tarball directly. Use patches instead, even if it takes you an extra hour to do it right. When you update your rpm in a few months, its going to save you a lot of time. | ||
Line 12: | Line 23: | ||
5) Dont make rpms interactive. Avoid any output, special commands, documentation, that get displayed during the installation. If its being run through yum, a web interface, etc. Odds are noone will see it anyway, and worst case, it could break those apps. | 5) Dont make rpms interactive. Avoid any output, special commands, documentation, that get displayed during the installation. If its being run through yum, a web interface, etc. Odds are noone will see it anyway, and worst case, it could break those apps. | ||
+ | |||
+ | |||
+ | == building rpms with rpmbuild == | ||
+ | |||
+ | 1) Build as yourself. Not root, you'll need to do some work first. Start with your ~/.rpmmacros file | ||
+ | vim ~/.rpmmacros | ||
+ | |||
+ | 2) Add path to build dirs | ||
+ | %_topdir /home/sshinn/src/redhat/ | ||
+ | |||
+ | 3) Create your builddirs | ||
+ | mkdir -p ~/src/redhat | ||
+ | cd ~/src/redhat | ||
+ | mkdir RPMS SPECS SOURCES BUILD SRPMS | ||
+ | cd RPMS | ||
+ | mkdir i386 i686 x86_64 | ||
+ | |||
+ | 4) Build stuff, example: | ||
+ | rpmbuild --rebuild whatever-1.0-1.src.rpm | ||
+ | |||
+ | == building rpms with mock == | ||
+ | |||
+ | |||
+ | mock -r <DISTRO> whatever.src.rpm | ||
+ | |||
+ | On my system, Ive called my /etc/mock/ configs el4-i386.cfg, el5-x86_64.cfg, so the way I run it is: | ||
+ | |||
+ | mock -r el4-i386 whatever.src.rpm | ||
+ | |||
+ | I also wrote a wrapper around [[Mock]] to rapidly build packages for multiple platforms called "art-build". Its loosely based on Dag Wieers DAR package (pre-mock builder), so instead of building from the src.rpm, I build from the .spec file. You can see art-build here: http://www.atomicorp.com/Tutorials/Building%20RPMS/ | ||
+ | |||
+ | == Modifying RPMS == | ||
+ | |||
+ | |||
+ | == SPEC: Conditional Statements == | ||
+ | |||
+ | Example 1: an if someversion, else (new way) | ||
+ | |||
+ | %if 0%{?el3}%{?el4} | ||
+ | BuildRequires: somepackage | ||
+ | %else | ||
+ | BuildRequires: someotherpackage | ||
+ | %endif | ||
+ | |||
+ | |||
+ | Example 2: Specific version (old way) | ||
+ | |||
+ | %{?fc4:BuildRequires: libpcap } | ||
+ | |||
+ | == SPEC: automatically add in the date to a changelog == | ||
+ | |||
+ | %define date %(echo `LC_ALL="C" date +"%a %b %d %Y"`) | ||
+ | %changelog | ||
+ | * %{date} PLD Team <feedback@pld-linux.org> | ||
+ | |||
+ | == Requires/BuildRequires: == | ||
+ | |||
+ | Some interesting ways to implement a Requires: | ||
+ | |||
+ | BuildRequires: %{_includedir}/pcap.h | ||
+ | |||
+ | This would get around a problem where two distros are calling a package different things. In this example it would get around libpcap being called "libpcap" on el4, and "libpcap-devel" on fc9. | ||
+ | |||
+ | |||
+ | == SPEC: Post/Postun Notes == | ||
+ | |||
+ | %post | ||
+ | # only rpm -i (not rpm {-U|-F}) except if this is a first time install | ||
+ | if [ $1 = 1 ]; then | ||
+ | echo whatever | ||
+ | fi | ||
+ | # only rpm {-U|-F} | ||
+ | if [ $1 = 2 ]; then | ||
+ | echo whatever | ||
+ | fi | ||
+ | |||
+ | |||
+ | %pre | ||
+ | # only on rpm {-U|-F} | ||
+ | |||
+ | if [ $1 = 2 ]; then | ||
+ | echo "pre code 2, upgrade event" | ||
+ | |||
+ | fi | ||
+ | |||
+ | %preun | ||
+ | # only rpm -e (not rpm {-U|-F}) | ||
+ | if [ $1 = 0 ]; then | ||
+ | echo whatever | ||
+ | fi | ||
+ | |||
+ | |||
+ | %postun | ||
+ | # only rpm -e (not rpm {-U|-F}) | ||
+ | if [ $1 = 0 ]; then | ||
+ | echo whatever | ||
+ | fi | ||
+ | # only rpm {-U|-F} (not rpm -e) | ||
+ | if [ $1 = 1 ]; then | ||
+ | /sbin/service syslog-ng condrestart | ||
+ | fi |
Latest revision as of 09:47, 27 April 2010
[edit] Abstract
A src.rpm is completely self contained, it has everything internal to it to archive, patch, build, and install a piece of software. It also contains macros to run actions before, and after the package is installed, and trigger macros to run before/after its installed when it detects other packages. The action of building an RPM will never involve you installing the package as a requirement to build it.
[edit] PSA App Vault RPMS
What makes app vault rpms unique is that you are in effect packaging something for another package management system. That involves more steps, and more changes that have nothing to do with the RPM system. IE, they have their own XML file used to describe the application, and its dependencies.
[edit] So here are some tips on building a package that is maintainable:
1) dont ever modify the application tarball directly. Use patches instead, even if it takes you an extra hour to do it right. When you update your rpm in a few months, its going to save you a lot of time.
2) leverage the %install macro if you've got to move files around. This is especially handy since the PSA app vault packages rebundle the web app as httpdocs.tar. Dont waste time doing that up front, when you do it in %install it will make your life a lot easier on the next update.
3) Try to avoid using the Epoch: tag (this overrides the version #). I went Epoch crazy early on, and its coming back to haunt me now. Only use the Epoch tag when all other options have been exhausted.
4) When you're building binary RPMs (not app vault), check out mock. It builds a chrooted OS for whatever platform you need to build packages for. This is useful in that it keeps your build tree away from your production OS.
5) Dont make rpms interactive. Avoid any output, special commands, documentation, that get displayed during the installation. If its being run through yum, a web interface, etc. Odds are noone will see it anyway, and worst case, it could break those apps.
[edit] building rpms with rpmbuild
1) Build as yourself. Not root, you'll need to do some work first. Start with your ~/.rpmmacros file
vim ~/.rpmmacros
2) Add path to build dirs
%_topdir /home/sshinn/src/redhat/
3) Create your builddirs
mkdir -p ~/src/redhat cd ~/src/redhat mkdir RPMS SPECS SOURCES BUILD SRPMS cd RPMS mkdir i386 i686 x86_64
4) Build stuff, example:
rpmbuild --rebuild whatever-1.0-1.src.rpm
[edit] building rpms with mock
mock -r <DISTRO> whatever.src.rpm
On my system, Ive called my /etc/mock/ configs el4-i386.cfg, el5-x86_64.cfg, so the way I run it is:
mock -r el4-i386 whatever.src.rpm
I also wrote a wrapper around Mock to rapidly build packages for multiple platforms called "art-build". Its loosely based on Dag Wieers DAR package (pre-mock builder), so instead of building from the src.rpm, I build from the .spec file. You can see art-build here: http://www.atomicorp.com/Tutorials/Building%20RPMS/
[edit] Modifying RPMS
[edit] SPEC: Conditional Statements
Example 1: an if someversion, else (new way)
%if 0%{?el3}%{?el4} BuildRequires: somepackage %else BuildRequires: someotherpackage %endif
Example 2: Specific version (old way)
%{?fc4:BuildRequires: libpcap }
[edit] SPEC: automatically add in the date to a changelog
%define date %(echo `LC_ALL="C" date +"%a %b %d %Y"`) %changelog * %{date} PLD Team <feedback@pld-linux.org>
[edit] Requires/BuildRequires:
Some interesting ways to implement a Requires:
BuildRequires: %{_includedir}/pcap.h
This would get around a problem where two distros are calling a package different things. In this example it would get around libpcap being called "libpcap" on el4, and "libpcap-devel" on fc9.
[edit] SPEC: Post/Postun Notes
%post # only rpm -i (not rpm {-U|-F}) except if this is a first time install if [ $1 = 1 ]; then echo whatever fi # only rpm {-U|-F} if [ $1 = 2 ]; then echo whatever fi
%pre # only on rpm {-U|-F} if [ $1 = 2 ]; then echo "pre code 2, upgrade event"
fi
%preun # only rpm -e (not rpm {-U|-F}) if [ $1 = 0 ]; then echo whatever fi
%postun # only rpm -e (not rpm {-U|-F}) if [ $1 = 0 ]; then echo whatever fi # only rpm {-U|-F} (not rpm -e) if [ $1 = 1 ]; then /sbin/service syslog-ng condrestart fi