App-Oozie
view release on metacpan or search on metacpan
lib/App/Oozie/Run.pm view on Meta::CPAN
$self->appname( $guess );
}
# move to constructor?
(my $appname = $self->appname) =~ s{ [/]+ \z }{}xms;
$self->appname( $appname );
$self->logger->info( sprintf 'Job name: %s', $self->appname );
$self->logger->info( sprintf 'Job path (HDFS dir): %s', $self->path );
$self->setup_dates;
my($cmd_tmpl, $cmd_param) = $self->collect_oozie_cmd_args;
# Are we alone or do we need to kill our brothers and sisters?
$self->check_current_instances;
Template->new
->process(
\join( SPACE_CHAR, @{ $cmd_tmpl } ),
$cmd_param,
\my $command,
);
my $success = $self->execute( $command );
if(!$success){
return $success;
}
# go back where we started!
chdir $CWD if $CWD;
$logger->info(
sprintf 'Completed successfully in %s (took %s)',
sprintf( '%s%s', $self->cluster_name, ( $self->dryrun ? ' (dryrun is set)' : EMPTY_STRING ) ),
duration_exact( time - $run_start_epoch ),
);
return $success;
}
sub collect_oozie_cmd_args {
my $self = shift;
my $logger = $self->logger;
my @extra_oozie_args;
my @define = @{ $self->define };
my %extra_def = ();
# We are not supporting sla for bundles (yet)
if ( !($self->type eq 'bundle') ) {
%extra_def = (
$self->verify_sla,
);
}
if ( $self->type eq 'wf' ) {
%extra_def = (
%extra_def,
$self->check_coordinator_function_calls({
map { (split m{ [=] }xms, $_)[0] => 1 } @define
}),
);
}
if (@{ $self->errors } ) {
$logger->error(
'Overridable errors encountered',
( $self->force ? EMPTY_STRING : ' (relaunch using --force to proceed)' )
);
$logger->error( '- ' . $_ ) for @{ $self->errors };
die if !$self->force && !$self->dryrun;
}
my $hash_to_def = sub {
my($h, $no_quote) = @_;
my $tmpl = $no_quote ? q{-D%s=%s} : q{-D'%s=%s'};
map { sprintf $tmpl, $_, $h->{$_} } keys %{ $h }
};
# IMPORTANT ! keep this in sync with the sudoers file,
# if you have a corresponding setting in such a place
my %def = (
appName => '[% app_name %]',
startTime => '[% start_time %]',
endTime => '[% end_time %]',
workflowPath => '[% workflow_path %]',
'oozie.[% type %].application.path' => '[% workflow_path %]',
path => '[% path %]',
nameNode => '[% name_node %]',
'oozie.use.system.libpath' => 'true',
( @define ? ( map { split m{ [=] }xms, $_, 2 } @define ) : () ),
);
my %prop = $self->probe_settings;
my %owner = $self->probe_meta;
$self->logger->info( 'Combining owner info into job.properties' );
my $override_file = File::Temp->new(
SUFFIX => '.properties',
DIR => resolve_tmp_dir(),
);
my $original = EMPTY_STRING;
my $orig_filename = 'job.properties';
if ( open my $ORIG_FH, '<', $orig_filename ) {
local $/;
$original = <$ORIG_FH>;
if ( ! close $ORIG_FH ) {
$logger->warn(
sprintf 'Failed to close %s: %s',
$orig_filename,
$!,
);
}
}
$override_file->print( $original, "\n\n" );
my $c = Config::Properties->new( be_like_java => 1 );
for my $var ( keys %owner ) {
$c->setProperty( $var => $owner{ $var } );
}
$override_file->print( $c->saveToString );
my @args = (
$hash_to_def->( \%def ),
$hash_to_def->( \%extra_def ),
@extra_oozie_args,
'-config' => $override_file,
($self->doas ? (-doas => $self->doas) : ()), #impersonation
);
# These can't be set in the list above, because of Oozie requiring them
# to be set before the sub-command as otherwise they become no-op.
# You gotta love the Hadoop stack.
#
# This in turn also requires yet another sudoers template, so be careful
# with this and contact the BigData Team if you need something to be
# changed in this section.
#
# IMPORTANT! the order matters for this section for sudoers if you have a corresponding setting.
my @username_override = $prop{username_override}
? (
$hash_to_def->({ 'oozie.auth.token.cache' => 'false' }, 1),
$hash_to_def->({ 'user.name' => $prop{username_override} }, 1),
)
: ();
lib/App/Oozie/Run.pm view on Meta::CPAN
}
return %prop;
}
sub ask {
my $self = shift;
my $var = shift;
my $msg = "Please enter the new value for `$var` based on the definition above";
my($input, $count);
while ( 1 ) {
if ( ++$count > MAX_RETRY ) {
print "\tYou didn't specify anything 3 times, so I give up! ($var=undef)\n";
last;
}
print "$msg: ";
chomp($input = <STDIN>);
if ( $input eq EMPTY_STRING ) {
print "Nothing specified!\n";
next;
}
last;
}
if ( $input ne EMPTY_STRING ) {
print "\t$var will be set to '$input'\n";
}
return $input;
}
sub execute {
my $self = shift;
my $command = shift;
my $logger = $self->logger;
my $verbose = $self->verbose;
my $outbuffer;
if ( ! $self->dryrun ) {
$logger->info( 'Executing the command to schedule' );
my ($ok, $err, $full_buf, $stdout_buff, $stderr_buff);
($ok, $err, $full_buf, $stdout_buff, $stderr_buff) = IPC::Cmd::run(
command => $command,
verbose => 1,
buffer => \$outbuffer,
timeout => $self->timeout,
);
if ( ! $ok ) {
$logger->fatal( $err );
return 0;
}
if ( is_arrayref $stderr_buff && @{ $stderr_buff } ) {
$logger->warn( join "\n", @{ $stderr_buff } );
}
($outbuffer) = reverse
map {
split m{ \n }xms, $_
}
@{ $stdout_buff }
;
if (
# TODO: move to constant
$outbuffer =~ m{
([0-9-]+ oozie-oozi- [CWB])
}xms
) {
my $job_id = $1;
$self->log_console_url( $job_id );
}
else {
$logger->warn( 'Failed to locate the Oozie job id from the system call' );
}
return 1;
}
my $type = $self->type;
my @info = (
'Running oozie --dryrun for your command',
sprintf( 'This will dryrun or test run a %s job, no job will be queued or scheduled ', $type ),
);
push @info, 'In case of --type=wf you will only get an OK in case of success' if $type eq 'wf';
push @info, 'oozie --dryrun Output START';
$logger->info( $_ ) for @info;
IPC::Cmd::run(
command => $command,
verbose => 1,
buffer => \$outbuffer,
timeout => $self->timeout,
) or do {
$logger->fatal( sprintf 'Error encountered when trying to dryrun the new %s!!!', $type );
$logger->fatal( 'oozie response: ' . $outbuffer );
$logger->info( 'oozie --dryrun Output END' );
return 0;
};
$logger->info( 'oozie response: ' . $outbuffer );
$logger->info( 'oozie --dryrun Output END' );
return 1;
}
sub log_console_url {
my $self = shift;
my $job_id = shift;
$self->logger->info( sprintf 'Console URL: %s?job=%s', $self->oozie_uri, $job_id );
return;
}
1;
__END__
=pod
( run in 1.723 second using v1.01-cache-2.11-cpan-6aa56a78535 )