mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 04:01:58 +00:00
stop service if critical task activated (#2966)
filter out union lists instead of erroring
This commit is contained in:
@@ -24,6 +24,7 @@ use super::setup::CURRENT_SECRET;
|
||||
use crate::account::AccountInfo;
|
||||
use crate::auth::Sessions;
|
||||
use crate::context::config::ServerConfig;
|
||||
use crate::db::model::package::TaskSeverity;
|
||||
use crate::db::model::Database;
|
||||
use crate::disk::OsPartitionInfo;
|
||||
use crate::init::{check_time_is_synchronized, InitResult};
|
||||
@@ -403,21 +404,46 @@ impl RpcContext {
|
||||
}
|
||||
}
|
||||
}
|
||||
self.db
|
||||
.mutate(|db| {
|
||||
for (package_id, action_input) in &action_input {
|
||||
for (action_id, input) in action_input {
|
||||
for (_, pde) in db.as_public_mut().as_package_data_mut().as_entries_mut()? {
|
||||
pde.as_tasks_mut().mutate(|tasks| {
|
||||
Ok(update_tasks(tasks, package_id, action_id, input, false))
|
||||
})?;
|
||||
for id in
|
||||
self.db
|
||||
.mutate::<Vec<PackageId>>(|db| {
|
||||
for (package_id, action_input) in &action_input {
|
||||
for (action_id, input) in action_input {
|
||||
for (_, pde) in
|
||||
db.as_public_mut().as_package_data_mut().as_entries_mut()?
|
||||
{
|
||||
pde.as_tasks_mut().mutate(|tasks| {
|
||||
Ok(update_tasks(tasks, package_id, action_id, input, false))
|
||||
})?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.await
|
||||
.result?;
|
||||
db.as_public()
|
||||
.as_package_data()
|
||||
.as_entries()?
|
||||
.into_iter()
|
||||
.filter_map(|(id, pkg)| {
|
||||
(|| {
|
||||
if pkg.as_tasks().de()?.into_iter().any(|(_, t)| {
|
||||
t.active && t.task.severity == TaskSeverity::Critical
|
||||
}) {
|
||||
Ok(Some(id))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
})()
|
||||
.transpose()
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.await
|
||||
.result?
|
||||
{
|
||||
let svc = self.services.get(&id).await;
|
||||
if let Some(svc) = &*svc {
|
||||
svc.stop(procedure_id.clone(), false).await?;
|
||||
}
|
||||
}
|
||||
check_tasks.complete();
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -6,7 +6,7 @@ use models::{ActionId, PackageId, ProcedureName, ReplayId};
|
||||
|
||||
use crate::action::{ActionInput, ActionResult};
|
||||
use crate::db::model::package::{
|
||||
ActionVisibility, AllowedStatuses, TaskCondition, TaskEntry, TaskInput,
|
||||
ActionVisibility, AllowedStatuses, TaskCondition, TaskEntry, TaskInput, TaskSeverity,
|
||||
};
|
||||
use crate::prelude::*;
|
||||
use crate::rpc_continuations::Guid;
|
||||
@@ -78,7 +78,8 @@ pub fn update_tasks(
|
||||
action_id: &ActionId,
|
||||
input: &Value,
|
||||
was_run: bool,
|
||||
) {
|
||||
) -> bool {
|
||||
let mut critical_activated = false;
|
||||
tasks.retain(|_, v| {
|
||||
if &v.task.package_id != package_id || &v.task.action_id != action_id {
|
||||
return true;
|
||||
@@ -95,6 +96,9 @@ pub fn update_tasks(
|
||||
}
|
||||
} else {
|
||||
v.active = true;
|
||||
if v.task.severity == TaskSeverity::Critical {
|
||||
critical_activated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
@@ -106,7 +110,8 @@ pub fn update_tasks(
|
||||
} else {
|
||||
!was_run
|
||||
}
|
||||
})
|
||||
});
|
||||
critical_activated
|
||||
}
|
||||
|
||||
pub(super) struct RunAction {
|
||||
@@ -125,7 +130,7 @@ impl Handler<RunAction> for ServiceActor {
|
||||
id: ref action_id,
|
||||
input,
|
||||
}: RunAction,
|
||||
_: &BackgroundJobQueue,
|
||||
jobs: &BackgroundJobQueue,
|
||||
) -> Self::Response {
|
||||
let container = &self.0.persistent_container;
|
||||
let package_id = &self.0.id;
|
||||
@@ -162,7 +167,7 @@ impl Handler<RunAction> for ServiceActor {
|
||||
}
|
||||
let result = container
|
||||
.execute::<Option<ActionResult>>(
|
||||
id,
|
||||
id.clone(),
|
||||
ProcedureName::RunAction(action_id.clone()),
|
||||
json!({
|
||||
"input": input,
|
||||
@@ -171,19 +176,30 @@ impl Handler<RunAction> for ServiceActor {
|
||||
)
|
||||
.await
|
||||
.with_kind(ErrorKind::Action)?;
|
||||
self.0
|
||||
if self
|
||||
.0
|
||||
.ctx
|
||||
.db
|
||||
.mutate(|db| {
|
||||
let mut critical_activated = false;
|
||||
for (_, pde) in db.as_public_mut().as_package_data_mut().as_entries_mut()? {
|
||||
pde.as_tasks_mut().mutate(|tasks| {
|
||||
critical_activated |= pde.as_tasks_mut().mutate(|tasks| {
|
||||
Ok(update_tasks(tasks, package_id, action_id, &input, true))
|
||||
})?;
|
||||
}
|
||||
Ok(())
|
||||
Ok(critical_activated)
|
||||
})
|
||||
.await
|
||||
.result?;
|
||||
.result?
|
||||
{
|
||||
<Self as Handler<super::control::Stop>>::handle(
|
||||
self,
|
||||
id,
|
||||
super::control::Stop { wait: false },
|
||||
jobs,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ impl Service {
|
||||
}
|
||||
}
|
||||
|
||||
struct Stop {
|
||||
wait: bool,
|
||||
pub(super) struct Stop {
|
||||
pub wait: bool,
|
||||
}
|
||||
impl Handler<Stop> for ServiceActor {
|
||||
type Response = ();
|
||||
|
||||
@@ -35,7 +35,7 @@ use url::Url;
|
||||
use crate::context::{CliContext, RpcContext};
|
||||
use crate::db::model::package::{
|
||||
InstalledState, ManifestPreference, PackageDataEntry, PackageState, PackageStateMatchModelRef,
|
||||
UpdatingState,
|
||||
TaskSeverity, UpdatingState,
|
||||
};
|
||||
use crate::disk::mount::filesystem::ReadOnly;
|
||||
use crate::disk::mount::guard::{GenericMountGuard, MountGuard};
|
||||
@@ -526,7 +526,8 @@ impl Service {
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx.db
|
||||
let has_critical = ctx
|
||||
.db
|
||||
.mutate(|db| {
|
||||
for (action_id, input) in &action_input {
|
||||
for (_, pde) in db.as_public_mut().as_package_data_mut().as_entries_mut()? {
|
||||
@@ -541,10 +542,12 @@ impl Service {
|
||||
.as_idx_mut(&manifest.id)
|
||||
.or_not_found(&manifest.id)?;
|
||||
let actions = entry.as_actions().keys()?;
|
||||
entry.as_tasks_mut().mutate(|t| {
|
||||
Ok(t.retain(|_, v| {
|
||||
let has_critical = entry.as_tasks_mut().mutate(|t| {
|
||||
t.retain(|_, v| {
|
||||
v.task.package_id != manifest.id || actions.contains(&v.task.action_id)
|
||||
}))
|
||||
});
|
||||
Ok(t.iter()
|
||||
.any(|(_, t)| t.active && t.task.severity == TaskSeverity::Critical))
|
||||
})?;
|
||||
entry
|
||||
.as_state_info_mut()
|
||||
@@ -553,11 +556,15 @@ impl Service {
|
||||
entry.as_icon_mut().ser(&icon)?;
|
||||
entry.as_registry_mut().ser(registry)?;
|
||||
|
||||
Ok(())
|
||||
Ok(has_critical)
|
||||
})
|
||||
.await
|
||||
.result?;
|
||||
|
||||
if prev_state == Some(StartStop::Start) && !has_critical {
|
||||
service.start(procedure_id).await?;
|
||||
}
|
||||
|
||||
Ok(service)
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ use crate::prelude::*;
|
||||
use crate::progress::{
|
||||
FullProgressTracker, PhaseProgressTrackerHandle, ProgressTrackerWriter, ProgressUnits,
|
||||
};
|
||||
use crate::rpc_continuations::Guid;
|
||||
use crate::s9pk::manifest::PackageId;
|
||||
use crate::s9pk::merkle_archive::source::FileSource;
|
||||
use crate::s9pk::S9pk;
|
||||
@@ -344,9 +343,6 @@ impl ServiceMap {
|
||||
}),
|
||||
)
|
||||
.await?;
|
||||
if prev == Some(StartStop::Start) {
|
||||
new_service.start(Guid::new()).await?;
|
||||
}
|
||||
*service = Some(new_service.into());
|
||||
drop(service);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user