don't crash service if io-format is set for main (#1599)

This commit is contained in:
Aiden McClelland
2022-07-01 09:29:11 -06:00
committed by GitHub
parent 1b1ff05c81
commit f9b0f6ae35

View File

@@ -1,5 +1,5 @@
use std::borrow::Cow; use std::borrow::Cow;
use std::collections::{BTreeMap, BTreeSet}; use std::collections::{BTreeMap, BTreeSet, VecDeque};
use std::ffi::{OsStr, OsString}; use std::ffi::{OsStr, OsString};
use std::net::Ipv4Addr; use std::net::Ipv4Addr;
use std::path::PathBuf; use std::path::PathBuf;
@@ -16,10 +16,10 @@ use nix::sys::signal;
use nix::unistd::Pid; use nix::unistd::Pid;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;
use std::collections::VecDeque;
use tokio::io::{AsyncBufRead, AsyncBufReadExt, BufReader}; use tokio::io::{AsyncBufRead, AsyncBufReadExt, BufReader};
use tracing::instrument; use tracing::instrument;
use super::ProcedureName;
use crate::context::RpcContext; use crate::context::RpcContext;
use crate::id::{Id, ImageId}; use crate::id::{Id, ImageId};
use crate::s9pk::manifest::{PackageId, SYSTEM_PACKAGE_ID}; use crate::s9pk::manifest::{PackageId, SYSTEM_PACKAGE_ID};
@@ -28,8 +28,6 @@ use crate::util::Version;
use crate::volume::{VolumeId, Volumes}; use crate::volume::{VolumeId, Volumes};
use crate::{Error, ResultExt, HOST_IP}; use crate::{Error, ResultExt, HOST_IP};
use super::ProcedureName;
pub const NET_TLD: &str = "embassy"; pub const NET_TLD: &str = "embassy";
lazy_static::lazy_static! { lazy_static::lazy_static! {
@@ -187,31 +185,35 @@ impl DockerProcedure {
.with_kind(crate::ErrorKind::Docker)?, .with_kind(crate::ErrorKind::Docker)?,
); );
let output = NonDetachingJoinHandle::from(tokio::spawn(async move { let output = NonDetachingJoinHandle::from(tokio::spawn(async move {
if let Some(format) = io_format { match async {
let buffer = max_by_lines(&mut output, None).await?; if let Some(format) = io_format {
return Ok::<(Value, _), Error>(( let buffer = max_by_lines(&mut output, None).await?;
match format.from_slice(buffer.as_bytes()) { return Ok::<Value, Error>(
Ok(a) => a, match format.from_slice(buffer.as_bytes()) {
Err(e) => { Ok(a) => a,
tracing::warn!( Err(e) => {
"Failed to deserialize stdout from {}: {}, falling back to UTF-8 string.", tracing::warn!(
format, "Failed to deserialize stdout from {}: {}, falling back to UTF-8 string.",
e format,
); e
Value::String(buffer) );
} Value::String(buffer)
}, }
output, },
)); );
} }
let lines = buf_reader_to_lines(&mut output, 1000).await?; let lines = buf_reader_to_lines(&mut output, 1000).await?;
if lines.is_empty() { if lines.is_empty() {
return Ok((Value::Null, output)); return Ok(Value::Null);
} }
let joined_output = lines.join("\n"); let joined_output = lines.join("\n");
Ok((Value::String(joined_output), output)) Ok(Value::String(joined_output))
}.await {
Ok(a) => Ok((a, output)),
Err(e) => Err((e, output))
}
})); }));
let err_output = BufReader::new( let err_output = BufReader::new(
handle handle
@@ -246,10 +248,15 @@ impl DockerProcedure {
}; };
Ok( Ok(
if exit_status.success() || exit_status.code() == Some(143) { if exit_status.success() || exit_status.code() == Some(143) {
Ok( Ok(serde_json::from_value(
serde_json::from_value(output.await.with_kind(crate::ErrorKind::Unknown)??.0) output
.with_kind(crate::ErrorKind::Deserialization)?, .await
.with_kind(crate::ErrorKind::Unknown)?
.map(|(v, _)| v)
.map_err(|(e, _)| tracing::warn!("{}", e))
.unwrap_or_default(),
) )
.with_kind(crate::ErrorKind::Deserialization)?)
} else { } else {
Err(( Err((
exit_status.code().unwrap_or_default(), exit_status.code().unwrap_or_default(),
@@ -314,40 +321,49 @@ impl DockerProcedure {
.with_kind(crate::ErrorKind::Docker)?, .with_kind(crate::ErrorKind::Docker)?,
); );
let output = NonDetachingJoinHandle::from(tokio::spawn(async move { let output = NonDetachingJoinHandle::from(tokio::spawn(async move {
if let Some(format) = io_format { match async {
let buffer = max_by_lines(&mut output, None).await?; if let Some(format) = io_format {
return Ok::<(Value, _), Error>(( let buffer = max_by_lines(&mut output, None).await?;
match format.from_slice(&buffer.as_bytes()) { return Ok::<Value, Error>(
Ok(a) => a, match format.from_slice(buffer.as_bytes()) {
Err(e) => { Ok(a) => a,
tracing::warn!( Err(e) => {
"Failed to deserialize stdout from {}: {}, falling back to UTF-8 string.", tracing::warn!(
format, "Failed to deserialize stdout from {}: {}, falling back to UTF-8 string.",
e format,
); e
Value::String(buffer) );
} Value::String(buffer)
}, }
output, },
)); );
} }
let lines = buf_reader_to_lines(&mut output, 1000).await?; let lines = buf_reader_to_lines(&mut output, 1000).await?;
if lines.is_empty() { if lines.is_empty() {
return Ok((Value::Null, output)); return Ok(Value::Null);
} }
let joined_output = lines.join("\n"); let joined_output = lines.join("\n");
Ok((Value::String(joined_output), output)) Ok(Value::String(joined_output))
}.await {
Ok(a) => Ok((a, output)),
Err(e) => Err((e, output))
}
})); }));
let exit_status = handle.wait().await.with_kind(crate::ErrorKind::Docker)?; let exit_status = handle.wait().await.with_kind(crate::ErrorKind::Docker)?;
Ok( Ok(
if exit_status.success() || exit_status.code() == Some(143) { if exit_status.success() || exit_status.code() == Some(143) {
Ok( Ok(serde_json::from_value(
serde_json::from_value(output.await.with_kind(crate::ErrorKind::Unknown)??.0) output
.with_kind(crate::ErrorKind::Deserialization)?, .await
.with_kind(crate::ErrorKind::Unknown)?
.map(|(v, _)| v)
.map_err(|(e, _)| tracing::warn!("{}", e))
.unwrap_or_default(),
) )
.with_kind(crate::ErrorKind::Deserialization)?)
} else { } else {
Err(( Err((
exit_status.code().unwrap_or_default(), exit_status.code().unwrap_or_default(),