mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-24 21:35:00 +00:00
Add and test start_services() for Service.run_once_on_start.
This commit is contained in:
55
bin/pt-agent
55
bin/pt-agent
@@ -4647,6 +4647,7 @@ use Time::HiRes qw(sleep time);
|
|||||||
use JSON qw(decode_json);
|
use JSON qw(decode_json);
|
||||||
use File::Temp qw(tempfile);
|
use File::Temp qw(tempfile);
|
||||||
use File::Path;
|
use File::Path;
|
||||||
|
use FindBin;
|
||||||
|
|
||||||
use Percona::Toolkit;
|
use Percona::Toolkit;
|
||||||
use Percona::WebAPI::Client;
|
use Percona::WebAPI::Client;
|
||||||
@@ -5089,8 +5090,8 @@ sub run_agent {
|
|||||||
lib_dir => $lib_dir,
|
lib_dir => $lib_dir,
|
||||||
config => $config,
|
config => $config,
|
||||||
services => $services,
|
services => $services,
|
||||||
json => $args{json}, # optional, for testing
|
json => $args{json}, # optional, for testing
|
||||||
|
bin_dir => $args{bin_dir}, # optional, for testing
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5214,6 +5215,14 @@ sub get_services {
|
|||||||
schedule_services(
|
schedule_services(
|
||||||
services => $new_services,
|
services => $new_services,
|
||||||
lib_dir => $lib_dir,
|
lib_dir => $lib_dir,
|
||||||
|
bin_dir => $args{bin_dir}, # optional, for testing
|
||||||
|
);
|
||||||
|
|
||||||
|
# TODO: this probably can't/won't fail, but if it does, is it
|
||||||
|
# worth setting success=0?
|
||||||
|
start_services(
|
||||||
|
services => $new_services,
|
||||||
|
bin_dir => $args{bin_dir}, # optional, for testing
|
||||||
);
|
);
|
||||||
|
|
||||||
$services = $new_services;
|
$services = $new_services;
|
||||||
@@ -5268,8 +5277,9 @@ sub write_config {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check and init the --lib dir. This dir is used to save the Agent resource (/agent),
|
# Check and init the --lib dir. This dir is used to save the Agent resource
|
||||||
# Service resources (/services/), and crontab for services (/conrtab, /crontab.err).
|
# (/agent), Service resources (/services/), and crontab for services(/conrtab,
|
||||||
|
# /crontab.err).
|
||||||
sub init_lib_dir {
|
sub init_lib_dir {
|
||||||
my (%args) = @_;
|
my (%args) = @_;
|
||||||
|
|
||||||
@@ -5442,6 +5452,8 @@ sub make_new_crontab {
|
|||||||
# Optional args
|
# Optional args
|
||||||
my $crontab_list = defined $args{crontab_list} ? $args{crontab_list}
|
my $crontab_list = defined $args{crontab_list} ? $args{crontab_list}
|
||||||
: `crontab -l 2>/dev/null`;
|
: `crontab -l 2>/dev/null`;
|
||||||
|
my $bin_dir = defined $args{bin_dir} ? $args{bin_dir}
|
||||||
|
: "$FindBin::Bin/";
|
||||||
|
|
||||||
my @other_lines
|
my @other_lines
|
||||||
= grep { $_ !~ m/pt-agent (?:--run-service|--send-data)/ }
|
= grep { $_ !~ m/pt-agent (?:--run-service|--send-data)/ }
|
||||||
@@ -5452,12 +5464,12 @@ sub make_new_crontab {
|
|||||||
foreach my $service ( @$services ) {
|
foreach my $service ( @$services ) {
|
||||||
push @pt_agent_lines,
|
push @pt_agent_lines,
|
||||||
$service->run_schedule
|
$service->run_schedule
|
||||||
. " pt-agent --run-service "
|
. " ${bin_dir}pt-agent --run-service "
|
||||||
. $service->name;
|
. $service->name;
|
||||||
if ( $service->spool_schedule ) {
|
if ( $service->spool_schedule ) {
|
||||||
push @pt_agent_lines,
|
push @pt_agent_lines,
|
||||||
$service->spool_schedule
|
$service->spool_schedule
|
||||||
. " pt-agent --send-data "
|
. " ${bin_dir}pt-agent --send-data "
|
||||||
. $service->name;
|
. $service->name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5468,10 +5480,39 @@ sub make_new_crontab {
|
|||||||
return $new_crontab;
|
return $new_crontab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Start all services that have the run_once_on_start flag enabled. This is
|
||||||
|
# used for "setup services" so the user doesn't have to wait until the next
|
||||||
|
# the service is actually scheduled to run.
|
||||||
|
sub start_services {
|
||||||
|
my (%args) = @_;
|
||||||
|
have_required_args(\%args, qw(
|
||||||
|
services
|
||||||
|
)) or die;
|
||||||
|
my $services = $args{services};
|
||||||
|
|
||||||
|
# Optional args
|
||||||
|
my $bin_dir = defined $args{bin_dir} ? $args{bin_dir}
|
||||||
|
: "$FindBin::Bin/";
|
||||||
|
|
||||||
|
foreach my $service ( @$services ) {
|
||||||
|
next unless $service->run_once_on_start;
|
||||||
|
my $cmd = "${bin_dir}pt-agent --run-service " . $service->name;
|
||||||
|
_info('Starting ' . $service->name . ' service: ' . $cmd);
|
||||||
|
# TODO: need service-specific log files, else where is this output
|
||||||
|
# supposed to go?
|
||||||
|
system("$cmd </dev/null >/dev/null 2>&1 &");
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
# ########################## #
|
# ########################## #
|
||||||
# --run-service process subs #
|
# --run-service process subs #
|
||||||
# ########################## #
|
# ########################## #
|
||||||
|
|
||||||
|
# TODO: need service-specific PID files so two "--run-service enable-slow-log"
|
||||||
|
# can't run at the same time.
|
||||||
|
|
||||||
sub run_service {
|
sub run_service {
|
||||||
my (%args) = @_;
|
my (%args) = @_;
|
||||||
|
|
||||||
@@ -5560,7 +5601,7 @@ sub run_service {
|
|||||||
# special vars like __RUN_N_OUTPUT__, __TMPDIR__, etc.
|
# special vars like __RUN_N_OUTPUT__, __TMPDIR__, etc.
|
||||||
my $cmd = join(' ',
|
my $cmd = join(' ',
|
||||||
$task->program,
|
$task->program,
|
||||||
$task->options,
|
($task->options || ''),
|
||||||
'>',
|
'>',
|
||||||
$output_file,
|
$output_file,
|
||||||
);
|
);
|
||||||
|
@@ -34,6 +34,7 @@ sub test_make_new_crontab {
|
|||||||
my $new_crontab = pt_agent::make_new_crontab(
|
my $new_crontab = pt_agent::make_new_crontab(
|
||||||
services => $services,
|
services => $services,
|
||||||
crontab_list => $crontab_list,
|
crontab_list => $crontab_list,
|
||||||
|
bin_dir => '',
|
||||||
);
|
);
|
||||||
|
|
||||||
ok(
|
ok(
|
||||||
@@ -122,6 +123,7 @@ SKIP: {
|
|||||||
|
|
||||||
my $new_crontab = pt_agent::make_new_crontab(
|
my $new_crontab = pt_agent::make_new_crontab(
|
||||||
services => [ $svc0 ],
|
services => [ $svc0 ],
|
||||||
|
bin_dir => '',
|
||||||
);
|
);
|
||||||
|
|
||||||
is(
|
is(
|
||||||
|
@@ -141,7 +141,7 @@ is(
|
|||||||
"init_config_file()"
|
"init_config_file()"
|
||||||
);
|
);
|
||||||
|
|
||||||
my $tmpdir = tempdir("/tmp/pt-agent.$PID.XXXXXX", CLEANUP => 1);
|
my $tmpdir = tempdir("/tmp/pt-agent.$PID.XXXXXX", CLEANUP => 0);
|
||||||
mkdir "$tmpdir/services" or die "Error making $tmpdir/services: $OS_ERROR";
|
mkdir "$tmpdir/services" or die "Error making $tmpdir/services: $OS_ERROR";
|
||||||
|
|
||||||
my @ok_code = (); # callbacks
|
my @ok_code = (); # callbacks
|
||||||
@@ -308,6 +308,121 @@ is(
|
|||||||
"Crontab is the same"
|
"Crontab is the same"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# #############################################################################
|
||||||
|
# Test a run_once_on_start service
|
||||||
|
# #############################################################################
|
||||||
|
|
||||||
|
diag(`rm -f $tmpdir/* >/dev/null 2>&1`);
|
||||||
|
diag(`rm -rf $tmpdir/services/*`);
|
||||||
|
mkdir "$tmpdir/spool" or die $OS_ERROR;
|
||||||
|
|
||||||
|
$config_file = pt_agent::get_config_file();
|
||||||
|
unlink $config_file if -f $config_file;
|
||||||
|
pt_agent::init_config_file(file => $config_file, api_key => '123');
|
||||||
|
|
||||||
|
$config = Percona::WebAPI::Resource::Config->new(
|
||||||
|
ts => 1363720060,
|
||||||
|
name => 'Test run_once_on_start',
|
||||||
|
options => {
|
||||||
|
'check-interval' => "60",
|
||||||
|
'lib' => $tmpdir,
|
||||||
|
'spool' => "$tmpdir/spool",
|
||||||
|
'pid' => "$tmpdir/pid",
|
||||||
|
'log' => "$tmpdir/log"
|
||||||
|
},
|
||||||
|
links => {
|
||||||
|
self => '/agents/123/config',
|
||||||
|
services => '/agents/123/services',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
$run0 = Percona::WebAPI::Resource::Task->new(
|
||||||
|
name => 'run-at-start',
|
||||||
|
number => '0',
|
||||||
|
program => 'date',
|
||||||
|
output => 'spool',
|
||||||
|
);
|
||||||
|
|
||||||
|
$svc0 = Percona::WebAPI::Resource::Service->new(
|
||||||
|
name => 'test-run-at-start',
|
||||||
|
run_schedule => '0 0 1 1 *',
|
||||||
|
spool_schedule => '0 0 1 1 *',
|
||||||
|
run_once_on_start => 1, # here's the magic
|
||||||
|
tasks => [ $run0 ],
|
||||||
|
links => {
|
||||||
|
self => '/query-history',
|
||||||
|
data => '/query-history/data',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
$ua->{responses}->{get} = [
|
||||||
|
{
|
||||||
|
headers => { 'X-Percona-Resource-Type' => 'Config' },
|
||||||
|
content => as_hashref($config, with_links => 1),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers => { 'X-Percona-Resource-Type' => 'Service' },
|
||||||
|
content => [ as_hashref($svc0, with_links => 1) ],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers => { 'X-Percona-Resource-Type' => 'Config' },
|
||||||
|
content => as_hashref($config, with_links => 1),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers => { 'X-Percona-Resource-Type' => 'Service' },
|
||||||
|
content => [ as_hashref($svc0, with_links => 1) ],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
@ok_code = (); # callbacks
|
||||||
|
@oktorun = (1, 1, 0);
|
||||||
|
@wait = ();
|
||||||
|
|
||||||
|
$output = output(
|
||||||
|
sub {
|
||||||
|
pt_agent::run_agent(
|
||||||
|
agent => $agent,
|
||||||
|
client => $client,
|
||||||
|
interval => $interval,
|
||||||
|
config_file => $config_file,
|
||||||
|
lib_dir => $tmpdir,
|
||||||
|
oktorun => $oktorun, # optional, for testing
|
||||||
|
json => $json, # optional, for testing
|
||||||
|
bin_dir => "$trunk/bin/", # optional, for testing
|
||||||
|
);
|
||||||
|
},
|
||||||
|
stderr => 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
Percona::Test::wait_for_files("$tmpdir/spool/test-run-at-start");
|
||||||
|
|
||||||
|
like(
|
||||||
|
$output,
|
||||||
|
qr/Starting test-run-at-start service/,
|
||||||
|
"Ran service on start"
|
||||||
|
);
|
||||||
|
|
||||||
|
my @runs = $output =~ m/Starting test-run-at-start service/g;
|
||||||
|
|
||||||
|
is(
|
||||||
|
scalar @runs,
|
||||||
|
1,
|
||||||
|
"... only ran it once"
|
||||||
|
);
|
||||||
|
|
||||||
|
chomp($output = `cat $tmpdir/spool/test-run-at-start 2>/dev/null`);
|
||||||
|
ok(
|
||||||
|
$output,
|
||||||
|
"... service ran at start"
|
||||||
|
) or diag($output);
|
||||||
|
|
||||||
|
chomp($output = `crontab -l`);
|
||||||
|
like(
|
||||||
|
$output,
|
||||||
|
qr/--run-service test-run-at-start/,
|
||||||
|
"... service was scheduled"
|
||||||
|
);
|
||||||
|
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
# Done.
|
# Done.
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
@@ -320,4 +435,5 @@ if ( -f $config_file ) {
|
|||||||
unlink $config_file
|
unlink $config_file
|
||||||
or warn "Error removing $config_file: $OS_ERROR";
|
or warn "Error removing $config_file: $OS_ERROR";
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
done_testing;
|
||||||
|
@@ -81,6 +81,15 @@ is(
|
|||||||
) or diag($output);
|
) or diag($output);
|
||||||
|
|
||||||
$crontab = `crontab -l 2>/dev/null`;
|
$crontab = `crontab -l 2>/dev/null`;
|
||||||
|
|
||||||
|
# pt-agent uses $FindBin::Bin/pt-agent for the path to pt-agent,
|
||||||
|
# which in testing will be $trunk/t/pt-agent/ because that's where
|
||||||
|
# this file is located. However, if $FindBin::Bin resovles sym
|
||||||
|
# links where as $trunk does not, so to make things simple we just
|
||||||
|
# cut out the full path.
|
||||||
|
if ( $crontab ) {
|
||||||
|
$crontab =~ s! /.+?/pt-agent --! pt-agent --!g;
|
||||||
|
}
|
||||||
is(
|
is(
|
||||||
$crontab,
|
$crontab,
|
||||||
"* 0 * * * date > /dev/null
|
"* 0 * * * date > /dev/null
|
||||||
|
Reference in New Issue
Block a user