From 05cbb5112582766827ba79d3dc3e9d3cc53fcfa0 Mon Sep 17 00:00:00 2001 From: Joxit Date: Sat, 19 Mar 2022 22:35:41 +0100 Subject: [PATCH] feat: support OCI index images (such as produced by buildkit cache exports) (#227) fixes #227 --- .../dialogs/confirm-delete-image.riot | 2 +- src/components/tag-list/image-date.riot | 20 ++++++------- src/components/tag-list/image-tag.riot | 8 ++--- .../tag-list/tag-history-button.riot | 30 +++++++++++++++---- src/scripts/docker-image.js | 19 ++++++++---- 5 files changed, 53 insertions(+), 26 deletions(-) diff --git a/src/components/dialogs/confirm-delete-image.riot b/src/components/dialogs/confirm-delete-image.riot index c14007a..85006a2 100644 --- a/src/components/dialogs/confirm-delete-image.riot +++ b/src/components/dialogs/confirm-delete-image.riot @@ -69,7 +69,7 @@ oReq.open('GET', `${registryUrl}/v2/${name}/manifests/${tag}`); oReq.setRequestHeader( 'Accept', - 'application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json, application/vnd.docker.distribution.manifest.list.v2+json' + 'application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json, application/vnd.docker.distribution.manifest.list.v2+json, application/vnd.oci.image.index.v1+json' ); oReq.send(); }, diff --git a/src/components/tag-list/image-date.riot b/src/components/tag-list/image-date.riot index 33d69b9..91b2c90 100644 --- a/src/components/tag-list/image-date.riot +++ b/src/components/tag-list/image-date.riot @@ -15,27 +15,27 @@ along with this program. If not, see . --> -
{ getDate(props.image) } ago
+
{ getDate(props.image) }
-
\ No newline at end of file + diff --git a/src/components/tag-list/image-tag.riot b/src/components/tag-list/image-tag.riot index ad5dc62..c7e23ad 100644 --- a/src/components/tag-list/image-tag.riot +++ b/src/components/tag-list/image-tag.riot @@ -21,11 +21,11 @@ onMounted(props) { props.image.on('sha256', (sha256) => { this.update({ - sha256: sha256.substring(0, 19) + sha256: sha256 && sha256.substring(0, 19), }); }); props.image.trigger('get-sha256'); - } - } + }, + }; - \ No newline at end of file + diff --git a/src/components/tag-list/tag-history-button.riot b/src/components/tag-list/tag-history-button.riot index 77ca9a6..8595f18 100644 --- a/src/components/tag-list/tag-history-button.riot +++ b/src/components/tag-list/tag-history-button.riot @@ -15,16 +15,34 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . --> - + history - \ No newline at end of file + diff --git a/src/scripts/docker-image.js b/src/scripts/docker-image.js index ff1183d..9e701fc 100644 --- a/src/scripts/docker-image.js +++ b/src/scripts/docker-image.js @@ -56,6 +56,7 @@ export class DockerImage { onNotify, onAuthentication, }; + this.ociImage = false; observable(this); this.on('get-size', function () { if (this.size !== undefined) { @@ -107,11 +108,12 @@ export class DockerImage { self.variants = [image]; return; } - self.size = response.layers.reduce(function (acc, e) { + self.ociImage = response.mediaType === 'application/vnd.oci.image.index.v1+json'; + self.layers = self.ociImage ? response.manifests : response.layers; + self.size = self.layers.reduce(function (acc, e) { return acc + e.size; }, 0); - self.sha256 = response.config.digest; - self.layers = response.layers; + self.sha256 = response.config && response.config.digest; self.trigger('size', self.size); self.trigger('sha256', self.sha256); oReq.getContentDigest(function (digest) { @@ -121,7 +123,14 @@ export class DockerImage { self.opts.onNotify(ERROR_CAN_NOT_READ_CONTENT_DIGEST); } }); - self.getBlobs(response.config.digest); + if (!self.ociImage) { + self.getBlobs(self.sha256); + } else { + // Force updates + self.trigger('creation-date'); + self.trigger('blobs'); + self.trigger('oci-image'); + } } else if (this.status == 404) { self.opts.onNotify(`Manifest for ${self.name}:${self.tag} not found`, true); } else { @@ -131,7 +140,7 @@ export class DockerImage { oReq.open('GET', `${this.opts.registryUrl}/v2/${self.name}/manifests/${self.tag}`); oReq.setRequestHeader( 'Accept', - 'application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json' + + 'application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json, application/vnd.oci.image.index.v1+json' + (self.opts.list ? ', application/vnd.docker.distribution.manifest.list.v2+json' : '') ); oReq.send();