EIL Linux Client Agent
Technical Design Document
Table of Contents
0) Development Environment
0.a) Mercurial
0.a.1) Branches, tags and naming conventions
0.b) Windows Considerations
Development Environment
Before we begin, we should touch on the development environment used in the
Linux Client agent.
It is important that the Linux Client agent be developed under a proper
environment which respects Linux/Unix line-endings, and that changes are tracked
in the version control system.
For full build/development environment information, see the file BUILD_ENV.
0.a) Mercurial
Mercurial (hg) was chosen as the distributed version control system (DVCS)
because of its cross-platform nature and ease of use. It should be available on
your development platform of choice, but can also be found online at its
homepage here:
* http://mercurial.selenic.com/
If you are new to hg, then you should probably familiarize yourself with
the guides and tutorials available on the following pages:
* http://mercurial.selenic.com/guide/
* http://mercurial.selenic.com/wiki/Tutorial
* http://hgbook.red-bean.com/read/
NOTE: hg cannot integrate with TFS (neither can git, which we tried as well)
See dispatcher/docs/TFS_Notes.txt for more information.
0.a.1) Branches, tags and naming conventions
Inside of our Mercurial repository, we will adhere to the following naming
conventions:
* Tagging - Tags will be used for major releases and will be the same
as the version
* Branches - Branches will be used for experimental and/or disruptive
changes that might break the code. The general branch
"bigdev" is used for any large and disruptive changes and
can be re-used, provided no active development is currently
going on in it.
0.b) Windows Considerations
The Linux Client agent can be developed under Windows, provided that care is
given. Line endings MUST be respected, Mercurial MUST be used, etc.
In Windows, you should NOT use a Windows-centric IDE such as Visual Studio
to develop the Linux Client agent. Instead, you should install a more platform-
agnostic editor such as Notepad++, which is Open-Source software and available
for free from its homepage here:
* http://notepad-plus-plus.org/
Additionally, you should install the Windows version of Mercurial along with
the TortoiseHg extension. Additional extensions you may want to install to help
prevent Windows-centric applications from clobbering the Linux development
process include:
* http://mercurial.selenic.com/wiki/EolExtension
* http://mercurial.selenic.com/wiki/CasestopExtension
It is highly recommended that you do NOT develop Linux applications under
Windows unless you know what you are doing. Instead, it is much safer to simply
develop natively in Linux.
1.a) Project History
The original stated goal of the EIL Linux Client Agent project was to port
the existing C# Windows client to Linux/Mono (circa October 2010). However, due
to difficulties with the existing C# Windows client code (dependencies upon
Windows binary DLLs, dependencies upon .NET API calls not fully implemented in
current versions of Mono, and hard project requirements on platforms that did
not natively provide Mono support), this was scrapped in lieu of a more native
Linux solution.
Recommendations were made (and initial prototyping was done) to create the
native Linux Client Agent in Python (which was present on all desired Linux
target platforms), however Python was ultimately rejected because of
maintainability concerns due to there being no permanent staff member with
Python experience.
* An exception was made with the NMSA handler daemon, which is in Python.
The team wanted the handler integrated as soon as possible, and a thin
Python layer was determined the best path.
1.b) Linux Client Agent Re-Write Requirements
It was determined that the Linux Client Agent needed to be re-written in a
more native Linux way. The final design requirements were as follows:
* It was to be written in C/C++ and BASH
* The resultant binary would be linked statically
- The goal was to have the Linux Client Agent be something that
could be "dropped in" to any Linux system with minimal fuss and
no additional package dependency install.
- This requirement meant that care had to be given when C++ was
used in the code due to the fact that libstdc++ cannot currently
be statically linked using gcc. (Primarily, this means gSOAP must
be built without STL support, and no STL templates can be used.)
- Due to some complications with the binary on pretty standard
systems (SuSE) which *may* be due to ABI compatibility, we may
wish to re-evaluate this priority.
* Linux client agent should have custom, cross-distribution installer
* Client agent should not use "complex build systems"
other server) is unreachable.
* Client agent must interact with current .NET-based CCMS
- Current .NET-based CCMS runs WCF (Windows Communication
Foundation) and utilizes WS-Addressing (version 5,
http://www.w3.org/2005/08/addressing).
* The client agent should conform to LFHS, LSB and LANANA conventions
whenever possible (and whenever it doesn't conflict with previously
stated goals).
Linux Client Agent
Because of the requirements detailed above, it was determined that the EIL
Linux Client Agent should be split into two distinct components. One component
will interact with CCMS, obtaining SOAP commands and relaying information,
while the other component will translate those commands into instructions
native to whatever Linux distribution the agent is currently running on.
These two components are called the "Steward" and the "Dispatcher"
respectively.
2.a) Steward
The steward is the C/C++ component of the agent which utilizes gSOAP and
interacts with CCMS. It runs as a daemon.
The steward's job is to periodically report in with CCMS and check for any
queued commands. If a command exists, it will hand that command over to the
dispatcher.
The steward intercepts the following standard Linux signals:
* SIGHUP - Changes the state of the steward to 'shutdown'. In this
state, the steward will attempt to shut itself down cleanly and
correctly.
* SIGINT - Changes the state of the steward to 'shutdown'. This is
the same effect as sending 'SIGHUP' to the steward.
* SIGTERM - Changes the state of the steward to 'terminate'. This
tells the steward to terminate anything it is doing at the moment
and to stop execution as soon as possible. This should only be used
in extreme circumstances as it may leave elements of the steward in
an undefined state (for example, the log might not be flushed, any
soap interactions may not be properly closed, etc.)
In addition to the standard Linux signals, the steward interprets certain
non-POSIX defined signals as follows:
* SIGUSR1 - Causes the steward to re-check for an updated asset info
file. This does not guarantee that the asset information will be
updated with CCMS, as the file still must pass the various checks
found in lib_nmsa/assetHelper, but it re-triggers the logic to
check for updated asset info.
* SIGUSR2 - Causes the steward to initialize an upgrade as if a similar
request had been issued from CCMS.
The steward can log in one of two places. It has a flexible logging class
which automatically wraps logging in a client agent specific location (which
is determined by the client agent helper script, see 2.b.1) as well as logging
information to syslog. This makes the steward able to log in a standard Linux
daemon way (via syslog) which allows us to make use of log rotate as well as
the security features syslogs proffers, yet also gives us the flexibility to
maintain our own logging which can survive OS provisioning.
2.a.1) The script permission elevator
Due to security risks, the setuid bit is ignored on modern Linux
distributions when set on shell scripts. This is a problem for us as we need our
scripts to run with elevated permissions.
The issue is explained here:
http://www.faqs.org/faqs/unix-faq/faq/part4/section-7.html
We do not want to disable this security feature generally as it helps keep
our Linux systems safe, however, we do need a way to elevate the privileges of
our scripts as needed.
The script elevator is our secure solution to this problem. It is a tiny
binary which, when called, will elevate a script it is passed as an argument
to whatever it is setuid as provided that the calling GID is a the same as the
owner GID of the script.
This is not a perfect solution from a security standpoint, but it is
sufficient for our needs.
2.b) Dispatcher
The dispatcher is the BASH component of the agent which handles the
distribution-dependent functionality of the client agent. It is a wrapper
around a suite of scripts which execute various commands for the steward.
2.b.1) Client helper tools
In addition to command handling, the dispatcher also provides helper tools
and scripts for the rest of the client agent suite. This includes the
following:
* clientagent-helper.sh
- Helper script which provides glue between steward and
dispatcher.
* install_tool.sh
- Helper install script (satisfies the "distribution-agnostic"
installation need).
* rebuild.sh
- Script used to rebuild the gSOAP bindings (should only be used
when the CCMS details change, such as IP address or generative
XML).
* dispatcher/tests/
- Unit testing framework for the client agent (requires shunit2,
http://code.google.com/p/shunit2/).
* clientagent-bootstrap.sh
- The clientagent-bootstrap.sh script handles the basic bootstrap
install/upgrade process of the client agent itself. For more
information see section (6.a) of the INSTALL file.
* update-checker.sh
- The update-checker.sh script is intended to be run from a cron
job periodically to check for updates the client agent. See
section (6.a) of the INSTALL file for more information.
* logger.sh
- This shell script exposes client agent logging functionality to
external applications. See dispatcher/docs/API_Notes.txt for
more information.
Documentation
The EIL Linux Client Agent contains a number of documents to help in
extending and maintenance. They can be found in the source repository, or in
the doc/ install directory (generally /opt/intel/eil/clientagent/doc) after
installation. Most of this documentation is self-explanatory, but let's
briefly cover some of the highlights.
* README, LICENSE, INSTALL, etc.
- The file you read now, as well as the other all caps
documentation files are very loosely based upon the well-
established "Gnits Standards"
(http://en.wikipedia.org/wiki/Gnits_Standards). This is in
keeping with other native Linux/Unix projects.
* HTML Library Documentation
- Each C/C++ library included in the steward source tree has full
API documentation generated from comments in the source code.
This is done using the Doxygen tool (http://www.doxygen.org/).
- Rebuilding the API documentation is fairly simple, though care
must be giving to first purge the existing documentation from the
source repository and then re-add the documentation once it has
been regenerated (I am not sure this was the best procedural
decision in retrospect, but it is the one that has stuck). Thus,
the general process for rebuilding the documentation in a given
library is as follows:
$ cd lib_something/
$ hg rm html/
...watch the existing documentation purge...
$ hg commit -m "purge docs for rebuild"
$ doxygen Doxyfile
$ hg add html/
$ hg commit -m "add rebuilt docs"