Initial commit of docker flask.

This commit is contained in:
Krzysztof Płaczek
2018-03-09 10:33:19 +01:00
commit 6e9b3aed3a
16 changed files with 1128 additions and 0 deletions

17
templates/container.html Normal file
View File

@@ -0,0 +1,17 @@
{% extends "layout.html" %}
{% block body %}
<h1><a href="/">Dashboard</a> &raquo; {{ client_name }} &raquo; <a href="/{{ client_name }}/containers">Containers</a> &raquo; {{ container.name }}</h1>
<form action="{{ url_for('rename_container', client_name=client_name) }}" method="post">
<p><input type="text" name="name" size="60" value="{{ container.name }}"><!--
--><input type="hidden" name="short_id" value="{{ container.short_id }}"><!--
--><input type="submit" value="rename">
</form>
<h2>Details</h2>
<pre>
{{ container.attrs|pprint }}
</pre>
{% endblock %}

108
templates/containers.html Normal file
View File

@@ -0,0 +1,108 @@
{% extends "layout.html" %}
{% block body %}
<h1><a href="/">Dashboard</a> &raquo; {{ client_name }} &raquo; Containers</h1>
<a class="button--link" href="/{{ client_name }}/containers/all">All Containers</a>
<a class="button--link" href="/{{ client_name }}/containers/paused">Paused Containers</a>
<a class="button--link" href="/{{ client_name }}/containers">Running Containers</a>
<a class="button--link" href="/{{ client_name }}/containers/exited">Stopped Containers</a>
<input type="text" class="search_table" placeholder="search">
<h2>{{ currentComposerProject }}</h2>
{% for container in containers %}
{% if (loop.first) or (loop.previtem.attrs.Config.Labels['com.docker.compose.project'] != container.attrs.Config.Labels['com.docker.compose.project']) %}
<h2>
<a href="{{ url_for('containers_compose_action', client_name=client_name, compose_project=container.attrs.Config.Labels['com.docker.compose.project']) }}">{{
container.attrs.Config.Labels['com.docker.compose.project'] }}</a></h2>
{% endif%}
<!--<table>-->
<!--<thead>-->
<!--<tr>-->
<!--<th>COMPOSE PROJECT</th>-->
<!--<th>CONTAINER ID</th>-->
<!--<th>NAME</th>-->
<!--<th>COMMAND</th>-->
<!--<th>CREATED</th>-->
<!--<th>STATUS</th>-->
<!--<th>PORTS</th>-->
<!--<th>IMAGE</th>-->
<!--</tr>-->
<!--</thead>-->
<!--<tbody>-->
<div class="details">
<div>
<div class="details__status details__status--{{ container.status }}">{{ container.status }}</div>
<div class="details__name"><a class="button--link"
href="/{{ client_name }}/containers/id/{{ container.short_id }}">{{
container.name
}}</a></div>
<div class="details__id"><span title="{{ container.id }}">ShortID: {{ container.short_id }}</span></div>
</div>
<div>
<div class="details__created">{{ container.attrs['Created'][0:19] }}</div>
<div class="details__entrypoint">{{ container.attrs['Config']['Entrypoint'][0] }}</div>
<div class="details__image">{{ container.attrs['Config']['Image'] }}</div>
</div>
<div class="details__more-info">
<div class="more-info__ports">
{% for port in container.attrs['NetworkSettings']['Ports'] %}
{{ port }}
{% if container.attrs['NetworkSettings']['Ports'][port] is not none %}
{% if container.attrs['NetworkSettings']['Ports'][port] is not none and
container.attrs['NetworkSettings']['Ports'][port]|length > 0 %}
{% for port_exposed in container.attrs['NetworkSettings']['Ports'][port] %}
->{{ port_exposed['HostIp'] }}:{{ port_exposed['HostPort'] }}
{% endfor %}
{% endif %}
{% endif %}
{% endfor %}
</div>
</div>
<div>
</div>
<div class="details__controll">
<a class="button--link" href="/{{ client_name }}/containers/log/{{ container.short_id }}">log</a>
<a class="button--link" href="/{{ client_name }}/containers/export/{{ container.short_id }}">export</a>
{% if (container.status == 'exited') or (container.status == 'created') %}
<a class="button--link" href="/{{ client_name }}/containers/start/{{ container.short_id }}">start</a>
<a class="button--link" href="/{{ client_name }}/containers/remove/{{ container.short_id }}">remove</a>
{% endif %}
{% if container.status == 'running' %}
<a class="button--link" href="/{{ client_name }}/containers/stop/{{ container.short_id }}">stop</a>
<a class="button--link" href="/{{ client_name }}/containers/restart/{{ container.short_id }}">restart</a>
<a class="button--link" href="/{{ client_name }}/containers/top/{{ container.short_id }}">top</a>
{% endif %}
</div>
</div>
{% else %}
<div>
<div>
no containers
</div>
</div>
{% endfor %}
{% endblock %}

View File

@@ -0,0 +1,103 @@
{% extends "layout.html" %}
{% block body %}
<h1><a href="/">Dashboard</a> &raquo; {{ client_name }} &raquo; Containers</h1>
<a class="button--link" href="/{{ client_name }}/containers/all">All Containers</a>
<a class="button--link" href="/{{ client_name }}/containers/paused">Paused Containers</a>
<a class="button--link" href="/{{ client_name }}/containers">Running Containers</a>
<a class="button--link" href="/{{ client_name }}/containers/exited">Stopped Containers</a>
<input type="text" class="search_table" placeholder="search">
<h2>{{ currentComposerProject }}</h2>
{% for container in containers %}
{% if (loop.first) or (loop.previtem.attrs.Config.Labels['com.docker.compose.project'] != container.attrs.Config.Labels['com.docker.compose.project']) %}
{% if (loop.previtem is defined) and (loop.previtem.attrs.Config.Labels['com.docker.compose.project'] != container.attrs.Config.Labels['com.docker.compose.project'])%}
</tbody>
</table>
{% endif %}
<h2>{{ container.attrs.Config.Labels['com.docker.compose.project'] }}</h2>
<table>
<thead>
<tr>
<th>COMPOSE PROJECT</th>
<th>CONTAINER ID</th>
<th>NAME</th>
<th>COMMAND</th>
<th>CREATED</th>
<th>STATUS</th>
<th>PORTS</th>
<th>IMAGE</th>
</tr>
</thead>
<tbody>
{% endif%}
<tr>
<td>
{% if container.attrs.Config.Labels|length and container.attrs.Config.Labels['com.docker.compose.config-hash'] %}
<a href="{{ url_for('containers_compose_action', client_name=client_name, compose_project=container.attrs.Config.Labels['com.docker.compose.project']) }}">{{ container.attrs.Config.Labels['com.docker.compose.project'] }}</a>
{% endif%}
</td>
<td><span title="{{ container.id }}">{{ container.short_id }}</span></td>
<td><a href="/{{ client_name }}/containers/id/{{ container.short_id }}">{{ container.name }}</a></td>
<td>{{ container.attrs['Config']['Entrypoint'][0] }}</td>
<td>{{ container.attrs['Created'][0:19] }}</td>
<td>{{ container.status }}</td>
<td>
{% for port in container.attrs['NetworkSettings']['Ports'] %}
{{ port }}
{% if container.attrs['NetworkSettings']['Ports'][port] is not none %}
{% if container.attrs['NetworkSettings']['Ports'][port] is not none and
container.attrs['NetworkSettings']['Ports'][port]|length > 0 %}
{% for port_exposed in container.attrs['NetworkSettings']['Ports'][port] %}
->{{ port_exposed['HostIp'] }}:{{ port_exposed['HostPort'] }}
{% endfor %}
{% endif %}
{% endif %}
{% endfor %}
</td>
<td>{{ container.attrs['Config']['Image'] }}</td>
<td>
<a href="/{{ client_name }}/containers/log/{{ container.short_id }}">log</a>
<a href="/{{ client_name }}/containers/export/{{ container.short_id }}">export</a>
<a href="/{{ client_name }}/containers/stop/{{ container.short_id }}">stop</a>
<a href="/{{ client_name }}/containers/remove/{{ container.short_id }}">remove</a>
{% if container.status == 'running' %}
<a href="/{{ client_name }}/containers/top/{{ container.short_id }}">top</a>
{% endif %}
</td>
</tr>
{% else %}
<tr>
<td colspan="9">
no containers
</td>
</tr>
{% endfor %}
{% endblock %}

12
templates/image.html Normal file
View File

@@ -0,0 +1,12 @@
{% extends "layout.html" %}
{% block body %}
<h1><a href="/">Dashboard</a> &raquo; {{ client_name }} &raquo; <a href="/{{ client_name }}/images">Images</a>
&raquo; {% if image.attrs['RepoTags']|length %} {{ image.attrs['RepoTags'][0] }} {% else %} {{ image.attrs['Id'][7:]
}} {% endif %}</h1>
<h2>Details</h2>
<pre>
{{ image.attrs | pprint }}
</pre>
{% endblock %}

61
templates/images.html Normal file
View File

@@ -0,0 +1,61 @@
{% extends "layout.html" %}
{% block body %}
<h1><a href="/">Dashboard</a> &raquo; {{ client_name }} &raquo; Images</h1>
<a class="button--link" href="/{{ client_name }}/images/dangling">Dangling Images</a>
<a class="button--link" href="/{{ client_name }}/images/all">All Images</a>
<input type="text" class="search_table" placeholder="search">
<table>
<thead>
<tr>
<th>REPOSITORY</th>
<th>TAG</th>
<th>IMAGE ID</th>
<th>CREATED</th>
<th>SIZE</th>
</tr>
</thead>
<tbody>
{% for image in images %}
<tr>
<td>
{% if image.attrs['RepoTags']|length > 0 %}
<a href="{{ url_for('image_action', client_name=client_name, image_id=image.attrs['Id'][7:]) }}">{{ image.attrs['RepoTags'][0].split(':')[0] }} </a>
{% endif %}
</td>
<td>
{% if image.attrs['RepoTags']|length > 0 %}
{{ image.attrs['RepoTags'][0].split(':')[1] }}
{% endif %}
</td>
<td>{{ image.attrs['Id'][7:] }}</td>
<td>{{ image.attrs['Created'][0:19] }}</td>
<td>{{ image.attrs['Size']|file_size }}</td>
<td>
{% if image.attrs['RepoTags']|length %}
<a href="{{ url_for('export_image_action', client_name=client_name, image_tag=image.attrs['RepoTags'][0]|encode64 )}}">export</a>
<a href="{{ url_for('remove_image_action', client_name=client_name, image_tag=image.attrs['RepoTags'][0]|encode64 )}}">remove</a>
{% else %}
<a href="{{ url_for('remove_imageby_id_action', client_name=client_name, image_id=image.attrs['Id'][7:] )}}">remove</a>
{% endif %}
</td>
</tr>
{% else %}
<tr>
<td colspan="9">
no images
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

114
templates/index.html Normal file
View File

@@ -0,0 +1,114 @@
{% extends "layout.html" %}
{% block body %}
<h1>Dashboard</h1>
<table>
<tr>
{% for docker in data %}
<td>
<h2>{{ docker.client_name }}</h2>
<h3>Docker Info</h3>
<table>
<tr>
<td>All Containers:</td>
<td><a href="/{{ docker.client_name }}/containers/all">{{ docker['info'].Containers }}</a></td>
</tr>
<tr>
<td>Containers Paused:</td>
<td><a href="/{{ docker.client_name }}/containers/paused">{{ docker['info'].ContainersPaused }}</a></td>
</tr>
<tr>
<td>Containers Running:</td>
<td><a href="/{{ docker.client_name }}/containers">{{ docker['info'].ContainersRunning }}</a></td>
</tr>
<tr>
<td>Containers Stopped:</td>
<td><a href="/{{ docker.client_name }}/containers/exited">{{ docker['info'].ContainersStopped }}</a></td>
</tr>
<tr>
<td>Images:</td>
<td><a href="/{{ docker.client_name }}/images">{{ docker['info'].Images }}</a></td>
</tr>
<tr>
<td>Volumes:</td>
<td><a href="{{ url_for('volumes_action', client_name=docker.client_name) }}">{{ docker.volumes }}</a></td>
</tr>
<tr>
<td>Networks:</td>
<td><a href="{{ url_for('networks_action', client_name=docker.client_name) }}">{{ docker.networks }}</a></td>
</tr>
<tr>
<td>Architecture:</td>
<td>{{ docker['info'].Architecture }}</td>
</tr>
<tr>
<td>Server Version:</td>
<td>{{ docker['info'].ServerVersion }}</td>
</tr>
<tr>
<td>System Time:</td>
<td>{{ docker['info'].SystemTime[0:19] }}</td>
</tr>
</table>
<h3>Docker Version</h3>
<table>
<tr>
<td>Api Version:</td>
<td>{{ docker['version'].ApiVersion }}</td>
</tr>
<tr>
<td>Architecture:</td>
<td>{{ docker['version'].Arch }}</td>
</tr>
<tr>
<td>Build Time:</td>
<td>{{ docker['version'].BuildTime[0:19] }}</td>
</tr>
<tr>
<td>Experimental:</td>
<td>{{ docker['version'].Experimental }}</td>
</tr>
<tr>
<td>Git Commit:</td>
<td><a target="_blank" href="https://github.com/docker/docker-ce/commit/{{ docker['version'].GitCommit }}">{{ docker['version'].GitCommit }}</a></td>
</tr>
<tr>
<td>Go Version:</td>
<td>{{ docker['version'].GoVersion }}</td>
</tr>
<tr>
<td>KernelVersion:</td>
<td>{{ docker['version'].KernelVersion }}</td>
</tr>
<tr>
<td>MinAPIVersion:</td>
<td>{{ docker['version'].MinAPIVersion }}</td>
</tr>
<tr>
<td>Os:</td>
<td>{{ docker['version'].Os }}</td>
</tr>
<tr>
<td>Version:</td>
<td>{{ docker['version'].Version }}</td>
</tr>
</table>
</td>
{% endfor %}
</tr>
</table>
{% endblock %}

