From aa8186471cee5e91bdeb1d26f97f6ca49b2e6321 Mon Sep 17 00:00:00 2001 From: Niklas Keller Date: Mon, 30 Jan 2017 19:15:33 +0100 Subject: [PATCH] Issue certificates sequential, allow changing the challenge concurrency --- src/Commands/Auto.php | 34 +++++++++++++++++++++------------- src/Commands/Issue.php | 10 +++++++++- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/Commands/Auto.php b/src/Commands/Auto.php index 974280e..ca6a9a8 100644 --- a/src/Commands/Auto.php +++ b/src/Commands/Auto.php @@ -89,6 +89,14 @@ class Auto implements Command { return; } + if (isset($config["challenge-concurrency"]) && !is_numeric($config["challenge-concurrency"])) { + $this->climate->error("Config file ({$configPath}) defines an invalid 'challenge-concurrency' value."); + yield new CoroutineResult(self::EXIT_CONFIG_ERROR); + return; + } + + $concurrency = isset($config["challenge-concurrency"]) ? (int) $config["challenge-concurrency"] : null; + $command = implode(" ", array_map("escapeshellarg", [ PHP_BINARY, $GLOBALS["argv"][0], @@ -113,22 +121,16 @@ class Auto implements Command { 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"])); + foreach ($config["certificates"] as $i => $certificate) { + try { + $result = (yield \Amp\resolve($this->checkAndIssue($certificate, $config["server"], $config["storage"], $concurrency))); + $values[$i] = $result; + } catch (\Exception $e) { + $errors[$i] = $e; } - - list($chunkErrors, $chunkValues) = (yield \Amp\any($promises)); - - $errors += $chunkErrors; - $values += $chunkValues; } $status = [ @@ -171,10 +173,11 @@ class Auto implements Command { * @param array $certificate certificate configuration * @param string $server server to use for issuance * @param string $storage storage directory + * @param int|null $concurrency concurrent challenges * @return \Generator * @throws AcmeException if something does wrong */ - private function checkAndIssue(array $certificate, $server, $storage) { + private function checkAndIssue(array $certificate, $server, $storage, $concurrency = null) { $domainPathMap = $this->toDomainPathMap($certificate["paths"]); $domains = array_keys($domainPathMap); $commonName = reset($domains); @@ -230,6 +233,11 @@ class Auto implements Command { $args[] = $certificate["bits"]; } + if ($concurrency) { + $args[] = "--challenge-concurrency"; + $args[] = $concurrency; + } + $command = implode(" ", array_map("escapeshellarg", $args)); $process = new Process($command); diff --git a/src/Commands/Issue.php b/src/Commands/Issue.php index 864fdd2..bdd69db 100644 --- a/src/Commands/Issue.php +++ b/src/Commands/Issue.php @@ -82,7 +82,9 @@ class Issue implements Command { $acme = $this->acmeFactory->build($server, $keyPair); $errors = []; - $domainChunks = array_chunk($domains, 10, true); + $concurrency = $args->get("challenge-concurrency"); + + $domainChunks = array_chunk($domains, \min(20, \max($concurrency, 1)), true); foreach ($domainChunks as $domainChunk) { $promises = []; @@ -251,6 +253,12 @@ class Issue implements Command { "defaultValue" => 2048, "castTo" => "int", ], + "challenge-concurrency" => [ + "longPrefix" => "challenge-concurrency", + "description" => "Number of challenges to be solved concurrently.", + "defaultValue" => 10, + "castTo" => "int", + ], ]; } }