Commit 41fd71911e1f6209369d87523b993c5cdceaacf6

Authored by Peter M. Groen
1 parent 02844e59

Added Readme

README.md
1 -# DaemonBase Library  
2 \ No newline at end of file 1 \ No newline at end of file
  2 +# DaemonBase Library
  3 +
  4 +Simple C++ header only template for creating Linux daemons
  5 +
  6 +### What are daemon services/processes ?
  7 +A dæmon is a program that runs silently in the background.<br>
  8 +Commonly, dæmon processes are created to offer a specific service.
  9 +
  10 +**Dæmon** processes usually:
  11 +- Live for a long time;
  12 +- Started at boot time;
  13 +- Terminate only during shutdown;
  14 +- Have no controlling terminal.
  15 +
  16 +[//]: # (### Dæmon Characteristics)
  17 +
  18 +[//]: # (The previously listed characteristics have certain implications:)
  19 +
  20 +[//]: # ()
  21 +[//]: # (- do one thing, and one thing only)
  22 +
  23 +[//]: # (- resource leaks eventually surface)
  24 +
  25 +[//]: # (- consider current working directory)
  26 +
  27 +[//]: # (- no &#40;or only limited&#41; user-interaction possible)
  28 +
  29 +[//]: # (- how to create &#40;debugging&#41; output)
  30 +
  31 +### Usage
  32 +DaemonBase has a simple, straightforward api with callbacks to handle your daemon events.
  33 +```cpp
  34 +#include "daemonbase.h"
  35 +#include <cstdlib>
  36 +
  37 +using namespace osdev::components::daemon;
  38 +using namespace std::chrono_literals;
  39 +
  40 +class MyExampleDaemon : public DaemonBase
  41 +{
  42 +public:
  43 + void on_start(const daemonconfig &config) override
  44 + {
  45 + /// Called once after daemon starts automatically with system startup
  46 + /// or when you manually call `$ system,ctl start MyExampleDaemon`
  47 +
  48 + /// Initialize your code here...
  49 +
  50 +
  51 +
  52 + daemonlog::info("MyExampleDaemon::on_start(): MyExampleDaemon version: " + config.get("version") + " started successfully!");
  53 + }
  54 +
  55 + void on_update() override
  56 + {
  57 + /// Called every DURATION set in set_update_duration()...
  58 +
  59 + /// Update your code here
  60 +
  61 + daemonlog::info("MyExampleDaemon::on_update()");
  62 + }
  63 +
  64 + void on_stop() override
  65 + {
  66 + /// Called once before daemon is about to exit with system shutdown or when you manually call `$ systemctl stop MyExampleDaemon`
  67 + /// Cleanup your code here...
  68 +
  69 + daemonlog::info("MyExampleDaemon::on_stop()");
  70 + }
  71 +
  72 + void on_reload(const daemonconfig &cfg) override
  73 + {
  74 + /// Called once after your daemon's config fil is updated then reloaded with `$ systemctl reload MyExampleDaemon`
  75 + /// Handle your config updates here...
  76 +
  77 + daemonlog::info("MyExampleDaemon::on_reload(): new daemon version from updated config: " + cfg.get("version"));
  78 + }
  79 +};
  80 +
  81 +
  82 +int main(int argc, char *argv[])
  83 +{
  84 + MyExampleDaemon oDaemon; // Create the daemon instance.
  85 +
  86 + oDaemon.set_name("MyAweSomeExampleDaemon"); // Set daemon name to identify logs in syslog
  87 + oDaemon.set_update_duration(3s); // Set duration to sleep before triggering the on_update callback 3 seconds.
  88 + oDaemon.set_cwd("/root"); // set daemon's current working directory to roots home-folder
  89 + oDaemon.run(argc, argv); // run the daemon
  90 +
  91 + return(EXIT_SUCCESS); // Close the main process now the child process is running.
  92 +}
  93 +```
3 \ No newline at end of file 94 \ No newline at end of file
systemd/MyExampleDaemon.conf 0 → 100644
  1 +# here you can have your daemon configuration
  2 +name=@PROJECT_NAME@
  3 +version=@PROJECT_VERSION@
  4 +description=@PROJECT_DESCRIPTION@
0 \ No newline at end of file 5 \ No newline at end of file
systemd/MyExampleDaemon.service 0 → 100644
  1 +# Properties docs: https://www.freedesktop.org/software/systemd/man/systemd.service.html
  2 +[Unit]
  3 +Description=@PROJECT_DESCRIPTION@
  4 +After=network.target
  5 +
  6 +[Service]
  7 +Type=forking
  8 +ExecStart=/usr/bin/@PROJECT_NAME@ --config /etc/@PROJECT_NAME@/@PROJECT_NAME@.conf
  9 +ExecReload=/bin/kill -s SIGHUP $MAINPID
  10 +ExecStop=/bin/kill -s SIGTERM $MAINPID
  11 +User=root
  12 +SyslogIdentifier=@PROJECT_NAME@
  13 +
  14 +[Install]
  15 +WantedBy=multi-user.target
0 \ No newline at end of file 16 \ No newline at end of file
systemd/README.md 0 → 100644
  1 +Linux systems that use systemd for managing services, .service files are typically placed in the /lib/systemd/system/ directory or the /etc/systemd/system/ directory. The .conf files may be placed in a similar directory, such as /etc/MyExampleDaemon/.
  2 +
  3 +### .service
  4 +```ini
  5 +# Properties docs: https://www.freedesktop.org/software/systemd/man/systemd.service.html
  6 +[Unit]
  7 +Description=Simple C++ template example for creating Linux daemons
  8 +After=network.target
  9 +
  10 +[Service]
  11 +# Configures the process start-up type for this service unit. One of simple, exec, forking, oneshot, dbus, notify or idle.
  12 +# https://unix.stackexchange.com/questions/733890/systemd-service-unit-restart-on-failure-doesnt-restart-daemon
  13 +Type=forking
  14 +# when systemctl start is called
  15 +ExecStart=/usr/bin/MyExampleDaemon --config /etc/MyExampleDaemon/MyExampleDaemon.conf
  16 +# when systemctl reload MyExampleDaemon (for reloading of the service's configuration) it will trigger SIGHUP
  17 +# which will be caught by signal_handler and trigger the on_reload callback.
  18 +ExecReload=/bin/kill -s SIGHUP $MAINPID
  19 +# when systemctl stop MyExampleDaemon called: Will trigger SIGTERM which will be caught by signal_handler
  20 +# and trigger the on_stop callback.
  21 +ExecStop=/bin/kill -s SIGTERM $MAINPID
  22 +User=root
  23 +StandardError=syslog
  24 +SyslogIdentifier=MyExampleDaemon
  25 +
  26 +[Install]
  27 +# Start after boot
  28 +WantedBy=multi-user.target
  29 +```
  30 +
  31 +
  32 +### .conf
  33 +```ini
  34 +# here you can have your daemon configuration
  35 +name=MyExampleDaemon
  36 +version=0.0.1
  37 +description=Simple C++ template example for creating Linux daemons
  38 +```