ctdb-event: Update event tool to handle symbolic links
authorMartin Schwenke <martin@meltin.net>
Fri, 6 Jul 2018 07:51:27 +0000 (17:51 +1000)
committerAmitay Isaacs <amitay@samba.org>
Wed, 11 Jul 2018 09:48:38 +0000 (11:48 +0200)
Supports the case when scripts are installed in the data directory and
are linked to when enabled.

Signed-off-by: Martin Schwenke <martin@meltin.net>
Pair-programmed-with: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
ctdb/event/event_tool.c
ctdb/tests/eventd/etc-ctdb/events/data/README [new file with mode: 0644]
ctdb/tests/eventd/etc-ctdb/share/events/data/01.dummy.script [new file with mode: 0755]
ctdb/tests/eventd/eventd_009.sh [new file with mode: 0755]

index e2e720fd61dc8bcb88901b5823a81accb87f3ca7..b83288ccc011ae1cbe16db03966c615e184aa0f9 100644 (file)
@@ -18,6 +18,7 @@
 */
 
 #include "replace.h"
+#include "system/filesys.h"
 #include "system/time.h"
 
 #include <popt.h>
@@ -335,17 +336,67 @@ static int event_command_script_enable(TALLOC_CTX *mem_ctx,
 {
        struct event_tool_context *ctx = talloc_get_type_abort(
                private_data, struct event_tool_context);
+       struct stat statbuf;
+       char *script, *etc_script, *data_script;
+       int ret;
 
        if (argc != 2) {
                cmdline_usage(ctx->cmdline, "script enable");
                return 1;
        }
 
-       return event_command_script(mem_ctx,
-                                   ctx,
-                                   argv[0],
-                                   argv[1],
-                                   CTDB_EVENT_SCRIPT_ENABLE);
+       script = talloc_asprintf(mem_ctx, "events/%s/%s.script", argv[0], argv[1]);
+       if (script == NULL) {
+               return ENOMEM;
+       }
+
+       etc_script = path_etcdir_append(mem_ctx, script);
+       if (etc_script == NULL) {
+               return ENOMEM;
+       }
+
+       data_script = path_datadir_append(mem_ctx, script);
+       if (data_script == NULL) {
+               return ENOMEM;
+       }
+
+       ret = lstat(etc_script, &statbuf);
+       if (ret == 0) {
+               if (S_ISLNK(statbuf.st_mode)) {
+                       /* Link already exists */
+                       return 0;
+               } else if (S_ISREG(statbuf.st_mode)) {
+                       return event_command_script(mem_ctx,
+                                                   ctx,
+                                                   argv[0],
+                                                   argv[1],
+                                                   CTDB_EVENT_SCRIPT_ENABLE);
+               }
+
+               printf("Script %s is not a file or a link\n", etc_script);
+               return EINVAL;
+       } else {
+               if (errno == ENOENT) {
+                       ret = stat(data_script, &statbuf);
+                       if (ret != 0) {
+                               printf("Script %s does not exist in %s\n",
+                                      argv[1], argv[0]);
+                               return ENOENT;
+                       }
+
+                       ret = symlink(data_script, etc_script);
+                       if (ret != 0) {
+                               printf("Failed to create symlink %s\n",
+                                     etc_script);
+                               return EIO;
+                       }
+
+                       return 0;
+               }
+
+               printf("Script %s does not exist\n", etc_script);
+               return EINVAL;
+       }
 }
 
 static int event_command_script_disable(TALLOC_CTX *mem_ctx,
@@ -355,17 +406,51 @@ static int event_command_script_disable(TALLOC_CTX *mem_ctx,
 {
        struct event_tool_context *ctx = talloc_get_type_abort(
                private_data, struct event_tool_context);
+       struct stat statbuf;
+       char *script, *etc_script;
+       int ret;
+
 
        if (argc != 2) {
                cmdline_usage(ctx->cmdline, "script disable");
                return 1;
        }
 
-       return event_command_script(mem_ctx,
-                                   ctx,
-                                   argv[0],
-                                   argv[1],
-                                   CTDB_EVENT_SCRIPT_DISABLE);
+       script = talloc_asprintf(mem_ctx, "events/%s/%s.script", argv[0], argv[1]);
+       if (script == NULL) {
+               return ENOMEM;
+       }
+
+       etc_script = path_etcdir_append(mem_ctx, script);
+       if (etc_script == NULL) {
+               return ENOMEM;
+       }
+
+       ret = lstat(etc_script, &statbuf);
+       if (ret == 0) {
+               if (S_ISLNK(statbuf.st_mode)) {
+                       /* Link exists */
+                       ret = unlink(etc_script);
+                       if (ret != 0) {
+                               printf("Failed to remove symlink %s\n",
+                                      etc_script);
+                               return EIO;
+                       }
+
+                       return 0;
+               } else if (S_ISREG(statbuf.st_mode)) {
+                       return event_command_script(mem_ctx,
+                                                   ctx,
+                                                   argv[0],
+                                                   argv[1],
+                                                   CTDB_EVENT_SCRIPT_DISABLE);
+               }
+
+               printf("Script %s is not a file or a link\n", etc_script);
+               return EINVAL;
+       }
+
+       return 0;
 }
 
 struct cmdline_command event_commands[] = {
diff --git a/ctdb/tests/eventd/etc-ctdb/events/data/README b/ctdb/tests/eventd/etc-ctdb/events/data/README
new file mode 100644 (file)
index 0000000..f38a189
--- /dev/null
@@ -0,0 +1 @@
+initially empty event scripts directory
diff --git a/ctdb/tests/eventd/etc-ctdb/share/events/data/01.dummy.script b/ctdb/tests/eventd/etc-ctdb/share/events/data/01.dummy.script
new file mode 100755 (executable)
index 0000000..9c56f5b
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+case "$1" in
+"failure") exit 1 ;;
+*) exit 0 ;;
+esac
diff --git a/ctdb/tests/eventd/eventd_009.sh b/ctdb/tests/eventd/eventd_009.sh
new file mode 100755 (executable)
index 0000000..cc6c1b5
--- /dev/null
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+. "${TEST_SCRIPTS_DIR}/unit.sh"
+
+define_test "eventscript directory with links"
+
+setup_eventd
+
+ok_null
+simple_test run 10 data failure
+
+ok_null
+simple_test script enable data 01.dummy
+
+required_result 8 <<EOF
+Event failure in data failed
+EOF
+simple_test run 10 data failure
+
+required_result 1 <<EOF
+01.dummy             ERROR      DURATION DATETIME
+  OUTPUT: 
+EOF
+simple_test status data failure
+
+ok_null
+simple_test run 10 data monitor
+
+ok <<EOF
+01.dummy             OK         DURATION DATETIME
+EOF
+simple_test status data monitor
+
+ok_null
+simple_test script disable data 01.dummy
+
+ok_null
+simple_test run 10 data failure