From 9b5ea13a33f44d15a90bfda6c2a4b3b0089de57f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 18 Aug 2022 17:08:52 +0200 Subject: [PATCH 01/32] Use utils.sh in install script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- advanced/01-pihole.conf | 7 --- automated install/basic-install.sh | 82 +++++++++++++++--------------- test/test_any_automated_install.py | 1 + 3 files changed, 42 insertions(+), 48 deletions(-) diff --git a/advanced/01-pihole.conf b/advanced/01-pihole.conf index 1fb34905..677910f6 100644 --- a/advanced/01-pihole.conf +++ b/advanced/01-pihole.conf @@ -29,13 +29,6 @@ bogus-priv no-resolv -server=@DNS1@ -server=@DNS2@ - -interface=@INT@ - -cache-size=@CACHE_SIZE@ - log-queries log-facility=/var/log/pihole/pihole.log diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 4d860d33..998b9f15 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -83,6 +83,7 @@ PI_HOLE_INSTALL_DIR="/opt/pihole" PI_HOLE_CONFIG_DIR="/etc/pihole" PI_HOLE_BIN_DIR="/usr/local/bin" PI_HOLE_404_DIR="${webroot}/pihole" +FTL_CONFIG_FILE="${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" if [ -z "$useUpdateVars" ]; then useUpdateVars=false fi @@ -1264,35 +1265,30 @@ version_check_dnsmasq() { # Copy the new Pi-hole DNS config file into the dnsmasq.d directory install -D -m 644 -T "${dnsmasq_pihole_01_source}" "${dnsmasq_pihole_01_target}" printf "%b %b Installed %s\n" "${OVER}" "${TICK}" "${dnsmasq_pihole_01_target}" - # Replace our placeholder values with the GLOBAL DNS variables that we populated earlier - # First, swap in the interface to listen on, - sed -i "s/@INT@/$PIHOLE_INTERFACE/" "${dnsmasq_pihole_01_target}" + # Add settings with the GLOBAL DNS variables that we populated earlier + # First, set the interface to listen on + addOrEditKeyValPair "${dnsmasq_pihole_01_target}" "interface" "$PIHOLE_INTERFACE" if [[ "${PIHOLE_DNS_1}" != "" ]]; then - # then swap in the primary DNS server. - sed -i "s/@DNS1@/$PIHOLE_DNS_1/" "${dnsmasq_pihole_01_target}" - else - # Otherwise, remove the line which sets DNS1. - sed -i '/^server=@DNS1@/d' "${dnsmasq_pihole_01_target}" + # then add in the primary DNS server. + addOrEditKeyValPair "${dnsmasq_pihole_01_target}" "server" "$$PIHOLE_DNS_1" fi # Ditto if DNS2 is not empty if [[ "${PIHOLE_DNS_2}" != "" ]]; then - sed -i "s/@DNS2@/$PIHOLE_DNS_2/" "${dnsmasq_pihole_01_target}" - else - sed -i '/^server=@DNS2@/d' "${dnsmasq_pihole_01_target}" + addKey "${dnsmasq_pihole_01_target}" "server=$PIHOLE_DNS_2" fi # Set the cache size - sed -i "s/@CACHE_SIZE@/$CACHE_SIZE/" "${dnsmasq_pihole_01_target}" + addOrEditKeyValPair "${dnsmasq_pihole_01_target}" "cache-size" "$$CACHE_SIZE" sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' "${dnsmasq_conf}" # If the user does not want to enable logging, if [[ "${QUERY_LOGGING}" == false ]] ; then - # disable it by commenting out the directive in the DNS config file - sed -i 's/^log-queries/#log-queries/' "${dnsmasq_pihole_01_target}" + # remove itfrom the DNS config file + removeKey "${dnsmasq_pihole_01_target}" "log-queries" else - # Otherwise, enable it by uncommenting the directive in the DNS config file - sed -i 's/^#log-queries/log-queries/' "${dnsmasq_pihole_01_target}" + # Otherwise, enable it by adding the directive to the DNS config file + addKey "${dnsmasq_pihole_01_target}" "log-queries" fi printf " %b Installing %s..." "${INFO}" "${dnsmasq_rfc6761_06_source}" @@ -1365,9 +1361,9 @@ installConfigs() { chmod 644 "${PI_HOLE_CONFIG_DIR}/dns-servers.conf" # Install template file if it does not exist - if [[ ! -r "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" ]]; then + if [[ ! -r "${FTL_CONFIG_FILE}" ]]; then install -d -m 0755 ${PI_HOLE_CONFIG_DIR} - if ! install -T -o pihole -m 664 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL.conf" "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" &>/dev/null; then + if ! install -T -o pihole -m 664 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL.conf" "${FTL_CONFIG_FILE}" &>/dev/null; then printf " %b Error: Unable to initialize configuration file %s/pihole-FTL.conf\\n" "${COL_LIGHT_RED}" "${PI_HOLE_CONFIG_DIR}" return 1 fi @@ -1784,30 +1780,24 @@ create_pihole_user() { # This function saves any changes to the setup variables into the setupvars.conf file for future runs finalExports() { - # If the setup variable file exists, - if [[ -e "${setupVars}" ]]; then - # update the variables in the file - sed -i.update.bak '/PIHOLE_INTERFACE/d;/PIHOLE_DNS_1\b/d;/PIHOLE_DNS_2\b/d;/QUERY_LOGGING/d;/INSTALL_WEB_SERVER/d;/INSTALL_WEB_INTERFACE/d;/LIGHTTPD_ENABLED/d;/CACHE_SIZE/d;/DNS_FQDN_REQUIRED/d;/DNS_BOGUS_PRIV/d;/DNSMASQ_LISTENING/d;' "${setupVars}" - fi - # echo the information to the user - { - echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}" - echo "PIHOLE_DNS_1=${PIHOLE_DNS_1}" - echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}" - echo "QUERY_LOGGING=${QUERY_LOGGING}" - echo "INSTALL_WEB_SERVER=${INSTALL_WEB_SERVER}" - echo "INSTALL_WEB_INTERFACE=${INSTALL_WEB_INTERFACE}" - echo "LIGHTTPD_ENABLED=${LIGHTTPD_ENABLED}" - echo "CACHE_SIZE=${CACHE_SIZE}" - echo "DNS_FQDN_REQUIRED=${DNS_FQDN_REQUIRED:-true}" - echo "DNS_BOGUS_PRIV=${DNS_BOGUS_PRIV:-true}" - echo "DNSMASQ_LISTENING=${DNSMASQ_LISTENING:-local}" - }>> "${setupVars}" + # set or update the variables in the file + + addOrEditKeyValPair "${setupVars}" "PIHOLE_INTERFACE" "${PIHOLE_INTERFACE}" + addOrEditKeyValPair "${setupVars}" "PIHOLE_DNS_1" "${PIHOLE_DNS_1}" + addOrEditKeyValPair "${setupVars}" "PIHOLE_DNS_2" "${PIHOLE_DNS_2}" + addOrEditKeyValPair "${setupVars}" "QUERY_LOGGING" "${QUERY_LOGGING}" + addOrEditKeyValPair "${setupVars}" "INSTALL_WEB_SERVER" "${INSTALL_WEB_SERVER}" + addOrEditKeyValPair "${setupVars}" "INSTALL_WEB_INTERFACE" "${INSTALL_WEB_INTERFACE}" + addOrEditKeyValPair "${setupVars}" "LIGHTTPD_ENABLED" "${LIGHTTPD_ENABLED}" + addOrEditKeyValPair "${setupVars}" "CACHE_SIZE" "${CACHE_SIZE}" + addOrEditKeyValPair "${setupVars}" "DNS_FQDN_REQUIRED" "${DNS_FQDN_REQUIRED:-true}" + addOrEditKeyValPair "${setupVars}" "DNS_BOGUS_PRIV" "${DNS_BOGUS_PRIV:-true}" + addOrEditKeyValPair "${setupVars}" "DNSMASQ_LISTENING" "${DNSMASQ_LISTENING:-local}" + chmod 644 "${setupVars}" # Set the privacy level - sed -i '/PRIVACYLEVEL/d' "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" - echo "PRIVACYLEVEL=${PRIVACY_LEVEL}" >> "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" + addOrEditKeyValPair "${FTL_CONFIG_FILE}" "PRIVACYLEVEL" "${PRIVACY_LEVEL}" # Bring in the current settings and the functions to manipulate them source "${setupVars}" @@ -1895,6 +1885,16 @@ installPihole() { printf " %b Failure in dependent script copy function.\\n" "${CROSS}" exit 1 fi + + # /opt/pihole/utils.sh should be installed by installScripts now, so we can use it + if [ -f "${PI_HOLE_INSTALL_DIR}/utils.sh" ]; then + # shellcheck disable=SC1091 + source "${PI_HOLE_INSTALL_DIR}/utils.sh" + else + printf " %b Failure: /opt/pihole/utils.sh does not exist .\\n" "${CROSS}" + exit 1 + fi + # Install config files if ! installConfigs; then printf " %b Failure in dependent config copy function.\\n" "${CROSS}" @@ -2569,8 +2569,8 @@ main() { source "${setupVars}" # Get the privacy level if it exists (default is 0) - if [[ -f "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" ]]; then - PRIVACY_LEVEL=$(sed -ne 's/PRIVACYLEVEL=\(.*\)/\1/p' "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf") + if [[ -f "${FTL_CONFIG_FILE}" ]]; then + PRIVACY_LEVEL=$(sed -ne 's/PRIVACYLEVEL=\(.*\)/\1/p' "${FTL_CONFIG_FILE}") # If no setting was found, default to 0 PRIVACY_LEVEL="${PRIVACY_LEVEL:-0}" diff --git a/test/test_any_automated_install.py b/test/test_any_automated_install.py index 1e2a849b..70b30b6f 100644 --- a/test/test_any_automated_install.py +++ b/test/test_any_automated_install.py @@ -79,6 +79,7 @@ def test_setupVars_saved_to_file(host): echo start TERM=xterm source /opt/pihole/basic-install.sh + source /opt/pihole/utils.sh {} mkdir -p /etc/dnsmasq.d version_check_dnsmasq From 53c0982c8b52859062123ee041fb37fbf4b520a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 30 Aug 2022 20:03:38 +0200 Subject: [PATCH 02/32] Set connection timeout for curl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- gravity.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gravity.sh b/gravity.sh index 6f96b845..2d0d0ff5 100755 --- a/gravity.sh +++ b/gravity.sh @@ -641,7 +641,7 @@ gravity_DownloadBlocklistFromUrl() { fi # shellcheck disable=SC2086 - httpCode=$(curl -s -L ${compression} ${cmd_ext} ${heisenbergCompensator} -w "%{http_code}" -A "${agent}" "${url}" -o "${patternBuffer}" 2> /dev/null) + httpCode=$(curl --connect-timeout 10 -s -L ${compression} ${cmd_ext} ${heisenbergCompensator} -w "%{http_code}" -A "${agent}" "${url}" -o "${patternBuffer}" 2> /dev/null) case $url in # Did we "download" a local file? From 230d6a435fb2a5ea7f0afd99c28d764c072ba696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 31 Aug 2022 21:41:57 +0200 Subject: [PATCH 03/32] Semi hardcode the connection_timeout value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- gravity.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gravity.sh b/gravity.sh index 2d0d0ff5..7c831b22 100755 --- a/gravity.sh +++ b/gravity.sh @@ -40,6 +40,7 @@ gravityDBschema="${piholeGitDir}/advanced/Templates/gravity.db.sql" gravityDBcopy="${piholeGitDir}/advanced/Templates/gravity_copy.sql" domainsExtension="domains" +curl_connect_timeout=10 # Source setupVars from install script setupVars="${piholeDir}/setupVars.conf" @@ -641,7 +642,7 @@ gravity_DownloadBlocklistFromUrl() { fi # shellcheck disable=SC2086 - httpCode=$(curl --connect-timeout 10 -s -L ${compression} ${cmd_ext} ${heisenbergCompensator} -w "%{http_code}" -A "${agent}" "${url}" -o "${patternBuffer}" 2> /dev/null) + httpCode=$(curl --connect-timeout ${curl_connect_timeout} -s -L ${compression} ${cmd_ext} ${heisenbergCompensator} -w "%{http_code}" -A "${agent}" "${url}" -o "${patternBuffer}" 2> /dev/null) case $url in # Did we "download" a local file? From f90fb8b9467ae839509838af168fa909327cc9e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 14 Sep 2022 09:00:35 +0200 Subject: [PATCH 04/32] Change wording in chronometer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- advanced/Scripts/chronometer.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh index fddb3936..488bfd04 100755 --- a/advanced/Scripts/chronometer.sh +++ b/advanced/Scripts/chronometer.sh @@ -503,11 +503,11 @@ chronoFunc() { fi printFunc " Pi-hole: " "$ph_status" "$ph_info" - printFunc " Ads Today: " "$ads_percentage_today%" "$ads_info" + printFunc " Blocked %: " "$ads_percentage_today%" "$ads_info" printFunc "Local Qrys: " "$queries_cached_percentage%" "$dns_info" - printFunc " Blocked: " "$recent_blocked" - printFunc "Top Advert: " "$top_ad" + printFunc "Last Blckd: " "$recent_blocked" + printFunc " Top Blckd: " "$top_ad" # Provide more stats on screens with more lines if [[ "$scr_lines" -eq 17 ]]; then From 00e51f32b5a3bb2a779f9147ad957b2dcc6d4044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Sat, 17 Sep 2022 16:46:31 +0200 Subject: [PATCH 05/32] Blcked => Block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- advanced/Scripts/chronometer.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh index 488bfd04..af007994 100755 --- a/advanced/Scripts/chronometer.sh +++ b/advanced/Scripts/chronometer.sh @@ -503,11 +503,11 @@ chronoFunc() { fi printFunc " Pi-hole: " "$ph_status" "$ph_info" - printFunc " Blocked %: " "$ads_percentage_today%" "$ads_info" + printFunc " Blocked: " "$ads_percentage_today%" "$ads_info" printFunc "Local Qrys: " "$queries_cached_percentage%" "$dns_info" - printFunc "Last Blckd: " "$recent_blocked" - printFunc " Top Blckd: " "$top_ad" + printFunc "Last Block: " "$recent_blocked" + printFunc " Top Block: " "$top_ad" # Provide more stats on screens with more lines if [[ "$scr_lines" -eq 17 ]]; then From 73ca4ebdbc10b39b29ced4babc6238ff48c1d5c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 19 Sep 2022 11:44:53 +0200 Subject: [PATCH 06/32] Update test requirements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- test/requirements.txt | 1 - test/tox.centos_8.ini | 2 +- test/tox.debian_10.ini | 2 +- test/tox.debian_11.ini | 2 +- test/tox.fedora_34.ini | 2 +- test/tox.ubuntu_20.ini | 2 +- test/tox.ubuntu_22.ini | 2 +- 7 files changed, 6 insertions(+), 7 deletions(-) diff --git a/test/requirements.txt b/test/requirements.txt index d65ee6a5..0eb22a1b 100644 --- a/test/requirements.txt +++ b/test/requirements.txt @@ -1,6 +1,5 @@ docker-compose pytest pytest-xdist -pytest-cov pytest-testinfra tox diff --git a/test/tox.centos_8.ini b/test/tox.centos_8.ini index 71b147c7..dc160d2a 100644 --- a/test/tox.centos_8.ini +++ b/test/tox.centos_8.ini @@ -2,7 +2,7 @@ envlist = py3 [testenv] -whitelist_externals = docker +allowlist_externals = docker deps = -rrequirements.txt commands = docker build -f _centos_8.Dockerfile -t pytest_pihole:test_container ../ pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py ./test_centos_fedora_common_support.py ./test_centos_common_support.py diff --git a/test/tox.debian_10.ini b/test/tox.debian_10.ini index d21620dc..ef9fa7a0 100644 --- a/test/tox.debian_10.ini +++ b/test/tox.debian_10.ini @@ -2,7 +2,7 @@ envlist = py3 [testenv] -whitelist_externals = docker +allowlist_externals = docker deps = -rrequirements.txt commands = docker build -f _debian_10.Dockerfile -t pytest_pihole:test_container ../ pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py diff --git a/test/tox.debian_11.ini b/test/tox.debian_11.ini index f2546922..6d25a0c8 100644 --- a/test/tox.debian_11.ini +++ b/test/tox.debian_11.ini @@ -2,7 +2,7 @@ envlist = py3 [testenv] -whitelist_externals = docker +allowlist_externals = docker deps = -rrequirements.txt commands = docker build -f _debian_11.Dockerfile -t pytest_pihole:test_container ../ pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py diff --git a/test/tox.fedora_34.ini b/test/tox.fedora_34.ini index f4115a66..d58cb0d4 100644 --- a/test/tox.fedora_34.ini +++ b/test/tox.fedora_34.ini @@ -2,7 +2,7 @@ envlist = py3 [testenv] -whitelist_externals = docker +allowlist_externals = docker deps = -rrequirements.txt commands = docker build -f _fedora_34.Dockerfile -t pytest_pihole:test_container ../ pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py ./test_centos_fedora_common_support.py ./test_fedora_support.py diff --git a/test/tox.ubuntu_20.ini b/test/tox.ubuntu_20.ini index 80fb7485..4ae79a0c 100644 --- a/test/tox.ubuntu_20.ini +++ b/test/tox.ubuntu_20.ini @@ -2,7 +2,7 @@ envlist = py3 [testenv] -whitelist_externals = docker +allowlist_externals = docker deps = -rrequirements.txt commands = docker build -f _ubuntu_20.Dockerfile -t pytest_pihole:test_container ../ pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py diff --git a/test/tox.ubuntu_22.ini b/test/tox.ubuntu_22.ini index 41007a9c..3ddf7eca 100644 --- a/test/tox.ubuntu_22.ini +++ b/test/tox.ubuntu_22.ini @@ -2,7 +2,7 @@ envlist = py3 [testenv] -whitelist_externals = docker +allowlist_externals = docker deps = -rrequirements.txt commands = docker build -f _ubuntu_22.Dockerfile -t pytest_pihole:test_container ../ pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py From 0932c5c4983e247c85ff3553dc6fdb6eac39c391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 19 Sep 2022 12:45:36 +0200 Subject: [PATCH 07/32] Add black python code formatter action MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- .github/workflows/test.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7725ecc3..c0783538 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,7 +34,11 @@ jobs: - name: Run editorconfig-checker run: editorconfig-checker - + - + name: Run black python code formatter + uses: psf/black@stable + with: + src: "./test" distro-test: if: github.event.pull_request.draft == false From 0df38cd64ef4f77674f87188018d11f9d8fcfbd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 19 Sep 2022 14:44:10 +0200 Subject: [PATCH 08/32] Format all /test files with black MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- test/conftest.py | 179 +++-- test/setup.py | 4 +- test/test_any_automated_install.py | 902 +++++++++++----------- test/test_any_utils.py | 120 +-- test/test_centos_common_support.py | 19 +- test/test_centos_fedora_common_support.py | 54 +- test/test_fedora_support.py | 14 +- 7 files changed, 699 insertions(+), 593 deletions(-) diff --git a/test/conftest.py b/test/conftest.py index fb7e1eea..e395ec27 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -6,12 +6,12 @@ from textwrap import dedent SETUPVARS = { - 'PIHOLE_INTERFACE': 'eth99', - 'PIHOLE_DNS_1': '4.2.2.1', - 'PIHOLE_DNS_2': '4.2.2.2' + "PIHOLE_INTERFACE": "eth99", + "PIHOLE_DNS_1": "4.2.2.1", + "PIHOLE_DNS_2": "4.2.2.2", } -IMAGE = 'pytest_pihole:test_container' +IMAGE = "pytest_pihole:test_container" tick_box = "[\x1b[1;32m\u2713\x1b[0m]" cross_box = "[\x1b[1;31m\u2717\x1b[0m]" @@ -38,132 +38,187 @@ testinfra.backend.docker.DockerBackend.run = run_bash @pytest.fixture def host(): # run a container - docker_id = subprocess.check_output( - ['docker', 'run', '-t', '-d', '--cap-add=ALL', IMAGE]).decode().strip() + docker_id = ( + subprocess.check_output(["docker", "run", "-t", "-d", "--cap-add=ALL", IMAGE]) + .decode() + .strip() + ) # return a testinfra connection to the container docker_host = testinfra.get_host("docker://" + docker_id) yield docker_host # at the end of the test suite, destroy the container - subprocess.check_call(['docker', 'rm', '-f', docker_id]) + subprocess.check_call(["docker", "rm", "-f", docker_id]) # Helper functions def mock_command(script, args, container): - ''' + """ Allows for setup of commands we don't really want to have to run for real in unit tests - ''' - full_script_path = '/usr/local/bin/{}'.format(script) - mock_script = dedent(r'''\ + """ + full_script_path = "/usr/local/bin/{}".format(script) + mock_script = dedent( + r"""\ #!/bin/bash -e echo "\$0 \$@" >> /var/log/{script} - case "\$1" in'''.format(script=script)) + case "\$1" in""".format( + script=script + ) + ) for k, v in args.items(): - case = dedent(''' + case = dedent( + """ {arg}) echo {res} exit {retcode} - ;;'''.format(arg=k, res=v[0], retcode=v[1])) + ;;""".format( + arg=k, res=v[0], retcode=v[1] + ) + ) mock_script += case - mock_script += dedent(''' - esac''') - container.run(''' + mock_script += dedent( + """ + esac""" + ) + container.run( + """ cat < {script}\n{content}\nEOF chmod +x {script} - rm -f /var/log/{scriptlog}'''.format(script=full_script_path, - content=mock_script, - scriptlog=script)) + rm -f /var/log/{scriptlog}""".format( + script=full_script_path, content=mock_script, scriptlog=script + ) + ) def mock_command_passthrough(script, args, container): - ''' + """ Per other mock_command* functions, allows intercepting of commands we don't want to run for real in unit tests, however also allows only specific arguments to be mocked. Anything not defined will be passed through to the actual command. Example use-case: mocking `git pull` but still allowing `git clone` to work as intended - ''' - orig_script_path = container.check_output('command -v {}'.format(script)) - full_script_path = '/usr/local/bin/{}'.format(script) - mock_script = dedent(r'''\ + """ + orig_script_path = container.check_output("command -v {}".format(script)) + full_script_path = "/usr/local/bin/{}".format(script) + mock_script = dedent( + r"""\ #!/bin/bash -e echo "\$0 \$@" >> /var/log/{script} - case "\$1" in'''.format(script=script)) + case "\$1" in""".format( + script=script + ) + ) for k, v in args.items(): - case = dedent(''' + case = dedent( + """ {arg}) echo {res} exit {retcode} - ;;'''.format(arg=k, res=v[0], retcode=v[1])) + ;;""".format( + arg=k, res=v[0], retcode=v[1] + ) + ) mock_script += case - mock_script += dedent(r''' + mock_script += dedent( + r""" *) {orig_script_path} "\$@" - ;;'''.format(orig_script_path=orig_script_path)) - mock_script += dedent(''' - esac''') - container.run(''' + ;;""".format( + orig_script_path=orig_script_path + ) + ) + mock_script += dedent( + """ + esac""" + ) + container.run( + """ cat < {script}\n{content}\nEOF chmod +x {script} - rm -f /var/log/{scriptlog}'''.format(script=full_script_path, - content=mock_script, - scriptlog=script)) + rm -f /var/log/{scriptlog}""".format( + script=full_script_path, content=mock_script, scriptlog=script + ) + ) def mock_command_run(script, args, container): - ''' + """ Allows for setup of commands we don't really want to have to run for real in unit tests - ''' - full_script_path = '/usr/local/bin/{}'.format(script) - mock_script = dedent(r'''\ + """ + full_script_path = "/usr/local/bin/{}".format(script) + mock_script = dedent( + r"""\ #!/bin/bash -e echo "\$0 \$@" >> /var/log/{script} - case "\$1 \$2" in'''.format(script=script)) + case "\$1 \$2" in""".format( + script=script + ) + ) for k, v in args.items(): - case = dedent(''' + case = dedent( + """ \"{arg}\") echo {res} exit {retcode} - ;;'''.format(arg=k, res=v[0], retcode=v[1])) + ;;""".format( + arg=k, res=v[0], retcode=v[1] + ) + ) mock_script += case - mock_script += dedent(''' - esac''') - container.run(''' + mock_script += dedent( + """ + esac""" + ) + container.run( + """ cat < {script}\n{content}\nEOF chmod +x {script} - rm -f /var/log/{scriptlog}'''.format(script=full_script_path, - content=mock_script, - scriptlog=script)) + rm -f /var/log/{scriptlog}""".format( + script=full_script_path, content=mock_script, scriptlog=script + ) + ) def mock_command_2(script, args, container): - ''' + """ Allows for setup of commands we don't really want to have to run for real in unit tests - ''' - full_script_path = '/usr/local/bin/{}'.format(script) - mock_script = dedent(r'''\ + """ + full_script_path = "/usr/local/bin/{}".format(script) + mock_script = dedent( + r"""\ #!/bin/bash -e echo "\$0 \$@" >> /var/log/{script} - case "\$1 \$2" in'''.format(script=script)) + case "\$1 \$2" in""".format( + script=script + ) + ) for k, v in args.items(): - case = dedent(''' + case = dedent( + """ \"{arg}\") echo \"{res}\" exit {retcode} - ;;'''.format(arg=k, res=v[0], retcode=v[1])) + ;;""".format( + arg=k, res=v[0], retcode=v[1] + ) + ) mock_script += case - mock_script += dedent(''' - esac''') - container.run(''' + mock_script += dedent( + """ + esac""" + ) + container.run( + """ cat < {script}\n{content}\nEOF chmod +x {script} - rm -f /var/log/{scriptlog}'''.format(script=full_script_path, - content=mock_script, - scriptlog=script)) + rm -f /var/log/{scriptlog}""".format( + script=full_script_path, content=mock_script, scriptlog=script + ) + ) def run_script(Pihole, script): diff --git a/test/setup.py b/test/setup.py index 9f3b4b48..cdde20d3 100644 --- a/test/setup.py +++ b/test/setup.py @@ -2,6 +2,6 @@ from setuptools import setup setup( py_modules=[], - setup_requires=['pytest-runner'], - tests_require=['pytest'], + setup_requires=["pytest-runner"], + tests_require=["pytest"], ) diff --git a/test/test_any_automated_install.py b/test/test_any_automated_install.py index 70300243..895db6dc 100644 --- a/test/test_any_automated_install.py +++ b/test/test_any_automated_install.py @@ -10,39 +10,42 @@ from .conftest import ( mock_command_run, mock_command_2, mock_command_passthrough, - run_script + run_script, ) def test_supported_package_manager(host): - ''' + """ confirm installer exits when no supported package manager found - ''' + """ # break supported package managers - host.run('rm -rf /usr/bin/apt-get') - host.run('rm -rf /usr/bin/rpm') - package_manager_detect = host.run(''' + host.run("rm -rf /usr/bin/apt-get") + host.run("rm -rf /usr/bin/rpm") + package_manager_detect = host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect - ''') - expected_stdout = cross_box + ' No supported package manager found' + """ + ) + expected_stdout = cross_box + " No supported package manager found" assert expected_stdout in package_manager_detect.stdout # assert package_manager_detect.rc == 1 def test_setupVars_are_sourced_to_global_scope(host): - ''' + """ currently update_dialogs sources setupVars with a dot, then various other functions use the variables. This confirms the sourced variables are in scope between functions - ''' - setup_var_file = 'cat < /etc/pihole/setupVars.conf\n' + """ + setup_var_file = "cat < /etc/pihole/setupVars.conf\n" for k, v in SETUPVARS.items(): setup_var_file += "{}={}\n".format(k, v) setup_var_file += "EOF\n" host.run(setup_var_file) - script = dedent('''\ + script = dedent( + """\ set -e printSetupVars() { # Currently debug test function only @@ -56,7 +59,8 @@ def test_setupVars_are_sourced_to_global_scope(host): } update_dialogs printSetupVars - ''') + """ + ) output = run_script(host, script).stdout @@ -65,16 +69,17 @@ def test_setupVars_are_sourced_to_global_scope(host): def test_setupVars_saved_to_file(host): - ''' + """ confirm saved settings are written to a file for future updates to re-use - ''' + """ # dedent works better with this and padding matching script below - set_setup_vars = '\n' + set_setup_vars = "\n" for k, v in SETUPVARS.items(): set_setup_vars += " {}={}\n".format(k, v) host.run(set_setup_vars) - script = dedent('''\ + script = dedent( + """\ set -e echo start TERM=xterm @@ -85,7 +90,10 @@ def test_setupVars_saved_to_file(host): echo "" > /etc/pihole/pihole-FTL.conf finalExports cat /etc/pihole/setupVars.conf - '''.format(set_setup_vars)) + """.format( + set_setup_vars + ) + ) output = run_script(host, script).stdout @@ -94,48 +102,52 @@ def test_setupVars_saved_to_file(host): def test_selinux_not_detected(host): - ''' + """ confirms installer continues when SELinux configuration file does not exist - ''' - check_selinux = host.run(''' + """ + check_selinux = host.run( + """ rm -f /etc/selinux/config source /opt/pihole/basic-install.sh checkSelinux - ''') - expected_stdout = info_box + ' SELinux not detected' + """ + ) + expected_stdout = info_box + " SELinux not detected" assert expected_stdout in check_selinux.stdout assert check_selinux.rc == 0 def test_installPiholeWeb_fresh_install_no_errors(host): - ''' + """ confirms all web page assets from Core repo are installed on a fresh build - ''' - installWeb = host.run(''' + """ + installWeb = host.run( + """ umask 0027 source /opt/pihole/basic-install.sh installPiholeWeb - ''') - expected_stdout = info_box + ' Installing 404 page...' + """ + ) + expected_stdout = info_box + " Installing 404 page..." assert expected_stdout in installWeb.stdout - expected_stdout = tick_box + (' Creating directory for 404 page, ' - 'and copying files') + expected_stdout = tick_box + ( + " Creating directory for 404 page, " "and copying files" + ) assert expected_stdout in installWeb.stdout - expected_stdout = info_box + ' Backing up index.lighttpd.html' + expected_stdout = info_box + " Backing up index.lighttpd.html" assert expected_stdout in installWeb.stdout - expected_stdout = ('No default index.lighttpd.html file found... ' - 'not backing up') + expected_stdout = "No default index.lighttpd.html file found... " "not backing up" assert expected_stdout in installWeb.stdout - expected_stdout = tick_box + ' Installing sudoer file' + expected_stdout = tick_box + " Installing sudoer file" assert expected_stdout in installWeb.stdout - web_directory = host.run('ls -r /var/www/html/pihole').stdout - assert 'index.php' in web_directory + web_directory = host.run("ls -r /var/www/html/pihole").stdout + assert "index.php" in web_directory def get_directories_recursive(host, directory): if directory is None: return directory - ls = host.run('ls -d {}'.format(directory + '/*/')) + ls = host.run("ls -d {}".format(directory + "/*/")) directories = list(filter(bool, ls.stdout.splitlines())) dirs = directories for dirval in directories: @@ -148,61 +160,41 @@ def get_directories_recursive(host, directory): def test_installPihole_fresh_install_readableFiles(host): - ''' + """ confirms all necessary files are readable by pihole user - ''' + """ # dialog returns Cancel for user prompt - mock_command('dialog', {'*': ('', '0')}, host) + mock_command("dialog", {"*": ("", "0")}, host) # mock git pull - mock_command_passthrough('git', {'pull': ('', '0')}, host) + mock_command_passthrough("git", {"pull": ("", "0")}, host) # mock systemctl to not start lighttpd and FTL mock_command_2( - 'systemctl', + "systemctl", { - 'enable lighttpd': ( - '', - '0' - ), - 'restart lighttpd': ( - '', - '0' - ), - 'start lighttpd': ( - '', - '0' - ), - 'enable pihole-FTL': ( - '', - '0' - ), - 'restart pihole-FTL': ( - '', - '0' - ), - 'start pihole-FTL': ( - '', - '0' - ), - '*': ( - 'echo "systemctl call with $@"', - '0' - ), + "enable lighttpd": ("", "0"), + "restart lighttpd": ("", "0"), + "start lighttpd": ("", "0"), + "enable pihole-FTL": ("", "0"), + "restart pihole-FTL": ("", "0"), + "start pihole-FTL": ("", "0"), + "*": ('echo "systemctl call with $@"', "0"), }, - host + host, ) # try to install man - host.run('command -v apt-get > /dev/null && apt-get install -qq man') - host.run('command -v dnf > /dev/null && dnf install -y man') - host.run('command -v yum > /dev/null && yum install -y man') + host.run("command -v apt-get > /dev/null && apt-get install -qq man") + host.run("command -v dnf > /dev/null && dnf install -y man") + host.run("command -v yum > /dev/null && yum install -y man") # create configuration file - setup_var_file = 'cat < /etc/pihole/setupVars.conf\n' + setup_var_file = "cat < /etc/pihole/setupVars.conf\n" for k, v in SETUPVARS.items(): setup_var_file += "{}={}\n".format(k, v) setup_var_file += "INSTALL_WEB_SERVER=true\n" setup_var_file += "INSTALL_WEB_INTERFACE=true\n" setup_var_file += "EOF\n" host.run(setup_var_file) - install = host.run(''' + install = host.run( + """ export TERM=xterm export DEBIAN_FRONTEND=noninteractive umask 0027 @@ -212,183 +204,164 @@ def test_installPihole_fresh_install_readableFiles(host): runUnattended=true useUpdateVars=true main - ''') + """ + ) assert 0 == install.rc maninstalled = True - if (info_box + ' man not installed') in install.stdout: + if (info_box + " man not installed") in install.stdout: maninstalled = False - piholeuser = 'pihole' + piholeuser = "pihole" exit_status_success = 0 test_cmd = 'su --shell /bin/bash --command "test -{0} {1}" -p {2}' # check files in /etc/pihole for read, write and execute permission - check_etc = test_cmd.format('r', '/etc/pihole', piholeuser) + check_etc = test_cmd.format("r", "/etc/pihole", piholeuser) actual_rc = host.run(check_etc).rc assert exit_status_success == actual_rc - check_etc = test_cmd.format('x', '/etc/pihole', piholeuser) + check_etc = test_cmd.format("x", "/etc/pihole", piholeuser) actual_rc = host.run(check_etc).rc assert exit_status_success == actual_rc # readable and writable dhcp.leases - check_leases = test_cmd.format('r', '/etc/pihole/dhcp.leases', piholeuser) + check_leases = test_cmd.format("r", "/etc/pihole/dhcp.leases", piholeuser) actual_rc = host.run(check_leases).rc assert exit_status_success == actual_rc - check_leases = test_cmd.format('w', '/etc/pihole/dhcp.leases', piholeuser) + check_leases = test_cmd.format("w", "/etc/pihole/dhcp.leases", piholeuser) actual_rc = host.run(check_leases).rc # readable dns-servers.conf assert exit_status_success == actual_rc - check_servers = test_cmd.format( - 'r', '/etc/pihole/dns-servers.conf', piholeuser) + check_servers = test_cmd.format("r", "/etc/pihole/dns-servers.conf", piholeuser) actual_rc = host.run(check_servers).rc assert exit_status_success == actual_rc # readable install.log - check_install = test_cmd.format( - 'r', '/etc/pihole/install.log', piholeuser) + check_install = test_cmd.format("r", "/etc/pihole/install.log", piholeuser) actual_rc = host.run(check_install).rc assert exit_status_success == actual_rc # readable versions - check_localversion = test_cmd.format( - 'r', '/etc/pihole/versions', piholeuser) + check_localversion = test_cmd.format("r", "/etc/pihole/versions", piholeuser) actual_rc = host.run(check_localversion).rc assert exit_status_success == actual_rc # readable logrotate - check_logrotate = test_cmd.format( - 'r', '/etc/pihole/logrotate', piholeuser) + check_logrotate = test_cmd.format("r", "/etc/pihole/logrotate", piholeuser) actual_rc = host.run(check_logrotate).rc assert exit_status_success == actual_rc # readable macvendor.db - check_macvendor = test_cmd.format( - 'r', '/etc/pihole/macvendor.db', piholeuser) + check_macvendor = test_cmd.format("r", "/etc/pihole/macvendor.db", piholeuser) actual_rc = host.run(check_macvendor).rc assert exit_status_success == actual_rc # readable and writeable pihole-FTL.conf - check_FTLconf = test_cmd.format( - 'r', '/etc/pihole/pihole-FTL.conf', piholeuser) + check_FTLconf = test_cmd.format("r", "/etc/pihole/pihole-FTL.conf", piholeuser) actual_rc = host.run(check_FTLconf).rc assert exit_status_success == actual_rc - check_FTLconf = test_cmd.format( - 'w', '/etc/pihole/pihole-FTL.conf', piholeuser) + check_FTLconf = test_cmd.format("w", "/etc/pihole/pihole-FTL.conf", piholeuser) actual_rc = host.run(check_FTLconf).rc assert exit_status_success == actual_rc # readable setupVars.conf - check_setup = test_cmd.format( - 'r', '/etc/pihole/setupVars.conf', piholeuser) + check_setup = test_cmd.format("r", "/etc/pihole/setupVars.conf", piholeuser) actual_rc = host.run(check_setup).rc assert exit_status_success == actual_rc # check dnsmasq files # readable /etc/dnsmasq.conf - check_dnsmasqconf = test_cmd.format( - 'r', '/etc/dnsmasq.conf', piholeuser) + check_dnsmasqconf = test_cmd.format("r", "/etc/dnsmasq.conf", piholeuser) actual_rc = host.run(check_dnsmasqconf).rc assert exit_status_success == actual_rc # readable /etc/dnsmasq.d/01-pihole.conf - check_dnsmasqconf = test_cmd.format( - 'r', '/etc/dnsmasq.d', piholeuser) + check_dnsmasqconf = test_cmd.format("r", "/etc/dnsmasq.d", piholeuser) actual_rc = host.run(check_dnsmasqconf).rc assert exit_status_success == actual_rc - check_dnsmasqconf = test_cmd.format( - 'x', '/etc/dnsmasq.d', piholeuser) + check_dnsmasqconf = test_cmd.format("x", "/etc/dnsmasq.d", piholeuser) actual_rc = host.run(check_dnsmasqconf).rc assert exit_status_success == actual_rc check_dnsmasqconf = test_cmd.format( - 'r', '/etc/dnsmasq.d/01-pihole.conf', piholeuser) + "r", "/etc/dnsmasq.d/01-pihole.conf", piholeuser + ) actual_rc = host.run(check_dnsmasqconf).rc assert exit_status_success == actual_rc # check readable and executable /etc/init.d/pihole-FTL - check_init = test_cmd.format( - 'x', '/etc/init.d/pihole-FTL', piholeuser) + check_init = test_cmd.format("x", "/etc/init.d/pihole-FTL", piholeuser) actual_rc = host.run(check_init).rc assert exit_status_success == actual_rc - check_init = test_cmd.format( - 'r', '/etc/init.d/pihole-FTL', piholeuser) + check_init = test_cmd.format("r", "/etc/init.d/pihole-FTL", piholeuser) actual_rc = host.run(check_init).rc assert exit_status_success == actual_rc # check readable /etc/lighttpd/lighttpd.conf - check_lighttpd = test_cmd.format( - 'r', '/etc/lighttpd/lighttpd.conf', piholeuser) + check_lighttpd = test_cmd.format("r", "/etc/lighttpd/lighttpd.conf", piholeuser) actual_rc = host.run(check_lighttpd).rc assert exit_status_success == actual_rc # check readable and executable manpages if maninstalled is True: - check_man = test_cmd.format( - 'x', '/usr/local/share/man', piholeuser) + check_man = test_cmd.format("x", "/usr/local/share/man", piholeuser) actual_rc = host.run(check_man).rc assert exit_status_success == actual_rc - check_man = test_cmd.format( - 'r', '/usr/local/share/man', piholeuser) + check_man = test_cmd.format("r", "/usr/local/share/man", piholeuser) actual_rc = host.run(check_man).rc assert exit_status_success == actual_rc - check_man = test_cmd.format( - 'x', '/usr/local/share/man/man8', piholeuser) + check_man = test_cmd.format("x", "/usr/local/share/man/man8", piholeuser) actual_rc = host.run(check_man).rc assert exit_status_success == actual_rc - check_man = test_cmd.format( - 'r', '/usr/local/share/man/man8', piholeuser) + check_man = test_cmd.format("r", "/usr/local/share/man/man8", piholeuser) actual_rc = host.run(check_man).rc assert exit_status_success == actual_rc - check_man = test_cmd.format( - 'x', '/usr/local/share/man/man5', piholeuser) + check_man = test_cmd.format("x", "/usr/local/share/man/man5", piholeuser) actual_rc = host.run(check_man).rc assert exit_status_success == actual_rc - check_man = test_cmd.format( - 'r', '/usr/local/share/man/man5', piholeuser) + check_man = test_cmd.format("r", "/usr/local/share/man/man5", piholeuser) actual_rc = host.run(check_man).rc assert exit_status_success == actual_rc check_man = test_cmd.format( - 'r', '/usr/local/share/man/man8/pihole.8', piholeuser) + "r", "/usr/local/share/man/man8/pihole.8", piholeuser + ) actual_rc = host.run(check_man).rc assert exit_status_success == actual_rc check_man = test_cmd.format( - 'r', '/usr/local/share/man/man8/pihole-FTL.8', piholeuser) + "r", "/usr/local/share/man/man8/pihole-FTL.8", piholeuser + ) actual_rc = host.run(check_man).rc assert exit_status_success == actual_rc # check not readable sudoers file - check_sudo = test_cmd.format( - 'r', '/etc/sudoers.d/pihole', piholeuser) + check_sudo = test_cmd.format("r", "/etc/sudoers.d/pihole", piholeuser) actual_rc = host.run(check_sudo).rc assert exit_status_success != actual_rc # check not readable cron file - check_sudo = test_cmd.format( - 'x', '/etc/cron.d/', piholeuser) + check_sudo = test_cmd.format("x", "/etc/cron.d/", piholeuser) actual_rc = host.run(check_sudo).rc assert exit_status_success == actual_rc - check_sudo = test_cmd.format( - 'r', '/etc/cron.d/', piholeuser) + check_sudo = test_cmd.format("r", "/etc/cron.d/", piholeuser) actual_rc = host.run(check_sudo).rc assert exit_status_success == actual_rc - check_sudo = test_cmd.format( - 'r', '/etc/cron.d/pihole', piholeuser) + check_sudo = test_cmd.format("r", "/etc/cron.d/pihole", piholeuser) actual_rc = host.run(check_sudo).rc assert exit_status_success == actual_rc - directories = get_directories_recursive(host, '/etc/.pihole/') + directories = get_directories_recursive(host, "/etc/.pihole/") for directory in directories: - check_pihole = test_cmd.format('r', directory, piholeuser) + check_pihole = test_cmd.format("r", directory, piholeuser) actual_rc = host.run(check_pihole).rc - check_pihole = test_cmd.format('x', directory, piholeuser) + check_pihole = test_cmd.format("x", directory, piholeuser) actual_rc = host.run(check_pihole).rc findfiles = 'find "{}" -maxdepth 1 -type f -exec echo {{}} \\;;' filelist = host.run(findfiles.format(directory)) files = list(filter(bool, filelist.stdout.splitlines())) for file in files: - check_pihole = test_cmd.format('r', file, piholeuser) + check_pihole = test_cmd.format("r", file, piholeuser) actual_rc = host.run(check_pihole).rc @pytest.mark.parametrize("test_webpage", [True]) def test_installPihole_fresh_install_readableBlockpage(host, test_webpage): - ''' + """ confirms all web page assets from Core repo are readable by $LIGHTTPD_USER on a fresh build - ''' + """ piholeWebpage = [ "127.0.0.1", # "pi.hole" ] # dialog returns Cancel for user prompt - mock_command('dialog', {'*': ('', '0')}, host) + mock_command("dialog", {"*": ("", "0")}, host) # mock git pull - mock_command_passthrough('git', {'pull': ('', '0')}, host) + mock_command_passthrough("git", {"pull": ("", "0")}, host) # mock systemctl to start lighttpd and FTL - ligthttpdcommand = dedent(r'''\"\" + ligthttpdcommand = dedent( + r'''\"\" echo 'starting lighttpd with {}' if [ command -v "apt-get" >/dev/null 2>&1 ]; then LIGHTTPD_USER="www-data" @@ -418,63 +391,45 @@ def test_installPihole_fresh_install_readableBlockpage(host, test_webpage): /usr/sbin/lighttpd -tt -f '{config}' /usr/sbin/lighttpd -f '{config}' echo \"\"'''.format( - '{}', - usergroup='${{LIGHTTPD_USER}}:${{LIGHTTPD_GROUP}}', - chmodarg='{{}}', - config='/etc/lighttpd/lighttpd.conf', - run='/var/run/lighttpd', - cache='/var/cache/lighttpd', - uploads='/var/cache/lighttpd/uploads', - compress='/var/cache/lighttpd/compress' + "{}", + usergroup="${{LIGHTTPD_USER}}:${{LIGHTTPD_GROUP}}", + chmodarg="{{}}", + config="/etc/lighttpd/lighttpd.conf", + run="/var/run/lighttpd", + cache="/var/cache/lighttpd", + uploads="/var/cache/lighttpd/uploads", + compress="/var/cache/lighttpd/compress", ) ) - FTLcommand = dedent('''\"\" + FTLcommand = dedent( + '''\"\" set -x /etc/init.d/pihole-FTL restart - echo \"\"''') + echo \"\"''' + ) mock_command_run( - 'systemctl', + "systemctl", { - 'enable lighttpd': ( - '', - '0' - ), - 'restart lighttpd': ( - ligthttpdcommand.format('restart'), - '0' - ), - 'start lighttpd': ( - ligthttpdcommand.format('start'), - '0' - ), - 'enable pihole-FTL': ( - '', - '0' - ), - 'restart pihole-FTL': ( - FTLcommand, - '0' - ), - 'start pihole-FTL': ( - FTLcommand, - '0' - ), - '*': ( - 'echo "systemctl call with $@"', - '0' - ), + "enable lighttpd": ("", "0"), + "restart lighttpd": (ligthttpdcommand.format("restart"), "0"), + "start lighttpd": (ligthttpdcommand.format("start"), "0"), + "enable pihole-FTL": ("", "0"), + "restart pihole-FTL": (FTLcommand, "0"), + "start pihole-FTL": (FTLcommand, "0"), + "*": ('echo "systemctl call with $@"', "0"), }, - host + host, ) # create configuration file - setup_var_file = 'cat < /etc/pihole/setupVars.conf\n' + setup_var_file = "cat < /etc/pihole/setupVars.conf\n" for k, v in SETUPVARS.items(): setup_var_file += "{}={}\n".format(k, v) setup_var_file += "INSTALL_WEB_SERVER=true\n" setup_var_file += "INSTALL_WEB_INTERFACE=true\n" setup_var_file += "EOF\n" host.run(setup_var_file) - installWeb = host.run(''' + installWeb = host.run( + """ export TERM=xterm export DEBIAN_FRONTEND=noninteractive umask 0027 @@ -488,33 +443,32 @@ def test_installPihole_fresh_install_readableBlockpage(host, test_webpage): echo "webroot=${webroot}" echo "INSTALL_WEB_INTERFACE=${INSTALL_WEB_INTERFACE}" echo "INSTALL_WEB_SERVER=${INSTALL_WEB_SERVER}" - ''') + """ + ) assert 0 == installWeb.rc - piholeuser = 'pihole' - webuser = '' - user = re.findall( - r"^\s*LIGHTTPD_USER=.*$", installWeb.stdout, re.MULTILINE) + piholeuser = "pihole" + webuser = "" + user = re.findall(r"^\s*LIGHTTPD_USER=.*$", installWeb.stdout, re.MULTILINE) for match in user: - webuser = match.replace('LIGHTTPD_USER=', '').strip() - webroot = '' - user = re.findall( - r"^\s*webroot=.*$", installWeb.stdout, re.MULTILINE) + webuser = match.replace("LIGHTTPD_USER=", "").strip() + webroot = "" + user = re.findall(r"^\s*webroot=.*$", installWeb.stdout, re.MULTILINE) for match in user: - webroot = match.replace('webroot=', '').strip() + webroot = match.replace("webroot=", "").strip() if not webroot.strip(): - webroot = '/var/www/html' + webroot = "/var/www/html" installWebInterface = True interface = re.findall( - r"^\s*INSTALL_WEB_INTERFACE=.*$", installWeb.stdout, re.MULTILINE) + r"^\s*INSTALL_WEB_INTERFACE=.*$", installWeb.stdout, re.MULTILINE + ) for match in interface: - testvalue = match.replace('INSTALL_WEB_INTERFACE=', '').strip().lower() + testvalue = match.replace("INSTALL_WEB_INTERFACE=", "").strip().lower() if not testvalue.strip(): installWebInterface = testvalue == "true" installWebServer = True - server = re.findall( - r"^\s*INSTALL_WEB_SERVER=.*$", installWeb.stdout, re.MULTILINE) + server = re.findall(r"^\s*INSTALL_WEB_SERVER=.*$", installWeb.stdout, re.MULTILINE) for match in server: - testvalue = match.replace('INSTALL_WEB_SERVER=', '').strip().lower() + testvalue = match.replace("INSTALL_WEB_SERVER=", "").strip().lower() if not testvalue.strip(): installWebServer = testvalue == "true" # if webserver install was not requested @@ -525,87 +479,88 @@ def test_installPihole_fresh_install_readableBlockpage(host, test_webpage): test_cmd = 'su --shell /bin/bash --command "test -{0} {1}" -p {2}' # check files that need a running FTL to be created # readable and writeable pihole-FTL.db - check_FTLconf = test_cmd.format( - 'r', '/etc/pihole/pihole-FTL.db', piholeuser) + check_FTLconf = test_cmd.format("r", "/etc/pihole/pihole-FTL.db", piholeuser) actual_rc = host.run(check_FTLconf).rc assert exit_status_success == actual_rc - check_FTLconf = test_cmd.format( - 'w', '/etc/pihole/pihole-FTL.db', piholeuser) + check_FTLconf = test_cmd.format("w", "/etc/pihole/pihole-FTL.db", piholeuser) actual_rc = host.run(check_FTLconf).rc assert exit_status_success == actual_rc # check directories above $webroot for read and execute permission - check_var = test_cmd.format('r', '/var', webuser) + check_var = test_cmd.format("r", "/var", webuser) actual_rc = host.run(check_var).rc assert exit_status_success == actual_rc - check_var = test_cmd.format('x', '/var', webuser) + check_var = test_cmd.format("x", "/var", webuser) actual_rc = host.run(check_var).rc assert exit_status_success == actual_rc - check_www = test_cmd.format('r', '/var/www', webuser) + check_www = test_cmd.format("r", "/var/www", webuser) actual_rc = host.run(check_www).rc assert exit_status_success == actual_rc - check_www = test_cmd.format('x', '/var/www', webuser) + check_www = test_cmd.format("x", "/var/www", webuser) actual_rc = host.run(check_www).rc assert exit_status_success == actual_rc - check_html = test_cmd.format('r', '/var/www/html', webuser) + check_html = test_cmd.format("r", "/var/www/html", webuser) actual_rc = host.run(check_html).rc assert exit_status_success == actual_rc - check_html = test_cmd.format('x', '/var/www/html', webuser) + check_html = test_cmd.format("x", "/var/www/html", webuser) actual_rc = host.run(check_html).rc assert exit_status_success == actual_rc # check directories below $webroot for read and execute permission - check_admin = test_cmd.format('r', webroot + '/admin', webuser) + check_admin = test_cmd.format("r", webroot + "/admin", webuser) actual_rc = host.run(check_admin).rc assert exit_status_success == actual_rc - check_admin = test_cmd.format('x', webroot + '/admin', webuser) + check_admin = test_cmd.format("x", webroot + "/admin", webuser) actual_rc = host.run(check_admin).rc assert exit_status_success == actual_rc - directories = get_directories_recursive(host, webroot + '/admin/*/') + directories = get_directories_recursive(host, webroot + "/admin/*/") for directory in directories: - check_pihole = test_cmd.format('r', directory, webuser) + check_pihole = test_cmd.format("r", directory, webuser) actual_rc = host.run(check_pihole).rc - check_pihole = test_cmd.format('x', directory, webuser) + check_pihole = test_cmd.format("x", directory, webuser) actual_rc = host.run(check_pihole).rc findfiles = 'find "{}" -maxdepth 1 -type f -exec echo {{}} \\;;' filelist = host.run(findfiles.format(directory)) files = list(filter(bool, filelist.stdout.splitlines())) for file in files: - check_pihole = test_cmd.format('r', file, webuser) + check_pihole = test_cmd.format("r", file, webuser) actual_rc = host.run(check_pihole).rc # check web interface files # change nameserver to pi-hole # setting nameserver in /etc/resolv.conf to pi-hole does # not work here because of the way docker uses this file - ns = host.run( - r"sed -i 's/nameserver.*/nameserver 127.0.0.1/' /etc/resolv.conf") + ns = host.run(r"sed -i 's/nameserver.*/nameserver 127.0.0.1/' /etc/resolv.conf") pihole_is_ns = ns.rc == 0 def is_ip(address): m = re.match(r"(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})", address) return bool(m) + if installWebInterface is True: - check_pihole = test_cmd.format('r', webroot + '/pihole', webuser) + check_pihole = test_cmd.format("r", webroot + "/pihole", webuser) actual_rc = host.run(check_pihole).rc assert exit_status_success == actual_rc - check_pihole = test_cmd.format('x', webroot + '/pihole', webuser) + check_pihole = test_cmd.format("x", webroot + "/pihole", webuser) actual_rc = host.run(check_pihole).rc assert exit_status_success == actual_rc # check most important files in $webroot for read permission - check_index = test_cmd.format( - 'r', webroot + '/pihole/index.php', webuser) + check_index = test_cmd.format("r", webroot + "/pihole/index.php", webuser) actual_rc = host.run(check_index).rc assert exit_status_success == actual_rc if test_webpage is True: # check webpage for unreadable files noPHPfopen = re.compile( - (r"PHP Error(%d+):\s+fopen([^)]+):\s+" + - r"failed to open stream: " + - r"Permission denied in"), - re.I) + ( + r"PHP Error(%d+):\s+fopen([^)]+):\s+" + + r"failed to open stream: " + + r"Permission denied in" + ), + re.I, + ) # using cURL option --dns-servers is not possible status = ( - 'curl -s --head "{}" | ' + - 'head -n 1 | ' + - 'grep "HTTP/1.[01] [23].." > /dev/null') + 'curl -s --head "{}" | ' + + "head -n 1 | " + + 'grep "HTTP/1.[01] [23].." > /dev/null' + ) digcommand = r"dig A +short {} @127.0.0.1 | head -n 1" pagecontent = 'curl --verbose -L "{}"' for page in piholeWebpage: @@ -625,258 +580,285 @@ def test_installPihole_fresh_install_readableBlockpage(host, test_webpage): def test_update_package_cache_success_no_errors(host): - ''' + """ confirms package cache was updated without any errors - ''' - updateCache = host.run(''' + """ + updateCache = host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect update_package_cache - ''') - expected_stdout = tick_box + ' Update local cache of available packages' + """ + ) + expected_stdout = tick_box + " Update local cache of available packages" assert expected_stdout in updateCache.stdout - assert 'error' not in updateCache.stdout.lower() + assert "error" not in updateCache.stdout.lower() def test_update_package_cache_failure_no_errors(host): - ''' + """ confirms package cache was not updated - ''' - mock_command('apt-get', {'update': ('', '1')}, host) - updateCache = host.run(''' + """ + mock_command("apt-get", {"update": ("", "1")}, host) + updateCache = host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect update_package_cache - ''') - expected_stdout = cross_box + ' Update local cache of available packages' + """ + ) + expected_stdout = cross_box + " Update local cache of available packages" assert expected_stdout in updateCache.stdout - assert 'Error: Unable to update package cache.' in updateCache.stdout + assert "Error: Unable to update package cache." in updateCache.stdout def test_FTL_detect_aarch64_no_errors(host): - ''' + """ confirms only aarch64 package is downloaded for FTL engine - ''' + """ # mock uname to return aarch64 platform - mock_command('uname', {'-m': ('aarch64', '0')}, host) + mock_command("uname", {"-m": ("aarch64", "0")}, host) # mock `which sh` to return `/bin/sh` - mock_command('which', {'sh': ('/bin/sh', '0')}, host) + mock_command("which", {"sh": ("/bin/sh", "0")}, host) # mock ldd to respond with aarch64 shared library - mock_command('ldd', {'/bin/sh': ('/lib/ld-linux-aarch64.so.1', '0')}, host) - detectPlatform = host.run(''' + mock_command("ldd", {"/bin/sh": ("/lib/ld-linux-aarch64.so.1", "0")}, host) + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}" - ''') - expected_stdout = info_box + ' FTL Checks...' + """ + ) + expected_stdout = info_box + " FTL Checks..." assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Detected AArch64 (64 Bit ARM) processor' + expected_stdout = tick_box + " Detected AArch64 (64 Bit ARM) processor" assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Downloading and Installing FTL' + expected_stdout = tick_box + " Downloading and Installing FTL" assert expected_stdout in detectPlatform.stdout def test_FTL_detect_armv4t_no_errors(host): - ''' + """ confirms only armv4t package is downloaded for FTL engine - ''' + """ # mock uname to return armv4t platform - mock_command('uname', {'-m': ('armv4t', '0')}, host) + mock_command("uname", {"-m": ("armv4t", "0")}, host) # mock `which sh` to return `/bin/sh` - mock_command('which', {'sh': ('/bin/sh', '0')}, host) + mock_command("which", {"sh": ("/bin/sh", "0")}, host) # mock ldd to respond with armv4t shared library - mock_command('ldd', {'/bin/sh': ('/lib/ld-linux.so.3', '0')}, host) - detectPlatform = host.run(''' + mock_command("ldd", {"/bin/sh": ("/lib/ld-linux.so.3", "0")}, host) + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}" - ''') - expected_stdout = info_box + ' FTL Checks...' + """ + ) + expected_stdout = info_box + " FTL Checks..." assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + (' Detected ARMv4 processor') + expected_stdout = tick_box + (" Detected ARMv4 processor") assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Downloading and Installing FTL' + expected_stdout = tick_box + " Downloading and Installing FTL" assert expected_stdout in detectPlatform.stdout def test_FTL_detect_armv5te_no_errors(host): - ''' + """ confirms only armv5te package is downloaded for FTL engine - ''' + """ # mock uname to return armv5te platform - mock_command('uname', {'-m': ('armv5te', '0')}, host) + mock_command("uname", {"-m": ("armv5te", "0")}, host) # mock `which sh` to return `/bin/sh` - mock_command('which', {'sh': ('/bin/sh', '0')}, host) + mock_command("which", {"sh": ("/bin/sh", "0")}, host) # mock ldd to respond with ld-linux shared library - mock_command('ldd', {'/bin/sh': ('/lib/ld-linux.so.3', '0')}, host) - detectPlatform = host.run(''' + mock_command("ldd", {"/bin/sh": ("/lib/ld-linux.so.3", "0")}, host) + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}" - ''') - expected_stdout = info_box + ' FTL Checks...' + """ + ) + expected_stdout = info_box + " FTL Checks..." assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + (' Detected ARMv5 (or newer) processor') + expected_stdout = tick_box + (" Detected ARMv5 (or newer) processor") assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Downloading and Installing FTL' + expected_stdout = tick_box + " Downloading and Installing FTL" assert expected_stdout in detectPlatform.stdout def test_FTL_detect_armv6l_no_errors(host): - ''' + """ confirms only armv6l package is downloaded for FTL engine - ''' + """ # mock uname to return armv6l platform - mock_command('uname', {'-m': ('armv6l', '0')}, host) + mock_command("uname", {"-m": ("armv6l", "0")}, host) # mock ldd to respond with ld-linux-armhf shared library # mock `which sh` to return `/bin/sh` - mock_command('which', {'sh': ('/bin/sh', '0')}, host) - mock_command('ldd', {'/bin/sh': ('/lib/ld-linux-armhf.so.3', '0')}, host) - detectPlatform = host.run(''' + mock_command("which", {"sh": ("/bin/sh", "0")}, host) + mock_command("ldd", {"/bin/sh": ("/lib/ld-linux-armhf.so.3", "0")}, host) + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}" - ''') - expected_stdout = info_box + ' FTL Checks...' + """ + ) + expected_stdout = info_box + " FTL Checks..." assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + (' Detected ARMv6 processor ' - '(with hard-float support)') + expected_stdout = tick_box + ( + " Detected ARMv6 processor " "(with hard-float support)" + ) assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Downloading and Installing FTL' + expected_stdout = tick_box + " Downloading and Installing FTL" assert expected_stdout in detectPlatform.stdout def test_FTL_detect_armv7l_no_errors(host): - ''' + """ confirms only armv7l package is downloaded for FTL engine - ''' + """ # mock uname to return armv7l platform - mock_command('uname', {'-m': ('armv7l', '0')}, host) + mock_command("uname", {"-m": ("armv7l", "0")}, host) # mock ldd to respond with ld-linux-armhf shared library # mock `which sh` to return `/bin/sh` - mock_command('which', {'sh': ('/bin/sh', '0')}, host) - mock_command('ldd', {'/bin/sh': ('/lib/ld-linux-armhf.so.3', '0')}, host) - detectPlatform = host.run(''' + mock_command("which", {"sh": ("/bin/sh", "0")}, host) + mock_command("ldd", {"/bin/sh": ("/lib/ld-linux-armhf.so.3", "0")}, host) + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}" - ''') - expected_stdout = info_box + ' FTL Checks...' + """ + ) + expected_stdout = info_box + " FTL Checks..." assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + (' Detected ARMv7 processor ' - '(with hard-float support)') + expected_stdout = tick_box + ( + " Detected ARMv7 processor " "(with hard-float support)" + ) assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Downloading and Installing FTL' + expected_stdout = tick_box + " Downloading and Installing FTL" assert expected_stdout in detectPlatform.stdout def test_FTL_detect_armv8a_no_errors(host): - ''' + """ confirms only armv8a package is downloaded for FTL engine - ''' + """ # mock uname to return armv8a platform - mock_command('uname', {'-m': ('armv8a', '0')}, host) + mock_command("uname", {"-m": ("armv8a", "0")}, host) # mock `which sh` to return `/bin/sh` - mock_command('which', {'sh': ('/bin/sh', '0')}, host) + mock_command("which", {"sh": ("/bin/sh", "0")}, host) # mock ldd to respond with ld-linux-armhf shared library - mock_command('ldd', {'/bin/sh': ('/lib/ld-linux-armhf.so.3', '0')}, host) - detectPlatform = host.run(''' + mock_command("ldd", {"/bin/sh": ("/lib/ld-linux-armhf.so.3", "0")}, host) + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}" - ''') - expected_stdout = info_box + ' FTL Checks...' + """ + ) + expected_stdout = info_box + " FTL Checks..." assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Detected ARMv8 (or newer) processor' + expected_stdout = tick_box + " Detected ARMv8 (or newer) processor" assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Downloading and Installing FTL' + expected_stdout = tick_box + " Downloading and Installing FTL" assert expected_stdout in detectPlatform.stdout def test_FTL_detect_x86_64_no_errors(host): - ''' + """ confirms only x86_64 package is downloaded for FTL engine - ''' + """ # mock `which sh` to return `/bin/sh` - mock_command('which', {'sh': ('/bin/sh', '0')}, host) - detectPlatform = host.run(''' + mock_command("which", {"sh": ("/bin/sh", "0")}, host) + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}" - ''') - expected_stdout = info_box + ' FTL Checks...' + """ + ) + expected_stdout = info_box + " FTL Checks..." assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Detected x86_64 processor' + expected_stdout = tick_box + " Detected x86_64 processor" assert expected_stdout in detectPlatform.stdout - expected_stdout = tick_box + ' Downloading and Installing FTL' + expected_stdout = tick_box + " Downloading and Installing FTL" assert expected_stdout in detectPlatform.stdout def test_FTL_detect_unknown_no_errors(host): - ''' confirms only generic package is downloaded for FTL engine ''' + """confirms only generic package is downloaded for FTL engine""" # mock uname to return generic platform - mock_command('uname', {'-m': ('mips', '0')}, host) + mock_command("uname", {"-m": ("mips", "0")}, host) # mock `which sh` to return `/bin/sh` - mock_command('which', {'sh': ('/bin/sh', '0')}, host) - detectPlatform = host.run(''' + mock_command("which", {"sh": ("/bin/sh", "0")}, host) + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}" - ''') - expected_stdout = 'Not able to detect processor (unknown: mips)' + """ + ) + expected_stdout = "Not able to detect processor (unknown: mips)" assert expected_stdout in detectPlatform.stdout def test_FTL_download_aarch64_no_errors(host): - ''' + """ confirms only aarch64 package is downloaded for FTL engine - ''' + """ # mock dialog answers and ensure installer dependencies - mock_command('dialog', {'*': ('', '0')}, host) - host.run(''' + mock_command("dialog", {"*": ("", "0")}, host) + host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect install_dependent_packages ${INSTALLER_DEPS[@]} - ''') - download_binary = host.run(''' + """ + ) + download_binary = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user FTLinstall "pihole-FTL-aarch64-linux-gnu" - ''') - expected_stdout = tick_box + ' Downloading and Installing FTL' + """ + ) + expected_stdout = tick_box + " Downloading and Installing FTL" assert expected_stdout in download_binary.stdout - assert 'error' not in download_binary.stdout.lower() + assert "error" not in download_binary.stdout.lower() def test_FTL_binary_installed_and_responsive_no_errors(host): - ''' + """ confirms FTL binary is copied and functional in installed location - ''' - installed_binary = host.run(''' + """ + installed_binary = host.run( + """ source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) @@ -884,176 +866,189 @@ def test_FTL_binary_installed_and_responsive_no_errors(host): binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}" - ''') - version_check = host.run(''' + """ + ) + version_check = host.run( + """ VERSION=$(pihole-FTL version) echo ${VERSION:0:1} - ''') - expected_stdout = 'v' + """ + ) + expected_stdout = "v" assert expected_stdout in version_check.stdout def test_IPv6_only_link_local(host): - ''' + """ confirms IPv6 blocking is disabled for Link-local address - ''' + """ # mock ip -6 address to return Link-local address mock_command_2( - 'ip', - { - '-6 address': ( - 'inet6 fe80::d210:52fa:fe00:7ad7/64 scope link', - '0' - ) - }, - host + "ip", + {"-6 address": ("inet6 fe80::d210:52fa:fe00:7ad7/64 scope link", "0")}, + host, ) - detectPlatform = host.run(''' + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh find_IPv6_information - ''') - expected_stdout = ('Unable to find IPv6 ULA/GUA address') + """ + ) + expected_stdout = "Unable to find IPv6 ULA/GUA address" assert expected_stdout in detectPlatform.stdout def test_IPv6_only_ULA(host): - ''' + """ confirms IPv6 blocking is enabled for ULA addresses - ''' + """ # mock ip -6 address to return ULA address mock_command_2( - 'ip', + "ip", { - '-6 address': ( - 'inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global', - '0' + "-6 address": ( + "inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global", + "0", ) }, - host + host, ) - detectPlatform = host.run(''' + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh find_IPv6_information - ''') - expected_stdout = 'Found IPv6 ULA address' + """ + ) + expected_stdout = "Found IPv6 ULA address" assert expected_stdout in detectPlatform.stdout def test_IPv6_only_GUA(host): - ''' + """ confirms IPv6 blocking is enabled for GUA addresses - ''' + """ # mock ip -6 address to return GUA address mock_command_2( - 'ip', + "ip", { - '-6 address': ( - 'inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global', - '0' + "-6 address": ( + "inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global", + "0", ) }, - host + host, ) - detectPlatform = host.run(''' + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh find_IPv6_information - ''') - expected_stdout = 'Found IPv6 GUA address' + """ + ) + expected_stdout = "Found IPv6 GUA address" assert expected_stdout in detectPlatform.stdout def test_IPv6_GUA_ULA_test(host): - ''' + """ confirms IPv6 blocking is enabled for GUA and ULA addresses - ''' + """ # mock ip -6 address to return GUA and ULA addresses mock_command_2( - 'ip', + "ip", { - '-6 address': ( - 'inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global\n' - 'inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global', - '0' + "-6 address": ( + "inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global\n" + "inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global", + "0", ) }, - host + host, ) - detectPlatform = host.run(''' + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh find_IPv6_information - ''') - expected_stdout = 'Found IPv6 ULA address' + """ + ) + expected_stdout = "Found IPv6 ULA address" assert expected_stdout in detectPlatform.stdout def test_IPv6_ULA_GUA_test(host): - ''' + """ confirms IPv6 blocking is enabled for GUA and ULA addresses - ''' + """ # mock ip -6 address to return ULA and GUA addresses mock_command_2( - 'ip', + "ip", { - '-6 address': ( - 'inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global\n' - 'inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global', - '0' + "-6 address": ( + "inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global\n" + "inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global", + "0", ) }, - host + host, ) - detectPlatform = host.run(''' + detectPlatform = host.run( + """ source /opt/pihole/basic-install.sh find_IPv6_information - ''') - expected_stdout = 'Found IPv6 ULA address' + """ + ) + expected_stdout = "Found IPv6 ULA address" assert expected_stdout in detectPlatform.stdout def test_validate_ip(host): - ''' + """ Tests valid_ip for various IP addresses - ''' + """ def test_address(addr, success=True): - output = host.run(''' + output = host.run( + """ source /opt/pihole/basic-install.sh valid_ip "{addr}" - '''.format(addr=addr)) + """.format( + addr=addr + ) + ) assert output.rc == 0 if success else 1 - test_address('192.168.1.1') - test_address('127.0.0.1') - test_address('255.255.255.255') - test_address('255.255.255.256', False) - test_address('255.255.256.255', False) - test_address('255.256.255.255', False) - test_address('256.255.255.255', False) - test_address('1092.168.1.1', False) - test_address('not an IP', False) - test_address('8.8.8.8#', False) - test_address('8.8.8.8#0') - test_address('8.8.8.8#1') - test_address('8.8.8.8#42') - test_address('8.8.8.8#888') - test_address('8.8.8.8#1337') - test_address('8.8.8.8#65535') - test_address('8.8.8.8#65536', False) - test_address('8.8.8.8#-1', False) - test_address('00.0.0.0', False) - test_address('010.0.0.0', False) - test_address('001.0.0.0', False) - test_address('0.0.0.0#00', False) - test_address('0.0.0.0#01', False) - test_address('0.0.0.0#001', False) - test_address('0.0.0.0#0001', False) - test_address('0.0.0.0#00001', False) + test_address("192.168.1.1") + test_address("127.0.0.1") + test_address("255.255.255.255") + test_address("255.255.255.256", False) + test_address("255.255.256.255", False) + test_address("255.256.255.255", False) + test_address("256.255.255.255", False) + test_address("1092.168.1.1", False) + test_address("not an IP", False) + test_address("8.8.8.8#", False) + test_address("8.8.8.8#0") + test_address("8.8.8.8#1") + test_address("8.8.8.8#42") + test_address("8.8.8.8#888") + test_address("8.8.8.8#1337") + test_address("8.8.8.8#65535") + test_address("8.8.8.8#65536", False) + test_address("8.8.8.8#-1", False) + test_address("00.0.0.0", False) + test_address("010.0.0.0", False) + test_address("001.0.0.0", False) + test_address("0.0.0.0#00", False) + test_address("0.0.0.0#01", False) + test_address("0.0.0.0#001", False) + test_address("0.0.0.0#0001", False) + test_address("0.0.0.0#00001", False) def test_os_check_fails(host): - ''' Confirms install fails on unsupported OS ''' - host.run(''' + """Confirms install fails on unsupported OS""" + host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect install_dependent_packages ${OS_CHECK_DEPS[@]} @@ -1062,65 +1057,78 @@ def test_os_check_fails(host): ID=UnsupportedOS VERSION_ID="2" EOT - ''') - detectOS = host.run('''t + """ + ) + detectOS = host.run( + """t source /opt/pihole/basic-install.sh os_check - ''') - expected_stdout = 'Unsupported OS detected: UnsupportedOS' + """ + ) + expected_stdout = "Unsupported OS detected: UnsupportedOS" assert expected_stdout in detectOS.stdout def test_os_check_passes(host): - ''' Confirms OS meets the requirements ''' - host.run(''' + """Confirms OS meets the requirements""" + host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect install_dependent_packages ${OS_CHECK_DEPS[@]} install_dependent_packages ${INSTALLER_DEPS[@]} - ''') - detectOS = host.run(''' + """ + ) + detectOS = host.run( + """ source /opt/pihole/basic-install.sh os_check - ''') - expected_stdout = 'Supported OS detected' + """ + ) + expected_stdout = "Supported OS detected" assert expected_stdout in detectOS.stdout def test_package_manager_has_installer_deps(host): - ''' Confirms OS is able to install the required packages for the installer''' - mock_command('dialog', {'*': ('', '0')}, host) - output = host.run(''' + """Confirms OS is able to install the required packages for the installer""" + mock_command("dialog", {"*": ("", "0")}, host) + output = host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect install_dependent_packages ${INSTALLER_DEPS[@]} - ''') + """ + ) - assert 'No package' not in output.stdout + assert "No package" not in output.stdout assert output.rc == 0 def test_package_manager_has_pihole_deps(host): - ''' Confirms OS is able to install the required packages for Pi-hole ''' - mock_command('dialog', {'*': ('', '0')}, host) - output = host.run(''' + """Confirms OS is able to install the required packages for Pi-hole""" + mock_command("dialog", {"*": ("", "0")}, host) + output = host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect install_dependent_packages ${PIHOLE_DEPS[@]} - ''') + """ + ) - assert 'No package' not in output.stdout + assert "No package" not in output.stdout assert output.rc == 0 def test_package_manager_has_web_deps(host): - ''' Confirms OS is able to install the required packages for web ''' - mock_command('dialog', {'*': ('', '0')}, host) - output = host.run(''' + """Confirms OS is able to install the required packages for web""" + mock_command("dialog", {"*": ("", "0")}, host) + output = host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect install_dependent_packages ${PIHOLE_WEB_DEPS[@]} - ''') + """ + ) - assert 'No package' not in output.stdout + assert "No package" not in output.stdout assert output.rc == 0 diff --git a/test/test_any_utils.py b/test/test_any_utils.py index 5126f263..a2604dc2 100644 --- a/test/test_any_utils.py +++ b/test/test_any_utils.py @@ -1,22 +1,27 @@ def test_key_val_replacement_works(host): - ''' Confirms addOrEditKeyValPair either adds or replaces a key value pair in a given file ''' - host.run(''' + """Confirms addOrEditKeyValPair either adds or replaces a key value pair in a given file""" + host.run( + """ source /opt/pihole/utils.sh addOrEditKeyValPair "./testoutput" "KEY_ONE" "value1" addOrEditKeyValPair "./testoutput" "KEY_TWO" "value2" addOrEditKeyValPair "./testoutput" "KEY_ONE" "value3" addOrEditKeyValPair "./testoutput" "KEY_FOUR" "value4" - ''') - output = host.run(''' + """ + ) + output = host.run( + """ cat ./testoutput - ''') - expected_stdout = 'KEY_ONE=value3\nKEY_TWO=value2\nKEY_FOUR=value4\n' + """ + ) + expected_stdout = "KEY_ONE=value3\nKEY_TWO=value2\nKEY_FOUR=value4\n" assert expected_stdout == output.stdout def test_key_addition_works(host): - ''' Confirms addKey adds a key (no value) to a file without duplicating it ''' - host.run(''' + """Confirms addKey adds a key (no value) to a file without duplicating it""" + host.run( + """ source /opt/pihole/utils.sh addKey "./testoutput" "KEY_ONE" addKey "./testoutput" "KEY_ONE" @@ -24,17 +29,21 @@ def test_key_addition_works(host): addKey "./testoutput" "KEY_TWO" addKey "./testoutput" "KEY_THREE" addKey "./testoutput" "KEY_THREE" - ''') - output = host.run(''' + """ + ) + output = host.run( + """ cat ./testoutput - ''') - expected_stdout = 'KEY_ONE\nKEY_TWO\nKEY_THREE\n' + """ + ) + expected_stdout = "KEY_ONE\nKEY_TWO\nKEY_THREE\n" assert expected_stdout == output.stdout def test_key_removal_works(host): - ''' Confirms removeKey removes a key or key/value pair ''' - host.run(''' + """Confirms removeKey removes a key or key/value pair""" + host.run( + """ source /opt/pihole/utils.sh addOrEditKeyValPair "./testoutput" "KEY_ONE" "value1" addOrEditKeyValPair "./testoutput" "KEY_TWO" "value2" @@ -42,81 +51,100 @@ def test_key_removal_works(host): addKey "./testoutput" "KEY_FOUR" removeKey "./testoutput" "KEY_TWO" removeKey "./testoutput" "KEY_FOUR" - ''') - output = host.run(''' + """ + ) + output = host.run( + """ cat ./testoutput - ''') - expected_stdout = 'KEY_ONE=value1\nKEY_THREE=value3\n' + """ + ) + expected_stdout = "KEY_ONE=value1\nKEY_THREE=value3\n" assert expected_stdout == output.stdout def test_getFTLAPIPortFile_default(host): - ''' Confirms getFTLAPIPortFile returns the default API port file path ''' - output = host.run(''' + """Confirms getFTLAPIPortFile returns the default API port file path""" + output = host.run( + """ source /opt/pihole/utils.sh getFTLAPIPortFile - ''') - expected_stdout = '/run/pihole-FTL.port\n' + """ + ) + expected_stdout = "/run/pihole-FTL.port\n" assert expected_stdout == output.stdout def test_getFTLAPIPort_default(host): - ''' Confirms getFTLAPIPort returns the default API port ''' - output = host.run(''' + """Confirms getFTLAPIPort returns the default API port""" + output = host.run( + """ source /opt/pihole/utils.sh getFTLAPIPort "/run/pihole-FTL.port" - ''') - expected_stdout = '4711\n' + """ + ) + expected_stdout = "4711\n" assert expected_stdout == output.stdout def test_getFTLAPIPortFile_and_getFTLAPIPort_custom(host): - ''' Confirms getFTLAPIPort returns a custom API port in a custom PORTFILE location ''' - host.run(''' + """Confirms getFTLAPIPort returns a custom API port in a custom PORTFILE location""" + host.run( + """ tmpfile=$(mktemp) echo "PORTFILE=${tmpfile}" > /etc/pihole/pihole-FTL.conf echo "1234" > ${tmpfile} - ''') - output = host.run(''' + """ + ) + output = host.run( + """ source /opt/pihole/utils.sh FTL_API_PORT_FILE=$(getFTLAPIPortFile) getFTLAPIPort "${FTL_API_PORT_FILE}" - ''') - expected_stdout = '1234\n' + """ + ) + expected_stdout = "1234\n" assert expected_stdout == output.stdout def test_getFTLPIDFile_default(host): - ''' Confirms getFTLPIDFile returns the default PID file path ''' - output = host.run(''' + """Confirms getFTLPIDFile returns the default PID file path""" + output = host.run( + """ source /opt/pihole/utils.sh getFTLPIDFile - ''') - expected_stdout = '/run/pihole-FTL.pid\n' + """ + ) + expected_stdout = "/run/pihole-FTL.pid\n" assert expected_stdout == output.stdout def test_getFTLPID_default(host): - ''' Confirms getFTLPID returns the default value if FTL is not running ''' - output = host.run(''' + """Confirms getFTLPID returns the default value if FTL is not running""" + output = host.run( + """ source /opt/pihole/utils.sh getFTLPID - ''') - expected_stdout = '-1\n' + """ + ) + expected_stdout = "-1\n" assert expected_stdout == output.stdout def test_getFTLPIDFile_and_getFTLPID_custom(host): - ''' Confirms getFTLPIDFile returns a custom PID file path ''' - host.run(''' + """Confirms getFTLPIDFile returns a custom PID file path""" + host.run( + """ tmpfile=$(mktemp) echo "PIDFILE=${tmpfile}" > /etc/pihole/pihole-FTL.conf echo "1234" > ${tmpfile} - ''') - output = host.run(''' + """ + ) + output = host.run( + """ source /opt/pihole/utils.sh FTL_PID_FILE=$(getFTLPIDFile) getFTLPID "${FTL_PID_FILE}" - ''') - expected_stdout = '1234\n' + """ + ) + expected_stdout = "1234\n" assert expected_stdout == output.stdout diff --git a/test/test_centos_common_support.py b/test/test_centos_common_support.py index 3497267a..871fee29 100644 --- a/test/test_centos_common_support.py +++ b/test/test_centos_common_support.py @@ -8,17 +8,20 @@ from .conftest import ( def test_enable_epel_repository_centos(host): - ''' + """ confirms the EPEL package repository is enabled when installed on CentOS - ''' - package_manager_detect = host.run(''' + """ + package_manager_detect = host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect - ''') - expected_stdout = info_box + (' Enabling EPEL package repository ' - '(https://fedoraproject.org/wiki/EPEL)') + """ + ) + expected_stdout = info_box + ( + " Enabling EPEL package repository " "(https://fedoraproject.org/wiki/EPEL)" + ) assert expected_stdout in package_manager_detect.stdout - expected_stdout = tick_box + ' Installed' + expected_stdout = tick_box + " Installed" assert expected_stdout in package_manager_detect.stdout - epel_package = host.package('epel-release') + epel_package = host.package("epel-release") assert epel_package.is_installed diff --git a/test/test_centos_fedora_common_support.py b/test/test_centos_fedora_common_support.py index df806771..7e0bae4e 100644 --- a/test/test_centos_fedora_common_support.py +++ b/test/test_centos_fedora_common_support.py @@ -6,60 +6,70 @@ from .conftest import ( def mock_selinux_config(state, host): - ''' + """ Creates a mock SELinux config file with expected content - ''' + """ # validate state string - valid_states = ['enforcing', 'permissive', 'disabled'] + valid_states = ["enforcing", "permissive", "disabled"] assert state in valid_states # getenforce returns the running state of SELinux - mock_command('getenforce', {'*': (state.capitalize(), '0')}, host) + mock_command("getenforce", {"*": (state.capitalize(), "0")}, host) # create mock configuration with desired content - host.run(''' + host.run( + """ mkdir /etc/selinux echo "SELINUX={state}" > /etc/selinux/config - '''.format(state=state.lower())) + """.format( + state=state.lower() + ) + ) def test_selinux_enforcing_exit(host): - ''' + """ confirms installer prompts to exit when SELinux is Enforcing by default - ''' + """ mock_selinux_config("enforcing", host) - check_selinux = host.run(''' + check_selinux = host.run( + """ source /opt/pihole/basic-install.sh checkSelinux - ''') - expected_stdout = cross_box + ' Current SELinux: enforcing' + """ + ) + expected_stdout = cross_box + " Current SELinux: enforcing" assert expected_stdout in check_selinux.stdout - expected_stdout = 'SELinux Enforcing detected, exiting installer' + expected_stdout = "SELinux Enforcing detected, exiting installer" assert expected_stdout in check_selinux.stdout assert check_selinux.rc == 1 def test_selinux_permissive(host): - ''' + """ confirms installer continues when SELinux is Permissive - ''' + """ mock_selinux_config("permissive", host) - check_selinux = host.run(''' + check_selinux = host.run( + """ source /opt/pihole/basic-install.sh checkSelinux - ''') - expected_stdout = tick_box + ' Current SELinux: permissive' + """ + ) + expected_stdout = tick_box + " Current SELinux: permissive" assert expected_stdout in check_selinux.stdout assert check_selinux.rc == 0 def test_selinux_disabled(host): - ''' + """ confirms installer continues when SELinux is Disabled - ''' + """ mock_selinux_config("disabled", host) - check_selinux = host.run(''' + check_selinux = host.run( + """ source /opt/pihole/basic-install.sh checkSelinux - ''') - expected_stdout = tick_box + ' Current SELinux: disabled' + """ + ) + expected_stdout = tick_box + " Current SELinux: disabled" assert expected_stdout in check_selinux.stdout assert check_selinux.rc == 0 diff --git a/test/test_fedora_support.py b/test/test_fedora_support.py index 57a6c5c4..e7d31a5d 100644 --- a/test/test_fedora_support.py +++ b/test/test_fedora_support.py @@ -1,13 +1,15 @@ def test_epel_and_remi_not_installed_fedora(host): - ''' + """ confirms installer does not attempt to install EPEL/REMI repositories on Fedora - ''' - package_manager_detect = host.run(''' + """ + package_manager_detect = host.run( + """ source /opt/pihole/basic-install.sh package_manager_detect - ''') - assert package_manager_detect.stdout == '' + """ + ) + assert package_manager_detect.stdout == "" - epel_package = host.package('epel-release') + epel_package = host.package("epel-release") assert not epel_package.is_installed From 17ec88d96f2eaddd4f1836d5e2aa660b70f38ffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 19 Sep 2022 14:48:58 +0200 Subject: [PATCH 09/32] Remove `installed_binary` variable which was leftover from https://github.com/pi-hole/pi-hole/pull/4893 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- test/test_any_automated_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_any_automated_install.py b/test/test_any_automated_install.py index 895db6dc..f3432575 100644 --- a/test/test_any_automated_install.py +++ b/test/test_any_automated_install.py @@ -857,7 +857,7 @@ def test_FTL_binary_installed_and_responsive_no_errors(host): """ confirms FTL binary is copied and functional in installed location """ - installed_binary = host.run( + host.run( """ source /opt/pihole/basic-install.sh create_pihole_user From b6d1bd7335ac1655b22d528b6006cfecf5071b14 Mon Sep 17 00:00:00 2001 From: Adam Warner Date: Mon, 19 Sep 2022 22:01:05 +0100 Subject: [PATCH 10/32] Read docker tag from file in root, not the previously set environment variable Signed-off-by: Adam Warner --- advanced/Scripts/updatecheck.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/advanced/Scripts/updatecheck.sh b/advanced/Scripts/updatecheck.sh index b1e111ae..550a7142 100755 --- a/advanced/Scripts/updatecheck.sh +++ b/advanced/Scripts/updatecheck.sh @@ -37,6 +37,8 @@ rm -f "/etc/pihole/localversions" VERSION_FILE="/etc/pihole/versions" touch "${VERSION_FILE}" chmod 644 "${VERSION_FILE}" +# if /pihole.docker.tag file exists, we will use it's value later in this script +DOCKER_TAG=$(cat file 2>/dev/null) if [[ "$2" == "remote" ]]; then @@ -55,7 +57,7 @@ if [[ "$2" == "remote" ]]; then GITHUB_FTL_VERSION="$(curl -s 'https://api.github.com/repos/pi-hole/FTL/releases/latest' 2> /dev/null | jq --raw-output .tag_name)" addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_FTL_VERSION" "${GITHUB_FTL_VERSION}" - if [[ "${PIHOLE_DOCKER_TAG}" ]]; then + if [[ "${DOCKER_TAG}" ]]; then GITHUB_DOCKER_VERSION="$(curl -s 'https://api.github.com/repos/pi-hole/docker-pi-hole/releases/latest' 2> /dev/null | jq --raw-output .tag_name)" addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_DOCKER_VERSION" "${GITHUB_DOCKER_VERSION}" fi @@ -84,9 +86,8 @@ else FTL_VERSION="$(pihole-FTL version)" addOrEditKeyValPair "${VERSION_FILE}" "FTL_VERSION" "${FTL_VERSION}" - # PIHOLE_DOCKER_TAG is set as env variable only on docker installations - if [[ "${PIHOLE_DOCKER_TAG}" ]]; then - addOrEditKeyValPair "${VERSION_FILE}" "DOCKER_VERSION" "${PIHOLE_DOCKER_TAG}" + if [[ "${DOCKER_TAG}" ]]; then + addOrEditKeyValPair "${VERSION_FILE}" "DOCKER_VERSION" "${DOCKER_TAG}" fi fi From d4ce5b1c2a53fd2dee7299281ef499c054575ec8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 22 Sep 2022 14:49:25 +0200 Subject: [PATCH 11/32] Fix tabs in dialog boxes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- automated install/basic-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index a51f5d9a..337a3042 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -999,10 +999,10 @@ If you want to specify a port other than 53, separate it with a hash.\ # and continue the loop. DNSSettingsCorrect=False else - dialog --no-shadow --keep-tite \ + dialog --no-shadow --no-collapse --keep-tite \ --backtitle "Specify Upstream DNS Provider(s)" \ --title "Upstream DNS Provider(s)" \ - --yesno "Are these settings correct?\\n\\tDNS Server 1:\\t${PIHOLE_DNS_1}\\n\\tDNS Server 2:\\t${PIHOLE_DNS_2}" \ + --yesno "Are these settings correct?\\n"$'\t'"DNS Server 1:"$'\t'"${PIHOLE_DNS_1}\\n"$'\t'"DNS Server 2:"$'\t'"${PIHOLE_DNS_2}" \ "${r}" "${c}" && result=0 || result=$? case ${result} in From bb57a9e6168b52b91e3ac04e59734aa270d81e10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 22 Sep 2022 22:33:11 +0200 Subject: [PATCH 12/32] Handle more than one default gateway in debug script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- advanced/Scripts/piholeDebug.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh index ab16d7ff..074b2d1f 100755 --- a/advanced/Scripts/piholeDebug.sh +++ b/advanced/Scripts/piholeDebug.sh @@ -680,17 +680,18 @@ ping_gateway() { # Check if we are using IPv4 or IPv6 # Find the default gateway using IPv4 or IPv6 local gateway - gateway="$(ip -"${protocol}" route | grep default | grep "${PIHOLE_INTERFACE}" | cut -d ' ' -f 3)" + mapfile -t gateway < <(ip -"${protocol}" route | grep default | grep "${PIHOLE_INTERFACE}" | cut -d ' ' -f 3) - # If the gateway variable has a value (meaning a gateway was found), - if [[ -n "${gateway}" ]]; then - log_write "${INFO} Default IPv${protocol} gateway: ${gateway}" + # If the gateway array is not empty (meaning a gateway was found), + if [[ ${#gateway[@]} -ne 0 ]]; then + log_write "${INFO} Default IPv${protocol} gateway(s):" + for i in "${gateway[@]}"; do log_write " $i"; done # Let the user know we will ping the gateway for a response - log_write " * Pinging ${gateway}..." + log_write " * Pinging first gateway ${gateway[0]}..." # Try to quietly ping the gateway 3 times, with a timeout of 3 seconds, using numeric output only, # on the pihole interface, and tail the last three lines of the output # If pinging the gateway is not successful, - if ! ${cmd} -c 1 -W 2 -n "${gateway}" -I "${PIHOLE_INTERFACE}" >/dev/null; then + if ! ${cmd} -c 1 -W 2 -n "${gateway[0]}" -I "${PIHOLE_INTERFACE}" >/dev/null; then # let the user know log_write "${CROSS} ${COL_RED}Gateway did not respond.${COL_NC} ($FAQ_GATEWAY)\\n" # and return an error code From ba8a50c82927f080ce2dce0d27fab311ad48edae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 24 Sep 2022 10:08:26 +0000 Subject: [PATCH 13/32] Bump actions/stale from 5.2.0 to 6.0.0 Bumps [actions/stale](https://github.com/actions/stale) from 5.2.0 to 6.0.0. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/v5.2.0...v6.0.0) --- updated-dependencies: - dependency-name: actions/stale dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 6b70a153..7b82bdbd 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -13,7 +13,7 @@ jobs: issues: write steps: - - uses: actions/stale@v5.2.0 + - uses: actions/stale@v6.0.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} days-before-stale: 30 From 755ec8bf2f7a500e691dd1ce4281e55f396054fd Mon Sep 17 00:00:00 2001 From: Adam Warner Date: Sat, 24 Sep 2022 16:08:45 +0100 Subject: [PATCH 14/32] $$ != $ Signed-off-by: Adam Warner --- automated install/basic-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index c0abae8b..f3df72e6 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -1270,7 +1270,7 @@ version_check_dnsmasq() { addOrEditKeyValPair "${dnsmasq_pihole_01_target}" "interface" "$PIHOLE_INTERFACE" if [[ "${PIHOLE_DNS_1}" != "" ]]; then # then add in the primary DNS server. - addOrEditKeyValPair "${dnsmasq_pihole_01_target}" "server" "$$PIHOLE_DNS_1" + addOrEditKeyValPair "${dnsmasq_pihole_01_target}" "server" "$PIHOLE_DNS_1" fi # Ditto if DNS2 is not empty if [[ "${PIHOLE_DNS_2}" != "" ]]; then @@ -1278,7 +1278,7 @@ version_check_dnsmasq() { fi # Set the cache size - addOrEditKeyValPair "${dnsmasq_pihole_01_target}" "cache-size" "$$CACHE_SIZE" + addOrEditKeyValPair "${dnsmasq_pihole_01_target}" "cache-size" "$CACHE_SIZE" sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' "${dnsmasq_conf}" From 951b4ed0029f8001f1ee0d4969f99b9f5b7f4b10 Mon Sep 17 00:00:00 2001 From: Peter Russell Date: Sat, 24 Sep 2022 17:14:44 +0200 Subject: [PATCH 15/32] Remove cronjob that checks local versions every 10 minutes - only check when required (#4939) * eliminate updatechecker local from pihole cron job Signed-off-by: jpgpi250 * resolving stickler-ci items Signed-off-by: jpgpi250 * undo changes to updatecheck.sh (request from PromoFaux) Signed-off-by: jpgpi250 * applied recommendation from PromoFaux Signed-off-by: jpgpi250 * Indent the code inside the function Signed-off-by: jpgpi250 * removed unnecessary updatecheck for core Signed-off-by: jpgpi250 * eliminate updatechecker local from pihole cron job Co-authored-by: jpgpi250 Signed-off-by: Adam Warner Signed-off-by: jpgpi250 Signed-off-by: Adam Warner Co-authored-by: Adam Warner --- advanced/Scripts/piholeCheckout.sh | 9 +++++++++ advanced/Templates/pihole.cron | 3 --- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh index 7c4a1f77..8c4c6db3 100755 --- a/advanced/Scripts/piholeCheckout.sh +++ b/advanced/Scripts/piholeCheckout.sh @@ -42,6 +42,11 @@ warning1() { esac } +updateCheckFunc() { + /opt/pihole/updatecheck.sh + /opt/pihole/updatecheck.sh x remote +} + checkout() { local corebranches local webbranches @@ -164,6 +169,8 @@ checkout() { exit 1 fi checkout_pull_branch "${webInterfaceDir}" "${2}" + # Force an update of the updatechecker + updateCheckFunc elif [[ "${1}" == "ftl" ]] ; then local path local oldbranch @@ -178,6 +185,8 @@ checkout() { FTLinstall "${binary}" restart_service pihole-FTL enable_service pihole-FTL + # Force an update of the updatechecker + updateCheckFunc else echo " ${CROSS} Requested branch \"${2}\" is not available" ftlbranches=( $(git ls-remote https://github.com/pi-hole/ftl | grep 'heads' | sed 's/refs\/heads\///;s/ //g' | awk '{print $2}') ) diff --git a/advanced/Templates/pihole.cron b/advanced/Templates/pihole.cron index 46640fbb..336a66fe 100644 --- a/advanced/Templates/pihole.cron +++ b/advanced/Templates/pihole.cron @@ -28,9 +28,6 @@ @reboot root /usr/sbin/logrotate --state /var/lib/logrotate/pihole /etc/pihole/logrotate -# Pi-hole: Grab local version and branch every 10 minutes -*/10 * * * * root PATH="$PATH:/usr/sbin:/usr/local/bin/" pihole updatechecker local - # Pi-hole: Grab remote version every 24 hours 59 17 * * * root PATH="$PATH:/usr/sbin:/usr/local/bin/" pihole updatechecker remote @reboot root PATH="$PATH:/usr/sbin:/usr/local/bin/" pihole updatechecker remote reboot From 9debd221796b5b130994b2d9a2775fa814df40be Mon Sep 17 00:00:00 2001 From: Adam Warner Date: Sun, 25 Sep 2022 15:51:09 +0100 Subject: [PATCH 16/32] If, after reading /pihole.docker.tag into DOCKER_TAG, it does not match an expected pattern, unset it - this should prevent arbitary code from being run Signed-off-by: Adam Warner --- advanced/Scripts/updatecheck.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/advanced/Scripts/updatecheck.sh b/advanced/Scripts/updatecheck.sh index 550a7142..a9d7523e 100755 --- a/advanced/Scripts/updatecheck.sh +++ b/advanced/Scripts/updatecheck.sh @@ -37,8 +37,14 @@ rm -f "/etc/pihole/localversions" VERSION_FILE="/etc/pihole/versions" touch "${VERSION_FILE}" chmod 644 "${VERSION_FILE}" + # if /pihole.docker.tag file exists, we will use it's value later in this script -DOCKER_TAG=$(cat file 2>/dev/null) +DOCKER_TAG=$(cat /pihole.docker.tag 2>/dev/null) +regex='^([0-9]+\.){1,2}(\*|[0-9]+)(-.*)?$|(^nightly$)|(^dev.*$)' +if [[ ! "${DOCKER_TAG}" =~ $regex ]]; then + # DOCKER_TAG does not match the pattern (see https://regex101.com/r/RsENuz/1), so unset it. + unset DOCKER_TAG +fi if [[ "$2" == "remote" ]]; then From bf5fffaca776ee35d4d0c6ee4197b4faa81a7f9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Sun, 25 Sep 2022 18:03:44 +0200 Subject: [PATCH 17/32] Better wording and test with color MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- .github/workflows/test.yml | 76 +++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 42 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c0783538..543ccb0a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,33 +12,28 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - - name: Checkout repository - uses: actions/checkout@v3.0.2 - - - name: Check scripts in repository are executable - run: | - IFS=$'\n'; - for f in $(find . -name '*.sh'); do if [[ ! -x $f ]]; then echo "$f is not executable" && FAIL=1; fi ;done - unset IFS; - # If FAIL is 1 then we fail. - [[ $FAIL == 1 ]] && exit 1 || echo "Scripts are executable!" - - - name: Spell-Checking - uses: codespell-project/actions-codespell@master - with: - ignore_words_file: .codespellignore - - - name: Get editorconfig-checker - uses: editorconfig-checker/action-editorconfig-checker@main # tag v1.0.0 is really out of date - - - name: Run editorconfig-checker - run: editorconfig-checker - - - name: Run black python code formatter - uses: psf/black@stable - with: - src: "./test" + - name: Checkout repository + uses: actions/checkout@v3.0.2 + - name: Check scripts in repository are executable + run: | + IFS=$'\n'; + for f in $(find . -name '*.sh'); do if [[ ! -x $f ]]; then echo "$f is not executable" && FAIL=1; fi ;done + unset IFS; + # If FAIL is 1 then we fail. + [[ $FAIL == 1 ]] && exit 1 || echo "Scripts are executable!" + - name: Spell-Checking + uses: codespell-project/actions-codespell@master + with: + ignore_words_file: .codespellignore + - name: Get editorconfig-checker + uses: editorconfig-checker/action-editorconfig-checker@main # tag v1.0.0 is really out of date + - name: Run editorconfig-checker + run: editorconfig-checker + - name: Check python code formatting with black + uses: psf/black@stable + with: + src: "./test" + options: "--check --diff --color" distro-test: if: github.event.pull_request.draft == false @@ -47,21 +42,18 @@ jobs: strategy: fail-fast: false matrix: - distro: [debian_10, debian_11, ubuntu_20, ubuntu_22, centos_8, fedora_34] + distro: + [debian_10, debian_11, ubuntu_20, ubuntu_22, centos_8, fedora_34] env: DISTRO: ${{matrix.distro}} steps: - - - name: Checkout repository - uses: actions/checkout@v3.0.2 - - - name: Set up Python 3.10 - uses: actions/setup-python@v4.2.0 - with: - python-version: '3.10' - - - name: Install dependencies - run: pip install -r test/requirements.txt - - - name: Test with tox - run: tox -c test/tox.${DISTRO}.ini + - name: Checkout repository + uses: actions/checkout@v3.0.2 + - name: Set up Python 3.10 + uses: actions/setup-python@v4.2.0 + with: + python-version: "3.10" + - name: Install dependencies + run: pip install -r test/requirements.txt + - name: Test with tox + run: tox -c test/tox.${DISTRO}.ini From 22ebf2148762178351541fd22f3af99755fba291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Sun, 25 Sep 2022 17:49:24 +0200 Subject: [PATCH 18/32] Use POSIX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- advanced/Scripts/piholeDebug.sh | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh index 074b2d1f..91e16850 100755 --- a/advanced/Scripts/piholeDebug.sh +++ b/advanced/Scripts/piholeDebug.sh @@ -678,20 +678,24 @@ ping_gateway() { local protocol="${1}" ping_ipv4_or_ipv6 "${protocol}" # Check if we are using IPv4 or IPv6 - # Find the default gateway using IPv4 or IPv6 + # Find the default gateways using IPv4 or IPv6 local gateway - mapfile -t gateway < <(ip -"${protocol}" route | grep default | grep "${PIHOLE_INTERFACE}" | cut -d ' ' -f 3) - # If the gateway array is not empty (meaning a gateway was found), - if [[ ${#gateway[@]} -ne 0 ]]; then - log_write "${INFO} Default IPv${protocol} gateway(s):" - for i in "${gateway[@]}"; do log_write " $i"; done + log_write "${INFO} Default IPv${protocol} gateway(s):" + + while IFS= read -r gateway; do + log_write " ${gateway}" + done < <(ip -"${protocol}" route | grep default | grep "${PIHOLE_INTERFACE}" | cut -d ' ' -f 3) + + gateway=$(ip -"${protocol}" route | grep default | grep "${PIHOLE_INTERFACE}" | cut -d ' ' -f 3 | head -n 1) + # If there was at least one gateway + if [ -n "${gateway}" ]; then # Let the user know we will ping the gateway for a response - log_write " * Pinging first gateway ${gateway[0]}..." + log_write " * Pinging first gateway ${gateway}..." # Try to quietly ping the gateway 3 times, with a timeout of 3 seconds, using numeric output only, # on the pihole interface, and tail the last three lines of the output # If pinging the gateway is not successful, - if ! ${cmd} -c 1 -W 2 -n "${gateway[0]}" -I "${PIHOLE_INTERFACE}" >/dev/null; then + if ! ${cmd} -c 1 -W 2 -n "${gateway}" -I "${PIHOLE_INTERFACE}" >/dev/null; then # let the user know log_write "${CROSS} ${COL_RED}Gateway did not respond.${COL_NC} ($FAQ_GATEWAY)\\n" # and return an error code From e1a2591c4d76c8f6817cd2924757dfe61895bbe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 26 Sep 2022 10:40:39 +0200 Subject: [PATCH 19/32] Format test.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- .github/workflows/test.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 543ccb0a..442f1c0d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,6 +14,7 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3.0.2 + - name: Check scripts in repository are executable run: | IFS=$'\n'; @@ -21,14 +22,18 @@ jobs: unset IFS; # If FAIL is 1 then we fail. [[ $FAIL == 1 ]] && exit 1 || echo "Scripts are executable!" + - name: Spell-Checking uses: codespell-project/actions-codespell@master with: ignore_words_file: .codespellignore + - name: Get editorconfig-checker uses: editorconfig-checker/action-editorconfig-checker@main # tag v1.0.0 is really out of date + - name: Run editorconfig-checker run: editorconfig-checker + - name: Check python code formatting with black uses: psf/black@stable with: @@ -49,11 +54,14 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3.0.2 + - name: Set up Python 3.10 uses: actions/setup-python@v4.2.0 with: python-version: "3.10" + - name: Install dependencies run: pip install -r test/requirements.txt + - name: Test with tox run: tox -c test/tox.${DISTRO}.ini From 3d01e4d0cfffbfe61c03d4591ac9020917e9cada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 21 Sep 2022 09:24:44 +0200 Subject: [PATCH 20/32] No detour - use pihole-FTL.conf to get the API port number MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- advanced/Scripts/utils.sh | 47 +++++++++------------------ advanced/Templates/pihole-FTL.service | 6 ++-- pihole | 5 ++- test/test_any_utils.py | 34 ++++++++++--------- 4 files changed, 38 insertions(+), 54 deletions(-) diff --git a/advanced/Scripts/utils.sh b/advanced/Scripts/utils.sh index a9e05692..511dfc13 100755 --- a/advanced/Scripts/utils.sh +++ b/advanced/Scripts/utils.sh @@ -32,8 +32,8 @@ addOrEditKeyValPair() { local value="${3}" if grep -q "^${key}=" "${file}"; then - # Key already exists in file, modify the value - sed -i "/^${key}=/c\\${key}=${value}" "${file}" + # Key already exists in file, modify the value + sed -i "/^${key}=/c\\${key}=${value}" "${file}" else # Key does not already exist, add it and it's value echo "${key}=${value}" >> "${file}" @@ -52,8 +52,8 @@ addKey(){ local key="${2}" if ! grep -q "^${key}" "${file}"; then - # Key does not exist, add it. - echo "${key}" >> "${file}" + # Key does not exist, add it. + echo "${key}" >> "${file}" fi } @@ -70,47 +70,32 @@ removeKey() { sed -i "/^${key}/d" "${file}" } -####################### -# returns path of FTL's port file -####################### -getFTLAPIPortFile() { - local FTLCONFFILE="/etc/pihole/pihole-FTL.conf" - local DEFAULT_PORT_FILE="/run/pihole-FTL.port" - local FTL_APIPORT_FILE - - if [ -s "${FTLCONFFILE}" ]; then - # if PORTFILE is not set in pihole-FTL.conf, use the default path - FTL_APIPORT_FILE="$({ grep '^PORTFILE=' "${FTLCONFFILE}" || echo "${DEFAULT_PORT_FILE}"; } | cut -d'=' -f2-)" - else - # if there is no pihole-FTL.conf, use the default path - FTL_APIPORT_FILE="${DEFAULT_PORT_FILE}" - fi - - echo "${FTL_APIPORT_FILE}" -} - ####################### -# returns FTL's current telnet API port based on the content of the pihole-FTL.port file +# returns FTL's current telnet API port based on the setting in /etc/pihole-FTL.conf # # Takes one argument: path to pihole-FTL.port # Example getFTLAPIPort "/run/pihole-FTL.port" ####################### getFTLAPIPort(){ - local PORTFILE="${1}" + local FTLCONFFILE="/etc/pihole/pihole-FTL.conf" local DEFAULT_FTL_PORT=4711 local ftl_api_port - if [ -s "$PORTFILE" ]; then - # -s: FILE exists and has a size greater than zero - ftl_api_port=$(cat "${PORTFILE}") + if [ -s "$FTLCONFFILE" ]; then + # if FTLPORT is not set in pihole-FTL.conf, use the default port + ftl_api_port="$({ grep '^FTLPORT=' "${FTLCONFFILE}" || echo "${DEFAULT_FTL_PORT}"; } | cut -d'=' -f2-)" # Exploit prevention: unset the variable if there is malicious content # Verify that the value read from the file is numeric - expr "$ftl_api_port" : "[^[:digit:]]" > /dev/null && unset ftl_api_port + expr "${ftl_api_port}" : "[^[:digit:]]" > /dev/null && unset ftl_api_port + else + # if there is no pihole-FTL.conf, use the default port + ftl_api_port="${DEFAULT_FTL_PORT}" fi - # echo the port found in the portfile or default to the default port - echo "${ftl_api_port:=$DEFAULT_FTL_PORT}" + # If the ftl_api_port contained malicious stuff, substitute with -1 + ftl_api_port=${ftl_api_port:=-1} + echo "${ftl_api_port}" } ####################### diff --git a/advanced/Templates/pihole-FTL.service b/advanced/Templates/pihole-FTL.service index 46e5c1f2..bc1b1d20 100644 --- a/advanced/Templates/pihole-FTL.service +++ b/advanced/Templates/pihole-FTL.service @@ -9,7 +9,7 @@ # Description: Enable service provided by pihole-FTL daemon ### END INIT INFO -#source utils.sh for getFTLPIDFile(), getFTLPID (), getFTLAPIPortFile() +#source utils.sh for getFTLPIDFile(), getFTLPID () PI_HOLE_SCRIPT_DIR="/opt/pihole" utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh" . "${utilsfile}" @@ -31,7 +31,6 @@ start() { # Touch files to ensure they exist (create if non-existing, preserve if existing) mkdir -pm 0755 /run/pihole /var/log/pihole [ ! -f "${FTL_PID_FILE}" ] && install -D -m 644 -o pihole -g pihole /dev/null "${FTL_PID_FILE}" - [ ! -f "${FTL_PORT_FILE}" ] && install -D -m 644 -o pihole -g pihole /dev/null "${FTL_PORT_FILE}" [ ! -f /var/log/pihole/FTL.log ] && install -m 644 -o pihole -g pihole /dev/null /var/log/pihole/FTL.log [ ! -f /var/log/pihole/pihole.log ] && install -m 640 -o pihole -g pihole /dev/null /var/log/pihole/pihole.log [ ! -f /etc/pihole/dhcp.leases ] && install -m 644 -o pihole -g pihole /dev/null /etc/pihole/dhcp.leases @@ -91,7 +90,7 @@ stop() { echo "Not running" fi # Cleanup - rm -f /run/pihole/FTL.sock /dev/shm/FTL-* "${FTL_PID_FILE}" "${FTL_PORT_FILE}" + rm -f /run/pihole/FTL.sock /dev/shm/FTL-* "${FTL_PID_FILE}" echo } @@ -111,7 +110,6 @@ status() { # Get file paths FTL_PID_FILE="$(getFTLPIDFile)" -FTL_PORT_FILE="$(getFTLAPIPortFile)" # Get FTL's current PID FTL_PID="$(getFTLPID ${FTL_PID_FILE})" diff --git a/pihole b/pihole index 1047d152..aad83451 100755 --- a/pihole +++ b/pihole @@ -303,14 +303,13 @@ analyze_ports() { statusFunc() { # Determine if there is pihole-FTL service is listening - local pid port ftl_api_port ftl_pid_file ftl_apiport_file + local pid port ftl_api_port ftl_pid_file ftl_pid_file="$(getFTLPIDFile)" pid="$(getFTLPID ${ftl_pid_file})" - ftl_apiport_file="${getFTLAPIPortFile}" - ftl_api_port="$(getFTLAPIPort ${ftl_apiport_file})" + ftl_api_port="$(getFTLAPIPort)" if [[ "$pid" -eq "-1" ]]; then case "${1}" in "web") echo "-1";; diff --git a/test/test_any_utils.py b/test/test_any_utils.py index a2604dc2..6a1146ee 100644 --- a/test/test_any_utils.py +++ b/test/test_any_utils.py @@ -62,47 +62,49 @@ def test_key_removal_works(host): assert expected_stdout == output.stdout -def test_getFTLAPIPortFile_default(host): - """Confirms getFTLAPIPortFile returns the default API port file path""" +def test_getFTLAPIPort_default(host): + """Confirms getFTLAPIPort returns the default API port""" output = host.run( """ source /opt/pihole/utils.sh - getFTLAPIPortFile + getFTLAPIPort """ ) - expected_stdout = "/run/pihole-FTL.port\n" + expected_stdout = "4711\n" assert expected_stdout == output.stdout -def test_getFTLAPIPort_default(host): - """Confirms getFTLAPIPort returns the default API port""" +def test_getFTLAPIPort_custom(host): + """Confirms getFTLAPIPort returns a custom API port""" + host.run( + """ + echo "FTLPORT=1234" > /etc/pihole/pihole-FTL.conf + """ + ) output = host.run( """ source /opt/pihole/utils.sh - getFTLAPIPort "/run/pihole-FTL.port" + getFTLAPIPort """ ) - expected_stdout = "4711\n" + expected_stdout = "1234\n" assert expected_stdout == output.stdout -def test_getFTLAPIPortFile_and_getFTLAPIPort_custom(host): - """Confirms getFTLAPIPort returns a custom API port in a custom PORTFILE location""" +def test_getFTLAPIPort_malicious(host): + """Confirms getFTLAPIPort returns -1 if the setting in pihole-FTL.conf contains non-digits""" host.run( """ - tmpfile=$(mktemp) - echo "PORTFILE=${tmpfile}" > /etc/pihole/pihole-FTL.conf - echo "1234" > ${tmpfile} + echo "FTLPORT=*$ssdfsd" > /etc/pihole/pihole-FTL.conf """ ) output = host.run( """ source /opt/pihole/utils.sh - FTL_API_PORT_FILE=$(getFTLAPIPortFile) - getFTLAPIPort "${FTL_API_PORT_FILE}" + getFTLAPIPort """ ) - expected_stdout = "1234\n" + expected_stdout = "-1\n" assert expected_stdout == output.stdout From 25ba68104b1b9c6300d45920514a06c1cccdb516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Sun, 25 Sep 2022 18:16:20 +0200 Subject: [PATCH 21/32] Remove last traces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- advanced/Scripts/chronometer.sh | 4 +++- advanced/Scripts/piholeDebug.sh | 2 -- advanced/Scripts/utils.sh | 5 +---- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh index af007994..d69a56d3 100755 --- a/advanced/Scripts/chronometer.sh +++ b/advanced/Scripts/chronometer.sh @@ -14,7 +14,9 @@ LC_NUMERIC=C # Retrieve stats from FTL engine pihole-FTL() { local ftl_port LINE - ftl_port=$(cat /run/pihole-FTL.port 2> /dev/null) + # shellcheck disable=SC1091 + . /opt/pihole/utils.sh + ftl_port=$(getFTLAPIPort) if [[ -n "$ftl_port" ]]; then # Open connection to FTL exec 3<>"/dev/tcp/127.0.0.1/$ftl_port" diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh index 91e16850..dbf56709 100755 --- a/advanced/Scripts/piholeDebug.sh +++ b/advanced/Scripts/piholeDebug.sh @@ -126,7 +126,6 @@ PIHOLE_COMMAND="${BIN_DIRECTORY}/pihole" PIHOLE_COLTABLE_FILE="${BIN_DIRECTORY}/COL_TABLE" FTL_PID="${RUN_DIRECTORY}/pihole-FTL.pid" -FTL_PORT="${RUN_DIRECTORY}/pihole-FTL.port" PIHOLE_LOG="${LOG_DIRECTORY}/pihole.log" PIHOLE_LOG_GZIPS="${LOG_DIRECTORY}/pihole.log.[0-9].*" @@ -155,7 +154,6 @@ REQUIRED_FILES=("${PIHOLE_CRON_FILE}" "${PIHOLE_COMMAND}" "${PIHOLE_COLTABLE_FILE}" "${FTL_PID}" -"${FTL_PORT}" "${PIHOLE_LOG}" "${PIHOLE_LOG_GZIPS}" "${PIHOLE_DEBUG_LOG}" diff --git a/advanced/Scripts/utils.sh b/advanced/Scripts/utils.sh index 511dfc13..ef7ad219 100755 --- a/advanced/Scripts/utils.sh +++ b/advanced/Scripts/utils.sh @@ -73,10 +73,7 @@ removeKey() { ####################### # returns FTL's current telnet API port based on the setting in /etc/pihole-FTL.conf -# -# Takes one argument: path to pihole-FTL.port -# Example getFTLAPIPort "/run/pihole-FTL.port" -####################### +######################## getFTLAPIPort(){ local FTLCONFFILE="/etc/pihole/pihole-FTL.conf" local DEFAULT_FTL_PORT=4711 From 276c480f5001465d994dacf6e30d1e1c2d0a3b0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 26 Sep 2022 23:40:09 +0200 Subject: [PATCH 22/32] Return default port if non-numeric characters are set in pihole-FTL.conf for FTLPORT. FTL does the same in such case and provide the API on 4711 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- advanced/Scripts/utils.sh | 8 +++----- test/test_any_utils.py | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/advanced/Scripts/utils.sh b/advanced/Scripts/utils.sh index ef7ad219..1174fa62 100755 --- a/advanced/Scripts/utils.sh +++ b/advanced/Scripts/utils.sh @@ -82,16 +82,14 @@ getFTLAPIPort(){ if [ -s "$FTLCONFFILE" ]; then # if FTLPORT is not set in pihole-FTL.conf, use the default port ftl_api_port="$({ grep '^FTLPORT=' "${FTLCONFFILE}" || echo "${DEFAULT_FTL_PORT}"; } | cut -d'=' -f2-)" - # Exploit prevention: unset the variable if there is malicious content - # Verify that the value read from the file is numeric - expr "${ftl_api_port}" : "[^[:digit:]]" > /dev/null && unset ftl_api_port + # Exploit prevention: set the port to the default port if there is malicious (non-numeric) + # content set in pihole-FTL.conf + expr "${ftl_api_port}" : "[^[:digit:]]" > /dev/null && ftl_api_port="${DEFAULT_FTL_PORT}" else # if there is no pihole-FTL.conf, use the default port ftl_api_port="${DEFAULT_FTL_PORT}" fi - # If the ftl_api_port contained malicious stuff, substitute with -1 - ftl_api_port=${ftl_api_port:=-1} echo "${ftl_api_port}" } diff --git a/test/test_any_utils.py b/test/test_any_utils.py index 6a1146ee..5b4075d9 100644 --- a/test/test_any_utils.py +++ b/test/test_any_utils.py @@ -92,7 +92,7 @@ def test_getFTLAPIPort_custom(host): def test_getFTLAPIPort_malicious(host): - """Confirms getFTLAPIPort returns -1 if the setting in pihole-FTL.conf contains non-digits""" + """Confirms getFTLAPIPort returns 4711 if the setting in pihole-FTL.conf contains non-digits""" host.run( """ echo "FTLPORT=*$ssdfsd" > /etc/pihole/pihole-FTL.conf @@ -104,7 +104,7 @@ def test_getFTLAPIPort_malicious(host): getFTLAPIPort """ ) - expected_stdout = "-1\n" + expected_stdout = "4711\n" assert expected_stdout == output.stdout From a705fbca7323ab7a134600aa662b187e23b25ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 29 Sep 2022 19:13:23 +0200 Subject: [PATCH 23/32] Add Fedora 35 and 36 to the test suite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- .github/workflows/test.yml | 11 ++++++++++- test/_fedora_35.Dockerfile | 18 ++++++++++++++++++ test/_fedora_36.Dockerfile | 18 ++++++++++++++++++ test/tox.fedora_35.ini | 8 ++++++++ test/tox.fedora_36.ini | 8 ++++++++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 test/_fedora_35.Dockerfile create mode 100644 test/_fedora_36.Dockerfile create mode 100644 test/tox.fedora_35.ini create mode 100644 test/tox.fedora_36.ini diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 442f1c0d..1f83c1b8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -48,7 +48,16 @@ jobs: fail-fast: false matrix: distro: - [debian_10, debian_11, ubuntu_20, ubuntu_22, centos_8, fedora_34] + [ + debian_10, + debian_11, + ubuntu_20, + ubuntu_22, + centos_8, + fedora_34, + fedora_35, + fedora_36, + ] env: DISTRO: ${{matrix.distro}} steps: diff --git a/test/_fedora_35.Dockerfile b/test/_fedora_35.Dockerfile new file mode 100644 index 00000000..eb3623d5 --- /dev/null +++ b/test/_fedora_35.Dockerfile @@ -0,0 +1,18 @@ +FROM fedora:35 +RUN dnf install -y git + +ENV GITDIR /etc/.pihole +ENV SCRIPTDIR /opt/pihole + +RUN mkdir -p $GITDIR $SCRIPTDIR /etc/pihole +ADD . $GITDIR +RUN cp $GITDIR/advanced/Scripts/*.sh $GITDIR/gravity.sh $GITDIR/pihole $GITDIR/automated\ install/*.sh $SCRIPTDIR/ +ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR + +RUN true && \ + chmod +x $SCRIPTDIR/* + +ENV SKIP_INSTALL true +ENV OS_CHECK_DOMAIN_NAME dev-supportedos.pi-hole.net + +#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \ diff --git a/test/_fedora_36.Dockerfile b/test/_fedora_36.Dockerfile new file mode 100644 index 00000000..e0504538 --- /dev/null +++ b/test/_fedora_36.Dockerfile @@ -0,0 +1,18 @@ +FROM fedora:36 +RUN dnf install -y git + +ENV GITDIR /etc/.pihole +ENV SCRIPTDIR /opt/pihole + +RUN mkdir -p $GITDIR $SCRIPTDIR /etc/pihole +ADD . $GITDIR +RUN cp $GITDIR/advanced/Scripts/*.sh $GITDIR/gravity.sh $GITDIR/pihole $GITDIR/automated\ install/*.sh $SCRIPTDIR/ +ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR + +RUN true && \ + chmod +x $SCRIPTDIR/* + +ENV SKIP_INSTALL true +ENV OS_CHECK_DOMAIN_NAME dev-supportedos.pi-hole.net + +#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \ diff --git a/test/tox.fedora_35.ini b/test/tox.fedora_35.ini new file mode 100644 index 00000000..5e90426d --- /dev/null +++ b/test/tox.fedora_35.ini @@ -0,0 +1,8 @@ +[tox] +envlist = py3 + +[testenv] +allowlist_externals = docker +deps = -rrequirements.txt +commands = docker build -f _fedora_35.Dockerfile -t pytest_pihole:test_container ../ + pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py ./test_centos_fedora_common_support.py ./test_fedora_support.py diff --git a/test/tox.fedora_36.ini b/test/tox.fedora_36.ini new file mode 100644 index 00000000..1d250f82 --- /dev/null +++ b/test/tox.fedora_36.ini @@ -0,0 +1,8 @@ +[tox] +envlist = py3 + +[testenv] +allowlist_externals = docker +deps = -rrequirements.txt +commands = docker build -f _fedora_36.Dockerfile -t pytest_pihole:test_container ../ + pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py ./test_centos_fedora_common_support.py ./test_fedora_support.py From d48c55713450739073cd19d738031ccd03bb7175 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Fri, 30 Sep 2022 17:13:08 -0300 Subject: [PATCH 24/32] Fix Deepsource warning message for index.php file Signed-off-by: RD WebDesign --- advanced/index.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/advanced/index.php b/advanced/index.php index 9a2b19e6..f3f2ce1c 100644 --- a/advanced/index.php +++ b/advanced/index.php @@ -29,7 +29,8 @@ if (!empty($_SERVER["FQDN"])) { if ($serverName === "pi.hole" || (!empty($_SERVER["VIRTUAL_HOST"]) && $serverName === $_SERVER["VIRTUAL_HOST"])) { // Redirect to Web Interface - exit(header("Location: /admin")); + header("Location: /admin"); + exit(); } elseif (filter_var($serverName, FILTER_VALIDATE_IP) || in_array($serverName, $authorizedHosts)) { // When directly browsing via IP or authorized hostname // Render splash/landing page based off presence of $landPage file @@ -75,6 +76,6 @@ EOT; exit($splashPage); } -exit(header("HTTP/1.1 404 Not Found")); - +header("HTTP/1.1 404 Not Found"); +exit(); ?> From 6057b134ae34c44131cd4648b957819d85bb2da0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Sat, 1 Oct 2022 10:03:13 +0200 Subject: [PATCH 25/32] Add initscripts to Fedora 35 and 36 dockerfile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- test/_fedora_35.Dockerfile | 2 +- test/_fedora_36.Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/_fedora_35.Dockerfile b/test/_fedora_35.Dockerfile index eb3623d5..83c17650 100644 --- a/test/_fedora_35.Dockerfile +++ b/test/_fedora_35.Dockerfile @@ -1,5 +1,5 @@ FROM fedora:35 -RUN dnf install -y git +RUN dnf install -y git initscripts ENV GITDIR /etc/.pihole ENV SCRIPTDIR /opt/pihole diff --git a/test/_fedora_36.Dockerfile b/test/_fedora_36.Dockerfile index e0504538..847767e7 100644 --- a/test/_fedora_36.Dockerfile +++ b/test/_fedora_36.Dockerfile @@ -1,5 +1,5 @@ FROM fedora:36 -RUN dnf install -y git +RUN dnf install -y git initscripts ENV GITDIR /etc/.pihole ENV SCRIPTDIR /opt/pihole From 3731b65bd59ce73115c8f55c548b01f3c0495af3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Sat, 1 Oct 2022 10:04:26 +0200 Subject: [PATCH 26/32] Remoce Fedora 34 from tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- .github/workflows/test.yml | 1 - test/_fedora_34.Dockerfile | 18 ------------------ test/tox.fedora_34.ini | 8 -------- 3 files changed, 27 deletions(-) delete mode 100644 test/_fedora_34.Dockerfile delete mode 100644 test/tox.fedora_34.ini diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1f83c1b8..bb2d68d5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -54,7 +54,6 @@ jobs: ubuntu_20, ubuntu_22, centos_8, - fedora_34, fedora_35, fedora_36, ] diff --git a/test/_fedora_34.Dockerfile b/test/_fedora_34.Dockerfile deleted file mode 100644 index 9c90ce7d..00000000 --- a/test/_fedora_34.Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM fedora:34 -RUN dnf install -y git - -ENV GITDIR /etc/.pihole -ENV SCRIPTDIR /opt/pihole - -RUN mkdir -p $GITDIR $SCRIPTDIR /etc/pihole -ADD . $GITDIR -RUN cp $GITDIR/advanced/Scripts/*.sh $GITDIR/gravity.sh $GITDIR/pihole $GITDIR/automated\ install/*.sh $SCRIPTDIR/ -ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR - -RUN true && \ - chmod +x $SCRIPTDIR/* - -ENV SKIP_INSTALL true -ENV OS_CHECK_DOMAIN_NAME dev-supportedos.pi-hole.net - -#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \ diff --git a/test/tox.fedora_34.ini b/test/tox.fedora_34.ini deleted file mode 100644 index d58cb0d4..00000000 --- a/test/tox.fedora_34.ini +++ /dev/null @@ -1,8 +0,0 @@ -[tox] -envlist = py3 - -[testenv] -allowlist_externals = docker -deps = -rrequirements.txt -commands = docker build -f _fedora_34.Dockerfile -t pytest_pihole:test_container ../ - pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py ./test_centos_fedora_common_support.py ./test_fedora_support.py From 34b66002e9c41caa70025ab12160733d5d4b8b78 Mon Sep 17 00:00:00 2001 From: Adam Warner Date: Sat, 1 Oct 2022 17:11:54 +0100 Subject: [PATCH 27/32] `leasetime` (local) should have an `h` after it to signify 24h lease, else it will be read as two minutes (minimum integer value) Signed-off-by: Adam Warner --- advanced/Scripts/webpage.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh index 3ee48aef..020d5f84 100755 --- a/advanced/Scripts/webpage.sh +++ b/advanced/Scripts/webpage.sh @@ -393,13 +393,13 @@ ProcessDHCPSettings() { if [[ "${DHCP_LEASETIME}" == "0" ]]; then leasetime="infinite" elif [[ "${DHCP_LEASETIME}" == "" ]]; then - leasetime="24" - addOrEditKeyValPair "${setupVars}" "DHCP_LEASETIME" "${leasetime}" + leasetime="24h" + addOrEditKeyValPair "${setupVars}" "DHCP_LEASETIME" "24" elif [[ "${DHCP_LEASETIME}" == "24h" ]]; then #Installation is affected by known bug, introduced in a previous version. #This will automatically clean up setupVars.conf and remove the unnecessary "h" - leasetime="24" - addOrEditKeyValPair "${setupVars}" "DHCP_LEASETIME" "${leasetime}" + leasetime="24h" + addOrEditKeyValPair "${setupVars}" "DHCP_LEASETIME" "24" else leasetime="${DHCP_LEASETIME}h" fi From b7b5ffa8dd9d1c2f8a99271394f9ad4722b66345 Mon Sep 17 00:00:00 2001 From: Adam Warner Date: Sat, 1 Oct 2022 20:05:22 +0100 Subject: [PATCH 28/32] remove old code per review from @yubiuser and @dschaper Signed-off-by: Adam Warner --- advanced/Scripts/webpage.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh index 020d5f84..e02e03f9 100755 --- a/advanced/Scripts/webpage.sh +++ b/advanced/Scripts/webpage.sh @@ -395,11 +395,6 @@ ProcessDHCPSettings() { elif [[ "${DHCP_LEASETIME}" == "" ]]; then leasetime="24h" addOrEditKeyValPair "${setupVars}" "DHCP_LEASETIME" "24" - elif [[ "${DHCP_LEASETIME}" == "24h" ]]; then - #Installation is affected by known bug, introduced in a previous version. - #This will automatically clean up setupVars.conf and remove the unnecessary "h" - leasetime="24h" - addOrEditKeyValPair "${setupVars}" "DHCP_LEASETIME" "24" else leasetime="${DHCP_LEASETIME}h" fi From 4265bcb178906265044a841fd27ce1a1f13ed99f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Sat, 8 Oct 2022 22:08:39 +0200 Subject: [PATCH 29/32] Add initscripts to CentOS8 dockerfile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- test/_centos_8.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/_centos_8.Dockerfile b/test/_centos_8.Dockerfile index 2a894587..a07a67e9 100644 --- a/test/_centos_8.Dockerfile +++ b/test/_centos_8.Dockerfile @@ -1,5 +1,5 @@ FROM quay.io/centos/centos:stream8 -RUN yum install -y git +RUN yum install -y git initscripts ENV GITDIR /etc/.pihole ENV SCRIPTDIR /opt/pihole From cf467db61def94a703cf1b01eae540cdad34b92e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 9 Oct 2022 18:45:54 +0000 Subject: [PATCH 30/32] Bump actions/stale from 6.0.0 to 6.0.1 Bumps [actions/stale](https://github.com/actions/stale) from 6.0.0 to 6.0.1. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/v6.0.0...v6.0.1) --- updated-dependencies: - dependency-name: actions/stale dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 7b82bdbd..a17d5a94 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -13,7 +13,7 @@ jobs: issues: write steps: - - uses: actions/stale@v6.0.0 + - uses: actions/stale@v6.0.1 with: repo-token: ${{ secrets.GITHUB_TOKEN }} days-before-stale: 30 From 223ef72250b258b74eeb27228eb14579632831fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 9 Oct 2022 18:46:02 +0000 Subject: [PATCH 31/32] Bump actions/checkout from 3.0.2 to 3.1.0 Bumps [actions/checkout](https://github.com/actions/checkout) from 3.0.2 to 3.1.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3.0.2...v3.1.0) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/sync-back-to-dev.yml | 2 +- .github/workflows/test.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 2c844337..b0ebb90e 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -25,7 +25,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3.0.2 + uses: actions/checkout@v3.1.0 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/sync-back-to-dev.yml b/.github/workflows/sync-back-to-dev.yml index dd66ebdc..f689ae36 100644 --- a/.github/workflows/sync-back-to-dev.yml +++ b/.github/workflows/sync-back-to-dev.yml @@ -11,7 +11,7 @@ jobs: name: Syncing branches steps: - name: Checkout - uses: actions/checkout@v3.0.2 + uses: actions/checkout@v3.1.0 - name: Opening pull request id: pull uses: tretuna/sync-branches@1.4.0 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bb2d68d5..ff3af994 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3.0.2 + uses: actions/checkout@v3.1.0 - name: Check scripts in repository are executable run: | @@ -61,7 +61,7 @@ jobs: DISTRO: ${{matrix.distro}} steps: - name: Checkout repository - uses: actions/checkout@v3.0.2 + uses: actions/checkout@v3.1.0 - name: Set up Python 3.10 uses: actions/setup-python@v4.2.0 From c5b3b8dd680c9a288fc6ce6e974e2797de9ce9b7 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Sat, 8 Oct 2022 16:29:10 -0300 Subject: [PATCH 32/32] Fix `pihole -r` dialog exit - if an option is selected: Get option (repair/reconfigure); - if exit or ESC: Get exit code (1/255) Signed-off-by: RD WebDesign --- automated install/basic-install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index f3df72e6..d4c1ce77 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -2022,9 +2022,8 @@ update_dialogs() { \\n($strAdd)"\ "${r}" "${c}" 2 \ "${opt1a}" "${opt1b}" \ - "${opt2a}" "${opt2b}" || true) + "${opt2a}" "${opt2b}") || result=$? - result=$? case ${result} in "${DIALOG_CANCEL}" | "${DIALOG_ESC}") printf " %b Cancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"