From cdec55dc8417f0e221d8edd61c2e45f410a2992b Mon Sep 17 00:00:00 2001 From: Carlos Salguero Date: Wed, 14 Feb 2018 12:54:02 -0300 Subject: [PATCH] PMM-1479 Switched to UUID for version check In order to be able to count individual users for the usage stats, we need to implement UUID instead of just using MD5(hostname) since most servers are just 'localhost' or 'db1'. Using UUID we would be able to count unique users. --- lib/VersionCheck.pm | 60 ++++++++++++++++++++++++++++++++++++++------ t/lib/VersionCheck.t | 18 ++++++++++++- 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/lib/VersionCheck.pm b/lib/VersionCheck.pm index 0c126d11..b612dd04 100644 --- a/lib/VersionCheck.pm +++ b/lib/VersionCheck.pm @@ -48,6 +48,14 @@ eval { require HTTP::Micro; }; +my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; +my @vc_dirs = ( + '/etc/percona', + '/etc/percona-toolkit', + '/tmp', + "$home", +); + # Return the version check file used to keep track of # MySQL instance that have been checked and when. Some # systems use random tmp dirs; we don't want that else @@ -55,13 +63,6 @@ eval { # per system is the goal, so prefer global sys dirs first. { my $file = 'percona-version-check'; - my $home = $ENV{HOME} || $ENV{HOMEPATH} || $ENV{USERPROFILE} || '.'; - my @vc_dirs = ( - '/etc/percona', - '/etc/percona-toolkit', - '/tmp', - "$home", - ); sub version_check_file { foreach my $dir ( @vc_dirs ) { @@ -326,6 +327,49 @@ sub get_instance_id { return $name, $id; } + +# This function has been implemented solely to be able to count individual +# Toolkit users for statistics. It uses a random UUID, no client info is +# being gathered nor stored +sub get_uuid { + my $uuid_file = '/.percona-toolkit.uuid'; + foreach my $dir (@vc_dirs) { + my $filename = $dir.$uuid_file; + my $uuid=_read_uuid($filename); + return $uuid if $uuid; + } + + my $filename = $ENV{"HOME"} . $uuid_file; + my $uuid = _generate_uuid(); + + open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; + print $fh $uuid; + close $fh; + + return $uuid; +} + +sub _generate_uuid { + return sprintf+($}="%04x")."$}-$}-$}-$}-".$}x3,map rand 65537,0..7; +} + +sub _read_uuid { + my $filename = shift; + my $fh; + + eval { + open($fh, '<:encoding(UTF-8)', $filename); + }; + return if ($EVAL_ERROR); + + my $uuid; + eval { $uuid = <$fh>; }; + return if ($EVAL_ERROR); + + chomp $uuid; + return $uuid; +} + # ############################################################################# # Protocol handlers # ############################################################################# @@ -387,7 +431,7 @@ sub pingback { my $client_content = encode_client_response( items => $items, versions => $versions, - general_id => md5_hex( hostname() ), + general_id => get_uuid(), ); my $client_response = { diff --git a/t/lib/VersionCheck.t b/t/lib/VersionCheck.t index ba9881a5..30436a68 100644 --- a/t/lib/VersionCheck.t +++ b/t/lib/VersionCheck.t @@ -201,7 +201,7 @@ is_deeply( # Former Pingback tests # ############################################################################# -my $general_id = md5_hex( hostname() ); +my $general_id = VersionCheck::get_uuid(); my $master_id; # the instance ID, _not_ 12345 etc. my $slave1_id; # the instance ID, _not_ 12346 etc. my ($mysql_ver, $mysql_distro); @@ -679,6 +679,22 @@ foreach my $tool ( @vc_tools ) { ); } +my $should_remove_uuid_file; +my $home_uuid_file = $ENV{"HOME"} . "/.percona-toolkit.uuid"; + +if ( ! -e $home_uuid_file ) { + $should_remove_uuid_file = 1; +} + +my $uuid = VersionCheck::get_uuid(); +is ( + length($uuid), + 36, + "Have a valid UUID4", +); + +unlink $home_uuid_file if $should_remove_uuid_file; + # ############################################################################# # Done. # #############################################################################