diff --git a/appmgr/src/apps.rs b/appmgr/src/apps.rs index 96a445084..00e6c4dc6 100644 --- a/appmgr/src/apps.rs +++ b/appmgr/src/apps.rs @@ -131,7 +131,7 @@ pub async fn remove(id: &str) -> Result<(), failure::Error> { Ok(()) } -pub async fn status(id: &str) -> Result { +pub async fn status(id: &str, remap_crashed: bool) -> Result { let output = std::process::Command::new("docker") .args(&["inspect", id, "--format", "{{.State.Status}}"]) .stdout(std::process::Stdio::piped()) @@ -155,6 +155,19 @@ pub async fn status(id: &str) -> Result { "restarting" => DockerStatus::Restarting, "removing" => DockerStatus::Removing, "dead" => DockerStatus::Dead, + "exited" + if remap_crashed && { + let path = PersistencePath::from_ref("running.yaml"); + if let Some(mut f) = path.maybe_read(false).await.transpose()? { + let running: Vec = from_yaml_async_reader(&mut *f).await?; + running.iter().filter(|a| a.as_str() == id).next().is_some() + } else { + false + } + } => + { + DockerStatus::Restarting + } "created" | "exited" => DockerStatus::Stopped, "paused" => DockerStatus::Paused, _ => Err(format_err!("unknown status: {}", status))?, @@ -275,7 +288,7 @@ pub async fn info_full( Ok(AppInfoFull { info: info(id).await?, status: if with_status { - Some(status(id).await?) + Some(status(id, true).await?) } else { None }, @@ -379,8 +392,12 @@ pub async fn list( let info = list_info().await?; futures::future::join_all(info.into_iter().map(move |(id, info)| async move { let (status, manifest, config, dependencies) = futures::try_join!( - OptionFuture::from(if with_status { Some(status(&id)) } else { None }) - .map(Option::transpose), + OptionFuture::from(if with_status { + Some(status(&id, true)) + } else { + None + }) + .map(Option::transpose), OptionFuture::from(if with_manifest { Some(manifest(&id)) } else { diff --git a/appmgr/src/backup.rs b/appmgr/src/backup.rs index 52a30c6a9..da6e0380e 100644 --- a/appmgr/src/backup.rs +++ b/appmgr/src/backup.rs @@ -56,7 +56,7 @@ pub async fn create_backup>( f.flush().await?; } - let status = crate::apps::status(app_id).await?; + let status = crate::apps::status(app_id, false).await?; let exclude = if volume_path.is_dir() { let ignore_path = volume_path.join(".backupignore"); if ignore_path.is_file() { @@ -148,7 +148,7 @@ pub async fn restore_backup>( ); } - let status = crate::apps::status(app_id).await?; + let status = crate::apps::status(app_id, false).await?; let running = status.status == crate::apps::DockerStatus::Running; if running { crate::control::stop_app(app_id, true, false).await?; diff --git a/appmgr/src/config/mod.rs b/appmgr/src/config/mod.rs index 67df94f9e..20b41b5a6 100644 --- a/appmgr/src/config/mod.rs +++ b/appmgr/src/config/mod.rs @@ -137,7 +137,9 @@ pub async fn configure( &mut res.stopped, ) .await?; - if crate::apps::status(&dependent).await?.status != crate::apps::DockerStatus::Stopped { + if crate::apps::status(&dependent, false).await?.status + != crate::apps::DockerStatus::Stopped + { crate::control::stop_app(&dependent, false, dry_run).await?; res.stopped.insert( // TODO: maybe don't do this if its not running @@ -283,7 +285,8 @@ pub async fn configure( crate::apps::set_configured(name, true).await?; crate::apps::set_recoverable(name, false).await?; } - if crate::apps::status(name).await?.status != crate::apps::DockerStatus::Stopped { + if crate::apps::status(name, false).await?.status != crate::apps::DockerStatus::Stopped + { if !dry_run { crate::apps::set_needs_restart(name, true).await?; } diff --git a/appmgr/src/control.rs b/appmgr/src/control.rs index f4c1d0381..1a6434e26 100644 --- a/appmgr/src/control.rs +++ b/appmgr/src/control.rs @@ -20,7 +20,7 @@ pub async fn start_app(name: &str, update_metadata: bool) -> Result<(), Error> { true, ) .await?; - let status = crate::apps::status(name).await?.status; + let status = crate::apps::status(name, false).await?.status; if status == crate::apps::DockerStatus::Stopped { if update_metadata { crate::config::configure(name, None, None, false).await?; @@ -111,7 +111,7 @@ pub async fn stop_dependents( ) -> BoxFuture<'a, Result<(), Error>> { async move { for dependent in crate::apps::dependents(name, false).await? { - if crate::apps::status(&dependent).await?.status + if crate::apps::status(&dependent, false).await?.status != crate::apps::DockerStatus::Stopped { stop_dependents_rec(&dependent, dry_run, DependencyError::NotRunning, res) @@ -229,7 +229,7 @@ pub async fn repair_app_status() -> Result<(), Error> { true, ) .await?; - if crate::apps::status(&name).await?.status == crate::apps::DockerStatus::Stopped { + if crate::apps::status(&name, false).await?.status == crate::apps::DockerStatus::Stopped { start_app(&name, true).await?; } crate::util::unlock(lock).await?; diff --git a/appmgr/src/dependencies.rs b/appmgr/src/dependencies.rs index df7732461..a5ed12d9b 100644 --- a/appmgr/src/dependencies.rs +++ b/appmgr/src/dependencies.rs @@ -115,7 +115,9 @@ impl DepInfo { if !errors.is_empty() { return Ok(Err(DependencyError::ConfigUnsatisfied(errors))); } - if crate::apps::status(dependency_id).await?.status != crate::apps::DockerStatus::Running { + if crate::apps::status(dependency_id, false).await?.status + != crate::apps::DockerStatus::Running + { return Ok(Err(DependencyError::NotRunning)); } Ok(Ok(())) diff --git a/appmgr/src/install.rs b/appmgr/src/install.rs index 192f0d643..df86afb3c 100644 --- a/appmgr/src/install.rs +++ b/appmgr/src/install.rs @@ -561,7 +561,8 @@ pub async fn install_v0( if dep_info.mount_shared && crate::apps::list_info().await?.get(&dep_id).is_some() && crate::apps::manifest(&dep_id).await?.shared.is_some() - && crate::apps::status(&dep_id).await?.status != crate::apps::DockerStatus::Stopped + && crate::apps::status(&dep_id, false).await?.status + != crate::apps::DockerStatus::Stopped { crate::apps::set_needs_restart(&dep_id, true).await?; } diff --git a/appmgr/src/update.rs b/appmgr/src/update.rs index 1b8ab598c..9b60111d3 100644 --- a/appmgr/src/update.rs +++ b/appmgr/src/update.rs @@ -19,7 +19,9 @@ pub async fn update( let version = crate::registry::version(name, &version_req).await?; let mut res = LinearMap::new(); for dependent in crate::apps::dependents(name, false).await? { - if crate::apps::status(&dependent).await?.status != crate::apps::DockerStatus::Stopped { + if crate::apps::status(&dependent, false).await?.status + != crate::apps::DockerStatus::Stopped + { let manifest = crate::apps::manifest(&dependent).await?; match manifest.dependencies.0.get(name) { Some(dep) if !version.satisfies(&dep.version) => { @@ -30,7 +32,8 @@ pub async fn update( &mut res, ) .await?; - if crate::apps::status(name).await?.status != crate::apps::DockerStatus::Stopped + if crate::apps::status(name, false).await?.status + != crate::apps::DockerStatus::Stopped { crate::control::stop_app(&dependent, false, dry_run).await?; res.insert( @@ -53,7 +56,8 @@ pub async fn update( &mut res, ) .await?; - if crate::apps::status(name).await?.status != crate::apps::DockerStatus::Stopped + if crate::apps::status(name, false).await?.status + != crate::apps::DockerStatus::Stopped { crate::control::stop_app(&dependent, false, dry_run).await?; res.insert(