aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2017-03-14 18:24:46 +0100
committerJosé Bollo <jose.bollo@iot.bzh>2017-03-17 13:01:40 +0100
commitcdd05aa3e66a876dba01f04173d817b9e5e039a0 (patch)
treeec309a4b9bd1ef1860ebc54d431b2a7e37db4c00
parentfcc925c4a6d7bc82106f6c8da13b1a58a7b23115 (diff)
wgtpkg-unit: add management of wanted-by in unit descriptions
This allows the automatic creation of the links in wants subdirectories. Change-Id: Ib948fb11abbbd902f733279136f51ad1649923ef Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-rw-r--r--conf/afm-unit.conf10
-rw-r--r--src/wgtpkg-unit.c141
-rw-r--r--src/wgtpkg-unit.h2
3 files changed, 119 insertions, 34 deletions
diff --git a/conf/afm-unit.conf b/conf/afm-unit.conf
index 18ade85..86ab626 100644
--- a/conf/afm-unit.conf
+++ b/conf/afm-unit.conf
@@ -45,6 +45,10 @@
;
; gives the name and type of the unit
;
+; - %systemd-unit wanted-by NAME
+;
+; tells to install a link to unit in the wants of NAME
+;
;---------------------------------------------------------------------------------
{{#targets}}
%begin systemd-unit
@@ -147,7 +151,7 @@ ExecStart={{:#metadata.install-dir}}/{{content.src}}
{{#content.type=application/vnd.agl.service}}
%systemd-unit user
-%systemd-unit service afm-api-{{:#target}}
+%systemd-unit service afm-service-{{:#target}}
ExecStart=/usr/bin/afb-daemon \
--rootdir={{:#metadata.install-dir}} \
@@ -168,8 +172,7 @@ ExecStart=/usr/bin/afb-daemon \
# auto generated by wgtpkg-unit for {{id}} version {{version}} target {{:#target}}
#
%systemd-unit user
-%systemd-unit socket afm-api-{{:#target}}
-
+%systemd-unit socket afm-service-{{:#target}}
[socket]
SmackLabel=*
@@ -184,6 +187,7 @@ FileDescriptorName={{:#target}}
{{#required-permission.urn:AGL:permission::system:run-by-default}}
[install]
WantedBy=default.target
+%systemd-unit wanted-by default.target
{{/required-permission.urn:AGL:permission::system:run-by-default}}
;---------------------------------------------------------------------------------
%end systemd-unit
diff --git a/src/wgtpkg-unit.c b/src/wgtpkg-unit.c
index 93cfe64..9e6a1e2 100644
--- a/src/wgtpkg-unit.c
+++ b/src/wgtpkg-unit.c
@@ -193,8 +193,8 @@ static char *offset(char *text, const char *pattern, char **args)
*/
static int process_one_unit(char *spec, struct unitdesc *desc)
{
- char *nsoc, *nsrv, *name;
- int isuser, issystem, issock, isserv;
+ char *nsoc, *nsrv, *name, *wanted;
+ int isuser, issystem, issock, isserv, iswanted;
size_t len;
/* finds the configuration directive of the unit */
@@ -202,6 +202,7 @@ static int process_one_unit(char *spec, struct unitdesc *desc)
issystem = !!offset(spec, "%systemd-unit system\n", NULL);
issock = !!offset(spec, "%systemd-unit socket ", &nsoc);
isserv = !!offset(spec, "%systemd-unit service ", &nsrv);
+ iswanted = !!offset(spec, "%systemd-unit wanted-by ", &wanted);
/* check the unit scope */
if ((isuser + issystem) == 1) {
@@ -228,6 +229,15 @@ static int process_one_unit(char *spec, struct unitdesc *desc)
desc->name_length = 0;
}
+ if (iswanted) {
+ len = (size_t)(strchrnul(wanted, '\n') - wanted);
+ desc->wanted_by = strndup(wanted, len);
+ desc->wanted_by_length = len;
+ } else {
+ desc->wanted_by = NULL;
+ desc->wanted_by_length = 0;
+ }
+
desc->content = spec;
desc->content_length = pack(spec, '%');
@@ -292,8 +302,10 @@ static int process_all_units(char *corpus, int (*process)(void *closure, const s
rc = process(closure, descs, n);
/* cleanup and frees */
- while(n)
+ while(n) {
free((char *)(descs[--n].name));
+ free((char *)(descs[n].wanted_by));
+ }
free(descs);
return rc;
@@ -357,62 +369,129 @@ int unit_generator_process(struct json_object *jdesc, int (*process)(void *closu
/**************** SPECIALIZED PART *****************************/
-
-static int get_unit_path(char *path, size_t pathlen, const struct unitdesc *desc)
+static int check_unit_desc(const struct unitdesc *desc, int tells)
{
- int rc;
+ if (desc->scope != unitscope_unknown && desc->type != unittype_unknown && desc->name != NULL)
+ return 0;
- if (desc->scope == unitscope_unknown || desc->type == unittype_unknown || desc->name == NULL) {
+ if (tells) {
if (desc->scope == unitscope_unknown)
ERROR("unit of unknown scope");
if (desc->type == unittype_unknown)
ERROR("unit of unknown type");
if (desc->name == NULL)
ERROR("unit of unknown name");
+ }
+ errno = EINVAL;
+ return -1;
+}
+
+static int get_unit_path(char *path, size_t pathlen, const struct unitdesc *desc)
+{
+ int rc;
+
+ rc = snprintf(path, pathlen, "%s/%s/%s.%s",
+ SYSTEMD_UNITS_ROOT,
+ desc->scope == unitscope_system ? "system" : "user",
+ desc->name,
+ desc->type == unittype_socket ? "socket" : "service");
+
+ if (rc >= 0 && (size_t)rc >= pathlen) {
+ ERROR("can't set the unit path");
errno = EINVAL;
rc = -1;
}
- else {
- rc = snprintf(path, pathlen, "%s/%s/%s.%s",
- SYSTEMD_UNITS_ROOT,
- desc->scope == unitscope_system ? "system" : "user",
- desc->name,
- desc->type == unittype_socket ? "socket" : "service");
-
- if (rc >= 0 && (size_t)rc >= pathlen) {
- ERROR("can't set the unit name");
- errno = EINVAL;
- rc = -1;
- }
+ return rc;
+}
+
+static int get_wants_path(char *path, size_t pathlen, const struct unitdesc *desc)
+{
+ int rc;
+
+ rc = snprintf(path, pathlen, "%s/%s/%s.wants/%s.%s",
+ SYSTEMD_UNITS_ROOT,
+ desc->scope == unitscope_system ? "system" : "user",
+ desc->wanted_by,
+ desc->name,
+ desc->type == unittype_socket ? "socket" : "service");
+
+ if (rc >= 0 && (size_t)rc >= pathlen) {
+ ERROR("can't set the wants path");
+ errno = EINVAL;
+ rc = -1;
}
return rc;
}
-static int do_install_units(void *closure, const struct unitdesc descs[], unsigned count)
+static int get_wants_target(char *path, size_t pathlen, const struct unitdesc *desc)
{
int rc;
+
+ rc = snprintf(path, pathlen, "../%s.%s",
+ desc->name,
+ desc->type == unittype_socket ? "socket" : "service");
+
+ if (rc >= 0 && (size_t)rc >= pathlen) {
+ ERROR("can't set the wants target");
+ errno = EINVAL;
+ rc = -1;
+ }
+ return rc;
+}
+
+static int do_uninstall_units(void *closure, const struct unitdesc descs[], unsigned count)
+{
+ int rc, rc2;
unsigned i;
- char path[PATH_MAX + 1];
+ char path[PATH_MAX];
for (i = 0 ; i < count ; i++) {
- rc = get_unit_path(path, sizeof path, &descs[i]);
- if (rc >= 0) {
- rc = putfile(path, descs[i].content, descs[i].content_length);
+ rc = check_unit_desc(&descs[i], 0);
+ if (rc == 0) {
+ rc = get_unit_path(path, sizeof path, &descs[i]);
+ if (rc >= 0) {
+ rc = unlink(path);
+ }
+ if (descs[i].wanted_by != NULL) {
+ rc2 = get_wants_path(path, sizeof path, &descs[i]);
+ if (rc2 >= 0)
+ rc2 = unlink(path);
+ rc = rc < 0 ? rc : rc2;
+ }
}
}
return 0;
}
-static int do_uninstall_units(void *closure, const struct unitdesc descs[], unsigned count)
+static int do_install_units(void *closure, const struct unitdesc descs[], unsigned count)
{
int rc;
unsigned i;
- char path[PATH_MAX];
-
- for (i = 0 ; i < count ; i++) {
- rc = get_unit_path(path, sizeof path, &descs[i]);
- if (rc >= 0) {
- rc = unlink(path);
+ char path[PATH_MAX + 1], target[PATH_MAX + 1];
+
+ i = 0;
+ while (i < count) {
+ rc = check_unit_desc(&descs[i], 1);
+ if (!rc) {
+ rc = get_unit_path(path, sizeof path, &descs[i]);
+ if (rc >= 0) {
+ rc = putfile(path, descs[i].content, descs[i].content_length);
+ if (descs[i].wanted_by != NULL) {
+ rc = get_wants_path(path, sizeof path, &descs[i]);
+ if (rc >= 0) {
+ rc = get_wants_target(target, sizeof target, &descs[i]);
+ if (rc >= 0) {
+ unlink(path); /* TODO? check? */
+ rc = symlink(target, path);
+ }
+ }
+ }
+ i++;
+ }
+ }
+ if (rc < 0) {
+ do_uninstall_units(closure, descs, i);
+ return rc;
}
}
return 0;
diff --git a/src/wgtpkg-unit.h b/src/wgtpkg-unit.h
index 1d56eb3..f152736 100644
--- a/src/wgtpkg-unit.h
+++ b/src/wgtpkg-unit.h
@@ -39,6 +39,8 @@ struct unitdesc {
size_t name_length;
const char *content;
size_t content_length;
+ const char *wanted_by;
+ size_t wanted_by_length;
};
extern int unit_generator_on(const char *filename);