mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 10:21:52 +00:00
Compare commits
14 Commits
v0.3.4-rc.
...
v0.3.4.1-c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d966e35054 | ||
|
|
1675570291 | ||
|
|
9b88de656e | ||
|
|
3d39b5653d | ||
|
|
eb5f7f64ad | ||
|
|
9fc0164c4d | ||
|
|
65eb520cca | ||
|
|
f7f07932b4 | ||
|
|
de52494039 | ||
|
|
4d87ee2bb6 | ||
|
|
d0ba0936ca | ||
|
|
b08556861f | ||
|
|
c96628ad49 | ||
|
|
a615882b3f |
2
backend/Cargo.lock
generated
2
backend/Cargo.lock
generated
@@ -1354,7 +1354,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "embassy-os"
|
||||
version = "0.3.4"
|
||||
version = "0.3.4-rev.1"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"async-compression",
|
||||
|
||||
@@ -14,7 +14,7 @@ keywords = [
|
||||
name = "embassy-os"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/Start9Labs/embassy-os"
|
||||
version = "0.3.4"
|
||||
version = "0.3.4-rev.1"
|
||||
|
||||
[lib]
|
||||
name = "embassy"
|
||||
|
||||
@@ -56,7 +56,7 @@ pub struct Action {
|
||||
pub input_spec: ConfigSpec,
|
||||
}
|
||||
impl Action {
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub fn validate(
|
||||
&self,
|
||||
container: &Option<DockerContainers>,
|
||||
@@ -74,7 +74,7 @@ impl Action {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn execute(
|
||||
&self,
|
||||
ctx: &RpcContext,
|
||||
@@ -120,7 +120,7 @@ fn display_action_result(action_result: ActionResult, matches: &ArgMatches) {
|
||||
}
|
||||
|
||||
#[command(about = "Executes an action", display(display_action_result))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn action(
|
||||
#[context] ctx: RpcContext,
|
||||
#[arg(rename = "id")] pkg_id: PackageId,
|
||||
|
||||
@@ -90,7 +90,7 @@ fn gen_pwd() {
|
||||
)
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, password))]
|
||||
#[instrument(skip_all)]
|
||||
async fn cli_login(
|
||||
ctx: CliContext,
|
||||
password: Option<PasswordType>,
|
||||
@@ -145,7 +145,7 @@ where
|
||||
display(display_none),
|
||||
metadata(authenticated = false)
|
||||
)]
|
||||
#[instrument(skip(ctx, password))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn login(
|
||||
#[context] ctx: RpcContext,
|
||||
#[request] req: &RequestParts,
|
||||
@@ -183,7 +183,7 @@ pub async fn login(
|
||||
}
|
||||
|
||||
#[command(display(display_none), metadata(authenticated = false))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn logout(
|
||||
#[context] ctx: RpcContext,
|
||||
#[request] req: &RequestParts,
|
||||
@@ -250,7 +250,7 @@ fn display_sessions(arg: SessionList, matches: &ArgMatches) {
|
||||
}
|
||||
|
||||
#[command(display(display_sessions))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn list(
|
||||
#[context] ctx: RpcContext,
|
||||
#[request] req: &RequestParts,
|
||||
@@ -296,7 +296,7 @@ impl AsLogoutSessionId for KillSessionId {
|
||||
}
|
||||
|
||||
#[command(display(display_none))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn kill(
|
||||
#[context] ctx: RpcContext,
|
||||
#[arg(parse(parse_comma_separated))] ids: Vec<String>,
|
||||
@@ -305,7 +305,7 @@ pub async fn kill(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, old_password, new_password))]
|
||||
#[instrument(skip_all)]
|
||||
async fn cli_reset_password(
|
||||
ctx: CliContext,
|
||||
old_password: Option<PasswordType>,
|
||||
@@ -369,7 +369,7 @@ impl SetPasswordReceipt {
|
||||
custom_cli(cli_reset_password(async, context(CliContext))),
|
||||
display(display_none)
|
||||
)]
|
||||
#[instrument(skip(ctx, old_password, new_password))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn reset_password(
|
||||
#[context] ctx: RpcContext,
|
||||
#[arg(rename = "old-password")] old_password: Option<PasswordType>,
|
||||
@@ -403,7 +403,7 @@ pub async fn reset_password(
|
||||
display(display_none),
|
||||
metadata(authenticated = false)
|
||||
)]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_pubkey(#[context] ctx: RpcContext) -> Result<Jwk, RpcError> {
|
||||
let secret = ctx.as_ref().clone();
|
||||
let pub_key = secret.to_public_key()?;
|
||||
|
||||
@@ -35,7 +35,7 @@ fn parse_comma_separated(arg: &str, _: &ArgMatches) -> Result<BTreeSet<PackageId
|
||||
}
|
||||
|
||||
#[command(rename = "create", display(display_none))]
|
||||
#[instrument(skip(ctx, old_password, password))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn backup_all(
|
||||
#[context] ctx: RpcContext,
|
||||
#[arg(rename = "target-id")] target_id: BackupTargetId,
|
||||
@@ -161,7 +161,7 @@ pub async fn backup_all(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(db, packages))]
|
||||
#[instrument(skip_all)]
|
||||
async fn assure_backing_up(
|
||||
db: &mut PatchDbHandle,
|
||||
packages: impl IntoIterator<Item = &PackageId>,
|
||||
@@ -200,7 +200,7 @@ async fn assure_backing_up(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, db, backup_guard))]
|
||||
#[instrument(skip_all)]
|
||||
async fn perform_backup<Db: DbHandle>(
|
||||
ctx: &RpcContext,
|
||||
mut db: Db,
|
||||
|
||||
@@ -92,7 +92,7 @@ impl BackupActions {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, db))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn create<Db: DbHandle>(
|
||||
&self,
|
||||
ctx: &RpcContext,
|
||||
@@ -189,7 +189,7 @@ impl BackupActions {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, db))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn restore<Db: DbHandle>(
|
||||
&self,
|
||||
ctx: &RpcContext,
|
||||
|
||||
@@ -46,7 +46,7 @@ fn parse_comma_separated(arg: &str, _: &ArgMatches) -> Result<Vec<PackageId>, Er
|
||||
}
|
||||
|
||||
#[command(rename = "restore", display(display_none))]
|
||||
#[instrument(skip(ctx, password))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn restore_packages_rpc(
|
||||
#[context] ctx: RpcContext,
|
||||
#[arg(parse(parse_comma_separated))] ids: Vec<PackageId>,
|
||||
@@ -169,7 +169,7 @@ impl ProgressInfo {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn recover_full_embassy(
|
||||
ctx: SetupContext,
|
||||
disk_guid: Arc<String>,
|
||||
@@ -306,7 +306,7 @@ async fn restore_packages(
|
||||
Ok((backup_guard, tasks, progress_info))
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, db, backup_guard))]
|
||||
#[instrument(skip_all)]
|
||||
async fn assure_restoring(
|
||||
ctx: &RpcContext,
|
||||
db: &mut PatchDbHandle,
|
||||
@@ -376,7 +376,7 @@ async fn assure_restoring(
|
||||
Ok(guards)
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, guard))]
|
||||
#[instrument(skip_all)]
|
||||
async fn restore_package<'a>(
|
||||
ctx: RpcContext,
|
||||
manifest: Manifest,
|
||||
|
||||
@@ -223,7 +223,7 @@ fn display_backup_info(info: BackupInfo, matches: &ArgMatches) {
|
||||
}
|
||||
|
||||
#[command(display(display_backup_info))]
|
||||
#[instrument(skip(ctx, password))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn info(
|
||||
#[context] ctx: RpcContext,
|
||||
#[arg(rename = "target-id")] target_id: BackupTargetId,
|
||||
|
||||
@@ -17,7 +17,7 @@ use embassy::{Error, ErrorKind, ResultExt, IS_RASPBERRY_PI};
|
||||
use tokio::process::Command;
|
||||
use tracing::instrument;
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
async fn setup_or_init(cfg_path: Option<PathBuf>) -> Result<(), Error> {
|
||||
if tokio::fs::metadata("/cdrom").await.is_ok() {
|
||||
let ctx = InstallContext::init(cfg_path).await?;
|
||||
@@ -117,7 +117,7 @@ async fn run_script_if_exists<P: AsRef<Path>>(path: P) {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
async fn inner_main(cfg_path: Option<PathBuf>) -> Result<Option<Shutdown>, Error> {
|
||||
if *IS_RASPBERRY_PI && tokio::fs::metadata(STANDBY_MODE_PATH).await.is_ok() {
|
||||
tokio::fs::remove_file(STANDBY_MODE_PATH).await?;
|
||||
|
||||
@@ -12,7 +12,7 @@ use futures::{FutureExt, TryFutureExt};
|
||||
use tokio::signal::unix::signal;
|
||||
use tracing::instrument;
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
async fn inner_main(cfg_path: Option<PathBuf>) -> Result<Option<Shutdown>, Error> {
|
||||
let (rpc_ctx, server, shutdown) = {
|
||||
let rpc_ctx = RpcContext::init(
|
||||
|
||||
@@ -31,7 +31,7 @@ pub struct ConfigActions {
|
||||
pub set: PackageProcedure,
|
||||
}
|
||||
impl ConfigActions {
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub fn validate(
|
||||
&self,
|
||||
container: &Option<DockerContainers>,
|
||||
@@ -47,7 +47,7 @@ impl ConfigActions {
|
||||
.with_ctx(|_| (crate::ErrorKind::ValidateS9pk, "Config Set"))?;
|
||||
Ok(())
|
||||
}
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get(
|
||||
&self,
|
||||
ctx: &RpcContext,
|
||||
@@ -71,7 +71,7 @@ impl ConfigActions {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn set(
|
||||
&self,
|
||||
ctx: &RpcContext,
|
||||
|
||||
@@ -214,7 +214,7 @@ impl ConfigGetReceipts {
|
||||
}
|
||||
|
||||
#[command(display(display_serializable))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get(
|
||||
#[context] ctx: RpcContext,
|
||||
#[parent_data] id: PackageId,
|
||||
@@ -240,7 +240,7 @@ pub async fn get(
|
||||
display(display_none),
|
||||
metadata(sync_db = true)
|
||||
)]
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub fn set(
|
||||
#[parent_data] id: PackageId,
|
||||
#[allow(unused_variables)]
|
||||
@@ -413,7 +413,7 @@ impl ConfigReceipts {
|
||||
}
|
||||
|
||||
#[command(rename = "dry", display(display_serializable))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn set_dry(
|
||||
#[context] ctx: RpcContext,
|
||||
#[parent_data] (id, config, timeout): (PackageId, Option<Config>, Option<Duration>),
|
||||
@@ -440,7 +440,7 @@ pub async fn set_dry(
|
||||
Ok(BreakageRes(breakages))
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn set_impl(
|
||||
ctx: RpcContext,
|
||||
(id, config, timeout): (PackageId, Option<Config>, Option<Duration>),
|
||||
@@ -465,7 +465,7 @@ pub async fn set_impl(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, db, receipts))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn configure<'a, Db: DbHandle>(
|
||||
ctx: &RpcContext,
|
||||
db: &'a mut Db,
|
||||
@@ -485,7 +485,7 @@ pub async fn configure<'a, Db: DbHandle>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, db, receipts))]
|
||||
#[instrument(skip_all)]
|
||||
pub fn configure_rec<'a, Db: DbHandle>(
|
||||
ctx: &'a RpcContext,
|
||||
db: &'a mut Db,
|
||||
@@ -771,7 +771,7 @@ pub fn configure_rec<'a, Db: DbHandle>(
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub fn not_found() -> Error {
|
||||
Error::new(eyre!("Could not find"), crate::ErrorKind::Incoherent)
|
||||
}
|
||||
|
||||
@@ -54,7 +54,8 @@ impl Drop for CliContextSeed {
|
||||
true,
|
||||
)
|
||||
.unwrap();
|
||||
let store = self.cookie_store.lock().unwrap();
|
||||
let mut store = self.cookie_store.lock().unwrap();
|
||||
store.remove("localhost", "", "local");
|
||||
store.save_json(&mut *writer).unwrap();
|
||||
writer.sync_all().unwrap();
|
||||
std::fs::rename(tmp, &self.cookie_path).unwrap();
|
||||
@@ -68,7 +69,7 @@ const DEFAULT_PORT: u16 = 5959;
|
||||
pub struct CliContext(Arc<CliContextSeed>);
|
||||
impl CliContext {
|
||||
/// BLOCKING
|
||||
#[instrument(skip(matches))]
|
||||
#[instrument(skip_all)]
|
||||
pub fn init(matches: &ArgMatches) -> Result<Self, crate::Error> {
|
||||
let local_config_path = local_config_path();
|
||||
let base: CliContextConfig = load_config_from_paths(
|
||||
@@ -101,19 +102,22 @@ impl CliContext {
|
||||
.unwrap_or(Path::new("/"))
|
||||
.join(".cookies.json")
|
||||
});
|
||||
let cookie_store = Arc::new(CookieStoreMutex::new(if cookie_path.exists() {
|
||||
let mut store = CookieStore::load_json(BufReader::new(File::open(&cookie_path)?))
|
||||
.map_err(|e| eyre!("{}", e))
|
||||
.with_kind(crate::ErrorKind::Deserialization)?;
|
||||
let cookie_store = Arc::new(CookieStoreMutex::new({
|
||||
let mut store = if cookie_path.exists() {
|
||||
CookieStore::load_json(BufReader::new(File::open(&cookie_path)?))
|
||||
.map_err(|e| eyre!("{}", e))
|
||||
.with_kind(crate::ErrorKind::Deserialization)?
|
||||
} else {
|
||||
CookieStore::default()
|
||||
};
|
||||
if let Ok(local) = std::fs::read_to_string(LOCAL_AUTH_COOKIE_PATH) {
|
||||
store
|
||||
.insert_raw(&Cookie::new("local", local), &"http://localhost".parse()?)
|
||||
.with_kind(crate::ErrorKind::Network)?;
|
||||
}
|
||||
store
|
||||
} else {
|
||||
CookieStore::default()
|
||||
}));
|
||||
|
||||
Ok(CliContext(Arc::new(CliContextSeed {
|
||||
base_url: url.clone(),
|
||||
rpc_url: {
|
||||
|
||||
@@ -18,7 +18,7 @@ pub struct DiagnosticContextConfig {
|
||||
pub datadir: Option<PathBuf>,
|
||||
}
|
||||
impl DiagnosticContextConfig {
|
||||
#[instrument(skip(path))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn load<P: AsRef<Path> + Send + 'static>(path: Option<P>) -> Result<Self, Error> {
|
||||
tokio::task::spawn_blocking(move || {
|
||||
load_config_from_paths(
|
||||
@@ -52,7 +52,7 @@ pub struct DiagnosticContextSeed {
|
||||
#[derive(Clone)]
|
||||
pub struct DiagnosticContext(Arc<DiagnosticContextSeed>);
|
||||
impl DiagnosticContext {
|
||||
#[instrument(skip(path))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn init<P: AsRef<Path> + Send + 'static>(
|
||||
path: Option<P>,
|
||||
disk_guid: Option<Arc<String>>,
|
||||
|
||||
@@ -15,7 +15,7 @@ use crate::Error;
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct InstallContextConfig {}
|
||||
impl InstallContextConfig {
|
||||
#[instrument(skip(path))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn load<P: AsRef<Path> + Send + 'static>(path: Option<P>) -> Result<Self, Error> {
|
||||
tokio::task::spawn_blocking(move || {
|
||||
load_config_from_paths(
|
||||
@@ -38,7 +38,7 @@ pub struct InstallContextSeed {
|
||||
#[derive(Clone)]
|
||||
pub struct InstallContext(Arc<InstallContextSeed>);
|
||||
impl InstallContext {
|
||||
#[instrument(skip(path))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn init<P: AsRef<Path> + Send + 'static>(path: Option<P>) -> Result<Self, Error> {
|
||||
let _cfg = InstallContextConfig::load(path.as_ref().map(|p| p.as_ref().to_owned())).await?;
|
||||
let (shutdown, _) = tokio::sync::broadcast::channel(1);
|
||||
|
||||
@@ -86,7 +86,7 @@ impl RpcContextConfig {
|
||||
}
|
||||
Ok(db)
|
||||
}
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn secret_store(&self) -> Result<PgPool, Error> {
|
||||
init_postgres(self.datadir()).await?;
|
||||
let secret_store =
|
||||
@@ -173,7 +173,7 @@ impl RpcCleanReceipts {
|
||||
#[derive(Clone)]
|
||||
pub struct RpcContext(Arc<RpcContextSeed>);
|
||||
impl RpcContext {
|
||||
#[instrument(skip(cfg_path))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn init<P: AsRef<Path> + Send + 'static>(
|
||||
cfg_path: Option<P>,
|
||||
disk_guid: Arc<String>,
|
||||
@@ -260,7 +260,7 @@ impl RpcContext {
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn shutdown(self) -> Result<(), Error> {
|
||||
self.managers.empty().await?;
|
||||
self.secret_store.close().await;
|
||||
@@ -270,7 +270,7 @@ impl RpcContext {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn cleanup(&self) -> Result<(), Error> {
|
||||
let mut db = self.db.handle();
|
||||
let receipts = RpcCleanReceipts::new(&mut db).await?;
|
||||
@@ -348,7 +348,7 @@ impl RpcContext {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn clean_continuations(&self) {
|
||||
let mut continuations = self.rpc_stream_continuations.lock().await;
|
||||
let mut to_remove = Vec::new();
|
||||
@@ -362,7 +362,7 @@ impl RpcContext {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self, handler))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn add_continuation(&self, guid: RequestGuid, handler: RpcContinuation) {
|
||||
self.clean_continuations().await;
|
||||
self.rpc_stream_continuations
|
||||
|
||||
@@ -25,7 +25,7 @@ pub struct SdkContextSeed {
|
||||
pub struct SdkContext(Arc<SdkContextSeed>);
|
||||
impl SdkContext {
|
||||
/// BLOCKING
|
||||
#[instrument(skip(matches))]
|
||||
#[instrument(skip_all)]
|
||||
pub fn init(matches: &ArgMatches) -> Result<Self, crate::Error> {
|
||||
let local_config_path = local_config_path();
|
||||
let base: SdkContextConfig = load_config_from_paths(
|
||||
@@ -49,7 +49,7 @@ impl SdkContext {
|
||||
})))
|
||||
}
|
||||
/// BLOCKING
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub fn developer_key(&self) -> Result<ed25519_dalek::Keypair, Error> {
|
||||
if !self.developer_key_path.exists() {
|
||||
return Err(Error::new(eyre!("Developer Key does not exist! Please run `embassy-sdk init` before running this command."), crate::ErrorKind::Uninitialized));
|
||||
|
||||
@@ -47,7 +47,7 @@ pub struct SetupContextConfig {
|
||||
pub datadir: Option<PathBuf>,
|
||||
}
|
||||
impl SetupContextConfig {
|
||||
#[instrument(skip(path))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn load<P: AsRef<Path> + Send + 'static>(path: Option<P>) -> Result<Self, Error> {
|
||||
tokio::task::spawn_blocking(move || {
|
||||
load_config_from_paths(
|
||||
@@ -92,7 +92,7 @@ impl AsRef<Jwk> for SetupContextSeed {
|
||||
#[derive(Clone)]
|
||||
pub struct SetupContext(Arc<SetupContextSeed>);
|
||||
impl SetupContext {
|
||||
#[instrument(skip(path))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn init<P: AsRef<Path> + Send + 'static>(path: Option<P>) -> Result<Self, Error> {
|
||||
let cfg = SetupContextConfig::load(path.as_ref().map(|p| p.as_ref().to_owned())).await?;
|
||||
let (shutdown, _) = tokio::sync::broadcast::channel(1);
|
||||
@@ -110,7 +110,7 @@ impl SetupContext {
|
||||
setup_result: RwLock::new(None),
|
||||
})))
|
||||
}
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn db(&self, account: &AccountInfo) -> Result<PatchDb, Error> {
|
||||
let db_path = self.datadir.join("main").join("embassy.db");
|
||||
let db = PatchDb::open(&db_path)
|
||||
@@ -122,7 +122,7 @@ impl SetupContext {
|
||||
}
|
||||
Ok(db)
|
||||
}
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn secret_store(&self) -> Result<PgPool, Error> {
|
||||
init_postgres(&self.datadir).await?;
|
||||
let secret_store =
|
||||
|
||||
@@ -61,7 +61,7 @@ impl StartReceipts {
|
||||
}
|
||||
|
||||
#[command(display(display_none), metadata(sync_db = true))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn start(#[context] ctx: RpcContext, #[arg] id: PackageId) -> Result<(), Error> {
|
||||
let mut db = ctx.db.handle();
|
||||
let mut tx = db.begin().await?;
|
||||
@@ -120,7 +120,7 @@ impl StopReceipts {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(db))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn stop_common<Db: DbHandle>(
|
||||
db: &mut Db,
|
||||
id: &PackageId,
|
||||
@@ -154,7 +154,7 @@ pub fn stop(#[arg] id: PackageId) -> Result<PackageId, Error> {
|
||||
}
|
||||
|
||||
#[command(rename = "dry", display(display_serializable))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn stop_dry(
|
||||
#[context] ctx: RpcContext,
|
||||
#[parent_data] id: PackageId,
|
||||
@@ -170,7 +170,7 @@ pub async fn stop_dry(
|
||||
Ok(BreakageRes(breakages))
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn stop_impl(ctx: RpcContext, id: PackageId) -> Result<MainStatus, Error> {
|
||||
let mut db = ctx.db.handle();
|
||||
let mut tx = db.begin().await?;
|
||||
|
||||
@@ -27,7 +27,7 @@ use crate::middleware::auth::{HasValidSession, HashSessionToken};
|
||||
use crate::util::serde::{display_serializable, IoFormat};
|
||||
use crate::{Error, ResultExt};
|
||||
|
||||
#[instrument(skip(ctx, session, ws_fut))]
|
||||
#[instrument(skip_all)]
|
||||
async fn ws_handler<
|
||||
WSFut: Future<Output = Result<Result<WebSocketStream<Upgraded>, HyperError>, JoinError>>,
|
||||
>(
|
||||
@@ -73,7 +73,7 @@ async fn subscribe_to_session_kill(
|
||||
recv
|
||||
}
|
||||
|
||||
#[instrument(skip(_has_valid_authentication, kill, sub, stream))]
|
||||
#[instrument(skip_all)]
|
||||
async fn deal_with_messages(
|
||||
_has_valid_authentication: HasValidSession,
|
||||
mut kill: oneshot::Receiver<()>,
|
||||
@@ -205,7 +205,7 @@ pub fn put() -> Result<(), RpcError> {
|
||||
}
|
||||
|
||||
#[command(display(display_serializable))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn ui(
|
||||
#[context] ctx: RpcContext,
|
||||
#[arg] pointer: JsonPointer,
|
||||
|
||||
@@ -191,7 +191,7 @@ impl DependencyError {
|
||||
(DependencyError::Transitive, _) => DependencyError::Transitive,
|
||||
}
|
||||
}
|
||||
#[instrument(skip(ctx, db, receipts))]
|
||||
#[instrument(skip_all)]
|
||||
pub fn try_heal<'a, Db: DbHandle>(
|
||||
self,
|
||||
ctx: &'a RpcContext,
|
||||
@@ -693,7 +693,7 @@ pub struct ConfigDryRes {
|
||||
}
|
||||
|
||||
#[command(rename = "dry", display(display_serializable))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn configure_dry(
|
||||
#[context] ctx: RpcContext,
|
||||
#[parent_data] (pkg_id, dependency_id): (PackageId, PackageId),
|
||||
@@ -784,7 +784,7 @@ pub async fn configure_logic(
|
||||
spec,
|
||||
})
|
||||
}
|
||||
#[instrument(skip(db, current_dependencies, current_dependent_receipt))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn add_dependent_to_current_dependents_lists<'a, Db: DbHandle>(
|
||||
db: &mut Db,
|
||||
dependent_id: &PackageId,
|
||||
@@ -919,7 +919,7 @@ impl BreakTransitiveReceipts {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(db, receipts))]
|
||||
#[instrument(skip_all)]
|
||||
pub fn break_transitive<'a, Db: DbHandle>(
|
||||
db: &'a mut Db,
|
||||
id: &'a PackageId,
|
||||
@@ -986,7 +986,7 @@ pub fn break_transitive<'a, Db: DbHandle>(
|
||||
.boxed()
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, db, locks))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn heal_all_dependents_transitive<'a, Db: DbHandle>(
|
||||
ctx: &'a RpcContext,
|
||||
db: &'a mut Db,
|
||||
@@ -1004,7 +1004,7 @@ pub async fn heal_all_dependents_transitive<'a, Db: DbHandle>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, db, receipts))]
|
||||
#[instrument(skip_all)]
|
||||
pub fn heal_transitive<'a, Db: DbHandle>(
|
||||
ctx: &'a RpcContext,
|
||||
db: &'a mut Db,
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::util::display_none;
|
||||
use crate::{Error, ResultExt};
|
||||
|
||||
#[command(cli_only, blocking, display(display_none))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub fn init(#[context] ctx: SdkContext) -> Result<(), Error> {
|
||||
if !ctx.developer_key_path.exists() {
|
||||
let parent = ctx.developer_key_path.parent().unwrap_or(Path::new("/"));
|
||||
|
||||
@@ -35,7 +35,7 @@ impl RepairStrategy {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn e2fsck_preen(
|
||||
logicalname: impl AsRef<Path> + std::fmt::Debug,
|
||||
) -> Result<RequiresReboot, Error> {
|
||||
@@ -59,7 +59,7 @@ fn backup_existing_undo_file<'a>(path: &'a Path) -> BoxFuture<'a, Result<(), Err
|
||||
.boxed()
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn e2fsck_aggressive(
|
||||
logicalname: impl AsRef<Path> + std::fmt::Debug,
|
||||
) -> Result<RequiresReboot, Error> {
|
||||
|
||||
@@ -17,7 +17,7 @@ pub const PASSWORD_PATH: &'static str = "/etc/embassy/password";
|
||||
pub const DEFAULT_PASSWORD: &'static str = "password";
|
||||
pub const MAIN_FS_SIZE: FsSize = FsSize::Gigabytes(8);
|
||||
|
||||
#[instrument(skip(disks, datadir, password))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn create<I, P>(
|
||||
disks: &I,
|
||||
pvscan: &BTreeMap<PathBuf, Option<String>>,
|
||||
@@ -34,7 +34,7 @@ where
|
||||
Ok(guid)
|
||||
}
|
||||
|
||||
#[instrument(skip(disks))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn create_pool<I, P>(
|
||||
disks: &I,
|
||||
pvscan: &BTreeMap<PathBuf, Option<String>>,
|
||||
@@ -84,7 +84,7 @@ pub enum FsSize {
|
||||
FreePercentage(usize),
|
||||
}
|
||||
|
||||
#[instrument(skip(datadir, password))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn create_fs<P: AsRef<Path>>(
|
||||
guid: &str,
|
||||
datadir: P,
|
||||
@@ -139,7 +139,7 @@ pub async fn create_fs<P: AsRef<Path>>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(datadir, password))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn create_all_fs<P: AsRef<Path>>(
|
||||
guid: &str,
|
||||
datadir: P,
|
||||
@@ -157,7 +157,7 @@ pub async fn create_all_fs<P: AsRef<Path>>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(datadir))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn unmount_fs<P: AsRef<Path>>(guid: &str, datadir: P, name: &str) -> Result<(), Error> {
|
||||
unmount(datadir.as_ref().join(name)).await?;
|
||||
Command::new("cryptsetup")
|
||||
@@ -170,7 +170,7 @@ pub async fn unmount_fs<P: AsRef<Path>>(guid: &str, datadir: P, name: &str) -> R
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(datadir))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn unmount_all_fs<P: AsRef<Path>>(guid: &str, datadir: P) -> Result<(), Error> {
|
||||
unmount_fs(guid, &datadir, "main").await?;
|
||||
unmount_fs(guid, &datadir, "package-data").await?;
|
||||
@@ -181,7 +181,7 @@ pub async fn unmount_all_fs<P: AsRef<Path>>(guid: &str, datadir: P) -> Result<()
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(datadir))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn export<P: AsRef<Path>>(guid: &str, datadir: P) -> Result<(), Error> {
|
||||
Command::new("sync").invoke(ErrorKind::Filesystem).await?;
|
||||
unmount_all_fs(guid, datadir).await?;
|
||||
@@ -197,7 +197,7 @@ pub async fn export<P: AsRef<Path>>(guid: &str, datadir: P) -> Result<(), Error>
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(datadir, password))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn import<P: AsRef<Path>>(
|
||||
guid: &str,
|
||||
datadir: P,
|
||||
@@ -254,7 +254,7 @@ pub async fn import<P: AsRef<Path>>(
|
||||
mount_all_fs(guid, datadir, repair, password).await
|
||||
}
|
||||
|
||||
#[instrument(skip(datadir, password))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn mount_fs<P: AsRef<Path>>(
|
||||
guid: &str,
|
||||
datadir: P,
|
||||
@@ -285,7 +285,7 @@ pub async fn mount_fs<P: AsRef<Path>>(
|
||||
Ok(reboot)
|
||||
}
|
||||
|
||||
#[instrument(skip(datadir, password))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn mount_all_fs<P: AsRef<Path>>(
|
||||
guid: &str,
|
||||
datadir: P,
|
||||
|
||||
@@ -35,7 +35,7 @@ impl<G: GenericMountGuard> BackupMountGuard<G> {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(password))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn mount(backup_disk_mount_guard: G, password: &str) -> Result<Self, Error> {
|
||||
let backup_disk_path = backup_disk_mount_guard.as_ref();
|
||||
let unencrypted_metadata_path =
|
||||
@@ -145,7 +145,7 @@ impl<G: GenericMountGuard> BackupMountGuard<G> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn mount_package_backup(
|
||||
&self,
|
||||
id: &PackageId,
|
||||
@@ -159,7 +159,7 @@ impl<G: GenericMountGuard> BackupMountGuard<G> {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn save(&self) -> Result<(), Error> {
|
||||
let metadata_path = self.as_ref().join("metadata.cbor");
|
||||
let backup_disk_path = self.backup_disk_path();
|
||||
@@ -180,7 +180,7 @@ impl<G: GenericMountGuard> BackupMountGuard<G> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn unmount(mut self) -> Result<(), Error> {
|
||||
if let Some(guard) = self.encrypted_guard.take() {
|
||||
guard.unmount().await?;
|
||||
@@ -191,7 +191,7 @@ impl<G: GenericMountGuard> BackupMountGuard<G> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn save_and_unmount(self) -> Result<(), Error> {
|
||||
self.save().await?;
|
||||
self.unmount().await?;
|
||||
|
||||
@@ -33,7 +33,7 @@ async fn resolve_hostname(hostname: &str) -> Result<IpAddr, Error> {
|
||||
.parse()?)
|
||||
}
|
||||
|
||||
#[instrument(skip(path, password, mountpoint))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn mount_cifs(
|
||||
hostname: &str,
|
||||
path: impl AsRef<Path>,
|
||||
|
||||
@@ -95,7 +95,7 @@ pub struct TmpMountGuard {
|
||||
}
|
||||
impl TmpMountGuard {
|
||||
/// DRAGONS: if you try to mount something as ro and rw at the same time, the ro mount will be upgraded to rw.
|
||||
#[instrument(skip(filesystem))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn mount(filesystem: &impl FileSystem, mount_type: MountType) -> Result<Self, Error> {
|
||||
let mountpoint = tmp_mountpoint(filesystem).await?;
|
||||
let mut tmp_mounts = TMP_MOUNTS.lock().await;
|
||||
|
||||
@@ -5,7 +5,7 @@ use tracing::instrument;
|
||||
use crate::util::Invoke;
|
||||
use crate::{Error, ResultExt};
|
||||
|
||||
#[instrument(skip(src, dst))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn bind<P0: AsRef<Path>, P1: AsRef<Path>>(
|
||||
src: P0,
|
||||
dst: P1,
|
||||
@@ -40,7 +40,7 @@ pub async fn bind<P0: AsRef<Path>, P1: AsRef<Path>>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(mountpoint))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn unmount<P: AsRef<Path>>(mountpoint: P) -> Result<(), Error> {
|
||||
tracing::debug!("Unmounting {}.", mountpoint.as_ref().display());
|
||||
tokio::process::Command::new("umount")
|
||||
|
||||
@@ -69,7 +69,7 @@ lazy_static::lazy_static! {
|
||||
static ref PARTITION_REGEX: Regex = Regex::new("-part[0-9]+$").unwrap();
|
||||
}
|
||||
|
||||
#[instrument(skip(path))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_partition_table<P: AsRef<Path>>(path: P) -> Result<Option<PartitionTable>, Error> {
|
||||
Ok(String::from_utf8(
|
||||
Command::new("fdisk")
|
||||
@@ -87,7 +87,7 @@ pub async fn get_partition_table<P: AsRef<Path>>(path: P) -> Result<Option<Parti
|
||||
}))
|
||||
}
|
||||
|
||||
#[instrument(skip(path))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_vendor<P: AsRef<Path>>(path: P) -> Result<Option<String>, Error> {
|
||||
let vendor = tokio::fs::read_to_string(
|
||||
Path::new(SYS_BLOCK_PATH)
|
||||
@@ -110,7 +110,7 @@ pub async fn get_vendor<P: AsRef<Path>>(path: P) -> Result<Option<String>, Error
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(path))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_model<P: AsRef<Path>>(path: P) -> Result<Option<String>, Error> {
|
||||
let model = tokio::fs::read_to_string(
|
||||
Path::new(SYS_BLOCK_PATH)
|
||||
@@ -129,7 +129,7 @@ pub async fn get_model<P: AsRef<Path>>(path: P) -> Result<Option<String>, Error>
|
||||
Ok(if model.is_empty() { None } else { Some(model) })
|
||||
}
|
||||
|
||||
#[instrument(skip(path))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_capacity<P: AsRef<Path>>(path: P) -> Result<u64, Error> {
|
||||
Ok(String::from_utf8(
|
||||
Command::new("blockdev")
|
||||
@@ -142,7 +142,7 @@ pub async fn get_capacity<P: AsRef<Path>>(path: P) -> Result<u64, Error> {
|
||||
.parse::<u64>()?)
|
||||
}
|
||||
|
||||
#[instrument(skip(path))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_label<P: AsRef<Path>>(path: P) -> Result<Option<String>, Error> {
|
||||
let label = String::from_utf8(
|
||||
Command::new("lsblk")
|
||||
@@ -157,7 +157,7 @@ pub async fn get_label<P: AsRef<Path>>(path: P) -> Result<Option<String>, Error>
|
||||
Ok(if label.is_empty() { None } else { Some(label) })
|
||||
}
|
||||
|
||||
#[instrument(skip(path))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_used<P: AsRef<Path>>(path: P) -> Result<u64, Error> {
|
||||
Ok(String::from_utf8(
|
||||
Command::new("df")
|
||||
@@ -175,7 +175,7 @@ pub async fn get_used<P: AsRef<Path>>(path: P) -> Result<u64, Error> {
|
||||
.parse::<u64>()?)
|
||||
}
|
||||
|
||||
#[instrument(skip(path))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_available<P: AsRef<Path>>(path: P) -> Result<u64, Error> {
|
||||
Ok(String::from_utf8(
|
||||
Command::new("df")
|
||||
@@ -193,7 +193,7 @@ pub async fn get_available<P: AsRef<Path>>(path: P) -> Result<u64, Error> {
|
||||
.parse::<u64>()?)
|
||||
}
|
||||
|
||||
#[instrument(skip(path))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_percentage<P: AsRef<Path>>(path: P) -> Result<u64, Error> {
|
||||
Ok(String::from_utf8(
|
||||
Command::new("df")
|
||||
@@ -212,7 +212,7 @@ pub async fn get_percentage<P: AsRef<Path>>(path: P) -> Result<u64, Error> {
|
||||
.parse::<u64>()?)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn pvscan() -> Result<BTreeMap<PathBuf, Option<String>>, Error> {
|
||||
let pvscan_out = Command::new("pvscan")
|
||||
.invoke(crate::ErrorKind::DiskManagement)
|
||||
@@ -248,7 +248,7 @@ pub async fn recovery_info(
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn list(os: &OsPartitionInfo) -> Result<Vec<DiskInfo>, Error> {
|
||||
struct DiskIndex {
|
||||
parts: IndexSet<PathBuf>,
|
||||
|
||||
@@ -44,7 +44,7 @@ pub fn generate_id() -> String {
|
||||
id.to_string()
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_current_hostname() -> Result<Hostname, Error> {
|
||||
let out = Command::new("hostname")
|
||||
.invoke(ErrorKind::ParseSysInfo)
|
||||
@@ -53,7 +53,7 @@ pub async fn get_current_hostname() -> Result<Hostname, Error> {
|
||||
Ok(Hostname(out_string.trim().to_owned()))
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn set_hostname(hostname: &Hostname) -> Result<(), Error> {
|
||||
let hostname: &String = &hostname.0;
|
||||
let _out = Command::new("hostnamectl")
|
||||
@@ -64,7 +64,7 @@ pub async fn set_hostname(hostname: &Hostname) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn sync_hostname(account: &AccountInfo) -> Result<(), Error> {
|
||||
set_hostname(&account.hostname).await?;
|
||||
Command::new("systemctl")
|
||||
|
||||
@@ -62,7 +62,7 @@ impl UpdateDependencyReceipts {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, db, deps, receipts))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn update_dependency_errors_of_dependents<'a, Db: DbHandle>(
|
||||
ctx: &RpcContext,
|
||||
db: &mut Db,
|
||||
@@ -99,7 +99,7 @@ pub async fn update_dependency_errors_of_dependents<'a, Db: DbHandle>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn cleanup(ctx: &RpcContext, id: &PackageId, version: &Version) -> Result<(), Error> {
|
||||
let mut errors = ErrorCollection::new();
|
||||
ctx.managers.remove(&(id.clone(), version.clone())).await;
|
||||
@@ -204,7 +204,7 @@ impl CleanupFailedReceipts {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, db, receipts))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn cleanup_failed<Db: DbHandle>(
|
||||
ctx: &RpcContext,
|
||||
db: &mut Db,
|
||||
@@ -272,7 +272,7 @@ pub async fn cleanup_failed<Db: DbHandle>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(db, current_dependencies, current_dependent_receipt))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn remove_from_current_dependents_lists<'a, Db: DbHandle>(
|
||||
db: &mut Db,
|
||||
id: &'a PackageId,
|
||||
@@ -340,7 +340,7 @@ impl UninstallReceipts {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[instrument(skip(ctx, secrets, db))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn uninstall<Ex>(
|
||||
ctx: &RpcContext,
|
||||
db: &mut PatchDbHandle,
|
||||
@@ -404,7 +404,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(secrets))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn remove_tor_keys<Ex>(secrets: &mut Ex, id: &PackageId) -> Result<(), Error>
|
||||
where
|
||||
for<'a> &'a mut Ex: Executor<'a, Database = Postgres>,
|
||||
|
||||
@@ -116,7 +116,7 @@ impl std::fmt::Display for MinMax {
|
||||
display(display_none),
|
||||
metadata(sync_db = true)
|
||||
)]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn install(
|
||||
#[context] ctx: RpcContext,
|
||||
#[arg] id: String,
|
||||
@@ -326,7 +326,7 @@ pub async fn install(
|
||||
}
|
||||
|
||||
#[command(rpc_only, display(display_none))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn sideload(
|
||||
#[context] ctx: RpcContext,
|
||||
#[arg] manifest: Manifest,
|
||||
@@ -482,7 +482,7 @@ pub async fn sideload(
|
||||
Ok(guid)
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
async fn cli_install(
|
||||
ctx: CliContext,
|
||||
target: String,
|
||||
@@ -574,7 +574,7 @@ pub async fn uninstall(#[arg] id: PackageId) -> Result<PackageId, Error> {
|
||||
}
|
||||
|
||||
#[command(rename = "dry", display(display_serializable))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn uninstall_dry(
|
||||
#[context] ctx: RpcContext,
|
||||
#[parent_data] id: PackageId,
|
||||
@@ -597,7 +597,7 @@ pub async fn uninstall_dry(
|
||||
Ok(BreakageRes(breakages))
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn uninstall_impl(ctx: RpcContext, id: PackageId) -> Result<(), Error> {
|
||||
let mut handle = ctx.db.handle();
|
||||
let mut tx = handle.begin().await?;
|
||||
@@ -700,7 +700,7 @@ impl DownloadInstallReceipts {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, temp_manifest, s9pk))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn download_install_s9pk(
|
||||
ctx: &RpcContext,
|
||||
temp_manifest: &Manifest,
|
||||
@@ -873,7 +873,7 @@ impl InstallS9Receipts {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, rdr))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin + Send + Sync>(
|
||||
ctx: &RpcContext,
|
||||
pkg_id: &PackageId,
|
||||
@@ -1402,7 +1402,7 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin + Send + Sync>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(datadir))]
|
||||
#[instrument(skip_all)]
|
||||
pub fn load_images<'a, P: AsRef<Path> + 'a + Send + Sync>(
|
||||
datadir: P,
|
||||
) -> BoxFuture<'a, Result<(), Error>> {
|
||||
@@ -1435,16 +1435,22 @@ pub fn load_images<'a, P: AsRef<Path> + 'a + Send + Sync>(
|
||||
copy_and_shutdown(&mut File::open(&path).await?, load_in)
|
||||
.await?
|
||||
}
|
||||
Some("s9pk") => {
|
||||
copy_and_shutdown(
|
||||
&mut S9pkReader::open(&path, false)
|
||||
.await?
|
||||
.docker_images()
|
||||
.await?,
|
||||
load_in,
|
||||
)
|
||||
.await?
|
||||
Some("s9pk") => match async {
|
||||
let mut reader = S9pkReader::open(&path, true).await?;
|
||||
copy_and_shutdown(&mut reader.docker_images().await?, load_in)
|
||||
.await?;
|
||||
Ok::<_, Error>(())
|
||||
}
|
||||
.await
|
||||
{
|
||||
Ok(()) => (),
|
||||
Err(e) => {
|
||||
tracing::error!(
|
||||
"Error loading docker images from s9pk: {e}"
|
||||
);
|
||||
tracing::debug!("{e:?}");
|
||||
}
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ pub async fn update() -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
#[command(display(display_serializable))]
|
||||
pub async fn dry(
|
||||
#[context] ctx: RpcContext,
|
||||
|
||||
@@ -64,7 +64,7 @@ impl Stream for LogStream {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(logs, ws_fut))]
|
||||
#[instrument(skip_all)]
|
||||
async fn ws_handler<
|
||||
WSFut: Future<Output = Result<Result<WebSocketStream<Upgraded>, HyperError>, JoinError>>,
|
||||
>(
|
||||
@@ -409,7 +409,7 @@ async fn journalctl(
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn fetch_logs(
|
||||
id: LogSource,
|
||||
limit: Option<usize>,
|
||||
@@ -456,7 +456,7 @@ pub async fn fetch_logs(
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn follow_logs(
|
||||
ctx: RpcContext,
|
||||
id: LogSource,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use itertools::Itertools;
|
||||
use patch_db::{DbHandle, LockReceipt, LockType};
|
||||
use tracing::instrument;
|
||||
|
||||
@@ -90,7 +91,7 @@ impl HealthCheckStatusReceipt {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, db))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn check<Db: DbHandle>(
|
||||
ctx: &RpcContext,
|
||||
db: &mut Db,
|
||||
@@ -111,6 +112,7 @@ pub async fn check<Db: DbHandle>(
|
||||
};
|
||||
|
||||
let health_results = if let Some(started) = started {
|
||||
tracing::debug!("Checking health of {}", id);
|
||||
manifest
|
||||
.health_checks
|
||||
.check_all(
|
||||
@@ -129,6 +131,24 @@ pub async fn check<Db: DbHandle>(
|
||||
if !should_commit.load(Ordering::SeqCst) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if !health_results
|
||||
.iter()
|
||||
.any(|(_, res)| matches!(res, HealthCheckResult::Failure { .. }))
|
||||
{
|
||||
tracing::debug!("All health checks succeeded for {}", id);
|
||||
} else {
|
||||
tracing::debug!(
|
||||
"Some health checks failed for {}: {}",
|
||||
id,
|
||||
health_results
|
||||
.iter()
|
||||
.filter(|(_, res)| matches!(res, HealthCheckResult::Failure { .. }))
|
||||
.map(|(id, _)| &*id)
|
||||
.join(", ")
|
||||
);
|
||||
}
|
||||
|
||||
let current_dependents = {
|
||||
let mut checkpoint = tx.begin().await?;
|
||||
let receipts = HealthCheckStatusReceipt::new(&mut checkpoint, id).await?;
|
||||
@@ -153,9 +173,7 @@ pub async fn check<Db: DbHandle>(
|
||||
current_dependents
|
||||
};
|
||||
|
||||
tracing::debug!("Checking health of {}", id);
|
||||
let receipts = crate::dependencies::BreakTransitiveReceipts::new(&mut tx).await?;
|
||||
tracing::debug!("Got receipts {}", id);
|
||||
|
||||
for (dependent, info) in (current_dependents).0.iter() {
|
||||
let failures: BTreeMap<HealthCheckId, HealthCheckResult> = health_results
|
||||
|
||||
@@ -39,7 +39,7 @@ pub const HEALTH_CHECK_GRACE_PERIOD_SECONDS: u64 = 5;
|
||||
#[derive(Default)]
|
||||
pub struct ManagerMap(RwLock<BTreeMap<(PackageId, Version), Arc<Manager>>>);
|
||||
impl ManagerMap {
|
||||
#[instrument(skip(self, ctx, db, secrets))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn init<Db: DbHandle, Ex>(
|
||||
&self,
|
||||
ctx: &RpcContext,
|
||||
@@ -78,7 +78,7 @@ impl ManagerMap {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(self, ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn add(&self, ctx: RpcContext, manifest: Manifest) -> Result<(), Error> {
|
||||
let mut lock = self.0.write().await;
|
||||
let id = (manifest.id.clone(), manifest.version.clone());
|
||||
@@ -91,7 +91,7 @@ impl ManagerMap {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn remove(&self, id: &(PackageId, Version)) {
|
||||
if let Some(man) = self.0.write().await.remove(id) {
|
||||
if let Err(e) = man.exit().await {
|
||||
@@ -101,7 +101,7 @@ impl ManagerMap {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn empty(&self) -> Result<(), Error> {
|
||||
let res =
|
||||
futures::future::join_all(std::mem::take(&mut *self.0.write().await).into_iter().map(
|
||||
@@ -128,7 +128,7 @@ impl ManagerMap {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get(&self, id: &(PackageId, Version)) -> Option<Arc<Manager>> {
|
||||
self.0.read().await.get(id).cloned()
|
||||
}
|
||||
@@ -174,7 +174,7 @@ pub enum OnStop {
|
||||
Exit,
|
||||
}
|
||||
|
||||
#[instrument(skip(state))]
|
||||
#[instrument(skip_all)]
|
||||
async fn run_main(
|
||||
state: &Arc<ManagerSharedState>,
|
||||
) -> Result<Result<NoOutput, (i32, String)>, Error> {
|
||||
@@ -232,7 +232,7 @@ async fn start_up_image(
|
||||
}
|
||||
|
||||
impl Manager {
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
async fn create(ctx: RpcContext, manifest: Manifest) -> Result<Self, Error> {
|
||||
let (on_stop, recv) = channel(OnStop::Sleep);
|
||||
let seed = Arc::new(ManagerSeed {
|
||||
@@ -271,7 +271,7 @@ impl Manager {
|
||||
send_signal(&self.shared, signal).await
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
async fn exit(&self) -> Result<(), Error> {
|
||||
self.shared
|
||||
.commit_health_check_results
|
||||
@@ -433,7 +433,7 @@ pub struct PersistentContainer {
|
||||
}
|
||||
|
||||
impl PersistentContainer {
|
||||
#[instrument(skip(seed))]
|
||||
#[instrument(skip_all)]
|
||||
async fn init(seed: &Arc<ManagerSeed>) -> Result<Option<Self>, Error> {
|
||||
Ok(if let Some(containers) = &seed.manifest.containers {
|
||||
let (running_docker, rpc_client) =
|
||||
@@ -722,7 +722,7 @@ fn sigterm_timeout(manifest: &Manifest) -> Option<Duration> {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(shared))]
|
||||
#[instrument(skip_all)]
|
||||
async fn stop(shared: &ManagerSharedState) -> Result<(), Error> {
|
||||
shared
|
||||
.commit_health_check_results
|
||||
@@ -746,7 +746,7 @@ async fn stop(shared: &ManagerSharedState) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(shared))]
|
||||
#[instrument(skip_all)]
|
||||
async fn start(shared: &ManagerSharedState) -> Result<(), Error> {
|
||||
shared.on_stop.send_modify(|status| {
|
||||
if matches!(*status, OnStop::Sleep) {
|
||||
@@ -761,7 +761,7 @@ async fn start(shared: &ManagerSharedState) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(shared))]
|
||||
#[instrument(skip_all)]
|
||||
async fn pause(shared: &ManagerSharedState) -> Result<(), Error> {
|
||||
if let Err(e) = shared
|
||||
.seed
|
||||
@@ -778,7 +778,7 @@ async fn pause(shared: &ManagerSharedState) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(shared))]
|
||||
#[instrument(skip_all)]
|
||||
async fn resume(shared: &ManagerSharedState) -> Result<(), Error> {
|
||||
shared
|
||||
.seed
|
||||
|
||||
@@ -47,7 +47,7 @@ pub struct EncryptedWire {
|
||||
encrypted: serde_json::Value,
|
||||
}
|
||||
impl EncryptedWire {
|
||||
#[instrument(skip(current_secret))]
|
||||
#[instrument(skip_all)]
|
||||
pub fn decrypt(self, current_secret: impl AsRef<Jwk>) -> Option<String> {
|
||||
let current_secret = current_secret.as_ref();
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ pub struct Migrations {
|
||||
pub to: IndexMap<VersionRange, PackageProcedure>,
|
||||
}
|
||||
impl Migrations {
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub fn validate(
|
||||
&self,
|
||||
container: &Option<DockerContainers>,
|
||||
@@ -55,7 +55,7 @@ impl Migrations {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub fn from<'a>(
|
||||
&'a self,
|
||||
container: &'a Option<DockerContainers>,
|
||||
@@ -95,7 +95,7 @@ impl Migrations {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub fn to<'a>(
|
||||
&'a self,
|
||||
ctx: &'a RpcContext,
|
||||
|
||||
@@ -16,7 +16,7 @@ use crate::{Error, ResultExt};
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct Interfaces(pub BTreeMap<InterfaceId, Interface>); // TODO
|
||||
impl Interfaces {
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub fn validate(&self) -> Result<(), Error> {
|
||||
for (_, interface) in &self.0 {
|
||||
interface.validate().with_ctx(|_| {
|
||||
@@ -28,7 +28,7 @@ impl Interfaces {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
#[instrument(skip(secrets))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn install<Ex>(
|
||||
&self,
|
||||
secrets: &mut Ex,
|
||||
@@ -90,7 +90,7 @@ pub struct Interface {
|
||||
pub protocols: IndexSet<String>,
|
||||
}
|
||||
impl Interface {
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub fn validate(&self) -> Result<(), color_eyre::eyre::Report> {
|
||||
if self.tor_config.is_some() && !self.protocols.contains("tcp") {
|
||||
color_eyre::eyre::bail!("must support tcp to set up a tor hidden service");
|
||||
|
||||
@@ -31,7 +31,7 @@ pub struct NetController {
|
||||
}
|
||||
|
||||
impl NetController {
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn init(
|
||||
tor_control: SocketAddr,
|
||||
dns_bind: &[SocketAddr],
|
||||
@@ -139,7 +139,7 @@ impl NetController {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn create_service(
|
||||
self: &Arc<Self>,
|
||||
package: PackageId,
|
||||
|
||||
@@ -143,21 +143,21 @@ pub async fn export_cert(chain: &[&X509], target: &Path) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
fn rand_serial() -> Result<Asn1Integer, Error> {
|
||||
let mut bn = BigNum::new()?;
|
||||
bn.rand(64, MsbOption::MAYBE_ZERO, false)?;
|
||||
let asn1 = Asn1Integer::from_bn(&bn)?;
|
||||
Ok(asn1)
|
||||
}
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub fn generate_key() -> Result<PKey<Private>, Error> {
|
||||
let new_key = EcKey::generate(EC_GROUP.as_ref())?;
|
||||
let key = PKey::from_ec_key(new_key)?;
|
||||
Ok(key)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub fn make_root_cert(root_key: &PKey<Private>, hostname: &Hostname) -> Result<X509, Error> {
|
||||
let mut builder = X509Builder::new()?;
|
||||
builder.set_version(CERTIFICATE_VERSION)?;
|
||||
@@ -208,7 +208,7 @@ pub fn make_root_cert(root_key: &PKey<Private>, hostname: &Hostname) -> Result<X
|
||||
let cert = builder.build();
|
||||
Ok(cert)
|
||||
}
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub fn make_int_cert(
|
||||
signer: (&PKey<Private>, &X509),
|
||||
applicant: &PKey<Private>,
|
||||
@@ -334,7 +334,7 @@ impl std::fmt::Display for SANInfo {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub fn make_leaf_cert(
|
||||
signer: (&PKey<Private>, &X509),
|
||||
applicant: (&PKey<Private>, &SANInfo),
|
||||
|
||||
@@ -93,7 +93,7 @@ pub struct TorControllerInner {
|
||||
services: BTreeMap<String, BTreeMap<u16, BTreeMap<SocketAddr, Weak<()>>>>,
|
||||
}
|
||||
impl TorControllerInner {
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
key: &TorSecretKeyV3,
|
||||
@@ -135,7 +135,7 @@ impl TorControllerInner {
|
||||
Ok(rc)
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
async fn gc(&mut self, key: &TorSecretKeyV3, external: u16) -> Result<(), Error> {
|
||||
let onion_base = key
|
||||
.public()
|
||||
@@ -174,7 +174,7 @@ impl TorControllerInner {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
async fn init(tor_control: SocketAddr) -> Result<Self, Error> {
|
||||
let mut conn = torut::control::UnauthenticatedConn::new(
|
||||
TcpStream::connect(tor_control).await?, // TODO
|
||||
@@ -196,7 +196,7 @@ impl TorControllerInner {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
async fn list_services(&mut self) -> Result<Vec<OnionAddressV3>, Error> {
|
||||
self.connection
|
||||
.get_info("onions/current")
|
||||
|
||||
@@ -47,7 +47,7 @@ pub async fn country() -> Result<(), Error> {
|
||||
}
|
||||
|
||||
#[command(display(display_none))]
|
||||
#[instrument(skip(ctx, password))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn add(
|
||||
#[context] ctx: RpcContext,
|
||||
#[arg] ssid: String,
|
||||
@@ -103,7 +103,7 @@ pub async fn add(
|
||||
}
|
||||
|
||||
#[command(display(display_none))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn connect(#[context] ctx: RpcContext, #[arg] ssid: String) -> Result<(), Error> {
|
||||
let wifi_manager = wifi_manager(&ctx)?;
|
||||
if !ssid.is_ascii() {
|
||||
@@ -155,7 +155,7 @@ pub async fn connect(#[context] ctx: RpcContext, #[arg] ssid: String) -> Result<
|
||||
}
|
||||
|
||||
#[command(display(display_none))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn delete(#[context] ctx: RpcContext, #[arg] ssid: String) -> Result<(), Error> {
|
||||
let wifi_manager = wifi_manager(&ctx)?;
|
||||
if !ssid.is_ascii() {
|
||||
@@ -293,7 +293,7 @@ fn display_wifi_list(info: Vec<WifiListOut>, matches: &ArgMatches) {
|
||||
}
|
||||
|
||||
#[command(display(display_wifi_info))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get(
|
||||
#[context] ctx: RpcContext,
|
||||
#[allow(unused_variables)]
|
||||
@@ -347,7 +347,7 @@ pub async fn get(
|
||||
}
|
||||
|
||||
#[command(rename = "get", display(display_wifi_list))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_available(
|
||||
#[context] ctx: RpcContext,
|
||||
#[allow(unused_variables)]
|
||||
@@ -457,7 +457,7 @@ impl WpaCli {
|
||||
WpaCli { interface }
|
||||
}
|
||||
|
||||
#[instrument(skip(self, psk))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn set_add_network_low(&mut self, ssid: &Ssid, psk: &Psk) -> Result<(), Error> {
|
||||
let _ = Command::new("nmcli")
|
||||
.arg("-a")
|
||||
@@ -473,7 +473,7 @@ impl WpaCli {
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
#[instrument(skip(self, psk))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn add_network_low(&mut self, ssid: &Ssid, psk: &Psk) -> Result<(), Error> {
|
||||
if self.find_networks(ssid).await?.is_empty() {
|
||||
Command::new("nmcli")
|
||||
@@ -567,7 +567,7 @@ impl WpaCli {
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn list_networks_low(&self) -> Result<BTreeMap<NetworkId, WifiInfo>, Error> {
|
||||
let r = Command::new("nmcli")
|
||||
.arg("-t")
|
||||
@@ -596,7 +596,7 @@ impl WpaCli {
|
||||
.collect::<BTreeMap<NetworkId, WifiInfo>>())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn list_wifi_low(&self) -> Result<WifiList, Error> {
|
||||
let r = Command::new("nmcli")
|
||||
.arg("-g")
|
||||
@@ -681,7 +681,7 @@ impl WpaCli {
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
#[instrument(skip(db))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn select_network(&mut self, db: impl DbHandle, ssid: &Ssid) -> Result<bool, Error> {
|
||||
let m_id = self.check_active_network(ssid).await?;
|
||||
match m_id {
|
||||
@@ -717,7 +717,7 @@ impl WpaCli {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_current_network(&self) -> Result<Option<Ssid>, Error> {
|
||||
let r = Command::new("iwgetid")
|
||||
.arg(&self.interface)
|
||||
@@ -733,7 +733,7 @@ impl WpaCli {
|
||||
Ok(Some(Ssid(network.to_owned())))
|
||||
}
|
||||
}
|
||||
#[instrument(skip(db))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn remove_network(&mut self, db: impl DbHandle, ssid: &Ssid) -> Result<bool, Error> {
|
||||
let found_networks = self.find_networks(ssid).await?;
|
||||
if found_networks.is_empty() {
|
||||
@@ -745,7 +745,7 @@ impl WpaCli {
|
||||
self.save_config(db).await?;
|
||||
Ok(true)
|
||||
}
|
||||
#[instrument(skip(psk, db))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn set_add_network(
|
||||
&mut self,
|
||||
db: impl DbHandle,
|
||||
@@ -757,7 +757,7 @@ impl WpaCli {
|
||||
self.save_config(db).await?;
|
||||
Ok(())
|
||||
}
|
||||
#[instrument(skip(psk, db))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn add_network(
|
||||
&mut self,
|
||||
db: impl DbHandle,
|
||||
@@ -771,7 +771,7 @@ impl WpaCli {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn interface_connected(interface: &str) -> Result<bool, Error> {
|
||||
let out = Command::new("ifconfig")
|
||||
.arg(interface)
|
||||
@@ -792,7 +792,7 @@ pub fn country_code_parse(code: &str, _matches: &ArgMatches) -> Result<CountryCo
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(main_datadir))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn synchronize_wpa_supplicant_conf<P: AsRef<Path>>(
|
||||
main_datadir: P,
|
||||
wifi_iface: &str,
|
||||
|
||||
@@ -23,7 +23,7 @@ pub async fn notification() -> Result<(), Error> {
|
||||
}
|
||||
|
||||
#[command(display(display_serializable))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn list(
|
||||
#[context] ctx: RpcContext,
|
||||
#[arg] before: Option<i32>,
|
||||
@@ -232,7 +232,7 @@ impl NotificationManager {
|
||||
cache: Mutex::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
#[instrument(skip(self, db))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn notify<Db: DbHandle, T: NotificationType>(
|
||||
&self,
|
||||
db: &mut Db,
|
||||
|
||||
@@ -75,7 +75,7 @@ impl DockerContainer {
|
||||
/// Idea is that we are going to send it command and get the inputs be filtered back from the manager.
|
||||
/// Then we could in theory run commands without the cost of running the docker exec which is known to have
|
||||
/// a dely of > 200ms which is not acceptable.
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn long_running_execute(
|
||||
&self,
|
||||
ctx: &RpcContext,
|
||||
@@ -212,7 +212,7 @@ impl DockerProcedure {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, input))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn execute<I: Serialize, O: DeserializeOwned>(
|
||||
&self,
|
||||
ctx: &RpcContext,
|
||||
@@ -226,7 +226,6 @@ impl DockerProcedure {
|
||||
let name = name.docker_name();
|
||||
let name: Option<&str> = name.as_ref().map(|x| &**x);
|
||||
let mut cmd = tokio::process::Command::new("docker");
|
||||
tracing::debug!("{:?} is run", name);
|
||||
let container_name = Self::container_name(pkg_id, name);
|
||||
cmd.arg("run")
|
||||
.arg("--rm")
|
||||
@@ -393,7 +392,7 @@ impl DockerProcedure {
|
||||
)
|
||||
}
|
||||
|
||||
#[instrument(skip(_ctx, input))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn inject<I: Serialize, O: DeserializeOwned>(
|
||||
&self,
|
||||
_ctx: &RpcContext,
|
||||
@@ -408,7 +407,6 @@ impl DockerProcedure {
|
||||
let name: Option<&str> = name.as_deref();
|
||||
let mut cmd = tokio::process::Command::new("docker");
|
||||
|
||||
tracing::debug!("{:?} is exec", name);
|
||||
cmd.arg("exec");
|
||||
|
||||
cmd.args(self.docker_args_inject(pkg_id).await?);
|
||||
@@ -548,7 +546,7 @@ impl DockerProcedure {
|
||||
)
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, input))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn sandboxed<I: Serialize, O: DeserializeOwned>(
|
||||
&self,
|
||||
ctx: &RpcContext,
|
||||
|
||||
@@ -57,7 +57,7 @@ impl JsProcedure {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(directory, input, rpc_client))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn execute<I: Serialize, O: DeserializeOwned>(
|
||||
&self,
|
||||
directory: &PathBuf,
|
||||
@@ -111,7 +111,7 @@ impl JsProcedure {
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, input))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn sandboxed<I: Serialize, O: DeserializeOwned>(
|
||||
&self,
|
||||
ctx: &RpcContext,
|
||||
|
||||
@@ -40,7 +40,7 @@ impl PackageProcedure {
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub fn validate(
|
||||
&self,
|
||||
container: &Option<DockerContainers>,
|
||||
@@ -58,7 +58,7 @@ impl PackageProcedure {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, input))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn execute<I: Serialize, O: DeserializeOwned + 'static>(
|
||||
&self,
|
||||
ctx: &RpcContext,
|
||||
@@ -121,7 +121,7 @@ impl PackageProcedure {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, input))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn sandboxed<I: Serialize, O: DeserializeOwned>(
|
||||
&self,
|
||||
container: &Option<DockerContainers>,
|
||||
|
||||
@@ -18,7 +18,7 @@ pub async fn properties(#[context] ctx: RpcContext, #[arg] id: PackageId) -> Res
|
||||
Ok(fetch_properties(ctx, id).await?)
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn fetch_properties(ctx: RpcContext, id: PackageId) -> Result<Value, Error> {
|
||||
let mut db = ctx.db.handle();
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ impl<
|
||||
> S9pkPacker<'a, W, RLicense, RInstructions, RIcon, RDockerImages, RAssets, RScripts>
|
||||
{
|
||||
/// BLOCKING
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn pack(mut self, key: &ed25519_dalek::Keypair) -> Result<(), Error> {
|
||||
let header_pos = self.writer.stream_position().await?;
|
||||
if header_pos != 0 {
|
||||
|
||||
@@ -31,7 +31,7 @@ pub mod reader;
|
||||
pub const SIG_CONTEXT: &'static [u8] = b"s9pk";
|
||||
|
||||
#[command(cli_only, display(display_none))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn pack(#[context] ctx: SdkContext, #[arg] path: Option<PathBuf>) -> Result<(), Error> {
|
||||
use tokio::fs::File;
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ pub struct ImageTag {
|
||||
pub version: Version,
|
||||
}
|
||||
impl ImageTag {
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub fn validate(&self, id: &PackageId, version: &Version) -> Result<(), Error> {
|
||||
if id != &self.package_id {
|
||||
return Err(Error::new(
|
||||
@@ -168,7 +168,7 @@ impl<R: AsyncRead + AsyncSeek + Unpin + Send + Sync> S9pkReader<InstallProgressT
|
||||
}
|
||||
}
|
||||
impl<R: AsyncRead + AsyncSeek + Unpin + Send + Sync> S9pkReader<R> {
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn validate(&mut self) -> Result<(), Error> {
|
||||
if self.toc.icon.length > 102_400 {
|
||||
// 100 KiB
|
||||
@@ -286,7 +286,7 @@ impl<R: AsyncRead + AsyncSeek + Unpin + Send + Sync> S9pkReader<R> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn image_tags(&mut self) -> Result<Vec<ImageTag>, Error> {
|
||||
let mut tar = tokio_tar::Archive::new(self.docker_images().await?);
|
||||
let mut entries = tar.entries()?;
|
||||
@@ -314,7 +314,7 @@ impl<R: AsyncRead + AsyncSeek + Unpin + Send + Sync> S9pkReader<R> {
|
||||
crate::ErrorKind::ParseS9pk,
|
||||
))
|
||||
}
|
||||
#[instrument(skip(rdr))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn from_reader(mut rdr: R, check_sig: bool) -> Result<Self, Error> {
|
||||
let header = Header::deserialize(&mut rdr).await?;
|
||||
|
||||
|
||||
@@ -303,7 +303,7 @@ pub async fn execute(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
#[command(rpc_only)]
|
||||
pub async fn complete(#[context] ctx: SetupContext) -> Result<SetupResult, Error> {
|
||||
let (guid, setup_result) = if let Some((guid, setup_result)) = &*ctx.setup_result.read().await {
|
||||
@@ -320,14 +320,14 @@ pub async fn complete(#[context] ctx: SetupContext) -> Result<SetupResult, Error
|
||||
Ok(setup_result)
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
#[command(rpc_only)]
|
||||
pub async fn exit(#[context] ctx: SetupContext) -> Result<(), Error> {
|
||||
ctx.shutdown.send(()).expect("failed to shutdown");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, embassy_password, recovery_password))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn execute_inner(
|
||||
ctx: SetupContext,
|
||||
embassy_logicalname: PathBuf,
|
||||
@@ -380,7 +380,7 @@ async fn fresh_setup(
|
||||
))
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, embassy_password, recovery_password))]
|
||||
#[instrument(skip_all)]
|
||||
async fn recover(
|
||||
ctx: SetupContext,
|
||||
guid: Arc<String>,
|
||||
@@ -399,7 +399,7 @@ async fn recover(
|
||||
.await
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, embassy_password))]
|
||||
#[instrument(skip_all)]
|
||||
async fn migrate(
|
||||
ctx: SetupContext,
|
||||
guid: Arc<String>,
|
||||
@@ -429,6 +429,7 @@ async fn migrate(
|
||||
ignore_existing: false,
|
||||
exclude: Vec::new(),
|
||||
no_permissions: false,
|
||||
no_owner: false,
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
@@ -441,6 +442,7 @@ async fn migrate(
|
||||
ignore_existing: false,
|
||||
exclude: vec!["tmp".to_owned()],
|
||||
no_permissions: false,
|
||||
no_owner: false,
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -21,19 +21,19 @@ struct SoundInterface {
|
||||
guard: Option<FileLock>,
|
||||
}
|
||||
impl SoundInterface {
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn lease() -> Result<Self, Error> {
|
||||
let guard = FileLock::new(SOUND_LOCK_FILE, true).await?;
|
||||
Ok(SoundInterface { guard: Some(guard) })
|
||||
}
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn close(mut self) -> Result<(), Error> {
|
||||
if let Some(lock) = self.guard.take() {
|
||||
lock.unlock().await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn play_for_time_slice(
|
||||
&mut self,
|
||||
tempo_qpm: u16,
|
||||
@@ -59,7 +59,7 @@ impl<'a, T> Song<T>
|
||||
where
|
||||
T: IntoIterator<Item = (Option<Note>, TimeSlice)> + Clone,
|
||||
{
|
||||
#[instrument(skip(self))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn play(&self) -> Result<(), Error> {
|
||||
let mut sound = SoundInterface::lease().await?;
|
||||
for (note, slice) in self.note_sequence.clone() {
|
||||
|
||||
@@ -57,7 +57,7 @@ pub fn ssh() -> Result<(), Error> {
|
||||
}
|
||||
|
||||
#[command(display(display_none))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn add(#[context] ctx: RpcContext, #[arg] key: PubKey) -> Result<SshKeyResponse, Error> {
|
||||
let pool = &ctx.secret_store;
|
||||
// check fingerprint for duplicates
|
||||
@@ -92,7 +92,7 @@ pub async fn add(#[context] ctx: RpcContext, #[arg] key: PubKey) -> Result<SshKe
|
||||
}
|
||||
}
|
||||
#[command(display(display_none))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn delete(#[context] ctx: RpcContext, #[arg] fingerprint: String) -> Result<(), Error> {
|
||||
let pool = &ctx.secret_store;
|
||||
// check if fingerprint is in DB
|
||||
@@ -142,7 +142,7 @@ fn display_all_ssh_keys(all: Vec<SshKeyResponse>, matches: &ArgMatches) {
|
||||
}
|
||||
|
||||
#[command(display(display_all_ssh_keys))]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn list(
|
||||
#[context] ctx: RpcContext,
|
||||
#[allow(unused_variables)]
|
||||
@@ -172,7 +172,7 @@ pub async fn list(
|
||||
.collect())
|
||||
}
|
||||
|
||||
#[instrument(skip(pool, dest))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn sync_keys_from_db<P: AsRef<Path>>(
|
||||
pool: &Pool<Postgres>,
|
||||
dest: P,
|
||||
|
||||
@@ -18,7 +18,7 @@ use crate::{Error, ResultExt};
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct HealthChecks(pub BTreeMap<HealthCheckId, HealthCheck>);
|
||||
impl HealthChecks {
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub fn validate(
|
||||
&self,
|
||||
container: &Option<DockerContainers>,
|
||||
@@ -71,7 +71,7 @@ pub struct HealthCheck {
|
||||
pub timeout: Option<Duration>,
|
||||
}
|
||||
impl HealthCheck {
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn check(
|
||||
&self,
|
||||
ctx: &RpcContext,
|
||||
|
||||
@@ -510,7 +510,7 @@ async fn launch_disk_task(
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
async fn get_temp() -> Result<Celsius, Error> {
|
||||
let temp_file = "/sys/class/thermal/thermal_zone0/temp";
|
||||
let milli = tokio::fs::read_to_string(temp_file)
|
||||
@@ -550,7 +550,7 @@ impl ProcStat {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
async fn get_proc_stat() -> Result<ProcStat, Error> {
|
||||
use tokio::io::AsyncBufReadExt;
|
||||
let mut cpu_line = String::new();
|
||||
@@ -592,7 +592,7 @@ async fn get_proc_stat() -> Result<ProcStat, Error> {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
async fn get_cpu_info(last: &mut ProcStat) -> Result<MetricsCpu, Error> {
|
||||
let new = get_proc_stat().await?;
|
||||
let total_old = last.total();
|
||||
@@ -619,7 +619,7 @@ pub struct MemInfo {
|
||||
swap_total: Option<u64>,
|
||||
swap_free: Option<u64>,
|
||||
}
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
async fn get_mem_info() -> Result<MetricsMemory, Error> {
|
||||
let contents = tokio::fs::read_to_string("/proc/meminfo").await?;
|
||||
let mut mem_info = MemInfo {
|
||||
@@ -693,7 +693,7 @@ async fn get_mem_info() -> Result<MetricsMemory, Error> {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
async fn get_disk_info() -> Result<MetricsDisk, Error> {
|
||||
let package_used_task = get_used("/embassy-data/package-data");
|
||||
let package_available_task = get_available("/embassy-data/package-data");
|
||||
|
||||
@@ -41,7 +41,7 @@ lazy_static! {
|
||||
display(display_update_result),
|
||||
metadata(sync_db = true)
|
||||
)]
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn update_system(
|
||||
#[context] ctx: RpcContext,
|
||||
#[arg(rename = "marketplace-url")] marketplace_url: Url,
|
||||
@@ -75,7 +75,7 @@ fn display_update_result(status: UpdateResult, _: &ArgMatches) {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
async fn maybe_do_update(
|
||||
ctx: RpcContext,
|
||||
marketplace_url: Url,
|
||||
@@ -194,7 +194,7 @@ async fn maybe_do_update(
|
||||
Ok(rev)
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx, eos_url))]
|
||||
#[instrument(skip_all)]
|
||||
async fn do_update(ctx: RpcContext, eos_url: EosUrl) -> Result<(), Error> {
|
||||
let mut rsync = Rsync::new(
|
||||
eos_url.rsync_path()?,
|
||||
@@ -306,6 +306,7 @@ async fn sync_boot() -> Result<(), Error> {
|
||||
ignore_existing: false,
|
||||
exclude: Vec::new(),
|
||||
no_permissions: false,
|
||||
no_owner: false,
|
||||
},
|
||||
)
|
||||
.await?
|
||||
@@ -333,7 +334,7 @@ async fn sync_boot() -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
async fn swap_boot_label() -> Result<(), Error> {
|
||||
tokio::fs::write("/media/embassy/config/upgrade", b"").await?;
|
||||
Ok(())
|
||||
|
||||
@@ -282,7 +282,7 @@ impl Drop for FileLock {
|
||||
}
|
||||
}
|
||||
impl FileLock {
|
||||
#[instrument(skip(path))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn new(path: impl AsRef<Path> + Send + Sync, blocking: bool) -> Result<Self, Error> {
|
||||
lazy_static! {
|
||||
static ref INTERNAL_LOCKS: Mutex<BTreeMap<PathBuf, Arc<Mutex<()>>>> =
|
||||
|
||||
@@ -20,8 +20,9 @@ mod v0_3_2;
|
||||
mod v0_3_2_1;
|
||||
mod v0_3_3;
|
||||
mod v0_3_4;
|
||||
mod v0_3_4_1;
|
||||
|
||||
pub type Current = v0_3_4::Version;
|
||||
pub type Current = v0_3_4_1::Version;
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
#[serde(untagged)]
|
||||
@@ -37,6 +38,7 @@ enum Version {
|
||||
V0_3_2_1(Wrapper<v0_3_2_1::Version>),
|
||||
V0_3_3(Wrapper<v0_3_3::Version>),
|
||||
V0_3_4(Wrapper<v0_3_4::Version>),
|
||||
V0_3_4_1(Wrapper<v0_3_4_1::Version>),
|
||||
Other(emver::Version),
|
||||
}
|
||||
|
||||
@@ -63,6 +65,7 @@ impl Version {
|
||||
Version::V0_3_2_1(Wrapper(x)) => x.semver(),
|
||||
Version::V0_3_3(Wrapper(x)) => x.semver(),
|
||||
Version::V0_3_4(Wrapper(x)) => x.semver(),
|
||||
Version::V0_3_4_1(Wrapper(x)) => x.semver(),
|
||||
Version::Other(x) => x.clone(),
|
||||
}
|
||||
}
|
||||
@@ -244,6 +247,10 @@ pub async fn init<Db: DbHandle>(
|
||||
v.0.migrate_to(&Current::new(), db, secrets, receipts)
|
||||
.await?
|
||||
}
|
||||
Version::V0_3_4_1(v) => {
|
||||
v.0.migrate_to(&Current::new(), db, secrets, receipts)
|
||||
.await?
|
||||
}
|
||||
Version::Other(_) => {
|
||||
return Err(Error::new(
|
||||
eyre!("Cannot downgrade"),
|
||||
@@ -287,6 +294,7 @@ mod tests {
|
||||
Just(Version::V0_3_2_1(Wrapper(v0_3_2_1::Version::new()))),
|
||||
Just(Version::V0_3_3(Wrapper(v0_3_3::Version::new()))),
|
||||
Just(Version::V0_3_4(Wrapper(v0_3_4::Version::new()))),
|
||||
Just(Version::V0_3_4_1(Wrapper(v0_3_4_1::Version::new()))),
|
||||
em_version().prop_map(Version::Other),
|
||||
]
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ mod legacy {
|
||||
id.to_string()
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_current_hostname() -> Result<Hostname, Error> {
|
||||
let out = Command::new("hostname")
|
||||
.invoke(ErrorKind::ParseSysInfo)
|
||||
@@ -104,7 +104,7 @@ mod legacy {
|
||||
Ok(Hostname(out_string.trim().to_owned()))
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn set_hostname(hostname: &Hostname) -> Result<(), Error> {
|
||||
let hostname: &String = &hostname.0;
|
||||
let _out = Command::new("hostnamectl")
|
||||
@@ -115,7 +115,7 @@ mod legacy {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(handle))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_id<Db: DbHandle>(handle: &mut Db) -> Result<String, Error> {
|
||||
let id = crate::db::DatabaseModel::new()
|
||||
.server_info()
|
||||
@@ -142,7 +142,7 @@ mod legacy {
|
||||
}
|
||||
return Ok(Hostname(format!("embassy-{}", id)));
|
||||
}
|
||||
#[instrument(skip(handle))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn sync_hostname<Db: DbHandle>(handle: &mut Db) -> Result<(), Error> {
|
||||
set_hostname(&get_hostname(handle).await?).await?;
|
||||
Command::new("systemctl")
|
||||
|
||||
30
backend/src/version/v0_3_4_1.rs
Normal file
30
backend/src/version/v0_3_4_1.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use async_trait::async_trait;
|
||||
use emver::VersionRange;
|
||||
|
||||
use super::v0_3_0::V0_3_0_COMPAT;
|
||||
use super::*;
|
||||
|
||||
const V0_3_4_1: emver::Version = emver::Version::new(0, 3, 4, 1);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Version;
|
||||
|
||||
#[async_trait]
|
||||
impl VersionT for Version {
|
||||
type Previous = v0_3_4::Version;
|
||||
fn new() -> Self {
|
||||
Version
|
||||
}
|
||||
fn semver(&self) -> emver::Version {
|
||||
V0_3_4_1
|
||||
}
|
||||
fn compat(&self) -> &'static VersionRange {
|
||||
&*V0_3_0_COMPAT
|
||||
}
|
||||
async fn up<Db: DbHandle>(&self, _db: &mut Db, _secrets: &PgPool) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
async fn down<Db: DbHandle>(&self, _db: &mut Db, _secrets: &PgPool) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ pub const BACKUP_DIR: &str = "/media/embassy/backups";
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct Volumes(BTreeMap<VolumeId, Volume>);
|
||||
impl Volumes {
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub fn validate(&self, interfaces: &Interfaces) -> Result<(), Error> {
|
||||
for (id, volume) in &self.0 {
|
||||
volume
|
||||
@@ -30,7 +30,7 @@ impl Volumes {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
#[instrument(skip(ctx))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn install(
|
||||
&self,
|
||||
ctx: &RpcContext,
|
||||
@@ -142,7 +142,7 @@ pub enum Volume {
|
||||
Backup { readonly: bool },
|
||||
}
|
||||
impl Volume {
|
||||
#[instrument]
|
||||
#[instrument(skip_all)]
|
||||
pub fn validate(&self, interfaces: &Interfaces) -> Result<(), color_eyre::eyre::Report> {
|
||||
match self {
|
||||
Volume::Certificate { interface_id } => {
|
||||
|
||||
@@ -32,3 +32,4 @@ rsync
|
||||
systemd-timesyncd
|
||||
magic-wormhole
|
||||
nyx
|
||||
bash-completion
|
||||
@@ -13,17 +13,28 @@ mkdir -p /media/embassy/next/run
|
||||
mkdir -p /media/embassy/next/dev
|
||||
mkdir -p /media/embassy/next/sys
|
||||
mkdir -p /media/embassy/next/proc
|
||||
mkdir -p /media/embassy/next/boot
|
||||
mount --bind /run /media/embassy/next/run
|
||||
mount --bind /dev /media/embassy/next/dev
|
||||
mount --bind /sys /media/embassy/next/sys
|
||||
mount --bind /proc /media/embassy/next/proc
|
||||
mount --bind /boot /media/embassy/next/boot
|
||||
|
||||
chroot /media/embassy/next
|
||||
rm /media/embassy/next/usr/local/bin/apt
|
||||
rm /media/embassy/next/usr/local/bin/apt-get
|
||||
rm /media/embassy/next/usr/local/bin/aptitude
|
||||
|
||||
chroot /media/embassy/next $@
|
||||
|
||||
ln -sf /usr/lib/embassy/scripts/fake-apt /media/embassy/next/usr/local/bin/apt
|
||||
ln -sf /usr/lib/embassy/scripts/fake-apt /media/embassy/next/usr/local/bin/apt-get
|
||||
ln -sf /usr/lib/embassy/scripts/fake-apt /media/embassy/next/usr/local/bin/aptitude
|
||||
|
||||
umount /media/embassy/next/run
|
||||
umount /media/embassy/next/dev
|
||||
umount /media/embassy/next/sys
|
||||
umount /media/embassy/next/proc
|
||||
umount /media/embassy/next/boot
|
||||
|
||||
echo 'Upgrading...'
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
set -e
|
||||
|
||||
# install dependencies
|
||||
apt update
|
||||
apt install --no-install-recommends -y xserver-xorg x11-xserver-utils xinit firefox-esr matchbox-window-manager libnss3-tools
|
||||
/usr/bin/apt update
|
||||
/usr/bin/apt install --no-install-recommends -y xserver-xorg x11-xserver-utils xinit firefox-esr matchbox-window-manager libnss3-tools
|
||||
|
||||
# create kiosk script
|
||||
cat > /home/start9/kiosk.sh << 'EOF'
|
||||
|
||||
21
build/lib/scripts/fake-apt
Executable file
21
build/lib/scripts/fake-apt
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
>&2 echo 'THIS IS NOT A STANDARD DEBIAN SYSTEM'
|
||||
>&2 echo 'USING apt COULD CAUSE IRREPARABLE DAMAGE TO YOUR EMBASSY'
|
||||
>&2 echo 'PLEASE TURN BACK NOW!!!'
|
||||
if [ "$1" == "upgrade" ] && [ "$(whoami)" == "root" ]; then
|
||||
>&2 echo 'IF YOU THINK RUNNING "sudo apt upgrade" IS A REASONABLE THING TO DO ON THIS SYSTEM, YOU PROBABLY SHOULDN'"'"'T BE ON THE COMMAND LINE.'
|
||||
>&2 echo 'YOU ARE BEING REMOVED FROM THIS SESSION FOR YOUR OWN SAFETY.'
|
||||
pkill -9 -t $(tty | sed 's|^/dev/||g')
|
||||
fi
|
||||
>&2 echo
|
||||
>&2 echo 'If you are SURE you know what you are doing, and are willing to accept the DIRE CONSEQUENCES of doing so, you can run the following command to disable this protection:'
|
||||
>&2 echo ' sudo rm /usr/local/bin/apt'
|
||||
>&2 echo
|
||||
>&2 echo 'Otherwise, what you probably want to do is run:'
|
||||
>&2 echo ' sudo /usr/lib/embassy/scripts/chroot-and-upgrade'
|
||||
>&2 echo 'You can run apt in this context to add packages to your system.'
|
||||
>&2 echo 'When you are done with your changes, type "exit" and the device will reboot into a system with the changes applied.'
|
||||
>&2 echo 'This is still NOT RECOMMENDED if you don'"'"'t know what you are doing, but at least isn'"'"'t guaranteed to break things.'
|
||||
|
||||
exit 1
|
||||
20
build/lib/scripts/persist-apt-install
Executable file
20
build/lib/scripts/persist-apt-install
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
>&2 echo "usage: $0 <PACKAGE_NAME>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TO_INSTALL=()
|
||||
while [ -n "$1" ]; do
|
||||
if ! dpkg -s "$1"; then
|
||||
TO_INSTALL+=("$1")
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if [ ${#TO_INSTALL[@]} -ne 0 ]; then
|
||||
/usr/lib/embassy/scripts/chroot-and-upgrade << EOF
|
||||
apt-get update && apt-get install -y ${TO_INSTALL[@]}
|
||||
EOF
|
||||
fi
|
||||
@@ -112,3 +112,7 @@ rm -f /etc/motd
|
||||
ln -sf /usr/lib/embassy/motd /etc/update-motd.d/00-embassy
|
||||
chmod -x /etc/update-motd.d/*
|
||||
chmod +x /etc/update-motd.d/00-embassy
|
||||
|
||||
ln -sf /usr/lib/embassy/scripts/fake-apt /usr/local/bin/apt
|
||||
ln -sf /usr/lib/embassy/scripts/fake-apt /usr/local/bin/apt-get
|
||||
ln -sf /usr/lib/embassy/scripts/fake-apt /usr/local/bin/aptitude
|
||||
@@ -11,10 +11,9 @@ cat > /etc/rsyncd.conf << RD
|
||||
uid = root
|
||||
gid = root
|
||||
use chroot = yes
|
||||
max connections = 4
|
||||
max connections = 50
|
||||
pid file = /var/run/rsyncd.pid
|
||||
exclude = lost+found/
|
||||
transfer logging = yes
|
||||
timeout = 900
|
||||
ignore nonreadable = yes
|
||||
dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
|
||||
@@ -35,12 +34,13 @@ do
|
||||
echo "Making new dir $new_dir"
|
||||
mkdir -p $new_dir
|
||||
|
||||
if ! test -n "$(mount -l | grep $new_dir)"
|
||||
then
|
||||
echo "Mounting $filename to $new_dir"
|
||||
mount $filename $new_dir
|
||||
if test -n "$(mount -l | grep $new_dir)"; then
|
||||
umount $new_dir
|
||||
fi
|
||||
|
||||
|
||||
echo "Mounting $filename to $new_dir"
|
||||
mount $filename $new_dir
|
||||
|
||||
cat >> /etc/rsyncd.conf << INSERTING
|
||||
[$version]
|
||||
path = $version_dir
|
||||
|
||||
@@ -35,11 +35,6 @@
|
||||
"glob": "**/*",
|
||||
"input": "node_modules/monaco-editor",
|
||||
"output": "assets/monaco-editor/"
|
||||
},
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "node_modules/@taiga-ui/icons/src",
|
||||
"output": "assets/taiga-ui/icons"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
@@ -160,11 +155,6 @@
|
||||
"glob": "**/*.svg",
|
||||
"input": "node_modules/ionicons/dist/ionicons/svg",
|
||||
"output": "./svg"
|
||||
},
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "node_modules/@taiga-ui/icons/src",
|
||||
"output": "assets/taiga-ui/icons"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
@@ -295,11 +285,6 @@
|
||||
"glob": "**/*.svg",
|
||||
"input": "node_modules/ionicons/dist/ionicons/svg",
|
||||
"output": "./svg"
|
||||
},
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "node_modules/@taiga-ui/icons/src",
|
||||
"output": "assets/taiga-ui/icons"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
@@ -420,11 +405,6 @@
|
||||
"glob": "**/*.svg",
|
||||
"input": "node_modules/ionicons/dist/ionicons/svg",
|
||||
"output": "./svg"
|
||||
},
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "node_modules/@taiga-ui/icons/src",
|
||||
"output": "assets/taiga-ui/icons"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "embassy-os",
|
||||
"version": "0.3.4",
|
||||
"version": "0.3.4.1",
|
||||
"author": "Start9 Labs, Inc",
|
||||
"homepage": "https://start9.com/",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": null,
|
||||
"ack-welcome": "0.3.4",
|
||||
"ack-welcome": "0.3.4.1",
|
||||
"marketplace": {
|
||||
"selected-url": "https://registry.start9.com/",
|
||||
"known-hosts": {
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
[formControlName]="entry.key"
|
||||
(ionFocus)="presentAlertChangeWarning(entry.key, spec)"
|
||||
(ionChange)="handleInputChange()"
|
||||
>
|
||||
</ion-textarea>
|
||||
></ion-textarea>
|
||||
<ng-template #notTextArea>
|
||||
<ion-input
|
||||
type="text"
|
||||
@@ -38,8 +37,7 @@
|
||||
[formControlName]="entry.key"
|
||||
(ionFocus)="presentAlertChangeWarning(entry.key, spec)"
|
||||
(ionChange)="handleInputChange()"
|
||||
>
|
||||
</ion-input>
|
||||
></ion-input>
|
||||
</ng-template>
|
||||
<ion-button
|
||||
*ngIf="spec.type === 'string' && spec.masked"
|
||||
@@ -59,8 +57,9 @@
|
||||
slot="end"
|
||||
color="light"
|
||||
style="font-size: medium"
|
||||
>{{ spec.units }}</ion-note
|
||||
>
|
||||
{{ spec.units }}
|
||||
</ion-note>
|
||||
</ion-item>
|
||||
<p class="error-message">
|
||||
<span *ngIf="(formGroup | getControl: entry.key).errors as errors">
|
||||
@@ -92,11 +91,11 @@
|
||||
*ngIf="original?.[entry.key] === undefined"
|
||||
color="success"
|
||||
>
|
||||
(New)</ion-text
|
||||
>
|
||||
(New)
|
||||
</ion-text>
|
||||
<ion-text *ngIf="entry.value.dirty" color="warning">
|
||||
(Edited)</ion-text
|
||||
>
|
||||
(Edited)
|
||||
</ion-text>
|
||||
</b>
|
||||
</ion-label>
|
||||
<!-- boolean -->
|
||||
@@ -157,14 +156,9 @@
|
||||
></ion-icon>
|
||||
</ion-item-divider>
|
||||
<!-- body -->
|
||||
<div
|
||||
<tui-expand
|
||||
[expanded]="objectDisplay[entry.key].expanded"
|
||||
[id]="objectId | toElementId: entry.key"
|
||||
[ngStyle]="{
|
||||
'max-height': objectDisplay[entry.key].height,
|
||||
overflow: 'hidden',
|
||||
'transition-property': 'max-height',
|
||||
'transition-duration': '.42s'
|
||||
}"
|
||||
>
|
||||
<div class="nested-wrapper">
|
||||
<form-object
|
||||
@@ -172,11 +166,10 @@
|
||||
[formGroup]="$any(entry.value)"
|
||||
[current]="current?.[entry.key]"
|
||||
[original]="original?.[entry.key]"
|
||||
(onResize)="resize(entry.key)"
|
||||
(hasNewOptions)="setHasNew(entry.key)"
|
||||
></form-object>
|
||||
</div>
|
||||
</div>
|
||||
</tui-expand>
|
||||
</ng-container>
|
||||
<!-- union -->
|
||||
<form-union
|
||||
@@ -259,15 +252,10 @@
|
||||
></ion-icon>
|
||||
</ion-item>
|
||||
<!-- object/union body -->
|
||||
<div
|
||||
<tui-expand
|
||||
style="padding-left: 24px"
|
||||
[expanded]="objectListDisplay[entry.key][i].expanded"
|
||||
[id]="objectId | toElementId: entry.key:i"
|
||||
[ngStyle]="{
|
||||
'max-height': objectListDisplay[entry.key][i].height,
|
||||
overflow: 'hidden',
|
||||
'transition-property': 'max-height',
|
||||
'transition-duration': '.42s'
|
||||
}"
|
||||
>
|
||||
<form-object
|
||||
*ngIf="spec.subtype === 'object'"
|
||||
@@ -278,7 +266,6 @@
|
||||
(onInputChange)="
|
||||
updateLabel(entry.key, i, $any(spec.spec)['display-as'])
|
||||
"
|
||||
(onResize)="resize(entry.key, i)"
|
||||
></form-object>
|
||||
<form-union
|
||||
*ngIf="spec.subtype === 'union'"
|
||||
@@ -289,7 +276,6 @@
|
||||
(onInputChange)="
|
||||
updateLabel(entry.key, i, $any(spec.spec)['display-as'])
|
||||
"
|
||||
(onResize)="resize(entry.key, i)"
|
||||
></form-union>
|
||||
<div style="text-align: right; padding-top: 12px">
|
||||
<ion-button
|
||||
@@ -301,7 +287,7 @@
|
||||
Delete
|
||||
</ion-button>
|
||||
</div>
|
||||
</div>
|
||||
</tui-expand>
|
||||
</ng-container>
|
||||
<!-- string or number -->
|
||||
<div
|
||||
@@ -318,8 +304,7 @@
|
||||
$any(spec.spec).placeholder || 'Enter ' + spec.name
|
||||
"
|
||||
[formControlName]="i"
|
||||
>
|
||||
</ion-input>
|
||||
></ion-input>
|
||||
<ion-button
|
||||
strong
|
||||
fill="clear"
|
||||
|
||||
@@ -18,6 +18,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||
import { SharedPipesModule } from '@start9labs/shared'
|
||||
import { TuiElasticContainerModule } from '@taiga-ui/kit'
|
||||
import { EnumListPageModule } from 'src/app/modals/enum-list/enum-list.module'
|
||||
import { TuiExpandModule } from '@taiga-ui/core'
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@@ -39,6 +40,7 @@ import { EnumListPageModule } from 'src/app/modals/enum-list/enum-list.module'
|
||||
SharedPipesModule,
|
||||
EnumListPageModule,
|
||||
TuiElasticContainerModule,
|
||||
TuiExpandModule,
|
||||
],
|
||||
exports: [FormObjectComponent, FormLabelComponent],
|
||||
})
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
ChangeDetectionStrategy,
|
||||
Inject,
|
||||
inject,
|
||||
SimpleChanges,
|
||||
} from '@angular/core'
|
||||
import { FormArray, UntypedFormArray, UntypedFormGroup } from '@angular/forms'
|
||||
import { AlertButton, AlertController, ModalController } from '@ionic/angular'
|
||||
@@ -41,15 +42,14 @@ export class FormObjectComponent {
|
||||
@Input() current?: Config
|
||||
@Input() original?: Config
|
||||
@Output() onInputChange = new EventEmitter<void>()
|
||||
@Output() onResize = new EventEmitter<void>()
|
||||
@Output() hasNewOptions = new EventEmitter<void>()
|
||||
warningAck: { [key: string]: boolean } = {}
|
||||
unmasked: { [key: string]: boolean } = {}
|
||||
objectDisplay: {
|
||||
[key: string]: { expanded: boolean; height: string; hasNewOptions: boolean }
|
||||
[key: string]: { expanded: boolean; hasNewOptions: boolean }
|
||||
} = {}
|
||||
objectListDisplay: {
|
||||
[key: string]: { expanded: boolean; height: string; displayAs: string }[]
|
||||
[key: string]: { expanded: boolean; displayAs: string }[]
|
||||
} = {}
|
||||
objectId = v4()
|
||||
|
||||
@@ -63,6 +63,37 @@ export class FormObjectComponent {
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.setDisplays()
|
||||
|
||||
// setTimeout hack to avoid ExpressionChangedAfterItHasBeenCheckedError
|
||||
setTimeout(() => {
|
||||
if (
|
||||
this.original &&
|
||||
Object.keys(this.current || {}).some(
|
||||
key => this.original![key] === undefined,
|
||||
)
|
||||
)
|
||||
this.hasNewOptions.emit()
|
||||
})
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
const specChanges = changes['objectSpec']
|
||||
|
||||
if (!specChanges) return
|
||||
|
||||
if (
|
||||
!specChanges.firstChange &&
|
||||
Object.keys({
|
||||
...specChanges.previousValue,
|
||||
...specChanges.currentValue,
|
||||
}).length !== Object.keys(specChanges.previousValue).length
|
||||
) {
|
||||
this.setDisplays()
|
||||
}
|
||||
}
|
||||
|
||||
private setDisplays() {
|
||||
Object.keys(this.objectSpec).forEach(key => {
|
||||
const spec = this.objectSpec[key]
|
||||
|
||||
@@ -74,7 +105,6 @@ export class FormObjectComponent {
|
||||
]
|
||||
this.objectListDisplay[key][index] = {
|
||||
expanded: false,
|
||||
height: '0px',
|
||||
displayAs: displayAs
|
||||
? (Mustache as any).render(displayAs, obj)
|
||||
: '',
|
||||
@@ -83,33 +113,10 @@ export class FormObjectComponent {
|
||||
} else if (spec.type === 'object') {
|
||||
this.objectDisplay[key] = {
|
||||
expanded: false,
|
||||
height: '0px',
|
||||
hasNewOptions: false,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// setTimeout hack to avoid ExpressionChangedAfterItHasBeenCheckedError
|
||||
setTimeout(() => {
|
||||
if (this.original) {
|
||||
Object.keys(this.current || {}).forEach(key => {
|
||||
if ((this.original as Config)[key] === undefined) {
|
||||
this.hasNewOptions.emit()
|
||||
}
|
||||
})
|
||||
}
|
||||
}, 10)
|
||||
}
|
||||
|
||||
resize(key: string, i?: number): void {
|
||||
setTimeout(() => {
|
||||
if (i !== undefined) {
|
||||
this.objectListDisplay[key][i].height = this.getScrollHeight(key, i)
|
||||
} else {
|
||||
this.objectDisplay[key].height = this.getScrollHeight(key)
|
||||
}
|
||||
this.onResize.emit()
|
||||
}, 250) // 250 to match transition-duration defined in html, for smooth recursive resize
|
||||
}
|
||||
|
||||
addListItemWrapper<T extends ValueSpec>(
|
||||
@@ -121,20 +128,11 @@ export class FormObjectComponent {
|
||||
|
||||
toggleExpandObject(key: string) {
|
||||
this.objectDisplay[key].expanded = !this.objectDisplay[key].expanded
|
||||
this.objectDisplay[key].height = this.objectDisplay[key].expanded
|
||||
? this.getScrollHeight(key)
|
||||
: '0px'
|
||||
this.onResize.emit()
|
||||
}
|
||||
|
||||
toggleExpandListObject(key: string, i: number) {
|
||||
this.objectListDisplay[key][i].expanded =
|
||||
!this.objectListDisplay[key][i].expanded
|
||||
this.objectListDisplay[key][i].height = this.objectListDisplay[key][i]
|
||||
.expanded
|
||||
? this.getScrollHeight(key, i)
|
||||
: '0px'
|
||||
this.onResize.emit()
|
||||
}
|
||||
|
||||
updateLabel(key: string, i: number, displayAs: string) {
|
||||
@@ -275,7 +273,6 @@ export class FormObjectComponent {
|
||||
'display-as'
|
||||
]
|
||||
this.objectListDisplay[key].push({
|
||||
height: '0px',
|
||||
expanded: false,
|
||||
displayAs: displayAs ? Mustache.render(displayAs, newItem.value) : '',
|
||||
})
|
||||
@@ -296,8 +293,8 @@ export class FormObjectComponent {
|
||||
}
|
||||
|
||||
private deleteListItem(key: string, index: number, markDirty = true): void {
|
||||
if (this.objectListDisplay[key])
|
||||
this.objectListDisplay[key][index].height = '0px'
|
||||
// if (this.objectListDisplay[key])
|
||||
// this.objectListDisplay[key][index].height = '0px'
|
||||
const arr = this.formGroup.get(key) as UntypedFormArray
|
||||
if (markDirty) arr.markAsDirty()
|
||||
pauseFor(250).then(() => {
|
||||
@@ -328,13 +325,6 @@ export class FormObjectComponent {
|
||||
arr.markAsDirty()
|
||||
}
|
||||
|
||||
private getScrollHeight(key: string, index = 0): string {
|
||||
const element = this.document.getElementById(
|
||||
getElementId(this.objectId, key, index),
|
||||
)
|
||||
return `${element?.scrollHeight}px`
|
||||
}
|
||||
|
||||
asIsOrder() {
|
||||
return 0
|
||||
}
|
||||
@@ -352,8 +342,6 @@ export class FormUnionComponent {
|
||||
@Input() current?: Config
|
||||
@Input() original?: Config
|
||||
|
||||
@Output() onResize = new EventEmitter<void>()
|
||||
|
||||
get unionValue() {
|
||||
return this.formGroup.get(this.spec.tag.id)?.value
|
||||
}
|
||||
@@ -374,10 +362,7 @@ export class FormUnionComponent {
|
||||
|
||||
objectId = v4()
|
||||
|
||||
constructor(
|
||||
private readonly formService: FormService,
|
||||
@Inject(DOCUMENT) private readonly document: Document,
|
||||
) {}
|
||||
constructor(private readonly formService: FormService) {}
|
||||
|
||||
updateUnion(e: any): void {
|
||||
const tagId = this.spec.tag.id
|
||||
@@ -397,12 +382,6 @@ export class FormUnionComponent {
|
||||
this.formGroup.addControl(control, unionGroup.controls[control])
|
||||
})
|
||||
}
|
||||
|
||||
resize(): void {
|
||||
setTimeout(() => {
|
||||
this.onResize.emit()
|
||||
}, 250) // 250 to match transition-duration, defined in html
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
[formGroup]="formGroup"
|
||||
[current]="current"
|
||||
[original]="original"
|
||||
(onResize)="resize()"
|
||||
></form-object>
|
||||
</tui-elastic-container>
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,27 @@
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding">
|
||||
<h2>This release</h2>
|
||||
<h2>This Release</h2>
|
||||
|
||||
<h4>0.3.4.1</h4>
|
||||
<p class="note-padding">
|
||||
View the complete
|
||||
<a
|
||||
href="https://github.com/Start9Labs/embassy-os/releases/tag/v0.3.4.1"
|
||||
target="_blank"
|
||||
noreferrer
|
||||
>
|
||||
release notes
|
||||
</a>
|
||||
for more details.
|
||||
</p>
|
||||
<h6>Highlights</h6>
|
||||
<ul class="spaced-list">
|
||||
<li>0.3.4 bug fixes</li>
|
||||
</ul>
|
||||
|
||||
<h2>Previous Releases</h2>
|
||||
|
||||
<h4>0.3.4</h4>
|
||||
<p class="note-padding">
|
||||
View the complete
|
||||
|
||||
@@ -40,7 +40,10 @@
|
||||
<ion-label>
|
||||
<h1 style="line-height: 1.3">{{ pkg.manifest.title }}</h1>
|
||||
<h2 class="inline">
|
||||
<span>{{ local.manifest.version | displayEmver }}</span>
|
||||
<span>
|
||||
{{ local.installed?.manifest?.version || '' |
|
||||
displayEmver }}
|
||||
</span>
|
||||
|
||||
<ion-icon name="arrow-forward"></ion-icon>
|
||||
|
||||
@@ -92,7 +95,7 @@
|
||||
<ion-button
|
||||
fill="clear"
|
||||
strong
|
||||
(click)="viewInMarketplace($event, local)"
|
||||
(click)="viewInMarketplace($event, host.url, pkg.manifest.id)"
|
||||
>
|
||||
View listing
|
||||
<ion-icon slot="end" name="open-outline"></ion-icon>
|
||||
|
||||
@@ -55,13 +55,11 @@ export class UpdatesPage {
|
||||
private readonly alertCtrl: AlertController,
|
||||
) {}
|
||||
|
||||
viewInMarketplace(event: Event, pkg: PackageDataEntry) {
|
||||
viewInMarketplace(event: Event, url: string, id: string) {
|
||||
event.stopPropagation()
|
||||
const url = pkg.installed?.['marketplace-url']
|
||||
const queryParams = url ? { url } : {}
|
||||
|
||||
this.navCtrl.navigateForward([`marketplace/${pkg.manifest.id}`], {
|
||||
queryParams,
|
||||
this.navCtrl.navigateForward([`marketplace/${id}`], {
|
||||
queryParams: { url },
|
||||
})
|
||||
}
|
||||
|
||||
@@ -161,6 +159,7 @@ export class UpdatesPage {
|
||||
private async update(id: string, version: string, url: string) {
|
||||
try {
|
||||
await this.marketplaceService.installPackage(id, version, url)
|
||||
delete this.marketplaceService.updateQueue[id]
|
||||
} catch (e: any) {
|
||||
delete this.marketplaceService.updateQueue[id]
|
||||
this.marketplaceService.updateErrors[id] = e.message
|
||||
|
||||
@@ -1169,6 +1169,113 @@ export module Mock {
|
||||
} as any // @TODO why is this necessary?
|
||||
|
||||
export const ConfigSpec: RR.GetPackageConfigRes['spec'] = {
|
||||
bitcoin: {
|
||||
type: 'object',
|
||||
name: 'Bitcoin Settings',
|
||||
description:
|
||||
'RPC and P2P interface configuration options for Bitcoin Core',
|
||||
spec: {
|
||||
'bitcoind-p2p': {
|
||||
type: 'union',
|
||||
tag: {
|
||||
id: 'type',
|
||||
name: 'Bitcoin Core P2P',
|
||||
description:
|
||||
'<p>The Bitcoin Core node to connect to over the peer-to-peer (P2P) interface:</p><ul><li><strong>Bitcoin Core</strong>: The Bitcoin Core service installed on this device</li><li><strong>External Node</strong>: A Bitcoin node running on a different device</li></ul>',
|
||||
'variant-names': {
|
||||
internal: 'Bitcoin Core',
|
||||
external: 'External Node',
|
||||
},
|
||||
},
|
||||
default: 'internal',
|
||||
variants: {
|
||||
internal: {},
|
||||
external: {
|
||||
'p2p-host': {
|
||||
type: 'string',
|
||||
name: 'Public Address',
|
||||
description: 'The public address of your Bitcoin Core server',
|
||||
nullable: false,
|
||||
masked: false,
|
||||
copyable: false,
|
||||
},
|
||||
'p2p-port': {
|
||||
type: 'number',
|
||||
name: 'P2P Port',
|
||||
description:
|
||||
'The port that your Bitcoin Core P2P server is bound to',
|
||||
nullable: false,
|
||||
range: '[0,65535]',
|
||||
integral: true,
|
||||
default: 8333,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
advanced: {
|
||||
name: 'Advanced',
|
||||
type: 'object',
|
||||
description: 'Advanced settings',
|
||||
spec: {
|
||||
rpcsettings: {
|
||||
name: 'RPC Settings',
|
||||
type: 'object',
|
||||
description: 'rpc username and password',
|
||||
warning:
|
||||
'Adding RPC users gives them special permissions on your node.',
|
||||
spec: {
|
||||
rpcuser2: {
|
||||
name: 'RPC Username',
|
||||
type: 'string',
|
||||
description: 'rpc username',
|
||||
nullable: false,
|
||||
default: 'defaultrpcusername',
|
||||
pattern: '^[a-zA-Z]+$',
|
||||
'pattern-description': 'must contain only letters.',
|
||||
masked: false,
|
||||
copyable: true,
|
||||
},
|
||||
rpcuser: {
|
||||
name: 'RPC Username',
|
||||
type: 'string',
|
||||
description: 'rpc username',
|
||||
nullable: false,
|
||||
default: 'defaultrpcusername',
|
||||
pattern: '^[a-zA-Z]+$',
|
||||
'pattern-description': 'must contain only letters.',
|
||||
masked: false,
|
||||
copyable: true,
|
||||
},
|
||||
rpcpass: {
|
||||
name: 'RPC User Password',
|
||||
type: 'string',
|
||||
description: 'rpc password',
|
||||
nullable: false,
|
||||
default: {
|
||||
charset: 'a-z,A-Z,2-9',
|
||||
len: 20,
|
||||
},
|
||||
masked: true,
|
||||
copyable: true,
|
||||
},
|
||||
rpcpass2: {
|
||||
name: 'RPC User Password',
|
||||
type: 'string',
|
||||
description: 'rpc password',
|
||||
nullable: false,
|
||||
default: {
|
||||
charset: 'a-z,A-Z,2-9',
|
||||
len: 20,
|
||||
},
|
||||
masked: true,
|
||||
copyable: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
testnet: {
|
||||
name: 'Testnet',
|
||||
type: 'boolean',
|
||||
@@ -1449,6 +1556,29 @@ export module Mock {
|
||||
},
|
||||
},
|
||||
external: {
|
||||
'emergency-contact': {
|
||||
name: 'Emergency Contact',
|
||||
type: 'object',
|
||||
description: 'The person to contact in case of emergency.',
|
||||
spec: {
|
||||
name: {
|
||||
type: 'string',
|
||||
name: 'Name',
|
||||
nullable: false,
|
||||
masked: false,
|
||||
copyable: false,
|
||||
pattern: '^[a-zA-Z]+$',
|
||||
'pattern-description': 'Must contain only letters.',
|
||||
},
|
||||
email: {
|
||||
type: 'string',
|
||||
name: 'Email',
|
||||
nullable: false,
|
||||
masked: false,
|
||||
copyable: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
'public-domain': {
|
||||
name: 'Public Domain',
|
||||
type: 'string',
|
||||
@@ -1520,8 +1650,8 @@ export module Mock {
|
||||
copyable: false,
|
||||
},
|
||||
},
|
||||
advanced: {
|
||||
name: 'Advanced',
|
||||
'more-advanced': {
|
||||
name: 'More Advanced',
|
||||
type: 'object',
|
||||
description: 'Advanced settings',
|
||||
spec: {
|
||||
@@ -1726,8 +1856,7 @@ export module Mock {
|
||||
rulemakers: [],
|
||||
},
|
||||
'bitcoin-node': {
|
||||
type: 'external',
|
||||
'public-domain': 'hello.com',
|
||||
type: 'internal',
|
||||
},
|
||||
port: 20,
|
||||
rpcallowip: undefined,
|
||||
|
||||
@@ -21,13 +21,17 @@ export class ThemeSwitcherService extends BehaviorSubject<string> {
|
||||
.watch$('ui', 'theme')
|
||||
.pipe(take(1), filter(Boolean))
|
||||
.subscribe(theme => {
|
||||
this.next(theme)
|
||||
this.updateTheme(theme)
|
||||
})
|
||||
}
|
||||
|
||||
override next(currentTheme: string): void {
|
||||
this.embassyApi.setDbValue(['theme'], currentTheme)
|
||||
this.windowRef.document.body.setAttribute('data-theme', currentTheme)
|
||||
super.next(currentTheme)
|
||||
override next(theme: string): void {
|
||||
this.embassyApi.setDbValue(['theme'], theme)
|
||||
this.updateTheme(theme)
|
||||
}
|
||||
|
||||
private updateTheme(theme: string): void {
|
||||
this.windowRef.document.body.setAttribute('data-theme', theme)
|
||||
super.next(theme)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ pub struct RsyncOptions {
|
||||
pub exclude: Vec<String>,
|
||||
#[serde(default = "const_true")]
|
||||
pub no_permissions: bool,
|
||||
#[serde(default = "const_true")]
|
||||
pub no_owner: bool,
|
||||
}
|
||||
impl Default for RsyncOptions {
|
||||
fn default() -> Self {
|
||||
@@ -32,6 +34,7 @@ impl Default for RsyncOptions {
|
||||
ignore_existing: false,
|
||||
exclude: Vec::new(),
|
||||
no_permissions: false,
|
||||
no_owner: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,6 +64,9 @@ impl Rsync {
|
||||
if options.no_permissions {
|
||||
cmd.arg("--no-perms");
|
||||
}
|
||||
if options.no_owner {
|
||||
cmd.arg("--no-owner");
|
||||
}
|
||||
for exclude in options.exclude {
|
||||
cmd.arg(format!("--exclude={}", exclude));
|
||||
}
|
||||
|
||||
2
system-images/compat/Cargo.lock
generated
2
system-images/compat/Cargo.lock
generated
@@ -1171,7 +1171,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "embassy-os"
|
||||
version = "0.3.4"
|
||||
version = "0.3.4-rev.1"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"async-compression",
|
||||
|
||||
Reference in New Issue
Block a user