Skip to content

Commit

Permalink
Add diagnostic job for checking presence of a file on mirrors
Browse files Browse the repository at this point in the history
  • Loading branch information
andrii-suse committed Nov 16, 2023
1 parent f105bad commit 863fb70
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 1 deletion.
15 changes: 15 additions & 0 deletions assets/javascripts/mirrorlist.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,18 @@ function initMap(lat, lng, idx) {
// setTimeout(function(){ marker.showPopup(); }, 500);
}

function checkFileOnMirrors(path) {
$.ajax({
url: '/rest/server/check_file?file=' + path,
type: "PUT",
dataType: 'json',
success: function(response) {
handleCheckFileOnMirror(response.job_id);
},
error: handleAdminTableApiError
});
}

function handleCheckFileOnMirror(job_id) {
$(location).attr('href', '/minion/jobs?id=' + job_id);
}
106 changes: 106 additions & 0 deletions lib/MirrorCache/Task/MirrorFileCheck.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Copyright (C) 2023 SUSE LLC
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, see <http://www.gnu.org/licenses/>.

package MirrorCache::Task::MirrorFileCheck;
use Mojo::Base 'Mojolicious::Plugin';

use Mojo::UserAgent;

sub register {
my ($self, $app) = @_;

$app->minion->add_task(mirror_file_check => sub { _check($app, @_) });
}

sub _check {
my ($app, $job, $path, $args) = (shift, shift, shift, ref $_[0] ? $_[0] : {@_});;
return $job->fail('Empty path is not allowed') unless $path;

my $minion = $app->minion;
my $schema = $app->schema;

# my $mirrors = $schema->resultset('Server')->search({country => 'de'});
my @mirrors = $schema->resultset('Server')->search({ enabled => '1' });
my ($countok, $counterr, $countoth) = (0, 0, 0);
my $concurrency = 8;
my $current = 0;
$concurrency = @mirrors unless $concurrency < @mirrors;
$job->note(_concurrency => $concurrency);

for (my $i = 0; $i < $concurrency; $i++){
my $m = shift @mirrors;
next unless $m;
my $id = $m->id;
my $urldir = $m->urldir;
$urldir = '/' unless $urldir;
my $url = $m->hostname . $m->urldir . $path;
# it looks that defining $ua outside the loop greatly increases overal memory usage footprint for the task
my $ua = Mojo::UserAgent->new->request_timeout(4)->connect_timeout(4);

my ($next, $then, $catch);
my $started = time();
$current++;


$next = sub {
$m = shift;
unless ($m) {
$current--;
unless ($current) {
Mojo::IOLoop->stop unless $current;
}
return;
};
$id = $m->id;
my $urldir = $m->urldir;
$urldir = '/' unless $urldir;
$url = $m->hostname . $m->urldir . $path;
$started = time();
return $ua->head_p($url)->then($then, $catch);
};

$then = sub {
my $tx = shift;
my $elapsed = int(1000*(time() - $started));
my $code = $tx->res->code;
$job->note($m->hostname => $code . " ($elapsed ms) id=$id " . $tx->req->url);
if ($code == 200) {
$countok++;
} elsif ($code > 399) {
$counterr++;
} else {
$countoth++;
}
$next->(shift @mirrors);
};

$catch = sub {
my $err = shift;
my $elapsed = int(1000*(time() - $started));
$job->note($m->hostname => $err . " ($elapsed ms) id=$id " . $url);
$counterr++;
$next->(shift @mirrors);
};

$ua->head_p($url)->then($then, $catch);
}
# sleep 5;

Mojo::IOLoop->start;
$job->note(_ok => $countok, _err => $counterr, _oth => $countoth);
$job->finish;
}

1;
1 change: 1 addition & 0 deletions lib/MirrorCache/WebAPI.pm
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ sub _setup_webui {
$rest_operator_r->post('/server/:id')->name('post_server')->to('table#update', table => 'Server');
$rest_operator_r->delete('/server/:id')->to('table#destroy', table => 'Server');
$rest_operator_r->put('/server/location/:id')->name('rest_put_server_location')->to('server_location#update_location');
$rest_operator_r->put('/server/check_file')->name('rest_put_server_check_file')->to('server_check_file#start');
$rest_operator_r->post('/server/note/#hostname')->name('rest_put_server_note')->to('server_note#ins');
$rest_operator_r->get('/server/note/#hostname')->name('rest_get_server_note')->to('server_note#list');
$rest_operator_r->get('/server/contact/#hostname')->name('rest_get_server_contact')->to('server_note#list_contact');
Expand Down
39 changes: 39 additions & 0 deletions lib/MirrorCache/WebAPI/Controller/Rest/ServerCheckFile.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright (C) 2023 SUSE LLC
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, see <http://www.gnu.org/licenses/>.

package MirrorCache::WebAPI::Controller::Rest::ServerCheckFile;
use Mojo::Base 'Mojolicious::Controller';
use Data::Dumper;

sub start {
my ($self) = @_;

my $path = $self->param("file");
return $self->render(code => 400, text => "Mandatory argument is missing") unless $path;

my $job_id;
eval {
$job_id = $self->minion->enqueue('mirror_file_check' => [$path]);
};
return $self->render(code => 500, text => Dumper($@)) unless $job_id;

return $self->render(
json => {
job_id => $job_id,
}
);
}

1;
4 changes: 3 additions & 1 deletion lib/MirrorCache/WebAPI/Plugin/Backstage.pm
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ sub register_tasks {
$app->plugin($_)
for (
qw(MirrorCache::Task::MirrorCheckFromStat),
qw(MirrorCache::Task::MirrorFileCheck),
qw(MirrorCache::Task::MirrorScanScheduleFromMisses),
qw(MirrorCache::Task::MirrorScanScheduleFromPathErrors),
qw(MirrorCache::Task::MirrorScanSchedule),
Expand Down Expand Up @@ -91,7 +92,8 @@ eval {
$app->minion->backend->no_txn(1) if $db eq 'mysql';

$self->register_tasks;
};
1;
} or $app->log->error($@);
# Enable the Minion Admin interface under /minion
my $auth =
$app->routes->under('/minion')->to('session#ensure_operator');
Expand Down
5 changes: 5 additions & 0 deletions templates/mirrorlist.html.ep
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ img.huechange1 { filter: hue-rotate(90deg) }


<script>
var is_operator = <%= (is_operator) ? 'true' : 'false' %>;
var preferred_url = "<%= $preferred_url %>";
var lat = <%= $lat %>;
var lng = <%= $lng %>;
Expand Down Expand Up @@ -168,4 +169,8 @@ var lng = <%= $lng %>;

<button onclick="toggleMap(<%=$lat%>,<%=$lng%>,3);">Toggle map</button>
<div id="mapAll" style="width: 600px; height: 400px; display: none"></div>
% if (is_operator) {
<button onclick="checkFileOnMirrors('<%= $cur_path %>');">Check file on mirrors</button>
% }
</div>

0 comments on commit 863fb70

Please sign in to comment.