Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support for Pi-hole running inside a Docker container #18

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
266 changes: 145 additions & 121 deletions pihole-cloudsync
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
# pihole-cloudsync
# Helper script to keep multiple Pi-holes' lists synchronized via Git

# Version 4.0 - March 28, 2020 - Steve Jenkins (stevejenkins.com)
version='4.1'
update='April 2, 2020'
# Version 4.1 - April 2, 2020 - Steve Jenkins (stevejenkins.com)
# Version 4.1tb - 13 June 2020 - IarwainBen-adar ([email protected])
# └─TB: Added support for Pi-hole running in a Docker container
version='4.1tb'
update='13 June 2020'

# SETUP
# Follow the instructions in the README to set up your own private Git
Expand All @@ -16,22 +18,23 @@ update='April 2, 2020'
# USAGE: pihole-cloudsync <option>

# OPTIONS:
# --initpush Initialize Primary Pi-hole in "Push" mode
# --initpull Initialize Secondary Pi-hole in "Pull" mode
# --push, --upload, --up, -u Push (upload) your Pi-hole lists to a remote Git repo
# --pull, --download, --down, -d Pull (download) your lists from a remote Git repo
# --help, -h, -? Show the current version of pihole-cloudsync
# --version, -v Show version number
# --initpush Initialize Primary Pi-hole in "Push" mode
# --initpull Initialize Secondary Pi-hole in "Pull" mode
# --push, --upload, --up, -u Push (upload) your Pi-hole lists to a remote Git repo
# --pull, --download, --down, -d Pull (download) your lists from a remote Git repo
# --help, -h, -? Show the current version of pihole-cloudsync
# --version, -v Show version number

# EXAMPLES:
# 'pihole-cloudsync --push' will push (upload) your lists to a remote Git repo
# 'pihole-cloudsync --pull' will pull (download) your lists from a remote Git repo

# Project Home: https://github.com/stevejenkins/pihole-cloudsync

###########################################################################
# CONSTANTS
pihole_version=4
personal_git_dir='/usr/local/bin/my-pihole-lists'
# PIHOLE-CLOUDSYNC CONFIGURATION
pihole_version=5 # safe to default to version 5 at this point?
personal_git_dir='/etc/pihole/my-pihole-lists'
pihole_dir='/etc/pihole'
ad_list='adlists.list'
black_list='black.list'
Expand All @@ -40,12 +43,14 @@ whitelist_list='whitelist.txt'
regex_list='regex.list'
gravity_db='gravity.db'
custom_list='custom.list'

###########################################################################
# FOR SHARED HOSTS MODE ONLY
# RE-INITIALIZE WITH --initpush OR --initpull AFTER ENABLING THIS MODE
enable_hosts=off
local_hosts='/etc/hosts'
shared_hosts='sharedhosts.txt'

###########################################################################
# SHOULDN'T NEED TO EDIT BELOW THIS LINE

Expand All @@ -55,119 +60,132 @@ if [ "$EUID" -ne 0 ]
then SUDO='sudo'
fi

# Send pihole commands via docker exec if pihole is running in docker container
PIHOLECONTAINER=''
DOCKER=''
if [ -x "$(command -v docker)" ]; then
PIHOLECONTAINER=$(docker ps -f "ancestor=pihole/pihole" --format "{{.Names}}")
if [ -n "${PIHOLECONTAINER}" ] && $(docker inspect -f "{{.State.Running}}" "${PIHOLECONTAINER}"); then
DOCKER="docker exec -i ${PIHOLECONTAINER}"
fi
fi

# Case-insensitive check for Shared Hosts Mode
shared_hosts_mode=''
if [ $(echo "$enable_hosts" |tr [:upper:] [:lower:]) == "yes" ] || [ $(echo "$enable_hosts" |tr [:upper:] [:lower:]) == "y" ] || [ $(echo "$enable_hosts" |tr [:upper:] [:lower:]) == "on" ] || [ $(echo "$enable_hosts" |tr [:upper:] [:lower:]) == "true" ] || [ $(echo "$enable_hosts" |tr [:upper:] [:lower:]) == "1" ]; then
shared_hosts_mode='1'
echo "Shared Hosts Mode ENABLED.";
shared_hosts_mode='1'
echo "Shared Hosts Mode ENABLED.";
else
echo "Shared Hosts Mode DISABLED.";
echo "Shared Hosts Mode DISABLED.";
fi

