]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mworker/cli: set expert/experimental mode from the CLI
authorWilliam Lallemand <wlallemand@haproxy.org>
Tue, 1 Feb 2022 15:08:50 +0000 (16:08 +0100)
committerWilliam Lallemand <wlallemand@haproxy.org>
Tue, 1 Feb 2022 16:33:06 +0000 (17:33 +0100)
Allow to set the master CLI in expert or experimental mode. No command
within the master are unlocked yet, but it gives the ability to send
expert or experimental commands to the workers.

    echo "@1; experimental-mode on; del server be1/s2" | socat /var/run/haproxy.master -
    echo "experimental-mode on; @1 del server be1/s2" | socat /var/run/haproxy.master -

doc/management.txt
include/haproxy/stream-t.h
src/cli.c

index b9b7ebdfb7b0e418f2c86fbdf6b5d75c905d1c24..5bcdd177795d489380e49889a5a4ff6b816becbb 100644 (file)
@@ -1941,6 +1941,13 @@ experimental-mode [on|off]
   development. These features are currently not stable and should be used with
   care. They may be subject to breaking changes across versions.
 
+  When used from the master CLI, this command shouldn't be prefixed, as it will
+  set the mode for any worker when connecting to its CLI.
+
+  Example:
+    echo "@1; experimental-mode on; del server be1/s2" | socat /var/run/haproxy.master -
+    echo "experimental-mode on; @1 del server be1/s2" | socat /var/run/haproxy.master -
+
 expert-mode [on|off]
   This command is similar to experimental-mode but is used to toggle the
   expert mode.
@@ -1953,6 +1960,13 @@ expert-mode [on|off]
   This command is only accessible in admin level. Changing to another level
   automatically resets the expert mode.
 
+  When used from the master CLI, this command shouldn't be prefixed, as it will
+  set the mode for any worker when connecting to its CLI.
+
+  Example:
+    echo "@1; expert-mode on; debug dev exit 1" | socat /var/run/haproxy.master -
+    echo "expert-mode on; @1 debug dev exit 1" | socat /var/run/haproxy.master -
+
 get map <map> <value>
 get acl <acl> <value>
   Lookup the value <value> in the map <map> or in the ACL <acl>. <map> or <acl>
index f942823def4157e58f142373919d0e4e4e1fd850..e44d2ac607e7924d088c4261fd3684deb842d586 100644 (file)
 #define SF_WEBSOCKET    0x00400000     /* websocket stream */
 
 /* flags for the proxy of the master CLI */
-/* 0x1.. to 0x3 are reserved for ACCESS_LVL_MASK */
+/* 0x0001.. to 0x8000 are reserved for ACCESS_* flags from cli-t.h */
 
-#define PCLI_F_PROMPT          0x4
-#define PCLI_F_PAYLOAD         0x8
+#define PCLI_F_PROMPT   0x10000
+#define PCLI_F_PAYLOAD  0x20000
 
 struct hlua;
 struct proxy;
index 16ddf052675945fbef38272c3c3f85841cb9aae7..841a88dc9db91ed62d14734a951ffc4c20152386 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -1751,6 +1751,10 @@ static int cli_parse_expert_experimental_mode(char **args, char *payload, struct
        char *level_str;
        char *output = NULL;
 
+       /* this will ask the applet to not output a \n after the command */
+       if (*args[1] && *args[2] && strcmp(args[2], "-") == 0)
+               appctx->st1 |= APPCTX_CLI_ST1_NOLF;
+
        if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
                return 1;
 
@@ -2262,6 +2266,27 @@ int pcli_find_and_exec_kw(struct stream *s, char **args, int argl, char **errmsg
                s->pcli_flags &= ~ACCESS_LVL_MASK;
                s->pcli_flags |= ACCESS_LVL_USER;
                return argl;
+
+       } else if (strcmp(args[0], "expert-mode") == 0) {
+               if (!pcli_has_level(s, ACCESS_LVL_ADMIN)) {
+                       memprintf(errmsg, "Permission denied!\n");
+                       return -1;
+               }
+
+               s->pcli_flags &= ~ACCESS_EXPERT;
+               if ((argl > 1) && (strcmp(args[1], "on") == 0))
+                       s->pcli_flags |= ACCESS_EXPERT;
+               return argl;
+
+       } else if (strcmp(args[0], "experimental-mode") == 0) {
+               if (!pcli_has_level(s, ACCESS_LVL_ADMIN)) {
+                       memprintf(errmsg, "Permission denied!\n");
+                       return -1;
+               }
+               s->pcli_flags &= ~ACCESS_EXPERIMENTAL;
+               if ((argl > 1) && (strcmp(args[1], "on") == 0))
+                       s->pcli_flags |= ACCESS_EXPERIMENTAL;
+               return argl;
        }
 
        return 0;
@@ -2410,6 +2435,15 @@ int pcli_parse_request(struct stream *s, struct channel *req, char **errmsg, int
        }
 
        if (ret > 1) {
+               if (s->pcli_flags & ACCESS_EXPERIMENTAL) {
+                       ci_insert_line2(req, 0, "experimental-mode on -", strlen("experimental-mode on -"));
+                       ret += strlen("experimental-mode on -") + 2;
+               }
+               if (s->pcli_flags & ACCESS_EXPERT) {
+                       ci_insert_line2(req, 0, "expert-mode on -", strlen("expert-mode on -"));
+                       ret += strlen("expert-mode on -") + 2;
+               }
+
                if (pcli_has_level(s, ACCESS_LVL_ADMIN)) {
                        goto end;
                } else if (pcli_has_level(s, ACCESS_LVL_OPER)) {