mirror of
https://github.com/duncs/clusterssh.git
synced 2025-07-02 09:31:15 +00:00
More config functionality
Load up config files and write out default config file if it doesnt exist.
This commit is contained in:
parent
b51644512d
commit
74e3913680
3 changed files with 254 additions and 3 deletions
2
Build.PL
2
Build.PL
|
@ -24,6 +24,7 @@ my $build = Module::Build->new(
|
||||||
'X11::Protocol' => '0.56',
|
'X11::Protocol' => '0.56',
|
||||||
'Locale::Maketext' => 0,
|
'Locale::Maketext' => 0,
|
||||||
'Exception::Class' => '1.31',
|
'Exception::Class' => '1.31',
|
||||||
|
'Try::Tiny' => 0,
|
||||||
},
|
},
|
||||||
build_requires => {
|
build_requires => {
|
||||||
'Test::Pod::Coverage' => 0,
|
'Test::Pod::Coverage' => 0,
|
||||||
|
@ -31,6 +32,7 @@ my $build = Module::Build->new(
|
||||||
'Test::Trap' => 0,
|
'Test::Trap' => 0,
|
||||||
'Readonly' => 0,
|
'Readonly' => 0,
|
||||||
'File::Which' => 0,
|
'File::Which' => 0,
|
||||||
|
'File::Temp' => 0,
|
||||||
},
|
},
|
||||||
add_to_cleanup => ['App-ClusterSSH-*'],
|
add_to_cleanup => ['App-ClusterSSH-*'],
|
||||||
create_makefile_pl => 'traditional',
|
create_makefile_pl => 'traditional',
|
||||||
|
|
|
@ -7,6 +7,7 @@ use version;
|
||||||
our $VERSION = version->new('0.01');
|
our $VERSION = version->new('0.01');
|
||||||
|
|
||||||
use Carp;
|
use Carp;
|
||||||
|
use Try::Tiny;
|
||||||
|
|
||||||
use base qw/ App::ClusterSSH::Base /;
|
use base qw/ App::ClusterSSH::Base /;
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@ my %default_config = (
|
||||||
|
|
||||||
extra_cluster_file => "",
|
extra_cluster_file => "",
|
||||||
|
|
||||||
unmap_on_redraw => "no",
|
unmap_on_redraw => "no", # Debian #329440
|
||||||
|
|
||||||
show_history => 0,
|
show_history => 0,
|
||||||
history_width => 40,
|
history_width => 40,
|
||||||
|
@ -167,6 +168,68 @@ sub parse_config_file {
|
||||||
$self->validate_args(%read_config);
|
$self->validate_args(%read_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub load_configs {
|
||||||
|
my ($self, @configs) = @_;
|
||||||
|
|
||||||
|
if ( -e $ENV{HOME} . '/.csshrc' ) {
|
||||||
|
warn( $self->loc('[_1] is no longer used - please see documentation and remove', $ENV{HOME} . '/.csshrc'), $/);
|
||||||
|
}
|
||||||
|
|
||||||
|
for my $config ( '/etc/csshrc', $ENV{HOME} . '/.csshrc', $ENV{HOME} . '/.clusterssh/config', ) {
|
||||||
|
$self->parse_config_file($config) if( -e $config );
|
||||||
|
}
|
||||||
|
|
||||||
|
# write out default config file if necesasry
|
||||||
|
try {
|
||||||
|
$self->write_user_config_file();
|
||||||
|
} catch {
|
||||||
|
warn $_,$/;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Attempt to load in provided config files. Also look for anything
|
||||||
|
# relative to config directory
|
||||||
|
for my $config ( @configs ) {
|
||||||
|
$self->parse_config_file($config) if( -e $config );
|
||||||
|
|
||||||
|
my $file = $ENV{HOME} . '/.clusterssh/config_'.$config;
|
||||||
|
$self->parse_config_file($file) if( -e $file );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub write_user_config_file {
|
||||||
|
my ($self) = @_;
|
||||||
|
|
||||||
|
return if ( -f "$ENV{HOME}/.clusterssh/config" );
|
||||||
|
|
||||||
|
if(! -d "$ENV{HOME}/.clusterssh" ) {
|
||||||
|
if(!mkdir("$ENV{HOME}/.clusterssh")) {
|
||||||
|
croak(
|
||||||
|
App::ClusterSSH::Exception::Config->throw(
|
||||||
|
error => $self->loc('Unable to create directory [_1]: [_2]', '$HOME/.clusterssh', $!),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( open( CONFIG, ">", "$ENV{HOME}/.clusterssh/config" ) ) {
|
||||||
|
foreach ( sort( keys(%$self) ) ) {
|
||||||
|
print CONFIG "$_=$self->{$_}\n";
|
||||||
|
}
|
||||||
|
close(CONFIG);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
croak(
|
||||||
|
App::ClusterSSH::Exception::Config->throw(
|
||||||
|
error => $self->loc('Unable to write default [_1]: [_2]', '$HOME/.clusterssh/config', $!),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
# could use File::Which for some of this but we also search a few other places
|
# could use File::Which for some of this but we also search a few other places
|
||||||
# just in case $PATH isnt set up right
|
# just in case $PATH isnt set up right
|
||||||
sub find_binary {
|
sub find_binary {
|
||||||
|
@ -263,11 +326,21 @@ Read in configuration from given filename
|
||||||
|
|
||||||
Validate and apply all configuration loaded at this point
|
Validate and apply all configuration loaded at this point
|
||||||
|
|
||||||
=item $path = $self->find_binary('<name>');
|
=item $path = $config->find_binary('<name>');
|
||||||
|
|
||||||
Locate the binary <name> and return the full path. Doesn't just search
|
Locate the binary <name> and return the full path. Doesn't just search
|
||||||
$PATH in case the environment isn't set up correctly
|
$PATH in case the environment isn't set up correctly
|
||||||
|
|
||||||
|
=item $conifig->load_configs(@extra);
|
||||||
|
|
||||||
|
Load up configuration from known locations (warn if .csshrc file found) and
|
||||||
|
load in option files as necessary.
|
||||||
|
|
||||||
|
=item $config->write_user_config_file();
|
||||||
|
|
||||||
|
Write out default $HOME/.clusterssh/config file (before option config files
|
||||||
|
are loaded).
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head1 AUTHOR
|
=head1 AUTHOR
|
||||||
|
|
178
t/15config.t
178
t/15config.t
|
@ -7,10 +7,11 @@ use lib "$Bin/../lib";
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use Test::Trap;
|
use Test::Trap;
|
||||||
use File::Which qw(which);
|
use File::Which qw(which);
|
||||||
|
use File::Temp qw(tempdir);
|
||||||
|
|
||||||
use Readonly;
|
use Readonly;
|
||||||
|
|
||||||
BEGIN { use_ok("App::ClusterSSH::Config") }
|
BEGIN { use_ok("App::ClusterSSH::Config") || BAIL_OUT('failed to use module')}
|
||||||
|
|
||||||
my $config;
|
my $config;
|
||||||
|
|
||||||
|
@ -219,4 +220,179 @@ is( $trap->stderr, q{}, 'Expecting no STDERR' );
|
||||||
is_deeply( $config, \%expected, 'amended config is correct' );
|
is_deeply( $config, \%expected, 'amended config is correct' );
|
||||||
is($path, which('ls'), 'Found correct path to "ls"');
|
is($path, which('ls'), 'Found correct path to "ls"');
|
||||||
|
|
||||||
|
note('Checks on loading configs');
|
||||||
|
note('empty dir');
|
||||||
|
$ENV{HOME} = tempdir( CLEANUP => 1 );
|
||||||
|
$config = App::ClusterSSH::Config->new();
|
||||||
|
trap {
|
||||||
|
$config->load_configs();
|
||||||
|
};
|
||||||
|
is( $trap->leaveby, 'return', 'returned ok' );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
is( $trap->die, undef, 'die message correct' );
|
||||||
|
is( $trap->stdout, q{}, 'Expecting no STDOUT' );
|
||||||
|
is( $trap->stderr, q{}, 'Expecting no STDERR' );
|
||||||
|
#note(qx/ls -laR $ENV{HOME}/);
|
||||||
|
ok( -d $ENV{HOME}.'/.clusterssh', '.clusterssh dir exists');
|
||||||
|
ok( -f $ENV{HOME}.'/.clusterssh/config', '.clusterssh config file exists');
|
||||||
|
is_deeply( $config, \%expected, 'amended config is correct' );
|
||||||
|
$ENV{HOME} = undef;
|
||||||
|
|
||||||
|
note('.csshrc warning');
|
||||||
|
$ENV{HOME} = tempdir( CLEANUP => 1 );
|
||||||
|
open(my $csshrc, '>', $ENV{HOME}.'/.csshrc');
|
||||||
|
print $csshrc 'auto_quit = no', $/;
|
||||||
|
close($csshrc);
|
||||||
|
$expected{auto_quit}='no';
|
||||||
|
$config = App::ClusterSSH::Config->new();
|
||||||
|
trap {
|
||||||
|
$config->load_configs();
|
||||||
|
};
|
||||||
|
is( $trap->leaveby, 'return', 'returned ok' );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
is( $trap->die, undef, 'die message correct' );
|
||||||
|
is( $trap->stdout, q{}, 'Expecting no STDOUT' );
|
||||||
|
is( $trap->stderr, $ENV{HOME}.'/.csshrc is no longer used - please see documentation and remove'.$/, 'Got correct STDERR output for .csshrc' );
|
||||||
|
ok( -d $ENV{HOME}.'/.clusterssh', '.clusterssh dir exists');
|
||||||
|
ok( -f $ENV{HOME}.'/.clusterssh/config', '.clusterssh config file exists');
|
||||||
|
is_deeply( $config, \%expected, 'amended config is correct' );
|
||||||
|
|
||||||
|
note('.csshrc warning and .clusterssh dir plus config');
|
||||||
|
open($csshrc, '>', $ENV{HOME}.'/.clusterssh/config');
|
||||||
|
print $csshrc 'window_tiling = no', $/;
|
||||||
|
close($csshrc);
|
||||||
|
$expected{window_tiling}='no';
|
||||||
|
$config = App::ClusterSSH::Config->new();
|
||||||
|
trap {
|
||||||
|
$config->load_configs();
|
||||||
|
};
|
||||||
|
is( $trap->leaveby, 'return', 'returned ok' );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
is( $trap->die, undef, 'die message correct' );
|
||||||
|
is( $trap->stdout, q{}, 'Expecting no STDOUT' );
|
||||||
|
is( $trap->stderr, $ENV{HOME}.'/.csshrc is no longer used - please see documentation and remove'.$/, 'Got correct STDERR output for .csshrc' );
|
||||||
|
ok( -d $ENV{HOME}.'/.clusterssh', '.clusterssh dir exists');
|
||||||
|
ok( -f $ENV{HOME}.'/.clusterssh/config', '.clusterssh config file exists');
|
||||||
|
is_deeply( $config, \%expected, 'amended config is correct' );
|
||||||
|
|
||||||
|
note('no .csshrc warning and .clusterssh dir');
|
||||||
|
unlink($ENV{HOME}.'/.csshrc');
|
||||||
|
$expected{auto_quit}='yes';
|
||||||
|
$config = App::ClusterSSH::Config->new();
|
||||||
|
trap {
|
||||||
|
$config->load_configs();
|
||||||
|
};
|
||||||
|
is( $trap->leaveby, 'return', 'returned ok' );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
is( $trap->die, undef, 'die message correct' );
|
||||||
|
is( $trap->stdout, q{}, 'Expecting no STDOUT' );
|
||||||
|
is( $trap->stderr, '', 'Expecting no STDERR' );
|
||||||
|
ok( -d $ENV{HOME}.'/.clusterssh', '.clusterssh dir exists');
|
||||||
|
ok( -f $ENV{HOME}.'/.clusterssh/config', '.clusterssh config file exists');
|
||||||
|
is_deeply( $config, \%expected, 'amended config is correct' );
|
||||||
|
|
||||||
|
note('no .csshrc warning, .clusterssh dir plus config + extra config');
|
||||||
|
open($csshrc, '>', $ENV{HOME}.'/clusterssh.config');
|
||||||
|
print $csshrc 'terminal = something', $/;
|
||||||
|
close($csshrc);
|
||||||
|
$expected{terminal}='something';
|
||||||
|
$config = App::ClusterSSH::Config->new();
|
||||||
|
trap {
|
||||||
|
$config->load_configs($ENV{HOME}.'/clusterssh.config');
|
||||||
|
};
|
||||||
|
is( $trap->leaveby, 'return', 'returned ok' );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
is( $trap->die, undef, 'die message correct' );
|
||||||
|
is( $trap->stdout, q{}, 'Expecting no STDOUT' );
|
||||||
|
is( $trap->stderr, '', 'Expecting no STDERR' );
|
||||||
|
ok( -d $ENV{HOME}.'/.clusterssh', '.clusterssh dir exists');
|
||||||
|
ok( -f $ENV{HOME}.'/.clusterssh/config', '.clusterssh config file exists');
|
||||||
|
is_deeply( $config, \%expected, 'amended config is correct' );
|
||||||
|
|
||||||
|
note('no .csshrc warning, .clusterssh dir plus config + more extra configs');
|
||||||
|
open($csshrc, '>', $ENV{HOME}.'/.clusterssh/config_ABC');
|
||||||
|
print $csshrc 'ssh_args = something', $/;
|
||||||
|
close($csshrc);
|
||||||
|
$expected{ssh_args}='something';
|
||||||
|
$config = App::ClusterSSH::Config->new();
|
||||||
|
trap {
|
||||||
|
$config->load_configs($ENV{HOME}.'/clusterssh.config', 'ABC');
|
||||||
|
};
|
||||||
|
is( $trap->leaveby, 'return', 'returned ok' );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
is( $trap->die, undef, 'die message correct' );
|
||||||
|
is( $trap->stdout, q{}, 'Expecting no STDOUT' );
|
||||||
|
is( $trap->stderr, '', 'Expecting no STDERR' );
|
||||||
|
ok( -d $ENV{HOME}.'/.clusterssh', '.clusterssh dir exists');
|
||||||
|
ok( -f $ENV{HOME}.'/.clusterssh/config', '.clusterssh config file exists');
|
||||||
|
is_deeply( $config, \%expected, 'amended config is correct' );
|
||||||
|
|
||||||
|
note('check .clusterssh file is an error');
|
||||||
|
$ENV{HOME} = tempdir( CLEANUP => 1 );
|
||||||
|
open($csshrc, '>', $ENV{HOME}.'/.clusterssh');
|
||||||
|
print $csshrc 'should_be_dir_not_file = PROBLEM', $/;
|
||||||
|
close($csshrc);
|
||||||
|
$config = App::ClusterSSH::Config->new();
|
||||||
|
trap {
|
||||||
|
$config->write_user_config_file();
|
||||||
|
};
|
||||||
|
is( $trap->leaveby, 'die', 'died ok' );
|
||||||
|
isa_ok( $trap->die, 'App::ClusterSSH::Exception::Config' );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
is( $trap->die, 'Unable to create directory $HOME/.clusterssh: File exists', 'die message correct' );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
is( $trap->stdout, q{}, 'Expecting no STDOUT' );
|
||||||
|
is( $trap->stderr, q{}, 'Expecting no STDERR' );
|
||||||
|
|
||||||
|
note('check failure to write default config is caught');
|
||||||
|
$ENV{HOME} = tempdir( CLEANUP => 1 );
|
||||||
|
mkdir($ENV{HOME}.'/.clusterssh');
|
||||||
|
mkdir($ENV{HOME}.'/.clusterssh/config');
|
||||||
|
$config = App::ClusterSSH::Config->new();
|
||||||
|
trap {
|
||||||
|
$config->write_user_config_file();
|
||||||
|
};
|
||||||
|
is( $trap->leaveby, 'die', 'died ok' );
|
||||||
|
isa_ok( $trap->die, 'App::ClusterSSH::Exception::Config' );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
is( $trap->die, 'Unable to write default $HOME/.clusterssh/config: Is a directory', 'die message correct' );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
is( $trap->stdout, q{}, 'Expecting no STDOUT' );
|
||||||
|
is( $trap->stderr, q{}, 'Expecting no STDERR' );
|
||||||
|
|
||||||
|
note('check .clusterssh errors via load_configs are not fatal');
|
||||||
|
$ENV{HOME} = tempdir( CLEANUP => 1 );
|
||||||
|
open($csshrc, '>', $ENV{HOME}.'/.clusterssh');
|
||||||
|
print $csshrc 'should_be_dir_not_file = PROBLEM', $/;
|
||||||
|
close($csshrc);
|
||||||
|
$config = App::ClusterSSH::Config->new();
|
||||||
|
trap {
|
||||||
|
$config->load_configs();
|
||||||
|
};
|
||||||
|
is( $trap->leaveby, 'return', 'died ok' );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
is( $trap->stdout, q{}, 'Expecting no STDOUT' );
|
||||||
|
is( $trap->stderr, q{Unable to create directory $HOME/.clusterssh: File exists}.$/, 'Expecting no STDERR' );
|
||||||
|
|
||||||
|
note('check failure to write default config is caught');
|
||||||
|
$ENV{HOME} = tempdir( CLEANUP => 1 );
|
||||||
|
mkdir($ENV{HOME}.'/.clusterssh');
|
||||||
|
mkdir($ENV{HOME}.'/.clusterssh/config');
|
||||||
|
$config = App::ClusterSSH::Config->new();
|
||||||
|
trap {
|
||||||
|
$config->load_configs();
|
||||||
|
};
|
||||||
|
is( $trap->leaveby, 'return', 'died ok' );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
isa_ok( $config, "App::ClusterSSH::Config" );
|
||||||
|
is( $trap->stdout, q{}, 'Expecting no STDOUT' );
|
||||||
|
is( $trap->stderr, q{Unable to write default $HOME/.clusterssh/config: Is a directory}.$/, 'Expecting no STDERR' );
|
||||||
|
|
||||||
done_testing();
|
done_testing();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue