{% extends "base.html" %} {% block title %}Overview{% endblock %} {% block content %} <main> <section class="system-info"> <article> <table class="full-width"> <tbody> <tr> <th>Hostname</th> <td colspan="2"> {{ system.host_name }} </td> </tr> <tr> <th>OS info</th> <td colspan="2"> {{ system.name }} {{ system.os_version }} (kernel {{ system.kernel_version }}) </td> </tr> <tr> <th>Load Avg</th> <td colspan="2"> {{ system.load_average.0 }}, {{ system.load_average.1 }}, {{ system.load_average.2 }} </td> </tr> <tr> <th>Memory</th> <td> {{ system.used_memory|filesizeformat }} / {{ system.total_memory|filesizeformat }} </td> <td> <progress id="memory" value="{{system.used_memory}}" max="{{system.total_memory}}"> {{ "{:.2}"|format(system.used_memory/system.total_memory*100) }}% </progress> </td> </tr> </tbody> </table> </article> <article> <table class="full-width"> <tbody> {% for disk in system.disks %} <tr> <th title="{{disk.device_name}}">{{disk.mount_point}}</th> <td> {{ (disk.total_space-disk.available_space)|filesizeformat }} / {{ disk.total_space|filesizeformat }} </td> <td> <progress id="disk-{{disk.device_name}}" value="{{disk.total_space-disk.available_space}}" max="{{disk.total_space}}"> </progress> </td> </tr> {% endfor %} </tbody> </table> </article> </section> <section class="stack-list"> <h2> Stacks <form action="/stack/_/new"><button>+</button></form> </h2> <table class="table full-width"> <thead> <tr> <th colspan="2">Name</th> <th>Service status</th> </tr> </thead> <tbody> {% for stack in info.stacks %} <tr> <td class="status {% if stack.active %}active{% endif %}"></td> <td> <a href="/stack/{{stack.folder}}/"> {{stack.name}} </a> </td> <td> {% let (running, stopped) = stack.stats() %} {% if running > 0 %} <span class="count running" title="{{running}} running">{{running}}</span> {% endif %} {% if stopped > 0 %} <span class="count stopped" title="{{stopped}} stopped">{{stopped}}</span> {% endif %} </td> </li> </tr> {% endfor %} </tbody> </table> </section> <section class="container-list"> <h2>Containers</h2> <table class="containers table full-width"> <thead> <tr> <th>Name</th> <th>Stack</th> <th>State</th> <th>Image</th> </tr> </thead> <tbody> {% for container in info.containers %} <tr> <td><a href="/container/{{container.name}}/">{{container.name}}</a></td> <td>{{container.stack().unwrap_or_default()}}</td> <td class="status {{container.state}}">{{container.state}}</td> <td>{{container.image}}</td> </tr> {% endfor %} </tbody> </table> </section> </main> <style scoped> .containers { & .status { text-align: center; font-weight: bold; color: white; padding: 0 10px; &.exited { background-color: var(--danger-bright); } &.running { background-color: var(--success-bright); } } } .container-list { grid-area: con; } .stack-list { grid-area: stk; & td { padding: 4px 8px; &.status { width: 6px; padding: 0; background-color: var(--danger-bright); &.active { background-color: #33B074; } } } } .system-info { grid-area: sys; display: flex; gap: 1rem; flex-direction: column; & th { font-weight: bold; padding-right: 2ch; text-align: left; } } .count { &::before { content: "◉"; margin-right: 0.5ch; } &.running::before { color: var(--success-bright); } &.stopped::before { color: var(--danger-bright); } } @media (min-width: 1000px) { .system-info { flex-direction: row; justify-content: space-between; } main { display: grid; gap: 1rem; grid-template-areas: "sys sys" "stk con"; grid-template-rows: 100px 1fr; grid-template-columns: 1fr 2fr; } } </style> {% endblock %}