A Beginner's Guide to Rolling Your Own RPMs for SME/E-smith

-A starter guide written for a beginner by a beginner-

--DRAFT--


Thanks to Darrell May for his counsel and Abe Loveless for his eagle-eyes.


A conceptual companion guide (with graphics)is available

The original document is published at http://www.tech-geeks.org/contrib/mdrone/beginners-guide-to-rolling-rpms.htm


Intro

This guide will show the novice user how to create an RPM on the SME/E-smith server. A simple web application RPM will be created and installed as a starter project.

Goal

To create an RPM that will install a php/mysql web application into /home/e-smith/files/primary/html/webapp (so that it's accessible at http://yourservername/webapp) and will create the database, dbuser, dbpasswd, and populate the database tables with sample data.

Hopefully, this guide will not only produce a working web application, but will help the end-user understand the organization and basic mechanisms involved in creating a RPM package.

The web application is a modified version of the Employee Directory application available at www.gotocode.com.

Conventions

All RPMs must include version and release numbers. So, if you have an application named "myapp", its rpm name will be something like "myapp-0.3-1.rpm". The naming convention is: "appname-version-release.rpm". E-smith-specific RPMs are usually prefaced by "e-smith-". It appears to be a standard practice that RPMs should be created by some user other than "root".

Step 1

Create an unprivileged user on your system using the server-manager. You can create a user account for yourself, or you can create an "rpmmaker" account (or something similar). For the remainder of this guide, we will refer to the unprivileged user as "rpmmaker".

Step 2

Be sure to set a password for this user.

Step 3

Now you will need to give this user a shell to work with. Get root.

        # chsh rpmmaker

You will be prompted for a shell. Type in "/bin/bash" (without quotes) followed by pressing the Enter key to return to the command prompt.

Step 3bis, added by schirrms April the 2, 2006

On Centos 4.2, and presumably also on SME 7, there is an additional step needed to prepare this account : to create or rebuild a rpm database, the user need write access in

               /var/lock/rpm

By default, only the user rpm can write in this directory. Let's change it :

        # give the rpm group write access to the directory :
        chmod g+w /var/lock/rpm
        # control the work :
        ls -ld /var/lock/rpm
        # shoud be something like :
        # drwxrwxr-x  2 rpm rpm 4096 avr  2 13:57 /var/lock/rpm
        # eventually, it could also be necessary to remove the transaction file
        rm /var/lock/rpm/transaction
        # add the rpm user in the rpm group
        usermod -G rpm rpmmaker

Another tip for SME 7 : by default, patch is not installed. But this is useful when working with RPM. easy to add :

        yum --enablerepo=base install patch
Step 4

Login as the new user:

        # su - rpmmaker

You will see a new command prompt

bash-2.05$

Type "pwd" to see the "present working directory"

bash-2.05$ pwd /home/e-smith/files/users/rpmmaker

This is the new user's workspace. You can return to this directory by typing "cd $HOME" or "cd " (cd tilde). The tilde () in this situation is a shortcut for /home/e-smith/files/users/rpmmaker.

Step 5

Now we need to set up an RPM sandbox within this user's space.

bash-2.05$ cd $HOME

bash-2.05$ mkdir -p rpms/{SRPMS,BUILD,SPECS,SOURCES,RPMS,lib}

bash-2.05$ mkdir -p rpms/RPMS/{i386,noarch}

bash-2.05$ rpm --initdb --dbpath $HOME/rpms/lib

bash-2.05$ echo "%_topdir $HOME/rpms" > $HOME/.rpmmacros

Step 5.1

By default the executable 'rpmbuild' is not installed on a SME 7 machine:

bash-2.05$ yum install rpm-build

Step 6

Move into the SPECS directory

bash-2.05$ cd $HOME/rpms/SPECS

Grab the sample webapp-1.0.spec file from the TechGeeks server

bash-2.05$ wget http://www.tech-geeks.org/contrib/mdrone/rpmmaker/webapp-1.0.spec

Step 7

If you want to get right to the RPM building part, complete Step 7. If you want to learn more about setting up the SOURCES directory structure, read (Step 7a).

Move into the $HOME/rpms/SOURCES directory

bash-2.05$ cd $HOME/rpms/SOURCES

Get the webapp-1.0.tar.gz archive from http://www.tech-geeks.org/contrib/mdrone/rpmmaker

bash-2.05$ wget http://www.tech-geeks.org/contrib/mdrone/rpmmaker/webapp-1.0.tar.gz

After you wget the webapp-1.0.tar.gz file, it will be located at:

$HOME/rpms/SOURCES/webapp-1.0.tar.gz

The gzipped tar archive contains all of the application files stored in a specialized directory structure:

/webapp-1.0/root/home/e-smith/files/primary/html/webapp/

Scroll down to Step 8 to learn more about this directory organization.

(Step 7a)

If you are creating the RPM structure based on your own application, follow these steps. These directions are based on my own convoluted approach to doing this, and presume that you have a "webapp" located at /home/e-smith/files/primary/html/webapp.

Move into the $HOME/rpms/SOURCES directory

bash-2.05$ cd $HOME/rpms/SOURCES

Create the directory structure for your application, including the "application package name" directory and a "root" subdirectory:

bash-2.05$ mkdir -pv webapp-1.0/root

(You will see a listing of the directories as they are created)

If you are creating your own RPM, you will want to move into the newly created $HOME/rpms/SOURCES/webapp-1.0/root directory and create a gzipped tar archive of your application, once again, presuming that your application is located at /home/e-smith/files/primary/html/webapp.

bash-2.05$ cd $HOME/rpms/SOURCES/webapp-1.0/root bash-2.05$ tar -cvf webapp-1.0.tar /home/e-smith/files/primary/html/webapp

optional---out of habit, I tend to gzip all my tar archives bash-2.05$ gzip webapp-1.0.tar

Then you will need to unpack the new tar archive that you just created in order to re-pack it with the "/webapp-1.0/root" prepended.

if gzipped bash-2.05$ tar -xvzf webapp-1.0.tar.gz if not gzipped bash-2.05$ tar -xvf webapp-1.0.tar bash-2.05$ rm -f webapp-1.0.tar.gz

bash-2.05$ cd $HOME/rpms/SOURCES bash-2.05$ tar -cvf webapp-1.0.tar webapp-1.0 bash-2.05$ gzip webapp-1.0.tar

SME 7 : small changes (add by PSchirrms April the 16, 2006) The file must by compressed. This can be done in one step : bash-3.00$ tar czvf webapp-1.0.tar.gz /home/e-smith/files/primary/html/webapp

The result should be $HOME/rpms/SOURCES/webapp-1.0.tar.gz that contains a webapp-1.0/root/home/e-smith/files/primary/html/webapp/... structure.

While this is a workable method, I sure would like to know a better way to accomplish this stage. I have tried creating the directory structure ahead of time with "mkdir -pv" and then copying the application files into it prior to running "tar zcvf" to create the archive. An application with multiple target directories (particularly in the case of packaging server-manager panels) would require more than a simple directory structure, as configuration files and modifications would need to occur at various places on the SME/E-smith server.

Step 8

Methods and Madness

Ultimately, the application now resides as a gzipped tar archive inside of the $HOME/rpms/SOURCES directory, from which it will be converted into a structure that is recognizable by rpm in the /rpms/BUILD directory. As it is now, the organizational setup is as follows:

        $HOME/rpms/SOURCES/webapp-1.0/root/home/e-smith/files/primary/html/webapp
                       ^^^^^^^^^^
                           |---The "webapp-1.0" directory is the parent directory
                           |    for the application
                           |---Every application must have it's own parent directory.

        $HOME/rpms/SOURCES/webapp-1.0/root/home/e-smith/files/primary/html/webapp
                                  ^^^^
                                   |---Every parent directory must have a "root" subdirectory.

        $HOME/rpms/SOURCES/webapp-1.0/root/home/e-smith/files/primary/html/webapp
                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                           |---Inside the "root" subdirectory is where you start
                                               the "normal" directory structure of where the files
                                               will eventually be created on the server.
Step 9

Edit and customize the webapp-1.0.spec file

bash-2.05$ pico -w $HOME/rpms/SPEC/webapp-1.0.spec

There are a few things that you should change in the file below. Those lines that contain comments (#) should be modified.

        ----------------------begin webapp-1.0.spec file contents-------------------
        Summary: Sample Project Web Application for SME/E-smith
        %define name webapp
        Name: %{name}
        %define version 1.0
        %define release 1
        Version: %{version}
        Release: %{release}
        Copyright: GPL
        Group: /Web/Applications
        Source: %{name}-%{version}.tar.gz
        Packager: Your Name   # edit this line
        BuildRoot: /var/tmp/%{name}-%{version}-%{release}-buildroot
        BuildArchitectures: noarch
        Requires: e-smith-base

        %description
        This RPM is being used as a project to learn how RPMs are built on
        SME/E-smith.  The target audience is the Linux/E-smith administrator
        who wants to package any new applications.

        %changelog
        * Wed Dec 25 2002 Your Name   #edit these lines
        - 1.0-1
        - Converted the application from the standard Employee Directory at gotocode.com

        %prep

        %setup

        %build

        %install
        /bin/rm -rf $RPM_BUILD_ROOT
        (cd root   ; /usr/bin/find . -depth -print | /bin/cpio -dump $RPM_BUILD_ROOT)
        /bin/rm -f %{name}-%{version}-filelist
        /sbin/e-smith/genfilelist $RPM_BUILD_ROOT > %{name}-%{version}-filelist

        %files -f %{name}-%{version}-filelist

        %defattr(-,root,root)

        %clean
        rm -rf $RPM_BUILD_ROOT

        %pre

        %post
        # This section creates the database, dbuser, dbpasswd and data after the
        # package has been installed

        echo exit | mysql webapp  2>&1 &> /dev/null
        if "$?" = "1" ; then
          echo "Creating database..."
          mysql < $RPM_BUILD_ROOT/home/e-smith/files/primary/html/webapp/db/webapp.sql
            echo "grant all on webapp.* to webapp@localhost identified by 'webapp';" | mysql
            mysqladmin reload
        fi

        %preun

        %postun

        ----------------------end webapp-1.0.spec file contents-------------------

If the system does not allow you to edit this file, you might have to drop back into the root user mode and change the file ownership or permissions, but I suspect that you'll be able to edit it with no trouble.

Step 10

Next you need to create the packaging structure inside the /rpms/BUILD directory:

bash-2.04$ cd $HOME/rpms/SPEC bash-2.04$ rpm -bp webapp-1.0.spec SME 7 : --> rpmbuild -bp webapp-1.0.spec

If you receive no errors, you can check to see if everything was created correctly inside of the $HOME/rpms/BUILD directory

bash-2.04$ ls $HOME/rpms/BUILD

You should see a "webapp-1.0" directory listed.

Step 11

Now we're actually ready to create the RPMs. From inside $HOME/rpms/SPECS, issue:

bash-2.04$ rpm -ba webapp-1.0.spec SME 7 : --> rpmbuild -ba webapp-1.0.spec

Step 12

The RPMs should have been created in $HOME/rpms/RPMS/noarch and $HOME/rpms/SRPMS

bash-2.04$ cd $HOME/rpms/RPMS/noarch; ls bash-2.04$ cd $HOME/rpms/SRPMS; ls

Step 13

Become the root user and navigate to the rpmmaker's rpms/RPMS/noarch directory:

        # cd /home/e-smith/files/users/rpmmaker/rpms/RPMS/noarch
Step 14

Install the rpm and check it out:

        # rpm -Uvh webapp-1.0-1.noarch.rpm

        Preparing...                ########################################### 100%
           1:webapp                 ########################################### 100%
        Creating database...

SME 7 : yum localinstall webapp-1.0-1.noarch.rpm

Step 15

Test it out: http://yourservername/webapp/Default.php

Admin user is: username=admin, password=admin

Step 16

Uninstall is:

        # rpm -e webapp-1.0-1

The database is not removed by the "rpm -e" command. This will need to be removed manually by the database administrator. The command:

        # mysqladmin drop webapp

...should do the trick.

If you want to distribute your RPMs, you will need to move both the webapp-1.0-1.noarch.rpm and the webapp-1.0-1.src.rpm from their current directories and into your webspace somewhere.

Appendix

Let's say you want to distribute a shell script and some gzipped tar archives as an RPM. You want the whole thing to wind up installed in the /root directory. The solution is to create a gzipped tar archive in /rpms/SOURCES with a name like mypackage-0.1.tar.gz that contains the following structure:

mypackage-0.1/root/root/mypackage

The command:

mkdir -pv $HOME/rpms/SOURCES/mypackage-0.1/root/root/mypackage

...should work nicely.

Now you can copy the webapp-1.0.spec file to mypackage-0.1.spec and modify it to work with your new package.

Then you should be ready to roll your own RPM with "rpm -bp" and "rpm -ba".

Contributed by: Mark Drone (mdrone@tech-geeks.org)

http://www.tech-geeks.org/contrib/mdrone


Permission to reproduce, archive, modify, and distribute this document

granted to all under the condition that the author's name remain affixed.


Back to Development