2011-07-08 13:00:29 +01:00
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
|
2018-11-24 23:37:51 +00:00
|
|
|
package App::ClusterSSH::Config;
|
|
|
|
|
|
|
|
# ABSTRACT: ClusterSSH::Config - Object representing application configuration
|
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
|
|
|
|
Object representing application configuration
|
|
|
|
|
|
|
|
=cut
|
2011-07-08 13:00:29 +01:00
|
|
|
|
|
|
|
use Carp;
|
2011-07-25 18:23:07 +01:00
|
|
|
use Try::Tiny;
|
2011-07-08 13:00:29 +01:00
|
|
|
|
2011-08-31 21:01:12 +01:00
|
|
|
use FindBin qw($Script);
|
2013-02-13 22:10:30 +00:00
|
|
|
use File::Copy;
|
2011-08-31 21:01:12 +01:00
|
|
|
|
2011-07-08 13:00:29 +01:00
|
|
|
use base qw/ App::ClusterSSH::Base /;
|
2011-11-21 22:03:54 +00:00
|
|
|
use App::ClusterSSH::Cluster;
|
2011-07-08 13:00:29 +01:00
|
|
|
|
2011-11-21 22:03:54 +00:00
|
|
|
my $clusters;
|
2011-11-23 21:33:50 +00:00
|
|
|
my %old_clusters;
|
2014-06-20 15:16:41 +01:00
|
|
|
my @app_specific = (qw/ command title comms method parent /);
|
2013-03-08 07:58:39 +00:00
|
|
|
|
|
|
|
# list of config items to not write out when writing the default config
|
|
|
|
my @ignore_default_config = (qw/ user /);
|
|
|
|
|
2013-04-15 21:56:19 +01:00
|
|
|
my %default_config = (
|
2011-07-08 13:00:29 +01:00
|
|
|
terminal => "xterm",
|
|
|
|
terminal_args => "",
|
|
|
|
terminal_title_opt => "-T",
|
|
|
|
terminal_colorize => 1,
|
|
|
|
terminal_bg_style => 'dark',
|
|
|
|
terminal_allow_send_events => "-xrm '*.VT100.allowSendEvents:true'",
|
|
|
|
terminal_font => "6x13",
|
|
|
|
terminal_size => "80x24",
|
|
|
|
|
|
|
|
use_hotkeys => "yes",
|
2015-11-26 08:53:51 +00:00
|
|
|
key_quit => "Alt-q",
|
2011-07-08 13:00:29 +01:00
|
|
|
key_addhost => "Control-Shift-plus",
|
|
|
|
key_clientname => "Alt-n",
|
|
|
|
key_history => "Alt-h",
|
2013-04-21 22:13:54 +01:00
|
|
|
key_localname => "Alt-l",
|
2011-07-08 13:00:29 +01:00
|
|
|
key_retilehosts => "Alt-r",
|
2014-01-13 18:44:12 +00:00
|
|
|
key_macros_enable => "Alt-p",
|
2011-07-08 13:00:29 +01:00
|
|
|
key_paste => "Control-v",
|
2013-04-21 22:05:17 +01:00
|
|
|
key_username => "Alt-u",
|
2019-03-28 22:52:03 +00:00
|
|
|
key_user_1 => "Alt-1",
|
|
|
|
key_user_2 => "Alt-2",
|
|
|
|
key_user_3 => "Alt-3",
|
|
|
|
key_user_4 => "Alt-4",
|
2011-07-08 13:00:29 +01:00
|
|
|
mouse_paste => "Button-2",
|
|
|
|
auto_quit => "yes",
|
2011-11-23 21:33:50 +00:00
|
|
|
auto_close => 5,
|
2015-03-19 18:57:20 +01:00
|
|
|
use_natural_sort => 0,
|
2011-07-08 13:00:29 +01:00
|
|
|
window_tiling => "yes",
|
|
|
|
window_tiling_direction => "right",
|
|
|
|
console_position => "",
|
|
|
|
|
|
|
|
screen_reserve_top => 0,
|
|
|
|
screen_reserve_bottom => 60,
|
|
|
|
screen_reserve_left => 0,
|
|
|
|
screen_reserve_right => 0,
|
|
|
|
|
|
|
|
terminal_reserve_top => 5,
|
|
|
|
terminal_reserve_bottom => 0,
|
|
|
|
terminal_reserve_left => 5,
|
|
|
|
terminal_reserve_right => 0,
|
|
|
|
|
|
|
|
terminal_decoration_height => 10,
|
|
|
|
terminal_decoration_width => 8,
|
|
|
|
|
2013-02-26 20:10:01 +00:00
|
|
|
console => 'console',
|
|
|
|
console_args => '',
|
|
|
|
rsh => 'rsh',
|
|
|
|
rsh_args => "",
|
|
|
|
telnet => 'telnet',
|
|
|
|
telnet_args => "",
|
|
|
|
ssh => 'ssh',
|
|
|
|
ssh_args => "",
|
2015-11-15 22:17:29 +00:00
|
|
|
sftp => 'sftp',
|
|
|
|
sftp_args => "",
|
2011-07-08 13:00:29 +01:00
|
|
|
|
2016-01-23 17:02:52 +00:00
|
|
|
extra_tag_file => '',
|
2013-04-15 21:56:19 +01:00
|
|
|
extra_cluster_file => '',
|
2013-03-25 13:13:03 +00:00
|
|
|
external_cluster_command => '',
|
2017-12-22 11:36:09 +00:00
|
|
|
external_command_mode => '0600',
|
|
|
|
external_command_pipe => '',
|
2011-07-08 13:00:29 +01:00
|
|
|
|
2011-07-25 18:23:07 +01:00
|
|
|
unmap_on_redraw => "no", # Debian #329440
|
2011-07-08 13:00:29 +01:00
|
|
|
|
|
|
|
show_history => 0,
|
|
|
|
history_width => 40,
|
|
|
|
history_height => 10,
|
|
|
|
|
|
|
|
command => q{},
|
2020-04-18 17:05:00 +01:00
|
|
|
command_pre => q{},
|
|
|
|
command_post => q{},
|
2016-09-07 09:25:44 +01:00
|
|
|
hide_menu => 0,
|
2011-07-08 13:00:29 +01:00
|
|
|
max_host_menu_items => 30,
|
|
|
|
|
2014-01-13 18:44:12 +00:00
|
|
|
macros_enabled => 'yes',
|
|
|
|
macro_servername => '%s',
|
|
|
|
macro_hostname => '%h',
|
|
|
|
macro_username => '%u',
|
|
|
|
macro_newline => '%n',
|
|
|
|
macro_version => '%v',
|
2019-03-28 22:52:03 +00:00
|
|
|
macro_user_1 => '%1',
|
|
|
|
macro_user_2 => '%2',
|
|
|
|
macro_user_3 => '%3',
|
|
|
|
macro_user_4 => '%4',
|
|
|
|
|
|
|
|
macro_user_1_command => '',
|
|
|
|
macro_user_2_command => '',
|
|
|
|
macro_user_3_command => '',
|
|
|
|
macro_user_4_command => '',
|
2014-01-13 18:44:12 +00:00
|
|
|
|
2011-07-08 13:00:29 +01:00
|
|
|
max_addhost_menu_cluster_items => 6,
|
|
|
|
menu_send_autotearoff => 0,
|
|
|
|
menu_host_autotearoff => 0,
|
|
|
|
|
2016-10-18 21:23:15 +01:00
|
|
|
unique_servers => 0,
|
2011-11-18 22:31:12 +00:00
|
|
|
use_all_a_records => 0,
|
|
|
|
|
2015-09-26 09:25:52 -07:00
|
|
|
send_menu_xml_file => $ENV{HOME} . '/.clusterssh/send_menu',
|
2013-02-13 17:50:26 +00:00
|
|
|
|
2017-03-07 22:01:27 +00:00
|
|
|
auto_wm_decoration_offsets => "no", # Debian #842965
|
|
|
|
|
2013-03-08 07:58:39 +00:00
|
|
|
# don't set username here as takes precendence over ssh config
|
2013-04-15 21:56:19 +01:00
|
|
|
user => '',
|
2017-04-29 17:08:22 +02:00
|
|
|
rows => -1,
|
|
|
|
cols => -1,
|
2017-05-01 17:24:04 +02:00
|
|
|
|
|
|
|
fillscreen => "no",
|
|
|
|
|
2011-07-08 13:00:29 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
sub new {
|
|
|
|
my ( $class, %args ) = @_;
|
|
|
|
|
|
|
|
my $self = $class->SUPER::new(%default_config);
|
|
|
|
|
2011-08-31 21:01:12 +01:00
|
|
|
( my $comms = $Script ) =~ s/^c//;
|
2012-11-26 21:41:05 +00:00
|
|
|
|
|
|
|
$comms = 'telnet' if ( $comms eq 'tel' );
|
|
|
|
$comms = 'console' if ( $comms eq 'con' );
|
2013-02-14 21:16:49 +00:00
|
|
|
$comms = 'ssh' if ( $comms eq 'lusterssh' );
|
2015-11-15 22:17:29 +00:00
|
|
|
$comms = 'sftp' if ( $comms eq 'sftp' );
|
2011-08-31 21:01:12 +01:00
|
|
|
|
|
|
|
# list of allowed comms methods
|
2015-11-15 22:17:29 +00:00
|
|
|
if ( 'ssh rsh telnet sftp console' !~ m/\b$comms\b/ ) {
|
2011-08-31 21:01:12 +01:00
|
|
|
$self->{comms} = 'ssh';
|
|
|
|
}
|
2012-11-26 21:41:05 +00:00
|
|
|
else {
|
|
|
|
$self->{comms} = $comms;
|
|
|
|
}
|
2011-08-31 21:01:12 +01:00
|
|
|
|
|
|
|
$self->{title} = uc($Script);
|
|
|
|
|
2011-11-23 21:33:50 +00:00
|
|
|
$clusters = App::ClusterSSH::Cluster->new();
|
2011-11-21 22:03:54 +00:00
|
|
|
|
2011-07-08 14:30:03 +01:00
|
|
|
return $self->validate_args(%args);
|
2011-07-08 13:00:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sub validate_args {
|
|
|
|
my ( $self, %args ) = @_;
|
|
|
|
|
|
|
|
my @unknown_config = ();
|
|
|
|
|
|
|
|
foreach my $config ( sort( keys(%args) ) ) {
|
2011-08-31 21:01:12 +01:00
|
|
|
if ( grep /$config/, @app_specific ) {
|
|
|
|
|
|
|
|
# $self->{$config} ||= 'unknown';
|
2011-07-28 10:23:49 +01:00
|
|
|
next;
|
|
|
|
}
|
2011-07-11 22:07:57 +01:00
|
|
|
|
2011-07-08 14:30:03 +01:00
|
|
|
if ( exists $self->{$config} ) {
|
|
|
|
$self->{$config} = $args{$config};
|
2011-07-08 13:00:29 +01:00
|
|
|
}
|
|
|
|
else {
|
2011-07-08 14:30:03 +01:00
|
|
|
push( @unknown_config, $config );
|
2011-07-08 13:00:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-08 14:30:03 +01:00
|
|
|
if (@unknown_config) {
|
|
|
|
croak(
|
|
|
|
App::ClusterSSH::Exception::Config->throw(
|
|
|
|
unknown_config => \@unknown_config,
|
|
|
|
error => $self->loc(
|
2013-02-13 22:10:30 +00:00
|
|
|
'Unknown configuration parameters: [_1]' . $/,
|
2011-07-08 14:30:03 +01:00
|
|
|
join( ',', @unknown_config )
|
|
|
|
)
|
|
|
|
)
|
|
|
|
);
|
2011-07-08 13:00:29 +01:00
|
|
|
}
|
|
|
|
|
2013-02-13 22:10:30 +00:00
|
|
|
if ( !$self->{comms} ) {
|
2013-02-13 21:41:30 +00:00
|
|
|
croak(
|
|
|
|
App::ClusterSSH::Exception::Config->throw(
|
2013-02-13 22:10:30 +00:00
|
|
|
error => $self->loc( 'Invalid variable: comms' . $/ ),
|
2013-02-13 21:41:30 +00:00
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !$self->{ $self->{comms} } ) {
|
|
|
|
croak(
|
|
|
|
App::ClusterSSH::Exception::Config->throw(
|
2013-02-13 22:10:30 +00:00
|
|
|
error => $self->loc(
|
|
|
|
'Invalid variable: [_1]' . $/,
|
|
|
|
$self->{comms}
|
|
|
|
),
|
2013-02-13 21:41:30 +00:00
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
2013-02-13 22:10:30 +00:00
|
|
|
|
2014-12-12 17:18:19 +00:00
|
|
|
# check the terminal has been found correctly
|
2015-12-03 21:58:32 +00:00
|
|
|
# looking for the terminal should not be fatal
|
2014-12-12 17:18:19 +00:00
|
|
|
if ( !-e $self->{terminal} ) {
|
2016-01-23 17:02:52 +00:00
|
|
|
eval { $self->{terminal} = $self->find_binary( $self->{terminal} ); };
|
|
|
|
if ($@) {
|
2015-12-03 21:58:32 +00:00
|
|
|
warn $@->message;
|
|
|
|
}
|
2014-12-12 17:18:19 +00:00
|
|
|
}
|
2013-02-13 21:41:30 +00:00
|
|
|
|
2011-07-08 13:00:29 +01:00
|
|
|
return $self;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub parse_config_file {
|
|
|
|
my ( $self, $config_file ) = @_;
|
|
|
|
|
2011-07-08 14:30:03 +01:00
|
|
|
$self->debug( 2, 'Loading in config file: ', $config_file );
|
2011-07-08 13:00:29 +01:00
|
|
|
|
2013-04-15 21:56:19 +01:00
|
|
|
# if ( !-e $config_file || !-r $config_file ) {
|
|
|
|
# croak(
|
|
|
|
# App::ClusterSSH::Exception::Config->throw(
|
|
|
|
# error => $self->loc(
|
|
|
|
# 'File [_1] does not exist or cannot be read' . $/,
|
|
|
|
# $config_file
|
|
|
|
# ),
|
|
|
|
# ),
|
|
|
|
# );
|
|
|
|
# }
|
|
|
|
#
|
|
|
|
# open( CFG, $config_file ) or die("Couldnt open $config_file: $!");
|
|
|
|
# my $l;
|
|
|
|
# my %read_config;
|
|
|
|
# while ( defined( $l = <CFG> ) ) {
|
|
|
|
# next
|
|
|
|
# if ( $l =~ /^\s*$/ || $l =~ /^#/ )
|
|
|
|
# ; # ignore blank lines & commented lines
|
|
|
|
# $l =~ s/#.*//; # remove comments from remaining lines
|
|
|
|
# $l =~ s/\s*$//; # remove trailing whitespace
|
|
|
|
#
|
|
|
|
# # look for continuation lines
|
|
|
|
# chomp $l;
|
|
|
|
# if ( $l =~ s/\\\s*$// ) {
|
|
|
|
# $l .= <CFG>;
|
|
|
|
# redo unless eof(CFG);
|
|
|
|
# }
|
|
|
|
#
|
|
|
|
# next unless $l =~ m/\s*(\S+)\s*=\s*(.*)\s*/;
|
|
|
|
# my ( $key, $value ) = ( $1, $2 );
|
|
|
|
# if ( defined $key && defined $value ) {
|
|
|
|
# $read_config{$key} = $value;
|
|
|
|
# $self->debug( 3, "$key=$value" );
|
|
|
|
# }
|
|
|
|
# }
|
|
|
|
# close(CFG);
|
2011-07-08 14:30:03 +01:00
|
|
|
|
|
|
|
my %read_config;
|
2013-04-15 21:56:19 +01:00
|
|
|
%read_config
|
|
|
|
= $self->load_file( type => 'config', filename => $config_file );
|
2011-07-08 14:30:03 +01:00
|
|
|
|
2013-02-13 21:41:30 +00:00
|
|
|
# grab any clusters from the config before validating it
|
2011-07-11 22:07:57 +01:00
|
|
|
if ( $read_config{clusters} ) {
|
|
|
|
$self->debug( 3, "Picked up clusters defined in $config_file" );
|
|
|
|
foreach my $cluster ( sort split / /, $read_config{clusters} ) {
|
2011-11-23 21:33:50 +00:00
|
|
|
if ( $read_config{$cluster} ) {
|
2013-03-08 07:58:39 +00:00
|
|
|
$clusters->register_tag( $cluster,
|
|
|
|
split( / /, $read_config{$cluster} ) );
|
2011-11-25 22:09:33 +00:00
|
|
|
$old_clusters{$cluster} = $read_config{$cluster};
|
2011-11-23 21:33:50 +00:00
|
|
|
delete( $read_config{$cluster} );
|
2011-11-21 22:03:54 +00:00
|
|
|
}
|
2011-07-11 22:07:57 +01:00
|
|
|
}
|
|
|
|
delete( $read_config{clusters} );
|
|
|
|
}
|
|
|
|
|
2011-07-08 14:30:03 +01:00
|
|
|
# tidy up entries, just in case
|
2011-07-11 22:07:57 +01:00
|
|
|
$read_config{terminal_font} =~ s/['"]//g
|
|
|
|
if ( $read_config{terminal_font} );
|
2011-07-08 14:30:03 +01:00
|
|
|
|
|
|
|
$self->validate_args(%read_config);
|
2019-03-28 22:52:03 +00:00
|
|
|
|
|
|
|
# Look at the user macros and if not set remove the hotkey for them
|
|
|
|
for my $i (qw/ 1 2 3 4 /) {
|
|
|
|
if ( ! $self->{"macro_user_${i}_command"} ) {
|
|
|
|
delete $self->{"key_user_${i}"};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $self;
|
2011-07-08 13:00:29 +01:00
|
|
|
}
|
|
|
|
|
2011-07-25 18:23:07 +01:00
|
|
|
sub load_configs {
|
2011-08-31 21:01:12 +01:00
|
|
|
my ( $self, @configs ) = @_;
|
2011-07-25 18:23:07 +01:00
|
|
|
|
2011-08-31 21:01:12 +01:00
|
|
|
for my $config (
|
|
|
|
'/etc/csshrc',
|
|
|
|
$ENV{HOME} . '/.csshrc',
|
|
|
|
$ENV{HOME} . '/.clusterssh/config',
|
|
|
|
)
|
|
|
|
{
|
2023-01-04 21:23:35 -08:00
|
|
|
$self->parse_config_file($config) if ( -e $config && ! -d _ );
|
2011-07-25 18:23:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# write out default config file if necesasry
|
|
|
|
try {
|
|
|
|
$self->write_user_config_file();
|
2011-08-31 21:01:12 +01:00
|
|
|
}
|
|
|
|
catch {
|
|
|
|
warn $_, $/;
|
2011-07-25 18:23:07 +01:00
|
|
|
};
|
|
|
|
|
2011-08-31 21:01:12 +01:00
|
|
|
# Attempt to load in provided config files. Also look for anything
|
2011-07-25 18:23:07 +01:00
|
|
|
# relative to config directory
|
2011-08-31 21:01:12 +01:00
|
|
|
for my $config (@configs) {
|
|
|
|
next unless ($config); # can be null when passed from Getopt::Long
|
2023-01-04 21:23:35 -08:00
|
|
|
$self->parse_config_file($config) if ( -e $config && ! -d _ );
|
2011-07-25 18:23:07 +01:00
|
|
|
|
2011-08-31 21:01:12 +01:00
|
|
|
my $file = $ENV{HOME} . '/.clusterssh/config_' . $config;
|
2023-01-04 21:23:35 -08:00
|
|
|
$self->parse_config_file($file) if ( -e $file && ! -d _ );
|
2011-07-25 18:23:07 +01:00
|
|
|
}
|
|
|
|
|
2021-04-01 10:25:58 +02:00
|
|
|
# Override confuration via environment variable using cssh_ prefix
|
|
|
|
# eg: terminal_size => cssh_terminal_size
|
|
|
|
foreach my $config_key ( sort( keys(%default_config) ) ) {
|
|
|
|
my $env_config_key = "cssh_".$config_key;
|
|
|
|
if ( exists $ENV{uc($env_config_key)} ) {
|
|
|
|
$env_config_key = uc($env_config_key);
|
|
|
|
}
|
|
|
|
if ( exists $ENV{$env_config_key} ) {
|
|
|
|
$self->{$config_key} = $ENV{$env_config_key};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-25 18:23:07 +01:00
|
|
|
return $self;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub write_user_config_file {
|
|
|
|
my ($self) = @_;
|
|
|
|
|
2013-02-13 22:10:30 +00:00
|
|
|
# attempt to move the old config file to one side
|
|
|
|
if ( -f "$ENV{HOME}/.csshrc" ) {
|
|
|
|
eval { move( "$ENV{HOME}/.csshrc", "$ENV{HOME}/.csshrc.DISABLED" ) };
|
|
|
|
|
|
|
|
if ($@) {
|
|
|
|
croak(
|
|
|
|
App::ClusterSSH::Exception::Config->throw(
|
|
|
|
error => $self->loc(
|
|
|
|
'Unable to move [_1] to [_2]: [_3]' . $/,
|
|
|
|
'$HOME/.csshrc', '$HOME/.csshrc.DISABLED', $@
|
|
|
|
),
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
warn(
|
|
|
|
$self->loc(
|
|
|
|
'Moved [_1] to [_2]' . $/, '$HOME/.csshrc',
|
|
|
|
'$HOME/.csshrc.DISABLED'
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-25 18:23:07 +01:00
|
|
|
return if ( -f "$ENV{HOME}/.clusterssh/config" );
|
|
|
|
|
2011-08-31 21:01:12 +01:00
|
|
|
if ( !-d "$ENV{HOME}/.clusterssh" ) {
|
|
|
|
if ( !mkdir("$ENV{HOME}/.clusterssh") ) {
|
|
|
|
croak(
|
|
|
|
App::ClusterSSH::Exception::Config->throw(
|
|
|
|
error => $self->loc(
|
2013-02-13 22:10:30 +00:00
|
|
|
'Unable to create directory [_1]: [_2]' . $/,
|
2011-08-31 21:01:12 +01:00
|
|
|
'$HOME/.clusterssh', $!
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
2011-07-25 18:23:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-14 21:23:49 +00:00
|
|
|
# Debian #673507 - migrate clusters prior to writing ~/.clusterssh/config
|
|
|
|
# in order to update the extra_cluster_file property
|
|
|
|
if (%old_clusters) {
|
|
|
|
if ( open( my $fh, ">", "$ENV{HOME}/.clusterssh/clusters" ) ) {
|
|
|
|
print $fh '# '
|
|
|
|
. $self->loc('Tag definitions moved from old .csshrc file'),
|
|
|
|
$/;
|
|
|
|
foreach ( sort( keys(%old_clusters) ) ) {
|
|
|
|
print $fh $_, ' ', join( ' ', $old_clusters{$_} ), $/;
|
|
|
|
}
|
|
|
|
close($fh);
|
2013-03-08 07:58:39 +00:00
|
|
|
}
|
|
|
|
else {
|
2013-02-14 21:23:49 +00:00
|
|
|
croak(
|
|
|
|
App::ClusterSSH::Exception::Config->throw(
|
|
|
|
error => $self->loc(
|
|
|
|
'Unable to write [_1]: [_2]' . $/,
|
2013-03-08 07:58:39 +00:00
|
|
|
'$HOME/.clusterssh/clusters',
|
|
|
|
$!
|
2013-02-14 21:23:49 +00:00
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-25 18:23:07 +01:00
|
|
|
if ( open( CONFIG, ">", "$ENV{HOME}/.clusterssh/config" ) ) {
|
|
|
|
foreach ( sort( keys(%$self) ) ) {
|
2013-04-15 21:56:19 +01:00
|
|
|
my $comment = '';
|
2013-03-08 07:58:39 +00:00
|
|
|
if ( grep /$_/, @ignore_default_config ) {
|
2013-04-15 21:56:19 +01:00
|
|
|
$comment = '#';
|
2013-03-08 07:58:39 +00:00
|
|
|
}
|
2013-04-15 21:56:19 +01:00
|
|
|
print CONFIG ${comment}, $_, '=', $self->{$_}, $/;
|
2011-07-25 18:23:07 +01:00
|
|
|
}
|
|
|
|
close(CONFIG);
|
2013-02-13 22:10:30 +00:00
|
|
|
warn(
|
|
|
|
$self->loc(
|
|
|
|
'Created new configuration file within [_1]' . $/,
|
|
|
|
'$HOME/.clusterssh/'
|
|
|
|
)
|
|
|
|
);
|
2011-07-25 18:23:07 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
croak(
|
|
|
|
App::ClusterSSH::Exception::Config->throw(
|
2011-08-31 21:01:12 +01:00
|
|
|
error => $self->loc(
|
2013-02-13 22:10:30 +00:00
|
|
|
'Unable to write default [_1]: [_2]' . $/,
|
|
|
|
'$HOME/.clusterssh/config', $!
|
2011-08-31 21:01:12 +01:00
|
|
|
),
|
2011-07-25 18:23:07 +01:00
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
2011-11-23 21:33:50 +00:00
|
|
|
|
2011-07-25 18:23:07 +01:00
|
|
|
return $self;
|
|
|
|
}
|
|
|
|
|
2014-12-12 17:18:19 +00:00
|
|
|
# search given directories for the given file
|
|
|
|
sub search_dirs {
|
|
|
|
my ( $self, $file, @directories ) = @_;
|
|
|
|
|
|
|
|
my $path;
|
|
|
|
|
|
|
|
foreach my $dir (@directories) {
|
|
|
|
$self->debug( 3, "Looking for $file in $dir" );
|
|
|
|
|
|
|
|
if ( -f $dir . '/' . $file && -x $dir . '/' . $file ) {
|
|
|
|
$path = $dir . '/' . $file;
|
|
|
|
$self->debug( 2, "Found at $path" );
|
|
|
|
last;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $path;
|
|
|
|
}
|
|
|
|
|
2011-07-21 08:23:49 +01:00
|
|
|
# could use File::Which for some of this but we also search a few other places
|
|
|
|
# just in case $PATH isnt set up right
|
|
|
|
sub find_binary {
|
|
|
|
my ( $self, $binary ) = @_;
|
|
|
|
|
|
|
|
if ( !$binary ) {
|
|
|
|
croak(
|
|
|
|
App::ClusterSSH::Exception::Config->throw(
|
2013-02-13 22:10:30 +00:00
|
|
|
error => $self->loc('argument not provided') . $/,
|
2011-07-21 08:23:49 +01:00
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
$self->debug( 2, "Looking for $binary" );
|
2011-11-25 22:09:33 +00:00
|
|
|
|
|
|
|
# if not found, strip the path and look again
|
|
|
|
if ( $binary =~ m!^/! ) {
|
|
|
|
if ( -f $binary ) {
|
2014-12-12 17:18:19 +00:00
|
|
|
$self->debug( 2, "Already have full path to in $binary" );
|
2011-11-25 22:09:33 +00:00
|
|
|
return $binary;
|
|
|
|
}
|
|
|
|
else {
|
2014-12-12 17:18:19 +00:00
|
|
|
$self->debug( 2, "Full path for $binary incorrect; searching" );
|
2011-11-25 22:09:33 +00:00
|
|
|
$binary =~ s!^.*/!!;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-21 08:23:49 +01:00
|
|
|
my $path;
|
|
|
|
if ( !-x $binary || substr( $binary, 0, 1 ) ne '/' ) {
|
2014-12-12 17:18:19 +00:00
|
|
|
$path = $self->search_dirs( $binary, split( /:/, $ENV{PATH} ) );
|
2011-07-21 08:23:49 +01:00
|
|
|
|
2014-12-12 17:18:19 +00:00
|
|
|
# if it is on $PATH then no need to qualitfy the path to it
|
|
|
|
# keep it as it is
|
|
|
|
if ($path) {
|
|
|
|
return $binary;
|
2011-07-21 08:23:49 +01:00
|
|
|
}
|
2014-12-12 17:18:19 +00:00
|
|
|
else {
|
|
|
|
$path = $self->search_dirs(
|
|
|
|
$binary, qw!
|
|
|
|
/bin
|
|
|
|
/sbin
|
|
|
|
/usr/sbin
|
|
|
|
/usr/bin
|
|
|
|
/usr/local/bin
|
|
|
|
/usr/local/sbin
|
|
|
|
/opt/local/bin
|
|
|
|
/opt/local/sbin
|
|
|
|
!
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2011-07-21 08:23:49 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
$self->debug( 2, "Already configured OK" );
|
|
|
|
$path = $binary;
|
|
|
|
}
|
|
|
|
if ( !$path || !-f $path || !-x $path ) {
|
|
|
|
croak(
|
|
|
|
App::ClusterSSH::Exception::Config->throw(
|
|
|
|
error => $self->loc(
|
2013-02-13 22:10:30 +00:00
|
|
|
'"[_1]" binary not found - please amend $PATH or the cssh config file'
|
|
|
|
. $/,
|
2011-07-21 08:23:49 +01:00
|
|
|
$binary
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
chomp($path);
|
|
|
|
return $path;
|
|
|
|
}
|
|
|
|
|
2011-07-28 10:23:49 +01:00
|
|
|
sub dump {
|
|
|
|
my ( $self, $no_exit, ) = @_;
|
|
|
|
|
2011-08-31 21:01:12 +01:00
|
|
|
$self->debug( 3, 'Dumping config to STDOUT' );
|
2017-03-04 11:11:35 +00:00
|
|
|
print( '# Configuration dump produced by "cssh -d"', $/ );
|
2011-07-28 10:23:49 +01:00
|
|
|
|
2011-08-31 21:01:12 +01:00
|
|
|
foreach my $key ( sort keys %$self ) {
|
2013-04-15 21:56:19 +01:00
|
|
|
my $comment = '';
|
2011-08-31 21:01:12 +01:00
|
|
|
if ( grep /$key/, @app_specific ) {
|
|
|
|
next;
|
|
|
|
}
|
2013-03-08 07:58:39 +00:00
|
|
|
if ( grep /$key/, @ignore_default_config ) {
|
2013-04-15 21:56:19 +01:00
|
|
|
$comment = '#';
|
2013-03-08 07:58:39 +00:00
|
|
|
}
|
|
|
|
print $comment, $key, '=', $self->{$key}, $/;
|
2011-07-28 10:23:49 +01:00
|
|
|
}
|
|
|
|
|
2011-08-31 21:01:12 +01:00
|
|
|
$self->exit if ( !$no_exit );
|
2011-07-28 10:23:49 +01:00
|
|
|
}
|
|
|
|
|
2011-07-08 13:00:29 +01:00
|
|
|
#use overload (
|
|
|
|
# q{""} => sub {
|
|
|
|
# my ($self) = @_;
|
|
|
|
# return $self->{hostname};
|
|
|
|
# },
|
|
|
|
# fallback => 1,
|
|
|
|
#);
|
|
|
|
|
|
|
|
1;
|
|
|
|
|
|
|
|
=head1 METHODS
|
|
|
|
|
|
|
|
=over 4
|
|
|
|
|
|
|
|
=item $host=ClusterSSH::Config->new ({ })
|
|
|
|
|
|
|
|
Create a new configuration object.
|
|
|
|
|
2011-07-21 08:23:49 +01:00
|
|
|
=item $config->parse_config_file('<filename>');
|
2011-07-08 13:00:29 +01:00
|
|
|
|
|
|
|
Read in configuration from given filename
|
|
|
|
|
|
|
|
=item $config->validate_args();
|
|
|
|
|
2011-07-08 14:30:03 +01:00
|
|
|
Validate and apply all configuration loaded at this point
|
2011-07-08 13:00:29 +01:00
|
|
|
|
2014-12-12 17:18:19 +00:00
|
|
|
=item $path = $config->search_dirs('<name>', @seaarch_directories);
|
|
|
|
|
|
|
|
Search the given directories for the name given. Return undef if not found.
|
|
|
|
|
2011-07-25 18:23:07 +01:00
|
|
|
=item $path = $config->find_binary('<name>');
|
2011-07-21 08:23:49 +01:00
|
|
|
|
|
|
|
Locate the binary <name> and return the full path. Doesn't just search
|
|
|
|
$PATH in case the environment isn't set up correctly
|
|
|
|
|
2011-07-28 10:23:49 +01:00
|
|
|
=item $config->load_configs(@extra);
|
2011-07-25 18:23:07 +01:00
|
|
|
|
|
|
|
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).
|
|
|
|
|
2011-07-28 10:23:49 +01:00
|
|
|
=item $config->dump()
|
|
|
|
|
|
|
|
Write currently defined configuration to STDOUT
|
|
|
|
|
2011-07-08 13:00:29 +01:00
|
|
|
=back
|