Skip to content

Commit

Permalink
ncm-sysconfig: Modernise and add unit tests
Browse files Browse the repository at this point in the history
* Switch to CAF for all file interaction and declare NoAction support.
  * Use logger with FileWriters
  * Declare no-action support
* Factor out filelist read/write to seperate functions.
* Add a set of basic Configure unit tests.
* Move pod into main source module
  * Switch nlists to dicts in pod
  * Move example to schema and remove redundant pod
  • Loading branch information
jrha committed Jun 15, 2018
1 parent 28a99d6 commit 77e22ce
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 105 deletions.
130 changes: 71 additions & 59 deletions ncm-sysconfig/src/main/perl/sysconfig.pm
Original file line number Diff line number Diff line change
@@ -1,109 +1,121 @@
#${PMcomponent}

use parent qw(NCM::Component);
=head1 NAME
sysconfig: management of sysconfig files
=head1 DESCRIPTION
The I<sysconfig> component manages system configuration files in
C<< /etc/sysconfig >> . These are files which contain key-value pairs.
However there is the possibility to add verbatim text either before or after the key-value pair definitions.
=cut

use parent qw(NCM::Component CAF::Path);

our $EC = LC::Exception::Context->new->will_store_all;

use LC::Check;
our $NoActionSupported = 1;

use File::Path;
use File::Basename;
use Readonly;

Readonly my $QUOTE => "\"";
Readonly my $SYSCONFIGDIR => "/etc/sysconfig"; # The base directory for sysconfig files.

sub Configure
sub filelist_read
{
my ($self, $config) = @_;
my ($self) = @_;

# Read first the list of sysconfig files which have been
# previously managed by this component. These will have to
# be deleted if no longer in the configuration.
my %filelist;
my $fh = CAF::FileReader->open("$SYSCONFIGDIR/ncm-sysconfig", log => $self);
while (my $line = <$fh>) {
chomp($line);
$filelist{$line} = 1;
}
$fh->close();

# Define paths for convenience.
my $base = "/software/components/sysconfig";
return %filelist;
}

# The base directory for sysconfig files.
my $sysconfigdir = "/etc/sysconfig";
sub filelist_write
{
my ($self, %filelist) = @_;

# Write the list of managed configuration files.
my $fh = CAF::FileWriter->open("$SYSCONFIGDIR/ncm-sysconfig", log => $self);
for my $file (keys %filelist) {
print $fh "$file\n";
}
$fh->close();

return 1;
}

