$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
require_once "$docroot/webGui/include/Helpers.php";
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
// add translations
$_SERVER['REQUEST_URI'] = 'docker';
require_once "$docroot/webGui/include/Translations.php";
$DockerClient = new DockerClient();
$DockerTemplates = new DockerTemplates();
$containers = $DockerClient->getDockerContainers();
$images = $DockerClient->getDockerImages();
$user_prefs = $dockerManPaths['user-prefs'];
$autostart_file = $dockerManPaths['autostart-file'];
if (!$containers && !$images) {
echo "
";
if ($template && empty($composestack)) {
$appname = "".htmlspecialchars($name)."";
} else {
$appname = htmlspecialchars($name);
}
echo "$image$appname "._($status).(!empty($composestack) ? ' Compose Stack: ' . $composestack : '')."";
echo ""._('Container ID').": $id ";
if ($ct['BaseImage']) echo " ".htmlspecialchars($ct['BaseImage'])." ";
echo _('By').": ";
$registry = $info['registry'];
['strRepo' => $author, 'strTag' => $version] = DockerUtil::parseImageTag($ct['Image']);
if ($registry) {
echo " ".htmlspecialchars(compress($author,24))."";
} else {
echo htmlspecialchars(compress($author,24));
}
echo " | ";
switch ($updateStatus) {
case 0:
if ($ct['Manager'] == "dockerman") {
echo " "._('up-to-date')."";
echo "";
} elseif (!empty($composestack)) {
echo " Compose ";
echo " "._('up-to-date')."";
} else {
echo " 3rd Party ";
echo " "._('up-to-date')."";
}
break;
case 1:
echo " "._('update ready')." ";
if ($ct['Manager'] == "dockerman") {
echo " "._('apply update')."";
} elseif (!empty($composestack)) {
echo " Compose ";
echo " "._('update available')."";
} else {
echo " 3rd Party ";
echo " "._('update available')."";
}
break;
case 2:
echo " "._('rebuild ready')." ";
echo " "._('rebuilding')."";
break;
default:
if ($ct['Manager'] == "dockerman") {
echo " "._('not available')."";
echo "";
} elseif (!empty($composestack)) {
echo " Compose ";
echo " "._('not available')."";
} else {
echo " 3rd Party ";
echo " "._('not available')."";
}
break;
}
// Check if Tailscale for container is enabled by checking if TShostname is set
if (!empty($TShostname)) {
if ($running) {
// Get stats from container and check if they are not empty
$TSstats = tailscale_stats($name);
if (!empty($TSstats)) {
// Construct TSinfo from TSstats
$TSinfo = '';
if (!$TSstats["Self"]["Online"]) {
$TSinfo .= "Online:\t\t❌\nPlease check the logs!";
} else {
$TS_version = explode('-', $TSstats["Version"])[0];
if (!empty($TS_version)) {
if (!empty($TS_latest_version)) {
if ($TS_version !== $TS_latest_version) {
$TSinfo .= "Version:\t\t" . $TS_version . " ➔ " . $TS_latest_version . " available!\n";
} else {
$TSinfo .= "Version:\t\t" . $TS_version . "\n";
}
} else {
$TSinfo .= "Version:\t\t" . $TS_version . "\n";
}
}
$TSinfo .= "Online:\t\t✅\n";
$TS_DNSName = $TSstats["Self"]["DNSName"];
$TS_HostNameActual = substr($TS_DNSName, 0, strpos($TS_DNSName, '.'));
if (strcasecmp($TS_HostNameActual, $TShostname) !== 0 && !empty($TS_DNSName)) {
$TSinfo .= "Hostname:\tReal Hostname ➔ " . $TS_HostNameActual . "\n";
} else {
$TSinfo .= "Hostname:\t" . $TShostname . "\n";
}
// Map region relay code to cleartext region if TS_derp_list is available
if (!empty($TS_derp_list)) {
foreach ($TS_derp_list['Regions'] as $region) {
if ($region['RegionCode'] === $TSstats["Self"]["Relay"]) {
$TSregion = $region['RegionName'];
break;
}
}
if (!empty($TSregion)) {
$TSinfo .= "Main Relay:\t" . $TSregion . "\n";
} else {
$TSinfo .= "Main Relay:\t" . $TSstats["Self"]["Relay"] . "\n";
}
} else {
$TSinfo .= "Main Relay:\t" . $TSstats["Self"]["Relay"] . "\n";
}
if (!empty($TSstats["Self"]["TailscaleIPs"])) {
$TSinfo .= "Addresses:\t" . implode("\n\t\t\t", $TSstats["Self"]["TailscaleIPs"]) . "\n";
}
if (!empty($TSstats["Self"]["PrimaryRoutes"])) {
$TSinfo .= "Routes:\t\t" . implode("\n\t\t\t", $TSstats["Self"]["PrimaryRoutes"]) . "\n";
}
if ($TSstats["Self"]["ExitNodeOption"]) {
$TSinfo .= "Is Exit Node:\t✅\n";
} else {
if (!empty($TSstats["ExitNodeStatus"])) {
$TS_exit_node_status = ($TSstats["ExitNodeStatus"]["Online"]) ? "✅" : "❌";
$TSinfo .= "Exit Node:\t" . strstr($TSstats["ExitNodeStatus"]["TailscaleIPs"][0], '/', true) . " | Status: " . $TS_exit_node_status ."\n";
} else {
$TSinfo .= "Is Exit Node:\t❌\n";
}
}
if (!empty($TSwebGui)) {
$TSinfo .= "URL:\t\t" . $TSwebGui . "\n";
}
if (!empty($TSstats["Self"]["KeyExpiry"])) {
$TS_expiry = new DateTime($TSstats["Self"]["KeyExpiry"]);
$current_Date = new DateTime();
$TS_expiry_formatted = $TS_expiry->format('Y-m-d');
$TS_expiry_diff = $current_Date->diff($TS_expiry);
if ($TS_expiry_diff->invert) {
$TSinfo .= "Key Expiry:\t❌ Expired! Renew/Disable key expiry!\n";
} else {
$TSinfo .= "Key Expiry:\t" . $TS_expiry_formatted . " (" . $TS_expiry_diff->days . " days)\n";
}
}
}
// Display message to refresh page if Tailscale in the container wasn't maybe ready to get the data
} else {
echo " Tailscale | ";
}
// Display TSinfo if data was fetched correctly
echo "
Tailscale
";
// Display message that container isn't running
} else {
echo "
Tailscale
";
}
}
echo " ".compress(_($version),12,0)."
";
echo " ".implode(' ',$networks)." | ";
echo " ".implode(' ',$network_ips)." | ";
echo "".implode(' ',$ports_internal)." | ";
echo "".implode(' ',$ports_external)." | ";
echo "".implode(' ',$paths)." | ";
echo "0% ";
echo " 0 / 0 | ";
if (empty($composestack)) {
if ($ct['Manager'] == "dockerman") {
echo "";
} else {
echo " | 3rd Party";
}
} else {
echo " | Compose";
}
echo ""._('wait')." | ";
echo "".htmlspecialchars(str_replace('Up',_('Uptime').':',my_lang_log($ct['Status'])))." "._('Created').": ".htmlspecialchars(my_lang_time($ct['Created']))." |
";
}
foreach ($images as $image) {
if (count($image['usedBy'])) continue;
$id = $image['Id'];
$menu = sprintf("onclick=\"addDockerImageContext('%s','%s')\"", $id, implode(',',$image['Tags']));
echo "";
echo " ("._('orphan image').") "._('stopped')."";
echo " | "._('Image ID').": $id ";
echo implode(', ',$image['Tags']);
echo " | "._('Created')." ".htmlspecialchars(_($image['Created'],0))." |
";
}
echo "\0".implode($docker)."\0".(pgrep('rc.docker')!==false ? 1:0);
?>