Skip to content

Commit

Permalink
Add unused containers to orphan page, automate pruning after some tes…
Browse files Browse the repository at this point in the history
…ting
  • Loading branch information
austinwbest committed Oct 17, 2024
1 parent 772b21f commit 6fbf821
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 14 deletions.
57 changes: 43 additions & 14 deletions root/app/www/public/ajax/orphans.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,19 @@
require 'shared.php';

if ($_POST['m'] == 'init') {
$images = apiRequest('docker-getOrphanContainers');
$images = json_decode($images['result'], true);
$volumes = apiRequest('docker-getOrphanVolumes');
$volumes = json_decode($volumes['result'], true);
$networks = apiRequest('docker-getOrphanNetworks');
$networks = json_decode($networks['result'], true);

$images = apiRequest('docker-getOrphanContainers');
$images = json_decode($images['result'], true);
$volumes = apiRequest('docker-getOrphanVolumes');
$volumes = json_decode($volumes['result'], true);
$networks = apiRequest('docker-getOrphanNetworks');
$networks = json_decode($networks['result'], true);
$unusedContainers = apiRequest('docker-getUnusedContainers');
$unusedContainers = json_decode($unusedContainers['result'], true);
?>
<div class="container-fluid pt-4 px-4 mb-5">
<div class="bg-secondary rounded h-100 p-4">
<h4 class="mt-3 mb-0">Images</h4>
<span class="small-text text-muted">docker images -f dangling=true</span>
<span class="small-text text-muted"><?= DockerSock::ORPHAN_CONTAINERS ?></span>
<div class="table-responsive">
<table class="table">
<thead>
Expand Down Expand Up @@ -50,8 +51,36 @@
</tbody>
</table>
</div>
<h4 class="mt-3 mb-0">Unused containers</h4>
<span class="small-text text-muted"><?= DockerSock::UNUSED_CONTAINERS ?></span>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col"><input type="checkbox" class="form-check-input orphan-checkall" onclick="$('.orphanUnusedContainers-check').prop('checked', $(this).prop('checked'));"></th>
<th scope="col">ID</th>
<th scope="col">Repository</th>
<th scope="col">Tag</th>
</tr>
</thead>
<tbody>
<?php
foreach ($unusedContainers as $container) {
?>
<tr id="unused-<?= $container['ID'] ?>">
<th scope="row"><input id="unusedContainer-<?= $container['ID'] ?>" type="checkbox" class="form-check-input orphanUnusedContainers-check orphan"></th>
<td><?= $container['ID'] ?></td>
<td><?= $container['Repository'] ?></td>
<td><?= $container['Tag'] ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
<h4 class="mt-3 mb-0">Volumes</h4>
<span class="small-text text-muted">docker volume ls -qf dangling=true</span>
<span class="small-text text-muted"><?= DockerSock::ORPHAN_VOLUMES ?></span>
<div class="table-responsive">
<table class="table">
<thead>
Expand All @@ -77,7 +106,7 @@
</table>
</div>
<h4 class="mt-3 mb-0">Networks</h4>
<span class="small-text text-muted">docker network ls -qf dangling=true</span>
<span class="small-text text-muted"><?= DockerSock::ORPHAN_NETWORKS ?></span>
<div class="table-responsive">
<table class="table">
<thead>
Expand Down Expand Up @@ -125,21 +154,21 @@
if ($_POST['m'] == 'removeOrphans') {
switch ($_POST['action']) {
case 'remove':
if ($_POST['type'] == 'image') {
if ($_POST['type'] == 'image' || $_POST['type'] == 'unused') {
$apiRequest = apiRequest('docker-removeImage', [], ['image' => $_POST['orphan']])['result'];
if (stripos($apiRequest, 'error') !== false || stripos($apiRequest, 'help') !== false) {
if (stri_contains($apiRequest, 'error') || stri_contains($apiRequest, 'help')) {
echo $apiRequest;
}
}
if ($_POST['type'] == 'network') {
$apiRequest = apiRequest('docker-removeNetwork', [], ['id' => $_POST['orphan']])['result'];
if (stripos($apiRequest, 'error') !== false || stripos($apiRequest, 'help') !== false) {
if (stri_contains($apiRequest, 'error') || stri_contains($apiRequest, 'help')) {
echo $apiRequest;
}
}
if ($_POST['type'] == 'volume') {
$apiRequest = apiRequest('docker-removeVolume', [], ['name' => $_POST['orphan']])['result'];
if (stripos($apiRequest, 'error') !== false || stripos($apiRequest, 'help') !== false) {
if (stri_contains($apiRequest, 'error') || stri_contains($apiRequest, 'help')) {
echo $apiRequest;
}
}
Expand Down
1 change: 1 addition & 0 deletions root/app/www/public/classes/interfaces/Docker.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ interface DockerSock
public const START_CONTAINER = '/usr/bin/docker container start %s';
public const STOP_CONTAINER = '/usr/bin/docker container stop %s%s';
public const ORPHAN_CONTAINERS = '/usr/bin/docker images -f dangling=true --format="{{json . }}" | jq -s --tab .';
public const UNUSED_CONTAINERS = '/usr/bin/docker images --format \'{{.ID}}:{{.Repository}}:{{.Tag}}\' | grep -v "$(docker ps --format {{.Image}})"';
public const CONTAINER_PORT = '/usr/bin/docker port %s %s';
//-- IMAGE SPECIFIC
public const REMOVE_IMAGE = '/usr/bin/docker image rm %s';
Expand Down
22 changes: 22 additions & 0 deletions root/app/www/public/classes/traits/Docker/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,28 @@ public function stopContainer($containerName)
return $this->shell->exec($cmd . ' 2>&1');
}

public function getUnusedContainers()
{
$unused = [];
$cmd = DockerSock::UNUSED_CONTAINERS;
$containers = $this->shell->exec($cmd . ' 2>&1');

if ($containers) {
$containerList = explode("\n", $containers);
foreach ($containerList as $container) {
list($id, $image, $tag) = explode(':', $container);

if (!$id) {
continue;
}

$unused[] = ['ID' => $id, 'Repository' => $image, 'Tag' => $tag];
}
}

return json_encode($unused);
}

public function getOrphanContainers()
{
$cmd = DockerSock::ORPHAN_CONTAINERS;
Expand Down
2 changes: 2 additions & 0 deletions root/app/www/public/functions/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ function apiRequestLocal($endpoint, $parameters = [], $payload = [])
return $docker->getOrphanNetworks();
case 'docker-getOrphanVolumes':
return $docker->getOrphanVolumes();
case 'docker-getUnusedContainers':
return $docker->getUnusedContainers();
case 'docker-imageSizes':
return $docker->getImageSizes();
case 'docker-inspect':
Expand Down
5 changes: 5 additions & 0 deletions root/app/www/public/functions/helpers/strings.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
----------------------------------
*/

function stri_contains(string|null $haystack, string $needle)
{
return str_contains(strtolower($haystack), strtolower($needle));
}

function str_equals_any(string|null $haystack, array $needles): bool
{
if (!$haystack) {
Expand Down
2 changes: 2 additions & 0 deletions root/app/www/public/js/orphans.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ function removeOrphans()
type = 'volume';
} else if (split[0] == 'orphanNetwork') {
type = 'network';
} else if (split[0] == 'unusedContainer') {
type = 'unused';
}

selectedOrphans.push({'orphan': split[1], 'type': type});
Expand Down

0 comments on commit 6fbf821

Please sign in to comment.