Skip to content

Commit

Permalink
Merge pull request #1623 from RexOps/test_augeas
Browse files Browse the repository at this point in the history
Add initial Augeas tests
  • Loading branch information
ferki committed Oct 22, 2024
2 parents 7de161c + 471c679 commit ba36461
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 22 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ jobs:
name: build.tar
- name: Extract build tarball
run: tar xvf build.tar
- name: Install packages
run: sudo apt-get install -y augeas-tools libaugeas-dev
- name: Setup Perl
id: perl
uses: shogo82148/actions-setup-perl@v1
Expand Down Expand Up @@ -125,7 +127,7 @@ jobs:
- name: Extract build tarball
run: tar xvf build.tar
- name: Install packages
run: sudo apt-get install -y aspell
run: sudo apt-get install -y aspell libaugeas-dev
- name: Setup Perl
id: perl
uses: shogo82148/actions-setup-perl@v1
Expand Down
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Revision history for Rex

[BUG FIXES]
- Return only the first found command
- Fix inconsistent augtool wrapper usage
- Fix Config::Augeas detection

[DOCUMENTATION]

Expand All @@ -15,6 +17,8 @@ Revision history for Rex
[MINOR]

[NEW FEATURES]
- Add config option to prepend Augeas commands
- Add config option to control local Augeas backend

[REVISION]

Expand Down
5 changes: 5 additions & 0 deletions dist.ini
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ File::LibMagic = 0
Test::mysqld = 0
DBD::mysql = 0

[OptionalFeature / use_config_augeas]
-relationship = suggests
-description = Run Augeas commands with Config::Augeas
Config::Augeas = 0

[Test::MinimumVersion]
max_target_perl = 5.12.5

Expand Down
44 changes: 24 additions & 20 deletions lib/Rex/Commands/Augeas.pm
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,10 @@ use Rex::Commands::File;
use Rex::Helper::Path;
use Rex::Helper::Run;
use IO::String;
use Module::Load::Conditional qw(can_load);

my $has_config_augeas = 0;

BEGIN {
use Rex::Require;
if ( Config::Augeas->is_loadable ) {
Config::Augeas->use;
$has_config_augeas = 1;
}
}
my $has_config_augeas =
can_load( modules => { 'Config::Augeas' => undef } ) ? 1 : 0;

@EXPORT = qw(augeas);

