ctdb-scripts: Drop node count from "ctdb natgw status" output
[vlendec/samba-autobuild/.git] / ctdb / tools / ctdb_natgw
1 #!/bin/sh
2
3 if [ -z "$CTDB_BASE" ] ; then
4     export CTDB_BASE="/usr/local/etc/ctdb"
5 fi
6
7 . "${CTDB_BASE}/functions"
8 loadconfig "ctdb"
9
10 # Default NAT gateway nodes file location
11 [ -n "$CTDB_NATGW_NODES" ] || CTDB_NATGW_NODES="${CTDB_BASE}/natgw_nodes"
12
13 [ -n "$CTDB_SOCKET" ] && export CTDB_SOCKET
14
15 ############################################################
16
17 usage ()
18 {
19 cat <<EOF
20 $0 <option>
21
22 <option> is one of:
23   master     Display node number and private IP address of master node
24   list       List private IP addresses of nodes in group, annotate master
25   status     Show status of nodes in NAT gateway group
26   natgwlist  Combination of "master" and "status", for backward compatiblity
27 EOF
28     exit 1
29 }
30
31 nodestatus_X=""
32 # Fields are:
33 # Node|IP|Disconnected|Banned|Disabled|Unhealthy|Stopped|Inactive|PartiallyOnline|ThisNode
34 get_nodestatus_X ()
35 {
36     # Result is cached in global variable nodestatus_X
37     [ -n "$nodestatus_X" ] || \
38         nodestatus_X=$(ctdb -X nodestatus all |
39                               sed -e '1d' -e 's@^|@@' -e 's@|$@@')
40 }
41
42 get_nodestatus ()
43 {
44     # Result is cached in global variable nodestatus
45     [ -n "$nodestatus" ] || nodestatus=$(ctdb nodestatus all)
46     [ $? -ne 255 ] # ctdb nodestatus returns 255 on failure
47 }
48
49 get_natgw_nodes ()
50 {
51     # Result is cached in global variable natgw_nodes
52     if [ -n "$natgw_nodes" ] ; then
53         return
54     fi
55
56     if [ ! -r "$CTDB_NATGW_NODES" ] ; then
57         return 1
58     fi
59
60     natgw_nodes=$(cat "$CTDB_NATGW_NODES") || return 1
61
62     # Sanity check file contents here
63     while read _ip _options ; do
64         # Skip comments
65         case "$_ip" in
66             \#*) continue ;;
67         esac
68         case "$_options" in
69             slave-only|"") : ;;
70             *) die "${prog}: Invalid options \"${_options}\" in  \"$CTDB_NATGW_NODES\""
71         esac
72     done <<EOF
73 $natgw_nodes
74 EOF
75
76     return 0
77 }
78
79 # Print the PNN and IP address of the NAT gateway master node
80 find_master ()
81 {
82     get_natgw_nodes || \
83         die "${prog}: NAT gateway nodes file \"$CTDB_NATGW_NODES\" not found"
84     get_nodestatus_X  || \
85         die "${prog}: Unable to get status of nodes"
86
87     # $_ms is an @-delimited list of nodes that are allowed to be the master
88     _ms="@"
89     while read _ip _options ; do
90         case "$_options" in
91             "") _ms="${_ms}${_ip}@" ;;
92         esac
93     done <<EOF
94 $natgw_nodes
95 EOF
96
97     # Now filter by $ms and by status of nodes...
98
99     # Note that the 3 awk invocations below have "||" between them, so
100     # the first to succeed will select the master node.
101
102     # First try for a fully active and healthy node, so must not be
103     # DISABLED, UNHEALTHY or INACTIVE (last covers DISCONNECTED,
104     # BANNED or STOPPED)
105     awk -F '|' -v ms="$_ms" \
106         'BEGIN { ret = 2 }
107          ms ~ "@" $2 "@" && \
108              $5 == 0 && $6 == 0 && $8 == 0 { print $1, $2 ; ret=0 ; exit }
109          END { exit ret }' <<EOF ||
110 $nodestatus_X
111 EOF
112     # Not found?  UNHEALTHY/BANNED will do, so node must not be
113     # DISCONNECTED, DISABLED or STOPPED
114     awk -F '|' -v ms="$_ms" \
115         'BEGIN { ret = 2 }
116          ms ~ "@" $2 "@" && \
117              $3 == 0 && $5 == 0 && $7 == 0 { print $1, $2 ; ret=0 ; exit }
118          END { exit ret }' <<EOF ||
119 $nodestatus_X
120 EOF
121     # Not found?  STOPPED will do, so node must not be DISCONNECTED or
122     # DISABLED
123     awk -F '|' -v ms="$_ms" \
124         'BEGIN { ret = 2 }
125          ms ~ "@" $2 "@" && \
126              $3 == 0 && $5 == 0 { print $1, $2 ; ret=0 ; exit }
127          END { exit ret }' <<EOF
128 $nodestatus_X
129 EOF
130 }
131
132 # List all nodes in the NAT gateway group, annotating the master node
133 nodes_list ()
134 {
135     get_natgw_nodes || \
136         die "${prog}: NAT gateway nodes file \"$CTDB_NATGW_NODES\" not found"
137     set -- $(find_master)  || \
138         die "${prog}: Unable to determine NAT gateway master node"
139     _master_ip="$2"
140
141     # Annotate the master node
142     while read _ip _options ; do
143         if [ "$_ip" = "$_master_ip" ] ; then
144             _options="MASTER${_options:+,}${_options}"
145         fi
146         printf "${_ip}${_options:+\t}${_options}\n"
147     done <<EOF
148 $natgw_nodes
149 EOF
150 }
151
152 # Print the status of all nodes in the NAT gateway group, along with a count
153 nodes_status ()
154 {
155     get_natgw_nodes || \
156         die "${prog}: NAT gateway nodes file \"$CTDB_NATGW_NODES\" not found"
157     get_nodestatus || \
158         die "${prog}: Unable to get status of nodes"
159
160     # $_ns is a @-delimited list of nodes in the NAT gateway group
161     _ns="@"
162     while read _ip _options ; do
163         _ns="${_ns}${_ip}@"
164     done <<EOF
165 $natgw_nodes
166 EOF
167
168     # Print status of nodes in $_ns, along with node count
169     awk -v ns="$_ns" 'ns ~ "@" $2 "@" { print $0 }' <<EOF
170 $nodestatus
171 EOF
172 }
173
174 # For backward compatibility
175 natgwlist ()
176 {
177     _ret=0
178     find_master
179     if [ $? -eq 2 ] ; then
180         echo "-1 0.0.0.0"
181         _ret=2
182     fi
183     _t=$(nodes_status) || return $?
184     _n=$(echo "$_t" | wc -l)
185     echo "Number of nodes:${_n}"
186     echo "$_t"
187     return $_ret
188 }
189
190 prog=$(basename "$0")
191 cmd="$1"
192
193 case "$cmd" in
194     master)    find_master ;;
195     list)      nodes_list ;;
196     status)    nodes_status ;;
197     natgwlist) natgwlist ;;
198     *)         usage ;;
199 esac