From 5b22d0a3b3cdf432c76f52b9041cc17938e59f53 Mon Sep 17 00:00:00 2001 From: Aiden McClelland Date: Thu, 17 Jun 2021 11:57:11 -0600 Subject: [PATCH] appmgr: minor fixes --- appmgr/Cargo.toml | 1 - appmgr/deny.toml | 22 +++++++++++++++++++++ appmgr/src/bin/embassyd.rs | 39 +++++++++++++++++++++++++++++++++----- appmgr/src/config/spec.rs | 18 +++++++++--------- appmgr/src/config/util.rs | 7 ++++--- appmgr/src/context/cli.rs | 2 +- appmgr/src/context/rpc.rs | 28 ++++++++++++++++++--------- appmgr/src/util.rs | 34 +++++++++++++++++++++++++++++++++ 8 files changed, 123 insertions(+), 28 deletions(-) create mode 100644 appmgr/deny.toml diff --git a/appmgr/Cargo.toml b/appmgr/Cargo.toml index 46192e26e..bcf7b2a62 100644 --- a/appmgr/Cargo.toml +++ b/appmgr/Cargo.toml @@ -11,7 +11,6 @@ keywords = [ "full-node", "lightning", ] -license = "Start9 Personal Use License v1.0" name = "embassy-os" readme = "README.md" repository = "https://github.com/Start9Labs/embassy-os" diff --git a/appmgr/deny.toml b/appmgr/deny.toml new file mode 100644 index 000000000..7b4924cdc --- /dev/null +++ b/appmgr/deny.toml @@ -0,0 +1,22 @@ +[licenses] +unlicensed = "warn" +allow-osi-fsf-free = "neither" +copyleft = "deny" +confidence-threshold = 0.93 +allow = [ + "Apache-2.0", + "Apache-2.0 WITH LLVM-exception", + "MIT", + "ISC", + "MPL-2.0", + "CC0-1.0", + "BSD-2-Clause", + "BSD-3-Clause", + "LGPL-3.0", + "OpenSSL", +] + +clarify = [ + { name = "webpki", expression = "ISC", license-files = [ { path = "LICENSE", hash = 0x001c7e6c } ] }, + { name = "ring", expression = "OpenSSL", license-files = [ { path = "LICENSE", hash = 0xbd0eed23 } ] }, +] diff --git a/appmgr/src/bin/embassyd.rs b/appmgr/src/bin/embassyd.rs index 19719baa7..ae3da1d31 100644 --- a/appmgr/src/bin/embassyd.rs +++ b/appmgr/src/bin/embassyd.rs @@ -1,3 +1,4 @@ +use std::path::Path; use std::time::Duration; use embassy::context::{EitherContext, RpcContext}; @@ -14,9 +15,8 @@ fn status_fn(_: i32) -> StatusCode { StatusCode::OK } -async fn inner_main() -> Result<(), Error> { - simple_logging::log_to_stderr(log::LevelFilter::Info); - let rpc_ctx = RpcContext::init().await?; +async fn inner_main(cfg_path: Option<&str>) -> Result<(), Error> { + let rpc_ctx = RpcContext::init(cfg_path).await?; if !rpc_ctx.db.exists(&::default()).await? { rpc_ctx .db @@ -24,7 +24,12 @@ async fn inner_main() -> Result<(), Error> { .await?; } let ctx = EitherContext::Rpc(rpc_ctx.clone()); - let server = rpc_server!(embassy::main_api, ctx, status_fn); + let server = rpc_server!({ + command: embassy::main_api, + context: ctx, + status: status_fn, + + }); let status_ctx = rpc_ctx.clone(); let status_daemon = daemon( move || { @@ -70,8 +75,32 @@ async fn inner_main() -> Result<(), Error> { } fn main() { + let matches = clap::App::new("embassyd") + .arg( + clap::Arg::with_name("config") + .short("c") + .long("config") + .takes_value(true), + ) + .arg( + clap::Arg::with_name("verbosity") + .short("v") + .multiple(true) + .takes_value(false), + ) + .get_matches(); + + simple_logging::log_to_stderr(match matches.occurrences_of("verbosity") { + 0 => log::LevelFilter::Off, + 1 => log::LevelFilter::Error, + 2 => log::LevelFilter::Warn, + 3 => log::LevelFilter::Info, + 4 => log::LevelFilter::Debug, + _ => log::LevelFilter::Trace, + }); + let cfg_path = matches.value_of("config"); let rt = tokio::runtime::Runtime::new().expect("failed to initialize runtime"); - match rt.block_on(inner_main()) { + match rt.block_on(inner_main(cfg_path)) { Ok(_) => (), Err(e) => { drop(rt); diff --git a/appmgr/src/config/spec.rs b/appmgr/src/config/spec.rs index 2bbb10fdb..b6dcfa088 100644 --- a/appmgr/src/config/spec.rs +++ b/appmgr/src/config/spec.rs @@ -238,7 +238,7 @@ where } #[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[serde(rename_all = "kebab-case")] pub struct WithDescription { #[serde(flatten)] pub inner: T, @@ -497,7 +497,7 @@ impl DefaultableWith for ValueSpecBoolean { } #[derive(Clone, Debug, Serialize)] -#[serde(rename_all = "camelCase")] +#[serde(rename_all = "kebab-case")] pub struct ValueSpecEnum { pub values: IndexSet, pub value_names: IndexMap, @@ -505,7 +505,7 @@ pub struct ValueSpecEnum { impl<'de> serde::de::Deserialize<'de> for ValueSpecEnum { fn deserialize>(deserializer: D) -> Result { #[derive(Deserialize)] - #[serde(rename_all = "camelCase")] + #[serde(rename_all = "kebab-case")] pub struct _ValueSpecEnum { pub values: IndexSet, #[serde(default)] @@ -944,7 +944,7 @@ impl DefaultableWith for ValueSpecNumber { } #[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[serde(rename_all = "kebab-case")] pub struct ValueSpecObject { pub spec: ConfigSpec, #[serde(default)] @@ -1120,7 +1120,7 @@ impl ConfigSpec { } #[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[serde(rename_all = "kebab-case")] pub struct Pattern { #[serde(with = "util::serde_regex")] pub pattern: Regex, @@ -1254,7 +1254,7 @@ impl Entropy { } #[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[serde(rename_all = "kebab-case")] pub struct UnionTag { pub id: String, pub name: String, @@ -1263,7 +1263,7 @@ pub struct UnionTag { } #[derive(Clone, Debug, Serialize)] -#[serde(rename_all = "camelCase")] +#[serde(rename_all = "kebab-case")] pub struct ValueSpecUnion { pub tag: UnionTag, pub variants: IndexMap, @@ -1274,14 +1274,14 @@ pub struct ValueSpecUnion { impl<'de> serde::de::Deserialize<'de> for ValueSpecUnion { fn deserialize>(deserializer: D) -> Result { #[derive(Deserialize)] - #[serde(rename_all = "camelCase")] + #[serde(rename_all = "kebab-case")] #[serde(untagged)] pub enum _UnionTag { Old(String), New(UnionTag), } #[derive(Deserialize)] - #[serde(rename_all = "camelCase")] + #[serde(rename_all = "kebab-case")] pub struct _ValueSpecUnion { pub variants: IndexMap, pub tag: _UnionTag, diff --git a/appmgr/src/config/util.rs b/appmgr/src/config/util.rs index 0b56105ac..8e29d6509 100644 --- a/appmgr/src/config/util.rs +++ b/appmgr/src/config/util.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::ops::{Bound, RangeBounds, RangeInclusive}; use rand::distributions::Distribution; @@ -311,8 +312,8 @@ impl<'de> serde::de::Deserialize<'de> for UniqueBy { mut map: A, ) -> Result { let mut variant = None; - while let Some(key) = map.next_key()? { - match key { + while let Some(key) = map.next_key::>()? { + match key.as_ref() { "any" => { return Ok(UniqueBy::Any(map.next_value()?)); } @@ -325,7 +326,7 @@ impl<'de> serde::de::Deserialize<'de> for UniqueBy { } } Err(serde::de::Error::unknown_variant( - variant.unwrap_or_default(), + variant.unwrap_or_default().as_ref(), &["any", "all"], )) } diff --git a/appmgr/src/context/cli.rs b/appmgr/src/context/cli.rs index 2dd16d96e..02fc88840 100644 --- a/appmgr/src/context/cli.rs +++ b/appmgr/src/context/cli.rs @@ -45,7 +45,7 @@ impl CliContext { } else { CliContextConfig::default() }; - if let Some(bind) = base.server_config.bind { + if let Some(bind) = base.server_config.bind_rpc { if base.host.is_none() { base.host = Some(match bind.ip() { IpAddr::V4(a) => Host::Ipv4(a), diff --git a/appmgr/src/context/rpc.rs b/appmgr/src/context/rpc.rs index 1a5aa2612..816e95b65 100644 --- a/appmgr/src/context/rpc.rs +++ b/appmgr/src/context/rpc.rs @@ -11,38 +11,48 @@ use serde::Deserialize; use sqlx::SqlitePool; use tokio::fs::File; -use crate::util::{from_yaml_async_reader, AsyncFileExt}; +use crate::net::mdns::LanHandle; +use crate::util::{from_toml_async_reader, AsyncFileExt, Container}; use crate::{Error, ResultExt}; #[derive(Debug, Default, Deserialize)] #[serde(rename_all = "kebab-case")] pub struct RpcContextConfig { - pub bind: Option, + pub bind_rpc: Option, + pub bind_ws: Option, pub db: Option, pub secret_store: Option, } + pub struct RpcContextSeed { - pub bind: SocketAddr, + pub bind_rpc: SocketAddr, + pub bind_ws: SocketAddr, pub db: PatchDb, pub secret_store: SqlitePool, pub docker: Docker, + // pub lan_handle: Container, + // pub } #[derive(Clone)] pub struct RpcContext(Arc); impl RpcContext { - pub async fn init() -> Result { - let cfg_path = Path::new(crate::CONFIG_PATH); + pub async fn init>(cfg_path: Option

) -> Result { + let cfg_path = cfg_path + .as_ref() + .map(|p| p.as_ref()) + .unwrap_or(Path::new(crate::CONFIG_PATH)); let base = if let Some(f) = File::maybe_open(cfg_path) .await .with_ctx(|_| (crate::ErrorKind::Filesystem, cfg_path.display().to_string()))? { - from_yaml_async_reader(f).await? + from_toml_async_reader(f).await? } else { RpcContextConfig::default() }; let seed = Arc::new(RpcContextSeed { - bind: base.bind.unwrap_or(([127, 0, 0, 1], 5959).into()), + bind_rpc: base.bind_rpc.unwrap_or(([127, 0, 0, 1], 5959).into()), + bind_ws: base.bind_ws.unwrap_or(([127, 0, 0, 1], 5960).into()), db: PatchDb::open( base.db .unwrap_or_else(|| Path::new("/mnt/embassy-os/embassy.db").to_owned()), @@ -62,13 +72,13 @@ impl RpcContext { } impl Context for RpcContext { fn host(&self) -> Host<&str> { - match self.0.bind.ip() { + match self.0.bind_rpc.ip() { IpAddr::V4(a) => Host::Ipv4(a), IpAddr::V6(a) => Host::Ipv6(a), } } fn port(&self) -> u16 { - self.0.bind.port() + self.0.bind_rpc.port() } } impl Deref for RpcContext { diff --git a/appmgr/src/util.rs b/appmgr/src/util.rs index a26594a72..1d38853df 100644 --- a/appmgr/src/util.rs +++ b/appmgr/src/util.rs @@ -14,6 +14,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value; use tokio::fs::File; use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, ReadBuf}; +use tokio::sync::RwLock; use crate::{Error, ResultExt as _}; @@ -145,6 +146,29 @@ where Ok(()) } +pub async fn from_toml_async_reader(mut reader: R) -> Result +where + T: for<'de> serde::Deserialize<'de>, + R: AsyncRead + Unpin, +{ + let mut buffer = Vec::new(); + reader.read_to_end(&mut buffer).await?; + serde_toml::from_slice(&buffer) + .map_err(anyhow::Error::from) + .with_kind(crate::ErrorKind::Deserialization) +} + +pub async fn to_toml_async_writer(mut writer: W, value: &T) -> Result<(), crate::Error> +where + T: serde::Serialize, + W: AsyncWrite + Unpin, +{ + let mut buffer = serde_toml::to_vec(value).with_kind(crate::ErrorKind::Serialization)?; + buffer.extend_from_slice(b"\n"); + writer.write_all(&buffer).await?; + Ok(()) +} + pub async fn from_cbor_async_reader(mut reader: R) -> Result where T: for<'de> serde::Deserialize<'de>, @@ -771,3 +795,13 @@ pub fn parse_duration(arg: &str, matches: &ArgMatches<'_>) -> Result(RwLock>); +impl Container { + pub async fn set(&self, value: T) { + *self.0.write().await = Some(value); + } + pub async fn drop(&self) { + *self.0.write().await = None; + } +}