Expand All @@ -81,9 +75,15 @@ sub augeas {

my $is_ssh = Rex::is_ssh();
my $aug; # Augeas object (non-SSH only)
if ( !$is_ssh && $has_config_augeas ) {

my $use_augtool =
!$has_config_augeas || Rex::Config->get_local_augeas_backend eq 'augtool';

if ( !$is_ssh && !$use_augtool ) {
Rex::Logger::debug("Creating Config::Augeas Object");
$aug = Config::Augeas->new;
my $commands_to_prepend = Rex::Config->get_augeas_commands_prepend();
$aug->srun( join qq(\n), @{$commands_to_prepend} );
}

my $on_change; # Any code to run on change
Expand All @@ -107,7 +107,7 @@ This modifies the keys given in @options in $file.
$on_change = delete $config_option->{on_change}
if ref $config_option->{on_change} eq 'CODE';

if ( $is_ssh || !$has_config_augeas ) {
if ( $is_ssh || $use_augtool ) {
my @commands;
for my $key ( keys %{$config_option} ) {
Rex::Logger::debug( "modifying $key -> " . $config_option->{$key} );
Expand Down Expand Up @@ -152,7 +152,7 @@ Remove an entry.
for my $aug_key (@options) {
Rex::Logger::debug("deleting $aug_key");

if ( $is_ssh || !$has_config_augeas ) {
if ( $is_ssh || $use_augtool ) {
push @commands, "rm $aug_key\n";
}
else {
Expand All @@ -161,7 +161,7 @@ Remove an entry.
}
}

if ( $is_ssh || !$has_config_augeas ) {
if ( $is_ssh || $use_augtool ) {
my $result = _run_augtool(@commands);
$ret = $result->{return};
$changed = $result->{changed};
Expand Down Expand Up @@ -202,7 +202,7 @@ Insert an item into the file. Here, the order of the options is important. If th
pop @options;
}

if ( $is_ssh || !$has_config_augeas ) {
if ( $is_ssh || $use_augtool ) {
my $position = ( exists $opts->{"before"} ? "before" : "after" );
unless ( exists $opts->{$position} ) {
Rex::Logger::info(
Expand Down Expand Up @@ -271,9 +271,9 @@ Dump the contents of a file to STDOUT.
my $file = shift @options;
my $aug_key = $file;

if ( $is_ssh || !$has_config_augeas ) {
my @list = i_exec "augtool", "print", $aug_key;
print join( "\n", @list ) . "\n";
if ( $is_ssh || $use_augtool ) {
my $output = _run_augtool("print $aug_key");
say $output->{'return'};
}
else {
$aug->print($aug_key);
Expand All @@ -298,7 +298,7 @@ Check if an item exists.
my $aug_key = $file;
my $val = $options[0] || "";

if ( $is_ssh || !$has_config_augeas ) {
if ( $is_ssh || $use_augtool ) {
my @paths;
my $result = _run_augtool("match $aug_key");
for my $line ( split "\n", $result->{return} ) {
Expand Down Expand Up @@ -355,7 +355,7 @@ Returns the value of the given item.
elsif ( $action eq "get" ) {
my $file = shift @options;

if ( $is_ssh || !$has_config_augeas ) {
if ( $is_ssh || $use_augtool ) {
my @lines;
my $result = _run_augtool("get $file");
for my $line ( split "\n", $result->{return} ) {
Expand Down Expand Up @@ -394,8 +394,12 @@ sub _run_augtool {
unless can_run "augtool";
my $rnd_file = get_tmp_file;
my $fh = Rex::Interface::File->create;

my $commands_to_prepend = Rex::Config->get_augeas_commands_prepend();
unshift @commands, @{$commands_to_prepend};

$fh->open( ">", $rnd_file );
$fh->write($_) foreach (@commands);
$fh->write( $_ . qq(\n) ) foreach (@commands);
$fh->close;
my ( $return, $error ) = i_run "augtool --file $rnd_file --autosave",
sub { @_ }, fail_ok => 1;
Expand Down
47 changes: 46 additions & 1 deletion lib/Rex/Config.pm
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ our (
$use_template_ng, $use_rex_kvm_agent,
$autodie, $task_chaining_cmdline_args,
$waitpid_blocking_sleep_time, $write_utf8_files,
$default_auth,
$default_auth, $augeas_commands_prepend,
$local_augeas_backend,
);

# some defaults
Expand Down Expand Up @@ -1632,6 +1633,50 @@ sub get_default_auth {
return $default_auth // 1;
}

=head2 set_augeas_commands_prepend
=head2 get_augeas_commands_prepend
Sets and gets the value of the C<$augeas_commands_prepend> configuration variable.
This controls the list of commands Rex should prepend at the beginning of the command file for Augeas operations.
Default is C<[]>.
=cut

sub set_augeas_commands_prepend {
my $self = shift;
$augeas_commands_prepend = shift;
return $augeas_commands_prepend;
}

sub get_augeas_commands_prepend {
return $augeas_commands_prepend // [];
}

=head2 set_local_augeas_backend
=head2 get_local_augeas_backend
Sets and gets the value of the C<$local_augeas_backend> configuration variable.
This controls which Augeas backend to use for local operations, C<augtool> or C<Config::Augeas>.
Default is C<Config::Augeas>.
=cut

sub set_local_augeas_backend {
my $self = shift;
$local_augeas_backend = shift;
return $local_augeas_backend;
}

sub get_local_augeas_backend {
return $local_augeas_backend // 'Config::Augeas';
}

=head2 register_set_handler($handler_name, $code)
Register a handler that gets called by I<set>.
Expand Down
91 changes: 91 additions & 0 deletions t/augeas.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#!/usr/bin/env perl

use v5.12.5;
use warnings;

our $VERSION = '9999.99.99_99'; # VERSION

use Test::More;
use Test::Warnings;
use Test::Output;

use File::Temp qw(tmpnam);
use Module::Load::Conditional qw(check_install);
use Rex::Commands::Augeas;
use Rex::Commands::Run;

my $augeas_binary = 'augtool';
my $augeas_module = 'Config::Augeas';

my @augeas_backends;

if ( can_run($augeas_binary) ) {
push @augeas_backends, $augeas_binary;
}

if ( check_install( module => $augeas_module ) ) {
push @augeas_backends, $augeas_module;
}

if (@augeas_backends) {
plan tests => 1 + scalar @augeas_backends;
}
else {
plan skip_all => 'Could not find any Augeas backends';
}

my $file = tmpnam();
my $test_value = 'rex';

for my $backend (@augeas_backends) {
Rex::Config->set_local_augeas_backend($backend);

subtest "Simplelines lens with $backend" => sub {
plan tests => 7;

Rex::Config->set_augeas_commands_prepend(
[ "transform Simplelines incl $file", 'load', ] );

my $path = '/files' . $file . '/1';

is( -e $file, undef, 'test file does not exist yet' );

# modify

augeas modify => $path => $test_value;

is( -e $file, 1, 'test file created' );

# exists

my $has_first_entry = augeas exists => $path;

is( $has_first_entry, 1, 'first entry exists' );

# get

my $retrieved_value = augeas get => $path;

is( $retrieved_value, $test_value, 'test value retrieved' );

# dump

stdout_is(
sub { augeas dump => $path },
qq($path = "$test_value"\n),
'correct dump output'
);

# remove

augeas remove => $path;

my $still_has_first_entry = augeas exists => $path;

is( $still_has_first_entry, 0, 'first entry removed' );

unlink $file;

is( -e $file, undef, 'test file cleaned up' );
};
}

0 comments on commit ba36461

Please sign in to comment.