The 6-Month Ruling

Recently I have started going through all my CPAN modules one-by-one and getting any fixes that are in there out onto CPAN. Some have had bug fixes sitting in the repository for at least 1 year. Because of this, I’m thinking of giving myself a “6-month ruling” where I should probably release a new version of a module at least every 6 months. This should keep me from at least forgetting about publishing forgotten bug fixes in the repositories.

Should Perl Modules Default to Non-Blocking?

I have been thinking about possibly changing my modules and for the creation of new modules in the future to be non-blocking (like utilizing AnyEvent or something else generic). Typically these days my main work involves node.js, which emphases non-blocking (i.m.o). Then a post came up recently that made me think about this again (yes, I know in this particular case non-blocking still would not have solved the issue here, which was, apparently, that the person did not want to use event-based programming, but it just reminded me on my thoughts on non-blocking).

The main thing with non-blocking is that if you want to use something that is blocking, it is harder to use that in a non-blocking environment unless you can shove that blocking behavior into a background thread and put an event wrapper around it. Also, a non-blocking module can always be used in a blocking way, so I think this makes it a win-win.

Note: By “default to non-blocking” I mean that they can behave in a non-blocking way, so the module can behave both blocking and non-blocking.

Net-TacacsPlus Perl Distribution

Recently after submitting a few patches to the Net-TacacsPlus Perl distribution, I suggested to the maintainer, Jozef Kutej, that the POE pieces be split out of the distribution into their own distribution. I suggested this because I felt like the POE pieces were not used by enough of the Net-TacacsPlus users (plus in my use of Net-TacacsPlus I wasn’t using POE, so I felt it was unnecessary to install POE and its requirements).

Anyhow, after splitting the repository into two separate distributions, Jozef uploaded a TRIAL and then granted me co-maintainer status on the Net-TacacsPlus distribution and I uploaded the new distribution, as well as the new POE-Component-Server-TacacsPlus distribution.

Nothing on the CPAN should be affected by this distribution split, but any code on the DarkPAN should be fine as long as the dependencies are marked on the modules they require instead of the base module on the distribution they depend on.

CPAN Testers Metabase has a certificate

As an update to my previous post, David Golden has posted an update that the certificate for metabase.cpantesters.org is now signed by a certificate authority that is included in Mozilla-CA! This means anyone who was using my hypothetical distribution as a work-around in the mean time should not only stop using it, but it will no longer connect as the certificate has changed! You’d end up with the following error:

CPAN::Reporter: Test::Reporter: error from 'Test::Reporter::Transport::Metabase::CPANTesters:'
fact submission failed: Can't connect to metabase.cpantesters.org:443 (certificate verify failed) at C:\strawberry\perl\site\lib/Metabase/Client/Simple.pm line 111
...
        Test::Reporter::Transport::Metabase::CPANTesters::send('Test::Reporter::Transport::Metabase::CPANTesters=HASH(0x7a932b8)', 'Test::Reporter=HASH(0x62cb790)') called at C:\strawberry\perl\site\lib/Test/Reporter.pm line 279
...

Simply modify your CPAN::Reporter configuration to use the standard Metabase transport with the CPAN Testers metabase URI. Here is a short script you can run to automatically update your configuration:

#!/usr/bin/env perl
 
use 5.006;
use CPAN::Reporter::Config;
 
my $config_file = CPAN::Reporter::Config::_get_config_file();
my $config = CPAN::Reporter::Config::_open_config_file();
 
my ($class, %args) = split m{\s+}mosx, $config->{_}->{transport};
 
if ($class eq 'Metabase::CPANTesters') {
    print "Modifying configuration file transport line from\n", $config->{_}->{transport}, "\n";
    # Correct the transport information
    $class = 'Metabase';
    $args{uri} = 'https://metabase.cpantesters.org/api/v1/';
    $config->{_}->{transport} = "$class " . join q{ }, %args;
    print "to\n", $config->{_}->{transport}, "\n";
    # Write the configuration
    $config->write($config_file);
    print "Done\n";
}
elsif ($config->{_}->{transport}) {
    # Modification does not look necessary
    print "Leaving transport configuration set to\n", $config->{_}->{transport}, "\n";
}
else {
    # Modification does not look like it should occur
    print "Not modifying configuration without transport directive\n";
}
 
exit 0;

In order to be fully capable of submitting reports through CPAN::Reporter, be sure to have the following modules installed:

IO::Socket::SSL
Mozilla::CA

For a full uninstall of the hypothetical distribution, please see the UNINSTALL file now included with the distribution.

CPAN::Reporter, Transport::Metabase, and libwww-lwp 6

