A library for writing host-specific, single-binary configuration management and deployment tools
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

48 lines
1.2 KiB

7 years ago
7 years ago
7 years ago
7 years ago
5 years ago
5 years ago
7 years ago
5 years ago
7 years ago
7 years ago
5 years ago
7 years ago
  1. use crate::command_runner::CommandRunner;
  2. use crate::symbols::Symbol;
  3. use std::borrow::Borrow;
  4. use std::error::Error;
  5. use std::fs;
  6. use std::marker::PhantomData;
  7. use std::os::unix::fs::MetadataExt;
  8. use std::path::Path;
  9. use users::get_user_by_name;
  10. #[derive(Debug)]
  11. pub struct Owner<_C, C, P, U> {
  12. path: P,
  13. user_name: U,
  14. command_runner: C,
  15. phantom: PhantomData<_C>,
  16. }
  17. impl<_C, C, P, U> Owner<_C, C, P, U> {
  18. pub fn new(path: P, user_name: U, command_runner: C) -> Self {
  19. Self {
  20. path,
  21. user_name,
  22. command_runner,
  23. phantom: PhantomData::default(),
  24. }
  25. }
  26. }
  27. impl<_C: CommandRunner, C: Borrow<_C>, P: AsRef<Path>, U: AsRef<str>> Symbol
  28. for Owner<_C, C, P, U>
  29. {
  30. fn target_reached(&self) -> Result<bool, Box<dyn Error>> {
  31. if !self.path.as_ref().exists() {
  32. return Ok(false);
  33. }
  34. let actual_uid = fs::metadata(self.path.as_ref()).unwrap().uid();
  35. let target_uid = get_user_by_name(self.user_name.as_ref()).unwrap().uid();
  36. Ok(actual_uid == target_uid)
  37. }
  38. fn execute(&self) -> Result<(), Box<dyn Error>> {
  39. self.command_runner.borrow().run_successfully(
  40. "chown",
  41. args!["-R", self.user_name.as_ref(), self.path.as_ref()],
  42. )
  43. }
  44. }