#!/bin/bash do { #//////////////////////////////////// # DietPi Services Script # #//////////////////////////////////// # Created by Daniel Knight / daniel.knight@dietpi.com / dietpi.com # # Info: # - Allows service control for all listed programs used in dietpi-software # - Disable removes the autostart from init.d and systemD. This allows DietPi to control program services below. # # Usage: # - /DietPi/dietpi/dietpi-services $AVAILABLE_OPTIONS #//////////////////////////////////// setglobal AVAILABLE_OPTIONS = '' - start/stop/restart/status (all services, known to DietPi) - start/stop/restart servicename (single service, SystemD) - systemd_controlled/dietpi_controlled (all services, known to DietPi) - enable/disable servicename (single service, SystemD) - enable/disable all (all services, known to DietPi) - mask/unmask servicename (single service, SystemD)'' #Grab Inputs setglobal INPUT_MODE = $1 setglobal INPUT_S2 = $2 #Import DietPi-Globals --------------------------------------------------------------- source /DietPi/dietpi/func/dietpi-globals G_CHECK_ROOT_USER export G_PROGRAM_NAME='DietPi-Services' #Import DietPi-Globals --------------------------------------------------------------- setglobal aSERVICE_NAME = ''( 'cron' 'transmission-daemon' 'proftpd' 'smbd' 'nmbd' 'nfs-kernel-server' 'vsftpd' 'apache2' 'nginx' 'lighttpd' 'php5-fpm' 'php7.0-fpm' 'mysql' 'mpd' 'ympd' 'minidlna' 'noip2' 'grasshopper' 'dnsmasq' 'pihole-FTL' 'subsonic' 'webiopi' 'haproxy' 'fail2ban' 'openvpn' 'isc-dhcp-server' 'hostapd' 'avahi-daemon' 'shairport-sync' 'squeezelite' 'mopidy' #'mariadb' #: https://github.com/Fourdee/DietPi/issues/1000#issuecomment-307760517 'redis-server' 'emonhub' 'netdata' 'mumble-server' 'emby-server' 'plexmediaserver' 'cuberite' 'supervisor' 'gogs' 'qbittorrent' 'syncthing' 'syncthing-inotify' 'rtorrent' 'urbackupsrv' 'sickrage' 'roonbridge' 'mosquitto' 'networkaudiod' 'node-red' 'tomcat8' 'rpimonitor' 'openmediavault-engined' 'blynkserver' 'aria2' 'yacy' 'tonido' 'icecast2' 'darkice' 'motioneye' 'cups' 'cloudprintd' 'virtualhere' 'sabnzbd' 'spotify-connect-web' 'couchpotato' 'koel' 'sonarr' 'radarr' 'plexpy' 'jackett' 'nzbget' 'octoprint' 'roonserver' 'htpc-manager' 'home-assistant' 'openbazaar' #'dietpi-wifi-monitor' : https://github.com/Fourdee/DietPi/issues/1288#issuecomment-350653480 'docker' 'bdd' 'minio' 'gmrender' 'nukkit' 'gitea' 'pi-spc' 'raspotify' #'moode-worker' 'voice-recognizer' 'alsa-init' ) # - User: read custom services file setglobal FP_INCLUDE_SERVICES = ''/DietPi/dietpi/.dietpi-services_include'' if test -f $FP_INCLUDE_SERVICES { while read line { setglobal index = $(#aSERVICE_NAME[@]) compat array-assign aSERVICE_NAME '$index' $line } < "$FP_INCLUDE_SERVICES" } #init setglobal aSERVICE_AVAILABLE = '0' for ((i=0; i<${#aSERVICE_NAME[@]}; i++)) do aSERVICE_AVAILABLE[$i]=0 done #Check if service name is available on system. proc Populate_Available_Array { #Find dpkg program names dpkg --get-selections | awk '{print $1}' > $FP_TEMP for ((i=0; i<${#aSERVICE_NAME[@]}; i++)) do if [ -f /etc/systemd/system/${aSERVICE_NAME[$i]}.service ] || [ -f /lib/systemd/system/${aSERVICE_NAME[$i]}.service ]; then aSERVICE_AVAILABLE[$i]=1 elif [ -f /etc/init.d/${aSERVICE_NAME[$i]} ]; then aSERVICE_AVAILABLE[$i]=1 # - Check dpkg for matching packages. elif (( $(grep -ci -m1 "^${aSERVICE_NAME[$i]}$" "$FP_TEMP") )); then aSERVICE_AVAILABLE[$i]=1 fi done } proc Print_Status { #$1 = Method #$2 = name #$3 = exit code # NB: SystemD exit code 5 = not loaded/active, so dont trigger a failed result. #ok if sh-expr ' $3 == 0 || $3 == 5 ' { G_DIETPI-NOTIFY 0 "$1 : $2" #failed } else { G_DIETPI-NOTIFY 1 "$1 : $2" } } #$1 = mode (eg: start/stop/restart) proc Set_Running_State{ local target_state="$1" #???????????????????????????????????????????????????????????????????????? # Although this allows for simple service control without using SystemD, we really should convert these to SystemD services. To keep everything consistent, clean, and obtain a correct exit code. #DietPi: Non-service based control for specific dietpi-software installed programs. # - Start order first setglobal index = '0' setglobal aDIETPISERVICE_FP = ''() setglobal aDIETPISERVICE_NAME = ''() compat array-assign aDIETPISERVICE_NAME '$index' ''BruteFIR'';compat array-assign aDIETPISERVICE_FP '$index' ''/var/lib/dietpi/dietpi-software/services/brutefir.service'';sh-expr 'index++'; compat array-assign aDIETPISERVICE_NAME '$index' ''JackD'';compat array-assign aDIETPISERVICE_FP '$index' ''/var/lib/dietpi/dietpi-software/services/jackd.service'';sh-expr 'index++'; compat array-assign aDIETPISERVICE_NAME '$index' ''Jconvolver'';compat array-assign aDIETPISERVICE_FP '$index' ''/var/lib/dietpi/dietpi-software/services/jconvolver.service'';sh-expr 'index++'; for ((i=0; i<${#aDIETPISERVICE_NAME[@]}; i++)) do if [ -f ${aDIETPISERVICE_FP[$i]} ]; then G_DIETPI-NOTIFY -2 "${aDIETPISERVICE_NAME[$i]}" ${aDIETPISERVICE_FP[$i]} $target_state &> /dev/null Print_Status $target_state ${aDIETPISERVICE_NAME[$i]} $? fi done unset aDIETPISERVICE_NAME unset aDIETPISERVICE_FP #???????????????????????????????????????????????????????????????????????? #### ALLO Special #### setglobal aALLO_EXCLUDED_SERVICES_DURING_STOP = ''( 'apache2' 'nginx' 'lighttpd' 'php5-fpm' 'php7.0-fpm' 'mysql' 'avahi-daemon' ) #### ALLO Special #### #Linux: installed services for ((i=0; i<${#aSERVICE_NAME[@]}; i++)) do #### ALLO Special #### # - Allo web interface image: Exclude stop on aALLO_EXCLUDED_SERVICES_DURING_STOP service list if [ -d /var/www/allo ] && [ "$target_state" = "stop" ]; then for ((j=0; j<${#aALLO_EXCLUDED_SERVICES_DURING_STOP[@]}; j++)) do if [ "${aSERVICE_NAME[$i]}" = "${aALLO_EXCLUDED_SERVICES_DURING_STOP[$j]}" ]; then aSERVICE_AVAILABLE[$i]=0 break fi done fi #### ALLO Special #### #Apply if (( ${aSERVICE_AVAILABLE[$i]} == 1 )); then G_DIETPI-NOTIFY -2 "${aSERVICE_NAME[$i]}" systemctl $target_state ${aSERVICE_NAME[$i]} &> /dev/null Print_Status $target_state ${aSERVICE_NAME[$i]} $? fi done unset aALLO_EXCLUDED_SERVICES_DURING_STOP #???????????????????????????????????????????????????????????????????????? # Although this allows for simple service control without using SystemD, we really should convert these to SystemD services. To keep everything consistent, clean, and obtain a correct exit code. #DietPi: Non-service based control for specific dietpi-software installed programs. # - Start prority last setglobal index = '0' setglobal aDIETPISERVICE_FP = ''() setglobal aDIETPISERVICE_NAME = ''() compat array-assign aDIETPISERVICE_NAME '$index' ''RaspimJpeg'';compat array-assign aDIETPISERVICE_FP '$index' ''/var/lib/dietpi/dietpi-software/services/raspimjpeg.service'';sh-expr 'index++'; compat array-assign aDIETPISERVICE_NAME '$index' ''Deluge'';compat array-assign aDIETPISERVICE_FP '$index' ''/var/lib/dietpi/dietpi-software/services/deluge.service'';sh-expr 'index++'; compat array-assign aDIETPISERVICE_NAME '$index' ''SqueezeBox Server'';compat array-assign aDIETPISERVICE_FP '$index' ''/var/lib/dietpi/dietpi-software/services/squeezeboxserver.service'';sh-expr 'index++'; for ((i=0; i<${#aDIETPISERVICE_NAME[@]}; i++)) do if [ -f ${aDIETPISERVICE_FP[$i]} ]; then G_DIETPI-NOTIFY -2 "${aDIETPISERVICE_NAME[$i]}" ${aDIETPISERVICE_FP[$i]} $target_state &> /dev/null Print_Status $target_state ${aDIETPISERVICE_NAME[$i]} $? fi done unset aDIETPISERVICE_NAME unset aDIETPISERVICE_FP #???????????????????????????????????????????????????????????????????????? echo -e "" #Apply process tool settings if test $target_state = "start" || test $target_state = "restart" { /DietPi/dietpi/dietpi-process_tool 1 } } setglobal FP_TEMP = '"/tmp/.dietpi-services_installed'" #///////////////////////////////////////////////////////////////////////////////////// # Main #///////////////////////////////////////////////////////////////////////////////////// #Info G_DIETPI-NOTIFY 3 DietPi-Services $INPUT_MODE #Obtain an array of available services installed on system. Populate_Available_Array #----------------------------------------------------------------------------------- #dietpi_controlled/systemd_controlled if test $INPUT_MODE = 'dietpi_controlled' || test $INPUT_MODE = 'systemd_controlled' { setglobal SYSTEMD_CMD = ''disable'' if test $INPUT_MODE = "systemd_controlled" { setglobal SYSTEMD_CMD = ''enable'' } for ((i=0; i<${#aSERVICE_NAME[@]}; i++)) do #Apply if (( ${aSERVICE_AVAILABLE[$i]} == 1 )); then G_DIETPI-NOTIFY -2 "${aSERVICE_NAME[$i]}" systemctl $SYSTEMD_CMD ${aSERVICE_NAME[$i]} &> /dev/null Print_Status $INPUT_MODE ${aSERVICE_NAME[$i]} $? fi done systemctl daemon-reload &> /dev/null echo -e "" #----------------------------------------------------------------------------------- #mask/unmask/enable/disable } elif test $INPUT_MODE = "enable" || test $INPUT_MODE = "disable" || test $INPUT_MODE = "unmask" || test $INPUT_MODE = "mask" { #Switch to mask, as DietPi_Controlled uses disable to take over from SystemD setglobal SYSTEMD_CMD = ''mask'' if test $INPUT_MODE = "enable" || test $INPUT_MODE = "unmask" { setglobal SYSTEMD_CMD = ''unmask'' } # - Process ALL known services if test $INPUT_S2 = 'all' { if test $INPUT_MODE = "disable" || test $INPUT_MODE = "mask" { echo -e "" Set_Running_State stop } for ((i=0; i<${#aSERVICE_NAME[@]}; i++)) do if (( ${aSERVICE_AVAILABLE[$i]} )); then G_DIETPI-NOTIFY 0 "$INPUT_MODE $INPUT_S2: ${aSERVICE_NAME[$i]}" systemctl $SYSTEMD_CMD ${aSERVICE_NAME[$i]} fi done # - Process user defined single entry via cmd input } else { systemctl stop $INPUT_S2 systemctl $SYSTEMD_CMD $INPUT_S2 if sh-expr ' $? == 0 ' { G_DIETPI-NOTIFY 0 "$INPUT_MODE $INPUT_S2" } else { G_DIETPI-NOTIFY 1 "$INPUT_MODE $INPUT_S2" } } systemctl daemon-reload &> /dev/null if test $INPUT_MODE = "unmask" || test $INPUT_MODE = "enable" { echo -e "" Set_Running_State start } echo -e "" #----------------------------------------------------------------------------------- #status } elif test $INPUT_MODE = "status" { for ((i=0; i<${#aSERVICE_NAME[@]}; i++)) do #Apply if (( ${aSERVICE_AVAILABLE[$i]} == 1 )); then STATUS="${aSERVICE_NAME[$i]}\t$(systemctl status ${aSERVICE_NAME[$i]} | grep -m1 'Active' | cut -c12-)" if [[ "$STATUS" =~ .*'failed'.* ]]; then G_DIETPI-NOTIFY 1 "$STATUS" systemctl status "${aSERVICE_NAME[$i]}" -l --no-pager elif [[ "$STATUS" =~ .*'inactive'.* ]]; then G_DIETPI-NOTIFY 2 "$STATUS" else G_DIETPI-NOTIFY 0 "$STATUS" fi fi done echo -e "" #----------------------------------------------------------------------------------- #start/stop/restart } elif test $INPUT_MODE = "start" || test $INPUT_MODE = "stop" || test $INPUT_MODE = "restart" { #Single use case, basically a alias for systemD if test -n $INPUT_S2 { systemctl $INPUT_MODE $INPUT_S2 &> /dev/null if sh-expr ' $? == 0 ' { G_DIETPI-NOTIFY 0 "$INPUT_MODE $INPUT_S2" } else { G_DIETPI-NOTIFY 1 "$INPUT_MODE $INPUT_S2" } echo -e "" #All services controlled } else { # Control ownCloud and Nextcloud maintenance mode: if test $INPUT_MODE = "stop" || test $INPUT_MODE = "restart" { grep -q "'maintenance' => false," /var/www/owncloud/config/config.php &> /dev/null && G_RUN_CMD occ maintenance:mode --on grep -q "'maintenance' => false," /var/www/nextcloud/config/config.php &> /dev/null && G_RUN_CMD ncc maintenance:mode --on } Set_Running_State $INPUT_MODE # Control ownCloud and Nextcloud maintenance mode: if test $INPUT_MODE = "restart" || test $INPUT_MODE = "start" { grep -q "'maintenance' => true," /var/www/owncloud/config/config.php &> /dev/null && G_RUN_CMD occ maintenance:mode --off grep -q "'maintenance' => true," /var/www/nextcloud/config/config.php &> /dev/null && G_RUN_CMD ncc maintenance:mode --off } } #----------------------------------------------------------------------------------- #Invalid command } else { G_DIETPI-NOTIFY 2 "Invalid command\e[0m\nAvailable commands:\n$AVAILABLE_OPTIONS\n" } #----------------------------------------------------------------------------------- rm $FP_TEMP unset aSERVICE_NAME unset aSERVICE_AVAILABLE #----------------------------------------------------------------------------------- exit #----------------------------------------------------------------------------------- }