diff --git a/files/CONTROL/control b/files/CONTROL/control index a9d9d4a1..5e8b12aa 100644 --- a/files/CONTROL/control +++ b/files/CONTROL/control @@ -1,6 +1,6 @@ Package: pi-hole Version: -Depends: bash, cron, curl, git-http, ca-bundle, bind-dig, iputils-ping, net-tools, findutils, grep, sed, jq, libcap-bin, shadow-su, psmisc, procps-ng-pgrep +Depends: bash, cron, curl, git-http, ca-bundle, bind-dig, iputils-ping, net-tools, findutils, grep, sed, jq, libcap-bin, shadow-su, psmisc, procps-ng-pgrep, rev Section: net URL: https://github.com/jacklul/entware-pi-hole Maintainer: Jack'lul, https://jacklul.github.io diff --git a/files/CONTROL/postinst b/files/CONTROL/postinst new file mode 100644 index 00000000..d9f094c6 --- /dev/null +++ b/files/CONTROL/postinst @@ -0,0 +1,83 @@ +#!/bin/sh + +# Link to system files if they don't exist in /opt +[ ! -f "/opt/etc/hosts" ] && [ -f "/etc/hosts" ] && ln -s "/etc/hosts" "/opt/etc/hosts" +[ ! -f "/opt/etc/ethers" ] && [ -f "/etc/ethers" ] && ln -s "/etc/ethers" "/opt/etc/ethers" +[ ! -f "/opt/etc/resolv.conf" ] && [ -f "/etc/resolv.conf" ] && ln -s "/etc/resolv.conf" "/opt/etc/resolv.conf" + +# Set random gravity update and updatechecker times +if [ -f "/opt/etc/cron.d/pihole" ]; then + MINUTE_GRAVITY="$(bash -c "echo \$((1 + RANDOM % 58))")" + MINUTE_UPDATECHECK="$(bash -c "echo \$((1 + RANDOM % 58))")" + HOUR_GRAVITY="$(bash -c "echo \$((3 + RANDOM % 2))")" + HOUR_UPDATECHECK="$(bash -c "echo \$((12 + RANDOM % 8))")" + + if [ -n "$MINUTE_GRAVITY" ] && [ -n "$MINUTE_UPDATECHECK" ] && [ -n "$HOUR_GRAVITY" ] && [ -n "$HOUR_UPDATECHECK" ]; then + sed "s/59 1 /$MINUTE_GRAVITY $HOUR_GRAVITY /" -i "/opt/etc/cron.d/pihole" + sed "s/59 17 /$MINUTE_UPDATECHECK $HOUR_UPDATECHECK /" -i "/opt/etc/cron.d/pihole" + fi +fi + +# Set user and group used for rotating the logs +if [ -f "/opt/etc/pihole/logrotate" ]; then + #shellcheck disable=SC2010 + LOG_USER_GROUP="$(ls -al "/opt/var/log" | grep ' \.$' | awk '{print $3 " " $4}')" + + if [ -n "$LOG_USER_GROUP" ]; then + if grep -q "# su #" "/opt/etc/pihole/logrotate"; then + sed "s/# su #/su $LOG_USER_GROUP/g;" -i "/opt/etc/pihole/logrotate" + else + sed "s/su.*$/su $LOG_USER_GROUP/g;" -i "/opt/etc/pihole/logrotate" + fi + fi +fi + +# Some of these commands might be missing depending on the system +# so we check if they exist and then prompt the user to install them +COREUTILS_DEPS="basename cat chmod chown cp cut date df dirname du echo expr false head id install kill ln ls mkdir mktemp mv nohup printf pwd rm sha1sum sleep sort stat stty tail tee test timeout touch tr true tty uptime whoami" + +CHECK_COMMAND="" +type 2> /dev/null && CHECK_COMMAND="type" +which --help > /dev/null 2>&1 && CHECK_COMMAND="which" + +if [ -n "$CHECK_COMMAND" ]; then + MISSING_CMDS="" + MISSING_PKGS="" + + for COREUTILS_COMMAND in $COREUTILS_DEPS; do + #shellcheck disable=SC2086 + if ! $CHECK_COMMAND $COREUTILS_COMMAND > /dev/null 2>&1; then + MISSING_CMDS="$MISSING_CMDS $COREUTILS_COMMAND" + MISSING_PKGS="$MISSING_PKGS coreutils-$COREUTILS_COMMAND" + fi + done + + if [ -n "$MISSING_CMDS" ]; then + MISSING_CMDS="$(echo "$MISSING_CMDS" | awk '{$1=$1};1')" + MISSING_PKGS="$(echo "$MISSING_PKGS" | awk '{$1=$1};1')" + + cat << EOF +Your system is missing required commands: + $MISSING_CMDS + +Install them by running the following command: + opkg install $MISSING_PKGS + +EOF + + STDIN_FD="$(readlink -f /proc/$$/fd/0 2> /dev/null)" + if [ -n "$STDIN_FD" ] && [ "$STDIN_FD" != "/dev/null" ]; then + printf "Press any key to continue..." + #shellcheck disable=SC2034 + read -r reply + fi + fi +else + cat << EOF +Unable to check for script dependencies - 'type' and 'which' commands not found + +Make sure the following commands are available on your system: + $COREUTILS_DEPS + +EOF +fi diff --git a/files/opt/etc/init.d/S55pihole-FTL b/files/opt/etc/init.d/S55pihole-FTL index 9e87ff1c..f7b53a92 100644 --- a/files/opt/etc/init.d/S55pihole-FTL +++ b/files/opt/etc/init.d/S55pihole-FTL @@ -14,90 +14,63 @@ logecho() { echo "$@" } -install() { - # Install missing dependencies required by scripts - bash /opt/share/pihole/dependencies.sh "$1" || exit 1 - - # Set random gravity update and updatechecker times - # Comment/uncomment logrotate line based on binary presence - # Set user and group for rotated log files - bash < /dev/null)" != "" ]; then + TARGET_USER="pihole" - # Execute pre start script through rc.func's PRECMD, we have to run poststop here as well for cleanup - PRECMD="bash /opt/share/pihole/pihole-FTL-poststop.sh ; bash /opt/share/pihole/pihole-FTL-prestart.sh" -fi + if [ -f /opt/sbin/setcap ] && [ -f /opt/bin/su ]; then + if setcap CAP_NET_BIND_SERVICE,CAP_NET_RAW,CAP_NET_ADMIN,CAP_SYS_NICE,CAP_IPC_LOCK,CAP_CHOWN+eip "/opt/sbin/pihole-FTL"; then + TARGET_USER="" + PREARGS="su -s sh -c" + ARGS="pihole" + fi + fi -if [ -f /opt/bin/id ] && [ -z "$ARGS" ] && [ -z "$PREARGS" ]; then - ROOT_USER="$(id -nu 0)" # get username of ID 0 user - - if [ "$(id -u pihole 2> /dev/null)" != "" ]; then # use the pihole user when available - TARGET_USER="pihole" - - if [ -f /opt/sbin/setcap ] && [ -f /opt/bin/su ]; then # attempt to start with setcap and su - if setcap CAP_NET_BIND_SERVICE,CAP_NET_RAW,CAP_NET_ADMIN,CAP_SYS_NICE,CAP_IPC_LOCK,CAP_CHOWN+eip "/opt/sbin/pihole-FTL"; then - TARGET_USER="" - PREARGS="su -s sh -c" - ARGS="pihole" + if [ -n "$TARGET_USER" ]; then # setcap not supported - start as root user but then change to pihole + ARGS="-- -u $TARGET_USER" + logecho "Starting pihole-FTL as '$ROOT_USER' (then dropping to '$TARGET_USER') because setting capabilities is not supported on this system" + fi + else # start as root user + ARGS="-- -u $ROOT_USER" + logecho "Starting pihole-FTL as '$TARGET_USER' because 'pihole' user does not exist" + fi fi fi + ;; +esac - if [ -n "$TARGET_USER" ]; then - ARGS="-- -u $TARGET_USER" - logecho "Starting pihole-FTL as '$ROOT_USER' (then dropping to '$TARGET_USER') because setting capabilities is not supported on this system" - fi - else - ARGS="-- -u $ROOT_USER" - logecho "Starting pihole-FTL as '$TARGET_USER' because 'pihole' user does not exist" - fi +# Execute pre start script through rc.func's PRECMD, we have to run poststop here as well for potential cleanup +if [ -z "$PRECMD" ]; then + PRECMD="bash /opt/share/pihole/pihole-FTL-poststop.sh ; bash /opt/share/pihole/pihole-FTL-prestart.sh" fi . /opt/etc/init.d/rc.func -if [ -f /opt/bin/bash ]; then - case $1 in - stop | kill) - # Run poststop when stopping by user - bash /opt/share/pihole/pihole-FTL-poststop.sh - ;; - esac -fi +case $1 in + start | restart) + if [ "$(id -u pihole 2> /dev/null)" != "" ]; then + # This fixes permission issue for queries database's journal + PI_HOLE_QUERIESDB_FILE="$(pihole-FTL --config -q files.database)" + if [ -n "$PI_HOLE_QUERIESDB_FILE" ]; then + { sleep 1; chown pihole:pihole "$PI_HOLE_QUERIESDB_FILE-*"; } & + fi + fi + ;; + stop | kill) + # Run poststop after stop/kill + bash /opt/share/pihole/pihole-FTL-poststop.sh + ;; +esac diff --git a/files/opt/share/pihole/dependencies.sh b/files/opt/share/pihole/dependencies.sh deleted file mode 100644 index b59d3727..00000000 --- a/files/opt/share/pihole/dependencies.sh +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/env bash -# This script is part of https://github.com/jacklul/entware-pi-hole -# It will install any missing dependencies required by Pi-hole scripts -# It is automatically executed by init.d script - -# This array contains command => Entware package name definition -declare -A DEPENDENCIES=( - ["basename"]="coreutils-basename" - ["cat"]="coreutils-cat" - ["chmod"]="coreutils-chmod" - ["chown"]="coreutils-chown" - ["cp"]="coreutils-cp" - ["cut"]="coreutils-cut" - ["date"]="coreutils-date" - ["dirname"]="coreutils-dirname" - ["echo"]="coreutils-echo" - ["expr"]="coreutils-expr" - ["false"]="coreutils-false" - ["head"]="coreutils-head" - ["id"]="coreutils-id" - ["install"]="coreutils-install" - ["kill"]="coreutils-kill" - ["ln"]="coreutils-ln" - ["mkdir"]="coreutils-mkdir" - ["mktemp"]="coreutils-mktemp" - ["mv"]="coreutils-mv" - ["nohup"]="coreutils-nohup" - ["printf"]="coreutils-printf" - ["pwd"]="coreutils-pwd" - ["readlink"]="coreutils-readlink" - ["rm"]="coreutils-rm" - ["sha1sum"]="coreutils-sha1sum" - ["sleep"]="coreutils-sleep" - ["stat"]="coreutils-stat" - ["tail"]="coreutils-tail" - ["tee"]="coreutils-tee" - ["timeout"]="coreutils-timeout" - ["touch"]="coreutils-touch" - ["tr"]="coreutils-tr" - ["true"]="coreutils-true" - ["wc"]="coreutils-wc" - ["whoami"]="coreutils-whoami" - ["rev"]="rev" - #["lshw"]="lshw" # not available in Entware - ["lscpu"]="lscpu" -) - -# This array will contain packages that will be installed -TO_INSTALL=() - -# Is this script running in an interactive shell? -INTERACTIVE=$([ "$(readlink -f /proc/$$/fd/0 2> /dev/null)" = "/dev/null" ] && echo false || echo true) - -# Supress output if called with start or restart argument -SILENT=$([ "$1" = "silent" ] && echo true || echo false) - -# Check only (nothing will be installed) -CHECK=$([ "$1" = "check" ] && echo true || echo false) - -# Control file -CONTROL_FILE="/opt/lib/opkg/info/pi-hole.control" - -####################################### - -function cecho() { - if [ "$INTERACTIVE" = true ] && [ "$SILENT" = false ]; then - echo "$@" 2> /dev/null - fi -} - -if [ -f "$CONTROL_FILE" ]; then - cecho "Checking for core dependencies..." - - DEPENDS="$(grep "^Depends:" < "$CONTROL_FILE" | sed -e "s/^[^:]*:[[:space:]]*//")" - IFS=', ' read -r -a CORE_PACKAGES <<< "$DEPENDS" - INSTALLED="$(opkg list-installed)" - - for CORE_PACKAGE in "${CORE_PACKAGES[@]}"; do - cecho -n "- $CORE_PACKAGE" - - if ! echo "$INSTALLED" | grep -q "$CORE_PACKAGE -"; then - cecho -n " ✗" - - if [ "$CHECK" = false ]; then - cecho -n " (will install '$CORE_PACKAGE' package)" - fi - - TO_INSTALL+=("$CORE_PACKAGE") - else - cecho -n " ✓" - fi - - cecho "" - done -fi - -cecho "Checking for scripting dependencies..." - -for KEY in "${!DEPENDENCIES[@]}"; do - cecho -n "- $KEY" - - if ! command -v "$KEY" &> /dev/null; then - cecho -n " ✗" - - if [ "$CHECK" = false ]; then - cecho -n " (will install '${DEPENDENCIES[$KEY]}' package)" - fi - - TO_INSTALL+=("${DEPENDENCIES[$KEY]}") - else - cecho -n " ✓" - fi - - cecho "" -done - -if [ "${#TO_INSTALL[@]}" -ne 0 ]; then - if [ "$CHECK" = false ]; then - cecho "Installing packages..." - - #shellcheck disable=SC2046 - opkg install "${TO_INSTALL[@]}" $([ "$SILENT" = true ] && echo "-V0") || exit 1 - else - echo "Missing packages: ${TO_INSTALL[*]}" - exit 1 - fi -fi - -exit 0 diff --git a/scripts/ipk.sh b/scripts/ipk.sh index 2ed3aa55..e7d23dcc 100644 --- a/scripts/ipk.sh +++ b/scripts/ipk.sh @@ -82,6 +82,11 @@ sed -e "s/^Version:.*/Version: $PACKAGE_VERSION/" -i "$PACKAGE_DIR/CONTROL/contr sed -e "s/^Architecture:.*/Architecture: $PACKAGE_ARCHITECTURE/" -i "$PACKAGE_DIR/CONTROL/control" sed -e "s/^Installed-Size:.*/Installed-Size: $INSTALLED_SIZE/" -i "$PACKAGE_DIR/CONTROL/control" +[ -f "$PACKAGE_DIR/CONTROL/preinst" ] && chmod 0755 "$PACKAGE_DIR/CONTROL/preinst" +[ -f "$PACKAGE_DIR/CONTROL/postinst" ] && chmod 0755 "$PACKAGE_DIR/CONTROL/postinst" +[ -f "$PACKAGE_DIR/CONTROL/prerm" ] && chmod 0755 "$PACKAGE_DIR/CONTROL/prerm" +[ -f "$PACKAGE_DIR/CONTROL/postrm" ] && chmod 0755 "$PACKAGE_DIR/CONTROL/postrm" + sudo chown -R 0:0 "$PACKAGE_DIR/CONTROL" ( cd "$PACKAGE_DIR/CONTROL" && tar --format=gnu --numeric-owner --sort=name -cf - --mtime="$TIMESTAMP" . | gzip -n - > "$TMP_DIR/control.tar.gz" )