Fixes and improvements for Docker

- fixed deletion of orphan images
- inline list update when removing container or image
- fixed list updating after execution error
- added animation when removing container or image
- delete old xml file when container is renamed
- fixed IP assignment with multiple containers based on the same image
This commit is contained in:
bergware
2018-03-16 17:15:21 +01:00
parent 863736c32a
commit 9dfd418dd4
4 changed files with 66 additions and 139 deletions

View File

@@ -381,8 +381,8 @@ function xmlToCommand($xml, $create_paths=false) {
global $var;
global $docroot;
$xml = xmlToVar($xml);
$cmdName = (strlen($xml['Name'])) ? '--name='.escapeshellarg($xml['Name']) : '';
$cmdPrivileged = (strtolower($xml['Privileged']) == 'true') ? '--privileged=true' : '';
$cmdName = strlen($xml['Name']) ? '--name='.escapeshellarg($xml['Name']) : '';
$cmdPrivileged = strtolower($xml['Privileged'])=='true' ? '--privileged=true' : '';
$cmdNetwork = '--net='.escapeshellarg(strtolower($xml['Network']));
$cmdMyIP = $xml['MyIP'] ? '--ip='.escapeshellarg($xml['MyIP']) : '';
$Volumes = [''];
@@ -434,9 +434,7 @@ function xmlToCommand($xml, $create_paths=false) {
$xml['ExtraParams'],
escapeshellarg($xml['Repository']),
$xml['PostArgs']);
$cmd = trim(preg_replace('/\s+/', ' ', $cmd));
return [$cmd, $xml['Name'], $xml['Repository']];
return [preg_replace('/\s+/', ' ', $cmd), $xml['Name'], $xml['Repository']];
}
function execCommand($command) {
@@ -532,11 +530,10 @@ function getUsedIPs() {
##
## CREATE CONTAINER
##
if (isset($_POST['contName'])) {
$postXML = postToXML($_POST, true);
$dry_run = ($_POST['dryRun'] == "true") ? true : false;
$dry_run = $_POST['dryRun']=='true' ? true : false;
$existing = $_POST['existingContainer'] ?? false;
$create_paths = $dry_run ? false : true;
// Get the command line
@@ -547,10 +544,8 @@ if (isset($_POST['contName'])) {
// Saving the generated configuration file.
$userTmplDir = $dockerManPaths['templates-user'];
if (!is_dir($userTmplDir)) {
mkdir($userTmplDir, 0777, true);
}
if (!empty($Name)) {
if (!is_dir($userTmplDir)) mkdir($userTmplDir, 0777, true);
if ($Name) {
$filename = sprintf('%s/my-%s.xml', $userTmplDir, $Name);
file_put_contents($filename, $postXML);
}
@@ -591,7 +586,6 @@ if (isset($_POST['contName'])) {
}
// Remove old container if renamed
$existing = isset($_POST['existingContainer']) ? $_POST['existingContainer'] : false;
if ($existing && $DockerClient->doesContainerExist($existing)) {
// determine if the container is still running
$oldContainerDetails = $DockerClient->getContainerDetails($existing);
@@ -605,6 +599,8 @@ if (isset($_POST['contName'])) {
// force kill container if still running after 10 seconds
removeContainer($existing);
// remove old template
@unlink("$userTmplDir/my-$existing.xml");
}
if ($startContainer) {

View File

@@ -1,6 +1,7 @@
<?PHP
/* Copyright 2005-2017, Lime Technology
* Copyright 2014-2017, Guilherme Jardim, Eric Schultz, Jon Panozzo.
/* Copyright 2005-2018, Lime Technology
* Copyright 2014-2018, Guilherme Jardim, Eric Schultz, Jon Panozzo.
* Copyright 2012-2018, Bergware International.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2,
@@ -46,13 +47,11 @@ class DockerTemplates {
if ($this->verbose) echo $m."\n";
}
public function download_url($url, $path = "", $bg = false) {
exec("curl --max-time 60 --silent --insecure --location --fail ".($path ? " -o ".escapeshellarg($path) : "")." ".escapeshellarg($url)." ".($bg ? ">/dev/null 2>&1 &" : "2>/dev/null"), $out, $exit_code);
return ($exit_code === 0) ? implode("\n", $out) : false;
}
public function listDir($root, $ext = null) {
$iter = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($root,
@@ -68,7 +67,6 @@ class DockerTemplates {
return $paths;
}
public function getTemplates($type) {
global $dockerManPaths;
$tmpls = [];
@@ -90,7 +88,6 @@ class DockerTemplates {
return $tmpls;
}
private function removeDir($path) {
if (is_dir($path)) {
$files = array_diff(scandir($path), ['.', '..']);
@@ -104,11 +101,10 @@ class DockerTemplates {
return false;
}
public function downloadTemplates($Dest = null, $Urls = null) {
global $dockerManPaths;
$Dest = ($Dest) ? $Dest : $dockerManPaths['templates-storage'];
$Urls = ($Urls) ? $Urls : $dockerManPaths['template-repos'];
$Dest = $Dest ?: $dockerManPaths['templates-storage'];
$Urls = $Urls ?: $dockerManPaths['template-repos'];
$repotemplates = [];
$output = [];
$tmp_dir = "/tmp/tmp-".mt_rand();
@@ -129,10 +125,10 @@ class DockerTemplates {
$github_api = ['url' => ''];
foreach ($github_api_regexes as $api_regex) {
if (preg_match($api_regex, $url, $matches)) {
$github_api['user'] = (isset($matches[1])) ? $matches[1] : "";
$github_api['repo'] = (isset($matches[2])) ? $matches[2] : "";
$github_api['branch'] = (isset($matches[3])) ? $matches[3] : "master";
$github_api['path'] = (isset($matches[4])) ? $matches[4] : "";
$github_api['user'] = $matches[1] ?? "";
$github_api['repo'] = $matches[2] ?? "";
$github_api['branch'] = $matches[3] ?? "master";
$github_api['path'] = $matches[4] ?? "";
$github_api['url'] = sprintf("https://github.com/%s/%s/archive/%s.tar.gz", $github_api['user'], $github_api['repo'], $github_api['branch']);
break;
}
@@ -151,10 +147,10 @@ class DockerTemplates {
];
foreach ($custom_api_regexes as $api_regex) {
if (preg_match($api_regex, $url, $matches)) {
$github_api['user'] = (isset($matches[1])) ? $matches[1] : "";
$github_api['repo'] = (isset($matches[2])) ? $matches[2] : "";
$github_api['branch'] = (isset($matches[3])) ? $matches[3] : "master";
$github_api['path'] = (isset($matches[4])) ? $matches[4] : "";
$github_api['user'] = $matches[1] ?? "";
$github_api['repo'] = $matches[2] ?? "";
$github_api['branch'] = $matches[3] ?? "master";
$github_api['path'] = $matches[4] ?? "";
$github_api['url'] = sprintf("https://".$parse['host']."/%s/%s/repository/archive.tar.gz?ref=%s", $github_api['user'], $github_api['repo'], $github_api['branch']);
break;
}
@@ -213,7 +209,6 @@ class DockerTemplates {
return $output;
}
public function getTemplateValue($Repository, $field, $scope = "all") {
foreach ($this->getTemplates($scope) as $file) {
$doc = new DOMDocument();
@@ -228,7 +223,6 @@ class DockerTemplates {
return null;
}
public function getUserTemplate($Container) {
foreach ($this->getTemplates("user") as $file) {
$doc = new DOMDocument('1.0', 'utf-8');
@@ -241,11 +235,9 @@ class DockerTemplates {
return false;
}
public function getControlURL($name) {
global $eth0;
$DockerClient = new DockerClient();
$Repository = "";
foreach ($DockerClient->getDockerContainers() as $ct) {
if ($ct['Name'] == $name) {
@@ -254,12 +246,10 @@ class DockerTemplates {
break;
}
}
$WebUI = $this->getTemplateValue($Repository, "WebUI");
$myIP = $this->getTemplateValue($Repository, "MyIP");
$network = $this->getTemplateValue($Repository, "Network");
if (!$myIP && preg_match('%^(br|eth|bond)[0-9]%',$network)) {
$name = $this->getTemplateValue($Repository, "Name");
$myIP = exec("docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $name");
}
if (preg_match("%\[IP\]%", $WebUI)) {
@@ -279,7 +269,6 @@ class DockerTemplates {
return $WebUI;
}
public function removeContainerInfo($container) {
global $dockerManPaths;
@@ -290,7 +279,6 @@ class DockerTemplates {
}
}
public function removeImageInfo($image) {
global $dockerManPaths;
$image = DockerUtil::ensureImageTag($image);
@@ -302,57 +290,33 @@ class DockerTemplates {
}
}
public function getAllInfo($reload = false) {
global $dockerManPaths;
$DockerClient = new DockerClient();
$DockerUpdate = new DockerUpdate();
$DockerUpdate->verbose = $this->verbose;
$new_info = [];
$info = DockerUtil::loadJSON($dockerManPaths['webui-info']);
$autostart_file = $dockerManPaths['autostart-file'];
$allAutoStart = @file($autostart_file, FILE_IGNORE_NEW_LINES);
if ($allAutoStart === false) $allAutoStart = [];
$allAutoStart = @file($dockerManPaths['autostart-file'], FILE_IGNORE_NEW_LINES) ?: [];
foreach ($DockerClient->getDockerContainers() as $ct) {
$name = $ct['Name'];
$image = $ct['Image'];
$tmp = is_array($info[$name]) ? $info[$name] : [];
$tmp = $info[$name] ?? [];
$tmp['running'] = $ct['Running'];
$tmp['autostart'] = in_array($name, $allAutoStart);
if (!$tmp['icon'] || $reload) {
$icon = $this->getIcon($image);
$tmp['icon'] = $icon ?: null;
}
$WebUI = $this->getControlURL($name);
$tmp['url'] = $WebUI ?: null;
$Registry = $this->getTemplateValue($image, "Registry");
$tmp['registry'] = ($Registry) ? $Registry : null;
$Support = $this->getTemplateValue($image, "Support");
$tmp['Support'] = ($Support) ? $Support : null;
$Project = $this->getTemplateValue($image, "Project");
$tmp['Project'] = ($Project) ? $Project : null;
if (!$tmp['icon'] || $reload) $tmp['icon'] = $this->getIcon($image) ?: null;
$tmp['url'] = $this->getControlURL($name) ?: null;
$tmp['registry'] = $this->getTemplateValue($image, "Registry") ?: null;
$tmp['Support'] = $this->getTemplateValue($image, "Support") ?: null;
$tmp['Project'] = $this->getTemplateValue($image, "Project") ?: null;
if (!$tmp['updated'] || $reload) {
if ($reload) $DockerUpdate->reloadUpdateStatus($image);
$vs = $DockerUpdate->getUpdateStatus($image);
$tmp['updated'] = ($vs === null) ? null : (($vs === true) ? 'true' : 'false');
}
if (!$tmp['template'] || $reload) {
$tmp['template'] = $this->getUserTemplate($name);
}
if ($reload) {
$DockerUpdate->updateUserTemplate($name);
}
if (!$tmp['template'] || $reload) $tmp['template'] = $this->getUserTemplate($name);
if ($reload) $DockerUpdate->updateUserTemplate($name);
$this->debug("\n$name");
foreach ($tmp as $c => $d) $this->debug(sprintf(" %-10s: %s", $c, $d));
@@ -362,7 +326,6 @@ class DockerTemplates {
return $new_info;
}
public function getIcon($Repository) {
global $docroot, $dockerManPaths;
@@ -383,7 +346,6 @@ class DockerTemplates {
}
}
######################################
## DOCKERUPDATE CLASS ##
######################################
@@ -394,23 +356,19 @@ class DockerUpdate{
if ($this->verbose) echo $m."\n";
}
private function xml_encode($string) {
return htmlspecialchars($string, ENT_XML1, 'UTF-8');
}
private function xml_decode($string) {
return strval(html_entity_decode($string, ENT_XML1, 'UTF-8'));
}
public function download_url($url, $path = "", $bg = false) {
exec("curl --max-time 30 --silent --insecure --location --fail ".($path ? " -o ".escapeshellarg($path) : "")." ".escapeshellarg($url)." ".($bg ? ">/dev/null 2>&1 &" : "2>/dev/null"), $out, $exit_code);
return ($exit_code === 0) ? implode("\n", $out) : false;
}
public function download_url_and_headers($url, $headers = [], $path = "", $bg = false) {
$strHeaders = '';
foreach ($headers as $header) {
@@ -420,7 +378,6 @@ class DockerUpdate{
return ($exit_code === 0) ? implode("\n", $out) : false;
}
// DEPRECATED: Only used for Docker Index V1 type update checks
public function getRemoteVersion($image) {
list($strRepo, $strTag) = explode(':', DockerUtil::ensureImageTag($image));
@@ -430,7 +387,6 @@ class DockerUpdate{
return ($apiContent === false) ? null : substr(json_decode($apiContent, true)[0]['id'], 0, 8);
}
public function getRemoteVersionV2($image) {
list($strRepo, $strTag) = explode(':', DockerUtil::ensureImageTag($image));
@@ -473,14 +429,12 @@ class DockerUpdate{
return $strDigest;
}
// DEPRECATED: Only used for Docker Index V1 type update checks
public function getLocalVersion($image) {
$DockerClient = new DockerClient();
return substr($DockerClient->getImageID($image), 0, 8);
}
public function getUpdateStatus($image) {
global $dockerManPaths;
$image = DockerUtil::ensureImageTag($image);
@@ -496,7 +450,6 @@ class DockerUpdate{
return null;
}
public function reloadUpdateStatus($image = null) {
global $dockerManPaths;
$DockerClient = new DockerClient();
@@ -519,7 +472,6 @@ class DockerUpdate{
DockerUtil::saveJSON($dockerManPaths['update-status'], $updateStatus);
}
public function setUpdateStatus($image, $version) {
global $dockerManPaths;
$image = DockerUtil::ensureImageTag($image);
@@ -533,7 +485,6 @@ class DockerUpdate{
DockerUtil::saveJSON($dockerManPaths['update-status'], $updateStatus);
}
public function updateUserTemplate($Container) {
$changed = false;
$DockerTemplates = new DockerTemplates();
@@ -636,7 +587,6 @@ class DockerUpdate{
}
}
######################################
## DOCKERCLIENT CLASS ##
######################################
@@ -646,14 +596,12 @@ class DockerClient {
private $allImagesCache = null;
private function build_sorter($key) {
return function ($a, $b) use ($key) {
return strnatcmp(strtolower($a[$key]), strtolower($b[$key]));
};
}
public function humanTiming($time) {
$time = time() - $time; // to get the time since that moment
$tokens = [
@@ -668,11 +616,10 @@ class DockerClient {
foreach ($tokens as $unit => $text) {
if ($time < $unit) continue;
$numberOfUnits = floor($time / $unit);
return $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'').' ago';
return $numberOfUnits.' '.$text.(($numberOfUnits==1)?'':'s').' ago';
}
}
public function formatBytes($size) {
if ($size == 0) return '0 B';
$base = log($size) / log(1024);
@@ -680,7 +627,6 @@ class DockerClient {
return round(pow(1024, $base - floor($base)), 0) .' '. $suffix[floor($base)];
}
public function getDockerJSON($url, $method = "GET", &$code = null, $callback = null, $unchunk = false) {
$fp = stream_socket_client('unix:///var/run/docker.sock', $errno, $errstr);
@@ -713,7 +659,6 @@ class DockerClient {
return $data;
}
function doesContainerExist($container) {
foreach ($this->getDockerContainers() as $ct) {
if ($ct['Name'] == $container) {
@@ -723,7 +668,6 @@ class DockerClient {
return false;
}
function doesImageExist($image) {
foreach ($this->getDockerImages() as $img) {
if (strpos($img['Tags'][0], $image) !== false) {
@@ -733,24 +677,20 @@ class DockerClient {
return false;
}
public function getInfo() {
$info = $this->getDockerJSON("/info");
$version = $this->getDockerJSON("/version");
return array_merge($info, $version);
}
public function getContainerLog($id, $callback, $tail = null, $since = null) {
$this->getDockerJSON("/containers/${id}/logs?stderr=1&stdout=1&tail=".urlencode($tail)."&since=".urlencode($since), "GET", $code, $callback, true);
}
public function getContainerDetails($id) {
return $this->getDockerJSON("/containers/${id}/json");
}
public function startContainer($id) {
$this->getDockerJSON("/containers/${id}/start", "POST", $code);
$this->allContainersCache = null; // flush cache
@@ -763,7 +703,6 @@ class DockerClient {
return (array_key_exists($code, $codes)) ? $codes[$code] : 'Error code '.$code;
}
public function stopContainer($id) {
$this->getDockerJSON("/containers/${id}/stop?t=10", "POST", $code);
$this->allContainersCache = null; // flush cache
@@ -776,7 +715,6 @@ class DockerClient {
return (array_key_exists($code, $codes)) ? $codes[$code] : 'Error code '.$code;
}
public function restartContainer($id) {
$this->getDockerJSON("/containers/${id}/restart?t=10", "POST", $code);
$this->allContainersCache = null; // flush cache
@@ -788,7 +726,6 @@ class DockerClient {
return (array_key_exists($code, $codes)) ? $codes[$code] : 'Error code '.$code;
}
public function removeContainer($id) {
global $docroot, $dockerManPaths;
// Purge cached container information
@@ -819,14 +756,12 @@ class DockerClient {
return (array_key_exists($code, $codes)) ? $codes[$code] : 'Error code '.$code;
}
public function pullImage($image, $callback = null) {
$ret = $this->getDockerJSON("/images/create?fromImage=".urlencode($image), "POST", $code, $callback);
$this->allImagesCache = null; // flush cache
return $ret;
}
public function removeImage($id) {
global $dockerManPaths;
$image = $this->getImageName($id);
@@ -851,12 +786,10 @@ class DockerClient {
return (array_key_exists($code, $codes)) ? $codes[$code] : 'Error code '.$code;
}
private function getImageDetails($id) {
return $this->getDockerJSON("/images/${id}/json");
}
public function getDockerContainers() {
// Return cached values
if (is_array($this->allContainersCache)) {
@@ -871,21 +804,21 @@ class DockerClient {
$c["Image"] = DockerUtil::ensureImageTag($obj['Image']);
$c["ImageId"] = substr(str_replace('sha256:', '', $details["Image"]), 0, 12);
$c["Name"] = substr($details['Name'], 1);
$c["Status"] = $obj['Status'] ? $obj['Status'] : "None";
$c["Status"] = $obj['Status'] ?: "None";
$c["Running"] = $details["State"]["Running"];
$c["Cmd"] = $obj['Command'];
$c["Id"] = substr($obj['Id'], 0, 12);
$c['Volumes'] = $details["HostConfig"]['Binds'];
$c["Created"] = $this->humanTiming($obj['Created']);
$c["NetworkMode"] = $details['HostConfig']['NetworkMode'];
$c["BaseImage"] = isset($obj["Labels"]["BASEIMAGE"]) ? $obj["Labels"]["BASEIMAGE"] : false;
$c["BaseImage"] = $obj["Labels"]["BASEIMAGE"] ?? false;
$c["Ports"] = [];
if ($c["NetworkMode"] != 'host' && !empty($details['HostConfig']['PortBindings'])) {
foreach ($details['HostConfig']['PortBindings'] as $port => $value) {
list($PrivatePort, $Type) = explode("/", $port);
$c["Ports"][] = [
'IP' => empty($value[0]['HostIP']) ? '0.0.0.0' : $value[0]['HostIP'],
'IP' => $value[0]['HostIP'] ?? '0.0.0.0',
'PrivatePort' => $PrivatePort,
'PublicPort' => $value[0]['HostPort'],
'Type' => $Type
@@ -899,7 +832,6 @@ class DockerClient {
return $this->allContainersCache;
}
public function getContainerID($Container) {
foreach ($this->getDockerContainers() as $ct) {
if (preg_match("%" . preg_quote($Container, "%") . "%", $ct["Name"])) {
@@ -909,7 +841,6 @@ class DockerClient {
return null;
}
public function getImageID($Image) {
if ( ! strpos($Image,":") ) {
$Image .= ":latest";
@@ -943,7 +874,6 @@ class DockerClient {
return $out;
}
public function getDockerImages() {
// Return cached values
if (is_array($this->allImagesCache)) {
@@ -958,7 +888,7 @@ class DockerClient {
$c["ParentId"] = substr(str_replace('sha256:', '', $obj['ParentId']), 0, 12);
$c["Size"] = $this->formatBytes($obj['Size']);
$c["VirtualSize"] = $this->formatBytes($obj['VirtualSize']);
$c["Tags"] = isset($obj['RepoTags']) ? array_map("htmlspecialchars", $obj['RepoTags']) : array();
$c["Tags"] = array_map("htmlspecialchars", $obj['RepoTags'] ?? []);
$c["Repository"] = vsprintf('%1$s/%2$s', preg_split("#[:\/]#", DockerUtil::ensureImageTag($obj['RepoTags'][0])));
$c["usedBy"] = $this->usedBy($c["Id"]);
@@ -967,14 +897,12 @@ class DockerClient {
return $this->allImagesCache;
}
public function flushCaches() {
$this->allContainersCache = null;
$this->allImagesCache = null;
}
}
######################################
## DOCKERUTIL CLASS ##
######################################
@@ -999,7 +927,6 @@ class DockerUtil {
return trim($strRepo).':'.trim($strTag);
}
public static function loadJSON($path) {
$objContent = (is_file($path)) ? json_decode(file_get_contents($path), true) : [];
if (empty($objContent)) $objContent = [];
@@ -1007,12 +934,10 @@ class DockerUtil {
return $objContent;
}
public static function saveJSON($path, $content) {
if (!is_dir(dirname($path))) @mkdir(dirname($path), 0755, true);
return file_put_contents($path, json_encode($content, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
}
}
?>

View File

@@ -113,15 +113,16 @@ foreach ($all_containers as $ct) {
}
foreach ($DockerClient->getDockerImages() as $image) {
if (count($image['usedBy'])) continue;
$menu[] = sprintf("addDockerImageContext('%s','%s');",$image['Id'],implode(', ',$image['Tags']));
$id = $image['Id'];
$menu[] = sprintf("addDockerImageContext('%s','%s');",$id,implode(',',$image['Tags']));
echo "<tr class='advanced'><td style='width:48px;padding:4px'>";
echo "<div id='context-{$image['Id']}' style='display:block;cursor:pointer'>";
echo "<div id='$id' style='display:block;cursor:pointer'>";
echo "<div style='position:relative;width:48px;height:48px;margin:0 auto'>";
echo "<img src='/webGui/images/disk.png' style='position:absolute;opacity:0.3;top:0;bottom:0;left:0;right:0;width:48px;height:48px'>";
echo "</div></div></td>";
echo "<td data-sort-value='ZZZZZZZZZZZ'><i>(orphan image)</i><div style='width:160px;'>Image ID: ".htmlspecialchars($image['Id'])."</div>";
if (strpos(implode($image['Tags']),"&lt;none&gt;:&lt;none&gt;")===false) echo "<div style='width:'160px'>".implode('<br>',array_map('htmlspecialchars',$image['Tags']))."</div>";
echo "</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>";
echo "<td><i>(orphan image)</i><div style='width:160px;'>Image ID: $id</div>";
echo "<div style='width:160px'>".implode('<br>',array_map('htmlspecialchars',$image['Tags']))."</div></td>";
echo "<td colspan=4'>&nbsp;</td>";
echo "<td><div class='advanced' style='width:124px'>Created ".htmlspecialchars($image['Created'])."</div></td></tr>";
}
echo "\0".implode($menu).implode($docker);

View File

@@ -37,7 +37,7 @@ function addDockerContainerContext(container, image, template, started, update,
function addDockerImageContext(image, imageTag) {
var opts = [{header:'(orphan image)'}];
opts.push({text:"Remove", icon:"fa-trash", action:function(e){e.preventDefault(); rmImage(image, imageTag);}});
context.attach('#context-'+image, opts);
context.attach('#'+image, opts);
}
function execUpContainer(container) {
var title = "Updating the container: "+container;
@@ -70,8 +70,7 @@ function popupWithIframe(title, cmd, reload, func) {
});
$(".ui-dialog .ui-dialog-titlebar").addClass("menu");
$(".ui-dialog .ui-dialog-title").css("text-align", "center").css("width", "100%");
$(".ui-dialog .ui-dialog-content").css("padding", "0");
//$('.ui-widget-overlay').click(function() {$("#iframe-popup").dialog("close");});
$(".ui-dialog .ui-dialog-content").css("padding", "12");
}
function addContainer() {
var path = location.pathname;
@@ -94,12 +93,13 @@ function updateContainer(container) {
showCancelButton:true,
confirmButtonColor:"#8CD4F5",
confirmButtonText:"Yes, update it!"
}, function() {
},function(){
execUpContainer(container);
});
}
function rmContainer(container, image, id) {
var body = "Remove container: "+container+"<br><br><label><input id=\"removeimagechk\" type=\"checkbox\" checked style=\"display:inline; width:unset; height:unset; margin-top:unset; margin-bottom:unset\">also remove image</label>";
$('input[type=button]').prop('disabled',true);
swal({
title:"Are you sure?",
text:body,
@@ -108,18 +108,19 @@ function rmContainer(container, image, id) {
showCancelButton:true,
confirmButtonColor:"#DD6B55",
confirmButtonText:"Yes, delete it!",
closeOnConfirm:false,
showLoaderOnConfirm:true
}, function() {
},function(){
$('#'+id).find('i').removeClass().addClass('iconstatus fa fa-trash orange-text');
if ($("#removeimagechk").prop('checked')) {
eventControl({action:"remove_all", container:id, image:image});
eventControl({action:"remove_all", container:id, image:image},'loadlist');
} else {
eventControl({action:"remove_container", container:id});
eventControl({action:"remove_container", container:id},'loadlist');
}
});
}
function rmImage(image, imageName) {
var body = "Remove image: "+$('<textarea />').html(imageName).text();
$('input[type=button]').prop('disabled',true);
swal({
title:"Are you sure?",
text:body,
@@ -127,32 +128,36 @@ function rmImage(image, imageName) {
showCancelButton:true,
confirmButtonColor:"#DD6B55",
confirmButtonText:"Yes, delete it!",
closeOnConfirm:false,
showLoaderOnConfirm:true
}, function() {
eventControl({action:"remove_image", image:image});
},function(){
$('#'+image).find('i').removeClass().addClass('iconstatus fa fa-trash orange-text');
eventControl({action:"remove_image", image:image},'loadlist');
});
}
function eventControl(params, reload) {
var spin = typeof reload != 'undefined';
function eventControl(params, spin) {
if (spin) $('#'+params['container']).find('i').addClass('fa-spin');
$.post(eventURL, params, function(data) {
if (data.success === true) {
if (spin) setTimeout(reload+'()',500); else location=window.location.href;
if (spin) setTimeout(spin+'()',500); else location=window.location.href;
} else {
swal({title:"Execution error", text:data.success, type:"error"});
swal({
title:"Execution error",
text:data.success, type:"error"
},function(){
if (spin) setTimeout(spin+'()',500); else location=window.location.href;
});
}
}, "json");
},'json');
}
function startAll() {
$('input[type=button]').prop('disabled',true);
for (var i=0,ct; ct=docker[i]; i++) if (ct.state=='false') $('#'+ct.id).find('i').addClass('fa-spin');
$.post('/plugins/dynamix.docker.manager/include/ContainerManager.php',{action:'start'}, function(){loadlist();});
$.post('/plugins/dynamix.docker.manager/include/ContainerManager.php',{action:'start'},function(){loadlist();});
}
function stopAll() {
$('input[type=button]').prop('disabled',true);
for (var i=0,ct; ct=docker[i]; i++) if (ct.state=='true') $('#'+ct.id).find('i').addClass('fa-spin');
$.post('/plugins/dynamix.docker.manager/include/ContainerManager.php',{action:'stop'}, function(){loadlist();});
$.post('/plugins/dynamix.docker.manager/include/ContainerManager.php',{action:'stop'},function(){loadlist();});
}
function checkAll() {
$('input[type=button]').prop('disabled',true);
@@ -169,7 +174,7 @@ function updateAll() {
function containerLogs(container, id) {
var height = 600;
var width = 900;
var run = eventURL+"?action=log&container="+id+"&title=Log for:"+container;
var run = eventURL+'?action=log&container='+id+'&title=Log for: '+container;
var top = (screen.height-height) / 2;
var left = (screen.width-width) / 2;
var options = 'resizeable=yes,scrollbars=yes,height='+height+',width='+width+',top='+top+',left='+left;