From ffb8a7411126e07118cd8d55de849d9f5aa47b67 Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Sat, 31 Dec 2016 22:34:20 -0800 Subject: [PATCH 1/7] Defensive `is_repo` `is_repo` defended Document return codes for `is_repo()` `is_repo` tested for 128,1,0 return values. --- automated install/basic-install.sh | 39 +++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index dc21ac97..bf85cca3 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -133,26 +133,40 @@ fi ####### FUNCTIONS ########## is_repo() { - # Use git to check if directory is currently under VCS, return the value + # Use git to check if directory is currently under VCS, return the value 128 + # if directory is not a repo. Return 1 if directory does not exist. local directory="${1}" - if [ -d $directory ]; then + local curdir + local rc + + curdir="${PWD}" + if [[ -d "${directory}" ]]; then # git -C is not used here to support git versions older than 1.8.4 - curdir=$PWD; cd $directory; git status --short &> /dev/null; rc=$?; cd $curdir - return $rc + cd "${directory}" + git status --short &> /dev/null || rc=$? else - # non-zero return code if directory does not exist OR is not a valid git repository - return 1 + # non-zero return code if directory does not exist + rc=1 fi + cd "${curdir}" + return "${rc:-0}" } make_repo() { local directory="${1}" local remoteRepo="${2}" - # Remove the non-repod interface and clone the interface - echo -n "::: Cloning $remoteRepo into $directory..." - rm -rf "${directory}" - git clone -q --depth 1 "${remoteRepo}" "${directory}" &> /dev/null - echo " done!" + + echo -n "::: Cloning ${remoteRepo} into ${directory}..." + # Clean out the directory if it exists for git to clone into + if [[ -d "${directory}" ]]; then + rm -rf "${directory}" + fi + if ! git clone -q --depth 1 "${remoteRepo}" "${directory}" &> /dev/null; then + return $? + else + echo " done!" + fi + return 0 } update_repo() { @@ -175,8 +189,9 @@ getGitFiles() { if is_repo "${directory}"; then update_repo "${directory}" else - make_repo "${directory}" "${remoteRepo}" + make_repo "${directory}" "${remoteRepo}" || { echo "!!! Unable to clone ${remoteRepo}"; return 1; } fi + return 0 } find_IPv4_information() { From ab9c8f48595abce8244b8220730341c7c70add62 Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Sat, 31 Dec 2016 23:59:07 -0800 Subject: [PATCH 2/7] `make_repo` more defensive. Signed-off-by: Dan Schaper --- automated install/basic-install.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index bf85cca3..efc583ee 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -161,11 +161,8 @@ make_repo() { if [[ -d "${directory}" ]]; then rm -rf "${directory}" fi - if ! git clone -q --depth 1 "${remoteRepo}" "${directory}" &> /dev/null; then - return $? - else - echo " done!" - fi + git clone -q --depth 1 "${remoteRepo}" "${directory}" &> /dev/null || return $? + echo " done!" return 0 } @@ -189,7 +186,10 @@ getGitFiles() { if is_repo "${directory}"; then update_repo "${directory}" else - make_repo "${directory}" "${remoteRepo}" || { echo "!!! Unable to clone ${remoteRepo}"; return 1; } + make_repo "${directory}" "${remoteRepo}" || \ + { echo "!!! Unable to clone ${remoteRepo} into ${directory}"; \ + return 1; \ + } fi return 0 } @@ -1091,8 +1091,8 @@ main() { echo "::: --reconfigure passed to install script. Not downloading/updating local repos" else # Get Git files for Core and Admin - getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl} - getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl} + getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl} || { echo "Unable to clone ${piholeGitUrl}"; exit 1; } + getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl} || { echo "Unable to clone ${webInterfaceGitUrl}"; exit 1; } fi if [[ ${useUpdateVars} == false ]]; then From 7cceb8615a8dddc1ad2f25d92ba3579691430803 Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Sat, 31 Dec 2016 22:34:20 -0800 Subject: [PATCH 3/7] `make_repo` more defensive. Signed-off-by: Dan Schaper --- automated install/basic-install.sh | 41 ++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index dc21ac97..efc583ee 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -133,26 +133,37 @@ fi ####### FUNCTIONS ########## is_repo() { - # Use git to check if directory is currently under VCS, return the value + # Use git to check if directory is currently under VCS, return the value 128 + # if directory is not a repo. Return 1 if directory does not exist. local directory="${1}" - if [ -d $directory ]; then + local curdir + local rc + + curdir="${PWD}" + if [[ -d "${directory}" ]]; then # git -C is not used here to support git versions older than 1.8.4 - curdir=$PWD; cd $directory; git status --short &> /dev/null; rc=$?; cd $curdir - return $rc + cd "${directory}" + git status --short &> /dev/null || rc=$? else - # non-zero return code if directory does not exist OR is not a valid git repository - return 1 + # non-zero return code if directory does not exist + rc=1 fi + cd "${curdir}" + return "${rc:-0}" } make_repo() { local directory="${1}" local remoteRepo="${2}" - # Remove the non-repod interface and clone the interface - echo -n "::: Cloning $remoteRepo into $directory..." - rm -rf "${directory}" - git clone -q --depth 1 "${remoteRepo}" "${directory}" &> /dev/null + + echo -n "::: Cloning ${remoteRepo} into ${directory}..." + # Clean out the directory if it exists for git to clone into + if [[ -d "${directory}" ]]; then + rm -rf "${directory}" + fi + git clone -q --depth 1 "${remoteRepo}" "${directory}" &> /dev/null || return $? echo " done!" + return 0 } update_repo() { @@ -175,8 +186,12 @@ getGitFiles() { if is_repo "${directory}"; then update_repo "${directory}" else - make_repo "${directory}" "${remoteRepo}" + make_repo "${directory}" "${remoteRepo}" || \ + { echo "!!! Unable to clone ${remoteRepo} into ${directory}"; \ + return 1; \ + } fi + return 0 } find_IPv4_information() { @@ -1076,8 +1091,8 @@ main() { echo "::: --reconfigure passed to install script. Not downloading/updating local repos" else # Get Git files for Core and Admin - getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl} - getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl} + getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl} || { echo "Unable to clone ${piholeGitUrl}"; exit 1; } + getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl} || { echo "Unable to clone ${webInterfaceGitUrl}"; exit 1; } fi if [[ ${useUpdateVars} == false ]]; then From ad07655630bb5058ee3eabe34a2ce076e25797c9 Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Sun, 1 Jan 2017 00:07:10 -0800 Subject: [PATCH 4/7] Defensive git cloning Signed-off-by: Dan Schaper --- automated install/basic-install.sh | 31 ++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index efc583ee..74e049e2 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -168,12 +168,16 @@ make_repo() { update_repo() { local directory="${1}" + # Pull the latest commits - echo -n "::: Updating repo in $1..." - cd "${directory}" || exit 1 - git stash -q &> /dev/null - git pull -q &> /dev/null - echo " done!" + echo -n "::: Updating repo in ${1}..." + if [[ -d "${directory}" ]]; then + cd "${directory}" + git stash -q &> /dev/null || true # Okay for stash failure + git pull -q &> /dev/null || return $? + echo " done!" + fi + return 0 } getGitFiles() { @@ -184,12 +188,9 @@ getGitFiles() { echo ":::" echo "::: Checking for existing repository..." if is_repo "${directory}"; then - update_repo "${directory}" + update_repo "${directory}" || return 1 else - make_repo "${directory}" "${remoteRepo}" || \ - { echo "!!! Unable to clone ${remoteRepo} into ${directory}"; \ - return 1; \ - } + make_repo "${directory}" "${remoteRepo}" || return 1 fi return 0 } @@ -1091,8 +1092,14 @@ main() { echo "::: --reconfigure passed to install script. Not downloading/updating local repos" else # Get Git files for Core and Admin - getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl} || { echo "Unable to clone ${piholeGitUrl}"; exit 1; } - getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl} || { echo "Unable to clone ${webInterfaceGitUrl}"; exit 1; } + getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl} || \ + { echo "!!! Unable to clone ${piholeGitUrl} into ${PI_HOLE_LOCAL_REPO}, unable to continue."; \ + exit 1; \ + } + getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl} || \ + { echo "!!! Unable to clone ${webInterfaceGitUrl} into ${webInterfaceDir}, unable to continue."; \ + exit 1; \ + } fi if [[ ${useUpdateVars} == false ]]; then From fa055481a70762acf29af07dfa96dce5a85d6062 Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Sun, 1 Jan 2017 06:32:49 -0800 Subject: [PATCH 5/7] Shellcheck screen size Signed-off-by: Dan Schaper --- 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 74e049e2..8a333eb4 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -36,8 +36,8 @@ QUERY_LOGGING=true # Find the rows and columns will default to 80x24 is it can not be detected screen_size=$(stty size 2>/dev/null || echo 24 80) -rows=$(echo $screen_size | awk '{print $1}') -columns=$(echo $screen_size | awk '{print $2}') +rows=$(echo "${screen_size}" | awk '{print $1}') +columns=$(echo "${screen_size}" | awk '{print $2}') # Divide by two so the dialogs take up half of the screen, which looks nice. r=$(( rows / 2 )) From 8be37130e92f3a3825b816a5d0f140b7014d6de5 Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Sun, 1 Jan 2017 06:45:03 -0800 Subject: [PATCH 6/7] Move first check to `main()`, `basic-install.sh` can now be sourced. Set `PH_TEST=true` then `source basic-install.sh`. Careful for `set -e`. Signed-off-by: Dan Schaper --- automated install/basic-install.sh | 44 +++++++++++++++--------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index 8a333eb4..c1265c17 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -51,28 +51,6 @@ skipSpaceCheck=false reconfigure=false runUnattended=false -######## FIRST CHECK ######## -# Must be root to install -echo ":::" -if [[ ${EUID} -eq 0 ]]; then - echo "::: You are root." -else - echo "::: Script called with non-root privileges. The Pi-hole installs server packages and configures" - echo "::: system networking, it requires elevated rights. Please check the contents of the script for" - echo "::: any concerns with this requirement. Please be sure to download this script from a trusted source." - echo ":::" - echo "::: Detecting the presence of the sudo utility for continuation of this install..." - - if command -v sudo &> /dev/null; then - echo "::: Utility sudo located." - exec curl -sSL https://install.pi-hole.net | sudo bash "$@" - exit $? - else - echo "::: sudo is needed for the Web interface to run pihole commands. Please run this script as root and it will be automatically installed." - exit 1 - fi -fi - # Compatibility if command -v apt-get &> /dev/null; then @@ -1050,6 +1028,28 @@ update_dialogs() { main() { + ######## FIRST CHECK ######## + # Must be root to install + echo ":::" + if [[ ${EUID} -eq 0 ]]; then + echo "::: You are root." + else + echo "::: Script called with non-root privileges. The Pi-hole installs server packages and configures" + echo "::: system networking, it requires elevated rights. Please check the contents of the script for" + echo "::: any concerns with this requirement. Please be sure to download this script from a trusted source." + echo ":::" + echo "::: Detecting the presence of the sudo utility for continuation of this install..." + + if command -v sudo &> /dev/null; then + echo "::: Utility sudo located." + exec curl -sSL https://install.pi-hole.net | sudo bash "$@" + exit $? + else + echo "::: sudo is needed for the Web interface to run pihole commands. Please run this script as root and it will be automatically installed." + exit 1 + fi + fi + # Check arguments for the undocumented flags for var in "$@"; do case "$var" in From 7750e1344ce5d482a1bd2d4f1e9fdba18d95af1f Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Sun, 1 Jan 2017 07:10:14 -0800 Subject: [PATCH 7/7] DRY `displayFinalMessage` Signed-off-by: Dan Schaper --- automated install/basic-install.sh | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh index c1265c17..c501452d 100755 --- a/automated install/basic-install.sh +++ b/automated install/basic-install.sh @@ -966,29 +966,18 @@ checkSelinux() { } displayFinalMessage() { - if (( ${#1} > 0 )) ; then # Final completion message to user whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using: IPv4: ${IPV4_ADDRESS%/*} -IPv6: ${IPV6_ADDRESS} +IPv6: ${IPV6_ADDRESS:-"Not Configured"} If you set a new IP address, you should restart the Pi. The install log is in /etc/pihole. View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin -The currently set password is ${1}" ${r} ${c} - else - whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using: -IPv4: ${IPV4_ADDRESS%/*} -IPv6: ${IPV6_ADDRESS} - -If you set a new IP address, you should restart the Pi. - -The install log is in /etc/pihole. -View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin" ${r} ${c} - fi +Your Admin Webpage login password is ${1:-"NOT SET"}" ${r} ${c} } update_dialogs() {