private function doExecute(Manager $args)
{
$configPath = $args->get("config");
try {
$config = Yaml::parse((yield \Amp\File\get($configPath)));
} catch (FilesystemException $e) {
$this->climate->error("Config file ({$configPath}) not found.");
(yield new CoroutineResult(self::EXIT_CONFIG_ERROR));
return;
} catch (ParseException $e) {
$this->climate->error("Config file ({$configPath}) had an invalid format and couldn't be parsed.");
(yield new CoroutineResult(self::EXIT_CONFIG_ERROR));
return;
}
if ($args->defined("server")) {
$config["server"] = $args->get("server");
} else {
if (!isset($config["server"]) && $args->exists("server")) {
$config["server"] = $args->get("server");
}
}
if ($args->defined("storage")) {
$config["storage"] = $args->get("storage");
} else {
if (!isset($config["storage"]) && $args->exists("storage")) {
$config["storage"] = $args->get("storage");
}
}
if (!isset($config["server"])) {
$this->climate->error("Config file ({$configPath}) didn't have a 'server' set nor was it passed as command line argument.");
(yield new CoroutineResult(self::EXIT_CONFIG_ERROR));
return;
}
if (!isset($config["storage"])) {
$this->climate->error("Config file ({$configPath}) didn't have a 'storage' set nor was it passed as command line argument.");
(yield new CoroutineResult(self::EXIT_CONFIG_ERROR));
return;
}
if (!isset($config["email"])) {
$this->climate->error("Config file ({$configPath}) didn't have a 'email' set.");
(yield new CoroutineResult(self::EXIT_CONFIG_ERROR));
return;
}
if (!isset($config["certificates"]) || !is_array($config["certificates"])) {
$this->climate->error("Config file ({$configPath}) didn't have a 'certificates' section that's an array.");
(yield new CoroutineResult(self::EXIT_CONFIG_ERROR));
return;
}
$command = implode(" ", array_map("escapeshellarg", [PHP_BINARY, $GLOBALS["argv"][0], "setup", "--server", $config["server"], "--storage", $config["storage"], "--email", $config["email"]]));
$process = new Process($command);
$result = (yield $process->exec(Process::BUFFER_ALL));
if ($result->exit !== 0) {
$this->climate->error("Registration failed ({$result->exit})");
$this->climate->error($command);
$this->climate->br()->out($result->stdout);
$this->climate->br()->error($result->stderr);
(yield new CoroutineResult(self::EXIT_SETUP_ERROR));
return;
}
$certificateChunks = array_chunk($config["certificates"], 10, true);
$errors = [];
$values = [];
foreach ($certificateChunks as $certificateChunk) {
$promises = [];
foreach ($certificateChunk as $certificate) {
$promises[] = \Amp\resolve($this->checkAndIssue($certificate, $config["server"], $config["storage"]));
}
list($chunkErrors, $chunkValues) = (yield \Amp\any($promises));
$errors += $chunkErrors;
$values += $chunkValues;
}
$status = ["no_change" => count(array_filter($values, function ($value) {
return $value === self::STATUS_NO_CHANGE;
})), "renewed" => count(array_filter($values, function ($value) {
return $value === self::STATUS_RENEWED;
})), "failure" => count($errors)];
if ($status["renewed"] > 0) {
foreach ($values as $i => $value) {
if ($value === self::STATUS_RENEWED) {
$certificate = $config["certificates"][$i];
$this->climate->info("Certificate for " . implode(", ", array_keys($this->toDomainPathMap($certificate["paths"]))) . " successfully renewed.");
}
}
}
if ($status["failure"] > 0) {
foreach ($errors as $i => $error) {
$certificate = $config["certificates"][$i];
$this->climate->error("Issuance for the following domains failed: " . implode(", ", array_keys($this->toDomainPathMap($certificate["paths"]))));
$this->climate->error("Reason: {$error}");
}
$exitCode = $status["renewed"] > 0 ? self::EXIT_ISSUANCE_PARTIAL : self::EXIT_ISSUANCE_ERROR;
(yield new CoroutineResult($exitCode));
return;
}
if ($status["renewed"] > 0) {
(yield new CoroutineResult(self::EXIT_ISSUANCE_OK));
return;
}
}