Difference between revisions of "RPM Quick Reference"

From NST Wiki
Jump to navigationJump to search
(HowTo Rebuild An RPM Package From An Installed RPM)
(HowTo Rebuild An RPM Package From An Installed RPM)
 
Line 303: Line 303:
  
 
== HowTo Rebuild An RPM Package From An Installed RPM ==
 
== HowTo Rebuild An RPM Package From An Installed RPM ==
The '''[http://sourceforge.net/projects/rpmrebuild/?source=navbar rpmrebuild]''' utility is a tool to build an RPM file from a package that has already been installed. This tool does not require any rpm building knowledge.
+
The '''[http://sourceforge.net/projects/rpmrebuild/?source=navbar rpmrebuild]''' utility is a tool to build an RPM file from a package that has already been installed. This tool does not require any RPM building knowledge.
  
 
=== rpmbuild Example ===
 
=== rpmbuild Example ===

Latest revision as of 07:46, 22 May 2015

RPM Build Tips

RPM Reference Documentation

Tips on RPM "%macros"

To find the secret "%macros", try commands like:

rpmbuild --showrc | grep _ln
rpmbuild --showrc | grep share

To find RPM query format macros:

rpm --querytags | less

Values Passed to the %pre, %post, %preun, and %postun Scripts

Reference: Fedora Packaging:ScriptletSnippets

  1. When the first version of a package is installed, its %pre and %post scripts will be passed an argument equal to 1.
  2. When the last version of a package is erased, its %preun and %postun scripts will be passed an argument equal to 0.
  3. When upgrading the value passed will be greater than 1 (1 for version already installed, plus 1 for version being installed).

Example: %pre, %post, %preun, and %postun Scripts for the 'ntop' RPM Package

Warning.png NST 18 and above now uses the new systemd "Macroized Scriptlets" found in the reference: Fedora Packaging:ScriptletSnippets for the %post, %preun and %postun sections.

SysV and LSB Init Service Scripts

%pre
#
# ntop package first install:
#
# Add an 'ntop' group and user...
if [ $1 -eq 1 ]; the
  /usr/bin/getent group %{name} >/dev/null || /usr/sbin/groupadd -r %{name};
  /usr/bin/getent passwd %{name} >/dev/null || \
    /usr/sbin/useradd -r -g %{name} -d %{_localstatedir}/lib/ntop -s /sbin/nologin -c "ntop" %{name} >/dev/null || :;
fi

%post
#
# ntop package first install:
#
# Add an 'ntop' service and set the boot state to: 'disabled'
if [ $1 -eq 1 ]; then
  /sbin/chkconfig --add %{name} &> /dev/null || :;
  /bin/systemctl disable %{name}.service &> /dev/null || :;
fi

%preun
#
# ntop package removal:
#
# Stop a running 'ntop' service and remove start/stop links...
if [ $1 -eq 0 ]; then
  /bin/systemctl stop %{name}.service &> /dev/null || :;
  /sbin/chkconfig --del %{name} &> /dev/null || :;
fi

%postun
#
# Package removal:
#
# Remove group and user 'ntop' from system...
if [ $1 -eq 0 ]; then
  /usr/sbin/usergroup %{name} 2>/dev/null || :;
  /usr/sbin/userdel -f %{name} 2>/dev/null || :;
fi
#
# ntop package upgrade:
#
# If 'ntop' was running, stop it and restart it with the upgraded version...
if [ $1 -ge 1 ]; then
  /bin/systemctl try-restart %{name}.service &> /dev/null || :;
fi

Systemd Service Control

%pre
#
# ntop package first install:
#
# Add an 'ntop' group and user...
if [ $1 -eq 1 ]; the
  /usr/bin/getent group %{name} >/dev/null || /usr/sbin/groupadd -r %{name};
  /usr/bin/getent passwd %{name} >/dev/null || \
    /usr/sbin/useradd -r -g %{name} -d %{_localstatedir}/lib/ntop -s /sbin/nologin -c "ntop" %{name} >/dev/null || :;
fi