sub Configure
{
my ($self, $config) = @_;

# Load configuration into a hash
my $sysconfig_config = $config->getElement($base)->getTree();
my $sysconfig_config = $config->getTree($self->prefix());

# Ensure that sysconfig directory exists.
mkpath($sysconfigdir,0,0755) unless (-e $sysconfigdir);
if (! -d $sysconfigdir) {
$self->error("$sysconfigdir isn't a directory or can't be created");
return 1;
}
$self->directory($SYSCONFIGDIR, owner=>0, group=>0, mode=>0755);

# This will be a list of the configuration files managed by this component.
my %newcfg;
my %files_managed;

# Read first the list of sysconfig files which have been
# previously managed by this component. These will have to
# be deleted if no longer in the configuration.
my %oldcfg;
if (-f "$sysconfigdir/ncm-sysconfig") {
open CONF, "<", "$sysconfigdir/ncm-sysconfig";
while (<CONF>) {
chomp;
$oldcfg{$_} = 1;
}
}
my %files_previous = $self->filelist_read();

# Loop over all of the defined files, writing each as necessary.
if ( $sysconfig_config->{files} ) {
for my $file (sort keys %{$sysconfig_config->{files}}) {
foreach my $file (sort keys %{$sysconfig_config->{files}}) {

my $pairs = $sysconfig_config->{files}->{$file};

# Start with an empty file.
my $contents = '';

# Add the prologue if it exists.
if (defined($pairs->{"prologue"})) {
$contents .= $pairs->{"prologue"} . "\n";
if (defined($pairs->{prologue})) {
$contents .= "$pairs->{prologue}\n";
}

# Loop over the pairs adding the information to the file.
for my $key (sort keys %{$pairs}) {
for my $key (sort keys %$pairs) {
if ($key ne 'prologue' && $key ne 'epilogue') {
$contents .= $key . '=' . $pairs->{$key} . "\n";
$contents .= "$key=$pairs->{$key}\n";
}
}

# Add the epilogue if it exists.
if (defined($pairs->{"epilogue"})) {
$contents .= $pairs->{"epilogue"} . "\n";
if (defined($pairs->{epilogue})) {
$contents .= "$pairs->{epilogue}\n";
}

# Now actually update the file, if needed.

my $result = LC::Check::file("$sysconfigdir/$file",
backup => ".old",
contents => $contents,
);
unless ( $result >= 0 ) {
$self->error("Error updating file $sysconfigdir/$file");
}
my $fh = CAF::FileWriter->open("$SYSCONFIGDIR/$file", backup => ".old", log => $self);
print $fh $contents;
$fh->close();

# Remove this file from the list of old configuration
# files add to the new configuration files.
delete($oldcfg{"$sysconfigdir/$file"});
$newcfg{"$sysconfigdir/$file"} = 1;
delete($files_previous{"$SYSCONFIGDIR/$file"});
$files_managed{"$SYSCONFIGDIR/$file"} = 1;
}
}

# Remove any old configuration files which haven't been updated.
for my $file (keys %oldcfg) {
unlink $file if (-e $file);
for my $file (keys %files_previous) {
$self->cleanup($file);
}

# Write the list of managed configuration files.
if(open CONF, ">", "$sysconfigdir/ncm-sysconfig") {
for my $file (keys %newcfg) {
print CONF $file . "\n";
}
close CONF;
} else {
$self->error("error writing file $sysconfigdir/ncm-sysconfig");
return 1;
}
$self->filelist_write(%files_managed);

return 0;
return 1;
}

1; # Required for PERL modules
1; # Required for PERL modules
46 changes: 0 additions & 46 deletions ncm-sysconfig/src/main/perl/sysconfig.pod

This file was deleted.

29 changes: 29 additions & 0 deletions ncm-sysconfig/src/test/perl/configure.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use strict;
use warnings;
use Test::More;
use Test::Quattor qw(configure);
use NCM::Component::sysconfig;

$CAF::Object::NoAction = 1;

my $cmp = NCM::Component::sysconfig->new('sysconfig');
my $cfg = get_config_for_profile('configure');

# Set up list of previously managed files
set_file_contents('/etc/sysconfig/ncm-sysconfig', "/etc/sysconfig/delete_me\n/etc/sysconfig/examplefile\n");

# Set up existing files with garbage contents
set_file_contents('/etc/sysconfig/delete_me', "DELETE_ME=delete_me\n");
set_file_contents('/etc/sysconfig/examplefile', "NOPE=nope_nope\n");

is($cmp->Configure($cfg), 1, "Does the component run correctly with a test profile?");

isa_ok(get_file('/etc/sysconfig/ncm-sysconfig'), "CAF::FileWriter", "Is the file-handle for the list of managed files the correct class?");
is(get_file_contents('/etc/sysconfig/ncm-sysconfig'), "/etc/sysconfig/examplefile\n", "Is the list of managed files updated correctly?");

is(get_file_contents('/etc/sysconfig/delete_me'), undef, "Has the previously managed file been deleted?");

isa_ok(get_file('/etc/sysconfig/examplefile'), "CAF::FileWriter", "Is the file-handle for the example file the correct class?");
is(get_file_contents('/etc/sysconfig/examplefile'), "key1=testvalue\nkey2=valuetest\n", "Does the example file have the correct contents?");

done_testing();
6 changes: 6 additions & 0 deletions ncm-sysconfig/src/test/resources/configure.pan
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
object template configure;

prefix '/software/components/sysconfig';

'files/examplefile/key1' = 'testvalue';
'files/examplefile/key2' = 'valuetest';

0 comments on commit 77e22ce

Please sign in to comment.