my ($self, $worker_cmd, $required_worker_count, $iteration, $rc_name, $rc_specific_submission_cmd_args, $submit_log_subdir) = @_;
my $worker_cmd_components = [ split_for_bash($worker_cmd) ];
my $job_array_common_name = $self->job_array_common_name($rc_name, $iteration);
# Name collision detection
my $extra_suffix = 0;
my $service_name = $job_array_common_name;
while (scalar(@{ $self->GET( '/tasks?filters={"name":["' . $service_name . '"]}' ) })) {
$extra_suffix++;
$service_name = "$job_array_common_name-$extra_suffix";
}
if ($extra_suffix) {
warn "'$job_array_common_name' already used to name a service. Using '$service_name' instead.\n";
$job_array_common_name = $service_name;
}
die "The image name for the ".$self->name." DockerSwarm meadow is not configured. Cannot submit jobs !" unless $self->config_get('ImageName');
# If the resource description is missing, use 1 core
my $default_resources = {
'Reservations' => {
'NanoCPUs' => 1_000_000_000,
},
};
my $resources = destringify($rc_specific_submission_cmd_args);
my $service_create_data = {
'Name' => $job_array_common_name, # NB: service names in DockerSwarm have to be unique!
'TaskTemplate' => {
'ContainerSpec' => {
'Image' => $self->config_get('ImageName'),
'Args' => $worker_cmd_components,
'Mounts' => $self->config_get('Mounts'),
'Env' => [
# Propagate these to the workers
"DOCKER_MASTER_ADDR=$self->{'_DOCKER_MASTER_ADDR'}",
"_EHIVE_HIDDEN_PASS=$ENV{'_EHIVE_HIDDEN_PASS'}",
],
},
# NOTE: By default, docker alway keeps logs. Should we disable them here
# $submit_log_subdir has been set ? There are no options to redirect
# the logs, so the option's value would be ignored.
#'LogDriver' => {
#'Name' => 'none',
#},
'Resources' => $resources || $default_resources,
'RestartPolicy' => {
'Condition' => 'none',
},
},
'Mode' => {
'Replicated' => {
'Replicas' => int($required_worker_count),
},
},
};
my $service_created_struct = $self->POST( '/services/create', $service_create_data );
unless (exists $service_created_struct->{'ID'}) {
die "Submission unsuccessful: " . ($service_created_struct->{'message'}
}
# Give some time to the Docker daemon to process the request
sleep(5);
my $service_id = $service_created_struct->{'ID'};
my $service_tasks_list = $self->GET( qq{/tasks?filters={"service":["$service_id"]}} );
if (scalar(@$service_tasks_list) != int($required_worker_count)) {
die "Submission unsuccessful: found " . scalar(@$service_tasks_list) . " tasks instead of " . int($required_worker_count) . "\n";
}
my @children_task_ids =
map { $_->{
'ID'} } @$service_tasks_list;
return \@children_task_ids;
}