ctdb-scripts: Improve NFS-Ganesha export path extraction
authorMartin Schwenke <mschwenke@ddn.com>
Tue, 30 Apr 2024 05:00:34 +0000 (15:00 +1000)
committerMartin Schwenke <mschwenke@ddn.com>
Tue, 21 May 2024 23:15:18 +0000 (09:15 +1000)
Path values do not need to have quotes.  The current code fails if
there aren't any.

Instead, implement a 2 stage parser using 2 sed commands.  See
comments in the code for details.

Regexps are POSIX basic regular expressions, apart from \<WORD\> (used
to ensure WORD is on word boundaries, and the 'i' flag for case
insensitivity.  The latter is supported in FreeBSD sed.

This code successfully parses Path values out of the following
monstrosity:

path = "/foo/bar1;a";
   Path = /foo/bar2;
Something = false;
Pseudo = "/foo/bar3x" ; Path = "/foo/bar3; y" ; Access_type = RO;
Pseudo = "/foo/bar4x" ; path=/foo/bar4; Access_type = RO;
Pseudo = "/foo/barNONONO" ; not_Path=/foo/barNONONO; Access_type = RO;
   Path = /foo/bar5
Pseudo = "/foo/bar6x Path=foo" ; Path=/foo/bar6; Access_type = RO

This is probably the best that can be done within a shell script.

Signed-off-by: Martin Schwenke <mschwenke@ddn.com>
ctdb/doc/examples/nfs-ganesha-callout

index 64f57506d9f821e6fb3e452f550d2fc4e8c57ccc..f08dc49562622f75bf72ee1524c0a02aba566dbd 100755 (executable)
@@ -324,9 +324,29 @@ nfs_startup()
 
 nfs_monitor_list_shares()
 {
-       grep Path "$nfs_exports_file" |
-               cut -f2 -d\" |
-               sort -u
+       # The 1st sed command prints anything after "Path = ", where
+       # Path is matched case-insensitively, and must be on a word
+       # boundary.  This also deletes any semicolon-terminated items
+       # before Path.  Each output line now starts with a value for
+       # Path, but may have other settings after a semicolon.
+       _s1='s/.*;*[[:space:]]*\<path\>[[:space:]]*=[[:space:]]*//ip'
+
+       # The 2nd sed command has 2 steps:
+       #
+       # a. Attempt to match an unquoted value not containing
+       #    semicolon or double-quote, followed by an optional
+       #    line-terminating semicolon or a semicolon followed by
+       #    anything else.  Keep the value and double-quote it.  If
+       #    the value was already quoted then the line will be
+       #    unchanged.  The pattern space now starts with a
+       #    double-quoted value.
+       _s2a='s/^\([^";][^";]*\)[[:space:]]*\(;*[[:space:]]*$\|;.*\)/"\1"/'
+       # b. Finally, print the contents of double-quotes at the
+       #    beginning of the pattern space, discarding anything
+       #    that follows.
+       _s2b='s/^"\([^"][^"]*\)".*/\1/p'
+
+       sed -n -e "$_s1" "$nfs_exports_file" | sed -n -e "$_s2a" -e "$_s2b"
 }
 
 ##################################################