Get and send real program version when the agent starts.

This commit is contained in:
Daniel Nichter
2013-03-21 13:50:49 -06:00
parent f04d0e575a
commit c1cce0c6ca
5 changed files with 146 additions and 45 deletions

View File

@@ -4679,8 +4679,6 @@ sub main {
if ( !$o->get('help') ) {
}
#Pingback::validate_options($o);
$o->usage_or_errors();
@@ -4694,16 +4692,20 @@ sub main {
. "in a --config file or specify it with --api-key.");
}
# ########################################################################
# Connect to MysSQL.
# ########################################################################
my $cxn = Cxn->new(
dsn_string => '',
OptionParser => $o,
DSNParser => $dp,
);
# ########################################################################
# --run-service
# This runs locally and offline, doesn't need a web API connection.
# ########################################################################
if ( my $service = $o->get('run-service') ) {
my $cxn = Cxn->new(
dsn_string => '',
OptionParser => $o,
DSNParser => $dp,
);
$exit_status = run_service(
service => $service,
spool_dir => $o->get('spool'),
@@ -4714,28 +4716,15 @@ sub main {
exit $exit_status;
}
# ########################################################################
# Daemonize first so all output goes to the --log.
# ########################################################################
my $daemon;
if ( $o->get('daemonize') ) {
$daemon = new Daemon(o=>$o);
$daemon->daemonize();
PTDEBUG && _d('I am a daemon now');
}
elsif ( $o->get('pid') ) {
$daemon = new Daemon(o=>$o);
$daemon->make_PID_file();
}
# ########################################################################
# Connect to the Percona web API.
# ########################################################################
my ($client, $agent);
eval {
($client, $agent) = connect_to_percona(
api_key => $api_key,
api_key => $api_key,
lib_dir => $o->get('lib'),
Cxn => $cxn,
);
};
if ( $EVAL_ERROR ) {
@@ -4766,6 +4755,18 @@ sub main {
# external errors, like Percona web API not responding, should be
# retried forever.
# ########################################################################
# Daemonize first so all output goes to the --log.
my $daemon;
if ( $o->get('daemonize') ) {
$daemon = new Daemon(o=>$o);
$daemon->daemonize();
PTDEBUG && _d('I am a daemon now');
}
elsif ( $o->get('pid') ) {
$daemon = new Daemon(o=>$o);
$daemon->make_PID_file();
}
# Check and init the config file.
my $config_file = get_config_file();
@@ -4837,9 +4838,11 @@ sub connect_to_percona {
have_required_args(\%args, qw(
api_key
lib_dir
Cxn
)) or die;
my $api_key = $args{api_key};
my $lib_dir = $args{lib_dir};
my $cxn = $args{Cxn};
# During initial connection and agent init, wait less time
# than --check-interval between errors.
@@ -4866,6 +4869,7 @@ sub connect_to_percona {
interval => $init_wait,
lib_dir => $lib_dir,
agents_link => $entry_links->{agents},
Cxn => $cxn,
);
return $client, $agent;
@@ -4920,11 +4924,13 @@ sub init_agent {
interval
lib_dir
agents_link
Cxn
)) or die;
my $client = $args{client};
my $interval = $args{interval};
my $lib_dir = $args{lib_dir};
my $agents_link = $args{agents_link};
my $cxn = $args{Cxn};
# Optional args
my $versions = $args{versions};
@@ -4934,7 +4940,22 @@ sub init_agent {
# Do a version-check every time the agent starts. If versions
# have changed, this can affect how services are implemented.
$versions ||= get_versions();
if ( !$versions ) {
TRY:
for ( 1..3 ) {
eval {
$cxn->connect();
};
if ( $EVAL_ERROR ) {
_warn("Cannot connect to MySQL: $EVAL_ERROR");
$interval->();
next TRY;
}
$versions = get_versions(dbh => $cxn->dbh, dsn => $cxn->dsn);
$cxn->dbh->disconnect();
last TRY;
}
}
# If there's a saved agent, then this is an existing agent being
# restarted. Else this is a new agent.
@@ -5387,13 +5408,19 @@ sub run_service {
# Take a quick look through all the tasks to see if any
# will require a MySQL connection. If so, connect now.
if ( grep { $_->query } @$tasks ) {
eval {
$cxn->connect();
};
if ( $EVAL_ERROR ) {
_warn("Cannot connect to MySQL: $EVAL_ERROR");
return 1;
TRY:
for ( 1..3 ) {
eval {
$cxn->connect();
};
if ( $EVAL_ERROR ) {
_warn("Cannot connect to MySQL: $EVAL_ERROR");
sleep(5);
next TRY;
}
last TRY;
}
return 1 unless $cxn->dbh;
}
my @output_files;
@@ -5760,12 +5787,54 @@ sub _err {
exit $exit_status;
}
# TODO: use VersionCheck::get_versions().
sub get_versions {
return {
'Perl' => sprintf('%vd', $PERL_VERSION),
'Percona::WebAPI::Client' => "$Percona::WebAPI::Client::VERSION",
};
my (%args) = @_;
my $dbh = $args{dbh};
my $dsn = $args{dsn};
# This is currently the actual response from GET v.percona.com
my $fake_response = <<EOL;
OS;os_version
MySQL;mysql_variable;version_comment,version
Perl;perl_version
DBD::mysql;perl_module_version
Percona::Toolkit;perl_module_version
EOL
my $items = VersionCheck::parse_server_response(
response => $fake_response,
);
my ($name, $id) = VersionCheck::get_instance_id(
{ dbh => $dbh, dsn => $dsn },
);
my $instances = [
{ name => $name, id => $id, dbh => $dbh, dsn => $dsn },
{ name => 'system', id => 0, },
];
my $versions = VersionCheck::get_versions(
items => $items,
instances => $instances,
);
my %version_for;
foreach my $item ( sort keys %$items ) {
next unless exists $versions->{$item};
if ( ref($versions->{$item}) eq 'HASH' ) {
my $mysql_versions = $versions->{$item};
for my $id ( sort keys %$mysql_versions ) {
$version_for{$item} = $mysql_versions->{$id};
}
}
else {
$version_for{$item} = $versions->{$item};
}
}
PTDEBUG && _d('Versions:', Dumper(\%version_for));
return \%version_for;
}
# Catches signals so we can exit gracefully.

View File

@@ -23,9 +23,10 @@ package Percona::Test::Mock::UserAgent;
sub new {
my ($class, %args) = @_;
my $self = {
encode => $args{encode} || sub { return $_[0] },
decode => $args{decode} || sub { return $_[0] },
requests => [],
encode => $args{encode} || sub { return $_[0] },
decode => $args{decode} || sub { return $_[0] },
requests => [],
request_objs => [],
responses => {
get => [],
post => [],
@@ -35,14 +36,16 @@ sub new {
post => [],
put => [],
},
last_request => undef,
};
return bless $self, $class;
}
sub request {
my ($self, $req) = @_;
$self->{last_request} = $req;
if ( scalar @{$self->{request_objs}} > 10 ) {
$self->{request_objs} = [];
}
push @{$self->{request_objs}}, $req;
my $type = lc($req->method);
push @{$self->{requests}}, uc($type) . ' ' . $req->uri;
if ( $type eq 'post' || $type eq 'put' ) {

View File

@@ -33,8 +33,6 @@ use warnings FATAL => 'all';
use English qw(-no_match_vars);
use constant PTDEVDEBUG => $ENV{PTDEVDEBUG} || 0;
use Percona::Toolkit;
use Carp qw(croak);
use Test::More;

View File

@@ -13,10 +13,24 @@ use Test::More;
use JSON;
use File::Temp qw(tempdir);
use Percona::Test;
use PerconaTest;
use Sandbox;
use Percona::Test::Mock::UserAgent;
require "$trunk/bin/pt-agent";
my $dp = new DSNParser(opts=>$dsn_opts);
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
my $dbh = $sb->get_dbh_for('master');
my $dsn = $sb->dsn_for('master');
my $o = new OptionParser();
$o->get_specs("$trunk/bin/pt-agent");
$o->get_opts();
my $cxn = Cxn->new(
dsn_string => $dsn,
OptionParser => $o,
DSNParser => $dp,
);
Percona::Toolkit->import(qw(Dumper));
Percona::WebAPI::Representation->import(qw(as_hashref));
@@ -47,8 +61,6 @@ my $return_agent = {
uuid => '123',
hostname => `hostname`,
versions => {
'Percona::WebAPI::Client' => "$Percona::WebAPI::Client::VERSION",
'Perl' => sprintf('%vd', $PERL_VERSION),
},
links => {
self => '/agents/123',
@@ -86,6 +98,7 @@ my $output = output(
interval => $interval,
agents_link => "/agents",
lib_dir => $tmpdir,
Cxn => $cxn,
);
},
stderr => 1,
@@ -118,6 +131,21 @@ like(
"Saved new Agent"
) or diag($output);
my $sent_versions = decode_json($ua->{request_objs}->[0]->content);
my $os = VersionCheck::get_os_version();
is(
$sent_versions->{versions}->{OS} || '',
$os,
"Sent OS version"
) or diag(Dumper($sent_versions));
like(
$sent_versions->{versions}->{MySQL} || '',
qr/$sandbox_version/,
"Sent MySQL version"
) or diag(Dumper($sent_versions));
# Repeat this test but this time fake an error, so the tool isn't
# able to create the Agent first time, so it should wait (call
# interval), and try again.
@@ -158,6 +186,7 @@ $output = output(
interval => $interval,
agents_link => '/agents',
lib_dir => $tmpdir,
Cxn => $cxn,
);
},
stderr => 1,
@@ -242,6 +271,7 @@ $output = output(
interval => $interval,
agents_link => '/agents',
lib_dir => $tmpdir,
Cxn => $cxn,
);
},
stderr => 1,
@@ -277,4 +307,5 @@ is_deeply(
# #############################################################################
# Done.
# #############################################################################
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
done_testing;

View File

@@ -139,7 +139,7 @@ ok(
);
is(
$ua->{last_request}->header('content-type'),
$ua->{request_objs}->[-1]->header('content-type'),
'multipart/form-data; boundary=Ym91bmRhcnk',
'Content-Type=multipart/form-data; boundary=Ym91bmRhcnk'
) or diag(Dumper($ua));