Compare commits

..

4 commits

6 changed files with 27 additions and 23 deletions

View file

@ -456,11 +456,11 @@ impl<D, P: AsRef<Path>> ImplementationBuilder<SystemdSocketService<D, P>> for De
FileSymbol::new( FileSymbol::new(
conf_path.clone_rc(), conf_path.clone_rc(),
if resource.4 { if resource.4 {
systemd_nodejs_service(&resource.2, socket_path, &resource.3) systemd_nodejs_service(resource.2.as_ref(), socket_path, &resource.3)
} else { } else {
systemd_socket_service( systemd_socket_service(
socket_path, socket_path,
resource.2.as_ref().to_str().unwrap(), &resource.2,
&resource.3, &resource.3,
"", "",
) )

View file

@ -5,6 +5,7 @@ use crate::artifacts::{
use crate::templates::php::FpmPoolConfig; use crate::templates::php::FpmPoolConfig;
use std::hash::Hash; use std::hash::Hash;
use std::path::Path; use std::path::Path;
use std::ffi::OsStr;
pub trait Resource { pub trait Resource {
type Artifact; type Artifact;
@ -136,7 +137,7 @@ impl Resource for User {
} }
#[derive(Debug, Hash, PartialEq, Eq)] #[derive(Debug, Hash, PartialEq, Eq)]
pub struct SystemdSocketService<D, P>(pub D, pub &'static str, pub P, pub P, pub bool); pub struct SystemdSocketService<D, P>(pub D, pub &'static str, pub Rc<OsStr>, pub P, pub bool);
impl<D, P> Resource for SystemdSocketService<D, P> { impl<D, P> Resource for SystemdSocketService<D, P> {
type Artifact = (PathArtifact, PathArtifact, UserNameArtifact); type Artifact = (PathArtifact, PathArtifact, UserNameArtifact);
} }
@ -179,7 +180,7 @@ impl<D, P, C> Resource for ServePhp<D, P, C> {
// Domain, service name, exec, static, dir // Domain, service name, exec, static, dir
#[derive(Debug, Hash, PartialEq, Eq)] #[derive(Debug, Hash, PartialEq, Eq)]
pub struct ServeService<D, P>(pub D, pub &'static str, pub P, pub P, pub P, pub bool); pub struct ServeService<D, P>(pub D, pub &'static str, pub Rc<OsStr>, pub P, pub P, pub bool);
impl<D, P> Resource for ServeService<D, P> { impl<D, P> Resource for ServeService<D, P> {
type Artifact = PathArtifact; type Artifact = PathArtifact;
} }
@ -187,7 +188,7 @@ impl<D> ServeService<D, Rc<Path>> {
pub fn new( pub fn new(
domain: D, domain: D,
service_name: &'static str, service_name: &'static str,
exec: impl Into<Rc<Path>>, exec: impl Into<Rc<OsStr>>,
static_path: impl Into<Rc<Path>>, static_path: impl Into<Rc<Path>>,
working_directory: impl Into<Rc<Path>>, working_directory: impl Into<Rc<Path>>,
is_nodejs: bool, is_nodejs: bool,

View file

@ -1,5 +1,5 @@
use crate::async_utils::sleep; use crate::async_utils::sleep;
use crate::command_runner::{CommandRunner, SetuidCommandRunner}; use crate::command_runner::{CommandRunner, StdCommandRunner, SetuidCommandRunner};
use crate::symbols::Symbol; use crate::symbols::Symbol;
use async_trait::async_trait; use async_trait::async_trait;
use std::error::Error; use std::error::Error;
@ -12,6 +12,7 @@ pub struct UserService<'a, S: AsRef<Path>, U: AsRef<str>> {
socket_path: S, socket_path: S,
service_name: &'a str, service_name: &'a str,
command_runner: SetuidCommandRunner<U>, command_runner: SetuidCommandRunner<U>,
root_command_runner: StdCommandRunner,
} }
impl<S: AsRef<Path>, U: AsRef<str>> UserService<'static, S, U> { impl<S: AsRef<Path>, U: AsRef<str>> UserService<'static, S, U> {
@ -20,13 +21,14 @@ impl<S: AsRef<Path>, U: AsRef<str>> UserService<'static, S, U> {
socket_path, socket_path,
service_name, service_name,
command_runner: SetuidCommandRunner::new(user_name), command_runner: SetuidCommandRunner::new(user_name),
root_command_runner: StdCommandRunner,
} }
} }
} }
impl<S: AsRef<Path>, U: AsRef<str>> UserService<'_, S, U> { impl<S: AsRef<Path>, U: AsRef<str>> UserService<'_, S, U> {
async fn systemctl_wait_for_dbus(&self, args: &[&OsStr]) -> Result<String, Box<dyn Error>> { async fn systemctl_wait_for_dbus(&self, args: &[&OsStr]) -> Result<String, Box<dyn Error>> {
let mut tries = 5; let mut tries = 10;
loop { loop {
let result = self.command_runner.run_with_args("systemctl", args).await?; let result = self.command_runner.run_with_args("systemctl", args).await?;
if result.status.success() { if result.status.success() {
@ -34,14 +36,15 @@ impl<S: AsRef<Path>, U: AsRef<str>> UserService<'_, S, U> {
} }
let raw_stderr = std::str::from_utf8(&result.stderr)?; let raw_stderr = std::str::from_utf8(&result.stderr)?;
let stderr = raw_stderr.trim_end(); let stderr = raw_stderr.trim_end();
if stderr != "Failed to connect to bus: No such file or directory" { if stderr != "Failed to connect to bus: No such file or directory" &&
stderr != "Failed to connect to user scope bus via local transport: No such file or directory" {
return Err(stderr.into()); return Err(stderr.into());
} }
tries -= 1; tries -= 1;
if tries == 0 { if tries == 0 {
return Err("Gave up waiting for dbus to appear".to_string().into()); return Err("Gave up waiting for dbus to appear".to_string().into());
} }
sleep(Duration::from_millis(500)).await; sleep(Duration::from_millis(100)).await;
} }
} }
@ -63,10 +66,10 @@ impl<S: AsRef<Path>, U: AsRef<str>> UserService<'_, S, U> {
return Err( return Err(
std::str::from_utf8( std::str::from_utf8(
&self &self
.command_runner .root_command_runner
.get_output( .get_output(
"journalctl", "journalctl",
args!["--user", format!("--user-unit={}", self.service_name)], args![ /*"--user", format!("--user-unit={}", self.service_name)*/ ],
) )
.await?, .await?,
)? )?

View file

@ -27,8 +27,10 @@ mod test {
"/challenges_snippet.conf" "/challenges_snippet.conf"
), ),
"server { "server {
listen 443 ssl http2; listen 443 ssl;
listen [::]:443 ssl http2; listen [::]:443 ssl;
http2 on;
server_name testdomain; server_name testdomain;
include \"/challenges_snippet.conf\"; include \"/challenges_snippet.conf\";

View file

@ -24,8 +24,10 @@ pub fn server_config<D: Display, C: AsRef<Path>, K: AsRef<Path>, T: Display, S:
) -> String { ) -> String {
format!( format!(
"server {{ "server {{
listen 443 ssl http2; listen 443 ssl;
listen [::]:443 ssl http2; listen [::]:443 ssl;
http2 on;
server_name {}; server_name {};
include \"{}\"; include \"{}\";
@ -90,12 +92,10 @@ pub trait SocketSpec {
} }
impl<T: AsRef<Path>> SocketSpec for T { impl<T: AsRef<Path>> SocketSpec for T {
#[must_use]
fn to_proxy_pass(&self) -> String { fn to_proxy_pass(&self) -> String {
format!("unix:{}:", self.as_ref().to_str().unwrap()) format!("unix:{}:", self.as_ref().to_str().unwrap())
} }
#[must_use]
fn to_uwsgi_pass(&self) -> String { fn to_uwsgi_pass(&self) -> String {
format!("unix:{}", self.as_ref().to_str().unwrap()) format!("unix:{}", self.as_ref().to_str().unwrap())
} }
@ -105,19 +105,16 @@ impl<T: AsRef<Path>> SocketSpec for T {
pub struct LocalTcpSocket(NonZeroUsize); pub struct LocalTcpSocket(NonZeroUsize);
impl LocalTcpSocket { impl LocalTcpSocket {
#[must_use]
pub const fn new(x: NonZeroUsize) -> Self { pub const fn new(x: NonZeroUsize) -> Self {
Self(x) Self(x)
} }
} }
impl SocketSpec for LocalTcpSocket { impl SocketSpec for LocalTcpSocket {
#[must_use]
fn to_proxy_pass(&self) -> String { fn to_proxy_pass(&self) -> String {
format!("localhost:{}", self.0) format!("localhost:{}", self.0)
} }
#[must_use]
fn to_uwsgi_pass(&self) -> String { fn to_uwsgi_pass(&self) -> String {
format!("localhost:{}", self.0) format!("localhost:{}", self.0)
} }

View file

@ -1,8 +1,9 @@
use std::path::Path; use std::path::Path;
use std::ffi::OsStr;
pub fn socket_service( pub fn socket_service(
socket_path: impl AsRef<Path>, socket_path: impl AsRef<Path>,
exec: &str, exec: &OsStr,
dir: impl AsRef<Path>, dir: impl AsRef<Path>,
additional: &str, additional: &str,
) -> String { ) -> String {
@ -18,7 +19,7 @@ Restart=always
WantedBy=default.target WantedBy=default.target
", ",
socket_path.as_ref().to_str().unwrap(), socket_path.as_ref().to_str().unwrap(),
exec, exec.display(),
dir.as_ref().to_str().unwrap(), dir.as_ref().to_str().unwrap(),
additional additional
) )
@ -31,7 +32,7 @@ pub fn nodejs_service<N: AsRef<Path>, S: AsRef<Path>>(
) -> String { ) -> String {
socket_service( socket_service(
&socket_path, &socket_path,
&format!("/usr/bin/nodejs {}", nodejs_path.as_ref().to_str().unwrap()), format!("/usr/bin/nodejs {}", nodejs_path.as_ref().to_str().unwrap()).as_ref(),
dir, dir,
&format!( &format!(
"Environment=NODE_ENV=production "Environment=NODE_ENV=production