Skip to content

Commit 9ebbbc3

Browse files
committed
fix: buildx multiarch image date and history not shown (#309)
Support images created with buildx and `--provenance true` fixes #309
1 parent d2222be commit 9ebbbc3

File tree

5 files changed

+1305
-4
lines changed

5 files changed

+1305
-4
lines changed

src/scripts/docker-image.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,26 @@
1414
* You should have received a copy of the GNU Affero General Public License
1515
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
*/
17-
import { Http } from './http';
18-
import { isDigit, eventTransfer, ERROR_CAN_NOT_READ_CONTENT_DIGEST } from './utils';
17+
import { Http } from './http.js';
18+
import { eventTransfer, ERROR_CAN_NOT_READ_CONTENT_DIGEST } from './utils.js';
1919
import observable from '@riotjs/observable';
2020

21+
export const supportListManifest = (response) => {
22+
if (response.mediaType === 'application/vnd.docker.distribution.manifest.list.v2+json') {
23+
return true;
24+
}
25+
if (response.mediaType === 'application/vnd.oci.image.index.v1+json' && Array.isArray(response.manifests)) {
26+
return !response.manifests.some(({ mediaType }) => mediaType !== 'application/vnd.oci.image.manifest.v1+json');
27+
}
28+
return false;
29+
};
30+
31+
export const filterWrongManifests = (response) => {
32+
return response.manifests.filter(
33+
({ annotations }) => !annotations || annotations['vnd.docker.reference.type'] !== 'attestation-manifest'
34+
);
35+
};
36+
2137
export class DockerImage {
2238
constructor(name, tag, { list, registryUrl, onNotify, onAuthentication, useControlCacheHeader }) {
2339
this.name = name;
@@ -73,8 +89,8 @@ export class DockerImage {
7389
oReq.addEventListener('loadend', function () {
7490
if (this.status === 200 || this.status === 202) {
7591
const response = JSON.parse(this.responseText);
76-
if (response.mediaType === 'application/vnd.docker.distribution.manifest.list.v2+json' && self.opts.list) {
77-
self.trigger('list', response);
92+
if (supportListManifest(response) && self.opts.list) {
93+
self.trigger('list', filterWrongManifests(response));
7894
const manifest = response.manifests[0];
7995
const image = new DockerImage(self.name, manifest.digest, { ...self.opts, list: false });
8096
eventTransfer(image, self);

test/docker-image.test.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { supportListManifest, filterWrongManifests } from '../src/scripts/docker-image.js';
2+
import { dockerManifestList } from './fixtures/docker-manifest-list.js';
3+
import { ociImageIndexLayer } from './fixtures/oci-image-index-layer.js';
4+
import { ociImageIndexManifest } from './fixtures/oci-image-index-manifest.js';
5+
import assert from 'assert';
6+
7+
describe('docker-image', () => {
8+
describe('supportListManifest', () => {
9+
/**
10+
* Manifest of an image created with:
11+
* docker buildx build --platform amd64,arm -t joxit/docker-registry-ui:buildx --push --provenance false .
12+
*/
13+
it('should support mediaType `application/vnd.docker.distribution.manifest.list.v2+json`', () => {
14+
assert.ok(supportListManifest(dockerManifestList['application/vnd.docker.distribution.manifest.list.v2+json']));
15+
});
16+
/**
17+
* Index of an image created with:
18+
* docker buildx build --platform amd64,arm -t joxit/docker-registry-ui:buildx --push --provenance true .
19+
*/
20+
it('should support mediaType `application/vnd.oci.image.index.v1+json`', () => {
21+
assert.ok(supportListManifest(ociImageIndexManifest['application/vnd.oci.image.index.v1+json']));
22+
});
23+
/**
24+
* Index of an image created with:
25+
* buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=. --export-cache type=registry,ref=joxit/docker-registry-ui:buildkit
26+
*/
27+
it('should not support mediaType `application/vnd.oci.image.index.v1+json` with layers (`application/vnd.oci.image.layer.v1.tar+gzip`)', () => {
28+
assert.ok(!supportListManifest(ociImageIndexLayer['application/vnd.oci.image.index.v1+json']));
29+
});
30+
});
31+
describe('supportListManifest', () => {
32+
it('should return all manifests for `application/vnd.docker.distribution.manifest.list.v2+json`', () => {
33+
assert.equal(
34+
filterWrongManifests(dockerManifestList['application/vnd.docker.distribution.manifest.list.v2+json']).length,
35+
2
36+
);
37+
});
38+
it('should return all manifests for `application/vnd.oci.image.index.v1+json`', () => {
39+
assert.equal(
40+
filterWrongManifests(ociImageIndexManifest['application/vnd.oci.image.index.v1+json']).length,
41+
2
42+
);
43+
});
44+
});
45+
});

0 commit comments

Comments
 (0)