Merge branch 'malte/daemon' into 'main'
Add daemon CLI commands See merge request husk-project/husk-milter!7
This commit is contained in:
Generated
+159
-17
@@ -356,7 +356,7 @@ dependencies = [
|
|||||||
"js-sys",
|
"js-sys",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"windows-link",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -551,6 +551,15 @@ version = "0.0.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1"
|
checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "daemonix"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0b747381562a10fd2104e9333ad72fe5158d79de81b64426fc9e229c6d3fb38"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "data-encoding"
|
name = "data-encoding"
|
||||||
version = "2.11.0"
|
version = "2.11.0"
|
||||||
@@ -975,7 +984,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8"
|
checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustix",
|
"rustix",
|
||||||
"windows-link",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1205,6 +1214,7 @@ dependencies = [
|
|||||||
"bytes",
|
"bytes",
|
||||||
"clap",
|
"clap",
|
||||||
"clap_complete",
|
"clap_complete",
|
||||||
|
"daemonix",
|
||||||
"fastrand",
|
"fastrand",
|
||||||
"indymilter",
|
"indymilter",
|
||||||
"log",
|
"log",
|
||||||
@@ -1217,6 +1227,7 @@ dependencies = [
|
|||||||
"sequoia-wot",
|
"sequoia-wot",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
|
"sysinfo",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror 2.0.18",
|
"thiserror 2.0.18",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -1312,7 +1323,7 @@ dependencies = [
|
|||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"windows-core",
|
"windows-core 0.62.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1467,7 +1478,7 @@ dependencies = [
|
|||||||
"socket2",
|
"socket2",
|
||||||
"widestring",
|
"widestring",
|
||||||
"windows-registry",
|
"windows-registry",
|
||||||
"windows-result",
|
"windows-result 0.4.1",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1638,7 +1649,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
|
checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"windows-link",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1861,6 +1872,15 @@ dependencies = [
|
|||||||
"minimal-lexical",
|
"minimal-lexical",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ntapi"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3b335231dfd352ffb0f8017f3b6027a4917f7df785ea2143d8af2adc66980ae"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.19"
|
version = "0.2.19"
|
||||||
@@ -1880,6 +1900,25 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc2-core-foundation"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc2-io-kit"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"objc2-core-foundation",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.21.4"
|
version = "1.21.4"
|
||||||
@@ -1987,7 +2026,7 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"windows-link",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2602,7 +2641,7 @@ dependencies = [
|
|||||||
"sequoia-keystore-gpg-agent",
|
"sequoia-keystore-gpg-agent",
|
||||||
"sequoia-keystore-softkeys",
|
"sequoia-keystore-softkeys",
|
||||||
"sequoia-openpgp",
|
"sequoia-openpgp",
|
||||||
"thiserror 1.0.69",
|
"thiserror 2.0.18",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
]
|
]
|
||||||
@@ -2619,7 +2658,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"sequoia-openpgp",
|
"sequoia-openpgp",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror 1.0.69",
|
"thiserror 2.0.18",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2980,6 +3019,20 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sysinfo"
|
||||||
|
version = "0.36.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "252800745060e7b9ffb7b2badbd8b31cfa4aa2e61af879d0a3bf2a317c20217d"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"memchr",
|
||||||
|
"ntapi",
|
||||||
|
"objc2-core-foundation",
|
||||||
|
"objc2-io-kit",
|
||||||
|
"windows",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "system-configuration"
|
name = "system-configuration"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@@ -3549,6 +3602,41 @@ version = "0.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows"
|
||||||
|
version = "0.61.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
|
||||||
|
dependencies = [
|
||||||
|
"windows-collections",
|
||||||
|
"windows-core 0.61.2",
|
||||||
|
"windows-future",
|
||||||
|
"windows-link 0.1.3",
|
||||||
|
"windows-numerics",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-collections"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
|
||||||
|
dependencies = [
|
||||||
|
"windows-core 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-core"
|
||||||
|
version = "0.61.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
|
||||||
|
dependencies = [
|
||||||
|
"windows-implement",
|
||||||
|
"windows-interface",
|
||||||
|
"windows-link 0.1.3",
|
||||||
|
"windows-result 0.3.4",
|
||||||
|
"windows-strings 0.4.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-core"
|
name = "windows-core"
|
||||||
version = "0.62.2"
|
version = "0.62.2"
|
||||||
@@ -3557,9 +3645,20 @@ checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-implement",
|
"windows-implement",
|
||||||
"windows-interface",
|
"windows-interface",
|
||||||
"windows-link",
|
"windows-link 0.2.1",
|
||||||
"windows-result",
|
"windows-result 0.4.1",
|
||||||
"windows-strings",
|
"windows-strings 0.5.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-future"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
|
||||||
|
dependencies = [
|
||||||
|
"windows-core 0.61.2",
|
||||||
|
"windows-link 0.1.3",
|
||||||
|
"windows-threading",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3584,21 +3683,46 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-link"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-link"
|
name = "windows-link"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-numerics"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
|
||||||
|
dependencies = [
|
||||||
|
"windows-core 0.61.2",
|
||||||
|
"windows-link 0.1.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-registry"
|
name = "windows-registry"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720"
|
checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-link",
|
"windows-link 0.2.1",
|
||||||
"windows-result",
|
"windows-result 0.4.1",
|
||||||
"windows-strings",
|
"windows-strings 0.5.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-result"
|
||||||
|
version = "0.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link 0.1.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3607,7 +3731,16 @@ version = "0.4.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
|
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-link",
|
"windows-link 0.2.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-strings"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link 0.1.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3616,7 +3749,7 @@ version = "0.5.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
|
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-link",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3652,7 +3785,7 @@ version = "0.61.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-link",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3686,6 +3819,15 @@ dependencies = [
|
|||||||
"windows_x86_64_msvc 0.52.6",
|
"windows_x86_64_msvc 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-threading"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link 0.1.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_gnullvm"
|
name = "windows_aarch64_gnullvm"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
|
|||||||
@@ -28,11 +28,15 @@ sequoia-openpgp = "2.3.0"
|
|||||||
sequoia-wot = "0.15.0"
|
sequoia-wot = "0.15.0"
|
||||||
serde = "1.0.228"
|
serde = "1.0.228"
|
||||||
serde_derive = "1.0.228"
|
serde_derive = "1.0.228"
|
||||||
|
sysinfo = "0.36.1"
|
||||||
tempfile = "3.27.0"
|
tempfile = "3.27.0"
|
||||||
thiserror = "2.0.17"
|
thiserror = "2.0.17"
|
||||||
tokio = { version = "1.52.3", features = [ "tokio-macros", "rt-multi-thread", "signal" ] }
|
tokio = { version = "1.52.3", features = [ "tokio-macros", "rt-multi-thread", "signal" ] }
|
||||||
toml = "0.9.8"
|
toml = "0.9.8"
|
||||||
|
|
||||||
|
[target.'cfg(unix)'.dependencies]
|
||||||
|
daemonix = "0.1.0"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
anyhow = "1.0.100"
|
anyhow = "1.0.100"
|
||||||
clap = { version = "4", features = ["derive"] }
|
clap = { version = "4", features = ["derive"] }
|
||||||
|
|||||||
+15
-1
@@ -53,11 +53,25 @@ pub struct DaemonCommand {
|
|||||||
}
|
}
|
||||||
#[derive(Debug, Subcommand)]
|
#[derive(Debug, Subcommand)]
|
||||||
pub enum DaemonSubcommand {
|
pub enum DaemonSubcommand {
|
||||||
Start,
|
Start(DaemonStartCommand),
|
||||||
Stop,
|
Stop,
|
||||||
Status
|
Status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
#[clap(
|
||||||
|
name = "daemon",
|
||||||
|
about = "Start Husk",
|
||||||
|
)]
|
||||||
|
pub struct DaemonStartCommand {
|
||||||
|
#[clap(
|
||||||
|
long = "background",
|
||||||
|
help = "Start Husk as a background process.",
|
||||||
|
default_value_t = false,
|
||||||
|
)]
|
||||||
|
background: bool,
|
||||||
|
}
|
||||||
|
|
||||||
// Introducer subcommands
|
// Introducer subcommands
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
|
|||||||
@@ -13,6 +13,12 @@ pub mod signkey;
|
|||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum CommandError {
|
pub enum CommandError {
|
||||||
|
#[error("Daemon already running, pid: {0}")]
|
||||||
|
DaemonAlreadyRunning(String),
|
||||||
|
#[error("Invalid pid file path: {0}")]
|
||||||
|
InvalidPidFilePath(String),
|
||||||
|
#[error("Cannot identify process")]
|
||||||
|
CannotIdentifyProcess,
|
||||||
#[error("Certificate not found: {0}")]
|
#[error("Certificate not found: {0}")]
|
||||||
CertNotFound(Fingerprint),
|
CertNotFound(Fingerprint),
|
||||||
#[error("Certificate not usable: {0}")]
|
#[error("Certificate not usable: {0}")]
|
||||||
|
|||||||
+28
-4
@@ -1,20 +1,44 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use crate::cli::cli_args::{DaemonCommand, DaemonSubcommand};
|
use crate::cli::cli_args::{DaemonCommand, DaemonSubcommand};
|
||||||
|
use crate::common::process_descr::ProcessDescr;
|
||||||
use crate::config::HuskConfigContainer;
|
use crate::config::HuskConfigContainer;
|
||||||
|
use crate::config::HuskConfig;
|
||||||
use crate::Daemon;
|
use crate::Daemon;
|
||||||
|
|
||||||
pub async fn dispatch(cmd: DaemonCommand, config: HuskConfigContainer) -> Result<()> {
|
pub async fn dispatch(cmd: DaemonCommand, config: HuskConfigContainer) -> Result<()> {
|
||||||
|
|
||||||
|
let c: HuskConfig = config.clone().into();
|
||||||
|
|
||||||
match cmd.subcommand {
|
match cmd.subcommand {
|
||||||
DaemonSubcommand::Start => {
|
DaemonSubcommand::Start(_sub_cmd) => {
|
||||||
Daemon::run(config).await?;
|
// Write the pid file.
|
||||||
|
let pid_file_name = c.get_pid_file();
|
||||||
|
ProcessDescr::create(pid_file_name.clone())?;
|
||||||
|
|
||||||
|
let result_code = Daemon::run(config).await;
|
||||||
|
|
||||||
|
// and remove it when the daemon terminated.
|
||||||
|
let _ = ProcessDescr::remove(pid_file_name);
|
||||||
|
return result_code;
|
||||||
},
|
},
|
||||||
DaemonSubcommand::Stop => {
|
DaemonSubcommand::Stop => {
|
||||||
println!("stop");
|
let process_descr = ProcessDescr::load(c.get_pid_file())?;
|
||||||
|
if process_descr.send_sig_interrupt().is_ok() {
|
||||||
|
let _ = ProcessDescr::remove(process_descr.file_location);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
DaemonSubcommand::Status => {
|
DaemonSubcommand::Status => {
|
||||||
println!("status");
|
if let Ok(process_descr) = ProcessDescr::load(c.get_pid_file()) {
|
||||||
|
if process_descr.is_running() {
|
||||||
|
println!("Running, with pid: {}", process_descr.pid);
|
||||||
|
} else {
|
||||||
|
println!("Not running, but stale pid file detected: {}",
|
||||||
|
c.get_pid_file());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("Not running");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
pub mod crypto;
|
pub mod crypto;
|
||||||
pub mod escape;
|
pub mod escape;
|
||||||
|
pub mod process_descr;
|
||||||
|
|||||||
@@ -0,0 +1,138 @@
|
|||||||
|
//! pid file handling
|
||||||
|
|
||||||
|
use std::io::Read;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::fs::DirBuilder;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::fs::remove_file;
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use sysinfo::System;
|
||||||
|
use sysinfo::RefreshKind;
|
||||||
|
use sysinfo::Signal;
|
||||||
|
use sysinfo::Pid;
|
||||||
|
use sysinfo::ProcessRefreshKind;
|
||||||
|
use serde::Serialize;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
use crate::commands::CommandError;
|
||||||
|
|
||||||
|
/// The pid file contains to process id, the process name and the time
|
||||||
|
/// the process started. These are used to identify a Husk process.
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct ProcessDescr {
|
||||||
|
pub pid: usize,
|
||||||
|
pub name: String,
|
||||||
|
pub started: u64,
|
||||||
|
pub file_location: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProcessDescr {
|
||||||
|
|
||||||
|
/// Create a file at `location` and populate it with the pid, the
|
||||||
|
/// process name and starting time of the current process.
|
||||||
|
pub fn create(location: String) -> Result<()> {
|
||||||
|
let location_path = PathBuf::from(location.clone());
|
||||||
|
|
||||||
|
let system = System::new_all();
|
||||||
|
let pid = std::process::id();
|
||||||
|
|
||||||
|
if let Some(process) = system.process(Pid::from(pid as usize)) {
|
||||||
|
|
||||||
|
let started = process.start_time();
|
||||||
|
let name = process.name().to_string_lossy().to_string();
|
||||||
|
|
||||||
|
if location_path.exists() {
|
||||||
|
return Err(CommandError::DaemonAlreadyRunning(pid.to_string()).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
// create directory
|
||||||
|
if let Some(path) = location_path.parent() {
|
||||||
|
DirBuilder::new()
|
||||||
|
.recursive(true)
|
||||||
|
.create(path)?;
|
||||||
|
} else {
|
||||||
|
return Err(CommandError::InvalidPidFilePath(location).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut descr_file = File::create(&location_path)?;
|
||||||
|
let content = ProcessDescr {
|
||||||
|
pid: pid as usize,
|
||||||
|
name: name,
|
||||||
|
started: started,
|
||||||
|
file_location: location,
|
||||||
|
};
|
||||||
|
descr_file.write_all(toml::to_string(&content)?.as_bytes())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(CommandError::InvalidPidFilePath(location).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove a pid file
|
||||||
|
pub fn remove(location: String) -> Result<()> {
|
||||||
|
let location_path = PathBuf::from(location.clone());
|
||||||
|
if location_path.is_file() {
|
||||||
|
remove_file(location_path)
|
||||||
|
.map_err(|e| e.into())
|
||||||
|
} else {
|
||||||
|
Err(CommandError::InvalidPidFilePath(location).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load a ProcessDescr object from `location`.
|
||||||
|
pub fn load(location: String) -> Result<Self> {
|
||||||
|
let location_path = PathBuf::from(location.clone());
|
||||||
|
if location_path.is_file() {
|
||||||
|
let mut file = File::open(location_path)?;
|
||||||
|
let mut buf: Vec<u8> = Vec::new();
|
||||||
|
let _ = file.read_to_end(&mut buf)?;
|
||||||
|
let buf = String::from_utf8_lossy(buf.as_slice());
|
||||||
|
let process_descr: ProcessDescr = toml::from_str(buf.to_string().as_str())?;
|
||||||
|
|
||||||
|
Ok(process_descr)
|
||||||
|
} else {
|
||||||
|
Err(CommandError::InvalidPidFilePath(location).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return true if the process described is running.
|
||||||
|
pub fn is_running(&self) -> bool {
|
||||||
|
self.get_process().is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the process identified by the `ProcessDescr`.
|
||||||
|
pub fn get_process(&self) -> Result<Pid> {
|
||||||
|
let system = System::new_with_specifics(
|
||||||
|
RefreshKind::nothing()
|
||||||
|
.with_processes(ProcessRefreshKind::everything())
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(process) = system.process(Pid::from(self.pid)) {
|
||||||
|
let process_name = process.name().to_string_lossy().to_string();
|
||||||
|
if process_name == self.name
|
||||||
|
&& process.start_time() == self.started {
|
||||||
|
return Ok(process.pid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(CommandError::CannotIdentifyProcess.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send SIG_INT to the process identified by the `ProcessDescr`.
|
||||||
|
pub fn send_sig_interrupt(&self) -> Result<()> {
|
||||||
|
let system = System::new_with_specifics(
|
||||||
|
RefreshKind::nothing()
|
||||||
|
.with_processes(ProcessRefreshKind::everything())
|
||||||
|
);
|
||||||
|
let pid = self.get_process()?;
|
||||||
|
|
||||||
|
if let Some(process) = system.process(pid) {
|
||||||
|
process.kill_with(Signal::Interrupt);
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(CommandError::CannotIdentifyProcess.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
-2
@@ -9,7 +9,9 @@ use toml;
|
|||||||
use log4rs;
|
use log4rs;
|
||||||
|
|
||||||
use crate::types::errors::HuskError;
|
use crate::types::errors::HuskError;
|
||||||
use crate::types::defaults::{CONSOLE_LOGGING, SUBJECT_REPLACEMENT};
|
use crate::types::defaults::CONSOLE_LOGGING;
|
||||||
|
use crate::types::defaults::PID_FILE_LOCATION;
|
||||||
|
use crate::types::defaults::SUBJECT_REPLACEMENT;
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
pub struct HuskConfig {
|
pub struct HuskConfig {
|
||||||
@@ -17,6 +19,7 @@ pub struct HuskConfig {
|
|||||||
pub sequoia_home: String,
|
pub sequoia_home: String,
|
||||||
pub keyservers: Option<Vec<String>>,
|
pub keyservers: Option<Vec<String>>,
|
||||||
pub subject_replacement: Option<String>,
|
pub subject_replacement: Option<String>,
|
||||||
|
pub pid_file: Option<String>,
|
||||||
logging: Option<toml::Value>,
|
logging: Option<toml::Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +79,13 @@ impl HuskConfig {
|
|||||||
SUBJECT_REPLACEMENT.to_string()
|
SUBJECT_REPLACEMENT.to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn get_pid_file(&self) -> String {
|
||||||
|
if let Some(pid_file) = &self.pid_file {
|
||||||
|
pid_file.clone()
|
||||||
|
} else {
|
||||||
|
PID_FILE_LOCATION.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type HuskConfigContainer = Arc<Mutex<HuskConfig>>;
|
pub type HuskConfigContainer = Arc<Mutex<HuskConfig>>;
|
||||||
@@ -101,7 +111,8 @@ mod tests {
|
|||||||
sequoia_home: "".into(),
|
sequoia_home: "".into(),
|
||||||
keyservers: None,
|
keyservers: None,
|
||||||
subject_replacement: None,
|
subject_replacement: None,
|
||||||
logging: None
|
logging: None,
|
||||||
|
pid_file: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(config.get_subject_replacement(), defaults::SUBJECT_REPLACEMENT);
|
assert_eq!(config.get_subject_replacement(), defaults::SUBJECT_REPLACEMENT);
|
||||||
|
|||||||
+2
-3
@@ -53,9 +53,8 @@ impl Daemon {
|
|||||||
|
|
||||||
let config = Default::default();
|
let config = Default::default();
|
||||||
|
|
||||||
indymilter::run(listener, callbacks, config, signal::ctrl_c())
|
let _ = indymilter::run(listener, callbacks, config, signal::ctrl_c())
|
||||||
.await
|
.await;
|
||||||
.expect("milter execution failed");
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-1
@@ -6,6 +6,9 @@ use std::sync::{Arc, Mutex};
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use types::defaults;
|
use types::defaults;
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
use daemonix::Daemonize;
|
||||||
|
|
||||||
pub mod cli;
|
pub mod cli;
|
||||||
use cli::cli_args::CliArgs;
|
use cli::cli_args::CliArgs;
|
||||||
pub mod commands;
|
pub mod commands;
|
||||||
@@ -17,8 +20,31 @@ pub mod daemon;
|
|||||||
use daemon::Daemon;
|
use daemon::Daemon;
|
||||||
pub mod common;
|
pub mod common;
|
||||||
|
|
||||||
|
pub fn main() -> anyhow::Result<()> {
|
||||||
|
|
||||||
|
let mut daemonize = 0;
|
||||||
|
// XXX keep this in sync with cli/cli_args.rs
|
||||||
|
for arg in std::env::args() {
|
||||||
|
if arg == "daemon" && daemonize == 0 { daemonize = 1; }
|
||||||
|
if arg == "start" && daemonize == 1 { daemonize = 2; }
|
||||||
|
if arg == "--background" && daemonize == 2 { daemonize = 3; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
if daemonize == 3 {
|
||||||
|
Daemonize::new().start()?;
|
||||||
|
eprintln!("pid: {}", std::process::id());
|
||||||
|
}
|
||||||
|
|
||||||
|
async_main().map_err(|e| {
|
||||||
|
log::error!("exiting: {}", e);
|
||||||
|
e
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn async_main() -> anyhow::Result<()> {
|
||||||
let args = CliArgs::parse();
|
let args = CliArgs::parse();
|
||||||
|
|
||||||
let config_file = match &args.config {
|
let config_file = match &args.config {
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ pub const CONFIG_FILE_LOCATION: &str = "/etc/husk/config.toml";
|
|||||||
/// and replaced by `SUBJECT_REPLACEMENT` (unless configured otherwise).
|
/// and replaced by `SUBJECT_REPLACEMENT` (unless configured otherwise).
|
||||||
pub const SUBJECT_REPLACEMENT: &str = "...";
|
pub const SUBJECT_REPLACEMENT: &str = "...";
|
||||||
|
|
||||||
|
pub const PID_FILE_LOCATION: &str = "/run/husk/pid";
|
||||||
|
|
||||||
/// Default logging configuration.
|
/// Default logging configuration.
|
||||||
pub const CONSOLE_LOGGING: &str = "
|
pub const CONSOLE_LOGGING: &str = "
|
||||||
[appenders.console]
|
[appenders.console]
|
||||||
|
|||||||
Reference in New Issue
Block a user