# Batch EXecutor -- Configuration
# (c) 2011-2013 Martin Mares <mj@ucw.cz>

use strict;
use warnings;

package BEX::Config;

# This file specifies default values, which can be overridden in BEX.cf

# A hash of all known machines and groups
# 'name' => { Option => ... }	for a machine; options:
#	Host => 'name'			Host name to use in ssh, ping, ...
# 'name' => ['a','b','c']	for a group containing specified machines/subgroups
our %machines = (
);

# Library directory where BEX modules live
our $lib = $ENV{"BEX_LIB"} // "lib";

# Home directory in which everything resides
our $home = $ENV{"BEX_HOME"} // ".";

# Configuration directory
our $cf_dir = $home . "/cf";

# A file whose contents should be prepended before the job. Should start with the "#!" line.
our $job_prolog = $cf_dir . '/prolog';

# A file whose contents should be appended to the job
our $job_epilog = $cf_dir . '/epilog';

# Keep history of successfully completed jobs
our $keep_history = 1;

# Before we try to connect to a host, ping it to check if it's alive
our $ping_hosts = 1;

# Whenever we want to run a job on a machine, we must obtain a lock.
# Available locking schemes are:
#	none - no locking takes place (dangerous!)
#	job - obtain exclusive access to the job, other jobs on the same
#	      host can run in parallel
#	host - obtain exclusive access to the host, other hosts can run
#	queue - obtain exclusive access to the whole queue
our $locking_scheme = 'host';

# Maximum number of simultaneously running jobs in `bex prun'
our $max_parallel_jobs = 5;

# When a job fails, skip all other jobs on the same host
# (however, when locking_scheme is set to `job', another instance of `bex run'
# still could run such jobs in parallel)
our $skip_on_fail = 0;

# How we run ssh (including options)
our $ssh_command = "ssh";

# Which user we log in as (if any)
our $ssh_user;

# How we run rsync to upload attachments (including options)
our $rsync_command = "rsync -a";

# Which editor should be used for editing jobs
our $editor_command = $ENV{"EDITOR"} // "/usr/bin/editor";

# Various utility functions

sub parse_machine_list(@);

sub parse_machine_list(@) {
	my %set = ();
	for my $m (@_) {
		if ($m eq '*') {
			for my $mm (keys %machines) {
				if (ref($machines{$mm}) eq 'HASH') {
					$set{$mm} = 1;
				}
			}
			next;
		}
		my $op = 1;
		if ($m =~ s{^!}{}) { $op = 0; }
		my $v = $machines{$m};
		if (!defined $v) {
			die "Unknown machine or group $m\n";
		} elsif (ref($v) eq 'HASH') {
			$set{$m} = $op;
		} elsif (ref($v) eq 'ARRAY') {
			for my $mm (parse_machine_list(@$v)) {
				$set{$mm} = $op;
			}
		}
	}
	return sort grep { $set{$_} } keys %set;
}

sub host_name($$) {
	my ($mach, $want_user) = @_;
	my $host = $machines{$mach}->{'Host'} // $mach;
	if ($want_user) {
		my $user = $machines{$mach}->{'User'} // $ssh_user;
		if (defined $user) {
			return $user . '@' . $host;
		}
	}
	return $host;
}

require $cf_dir . '/config';

42;