Recently libwww-lwp-6.00 hit the CPAN with one major change in the default operating behavior: connecting using the https protocol would cause the certificate chain from the server to be verified that it was issued by a trusted certificate authority. In my opinion this behavior is a good thing, as this finally brings libwww-lwp in line with all the browsers.

There were a few blog articles where this change caught people by surprise in that submissions to the CPAN Testers Metabase failed (due to metabase.cpantesters.org using a self-signed certificate). Because metabase.cpantesters.org uses a self-signed certificate, simply installing Mozilla::CA, which is a bundle of all the trusted CAs by Mozilla, will not correct the submissions failures (plus you have to install a few other modules). The typically error you will see once you have libwww-perl-6.00 install is as follows:

CPAN::Reporter: Test::Reporter: error from 'Test::Reporter::Transport::Metabase:'
fact submission failed: Can't connect to metabase.cpantesters.org:443 (certificate verify failed) at C:\strawberry\perl\site\lib/Metabase/Client/Simple.pm line 111

You may also see the following error if you do not have IO::Socket::SSL installed:

CPAN::Reporter: Test::Reporter: error from 'Test::Reporter::Transport::Metabase:'
fact submission failed: Can't connect to metabase.cpantesters.org:443 (Crypt-SSLeay can't verify hostnames) at C:\strawberry\perl\site\lib/Metabase/Client/Simple.pm line 111

As a work-around for this problem (without just disabling certificate checking or other environment changes) I wrote two classes that subclass Metabase::Client::Simple and Test::Reporter::Transport::Metabase that make them specific to submitting to the CPAN Testers Metabase and bundle the metabase.cpantesters.org certificate and check the certificate against the bundled one. Having a module where a certificate is bundled may or may not be what CPAN Testers Metabase wants, which is why I do not have any intentions on actually publishing this distribution. If you are interested in looking at it, you can view it as Github Gist 867743 (using the download button at the top results in the distribution tarball).

The premise is to subclass the Metabase transport to set the uri to be the CPAN Testers Metabase URI by default and to set the client to my client subclass. The client subclass simply wraps the LWP::UserAgent generation method and sets the SSL option to verify the certificate with the bundled certificate. This accomplished by this excerpt:

around _ua => sub {
    my $orig = shift;
    my $self = shift;
 
    my $ua_was_generated = !$self->{_ua};
 
    # Get the standard generated UA
    my $ua = $self->$orig(@_);
 
    if ($ua_was_generated) {
        # Add our SSL options to the UA
        $ua->ssl_opts(SSL_ca_file => File::ShareDir::dist_file('Test-Reporter-Transport-Metabase-CPANTesters', 'metabase.cpantesters.org.crt'));
    }
 
    return $ua;
};

If you are interested in using the module, you can download the tarball and run the commands outlined in INSTALL and be sure to change your CPAN Reporter configuration as noted in README to actually use the new module. After you install it, you can simply set your CPAN Reporter configuration file to have:

transport = Metabase::CPANTesters id_file ~/.cpanreporter/metabase_id.json

A possible solution to this situation may be for the Test::Reporter::Transport::Metabase to have an option for SSL parameters like the certificate file and pass that parameter on to Metabase::Client::Simple for it to set in it’s LWP::UserAgent instance (or metabase.cpantesters.org could have a certificate signed by a CA trusted by Mozilla, though this solution may cost money for the certificate purchase).

Net::NSCA::Client Introduction

I have realized that I’ve never announced my Perl module Net::NSCA::Client. This module was created to make it easy for Perl applications to report to a NSCA server. NSCA (which stands for NetSaint Check Acceptor) is not very good at it’s job, but there is no replacement for it that I am aware of (though I hope to change this in the future).

I needed to be able to send reports back to NSCA easily from Perl programs (and without needing to go through the send_nsca program that comes with NSCA). I came across Net::Nsca, which mostly works, besides for the fact that I need to change the packet version in the code to 3 (which is not easy to do since it wasn’t made to be changed).

I decided to make my own NSCA client, using Moose and would be hopefully more flexible. A sort example of sending a report in some routine in a server would be:

sub nsca_heart_beat {
    my ($self) = @_;
 
    $self->nsca_client->send_report(
        hostname => $self->hostname,
        service  => 'server',
        message  => 'Running',
        status   => $Net::NSCA::Client::STATUS_OK,
    );
 
    return;
}

This is good and all, but not really a killer feature by any means. What really is a winner here is the Net::NSCA::Client::ServerConfig class that was added in version 0.007. One of the biggest problems with NSCA is that what is sent over the network is not portable. Yes, the data is made to be aligned in network order, but it actually sends a native C structure over the network. The problem is what happens when the server and client happen to compile different structures? This is what ServerConfig is for. It also makes it easy if it any of the constants defined in the NSCA source files were changed when NSCA was built. This client is the only one of the currently three others on the CPAN to support this.

