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.

80 lines
1.9 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. use std::error::Error;
  2. use std::fmt;
  3. use std::ops::Deref;
  4. use command_runner::CommandRunner;
  5. use resources::Resource;
  6. use symbols::{Action, OwnedSymbolAction, Symbol, SymbolAction, SymbolRunner};
  7. pub struct Cron<'r, C, U, R: 'r + CommandRunner>
  8. where
  9. C: Deref<Target = str>,
  10. U: Deref<Target = str>,
  11. {
  12. user: U,
  13. content: C,
  14. command_runner: &'r R,
  15. }
  16. impl<'r, U, R: 'r + CommandRunner> Cron<'r, String, U, R>
  17. where
  18. U: Deref<Target = str>,
  19. {
  20. pub fn new<C: Deref<Target = str>>(user: U, content: C, command_runner: &'r R) -> Self {
  21. Cron {
  22. user,
  23. content: String::from(&*content) + "\n",
  24. command_runner,
  25. }
  26. }
  27. }
  28. impl<'r, C, U, R: 'r + CommandRunner> Symbol for Cron<'r, C, U, R>
  29. where
  30. C: Deref<Target = str>,
  31. U: Deref<Target = str>,
  32. {
  33. fn target_reached(&self) -> Result<bool, Box<dyn Error>> {
  34. let tab = self
  35. .command_runner
  36. .get_output("crontab", &["-l", "-u", &self.user])?;
  37. Ok(tab == self.content.bytes().collect::<Vec<u8>>())
  38. }
  39. fn execute(&self) -> Result<(), Box<dyn Error>> {
  40. let output = self.command_runner.run_with_args_and_stdin(
  41. "crontab",
  42. &["-u", &self.user, "-"],
  43. &self.content,
  44. )?;
  45. if !output.status.success() {
  46. return Err(String::from_utf8(output.stderr)?.into());
  47. }
  48. Ok(())
  49. }
  50. fn get_prerequisites(&self) -> Vec<Resource> {
  51. vec![]
  52. }
  53. fn as_action<'a>(&'a self, runner: &'a dyn SymbolRunner) -> Box<dyn Action + 'a> {
  54. Box::new(SymbolAction::new(runner, self))
  55. }
  56. fn into_action<'a>(self: Box<Self>, runner: &'a dyn SymbolRunner) -> Box<dyn Action + 'a>
  57. where
  58. Self: 'a,
  59. {
  60. Box::new(OwnedSymbolAction::new(runner, *self))
  61. }
  62. }
  63. impl<'r, C, U, R: 'r + CommandRunner> fmt::Display for Cron<'r, C, U, R>
  64. where
  65. C: Deref<Target = str>,
  66. U: Deref<Target = str>,
  67. {
  68. fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
  69. write!(f, "Cron {}", &*self.user)
  70. }
  71. }