Start user units at the system level
authorJosé Bollo <jose.bollo@iot.bzh>
Tue, 2 May 2017 16:13:23 +0000 (18:13 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Fri, 24 Nov 2017 16:44:57 +0000 (17:44 +0100)
When service name end with @ it means that the user
UID must be provided.

Change-Id: I6707df0151b7cab985cfc53a81fccf6a7150c9a3
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
conf/afm-unit-debug.conf.in
conf/afm-unit.conf.in
src/afm-udb.c
src/afm-urun.c
src/afm-user-daemon.c

index 75f7811..57f934e 100644 (file)
@@ -117,8 +117,8 @@ ConditionSecurity=smack
 # Automatic bound to required api
 {{#required-api}}
 {{#value=auto|ws}}
-BindsTo=afm-api-ws-{{name}}.socket
-After=afm-api-ws-{{name}}.socket
+BindsTo=afm-api-ws-{{name}}@%i.socket
+After=afm-api-ws-{{name}}@%i.socket
 {{/value=auto|ws}}
 {{/required-api}}
 %nl
@@ -128,6 +128,9 @@ EnvironmentFile=-@afm_confdir@/unit.env.d/*
 SmackProcessLabel=User::App::{{:id}}
 SuccessExitStatus=0 SIGKILL
 
+PAMName=su
+User=%i
+
 {{#required-permission}}
   {{#urn:AGL:permission::platform:no-oom}}      OOMScoreAdjust=-500             {{/urn:AGL:permission::platform:no-oom}}
   {{#urn:AGL:permission::partner:real-time}}    IOSchedulingClass=realtime      {{/urn:AGL:permission::partner:real-time}}
@@ -146,12 +149,12 @@ Environment=PATH=/usr/sbin:/usr/bin:/sbin:/bin:{{:#metadata.install-dir}}
 Environment=AFM_ID={{idaver}}{{^#target=main}}@{{:#target}}{{/#target=main}}
 EnvironmentFile=-/var/run/afm-debug/{{idaver}}{{^#target=main}}@{{:#target}}{{/#target=main}}.env
 
-%systemd-unit user
+%systemd-unit system
 {{#required-permission.urn:AGL:permission::public:hidden}}\
-%systemd-unit service afm-service-{{:id}}--{{:ver}}--{{:#target}}
+%systemd-unit service afm-service-{{:id}}--{{:ver}}--{{:#target}}@
 {{/required-permission.urn:AGL:permission::public:hidden}}\
 {{^required-permission.urn:AGL:permission::public:hidden}}\
-%systemd-unit service afm-appli-{{:id}}--{{:ver}}--{{:#target}}
+%systemd-unit service afm-appli-{{:id}}--{{:ver}}--{{:#target}}@
 {{/required-permission.urn:AGL:permission::public:hidden}}\
 
 Environment=LD_LIBRARY_PATH=$ORIGIN/lib
@@ -269,8 +272,8 @@ WantedBy=default.target
 
 # auto generated by wgtpkg-unit for {{:id}} version {{:version}} target {{:#target}} of {{:idaver}}
 #
-%systemd-unit user
-%systemd-unit socket afm-api-ws-{{name}}
+%systemd-unit system
+%systemd-unit socket afm-api-ws-{{name}}@
 
 [Socket]
 SmackLabel=*
@@ -278,10 +281,10 @@ ListenStream=%t/apis/ws/{{name}}
 FileDescriptorName={{name}}
 
 {{#required-permission.urn:AGL:permission::public:hidden}}\
-Service=afm-service-{{:id}}--{{:ver}}--{{:#target}}.service
+Service=afm-service-{{:id}}--{{:ver}}--{{:#target}}@%i.service
 {{/required-permission.urn:AGL:permission::public:hidden}}\
 {{^required-permission.urn:AGL:permission::public:hidden}}\
-Service=afm-appli-{{:id}}--{{:ver}}--{{:#target}}.service
+Service=afm-appli-{{:id}}--{{:ver}}--{{:#target}}@%i.service
 {{/required-permission.urn:AGL:permission::public:hidden}}\
 
 ;---------------------------------------------------------------------------------
index 7bd8581..0432ee3 100644 (file)
@@ -117,8 +117,8 @@ ConditionSecurity=smack
 # Automatic bound to required api
 {{#required-api}}
 {{#value=auto|ws}}
-BindsTo=afm-api-ws-{{name}}.socket
-After=afm-api-ws-{{name}}.socket
+BindsTo=afm-api-ws-{{name}}@%i.socket
+After=afm-api-ws-{{name}}@%i.socket
 {{/value=auto|ws}}
 {{/required-api}}
 %nl
@@ -128,6 +128,9 @@ EnvironmentFile=-@afm_confdir@/unit.env.d/*
 SmackProcessLabel=User::App::{{:id}}
 SuccessExitStatus=0 SIGKILL
 
+PAMName=su
+User=%i
+
 {{#required-permission}}
   {{#urn:AGL:permission::platform:no-oom}}      OOMScoreAdjust=-500             {{/urn:AGL:permission::platform:no-oom}}
   {{#urn:AGL:permission::partner:real-time}}    IOSchedulingClass=realtime      {{/urn:AGL:permission::partner:real-time}}
@@ -142,12 +145,12 @@ ExecStartPre=/bin/mkdir -p {{&#metadata.app-data-dir}}/{{:id}}
 Environment=AFM_APP_INSTALL_DIR={{:#metadata.install-dir}}
 Environment=PATH=/usr/sbin:/usr/bin:/sbin:/bin:{{:#metadata.install-dir}}
 
-%systemd-unit user
+%systemd-unit system
 {{#required-permission.urn:AGL:permission::public:hidden}}\
-%systemd-unit service afm-service-{{:id}}--{{:ver}}--{{:#target}}
+%systemd-unit service afm-service-{{:id}}--{{:ver}}--{{:#target}}@
 {{/required-permission.urn:AGL:permission::public:hidden}}\
 {{^required-permission.urn:AGL:permission::public:hidden}}\
-%systemd-unit service afm-appli-{{:id}}--{{:ver}}--{{:#target}}
+%systemd-unit service afm-appli-{{:id}}--{{:ver}}--{{:#target}}@
 {{/required-permission.urn:AGL:permission::public:hidden}}\
 
 Environment=LD_LIBRARY_PATH=$ORIGIN/lib
@@ -265,8 +268,8 @@ WantedBy=default.target
 
 # auto generated by wgtpkg-unit for {{:id}} version {{:version}} target {{:#target}} of {{:idaver}}
 #
-%systemd-unit user
-%systemd-unit socket afm-api-ws-{{name}}
+%systemd-unit system
+%systemd-unit socket afm-api-ws-{{name}}@
 
 [Socket]
 SmackLabel=*
@@ -274,10 +277,10 @@ ListenStream=%t/apis/ws/{{name}}
 FileDescriptorName={{name}}
 
 {{#required-permission.urn:AGL:permission::public:hidden}}\
-Service=afm-service-{{:id}}--{{:ver}}--{{:#target}}.service
+Service=afm-service-{{:id}}--{{:ver}}--{{:#target}}@%i.service
 {{/required-permission.urn:AGL:permission::public:hidden}}\
 {{^required-permission.urn:AGL:permission::public:hidden}}\
-Service=afm-appli-{{:id}}--{{:ver}}--{{:#target}}.service
+Service=afm-appli-{{:id}}--{{:ver}}--{{:#target}}@%i.service
 {{/required-permission.urn:AGL:permission::public:hidden}}\
 
 ;---------------------------------------------------------------------------------
index e3d5d77..0a48810 100644 (file)
@@ -17,6 +17,7 @@
 */
 
 #include <stdlib.h>
+#include <stdio.h>
 #include <assert.h>
 #include <string.h>
 #include <errno.h>
@@ -224,6 +225,8 @@ static int addunit(
 {
        struct json_object *priv, *pub, *id;
        const char *strid;
+       char *un = NULL;
+       size_t len;
 
        /* create the application structure */
        priv = json_object_new_object();
@@ -234,12 +237,30 @@ static int addunit(
        if (!pub)
                goto error;
 
+       /* make the unit name */
+       len = strlen(unitname);
+       assert(len >= (sizeof service_extension - 1));
+       assert(!memcmp(&unitname[len - (sizeof service_extension - 1)], service_extension, sizeof service_extension));
+       if (unitname[len - sizeof service_extension] == '@') {
+               char buffer[40];
+               size_t l = (size_t)snprintf(buffer, sizeof buffer, "%d", (int)getuid());
+               un = malloc(len + l + 1);
+               if (!un)
+                       goto error;
+               memcpy(&un[0], unitname, len - (sizeof service_extension - 1));
+               if (l)
+                       memcpy(&un[len - (sizeof service_extension - 1)], buffer, l);
+               memcpy(&un[len - (sizeof service_extension - 1) + l], service_extension, sizeof service_extension);
+       }
+
        /* adds the values */
        if (add_fields_of_content(priv, pub, content, length)
         || add_field(priv, pub, key_unit_path, unitpath)
-        || add_field(priv, pub, key_unit_name, unitname)
+        || add_field(priv, pub, key_unit_name, un ? : unitname)
         || add_field(priv, pub, key_unit_scope, isuser ? scope_user : scope_system))
                goto error;
+       free(un);
+       un = NULL;
 
        /* get the id */
        if (!json_object_object_get_ex(pub, key_id, &id)) {
@@ -258,6 +279,7 @@ static int addunit(
        return 0;
 
 error:
+       free(un);
        json_object_put(pub);
        json_object_put(priv);
        return -1;
index 1814437..5649973 100644 (file)
@@ -36,6 +36,8 @@
 #include "afm-udb.h"
 #include "afm-urun.h"
 
+static const char key_unit_d_path[] = "-unit-dpath-";
+
 /**************** get appli basis *********************/
 
 static int get_basis(struct json_object *appli, int *isuser, const char **dpath, int load)
@@ -51,7 +53,7 @@ static int get_basis(struct json_object *appli, int *isuser, const char **dpath,
        *isuser = strcmp(uscope, "system") != 0;
 
        /* get dpath */
-       if (!j_read_string_at(appli, "-unit-dpath-", dpath)) {
+       if (!j_read_string_at(appli, key_unit_d_path, dpath)) {
                if (!load) {
                        errno = ENOENT;
                        goto error;
@@ -65,12 +67,12 @@ static int get_basis(struct json_object *appli, int *isuser, const char **dpath,
                        ERROR("Can't load unit of name %s for %s: %m", uname, uscope);
                        goto error;
                }
-               if (!j_add_string(appli, "-unit-dpath-", dp)) {
+               if (!j_add_string(appli, key_unit_d_path, dp)) {
                        free(dp);
                        goto nomem;
                }
                free(dp);
-               j_read_string_at(appli, "-unit-dpath-", dpath);
+               j_read_string_at(appli, key_unit_d_path, dpath);
        }
 
        return 0;
@@ -238,6 +240,8 @@ static int not_yet_implemented(const char *what)
 int afm_urun_terminate(int runid)
 {
        int rc = systemd_unit_stop_pid(1 /* TODO: isuser? */, (unsigned)runid);
+       if (rc < 0)
+               rc = systemd_unit_stop_pid(0 /* TODO: isuser? */, (unsigned)runid);
        return rc < 0 ? rc : 0;
 }
 
@@ -313,7 +317,7 @@ error:
  */
 struct json_object *afm_urun_state(struct afm_udb *db, int runid)
 {
-       int i, n, isuser, pid;
+       int i, n, isuser, pid, wasuser;
        char *dpath;
        const char *udpath;
        const char *id;
@@ -325,7 +329,9 @@ struct json_object *afm_urun_state(struct afm_udb *db, int runid)
        result = NULL;
 
        /* get the dpath */
-       dpath = systemd_unit_dpath_by_pid(1 /* TODO: isuser? */, (unsigned)runid);
+       dpath = systemd_unit_dpath_by_pid(wasuser = 1, (unsigned)runid);
+       if (!dpath)
+               dpath = systemd_unit_dpath_by_pid(wasuser = 0, (unsigned)runid);
        if (!dpath) {
                errno = EINVAL;
                WARNING("searched runid %d not found", runid);
index 057f23e..ed5f2a2 100644 (file)
@@ -530,7 +530,7 @@ int main(int ac, char **av)
        srandom((unsigned int)time(NULL));
 
        /* init database */
-       afudb = afm_udb_create(0, 1, "afm-appli-");
+       afudb = afm_udb_create(1, 1, "afm-appli-");
        if (!afudb) {
                ERROR("afm_udb_create failed");
                return 1;