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.

72 lines
1.9 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
5 years ago
7 years ago
5 years ago
7 years ago
5 years ago
7 years ago
7 years ago
5 years ago
7 years ago
7 years ago
7 years ago
7 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 std::error::Error;
  2. use std::fmt;
  3. use std::fs;
  4. use std::os::unix::fs::MetadataExt;
  5. use std::path::Path;
  6. use users::get_user_by_name;
  7. use command_runner::CommandRunner;
  8. use resources::Resource;
  9. use symbols::{Action, OwnedSymbolAction, Symbol, SymbolAction, SymbolRunner};
  10. pub struct Owner<'a, C: CommandRunner, D: AsRef<Path>, U: AsRef<str>> {
  11. path: D,
  12. user_name: U,
  13. command_runner: &'a C,
  14. }
  15. impl<'a, C: CommandRunner, D: AsRef<Path>, U: AsRef<str>> Owner<'a, C, D, U> {
  16. pub fn new(path: D, user_name: U, command_runner: &'a C) -> Self {
  17. Owner {
  18. path,
  19. user_name,
  20. command_runner,
  21. }
  22. }
  23. }
  24. impl<'a, C: CommandRunner, D: AsRef<Path>, U: AsRef<str>> Symbol for Owner<'a, C, D, U> {
  25. fn target_reached(&self) -> Result<bool, Box<dyn Error>> {
  26. if !Path::new(self.path.as_ref()).exists() {
  27. return Ok(false);
  28. }
  29. let actual_uid = fs::metadata(self.path.as_ref()).unwrap().uid();
  30. let target_uid = get_user_by_name(self.user_name.as_ref()).unwrap().uid();
  31. Ok(actual_uid == target_uid)
  32. }
  33. fn execute(&self) -> Result<(), Box<dyn Error>> {
  34. let uname: &str = self.user_name.as_ref();
  35. self
  36. .command_runner
  37. .run_successfully("chown", args!["-R", uname, self.path.as_ref(),])
  38. }
  39. fn get_prerequisites(&self) -> Vec<Resource> {
  40. vec![Resource::new("user", self.user_name.as_ref())]
  41. }
  42. fn as_action<'b>(&'b self, runner: &'b dyn SymbolRunner) -> Box<dyn Action + 'b> {
  43. Box::new(SymbolAction::new(runner, self))
  44. }
  45. fn into_action<'b>(self: Box<Self>, runner: &'b dyn SymbolRunner) -> Box<dyn Action + 'b>
  46. where
  47. Self: 'b,
  48. {
  49. Box::new(OwnedSymbolAction::new(runner, *self))
  50. }
  51. }
  52. impl<'a, C: CommandRunner, D: AsRef<Path>, U: AsRef<str>> fmt::Display for Owner<'a, C, D, U> {
  53. fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
  54. write!(
  55. f,
  56. "Owner {} for {}",
  57. self.user_name.as_ref(),
  58. self.path.as_ref().display()
  59. )
  60. }
  61. }