Skip to content

Commit

Permalink
Configure each OBS instance individually
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Oct 15, 2024
1 parent ba047d7 commit 4f21851
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 112 deletions.
12 changes: 9 additions & 3 deletions cavil.conf
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,16 @@
well_known_url => 'https://id.opensuse.org/openidc/.well-known/openid-configuration'
},

# Optional SSH authentication credentials for the Open Build Service
# Authentication credentials for the Open Build Service (Basic or SSH)
obs => {
user => 'NAME',
ssh_key => 'SSH_PRIVATE_KEY_PATH'
'api.opensuse.org' => {
user => 'OBS_USER',
password => 'OBS_PASSWORD'
},
'api.suse.de' => {
user => 'IBS_USER',
ssh_key => 'SSH_PRIVATE_KEY_PATH'
}
},

# Token authentication strings for the dedicated bot REST API
Expand Down
3 changes: 1 addition & 2 deletions lib/Cavil.pm
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ sub startup ($self) {

# Optional OBS credentials
if (my $obs = $config->{obs}) {
$self->obs->user($obs->{user}) if $obs->{user};
$self->obs->ssh_key($obs->{ssh_key}) if $obs->{ssh_key};
$self->obs->config($obs);
}

# Short logs for systemd
Expand Down
46 changes: 25 additions & 21 deletions lib/Cavil/OBS.pm
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ use Mojo::UserAgent;
use Mojo::URL;
use Cavil::Util qw(obs_ssh_auth);

has ssh_hosts => sub { ['api.suse.de'] };
has ssh_key => sub { die 'Missing ssh key' };
has ua => sub {
has config => sub { {} };
has ua => sub {
my $ua = Mojo::UserAgent->new(inactivity_timeout => 600);
$ua->on(
start => sub ($ua, $tx) {
Expand All @@ -39,15 +38,14 @@ has ua => sub {
);
return $ua;
};
has user => sub { die 'Missing ssh user' };

sub check_for_embargo ($self, $api, $request) {
my $url = _url($api, 'public', 'request', $request);
my $url = _url($api, 'request', $request);
my $res = $self->_get($url);
croak "$url: " . $res->code unless $res->is_success;

for my $project ($res->dom->find('action [project]')->map('attr', 'project')->uniq->each) {
my $url = _url($api, 'public', 'source', $project, '_attribute');
my $url = _url($api, 'source', $project, '_attribute');
my $res = $self->_get($url);
my $code = $res->code;
next if $code == 404;
Expand All @@ -68,7 +66,7 @@ sub download_source ($self, $api, $project, $pkg, $dir, $options = {}) {
$dir = path($dir)->make_path;

# List files
my $url = _url($api, 'public', 'source', $project, $pkg)->query(expand => 1);
my $url = _url($api, 'source', $project, $pkg)->query(expand => 1);
$url->query([rev => $options->{rev}]) if defined $options->{rev};
my $res = $self->_get($url);
croak "$url: " . $res->code unless $res->is_success;
Expand All @@ -82,7 +80,7 @@ sub download_source ($self, $api, $project, $pkg, $dir, $options = {}) {
# We've actually seen this in IBS (usually a checksum mismatch)
next if $file->{name} eq '_meta';

my $url = _url($api, 'public', 'source', $project, $pkg, $file->{name});
my $url = _url($api, 'source', $project, $pkg, $file->{name});
$url->query([expand => 1, rev => $srcmd5]);
my $res = $self->_get($url);
croak "$url: " . $res->code unless $res->is_success;
Expand All @@ -94,7 +92,7 @@ sub download_source ($self, $api, $project, $pkg, $dir, $options = {}) {
}

sub package_info ($self, $api, $project, $pkg, $options = {}) {
my $url = _url($api, 'public', 'source', $project, $pkg)->query(view => 'info');
my $url = _url($api, 'source', $project, $pkg)->query(view => 'info');
$url->query([rev => $options->{rev}]) if defined $options->{rev};
my $res = $self->_get($url);
croak "$url: " . $res->code unless $res->is_success;
Expand All @@ -109,7 +107,7 @@ sub package_info ($self, $api, $project, $pkg, $options = {}) {
}

sub _find_link_target ($self, $api, $project, $pkg, $lrev) {
my $url = _url($api, 'public', 'source', $project, $pkg);
my $url = _url($api, 'source', $project, $pkg);
my $query = {expand => 1};
$query->{rev} = $lrev if defined $lrev;
$url->query($query);
Expand All @@ -127,7 +125,7 @@ sub _find_link_target ($self, $api, $project, $pkg, $lrev) {
return $linfo unless $match && !$linfo->{match};
}
}
$url = _url($api, 'public', 'source', $project, $pkg, '_meta');
$url = _url($api, 'source', $project, $pkg, '_meta');
$res = $self->_get($url);

# This is severe as we already checked the sources
Expand All @@ -141,18 +139,24 @@ sub _find_link_target ($self, $api, $project, $pkg, $lrev) {
sub _get ($self, $url) {
my $ua = $self->ua;

# "api.suse.de" does not have public API endpoints
my $host = $url->host;
my $path = $url->path;
my $hosts = $self->ssh_hosts;
shift @{$path->parts} if (grep { $host eq $_ } @$hosts) && $path->parts->[0] eq 'public';

my $tx = $ua->get($url);
my $host = $url->host;
die "Missing configuration for OBS instance: $host" unless my $config = $self->config->{$host};
die "Missing user for OBS instance: $host" unless my $user = $config->{user};

# "api.suse.de" needs ssh authentication
my $res = $tx->res;
$tx = $ua->get($url, {Authorization => obs_ssh_auth($res->headers->www_authenticate, $self->user, $self->ssh_key)})
if $res->code == 401;
my $tx;
if (my $ssh_key = $config->{ssh_key}) {
$tx = $ua->get($url);
my $res = $tx->res;
$tx = $ua->get($url, {Authorization => obs_ssh_auth($res->headers->www_authenticate, $user, $ssh_key)})
if $res->code == 401;
}

# All other instances should use basic authentication
else {
die "Missing password for OBS instance: $host" unless my $password = $config->{password};
$tx = $ua->get($url->userinfo("$user:$password"));
}

return $tx->result;
}
Expand Down
13 changes: 6 additions & 7 deletions t/api.t
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,15 @@ $routes->add_condition(
}
);
$routes->get(
'/public/source/:project/perl-Mojolicious' => [project => ['devel:languages:perl']] => (query => {view => 'info'}) =>
'/source/:project/perl-Mojolicious' => [project => ['devel:languages:perl']] => (query => {view => 'info'}) =>
{text => <<'EOF'});
<sourceinfo package="perl-Mojolicious" rev="69" vrev="1"
srcmd5="236d7b56886a0d2799c0d114eddbb7f1"
verifymd5="236d7b56886a0d2799c0d114eddbb7f1">
<filename>perl-Mojolicious.spec</filename>
</sourceinfo>
EOF
$routes->get(
'/public/source/:project/perl-Mojolicious' => [project => ['devel:languages:perl']] => (query => {expand => 1}) =>
$routes->get('/source/:project/perl-Mojolicious' => [project => ['devel:languages:perl']] => (query => {expand => 1}) =>
{text => <<'EOF'});
<directory name="perl-Mojolicious" rev="4bf9ea937901cae5816321f8ebbf2ee1"
vrev="160" srcmd5="4bf9ea937901cae5816321f8ebbf2ee1">
Expand All @@ -76,8 +75,7 @@ $routes->get(
size="2420" mtime="1496988145" />
</directory>
EOF
$routes->get(
'/public/source/:project/perl-Mojolicious/_meta' => [project => ['devel:languages:perl']] => {text => <<'EOF'});
$routes->get('/source/:project/perl-Mojolicious/_meta' => [project => ['devel:languages:perl']] => {text => <<'EOF'});
<package name="perl-Mojolicious" project="devel:languages:perl">
<title>The Web In A Box!</title>
<description>Test package</description>
Expand All @@ -86,10 +84,11 @@ $routes->get(
</package>
EOF
my @files = qw(Mojolicious-7.25.tar.gz perl-Mojolicious.changes perl-Mojolicious.spec);
$routes->get("/public/source/:project/perl-Mojolicious/$_" => [project => ['devel:languages:perl']] =>
$routes->get("/source/:project/perl-Mojolicious/$_" => [project => ['devel:languages:perl']] =>
{data => path(__FILE__)->sibling('legal-bot', 'perl-Mojolicious', 'c7cfdab0e71b0bebfdf8b2dc3badfecd', $_)->slurp})
for @files;
my $api = 'http://127.0.0.1:' . $t->app->obs->ua->server->app($mock_app)->url->port;
$t->app->obs->config({'127.0.0.1' => {user => 'test', password => 'testing'}});

subtest 'Not authenticated' => sub {
$t->get_ok('/package/1')->status_is(403)->content_like(qr/permission/);
Expand Down Expand Up @@ -128,7 +127,7 @@ subtest 'Create package' => sub {
start => sub {
my $job = shift;
return unless $job->task eq 'obs_import';
$job->app->obs(Cavil::OBS->new);
$job->app->obs(Cavil::OBS->new(config => $job->app->obs->config));
my $api = 'http://127.0.0.1:' . $job->app->obs->ua->server->app($mock_app)->url->port;
$job->args->[1]{api} = $api;
}
Expand Down
15 changes: 8 additions & 7 deletions t/command_obs.t
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ app->routes->add_condition(
}
);

get '/public/source/:project/perl-Mojolicious' => [project => ['home:kraih']] => (query => {view => 'info'}) =>
get '/source/:project/perl-Mojolicious' => [project => ['home:kraih']] => (query => {view => 'info'}) =>
{text => <<'EOF'};
<sourceinfo package="perl-Mojolicious" rev="9199eca9ec0fa5cffe4c3a6cb99a8093"
vrev="140"
Expand All @@ -59,7 +59,7 @@ verifymd5="bb19066400b2b60e2310b45f10d12f56">
</sourceinfo>
EOF

get '/public/source/:project/perl-Mojolicious/_meta' => [project => ['home:kraih']] => {text => <<'EOF'};
get '/source/:project/perl-Mojolicious/_meta' => [project => ['home:kraih']] => {text => <<'EOF'};
<package name="postgresql-plr" project="server:database:postgresql">
<title>Mojolicious</title>
<description>
Expand All @@ -68,7 +68,7 @@ get '/public/source/:project/perl-Mojolicious/_meta' => [project => ['home:kraih
</package>
EOF

get '/public/source/:project/perl-Mojolicious' => [project => ['home:kraih']] =>
get '/source/:project/perl-Mojolicious' => [project => ['home:kraih']] =>
(query => {expand => 1, rev => [1, '0e5c2d1c0c4178869cf7fb82482b9c52']}) => {text => <<'EOF'};
<directory name="perl-Mojolicious" rev="9199eca9ec0fa5cffe4c3a6cb99a8093"
vrev="140" srcmd5="9199eca9ec0fa5cffe4c3a6cb99a8093">
Expand All @@ -83,14 +83,15 @@ get '/public/source/:project/perl-Mojolicious' => [p
</directory>
EOF

get '/public/source/:project/perl-Mojolicious/perl-Mojolicious.spec' => [project => ['home:kraih']] =>
(query => {rev => '9199eca9ec0fa5cffe4c3a6cb99a8093'}) => {text => 'Mojolicious spec!'};
get '/source/:project/perl-Mojolicious/perl-Mojolicious.spec' => [project => ['home:kraih']] =>
(query => {rev => '9199eca9ec0fa5cffe4c3a6cb99a8093'}) => {text => 'Mojolicious spec!'};

get '/public/source/:project/perl-Mojolicious/:special' => [project => ['home:kraih']] =>
get '/source/:project/perl-Mojolicious/:special' => [project => ['home:kraih']] =>
(query => {rev => '9199eca9ec0fa5cffe4c3a6cb99a8093'}) => [special => ['perl-Mojo#licious.changes']] =>
{text => 'Mojolicious changes!'};

my $api = 'http://127.0.0.1:' . $app->obs->ua->server->app(app)->url->port;
my $api = 'http://127.0.0.1:'
. $app->obs->config({'127.0.0.1' => {user => 'test', password => 'testing'}})->ua->server->app(app)->url->port;

subtest 'OBS' => sub {
subtest 'Info' => sub {
Expand Down
21 changes: 11 additions & 10 deletions t/embargo.t
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@ app->routes->add_condition(
}
);

get '/public/source/:project/perl-Mojolicious.SUSE_SLE-15-SP2_Update' => [project => ['SUSE:Maintenance:4321']] =>
(query => {view => 'info'}) => {text => <<'EOF'};
get '/source/:project/perl-Mojolicious.SUSE_SLE-15-SP2_Update' => [project => ['SUSE:Maintenance:4321']] =>
(query => {view => 'info'}) => {text => <<'EOF'};
<sourceinfo package="perl-Mojolicious" rev="69" vrev="1"
srcmd5="236d7b56886a0d2799c0d114eddbb7ff"
verifymd5="236d7b56886a0d2799c0d114eddbb7ff">
<filename>perl-Mojolicious.spec</filename>
</sourceinfo>
EOF

get '/public/source/:project/perl-Mojolicious.SUSE_SLE-15-SP2_Update' => [project => ['SUSE:Maintenance:4321']] =>
(query => {expand => 1}) => {text => <<'EOF'};
get '/source/:project/perl-Mojolicious.SUSE_SLE-15-SP2_Update' => [project => ['SUSE:Maintenance:4321']] =>
(query => {expand => 1}) => {text => <<'EOF'};
<directory name="perl-Mojolicious.SUSE_SLE-15-SP2_Update" rev="4bf9ea937901cae5816321f8ebbf2ee1"
vrev="160" srcmd5="4bf9ea937901cae5816321f8ebbf2ee1">
<linkinfo project="openSUSE:Factory" package="perl-Mojolicious.SUSE_SLE-15-SP2_Update"
Expand All @@ -69,8 +69,8 @@ get '/public/source/:project/perl-Mojolicious.SUSE_SLE-15-SP2_Update' => [projec
</directory>
EOF

get '/public/source/:project/perl-Mojolicious.SUSE_SLE-15-SP2_Update/_meta' =>
[project => ['SUSE:Maintenance:4321']] => {text => <<'EOF'};
get '/source/:project/perl-Mojolicious.SUSE_SLE-15-SP2_Update/_meta' => [project => ['SUSE:Maintenance:4321']] =>
{text => <<'EOF'};
<package name="perl-Mojolicious.SUSE_SLE-15-SP2_Update" project="SUSE:Maintenance:4321">
<title>Job Queue</title>
<description>Test package</description>
Expand All @@ -80,11 +80,11 @@ get '/public/source/:project/perl-Mojolicious.SUSE_SLE-15-SP2_Update/_meta' =>
EOF

my @files = qw(Mojolicious-7.25.tar.gz perl-Mojolicious.changes perl-Mojolicious.spec);
get("/public/source/:project/perl-Mojolicious.SUSE_SLE-15-SP2_Update//$_" => [project => ['SUSE:Maintenance:4321']] =>
get("/source/:project/perl-Mojolicious.SUSE_SLE-15-SP2_Update//$_" => [project => ['SUSE:Maintenance:4321']] =>
{data => path(__FILE__)->sibling('legal-bot', 'perl-Mojolicious', 'c7cfdab0e71b0bebfdf8b2dc3badfecd', $_)->slurp})
for @files;

get '/public/request/4321' => {text => <<'EOF'};
get '/request/4321' => {text => <<'EOF'};
<request id="4321" creator="test2">
<action type="maintenance_release">
<source project="SUSE:Maintenance:4321" package="perl-Mojolicious.SUSE_SLE-15-SP2_Update"
Expand All @@ -95,7 +95,7 @@ get '/public/request/4321' => {text => <<'EOF'};
</request>
EOF

get '/public/source/:project/_attribute' => [project => 'SUSE:Maintenance:4321'] => {text => <<'EOF'};
get '/source/:project/_attribute' => [project => 'SUSE:Maintenance:4321'] => {text => <<'EOF'};
<attributes>
<attribute name="EmbargoDate" namespace="OBS">
<value>2024-03-27 07:00 UTC</value>
Expand All @@ -113,6 +113,7 @@ my $dir = $cavil_test->checkout_dir;
# Connect mock web service
my $mock_app = app;
my $api = 'http://127.0.0.1:' . $t->app->obs->ua->server->app($mock_app)->url->port;
$t->app->obs->config({'127.0.0.1' => {user => 'test', password => 'testing'}});

subtest 'Embargoed package does not existy yet' => sub {
$t->get_ok('/package/3' => {Authorization => 'Token test_token'})->status_is(404)->content_like(qr/No such package/);
Expand Down Expand Up @@ -141,7 +142,7 @@ subtest 'Embargoed packages' => sub {
my $job = shift;
my $task = $job->task;
return unless $task eq 'obs_import' || $task eq 'obs_embargo';
$job->app->obs(Cavil::OBS->new);
$job->app->obs(Cavil::OBS->new(config => $job->app->obs->config));
my $api = 'http://127.0.0.1:' . $job->app->obs->ua->server->app($mock_app)->url->port;
$job->args->[1]{api} = $api;
}
Expand Down
Loading

0 comments on commit 4f21851

Please sign in to comment.