mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 18:31:52 +00:00
appmgr: minor fixes
This commit is contained in:
@@ -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
22
appmgr/deny.toml
Normal 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 } ] },
|
||||
]
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"],
|
||||
))
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user