63
templates/layout.html Normal file
View File

@@ -0,0 +1,63 @@
<!doctype html>
<head>
<title>Docker Manager</title>
<link href="https://fonts.googleapis.com/css?family=Ubuntu&amp;subset=latin-ext" rel="stylesheet">
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='favicon.ico') }}"/>
</head>
<body>
<div class="container">
{% with flashes = get_flashed_messages() %}
{% if flashes %}
<ul class="flashes">
{% for message in flashes %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
{% block body %}{% endblock %}
</div>
<script>
window.onload = load;
function load() {
if(!!document.querySelector('input.search_table')){
document.querySelector('input.search_table').addEventListener('keyup', searchTable);
}
function searchTable(){
value = this.value;
document.querySelectorAll('table tbody tr').forEach(function(element){
if(element.innerText.indexOf(value) == -1){
element.style.display = 'none';
} else {
element.style.display = 'table-row';
}
})
document.querySelectorAll('.details').forEach(function(element){
if(element.innerText.indexOf(value) == -1){
element.style.display = 'none';
} else {
element.style.display = 'block';
}
})
}
if(!!document.querySelector('.logs')){
document.querySelector('.logs').scrollTop = 10e6;
}
}
</script>
</body>
</html>

13
templates/log.html Normal file
View File

@@ -0,0 +1,13 @@
{% extends "layout.html" %}
{% block body %}
<h1><a href="/">Dashboard</a> &raquo; {{ client_name }} &raquo; <a href="/{{ client_name }}/containers">Containers</a> &raquo; {{ container.name }} logs</h1>
<a class="button--link" href="{{ url_for('log_action', client_name=client_name, short_id=short_id, timestamp=1) }}">Log with timestamps</a>
<a class="button--link" href="{{ url_for('log_action', client_name=client_name, short_id=short_id, timestamp=0) }}">Log without timestamps </a>
<div class="logs">
{{ logs|safe }}
</div>
{% endblock %}

52
templates/networks.html Normal file
View File

@@ -0,0 +1,52 @@
{% extends "layout.html" %}
{% block body %}
<h1><a href="/">Dashboard</a> &raquo; {{ client_name }} &raquo; Networks</h1>
<input type="text" class="search_table" placeholder="search">
<table>
<thead>
<tr>
<th>DRIVER</th>
<th>LABELS</th>
<th>MOUNTPOINT</th>
<th>NAME</th>
<th>OPTIONS</th>
<th>SCOPE</th>
</tr>
</thead>
<tbody>
{% for network in networks %}
<tr>
<td>
<pre>
{{ network.attrs|pprint }}
</pre>
</td>
<td> {{ network.attrs['Driver'] }}</td>
<td> {{ network.attrs['Labels'] }}</td>
<td> {{ network.attrs['Mountpoint'] }}</td>
<td> {{ network.attrs['Name'] }}</td>
<td> {{ network.attrs['Options'] }}</td>
<td> {{ network.attrs['Scope'] }}</td>
</tr>
{% else %}
<tr>
<td colspan="6">
no networks
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

28
templates/top.html Normal file
View File

@@ -0,0 +1,28 @@
{% extends "layout.html" %}
{% block body %}
<h1><a href="/">Dashboard</a> &raquo; {{ client_name }} &raquo; <a href="/{{ client_name }}/containers">Containers</a> &raquo; {{ container.name }}
processes</h1>
<input type="text" class="search_table" placeholder="search">
<table>
<thead>
<tr>
{% for header in top['Titles'] %}
<th>{{ header }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for processes in top['Processes'] %}
<tr>
{% for process in processes %}
<td>{{ process }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

48
templates/volumes.html Normal file
View File

@@ -0,0 +1,48 @@
{% extends "layout.html" %}
{% block body %}
<h1><a href="/">Dashboard</a> &raquo; {{ client_name }} &raquo; Volumes</h1>
<a class="button--link" href="{{ url_for('volumes_prune_action', client_name=client_name) }}">Prune Unused Volumes</a>
<input type="text" class="search_table" placeholder="search">
<table>
<thead>
<tr>
<th>DRIVER</th>
<th>LABELS</th>
<th>MOUNTPOINT</th>
<th>NAME</th>
<th>OPTIONS</th>
<th>SCOPE</th>
</tr>
</thead>
<tbody>
{% for volume in volumes %}
<tr>
<td> {{ volume.attrs['Driver'] }}</td>
<td> {{ volume.attrs['Labels'] }}</td>
<td> {{ volume.attrs['Mountpoint'] }}</td>
<td> {{ volume.attrs['Name'] }}</td>
<td> {{ volume.attrs['Options'] }}</td>
<td> {{ volume.attrs['Scope'] }}</td>
</tr>
{% else %}
<tr>
<td colspan="6">
no images
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}