I’ve currently been working on this module in my spare time and coming up is support for encryption methods besides XOR (like AES) as well as complete support for the standard send_nsca.cfg configuration file, plus much more.

Mustang Emergency Brake Problem

I currently own a 2000 Ford Mustang. It is a manual transmission and with that I use the emergency brake very frequently. A few weeks ago, as I pulled up my emergency brake, there was a snap and it felt like it was now loose. On further inspection, it appeared that the bolt attaching the forward-end of the emergency brake handle came loose or broke. When I looked at it more and researching online, it became evident that this is actually a design flaw in the car model.

View of the broken bolt on the MustangOn the left is a photo of the bolt that has come undone on the emergency brake. The blue rectangle piece there is what used to be welded into that rectangle hole. Normally there is a bold going through the emergency brake mechanism and threads through that metal rectangle. Why Ford decided to weld a steel rectangle into a rectangular hold on the top of the transmission tunnel is beyond me. I’d figure the threads could have just been cut directly into the steel body.

How should I fix this? Well, of course the proper way of fixing the issue would be to weld the piece back on—but that is out-of-the-question too complicated. Perhaps not the welding itself, but certainly removing and covering the interior to shield from the sparks. Now that would be a nightmare.

View of the washer and nut from below the carI approached my friend to brain storm other ways to approach this. We came up with three different ways to “hotfix” the brake mechanism. What we did was take a galvanized washer and bend it to match the curvature of the transmission tunnel. Then this washer was placed on the underside of the car and the bolt was threaded though the emergency brake, the hole, the washer, and then a lock nut. The photo on the right is a view of the nut and washer at the top of the transmission tunnel.

So far it has been over a month and still working great.

Strawberry Perl, patch.exe and UAC

I work a lot with Perl 5 under Windows and have loved Strawberry Perl so much. I’ve been using ActiveState’s ActivePerl since 2001 and welcomed the UNIX-like experience Strawberry Perl gave me, especially because it was sometimes very hard to get some modules for ActivePerl.

Anyhow, in Windows Vista and up the User Account Control feature has a backwards-compatibility feature where for programs that don’t contain manifest files (presumably because they aren’t UAC-aware) Windows will look at certain characteristics of the file to determine if it needs Administrative privileges to run properly. One of the ways it determines this is by file name. The utility that comes with the C tool chain in Strawberry Perl patch.exe triggers this detection mechanism because of the word “patch” in the file name. Because of this it is pretty much impossible to install modules like Math::Pari that make use of the patch.exe program.

A few days ago I saw a new development release of Win32::Exe (0.12_03) was released and saw it supported viewing and modifying of embedded manifests! I decided to use this on the patch.exe file in Strawberry Perl to set the required privilege level to asInvoker (so that UAC is not needed) and it worked! Though you no longer need to do this for the April 2010 and up Strawberry Perl releases, anyone running an older version and not planning to upgrade soon may want to modify their path.exe with the following commands:

C:\> cpan MDOOTSON/Win32-Exe-0.12_03.tar.gz
C:\> perl -MWin32::Exe -e "$e=Win32::Exe->new('c:/strawberry/c/bin/patch.exe'); $m=$e->get_manifest; $m->set_execution_level('asInvoker'); $e->set_manifest($m); $e->write;"

Important Bug Fix in Authen::CAS::External 0.06

Earlier today I released an important bug fix to my distribution Authen-CAS-External (under version 0.06). The bug caused the distribution to fail on CAS deployments where the application was not deployed at the root URL (i.e. https://cas.domain.com/login worked fine, but https://cas.domain.com/cas/login did not work at all). The reason was because the LWP::UserAgent handler rules had m_path_match set to a static qr{\A /login}msx, which clearly would only match pages where login was at the root, which is not always the case. This was fixed by storing the path to login in the variable $cas_path and then changing the path match to qr{\A \Q$cas_path\E}msx. Note the \Q and \E are important so that the regular expression properly treats the path as a static string. The full patch can be seen in commit df8ef3b.

Big Updates to Nagios::Plugin::OverHTTP

I was contacted by Peter van Eijk who was interested in getting performance data support added to Nagios-Plugin-OverHTTP and I quickly moved to add it in. Version 0.14 added performance data support and a major overhaul was made to the class layout. I was inspired by the layout of Plack and thought that it was a great layout for a pluggable system. I hope to a “builder” class similar to Plack::Builder so users can create all kinds of plugins based off Nagios-Plugin-OverHTTP. As soon as the builder class comes out, I will created a very detailed post on the greatness of this plugin.