LCFG Core Project

May 2, 2017

Over the last few years I have been working on (and off) creating a new set of “core” libraries for LCFG. This is now finally edging towards the point of completion with most of the remaining work being related to polishing, testing and documentation.

This project originated from the need to remove dependencies on obsolete Perl XML libraries. The other main aims were to create a new OO API for resources/components and packages which would provide new opportunities for code reuse between client, ngeneric and server.

Over time several other aims have been added:

  • Simplify platform upgrades.
  • Platform independence / portability.
  • Make it possible to support new languages.
  • Ensure resource usage remains low.

Originally this was to be a rewrite just in Perl but the heavy resource usage of early prototypes showed it was necessary to move at least some of the functionality into C libraries. Since that point the chance to enhance portability was also identified and included in the aims for the project. As well as making it possible to target other platforms (other Linux or Unix, e.g. MacOSX), the enhanced portability should make it much simpler and quicker to port to new Redhat based platforms.

The intention is that the new core libraries will be totally platform-independent and portable, for example, no hardwired paths or assumptions that platform is Redhat/RPM (or even Linux) based. The new core is split two parts: C and Perl libraries with the aim that as much functionality as possible is in the C libraries to aid reuse from other languages (e.g. Python).

The aim is that these libraries should be able to co-exist alongside current libraries to ease the transition.

I have spent a lot of time on documenting the entire C API. The documentation is formatted into html and pdf using doxygen, I had not used this tool before but I am very pleased with the results and will definitely be using it more in the future. Although a slow task, documenting the functions has proved to be a very useful review process. It has helped me find many inconsistencies between functions with similar purposes and has led to numerous small improvements.

LCFG Client

The client has been reworked to use new Core libraries. This is where the platform-specific knowledge of paths, package manager, etc, is held.

Resource Support

Format Read Write
XML YES NO
DB YES YES
Status YES YES
Environment YES YES

There is currently no support for reading header files or source profiles but this could be added later.

There is new support for finding the “diffs” between resources, components and profiles.

Package Support

Format Read Write
XML YES YES
rpmcfg YES YES
rpmlist YES YES

There is currently no support for reading package list files but this could be added later.

Remaining Work

There is still work to be done on the top-level profile handling code and the code for finding the differences between resources, components and profiles needs reworking. Also the libraries for reading/writing XML files and Berkeley DB need documentation.

That is all the remaining work required on the “core” libraries. After that there will be some work to do on finishing the port of the client to the new libraries. I’ve had that working before but function APIs have changed, I don’t expect it to require a huge amount of work.


PostgreSQL 9.6

September 29, 2016

I’m currently working on upgrading both the PkgForge build farm and the BuzzSaw log file processor services to SL7.2. Both of these services use PostgreSQL databases and have been stuck on 9.2 for a while pending the server upgrades. The latest version of PostgreSQL (9.6) is due to be released today so I thought I would give the release candidate a whirl to see how I get on. There are numerous benefits over 9.2, in particular I am planning to use the new jsonb column type to store PkgForge build information which was previously serialised to a YAML file, being able to query that data directly from the DB should be very useful. The feature I am most interested in trying from 9.6 is parallel execution of sequential scans, joins and aggregates. This has the potential to make some of the large queries for the BuzzSaw DB much faster. My very simplistic first tests suggest that setting the max_parallel_workers_per_gather option to 4 will reduce the query time by at least 50%, it will need a bit more investigation and analyse to check it really is helpful but that’s an encouraging result.

A 2ndQuadrant blog post has some useful information on the new parallel sequential scan feature.


LCFG Client: Hasn’t died yet…

August 2, 2016

Coming back from holiday I was pleased to see that I have a v4 client instance which has now been running continuously for nearly 3 weeks without crashing. It hasn’t done a massive amount in that time but it has correctly applied some updates to both resources and packages.

In the time I’ve not been on holiday I’ve been working hard on documenting the code. For the C code I’ve chosen to use doxygen, it does a nice job of summarizing all the functions in each library and it makes it very simple to write the documentation using simple markup right next to the code for each function. I’ve also been working through some of the Perl modules and adding POD where necessary. It might soon be at the stage where others can pick it up and use it without needing to consult me for the details…


LCFG Client: It lives!

July 15, 2016

Cue forked lightning and crashes of thunder…

After much effort I finally have the first functional installation of the v4 LCFG client. This sees all the XML parsing and profile handling moved over to the new LCFG::Profile Perl modules which are wrappers around the new lcfg-core suite of libraries. There is still a bit of work required to properly handle LCFG contexts but otherwise it can handle everything we need. There are probably lots of small bugs to be resolved, there is also an almost total lack of documentation and the tests needs lot of attention but hey, at least it runs!


LCFG Profile – Secure mode

May 19, 2016

The LCFG client has a, slightly weird, feature called “secure mode“. This makes the client hold off applying any resource changes until they have been manually reviewed. The manual checking is done by examining the contents of a “hold file” which shows the differences in values for each modified resource in a simple text form. The file also contains a “signature” which is the MD5 digest (in hex) of the changes. A change set is applied manually by passing that signature to the client which then regenerates the hold file and compares that signature with the one supplied. This is not a heavily used feature of the client but it is something we want to support in the new LCFG profile framework. The new framework has built-in support for diffing the data structures which represent LCFG profiles, components and resources. This makes it relatively straightforward to add a feature which generates the secure-mode hold file when required, the only awkward part was finding some code to do the MD5 digest in a nice way.

Here’s an example using the C API, error checking and suchlike has been dropped to keep it simple.


#include <lcfg/profile.h>
#include <lcfg/bdb.h>
#include <lcfg/differences.h>

int main(void) {

char * msg = NULL;

LCFGProfile * p1 = NULL;
lcfgprofile_from_status_dir( “/run/lcfg/status”,
&p1, NULL, &msg );

LCFGProfile * p2 = NULL;
lcfgprofile_from_bdb( “/var/lcfg/conf/profile/dbm/example.lcfg.org.DB2.db”,
&p2, NULL, 0, &msg );

LCFGDiffProfile * diff = NULL;
lcfgprofile_diff( p1, p2, &diff, &msg );

char * signature = NULL;
lcfgdiffprofile_to_holdfile( diff, “/tmp/holdfile”, &signature, &msg );

lcfgprofile_destroy(p1);
lcfgprofile_destroy(p2);
lcfgdiffprofile_destroy(diff);

free(msg);

return 0;
}


LCFG profile querying

May 13, 2016

The new LCFG profile framework makes it simple to retrieve component and resource information from profiles stored in the various standard formats (XML, Berkeley DB and status files).

Loading a profile from XML, DB or status directory:


my $p = LCFG::Profile->new_from_xml(“example.xml”);


my $p = LCFG::Profile->new_from_bdb(“example.db”);


my $p = LCFG::Profile->new_from_status_dir(“/run/lcfg/status”);

Loading a component from a DB or status file:


my $c = LCFG::Profile::Component->new_from_bdb( “example.bdb”, “client” );


my $c = LCFG::Profile::Component->new_from_statusfile( “/run/lcfg/status/client” );

Retrieving a component (e.g. client) from the profile:


my $c = $p->find_component(“client”);

Retrieving a resource (e.g. client.components) from a component:


my $r = $c->find_resource(“components”);

Getting the resource value:


say $r->value;

For convenience, if the resource is a tag list then you can get the value as a perl list:


@comps = $r->value;
for my $comp (@comps) {

}


LCFG profile handling

May 13, 2016

Over the last few months the new libraries for handling LCFG profiles have been shaping up nicely. They are finally reaching a point where they match up with my original aims so I thought I’d give a taste of how it all works. Here’s an example of processing an LCFG XML profile into the Berkeley DB and rpmcfg files required by the client:

use LCFG::Profile;

my $xml    = '/var/lcfg/conf/profile/xml/example.lcfg.org.xml';
my $dbm    = '/tmp/example.lcfg.org.DB2.db';
my $dbm_ns = 'example';
my $rpmcfg = '/tmp/example.lcfg.org.rpmcfg';

my $new_profile = LCFG::Profile->new_from_xml($xml);

my $update_dbm = 0;
if ( -f $dbm ) {
    my $cur_profile = LCFG::Profile->new_from_bdb($dbm);

    my $diff = $cur_profile->diff($new_profile);

    if ( $diff->size > 0 ) {
        $update_dbm = 1;
    }
} else {
    $update_dbm = 1;
}

if ( $update_dbm ) {
    $new_profile->to_bdb( $dbm, $dbm_ns );
    say 'Updated DBM';
}

my $pkgs_changed = $new_profile->to_rpmcfg($rpmcfg);
if ( $pkgs_changed ) {
    say 'Updated packages';
}

This is basically what the LCFG client does whenever it processes a new profile but is a lot nicer than the current rdxprof code!


Platform-specific config

January 13, 2016

I recently came across this blog article titled Stop writing code that will break on Python 4!. Although the title mentions python 4 it is really discussing “any future major version“.

This is something we have learnt to deal with in LCFG over the years. We often have to tweak configuration slightly when developing support for new platforms and this results in lots of if/elseif/else statements based on the target platform. Once you’ve been through the platform upgrade cycle a few times you learn that the most efficient approach is to special-case the old platform and make the new platform the default. By assuming that the configuration required for the new platform will be the default going forwards (i.e. it sits in the “else” branch) you make the configuration for N+1 and also handle N+M at the same time.


Writing modern C

January 10, 2016

For the v4 LCFG client project I’ve been writing lots of C. To get my C knowledge up to scratch I’ve been consulting many books of varying vintages which leads to quite a mixture of coding styles. I’m quite keen to create code which is concerned “good” according to modern coding standards but I also want to ensure it will compile on a wide range of Unix-like systems, that seems to mean right now that the standard to aim for is C99. I recently came across an interesting article titled "How to C (as of 2016)" which gives a good summary of many important topics to consider. I’ve already been following many of the suggestions but there are also quite a few which are totally new to me. I’m not sure I agree with all of them (e.g. not using char) but I shall definitely be applying some of them.


Security awareness

November 20, 2015

I recently came across a series of short blog posts from the SANS Securing the Human site on the topic of Security Awareness. I found them to be quite interesting and thought provoking. If you’re interested in what can be done to improve the security of an organization I’d recommend these as a good starting point:

  1. The 4 Ws to Awareness Success
  2. The Why in Effective Awareness Programs
  3. The Who in Effective Awareness Training
  4. The What in Effective Awareness Training
  5. The How in Effective Awareness Training