From d98a36df5dd6231305cf6eb184cc85b6cc7fbe04 Mon Sep 17 00:00:00 2001 From: bergware Date: Sun, 25 Mar 2018 10:30:26 +0200 Subject: [PATCH] Docker code optimization --- .../include/CreateDocker.php | 156 ++++++------------ .../include/DockerClient.php | 93 +++++------ 2 files changed, 93 insertions(+), 156 deletions(-) diff --git a/plugins/dynamix.docker.manager/include/CreateDocker.php b/plugins/dynamix.docker.manager/include/CreateDocker.php index 011b0c388..1396cee43 100644 --- a/plugins/dynamix.docker.manager/include/CreateDocker.php +++ b/plugins/dynamix.docker.manager/include/CreateDocker.php @@ -13,7 +13,7 @@ ?>

"; echo "\n"; @flush(); - $retval = $DockerClient->stopContainer($name); $out = ($retval === true) ? "Successfully stopped container '$name'" : "Error: ".$retval; - echo "\n"; @flush(); } @@ -55,14 +52,11 @@ function stopContainer($name) { function removeContainer($name) { global $DockerClient; $waitID = mt_rand(); - echo "

"; echo "\n"; @flush(); - $retval = $DockerClient->removeContainer($name); $out = ($retval === true) ? "Successfully removed container '$name'" : "Error: ".$retval; - echo "\n"; @flush(); } @@ -70,14 +64,11 @@ function removeContainer($name) { function removeImage($image) { global $DockerClient; $waitID = mt_rand(); - echo "

"; echo "\n"; @flush(); - $retval = $DockerClient->removeImage($image); $out = ($retval === true) ? "Successfully removed image '$image'" : "Error: ".$retval; - echo "\n"; @flush(); } @@ -86,32 +77,25 @@ function pullImage($name, $image) { global $DockerClient, $DockerTemplates, $DockerUpdate; $waitID = mt_rand(); if (!preg_match("/:\S+$/", $image)) $image .= ":latest"; - echo "

"; echo "\n"; @flush(); - $alltotals = []; $laststatus = []; $strError = ''; - $DockerClient->pullImage($image, function ($line) use (&$alltotals, &$laststatus, &$waitID, &$strError, $image, $DockerClient, $DockerUpdate) { $cnt = json_decode($line, true); $id = (isset($cnt['id'])) ? trim($cnt['id']) : ''; $status = (isset($cnt['status'])) ? trim($cnt['status']) : ''; - if (isset($cnt['error'])) { $strError = $cnt['error']; } - if ($waitID !== false) { echo "\n"; @flush(); $waitID = false; } - if (empty($status)) return; - if (!empty($id)) { if (!empty($cnt['progressDetail']) && !empty($cnt['progressDetail']['total'])) { $alltotals[$id] = $cnt['progressDetail']['total']; @@ -119,13 +103,10 @@ function pullImage($name, $image) { if (empty($laststatus[$id])) { $laststatus[$id] = ''; } - switch ($status) { - case 'Waiting': // Omit break; - case 'Downloading': if ($laststatus[$id] != $status) { echo "\n"; @@ -137,12 +118,11 @@ function pullImage($name, $image) { echo "\n"; } else { // Docker must not know the total download size (http-chunked or something?) - // just show the current download progress without the percentage + // just show the current download progress without the percentage $alltotals[$id] = $current; echo "\n"; } break; - default: if ($laststatus[$id] == "Downloading") { echo "\n"; @@ -152,9 +132,7 @@ function pullImage($name, $image) { } break; } - $laststatus[$id] = $status; - } else { if (strpos($status, 'Status: ') === 0) { echo "\n"; @@ -165,37 +143,35 @@ function pullImage($name, $image) { } @flush(); }); - echo "\n"; @flush(); - if (!empty($strError)) { echo "\n"; @flush(); return false; } - return true; } function xml_encode($string) { return htmlspecialchars($string, ENT_XML1, 'UTF-8'); } + function xml_decode($string) { return strval(html_entity_decode($string, ENT_XML1, 'UTF-8')); } -function postToXML($post, $setOwnership = false) { +function postToXML($post, $setOwnership=false) { $dom = new domDocument; $dom->appendChild($dom->createElement("Container")); $xml = simplexml_import_dom($dom); - $xml["version"] = 2; + $xml['version'] = 2; $xml->Name = xml_encode(preg_replace('/\s+/', '', $post['contName'])); $xml->Repository = xml_encode(trim($post['contRepository'])); $xml->Registry = xml_encode(trim($post['contRegistry'])); $xml->Network = xml_encode($post['contNetwork']); $xml->MyIP = xml_encode($post['contMyIP']); - $xml->Privileged = (strtolower($post["contPrivileged"]) == 'on') ? 'true' : 'false'; + $xml->Privileged = strtolower($post['contPrivileged'])=='on' ? 'true' : 'false'; $xml->Support = xml_encode($post['contSupport']); $xml->Project = xml_encode($post['contProject']); $xml->Overview = xml_encode($post['contOverview']); @@ -212,13 +188,13 @@ function postToXML($post, $setOwnership = false) { $xml->MinVer = xml_encode($post['contMinVer']); # V1 compatibility - $xml->Description = xml_encode($post['contOverview']); - $xml->Networking->Mode = xml_encode($post['contNetwork']); + $xml->Description = xml_encode($post['contOverview']); + $xml->Networking->Mode = xml_encode($post['contNetwork']); $xml->Networking->addChild("Publish"); $xml->addChild("Data"); $xml->addChild("Environment"); - for ($i = 0; $i < count($post["confName"]); $i++) { + for ($i = 0; $i < count($post['confName']); $i++) { $Type = $post['confType'][$i]; $config = $xml->addChild('Config', xml_encode($post['confValue'][$i])); $config['Name'] = xml_encode($post['confName'][$i]); @@ -308,13 +284,11 @@ function xmlToVar($xml) { } # check if network exists if (!key_exists($out['Network'],$subnet)) $out['Network'] = 'none'; - # V1 compatibility - if ($xml["version"] != "2") { + if ($xml['version'] != '2') { if (isset($xml->Description)) { $out['Overview'] = stripslashes(xml_decode($xml->Description)); } - if (isset($xml->Networking->Publish->Port)) { $portNum = 0; foreach ($xml->Networking->Publish->Port as $port) { @@ -457,13 +431,11 @@ function xmlToCommand($xml, $create_paths=false) { function execCommand($command) { // $command should have all its args already properly run through 'escapeshellarg' - $descriptorspec = [ - 0 => ["pipe", "r"], // stdin is a pipe that the child will read from - 1 => ["pipe", "w"], // stdout is a pipe that the child will write to - 2 => ["pipe", "w"] // stderr is a pipe that the child will write to + 0 => ['pipe', 'r'], // stdin is a pipe that the child will read from + 1 => ['pipe', 'w'], // stdout is a pipe that the child will write to + 2 => ['pipe', 'w'] // stderr is a pipe that the child will write to ]; - $id = mt_rand(); echo '

