128keaton / NeverCLI

C++ components for NeverNVR
0 stars 0 forks source link

Create new binary that just manages the state/status of the camera daemons #5

Closed 128keaton closed 12 months ago

128keaton commented 1 year ago

If we'd like to use C++ natively, there is dbus, @aysent911 do you have any experience with dbus?

Otherwise, we can use bash scripts (not as great).

The idea is that we can tell this binary when a camera was deleted, updated, or added.

If created, it will generate the camera's JSON from input and then create and start the service. If deleted, it will stop and remove the service. If updated, it will regenerate the camera's JSON from input and then restart the service

128keaton commented 1 year ago

https://github.com/openbmc/phosphor-state-manager/blob/master/chassis_state_manager.cpp#L81

Some linked example with a very complex structure.

128keaton commented 1 year ago

https://github.com/makercrew/dbus-sample

128keaton commented 1 year ago

Maybe we can just monitor the processes and report status updates using dbus: https://stackoverflow.com/questions/61940461/how-to-get-the-state-of-a-service-with-sd-bus

Then we can just have a basic binary that generates services with parameters: https://stackoverflow.com/questions/62474719/creating-and-loading-a-systemd-service-from-a-c-program

aysent911 commented 1 year ago

I can get started with a few tutorials on dbus.

128keaton commented 1 year ago

https://unix.stackexchange.com/a/675213 has a great reference:

#include <systemd/sd-bus.h>

static void CallMethodSS(
    sd_bus* bus,
    const std::string& name,
    const std::string& method)
{
    sd_bus_error err = SD_BUS_ERROR_NULL;
    sd_bus_message* msg = nullptr;
    int r;

    r = sd_bus_call_method(bus,
        "org.freedesktop.systemd1",         /* <service>   */
        "/org/freedesktop/systemd1",        /* <path>      */
        "org.freedesktop.systemd1.Manager", /* <interface> */
        method.c_str(),                     /* <method>    */
        &err,                               /* object to return error in */
        &msg,                               /* return message on success */
        "ss",                               /* <input_signature (string-string)> */
        name.c_str(),  "replace" );         /* <arguments...> */

    if (r < 0)
    {
        std::string err_str("Could not send " + method +
                            " command to systemd for service: " + name +
                            ". Error: " + err.message );

        sd_bus_error_free(&err);
        sd_bus_message_unref(msg);
        throw exception(err_str);
    }

    // Extra stuff that might be useful:  display the response...
    char* response;
    r = sd_bus_message_read(msg, "o", &response);
    if (r < 0)
    {
      LogError("Failed to parse response message: %s\n", strerror(-r) );
    }

    sd_bus_error_free(&err);
    sd_bus_message_unref(msg);
}

I plan to install the two unit files for the daemons under /etc/systemd/system/, meaning names should be mappable to each service out of the box:

Screenshot 2023-11-09 at 2 15 18 PM

This daemon will need to run as root to start and enable (EnableUnitFiles()) so we will need to communicate with this daemon somehow without calling root. I think a Unix Domain Socket should work with JSON, see here where I am doing this already with Janus

128keaton commented 1 year ago

You can see here in Never Gateway that I am expecting a Unix Domain Socket somewhere like /tmp/nvr-gw-sock

I am expecting it to be a DGRAM socket for ease of debugging right now.

This is where the primary communication to the API gateway will take place. The binary here should create and monitor this socket for any messages. Right now the messages are constructed like shown:

{
    "name": "new",
    "configPath": "/nvr/cameras/camera-1.json"
}

Note that name can be new, update, or delete, since this binary should handle those events. Also note that the name of the recording/streaming services are expected to be something like nvr-stream@camera-1. If you notice, the configuration file's name (without extension) matches the end of that service descriptor, and this is on purpose.

The event new should trigger the enablement of the NVR service and start it for said camera configuration.

The event update should trigger a restart/reload of the NVR service for said camera configuration (the event is sent after the configuration has been changed on-disk)

The event delete should trigger the disablement/stoppage of the NVR service for said camera configuration.

aysent911 commented 12 months ago

The camera_status_manager is able to create camera-x.json files in /nvr/cameras/. Now working on starting the camera daemons.

aysent911 commented 12 months ago

The created binary can now start nvr-record@camera-x.service upon creating a camera JSON.