Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/scripts/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,9 @@ registryUI.stripHttps = function (url) {
}
return url.replace(/^https?:\/\//, '');
};

registryUI.eventTransfer = function(from, to) {
from.on('*', function(event, param) {
to.trigger(event, param);
})
}
28 changes: 26 additions & 2 deletions src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ main {
font-weight: inherit;
}

material-card, pagination .conatianer {
material-card, material-tabs, pagination .conatianer {
max-width: 95%;
margin: auto;
margin-top: 20px;
Expand All @@ -68,11 +68,34 @@ pagination .conatianer .pagination-centered {

/* 1515px * 0.95 = 1440px */
@media screen and (min-width: 1515px){
material-card, pagination .conatianer {
material-card, material-tabs, pagination .conatianer {
max-width: 1440px;
}
}

material-tabs {
display: block;
-webkit-box-shadow: 0 2px 5px 0 rgba(0,0,0,.16), 0 2px 10px 0 rgba(0,0,0,.12);
-ms-box-shadow: 0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12);
-moz-box-shadow: 0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12);
-o-box-shadow: 0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12);
box-shadow: 0 2px 5px 0 rgba(0,0,0,.16), 0 2px 10px 0 rgba(0,0,0,.12);
}

material-tabs material-button,
material-tabs material-button .content .text {
background-color: #fff;
color: #aaa;
text-transform: none;
}

material-tabs .line-wrapper .line {
background-color: #25313b;
}
material-tabs material-button.selected .content .text {
color: #25313b;
}

material-spinner {
align-self: center;
}
Expand Down Expand Up @@ -474,6 +497,7 @@ tag-history-element {
display: block;
padding: 20px;
min-width: 100px;
min-height: 3em;
width: 420px;
float: left;
overflow-x: auto;
Expand Down
15 changes: 13 additions & 2 deletions src/tags/app.tag
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
return char >= '0' && char <= '9';
};

registryUI.DockerImage = function(name, tag) {
registryUI.DockerImage = function(name, tag, list) {
this.name = name;
this.tag = tag;
this.list = list;
this.chars = 0;
riot.observable(this);
this.on('get-size', function() {
Expand Down Expand Up @@ -192,6 +193,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
oReq.addEventListener('loadend', function() {
if (this.status == 200 || this.status == 202) {
const response = JSON.parse(this.responseText);
if (response.mediaType === 'application/vnd.docker.distribution.manifest.list.v2+json') {
self.trigger('list', response);
const manifest = response.manifests[0];
const image = new registryUI.DockerImage(self.name, manifest.digest)
registryUI.eventTransfer(image, self)
image.fillInfo()
self.variants = [image];
return;
}
self.size = response.layers.reduce(function(acc, e) {
return acc + e.size;
}, 0);
Expand All @@ -214,7 +224,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
}
});
oReq.open('GET', registryUI.url() + '/v2/' + self.name + '/manifests/' + self.tag);
oReq.setRequestHeader('Accept', 'application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json');
oReq.setRequestHeader('Accept', 'application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.manifest.v1+json'
+ (self.list ? ', application/vnd.docker.distribution.manifest.list.v2+json' : ''));
oReq.send();
};

Expand Down
1 change: 0 additions & 1 deletion src/tags/tag-history-button.tag
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
this.on('mount', function() {
const self = this;
this.refs.button.root.onclick = function() {
registryUI.taghistory._image = self.opts.image;
registryUI.taghistory.go(self.opts.image.name, self.opts.image.tag);
};
});
Expand Down
92 changes: 57 additions & 35 deletions src/tags/tag-history.tag
Original file line number Diff line number Diff line change
Expand Up @@ -26,46 +26,48 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</div>
</material-card>
<div hide="{ registryUI.taghistory.loadend }" class="spinner-wrapper">
<material-spinner/>
<material-spinner />
</div>

<material-tabs if="{ this.archs }" useLine="true" tabs="{ this.archs }" tabchanged="{ this.tabchanged }" />

<material-card each="{ guiElement in this.elements }" class="tag-history-element">
<tag-history-element each="{ entry in guiElement }" if="{ entry.value && entry.value.length > 0}"/>
<tag-history-element each="{ entry in guiElement }" if="{ entry.value && entry.value.length > 0}" />
</material-card>
<script type="text/javascript">
const self = this;
const eltIdx = function(e) {
const eltIdx = function (e) {
switch (e) {
case 'id': return 1;
case 'created': return 2;
case 'created_by': return 3;
case 'size': return 4;
case 'os': return 5;
case 'architecture': return 6;
case 'created': return 1;
case 'created_by': return 2;
case 'size': return 3;
case 'os': return 4;
case 'architecture': return 5;
case 'id': return 6;
case 'linux': return 7;
case 'docker_version': return 8;
default: return 10;
}
};

const eltSort = function(e1, e2) {
const eltSort = function (e1, e2) {
return eltIdx(e1.key) - eltIdx(e2.key);
};

const modifySpecificAttributeTypes = function(attribute, value) {
const modifySpecificAttributeTypes = function (attribute, value) {
switch (attribute) {
case 'created':
return new Date(value).toLocaleString();
case 'created_by':
const cmd = value.match(/\/bin\/sh *-c *#\(nop\) *([A-Z]+)/);
return (cmd && cmd [1]) || 'RUN'
return (cmd && cmd[1]) || 'RUN'
case 'size':
return registryUI.bytesToSize(value);
case 'Entrypoint':
case 'Cmd':
return (value || []).join(' ');
case 'Labels':
return Object.keys(value || {}).map(function(elt) {
return Object.keys(value || {}).map(function (elt) {
return value[elt] ? elt + '=' + value[elt] : '';
});
case 'Volumes':
Expand All @@ -75,14 +77,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
return value || '';
};

const getConfig = function(blobs) {
const res = ['architecture', 'User', 'created', 'docker_version', 'os', 'Cmd', 'Entrypoint', 'Env', 'Labels', 'User', 'Volumes', 'WorkingDir', 'author', 'id', 'ExposedPorts'].reduce(function(acc, e) {
const value = blobs[e] || blobs.config[e];
if (value) {
acc[e] = value;
}
return acc;
}, {});
const getConfig = function (blobs) {
const res = ['architecture', 'User', 'created', 'docker_version', 'os', 'Cmd', 'Entrypoint', 'Env', 'Labels', 'User', 'Volumes', 'WorkingDir', 'author', 'id', 'ExposedPorts']
.reduce(function (acc, e) {
const value = blobs[e] || blobs.config[e];
if (value && e === 'architecture' && blobs.variant) {
acc[e] = value + blobs.variant;
} else if (value) {
acc[e] = value;
}
return acc;
}, {});

if (!res.author && (res.Labels && res.Labels.maintainer)) {
res.author = blobs.config.Labels.maintainer;
Expand All @@ -92,7 +97,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
return res;
};

const processBlobs = function(blobs) {
const processBlobs = function (blobs) {
function exec(elt) {
const guiElements = [];
for (var attribute in elt) {
Expand All @@ -107,27 +112,44 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
}
return guiElements.sort(eltSort);
}

self.elements.push(exec(getConfig(blobs)));
blobs.history.reverse().forEach(function(elt) { self.elements.push(exec(elt)) });
self.elements = new Array(blobs.history.length + 1);
self.elements[0] = exec(getConfig(blobs));
blobs.history.forEach(function (elt, i) { self.elements[blobs.history.length - i] = exec(elt) });
registryUI.taghistory.loadend = true;
self.update();
};

registryUI.taghistory.display = function() {
const multiArchList = function (manifests) {
manifests = manifests.manifests || manifests;
self.archs = manifests.map(function (manifest) {
return {
title: manifest.platform.os + '/' + manifest.platform.architecture + (manifest.platform.variant ? manifest.platform.variant : ''),
digest: manifest.digest
}
})
self.update();
};

self.tabchanged = function (arch, idx) {
self.elements = []
const blobs = registryUI.taghistory._image && registryUI.taghistory._image.blobs;
if (blobs) {
window.scrollTo(0, 0);
return processBlobs(blobs);
self.image.variants[idx] = self.image.variants[idx] || new registryUI.DockerImage(registryUI.taghistory.image, arch.digest);
if (self.image.variants[idx].blobs) {
return processBlobs(self.image.variants[idx].blobs);
}
const image = new registryUI.DockerImage(registryUI.taghistory.image, registryUI.taghistory.tag);
image.fillInfo()
image.on('blobs', processBlobs);
self.image.variants[idx].fillInfo();
self.image.variants[idx].on('blobs', processBlobs);
};

registryUI.taghistory.display = function () {
self.elements = []
self.image = new registryUI.DockerImage(registryUI.taghistory.image, registryUI.taghistory.tag, true);
self.image.fillInfo()
self.image.on('blobs', processBlobs);
self.image.on('list', multiArchList)
};

this.on('mount', function() {
self.refs['tag-history-tag'].tags['material-button'].root.onclick = function() {
this.on('mount', function () {
self.refs['tag-history-tag'].tags['material-button'].root.onclick = function () {
registryUI.taglist.go(registryUI.taghistory.image);
};
});
Expand Down