[feat #42] Add sha256 for images tag

This commit is contained in:
Joxit 2018-06-17 22:48:04 +02:00
parent 354d3159bd
commit 3430878e7d
11 changed files with 102 additions and 33 deletions

View file

@ -25,6 +25,8 @@ This web user interface uses [Riot](https://github.com/Riot/riot) the react-like
- Display image size (see #30)
- Add Title when using REGISTRY_URL (see #28)
- Alpine and Debian based images with supports for arm32v7
- Copy `docker pull` command to clipbloard
- Show sha256 for specific tag (hover image tag)
## Getting Started

View file

@ -49,7 +49,7 @@ gulp.task('riot-tag', ['html'], function() {
});
gulp.task('riot-static-tag', ['html'], function() {
return gulp.src(['src/tags/catalog.tag', 'src/tags/app.tag', 'src/tags/taglist.tag', 'src/tags/copy-to-clipboard.tag', 'src/tags/remove-image.tag', 'src/tags/image-size.tag'])
return gulp.src(['src/tags/catalog.tag', 'src/tags/app.tag', 'src/tags/taglist.tag', 'src/tags/copy-to-clipboard.tag', 'src/tags/remove-image.tag', 'src/tags/image-size.tag', 'src/tags/image-tag.tag'])
.pipe(concat('tags-static.js'))
.pipe(riot())
.pipe(minifier({}, uglify))

View file

@ -15,7 +15,7 @@
"devDependencies": {
"del": "^3.0.0",
"gulp": "^3.9",
"gulp-clean-css": "^3.9.3",
"gulp-clean-css": "^3.9.4",
"gulp-concat": "^2.6.0",
"gulp-filter": "^5.1.0",
"gulp-htmlmin": "^3.0.0",
@ -27,7 +27,7 @@
"riot": "^3.10.0",
"riot-mui": "^0.1.1",
"riot-route": "^3.1.3",
"uglify-js": "^3.3.16",
"uglify-js": "^3.4.0",
"uglify-js-harmony": "^2.7.7"
}
}

View file

@ -40,6 +40,7 @@
<!-- build:js scripts/tags.js -->
<script src="tags/catalog.tag" type="riot/tag"></script>
<script src="tags/taglist.tag" type="riot/tag"></script>
<script src="tags/image-tag.tag" type="riot/tag"></script>
<script src="tags/remove-image.tag" type="riot/tag"></script>
<script src="tags/copy-to-clipboard.tag" type="riot/tag"></script>
<script src="tags/add.tag" type="riot/tag"></script>

View file

@ -322,6 +322,6 @@ select {
padding: 12px 5px;
}
.copy-to-clipboard a {
.copy-to-clipboard a:hover {
cursor: pointer;
}

View file

@ -93,6 +93,55 @@
const args = path.match(re)
if (args) return args.slice(1)
});
registryUI.DockerImage = function (name, tag) {
this.name = name;
this.tag = tag;
riot.observable(this);
this.on('get-size', function() {
if (this.size !== undefined) {
return this.trigger('size', this.size);
}
return this.fillInfo();
});
this.on('get-sha256', function() {
if (this.size !== undefined) {
return this.trigger('sha256', this.sha256);
}
return this.fillInfo();
});
};
registryUI.DockerImage.compare = function(e1, e2) {
return e1.tag.localeCompare(e2);
};
registryUI.DockerImage.prototype.fillInfo = function() {
if (this._fillInfoWaiting) {
return;
}
this._fillInfoWaiting = true;
var oReq = new Http();
var self = this;
oReq.addEventListener('loadend', function () {
if (this.status == 200 || this.status == 202) {
var response = JSON.parse(this.responseText);
self.size = response.layers.reduce(function (acc, e) {
return acc + e.size;
}, 0);
self.sha256 = response.config.digest;
self.trigger('size', self.size);
self.trigger('sha256', self.sha256);
} else if (this.status == 404) {
registryUI.errorSnackbar('Manifest for ' + self.name + ':' + self.tag + ' not found');
} else {
registryUI.snackbar(this.responseText);
}
});
oReq.open('GET', registryUI.url() + '/v2/' + self.name + '/manifests/' + self.tag);
oReq.setRequestHeader('Accept', 'application/vnd.docker.distribution.manifest.v2+json');
oReq.send();
}
route.start(true);
</script>
</app>

View file

@ -20,7 +20,7 @@
<i class="material-icons">content_copy</i>
</a>
<script type="text/javascript">
this.dockerCmd = 'docker pull ' + registryUI.cleanName() + '/' + opts.name + ':' + opts.tag;
this.dockerCmd = 'docker pull ' + registryUI.cleanName() + '/' + opts.image.name + ':' + opts.image.tag;
this.copy = function () {
var copyText = this.refs['input'];
copyText.style.display = 'block';

View file

@ -15,7 +15,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<image-size>
<div>{ this.bytesToSize(this.size) }</div>
<div title="Compressed size of your image.">{ this.bytesToSize(this.size) }</div>
<script type="text/javascript">
var self = this;
this.bytesToSize = function (bytes) {
@ -28,21 +28,10 @@
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return Math.ceil(bytes / Math.pow(1024, i)) + ' ' + sizes[i];
};
var oReq = new Http();
oReq.addEventListener('loadend', function () {
if (this.status == 200 || this.status == 202) {
self.size = JSON.parse(this.responseText).layers.reduce(function (acc, e) {
return acc + e.size;
}, 0);
self.update();
} else if (this.status == 404) {
registryUI.errorSnackbar('Manifest for ' + opts.name + ':' + opts.tag + ' not found');
} else {
registryUI.snackbar(this.responseText);
}
opts.image.on('size', function(size) {
self.size = size;
self.update();
});
oReq.open('GET', registryUI.url() + '/v2/' + opts.name + '/manifests/' + opts.tag);
oReq.setRequestHeader('Accept', 'application/vnd.docker.distribution.manifest.v2+json');
oReq.send();
opts.image.trigger('get-size');
</script>
</image-size>

27
src/tags/image-tag.tag Normal file
View file

@ -0,0 +1,27 @@
<!--
Copyright (C) 2016-2018 Jones Magloire @Joxit
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
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/>.
-->
<image-tag>
<div title="{ this.sha256 }">{ opts.image.tag }</div>
<script type="text/javascript">
var self = this;
opts.image.on('sha256', function(sha256) {
self.sha256 = sha256.substring(0, 19);
self.update();
});
opts.image.trigger('get-sha256');
</script>
</image-tag>

View file

@ -15,13 +15,12 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<remove-image>
<a href="#" title="Delete image." onclick="registryUI.removeImage.remove('{ opts.name }', '{ opts.tag }')">
<a href="#" title="This will delete the image." onclick="registryUI.removeImage.remove('{ opts.image.name }', '{ opts.image.tag }')">
<i class="material-icons">delete</i>
</a>
<script type="text/javascript">
registryUI.removeImage = registryUI.removeImage || {}
registryUI.removeImage.update = this.update;
registryUI.removeImage = registryUI.removeImage || {};
registryUI.removeImage.remove = function (name, tag) {
var oReq = new Http();
oReq.addEventListener('loadend', function () {

View file

@ -37,15 +37,15 @@
</tr>
</thead>
<tbody>
<tr each="{ item in registryUI.taglist.tags }">
<td class="material-card-th-left">{ registryUI.taglist.name }</td>
<tr each="{ image in registryUI.taglist.tags }">
<td class="material-card-th-left">{ image.name }</td>
<td class="copy-to-clipboard">
<copy-to-clipboard name={ registryUI.taglist.name } tag={ item }/>
<copy-to-clipboard image={ image }/>
</td>
<td><image-size name={ registryUI.taglist.name } tag={ item } /></td>
<td>{ item }</td>
<td><image-size image="{ image }" /></td>
<td><image-tag image="{ image }" /></td>
<td show="{ registryUI.isImageRemoveActivated }">
<remove-image name={ registryUI.taglist.name } tag={ item }/>
<remove-image image={ image }/>
</td>
</tr>
</tbody>
@ -62,7 +62,9 @@
registryUI.taglist.tags = [];
if (this.status == 200) {
registryUI.taglist.tags = JSON.parse(this.responseText).tags || [];
registryUI.taglist.tags.sort();
registryUI.taglist.tags = registryUI.taglist.tags.map(function(tag) {
return new registryUI.DockerImage(registryUI.taglist.name, tag);
}).sort(registryUI.DockerImage.compare);
} else if (this.status == 404) {
registryUI.snackbar('Server not found', true);
} else {
@ -90,7 +92,7 @@
registryUI.taglist.tags.reverse();
registryUI.taglist.asc = false;
} else {
registryUI.taglist.tags.sort();
registryUI.taglist.tags.sort(registryUI.DockerImage.compare);
registryUI.taglist.asc = true;
}
registryUI.taglist.instance.update();