IUS Developer Guide


Introduction

This article outlines the basics of RPM packaging guidelines for IUS. It is a work in progress. If you need help on how to configure a local build system see Configuring a Dedicated RPM Development Box.


Package Guidelines

The following outlines standard guidelines that packaging developers should follow when creating and working with packages for IUS. In general we attempt to follow the Fedora Packaging Guidelines where possible, which should be a starting point for anyone just getting into packaging.


Package Categories

The packaging model of IUS is broken up into two package categories:


Package Types

See the SafeRepo Initiative specification.


Addon Packages

IUS Does Not Add Packages to RHEL. IUS provides newer versions of existing software. If you have a package that you want to add to RHEL, you should go through Fedora EPEL. The exception to this is Supporting Packages. For example, php52 replaces stock php... however we might add php52-pecl-XXXX that might not exist in RHEL but adds features for the use of php52. Another exception is mysql50-percona-highperf, which replaces mysql but is not just a newer version of the same software, it is patched by Percona.

Replacement Packages

This type of package Provides the same software that another Stock Package (i.e. php53 provides php). The following rules apply:

Parallel Installable Packages

This type of package is very much like a Replacement Package, however it is meant to be installed side-by-side with the Stock Distro Package that it would otherwise replace. Some distros sometimes use this technique to introduce newer software while not interrupting the system and software that require the older version of it. Python for example is a system critical piece of software. Upgrading it will always cause issues, however by parallel installing a newer version of python you have the best of both words. Users/Applications that require a newer version of that software can explicitly call the alternate location while other software continues to work fine. The following rules apply:


Additional Packaging Notes

IUS Packages Provide/Conflict - Never Obsolete

Packages in the IUS repository never obsolete a RHEL package directly. Meaning, if I subscribe to an IUS repo nothing will update automatically. See The SafeRepo Initiative for more on this. However, I can remove a RHEL package and replace it with an IUS package that provides the same package. This is accomplished through a few steps that need to be added to the spec file of the IUS package.

Lets take the 'php52' package for example. This package 'Provides: php', but does not 'Obsolete: php'. If we obsoleted 'php' then as soon as we subscribed a system to IUS yum would attempt to update 'php' with the 'php52' counterparts. This is not desired. The following directives in the spec help perform this:

%define basever 5.2
%define real_name php
%define name php52

... snip ...

Provides:  %{real_name} = %{version}-%{release}
Conflicts: %{real_name} < %{basever}
Conflicts: php51


Note: This has to be done for all subpackages accordingly as well.

Assuming that we have other packages such as an older 'php51' for other branches of PHP we want our 'php52' package to conflict with those packages. We also want our 'php52' package to conflict with 'php < 5.2'. Because we are building specifically for the purpose of upgrading to a newer branch of software, it is safe to assume that RHEL will never upgrade PHP to 5.2 (using RHEL 5 in the example).

Note: The exception to obsoletes is when an IUS package obsoletes another IUS package... for example, php53-pear might have obsoleted php-pear18.

IUS Packages Follow Fedora Package Collection

Because Fedora is upstream to RHEL, IUS follows changes that the Fedora maintainers make upstream. Meaning, anytime we make updates to a package we pull the latest Fedora SRPM as well and implement any patches/changes/etc that are relevant. We do not replace our SRPM with the Fedora SRPM... but rather manually go through the latest Fedora spec and make any relavant changes that haven't been made yet.


Package Wish List

IUS users are encouraged to submit packages to the Package Wish List when they want something added to IUS. This is a good place to start for new contributors who want to help with packaging bug might not have any packages in mind.


Managing Updates

See Managing Updates.


Converting Existing Packages For IUS

In general, when creating a new IUS package you will start with the SRPM of the software from that version of RHEL and build up from there. We want our packages to follow Redhat standards as much as possible to ensure seamless upgrades from stock RHEL to IUS packages.

The following points are examples, but not limited to the changes that will need to be made to the spec to build for IUS.

Rename The Spec File

The spec file should match the new name of the package. Using php as an example:

you@linuxbox ~] mv SPECS/php.spec SPECS/php52.spec


Add The IUS Release Tag

IUS packages are designated by a '.ius' tag in the release. For community packages, this should just be '.ius'. Enterprise packages will likely be tagged with '.ius.ent' or simply '.rs' as they are now.

Release: 1.ius%{?dist}


Define The Base Version, and Real Name

The base version is important as its used further down in the spec and makes things clean. Additionally, we need to reference the 'real name' of the package through out the spec. The following should be added to the top of the spec before the Preamble:

%define basever 5.2
%define real_name php
%define name php52

Note: We are using php as an example. Replace names accordingly.


Add the Provides/Conflicts for the Base Package

Provides:  %{real_name} = %{version}-%{release}
Conflicts: %{real_name} < %{basever}
Conflicts: php51


Update All Sub Packages

All sub packages need to both provide the real name of the sub package, as well as require the new name of the package. Take the php52-devel package for example:

%package devel
Group: Development/Libraries
Summary: Files needed for building PHP extensions.
Requires: %{name} = %{version}-%{release}, autoconf, automake
Provides: %{real_name}-devel = %{version}-%{release}
Conflicts: %{real_name}-devel < %{base_ver}

%description devel
The php-devel package contains the files needed for building PHP
extensions. If you need to compile your own PHP extensions, you will
need to install this package.

Note: We need to provide the '%{real_name}' of the sub package to resolve any dependencies in the system that are looking for the stock version of the software.


Modify The %setup Line

We need to tell %setup to use the real name of our software here:

%setup -q -n %{real_name}-%{version}


A Note On BuildRequires/Requires

This can sound a bit confusing, however it should be noted that IUS packages should not explicitly BuildRequire/Require a stock RHEL packages that another IUS package replaces. This can cause dependency hell during the build process with Mock because yum calls for 'XXX' package and if nothing is already installed you might get a conflict between all the packages that provide 'XXX' package. For example.. if a php52-pecl-pear package has a 'BuildRequires: php-pear' yum will freak out because php-pear requires php-cli ... and even though php52-cli provides php-cli, php52 isn't installed yet... so yum tries to install php along with php-cli .... and things just explode. For that example, we now have 'php52-pear' which isn't really needed since php-pear works fine... but this allows us explicitly make sure that php52 gets installed at build time and not php.


Contributing Packages or Changes

Currently we do not have a public build farm setup. We are debating whether to move everything to a dedicate Koji instance, or continue development on our existing build system and setup a public instance of that. In the mean time developers that want to contribute can simply branch our bazaar repos from which we can merge from and submit the builds to the build farm.


Branching Bazaar Repos

Each package has its own branch hosted on our LaunchPad project page. You can create your own branch, make changes, and then request a merge. Once merges have been approved your changes will appear in the next package release.

Assuming you have a LaunchPad account, the following is an example of merging from the official ius branch to make your changes:

you@linux ]$ mkdir ius

you@linux ]$ cd ius

you@linux ]$ bzr launchpad-login <your_launchpad_login>

you@linux ]$ bzr init

you@linux ]$ bzr branch lp:~ius-coredev/ius/php52
Branched 7 revision(s).   

you@linux ]$ cd php52

you@linux ]$ ls -lah
total 32K
drwxrwxr-x 8 you you 4.0K Oct 13 15:52 .
drwxrwxr-x 4 you you 4.0K Oct 13 15:50 ..
drwxrwxr-x 2 you you 4.0K Oct 13 15:52 BUILD
drwxrwxr-x 6 you you 4.0K Oct 13 15:52 .bzr
drwxrwxr-x 2 you you 4.0K Oct 13 15:52 RPMS
drwxrwxr-x 2 you you 4.0K Oct 13 15:52 SOURCES
drwxrwxr-x 2 you you 4.0K Oct 13 15:52 SPECS
drwxrwxr-x 2 you you 4.0K Oct 13 15:52 SRPMS


Modifying Packages

After making changes, you want to make sure that they build (and you probably want to test installing and using the RPMs as well). It is recommended that packagers use the Fedora Mock utility for building as this ensures builds are clean and all dependencies are resolved. After modifying, an example build might look like (don't forget to up the release):

you@linux ]$ rpmbuild -bs SPECS/php52.spec --nodeps
Wrote: /home/you/ius/php52/SRPMS/php52-5.2.11-2.ius.src.rpm

