Files
start-os/appmgr/src/control.rs
Aiden McClelland 4e9849cd38 refactor dependency errors (#574)
* refactor dependency errors

* fix hostname after restart

* fix errors from testing

* fix updating of current_dependents

* fixes
2022-01-21 20:35:52 -07:00

133 lines
3.5 KiB
Rust

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::dependencies::{
break_all_dependents_transitive, heal_all_dependents_transitive, BreakageRes, DependencyError,
TaggedDependencyError,
};
use crate::s9pk::manifest::PackageId;
use crate::status::MainStatus;
use crate::util::{display_none, display_serializable};
use crate::{Error, ResultExt};
#[command(display(display_none))]
pub async fn start(
#[context] ctx: RpcContext,
#[arg] id: PackageId,
) -> Result<WithRevision<()>, 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.clone(), version))
.await
.ok_or_else(|| {
Error::new(anyhow!("Manager not found"), crate::ErrorKind::Docker)
})?,
)
.await?;
status.save(&mut tx).await?;
heal_all_dependents_transitive(&ctx, &mut tx, &id).await?;
Ok(WithRevision {
revision: tx.commit(None).await?,
response: (),
})
}
async fn stop_common<Db: DbHandle>(
db: &mut Db,
id: &PackageId,
breakages: &mut BTreeMap<PackageId, TaggedDependencyError>,
) -> Result<(), Error> {
let mut status = crate::db::DatabaseModel::new()
.package_data()
.idx_model(&id)
.and_then(|pkg| pkg.installed())
.expect(db)
.await
.with_ctx(|_| {
(
crate::ErrorKind::NotFound,
format!("{} is not installed", id),
)
})?
.status()
.main()
.get_mut(db)
.await?;
*status = MainStatus::Stopping;
status.save(db).await?;
break_all_dependents_transitive(db, &id, DependencyError::NotRunning, breakages).await?;
Ok(())
}
#[command(subcommands(self(stop_impl(async)), stop_dry), display(display_none))]
pub fn stop(#[arg] id: PackageId) -> Result<PackageId, Error> {
Ok(id)
}
#[command(rename = "dry", display(display_serializable))]
pub async fn stop_dry(
#[context] ctx: RpcContext,
#[parent_data] id: PackageId,
) -> Result<BreakageRes, Error> {
let mut db = ctx.db.handle();
let mut tx = db.begin().await?;
let mut breakages = BTreeMap::new();
stop_common(&mut tx, &id, &mut breakages).await?;
Ok(BreakageRes {
breakages,
patch: tx.abort().await?,
})
}
pub async fn stop_impl(ctx: RpcContext, id: PackageId) -> Result<WithRevision<()>, Error> {
let mut db = ctx.db.handle();
let mut tx = db.begin().await?;
stop_common(&mut tx, &id, &mut BTreeMap::new()).await?;
Ok(WithRevision {
revision: tx.commit(None).await?,
response: (),
})
}