Mailinglist Archive: opensuse (1239 mails)

< Previous Next >
[opensuse] Re: lack of flexibility of systemd
Linda Walsh wrote:
Per Jessen wrote:
At this point, I would say stick with systemd. It _does_ still have
minor teething problems, but they are really mostly corner-cases. Occasionally migration incompatibilities appear where systemd no longer
supports what one was used to in sysvinit (see for instance Carlos'
spamd issue re inline comments).
----
How would you do something like the attached in systemd?

Or another for 'rcscript status' gave a stop-like display...

#!/bin/bash
#
# /etc/rc.d/transmission.rc script by Astara at tlinx.org (c) 2010
# use, modify and derive from, as thou wilt. If you find this
useful
# that's great! If you want to mention me in credits, that a
bonus! Enjoy!
# Developed and tested on suse 11.2 - 12.2

# transmission[{XX}] [verb] [{XX}] -- where {XX} is an *optional*

# integer and
is appended to the

# start script
name - to allow running

# more than one
instance -- I run 2

# a main one
'transmission, and a child

# transmission1


# running
multiple daemons allows finer

# grain control
of priorities

## note: "tmd" below, is my short-hand notation for "transmission-daemon"

# When {XX} is noted, for XX>0, home dir directs to 'child{XX}' under
# the real home directory
#
### BEGIN INIT INFO
# Provides: transmission
# Required-Start: $network, $local_fs,
# Should-Start: upnp $remote_fs named
# Required-Stop:
# Should-Stop:
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Short-Description: transmission-daemon: a file transfer daemon
# Description: transmission-daemon is a file transfer daemon utilizing
# the 'bit-torrent' protocol. This
allow for transferring
# large amounts of data by sharing the
network bandwith
# among downloaders. Note -- to make
effective use of
# this client, it is necessary to allow
incoming and
# outgoing traffic through a firewall.
# Only 1 port needs to be open and this
can be defined
# statically -- so you can manually add
rules to your
# firewall. The daemon will use
upnp to talk to a
# compliant firewall to ask it to open a
port for it,
# allowing for port randomization on
startup, if that
# is desired. Software upnp programs,
like 'linux-igd'
# are freely available by searching on
the web, will
# function as a upnp gateway and will
manage connections
# through a linux or other firewall.
### END INIT INFO
#

## support code & functions

Id="$(type -p id)"
Sed="$(type -p sed)"
Sudo="$(type -p sudo)"

use_group_access=1

if ((use_group_access)); then

unset Groups
typeset -Ax Groups

function _idparse {
# parse output of id:
# uid=##(name) gid=##(name) groups=##(name)[,##(name)]...
# Note, names may be 'absent' (in which case there are no
parens).
# grouplist is *comma* separated! -- but only on output of 'id';
# I don't "idnames" can start with a number... (we'll assume
not)
# if group has no name, put it's number in as it's name
# else you wouldn't see you are in those groups

while read id ; do
[[ $id =~ .?id= ]] && continue; #skip over uid/gid
entries
id="${id/\(/ }"
id="${id/\)/}"
gid="${id%% *}"
name="${id#$gid}"
name=${name##\ }
[[ -z $name ]] && name="$gid"
Groups[$name]="$gid"
done < <($Id|$Sed -r '
s/\) gid/\)\ngid/ ; s/\) groups/\)\ngroups/ ;
s/\\/\\\\/g ;
s/\),([0-9])/)\n\1/g ; s/\b([0-9]+),/\1\n/g ;
s/groups=//')
}
_idparse ## populate Groups Hash
fi

# I set my user defaults here as I try to use the group for access
# (doesn't actually work taht well because transmission-daemon
# has a design flaw and set's it's umask to it's own arbitrary value
# vs. allowing user to set it


tmd_user=torrent
# generic 'torrent' user to run torrents
tmd_home="$(eval echo ~$tmd_user)" #they better have a home
tmd_base_home="$tmd_home"
tmd_group="$(groups torrent 2>/dev/null |cut -d\ -f3)" #and a real
group
tmd_child=""

# note sudo is annoying to configure properly these days..
# best to sudo first then run this script:
# (ex. "sudo /etc/rc.d/transmission start"
if (($EUID != 0)) ; then
if [[ -n ${Groups[$tmd_group]:-} ]]; then
if [[ -z ${TRIED_ROOT:-} ]]; then
export TRIED_ROOT="yes"
exec sudo -E -g "$tmd_group" $0 "$@"
fi
fi
echo "Need Root privs to successully run this script..."
exit -1
fi
unset TRIED_ROOT >&/dev/null || ((0)) #no longer needed

