Files
webgui/plugins/dynamix.docker.manager/DockerContainers.page
Squidly271 6965583061 Add in Support & Project Links to Docker Context Menu
Every container added in via CA should already have the Support Link present (if added post 6.3)
Majority of apps in CA also have a project link present, but this will only thus far dockerMan hasn't saved that entry on user templates, so the Project link on the context menus will only appear for new containers added after the PR is aproved
2018-01-27 10:13:15 -05:00

270 lines
12 KiB
Plaintext

Menu="Docker:1"
Title="Docker Containers"
Tag="cubes"
Cond="(pgrep('dockerd')!==false)"
Markdown="false"
---
<?PHP
/* Copyright 2005-2017, Lime Technology
* Copyright 2014-2017, Guilherme Jardim, Eric Schultz, Jon Panozzo.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*/
?>
<?
// Add the Docker JSON client
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
$DockerClient = new DockerClient();
$DockerUpdate = new DockerUpdate();
$DockerTemplates = new DockerTemplates();
?>
<link type="text/css" rel="stylesheet" href="/webGui/styles/jquery.ui.css">
<link type="text/css" rel="stylesheet" href="/webGui/styles/jquery.switchbutton.css">
<style>
body {-webkit-overflow-scrolling: touch;}
img.started{opacity:1.0;}
img.stopped{opacity:0.3;}
.log{cursor:zoom-in;}
.exec{cursor:pointer;}
.fa-custom{font-size: 1.3em;}
.basic{display: block;}
.advanced{display:none;white-space: nowrap;}
.iconstatus{position:absolute;z-index:2;bottom:-4px;right:-4px;font-size:1.2em;text-shadow:0 0 2px #FFF;}
.iconstatus.started{font-size:1.3em;}
.iconstatus.stopped{font-size:1.2em;}
.started{color:#009900;}
.stopped{color:#EF3D47;}
.switch-button-label.off{color:inherit;}
</style>
<form id="formAutostart" method="POST" action="/plugins/dynamix.docker.manager/include/UpdateConfig.php" target="progressFrame">
<input type="hidden" name="action" value="autostart" />
<input type="hidden" name="container" value="none" />
</form>
<form id="formStartStop" method="POST" action="/update.php" target="progressFrame">
<input type="hidden" id="cmdStartStop" name="#command" value="">
<input type="hidden" id="cmdArg1" name="#arg[1]" value="">
<input type="hidden" id="cmdArg2" name="#arg[2]" value="">
</form>
<div id="dialog-confirm" style="display:none;" title="Dialog Title"></div>
<div id="iframe-popup" style="display:none;-webkit-overflow-scrolling:touch;"></div>
<span class="status" style="margin-top: -44px;"><input type="checkbox" class="advancedview"></span>
<table class="tablesorter shift" id="docker_containers">
<thead>
<tr>
<th>&nbsp;</th>
<th>Application</th>
<th>Version</th>
<th>Port Mappings <small>(App to Host)</small></th>
<th>Volume Mappings <small>(App to Host)</small></th>
<th width="80px" style="text-align: center">Autostart</th>
<th>Log</th>
</tr>
</thead>
<tbody id="docker_list">
<?
$all_containers = $DockerClient->getDockerContainers();
if (!$all_containers) {
$all_containers = [];
echo "<tr><td></td><td colspan=\"7\">No Docker Containers Installed</td></tr>";
}
$info = $DockerTemplates->getAllInfo();
$contextMenus = [];
$IP = $eth0["IPADDR:0"];
foreach ($all_containers as $ct) {
$name = $ct["Name"];
$is_autostart = ($info[$name]['autostart']) ? 'true' : 'false';
$updateStatus = $info[$name]['updated'];
$updateStatus = ($updateStatus == "true" || $updateStatus == "undef") ? 'true' : 'false';
$running = ($ct['Running']) ? 'true' : 'false';
$webGuiUrl = $info[$name]['url'];
$Support = $ct['Support'];
$Project = $ct['Project'];
$contextMenus[] = sprintf("addDockerContainerContext('%s', '%s', '%s', %s, %s, %s, '%s', '%s', '%s', '%s');", addslashes($ct['Name']), addslashes($ct['ImageId']), addslashes($info[$name]['template']), $running, $updateStatus, $is_autostart, addslashes($webGuiUrl), $ct["Id"], addslashes($info[$name]['Support']),addslashes($info[$name]['Project']));
$shape = ($ct["Running"]) ? "play" : "square";
$status = ($ct["Running"]) ? "started" : "stopped";
$Icon = $info[$name]['icon'];
if (!$Icon) {
$Icon = "/plugins/dynamix.docker.manager/images/question.png";
}
$ports = [];
foreach ($ct['Ports'] as $p) {
if (strlen($p['PublicPort'])) {
$ipAddr = sprintf("%s:%s", $IP, $p['PublicPort']);
$outFormat = sprintf('<a href="http://%s" target="_blank">%s/%s <i class="fa fa-arrows-h" style="margin: 0 3px"></i> %s</a>', $ipAddr, $p['PrivatePort'], $p['Type'], htmlspecialchars($ipAddr));
} else {
$outFormat = sprintf("%s/%s", $p['PrivatePort'], $p['Type']);
}
$ports[] = $outFormat;
}
$paths = [];
if (count($ct['Volumes'])){
foreach ($ct['Volumes'] as $value) {
if (preg_match('/localtime/', $value) == true) continue;
list($host_path, $container_path, $access_mode) = explode(":", $value);
$tip = 'Container volume \'' . $container_path . '\' has ' . ($access_mode == 'ro' ? 'read-only' : 'read-write') . ' access to Host path \'' . $host_path . '\'';
$paths[] = sprintf('<a href="/Shares/Browse?dir=%s" target="_blank" title="%s">%s <i class="fa fa-%s" style="margin: 0 3px"></i> %s</a>', urlencode($host_path), htmlspecialchars($tip), htmlspecialchars($container_path), ($access_mode == 'ro' ? 'long-arrow-left' : 'arrows-h'), htmlspecialchars($host_path));
}
}
?>
<tr>
<td style="width: 48px; padding: 4px">
<?
echo " <div id=\"context-".htmlspecialchars($name)."\" style=\"display:block; cursor:pointer\">
<div style=\"position: relative; width: 48px; height: 48px; margin: 0px auto;\">
<img src=\"".htmlspecialchars($Icon)."\" class=\"".htmlspecialchars($status)."\" style=\"position: absolute; z-index: 1; top: 0; bottom: 0; left: 0; right: 0; width: 48px; height: 48px;\"/>
<i class=\"fa iconstatus fa-$shape $status\" title=\"".htmlspecialchars($status)."\"></i>
</div>
</div>";
?>
</td>
<td>
<?if($info[$ct['Name']]['template']):?>
<a class="exec" onclick="editContainer('<?=addslashes(htmlspecialchars($ct['Name']));?>','<?=addslashes(htmlspecialchars($info[$ct['Name']]['template']));?>');"><?=htmlspecialchars($ct['Name']);?></a>
<?else:?>
<?=htmlspecialchars($ct['Name']);?>
<?endif;?>
<div class="advanced" style="color:#888; width: 160px;">Container ID: <?=htmlspecialchars($ct['Id']);?></div>
<?if($ct['BaseImage']):?>
<div class="advanced" style="color:#888; width: 160px;"><i class="fa fa-cubes" style="margin-right: 5px"></i><?=htmlspecialchars(${ct[BaseImage]})?></div>
<?endif;?>
<div class="advanced" style="color:#888; width: 160px;">By:
<?if($Registry = $info[$ct['Name']]['registry']):?>
<a href="<?=htmlspecialchars($Registry)?>" target="_blank"><?=htmlspecialchars($ct['Image'])?></a>
<?else:?>
<?=htmlspecialchars($ct['Image']);?>
<?endif;?>
</div>
</td>
<td class="updatecolumn">
<?
$updateStatus = $info[$ct['Name']]['updated'];
if ($updateStatus == "false") {
echo "<a class=\"exec\" onclick=\"updateContainer('" . addslashes(htmlspecialchars($ct["Name"])) . "');\"><span style=\"white-space:nowrap;\"><i class=\"fa fa-cloud-download\"></i> update ready</span></a>";
} elseif ($updateStatus == "true") {
echo "<span style=\"color:#44B012;white-space:nowrap;\"><i class=\"fa fa-check\"></i> up-to-date</span>";
echo "<div class=\"advanced\"><a class=\"exec\" onclick=\"updateContainer('" . addslashes(htmlspecialchars($ct["Name"])) . "');\" style=\"color:#888;\"><span style=\"white-space:nowrap;\"><i class=\"fa fa-cloud-download\"></i> force update</span></a></div>";
} else {
echo "<span style=\"color:#FF2400;white-space:nowrap;\"><i class=\"fa fa-exclamation-triangle\"></i> not available</span>";
echo "<div class=\"advanced\"><a class=\"exec\" onclick=\"updateContainer('" . addslashes(htmlspecialchars($ct["Name"])) . "');\" style=\"color:#888;\"><span style=\"white-space:nowrap;\"><i class=\"fa fa-cloud-download\"></i> force update</span></a></div>";
}
?>
</td>
<td style="white-space:nowrap;"><span class="docker_readmore"><?= implode("<br>", $ports); ?></span></td>
<td style="word-break:break-all;"><span class="docker_readmore"><?= implode("<br>", $paths); ?></span></td>
<td data-sort-value="<?=$is_autostart?>"><input type="checkbox" class="autostart" container="<?=htmlspecialchars($ct['Name']);?>" <?=$info[$ct['Name']]['autostart'] ? "checked" : ""?>></td>
<td><a class="log" onclick="containerLogs('<?=addslashes(htmlspecialchars($ct['Name']));?>','<?=$ct['Id'];?>', false, false)"><img class="basic" src="/plugins/dynamix/icons/log.png"/><div class="advanced" style="width: 124px;"><?=htmlspecialchars($ct['Status'])?></div><div class="advanced" style="color:#888;">Created <?=htmlspecialchars($ct['Created'])?></div></a></td>
</tr>
<?}?>
<?
foreach ($DockerClient->getDockerImages() as $image) {
if (count($image['usedBy'])) {
continue;
}
$contextMenus[] = sprintf("addDockerImageContext('%s', '%s');", $image['Id'], implode(', ', $image['Tags']));
?>
<tr class="advanced">
<td style="width: 48px; padding: 4px">
<?
echo " <div id=\"context-".htmlspecialchars($image['Id'])."\" style=\"display:block; cursor:pointer\">
<div style=\"position: relative; width: 48px; height: 48px; margin: 0px auto;\">
<img src=\"/webGui/images/disk.png\" style=\"position: absolute; z-index: 1; opacity: 0.3; top: 0; bottom: 0; left: 0; right: 0; width: 48px; height: 48px;\"/>
</div>
</div>";
?>
</td>
<td data-sort-value="ZZZZZZZZZZZ">
<i>(orphan image)</i>
<div style="color:#888; width: 160px;">Image ID: <?=htmlspecialchars($image['Id'])?></div>
<?if(strpos(implode($image['Tags']), "&lt;none&gt;:&lt;none&gt;") === false):?>
<div style="color:#888; width: 160px;"><?=implode("<br>", array_map('htmlspecialchars',$image['Tags']))?></div>
<?endif;?>
</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td><div class="advanced" style="width: 124px; color:#888;">Created <?=htmlspecialchars($image['Created'])?></div></td>
</tr>
<?}?>
</tbody>
</table>
<input type="button" onclick="addContainer()" value="Add Container"/>
<input type="button" onclick="reloadUpdate()" value="Check for Updates"/>
<script src="<?autov('/webGui/javascript/jquery.switchbutton.js')?>"></script>
<script src="<?autov('/plugins/dynamix.docker.manager/javascript/docker.js')?>"></script>
<script>
<?if ($display['resize']):?>
function resize(bind) {
var width = [];
var h = $('#docker_list').height();
var s = Math.max(window.innerHeight-300,370);
if (h>s || bind) {
$('#docker_list').height(s);
$('#docker_containers tbody tr:first-child td').each(function(){width.push($(this).width());});
$('#docker_containers thead tr th').each(function(i){$(this).width(width[i]);});
if (!bind) $('#docker_containers thead,#docker_containers tbody').addClass('fixed');
}
}
<?endif;?>
$(function() {
if ($.cookie('docker_listview_mode') == 'advanced') {
$('.advanced').show();
$('.basic').hide();
}
$('.autostart').switchButton({
labels_placement: "right"
});
$('.autostart').change(function () {
$.post( "/plugins/dynamix.docker.manager/include/UpdateConfig.php", { action: "autostart", container: $(this).attr('container'), response: "json" }, function( data ) {
$(this).prop('checked', data.autostart );
}, "json");
});
$('.advancedview').switchButton({
labels_placement: "left",
on_label: 'Advanced View',
off_label: 'Basic View',
checked: $.cookie('docker_listview_mode') == 'advanced'
});
$('.advancedview').change(function () {
$('.advanced').toggle('slow');
$('.basic').toggle('slow');
$.cookie('docker_listview_mode', $('.advancedview').is(':checked') ? 'advanced' : 'basic', { expires: 3650 });
});
<?if ($display['resize']):?>
resize();
$(window).bind('resize',function(){resize(true);});
<?endif;?>
$('#docker_containers').tablesorter( {sortList: [[1,0]], headers: {0: {sorter: false }, 7: {sorter: false }}});
$('#docker_containers tr:even').addClass('odd');
context.init({ preventDoubleContext: false });
<?=htmlspecialchars(implode("\n\t", $contextMenus));?>
$('.docker_readmore').readmore({maxHeight:48, moreLink: '<a href="#" style="text-align:center;"><i class="fa fa-chevron-down"></i></a>', lessLink: '<a href="#" style="text-align:center;"><i class="fa fa-chevron-up"></i></a>'});
});
</script>