Build_system_refactoring#
Overview#
The build system in FreeIPA 4.4 has following problems:
It is ineffective. This costs developer time every time we build IPA. Every developer typically builds IPA several times a day. Also, it slows down CI because it needs to build the packages as well.
The build system does not directly support rapid development approaches: Every patch-copy-test cycle requires either manual work (which is error prone) or full build (which is very slow). It slows down rapid prototyping.
Repeated build with minimal changes (like changing one file) takes long time, which prevents us from doing rapid devel cycle.
Theoretically the process should be very fast as proper Makefile would detect what can be skipped.
In reality the build takes 88 % of the time from the first build!
Is not reliable. Often, “git clean -xdf” is needed to get the build to pass.
It is hard to maintain and debug.
The proposal is to re-write the build system using current best practices and standard tools. Re-write from scratch is deemed to be more effecient than fixing bugs one by one because parts of current system are unnecessairly complex or can be replaced with standard solutions.
User stories#
Every user natually wants wants reliable build.
Developer building a development version of FreeIPA:
Expects very fast build
Wants very simple and quick installation of the new version
Needs easy way to extend/modify the build system as components change
Tester building latest version for test execution
Wants easy-to-follow procedure to build distribution packages with latest version of FreeIPA
Release engineer releasing new upstream version
Wants to use standard tools for creating tarball which is then consumed by packager
Packager preparing a package for Linux Distribution
Wants to use standard tools for packaging, without need for hacks
Design#
The proposed solution. This may include but is not limited to:
Information or update workflow
Access control (may include new permissions)
Compatibility with other (older) version of FreeIPA. Think if the feature requires a minimum Domain level.
For other hints what to consider see general considerations page.
Implementation#
Use autotools suite to orchestrate the build on the top-level
For Python parts: use setuptools instead of distutils
For C parts: use autotools
For Internationalization support: use standard gettextize framework + custom enhancements to support Zanata workflow
Web UI build was not touched nad is usin Dojo builder as it was before.
Dependencies:
New build-time depedency gettext-devel is needed for gettextize framework.
Feature Management#
CLI
Command |
Desired effect |
---|---|
./configure |
test system configuration and prepare build according to configuration options |
./makerpms.sh |
build RPMs from clean Git tree: autoreconf -i && ./configure && make rpms |
make all |
build complete FreeIPA |
make install |
install FreeIPA files into paths so FreeIPA can be executed right away |
make uninstall |
uninstall FreeIPA files so the system is clean again and new installation can be done (e.g. installation from different branch) |
make rpms |
create SRPM and RPMs |
make clean |
erase the files built by make all |
make |
Configuration#
configure script will have several configuration options (replacing RPM-specific SPEC file magic).
Configure option |
Default value |
Desired effect |
---|---|---|
PYTHON (environment variable) |
python in $PATH |
path to Python interpreter (use this to select Python 2/3) |
–disable-i18n-tests |
not present (tests enabled) |
do not execute ipatests/i18n.py (depends on python-polib) |
–disable-server |
server build is enabled |
do not build server components |
–enable-pylint |
don’t run pylint |
run pylint on Python packages using $PYTHON for make lint |
–with-jslint |
jsl in $PATH |
run JS lint |
–with-ipaplatform |
autodetect |
select Fedora/RHEL IPA ipaplatform to build for |
–without-ipatests |
include ipatests |
don’t include ipatests |
–with-vendor-suffix |
(empty string) |
vendor suffix; used in VENDOR_VERSION string stored in i papython/version.py; e.g. “-1.fc24”; this should be used from SPEC file, not necessary for upstream-only builds |
Platforms which are missing some of the tools will be able to use –without-feature and –disable-feature options to disable part of the build or check.
Versioning#
Current versioning scheme is partly responsible for the slow build. Developer build with IPA_VERSION_IS_GIT_SNAPSHOT=1 changes version values in version.m4 during each build. As a result, the whole autotools machinery needs to be re-executed on each build.
Me and jcholast decided to keep this behavior for option IPA_VERSION_IS_GIT_SNAPSHOT=1. If you want fast build, disable it. The main reason is that getting rid of this problem would require significant effort which would include code changes outside of build system.
For reference, here are pieces of the old build system which concern versioning:
Here is plan what we should do with these variables:
Variable |
What to do with it |
---|---|
IPA_VERSION_MAJOR |
move to VERSION.m4 |
IPA_VERSION_MINOR |
move to VERSION.m4 |
IPA_VERSION_RELEASE |
move to VERSION.m4 |
IPA_VERSION_ALPHA_RELEASE |
merge to IPA_VERSION_PRE_RELEASE in VERSION.m4 |
IPA_VERSION_BETA_RELEASE |
merge to IPA_VERSION_PRE_RELEASE in VERSION.m4 |
IPA_VERSION_RC_RELEASE |
merge to IPA_VERSION_PRE_RELEASE in VERSION.m4 |
IPA_VERSION_PRE_RELEASE |
new variable; string is appended to .. to form version number like “1.0.0rc1” |
IPA_VERSION_IS_GIT_SNAPSHOT |
move to VERSION.m4 |
IPA_DATA_VERSION |
move to VERSION.m4 |
IPA_API_VERSION_MAJOR |
move to VERSION.m4 |
IPA_API_VERSION_MINOR |
move to VERSION.m4 |
IPA_VENDOR_VERSION_SUFFIX (currently defined in SPEC) |
move to configure –with-vendor-suffix |
IPA_RPM_RELEASE (currently reads RELEASE file) |
remove, replaced by –with-vendor-suffix |
When IPA_VERSION_IS_GIT_SNAPSHOT is enabled, the configure script will touch VERSION.m4 file. On subsequent builds, this will trigger automatic re-execution of configure script (assuming AM_MAINTAINER_MODE is disabled).
How to Use#
All users can use multiple CPUs by running make with parameters “-j” or alternativelly “-l”. It is handy to specify these parameters in variable MAKEFLAGS like this:
$ export MAKEFLAGS="-j16"
so it applies to all make jobs by default.
Developer#
First round - build & install RPMs once to get all the depedencies and scriptlets ran:
$ rm Makefile # if Makefile exists, remove it
$ ./makerpms.sh # this runs configure with paths appropriate for subsequent installation
$ dnf install dist/rpms/*.rpm
Subsequent rapid development:
make install
will quickly rebuild files as needed and install new
files onto development system, so the new build can be tested
immediatelly.
Installing files to a remote machine:
The install target supports variable DESTDIR
which specifies where
to copy the files. This can be easily used together with SSHfs which
mounts complete root filesystem from a VM to developer’s machine:
$ mkdir /tmp/vm
$ sshfs -o transform_symlinks root@``\ ``:/ /tmp/vm
$ make install DESTDIR=/tmp/vm
This snippet will synchronize all files from developer’s machine onto a VM. Just keep in mind that it will not bump version in RPM database and things depending on this might break.
To remove all files from the latest build, you can use target
uninstall
:
$ make uninstall DESTDIR=/tmp/vm
Uninstallation ensures that there are no leftovers from the current version so new version can be safely installed. (Again, keep in mind that this will not touch RPM database.)
As an optimization for lower-bandwidth/high-latency links you can use
rsync
instead of sshfs
. Is is just additional step after
make install
:
$ mkdir /tmp/vm
$ make install DESTDIR=/tmp/vm
$ rsync -rlK /tmp/vm/ root@``\ ``:/
Tester#
$ autoreconf -i
$ ./configure
$ make rpms
Or alternatively:
$ ./makerpms.sh
will produce RPMs suitable for further FreeIPA testing.
Release engineer#
$ autoreconf -i
$ ./configure
$ make dist
will produce version.tar.gz suitable for further packaging
Packager#
$ autoreconf -i
$ ./configure
$ make install DESTDIR=
will install FreeIPA into correct paths in build root so it is very easy to take all installed files and just package them.
Packager - client only build#
$ autoreconf -i
$ ./configure --disable-server --without-ipatests
$ make install DESTDIR=
will install FreeIPA into correct paths in build root so it is very easy to take all installed files and just package them.
Note: This use case does not fully work yet. See progress in #6417
Translation maintainer#
Generate a new
.pot
file for Zanata:
$ make ipa.pot-update
Strip untranslated strings from
.po
files downloaded from Zanata:
$ make strip-po
Test all strings and translation system:
$ make polint
Test Plan#
Test scenarios that will be transformed to test cases for FreeIPA Continuous Integration during implementation or review phase. This can be also link to source in cgit with the test, if appropriate.