Skip to content

Commit

Permalink
[backend] local registry: implement auto-converting from fat manifest…
Browse files Browse the repository at this point in the history
… to amd64 manifest

Google's kaniko does not support manifest lists yet. So we do what
the upstream registry also does: check the accept header and select
the amd64/linux entry from the manifest list if the list is not
accepted by the client.
  • Loading branch information
mlschroe committed Sep 27, 2018
1 parent 5811a64 commit c91fadc
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 1 deletion.
28 changes: 27 additions & 1 deletion src/backend/bs_repserver
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ use Digest::SHA ();
use List::Util;
use Symbol;
use Encode;
use JSON::XS ();

use BSConfiguration;
use BSRPC ':https';
Expand Down Expand Up @@ -4016,6 +4017,14 @@ sub checkconstraints {
return ({'entry' => \@comp_workers}, $BSXML::dir);
}

sub registry_select_manifest {
my ($mani, $goarch, $goos) = @_;
for my $m (@{$mani->{'manifests'} || []}) {
return $m->{'digest'} if $m->{'platform'} && $m->{'platform'}->{'architecture'} eq $goarch && $m->{'platform'}->{'os'} eq $goos;
}
return undef;
}

sub registry_manifest {
my ($cgi, $regrepo, $manifest) = @_;
my $repodir = "$registrydir/$regrepo";
Expand All @@ -4032,7 +4041,24 @@ sub registry_manifest {
die("404 MANIFEST_UNKNOWN\n") unless $mani_json;
my $mani_id = "sha256:".Digest::SHA::sha256_hex($mani_json);
my $mani = JSON::XS::decode_json($mani_json);
my $ct = $mani->{'mediaType'} || 'application/vnd.docker.distribution.manifest.v2+json';
my $manifestct = 'application/vnd.docker.distribution.manifest.v2+json';
my $manifestlistct = 'application/vnd.docker.distribution.manifest.list.v2+json';
my $ct = $mani->{'mediaType'} || $manifestct;
my $accept = BSServer::header('Accept');
if ($accept && $accept ne '*/*') {
# check if the client accepts the content type
my @accept = split(/[\s,]+/, $accept);
s/;.*// for @accept;
my %accept = map {lc($_) => 1} @accept;
if (!$accept{lc($ct)} && !$accept{'*/*'}) {
if (!$is_manifest && lc($ct) eq lc($manifestlistct) && $accept{lc($manifestct)}) {
my $digest = registry_select_manifest($mani, 'amd64', 'linux');
die("404 MANIFEST_UNKNOWN\n") unless $digest;
return registry_manifest($cgi, $regrepo, $digest);
}
die("406 MANIFEST_UNACCEPTED\n");
}
}
my @hdrs = ("Content-Type: $ct", "Docker-Content-Digest: $mani_id", "Etag: \"$mani_id\"");
push @hdrs, 'Cache-Control: max-age=2678400' if $is_manifest;
BSRegistryServer::reply($mani_json, "Content-Type: $ct", "Docker-Content-Digest: $mani_id", "Etag: \"$mani_id\"");
Expand Down
2 changes: 2 additions & 0 deletions src/backend/bs_srcserver
Original file line number Diff line number Diff line change
Expand Up @@ -6298,6 +6298,8 @@ sub registry_forward {
my @hdrs;
my $range = BSServer::header('Range');
push @hdrs, "Range: $range" if $range;
my $accept = BSServer::header('Accept');
push @hdrs, "Accept: $accept" if $accept;
my $param = {
'uri' => "$repserver/registry/$path",
'request' => $req->{'action'},
Expand Down

0 comments on commit c91fadc

Please sign in to comment.