you@linux ]$ mock -r ius-5-x86_64 rebuild SRPMS/php52-5.2.11-2.ius.src.rpm
INFO: mock.py version 0.9.14 starting...
State Changed: init plugins
State Changed: start
INFO: Start(SRPMS/php52-5.2.11-2.ius.src.rpm)  Config(ius-5-x86_64)
State Changed: lock buildroot
State Changed: clean
State Changed: init
State Changed: lock buildroot
Mock Version: 0.9.14
State Changed: running yum
State Changed: setup
State Changed: build
INFO: Done(SRPMS/php52-5.2.11-2.ius.src.rpm) Config(ius-5-x86_64) 13 minutes 10 seconds
INFO: Results and/or logs in: /var/lib/mock/ius-5-x86_64-you/result


For more information, and an example IUS Mock config, see the Building Packages with Fedora Mock section. Should you're build, and testing be successful you then want to commit your changes.


Committing Changes To Launch Pad

Under the IUS Community Project branches, click 'Register a Branch'.

This creates a branch like lp:~you/ius/php52. You want to commit changes locally first and include a detailed log of the changes you made. Then, for the IUS CoreDev Team to be able to merge your changes in you need to commit to the LaunchPad branch under your accound:

you@linux ]$ bzr add SOURCES/php-5.2.11-mysourcechange.patch

you@linux ]$ bzr commit -m 'Adding patch to fix something in the source.'

you@linux ]$ bzr push lp:~you/ius/php52 --use-existing-dir
Created new branch.  


Once your branch is complete, go back to your Branches page for your user, click the branch and then click 'Propose for merging into another branch'. At this point you want to choose the branch for the package. Note, this is the target branch (where the proposed changes need to be applied).


Building Packages with Fedora Mock

The Fedora Mock utility is the preferred way of building packages locally.


Installing Mock

The mock package can be installed from Fedora, and Fedora EPEL repositories.

root@linux ~]# yum install mock.noarch

root@linux ~]# usermod -aG mock <username>

Note: All users building with mock need to be added to the mock system group (as I did above for <username>).


Example IUS Mock Config

Copy the following to /etc/mock/ius-el5-i386.cfg.

config_opts['root'] = 'ius-5-x86_64'
config_opts['target_arch'] = 'x86_64'
config_opts['chroot_setup_cmd'] = 'install buildsys-build'
config_opts['useradd'] = '/usr/sbin/useradd -m -u %(uid)s -g %(gid)s -d %(home)s -n %(user)s'
config_opts['dist'] = 'el5'  # only useful for --resultdir variable subst

config_opts['yum.conf'] = """
[main]
cachedir=/var/cache/yum
debuglevel=1
logfile=/var/log/yum.log
reposdir=/dev/null
retries=20
obsoletes=1
gpgcheck=0
assumeyes=1
# grub/syslinux on x86_64 need glibc-devel.i386 which pulls in glibc.i386, need to exclude all
# .i?86 packages except these.
exclude=[1-9A-Za-fh-z]*.i?86 g[0-9A-Za-km-z]*.i?86 gl[0-9A-Za-hj-z]*.i?86 gli[0-9A-Zac-z]*.i?86 glib[0-9A-Za-bd-z]*.i?86
# repos

[core]
name=base
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=x86_64&repo=os

[update]
name=updates
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=x86_64&repo=updates

[groups]
name=groups
baseurl=http://buildsys.fedoraproject.org/buildgroups/rhel5/x86_64/

[extras]
name=epel
mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=epel-5&arch=x86_64

[testing]
name=epel-testing
enabled=0
mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=testing-epel5&arch=x86_64

[local]
name=local
baseurl=http://kojipkgs.fedoraproject.org/repos/dist-5E-epel-build/latest/x86_64/
cost=2000
enabled=0

[ius]
name=ius
mirrorlist=http://dmirr.iuscommunity.org/mirrorlist?repo=ius-el5&arch=$basearch

"""


Optional Environment Configurations

FIX ME


Building With Mock

you@linux buildroot]$ vi SPECS/mypackage.spec

you@linux buildroot]$ rpmbuild -bs SPECS mypackages.spec

you@linux buildroot]$ mock -r ius-el5-x86_64 rebuild SRPMS/mypackage-0.1-1.ius.src.rpm

Results will be in /var/lib/mock/ius-el5-x86_64.


Troubleshooting Failed Builds

FIX ME

Doc/DeveloperGuide (last edited 2010-06-18 15:54:38 by derks)