# FUNCTIONS
push_initialize () {
cd $pihole_dir || exit
if [ "$pihole_version" == "5" ]; then
$SUDO touch $gravity_db $custom_list
$SUDO cp $gravity_db $custom_list $personal_git_dir
else
$SUDO touch $ad_list $black_list $blacklist_list $whitelist_list $regex_list
$SUDO cp $ad_list $black_list $blacklist_list $whitelist_list $regex_list $personal_git_dir
fi

if [ "$shared_hosts_mode" ]; then
$SUDO sed -n '/# SHARED HOSTS - START/,/# SHARED HOSTS - END/p' $local_hosts | $SUDO sed '1d;$d' > /tmp/$shared_hosts
$SUDO cp /tmp/$shared_hosts $personal_git_dir
fi
cd $personal_git_dir || exit
$SUDO git add .
echo "Local Pi-hole initialized in Push mode and local lists were added to local Git repo. Run 'pihole-cloudsync --push' to push to remote Git repo.";
cd $pihole_dir || exit
if [ "$pihole_version" == "5" ]; then
$SUDO touch $gravity_db $custom_list
$SUDO cp $gravity_db $custom_list $personal_git_dir
else
$SUDO touch $ad_list $black_list $blacklist_list $whitelist_list $regex_list
$SUDO cp $ad_list $black_list $blacklist_list $whitelist_list $regex_list $personal_git_dir
fi

if [ "$shared_hosts_mode" ]; then
$SUDO sed -n '/# SHARED HOSTS - START/,/# SHARED HOSTS - END/p' $local_hosts | $SUDO sed '1d;$d' > /tmp/$shared_hosts
$SUDO cp /tmp/$shared_hosts $personal_git_dir
fi
cd $personal_git_dir || exit
$SUDO git add .
echo "Local Pi-hole initialized in Push mode and local lists were added to local Git repo. Run 'pihole-cloudsync --push' to push to remote Git repo.";
}
pull_initialize () {
cd $personal_git_dir || exit
$SUDO git remote update > /dev/null
# Remove -q option if you don't want to run in "quiet" mode
$SUDO git fetch --all -q
$SUDO git reset --hard origin/master -q
if [ "$pihole_version" == "5" ]; then
$SUDO service pihole-FTL stop
$SUDO cp $gravity_db $custom_list $pihole_dir
$SUDO service pihole-FTL start
else
$SUDO cp $ad_list $black_list $blacklist_list $whitelist_list $regex_list $pihole_dir
fi

if [ "$shared_hosts_mode" ]; then
$SUDO cp $local_hosts /tmp/hosts
$SUDO sed -e '/# SHARED HOSTS - START/,/# SHARED HOSTS - END/{/^# SHARED HOSTS/!d}' \
-e "/# SHARED HOSTS - START.*$/r $shared_hosts" \
--in-place=.bak /tmp/hosts
$SUDO mv /tmp/hosts $local_hosts
fi
$SUDO pihole -g
echo "Local Pi-hole initialized in Pull mode and first pull successfully completed.";
echo "Future pulls can now be perfomed with 'pihole-cloudsync --pull'.";
cd $personal_git_dir || exit
$SUDO git remote update > /dev/null
# Remove -q option if you don't want to run in "quiet" mode
$SUDO git fetch --all -q
$SUDO git reset --hard origin/master -q
if [ "$pihole_version" == "5" ]; then
$SUDO $DOCKER service pihole-FTL stop
$SUDO cp $gravity_db $custom_list $pihole_dir
$SUDO $DOCKER service pihole-FTL start
else
$SUDO cp $ad_list $black_list $blacklist_list $whitelist_list $regex_list $pihole_dir
fi

if [ "$shared_hosts_mode" ]; then
$SUDO cp $local_hosts /tmp/hosts
$SUDO sed -e '/# SHARED HOSTS - START/,/# SHARED HOSTS - END/{/^# SHARED HOSTS/!d}' \
-e "/# SHARED HOSTS - START.*$/r $shared_hosts" \
--in-place=.bak /tmp/hosts
$SUDO mv /tmp/hosts $local_hosts
fi
$SUDO $DOCKER pihole -g
echo "Local Pi-hole initialized in Pull mode and first pull successfully completed.";
echo "Future pulls can now be perfomed with 'pihole-cloudsync --pull'.";
}
push () {
cd $pihole_dir || exit
cd $pihole_dir || exit
if [ "$pihole_version" == "5" ]; then
$SUDO cp $gravity_db $custom_list $personal_git_dir
else
$SUDO cp $ad_list $black_list $blacklist_list $whitelist_list $regex_list $personal_git_dir
fi

if [ "$shared_hosts_mode" ]; then
$SUDO sed -n '/# SHARED HOSTS - START/,/# SHARED HOSTS - END/p' $local_hosts | $SUDO sed '1d;$d' > /tmp/$shared_hosts
$SUDO cp /tmp/$shared_hosts $personal_git_dir
fi
cd $personal_git_dir || exit
$SUDO git remote update > /dev/null
else
$SUDO cp $ad_list $black_list $blacklist_list $whitelist_list $regex_list $personal_git_dir
fi

if [ "$shared_hosts_mode" ]; then
$SUDO sed -n '/# SHARED HOSTS - START/,/# SHARED HOSTS - END/p' $local_hosts | $SUDO sed '1d;$d' > /tmp/$shared_hosts
$SUDO cp /tmp/$shared_hosts $personal_git_dir
fi
cd $personal_git_dir || exit
$SUDO git remote update > /dev/null
CHANGED=$($SUDO git --work-tree=$personal_git_dir status --porcelain)
if [ -n "${CHANGED}" ]; then
echo 'Local Pi-hole lists are different than remote Git repo. Updating remote repo...';
rightnow=$(date +"%B %e, %Y %l:%M%p")
# Remove -q option if you don't want to run in "quiet" mode
$SUDO git commit -a -m "Updated $rightnow" -q
$SUDO git push -q
echo 'Done!';
exit 0
rightnow=$(date +"%B %e, %Y %l:%M%p")
# Remove -q option if you don't want to run in "quiet" mode
$SUDO git commit -a -m "Updated $rightnow" -q
$SUDO git push -q
echo 'Done!';
exit 0
else
echo 'Remote Git repo matches local Pi-hole lists. No further action required.';
exit 0
exit 0
fi
}
pull () {
cd $personal_git_dir || exit
$SUDO git remote update > /dev/null
CHANGED=$($SUDO git log HEAD..origin/master --oneline)
if [ -n "${CHANGED}" ]; then
cd $personal_git_dir || exit
$SUDO git remote update > /dev/null
CHANGED=$($SUDO git log HEAD..origin/master --oneline)
if [ -n "${CHANGED}" ]; then
echo 'Remote Git repo is different than local Pi-hole lists. Updating local lists...';
# Remove -q option if you don't want to run in "quiet" mode
$SUDO git fetch --all -q
$SUDO git reset --hard origin/master -q
if [ "$pihole_version" == "5" ]; then
$SUDO service pihole-FTL stop
$SUDO cp $gravity_db $custom_list $pihole_dir
$SUDO service pihole-FTL start
else
$SUDO cp $ad_list $black_list $blacklist_list $whitelist_list $regex_list $pihole_dir
fi

if [ "$shared_hosts_mode" ]; then
$SUDO cp $local_hosts /tmp/hosts
$SUDO sed -e '/# SHARED HOSTS - START/,/# SHARED HOSTS - END/{/^# SHARED HOSTS/!d}' \
-e "/# SHARED HOSTS - START.*$/r $shared_hosts" \
--in-place=.bak /tmp/hosts
$SUDO mv /tmp/hosts $local_hosts
fi
$SUDO pihole -g
$SUDO git reset --hard origin/master -q
if [ "$pihole_version" == "5" ]; then
$SUDO $DOCKER service pihole-FTL stop
$SUDO cp $gravity_db $custom_list $pihole_dir
$SUDO $DOCKER service pihole-FTL start
else
$SUDO cp $ad_list $black_list $blacklist_list $whitelist_list $regex_list $pihole_dir
fi

if [ "$shared_hosts_mode" ]; then
$SUDO cp $local_hosts /tmp/hosts
$SUDO sed -e '/# SHARED HOSTS - START/,/# SHARED HOSTS - END/{/^# SHARED HOSTS/!d}' \
-e "/# SHARED HOSTS - START.*$/r $shared_hosts" \
--in-place=.bak /tmp/hosts
$SUDO mv /tmp/hosts $local_hosts
fi
$SUDO $DOCKER pihole -g
echo 'Done!';
exit 0
else
echo 'Local Pi-hole lists match remote Git repo. No further action required.';
exit 0
fi
}
docker_test() {
$DOCKER printenv
}
###########################################################################
# Check to see whether a command line option was provided
if [ -z "$1" ]
Expand All @@ -178,43 +196,50 @@ fi
# Determine which action to perform (InitPush, InitPull, Push, Pull, or Help)
for arg in "$@"
do
# Test sending commands to docker container
if [ "$arg" == "--dockertest" ]
then
echo "$arg option detected. Testing docker container commands with 'printenv'.";
docker_test
exit 0
# Initialize - adds primary Pi-hole's lists to local Git repo before first push/upload
if [ "$arg" == "--initpush" ]
then
echo "$arg option detected. Initializing local Git repo for Push/Upload.";
push_initialize
exit 0
elif [ "$arg" == "--initpush" ]
then
echo "$arg option detected. Initializing local Git repo for Push/Upload.";
push_initialize
exit 0
# Initialize - adds primary Pi-hole's lists to local Git repo before first push/upload
elif [ "$arg" == "--initpull" ]
then
echo "$arg option detected. Initializing local Git repo for Pull/Download.";
pull_initialize
exit 0
then
echo "$arg option detected. Initializing local Git repo for Pull/Download.";
pull_initialize
exit 0
# Push / Upload - Pushes updated local Pi-hole lists to remote Git repo
elif [ "$arg" == "--push" ] || [ "$arg" == "--upload" ] || [ "$arg" == "--up" ] || [ "$arg" == "-u" ]
then
echo "$arg option detected. Running in Push/Upload mode."
push
exit 0
echo "$arg option detected. Running in Push/Upload mode."
push
exit 0
# Pull / Download - Pulls updated Pi-hole lists from remote Git repo
elif [ "$arg" == "--pull" ] || [ "$arg" == "--download" ] || [ "$arg" == "--down" ]|| [ "$arg" == "-d" ]
then
then
echo "$arg option detected. Running in Pull/Download mode."
pull
pull
exit 0
# Help - Displays help dialog
elif [ "$arg" == "--help" ] || [ "$arg" == "-h" ] || [ "$arg" == "-?" ]
then
cat << EOF
then
cat << EOF
Usage: pihole-cloudsync <option>

