diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh index 2ccad27c..9240c593 100755 --- a/advanced/Scripts/update.sh +++ b/advanced/Scripts/update.sh @@ -106,7 +106,8 @@ main() { # Install packages used by this installation script (necessary if users have removed e.g. git from their systems) package_manager_detect - install_dependent_packages "${INSTALLER_DEPS[@]}" + build_dependency_package + install_dependent_packages # This is unlikely if ! is_repo "${PI_HOLE_FILES_DIR}" ; then diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 4852929c..4e112f81 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -102,6 +102,18 @@ fi r=20 c=70 +# Content of Pi-hole's meta package control file +PIHOLE_META_PACKAGE_CONTROL_DEBIAN=$( + cat < +Architecture: all +Description: Pi-hole dependency meta package +Depends: grep,dnsutils,binutils,git,iproute2,dialog,ca-certificates,cron,curl,iputils-ping,psmisc,sudo,unzip,libcap2-bin,dns-root-data,libcap2,netcat-openbsd,procps,jq,lshw,bash-completion +EOM +) + ######## Undocumented Flags. Shhh ######## # These are undocumented flags; some of which we can use when repairing an installation # The runUnattended flag is one example of this @@ -362,10 +374,6 @@ test_dpkg_lock() { # Compatibility package_manager_detect() { - # pull common packages for both distributions out into a common variable - OS_CHECK_COMMON_DEPS=(grep) - PIHOLE_COMMON_DEPS=(curl psmisc sudo unzip jq); - INSTALLER_COMMON_DEPS=(git dialog ca-certificates) # First check to see if apt-get is installed. if is_command apt-get; then @@ -375,17 +383,11 @@ package_manager_detect() { # A variable to store the command used to update the package cache UPDATE_PKG_CACHE="${PKG_MANAGER} update" # The command we will use to actually install packages - PKG_INSTALL=("${PKG_MANAGER}" -qq --no-install-recommends install) + PKG_INSTALL="${PKG_MANAGER} -qq --no-install-recommends install" # grep -c will return 1 if there are no matches. This is an acceptable condition, so we OR TRUE to prevent set -e exiting the script. PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true" # Update package cache update_package_cache || exit 1 - # Packages required to perform the os_check and FTL binary detection - OS_CHECK_DEPS=(dnsutils binutils) - # Packages required to run this install script - INSTALLER_DEPS=(iproute2) - # Packages required to run Pi-hole - PIHOLE_DEPS=(cron iputils-ping libcap2-bin dns-root-data libcap2 netcat-openbsd procps lshw bash-completion) # If apt-get is not found, check for rpm. elif is_command rpm; then @@ -397,7 +399,7 @@ package_manager_detect() { fi # These variable names match the ones for apt-get. See above for an explanation of what they are for. - PKG_INSTALL=("${PKG_MANAGER}" install -y) + PKG_INSTALL="${PKG_MANAGER} install -y" # CentOS package manager returns 100 when there are packages to update so we need to || true to prevent the script from exiting. PKG_COUNT="${PKG_MANAGER} check-update | grep -E '(.i686|.x86|.noarch|.arm|.src|.riscv64)' | wc -l || true" OS_CHECK_DEPS=(bind-utils) @@ -413,6 +415,24 @@ package_manager_detect() { fi } +build_dependency_package(){ + # This function will build a package that contains all the dependencies needed for Pi-hole + mkdir -p /tmp/pihole-meta + chmod 0755 /tmp/pihole-meta + + if is_command apt-get; then + # move into the directory + pushd /tmp &>/dev/null || return 1 + mkdir -p /tmp/pihole-meta/DEBIAN + chmod 0755 /tmp/pihole-meta/DEBIAN + touch /tmp/pihole-meta/DEBIAN/control + echo "${PIHOLE_META_PACKAGE_CONTROL_DEBIAN}" > /tmp/pihole-meta/DEBIAN/control + dpkg-deb --build --root-owner-group pihole-meta + # Move back into the directory the user started in + popd &> /dev/null || return 1 + fi +} + # A function for checking if a directory is a git repository is_repo() { # Use a named, local variable instead of the vague $1, which is the first argument passed to this function @@ -1390,61 +1410,20 @@ notify_package_updates_available() { } install_dependent_packages() { + # Install meta dependency package - # Install packages passed in via argument array - # No spinner - conflicts with set -e - declare -a installArray - - # Debian based package install - debconf will download the entire package list - # so we just create an array of packages not currently installed to cut down on the - # amount of download traffic. - # NOTE: We may be able to use this installArray in the future to create a list of package that were - # installed by us, and remove only the installed packages, and not the entire list. if is_command apt-get; then - # For each package, check if it's already installed (and if so, don't add it to the installArray) - for i in "$@"; do - printf " %b Checking for %s..." "${INFO}" "${i}" - if dpkg-query -W -f='${Status}' "${i}" 2>/dev/null | grep "ok installed" &>/dev/null; then - printf "%b %b Checking for %s\\n" "${OVER}" "${TICK}" "${i}" - else - printf "%b %b Checking for %s (will be installed)\\n" "${OVER}" "${INFO}" "${i}" - installArray+=("${i}") - fi - done - # If there's anything to install, install everything in the list. - if [[ "${#installArray[@]}" -gt 0 ]]; then - test_dpkg_lock - # Running apt-get install with minimal output can cause some issues with - # requiring user input (e.g password for phpmyadmin see #218) - printf " %b Processing %s install(s) for: %s, please wait...\\n" "${INFO}" "${PKG_MANAGER}" "${installArray[*]}" - printf '%*s\n' "${c}" '' | tr " " - - "${PKG_INSTALL[@]}" "${installArray[@]}" - printf '%*s\n' "${c}" '' | tr " " - - return + if [ -f /tmp/pihole-meta.deb ]; then + eval "${PKG_INSTALL}" "/tmp/pihole-meta.deb" + rm /tmp/pihole-meta.deb + else + printf " %b Error: Unable to find dependency meta package.\\n" "${COL_LIGHT_RED}" + return 1 fi - printf "\\n" - return 0 fi # Install Fedora/CentOS packages - for i in "$@"; do - # For each package, check if it's already installed (and if so, don't add it to the installArray) - printf " %b Checking for %s..." "${INFO}" "${i}" - if "${PKG_MANAGER}" -q list installed "${i}" &>/dev/null; then - printf "%b %b Checking for %s\\n" "${OVER}" "${TICK}" "${i}" - else - printf "%b %b Checking for %s (will be installed)\\n" "${OVER}" "${INFO}" "${i}" - installArray+=("${i}") - fi - done - # If there's anything to install, install everything in the list. - if [[ "${#installArray[@]}" -gt 0 ]]; then - printf " %b Processing %s install(s) for: %s, please wait...\\n" "${INFO}" "${PKG_MANAGER}" "${installArray[*]}" - printf '%*s\n' "${c}" '' | tr " " - - "${PKG_INSTALL[@]}" "${installArray[@]}" - printf '%*s\n' "${c}" '' | tr " " - - return - fi + printf "\\n" return 0 } @@ -2269,9 +2248,12 @@ main() { # Notify user of package availability notify_package_updates_available - # Install packages necessary to perform os_check - printf " %b Checking for / installing Required dependencies for OS Check...\\n" "${INFO}" - install_dependent_packages "${OS_CHECK_COMMON_DEPS[@]}" "${OS_CHECK_DEPS[@]}" + # Build dependecy package + build_dependency_package + + # Install Pi-hole dependencies + printf " %b Installing required dependencies ...\\n" "${INFO}" + install_dependent_packages # Check that the installed OS is officially supported - display warning if not os_check @@ -2286,10 +2268,6 @@ main() { exit 1 fi - # Install packages used by this installation script - printf " %b Checking for / installing Required dependencies for this install script...\\n" "${INFO}" - install_dependent_packages "${INSTALLER_COMMON_DEPS[@]}" "${INSTALLER_DEPS[@]}" - # in case of an update if [[ -f "${PI_HOLE_V6_CONFIG}" ]]; then # if it's running unattended, @@ -2331,13 +2309,6 @@ main() { # Download or update the scripts by updating the appropriate git repos clone_or_update_repos - # Install the Core dependencies - local dep_install_list=("${PIHOLE_COMMON_DEPS[@]}" "${PIHOLE_DEPS[@]}") - - # Install packages used by the actual software - printf " %b Checking for / installing Required dependencies for Pi-hole software...\\n" "${INFO}" - install_dependent_packages "${dep_install_list[@]}" - unset dep_install_list # Create the pihole user create_pihole_user diff --git a/test/test_any_automated_install.py b/test/test_any_automated_install.py index 0930f0af..7d9a49ad 100644 --- a/test/test_any_automated_install.py +++ b/test/test_any_automated_install.py @@ -12,7 +12,7 @@ from .conftest import ( run_script, ) -FTL_BRANCH = "development-v6" +FTL_BRANCH = "development" def test_supported_package_manager(host): @@ -480,8 +480,8 @@ def test_os_check_fails(host): """ source /opt/pihole/basic-install.sh package_manager_detect - install_dependent_packages ${OS_CHECK_DEPS[@]} - install_dependent_packages ${INSTALLER_DEPS[@]} + build_dependency_package + install_dependent_packages cat < /etc/os-release ID=UnsupportedOS VERSION_ID="2" @@ -504,8 +504,8 @@ def test_os_check_passes(host): """ source /opt/pihole/basic-install.sh package_manager_detect - install_dependent_packages ${OS_CHECK_DEPS[@]} - install_dependent_packages ${INSTALLER_DEPS[@]} + build_dependency_package + install_dependent_packages """ ) detectOS = host.run( @@ -518,21 +518,6 @@ def test_os_check_passes(host): 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( - """ - source /opt/pihole/basic-install.sh - package_manager_detect - install_dependent_packages ${INSTALLER_DEPS[@]} - """ - ) - - 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) @@ -540,24 +525,11 @@ def test_package_manager_has_pihole_deps(host): """ source /opt/pihole/basic-install.sh package_manager_detect - install_dependent_packages ${PIHOLE_DEPS[@]} + build_dependency_package + install_dependent_packages """ ) 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( - """ - source /opt/pihole/basic-install.sh - package_manager_detect - install_dependent_packages ${PIHOLE_WEB_DEPS[@]} - """ - ) - - 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 59745c48..46b4acca 100644 --- a/test/test_any_utils.py +++ b/test/test_any_utils.py @@ -105,7 +105,7 @@ def test_setFTLConfigValue_getFTLConfigValue(host): source /opt/pihole/basic-install.sh create_pihole_user funcOutput=$(get_binary_name) - echo "development-v6" > /etc/pihole/ftlbranch + echo "development" > /etc/pihole/ftlbranch binary="pihole-FTL${funcOutput##*pihole-FTL}" theRest="${funcOutput%pihole-FTL*}" FTLdetect "${binary}" "${theRest}"