#presumably user is root-priv'ed now.
#parse command instance
prog="$(basename "$0")"
core="$(echo $prog |sed -r 's/^.*transmission/trm/ ;
s/^.*trm[0]*([1-9][0-9]+)/trm$1/')"

[[ ${core:0:3} == trm && ${#core} -gt 3 ]] && tmd_child="${core:3}"

[[ $# -gt 1 && $2 =~ ^[0-9]+$ ]] && tmd_child="$2"

tmd_child="${tmd_child##0}"

[[ $tmd_child ]] && tmd_home="$tmd_home/child$tmd_child"



tmd_umask=002

etc_loglevel=info #default logging level

#unset tmd_use_proxy # default
# don't use these by default
if [[ ! ${use_proxy:-} =~ ^y ]]; then
unset -v http_proxy
unset -v ftp_proxy
unset -v https_proxy
fi


if [[ -r ${tmd_log_level_file:-""} ]]; then
nlvl=$(<"$tmd_log_level_file")
if [[ $nlvl == info || $nlvl == debug ||
$nlvl == error || $nlvl == none ]] ; then
etc_loglevel=$nlvl
fi
fi
# use prefix 'tmd' = instead of full program/service name; its just too long


tmd_bin="/usr/bin/transmission-daemon"
tmd_piddir="/var/run/transmission/"

#make sure we can write in piddir
if [[ ! -d $tmd_piddir ]]; then
mkdir -m 6775 "$tmd_piddir" && chown $tmd_user.$tmd_group $tmd_piddir
fi

tmd_pidfile="$tmd_piddir/transmission-daemon$tmd_child.pid"
tmd_logdir="/var/log/transmission"
tmd_log="$tmd_logdir/daemon$tmd_child.log"
tmd_output_log="$tmd_logdir/output$tmd_child.log"

tmd_nice=5


# could use just "-c3" for lowest(idle) disk priority
tmd_ionicep="-c2 -n7" # best effort; lowest in class

tmd_existing_config=$tmd_home/settings.json

# read the daemon's current config to get values...for defaults

function read_json_config {
local cfg="${1:-}" local fl="${2:-}"
typeset -A $cfg
perl -wE '
use 5.12.0; $|=1;
my $cfg = shift @ARGV;
open (my $cfgh, "<", $ARGV[0]) or die "error opening config
file: $!\n";
my $bash_hash = "declare -A $cfg=(";
while (<$cfgh>) {
chomp;
m{^\s+ \" ([^"]+) \":\s+ \"? ([^"]+) \"? ,\s*$}x and do
{
my ($name, $val) = ($1, $2);
$bash_hash .= qq{[$name]=\"$value\" };
};
}
print "$bash_hash )\n";
' "$cfg" "$fl"
}

if [[ $# -ge 2 ]]; then
eval $(read_json_config "$1" "$2")
fi
eval $(read_json_config Config "$tmd_home/settings.json")



################################################################
# 'default' tmd_a_rgs:
#
[[ ${Config[blocklist-enabled]} =~ true ]] && blocklist="--blocklist"

[[ ${Config[download-dir]:-} ]] &&

ddd="--download-dir ${Config[download-dir]}"

[[ ${config[incomplete-dir]:-} ]] &&

icd="--incomplete-dir ${config[incomplete-dir]}"


### check for main data dirs being mounted

[[ $ddd ]] dir1="${Config[download-dir]}"
[[ $icd ]] dir2="${Config[download-dir]}"

if [[ $dir1 && ! -d $dir1 || $dir2 && ! -d $dir2 ]]; then
echo "Fatal error: Torrent data directories are not found"
echo "this may mean a disk is not mounted: will not proceed"
rc_fail 1
rc_status v
exit 1
fi

## note -- if you don't want to configure one of these; just comment
# it out - many of these will be set if it was able to
# read the json file from transmission's home dir.


tmda_config_dir="--config-dir $tmd_home"
tmda_dht="--dht"
tmda_encryption="--encryption-tolerated"
tmda_foreground="-f"
tmda_incomplete_dir="--incomplete-dir
$tmd_home/data/Downloading/transmission$tmd_child"
tmda_local_peer_discovery="--lpd"
tmda_logfile="--logfile $tmd_log"
tmda_loglevel="--log-error"
if [[ -z "$etc_loglevel" || $etc_loglevel == none ]] ; then
tmda_logfile="--logfile /dev/null"
else
tmda_loglevel="--log-$etc_loglevel"
fi
tmda_pidfile="--pid-file $tmd_pidfile"
tmda_portmap="--no-portmap"


tmda_peer_port="${tmda_peer_port_number:+"--peerport $tmda_peer_port_number"}"
tmda_port="${tmda_port_number:+"--port $tmda_port_number"}"

tmda_rpc_allowed_access="--allowed 192.168.4.*,192.168.3.*,127.0.0.1"

tmda_seedratio_glob="--no-global-seedratio"
tmda_watchdir="--no-watch-dir"

tmd_args=" ${tmda_blocklist:-}
${tmda_complete_dir:-}
${tmda_config_dir:-}
${tmda_dht:-}
${tmda_encryption:-}
${tmda_foreground:-}
${tmda_incomplete_dir:-}
${tmda_local_peer_discovery:-}
${tmda_logfile:-}
${tmda_loglevel:-}
${tmda_peerlimit_glob:-}
${tmda_peerlimit_per_torrent:-}
${tmda_peerport:-}
${tmda_port:-}
${tmda_pidfile:-}
${tmda_portmap:-}
${tmda_rpc_allowed_access:-}
${tmda_rpc_user:-}
${tmda_rpc_userpw:-}
${tmda_rpc_auth:-}
${tmda_seedratio_glob:-}
${tmda_watchdir:-}
"

#open file limit for our machine

ulimit -Hn16384
ulimit -Sn16384
ulimit -n 16384


ionice_bin=$(type -P ionice)

# Check for existence of config files;
# read system first

# possibility of a system config... (I don't have one)
test -r "${tmd_sys_config:-""}" && . "$tmd_sys_config"
tmd_sys_config="/etc/sysconfig/transmission$tmd_child"
# then read home-dir-config if present

# I put my config in the 'tmd' daemon's home dir.
# in an "etc" directory, in "rc-config"


tmd_home_config="$tmd_home/etc/rc-config"
test -r "$tmd_home_config" && . "$tmd_home_config"

tmd_etc="${tmd_etc:-"$tmd_home/etc"}"
tmd_log_level_file="${tmd_log_level_file:-"$tmd_etc/log_level"}"

#not sure how we could get this far w/o tmd_user not being set.

if [[ -z ${tmd_user:-} ]]; then
echo "tmd_user not set!"
exit -1
fi
if [[ -z ${tmd_group:-} ]]; then
echo "User \"$tmd_user\" has no group -- (no /etc/passwd?)"
exit -1
fi
if [[ -z ${tmd_home:-} ]]; then
echo "Configuration error: user \"$tmd_user\" has no home dir "
exit -1
fi


# Now read possible config options out of tmd user dir (I don't
# use this as all my config vals are the defaults in this script! ;-)
# but I DID use it to turn on options (debug and such) at times
# in the past.
# will look for a "environ" dir to read in "environment vars"
# that you want to set for transmission (if any; if you
# are doing development on it -- some debug options can be set in ENV


# read env options...
tmd_env="${tmd_env:-"$tmd_home/environ"}"

if [[ -d $tmd_env ]]; then
if [[ ! -r $tmd_env || ! -x $tmd_env ]]; then
echo "Environment directory $tmd_env exists, but isn't readable"
echo "Environment variables will be ignored"
else
cd $tmd_env;
readarray vars <<<$(find . -type f -name '[^.]*' -print|tr )
if ((${#vars[*]}>0)); then
for var in "${vars[@]}" ; do
echo "var=$var"
export $var=$(<"$var")
done
cd - >/dev/null
fi
fi
fi

# so note -- the tmd_secrets file can be anywhere -- it may
# have been set in the tmd_environ's to anything, but it defaults
# to a .secrets DIRECTORY in tmd_home

# may be set by tmd_env
# since this start script runs as root, these files probably don't
# have to be readable by anyone

# note -- I don't use a passwd on mine since it's interface is only
# open on an internal network


tmd_secrets="${tmd_secrets:-"$tmd_home/.secrets"}"
tmd_usr_file="$tmd_secrets/.tmd_user"
tmd_upw_file="$tmd_secrets/.tmd_userpw"

if [[ -r $tmd_usr_file ]]; then
tmda_rpc_user="$(<$tmd_usr_file)"
fi

tmda_rpc_user="${tmda_rpc_user:+"--username $tmda_rpc_user"}"

if [[ -r $tmd_upw_file ]]; then
tmda_rpc_userpw="$(<$tmd_upw_file)"
fi
tmda_rpc_userpw="${tmda_rpc_userpw:+"--password $tmda_rpc_userpw"}"
if [[ -n ${tmda_rpc_user:-""} && -n ${tmda_rpc_userpw:-""} ]]; then
tmda_rpc_auth="--auth"
fi


# some util that lets you start scripts as a user/var and such...


# non configurable vars go after here...
#startproc
stprc="/sbin/startproc"
[[ ! -e $stprc ]] && stprc=$(which startproc)
[[ ! -e $stprc ]] && { echo "Fatal: startproc not found" >&2; exit 1 ; }
#startproc's arg list....
startproc_args=" -l $tmd_output_log -p $tmd_pidfile -u $tmd_user -g $tmd_group
-n $tmd_nice"

test -x $tmd_bin || { echo "$tmd_bin not installed";
if [ "$1" = "stop" ]; then exit 0;
else exit 5; fi; }

sp_args="$startproc_args"

# Shell functions sourced from /etc/rc.status:
# rc_check check and set local and overall rc
status
# rc_status check and set local and overall rc status
# rc_status -v be verbose in local rc status and clear it
afterwards
# rc_status -v -r ditto and clear both the local and overall rc
status
# rc_status -s display "skipped" and exit with status 3
# rc_status -u display "unused" and exit with status 3
# rc_failed set local and overall rc status to failed
# rc_failed <num> set local and overall rc status to <num>
# rc_reset clear both the local and overall rc
status
# rc_exit exit appropriate to overall rc status
# rc_active checks whether a service is activated by
symlinks
set +e +u # rc.status has buggy code
. /etc/rc.status # SuSE's common run script env (only necessary for
#
defining "rc_xxxx" commands below that set status or exit
#set

# Reset status of this service
rc_reset # set's startup value to 'ok'

cd $tmd_home || {
/bin/false
rc_status -v # set bad status verbosely and leave
rc_exit
}

running=0
if [[ $1 != status ]]; then
/sbin/checkproc -p $tmd_pidfile $tmd_bin
running=$?
if [[ $running == 0 ]]; then running=1
else running=0
fi
fi

case "$1" in
start)
if (($running)) ; then
echo -n "Transmission already running... "
else
echo -n "Starting transmissiond "
## Start daemon with startproc(8). If thikks fails
## the return value is set appropriately by startproc.
if [[ -n "$tr_umask" ]]; then
umask $tr_umask
fi
all_args="$startproc_args $tmd_bin $tmd_args"
if [[ -x $ionice_bin && -n "${tmd_ionicep:-}" ]]; then
$ionice_bin $tmd_ionicep $stprc $all_args
else
$stprc $all_args
fi
fi

# Remember status and be verbose
rc_status -v
;;
stop)
if ((!$running)) ; then
echo -n "Transmission is already stopped... "
else
echo -n "Shutting down transmissiond "
## Stop daemon with killproc(8) and if this fails
## killproc sets the return value according to LSB.

/sbin/killproc -t 10 -p $tmd_pidfile -TERM $tmd_bin || {
echo -n "Sending Kill..."
/sbin/killproc -p $tmd_pidfile -t 1 -KILL
$tmd_bin
}
fi
# Remember status and be verbose
rc_status -v
;;
try-restart|condrestart)
## Do a restart only if the service was active before.
## Note: try-restart is now part of LSB (as of 1.9).
## RH has a similar command named condrestart.
if test "$1" = "condrestart"; then
echo -n "${attn} Use try-restart ${done}(LSB)${attn} "
echo "rather than condrestart ${warn}(RH)${norm}"
fi
$0 status
if test $? = 0; then
$0 restart
else
rc_reset # Not running is not a failure.
fi
# Remember status and be quiet
rc_status
;;
restart)
## Stop the service and regardless of whether it was
## running or not, start it again.
$0 stop
$0 start

# Remember status and be quiet
rc_status
;;
status)
echo -n "Checking for service transmission-daemon${tmd_child} "
## Check status with checkproc(8), if<F5><F5> process is running
## checkproc will return with exit status 0.

# Return value is slightly different for the status command:
# 0 - service up and running
# 1 - service dead, but /var/run/ pid file exists
# 2 - service dead, but /var/lock/ lock file exists
# 3 - service not running (unused)
# 4 - service status unknown :-(
# 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.)

# NOTE: checkproc returns LSB compliant status values.
/sbin/checkproc -p $tmd_pidfile $tmd_bin
# NOTE: rc_status knows that we called this init script with
# "status" option and adapts its messages accordingly.
rc_status -v
;;
probe)
## Optional: Probe for the necessity of a reload, print out the
## argument to this init script which is required for a reload.
## Note: probe is not (yet) part of LSB (as of 1.9)

if [[ $tmd_sys_config -nt $tmd_pidfile ||
$tmd_home_config -nt $tmd_pidfile ]]; then
echo reload
fi
;;
*)
echo "Usage: $0 {start|stop|status|try-restart|restart|probe}"
exit 1
;;
esac
rc_exit
# vim: ts=2 sw=2 syntax=sh
< Previous Next >
Follow Ups