Start user units at the system level
[src/app-framework-main.git] / src / afm-user-daemon.c
index d0bef18..ed5f2a2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- Copyright 2015 IoT.bzh
+ Copyright 2015, 2016, 2017 IoT.bzh
 
  author: José Bollo <jose.bollo@iot.bzh>
 
 #include "verbose.h"
 #include "utils-jbus.h"
 #include "utils-json.h"
+#include "utils-systemd.h"
 #include "afm.h"
-#include "afm-db.h"
-#include "afm-launch-mode.h"
-#include "afm-run.h"
+#include "afm-udb.h"
+#include "afm-urun.h"
 
 /*
  * name of the application
  */
 static const char appname[] = "afm-user-daemon";
 
+/*
+ * string for printing version
+ */
+static const char versionstr[] =
+       "\n"
+       "  %s  version="AFM_VERSION"\n"
+       "\n"
+       "  Copyright (C) 2015, 2016, 2017 \"IoT.bzh\"\n"
+       "  AFB comes with ABSOLUTELY NO WARRANTY.\n"
+       "  Licence Apache 2\n"
+       "\n";
+
 /*
  * string for printing usage
  */
 static const char usagestr[] =
-       "usage: %s [-q] [-v] [-m mode] [-r rootdir]... [-a appdir]...\n"
+       "usage: %s [option(s)]\n"
        "\n"
-       "   -a appdir    adds an application directory\n"
-       "   -r rootdir   adds a root directory of applications\n"
-       "   -m mode      set default launch mode (local or remote)\n"
        "   -d           run as a daemon\n"
        "   -u addr      address of user D-Bus to use\n"
        "   -s addr      address of system D-Bus to use\n"
        "   -q           quiet\n"
        "   -v           verbose\n"
+       "   -V           version\n"
        "\n";
 
 /*
  * Option definition for getopt_long
  */
-static const char options_s[] = "hdqvr:a:m:";
+static const char options_s[] = "hdqvV";
 static struct option options_l[] = {
-       { "root",        required_argument, NULL, 'r' },
-       { "application", required_argument, NULL, 'a' },
-       { "mode",        required_argument, NULL, 'm' },
        { "user-dbus",   required_argument, NULL, 'u' },
        { "system-dbus", required_argument, NULL, 's' },
        { "daemon",      no_argument,       NULL, 'd' },
        { "quiet",       no_argument,       NULL, 'q' },
        { "verbose",     no_argument,       NULL, 'v' },
        { "help",        no_argument,       NULL, 'h' },
+       { "version",     no_argument,       NULL, 'V' },
        { NULL, 0, NULL, 0 }
 };
 
@@ -85,7 +93,7 @@ static struct jbus *jbuses[2];
 /*
  * Handle to the database of applications
  */
-static struct afm_db *afdb;
+static struct afm_udb *afudb;
 
 /*
  * Returned error strings
@@ -154,7 +162,7 @@ static void on_runnables(struct sd_bus_message *smsg, struct json_object *obj, v
 {
        struct json_object *resp;
        INFO("method runnables called");
-       resp = afm_db_application_list(afdb);
+       resp = afm_udb_applications_public(afudb);
        jbus_reply_j(smsg, resp);
        json_object_put(resp);
 }
@@ -180,44 +188,33 @@ static void on_detail(struct sd_bus_message *smsg, struct json_object *obj, void
 
        /* wants details for appid */
        INFO("method detail called for %s", appid);
-       resp = afm_db_get_application_public(afdb, appid);
+       resp = afm_udb_get_application_public(afudb, appid);
        reply(smsg, resp, error_not_found);
        json_object_put(resp);
 }
 
