appmgr: minor fixes

This commit is contained in:
Aiden McClelland
2021-06-17 11:57:11 -06:00
committed by Aiden McClelland
parent 7ce162aaf7
commit 5b22d0a3b3
8 changed files with 123 additions and 28 deletions

View File

@@ -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"

22
appmgr/deny.toml Normal file
View File

@@ -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 } ] },
]

View File

@@ -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(&<JsonPointer>::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);

View File

@@ -238,7 +238,7 @@ where
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(rename_all = "kebab-case")]
pub struct WithDescription<T> {
#[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<String>,
pub value_names: IndexMap<String, String>,
@@ -505,7 +505,7 @@ pub struct ValueSpecEnum {
impl<'de> serde::de::Deserialize<'de> for ValueSpecEnum {
fn deserialize<D: serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(rename_all = "kebab-case")]
pub struct _ValueSpecEnum {
pub values: IndexSet<String>,
#[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<String, ConfigSpec>,
@@ -1274,14 +1274,14 @@ pub struct ValueSpecUnion {
impl<'de> serde::de::Deserialize<'de> for ValueSpecUnion {
fn deserialize<D: serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[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<String, ConfigSpec>,
pub tag: _UnionTag,

View File

@@ -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<Self::Value, A::Error> {
let mut variant = None;
while let Some(key) = map.next_key()? {
match key {
while let Some(key) = map.next_key::<Cow<str>>()? {
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"],
))
}

View File

@@ -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),

View File

@@ -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<SocketAddr>,
pub bind_rpc: Option<SocketAddr>,
pub bind_ws: Option<SocketAddr>,
pub db: Option<PathBuf>,
pub secret_store: Option<PathBuf>,
}
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<LanHandle>,
// pub
}
#[derive(Clone)]
pub struct RpcContext(Arc<RpcContextSeed>);
impl RpcContext {
pub async fn init() -> Result<Self, Error> {
let cfg_path = Path::new(crate::CONFIG_PATH);
pub async fn init<P: AsRef<Path>>(cfg_path: Option<P>) -> Result<Self, Error> {
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 {

View File

@@ -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<T, R>(mut reader: R) -> Result<T, crate::Error>
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<T, W>(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<T, R>(mut reader: R) -> Result<T, crate::Error>
where
T: for<'de> serde::Deserialize<'de>,
@@ -771,3 +795,13 @@ pub fn parse_duration(arg: &str, matches: &ArgMatches<'_>) -> Result<Duration, E
)),
}
}
pub struct Container<T>(RwLock<Option<T>>);
impl<T> Container<T> {
pub async fn set(&self, value: T) {
*self.0.write().await = Some(value);
}
pub async fn drop(&self) {
*self.0.write().await = None;
}
}