This section describes the process for building an RPM - step by step.
Choose a name and version number for your package. We are going to package the complete loggerdemo example and will use loggerdemo and 1.0.0 as the name and version number.
Collect all of the files which have been created in the previous sections into the /tmp/ directory. There is one additional file createlinks which looks like this:
#!/usr/bin/perl -w use esmith::Build::CreateLinks qw(:all); use File::Basename; my $panel = "manager"; panel_link("loggerdemo", $panel);
Create the directory hierarchy required for building the RPM. This is very close to the hierarchy on the installed system.
# Change to the SOURCES directory cd ~/rpms/SOURCES # Remove old files (check that you don't need anything here!) rm -rf loggerdemo-1.0.0 # Create new directory mkdir loggerdemo-1.0.0 cd loggerdemo-1.0.0 # The crontab template fragment mkdir -p root/etc/e-smith/templates/etc/crontab cp /tmp/25templatedemo root/etc/e-smith/templates/etc/crontab # The web panel description mkdir -p root/etc/e-smith/web/functions cp -p /tmp/loggerdemo !$ # The web panel implementation mkdir -p root/usr/lib/perl5/site_perl/esmith/FormMagick/Panel cp -p /tmp/loggerdemo.pm !$ # The web panel English localisation mkdir -p root/etc/e-smith/locale/en-us/etc/e-smith/web/functions cp -p /tmp/loggerdemo-en !$ # The createlinks auxiliary file cp -p /tmp/createlinks .
Your directory structure should now look like this:
[gordonr@sevendev1 loggerdemo-1.0.0]$ find . -type f ./root/etc/e-smith/templates/etc/crontab/25templatedemo ./root/etc/e-smith/locale/en-us/etc/e-smith/web/functions/loggerdemo ./root/etc/e-smith/web/functions/loggerdemo ./root/usr/lib/perl5/site_perl/esmith/FormMagick/Panel/loggerdemo.pm ./createlinks
Package the directory into a tarball:
cd ~/rpms/SOURCES tar zcvf loggerdemo-1.0.0.tar.gz loggerdemo-1.0.0
Create the RPM specification "SPEC" file ~/rpms/SPECS/loggerdemo.spec which looks like this:
%define name loggerdemo %define version 1.0.0 %define release 01 Summary: SME Server logger demo Name: %{name} Version: %{version} Release: %{release} License: GPL Group: Networking/Daemons Source: %{name}-%{version}.tar.gz Packager: Fred Frog <red@example.com> BuildRoot: /var/tmp/%{name}-%{version}-%{release}-buildroot BuildArchitectures: noarch %description Logger Demo sample application. %changelog * Thu Feb 2 2006 Fred Frog <fred@example.com> - 1.0.0-01 - Original version %prep %setup %build perl createlinks DEFAULTS=root/etc/e-smith/db/configuration/defaults/loggerdemo mkdir -p $DEFAULTS echo "service" > $DEFAULTS/type echo "enabled" > $DEFAULTS/status echo "10" > $DEFAULTS/Interval %install rm -rf $RPM_BUILD_ROOT (cd root ; find . -depth -print | cpio -dump $RPM_BUILD_ROOT) rm -f %{name}-%{version}-filelist /sbin/e-smith/genfilelist $RPM_BUILD_ROOT > %{name}-%{version}-filelist %clean rm -rf $RPM_BUILD_ROOT %post /etc/e-smith/events/actions/initialize-default-databases /etc/e-smith/events/actions/navigation-conf /sbin/e-smith/expand-template /etc/crontab true %postun /sbin/e-smith/expand-template /etc/crontab true %files -f %{name}-%{version}-filelist %defattr(-,root,root)
Note the %post (post-installation) and %postun (post-uninstallation) statements which expand the /etc/crontab template after installing or uninstalling the RPM.
Check that your RPM will build OK with "build prepare":
cd ~/rpms/SPECS rpmbuild -bp loggerdemo.spec
The last line of output should be + exit 0 if rpmbuild is successful.
Run the rpmbuild command again to actually create your RPM with the "build all" options:
rpmbuild -ba loggerdemo.spec
If everything was successful, the last line of output should again be + exit 0.
The RPMs should have been generated and put into ~/rpms/RPMS/noarch/ as this program can run equally well on any platform. A source RPM should also exist in ~/rpms/SRPMS/.
Test your RPM by installing it on an SME Server test box.
Note: RPMs need to be installed as root, but you should not log in as the root user. Instead, you should create a normal user and provide them with 'root' privileges via the sudo command. To provide full sudo rights to the user joe, use the su - -c /usr/sbin/visudo and add the following line to the end of the file:
joe ALL=(ALL) ALLYou can then use the sudo to run commands as root when required. You will be prompted for your password (not the root password) which ensures that someone else isn't using your terminal.
[joe@sevendev1 SPECS]$ sudo rpm -Uvh \ ~/rpms/RPMS/noarch/loggerdemo-1.0.0-01.noarch.rpm Preparing... ########################################### [100%] 1:loggerdemo ########################################### [100%] Migrating existing database mailpatterns Migrating existing database hosts Migrating existing database configuration Migrating existing database yum_repositories Migrating existing database networks Migrating existing database yum_updates Migrating existing database yum_installed Migrating existing database spamassassin Migrating existing database accounts Migrating existing database backups Migrating existing database yum_available Migrating existing database domains
Note: In almost all instances you should use the -U (upgrade) option to rpm instead of the -i (install) option. The -i option should be reserved for special operations, such as installing kernels.
The customization should be fully installed, and the /etc/crontab file should show the customization. Then remove the customization:
# remove the RPM sudo rpm -e loggerdemo
The customization should be completely gone, and the /etc/crontab file should look the way it did before.
The source tarballs of an RPM should not include symbolic links as they are difficult to store under many version control systems and cause issues when generating patches. Since the SME Server uses many symbolic links, there are simple methods for creating the ones required. This is done through the createlinks script which is called from the %build section of the SPEC file. Let's examine one. It starts with the standard Perl script header and an import of the required module:
#!/usr/bin/perl -w use esmith::Build::CreateLinks qw(:all);
The templates2events function can be used to create the appropriate templates2expand links in various events:
my $imap = "/var/service/imap"; my $imaps = "/var/service/imaps"; templates2events("/etc/dovecot.conf", qw(bootstrap-console-save console-save)); templates2events("$imap/config", qw(bootstrap-console-save email-update)); templates2events("$imaps/config", qw(bootstrap-console-save email-update));
Note that the first argument is a filename and the second argument is a list of events in which to create the link. The safe_symlink function can be used to create a generic symbolic link, as well as the directory hierarchy enclosing that link:
for my $event (qw( email-update ldap-update network-create network-delete )) { safe_symlink("sigusr1", "root/etc/e-smith/events/$event/services2adjust/imap"); } safe_symlink("daemontools", "root/etc/rc.d/init.d/imap");
The event_link function is used to create the links from the event directories to the generic actions directory. For example:
for my $event (qw(post-upgrade)) { event_link("imap-relocate-maildirs", $event, "05"); }
creates a symbolic link S05imap-relocate-maildirs in the post-upgrade event. The target of the symbolic link will be the imap-relocate-maildirs script in the /etc/e-smith/events/actions/ directory.
Finally, the service_link_enhanced function makes it simple to create the /etc/rc.d/rc7.d and similar startup symlinks:
service_link_enhanced("imap", "S55", "7"); service_link_enhanced("imap", "K45", "6"); service_link_enhanced("imap", "K45", "0"); service_link_enhanced("imap", "K45", "1");
More documentation on this module can be seen with the command perldoc esmith::Build::CreateLinks.