Gentoo Archives: gentoo-dev

From: James Yonan <jim@×××××.net>
To: Marko Mikulicic <marko@××××.org>, James Yonan <jim@×××××.net>
Cc: gentoo-dev@g.o
Subject: Re: [gentoo-dev] Init Scripts
Date: Sat, 28 Jun 2003 18:36:15
Message-Id: twig.1056825371.41079@yonan.net
Marko,

It's an interesting approach, though it requires that you gentooize the
openvpn config files, therefore breaking the ability to move the config files
across platforms.

I'm not sure if the init script you provided is just something you wrote for
personal use, or if you are making an argument that it (or the style it
embodies) should be officially incorporated as the Gentoo Init Script for
OpenVPN.  If it is the latter, then I must take this opportunity to argue :)

If you look at other services (apache, samba, etc.) there is a precedent for
only putting very minimal info (such as command line options) in conf.d, but
leaving the .conf files as they are in /etc/<package>.  I think it's important
for .conf files to be compatible across different distros and OSes, and IMHO
if you start moving too much complexity from .conf files to conf.d files, they
lose their lightweight "meta-configuration" properties, and instead just
become new versions of .conf files which don't add any new value and subtract
from portability.

Now having said that, I appreciate the elegance of a simple conf.d file that
can be understood and edited in 5 seconds.  I think the way that gentoo has
extracted the parameters formerly hardcoded in init.d files or buried in other
places and put them in conf.d is a nice idiom.  But I'm not sure where the
gentoo philosophy for .conf files fits in.  Certainly you're not going to put
apache.conf in a conf.d file.  Now maybe you figure out the 1% of apache.conf
that people really want to change and put that in conf.d.  But for the openvpn
case, I would argue that maintaining the existing configuration architecture
as it exists for other platforms, i.e. putting a .conf file for each tunnel in
/etc/openvpn, makes more sense, as it maintains the individuality of each
tunnel in a separate file.  I would use /etc/conf.d/openvpn for something like
global command line parameters to pass to each tunnel, but I'm not sure it's
the right place to put tunnel-specific configuration info.

For a supporting example, take NFS.  /etc/conf.d/nfs only contains global
command line parms, while /etc/exports has the per-share data.  Another
example is xinetd.  Conf files are split across services in /etc/xinetd and
the conf.d file only contains command line parameters.

Anyway, this is my approach to openvpn's init script:

#!/sbin/runscript

# OpenVPN start/stop script
# Adapted to Gentoo by James Yonan

# Originally Contributed to the OpenVPN project by
# Douglas Keller <doug@×××××××××××××××.org>
# 2002.05.15

# This script does the following:
#
# - Starts an openvpn process for each .conf file it finds in
#   /etc/openvpn.
#
# - If /etc/openvpn/xxx.sh exists for a xxx.conf file then it executes
#   it before starting openvpn (useful for doing openvpn --mktun...).

# Location of openvpn binary
openvpn=/usr/local/sbin/openvpn

# PID directory
piddir=/var/run/openvpn

# Our working directory (.conf files should be here)
work=/etc/openvpn

# Our options
opts="start stop restart condrestart"

depend() {
    need net
    use dns
}

start() {
    ebegin "Starting OpenVPN"

    # Load the TUN/TAP module
    /sbin/modprobe tun >/dev/null 2>&1

    if [ ! -d  $piddir ]; then
	mkdir $piddir
    fi

    cd $work

    # Start every .conf in $work and run .sh if exists
    local errors=0
    local successes=0
    local retstatus=0
    for c in `/bin/ls *.conf 2>/dev/null`; do
	bn=${c%%.conf}
	if [ -f "$bn.sh" ]; then
	    . $bn.sh
	fi
	rm -f $piddir/$bn.pid
	$openvpn --daemon --writepid $piddir/$bn.pid --config $c --cd $work
	if [ $? = 0 ]; then
	    successes=1
	else
	    errors=1
	fi
    done

    # Decide status based on errors/successes.
    # If at least one tunnel succeeded, we return success.
    # If some tunnels succeeded and some failed, we return
    #   success but give a warning.
    if [ $successes = 1 ]; then
	if [ $errors = 1 ]; then
	    ewarn "Note: At least one OpenVPN tunnel failed to start"
	fi
    else
	retstatus=1
	if [ $errors = 0 ]; then
	    ewarn "Note: No OpenVPN configuration files were found in $work"
	fi
    fi
    eend $retstatus "Error starting OpenVPN"
}

stop() {
    ebegin "Stopping OpenVPN"
    for pidf in `/bin/ls $piddir/*.pid 2>/dev/null`; do
	if [ -s $pidf ]; then
	    kill `cat $pidf` >/dev/null 2>&1
	fi
	rm -f $pidf
    done
    eend 0
}

# this should really be in runscript.sh
started() {
    if [ -L "${svcdir}/started/${myservice}" ]; then
	return 1
    else
	return 0
    fi
}

# attempt to restart ONLY if we are already started
condrestart() {
    started || restart
}

######################### 

James


Marko Mikulicic <marko@××××.org> said:

