fix: deleting cross-platform images leaves the deleted image in an unknown state (#226)

closes #226
This commit is contained in:
Joxit 2022-03-13 10:51:05 +01:00
parent 126509d7fa
commit 7c0874694a
No known key found for this signature in database
GPG key ID: F526592B8E012263

View file

@ -32,66 +32,80 @@
</div> </div>
</material-popup> </material-popup>
<script> <script>
import { import { Http } from '../../scripts/http';
Http
} from '../../scripts/http';
import router from '../../scripts/router'; import router from '../../scripts/router';
export default { export default {
displayImagesToDelete(toDelete, tags) { displayImagesToDelete(toDelete, tags) {
const digests = new Set(); const digests = new Set();
toDelete.forEach(image => { toDelete.forEach((image) => {
if (image.digest) { if (image.digest) {
digests.add(image.digest); digests.add(image.digest);
} }
}) });
return tags.filter(image => digests.has(image.digest)) return tags.filter((image) => digests.has(image.digest));
}, },
deleteImages() { deleteImages() {
this.props.toDelete.forEach(image => this.deleteImage(image, this.props)); this.props.toDelete.forEach((image) => this.getContentDigestThenDelete(image, this.props));
}, },
deleteImage(image, opts) { getContentDigestThenDelete({ name, tag }, opts) {
const { const { registryUrl, onNotify, onAuthentication } = opts;
registryUrl, const oReq = new Http({ onAuthentication });
ignoreError, const self = this;
onNotify, oReq.addEventListener('loadend', function () {
onAuthentication, if (this.status == 200 || this.status == 202) {
onClick oReq.getContentDigest(function (digest) {
} = opts; if (!digest) {
if (!image.digest) { onNotify(ERROR_CAN_NOT_READ_CONTENT_DIGEST);
onNotify(`Information for ${name}:${tag} are not yet loaded.`); } else {
return; self.deleteImage({ name, tag, digest }, opts);
} }
const name = image.name;
const tag = image.tag;
const oReq = new Http({
onAuthentication: onAuthentication
}); });
} else if (this.status == 404) {
onNotify(`Manifest for ${name}:${tag} not found`, true);
} else {
onNotify(this.responseText);
}
});
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'
);
oReq.send();
},
deleteImage({ name, tag, digest }, opts) {
const { registryUrl, ignoreError, onNotify, onAuthentication, onClick } = opts;
const oReq = new Http({ onAuthentication });
oReq.addEventListener('loadend', function () { oReq.addEventListener('loadend', function () {
if (this.status == 200 || this.status == 202) { if (this.status == 200 || this.status == 202) {
router.taglist(name); router.taglist(name);
onNotify(`Deleting ${name}:${tag} image. Run \`registry garbage-collect config.yml\` on your registry`); onNotify(`Deleting ${name}:${tag} image. Run \`registry garbage-collect config.yml\` on your registry`);
} else if (this.status == 404) { } else if (this.status == 404) {
ignoreError || onNotify({ ignoreError ||
onNotify({
message: 'Digest not found for this image in your registry.', message: 'Digest not found for this image in your registry.',
isError: true isError: true,
}); });
} else { } else {
onNotify(this.responseText); onNotify(this.responseText);
} }
onClick(); onClick();
}); });
oReq.open('DELETE', `${registryUrl}/v2/${name}/manifests/${image.digest}`); oReq.open('DELETE', `${registryUrl}/v2/${name}/manifests/${digest}`);
oReq.setRequestHeader('Accept', oReq.setRequestHeader(
'application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json'); 'Accept',
'application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json'
);
oReq.addEventListener('error', function () { oReq.addEventListener('error', function () {
onNotify({ onNotify({
message: 'An error occurred when deleting image. Check if your server accept DELETE methods Access-Control-Allow-Methods: [\'DELETE\'].', message:
isError: true "An error occurred when deleting image. Check if your server accept DELETE methods Access-Control-Allow-Methods: ['DELETE'].",
isError: true,
}); });
}); });
oReq.send(); oReq.send();
} },
} };
</script> </script>
<style> <style>
:host { :host {