-
 /*
  * On query "start" from 'smsg' with parameters of 'obj'.
  */
 static void on_start(struct sd_bus_message *smsg, struct json_object *obj, void *unused)
 {
-       const char *appid, *modestr;
+       const char *appid;
        char *uri;
        struct json_object *appli, *resp;
        int runid;
        char runidstr[20];
-       enum afm_launch_mode mode;
 
        /* get the parameters */
-       mode = invalid_launch_mode;
-       if (j_read_string(obj, &appid)) {
-               mode = get_default_launch_mode();
-       } else if (j_read_string_at(obj, "id", &appid)) {
-               if (j_read_string_at(obj, "mode", &modestr)) {
-                       mode = launch_mode_of_name(modestr);
-               } else {
-                       mode = get_default_launch_mode();
+       if (!j_read_string(obj, &appid)) {
+               if (!j_read_string_at(obj, "id", &appid)) {
+                       jbus_reply_error_s(smsg, error_bad_request);
+                       return;
                }
        }
-       if (!is_valid_launch_mode(mode)) {
-               jbus_reply_error_s(smsg, error_bad_request);
-               return;
-       }
 
        /* get the application */
-       INFO("method start called for %s mode=%s", appid,
-                                               name_of_launch_mode(mode));
-       appli = afm_db_get_application(afdb, appid);
+       INFO("method start called for %s", appid);
+       appli = afm_udb_get_application_private(afudb, appid);
        if (appli == NULL) {
                jbus_reply_error_s(smsg, error_not_found);
                return;
@@ -225,7 +222,7 @@ static void on_start(struct sd_bus_message *smsg, struct json_object *obj, void
 
        /* launch the application */
        uri = NULL;
-       runid = afm_run_start(appli, mode, &uri);
+       runid = afm_urun_start(appli);
        if (runid <= 0) {
                jbus_reply_error_s(smsg, error_cant_start);
                free(uri);
@@ -246,7 +243,7 @@ static void on_start(struct sd_bus_message *smsg, struct json_object *obj, void
                                        && j_add_string(resp, "uri", uri))
                jbus_reply_j(smsg, resp);
        else {
-               afm_run_stop(runid);
+               afm_urun_terminate(runid);
                jbus_reply_error_s(smsg, error_system);
        }
        json_object_put(resp);
@@ -254,29 +251,83 @@ static void on_start(struct sd_bus_message *smsg, struct json_object *obj, void
 }
 
 /*
- * On query "stop" from 'smsg' with parameters of 'obj'.
+ * On query "once" from 'smsg' with parameters of 'obj'.
  */
-static void on_stop(struct sd_bus_message *smsg, struct json_object *obj, void *unused)
+static void on_once(struct sd_bus_message *smsg, struct json_object *obj, void *unused)
+{
+       const char *appid;
+       struct json_object *appli, *resp;
+       int runid;
+
+       /* get the parameters */
+       if (!j_read_string(obj, &appid) && !j_read_string_at(obj, "id", &appid)) {
+               jbus_reply_error_s(smsg, error_bad_request);
+               return;
+       }
+
+       /* get the application */
+       INFO("method once called for %s", appid);
+       appli = afm_udb_get_application_private(afudb, appid);
+       if (appli == NULL) {
+               jbus_reply_error_s(smsg, error_not_found);
+               return;
+       }
+
+       /* launch the application */
+       runid = afm_urun_once(appli);
+       if (runid <= 0) {
+               jbus_reply_error_s(smsg, error_cant_start);
+               return;
+       }
+
+       /* returns the state */
+       resp = afm_urun_state(afudb, runid);
+       reply(smsg, resp, error_not_found);
+       json_object_put(resp);
+}
+
+/*
+ * On query "pause" from 'smsg' with parameters of 'obj'.
+ */
+static void on_pause(struct sd_bus_message *smsg, struct json_object *obj, void *unused)
 {
        int runid, status;
-       if (onrunid(smsg, obj, "stop", &runid)) {
-               status = afm_run_stop(runid);
+       if (onrunid(smsg, obj, "pause", &runid)) {
+               status = afm_urun_pause(runid);
                reply_status(smsg, status, error_not_found);
        }
 }
 
 /*
- * On query "continue" from 'smsg' with parameters of 'obj'.
+ * On query "resume" from 'smsg' with parameters of 'obj'.
  */
-static void on_continue(struct sd_bus_message *smsg, struct json_object *obj, void *unused)
+static void on_resume(struct sd_bus_message *smsg, struct json_object *obj, void *unused)
 {
        int runid, status;
-       if (onrunid(smsg, obj, "continue", &runid)) {
-               status = afm_run_continue(runid);
+       if (onrunid(smsg, obj, "resume", &runid)) {
+               status = afm_urun_resume(runid);
                reply_status(smsg, status, error_not_found);
        }
 }
 
+/*
+ * On query "stop" from 'smsg' with parameters of 'obj'.
+ */
+static void on_stop(struct sd_bus_message *smsg, struct json_object *obj, void *unused)
+{
+       NOTICE("call to obsolete 'stop'");
+       on_pause(smsg, obj, unused);
+}
+
+/*
+ * On query "continue" from 'smsg' with parameters of 'obj'.
+ */
+static void on_continue(struct sd_bus_message *smsg, struct json_object *obj, void *unused)
+{
+       NOTICE("call to obsolete 'continue'");
+       on_resume(smsg, obj, unused);
+}
+
 /*
  * On query "terminate" from 'smsg' with parameters of 'obj'.
  */
@@ -284,7 +335,7 @@ static void on_terminate(struct sd_bus_message *smsg, struct json_object *obj, v
 {
        int runid, status;
        if (onrunid(smsg, obj, "terminate", &runid)) {
-               status = afm_run_terminate(runid);
+               status = afm_urun_terminate(runid);
                reply_status(smsg, status, error_not_found);
        }
 }
@@ -296,7 +347,7 @@ static void on_runners(struct sd_bus_message *smsg, struct json_object *obj, voi
 {
        struct json_object *resp;
        INFO("method runners called");
-       resp = afm_run_list();
+       resp = afm_urun_list(afudb);
        jbus_reply_j(smsg, resp);
        json_object_put(resp);
 }
@@ -309,7 +360,7 @@ static void on_state(struct sd_bus_message *smsg, struct json_object *obj, void
        int runid;
        struct json_object *resp;
        if (onrunid(smsg, obj, "state", &runid)) {
-               resp = afm_run_state(runid);
+               resp = afm_urun_state(afudb, runid);
                reply(smsg, resp, error_not_found);
                json_object_put(resp);
        }
@@ -363,8 +414,13 @@ static void on_uninstall(struct sd_bus_message *smsg, const char *msg, void *unu
  */
 static void on_signal_changed(struct json_object *obj, void *unused)
 {
+       /* enforce daemon reload */
+       systemd_daemon_reload(1);
+       systemd_unit_restart_name(1, "sockets.target");
+
        /* update the database */
-       afm_db_update_applications(afdb);
+       afm_udb_update(afudb);
+
        /* re-propagate now */
        jbus_send_signal_j(user_bus, "changed", obj);
 }
@@ -398,7 +454,7 @@ static int open_bus(sd_bus **ret, int isuser, const char *address)
        int rc;
 
        if (address == NULL)
-               return (isuser ? sd_bus_open_user : sd_bus_open_system)(ret);
+               return (isuser ? sd_bus_default_user : sd_bus_default_system)(ret);
 
        rc = sd_bus_new(&b);
        if (rc < 0)
@@ -428,7 +484,6 @@ fail:
 int main(int ac, char **av)
 {
        int i, daemon = 0, rc;
-       enum afm_launch_mode mode;
        struct sd_event *evloop;
        struct sd_bus *sysbus, *usrbus;
        const char *sys_bus_addr, *usr_bus_addr;
@@ -443,6 +498,9 @@ int main(int ac, char **av)
                case 'h':
                        printf(usagestr, appname);
                        return 0;
+               case 'V':
+                       printf(versionstr, appname);
+                       return 0;
                case 'q':
                        if (verbosity)
                                verbosity--;
@@ -453,18 +511,6 @@ int main(int ac, char **av)
                case 'd':
                        daemon = 1;
                        break;
-               case 'r':
-                       break;
-               case 'a':
-                       break;
-               case 'm':
-                       mode = launch_mode_of_name(optarg);
-                       if (!is_valid_launch_mode(mode)) {
-                               ERROR("invalid mode '%s'", optarg);
-                               return 1;
-                       }
-                       set_default_launch_mode(mode);
-                       break;
                case 'u':
                        usr_bus_addr = optarg;
                        break;
@@ -483,45 +529,10 @@ int main(int ac, char **av)
        /* init random generator */
        srandom((unsigned int)time(NULL));
 
-       /* init runners */
-       if (afm_run_init()) {
-               ERROR("afm_run_init failed");
-               return 1;
-       }
-
-       /* init framework */
-       afdb = afm_db_create();
-       if (!afdb) {
-               ERROR("afm_create failed");
-               return 1;
-       }
-       if (afm_db_add_root(afdb, FWK_APP_DIR)) {
-               ERROR("can't add root %s", FWK_APP_DIR);
-               return 1;
-       }
-
-       /* second interpretation of arguments */
-       optind = 1;
-       while ((i = getopt_long(ac, av, options_s, options_l, NULL)) >= 0) {
-               switch (i) {
-               case 'r':
-                       if (afm_db_add_root(afdb, optarg)) {
-                               ERROR("can't add root %s", optarg);
-                               return 1;
-                       }
-                       break;
-               case 'a':
-                       if (afm_db_add_application(afdb, optarg)) {
-                               ERROR("can't add application %s", optarg);
-                               return 1;
-                       }
-                       break;
-               }
-       }
-
-       /* update the database */
-       if (afm_db_update_applications(afdb)) {
-               ERROR("afm_update_applications failed");
+       /* init database */
+       afudb = afm_udb_create(1, 1, "afm-appli-");
+       if (!afudb) {
+               ERROR("afm_udb_create failed");
                return 1;
        }
 
@@ -582,18 +593,22 @@ int main(int ac, char **av)
        if (jbus_add_service_j(user_bus, "runnables", on_runnables, NULL)
         || jbus_add_service_j(user_bus, "detail",    on_detail, NULL)
         || jbus_add_service_j(user_bus, "start",     on_start, NULL)
+        || jbus_add_service_j(user_bus, "once",      on_once, NULL)
         || jbus_add_service_j(user_bus, "terminate", on_terminate, NULL)
+        || jbus_add_service_j(user_bus, "pause",     on_pause, NULL)
+        || jbus_add_service_j(user_bus, "resume",    on_resume, NULL)
         || jbus_add_service_j(user_bus, "stop",      on_stop, NULL)
         || jbus_add_service_j(user_bus, "continue",  on_continue, NULL)
         || jbus_add_service_j(user_bus, "runners",   on_runners, NULL)
         || jbus_add_service_j(user_bus, "state",     on_state, NULL)
 #if defined(EXPLICIT_CALL)
         || jbus_add_service_s(user_bus, "install",   on_install, NULL)
-        || jbus_add_service_s(user_bus, "uninstall", on_uninstall, NULL)) {
+        || jbus_add_service_s(user_bus, "uninstall", on_uninstall, NULL)
 #else
         || jbus_add_service_s(user_bus, "install",   (void (*)(struct sd_bus_message *, const char *, void *))propagate, "install")
-        || jbus_add_service_s(user_bus, "uninstall", (void (*)(struct sd_bus_message *, const char *, void *))propagate, "uninstall")) {
+        || jbus_add_service_s(user_bus, "uninstall", (void (*)(struct sd_bus_message *, const char *, void *))propagate, "uninstall")
 #endif
+        ) {
                ERROR("adding services failed");
                return 1;
        }
@@ -610,17 +625,3 @@ int main(int ac, char **av)
        return 0;
 }
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-