NAME

Documentation For Deploy File '@{[$self->config]}'

SYNOPSIS

EOM

if (my $synopsis = $self->docs->get('SYNOPSIS')) {
    print $tempfile $synopsis;
} else {
    foreach my $task ($self->tasks->values) {
        print $tempfile <<EOM;
canella -c @{[$self->config]} I<role> @{[$task->name]}
EOM
    }
}

print $tempfile <<EOM;

ROLES

EOM foreach my $role ($self->roles->values) { print $tempfile <<EOM; =head2 @{[$role->name]}

EOM }

print $tempfile <<EOM;

TASKS

EOM foreach my $task ($self->tasks->values) { print $tempfile <<EOM =head2 @{[ $task->name ]}

@{[$task->description || '']}

EOM }

foreach my $section (grep { !/^SYNOPSIS$/ } $self->docs->keys) {
    print $tempfile <<EOM
=head1 $section

@{[ $self->docs->get($section) ]}

EOM }

print $tempfile "\n=cut\n";
$tempfile->flush;

local @ARGV = ('-F', $tempfile->filename);
exit(Pod::Perldoc->run());
}

# Thread-specific stash sub stash { my $self = shift; my $stash = $Coro::current->{Canella} ||= {};

if (@_ == 0) {
    return $stash;
}

if (@_ == 1) {
    return $stash->{$_[0]};
}

while (my ($key, $value) = splice @_, 0, 2) {
    $stash->{$key} = $value;
}
}

sub get_param { my ($self, $name) = @_; return $self->parameters->get($name); }

sub set_param { my ($self, $name, $value) = @_;

# If the same parameter has been overriden in the command line, respect
# that instead of the actual parameter given
if (defined(my $o_value = $self->override_parameters->get($name))) {
    return;
}
$self->parameters->set($name, $value);
}

sub get_role { $_[0]->roles->get($_[1]); }

sub add_role { my ($self, $name, %args) = @_;

if ($args{parameters}) {
    $args{parameters} = Hash::MultiValue->new(%{$args{parameters}});
}

$self->roles->set($name, Canella::Role->new(name => $name, %args));
}

sub get_task { $_[0]->tasks->get($_[1]); }

sub add_task { my $self = shift; $self->tasks->set($_[0]->name, $_[0]); }

sub call_task { my ($self, $task) = @_; my $host = $self->stash('current_host');

debugf "Starting task %s on host %s", $task->name, $host;
my $guard = guard {
    debugf "End task %s on host %s", $task->name, $host;
};
local $@;
eval { $task->execute($host) };
if (my $E = $@) {
    critf("[%s] %s", $host, $E);
}
}

sub build_cmd_executor { my ($self, @cmd) = @_;

if ($self->stash('sudo')) {
    unshift @cmd, "sudo";
}

my $cmd;
if (my $remote = $self->stash('current_remote')) {
    $remote->cmd(\@cmd);
    $cmd = $remote;
} else {
    $cmd = Canella::Exec::Local->new(cmd => \@cmd);
}
return $cmd;
}

sub run_cmd { my ($self, @cmd) = @_;

my $cmd = $self->build_cmd_executor(@cmd);
$cmd->execute();
if ($cmd->has_error) {
    croakf("Error executing command: %d", $cmd->error);
}
return ($cmd->stdout, $cmd->stderr);
}

sub build_runner { return Canella::TaskRunner->new; }

1;