Options:
--push, --upload, --up, -u Push (upload) your Pi-hole lists to a remote Git repo
--pull, --download, --down, -d Pull (download) your lists from a remote Git repo
--initpush Initialize Primary Pi-hole in "Push" mode
--initpull Initialize Secondary Pi-hole in "Pull" mode
--help, -h, -? Show this help dialog
--version, -v Show the current version of pihole-cloudsync
--push, --upload, --up, -u Push (upload) your Pi-hole lists to a remote Git repo
--pull, --download, --down, -d Pull (download) your lists from a remote Git repo
--initpush Initialize Primary Pi-hole in "Push" mode
--initpull Initialize Secondary Pi-hole in "Pull" mode
--help, -h, -? Show this help dialog
--version, -v Show the current version of pihole-cloudsync
--dockertest Validate connection to running Pi-hole docker container

Examples:
'pihole-cloudsync --push' will push (upload) your lists to a Git repo
Expand All @@ -225,13 +250,12 @@ EOF

# Version - Displays version number
elif [ "$arg" == "--version" ] || [ "$arg" == "-v" ]
then
echo 'pihole-cloudsync v'$version' - Updated '"$update";
echo 'https://github.com/stevejenkins/pihole-cloudsync';

then
echo 'pihole-cloudsync v'$version' - Updated '"$update";
echo 'https://github.com/stevejenkins/pihole-cloudsync';
# Invalid command line option was passed
else
echo "Invalid command line option. Try --push, --pull, or --help."
exit 1
echo "Invalid command line option. Try --push, --pull, or --help."
exit 1
fi
done