'; echo '"; echo ""; -$authoringMode = $dockercfg["DOCKER_AUTHORING_MODE"] == "yes" ? true : false; +$authoringMode = $dockercfg['DOCKER_AUTHORING_MODE'] == "yes" ? true : false; $authoring = $authoringMode ? 'advanced' : 'noshow'; $disableEdit = $authoringMode ? 'false' : 'true'; $showAdditionalInfo = ''; @@ -1745,12 +1690,10 @@ optgroup.title{background-color:#625D5D;color:#FFFFFF;text-align:center;margin-t for (var i = 0; i < categories.length; i++) { $("#catSelect option[value='"+categories[i]+"']").prop("selected", true); } - // Remove empty description if (!Settings.Description.length) { $('#canvas').find('#Overview:first').hide(); } - // Load config info var network = $('select[name="contNetwork"]')[0].selectedIndex; for (var i = 0; i < Settings.Config.length; i++) { @@ -1774,22 +1717,16 @@ optgroup.title{background-color:#625D5D;color:#FFFFFF;text-align:center;margin-t } else { $('#canvas').find('#Overview:first').hide(); } - // Show associated subnet with fixed IP (if existing) showSubnet($('select[name="contNetwork"]').val()); - // Add list of exposed host ports $("#configLocationPorts").html(makeUsedPorts(UsedPorts,$('input[name="contName"]').val())); - // Add list of assigned IP addresses $("#configLocationIPs").html(makeUsedIPs(UsedIPs,$('input[name="contName"]').val())); - // Add switchButton $('.switch-on-off').each(function(){var checked = $(this).is(":checked");$(this).switchButton({labels_placement: "right", checked:checked});}); - // Add dropdownchecklist to Select Categories $("#catSelect").dropdownchecklist({emptyText:'Select categories...', maxDropHeight:200, width:300, explicitClose:'...close'}); - - diff --git a/plugins/dynamix.docker.manager/include/DockerClient.php b/plugins/dynamix.docker.manager/include/DockerClient.php index 41fadc16b..f8586d30c 100644 --- a/plugins/dynamix.docker.manager/include/DockerClient.php +++ b/plugins/dynamix.docker.manager/include/DockerClient.php @@ -28,7 +28,9 @@ $dockerManPaths = [ ]; # load network variables if needed. -if (!isset($eth0) && is_file("$docroot/state/network.ini")) extract(parse_ini_file("$docroot/state/network.ini",true)); +if (!isset($eth0) && is_file("$docroot/state/network.ini")) { + extract(parse_ini_file("$docroot/state/network.ini",true)); +} # controlled docker execution function docker($cmd, &$var=null) { @@ -51,12 +53,12 @@ class DockerTemplates { if ($this->verbose) echo $m."\n"; } - public function download_url($url, $path = '', $bg = false) { + 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; + return $exit_code===0 ? implode("\n", $out) : false; } - public function listDir($root, $ext = null) { + public function listDir($root, $ext=null) { $iter = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($root, RecursiveDirectoryIterator::SKIP_DOTS), @@ -65,7 +67,7 @@ class DockerTemplates { $paths = []; foreach ($iter as $path => $fileinfo) { $fext = $fileinfo->getExtension(); - if ($ext && ($ext != $fext)) continue; + if ($ext && $ext != $fext) continue; if ($fileinfo->isFile()) $paths[] = ['path' => $path, 'prefix' => basename(dirname($path)), 'name' => $fileinfo->getBasename(".$fext")]; } return $paths; @@ -74,14 +76,18 @@ class DockerTemplates { public function getTemplates($type) { global $dockerManPaths; $tmpls = $dirs = []; - if ($type == 'all') { + switch ($type) { + case 'all': $dirs[] = $dockerManPaths['templates-user']; $dirs[] = $dockerManPaths['templates-storage']; - } elseif ($type == 'user') { + break; + case 'user': $dirs[] = $dockerManPaths['templates-user']; - } elseif ($type == 'default') { + break; + case 'default': $dirs[] = $dockerManPaths['templates-storage']; - } else { + break; + default: $dirs[] = $type; } foreach ($dirs as $dir) { @@ -98,18 +104,15 @@ class DockerTemplates { $this->removeDir(realpath($path).'/'.$file); } return rmdir($path); - } elseif (is_file($path)) { - return unlink($path); - } + } elseif (is_file($path)) return unlink($path); return false; } - public function downloadTemplates($Dest = null, $Urls = null) { + public function downloadTemplates($Dest=null, $Urls=null) { global $dockerManPaths; $Dest = $Dest ?: $dockerManPaths['templates-storage']; $Urls = $Urls ?: $dockerManPaths['template-repos']; - $repotemplates = []; - $output = []; + $repotemplates = $output = []; $tmp_dir = '/tmp/tmp-'.mt_rand(); if (!file_exists($dockerManPaths['template-repos'])) { @mkdir(dirname($dockerManPaths['template-repos']), 0777, true); @@ -212,7 +215,7 @@ class DockerTemplates { return $output; } - public function getTemplateValue($Repository, $field, $scope = 'all') { + public function getTemplateValue($Repository, $field, $scope='all') { foreach ($this->getTemplates($scope) as $file) { $doc = new DOMDocument(); $doc->load($file['path']); @@ -231,7 +234,7 @@ class DockerTemplates { $doc = new DOMDocument('1.0', 'utf-8'); $doc->load($file['path']); $Name = $doc->getElementsByTagName('Name')->item(0)->nodeValue; - if ($Name == $Container) return $file['path']; + if ($Name==$Container) return $file['path']; } return false; } @@ -260,9 +263,7 @@ class DockerTemplates { $ConfigPort = $matches[1]; if ($ct['NetworkMode'] == 'bridge') { foreach ($Ports as $key) { - if ($key['PrivatePort'] == $ConfigPort) { - $ConfigPort = $key['PublicPort']; - } + if ($key['PrivatePort'] == $ConfigPort) $ConfigPort = $key['PublicPort']; } } $WebUI = preg_replace("%\[PORT:\d+\]%", $ConfigPort, $WebUI); @@ -291,7 +292,7 @@ class DockerTemplates { } } - public function getAllInfo($reload = false) { + public function getAllInfo($reload=false) { global $dockerManPaths; $DockerClient = new DockerClient(); $DockerUpdate = new DockerUpdate(); @@ -363,12 +364,12 @@ class DockerUpdate{ return strval(html_entity_decode($string, ENT_XML1, 'UTF-8')); } - public function download_url($url, $path = '', $bg = false) { + 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) { + public function download_url_and_headers($url, $headers=[], $path='', $bg=false) { $strHeaders = ''; foreach ($headers as $header) { $strHeaders .= ' -H '.escapeshellarg($header); @@ -445,7 +446,7 @@ class DockerUpdate{ return null; } - public function reloadUpdateStatus($image = null) { + public function reloadUpdateStatus($image=null) { global $dockerManPaths; $DockerClient = new DockerClient(); $updateStatus = DockerUtil::loadJSON($dockerManPaths['update-status']); @@ -591,7 +592,7 @@ 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) { + public function getDockerJSON($url, $method='GET', &$code=null, $callback=null, $unchunk=false) { $fp = stream_socket_client('unix:///var/run/docker.sock', $errno, $errstr); if ($fp === false) { @@ -608,7 +609,7 @@ class DockerClient { $code = vsprintf('%2$s',preg_split("#\s+#", $line)); } $headers .= $line; - if (rtrim($line) == '') break; + if (rtrim($line)=='') break; } $data = []; while (($line = fgets($fp)) !== false) { @@ -623,14 +624,14 @@ class DockerClient { function doesContainerExist($container) { foreach ($this->getDockerContainers() as $ct) { - if ($ct['Name'] == $container) return true; + if ($ct['Name']==$container) return true; } return false; } function doesImageExist($image) { foreach ($this->getDockerImages() as $img) { - if (strpos($img['Tags'][0], $image) !== false) return true; + if (strpos($img['Tags'][0], $image)!==false) return true; } return false; } @@ -641,16 +642,16 @@ class DockerClient { 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 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"); + return $this->getDockerJSON("/containers/$id/json"); } public function startContainer($id) { - $this->getDockerJSON("/containers/${id}/start", 'POST', $code); + $this->getDockerJSON("/containers/$id/start", 'POST', $code); $this::$allContainersCache = null; // flush cache $codes = [ '204' => true, // No error @@ -658,11 +659,11 @@ class DockerClient { '404' => 'No such container', '500' => 'Server error' ]; - return (array_key_exists($code, $codes)) ? $codes[$code] : 'Error code '.$code; + return $codes[$code] ?: 'Error code '.$code; } public function stopContainer($id) { - $this->getDockerJSON("/containers/${id}/stop?t=10", 'POST', $code); + $this->getDockerJSON("/containers/$id/stop?t=10", 'POST', $code); $this::$allContainersCache = null; // flush cache $codes = [ '204' => true, // No error @@ -670,18 +671,18 @@ class DockerClient { '404' => 'No such container', '500' => 'Server error' ]; - return (array_key_exists($code, $codes)) ? $codes[$code] : 'Error code '.$code; + return $codes[$code] ?: 'Error code '.$code; } public function restartContainer($id) { - $this->getDockerJSON("/containers/${id}/restart?t=10", 'POST', $code); + $this->getDockerJSON("/containers/$id/restart?t=10", 'POST', $code); $this::$allContainersCache = null; // flush cache $codes = [ '204' => true, // No error '404' => 'No such container', '500' => 'Server error' ]; - return (array_key_exists($code, $codes)) ? $codes[$code] : 'Error code '.$code; + return $codes[$code] ?: 'Error code '.$code; } public function removeContainer($id) { @@ -699,7 +700,7 @@ class DockerClient { DockerUtil::saveJSON($dockerManPaths['webui-info'], $info); } // Attempt to remove container - $this->getDockerJSON("/containers/${id}?force=1", 'DELETE', $code); + $this->getDockerJSON("/containers/$id?force=1", 'DELETE', $code); $this::$allContainersCache = null; // flush cache $codes = [ '204' => true, // No error @@ -707,10 +708,10 @@ class DockerClient { '404' => 'No such container', '500' => 'Server error' ]; - return (array_key_exists($code, $codes)) ? $codes[$code] : 'Error code '.$code; + return $codes[$code] ?: 'Error code '.$code; } - public function pullImage($image, $callback = null) { + public function pullImage($image, $callback=null) { $ret = $this->getDockerJSON("/images/create?fromImage=".urlencode($image), 'POST', $code, $callback); $this::$allImagesCache = null; // flush cache return $ret; @@ -720,7 +721,7 @@ class DockerClient { global $dockerManPaths; $image = $this->getImageName($id); // Attempt to remove image - $this->getDockerJSON("/images/${id}?force=1", 'DELETE', $code); + $this->getDockerJSON("/images/$id?force=1", 'DELETE', $code); $this::$allImagesCache = null; // flush cache if (in_array($code, ['200', '404'])) { // Purge cached image information (only if delete was successful) @@ -737,11 +738,11 @@ class DockerClient { '409' => 'Conflict: image used by container(s): '.implode(', ', $this->usedBy($id)), '500' => 'Server error' ]; - return (array_key_exists($code, $codes)) ? $codes[$code] : 'Error code '.$code; + return $codes[$code] ?: 'Error code '.$code; } private function getImageDetails($id) { - return $this->getDockerJSON("/images/${id}/json"); + return $this->getDockerJSON("/images/$id/json"); } public function getDockerContainers() { @@ -786,7 +787,7 @@ class DockerClient { if (!strpos($Image,':')) $Image .= ':latest'; foreach ($this->getDockerImages() as $img) { foreach ($img['Tags'] as $tag) { - if ( $Image == $tag ) return $img['Id']; + if ($Image==$tag) return $img['Id']; } } return null; @@ -794,7 +795,7 @@ class DockerClient { public function getImageName($id) { foreach ($this->getDockerImages() as $img) { - if ($img['Id'] == $id) return $img['Tags'][0]; + if ($img['Id']==$id) return $img['Tags'][0]; } return null; } @@ -802,7 +803,7 @@ class DockerClient { private function usedBy($imageId) { $out = []; foreach ($this->getDockerContainers() as $ct) { - if ($ct['ImageId'] == $imageId) $out[] = $ct['Name']; + if ($ct['ImageId']==$imageId) $out[] = $ct['Name']; } return $out; }