Implement --daemonize for pueued

This commit is contained in:
Arne Beer 2020-01-28 00:34:55 +01:00
parent fc7c4070ee
commit 4c8331deaa
6 changed files with 41 additions and 8 deletions

2
Cargo.lock generated
View file

@ -773,7 +773,7 @@ dependencies = [
[[package]]
name = "pueue"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
"async-std 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -1,7 +1,7 @@
[package]
name = "pueue"
description = "A cli tool for managing long running shell commands."
version = "0.1.0"
version = "0.1.1"
authors = ["Arne Beer <contact@arne.beer>"]
homepage = "https://github.com/nukesor/pueue"
repository = "https://github.com/nukesor/pueue"

View file

@ -163,6 +163,13 @@ This would help me a lot!
## Starting the Daemon
### Local
Just run `pueued` anywhere on your commandline. It'll exit if you close the terminal, though.
### Background
To fork `pueued` into the background, add the `-d` or `--daemonize` flag. E.g. `pueued -d`. \
The daemon can be then shut down using the client: `pueue shutdown`
### Systemd
If you use Systemd and don't install Pueue with a package manager, place `pueued.service` in `/etc/systemd/user/`.
Afterward, every user can start/enable their own session with:
@ -170,10 +177,6 @@ Afterward, every user can start/enable their own session with:
systemctl --user start pueued.service
systemctl --user enable pueued.service
### Local
Just run `pueued` anywhere on your commandline. It'll exit if you close the terminal, though.
## Utilities
### JSON Support

View file

@ -15,7 +15,7 @@ pub struct Opt {
/// Closing the terminal won't kill the daemon any longer.
/// This should be avoided and rather be properly done using a service manager.
#[structopt(short, long)]
daemonize: bool,
pub daemonize: bool,
// /// The ip the daemon listens on. Overwrites the address in the config file
// #[structopt(short, long)]

View file

@ -1,5 +1,6 @@
use ::anyhow::{bail, Error, Result};
use ::simplelog::{Config, LevelFilter, SimpleLogger};
use ::std::process::Command;
use ::std::fs::create_dir_all;
use ::std::path::Path;
use ::std::sync::mpsc::channel;
@ -34,6 +35,10 @@ async fn main() -> Result<()> {
// Parse commandline options
let opt = Opt::from_args();
if opt.daemonize {
fork_daemon(&opt)?;
}
// Set the verbosity level for the client app
if opt.verbose >= 3 {
SimpleLogger::init(LevelFilter::Debug, Config::default())?;
@ -63,7 +68,7 @@ async fn main() -> Result<()> {
}
/// Initialize all directories needed for normal operation
pub fn init_directories(path: &String) {
fn init_directories(path: &String) {
let pueue_dir = Path::new(path);
if !pueue_dir.exists() {
if let Err(error) = create_dir_all(&pueue_dir) {
@ -93,3 +98,25 @@ pub fn init_directories(path: &String) {
}
}
}
/// This is a simple and cheap custom fork method
/// Simply spawn a new child with identical arguments and exit right away
fn fork_daemon(opt: &Opt) -> Result<()> {
let mut arguments = Vec::<String>::new();
if let Some(port) = &opt.port {
arguments.push("--port".to_string());
arguments.push(port.clone());
}
if opt.verbose > 0 {
arguments.push("-".to_string() + &" ".repeat(opt.verbose as usize));
}
Command::new("pueued")
.args(&arguments)
.spawn()?;
println!("Pueued is now running in the background");
std::process::exit(0);
}

View file

@ -1,6 +1,7 @@
use ::anyhow::Result;
use ::async_std::net::TcpStream;
use ::async_std::prelude::*;
use ::log::debug;
use ::byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use ::std::io::Cursor;
@ -9,6 +10,7 @@ use crate::message::*;
/// Convenience wrapper around send_bytes
/// Deserialize a message and feed the bytes into send_bytes
pub async fn send_message(message: &Message, socket: &mut TcpStream) -> Result<()> {
debug!("Sending message: {:?}", message);
// Prepare command for transfer and determine message byte size
let payload = serde_json::to_string(message)
.expect("Failed to serialize message.")
@ -70,6 +72,7 @@ pub async fn receive_message(socket: &mut TcpStream) -> Result<Message> {
// Deserialize the message
let message = String::from_utf8(payload_bytes)?;
debug!("Received message: {:?}", message);
let message: Message = serde_json::from_str(&message)?;
Ok(message)