mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 10:21:52 +00:00
recovery mode in embassyd
This commit is contained in:
committed by
Aiden McClelland
parent
df50197c5f
commit
6b3570e150
@@ -5,7 +5,9 @@ use embassy::context::rpc::RpcContextConfig;
|
||||
use embassy::context::{RecoveryContext, SetupContext};
|
||||
use embassy::disk::main::DEFAULT_PASSWORD;
|
||||
use embassy::hostname::get_product_key;
|
||||
use embassy::middleware::cors::cors;
|
||||
use embassy::middleware::encrypt::encrypt;
|
||||
use embassy::middleware::recovery::recovery;
|
||||
use embassy::util::Invoke;
|
||||
use embassy::{Error, ResultExt};
|
||||
use http::StatusCode;
|
||||
@@ -38,6 +40,7 @@ async fn init(cfg_path: Option<&str>) -> Result<(), Error> {
|
||||
context: ctx.clone(),
|
||||
status: status_fn,
|
||||
middleware: [
|
||||
cors,
|
||||
encrypt,
|
||||
]
|
||||
})
|
||||
@@ -144,7 +147,10 @@ async fn inner_main(cfg_path: Option<&str>) -> Result<(), Error> {
|
||||
command: embassy::recovery_api,
|
||||
context: ctx.clone(),
|
||||
status: status_fn,
|
||||
middleware: [ ]
|
||||
middleware: [
|
||||
cors,
|
||||
recovery,
|
||||
]
|
||||
})
|
||||
.with_graceful_shutdown({
|
||||
let mut shutdown = ctx.shutdown.subscribe();
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use embassy::context::RpcContext;
|
||||
use embassy::context::{RecoveryContext, RpcContext};
|
||||
use embassy::db::model::Database;
|
||||
use embassy::db::subscribe;
|
||||
use embassy::hostname::{get_hostname, get_id};
|
||||
use embassy::middleware::auth::auth;
|
||||
use embassy::middleware::cors::cors;
|
||||
use embassy::middleware::recovery::recovery;
|
||||
use embassy::net::tor::{os_key, tor_health_check};
|
||||
use embassy::shutdown::Shutdown;
|
||||
use embassy::status::{check_all, synchronize_all};
|
||||
@@ -250,7 +251,38 @@ fn main() {
|
||||
.enable_all()
|
||||
.build()
|
||||
.expect("failed to initialize runtime");
|
||||
rt.block_on(inner_main(cfg_path, filter))
|
||||
rt.block_on(async {
|
||||
match inner_main(cfg_path, filter).await {
|
||||
Ok(a) => Ok(a),
|
||||
Err(e) => {
|
||||
(|| async {
|
||||
log::error!("{}", e.source);
|
||||
log::debug!("{}", e.source);
|
||||
embassy::sound::BEETHOVEN.play().await?;
|
||||
let ctx = RecoveryContext::init(cfg_path, e).await?;
|
||||
rpc_server!({
|
||||
command: embassy::recovery_api,
|
||||
context: ctx.clone(),
|
||||
status: status_fn,
|
||||
middleware: [
|
||||
cors,
|
||||
recovery,
|
||||
]
|
||||
})
|
||||
.with_graceful_shutdown({
|
||||
let mut shutdown = ctx.shutdown.subscribe();
|
||||
async move {
|
||||
shutdown.recv().await.expect("context dropped");
|
||||
}
|
||||
})
|
||||
.await
|
||||
.with_kind(embassy::ErrorKind::Network)?;
|
||||
Ok::<_, Error>(None)
|
||||
})()
|
||||
.await
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
match res {
|
||||
|
||||
@@ -30,7 +30,7 @@ pub enum ErrorKind {
|
||||
InvalidOnionAddress = 22,
|
||||
Pack = 23,
|
||||
ValidateS9pk = 24,
|
||||
OpenSSL = 25,
|
||||
OpenSSL = 25, // REMOVE
|
||||
Tor = 26,
|
||||
ConfigGen = 27,
|
||||
ParseNumber = 28,
|
||||
@@ -56,6 +56,7 @@ pub enum ErrorKind {
|
||||
Zfs = 48,
|
||||
OpenSsl = 49,
|
||||
PasswordHashGeneration = 50,
|
||||
RecoveryMode = 51,
|
||||
}
|
||||
impl ErrorKind {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
@@ -85,7 +86,7 @@ impl ErrorKind {
|
||||
InvalidOnionAddress => "Invalid Onion Address",
|
||||
Pack => "Pack Error",
|
||||
ValidateS9pk => "S9PK Validation Error",
|
||||
OpenSSL => "OpenSSL Error",
|
||||
OpenSSL => "OpenSSL Error", // Remove
|
||||
Tor => "Tor Daemon Error",
|
||||
ConfigGen => "Config Generation Error",
|
||||
ParseNumber => "Number Parsing Error",
|
||||
@@ -111,6 +112,7 @@ impl ErrorKind {
|
||||
Zfs => "ZFS Error",
|
||||
OpenSsl => "OpenSSL Internal Error",
|
||||
PasswordHashGeneration => "Password Hash Generation Error",
|
||||
RecoveryMode => "Embassy is in Recovery Mode",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod auth;
|
||||
pub mod cors;
|
||||
pub mod encrypt;
|
||||
pub mod recovery;
|
||||
|
||||
36
appmgr/src/middleware/recovery.rs
Normal file
36
appmgr/src/middleware/recovery.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
use futures::FutureExt;
|
||||
use rpc_toolkit::hyper::http::Error as HttpError;
|
||||
use rpc_toolkit::hyper::{Body, Request, Response};
|
||||
use rpc_toolkit::rpc_server_helpers::{noop4, DynMiddlewareStage2, DynMiddlewareStage3};
|
||||
use rpc_toolkit::yajrc::RpcMethod;
|
||||
use rpc_toolkit::Metadata;
|
||||
|
||||
use crate::Error;
|
||||
|
||||
pub async fn recovery<M: Metadata>(
|
||||
_req: &mut Request<Body>,
|
||||
_metadata: M,
|
||||
) -> Result<Result<DynMiddlewareStage2, Response<Body>>, HttpError> {
|
||||
Ok(Ok(Box::new(|_, rpc_req| {
|
||||
let method = rpc_req.method.as_str().to_owned();
|
||||
async move {
|
||||
let res: DynMiddlewareStage3 = Box::new(|_, rpc_res| {
|
||||
async move {
|
||||
if let Err(e) = rpc_res {
|
||||
if e.code == -32601 {
|
||||
*e = Error::new(
|
||||
anyhow::anyhow!("{} is not available on the Recovery API", method),
|
||||
crate::ErrorKind::RecoveryMode,
|
||||
)
|
||||
.into();
|
||||
}
|
||||
}
|
||||
Ok(Ok(noop4()))
|
||||
}
|
||||
.boxed()
|
||||
});
|
||||
Ok::<_, HttpError>(Ok(res))
|
||||
}
|
||||
.boxed()
|
||||
})))
|
||||
}
|
||||
Reference in New Issue
Block a user