parallel: Implemented --hostgroup.

This commit is contained in:
Ole Tange 2014-11-11 04:56:55 +01:00
parent 8563f3f95a
commit 95958b623a
3 changed files with 77 additions and 13 deletions

View file

@ -723,6 +723,7 @@ sub options_hash {
"cat" => \$opt::cat, "cat" => \$opt::cat,
"fifo" => \$opt::fifo, "fifo" => \$opt::fifo,
"pipepart|pipe-part" => \$opt::pipepart, "pipepart|pipe-part" => \$opt::pipepart,
"hostgroup|hostgroups" => \$opt::hostgroups,
); );
} }
@ -1702,6 +1703,7 @@ sub start_more_jobs {
$jobs_started_this_round = 0; $jobs_started_this_round = 0;
# This will start 1 job on each --sshlogin (if possible) # This will start 1 job on each --sshlogin (if possible)
# thus distribute the jobs on the --sshlogins round robin # thus distribute the jobs on the --sshlogins round robin
for my $sshlogin (values %Global::host) { for my $sshlogin (values %Global::host) {
if($Global::JobQueue->empty() and not $opt::pipe) { if($Global::JobQueue->empty() and not $opt::pipe) {
# No more jobs in the queue # No more jobs in the queue
@ -2163,14 +2165,33 @@ sub get_job_with_sshlogin {
# Returns: # Returns:
# next job object for $sshlogin if any available # next job object for $sshlogin if any available
my $sshlogin = shift; my $sshlogin = shift;
my $job = undef;
my $job = $Global::JobQueue->get(); if ($opt::hostgroups) {
my @other_hostgroup_jobs = ();
while($job = $Global::JobQueue->get()) {
if($sshlogin->in_hostgroups($job->hostgroups())) {
# Found a job for this hostgroup
last;
} else {
# This job was not in the hostgroups of $sshlogin
push @other_hostgroup_jobs, $job;
}
}
$Global::JobQueue->unget(@other_hostgroup_jobs);
if(not defined $job) {
# No more jobs
return undef;
}
} else {
$job = $Global::JobQueue->get();
if(not defined $job) { if(not defined $job) {
# No more jobs # No more jobs
::debug("start", "No more jobs: JobQueue empty\n"); ::debug("start", "No more jobs: JobQueue empty\n");
return undef; return undef;
} }
# if(not $sshlogin->start_more()) { return undef; } }
my $clean_command = $job->replaced(); my $clean_command = $job->replaced();
if($clean_command =~ /^\s*$/) { if($clean_command =~ /^\s*$/) {
@ -3335,11 +3356,25 @@ sub new {
my $class = shift; my $class = shift;
my $sshlogin_string = shift; my $sshlogin_string = shift;
my $ncpus; my $ncpus;
if($sshlogin_string =~ s:^(\d+)/:: and defined $1) { my %hostgroups;
# SSHLogins can have these formats:
# @grp+grp/ncpu//usr/bin/ssh user@server
# ncpu//usr/bin/ssh user@server
# /usr/bin/ssh user@server
# user@server
# ncpu/user@server
# @grp+grp/user@server
if($sshlogin_string =~ s:^\@([^/]+)/::) {
# Look for SSHLogin hostgroups
%hostgroups = map { $_ => 1 } split(/\+/, $1);
}
if ($sshlogin_string =~ s:^(\d+)/::) {
# Override default autodetected ncpus unless missing # Override default autodetected ncpus unless missing
$ncpus = $1; $ncpus = $1;
} }
my $string = $sshlogin_string; my $string = $sshlogin_string;
# An SSHLogin is always in the hostgroup of its $string-name
$hostgroups{$string} = 1;
my @unget = (); my @unget = ();
my $no_slash_string = $string; my $no_slash_string = $string;
$no_slash_string =~ s/[^-a-z0-9:]/_/gi; $no_slash_string =~ s/[^-a-z0-9:]/_/gi;
@ -3351,6 +3386,7 @@ sub new {
'max_jobs_running' => undef, 'max_jobs_running' => undef,
'orig_max_jobs_running' => undef, 'orig_max_jobs_running' => undef,
'ncpus' => $ncpus, 'ncpus' => $ncpus,
'hostgroups' => \%hostgroups,
'sshcommand' => undef, 'sshcommand' => undef,
'serverlogin' => undef, 'serverlogin' => undef,
'control_path_dir' => undef, 'control_path_dir' => undef,
@ -3410,6 +3446,16 @@ sub jobs_completed {
return $self->{'jobs_completed'}; return $self->{'jobs_completed'};
} }
sub in_hostgroups {
# Input:
# @hostgroups = the hostgroups to look for
# Returns:
# true if intersection of @hostgroups and the hostgroups of this
# SSHLogin is non-empty
my $self = shift;
return grep { defined $self->{'hostgroups'}{$_} } @_;
}
sub inc_jobs_completed { sub inc_jobs_completed {
my $self = shift; my $self = shift;
$self->{'jobs_completed'}++; $self->{'jobs_completed'}++;
@ -6136,6 +6182,14 @@ sub tag {
return $self->{'tag'}; return $self->{'tag'};
} }
sub hostgroups {
my $self = shift;
if(not defined $self->{'hostgroups'}) {
$self->{'hostgroups'} = $self->{'commandline'}->{'arg_list'}[0][0]->{'hostgroups'};
}
return @{$self->{'hostgroups'}};
}
sub exitstatus { sub exitstatus {
my $self = shift; my $self = shift;
return $self->{'exitstatus'}; return $self->{'exitstatus'};
@ -7391,8 +7445,16 @@ package Arg;
sub new { sub new {
my $class = shift; my $class = shift;
my $orig = shift; my $orig = shift;
my @hostgroups;
if($opt::hostgroups) {
if($orig =~ s:@(.+)::) {
# We found hostgroups on the arg
@hostgroups = split(/\+/, $1);
}
}
return bless { return bless {
'orig' => $orig, 'orig' => $orig,
'hostgroups' => \@hostgroups,
}, ref($class) || $class; }, ref($class) || $class;
} }

View file

@ -4188,10 +4188,12 @@ Specifying the name of your distribution is not enough as you may have
installed software that is not in the VirtualBox images. installed software that is not in the VirtualBox images.
If you cannot reproduce the error on any of the VirtualBox images If you cannot reproduce the error on any of the VirtualBox images
above, you should assume the debugging will be done through you. That above, see if you can build a VirtualBox image on which you can
will put more burden on you and it is extra important you give any reproduce the error. If not you should assume the debugging will be
information that help. In general the problem will be fixed faster and done through you. That will put more burden on you and it is extra
with less work for you if you can reproduce the error on a VirtualBox. important you give any information that help. In general the problem
will be fixed faster and with less work for you if you can reproduce
the error on a VirtualBox.
=head1 AUTHOR =head1 AUTHOR

View file

@ -1211,7 +1211,7 @@ Output:
Note how job 1 and 2 were tried 3 times, but 0 was not retried because it had exit code 0. Note how job 1 and 2 were tried 3 times, but 0 was not retried because it had exit code 0.
=head2 Limiting the ressources =head2 Limiting the resources
To avoid overloading systems GNU Parallel can look at the system load To avoid overloading systems GNU Parallel can look at the system load
before starting another job: before starting another job: