/**
  * Constructor. The image will be updated with all associated properties from commandline.
  *
  * @param string $id Id of the new container
  * @return void
  * @access public
  */
 public function __construct($id, $data, $apiPort)
 {
     $now = date("c");
     $curl = curl_init();
     curl_setopt_array($curl, array(CURLOPT_RETURNTRANSFER => 1, CURLOPT_TIMEOUT => 30, CURLOPT_CONNECTTIMEOUT => 5));
     $this->id = $id;
     $item = $data[substr($id, 0, 12)];
     if (is_array($item->RepoTags) && count($item->RepoTags) > 0) {
         $this->repository = preg_split('/\\:/', $item->RepoTags[0])[0];
         $this->tag = preg_split('/\\:/', $item->RepoTags[0])[1];
     } else {
         $this->repository = "none";
         $this->tag = "none";
     }
     $this->created = OMVModuleDockerUtil::getWhen($now, date("c", $item->Created)) . " ago";
     $this->size = OMVModuleDockerUtil::bytesToSize($item->VirtualSize);
     $url = "http://localhost:" . $apiPort . "/images/{$id}/json";
     curl_setopt($curl, CURLOPT_URL, $url);
     if (!($response = curl_exec($curl))) {
         throw new OMVModuleDockerException('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
     }
     $imageData = json_decode($response);
     $this->ports = array();
     foreach ($imageData->Config->ExposedPorts as $exposedport => $hostports) {
         array_push($this->ports, array("name" => $exposedport));
     }
     $this->envVars = array();
     if (is_array($imageData->Config->Env)) {
         foreach ($imageData->Config->Env as $eVar) {
             $eVarAry = explode("=", $eVar);
             $this->envVars[$eVarAry[0]] = $eVarAry[1];
         }
     }
     curl_close($curl);
 }
 /**
  * Constructor. The container will be updated with all associated
  * properties from commandline.
  *
  * @param string $id      Id of the new image
  * @param array  $data    An associative array with all containers
  * @param imt    $apiPort An associative array with all containers
  *
  * @return void
  * @access public
  */
 public function __construct($id, $data, $apiPort)
 {
     $this->_id = $id;
     $now = date("c");
     $item = $data[substr($id, 0, 12)];
     $this->_status = $item->Status;
     $this->_command = $item->Command;
     $this->_created = OMVModuleDockerUtil::getWhen($now, date("c", $item->Created)) . " ago";
     $url = "http://localhost:" . $apiPort . "/containers/{$id}/json";
     $response = OMVModuleDockerUtil::doApiCall($url);
     $containerData = json_decode($response);
     $this->_image = $containerData->Config->Image;
     $this->_state = "running";
     if ($containerData->State->Running) {
         $this->_state = "running";
     } elseif ($containerData->State->Dead || $containerData->State->ExitCode !== 0) {
         $this->_state = "dead";
     } elseif ($containerData->State->ExitCode === 0 && strcmp($containerData->State->Error, "") === 0) {
         $this->_state = "stopped";
     }
     $this->_ports = array();
     if (isset($containerData->NetworkSettings->Ports)) {
         foreach ($containerData->NetworkSettings->Ports as $exposedport => $hostports) {
             if ($hostports) {
                 $this->_ports[$exposedport] = array();
                 foreach ($hostports as $hostport) {
                     $tmparray = array("HostIp" => $hostport->HostIp, "HostPort" => $hostport->HostPort);
                     array_push($this->_ports[$exposedport], $tmparray);
                 }
             } else {
                 $this->_ports[$exposedport] = null;
             }
         }
     }
     $this->_networkMode = $containerData->HostConfig->NetworkMode;
     if (strcmp($this->_networkMode, "default") === 0) {
         $this->_networkMode = "bridge";
     }
     $this->_privileged = $containerData->HostConfig->Privileged;
     $this->_restartPolicy = $containerData->HostConfig->RestartPolicy->Name;
     $this->_envVars = array();
     if (isset($containerData->Config->Env)) {
         foreach ($containerData->Config->Env as $eVar) {
             $eVarAry = explode("=", $eVar);
             $this->_envVars[$eVarAry[0]] = $eVarAry[1];
         }
     }
     $this->_imageId = substr($containerData->Image, 7);
     $this->_portBindings = array();
     if (isset($containerData->HostConfig->PortBindings)) {
         foreach ($containerData->HostConfig->PortBindings as $containerPort => $mappings) {
             foreach ($mappings as $mapping) {
                 array_push($this->_portBindings, array("containerportstring" => $containerPort, "containerportnr" => preg_split('/\\//', $containerPort)[0], "hostip" => $mapping->HostIp, "hostport" => $mapping->HostPort, "proto" => preg_split('/\\//', $containerPort)[1]));
             }
         }
     }
     $this->_bindMounts = array();
     $this->_timeSync = false;
     if (isset($containerData->HostConfig->Binds)) {
         foreach ($containerData->HostConfig->Binds as $bind) {
             if (strcmp($bind, "/etc/localtime:/etc/localtime:ro") === 0) {
                 $this->_timeSync = true;
                 continue;
             }
             $mode = "";
             if (isset(preg_split('/\\:/', $bind)[2])) {
                 $mode = preg_split('/\\:/', $bind)[2];
             }
             array_push($this->_bindMounts, array("from" => preg_split('/\\:/', $bind)[0], "to" => preg_split('/\\:/', $bind)[1], "mode" => $mode));
         }
     }
     if (isset($containerData->Mounts)) {
         foreach ($containerData->Mounts as $mount) {
             if (strcmp($mount->Mode, "") === 0 && isset($mount->Driver) && strcmp($mount->Driver, "local") === 0) {
                 array_push($this->_bindMounts, array("from" => $mount->Destination, "to" => "", "mode" => $mount->Mode));
             }
         }
     }
     $this->_names = ltrim($item->Names[0], "/");
     $this->_hasMounts = false;
     if (is_array($containerData->Mounts) && count($containerData->Mounts) > 0) {
         $this->_hasMounts = true;
     }
     $this->_volumesFrom = array();
     if (isset($containerData->HostConfig->VolumesFrom)) {
         foreach ($containerData->HostConfig->VolumesFrom as $volume) {
             array_push($this->_volumesFrom, array("from" => $volume));
         }
     }
     $this->_hostName = "";
     if (!(strcmp($containerData->Config->Hostname, "") === 0)) {
         $this->_hostName .= $containerData->Config->Hostname;
         if (!(strcmp($containerData->Config->Domainname, "") === 0)) {
             $this->_hostName .= "." . $containerData->Config->Domainname;
         }
     }
 }
 /**
  * Constructor. The container will be updated with all associated properties from commandline.
  *
  * @param string $id Id of the new image
  * @return void
  * @access public
  */
 public function __construct($id, $data, $apiPort)
 {
     $this->id = $id;
     $now = date("c");
     $curl = curl_init();
     curl_setopt_array($curl, array(CURLOPT_RETURNTRANSFER => 1, CURLOPT_TIMEOUT => 30, CURLOPT_CONNECTTIMEOUT => 5));
     $this->id = $id;
     $item = $data[substr($id, 0, 12)];
     $this->image = $item->Image;
     $this->status = $item->Status;
     $this->command = $item->Command;
     $this->created = OMVModuleDockerUtil::getWhen($now, date("c", $item->Created)) . " ago";
     $url = "http://localhost:" . $apiPort . "/containers/{$id}/json";
     curl_setopt($curl, CURLOPT_URL, $url);
     if (!($response = curl_exec($curl))) {
         throw new OMVModuleDockerException('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
     }
     $containerData = json_decode($response);
     if ($containerData->State->Running) {
         $this->state = "running";
     } elseif ($containerData->State->Dead) {
         $this->state = "dead";
     } elseif ($containerData->State->ExitCode === 0 && strcmp($containerData->State->Error, "") === 0) {
         $this->state = "stopped";
     }
     $this->ports = array();
     foreach ($containerData->NetworkSettings->Ports as $exposedport => $hostports) {
         if ($hostports) {
             $this->ports[$exposedport] = array();
             foreach ($hostports as $hostport) {
                 $tmparray = array("HostIp" => $hostport->HostIp, "HostPort" => $hostport->HostPort);
                 array_push($this->ports[$exposedport], $tmparray);
             }
         } else {
             $this->ports[$exposedport] = NULL;
         }
     }
     $this->networkMode = $containerData->HostConfig->NetworkMode;
     $this->privileged = $containerData->HostConfig->Privileged;
     $this->restartPolicy = $containerData->HostConfig->RestartPolicy->Name;
     $this->envVars = array();
     if (is_array($containerData->Config->Env)) {
         foreach ($containerData->Config->Env as $eVar) {
             $eVarAry = explode("=", $eVar);
             $this->envVars[$eVarAry[0]] = $eVarAry[1];
         }
     }
     $this->imageId = $containerData->Image;
     $this->portBindings = array();
     foreach ($containerData->HostConfig->PortBindings as $containerPort => $mappings) {
         foreach ($mappings as $mapping) {
             array_push($this->portBindings, array("containerportstring" => $containerPort, "containerportnr" => preg_split('/\\//', $containerPort)[0], "hostip" => $mapping->HostIp, "hostport" => $mapping->HostPort));
         }
     }
     $this->bindMounts = array();
     foreach ($containerData->HostConfig->Binds as $bind) {
         array_push($this->bindMounts, array("from" => preg_split('/\\:/', $bind)[0], "to" => preg_split('/\\:/', $bind)[1]));
     }
     $this->names = ltrim($item->Names[0], "/");
 }
 /**
  * Change the Docker daemon settings
  *
  * @param string $apiPort The new API port to use
  * @param string $absPath Absolute path where Docker files should be moved
  *
  * @return void
  *
  */
 public static function changeDockerSettings($context, $apiPort, $absPath)
 {
     self::$database = Database::getInstance();
     OMVModuleDockerUtil::stopDockerService();
     //Do some sanity checks before making changes to running config.
     //First check that there is no manual base path relocation in the file
     // /etc/default/docker
     $fileName = "/etc/default/docker";
     $data = file_get_contents($fileName);
     $lines = explode("\n", $data);
     foreach ($lines as $line) {
         if (strcmp($line, "### Do not change these lines. They are added and updated by the OMV Docker GUI plugin.") === 0) {
             break;
         } elseif (preg_match('/^[^\\#]+.*\\-g[\\s]?([^\\"]+)[\\s]?.*/', $line, $matches) && strcmp($absPath, "") !== 0) {
             OMVModuleDockerUtil::startDockerService();
             throw new OMVModuleDockerException("Docker " . "base path relocation detected in " . "configuration file\n" . "Please remove it manually " . "({$matches['1']})\n");
         }
     }
     // Next get the old settings object
     $oldSettings = self::$database->getAssoc(self::$dataModelPath);
     // Next umount old bind mount
     if (!(strcmp($oldSettings['dockermntent'], "") === 0)) {
         $oldMntent = Rpc::call("FsTab", "get", ["uuid" => $oldSettings['dockermntent']], $context);
         $me = new MountPoint($oldMntent['fsname'], $oldMntent['dir']);
         $cmd = "mount | grep /var/lib/docker/openmediavault | wc -l";
         unset($out);
         $process = new Process($cmd);
         $out = $process->execute();
         while ($out > 0) {
             $me->umount();
             $cmd = "mount | grep /var/lib/docker/openmediavault | wc -l";
             unset($out);
             $process = new Process($cmd);
             $out = $process->execute();
         }
     }
     //First update /etc/default/docker with user provided data
     $fileName = "/etc/default/docker";
     $data = file_get_contents($fileName);
     $lines = explode("\n", $data);
     $result = "";
     foreach ($lines as $line) {
         if (strcmp($line, "### Do not change these lines. They are added and updated by the OMV Docker GUI plugin.") === 0) {
             break;
         } elseif (preg_match('/^[^\\#]+.*\\-g[\\s]?([^\\"]+)[\\s]?.*/', $line, $matches) && strcmp($absPath, "") !== 0) {
             OMVModuleDockerUtil::startDockerService();
             throw new OMVModuleDockerException("Docker " . "base path relocation detected in " . "configuration file\n" . "Please remove it manually " . "({$matches['1']})\n");
         }
         $result .= $line . "\n";
     }
     $result = rtrim($result);
     $result .= "\n\n" . '### Do not change these lines. They are added ' . 'and updated by the OMV Docker GUI plugin.' . "\n";
     $result .= 'OMVDOCKER_API="-H tcp://127.0.0.1:' . $apiPort . '"' . "\n";
     if (strcmp($absPath, "") !== 0) {
         $result .= 'OMVDOCKER_IMAGE_PATH="-g /var/lib/docker/openmediavault"' . "\n";
     } else {
         $result .= 'OMVDOCKER_IMAGE_PATH=""' . "\n";
     }
     $result .= '### Do not add any configuration below this line. It will be ' . 'removed when the plugin is removed';
     file_put_contents("{$fileName}", $result);
     //Next fix OMV config backend if the base path should be relocated
     //Start by removing any old mntent entries
     $mnt = Rpc::call("FsTab", "getByDir", ["dir" => '/var/lib/docker/openmediavault'], $context);
     if ($mnt) {
         Rpc::call("FsTab", "delete", ["uuid" => $mnt['uuid']], $context);
     }
     //Next generate a new mntent entry if a shared folder is specified
     if (!(strcmp($absPath, "") === 0)) {
         $newMntent = ["uuid" => \OMV\Environment::get("OMV_CONFIGOBJECT_NEW_UUID"), "fsname" => $absPath, "dir" => "/var/lib/docker/openmediavault", "type" => "none", "opts" => "bind,defaults", "freq" => 0, "passno" => 0];
         $newMntent = Rpc::call("FsTab", "set", $newMntent, $context);
     }
     //Update settings object
     if (strcmp($absPath, "") === 0) {
         $tmpMntent = "";
     } else {
         $tmpMntent = $newMntent['uuid'];
     }
     $object = array("dockermntent" => $tmpMntent, "enabled" => $oldSettings['enabled'], "apiPort" => $oldSettings['apiPort'], "sharedfolderref" => $oldSettings['sharedfolderref']);
     $config = new ConfigObject(self::$dataModelPath);
     $config->setAssoc($object);
     self::$database->set($config);
     //Re-generate fstab entries
     $cmd = "export LANG=C; omv-mkconf fstab 2>&1";
     $process = new Process($cmd);
     $out = $process->execute();
     // Finally mount the new bind-mount entry
     if (!(strcmp($absPath, "") === 0)) {
         $me = new MountPoint($newMntent['fsname'], $newMntent['dir']);
         $me->mount();
         //Remount the bind-mount with defaults options
         $cmd = "export LANG=C; mount -o remount,bind,defaults " . $newMntent['fsname'] . " " . $newMntent['dir'] . " 2>&1";
         $process = new Process($cmd);
         $out = $process->execute();
     }
     OMVModuleDockerUtil::startDockerService();
 }
 /**
  * Returns an array with Container objects on the system
  *
  * @return array $objects An array with Container objects
  *
  */
 public static function getContainers($apiPort)
 {
     $objects = array();
     $curl = curl_init();
     curl_setopt_array($curl, array(CURLOPT_RETURNTRANSFER => 1, CURLOPT_TIMEOUT => 30, CURLOPT_CONNECTTIMEOUT => 5));
     $url = "http://localhost:" . $apiPort . "/containers/json?all=1";
     curl_setopt($curl, CURLOPT_URL, $url);
     if (!($response = curl_exec($curl))) {
         throw new OMVModuleDockerException('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
     }
     curl_close($curl);
     $data = array();
     foreach (json_decode($response) as $item) {
         $data[substr($item->Id, 0, 12)] = $item;
     }
     foreach ($data as $item) {
         $container = new OMVModuleDockerContainer($item->Id, $data, $apiPort);
         $ports = "";
         foreach ($container->getPorts() as $exposedport => $hostports) {
             if ($hostports) {
                 foreach ($hostports as $hostport) {
                     $ports .= $hostport["HostIp"] . ":" . $hostport["HostPort"] . "->" . $exposedport . ", ";
                 }
             } else {
                 $ports .= $exposedport . ", ";
             }
         }
         $image = OMVModuleDockerUtil::getImage(substr($container->getImageId(), 0, 12), $apiPort);
         $exposedPorts = $image->getPorts();
         $envvars = $image->getEnvVars();
         $ports = rtrim($ports, ", ");
         $obj = array("id" => $container->getId(), "image" => $container->getImage(), "command" => $container->getCommand(), "created" => $container->getCreated(), "state" => $container->getState(), "status" => $container->getStatus(), "name" => $container->getName(), "privileged" => $container->getPrivileged(), "restartpolicy" => $container->getRestartPolicy(), "networkmode" => ucfirst($container->getNetworkMode()), "envvars" => $envvars, "cenvvars" => $container->getEnvironmentVariables(), "exposedports" => $exposedPorts, "portbindings" => $container->getPortBindings(), "bindmounts" => $container->getBindMounts(), "ports" => $ports);
         array_push($objects, $obj);
     }
     return $objects;
 }
 /**
  * Constructor. The image will be updated with all associated properties
  * from commandline.
  *
  * @param string $id      Id of the new container
  * @param array  $data    Associative array with Image data
  * @param int    $apiPort Network port used by API calls
  */
 public function __construct($id, $data, $apiPort)
 {
     $now = date("c");
     $this->_id = $id;
     $item = $data[substr($id, 0, 12)];
     if (isset($item->RepoTags)) {
         $this->_repository = preg_split('/\\:/', $item->RepoTags[0])[0];
         $this->_tag = preg_split('/\\:/', $item->RepoTags[0])[1];
     } else {
         $this->_repository = "none";
         $this->_tag = "none";
     }
     $this->_created = OMVModuleDockerUtil::getWhen($now, date("c", $item->Created)) . " ago";
     $this->_size = OMVModuleDockerUtil::bytesToSize($item->VirtualSize);
     $url = "http://localhost:" . $apiPort . "/images/{$id}/json";
     $response = OMVModuleDockerUtil::doApiCall($url);
     $imageData = json_decode($response);
     $this->_timestamp = date("U", $item->Created);
     $this->_ports = array();
     if (isset($imageData->Config->ExposedPorts)) {
         foreach ($imageData->Config->ExposedPorts as $exposedport => $hostports) {
             array_push($this->_ports, array("name" => $exposedport));
         }
     }
     $this->_envVars = array();
     if (isset($imageData->Config->Env)) {
         foreach ($imageData->Config->Env as $eVar) {
             $eVarAry = explode("=", $eVar);
             $this->_envVars[$eVarAry[0]] = $eVarAry[1];
         }
     }
     $this->_volumes = array();
     if (isset($imageData->Config->Volumes)) {
         foreach ($imageData->Config->Volumes as $key => $val) {
             array_push($this->_volumes, array($key));
         }
     }
 }