From: Wolfgang Bumiller <w.bumiller@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH v2 backup 26/27] acme: pipe plugin output to task log
Date: Thu, 22 Apr 2021 16:02:12 +0200 [thread overview]
Message-ID: <20210422140213.30989-27-w.bumiller@proxmox.com> (raw)
In-Reply-To: <20210422140213.30989-1-w.bumiller@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
---
src/api2/node/certificates.rs | 9 ++++--
src/config/acme/plugin.rs | 57 +++++++++++++++++++++++++++++------
2 files changed, 54 insertions(+), 12 deletions(-)
diff --git a/src/api2/node/certificates.rs b/src/api2/node/certificates.rs
index f6da31ec..37a1f44a 100644
--- a/src/api2/node/certificates.rs
+++ b/src/api2/node/certificates.rs
@@ -347,11 +347,16 @@ async fn order_certificate(
})?;
worker.log("Setting up validation plugin");
- let validation_url = plugin_cfg.setup(&mut acme, &auth, domain_config).await?;
+ let validation_url = plugin_cfg
+ .setup(&mut acme, &auth, domain_config, Arc::clone(&worker))
+ .await?;
let result = request_validation(&worker, &mut acme, auth_url, validation_url).await;
- if let Err(err) = plugin_cfg.teardown(&mut acme, &auth, domain_config).await {
+ if let Err(err) = plugin_cfg
+ .teardown(&mut acme, &auth, domain_config, Arc::clone(&worker))
+ .await
+ {
worker.warn(format!(
"Failed to teardown plugin '{}' for domain '{}' - {}",
plugin_id, domain, err
diff --git a/src/config/acme/plugin.rs b/src/config/acme/plugin.rs
index f3cbc7fa..da47b6e6 100644
--- a/src/config/acme/plugin.rs
+++ b/src/config/acme/plugin.rs
@@ -8,7 +8,7 @@ use hyper::{Body, Request, Response};
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
use serde_json::Value;
-use tokio::io::AsyncWriteExt;
+use tokio::io::{AsyncBufReadExt, AsyncRead, AsyncWriteExt, BufReader};
use tokio::process::Command;
use proxmox::api::{
@@ -24,6 +24,7 @@ use proxmox_acme_rs::{Authorization, Challenge};
use crate::acme::AcmeClient;
use crate::api2::types::PROXMOX_SAFE_ID_FORMAT;
use crate::config::node::AcmeDomain;
+use crate::server::WorkerTask;
const ACME_PATH: &str = "/usr/share/proxmox-acme/proxmox-acme";
@@ -280,6 +281,7 @@ pub trait AcmePlugin {
client: &'b mut AcmeClient,
authorization: &'c Authorization,
domain: &'d AcmeDomain,
+ task: Arc<WorkerTask>,
) -> Pin<Box<dyn Future<Output = Result<&'c str, Error>> + Send + 'fut>>;
fn teardown<'fut, 'a: 'fut, 'b: 'fut, 'c: 'fut, 'd: 'fut>(
@@ -287,6 +289,7 @@ pub trait AcmePlugin {
client: &'b mut AcmeClient,
authorization: &'c Authorization,
domain: &'d AcmeDomain,
+ task: Arc<WorkerTask>,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'fut>>;
}
@@ -301,12 +304,29 @@ fn extract_challenge<'a>(
.ok_or_else(|| format_err!("no supported challenge type (dns-01) found"))
}
+async fn pipe_to_tasklog<T: AsyncRead + Unpin>(
+ pipe: T,
+ task: Arc<WorkerTask>,
+) -> Result<(), std::io::Error> {
+ let mut pipe = BufReader::new(pipe);
+ let mut line = String::new();
+ loop {
+ line.clear();
+ match pipe.read_line(&mut line).await {
+ Ok(0) => return Ok(()),
+ Ok(_) => task.log(line.as_str()),
+ Err(err) => return Err(err),
+ }
+ }
+}
+
impl DnsPlugin {
async fn action<'a>(
&self,
client: &mut AcmeClient,
authorization: &'a Authorization,
domain: &AcmeDomain,
+ task: Arc<WorkerTask>,
action: &str,
) -> Result<&'a str, Error> {
let challenge = extract_challenge(authorization, "dns-01")?;
@@ -339,20 +359,33 @@ impl DnsPlugin {
domain.alias.as_deref().unwrap_or(&domain.domain),
]);
- let mut child = command.stdin(Stdio::piped()).spawn()?;
+ // We could use 1 socketpair, but tokio wraps them all in `File` internally causing `close`
+ // to be called separately on all of them without exception, so we need 3 pipes :-(
+
+ let mut child = command
+ .stdin(Stdio::piped())
+ .stdout(Stdio::piped())
+ .stderr(Stdio::piped())
+ .spawn()?;
let mut stdin = child.stdin.take().expect("Stdio::piped()");
- match async move {
+ let stdout = child.stdout.take().expect("Stdio::piped() failed?");
+ let stdout = pipe_to_tasklog(stdout, Arc::clone(&task));
+ let stderr = child.stderr.take().expect("Stdio::piped() failed?");
+ let stderr = pipe_to_tasklog(stderr, Arc::clone(&task));
+ let stdin = async move {
stdin.write_all(&stdin_data).await?;
stdin.flush().await?;
Ok::<_, std::io::Error>(())
- }
- .await
- {
- Ok(()) => (),
+ };
+ match futures::try_join!(stdin, stdout, stderr) {
+ Ok(((), (), ())) => (),
Err(err) => {
if let Err(err) = child.kill().await {
- eprintln!("failed to kill '{} {}' command: {}", ACME_PATH, action, err);
+ task.log(format!(
+ "failed to kill '{} {}' command: {}",
+ ACME_PATH, action, err
+ ));
}
bail!("'{}' failed: {}", ACME_PATH, err);
}
@@ -378,8 +411,9 @@ impl AcmePlugin for DnsPlugin {
client: &'b mut AcmeClient,
authorization: &'c Authorization,
domain: &'d AcmeDomain,
+ task: Arc<WorkerTask>,
) -> Pin<Box<dyn Future<Output = Result<&'c str, Error>> + Send + 'fut>> {
- Box::pin(self.action(client, authorization, domain, "setup"))
+ Box::pin(self.action(client, authorization, domain, task, "setup"))
}
fn teardown<'fut, 'a: 'fut, 'b: 'fut, 'c: 'fut, 'd: 'fut>(
@@ -387,9 +421,10 @@ impl AcmePlugin for DnsPlugin {
client: &'b mut AcmeClient,
authorization: &'c Authorization,
domain: &'d AcmeDomain,
+ task: Arc<WorkerTask>,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'fut>> {
Box::pin(async move {
- self.action(client, authorization, domain, "teardown")
+ self.action(client, authorization, domain, task, "teardown")
.await
.map(drop)
})
@@ -441,6 +476,7 @@ impl AcmePlugin for StandaloneServer {
client: &'b mut AcmeClient,
authorization: &'c Authorization,
_domain: &'d AcmeDomain,
+ _task: Arc<WorkerTask>,
) -> Pin<Box<dyn Future<Output = Result<&'c str, Error>> + Send + 'fut>> {
use hyper::server::conn::AddrIncoming;
use hyper::service::{make_service_fn, service_fn};
@@ -484,6 +520,7 @@ impl AcmePlugin for StandaloneServer {
_client: &'b mut AcmeClient,
_authorization: &'c Authorization,
_domain: &'d AcmeDomain,
+ _task: Arc<WorkerTask>,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'fut>> {
Box::pin(async move {
if let Some(abort) = self.abort_handle.take() {
--
2.20.1
next prev parent reply other threads:[~2021-04-22 14:02 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-22 14:01 [pbs-devel] [PATCH v2 backup 00/27] Implements ACME support for PBS Wolfgang Bumiller
2021-04-22 14:01 ` [pbs-devel] [PATCH v2 backup 01/27] systemd: add reload_unit Wolfgang Bumiller
2021-04-28 10:15 ` [pbs-devel] applied: " Dietmar Maurer
2021-04-22 14:01 ` [pbs-devel] [PATCH v2 backup 02/27] add dns alias schema Wolfgang Bumiller
2021-04-28 10:26 ` Dietmar Maurer
2021-04-28 11:07 ` Wolfgang Bumiller
2021-04-29 10:20 ` [pbs-devel] applied: " Dietmar Maurer
2021-04-22 14:01 ` [pbs-devel] [PATCH v2 backup 03/27] tools::fs::scan_subdir: use nix::Error instead of anyhow Wolfgang Bumiller
2021-04-28 10:36 ` [pbs-devel] applied: " Dietmar Maurer
2021-04-22 14:01 ` [pbs-devel] [PATCH v2 backup 04/27] config: factor out certificate writing Wolfgang Bumiller
2021-04-28 10:59 ` [pbs-devel] applied: " Dietmar Maurer
2021-04-22 14:01 ` [pbs-devel] [PATCH v2 backup 05/27] CertInfo: add not_{after, before}_unix Wolfgang Bumiller
2021-04-28 11:05 ` Dietmar Maurer
2021-04-28 11:12 ` Wolfgang Bumiller
2021-04-29 6:13 ` Dietmar Maurer
2021-04-29 7:01 ` Wolfgang Bumiller
2021-04-29 7:08 ` Dietmar Maurer
2021-04-29 7:14 ` Wolfgang Bumiller
2021-04-29 8:33 ` Dietmar Maurer
2021-04-29 8:49 ` Wolfgang Bumiller
2021-04-29 9:06 ` [pbs-devel] applied: " Dietmar Maurer
2021-04-22 14:01 ` [pbs-devel] [PATCH v2 backup 06/27] CertInfo: add is_expired_after_epoch Wolfgang Bumiller
2021-04-29 9:11 ` [pbs-devel] applied: " Dietmar Maurer
2021-04-22 14:01 ` [pbs-devel] [PATCH v2 backup 07/27] tools: add ControlFlow type Wolfgang Bumiller
2021-04-29 9:17 ` [pbs-devel] applied: " Dietmar Maurer
2021-04-29 9:26 ` Wolfgang Bumiller
2021-04-22 14:01 ` [pbs-devel] [PATCH v2 backup 08/27] catalog shell: replace LoopState with ControlFlow Wolfgang Bumiller
2021-04-29 9:17 ` [pbs-devel] applied: " Dietmar Maurer
2021-04-22 14:01 ` [pbs-devel] [PATCH v2 backup 09/27] Cargo.toml: depend on proxmox-acme-rs Wolfgang Bumiller
2021-04-29 10:07 ` [pbs-devel] applied: " Dietmar Maurer
2021-04-22 14:01 ` [pbs-devel] [PATCH v2 backup 10/27] bump d/control Wolfgang Bumiller
2021-04-29 10:07 ` [pbs-devel] applied: " Dietmar Maurer
2021-04-22 14:01 ` [pbs-devel] [PATCH v2 backup 11/27] config::acl: make /system/certificates a valid path Wolfgang Bumiller
2021-04-29 10:08 ` [pbs-devel] applied: " Dietmar Maurer
2021-04-22 14:01 ` [pbs-devel] [PATCH v2 backup 12/27] add 'config file format' to tools::config Wolfgang Bumiller
2021-04-29 10:12 ` [pbs-devel] applied: " Dietmar Maurer
2021-04-22 14:01 ` [pbs-devel] [PATCH v2 backup 13/27] add node config Wolfgang Bumiller
2021-04-29 10:39 ` Dietmar Maurer
2021-04-29 12:40 ` Dietmar Maurer
2021-04-29 13:15 ` Wolfgang Bumiller
2021-04-22 14:02 ` [pbs-devel] [PATCH v2 backup 14/27] add acme config Wolfgang Bumiller
2021-04-29 10:48 ` Dietmar Maurer
2021-04-29 11:36 ` Wolfgang Bumiller
2021-04-29 10:53 ` Dietmar Maurer
2021-04-29 11:34 ` Wolfgang Bumiller
2021-04-22 14:02 ` [pbs-devel] [PATCH v2 backup 15/27] tools/http: dedup user agent string Wolfgang Bumiller
2021-04-28 10:37 ` Dietmar Maurer
2021-04-22 14:02 ` [pbs-devel] [PATCH v2 backup 16/27] tools/http: add request_with_agent helper Wolfgang Bumiller
2021-04-28 10:38 ` Dietmar Maurer
2021-04-22 14:02 ` [pbs-devel] [PATCH v2 backup 17/27] add async acme client implementation Wolfgang Bumiller
2021-04-22 14:02 ` [pbs-devel] [PATCH v2 backup 18/27] add config/acme api path Wolfgang Bumiller
2021-04-22 14:02 ` [pbs-devel] [PATCH v2 backup 19/27] add node/{node}/certificates api call Wolfgang Bumiller
2021-04-22 14:02 ` [pbs-devel] [PATCH v2 backup 20/27] add node/{node}/config api path Wolfgang Bumiller
2021-04-22 14:02 ` [pbs-devel] [PATCH v2 backup 21/27] add acme commands to proxmox-backup-manager Wolfgang Bumiller
2021-04-22 14:02 ` [pbs-devel] [PATCH v2 backup 22/27] implement standalone acme validation Wolfgang Bumiller
2021-04-22 14:02 ` [pbs-devel] [PATCH v2 backup 23/27] ui: add certificate & acme view Wolfgang Bumiller
2021-04-22 14:02 ` [pbs-devel] [PATCH v2 backup 24/27] daily-update: check acme certificates Wolfgang Bumiller
2021-04-22 14:02 ` [pbs-devel] [PATCH v2 backup 25/27] acme: create directories as needed Wolfgang Bumiller
2021-04-22 14:12 ` Wolfgang Bumiller
2021-04-22 14:02 ` Wolfgang Bumiller [this message]
2021-04-22 14:02 ` [pbs-devel] [PATCH v2 backup 27/27] api: acme: make account name optional in register call Wolfgang Bumiller
2021-04-23 10:43 ` [pbs-devel] [PATCH v2 backup 00/27] Implements ACME support for PBS Dominic Jäger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210422140213.30989-27-w.bumiller@proxmox.com \
--to=w.bumiller@proxmox.com \
--cc=pbs-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.