OSDN Git Service

Add README.
[osdn-codes/ppp-resource-agents.git] / PPPConnection
1 #!/bin/sh
2 #
3 #   OCF resource agent for PPP connection
4 #
5 #   License:      GNU General Public License version 2 (GPL2)
6 #   (c) 2017 Tatsuki Sugiura <sugi@nemui.org> and OSDN Corporation <tech@osdn.jp>
7 #
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of version 2 of the GNU General Public License as
10 # published by the Free Software Foundation.
11 #
12 # This program is distributed in the hope that it would be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 #
16 # Further, this software is distributed without any warranty that it is
17 # free of the rightful claim of any third person regarding infringement
18 # or the like.  Any license provided herein, whether implied or
19 # otherwise, applies only to this software file.  Patent licenses, if
20 # any, provided herein do not apply to combinations of this program with
21 # other software, or any other product whatsoever.
22 #
23 # You should have received a copy of the GNU General Public License
24 # along with this program; if not, write the Free Software Foundation,
25 # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
26 #
27
28 # Init
29 : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
30 . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
31 . ${OCF_FUNCTIONS_DIR}/findif.sh
32
33 # Defaults
34 OCF_RESKEY_expected_ip4_default=""
35 OCF_RESKEY_expected_ip6_default=""
36 OCF_RESKEY_isp_default="provider"
37 OCF_RESKEY_pon_retries_default="30"
38 OCF_RESKEY_pon_wait_sec_default="5"
39 OCF_RESKEY_poff_wait_sec_default="3"
40 OCF_RESKEY_ip_wait_sec_default="30"
41
42 : ${OCF_RESKEY_expected_ip4=${OCF_RESKEY_expected_ip4_default}}
43 : ${OCF_RESKEY_expected_ip6=${OCF_RESKEY_expected_ip6_default}}
44 : ${OCF_RESKEY_isp=${OCF_RESKEY_isp_default}}
45 : ${OCF_RESKEY_pon_retries=${OCF_RESKEY_pon_retries_default}}
46 : ${OCF_RESKEY_pon_wait_sec=${OCF_RESKEY_pon_wait_sec_default}}
47 : ${OCF_RESKEY_poff_wait_sec=${OCF_RESKEY_poff_wait_sec_default}}
48 : ${OCF_RESKEY_ip_wait_sec=${OCF_RESKEY_ip_wait_sec_default}}
49
50 meta_data() {
51         cat <<EOM
52 <?xml version="1.0"?>
53 <!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
54 <resource-agent name="PPPConnection" version="0.1">
55   <version>0.1</version>
56   <longdesc lang="en">
57 Handle ppp connection as OCF resource. This resource calls pon/poff to connect ppp.
58   </longdesc>
59   <shortdesc lang="en">
60 Handle ppp connection as OCF resource. This resource calls pon/poff to connect ppp.
61   </shortdesc>
62   <parameters>
63     <parameter name="expected_ip4" unique="1" required="0">
64       <longdesc lang="en">
65       Expected IPv4 address. If you specify this parameter,
66       startup and monitor proecesses will wait the address associated with ppp interface.
67       </longdesc>
68       <shortdesc lang="en">Expected IPv4 address</shortdesc>
69       <content type="string" default="" />
70     </parameter>
71     <parameter name="expected_ip6" unique="1" required="0">
72       <longdesc lang="en">
73       Expected IPv6 address. If you specify this parameter,
74       startup and monitor proecesses will wait the address associated with ppp interface.
75       </longdesc>
76       <shortdesc lang="en">Expected IPv6 address</shortdesc>
77       <content type="string" default="" />
78     </parameter>
79     <parameter name="isp" unique="1" required="0">
80       <longdesc lang="en">
81       ISP name. This will be passed to pon/poff, and pppd will be monitored with specified isp.
82       Default is "provider".
83       </longdesc>
84       <shortdesc lang="en">ISP name (default: provider)</shortdesc>
85       <content type="string" default="provider" />
86     </parameter>
87     <parameter name="pon_retries" unique="0" required="0">
88       <longdesc lang="en">
89       Retry limit for pon
90       </longdesc>
91       <shortdesc lang="en">Retry limit for pon</shortdesc>
92       <content type="integer" default="30" />
93     </parameter>
94     <parameter name="pon_wait_sec" unique="0" required="0">
95       <longdesc lang="en">
96       Resource will wait specified seconds for ppp connection up. When it's exceeded, retry to run pon.
97       </longdesc>
98       <shortdesc lang="en">Wait time for pon on each tries</shortdesc>
99       <content type="integer" default="5" />
100     </parameter>
101     <parameter name="poff_wait_sec" unique="0" required="0">
102       <longdesc lang="en">
103       Resource will wait specified seconds for ppp connection down. When it's exceeded, retry to run poff.
104       </longdesc>
105       <shortdesc lang="en">Wait time for poff on each tries</shortdesc>
106       <content type="integer" default="3" />
107     </parameter>
108     <parameter name="ip_wait_sec" unique="0" required="0">
109       <longdesc lang="en">
110       Resource will wait specified seconds for ppp interface aquires expected IP address provided by expected_ip4 or expected_ip6.
111       </longdesc>
112       <shortdesc lang="en">Wait time for expected ip</shortdesc>
113       <content type="integer" default="30" />
114     </parameter>
115   </parameters>
116   <actions>
117     <action name="start"        timeout="60s" />
118     <action name="stop"         timeout="60s" />
119     <action name="monitor"      timeout="10s" interval="30s" depth="0" />
120     <action name="meta-data"    timeout="5s" />
121     <action name="validate-all" timeout="10s" />
122   </actions>
123 </resource-agent>
124 EOM
125
126   exit $OCF_SUCCESS
127 }
128
129 ppp_usage() {
130         cat <<END
131 usage: $0 {start|stop|status|monitor|validate-all|meta-data}
132
133 Expects to have a fully populated OCF RA-compliant environment set.
134 END
135 }
136
137 ppp_validate() {
138   ppp_init
139   check_binary ps
140   check_binary $AWK
141   check_binary $EGREP
142   check_binary grep
143   check_binary pon
144   check_binary poff
145
146
147   if [ ! -z "$IP4" -o ! -z "$IP6" ]; then
148     check_binary $IP2UTIL
149   fi
150
151   if [ -z "$ISP" ]; then
152     ocf_log err "Isp name is not specified for PPPConnection"
153     exit $OCF_ERR_CONFIGURED
154   fi
155 }
156
157 ppp_init() {
158   ISP="$OCF_RESKEY_isp"
159   IP4="$OCF_RESKEY_expected_ip4"
160   IP6="$OCF_RESKEY_expected_ip6"
161 }
162
163 ppp_start() {
164   ppp_init
165   tries=0
166   while ! ppp_check_pppd; do
167     tries=`expr $tries + 1`
168     ocf_run pon $ISP
169     if [ "$tries" -gt "$OCF_RESKEY_pon_retries" ]; then
170       ocf_log err "Retry limit for pon is exceeded. Giving up!"
171       return $OCF_ERR_GENERIC
172     fi
173     if [ "$tries" -eq 1 ]; then
174       sleep 1
175     else
176       sleep $OCF_RESKEY_pon_wait_sec
177     fi
178   done
179   tries=0
180   while ! ppp_check_ip; do
181     tries=`expr $tries + 1`
182     sleep 1
183     if [ "$tries" -gt "$OCF_RESKEY_ip_wait_sec" ]; then
184       ocf_log err "Timeout to aquire expected IP address ${IP4} ${IP6}."
185       return $OCF_ERR_GENERIC
186     fi
187   done
188   return $OCF_SUCCESS
189 }
190
191 ppp_stop() {
192   ppp_init
193   tries=0
194   while ppp_check_pppd; do
195     tries=`expr $tries + 1`
196     ocf_run poff ${ISP}
197     if [ "$tries" -eq 1 ]; then
198       sleep 1
199       continue
200     elif [ "$tries" -gt 10 ]; then
201       ocf_log err "ppp connection is still active with isp '${ISP}', giving up to stop!"
202       return $OCF_ERR_GENERIC
203     elif [ "$tries" -gt 8 ]; then
204       ocf_log warn "pppd still running with isp '${ISP}'. Trying to send KILL signal..."
205       kill -KILL `ps -ewwwo pid,args | $EGREP "[p]ppd call ${ISP}\$" | $AWK '{print $1}'`
206     elif [ "$tries" -gt 5 ]; then
207       ocf_log warn "pppd still running with isp '${ISP}'. Trying to send TERM signal..."
208       kill -TERM `ps -ewwwo pid,args | $EGREP "[p]ppd call ${ISP}\$" | $AWK '{print $1}'`
209     fi
210     sleep $OCF_RESKEY_poff_wait_sec
211   done
212   return $OCF_SUCCESS
213 }
214
215 ppp_check_pppd() {
216   ppp_init
217   ps -ewwo args | $EGREP -q "[p]ppd call ${ISP}\$" || return 1
218   return 0
219 }
220
221 ppp_check_ip() {
222   ppp_init
223   if [ ! -z "$IP4" ]; then
224     $IP2UTIL -4 a list type ppp | grep "inet $IP4 "
225     $IP2UTIL -4 a list type ppp | grep -q "inet $IP4 " || return 1
226   fi
227   if [ ! -z "$IP6" ]; then
228     $IP2UTIL -6 a list type ppp | grep "inet6 $IP6 "
229     $IP2UTIL -6 a list type ppp | grep -q "inet6 $IP6 " || return 1
230   fi
231   return 0
232 }
233
234 ppp_echo_status() {
235   if ! ppp_check_pppd; then
236     echo "disconnected"
237     return 0
238   fi
239   if ! ppp_check_ip; then
240     echo "connecting"
241     return 0
242   fi
243   echo "connected"
244   return 0
245 }
246
247 ppp_monitor() {
248   ppp_init
249   local status=`ppp_echo_status`
250   case $status in
251     connected)
252       return $OCF_SUCCESS
253       ;;
254     connecting)
255       return $OCF_ERR_GENERIC
256       ;;
257     disconnected)
258       return $OCF_NOT_RUNNING
259       ;;
260     *)
261       return $OCF_ERR_GENERIC
262       ;;
263   esac
264 }
265
266
267 case $__OCF_ACTION in
268   meta-data)
269     meta_data
270     ;;
271   usage|help)
272     ppp_usage
273     exit $OCF_SUCCESS
274     ;;
275 esac
276
277 ppp_validate
278
279 case $__OCF_ACTION in
280   start)
281     ppp_start
282     exit $?
283     ;;
284   stop)
285     ppp_stop
286     exit $?
287     ;;
288   status)
289     ip_status=`ppp_echo_status`
290     if [ $ip_status = "connected" ]; then
291       echo "running"
292       exit $OCF_SUCCESS
293     else
294       echo "stopped"
295       exit $OCF_NOT_RUNNING
296     fi
297     ;;
298   monitor)
299     ppp_monitor
300     exit $?
301     ;;
302   validate-all)
303     exit $OCF_SUCCESS
304     ;;
305   *)
306     ppp_usage
307     exit $OCF_ERR_UNIMPLEMENTED
308     ;;
309 esac
310
311 # vim: ft=sh sw=2