%post
#
# ntop package first install:
#
# Add an 'ntop' service and set the boot state to: 'disabled'
if [ $1 -eq 1 ]; then 
  /bin/systemctl --no-reload disable %{name}.service &> /dev/null || :;
fi
/bin/systemctl --system daemon-reload &> /dev/null || :

%preun
#
# ntop package removal:
#
# Stop a running 'ntop' service and remove start/stop links...
if [ $1 -eq 0 ]; then
  /bin/systemctl stop %{name}.service &> /dev/null || :;
  /bin/systemctl --no-reload disable %{name}.service &> /dev/null || :;
fi

%postun
#
# Package removal:
#
# Remove group and user 'ntop' from system...
if [ $1 -eq 0 ]; then
  /usr/sbin/usergroup %{name} 2>/dev/null || :;
  /usr/sbin/userdel -f %{name} 2>/dev/null || :;
fi
#
# ntop package upgrade:
#
# If 'ntop' was running, stop it and restart it with the upgraded version...
if [ $1 -ge 1 ]; then
  /bin/systemctl try-restart %{name}.service &> /dev/null || :;
fi
/bin/systemctl --system daemon-reload &> /dev/null || :

Fedora RPM Scriptlet Ordering

From the Packaging:ScriptletSnippets page:

  1. %pretrans of new package
  2. %pre of new package
  3. (package install)
  4. %post of new package
  5. %triggerin of other packages (set off by installing new package)
  6. %triggerin of new package (if any are true)
  7. %triggerun of old package (if it's set off by uninstalling the old package)
  8. %triggerun of other packages (set off by uninstalling old package)
  9. %preun of old package
  10. (removal of old package)
  11. %postun of old package
  12. %triggerpostun of old package (if it's set off by uninstalling the old package)
  13. %triggerpostun of other packages (if they're setu off by uninstalling the old package)
  14. %posttrans of new package

Secret %pretrans and %posttrans RPM Scriptlets

There are apparently two secret scriptlets which may appear in a RPM spec file (discovered on the Packaging:ScriptletSnippets page). The %pretrans and %posttrans scriptlets are not well documented and I am not sure if they are part of RPMs in general or just part of RPMs which are used by Fedora (your mileage may vary).

%pretrans 
Runs before all RPM package transactions.
%postrans 
Runs after all RPM package transactions.

The %posttrans can be particularly useful when upgrading a RPM package.

Consider the following case. We had made the mistake of letting the package nst-config-root own the file /root/.gvimrc. We wanted to remove this file from being owned by the package, however, we wanted to keep the current instance of the file installed. Unfortunately, the normal scriptlet cycle during a upgrade is:

  • %pretrans - Not sure which version of RPM - suspect the newer one.
  • %pre - From newer RPM
  • %post - From newer RPM
  • %preun - From older RPM
  • Files present in new RPM but absent in old RPM are removed from the system
  • %postun - From older RPM
  • %posttrans - From newer RPM

In the case of removing /root/.gvimrc from RPM ownership and making a unowned copy we hit a issue. We could make a copy in the %pre section and we could copy it back in the %post section, but since the file removals and %postun sections occurred afterwards, our copy was always being removed.

To work around this, we added a %posttrans section to our spec file to restore the configuration files from the skeletion instances under the /etc/skel directory as follows:

%posttrans
# TODO: Remove this hack in the next release of the NST (won't be needed).
#
# HACK because we had a bunch of /root/.gvimrc type files under RPM control
# starting with the NST 18 release (you can remove in next release of NST)
#
# Restore any missing template configuration files which had been inadvertly
# part of this original RPM specification
#
for f in .emacs .gkrellm2/user-config .gvimrc .mozilla .nedit \
         .telnetrc .toprc .vimrc .Xdefaults; do
  if [ ! -f /root/${f} ] && [ -f /etc/skel/${f} ]; then
    %{__install} -D --mode=640 "/etc/skel/${f}" "/root/${f}";
  fi
done

HowTo: Show Spec File Scripts Within An RPM Package

Example: Show all scripts within the RPM package: "php-pear-Mail"

rpm -q php-pear-Mail --scripts | less

Example: To show post (%post) install scripts for RPM package: "nstwui"

rpm -q nstwui --queryformat "%{POSTIN}" | less

The Available RPM "Groups"

The Group: line in a spec file should be set to one of the group names allowed by Fedora. Refer to the file: "/usr/share/doc/rpm-*/GROUPS" on your development system to see what group names are available.

Downloading/Installing Source For A Fedora Package

You can use the yumdownloader and rpm commands to download (and install) the source code for most packages which can be yum installed. For example, the following demonstrates how to get the source code for the vnc-server package:

yumdownloader --source vnc-server
rpm -ivh vnc-4.1.3-1.fc10.src.rpm
ls ~/rpmbuild/SPECS ~/rpmbuild/SOURCES

How To Extract Files from an RPM Package Without Installing

First use the "yumdownloader" command to get the RPM package of interest. Then use the "rpm2cpio" and "cpio" utilities for conversion to "cpio" format and extraction. The example below extracts the "curl" package to directory: "/tmp/curl":

[root@shopper2 tmp]# mkdir -p /tmp/curl;

[root@shopper2 tmp]# yumdownloader curl;
curl-7.27.0-5.fc18.x86_64.rpm

[root@shopper2 tmp]# cd /tmp/curl/;

[root@shopper2 curl]# rpm2cpio /tmp/curl-7.27.0-5.fc18.x86_64.rpm | cpio -idmv;
./usr/bin/curl
./usr/share/doc/curl-7.27.0
./usr/share/doc/curl-7.27.0/BUGS
./usr/share/doc/curl-7.27.0/CHANGES
./usr/share/doc/curl-7.27.0/COPYING
./usr/share/doc/curl-7.27.0/FAQ
./usr/share/doc/curl-7.27.0/FEATURES
./usr/share/doc/curl-7.27.0/MANUAL
./usr/share/doc/curl-7.27.0/README
./usr/share/doc/curl-7.27.0/RESOURCES
./usr/share/doc/curl-7.27.0/TODO
./usr/share/doc/curl-7.27.0/TheArtOfHttpScripting
./usr/share/man/man1/curl.1.gz
1016 blocks

[root@shopper2 curl]# ls -alR /tmp/curl;
/tmp/curl:
total 0
drwxr-xr-x  3 root root  60 Jan 28 03:20 .
drwxrwxrwt 16 root root 460 Jan 28 03:30 ..
drwxr-xr-x  4 root root  80 Jan 28 03:20 usr

/tmp/curl/usr:
total 0
drwxr-xr-x 4 root root 80 Jan 28 03:20 .
drwxr-xr-x 3 root root 60 Jan 28 03:20 ..
drwxr-xr-x 2 root root 60 Jan 28 03:20 bin
drwxr-xr-x 4 root root 80 Jan 28 03:20 share

/tmp/curl/usr/bin:
total 152
drwxr-xr-x 2 root root     60 Jan 28 03:20 .
drwxr-xr-x 4 root root     80 Jan 28 03:20 ..
-rwxr-xr-x 1 root root 152488 Jan 15 08:43 curl

/tmp/curl/usr/share:
total 0
drwxr-xr-x 4 root root 80 Jan 28 03:20 .
drwxr-xr-x 4 root root 80 Jan 28 03:20 ..
drwxr-xr-x 3 root root 60 Jan 28 03:20 doc
drwxr-xr-x 3 root root 60 Jan 28 03:20 man

/tmp/curl/usr/share/doc:
total 0
drwxr-xr-x 3 root root  60 Jan 28 03:20 .
drwxr-xr-x 4 root root  80 Jan 28 03:20 ..
drwxr-xr-x 2 root root 240 Jan 28 03:20 curl-7.27.0

/tmp/curl/usr/share/doc/curl-7.27.0:
total 348
drwxr-xr-x 2 root root    240 Jan 28 03:20 .
drwxr-xr-x 3 root root     60 Jan 28 03:20 ..
-rw-r--r-- 1 root root   6044 Jul 20  2012 BUGS
-rw-r--r-- 1 root root 181982 Jan 15 08:41 CHANGES
-rw-r--r-- 1 root root   1044 Apr 25  2012 COPYING
-rw-r--r-- 1 root root  59952 Jul 20  2012 FAQ
-rw-r--r-- 1 root root   3904 Jul 20  2012 FEATURES
-rw-r--r-- 1 root root  36700 Jul 20  2012 MANUAL
-rw-r--r-- 1 root root   1608 Jan 15 08:41 README
-rw-r--r-- 1 root root   2287 Mar 19  2011 RESOURCES
-rw-r--r-- 1 root root  21751 Mar 19  2011 TheArtOfHttpScripting
-rw-r--r-- 1 root root  21874 Jun  3  2012 TODO

/tmp/curl/usr/share/man:
total 0
drwxr-xr-x 3 root root 60 Jan 28 03:20 .
drwxr-xr-x 4 root root 80 Jan 28 03:20 ..
drwxr-xr-x 2 root root 60 Jan 28 03:20 man1

/tmp/curl/usr/share/man/man1:
total 28
drwxr-xr-x 2 root root    60 Jan 28 03:20 .
drwxr-xr-x 3 root root    60 Jan 28 03:20 ..
-rw-r--r-- 1 root root 28391 Jan 15 08:41 curl.1.gz
[root@shopper2 curl]#

HowTo Rebuild An RPM Package From An Installed RPM

The rpmrebuild utility is a tool to build an RPM file from a package that has already been installed. This tool does not require any RPM building knowledge.

rpmbuild Example

Say we want to rebuild the open-ssh-server with a modified configuration file.

[root@shopper2 tmp]# rpm -q --verify openssh-server-6.4p1-8.fc20.x86_64
S.5....T.  c /etc/ssh/sshd_config

Simply just run the rpmrebuild utility:

[root@shopper2 tmp]# rpmrebuild -v openssh-server-6.4p1-8.fc20.x86_64
/usr/lib/rpmrebuild/rpmrebuild.sh: WARNING: some files have been modified:
S.5....T.  c /etc/ssh/sshd_config
Do you want to continue ? (y/N) y
Do you want to change release number ? (y/N) y
Enter the new release (old: 8.fc20): 8.nst20
Processing files: openssh-server-6.4p1-8.nst20.x86_64
Provides: config(openssh-server) = 6.4p1-8.fc20 openssh-server = 6.4p1-8.fc20 openssh-server(x86-64) = 6.4p1-8.fc20 openssh-server = 6.4p1-8.nst20 openssh-server(x86-64) = 6.4p1-8.nst20
Requires(interp): /bin/sh /bin/sh /bin/sh /bin/sh /bin/sh
Requires(rpmlib): rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 rpmlib(CompressedFileNames) <= 3.0.4-1
Requires(pre): /bin/sh
Requires(post): /bin/sh
Requires(preun): /bin/sh
Requires(postun): /bin/sh
Wrote: /root/rpmbuild/RPMS/x86_64/openssh-server-6.4p1-8.nst20.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.5Qn5V5
+ umask 022
+ cd /root/rpmbuild/BUILD
+ /usr/bin/rm -rf /root/.tmp/rpmrebuild.1169/my_root
+ exit 0
result: /root/rpmbuild/RPMS/x86_64/openssh-server-6.4p1-8.nst20.x86_64.rpm

Showing the Architecture

It is not easy to determine a RPM package architecture using the rpm command. You need to create a custom RPM format to see this information.

Using --queryformat to Show Architecture
[root@taco ~]# rpm -q --queryformat "%{NAME}-%{VERSION}.%{ARCH}\n" coreutils
coreutils-5.97.i386
[root@taco ~]# rpm -q --queryformat "%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n" kernel
kernel-2.6.20-1.2933.fc6.i686
kernel-2.6.20-1.2944.fc6.i686
[root@taco ~]#

The --queryformat FORMAT option is a powerful feature included with the RPM toolset. For details on the various format specifiers, see: "http://www.rpm.org/max-rpm/ch-queryformat-tags.html", or run the following command:

Using --querytags to Show --queryformat Options
[root@taco ~]# rpm --querytags | sort
ARCH
ARCHIVESIZE
BASENAMES
BUILDARCHS
BUILDHOST
BUILDTIME
C
CACHECTIME
CACHEPKGMTIME
CACHEPKGPATH
CACHEPKGSIZE
CHANGELOGNAME
CHANGELOGTEXT
CHANGELOGTIME
CLASSDICT
CONFLICTFLAGS
CONFLICTNAME
CONFLICTS
CONFLICTVERSION
COOKIE
COPYRIGHT
CVSID
D
DEPENDSDICT
DESCRIPTION
DIRINDEXES
DIRNAMES
DISTRIBUTION
DISTTAG
DISTURL
DSAHEADER
E
ENHANCESFLAGS
ENHANCESNAME
ENHANCESVERSION
EPOCH
EXCLUDEARCH
EXCLUDEOS
EXCLUSIVEARCH
EXCLUSIVEOS
FILECLASS
FILECOLORS
FILECONTEXTS
FILEDEPENDSN
FILEDEPENDSX
FILEDEVICES
FILEFLAGS
FILEGROUPNAME
FILEINODES
FILELANGS
FILELINKTOS
FILEMD5S
FILEMODES
FILEMTIMES
FILENAMES
FILEPROVIDE
FILERDEVS
FILEREQUIRE
FILESIZES
FILESTATES
FILEUSERNAME
FILEVERIFYFLAGS
FSCONTEXTS
FSNAMES
FSSIZES
GIF
GROUP
HDRID
HEADERI18NTABLE
HEADERIMAGE
HEADERIMMUTABLE
HEADERREGIONS
HEADERSIGNATURES
ICON
INSTALLCOLOR
INSTALLPREFIX
INSTALLTID
INSTALLTIME
INSTPREFIXES
LICENSE
N
NAME
O
OBSOLETEFLAGS
OBSOLETENAME
OBSOLETES
OBSOLETEVERSION
OLDFILENAMES
OPTFLAGS
OS
P
PACKAGER
PATCH
PATCHESFLAGS
PATCHESNAME
PATCHESVERSION
PAYLOADCOMPRESSOR
PAYLOADFLAGS
PAYLOADFORMAT
PKGID
PLATFORM
POLICIES
POSTIN
POSTINPROG
POSTTRANS
POSTTRANSPROG
POSTUN
POSTUNPROG
PREFIXES
PREIN
PREINPROG
PRETRANS
PRETRANSPROG
PREUN
PREUNPROG
PRIORITY
PROVIDEFLAGS
PROVIDENAME
PROVIDES
PROVIDEVERSION
PUBKEYS
R
RECONTEXTS
RELEASE
REMOVETID
REQUIREFLAGS
REQUIRENAME
REQUIRES
REQUIREVERSION
RHNPLATFORM
RPMVERSION
RSAHEADER
SERIAL
SHA1HEADER
SIGGPG
SIGMD5
SIGPGP
SIGSIZE
SIZE
SOURCE
SOURCEPACKAGE
SOURCEPKGID
SOURCERPM
SUGGESTSFLAGS
SUGGESTSNAME
SUGGESTSVERSION
SUMMARY
SVNID
TRIGGERCONDS
TRIGGERFLAGS
TRIGGERINDEX
TRIGGERNAME
TRIGGERSCRIPTPROG
TRIGGERSCRIPTS
TRIGGERTYPE
TRIGGERVERSION
URL
V
VENDOR
VERIFYSCRIPT
VERIFYSCRIPTPROG
VERSION
XPM
[root@taco ~]#

Removing i386 Packages

Paul has found the following command useful for removing the i386 - i686 compatibility packages from a x86_64 (64 bit) development machine:


Removing i386 Compatibility Packages
[root@taco ~]# rpm --erase $(rpm --queryformat '%{name}-%{version}-%{release}.%{arch}\n' -qa | grep i[3-6]86)

  
[root@taco ~]#