Welcome to little lamb

Code » anopa » commit 432ef35

Add aa-setready

author Olivier Brunel
2015-03-16 18:52:38 UTC
committer Olivier Brunel
2015-04-04 12:47:36 UTC
parent 48002be7c7d01076740f5d77b9b87f320672df83

Add aa-setready

doc/aa-setready.pod +85 -0
package/modes +1 -0
package/targets.mak +2 -0
src/utils/aa-setready.c +114 -0
src/utils/deps-exe/aa-setready +3 -0

diff --git a/doc/aa-setready.pod b/doc/aa-setready.pod
new file mode 100644
index 0000000..7c8e66a
--- /dev/null
+++ b/doc/aa-setready.pod
@@ -0,0 +1,85 @@
+=head1 NAME
+
+aa-setready - Set a service (un)ready
+
+=head1 SYNOPSIS
+
+B<aa-setready> [B<-U> | B<-D>] I<SERVICEDIR>
+
+=head1 OPTIONS
+
+=over
+
+=item B<-U, --ready>
+
+Mark the service ready, i.e. create the I<ready> file and emit event 'U' on
+I<event> fifodir. This is the default.
+
+=item B<-h, --help>
+
+Show help screen and exit.
+
+=item B<-D, --unready>
+
+Mark the service unready, i.e. remove the I<ready> file (if exists) and emit
+event 'D' on I<event> fifodir.
+
+=item B<-V, --version>
+
+Show version information and exit.
+
+=back
+
+=head1 DESCRIPTION
+
+B<aa-setready>(1) is a simple tool to mark a long-running service ready or
+"unready".
+
+Marking a service ready means create the I<ready> file (used by B<s6>) and emit
+event U on the service's fifodir I<event>. This is similar to what
+B<s6-notifywhenup> does.
+
+Marking a service unready means remove the I<ready> file if it exists, and emit
+event D on the service's fifodir I<event>. This is meant for service that can
+stay up (running) but lose their ready state (e.g. connection dropped).
+
+Obviously you need to have the appropriate permissions to perform all the needed
+tasks.
+
+=head2 RETURN VALUE
+
+B<aa-setready>(1) will return 0 on success. If an error occurs one or more
+warning messages will be shown on stderr, and it will return:
+
+=over
+
+=item B<1>
+
+Syntax error (e.g. unknown option)
+
+=item B<2>
+
+Failed to init timestamp (needed to write the I<ready> file)
+
+=item B<3>
+
+Failed to create I<ready> file
+
+=item B<4>
+
+Failed to remove the I<ready> file
+
+=item B<10>
+
+Failed to sent the event on I<event> fifodir
+
+=back
+
+It can also return a value higher than 10 if more than one error occurs, e.g. 13
+if it couldn't create the I<ready> file nor emit the event, or 14 if it couldn't
+remove the I<ready> file nor emit the event (Note that this doesn't occur when
+the file doesn't exist, which is not treated as an error.).
+
+Note that 1 and 2 will always causes immediate termination, i.e.
+B<aa-setready>(1) stops its execution right away (and therefore cannot return 11
+or 12).
diff --git a/package/modes b/package/modes
index 0eee9a1..e9045c4 100644
--- a/package/modes
+++ b/package/modes
@@ -8,6 +8,7 @@ aa-mvlog                0755
 aa-pivot                0755
 aa-reboot               0755
 aa-service              0755
+aa-setready             0755
 aa-shutdown             0755
 aa-stage0               0755
 aa-stage1               0755
diff --git a/package/targets.mak b/package/targets.mak
index eb86a32..263627e 100644
--- a/package/targets.mak
+++ b/package/targets.mak
@@ -9,6 +9,7 @@ aa-mvlog \
 aa-pivot \
 aa-reboot \
 aa-service \
+aa-setready \
 aa-start \
 aa-stop \
 aa-sync \
@@ -38,6 +39,7 @@ aa-mvlog.1 \
 aa-pivot.1 \
 aa-reboot.1 \
 aa-service.1 \
+aa-setready.1 \
 aa-shutdown.1 \
 aa-stage0.1 \
 aa-stage1.1 \
diff --git a/src/utils/aa-setready.c b/src/utils/aa-setready.c
new file mode 100644
index 0000000..20b6258
--- /dev/null
+++ b/src/utils/aa-setready.c
@@ -0,0 +1,114 @@
+
+#include <getopt.h>
+#include <errno.h>
+#include <unistd.h>
+#include <skalibs/strerr2.h>
+#include <skalibs/djbunix.h>
+#include <s6/ftrigw.h>
+#include <s6/s6-supervise.h>
+#include <anopa/common.h>
+
+extern char const *PROG;
+
+static void
+dieusage (int rc)
+{
+    aa_die_usage (rc, "[OPTION] SERVICEDIR",
+            " -U, --ready                   Mark service ready; This is the default.\n"
+            " -D, --unready                 Mark service not ready\n"
+            "\n"
+            " -h, --help                    Show this help screen and exit\n"
+            " -V, --version                 Show version information and exit\n"
+            );
+}
+
+int
+main (int argc, char * const argv[])
+{
+    PROG = "aa-setready";
+    int ready = 1;
+    int r = 0;
+
+    for (;;)
+    {
+        struct option longopts[] = {
+            { "unready",            no_argument,        NULL,   'D' },
+            { "help",               no_argument,        NULL,   'h' },
+            { "ready",              no_argument,        NULL,   'U' },
+            { "version",            no_argument,        NULL,   'V' },
+            { NULL, 0, 0, 0 }
+        };
+        int c;
+
+        c = getopt_long (argc, argv, "DhUV", longopts, NULL);
+        if (c == -1)
+            break;
+        switch (c)
+        {
+            case 'D':
+                ready = 0;
+                break;
+
+            case 'h':
+                dieusage (0);
+
+            case 'U':
+                ready = 1;
+                break;
+
+            case 'V':
+                aa_die_version ();
+
+            default:
+                dieusage (1);
+        }
+    }
+    argc -= optind;
+    argv += optind;
+
+    if (argc != 1)
+        dieusage (1);
+
+    {
+        int l = strlen (argv[0]);
+        char fifodir[l + 1 + sizeof (S6_SUPERVISE_EVENTDIR)];
+        char readyfile[l + 1 + sizeof (S6_SUPERVISE_READY_FILENAME)];
+
+        byte_copy (fifodir, l, argv[0]);
+        fifodir[l] = '/';
+        byte_copy (fifodir + l + 1, sizeof (S6_SUPERVISE_EVENTDIR), S6_SUPERVISE_EVENTDIR);
+
+        byte_copy (readyfile, l, argv[0]);
+        readyfile[l] = '/';
+        byte_copy (readyfile + l + 1, sizeof (S6_SUPERVISE_READY_FILENAME), S6_SUPERVISE_READY_FILENAME);
+
+        if (ready)
+        {
+            char data[TAIN_PACK];
+
+            if (!tain_now_g())
+                strerr_diefu1sys (2, "tain_now");
+            tain_pack (data, &STAMP);
+
+            if (!openwritenclose_suffix (readyfile, data, TAIN_PACK, ".new"))
+            {
+                r = 3;
+                strerr_warnwu2sys ("create ", readyfile);
+            }
+        }
+        else
+            if (unlink (readyfile) < 0 && errno != ENOENT)
+            {
+                r = 4;
+                strerr_warnwu2sys ("remove ", readyfile);
+            }
+
+        if (ftrigw_notify (fifodir, (ready) ? 'U' : 'D') < 0)
+        {
+            r += 10;
+            strerr_warnwu4sys ("send event ", (ready) ? "U": "D" , " via ", fifodir);
+        }
+    }
+
+    return r;
+}
diff --git a/src/utils/deps-exe/aa-setready b/src/utils/deps-exe/aa-setready
new file mode 100644
index 0000000..9d65c4b
--- /dev/null
+++ b/src/utils/deps-exe/aa-setready
@@ -0,0 +1,3 @@
+${LIBANOPA}
+-ls6
+-lskarnet