mirror of
https://github.com/Joxit/docker-registry-ui.git
synced 2025-04-28 16:09:54 +03:00
fix: deleting cross-platform images leaves the deleted image in an unknown state (#226)
closes #226
This commit is contained in:
parent
126509d7fa
commit
7c0874694a
1 changed files with 49 additions and 35 deletions
|
@ -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 {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue