Compare commits
2 commits
b20052269f
...
b7c6a14571
| Author | SHA1 | Date | |
|---|---|---|---|
| b7c6a14571 | |||
| da98bfba8c |
22 changed files with 87 additions and 64 deletions
|
|
@ -6,11 +6,11 @@ edition = "2018"
|
||||||
build = "src/build.rs"
|
build = "src/build.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
users = "0.10.0"
|
users = "0.11.0"
|
||||||
regex = "1.0.1"
|
regex = "1.0.1"
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
tokio = { version = "0.2", features = ["process", "io-util", "rt-core", "macros", "sync"] }
|
tokio = { version = "0.3", features = ["rt", "process", "io-util", "macros", "sync"] }
|
||||||
once_cell = "1.4"
|
once_cell = "1.4"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,15 @@ use std::{
|
||||||
thread,
|
thread,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
use tokio::runtime::Builder;
|
||||||
|
|
||||||
pub use async_trait::async_trait;
|
pub use async_trait::async_trait;
|
||||||
|
|
||||||
pub fn run<F: Future>(future: F) -> F::Output {
|
pub fn run<F: Future>(future: F) -> F::Output {
|
||||||
tokio::runtime::Runtime::new().unwrap().block_on(future)
|
Builder::new_current_thread()
|
||||||
|
.build()
|
||||||
|
.unwrap()
|
||||||
|
.block_on(future)
|
||||||
}
|
}
|
||||||
pub use tokio::try_join;
|
pub use tokio::try_join;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -719,9 +719,7 @@ impl<D: Clone> ImplementationBuilder<MariaDbDatabase<D>> for DefaultBuilder {
|
||||||
|
|
||||||
impl<D: Clone> ImplementationBuilder<PostgresqlDatabase<D>> for DefaultBuilder {
|
impl<D: Clone> ImplementationBuilder<PostgresqlDatabase<D>> for DefaultBuilder {
|
||||||
type Prerequisites = ();
|
type Prerequisites = ();
|
||||||
fn prerequisites(resource: &PostgresqlDatabase<D>) -> Self::Prerequisites {
|
fn prerequisites(_: &PostgresqlDatabase<D>) -> Self::Prerequisites {}
|
||||||
()
|
|
||||||
}
|
|
||||||
|
|
||||||
type Implementation = (PostgreSQLDatabaseSymbol<'static, String, String, StdCommandRunner>,);
|
type Implementation = (PostgreSQLDatabaseSymbol<'static, String, String, StdCommandRunner>,);
|
||||||
fn create(
|
fn create(
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ impl CommandRunner for StdCommandRunner {
|
||||||
.expect("Failed to write to stdin");
|
.expect("Failed to write to stdin");
|
||||||
let res = child.wait_with_output().await;
|
let res = child.wait_with_output().await;
|
||||||
//println!("{:?}", res);
|
//println!("{:?}", res);
|
||||||
|
#[allow(clippy::let_and_return)]
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -125,8 +126,8 @@ impl<U: AsRef<str>, C: CommandRunner> CommandRunner for SetuidCommandRunner<'_,
|
||||||
let uid = get_user_by_name(self.user_name.as_ref())
|
let uid = get_user_by_name(self.user_name.as_ref())
|
||||||
.expect("User does not exist")
|
.expect("User does not exist")
|
||||||
.uid();
|
.uid();
|
||||||
let _set_home = TempSetEnv::new("HOME", format!("/home/{}", self.user_name.as_ref()));
|
let set_home = TempSetEnv::new("HOME", format!("/home/{}", self.user_name.as_ref()));
|
||||||
let _set_dbus = TempSetEnv::new("XDG_RUNTIME_DIR", format!("/run/user/{}", uid));
|
let set_dbus = TempSetEnv::new("XDG_RUNTIME_DIR", format!("/run/user/{}", uid));
|
||||||
//println!("{} {:?}", program, args);
|
//println!("{} {:?}", program, args);
|
||||||
let mut child = Command::new(program)
|
let mut child = Command::new(program)
|
||||||
.args(args)
|
.args(args)
|
||||||
|
|
@ -143,6 +144,8 @@ impl<U: AsRef<str>, C: CommandRunner> CommandRunner for SetuidCommandRunner<'_,
|
||||||
.await
|
.await
|
||||||
.expect("Failed to write to stdin");
|
.expect("Failed to write to stdin");
|
||||||
let res = child.wait_with_output().await;
|
let res = child.wait_with_output().await;
|
||||||
|
drop(set_home);
|
||||||
|
drop(set_dbus);
|
||||||
//println!("{:?}", res);
|
//println!("{:?}", res);
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,23 +15,29 @@ use std::marker::PhantomData;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
pub trait Policy {
|
pub trait Policy {
|
||||||
|
#[must_use]
|
||||||
fn acme_user() -> &'static str {
|
fn acme_user() -> &'static str {
|
||||||
"acme"
|
"acme"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
fn user_home(user_name: &str) -> PathBuf {
|
fn user_home(user_name: &str) -> PathBuf {
|
||||||
format!("/home/{}", user_name).into()
|
Path::new("/home").join(user_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
fn user_name_for_domain(domain_name: &'_ str) -> String {
|
fn user_name_for_domain(domain_name: &'_ str) -> String {
|
||||||
domain_name.split('.').rev().fold(String::new(), |result, part| if result.is_empty() { result } else { result + "_" } + part)
|
domain_name.split('.').rev().fold(String::new(), |result, part| if result.is_empty() { result } else { result + "_" } + part)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
fn php_version() -> &'static str {
|
fn php_version() -> &'static str {
|
||||||
"7.0"
|
"7.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
fn path_for_data(name: impl Display) -> PathBuf {
|
fn path_for_data(name: impl Display) -> PathBuf {
|
||||||
("/root/data".as_ref() as &Path).join(format!("_{}", name))
|
Path::new("/root/data").join(format!("_{}", name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -286,7 +292,7 @@ impl<D: AsRef<Path>, POLICY> ResourceLocator<ServeCustom<D>> for DefaultLocator<
|
||||||
resource: &ServeCustom<D>,
|
resource: &ServeCustom<D>,
|
||||||
) -> (<ServeCustom<D> as Resource>::Artifact, Self::Prerequisites) {
|
) -> (<ServeCustom<D> as Resource>::Artifact, Self::Prerequisites) {
|
||||||
(
|
(
|
||||||
PathArtifact::from(("/etc/nginx/sites-enabled/".as_ref() as &Path).join(&resource.0)),
|
PathArtifact::from(Path::new("/etc/nginx/sites-enabled/").join(&resource.0)),
|
||||||
(),
|
(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -298,7 +304,7 @@ impl<D: AsRef<Path>, P, POLICY> ResourceLocator<ServePhp<D, P>> for DefaultLocat
|
||||||
resource: &ServePhp<D, P>,
|
resource: &ServePhp<D, P>,
|
||||||
) -> (<ServePhp<D, P> as Resource>::Artifact, Self::Prerequisites) {
|
) -> (<ServePhp<D, P> as Resource>::Artifact, Self::Prerequisites) {
|
||||||
(
|
(
|
||||||
PathArtifact::from(("/etc/nginx/sites-enabled/".as_ref() as &Path).join(&resource.0)),
|
PathArtifact::from(Path::new("/etc/nginx/sites-enabled/").join(&resource.0)),
|
||||||
(),
|
(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -313,7 +319,7 @@ impl<D: AsRef<Path>, P, POLICY> ResourceLocator<ServeService<D, P>> for DefaultL
|
||||||
Self::Prerequisites,
|
Self::Prerequisites,
|
||||||
) {
|
) {
|
||||||
(
|
(
|
||||||
PathArtifact::from(("/etc/nginx/sites-enabled/".as_ref() as &Path).join(&resource.0)),
|
PathArtifact::from(Path::new("/etc/nginx/sites-enabled/").join(&resource.0)),
|
||||||
(),
|
(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -325,7 +331,7 @@ impl<D: AsRef<Path>, POLICY> ResourceLocator<ServeRedir<D>> for DefaultLocator<P
|
||||||
resource: &ServeRedir<D>,
|
resource: &ServeRedir<D>,
|
||||||
) -> (<ServeRedir<D> as Resource>::Artifact, Self::Prerequisites) {
|
) -> (<ServeRedir<D> as Resource>::Artifact, Self::Prerequisites) {
|
||||||
(
|
(
|
||||||
PathArtifact::from(("/etc/nginx/sites-enabled/".as_ref() as &Path).join(&resource.0)),
|
PathArtifact::from(Path::new("/etc/nginx/sites-enabled/").join(&resource.0)),
|
||||||
(),
|
(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -340,7 +346,7 @@ impl<D: AsRef<Path>, P, POLICY> ResourceLocator<ServeStatic<D, P>> for DefaultLo
|
||||||
Self::Prerequisites,
|
Self::Prerequisites,
|
||||||
) {
|
) {
|
||||||
(
|
(
|
||||||
PathArtifact::from(("/etc/nginx/sites-enabled/".as_ref() as &Path).join(&resource.0)),
|
PathArtifact::from(Path::new("/etc/nginx/sites-enabled/").join(&resource.0)),
|
||||||
(),
|
(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ pub struct FilteringLogger<'a, L> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, L> FilteringLogger<'a, L> {
|
impl<'a, L> FilteringLogger<'a, L> {
|
||||||
pub fn new(logger: &'a L, max_level: Level) -> Self {
|
pub const fn new(logger: &'a L, max_level: Level) -> Self {
|
||||||
Self { logger, max_level }
|
Self { logger, max_level }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -104,6 +104,7 @@ pub struct StoringLogger {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StoringLogger {
|
impl StoringLogger {
|
||||||
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,6 @@ pub use symbol_runner::{
|
||||||
SymbolRunner,
|
SymbolRunner,
|
||||||
};
|
};
|
||||||
mod runnable;
|
mod runnable;
|
||||||
|
#[allow(clippy::module_inception)]
|
||||||
mod setup;
|
mod setup;
|
||||||
pub use setup::SetupFacade as Setup;
|
pub use setup::SetupFacade as Setup;
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ pub trait Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait(?Send)]
|
#[async_trait(?Send)]
|
||||||
|
#[allow(clippy::use_self)]
|
||||||
impl<S> Runnable for S
|
impl<S> Runnable for S
|
||||||
where
|
where
|
||||||
Self: Symbol + Debug,
|
Self: Symbol + Debug,
|
||||||
|
|
@ -32,6 +33,7 @@ where
|
||||||
|
|
||||||
macro_rules! runnable_for_tuple {
|
macro_rules! runnable_for_tuple {
|
||||||
( $($name:ident)* ) => (
|
( $($name:ident)* ) => (
|
||||||
|
#[allow(clippy::let_unit_value)]
|
||||||
#[async_trait(?Send)]
|
#[async_trait(?Send)]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
impl<$($name: Symbol + Debug,)*> Runnable for ($($name,)*) {
|
impl<$($name: Symbol + Debug,)*> Runnable for ($($name,)*) {
|
||||||
|
|
@ -117,7 +119,7 @@ mod test {
|
||||||
async fn run_symbol<S: Symbol + Debug, L: Logger>(
|
async fn run_symbol<S: Symbol + Debug, L: Logger>(
|
||||||
&self,
|
&self,
|
||||||
symbol: &S,
|
symbol: &S,
|
||||||
logger: &L,
|
_logger: &L,
|
||||||
force: bool,
|
force: bool,
|
||||||
) -> Result<bool, Box<dyn Error>> {
|
) -> Result<bool, Box<dyn Error>> {
|
||||||
let run = force || !symbol.target_reached().await?;
|
let run = force || !symbol.target_reached().await?;
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@ mod test {
|
||||||
async fn run_symbol<S: Symbol + Debug, L: Logger>(
|
async fn run_symbol<S: Symbol + Debug, L: Logger>(
|
||||||
&self,
|
&self,
|
||||||
symbol: &S,
|
symbol: &S,
|
||||||
logger: &L,
|
_logger: &L,
|
||||||
force: bool,
|
force: bool,
|
||||||
) -> Result<bool, Box<dyn Error>> {
|
) -> Result<bool, Box<dyn Error>> {
|
||||||
let run = force || !symbol.target_reached().await?;
|
let run = force || !symbol.target_reached().await?;
|
||||||
|
|
@ -239,10 +239,12 @@ mod test {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Artifacts;
|
struct Artifacts;
|
||||||
impl<V> FromArtifact<TestResource<V>> for Artifacts {
|
impl<V> FromArtifact<TestResource<V>> for Artifacts {
|
||||||
fn from_artifact(from: ()) -> Self {
|
fn from_artifact(_from: ()) -> Self {
|
||||||
Self
|
Self
|
||||||
}
|
}
|
||||||
|
#[allow(clippy::unused_unit)]
|
||||||
fn into_artifact(self) -> () {
|
fn into_artifact(self) -> () {
|
||||||
|
#[allow(clippy::unused_unit)]
|
||||||
()
|
()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,27 +17,14 @@ pub trait SymbolRunner {
|
||||||
) -> Result<bool, Box<dyn Error>>;
|
) -> Result<bool, Box<dyn Error>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
pub enum SymbolRunError {
|
pub struct ExecuteDidNotReachError;
|
||||||
Symbol(Box<dyn Error>),
|
|
||||||
ExecuteDidNotReach(()),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error for SymbolRunError {
|
impl Error for ExecuteDidNotReachError {}
|
||||||
fn cause(&self) -> Option<&dyn Error> {
|
|
||||||
match self {
|
|
||||||
Self::Symbol(ref e) => Some(&**e),
|
|
||||||
Self::ExecuteDidNotReach(_) => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for SymbolRunError {
|
impl fmt::Display for ExecuteDidNotReachError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
write!(f, "Target not reached after executing symbol")
|
||||||
Self::Symbol(ref e) => write!(f, "{}", e),
|
|
||||||
Self::ExecuteDidNotReach(_) => write!(f, "Target not reached after executing symbol"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,7 +32,8 @@ impl fmt::Display for SymbolRunError {
|
||||||
pub struct InitializingSymbolRunner;
|
pub struct InitializingSymbolRunner;
|
||||||
|
|
||||||
impl InitializingSymbolRunner {
|
impl InitializingSymbolRunner {
|
||||||
pub fn new() -> Self {
|
#[must_use]
|
||||||
|
pub const fn new() -> Self {
|
||||||
Self
|
Self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,7 +52,7 @@ impl InitializingSymbolRunner {
|
||||||
if target_reached {
|
if target_reached {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(Box::new(SymbolRunError::ExecuteDidNotReach(())))
|
Err(Box::new(ExecuteDidNotReachError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +90,8 @@ impl SymbolRunner for InitializingSymbolRunner {
|
||||||
pub struct DelayingSymbolRunner<R>(R);
|
pub struct DelayingSymbolRunner<R>(R);
|
||||||
|
|
||||||
impl<R> DelayingSymbolRunner<R> {
|
impl<R> DelayingSymbolRunner<R> {
|
||||||
pub fn new(symbol_runner: R) -> Self {
|
#[must_use]
|
||||||
|
pub const fn new(symbol_runner: R) -> Self {
|
||||||
Self(symbol_runner)
|
Self(symbol_runner)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +126,8 @@ where
|
||||||
pub struct DrySymbolRunner;
|
pub struct DrySymbolRunner;
|
||||||
|
|
||||||
impl DrySymbolRunner {
|
impl DrySymbolRunner {
|
||||||
pub fn new() -> Self {
|
#[must_use]
|
||||||
|
pub const fn new() -> Self {
|
||||||
Self
|
Self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -172,7 +162,8 @@ impl SymbolRunner for DrySymbolRunner {
|
||||||
pub struct ReportingSymbolRunner<R>(R);
|
pub struct ReportingSymbolRunner<R>(R);
|
||||||
|
|
||||||
impl<R> ReportingSymbolRunner<R> {
|
impl<R> ReportingSymbolRunner<R> {
|
||||||
pub fn new(symbol_runner: R) -> Self {
|
#[must_use]
|
||||||
|
pub const fn new(symbol_runner: R) -> Self {
|
||||||
Self(symbol_runner)
|
Self(symbol_runner)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -251,6 +242,7 @@ mod test {
|
||||||
T: Iterator<Item = Result<bool, Box<dyn Error>>>,
|
T: Iterator<Item = Result<bool, Box<dyn Error>>>,
|
||||||
> DummySymbol<T, E>
|
> DummySymbol<T, E>
|
||||||
{
|
{
|
||||||
|
#[must_use]
|
||||||
fn new<
|
fn new<
|
||||||
IE: IntoIterator<IntoIter = E, Item = Result<(), Box<dyn Error>>>,
|
IE: IntoIterator<IntoIter = E, Item = Result<(), Box<dyn Error>>>,
|
||||||
IT: IntoIterator<IntoIter = T, Item = Result<bool, Box<dyn Error>>>,
|
IT: IntoIterator<IntoIter = T, Item = Result<bool, Box<dyn Error>>>,
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ pub trait Storage {
|
||||||
pub struct SimpleStorage(PathBuf);
|
pub struct SimpleStorage(PathBuf);
|
||||||
|
|
||||||
impl SimpleStorage {
|
impl SimpleStorage {
|
||||||
|
#[must_use]
|
||||||
pub const fn new(base: PathBuf) -> Self {
|
pub const fn new(base: PathBuf) -> Self {
|
||||||
Self(base)
|
Self(base)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ pub struct Dir<P> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P> Dir<P> {
|
impl<P> Dir<P> {
|
||||||
pub fn new(path: P) -> Self {
|
pub const fn new(path: P) -> Self {
|
||||||
Self { path }
|
Self { path }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ pub struct File<D, C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D, C> File<D, C> {
|
impl<D, C> File<D, C> {
|
||||||
pub fn new(path: D, content: C) -> Self {
|
pub const fn new(path: D, content: C) -> Self {
|
||||||
Self { path, content }
|
Self { path, content }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,12 @@ impl<C: CommandRunner, _C: Borrow<C>, P: AsRef<Path>, S: AsRef<str>, B: AsRef<st
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn execute(&self) -> Result<(), Box<dyn Error>> {
|
async fn execute(&self) -> Result<(), Box<dyn Error>> {
|
||||||
if !self.target.as_ref().exists() {
|
if self.target.as_ref().exists() {
|
||||||
|
self
|
||||||
|
.run_git(&["fetch", self.source.as_ref(), self.branch.as_ref()])
|
||||||
|
.await?;
|
||||||
|
self.run_git(&["merge", "FETCH_HEAD"]).await?;
|
||||||
|
} else {
|
||||||
self
|
self
|
||||||
.command_runner
|
.command_runner
|
||||||
.borrow()
|
.borrow()
|
||||||
|
|
@ -80,11 +85,6 @@ impl<C: CommandRunner, _C: Borrow<C>, P: AsRef<Path>, S: AsRef<str>, B: AsRef<st
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
} else {
|
|
||||||
self
|
|
||||||
.run_git(&["fetch", self.source.as_ref(), self.branch.as_ref()])
|
|
||||||
.await?;
|
|
||||||
self.run_git(&["merge", "FETCH_HEAD"]).await?;
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ pub struct GitSubmodules<'a, P, C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, P, C> GitSubmodules<'a, P, C> {
|
impl<'a, P, C> GitSubmodules<'a, P, C> {
|
||||||
pub fn new(target: P, command_runner: &'a C) -> Self {
|
pub const fn new(target: P, command_runner: &'a C) -> Self {
|
||||||
Self {
|
Self {
|
||||||
target,
|
target,
|
||||||
command_runner,
|
command_runner,
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ impl<'a, N, C: CommandRunner, S> Dump<'a, N, C, S> {
|
||||||
impl<N: AsRef<str>, C: CommandRunner, S: Storage> Symbol for Dump<'_, N, C, S> {
|
impl<N: AsRef<str>, C: CommandRunner, S: Storage> Symbol for Dump<'_, N, C, S> {
|
||||||
async fn target_reached(&self) -> Result<bool, Box<dyn Error>> {
|
async fn target_reached(&self) -> Result<bool, Box<dyn Error>> {
|
||||||
let dump_date = self.storage.recent_date()?;
|
let dump_date = self.storage.recent_date()?;
|
||||||
let _modified_date = self.run_sql(&format!("select UNIX_TIMESTAMP(MAX(UPDATE_TIME)) from information_schema.tables WHERE table_schema = '{}'", self.db_name.as_ref())).await?;
|
let output = self.run_sql(&format!("select UNIX_TIMESTAMP(MAX(UPDATE_TIME)) from information_schema.tables WHERE table_schema = '{}'", self.db_name.as_ref())).await?;
|
||||||
let modified_date = _modified_date.trim_end();
|
let modified_date = output.trim_end();
|
||||||
Ok(modified_date != "NULL" && u64::from_str(modified_date)? <= dump_date)
|
Ok(modified_date != "NULL" && u64::from_str(modified_date)? <= dump_date)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ pub struct UserSession<'a, U, C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, U, C> UserSession<'a, U, C> {
|
impl<'a, U, C> UserSession<'a, U, C> {
|
||||||
pub fn new(user_name: U, command_runner: &'a C) -> Self {
|
pub const fn new(user_name: U, command_runner: &'a C) -> Self {
|
||||||
Self {
|
Self {
|
||||||
user_name,
|
user_name,
|
||||||
command_runner,
|
command_runner,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ pub struct Csr<C, D, K, P> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, D, K, P> Csr<C, D, K, P> {
|
impl<C, D, K, P> Csr<C, D, K, P> {
|
||||||
pub fn new(command_runner: C, domain: D, key_path: K, csr_path: P) -> Self {
|
pub const fn new(command_runner: C, domain: D, key_path: K, csr_path: P) -> Self {
|
||||||
Self {
|
Self {
|
||||||
command_runner,
|
command_runner,
|
||||||
domain,
|
domain,
|
||||||
|
|
|
||||||
|
|
@ -8,19 +8,17 @@ use std::path::Path;
|
||||||
pub struct Key<C, P> {
|
pub struct Key<C, P> {
|
||||||
file_path: P,
|
file_path: P,
|
||||||
command_runner: C,
|
command_runner: C,
|
||||||
|
bytes: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, P> Key<C, P> {
|
impl<C, P> Key<C, P> {
|
||||||
pub fn new(command_runner: C, file_path: P) -> Self {
|
pub const fn new(command_runner: C, file_path: P) -> Self {
|
||||||
Self {
|
Self {
|
||||||
file_path,
|
file_path,
|
||||||
command_runner,
|
command_runner,
|
||||||
|
bytes: 4096,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_bytes(&self) -> u32 {
|
|
||||||
4096
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait(?Send)]
|
#[async_trait(?Send)]
|
||||||
|
|
@ -57,7 +55,7 @@ impl<C: CommandRunner, P: AsRef<Path>> Symbol for Key<C, P> {
|
||||||
"genrsa",
|
"genrsa",
|
||||||
"-out",
|
"-out",
|
||||||
self.file_path.as_ref(),
|
self.file_path.as_ref(),
|
||||||
self.get_bytes().to_string(),
|
self.bytes.to_string(),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ pub struct User<U, C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U, C> User<U, C> {
|
impl<U, C> User<U, C> {
|
||||||
pub fn new(user_name: U, command_runner: C) -> Self {
|
pub const fn new(user_name: U, command_runner: C) -> Self {
|
||||||
Self {
|
Self {
|
||||||
user_name,
|
user_name,
|
||||||
command_runner,
|
command_runner,
|
||||||
|
|
@ -41,7 +41,7 @@ impl<U: AsRef<str>, C: CommandRunner> Symbol for User<U, C> {
|
||||||
// adduser is not reentrant because finding the next uid
|
// adduser is not reentrant because finding the next uid
|
||||||
// and creating the account is not an atomic operation
|
// and creating the account is not an atomic operation
|
||||||
let wait = WAIT.acquire().await;
|
let wait = WAIT.acquire().await;
|
||||||
self
|
let res = self
|
||||||
.command_runner
|
.command_runner
|
||||||
.run_successfully(
|
.run_successfully(
|
||||||
"adduser",
|
"adduser",
|
||||||
|
|
@ -51,7 +51,9 @@ impl<U: AsRef<str>, C: CommandRunner> Symbol for User<U, C> {
|
||||||
self.user_name.as_ref(),
|
self.user_name.as_ref(),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
.await
|
.await;
|
||||||
|
drop(wait);
|
||||||
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
pub fn default_server<P: AsRef<Path>>(challenges_snippet_path: P) -> String {
|
pub fn default_server<P: AsRef<Path>>(challenges_snippet_path: P) -> String {
|
||||||
format!(
|
format!(
|
||||||
"server {{
|
"server {{
|
||||||
|
|
@ -12,6 +13,7 @@ pub fn default_server<P: AsRef<Path>>(challenges_snippet_path: P) -> String {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
pub fn server_config<D: Display, C: AsRef<Path>, K: AsRef<Path>, T: Display, S: AsRef<Path>>(
|
pub fn server_config<D: Display, C: AsRef<Path>, K: AsRef<Path>, T: Display, S: AsRef<Path>>(
|
||||||
domain: D,
|
domain: D,
|
||||||
cert_path: C,
|
cert_path: C,
|
||||||
|
|
@ -53,6 +55,7 @@ server {{
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
pub fn php_snippet<SOCKET: AsRef<Path>, STATIC: AsRef<Path>>(
|
pub fn php_snippet<SOCKET: AsRef<Path>, STATIC: AsRef<Path>>(
|
||||||
index: &'static str,
|
index: &'static str,
|
||||||
socket_path: SOCKET,
|
socket_path: SOCKET,
|
||||||
|
|
@ -71,6 +74,7 @@ pub fn php_snippet<SOCKET: AsRef<Path>, STATIC: AsRef<Path>>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
pub fn redir_snippet(target: &str) -> String {
|
pub fn redir_snippet(target: &str) -> String {
|
||||||
format!(
|
format!(
|
||||||
"location / {{
|
"location / {{
|
||||||
|
|
@ -85,6 +89,7 @@ pub trait SocketSpec {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsRef<Path>> SocketSpec for T {
|
impl<T: AsRef<Path>> SocketSpec for T {
|
||||||
|
#[must_use]
|
||||||
fn to_nginx(&self) -> String {
|
fn to_nginx(&self) -> String {
|
||||||
format!("unix:{}:", self.as_ref().to_str().unwrap())
|
format!("unix:{}:", self.as_ref().to_str().unwrap())
|
||||||
}
|
}
|
||||||
|
|
@ -94,17 +99,20 @@ impl<T: AsRef<Path>> SocketSpec for T {
|
||||||
pub struct LocalTcpSocket(usize);
|
pub struct LocalTcpSocket(usize);
|
||||||
|
|
||||||
impl LocalTcpSocket {
|
impl LocalTcpSocket {
|
||||||
|
#[must_use]
|
||||||
pub const fn new(x: usize) -> Self {
|
pub const fn new(x: usize) -> Self {
|
||||||
Self(x)
|
Self(x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SocketSpec for LocalTcpSocket {
|
impl SocketSpec for LocalTcpSocket {
|
||||||
|
#[must_use]
|
||||||
fn to_nginx(&self) -> String {
|
fn to_nginx(&self) -> String {
|
||||||
format!("localhost:{}", self.0)
|
format!("localhost:{}", self.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
pub fn proxy_snippet<S: SocketSpec, STATIC: AsRef<Path>>(
|
pub fn proxy_snippet<S: SocketSpec, STATIC: AsRef<Path>>(
|
||||||
socket_path: &S,
|
socket_path: &S,
|
||||||
static_path: STATIC,
|
static_path: STATIC,
|
||||||
|
|
@ -125,6 +133,7 @@ pub fn proxy_snippet<S: SocketSpec, STATIC: AsRef<Path>>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
pub fn static_snippet<S: AsRef<Path>>(static_path: S) -> String {
|
pub fn static_snippet<S: AsRef<Path>>(static_path: S) -> String {
|
||||||
format!(
|
format!(
|
||||||
"root {};
|
"root {};
|
||||||
|
|
@ -134,6 +143,7 @@ pub fn static_snippet<S: AsRef<Path>>(static_path: S) -> String {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
pub fn dokuwiki_snippet() -> String {
|
pub fn dokuwiki_snippet() -> String {
|
||||||
"
|
"
|
||||||
location ~ /(data/|conf/|bin/|inc/|install.php) { deny all; }
|
location ~ /(data/|conf/|bin/|inc/|install.php) { deny all; }
|
||||||
|
|
@ -149,6 +159,7 @@ pub fn dokuwiki_snippet() -> String {
|
||||||
}".into()
|
}".into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
pub fn nextcloud_snippet() -> String {
|
pub fn nextcloud_snippet() -> String {
|
||||||
"
|
"
|
||||||
client_max_body_size 500M;
|
client_max_body_size 500M;
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ macro_rules! to_artifact {
|
||||||
for_each_tuple!(to_artifact);
|
for_each_tuple!(to_artifact);
|
||||||
|
|
||||||
impl<T: Resource> ToArtifact for Option<T> {
|
impl<T: Resource> ToArtifact for Option<T> {
|
||||||
|
// FIXME: https://github.com/rust-lang/rust-clippy/issues/2843
|
||||||
|
#![allow(clippy::use_self)]
|
||||||
type Artifact = Option<T::Artifact>;
|
type Artifact = Option<T::Artifact>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue