mirror of
https://github.com/Joxit/docker-registry-ui.git
synced 2025-04-27 15:39:54 +03:00
feat(dockerfile): show dockerfile in history page (#286)
This commit is contained in:
commit
b9a157c943
2 changed files with 134 additions and 16 deletions
68
src/components/dialogs/dockerfile.riot
Normal file
68
src/components/dialogs/dockerfile.riot
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2016-2023 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/>.
|
||||||
|
-->
|
||||||
|
<dockerfile>
|
||||||
|
<material-popup opened="{ props.opened }" onClick="{ props.onClose }">
|
||||||
|
<div class="material-popup-title">Dockerfile</div>
|
||||||
|
<div class="material-popup-content">
|
||||||
|
<template each="{ (_, idx) in props.elements }">
|
||||||
|
<template
|
||||||
|
each="{ element in props.elements[props.elements.length - 1 - idx].filter(e => e.key === 'created_by') }"
|
||||||
|
>
|
||||||
|
<div class="instruction">
|
||||||
|
<span class="keyword">{ element.value }</span>
|
||||||
|
<span>{ ' ' + element.content }</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div class="material-popup-action">
|
||||||
|
<material-button
|
||||||
|
class="dialog-button"
|
||||||
|
waves-color="rgba(158,158,158,.4)"
|
||||||
|
onClick="{ props.onClose }"
|
||||||
|
color="inherit"
|
||||||
|
text-color="var(--primary-text)"
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</material-button>
|
||||||
|
</div>
|
||||||
|
</material-popup>
|
||||||
|
<style>
|
||||||
|
:host material-popup .popup material-button {
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
:host material-popup .popup > .content {
|
||||||
|
max-width: 75em;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
:host .material-popup-content {
|
||||||
|
background-color: var(--hover-background);
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 800px) {
|
||||||
|
:host material-popup .popup > .content {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:host .instruction {
|
||||||
|
font-family: 'Roboto Mono', monospace !important;
|
||||||
|
margin: 0.75em 0;
|
||||||
|
}
|
||||||
|
:host .instruction .keyword {
|
||||||
|
color: var(--accent-text);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</dockerfile>
|
|
@ -29,11 +29,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
<i class="material-icons">arrow_back</i>
|
<i class="material-icons">arrow_back</i>
|
||||||
</material-button>
|
</material-button>
|
||||||
<h2>History of { props.image }:{ props.tag } <i class="material-icons">history</i></h2>
|
<h2>History of { props.image }:{ props.tag } <i class="material-icons">history</i></h2>
|
||||||
|
<material-button
|
||||||
|
text-color="var(--accent-text)"
|
||||||
|
color="inherit"
|
||||||
|
waves-color="var(--hover-background)"
|
||||||
|
waves-center="true"
|
||||||
|
rounded="true"
|
||||||
|
outlined
|
||||||
|
onClick="{ showDockerfile }"
|
||||||
|
>
|
||||||
|
Dockerfile
|
||||||
|
</material-button>
|
||||||
</div>
|
</div>
|
||||||
</material-card>
|
</material-card>
|
||||||
<div if="{ !state.loadend }" class="spinner-wrapper">
|
<div if="{ !state.loadend }" class="spinner-wrapper">
|
||||||
<material-spinner></material-spinner>
|
<material-spinner></material-spinner>
|
||||||
</div>
|
</div>
|
||||||
|
<dockerfile
|
||||||
|
opened="{ state.showDockerfile }"
|
||||||
|
on-close="{ onDockerfileClose }"
|
||||||
|
elements="{ state.elements }"
|
||||||
|
></dockerfile>
|
||||||
|
|
||||||
<material-tabs
|
<material-tabs
|
||||||
if="{ state.archs && state.loadend }"
|
if="{ state.archs && state.loadend }"
|
||||||
|
@ -57,11 +73,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
<script>
|
<script>
|
||||||
import { DockerImage } from '../../scripts/docker-image';
|
import { DockerImage } from '../../scripts/docker-image';
|
||||||
import { bytesToSize } from '../../scripts/utils';
|
import { bytesToSize } from '../../scripts/utils';
|
||||||
|
import Dockerfile from '../dialogs/dockerfile.riot';
|
||||||
import router from '../../scripts/router';
|
import router from '../../scripts/router';
|
||||||
import TagHistoryElement from './tag-history-element.riot';
|
import TagHistoryElement from './tag-history-element.riot';
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
TagHistoryElement,
|
TagHistoryElement,
|
||||||
|
Dockerfile,
|
||||||
},
|
},
|
||||||
onBeforeMount(props, state) {
|
onBeforeMount(props, state) {
|
||||||
state.elements = [];
|
state.elements = [];
|
||||||
|
@ -105,10 +123,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
for (var attribute in elt) {
|
for (var attribute in elt) {
|
||||||
if (elt.hasOwnProperty(attribute) && attribute != 'empty_layer') {
|
if (elt.hasOwnProperty(attribute) && attribute != 'empty_layer') {
|
||||||
const value = elt[attribute];
|
const value = elt[attribute];
|
||||||
const guiElement = {
|
const guiElement = modifySpecificAttributeTypes(attribute, value);
|
||||||
'key': attribute,
|
|
||||||
'value': modifySpecificAttributeTypes(attribute, value),
|
|
||||||
};
|
|
||||||
guiElements.push(guiElement);
|
guiElements.push(guiElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,6 +158,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
toTaglist() {
|
toTaglist() {
|
||||||
return router.taglist(this.props.image);
|
return router.taglist(this.props.image);
|
||||||
},
|
},
|
||||||
|
showDockerfile() {
|
||||||
|
console.log(this);
|
||||||
|
this.update({ showDockerfile: true });
|
||||||
|
},
|
||||||
|
onDockerfileClose() {
|
||||||
|
this.update({ showDockerfile: false });
|
||||||
|
},
|
||||||
};
|
};
|
||||||
const eltIdx = function (e) {
|
const eltIdx = function (e) {
|
||||||
switch (e) {
|
switch (e) {
|
||||||
|
@ -171,27 +193,47 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
return eltIdx(e1.key) - eltIdx(e2.key);
|
return eltIdx(e1.key) - eltIdx(e2.key);
|
||||||
};
|
};
|
||||||
|
|
||||||
const modifySpecificAttributeTypes = function (attribute, value) {
|
const parseCreatedBy = (value) => {
|
||||||
switch (attribute) {
|
if (value.startsWith('COPY')) {
|
||||||
|
return {
|
||||||
|
value: 'COPY',
|
||||||
|
content: value.replace(/^COPY /, ''),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let cmd = value.match(/\/bin\/sh *-c *#\(nop\) *([A-Z]+) (.*)/);
|
||||||
|
return {
|
||||||
|
value: (cmd && cmd[1]) || 'RUN',
|
||||||
|
content: (cmd && cmd[2]) || value.replace(/^\/bin\/sh *-c *(#\(nop\))?/, ''),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const modifySpecificAttributeTypes = function (key, value) {
|
||||||
|
switch (key) {
|
||||||
case 'created':
|
case 'created':
|
||||||
return new Date(value).toLocaleString();
|
return { key, value: new Date(value).toLocaleString() };
|
||||||
case 'created_by':
|
case 'created_by':
|
||||||
const cmd = value.match(/\/bin\/sh *-c *#\(nop\) *([A-Z]+)/);
|
const cmd = value.match(/\/bin\/sh *-c *#\(nop\) *([A-Z]+) (.*)/);
|
||||||
return (cmd && cmd[1]) || 'RUN';
|
return {
|
||||||
|
key,
|
||||||
|
...parseCreatedBy(value),
|
||||||
|
};
|
||||||
case 'size':
|
case 'size':
|
||||||
return bytesToSize(value);
|
return { key, value: bytesToSize(value) };
|
||||||
case 'Entrypoint':
|
case 'Entrypoint':
|
||||||
case 'Cmd':
|
case 'Cmd':
|
||||||
return (value || []).join(' ');
|
return { key, value: (value || []).join(' ') };
|
||||||
case 'Labels':
|
case 'Labels':
|
||||||
return Object.keys(value || {}).map(function (elt) {
|
return {
|
||||||
|
key,
|
||||||
|
value: Object.keys(value || {}).map(function (elt) {
|
||||||
return value[elt] ? elt + '=' + value[elt] : '';
|
return value[elt] ? elt + '=' + value[elt] : '';
|
||||||
});
|
}),
|
||||||
|
};
|
||||||
case 'Volumes':
|
case 'Volumes':
|
||||||
case 'ExposedPorts':
|
case 'ExposedPorts':
|
||||||
return Object.keys(value);
|
return { key, value: Object.keys(value) };
|
||||||
}
|
}
|
||||||
return value || '';
|
return { key, value: value || '' };
|
||||||
};
|
};
|
||||||
|
|
||||||
const getConfig = function (blobs, { historyCustomLabels }) {
|
const getConfig = function (blobs, { historyCustomLabels }) {
|
||||||
|
@ -238,4 +280,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
<style>
|
||||||
|
h2 {
|
||||||
|
flex-grow: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</tag-history>
|
</tag-history>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue