use std::collections::BTreeMap; use anyhow::anyhow; use chrono::Utc; use patch_db::DbHandle; use rpc_toolkit::command; use crate::context::RpcContext; use crate::db::util::WithRevision; use crate::s9pk::manifest::PackageId; use crate::status::MainStatus; use crate::util::display_none; use crate::{Error, ResultExt}; #[command(display(display_none))] pub async fn start( #[context] ctx: RpcContext, #[arg] id: PackageId, ) -> Result, Error> { let mut db = ctx.db.handle(); let mut tx = db.begin().await?; let installed = crate::db::DatabaseModel::new() .package_data() .idx_model(&id) .and_then(|pkg| pkg.installed()) .expect(&mut tx) .await .with_ctx(|_| { ( crate::ErrorKind::NotFound, format!("{} is not installed", id), ) })?; let version = installed .clone() .manifest() .version() .get(&mut tx, true) .await? .to_owned(); let mut status = installed.status().main().get_mut(&mut tx).await?; *status = MainStatus::Running { started: Utc::now(), health: BTreeMap::new(), }; status .synchronize( &*ctx.managers.get(&(id, version)).await.ok_or_else(|| { Error::new(anyhow!("Manager not found"), crate::ErrorKind::Docker) })?, ) .await?; status.save(&mut tx).await?; Ok(WithRevision { revision: tx.commit(None).await?, response: (), }) } #[command(display(display_none))] pub async fn stop( #[context] ctx: RpcContext, #[arg] id: PackageId, ) -> Result, Error> { let mut db = ctx.db.handle(); let mut tx = db.begin().await?; let mut status = crate::db::DatabaseModel::new() .package_data() .idx_model(&id) .and_then(|pkg| pkg.installed()) .expect(&mut tx) .await .with_ctx(|_| { ( crate::ErrorKind::NotFound, format!("{} is not installed", id), ) })? .status() .main() .get_mut(&mut tx) .await?; *status = MainStatus::Stopping; status.save(&mut tx).await?; Ok(WithRevision { revision: tx.commit(None).await?, response: (), }) }