Rename EtcTree -> FileTree.

This commit is contained in:
r-vdp 2023-04-13 12:07:09 +02:00
parent a642fe94dd
commit af853c014c
No known key found for this signature in database
5 changed files with 85 additions and 79 deletions

View file

@ -8,7 +8,7 @@ use std::path::{Path, PathBuf};
use std::{fs, io, process}; use std::{fs, io, process};
use thiserror::Error; use thiserror::Error;
use crate::activate::etc_files::EtcTree; use crate::activate::etc_files::FileTree;
use crate::{StorePath, STATE_FILE_NAME, SYSTEM_MANAGER_STATE_DIR}; use crate::{StorePath, STATE_FILE_NAME, SYSTEM_MANAGER_STATE_DIR};
#[derive(Error, Debug)] #[derive(Error, Debug)]
@ -34,7 +34,7 @@ pub type ActivationResult<R> = Result<R, ActivationError<R>>;
#[derive(Debug, Clone, Default, Serialize, Deserialize)] #[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct State { pub struct State {
etc_tree: EtcTree, file_tree: FileTree,
services: services::Services, services: services::Services,
} }
@ -78,15 +78,18 @@ pub fn activate(store_path: &StorePath, ephemeral: bool) -> Result<()> {
log::info!("Activating etc files..."); log::info!("Activating etc files...");
match etc_files::activate(store_path, old_state.etc_tree, ephemeral) { match etc_files::activate(store_path, old_state.file_tree, ephemeral) {
Ok(etc_tree) => { Ok(etc_tree) => {
log::info!("Activating systemd services..."); log::info!("Activating systemd services...");
match services::activate(store_path, old_state.services, ephemeral) { match services::activate(store_path, old_state.services, ephemeral) {
Ok(services) => State { etc_tree, services }, Ok(services) => State {
file_tree: etc_tree,
services,
},
Err(ActivationError::WithPartialResult { result, source }) => { Err(ActivationError::WithPartialResult { result, source }) => {
log::error!("Error during activation: {source:?}"); log::error!("Error during activation: {source:?}");
State { State {
etc_tree, file_tree: etc_tree,
services: result, services: result,
} }
} }
@ -95,7 +98,7 @@ pub fn activate(store_path: &StorePath, ephemeral: bool) -> Result<()> {
Err(ActivationError::WithPartialResult { result, source }) => { Err(ActivationError::WithPartialResult { result, source }) => {
log::error!("Error during activation: {source:?}"); log::error!("Error during activation: {source:?}");
State { State {
etc_tree: result, file_tree: result,
..old_state ..old_state
} }
} }
@ -111,15 +114,18 @@ pub fn deactivate() -> Result<()> {
let old_state = State::from_file(state_file)?; let old_state = State::from_file(state_file)?;
log::debug!("{old_state:?}"); log::debug!("{old_state:?}");
match etc_files::deactivate(old_state.etc_tree) { match etc_files::deactivate(old_state.file_tree) {
Ok(etc_tree) => { Ok(etc_tree) => {
log::info!("Deactivating systemd services..."); log::info!("Deactivating systemd services...");
match services::deactivate(old_state.services) { match services::deactivate(old_state.services) {
Ok(services) => State { etc_tree, services }, Ok(services) => State {
file_tree: etc_tree,
services,
},
Err(ActivationError::WithPartialResult { result, source }) => { Err(ActivationError::WithPartialResult { result, source }) => {
log::error!("Error during deactivation: {source:?}"); log::error!("Error during deactivation: {source:?}");
State { State {
etc_tree, file_tree: etc_tree,
services: result, services: result,
} }
} }
@ -128,7 +134,7 @@ pub fn deactivate() -> Result<()> {
Err(ActivationError::WithPartialResult { result, source }) => { Err(ActivationError::WithPartialResult { result, source }) => {
log::error!("Error during deactivation: {source:?}"); log::error!("Error during deactivation: {source:?}");
State { State {
etc_tree: result, file_tree: result,
..old_state ..old_state
} }
} }

View file

@ -9,7 +9,7 @@ use std::path;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::{fs, io}; use std::{fs, io};
use self::etc_tree::EtcFileStatus; use self::etc_tree::FileStatus;
use super::ActivationResult; use super::ActivationResult;
use crate::activate::ActivationError; use crate::activate::ActivationError;
use crate::{ use crate::{
@ -17,9 +17,9 @@ use crate::{
SYSTEM_MANAGER_STATIC_NAME, SYSTEM_MANAGER_STATIC_NAME,
}; };
pub use etc_tree::EtcTree; pub use etc_tree::FileTree;
type EtcActivationResult = ActivationResult<EtcTree>; type EtcActivationResult = ActivationResult<FileTree>;
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
@ -81,7 +81,7 @@ fn read_config(store_path: &StorePath) -> anyhow::Result<EtcFilesConfig> {
pub fn activate( pub fn activate(
store_path: &StorePath, store_path: &StorePath,
old_state: EtcTree, old_state: FileTree,
ephemeral: bool, ephemeral: bool,
) -> EtcActivationResult { ) -> EtcActivationResult {
let config = read_config(store_path) let config = read_config(store_path)
@ -90,7 +90,7 @@ pub fn activate(
let etc_dir = etc_dir(ephemeral); let etc_dir = etc_dir(ephemeral);
log::info!("Creating /etc entries in {}", etc_dir.display()); log::info!("Creating /etc entries in {}", etc_dir.display());
let initial_state = EtcTree::root_node(); let initial_state = FileTree::root_node();
let state = create_etc_static_link( let state = create_etc_static_link(
SYSTEM_MANAGER_STATIC_NAME, SYSTEM_MANAGER_STATIC_NAME,
@ -108,15 +108,15 @@ pub fn activate(
Ok(final_state) Ok(final_state)
} }
pub fn deactivate(old_state: EtcTree) -> EtcActivationResult { pub fn deactivate(old_state: FileTree) -> EtcActivationResult {
let final_state = old_state.deactivate(&try_delete_path).unwrap_or_default(); let final_state = old_state.deactivate(&try_delete_path).unwrap_or_default();
log::info!("Done"); log::info!("Done");
Ok(final_state) Ok(final_state)
} }
fn try_delete_path(path: &Path, status: &EtcFileStatus) -> bool { fn try_delete_path(path: &Path, status: &FileStatus) -> bool {
fn do_try_delete(path: &Path, status: &EtcFileStatus) -> anyhow::Result<()> { fn do_try_delete(path: &Path, status: &FileStatus) -> anyhow::Result<()> {
// exists() returns false for broken symlinks // exists() returns false for broken symlinks
if path.exists() || path.is_symlink() { if path.exists() || path.is_symlink() {
if path.is_symlink() { if path.is_symlink() {
@ -127,7 +127,7 @@ fn try_delete_path(path: &Path, status: &EtcFileStatus) -> bool {
if path.read_dir()?.next().is_none() { if path.read_dir()?.next().is_none() {
remove_dir(path) remove_dir(path)
} else { } else {
if let EtcFileStatus::Managed = status { if let FileStatus::Managed = status {
log::warn!("Managed directory not empty, ignoring: {}", path.display()); log::warn!("Managed directory not empty, ignoring: {}", path.display());
} }
Ok(()) Ok(())
@ -153,9 +153,9 @@ fn try_delete_path(path: &Path, status: &EtcFileStatus) -> bool {
fn create_etc_links<'a, E>( fn create_etc_links<'a, E>(
entries: E, entries: E,
etc_dir: &Path, etc_dir: &Path,
state: EtcTree, state: FileTree,
old_state: &EtcTree, old_state: &FileTree,
) -> EtcTree ) -> FileTree
where where
E: Iterator<Item = &'a EtcFile>, E: Iterator<Item = &'a EtcFile>,
{ {
@ -178,7 +178,7 @@ fn create_etc_static_link(
static_dir_name: &str, static_dir_name: &str,
store_path: &StorePath, store_path: &StorePath,
etc_dir: &Path, etc_dir: &Path,
state: EtcTree, state: FileTree,
) -> EtcActivationResult { ) -> EtcActivationResult {
let static_path = etc_dir.join(static_dir_name); let static_path = etc_dir.join(static_dir_name);
let new_state = create_dir_recursively(static_path.parent().unwrap(), state); let new_state = create_dir_recursively(static_path.parent().unwrap(), state);
@ -193,8 +193,8 @@ fn create_etc_static_link(
fn create_etc_link<P>( fn create_etc_link<P>(
link_target: &P, link_target: &P,
etc_dir: &Path, etc_dir: &Path,
state: EtcTree, state: FileTree,
old_state: &EtcTree, old_state: &FileTree,
) -> EtcActivationResult ) -> EtcActivationResult
where where
P: AsRef<Path>, P: AsRef<Path>,
@ -203,13 +203,13 @@ where
link_target: &Path, link_target: &Path,
absolute_target: &Path, absolute_target: &Path,
etc_dir: &Path, etc_dir: &Path,
state: EtcTree, state: FileTree,
old_state: &EtcTree, old_state: &FileTree,
upwards_path: &Path, upwards_path: &Path,
) -> EtcActivationResult { ) -> EtcActivationResult {
let link_path = etc_dir.join(link_target); let link_path = etc_dir.join(link_target);
if link_path.is_dir() && absolute_target.is_dir() { if link_path.is_dir() && absolute_target.is_dir() {
log::info!("Entering into directory..."); log::debug!("Entering into directory {}...", link_path.display());
Ok(absolute_target Ok(absolute_target
.read_dir() .read_dir()
.expect("Error reading the directory.") .expect("Error reading the directory.")
@ -250,8 +250,8 @@ where
fn go( fn go(
link_target: &Path, link_target: &Path,
etc_dir: &Path, etc_dir: &Path,
state: EtcTree, state: FileTree,
old_state: &EtcTree, old_state: &FileTree,
upwards_path: &Path, upwards_path: &Path,
) -> EtcActivationResult { ) -> EtcActivationResult {
let link_path = etc_dir.join(link_target); let link_path = etc_dir.join(link_target);
@ -272,6 +272,7 @@ where
} else if link_path.is_symlink() } else if link_path.is_symlink()
&& link_path.read_link().expect("Error reading link.") == target && link_path.read_link().expect("Error reading link.") == target
{ {
log::debug!("Link {} up to date.", link_path.display());
Ok(dir_state.register_managed_entry(&link_path)) Ok(dir_state.register_managed_entry(&link_path))
} else { } else {
let result = if link_path.exists() { let result = if link_path.exists() {
@ -304,8 +305,8 @@ where
fn create_etc_entry( fn create_etc_entry(
entry: &EtcFile, entry: &EtcFile,
etc_dir: &Path, etc_dir: &Path,
state: EtcTree, state: FileTree,
old_state: &EtcTree, old_state: &FileTree,
) -> EtcActivationResult { ) -> EtcActivationResult {
if entry.mode == "symlink" { if entry.mode == "symlink" {
if let Some(path::Component::Normal(link_target)) = entry.target.components().next() { if let Some(path::Component::Normal(link_target)) = entry.target.components().next() {
@ -331,7 +332,7 @@ fn create_etc_entry(
} }
} }
fn create_dir_recursively(dir: &Path, state: EtcTree) -> EtcActivationResult { fn create_dir_recursively(dir: &Path, state: FileTree) -> EtcActivationResult {
use itertools::FoldWhile::{Continue, Done}; use itertools::FoldWhile::{Continue, Done};
use path::Component; use path::Component;
@ -382,7 +383,7 @@ fn create_dir_recursively(dir: &Path, state: EtcTree) -> EtcActivationResult {
new_state new_state
} }
fn copy_file(source: &Path, target: &Path, mode: &str, old_state: &EtcTree) -> anyhow::Result<()> { fn copy_file(source: &Path, target: &Path, mode: &str, old_state: &FileTree) -> anyhow::Result<()> {
let exists = target.try_exists()?; let exists = target.try_exists()?;
if !exists || old_state.is_managed(target) { if !exists || old_state.is_managed(target) {
log::debug!( log::debug!(

View file

@ -7,14 +7,14 @@ use std::path::{Path, PathBuf};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub enum EtcFileStatus { pub enum FileStatus {
Managed, Managed,
Unmanaged, Unmanaged,
} }
impl EtcFileStatus { impl FileStatus {
fn merge(&self, other: &Self) -> Self { fn merge(&self, other: &Self) -> Self {
use EtcFileStatus::*; use FileStatus::*;
match (self, other) { match (self, other) {
(Unmanaged, Unmanaged) => Unmanaged, (Unmanaged, Unmanaged) => Unmanaged,
@ -25,22 +25,22 @@ impl EtcFileStatus {
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct EtcTree { pub struct FileTree {
status: EtcFileStatus, status: FileStatus,
path: PathBuf, path: PathBuf,
// TODO directories and files are now both represented as a string associated with a nested // TODO directories and files are now both represented as a string associated with a nested
// map. For files the nested map is simple empty. // map. For files the nested map is simple empty.
// We could potentially optimise this. // We could potentially optimise this.
nested: HashMap<String, EtcTree>, nested: HashMap<String, FileTree>,
} }
impl AsRef<EtcTree> for EtcTree { impl AsRef<FileTree> for FileTree {
fn as_ref(&self) -> &EtcTree { fn as_ref(&self) -> &FileTree {
self self
} }
} }
impl Default for EtcTree { impl Default for FileTree {
fn default() -> Self { fn default() -> Self {
Self::root_node() Self::root_node()
} }
@ -56,12 +56,12 @@ impl Default for EtcTree {
/// 3. Import from a file /// 3. Import from a file
/// 4. Add a path to the tree, that will from then on be considered as managed /// 4. Add a path to the tree, that will from then on be considered as managed
/// 5. /// 5.
impl EtcTree { impl FileTree {
fn new(path: PathBuf) -> Self { fn new(path: PathBuf) -> Self {
Self::with_status(path, EtcFileStatus::Unmanaged) Self::with_status(path, FileStatus::Unmanaged)
} }
fn with_status(path: PathBuf, status: EtcFileStatus) -> Self { fn with_status(path: PathBuf, status: FileStatus) -> Self {
Self { Self {
status, status,
path, path,
@ -73,8 +73,8 @@ impl EtcTree {
Self::new(PathBuf::from(path::MAIN_SEPARATOR_STR)) Self::new(PathBuf::from(path::MAIN_SEPARATOR_STR))
} }
pub fn get_status<'a>(&'a self, path: &Path) -> &'a EtcFileStatus { pub fn get_status<'a>(&'a self, path: &Path) -> &'a FileStatus {
fn go<'a, 'b, C>(tree: &'a EtcTree, mut components: C, path: &Path) -> &'a EtcFileStatus fn go<'a, 'b, C>(tree: &'a FileTree, mut components: C, path: &Path) -> &'a FileStatus
where where
C: Iterator<Item = path::Component<'b>>, C: Iterator<Item = path::Component<'b>>,
{ {
@ -84,7 +84,7 @@ impl EtcTree {
.nested .nested
.get(name.to_string_lossy().as_ref()) .get(name.to_string_lossy().as_ref())
.map(|subtree| go(subtree, components, path)) .map(|subtree| go(subtree, components, path))
.unwrap_or(&EtcFileStatus::Unmanaged), .unwrap_or(&FileStatus::Unmanaged),
path::Component::RootDir => go(tree, components, path), path::Component::RootDir => go(tree, components, path),
_ => todo!(), _ => todo!(),
} }
@ -97,13 +97,13 @@ impl EtcTree {
} }
pub fn is_managed(&self, path: &Path) -> bool { pub fn is_managed(&self, path: &Path) -> bool {
*self.get_status(path) == EtcFileStatus::Managed *self.get_status(path) == FileStatus::Managed
} }
// TODO is recursion OK here? // TODO is recursion OK here?
// Should we convert to CPS and use a crate like tramp to TCO this? // Should we convert to CPS and use a crate like tramp to TCO this?
pub fn register_managed_entry(self, path: &Path) -> Self { pub fn register_managed_entry(self, path: &Path) -> Self {
fn go<'a, C>(mut tree: EtcTree, mut components: Peekable<C>, path: PathBuf) -> EtcTree fn go<'a, C>(mut tree: FileTree, mut components: Peekable<C>, path: PathBuf) -> FileTree
where where
C: Iterator<Item = path::Component<'a>>, C: Iterator<Item = path::Component<'a>>,
{ {
@ -115,16 +115,14 @@ impl EtcTree {
|maybe_subtree| { |maybe_subtree| {
Some(go( Some(go(
maybe_subtree.unwrap_or_else(|| { maybe_subtree.unwrap_or_else(|| {
EtcTree::with_status( FileTree::with_status(
new_path.to_owned(), new_path.to_owned(),
// We only label as managed the final path entry, // We only label as managed the final path entry,
// to label intermediate nodes as managed, we should // to label intermediate nodes as managed, we should
// call this function for every one of them separately. // call this function for every one of them separately.
components components.peek().map_or(FileStatus::Managed, |_| {
.peek() FileStatus::Unmanaged
.map_or(EtcFileStatus::Managed, |_| { }),
EtcFileStatus::Unmanaged
}),
) )
}), }),
components, components,
@ -151,9 +149,9 @@ impl EtcTree {
go(self, path.components().peekable(), PathBuf::new()) go(self, path.components().peekable(), PathBuf::new())
} }
pub fn deactivate<F>(self, delete_action: &F) -> Option<EtcTree> pub fn deactivate<F>(self, delete_action: &F) -> Option<FileTree>
where where
F: Fn(&Path, &EtcFileStatus) -> bool, F: Fn(&Path, &FileStatus) -> bool,
{ {
let new_tree = self.nested.keys().fold(self.clone(), |mut new_tree, name| { let new_tree = self.nested.keys().fold(self.clone(), |mut new_tree, name| {
new_tree.nested = new_tree.nested.alter( new_tree.nested = new_tree.nested.alter(
@ -168,7 +166,7 @@ impl EtcTree {
// are not responsible for cleaning them up (we don't run the delete_action // are not responsible for cleaning them up (we don't run the delete_action
// closure on their paths). // closure on their paths).
if new_tree.nested.is_empty() { if new_tree.nested.is_empty() {
if let EtcFileStatus::Managed = new_tree.status { if let FileStatus::Managed = new_tree.status {
if delete_action(&new_tree.path, &new_tree.status) { if delete_action(&new_tree.path, &new_tree.status) {
None None
} else { } else {
@ -184,7 +182,7 @@ impl EtcTree {
pub fn update_state<F>(self, other: Self, delete_action: &F) -> Option<Self> pub fn update_state<F>(self, other: Self, delete_action: &F) -> Option<Self>
where where
F: Fn(&Path, &EtcFileStatus) -> bool, F: Fn(&Path, &FileStatus) -> bool,
{ {
let to_deactivate = other let to_deactivate = other
.nested .nested
@ -225,7 +223,7 @@ impl EtcTree {
// If our invariants are properly maintained, then we should never end up // If our invariants are properly maintained, then we should never end up
// here with dangling unmanaged nodes. // here with dangling unmanaged nodes.
debug_assert!(!merged.nested.is_empty() || merged.status == EtcFileStatus::Managed); debug_assert!(!merged.nested.is_empty() || merged.status == FileStatus::Managed);
Some(merged) Some(merged)
} }
@ -236,20 +234,20 @@ mod tests {
use super::*; use super::*;
use itertools::Itertools; use itertools::Itertools;
impl EtcTree { impl FileTree {
pub fn deactivate_managed_entry<F>(self, path: &Path, delete_action: &F) -> Self pub fn deactivate_managed_entry<F>(self, path: &Path, delete_action: &F) -> Self
where where
F: Fn(&Path, &EtcFileStatus) -> bool, F: Fn(&Path, &FileStatus) -> bool,
{ {
fn go<'a, C, F>( fn go<'a, C, F>(
mut tree: EtcTree, mut tree: FileTree,
path: PathBuf, path: PathBuf,
mut components: Peekable<C>, mut components: Peekable<C>,
delete_action: &F, delete_action: &F,
) -> EtcTree ) -> FileTree
where where
C: Iterator<Item = path::Component<'a>>, C: Iterator<Item = path::Component<'a>>,
F: Fn(&Path, &EtcFileStatus) -> bool, F: Fn(&Path, &FileStatus) -> bool,
{ {
log::debug!("Deactivating {}", path.display()); log::debug!("Deactivating {}", path.display());
@ -296,8 +294,8 @@ mod tests {
} }
#[test] #[test]
fn etc_tree_get_status() { fn get_status() {
let tree1 = EtcTree::root_node() let tree1 = FileTree::root_node()
.register_managed_entry(&PathBuf::from("/").join("foo").join("bar")) .register_managed_entry(&PathBuf::from("/").join("foo").join("bar"))
.register_managed_entry(&PathBuf::from("/").join("foo2")) .register_managed_entry(&PathBuf::from("/").join("foo2"))
.register_managed_entry(&PathBuf::from("/").join("foo2").join("baz")) .register_managed_entry(&PathBuf::from("/").join("foo2").join("baz"))
@ -319,8 +317,8 @@ mod tests {
} }
#[test] #[test]
fn etc_tree_register() { fn register() {
let tree = EtcTree::root_node() let tree = FileTree::root_node()
.register_managed_entry(&PathBuf::from("/").join("foo").join("bar")) .register_managed_entry(&PathBuf::from("/").join("foo").join("bar"))
.register_managed_entry(&PathBuf::from("/").join("foo2").join("baz").join("bar")) .register_managed_entry(&PathBuf::from("/").join("foo2").join("baz").join("bar"))
.register_managed_entry(&PathBuf::from("/").join("foo2").join("baz2").join("bar")); .register_managed_entry(&PathBuf::from("/").join("foo2").join("baz2").join("bar"));
@ -345,8 +343,8 @@ mod tests {
} }
#[test] #[test]
fn etc_tree_deactivate() { fn deactivate() {
let tree1 = EtcTree::root_node() let tree1 = FileTree::root_node()
.register_managed_entry(&PathBuf::from("/").join("foo").join("bar")) .register_managed_entry(&PathBuf::from("/").join("foo").join("bar"))
.register_managed_entry(&PathBuf::from("/").join("foo2")) .register_managed_entry(&PathBuf::from("/").join("foo2"))
.register_managed_entry(&PathBuf::from("/").join("foo2").join("baz")) .register_managed_entry(&PathBuf::from("/").join("foo2").join("baz"))
@ -406,8 +404,8 @@ mod tests {
} }
#[test] #[test]
fn etc_tree_update_state() { fn update_state() {
let tree1 = EtcTree::root_node() let tree1 = FileTree::root_node()
.register_managed_entry(&PathBuf::from("/").join("foo").join("bar")) .register_managed_entry(&PathBuf::from("/").join("foo").join("bar"))
.register_managed_entry(&PathBuf::from("/").join("foo2")) .register_managed_entry(&PathBuf::from("/").join("foo2"))
.register_managed_entry(&PathBuf::from("/").join("foo2").join("baz")) .register_managed_entry(&PathBuf::from("/").join("foo2").join("baz"))
@ -415,7 +413,7 @@ mod tests {
.register_managed_entry(&PathBuf::from("/").join("foo2").join("baz2")) .register_managed_entry(&PathBuf::from("/").join("foo2").join("baz2"))
.register_managed_entry(&PathBuf::from("/").join("foo2").join("baz2").join("bar")) .register_managed_entry(&PathBuf::from("/").join("foo2").join("baz2").join("bar"))
.register_managed_entry(&PathBuf::from("/").join("foo3").join("baz2").join("bar")); .register_managed_entry(&PathBuf::from("/").join("foo3").join("baz2").join("bar"));
let tree2 = EtcTree::root_node() let tree2 = FileTree::root_node()
.register_managed_entry(&PathBuf::from("/").join("foo").join("bar")) .register_managed_entry(&PathBuf::from("/").join("foo").join("bar"))
.register_managed_entry(&PathBuf::from("/").join("foo3").join("bar")) .register_managed_entry(&PathBuf::from("/").join("foo3").join("bar"))
.register_managed_entry(&PathBuf::from("/").join("foo4")) .register_managed_entry(&PathBuf::from("/").join("foo4"))

View file

@ -295,7 +295,7 @@ where
.iter() .iter()
.fold(HashSet::new(), |mut set, unit| match action(unit) { .fold(HashSet::new(), |mut set, unit| match action(unit) {
Ok(_) => { Ok(_) => {
log::info!("Unit {}: {}...", unit, log_action); log::debug!("Unit {}: {}...", unit, log_action);
set.insert(JobId { set.insert(JobId {
id: (*unit).to_owned(), id: (*unit).to_owned(),
}); });

View file

@ -201,7 +201,8 @@ impl ServiceManager {
let total_jobs = waiting_for.len(); let total_jobs = waiting_for.len();
if total_jobs > 0 { if total_jobs > 0 {
log::info!("Waiting for jobs to finish... (0/{})", total_jobs); log::info!("Waiting for jobs to finish...");
log::debug!("Waiting for jobs to finish... (0/{})", total_jobs);
} }
while !waiting_for.is_empty() { while !waiting_for.is_empty() {
@ -218,7 +219,7 @@ impl ServiceManager {
waiting_for = waiting_for.relative_complement(job_names.clone()); waiting_for = waiting_for.relative_complement(job_names.clone());
*job_names = im::HashSet::new(); *job_names = im::HashSet::new();
if !waiting_for.is_empty() { if !waiting_for.is_empty() {
log::info!( log::debug!(
"Waiting for jobs to finish... ({}/{})", "Waiting for jobs to finish... ({}/{})",
total_jobs - waiting_for.len(), total_jobs - waiting_for.len(),
total_jobs total_jobs