> This is a multi-part message in MIME format. > --------------030500030705070304060203 > Content-Type: text/plain; charset=us-ascii; format=flowed > Content-Transfer-Encoding: 7bit > > James Yonan wrote: > > Hi, > > > > I'm new to Gentoo and I'm trying to convert the RedHat init script for OpenVPN > > over to Gentoo's format. Though I'm still learning the Gentoo way of writing > > init scripts, I would like to suggest the following additions to runscript.sh: > > > [....] > > (2) Condrestart is a useful init script method, often seen in RH init scripts. > > It basically says "restart only if service is already running". It is > > commonly used to restart a daemon after a software update. OpenVPN needs it > > so that the VPN daemon can be restarted if a network adaptor gets a new IP > > address from a DHCP server. In cases like these, you obviously don't want to > > restart the daemon unless it is already running. Condrestart becomes > > breathtakingly simple if started() above is defined: > > > > condrestart() { > > started || restart > > } > > > > If there are better ways of doing these things in Gentoo, please let me know. > > Otherwise, I can send a formal patch of my changes to runscript.sh > > I don't know the soultion for your problem but I have written a simple > script for > openvpn, which I use with success on a bunch of machines. It is very > "gentooish" > because it puts the configuration in /etc/conf.d/openvpn. > Take a look at it, maybe it can be useful. > > marko > > --------------030500030705070304060203 > Content-Type: text/plain; > name="openvpn" > Content-Transfer-Encoding: 7bit > Content-Disposition: inline; > filename="openvpn" > > #!/sbin/runscript > > depend() { > need net > } > > session() { > echo $(eval echo \$\{${1}_${2}\}) > } > > start () { > ebegin "Starting openvpn" > for i in ${!remote_*}; do > > SESSION=${i##remote_} > einfo "starting session $SESSION" > > CMD="openvpn --float --remote $(session remote $SESSION)\ > --ifconfig $(session ifconfig $SESSION) --dev tun --daemon\ > --cd /etc/openvpn --writepid /var/run/openvpn/$SESSION.pid" > > if [ ! -z $(session secret $SESSION) ]; then > CMD="$CMD --secret $(session secret $SESSION)" > fi > if [ ! -z $(session verbose $SESSION) ]; then > CMD="$CMD --verb $(session verbose $SESSION)" > fi > if [ ! -z $(session shaper $SESSION) ]; then > CMD="$CMD --shaper $(session shaper $SESSION)" > fi > if [ ! -z $(session port $SESSION) ]; then > CMD="$CMD --port $(session port $SESSION)" > fi > if [ ! -z $(session compression $SESSION) ]; then > if [ "$(session compression $SESSION)" = "yes" ]; then > CMD="$CMD --comp-lzo" > fi > fi > > > if [ ! -d /var/run/openvpn ]; then > mkdir /var/run/openvpn > fi > > /usr/sbin/$CMD > # can't detect error > > if [ ! -z $(session route $SESSION) ]; then > GW=$(echo $(session ifconfig $SESSION) | cut -d " " -f 1) > > for ((i=0;i<5;i++)); do > ifconfig | grep -q $GW && break > sleep 1 > done > > ifconfig | grep -q $GW || { > retval=$? > eend ${retval} "Failed to set routing" > return ${retval} > } > einfo "setting route for network $(session route $SESSION)" > route add -net $(session route $SESSION) gw $GW > fi > done > > eend 0 > } > > stop () { > ebegin "Stopping openvpn" > > for pidf in $(/bin/ls /var/run/openvpn/*.pid 2>/dev/null); do > kill $(cat $pidf) > rm -f $pidf > done > > eend 0 > } > > --------------030500030705070304060203 > Content-Type: text/plain; > name="openvpn.conf" > Content-Transfer-Encoding: 7bit > Content-Disposition: inline; > filename="openvpn.conf" > > # /etc/conf.d/openvpn: > > ### abcdefg > > # hostname of the remote peer > remote_abcdefg="abcdefg.linux-site.net" > > # tun interface addresses > ifconfig_abcdefg="192.168.200.2 192.168.200.1" > > # (opt) ssl key (symmetric key) > secret_abcdefg="abcdefg.vpnkey" > > # verbosity level > verbose_abcdefg=5 > > # destination network ip > route_abcdefg=192.168.1.0/24 > > # limit outgoing traffic > #shaper_abcdefg=1000 > > # UDP port (default 5000) > #port_abcdefg=5000 > > # use compression ? (yes/no) > compression_abcdefg=yes > > ### xyzw > > # hostname of the remote peer > remote_xyzw="62.202.4.19" > > # tun interface addresses > ifconfig_xyzw="192.168.200.4 192.168.200.3" > > # (opt) ssl key (symmetric key) > secret_xyzw="xyzw.vpnkey" > > # verbosity level > verbose_xyzw=5 > > # destination network ip > route_xyzw=192.168.195.0/24 > > # limit outgoing traffic > #shaper_xyzw=1000 > > # UDP port (default 5000) > port_xyzw=5001 > > # use compression ? (yes/no) > compression_xyzw=yes > > > --------------030500030705070304060203-- >
-- -- gentoo-dev@g.o mailing list

Replies

Subject Author
Re: [gentoo-dev] Init Scripts Marko Mikulicic <marko@××××.org>