public function getProgramIsRunning($programName) { // what are we doing? $log = usingLog()->startAction("is program '{$programName}' running under supervisor on host '{$this->args[0]}'?"); // get the host details $hostDetails = $this->getHostDetails(); //run the supervisorctl command $result = usingHost($hostDetails->hostId)->runCommandAndIgnoreErrors("sudo supervisorctl status"); // |egrep '^$programName' | awk '{print \\$2}'"); // did the command succeed? if ($result->didCommandFail()) { $msg = "command failed with return code '{$result->returnCode}' and output '{$result->output}'"; $log->endAction($msg); throw new E5xx_ActionFailed(__METHOD__); } // reduce the output down $lines = explode("\n", $result->output); $lines = FilterForMatchingRegex::against($lines, "/^{$programName} /"); $lines = FilterColumns::from($lines, "1", ' '); if (empty($lines)) { $log->endAction("supervisor does not know about '{$programName}'"); return false; } // what happened? if ($lines[0] == 'RUNNING') { $log->endAction('current status is RUNNING'); return true; } // if we get here, then the program is not RUNNING, and we // treat that as a failure $log->endAction('current status is ' . $lines[0]); return false; }
/** * * @param HostDetails $hostDetails * @param SupportedHost $host * @return string */ public function determineIpAddress($hostDetails, SupportedHost $host) { // what are we doing? $log = usingLog()->startAction("query " . basename(__CLASS__) . " for IP address"); if (empty($hostDetails->ifaces)) { // set default network interfaces $hostDetails->ifaces = array('eth1', 'eth0'); } // how do we do this? foreach ($hostDetails->ifaces as $iface) { $command = "/sbin/ip addr show {$iface}"; $result = $host->runCommandViaHostManager($hostDetails, $command); // NOTE: the above command will return the exit code 0 even if the interface is not found if ($result->didCommandFail() || strpos($result->output, 'error fetching') !== false) { // no interface found // // move on to the next interface to check continue; } // reduce the output down to an IP address $lines = explode("\n", $result->output); $lines = FilterForMatchingString::against($lines, 'inet '); $lines = FilterColumns::from($lines, '1', ' '); // do we have an IP address? if (!isset($lines[0]) || empty(trim($lines[0]))) { // no, we do not continue; } // if we get here, then we have an IP address/netmask combo $parts = explode("/", $lines[0]); $ipAddress = trim($parts[0]); $log->endAction("IP address is '{$ipAddress}'"); return $ipAddress; } // if we get here, we do not know what the IP address is $msg = "could not determine IP address"; $log->endAction($msg); throw new E5xx_ActionFailed(__METHOD__, $msg); }
/** * * @param HostDetails $hostDetails * @param string $pid * @return boolean */ public function getPidIsRunning($hostDetails, $pid) { // what are we doing? $log = usingLog()->startAction("is process PID '{$pid}' running on UNIX '{$hostDetails->hostId}'?"); // SSH in and have a look $command = "ps -ef | grep '{$pid}'"; $result = $this->runCommand($hostDetails, $command); // what did we find? if ($result->didCommandFail() || empty($result->output)) { $log->endAction("cannot get process list"); return false; } // reduce down the output we have $pids = explode("\n", $result->output); $pids = FilterColumns::from($pids, "1", ' '); $pids = FilterForMatchingRegex::against($pids, "/^{$pid}\$/"); // success? if (empty($pids)) { $log->endAction("not running"); return false; } // success $log->endAction("is running"); return true; }
/** * * @param HostDetails $hostDetails * @param string $packageName * @return BaseObject */ public function getInstalledPackageDetails($hostDetails, $packageName) { // what are we doing? $log = usingLog()->startAction("get details for package '{$packageName}' installed in host '{$hostDetails->hostId}'"); // get the details $command = "sudo yum list installed {$packageName}"; $result = $this->runCommand($hostDetails, $command); // any luck? if ($result->didCommandFail()) { $log->endAction("could not get details ... package not installed?"); return new BaseObject(); } // study the output $parts = explode("\n", $result->output); $parts = FilterForMatchingString::against($parts, $packageName); $parts = FilterColumns::from($parts, "0-2", ' '); if (!isset($parts[0])) { $log->endAction("could not get details ... package not installed?"); return new BaseObject(); } $parts = explode(' ', $result->output); if (count($parts) < 3) { $log->endAction("could not get details ... package not installed?"); return new BaseObject(); } if (strtolower($parts[0]) == 'error:') { $log->endAction("could not get details ... package not installed?"); return new BaseObject(); } // we have some information to return $return = new BaseObject(); $return->name = $parts[0]; $return->version = $parts[1]; $return->repo = $parts[2]; // all done $log->endAction(); return $return; }
/** * extract a named field from the output of /usr/bin/sw_vers * * @param array $lines * the output of /usr/bin/sw_vers * @param string $fieldName * the field that we are looking for * @return string|null * the value of the field (if found) */ private static function extractField($lines, $fieldName) { $matches = FilterForMatchingString::against($lines, $fieldName); if (empty($matches)) { return null; } return TrimWhitespace::from(FilterColumns::from($matches[0], '1', ':')); }
/** * @covers ::from * @dataProvider provideDataToFilter */ public function testCanCallStatically($data, $columnNos, $expectedResult) { // ---------------------------------------------------------------- // setup your test // ---------------------------------------------------------------- // perform the change $actualResult = FilterColumns::from($data, $columnNos, ' ', PHP_EOL); // ---------------------------------------------------------------- // test the results $this->assertEquals($expectedResult, $actualResult); }
/** * @param string $sessionName * @return BaseObject|null */ public function getScreenSessionDetails($sessionName) { // what are we doing? $log = usingLog()->startAction("get details about screen session '{$sessionName}' on host '{$this->args[0]}' from Storyplayer"); // are there any details? $cmd = "screen -ls"; $result = usingHost($this->args[0])->runCommandAndIgnoreErrors($cmd); // NOTE: // // screen is not a well-behaved UNIX program, and its exit code // can be non-zero when everything is good if (empty($result->output)) { $msg = "unable to get list of screen sessions"; return null; } // do we have the session we are looking for? $lines = explode("\n", $result->output); $lines = FilterForMatchingRegex::against($lines, "/[0-9]+\\.{$sessionName}\t/"); $lines = FilterColumns::from($lines, "0", '.'); if (empty($lines)) { $msg = "screen session '{$sessionName}' is not running"; $log->endAction($msg); return null; } // there might be $processDetails = new BaseObject(); $processDetails->hostId = $this->args[0]; $processDetails->name = $sessionName; $processDetails->type = 'screen'; $processDetails->pid = trim(rtrim($lines[0])); // all done $log->endAction("session is running as PID '{$processDetails->pid}'"); return $processDetails; }
/** * * @param VagrantVmDetails $vmDetails * @return boolean */ public function isRunning($vmDetails) { // what are we doing? $log = usingLog()->startAction("determine status of Vagrant VM '{$vmDetails->hostId}'"); // if the box is running, it should have a status of 'running' $command = "vagrant status"; $result = $this->runCommandAgainstHostManager($vmDetails, $command); // reduce the output down to the exact host we are looking for $lines = explode("\n", $result->output); $lines = FilterForMatchingString::against($lines, $vmDetails->hostId); $lines = FilterColumns::from($lines, "1", ' '); // what is the status? $state = trim($lines[0]); if ($state != 'running') { $log->endAction("VM is not running; state is '{$state}'"); return false; } // all done $log->endAction("VM is running"); return true; }