feat: support OCI index images (such as produced by buildkit cache exports) (#227)
fixes #227
This commit is contained in:
parent
7c0874694a
commit
05cbb51125
|
@ -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();
|
||||
},
|
||||
|
|
|
@ -15,27 +15,27 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<image-date>
|
||||
<div title="Creation date { getLocalDate(props.image) }">{ getDate(props.image) } ago</div>
|
||||
<div title="Creation date { getLocalDate(props.image) }">{ getDate(props.image) }</div>
|
||||
<script>
|
||||
import {
|
||||
dateFormat,
|
||||
} from '../../scripts/utils';
|
||||
import { dateFormat } from '../../scripts/utils';
|
||||
export default {
|
||||
onMounted(props) {
|
||||
props.image.one('creation-date', (date) => {
|
||||
this.update({
|
||||
date: date,
|
||||
localDate: date.toLocaleString()
|
||||
localDate: date && date.toLocaleString(),
|
||||
});
|
||||
});
|
||||
props.image.trigger('get-date');
|
||||
},
|
||||
getDate(image) {
|
||||
return dateFormat(image.creationDate)
|
||||
return !image.ociImage ? `${dateFormat(image.creationDate)} ago` : 'Not Available';
|
||||
},
|
||||
getLocalDate(image) {
|
||||
return (image.creationDate && image.creationDate.toLocaleString()) || 'unknown'
|
||||
}
|
||||
}
|
||||
return !image.ociImage
|
||||
? (image.creationDate && image.creationDate.toLocaleString()) || 'unknown'
|
||||
: 'unavailable on OCI index/Buildkit export cache';
|
||||
},
|
||||
};
|
||||
</script>
|
||||
</image-date>
|
||||
</image-date>
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
</image-tag>
|
||||
</image-tag>
|
||||
|
|
|
@ -15,16 +15,34 @@ You should have received a copy of the GNU Affero General Public License
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<tag-history-button>
|
||||
<material-button title="This will show the history of given tag" waves-center="true" rounded="true" waves-color="#ddd"
|
||||
onClick="{ routeToHistory }">
|
||||
<material-button
|
||||
title="{ buttonTittle() }"
|
||||
waves-center="true"
|
||||
rounded="true"
|
||||
waves-color="#ddd"
|
||||
onClick="{ routeToHistory }"
|
||||
disabled="{ props.image.ociImage }"
|
||||
>
|
||||
<i class="material-icons">history</i>
|
||||
</material-button>
|
||||
<script>
|
||||
import router from '../../scripts/router';
|
||||
export default {
|
||||
onMounted(props) {
|
||||
props.image.one('oci-image', () => {
|
||||
this.update();
|
||||
});
|
||||
},
|
||||
buttonTittle() {
|
||||
return !this.props.image.ociImage
|
||||
? 'This will show the history of given tag'
|
||||
: 'History is unavailable on OCI index/Buildkit export cache';
|
||||
},
|
||||
routeToHistory() {
|
||||
router.history(this.props.image.name, this.props.image.tag)
|
||||
}
|
||||
}
|
||||
if (!this.props.image.ociImage) {
|
||||
router.history(this.props.image.name, this.props.image.tag);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
</tag-history-button>
|
||||
</tag-history-button>
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue