This repository allows to quickly checkout, build, test and develop the
ecosystem of 42ITy™ project, including components
of the project itself and customized or original dependency projects.
There are some third-party dependencies and tools (suggested in details
below) that this repository does not provide; they are expected to just
be on your build system when the corresponding configure
script runs.
To build the latest HEAD of each component’s default branch just run this:
$ git clone https://github.com/42ity/FTY && \ ( cd FTY && make world )
Note that this would require an internet connection to check out all the
repositories, and considerable time to build the ecosystem. To rebuild
the checkouts already present on your system (e.g. to continue a broken
build after installing dependencies), the ordinary make
should suffice.
It is recommended to have installed ccache
to speed up subsequent
rebuilds, as well as certain other common dependencies and tools.
For reference, you can find a list of additional packages needed on
Debian and Ubuntu Linux distributions in the .travis.yml
file.
Builds and tests should be executed as a non-root
user, because:
-
some component self-tests expect in-accessibility of certain paths;
-
tasks such as
make web-test-bios
run daemons as a non-privileged account that would not see into `root’s home directory with build artifacts.
You can run make help
for an overview of currently supported targets.
FTY is a "dispatcher" repository which links (as "git submodules") to the repositories used to build the 42ITy™ project. This includes some third party projects (git HEADs), forks of third-party projects customized for 42ITy™ needs, and of course lots of original development.
For a rebuild from scratch you’d need to compile and install the following
components in order (this is automated by the accompanying Makefile
):
-
gsl
andzproject
(optional — to refresh project definitions) -
libzmq
-
libczmq
(one of the supportedczmq
variants as discussed below) -
malamute
-
cxxtools
-
tntdb
-
log4cplus
-
fty-proto
-
fty-common
-
other
fty-*
components as needed and possibly with dependencies on each other as defined in theirprofile.xml
manifests forzproject
-
fty-core
andfty-rest
possibly come last
Note that the "git submodules" mechanism used by the FTY repository can
only refer to specific Git commit IDs, not branches or tags, so when you
first clone the repositories you will get a lot of "detached HEADs" in
the component subdirectories. This suffices for automated builds with
predetermined versions of the software. The FTY repository Makefile
recipes and scripts include additional methods to add support for human
developers as well, in order to both ease integration with their own
forks of the components on GitHub, and to follow actual Git branches
in the local workspace checkouts.
This repository tracks a couple of similar but separate branches:
-
master
refers to HEADs of our projects that we might experiment upgrading into — such as the zeromq ecosystem at this time; -
FTY
branch is a bit more conservative and tracks the state of third-party sources used in our daily work and recent releases.
The included Makefile
automates building of project components, including
the customized third-party projects, in the order of dependencies. It is
ready for correct parallel compilation with GNU Make 3.81 or newer, and can
take advantage of ccache
if available on your system.
It is up to the developer to provide a build environment with appropriate third-party software dependencies which our project does not modify, nor track git HEADs, nor build (such as MySQL/MariaDB libraries to link against, or lua-5.1/5.2, or libneon, or libapr, maybe openssl etc.), as well as an internet connection to completely check out the source code to build.
The Makefile
defines dependencies and recipes that can cause download or
update of sources from designated remote repositories using git
, so the
basic way to build the 42ITy™ ecosystem using those component revisions
that the FTY repository points to at any given time is to:
$ git clone https://github.com/42ity/FTY && \ cd FTY && \ make -j 4
To update sources from current state of remote Git branches and rebuild in
proper ordering whatever has changed later on, you can use e.g. make world
.
You can also do this for initial build command, if you want to build right
away with the current state of default branch in each component repository.
Also you can call a number of actions against specific components using a
metaphor of subdirectory in the recipes, e.g. make recheck/fty-example
.
See the Makefile
for different wildcard actions it defines (with percent
character), using this query for the current version: egrep '/%:$' Makefile
When running parallel make -jN
beware that if you spawn too many workers,
the operating system might kill off some of them if it is insufficiently
resourced, causing the build to fail not due to source code errors. In order
to take advantage of parallel processing, you may be well served by running
first a parallel and then a sequential build attempt: make -j 4 -k || make
The Makefile
provides a development-rebuild option, invoked like this:
$ make devel/fty-example
which takes effect both for components "prepped" as symlinks (e.g. by setting
PREP_TYPE_fty-example=cloneln-src
or cloneln-obj
in the Makefile
) and
as copies of files (PREP_TYPE_component=clonetar-src
or clonetar-obj
).
This is the default now, unless a recipe for some component defines a
different PREP_TYPE
because of its build-system quirks.
If the component was already configured, this recipe just runs a make
in its custom build directory and so recompiles just the binaries whose
sources you have changed right in the common checked-out Git workspace.
Of course, this only works as long as you have not added new source files,
etc. — but that sort of change would anyway need a rebuild/fty-example
.
Other similar limitations may exist but were not yet found or documented.
As a fallback, this would prep
/autogen
/configure
components that
were not yet "configured", and would fall back to a full rebuild
for
components that are not "prepped" as symlinks.
The intended use-case looks like this, to streamline iterations of small changes during development:
$ gmake devel/fty-example && gmake memcheck/fty-example
…or this for custom runs (assuming one platform so /*/
is not ambiguous
in the short example below):
$ gmake devel/fty-example && (cd .build/*/fty-example && src/test-me --arg -v)
Note
|
At this time, the devel/* recipe only looks at, and recompiles
if needed, the specified component — not those it might depend on — so
in case you edit lots of ecosystem, refresh such components explicitly:
|
$ gmake devel/{fty-proto,czmq}
This Makefile
supports make web-test
and make web-test-bios
recipes to
help with in-place testing of the fty-rest
component during development.
The make web-test
integration simply builds fty-rest
with dependencies
(including a copy of tntnet
from the tracked fork) and runs it with the
tntnet.xml
generated by fty-rest
(pointing to the freshly built copy of
bios-web.so
), as the developer’s user account on a dedicated port (8000
)
and using a dedicated directory for data files that the servlets might edit
without conflict with the OS — at least as long as sources do not use any
hardcoded paths. This recipe has the same effect as if developer went to the
fty-rest
workspace and executed make web-test
there (using same-named
recipe in that component), it just provides the depedencies built from the
freshest of sources.
The make web-test-bios
integration is intended for tests approaching the
reality of our product, running in our generated and pre-configured OS image
in a container or on a rack controller. As such, this recipe takes the same
/etc/tntnet/bios.xml
file (presence required) and environment variable
files as referred by the production systemd unit tntnet@bios.service
,
and produces a configuration patched for the compPath
reference to the
freshly built copy of bios_web.so
object with developed servlets.
Then this recipe disables the running instance of tntnet@bios.service
and uses sudo -E
to start the freshly built webserver in its place as
root
, so it changes credentials according to configuration just as the
packaged service does. As you can see, this recipe requires quite a bit
of circumstances and intentional system setup to work; in particular this
should keep your daily host operating system safe from experimental code ;)
Note
|
This repository includes an admin-sudo file that you can copy into
the /etc/sudoers.d (running as root ) in an instance of our OS image:
|
# cp admin-sudo /etc/sudoers.d/
Note
|
At this time, use of the patched /etc/tntnet/bios.xml from the OS image
does not take into account any customizations from the tntnet.xml template in
the fty-rest component sources under your development and testing.
|
Note that as part of the project’s evolution and legacy, it used to require
the czmq
version 3.0.2, and since that release was obsoleted by upstream
a while ago, we tracked our own fork with small fixes. Subsequently the code
of 42ITy™ components where it mattered was updated to support either the
CZMQ3 or CZMQ4 APIs, and now the Makefile
in this repository allows to
automate the builds against either our czmq-v3.0.2
fork or the upstream
czmq-master
from the GitHub, or using binary packages of zeromq stack
as provided in your OS by other means (beware that these can lag behind
respective upstream/master
or upstream/stable
branches and so can lack
the features that 42ITy codebase might need). Our current goal is to drop
the requirement of the obsoleted version and use the community-supported
master branch, where we can collaborate on fixes for bugs that bite us all.
To choose the czmq
version to build your FTY components against, you can
define the CI_CZMQ_VER=<value>
(as an exported environment variable, or
as a make
argument); suported values are 3
for our "czmq-v3.0.2" fork
(it is also the default choice if no value is set explicitly), 4
for
the upstream/master
which is currently under the 4.x umbrella versions,
and pkg
for OS packages of the whole libsodium
`libzmq`czmq
+malamute
stack.
The zeromq-related ecosystem of software projects has recently added support for building with the Address Sanitizer in supportive compilers such as the recent GCC versions. You can find more details about this technology at https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html and https://github.com/google/sanitizers/wiki/AddressSanitizer.
This can be enabled in Travis CI tests for projects generated with zproject
and now for (Travis or manually executed) builds done with the Makefile
provided by this FTY repository, by an exporting an environment variable
usually before a memcheck
/valgrind
build and run:
$ export ADDRESS_SANITIZER=enabled $ make memcheck/fty-example
Note that the actual compilation flags enabled by such toggle can depend
on contents of the configure.ac
scripts in each component project, and of
course functionality of the actual implementation depends on the evolution
level of the compiler in use for the build.
Also note that Leak Sanitizer (-llsan
) is not currently available in the
Travis CI operating environments.
This Makefile
has been verified on Debian 8 (devel images for the project
build farm); it also passes on Ubuntu-based systems used in the Travis CI
cloud. Much but not all of this code can also build under OpenIndiana, more
with a purpose to test the approach to portability than to use it there (in
the near term at least). Feel free to update the recipes if needed for other
OSes and distros, and take inspiration from hooks made for and used by the
OpenIndiana/SunOS integration.
Note that when you initially check out a clone of this repository, you only
get meta-data. To instantiate (or subsequently update) the actual source
code for the components, as well as to update the reference to Git HEADs of
the referenced components, run the ./sync.sh
script in this workspace.
Note
|
If you intend not only to build the unmodified 42ITy codebase, but to also collaborate about changes and improvements, see the chapter below about setting up your forks on GitHub and how to automate definition of references to both your "origin" fork and our common "upstream" repository. |
Note
|
In order for updates from the common codebase to come without conflicts,
never work in a master branch (or other preferred branch in certain repos)!
Use dedicated private branches for development of new features!
|
TODO: Add a regular job, or one triggered by commits to project repos, to
run such updates and push new references to common FTY dispatcher repo’s
upstream/master
.
As new agents and components and perhaps tweaked third-party projects are added into the mix, either in the common Git organization or in your own set of FTY repositories forks, you can add and check out new Git submodules like this:
:; git submodule add https://github.com/42ity/fty-new-agent
or (to specify a default non-master
branch right away):
:; git submodule add -b 42ity https://github.com/42ity/third-party-fork
Tracking and checkout of new repositories under https://github.com/42ity/ can
be automated using ./sync-repos.sh
script.
Note that after adding sources for a submodule, you’d likely want to reference
its place in the dependency chain for the Makefile
of this FTY workspace
as well (perhaps among COMPONENTS_FTY_EXPERIMENTAL
first, for skeleton
component directories). Don’t forget to git add
both the updated Makefile
and the new component directory, and to set up your own developer fork for it
as detailed below.
To maintain a repository that was forked off an original and actively developed third-party project, you may want to locally define another remote reference so as to track the upstream evolution. For this to work reliably, the 42ITy fork should use different branch names which are not equal to names or tags used by the original repository.
At this time the convention for settling on a certain release of the upstream project is to (assuming you have the admin rights for 42ITy org on GitHub):
-
Fork it on GitHub under the 42ITy org;
-
Go to Travis CI web interface at https://travis-ci.org/profile/42ity/, click to "Sync account" and enable the new fork in sliders below;
-
Fork the 42ITy replica to your developer account (you can also use a fork of original upstream repository — but then take extra care about pull request targeting later on);
-
Clone it to a temporary local workspace, outside the
FTY
directory; -
Check out the commit we settled on as the current baseline, usually some
X.Y(.Z)
release:git checkout 123cafe
orgit checkout release/1.2.3
; -
Nail it down for easier later comparisons or merging as we’d decide to move on to a new baseline:
git checkout -b 1.2.3-release
; -
Branch off a stable line we’d use to cut an end-user release at some point:
git checkout -b 1.2.3-FTY
; -
Branch off a "master-like" line we’d use to develop and stage improvements to this fork, like backported bugfixes or updated Travis integration recipes:
git checkout -b 1.2.3-FTY-master
— this stuff would be used in daily OS images and eventually passes from here to theX.Y(.Z)-FTY
branch; -
Put the new branching info to the 42ITy fork:
git push --all origin
-
Go to GitHub web interface, select the new 42ITy component and go Settings / Branches, e.g.: https://github.com/42ity/libzmq/settings/branches
-
Pick the
X.Y(.Z)-FTY-master
branch as the default, click accept; -
Prevent inadvertent changes to the non-
master
branches:-
Under Protected branches, choose the
X.Y(.Z)-FTY
and click that we want to "Protect this branch", "Require pull request reviews before merging" (and "Dismiss stale pull request approvals when new commits are pushed" under that), "Require status checks to pass before merging" (and "Require branches to be up to date before merging" as well as CI tests where defined) and finally "Include administrators" so at least two people are needed to push the changes to these branches (an admin can also unset this protection, when in a pinch). -
Repeat for
X.Y(.Z)-release
. -
Do not protect the branches we’d want to track from the original project, like the
master
for most of them, as you’d pull-push these occasionally (or even automatics would).
-
-
Finally, set up git submodule tracking (e.g. using the
sync-repos.sh
) in your checkout of the FTY repo; -
Revise that the appropriate
X.Y(.Z)-FTY-master
is the default tracking branch in.gitmodules
for FTYmaster
branch, andX.Y(.Z)-FTY
is for the FTYFTY
branch; -
Add corresponding commits to the FTY repos to begin tracking the project as submodule;
-
Update
Makefile
etc. as may be needed to track this component and maybe its build variants (like we have done to test various CZMQ versions); -
Possibly update our other projects (
project.xml
files and Travis recipes) to build by default against our specified fork and branch, rather than the upstream master repositories which may e.g. no longer expose bugs that can plague our builds… or vice versa (new bugs are introduced by upstreams from time to time, that we don’t see in our OS images). -
Push back the updates to the FTY repository on GitHub.
To use your local workspace for occasional synchronization from the original
project, run the git-myorigin
script detailed below to ensure that your
upstream
refers to the 42ITy fork, and origin
is your own private fork.
Then add tracking for the opensource
reference to the original project and
specify that you want certain branches (like master
) to come from there:
:; cd <newfork> :; git remote add opensource https://github.com/someorg/somerepo :; git remote set-url --push opensource no_push :; git branch --set-upstream-to=opensource/master master
While here, you can also make sure to push the FTY
branches to your
private repository, to use for PRs later on:
:; git branch --set-upstream-to=origin/1.0-FTY-master 1.0-FTY-master :; git branch --set-upstream-to=origin/1.0-FTY-master 1.0-FTY-master
For projects (currently czmq
) where branch and tag naming use the same
string values, which is valid but confuses some git
operations including
checkouts, you might want to forbid pulling remote tags:
:; git config remote.opensource.tagOpt --no-tags
Given sufficient rights in the 42ITy org, you can later synchronize the
master
branch upstream changes, so we can keep track of all changes
there (and of how far ahead/behind is our forked project), with:
:; cd <newfork> :; git checkout master && git pull --all && \ git merge opensource/master && git push upstream
Do not forget to git checkout X.Y(.Z)-FTY-master
after doing this, or
perhaps keep aside a workspace with a checkout of the FTY repository just
for this job. In particular, take care to not add to the git-submodule
tracking the commit IDs not pointing to the latest X.Y(.Z)-FTY(-master)
state. The ./git-sub-branch-list
can speed up such verification.
When updating the FTY repo itself and transplanting changes between the
repositories, make sure that the FTY
and master
branches keep pointing
where they should have (do not merge unexpected changes to .gitmodules
).
The git checkout master && git diff FTY .gitmodules
trick can help here.
Generally a git checkout master && git diff FTY
should only show the
.gitmodules
file and some different submodule references (commit IDs).
When starting a new component, don’t hesitate to start with fty-example
and
its project.xml
in particular to seed the generation of your new codebase
in a way similar to our other components.
If your codebase uses features of C++11 or newer standard, see notes in the
.travis.yml
file (re-)generated for your component about requesting an
appropriate build environment from the Travis CI farm, with a capable compiler.
If the new component delivers systemd
services that should be manageable
as part of the 42ITy™ product, consider updating the list of recognized
services used in fty-core::tools/systemd
and in fty-rest::systemctl.ecpp
(or rather fty-rest::helpers.cc
at this time).
Finally, although orthogonal to updating this repository, don’t forget to enable Travis CI for the new component and add or update some corresponding recipes on your build farm, if any.
If the submodule configuration needs updates due to evolution over time or
because of initial-setup errors, such as that a different remote repository
or default branch must be tracked, you may want to edit the .gitmodules
file directly to set the details you need. It may be required to git deinit
an existing working copy of the submodule and check it out again, to use the
new repository tracking metadata — so before such operations do not forget
to commit your changes and push them out into the GitHub fork. Alternately,
local copies of repositories are just directories with special files — so
you can just rename them to sit nearby, and as far as the Git software is
concerned, by this action you’ve just nuked a checked out submodule and
should simply re-init it again.
Also note that if you clone FTY
, the checked-out repositories will likely
initially refer to the component repository URLs as an origin
, while they
are rather upstream
for our context (and a real origin
would be your
development fork of each such component repo you collaborate on). In this
case, change to the subdirectory of the component in question and run the
git remote
commands to rename references, for example:
:; echo 'GITHUB_USER="mygithubname"' > ~/.git-myorigin :; ./git-myorigin */
For some more inspiration on workflow with submodules, refer to e.g.: