diff --git a/src/symbols/dir.rs b/src/symbols/dir.rs index 54a03df..a1104e0 100644 --- a/src/symbols/dir.rs +++ b/src/symbols/dir.rs @@ -7,17 +7,17 @@ use std::path::Path; use resources::Resource; use symbols::{Action, OwnedSymbolAction, Symbol, SymbolAction, SymbolRunner}; -pub struct Dir where D: AsRef + fmt::Display { +pub struct Dir where D: AsRef { path: D } -impl Dir where D: AsRef + fmt::Display { +impl Dir where D: AsRef { pub fn new(path: D) -> Self { Dir { path: path } } } -impl Symbol for Dir where D: AsRef + fmt::Display { +impl Symbol for Dir where D: AsRef { fn target_reached(&self) -> Result> { let metadata = fs::metadata(self.path.as_ref()); // Check if dir exists @@ -48,7 +48,7 @@ impl Symbol for Dir where D: AsRef + fmt::Display { } fn provides(&self) -> Option> { - Some(vec![ Resource::new("dir", self.path.to_string()) ]) + Some(vec![ Resource::new("dir", self.path.as_ref()) ]) } fn as_action<'a>(&'a self, runner: &'a SymbolRunner) -> Box { @@ -60,8 +60,8 @@ impl Symbol for Dir where D: AsRef + fmt::Display { } } -impl fmt::Display for Dir where D: AsRef + fmt::Display { +impl fmt::Display for Dir where D: AsRef { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{ - write!(f, "Dir {}", self.path) + write!(f, "Dir {}", self.path.as_ref()) } } diff --git a/src/symbols/factory.rs b/src/symbols/factory.rs index 1b7dd5f..b087699 100644 --- a/src/symbols/factory.rs +++ b/src/symbols/factory.rs @@ -1,10 +1,17 @@ +use std::ops::Deref; +use std::path::Path; + use command_runner::{CommandRunner, SetuidCommandRunner}; +use storage::SimpleStorage; use symbols::{Action, Symbol, SymbolRunner}; use symbols::acme::{AcmeCert, AcmeCertChain}; use symbols::file::File; +use symbols::git::checkout::GitCheckout; use symbols::hook::Hook; use symbols::list::ListAction; use symbols::nginx::server::NginxServer; +use symbols::owner::Owner; +use symbols::stored_directory::{StoredDirectory, StorageDirection}; use symbols::systemd::reload::ReloadService; use symbols::tls::SelfSignedTlsCert; @@ -86,4 +93,25 @@ pm.max_children = 10" self.command_runner ) } + + pub fn get_stored_directory<'a, T: Into>(&'a self, storage_name: &'static str, target: T) -> (Box, Box) { + let data = SimpleStorage::new("/root/data".to_string(), storage_name.to_string()); + let string_target = target.into(); + ( + Box::new(StoredDirectory::new(string_target.clone().into(), data.clone(), StorageDirection::Save, self.command_runner)).into_action(self.symbol_runner), + Box::new(StoredDirectory::new(string_target.into(), data.clone(), StorageDirection::Load, self.command_runner)).into_action(self.symbol_runner) + ) + } + + pub fn get_git_checkout<'a, T: 'a + AsRef>(&'a self, target: T, source: &'a str, branch: &'a str) -> Box { + Box::new(GitCheckout::new(target, source, branch, self.command_runner)).into_action(self.symbol_runner) + } + + pub fn get_owner<'a, F: 'a + AsRef>(&'a self, file: F, user: &'a str) -> Box { + Box::new(Owner::new(file, user.into(), self.command_runner)).into_action(self.symbol_runner) + } + + pub fn get_file<'a, F: 'a + Deref, P: 'a + AsRef>(&'a self, path: P, content: F) -> Box { + Box::new(File::new(path, content)).into_action(self.symbol_runner) + } } diff --git a/src/symbols/file.rs b/src/symbols/file.rs index cf33179..7f443e3 100644 --- a/src/symbols/file.rs +++ b/src/symbols/file.rs @@ -9,12 +9,12 @@ use std::path::Path; use symbols::{Action, OwnedSymbolAction, Symbol, SymbolAction, SymbolRunner}; use resources::Resource; -pub struct File where C: Deref, D: AsRef + fmt::Display { +pub struct File where C: Deref, D: AsRef { path: D, content: C } -impl File where C: Deref, D: AsRef + fmt::Display { +impl File where C: Deref, D: AsRef { pub fn new(path: D, content: C) -> Self { File { path: path, @@ -23,7 +23,7 @@ impl File where C: Deref, D: AsRef + fmt::Display { } } -impl Symbol for File where C: Deref, D: AsRef + fmt::Display { +impl Symbol for File where C: Deref, D: AsRef { fn target_reached(&self) -> Result> { let file = FsFile::open(self.path.as_ref()); // Check if file exists @@ -66,8 +66,8 @@ impl Symbol for File where C: Deref, D: AsRef + fmt } } -impl fmt::Display for File where C: Deref, D: AsRef + fmt::Display { +impl fmt::Display for File where C: Deref, D: AsRef { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{ - write!(f, "File {}", self.path) + write!(f, "File {}", self.path.as_ref().display()) } } diff --git a/src/symbols/git/checkout.rs b/src/symbols/git/checkout.rs index 0e401c2..e9c54f2 100644 --- a/src/symbols/git/checkout.rs +++ b/src/symbols/git/checkout.rs @@ -7,15 +7,15 @@ use command_runner::CommandRunner; use resources::Resource; use symbols::{Action, OwnedSymbolAction, Symbol, SymbolAction, SymbolRunner}; -pub struct GitCheckout<'a, C: 'a + CommandRunner> { - target: &'a str, +pub struct GitCheckout<'a, C: 'a + CommandRunner, T: AsRef> { + target: T, source: &'a str, branch: &'a str, command_runner: &'a C } -impl<'a, C: CommandRunner> GitCheckout<'a, C> { - pub fn new(target: &'a str, source: &'a str, branch: &'a str, command_runner: &'a C) -> Self { +impl<'a, C: CommandRunner, T: AsRef> GitCheckout<'a, C, T> { + pub fn new(target: T, source: &'a str, branch: &'a str, command_runner: &'a C) -> Self { GitCheckout { target: target, source: source, @@ -25,25 +25,25 @@ impl<'a, C: CommandRunner> GitCheckout<'a, C> { } } -impl<'a, C: CommandRunner> fmt::Display for GitCheckout<'a, C> { +impl<'a, C: CommandRunner, T: AsRef> fmt::Display for GitCheckout<'a, C, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Checkout {} (branch {}) into {}", self.source, self.branch, self.target) + write!(f, "Checkout {} (branch {}) into {}", self.source, self.branch, self.target.as_ref()) } } use std::fs::metadata; -impl<'a, C: CommandRunner> GitCheckout<'a, C> { +impl<'a, C: CommandRunner, T: AsRef> GitCheckout<'a, C, T> { fn _run_in_target_repo(&self, args: &[&str]) -> Result, Box> { - let mut new_args = vec!["-C", self.target]; + let mut new_args = vec!["-C", self.target.as_ref()]; new_args.extend_from_slice(args); self.command_runner.get_output("git", &new_args) } } -impl<'a, C: CommandRunner> Symbol for GitCheckout<'a, C> { +impl<'a, C: CommandRunner, T: AsRef> Symbol for GitCheckout<'a, C, T> { fn target_reached(&self) -> Result> { - if let Err(e) = metadata(self.target) { + if let Err(e) = metadata(self.target.as_ref()) { return if e.kind() == io::ErrorKind::NotFound { Ok(false) } else { @@ -58,8 +58,8 @@ impl<'a, C: CommandRunner> Symbol for GitCheckout<'a, C> { } fn execute(&self) -> Result<(), Box> { - if !Path::new(self.target).exists() { - return self.command_runner.run_successfully("git", &["clone", "--depth", "1", "-b", self.branch, self.source, self.target]); + if !Path::new(self.target.as_ref()).exists() { + return self.command_runner.run_successfully("git", &["clone", "--depth", "1", "-b", self.branch, self.source, self.target.as_ref()]); } try!(self._run_in_target_repo(&["fetch", self.source, self.branch])); try!(self._run_in_target_repo(&["merge", "FETCH_HEAD"])); @@ -67,11 +67,11 @@ impl<'a, C: CommandRunner> Symbol for GitCheckout<'a, C> { } fn get_prerequisites(&self) -> Vec { - vec![ Resource::new("dir", Path::new(self.target).parent().unwrap().to_string_lossy()) ] + vec![ Resource::new("dir", Path::new(self.target.as_ref()).parent().unwrap().to_string_lossy()) ] } fn provides(&self) -> Option> { - Some(vec![ Resource::new("dir", self.target.to_string()) ]) + Some(vec![ Resource::new("dir", self.target.as_ref().to_string()) ]) } fn as_action<'b>(&'b self, runner: &'b SymbolRunner) -> Box { diff --git a/src/symbols/nginx/server.rs b/src/symbols/nginx/server.rs index 1bbd7e9..a44782c 100644 --- a/src/symbols/nginx/server.rs +++ b/src/symbols/nginx/server.rs @@ -43,7 +43,7 @@ impl fmt::Display for NginxServerError { pub struct NginxServer<'a, C: 'a + CommandRunner, T> where T: Deref { command_runner: &'a C, - file: FileSymbol>, + file: FileSymbol, } use std::borrow::Cow; @@ -121,7 +121,7 @@ location @proxy {{ } pub fn new(domain: &'a str, content: String, command_runner: &'a C) -> Self { - let file_path: Cow = Cow::from(String::from("/etc/nginx/sites-enabled/") + domain); + let file_path = String::from("/etc/nginx/sites-enabled/") + domain; NginxServer { command_runner: command_runner, file: FileSymbol::new(file_path, content) diff --git a/src/symbols/owner.rs b/src/symbols/owner.rs index 5b9f12c..8b8a883 100644 --- a/src/symbols/owner.rs +++ b/src/symbols/owner.rs @@ -11,19 +11,19 @@ use command_runner::CommandRunner; use resources::Resource; use symbols::{Action, OwnedSymbolAction, Symbol, SymbolAction, SymbolRunner}; -pub struct Owner<'a, C: 'a + CommandRunner, D> where D: AsRef + fmt::Display { +pub struct Owner<'a, C: 'a + CommandRunner, D> where D: AsRef { path: D, user_name: Cow<'a, str>, command_runner: &'a C } -impl<'a, C: CommandRunner, D> Owner<'a, C, D> where D: AsRef + fmt::Display { +impl<'a, C: CommandRunner, D> Owner<'a, C, D> where D: AsRef { pub fn new(path: D, user_name: Cow<'a, str>, command_runner: &'a C) -> Self { Owner { path: path, user_name: user_name, command_runner: command_runner } } } -impl<'a, C: CommandRunner, D> Symbol for Owner<'a, C, D> where D: AsRef + fmt::Display { +impl<'a, C: CommandRunner, D> Symbol for Owner<'a, C, D> where D: AsRef { fn target_reached(&self) -> Result> { if !Path::new(self.path.as_ref()).exists() { return Ok(false); @@ -50,8 +50,8 @@ impl<'a, C: CommandRunner, D> Symbol for Owner<'a, C, D> where D: AsRef + f } } -impl<'a, C: CommandRunner, D> fmt::Display for Owner<'a, C, D> where D: AsRef + fmt::Display { +impl<'a, C: CommandRunner, D> fmt::Display for Owner<'a, C, D> where D: AsRef { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{ - write!(f, "Owner {} for {}", self.user_name, self.path) + write!(f, "Owner {} for {}", self.user_name, self.path.as_ref()) } } diff --git a/src/symbols/wordpress/plugin.rs b/src/symbols/wordpress/plugin.rs index b1c8a51..e41f24b 100644 --- a/src/symbols/wordpress/plugin.rs +++ b/src/symbols/wordpress/plugin.rs @@ -11,13 +11,13 @@ use command_runner::CommandRunner; use symbols::{Action, OwnedSymbolAction, Symbol, SymbolAction, SymbolRunner}; use resources::Resource; -pub struct WordpressPlugin<'a, C, R> where C: Deref + fmt::Display, R: 'a + CommandRunner { +pub struct WordpressPlugin<'a, C, R> where C: Deref, R: 'a + CommandRunner { base: C, name: C, command_runner: &'a R } -impl<'a, C, R> WordpressPlugin<'a, C, R> where C: Deref + fmt::Display, R: CommandRunner { +impl<'a, C, R> WordpressPlugin<'a, C, R> where C: Deref, R: CommandRunner { pub fn new(base: C, name: C, command_runner: &'a R) -> Self { WordpressPlugin { base: base, @@ -31,7 +31,7 @@ impl<'a, C, R> WordpressPlugin<'a, C, R> where C: Deref + fmt::Displ } } -impl<'a, C, R> Symbol for WordpressPlugin<'a, C, R> where C: Deref + fmt::Display, R: CommandRunner { +impl<'a, C, R> Symbol for WordpressPlugin<'a, C, R> where C: Deref, R: CommandRunner { fn target_reached(&self) -> Result> { if !self.get_path().exists() { return Ok(false); @@ -62,13 +62,13 @@ impl<'a, C, R> Symbol for WordpressPlugin<'a, C, R> where C: Deref + } } } - let upstream = try!(self.command_runner.get_output("curl", &["--form", &format!(r###"plugins={{"plugins":{{"{0}/{0}.php":{{"Version":"{1}", "PluginURI":"{2}"}}}}}}"###, self.name, version, plugin_uri), "https://api.wordpress.org/plugins/update-check/1.1/"])); + let upstream = try!(self.command_runner.get_output("curl", &["--form", &format!(r###"plugins={{"plugins":{{"{0}/{0}.php":{{"Version":"{1}", "PluginURI":"{2}"}}}}}}"###, &*self.name, version, plugin_uri), "https://api.wordpress.org/plugins/update-check/1.1/"])); Ok(try!(String::from_utf8(upstream)).contains(r###""plugins":[]"###)) } fn execute(&self) -> Result<(), Box> { - let source = format!("https://downloads.wordpress.org/plugin/{}.zip", self.name); - let zip = format!("/tmp/{}.zip", self.name); + let source = format!("https://downloads.wordpress.org/plugin/{}.zip", &*self.name); + let zip = format!("/tmp/{}.zip", &*self.name); try!(self.command_runner.run_successfully("curl", &[source.as_ref() as &str, "-o", zip.as_ref()])); try!(self.command_runner.run_successfully("rm", &["-rf", &self.get_path().to_string_lossy()])); self.command_runner.run_successfully("unzip", &[zip.as_ref(), "-d".as_ref(), Path::new(&*self.base).join("wp-content/plugins").as_os_str()]) @@ -90,9 +90,9 @@ impl<'a, C, R> Symbol for WordpressPlugin<'a, C, R> where C: Deref + } } -impl<'a, C, R> fmt::Display for WordpressPlugin<'a, C, R> where C: Deref + fmt::Display, R: CommandRunner { +impl<'a, C, R> fmt::Display for WordpressPlugin<'a, C, R> where C: Deref, R: CommandRunner { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{ - write!(f, "WordpressPlugin {}", self.name) + write!(f, "WordpressPlugin {}", &*self.name) } } diff --git a/src/symbols/wordpress/translation.rs b/src/symbols/wordpress/translation.rs index 0fb7c01..f4c6e29 100644 --- a/src/symbols/wordpress/translation.rs +++ b/src/symbols/wordpress/translation.rs @@ -11,15 +11,15 @@ use command_runner::CommandRunner; use symbols::{Action, OwnedSymbolAction, Symbol, SymbolAction, SymbolRunner}; use resources::Resource; -pub struct WordpressTranslation<'a, C, D, R> where C: AsRef + fmt::Display, D: AsRef + fmt::Display, R: 'a + CommandRunner { +pub struct WordpressTranslation<'a, C, D, R> where C: AsRef, D: AsRef, R: 'a + CommandRunner { path: D, version: &'a str, locale: C, command_runner: &'a R } -impl<'a, C, R> WordpressTranslation<'a, C, String, R> where C: AsRef + fmt::Display, R: CommandRunner { - pub fn new + fmt::Display>(path: D, version: &'a str, locale: C, command_runner: &'a R) -> Self { +impl<'a, C, R> WordpressTranslation<'a, C, String, R> where C: AsRef, R: CommandRunner { + pub fn new>(path: D, version: &'a str, locale: C, command_runner: &'a R) -> Self { WordpressTranslation { path: Path::new(path.as_ref()).join("wp-content/languages").to_string_lossy().to_string(), version: version, @@ -29,7 +29,7 @@ impl<'a, C, R> WordpressTranslation<'a, C, String, R> where C: AsRef + fmt: } } -impl<'a, C, D, R> WordpressTranslation<'a, C, D, R> where C: AsRef + fmt::Display, D: AsRef + fmt::Display, R: CommandRunner { +impl<'a, C, D, R> WordpressTranslation<'a, C, D, R> where C: AsRef, D: AsRef, R: CommandRunner { fn get_pairs(&self) -> Vec<(String, String)> { let version_x = self.version.trim_right_matches(|c: char| c.is_digit(10)).to_owned() + "x"; let locale: &str = self.locale.as_ref(); @@ -39,7 +39,7 @@ impl<'a, C, D, R> WordpressTranslation<'a, C, D, R> where C: AsRef + fmt::D for format in ["po", "mo"].into_iter() { res.push(( format!("https://translate.wordpress.org/projects/wp/{}/{}{}/default/export-translations?format={}", version_x, in_slug, path_locale, format), - format!("{}/{}{}.{}", self.path, out_slug, self.locale, format) + format!("{}/{}{}.{}", self.path.as_ref(), out_slug, self.locale.as_ref(), format) )) } } @@ -47,7 +47,7 @@ impl<'a, C, D, R> WordpressTranslation<'a, C, D, R> where C: AsRef + fmt::D } } -impl<'a, C, D, R> Symbol for WordpressTranslation<'a, C, D, R> where C: AsRef + fmt::Display, D: AsRef + fmt::Display, R: CommandRunner { +impl<'a, C, D, R> Symbol for WordpressTranslation<'a, C, D, R> where C: AsRef, D: AsRef, R: CommandRunner { fn target_reached(&self) -> Result> { let mut newest = String::new(); let match_date = Regex::new("(?m)^\"PO-Revision-Date: (.+)\\+0000\\\\n\"$").unwrap(); @@ -72,8 +72,8 @@ impl<'a, C, D, R> Symbol for WordpressTranslation<'a, C, D, R> where C: AsRef Result<(), Box> { @@ -96,9 +96,9 @@ impl<'a, C, D, R> Symbol for WordpressTranslation<'a, C, D, R> where C: AsRef fmt::Display for WordpressTranslation<'a, C, D, R> where C: AsRef + fmt::Display, D: AsRef + fmt::Display, R: CommandRunner { +impl<'a, C, D, R> fmt::Display for WordpressTranslation<'a, C, D, R> where C: AsRef, D: AsRef, R: CommandRunner { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{ - write!(f, "WordpressTranslation {}", self.path) + write!(f, "WordpressTranslation {}", self.path.as_ref()) } }