mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
Appmgr/debug/uninstall (#260)
* with context debuggging * appmgr: fix errors * appmgr: add more logging * appmgr: more logs * appmgr: make unbind more robust Co-authored-by: Aiden McClelland <me@drbonez.dev>
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
use std::path::Path;
|
||||
|
||||
use failure::ResultExt as _;
|
||||
use futures::future::try_join_all;
|
||||
|
||||
use crate::util::Invoke;
|
||||
use crate::Error;
|
||||
use crate::ResultExt;
|
||||
use crate::ResultExt as _;
|
||||
|
||||
pub const FSTAB: &'static str = "/etc/fstab";
|
||||
|
||||
@@ -153,6 +154,11 @@ pub async fn bind<P0: AsRef<Path>, P1: AsRef<Path>>(
|
||||
dst: P1,
|
||||
read_only: bool,
|
||||
) -> Result<(), Error> {
|
||||
log::info!(
|
||||
"Binding {} to {}",
|
||||
src.as_ref().display(),
|
||||
dst.as_ref().display()
|
||||
);
|
||||
let is_mountpoint = tokio::process::Command::new("mountpoint")
|
||||
.arg(dst.as_ref())
|
||||
.stdout(std::process::Stdio::null())
|
||||
@@ -185,6 +191,7 @@ pub async fn bind<P0: AsRef<Path>, P1: AsRef<Path>>(
|
||||
}
|
||||
|
||||
pub async fn unmount<P: AsRef<Path>>(mount_point: P) -> Result<(), Error> {
|
||||
log::info!("Unmounting {}.", mount_point.as_ref().display());
|
||||
let umount_output = tokio::process::Command::new("umount")
|
||||
.arg(mount_point.as_ref())
|
||||
.output()
|
||||
@@ -192,10 +199,14 @@ pub async fn unmount<P: AsRef<Path>>(mount_point: P) -> Result<(), Error> {
|
||||
crate::ensure_code!(
|
||||
umount_output.status.success(),
|
||||
crate::error::FILESYSTEM_ERROR,
|
||||
"Error Unmounting Drive: {}",
|
||||
"Error Unmounting Drive: {}: {}",
|
||||
mount_point.as_ref().display(),
|
||||
std::str::from_utf8(&umount_output.stderr).unwrap_or("Unknown Error")
|
||||
);
|
||||
tokio::fs::remove_dir_all(mount_point.as_ref()).await?;
|
||||
tokio::fs::remove_dir_all(mount_point.as_ref())
|
||||
.await
|
||||
.with_context(|e| format!("rm {}: {}", mount_point.as_ref().display(), e))
|
||||
.with_code(crate::error::FILESYSTEM_ERROR)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
use crate::failure::ResultExt;
|
||||
use std::path::Path;
|
||||
|
||||
use linear_map::LinearMap;
|
||||
|
||||
use crate::dependencies::{DependencyError, TaggedDependencyError};
|
||||
use crate::Error;
|
||||
use crate::ResultExt as _;
|
||||
|
||||
pub async fn remove(
|
||||
name: &str,
|
||||
@@ -55,76 +57,79 @@ pub async fn remove(
|
||||
log::info!("Removing tor hidden service.");
|
||||
crate::tor::rm_svc(name).await?;
|
||||
log::info!("Removing app metadata.");
|
||||
tokio::fs::remove_dir_all(Path::new(crate::PERSISTENCE_DIR).join("apps").join(name))
|
||||
.await?;
|
||||
log::info!("Destroying mounted volume.");
|
||||
let metadata_path = Path::new(crate::PERSISTENCE_DIR).join("apps").join(name);
|
||||
tokio::fs::remove_dir_all(&metadata_path)
|
||||
.await
|
||||
.with_context(|e| format!("rm {}: {}", metadata_path.display(), e))
|
||||
.with_code(crate::error::FILESYSTEM_ERROR)?;
|
||||
log::info!("Unbinding shared filesystem.");
|
||||
for (dep, info) in manifest.dependencies.0.iter() {
|
||||
if crate::apps::list_info().await?.contains_key(dep) {
|
||||
let installed_apps = crate::apps::list_info().await?;
|
||||
for (dep, _) in manifest.dependencies.0.iter() {
|
||||
let path = Path::new(crate::VOLUMES)
|
||||
.join(name)
|
||||
.join("start9")
|
||||
.join("public")
|
||||
.join(&dep);
|
||||
if path.exists() {
|
||||
crate::disks::unmount(&path).await?;
|
||||
} else {
|
||||
log::warn!("{} does not exist, skipping...", path.display());
|
||||
}
|
||||
let path = Path::new(crate::VOLUMES)
|
||||
.join(name)
|
||||
.join("start9")
|
||||
.join("shared")
|
||||
.join(&dep);
|
||||
if path.exists() {
|
||||
crate::disks::unmount(&path).await?;
|
||||
} else {
|
||||
log::warn!("{} does not exist, skipping...", path.display());
|
||||
}
|
||||
if installed_apps.contains_key(dep) {
|
||||
let dep_man = crate::apps::manifest(dep).await?;
|
||||
if info.mount_public && dep_man.public.is_some() {
|
||||
let path = Path::new(crate::VOLUMES)
|
||||
.join(name)
|
||||
.join("start9")
|
||||
.join("public")
|
||||
.join(&dep);
|
||||
if let Some(shared) = dep_man.shared {
|
||||
let path = Path::new(crate::VOLUMES).join(dep).join(&shared).join(name);
|
||||
if path.exists() {
|
||||
crate::disks::unmount(&path).await?;
|
||||
}
|
||||
}
|
||||
if info.mount_shared {
|
||||
if let Some(shared) = dep_man.shared {
|
||||
let path = Path::new(crate::VOLUMES)
|
||||
.join(name)
|
||||
.join("start9")
|
||||
.join("shared")
|
||||
.join(&dep);
|
||||
if path.exists() {
|
||||
crate::disks::unmount(&path).await?;
|
||||
}
|
||||
let path = Path::new(crate::VOLUMES).join(dep).join(&shared).join(name);
|
||||
if path.exists() {
|
||||
tokio::fs::remove_dir_all(
|
||||
Path::new(crate::VOLUMES).join(dep).join(&shared).join(name),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
tokio::fs::remove_dir_all(&path)
|
||||
.await
|
||||
.with_context(|e| format!("rm {}: {}", path.display(), e))
|
||||
.with_code(crate::error::FILESYSTEM_ERROR)?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log::warn!("{} is not installed, skipping...", dep);
|
||||
}
|
||||
}
|
||||
if manifest.public.is_some() || manifest.shared.is_some() {
|
||||
for dependent in crate::apps::dependents(&manifest.id, false).await? {
|
||||
if let Some(info) = crate::apps::manifest(&dependent)
|
||||
.await?
|
||||
.dependencies
|
||||
.0
|
||||
.get(&manifest.id)
|
||||
{
|
||||
if info.mount_public && manifest.public.is_some() {
|
||||
let path = Path::new(crate::VOLUMES)
|
||||
.join(name)
|
||||
.join("start9")
|
||||
.join("public")
|
||||
.join(&manifest.id);
|
||||
if path.exists() {
|
||||
crate::disks::unmount(&path).await?;
|
||||
}
|
||||
}
|
||||
if info.mount_shared && manifest.shared.is_some() {
|
||||
let path = Path::new(crate::VOLUMES)
|
||||
.join(name)
|
||||
.join("start9")
|
||||
.join("shared")
|
||||
.join(&manifest.id);
|
||||
if path.exists() {
|
||||
crate::disks::unmount(&path).await?;
|
||||
}
|
||||
}
|
||||
for dependent in crate::apps::dependents(name, false).await? {
|
||||
let path = Path::new(crate::VOLUMES)
|
||||
.join(&dependent)
|
||||
.join("start9")
|
||||
.join("public")
|
||||
.join(name);
|
||||
if path.exists() {
|
||||
crate::disks::unmount(&path).await?;
|
||||
} else {
|
||||
log::warn!("{} does not exist, skipping...", path.display());
|
||||
}
|
||||
let path = Path::new(crate::VOLUMES)
|
||||
.join(dependent)
|
||||
.join("start9")
|
||||
.join("shared")
|
||||
.join(name);
|
||||
if path.exists() {
|
||||
crate::disks::unmount(&path).await?;
|
||||
} else {
|
||||
log::warn!("{} does not exist, skipping...", path.display());
|
||||
}
|
||||
}
|
||||
}
|
||||
tokio::fs::remove_dir_all(Path::new(crate::VOLUMES).join(name)).await?;
|
||||
log::info!("Destroying mounted volume.");
|
||||
let volume_path = Path::new(crate::VOLUMES).join(name);
|
||||
tokio::fs::remove_dir_all(&volume_path)
|
||||
.await
|
||||
.with_context(|e| format!("rm {}: {}", volume_path.display(), e))
|
||||
.with_code(crate::error::FILESYSTEM_ERROR)?;
|
||||
log::info!("Pruning unused docker images.");
|
||||
crate::ensure_code!(
|
||||
std::process::Command::new("docker")
|
||||
|
||||
Reference in New Issue
Block a user