From 1cffa14c2008e2056a168c0c271d9316e3bcbcfc Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Sat, 1 Jun 2019 17:16:01 +0200 Subject: [PATCH] Renew certificates in parallel --- CHANGELOG.md | 1 + acmed/src/certificate.rs | 2 +- acmed/src/main.rs | 2 +- acmed/src/main_event_loop.rs | 72 +++++++++++++++++++++--------------- 4 files changed, 46 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f3245d..378c5b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - In hooks, the `stdin_str` has been added in replacement of the previous `stdin` behavior. ### Changed +- Certificates are renewed in parallel. - Hooks are now cleaned right after the current challenge has been validated instead of after the certificate's retrieval. - In hooks, the `stdin` field now refers to the path of the file that should be written into the hook's standard input. - The logging format has been re-written. diff --git a/acmed/src/certificate.rs b/acmed/src/certificate.rs index 58bc2fc..77a6e73 100644 --- a/acmed/src/certificate.rs +++ b/acmed/src/certificate.rs @@ -41,7 +41,7 @@ impl fmt::Display for Algorithm { } } -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct Certificate { pub account: Account, pub domains: Vec, diff --git a/acmed/src/main.rs b/acmed/src/main.rs index ecd0840..5dc4dbf 100644 --- a/acmed/src/main.rs +++ b/acmed/src/main.rs @@ -119,7 +119,7 @@ fn main() { ); let config_file = matches.value_of("config").unwrap_or(DEFAULT_CONFIG_FILE); - let mut srv = match MainEventLoop::new(&config_file, &root_certs) { + let srv = match MainEventLoop::new(&config_file, &root_certs) { Ok(s) => s, Err(e) => { error!("{}", e); diff --git a/acmed/src/main_event_loop.rs b/acmed/src/main_event_loop.rs index db89efd..398ab10 100644 --- a/acmed/src/main_event_loop.rs +++ b/acmed/src/main_event_loop.rs @@ -5,6 +5,24 @@ use acme_common::error::Error; use std::thread; use std::time::Duration; +fn renew_certificate(crt: &Certificate, root_certs: &[String]) { + let (status, is_success) = match request_certificate(crt, root_certs) { + Ok(_) => ("Success.".to_string(), true), + Err(e) => { + let e = e.prefix("Unable to renew the certificate"); + crt.warn(&e.message); + (e.message, false) + } + }; + match crt.call_post_operation_hooks(&status, is_success) { + Ok(_) => {} + Err(e) => { + let e = e.prefix("Post-operation hook error"); + crt.warn(&e.message); + } + }; +} + pub struct MainEventLoop { certs: Vec, root_certs: Vec, @@ -46,37 +64,33 @@ impl MainEventLoop { }) } - pub fn run(&mut self) { + pub fn run(&self) { loop { - for crt in self.certs.iter_mut() { - match crt.should_renew() { - Ok(sr) => { - if sr { - let (status, is_success) = - match request_certificate(crt, &self.root_certs) { - Ok(_) => ("Success.".to_string(), true), - Err(e) => { - let e = e.prefix("Unable to renew the certificate"); - crt.warn(&e.message); - (e.message, false) - } - }; - match crt.call_post_operation_hooks(&status, is_success) { - Ok(_) => {} - Err(e) => { - let e = e.prefix("Post-operation hook error"); - crt.warn(&e.message); - } - }; - } - } - Err(e) => { - crt.warn(&e.message); - } - }; - } - + self.renew_certificates(); thread::sleep(Duration::from_secs(crate::DEFAULT_SLEEP_TIME)); } } + + fn renew_certificates(&self) { + let mut handles = vec![]; + for crt in self.certs.iter() { + match crt.should_renew() { + Ok(true) => { + let root_certs = self.root_certs.clone(); + let cert = (*crt).clone(); + let handler = thread::spawn(move || { + renew_certificate(&cert, &root_certs); + }); + handles.push(handler); + } + Ok(false) => {} + Err(e) => { + crt.warn(&e.message); + } + }; + } + for handler in handles { + let _ = handler.join(); + } + } }