diff --git a/README.md b/README.md index 6eff972..742c2be 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,13 @@ -# Gravity Sync +

+ Gravity Sync +

+ +What is better than a [Pi-hole](https://github.com/pi-hole/pi-hole) blocking ads via DNS on your network? That's right, two Pi-hole blocking ads on your network! + +But if you have more than one Pi-hole in your network you'll want a simple way to keep the list configurations and local DNS settings identical between the two. That's Gravity Sync. ## Features -What is better than a [Pi-hole](https://github.com/pi-hole/pi-hole) blocking ads via DNS on your network? That's right, Two Pi-hole! (Redundency is key in any network infrastucture.) But if you have more than one Pi-hole in your network you'll want a simple way to keep the list configurations and local DNS settings identical between the two. That's where Gravity Sync comes in. - Gravity Sync will: - Sync the Adlist database (allow/block list) configurations stored in `gravity.db` between multiple Pi-hole. @@ -19,11 +23,9 @@ Gravity Sync will **not**: - Overwrite individual Pi-hole specific settings such as the device's network configuration, admin/API passwords/keys, upstream DNS resolvers, etc. - Keep DHCP settings or device leases synchronized. -It is suggested that you use an external DHCP server on your network (such as your router) when using multiple Pi-hole. - ### Disclaimer -Gravity Sync is not developed by or affiliated with the Pi-hole project. This is a community effort that seeks to implement replication, which is currently not a part of the core Pi-hole product. The code has been well tested across multiple user environments but there always is an element of risk involved with running any arbitrary software you find on the Internet. +Gravity Sync is not developed by or affiliated with the Pi-hole project. This is an effort that seeks to implement replication, which is currently not a part of the core Pi-hole product. The code has been tested across multiple user environments but there always is an element of risk involved with running any arbitrary software you find on the Internet. ## Setup Steps @@ -37,10 +39,12 @@ Gravity Sync is not developed by or affiliated with the Pi-hole project. This is ## Requirements -- Pi-hole 5.0 (or higher) must already be installed on at least two systems, using any of the Linux distribution that Pi-hole is [certified to run on](https://docs.pi-hole.net/main/prerequesites/#supported-operating-systems). -- While it is possible to leverage container/Docker deployments of Pi-hole and Gravity Sync, this configuration is currently not officially supported. Instructions here assume a "native" installation of Pi-hole. -- You will need to make sure that you have a Linux user account on both Pi-hole systems with `sudo` abilities on both the primary and secondary Pi-hole. Use of the `root` account is not permitted. Most of the pre-built images available for the Raspberry Pi already have this configured. During installation this user will be given passwordless sudo permissions to the `/etc/pihole` directory. -- The installer will perform checks to make sure the OpenSSH `ssh` and `rsync` commands are available on both the primary and secondary Pi-hole during installation, as well as `SQLite3` and `git` -- all four of these binaries are should be installed by default on most Linux distrobutions, including Raspberry Pi OS. If they are missing you will have an oppertunity to use whatever package manager is available on your system to correct the missing dependencies. These binaries are what do the heavy lifting between your Pi-hole nodes. (Note: If you're using a ultra-lightweight Pi distribution, such as DietPi, that uses Dropbear by default - you may need to convert it to use OpenSSH.) +- Pi-hole 5.0 (or higher) must already be installed on at least two systems, using any of the Linux distributions that Pi-hole is [certified to run on](https://docs.pi-hole.net/main/prerequesites/#supported-operating-systems). +- As of Gravity Sync 3.1, your Pi-hole installs can be a standard installation of Pi-hole or a Docker container deployment. In either case, Gravity Sync will run directly on the host OS, and not inside of a container image. +- If you are using containerized deployments of Pi-hole, only the [official Pi-hole Docker image](https://hub.docker.com/r/pihole/pihole) is supported. +- You will need a user account with local administrator privileges on the host OS at each side. This can be a dedicated account or the system's `root` account +- If you're using a non-root user, make sure that the account is a member of the `sudo` group on both the primary and secondary Pi-hole. Most of the pre-built images available for the Raspberry Pi already have this configured. During installation this user will be given passwordless sudo permissions to the system. +- The installer will perform checks to make sure the required components to use Gravity Sync such as OpenSSH `ssh`, `SQLite3`, and `rsync` (plus a few others) are available on both the primary and secondary Pi-hole during installation. If they are missing you will have an opportunity to use whatever package manager is available on your system to correct the missing dependencies. These binaries are what do the heavy lifting between your Pi-hole nodes. ### Pi-hole Architecture @@ -49,15 +53,13 @@ You will want to designate one Pi-Hole as primary and at least one as secondary. - The primary Pi-hole is where you'll make most of your configuration changes through the Web UI, doing things such as; manual allow-listing, adding block-lists, device/group management, configuring custom/local network DNS, and changing other list settings. - The secondary Pi-hole(s) are where you will install and configure Gravity Sync. -For more information and for reference architectures, please [refer to this document](https://github.com/vmstan/gravity-sync/blob/master/ADVANCED.md#reference-architectures) - -Starting with version 2.0, Gravity Sync will attempt to sync the Adlist database and Local DNS Settings on each Pi-hole regardless of where the data was changed. Previous versions only pulled data one way as the standard operation. +For more information and for reference architectures, please [refer to this document](https://github.com/vmstan/gravity-sync/blob/master/docs/ADVANCED.md#reference-architectures) ## Installation ### Primary Pi-Hole -Minimal preperation is required (as of version 2.2.3) on your primary Pi-hole. +Minimal preperation is required on your primary Pi-hole, the installer will mostly check that all dependencies have been met for use. Login to your _primary_ Pi-hole, and run the following command: @@ -79,32 +81,25 @@ Login to your _secondary_ Pi-hole, and run the following command: export GS_INSTALL=secondary && curl -sSL https://raw.githubusercontent.com/vmstan/gravity-sync/master/prep/gs-install.sh | bash ``` -This will verify you have everything necessary to use Gravity Sync. The installer will then use Git to make a copy of the Gravity Sync executables in your home directory, and direct you to proceed to Configuration step below. Once this has completed, you will now have a folder called `gravity-sync` in your home directory. Everything Gravity Sync runs from there. +This will verify you have everything necessary to use Gravity Sync. The installer will then use Git to make a copy of the Gravity Sync executables in the folder the installer was executed in, and direct you to proceed to Configuration step below. Once this has completed, you will now have a folder called `gravity-sync` in your installed directory. Everything Gravity Sync runs from there. Proceed to the Configuration section. ## Configuration -After you install Gravity Sync to your _secondary Pi-hole_ you will need to create a configuration file. - -```bash -cd $HOME/gravity-sync -./gravity-sync.sh configure -``` +After you install Gravity Sync to your _secondary Pi-hole_ you will need to create a configuration file. This will run automatically by the installer. This will guide you through the process of: - Specifying the IP or DNS name of your primary Pi-hole. - Specifying the SSH username to connect to your primary Pi-hole. -- Selecting the SSH authentication mechanism (key-pair or password.) - Configuring your key-pair and applying it to your primary Pi-hole. -- Testing your authentication method, and testing RSYNC to the primary. -- Perform a backup of the existing Pi-hole database. -- Adding your Gravity Sync user to the local SUDO configuration to run passwordless. The configuration will be saved as `gravity-sync.conf` in the same folder as the script. If you need to make adjustments to your settings in the future, you can edit this file or run the configuration tool to generate a new one. -After you're pleased your configuration, proceed to the Execution phase. +If you are deploying Gravity Sync to a system using Docker containers, the script should detect this and prompt for additional configuration. You can also choose to perform an advanced installation when prompted. + +After you're pleased with your configuration, proceed to the Execution phase. ## Execution @@ -184,7 +179,7 @@ You can run a `./gravity-sync.sh config` at any time to generate a new configura ## Starting Over -Starting in version 2.2, Gravity Sync has a built in tool to purge everything custom about itself from the system. +Gravity Sync has a built in tool to purge everything custom about itself from the system. ```bash ./gravity-sync.sh purge @@ -204,7 +199,7 @@ This function will totally wipe out your existing Gravity Sync installation and ### Uninstalling -If you are completely uninstalling Gravity Sync, the last step would be to remove the `gravity-sync` folder from your user's home directory. +If you are completely uninstalling Gravity Sync, the last step would be to remove the `gravity-sync` folder from your installation directory. ## Advanced Installation diff --git a/VERSION b/VERSION index d9c62ed..a0cd9f0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.2 \ No newline at end of file +3.1.0 \ No newline at end of file diff --git a/docs/ADVANCED.md b/docs/ADVANCED.md index 2c16818..b7956c5 100644 --- a/docs/ADVANCED.md +++ b/docs/ADVANCED.md @@ -10,11 +10,17 @@ The purpose of this guide is to break out the manual install instructions, and a ## Installation +If you don't want to use the automated installer, you can use git to manually clone Gravity Sync to your _secondary_ Pi-hole server. + +```bash +git clone https://github.com/vmstan/gravity-sync.git +``` + If you don't trust `git` to install your software, or just like doing things by hand, that's fine. -*Keep in mind that installing via this method means you won't be able to use Gravity Sync's built-in update mechanism.* +_Keep in mind that installing via this method means you won't be able to use Gravity Sync's built-in update mechanism._ -Download the latest release from [GitHub](https://github.com/vmstan/gravity-sync/releases) and extract the files to your *secondary* Pi-hole server. +Download the latest release from [GitHub](https://github.com/vmstan/gravity-sync/releases) and extract the files to your _secondary_ Pi-hole server. ```bash cd ~ @@ -23,10 +29,10 @@ unzip v3.x.x.zip -d gravity-sync cd gravity-sync ``` -Please note the script **must** be run from a folder in your user home directory (ex: /home/USER/gravity-sync) -- I wouldn't suggest deviating from the gravity-sync folder name. If you do you'll need to also change the configuration settings defined in the `gravity-sync.sh` script, which can be a little tedious to do every time you upgrade the script. - ## Configuration +If you don't want to use the automated configuration utility at `./gravity-sync.sh config` you can setup your configuration manually as well. + After you install Gravity Sync to your server there will be a file called `gravity-sync.conf.example` that you can use as the basis for your own `gravity-sync.conf` file. Make a copy of the example file and modify it with your site specific settings. ```bash @@ -34,7 +40,7 @@ cp gravity-sync.conf.example gravity-sync.conf vi gravity-sync.conf ``` -*Note: If you don't like VI or don't have VIM on your system, use NANO, or if you don't like any of those substitute for your text editor of choice. I'm not here to start a war.* +_Note: If you don't like VI or don't have VIM on your system, use NANO, or if you don't like any of those substitute for your text editor of choice. I'm not here to start a war._ Make sure you've set the REMOTE_HOST and REMOTE_USER variables with the IP (or DNS name) and user account to authenticate to the primary Pi. This account will need to have sudo permissions on the remote system. @@ -43,11 +49,9 @@ REMOTE_HOST='192.168.1.10' REMOTE_USER='pi' ``` -*Do not set the `REMOTE_PASS` variable until you've read the next section on SSH.* - ### SSH Configuration -Gravity Sync uses SSH to run commands on the primary Pi-hole, and sync the two systems by performing file copies. There are two methods available for authenticating with SSH. +Gravity Sync uses SSH to run commands on the primary Pi-hole, and sync the two systems by performing file copies. #### Key-Pair Authentication @@ -55,7 +59,7 @@ This is the preferred option, as it's more reliable and less dependent on third You'll need to generate an SSH key for your secondary Pi-hole user and copy it to your primary Pi-hole. This will allow you to connect to and copy the necessary files without needing a password each time. When generating the SSH key, accept all the defaults and do not put a passphrase on your key file. -*Note: If you already have this setup on your systems for other purposes, you can skip this step.* +_Note: If you already have this setup on your systems for other purposes, you can skip this step._ ```bash ssh-keygen -t rsa @@ -68,21 +72,7 @@ Make sure to leave the `REMOTE_PASS` variable set to nothing in `gravity-sync.co #### Password Authentication -This is the non-preferred option, as it depends on an non-standard utility called `sshpass` which must be installed on your secondary Pi-hole. Install it using your package manager of choice. The example below is for Raspberry Pi OS (previously Raspbian) or Ubuntu. - -```bash -sudo apt install sshpass -``` - -Then enter your password in the `gravity-sync.conf` file you configured above. - -```bash -REMOTE_PASS='password' -``` - -Gravity Sync will validate that the `sshpass` utility is installed on your system and fail-back to attempting key-pair authentication if it's not detected. - -Save. Keep calm, carry on. +This option has been removed from Gravity Sync as of version 3.1. ### The Pull Function @@ -116,7 +106,7 @@ Gravity Sync can also `restore` the database on the secondary Pi-hole in the eve ./gravity-sync.sh restore ``` -This will copy your last `gravity.db.backup` and `custom.list.backup` to the running copy on the secondary Pi-hole. +This will copy your last `gravity.db.backup` and `custom.list.backup` to the running copy on the secondary Pi-hole. This function purposefully asks for user interaction to avoid being accidentally automated. @@ -124,31 +114,114 @@ This function purposefully asks for user interaction to avoid being accidentally There are a series of advanced configuration options that you may need to change to better adapt Gravity Sync to your environment. They are referenced at the end of the `gravity-sync.conf` file. It is suggested that you make any necessary variable changes to this file, as they will supersede the ones located in the core script. If you want to revert back to the Gravity Sync default for any of these settings, just apply a `#` to the beginning of the line to comment it out. -#### `SSH_PORT=''` +#### `PH_IN_TYPE` and `RH_IN_TYPE` + +These variables allow you to configure either a default/standard Pi-hole installation on both the local and remote hosts. Available options are either `default` or `docker` exactly has written. + +- Default setting in Gravity Sync is `default`. +- These variables can be set via `./gravity-sync.sh config` function. + +#### `PIHOLE_DIR` and `RIHOLE_DIR` + +These variables allow you to change the location of the Pi-hole settings folder on both the local and remote hosts. This is required for Docker installations of Pi-hole. This directory location should be from the root of the file system and be configured **without** a trailing slash. + +- Default setting in Gravity Sync is `/etc/pihole`. +- These variables can be set via `./gravity-sync.sh config` function and required if a Docker install is selected. + +#### `PIHOLE_BIN` and `RIHOLE_BIN` + +These variables allow you to change the location of the Pi-hole binary folder on both the local and remote hosts. Unless you've done a custom Pi-hole installation, this setting is unlikely to require changes. This directory location should be from the root of the file system and be configured **without** a trailing slash. + +- Default setting in Gravity Sync is `/usr/local/bin/pihole`. + +#### `DOCKER_BIN` and `ROCKER_BIN` + +These variables allow you to change the location of the Docker binary folder on both the local and remote hosts. This may be necessary on some systems, if you've done a custom installation of Docker. This directory location should be from the root of the file system and be configured **without** a trailing slash. + +- Default setting in Gravity Sync is `/usr/bin/docker`. + +#### `FILE_OWNER` and `RILE_OWNER` + +These variables allow you to change the file owner of the Pi-hole gravity database on both the local and remote hosts. This is required for Docker installations of Pi-hole, but is likely unnecessary on standard installs. + +- Default setting in Gravity Sync is `pihole:pihole`. +- These variables are set via `./gravity-sync.sh config` function to `named:docker` automatically if a Docker install is selected. + +#### `DOCKER_CON` and `ROCKER_CON` + +These variables allow you to change the location of the name of the Docker container on both the local and remote hosts. + +- Default setting in Gravity Sync is `pihole`. +- These variables can be set via `./gravity-sync.sh config` function. + +#### `GRAVITY_FI` and `CUSTOM_DNS` + +These variables are for the `gravity.db` and `custom.list` files that are the two components replicated by Gravity Sync. You should not change them unless Pi-hole changes their naming convention for these files, in which case the core Gravity Sync files will be changed to adapt. + +#### `VERIFY_PASS` + +Gravity Sync will prompt to verify user interactivity during push, restore, or config operations (that overwrite an existing configuration) with the intention that it prevents someone from accidentally automating in the wrong direction or overwriting data intentionally. If you'd like to automate a push function, or just don't like to be asked twice to do something destructive, then you can opt-out. + +- Default setting in Gravity Sync is `0`, change to `1` to bypass this check. + +#### `SKIP_CUSTOM` + +Starting in v1.7.0, Gravity Sync manages the `custom.list` file that contains the "Local DNS Records" function within the Pi-hole interface. If you do not want to sync this setting, perhaps if you're doing a multi-site deployment with differing local DNS settings, then you can opt-out of this sync. + +- Default setting in Gravity Sync is `0`, change to `1` to exempt `custom.list` from replication. +- This variable can be set via `./gravity-sync.sh config` function. + +#### `DATE_OUTPUT` + +_This feature has not been implemented, but the intent is to provide the ability to add timestamped output to each status indicator in the script output (ex: [2020-05-28 19:46:54] [EXEC] \$MESSAGE)._ + +#### `PING_AVOID` + +The `./gravity-sync.sh config` function will attempt to ping the remote host to validate it has a valid network connection. If there is a firewall between your hosts preventing ICMP replies, or you otherwise wish to skip this step, it can be bypassed here. + +- Default setting in Gravity Sync is `0`, change to `1` to skip this network test. +- This variable can be set via `./gravity-sync.sh config` function. + +#### `ROOT_CHECK_AVOID` + +In versions of Gravity Sync prior to 3.1, at execution, Gravity Sync would check that it's deployed with its own user (not running as root), but for some deployments this was a hindrance. + +- This variable is no longer parsed by Gravity Sync. + +#### `BACKUP_RETAIN` + +The `./gravity-sync.sh backup` function will retain a defined number of days worth of `gravity.db` and `custom.list` backups. + +- Default setting in Gravity Sync is `7`, adjust as desired. +- This variable can be set via `./gravity-sync.sh config` function. + +#### `SSH_PORT` Gravity Sync is configured by default to use the standard SSH port (22) but if you need to change this, such as if you're traversing a NAT/firewall for a multi-site deployment, to use a non-standard port. -Default setting in Gravity Sync is 22. +- Default setting in Gravity Sync is 22. +- This variable can be set via `./gravity-sync.sh config` function. -#### `SSH_PKIF=''` +#### `SSH_PKIF` -Gravity Sync is configured by default to use the `.ssh/id_rsa` key-file that is generated using the `ssh-keygen` command. If you have an existing key-file stored somewhere else that you'd like to use, you can configure that here. The key-file will still need to be in the users $HOME directory. +Gravity Sync is configured by default to use the `.ssh/id_rsa` key-file that is generated using the `ssh-keygen` command. If you have an existing key-file stored somewhere else that you'd like to use, you can configure that here. The key-file will still need to be in the users `$HOME` directory. At this time Gravity Sync does not support using a passphrase in RSA key-files. If you have a passphrase applied to your standard `.ssh/id_rsa` either remove it, or generate a new file and specify that key for use only by Gravity Sync. -Default setting in Gravity Sync is `.ssh/id_rsa` +- Default setting in Gravity Sync is `.ssh/id_rsa`. +- This variable can be set via `./gravity-sync.sh config` function. -#### `LOG_PATH=''` +#### `LOG_PATH` -Gravity Sync will place logs in the same folder as the script (identified as .cron and .log) but if you'd like to place these in a another location, you can do that by identifying the full path to the directory. (ex: `/full/path/to/logs`) +Gravity Sync will place logs in the same folder as the script (identified as .cron and .log) but if you'd like to place these in a another location, you can do that by identifying the full path to the directory (ex: `/full/path/to/logs`) without a trailing slash. -Default setting in Gravity Sync is `$HOME/${LOCAL_FOLDR}` +- Default setting in Gravity Sync is a variable called `${LOCAL_FOLDR}`. #### `SYNCING_LOG=''` Gravity Sync will write a timestamp for any completed sync, pull, push or restore job to this file. If you want to change the name of this file, you will also need to adjust the LOG_PATH variable above, otherwise your file will be remove during an `update` operations. -Default setting in Gravity Sync is `gravity-sync.log` +- Default setting in Gravity Sync is `gravity-sync.log` #### `CRONJOB_LOG=''` @@ -156,54 +229,18 @@ Gravity Sync will log the execution history of the previous automation task via This will have an impact to both the `./gravity-sync.sh automate` function and the `./gravity-sync.sh cron` functions. If you need to change this after running the automate function, either modify your crontab manually or delete the entry and re-run the automate function. -Default setting in Gravity Sync is `gravity-sync.cron` +- Default setting in Gravity Sync is `gravity-sync.cron` #### `HISTORY_MD5=''` Gravity Sync will log the file hashes of the previous `smart` task to this file. If you want to change the name of this file, you will also need to adjust the LOG_PATH variable above, otherwise your file will be removed during an `update` operations. -Default setting in Gravity Sync is `gravity-sync.md5` - -#### `VERIFY_PASS=''` - -Gravity Sync will prompt to verify user interactivity during push, restore, or config operations (that overwrite an existing configuration) with the intention that it prevents someone from accidentally automating in the wrong direction or overwriting data intentionally. If you'd like to automate a push function, or just don't like to be asked twice to do something destructive, then you can opt-out. - -Default setting in Gravity Sync is 0, change to 1 to bypass this check. - -#### `SKIP_CUSTOM=''` - -Starting in v1.7.0, Gravity Sync manages the `custom.list` file that contains the "Local DNS Records" function within the Pi-hole interface. If you do not want to sync this setting, perhaps if you're doing a multi-site deployment with differing local DNS settings, then you can opt-out of this sync. - -Default setting in Gravity Sync is 0, change to 1 to exempt `custom.list` from replication. - -#### `DATE_OUTPUT=''` - -*This feature has not been fully implemented, but the intent is to provide the ability to add timestamped output to each status indicator in the script output (ex: [2020-05-28 19:46:54] [EXEC] $MESSAGE).* - -Default setting in Gravity Sync is 0, change to 1 to print timestamped output. +- Default setting in Gravity Sync is `gravity-sync.md5` #### `BASH_PATH=''` If you need to adjust the path to bash that is identified for automated execution via Crontab, you can do that here. This will only have an impact if changed before generating the crontab via the `./gravity-sync.sh automate` function. If you need to change this after the fact, either modify your crontab manually or delete the entry and re-run the automate function. -#### `PING_AVOID=''` - -The `./gravity-sync.sh config` function will attempt to ping the remote host to validate it has a valid network connection. If there is a firewall between your hosts preventing ping replies, or you otherwise wish to skip this step, it can by bypassed here. - -Default setting in Gravity Sync is 0, change to 1 to skip this network test. - -#### `ROOT_CHECK_AVOID=''` - -At execution, Gravity Sync will check that it's deployed with it's own user (not running as root), but for a container deployment this is not necessary. - -Default setting in Gravity Sync is 0, change to 1 to skip this root user test. - -#### `BACKUP_RETAIN=''` - -The `./gravity-sync.sh backup` function will retain a defined number of days worth of `gravity.db` and `custom.list` backups. - -Default setting in Gravity Sync is 7, adjust as desired. - ## Execution If you are just straight up unable to run the `gravity-sync.sh` file, make sure it's marked as an executable by Linux. @@ -237,8 +274,6 @@ git fetch --all git reset --hard origin/master ``` -Use `origin/development` to pull that branch instead. - If your code is still not updating after this, reinstallation is suggested rather than spending all your time troubleshooting `git` commands. ## Automation @@ -297,7 +332,7 @@ You make your configuration changes to the active VIP address and they will be s ![Crazy Town](https://user-images.githubusercontent.com/3002053/87058406-aa6dcb00-c1cd-11ea-8f64-59c529b00166.png) -For those who really love Pi-hole and Gravity Sync. Combining the best of both worlds. +For those who really love Pi-hole and Gravity Sync. Combining the best of both worlds. 1. Client requests an IP address from a DHCP server on the network and receives it along with DNS and gateway information back. Two DNS servers (VIPs) are returned to the client. 2. The VIPs are managed by the keepalived service on each side and will determine which of two Pi-hole responds. You can make your configuration changes to the active VIP address on either side. @@ -309,4 +344,4 @@ Here we use `./gravity-sync pull` on the secondary Pi-hole at each side, and off ## Troubleshooting -If you get the error `sudo: a terminal is required to read the password` or `sudo: no tty present and no askpass program specified` during your execution, make sure you have [implemented passwordless sudo](https://linuxize.com/post/how-to-run-sudo-command-without-password/), as defined in the system requirements, for the user accounts on both the local and remote systems. \ No newline at end of file +If you get the error `sudo: a terminal is required to read the password` or `sudo: no tty present and no askpass program specified` during your execution, make sure you have [implemented passwordless sudo](https://linuxize.com/post/how-to-run-sudo-command-without-password/), as defined in the system requirements, for the user accounts on both the local and remote systems. diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index aaf07c7..e325c7c 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,64 @@ # The Changelog +## 3.1 + +### The Container Release + +The premise of this release was to focus on adding better support for Docker container instances of Pi-hole. This release also changes a lot of things about the requirements that Gravity Sync has always had, which were not running as the root user, and requiring that the script be run from the user's home directory. Those two restrictions are gone. + +You can now use a standard Pi-hole install as your primary, or your secondary. You can use a Docker install of Pi-hole as your primary, or your secondary. You can mix and match between the two however you choose. You can have Pi-hole installed in different directories at each side, either as standard installs or with container configuration files in different locations. Overall it's much more flexible. + +#### Docker Support + +- Only the [official Pi-hole managed Docker image](https://hub.docker.com/r/pihole/pihole) is supported. Other builds may work, but they have not been tested. +- If you are using a name for your container other than the default `pihole` in your Docker configuration, you must specify this in your `gravity-sync.conf` file. +- Smart Sync, and the associated push/pull operations, now will send exec commands to run Pi-hole restart commands within the Docker container. +- Your container configuration must expose access to the virtual `/etc/pihole` location to the host's file system, and be configured in your `gravity-sync.conf` file. + +**Example:** if your container configuration looked something like like `-v /home/vmstan/etc-pihole/:/etc/pihole` then the location `/home/vmstan/etc-pihole` would need to be accessible by the user running Gravity Sync, and be configured as the `PIHOLE_DIR` (or `RIHOLE_DIR`) in your `gravity-sync.conf` file. + +#### Installation Script + +- Detects the running instance of default Pi-hole Docker container image, if standard Pi-hole lookup fails. Pi-hole must still be installed prior to Gravity Sync. +- Changes detection of root vs sudo users, and adapts commands to match. You no longer need to avoid running the script as `root`. +- Only deploys passwordless SUDO components if deemed necessary. (i.e. Not running as `root`.) +- Now automatically runs the local configuration function on the secondary Pi-hole after execution. +- Deploys script via `git` to whatever directory the installer runs in, instead of defaulting to the user's `$HOME` directory. +- Gravity Sync no longer requires that it be run from the user's `$HOME` directory. + +#### Configuration Workflow + +- Overall, a simpler configuration function, as the online installer now checks for the dependencies prior to execution. +- New users with basic Pi-hole installs will only be prompted for the address of the primary (remote) Pi-hole, an SSH user and then the SSH password to establish a trusted relationship and share the keyfiles. +- Automatically prompts on during setup to configure advanced variables if a Docker installation is detected on the secondary (local) Pi-hole. +- Advanced users can set more options for non-standard deployments at installation. If you are using a Docker deployment of Pi-hole on your primary (remote) Pi-hole, but not the system running Gravity Sync, you will need to enter this advanced mode when prompted. +- Existing users with default setups should not need to run the config utility again after upgrading, but those with custom installs (especially existing container users) should consider it to adopt new variable names and options in your config files. +- Creates a BASH environment alias to run the command `gravity-sync` from anywhere on the system. If you use a different shell (such as zsh or fish) as your default this may need to be added manually. + +#### New Variables + +- `REMOTE_FILE_OWNER` variable renamed `RILE_OWNER` for consistency. +- `RIHOLE_DIR` variable added to set different Pi-hole directory for remote host than local. +- `DOCKER_CON` and `ROCKER_CON` variables added to specify different names for local and remote Pi-hole Docker containers. +- `PH_IN_TYPE` and `RH_IN_TYPE` variables allow you to to either standard or Docker deployments of Pi-hole, per side. +- `DOCKER_BIN` and `ROCKER_BIN` variables allow you to set non-standard locations for Docker binary files, per side. +- Adds all variables to `gravity-sync.conf.example` for easy customization. + +#### Removals + +- Support for `sshpass` has been removed, the only valid authentication method going forward will be ssh-key based. +- If you've previously configured Gravity Sync using `sshpass` you will need to run `./gravity-sync.sh config` again to create a new configuration file. + +#### Bug Killer + +- Lots of long standing little buggles have been squashed. + +#### Branding + +- I made a logo. + +Gravity Sync + ## 3.0 ### The Breakout Release diff --git a/docs/gravity-header.svg b/docs/gravity-header.svg new file mode 100644 index 0000000..e29b60a --- /dev/null +++ b/docs/gravity-header.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/gs-logo.svg b/docs/gs-logo.svg new file mode 100644 index 0000000..2438174 --- /dev/null +++ b/docs/gs-logo.svg @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gravity-sync.conf.example b/gravity-sync.conf.example index 4247bde..ad33cb1 100644 --- a/gravity-sync.conf.example +++ b/gravity-sync.conf.example @@ -4,47 +4,51 @@ REMOTE_HOST='192.168.1.10' # User account on primary with SUDO rights -REMOTE_USER='pi' +REMOTE_USER='pi' -# OPTIONAL SETTINGS ###################### +# STANDARD VARIABLES ######################### -# Password for REMOTE_USER account -# Requires 'SSHPASS' installed on server -# (ex: sudo apt install sshpass) -# Less secure and possibly less reliable -# Leave blank to use (preferred) key-pair +### Installation Types +# PH_IN_TYPE='' # Pi-hole install type, `default` or `docker` (local) +# RH_IN_TYPE='' # Pi-hole install type, `default` or `docker` (remote) -REMOTE_PASS='' +### Pi-hole Folder/File Customization +# PIHOLE_DIR='' # default Pi-hole data directory (local) +# RIHOLE_DIR='' # default Pi-hole data directory (remote) +# PIHOLE_BIN='' # default Pi-hole binary directory (local) +# RIHOLE_BIN='' # default Pi-hole binary directory (remote) +# DOCKER_BIN='' # default Docker binary directory (local) +# ROCKER_BIN='' # default Docker binary directory (remote) +# FILE_OWNER='' # default Pi-hole file owner and group (local) +# RILE_OWNER='' # default Pi-hole file owner and group (remote) +# DOCKER_CON='' # default Pi-hole Docker container name (local) +# ROCKER_CON='' # default Pi-hole Docker container name (remote) -# ADVANCED SETTINGS ###################### +# GRAVITY_FI='' # default Pi-hole database file +# CUSTOM_DNS='' # default Pi-hole local DNS lookups -# Uncomment and set for auxiliary control -# Overrides gravity-sync.sh defaults -# See ADVANCED.md for more information +### Interaction Customization +# VERIFY_PASS='' # replace in gravity-sync.conf to overwrite +# SKIP_CUSTOM='' # replace in gravity-sync.conf to overwrite +# DATE_OUTPUT='' # replace in gravity-sync.conf to overwrite +# PING_AVOID='' # replace in gravity-sync.conf to overwrite +# ROOT_CHECK_AVOID='' # replace in gravity-sync.conf to overwrite -# SSH_PORT='' -# SSH_PKIF='' -# LOG_PATH='' -# SYNCING_LOG='' -# CRONJOB_LOG='' -# HISTORY_MD5='' +### Backup Customization +# BACKUP_RETAIN='' # replace in gravity-sync.conf to overwrite -# VERIFY_PASS='' -# SKIP_CUSTOM='' -# DATE_OUTPUT='' -# PING_AVOID='' -# ROOT_CHECK_AVOID='' +### SSH Customization +# SSH_PORT='' # default SSH port +# SSH_PKIF='' # default local SSH key -# BACKUP_RETAIN='' +### GS Folder/File Locations +# CONFIG_FILE='' # must exist with primary host/user configured +# GS_FILENAME='' # must exist because it's this script +# BACKUP_FOLD='' # must exist as subdirectory in LOCAL_FOLDR +# LOG_PATH='' # replace in gravity-sync.conf to overwrite +# SYNCING_LOG='' # replace in gravity-sync.conf to overwrite +# CRONJOB_LOG='' # replace in gravity-sync.conf to overwrite +# HISTORY_MD5='' # replace in gravity-sync.conf to overwrite -# PIHOLE DEFAULTS ######################## - -# Have a very good reason to change these! - -# PIHOLE_DIR='' -# GRAVITY_FI='' -# CUSTOM_DNS='' -# PIHOLE_BIN='' -# RIHOLE_BIN='' -# FILE_OWNER='' -# REMOTE_FILE_OWNER='' \ No newline at end of file +### OS Settings +# BASH_PATH='' # default OS bash path \ No newline at end of file diff --git a/gravity-sync.sh b/gravity-sync.sh index 674e9cc..22ef576 100755 --- a/gravity-sync.sh +++ b/gravity-sync.sh @@ -3,29 +3,37 @@ SCRIPT_START=$SECONDS # GRAVITY SYNC BY VMSTAN ##################### PROGRAM='Gravity Sync' -VERSION='3.0.2' +VERSION='3.1.0' -# Execute from the home folder of the user who owns it (ex: 'cd ~/gravity-sync') # For documentation or downloading updates visit https://github.com/vmstan/gravity-sync # Requires Pi-Hole 5.x or higher already be installed, for help visit https://pi-hole.net # REQUIRED SETTINGS ########################## -# Run './gravity-sync.sh config' to get started +# Run './gravity-sync.sh config' to get started, it will customize the script for your environment +# You should not to change the values of any variables here here to customize your install +# Add replacement variables to gravity-sync.conf, which will overwrite these defaults. # STANDARD VARIABLES ######################### -# GS Folder/File Locations -LOCAL_FOLDR='gravity-sync' # must exist in running user home folder -CONFIG_FILE='gravity-sync.conf' # must exist with primary host/user configured -GS_FILENAME='gravity-sync.sh' # must exist because it's this script -BACKUP_FOLD='backup' # must exist as subdirectory in LOCAL_FOLDR +# Installation Types +PH_IN_TYPE='default' # Pi-hole install type, `default` or `docker` (local) +RH_IN_TYPE='default' # Pi-hole install type, `default` or `docker` (remote) -# Logging Folder/File Locations -LOG_PATH="$HOME/${LOCAL_FOLDR}" # replace in gravity-sync.conf to overwrite -SYNCING_LOG='gravity-sync.log' # replace in gravity-sync.conf to overwrite -CRONJOB_LOG='gravity-sync.cron' # replace in gravity-sync.conf to overwrite -HISTORY_MD5='gravity-sync.md5' # replace in gravity-sync.conf to overwrite +# Pi-hole Folder/File Customization +PIHOLE_DIR='/etc/pihole' # default Pi-hole data directory (local) +RIHOLE_DIR='/etc/pihole' # default Pi-hole data directory (remote) +PIHOLE_BIN='/usr/local/bin/pihole' # default Pi-hole binary directory (local) +RIHOLE_BIN='/usr/local/bin/pihole' # default Pi-hole binary directory (remote) +DOCKER_BIN='/usr/bin/docker' # default Docker binary directory (local) +ROCKER_BIN='/usr/bin/docker' # default Docker binary directory (remote) +FILE_OWNER='pihole:pihole' # default Pi-hole file owner and group (local) +RILE_OWNER='pihole:pihole' # default Pi-hole file owner and group (remote) +DOCKER_CON='pihole' # default Pi-hole Docker container name (local) +ROCKER_CON='pihole' # default Pi-hole Docker container name (remote) + +GRAVITY_FI='gravity.db' # default Pi-hole database file +CUSTOM_DNS='custom.list' # default Pi-hole local DNS lookups # Interaction Customization VERIFY_PASS='0' # replace in gravity-sync.conf to overwrite @@ -37,66 +45,64 @@ ROOT_CHECK_AVOID='0' # replace in gravity-sync.conf to overwrite # Backup Customization BACKUP_RETAIN='7' # replace in gravity-sync.conf to overwrite -# Pi-hole Folder/File Locations -PIHOLE_DIR='/etc/pihole' # default Pi-hole data directory -GRAVITY_FI='gravity.db' # default Pi-hole database file -CUSTOM_DNS='custom.list' # default Pi-hole local DNS lookups -PIHOLE_BIN='/usr/local/bin/pihole' # default Pi-hole binary directory (local) -RIHOLE_BIN='/usr/local/bin/pihole' # default Pi-hole binary directory (remote) -FILE_OWNER='pihole:pihole' # default Pi-hole file owner and group (local) -REMOTE_FILE_OWNER='pihole:pihole' # default Pi-hole file owner and group (remote) +# SSH Customization +SSH_PORT='22' # default SSH port +SSH_PKIF='.ssh/id_rsa' # default local SSH key + +# GS Folder/File Locations +GS_FILEPATH=$(realpath $0) # auto determined - do not change! +LOCAL_FOLDR=$(dirname $GS_FILEPATH) # auto determined - do not change! +CONFIG_FILE='gravity-sync.conf' # must exist with primary host/user configured +GS_FILENAME='gravity-sync.sh' # must exist because it's this script +BACKUP_FOLD='backup' # must exist as subdirectory in LOCAL_FOLDR +LOG_PATH="${LOCAL_FOLDR}" # replace in gravity-sync.conf to overwrite +SYNCING_LOG='gravity-sync.log' # replace in gravity-sync.conf to overwrite +CRONJOB_LOG='gravity-sync.cron' # replace in gravity-sync.conf to overwrite +HISTORY_MD5='gravity-sync.md5' # replace in gravity-sync.conf to overwrite # OS Settings BASH_PATH='/bin/bash' # default OS bash path -# SSH CONFIGURATION ########################## - -# Suggested not to replace these values here -# Add replacement variables to gravity-sync.conf - -SSH_PORT='22' # default SSH port -SSH_PKIF='.ssh/id_rsa' # default local SSH key - ############################################## -### DO NOT CHANGE ANYTHING BELOW THIS LINE ### +### NEVER CHANGE ANYTHING BELOW THIS LINE! ### ############################################## # Import Color/Message Includes -source $HOME/${LOCAL_FOLDR}/includes/gs-colors.sh +source ${LOCAL_FOLDR}/includes/gs-colors.sh # FUNCTION DEFINITIONS ####################### # Core Functions -source $HOME/${LOCAL_FOLDR}/includes/gs-core.sh +source ${LOCAL_FOLDR}/includes/gs-core.sh # Gravity Replication Functions -source $HOME/${LOCAL_FOLDR}/includes/gs-compare.sh -source $HOME/${LOCAL_FOLDR}/includes/gs-pull.sh -source $HOME/${LOCAL_FOLDR}/includes/gs-push.sh -source $HOME/${LOCAL_FOLDR}/includes/gs-smart.sh -source $HOME/${LOCAL_FOLDR}/includes/gs-restore.sh -source $HOME/${LOCAL_FOLDR}/includes/gs-backup.sh +source ${LOCAL_FOLDR}/includes/gs-compare.sh +source ${LOCAL_FOLDR}/includes/gs-pull.sh +source ${LOCAL_FOLDR}/includes/gs-push.sh +source ${LOCAL_FOLDR}/includes/gs-smart.sh +source ${LOCAL_FOLDR}/includes/gs-restore.sh +source ${LOCAL_FOLDR}/includes/gs-backup.sh # Hashing & SSH Functions -source $HOME/${LOCAL_FOLDR}/includes/gs-hashing.sh -source $HOME/${LOCAL_FOLDR}/includes/gs-ssh.sh +source ${LOCAL_FOLDR}/includes/gs-hashing.sh +source ${LOCAL_FOLDR}/includes/gs-ssh.sh # Logging Functions -source $HOME/${LOCAL_FOLDR}/includes/gs-logging.sh +source ${LOCAL_FOLDR}/includes/gs-logging.sh # Validation Functions -source $HOME/${LOCAL_FOLDR}/includes/gs-validate.sh -source $HOME/${LOCAL_FOLDR}/includes/gs-intent.sh -source $HOME/${LOCAL_FOLDR}/includes/gs-root.sh +source ${LOCAL_FOLDR}/includes/gs-validate.sh +source ${LOCAL_FOLDR}/includes/gs-intent.sh +source ${LOCAL_FOLDR}/includes/gs-root.sh # Configuration Management -source $HOME/${LOCAL_FOLDR}/includes/gs-config.sh -source $HOME/${LOCAL_FOLDR}/includes/gs-update.sh -source $HOME/${LOCAL_FOLDR}/includes/gs-automate.sh -source $HOME/${LOCAL_FOLDR}/includes/gs-purge.sh +source ${LOCAL_FOLDR}/includes/gs-config.sh +source ${LOCAL_FOLDR}/includes/gs-update.sh +source ${LOCAL_FOLDR}/includes/gs-automate.sh +source ${LOCAL_FOLDR}/includes/gs-purge.sh # Exit Codes -source $HOME/${LOCAL_FOLDR}/includes/gs-exit.sh +source ${LOCAL_FOLDR}/includes/gs-exit.sh # SCRIPT EXECUTION ########################### @@ -119,13 +125,13 @@ case $# in start_gs task_restore ;; version) - start_gs + start_gs_noconfig task_version ;; update|upgrade) - start_gs + start_gs_noconfig task_update ;; dev|devmode|development|develop) - start_gs + start_gs_noconfig task_devmode ;; logs|log) start_gs diff --git a/includes/gs-automate.sh b/includes/gs-automate.sh index 1bb57a3..a10746e 100644 --- a/includes/gs-automate.sh +++ b/includes/gs-automate.sh @@ -56,7 +56,7 @@ function task_automate { MESSAGE="Saving New Sync Automation" echo_stat - (crontab -l 2>/dev/null; echo "*/${INPUT_AUTO_FREQ} * * * * ${BASH_PATH} $HOME/${LOCAL_FOLDR}/${GS_FILENAME} smart > ${LOG_PATH}/${CRONJOB_LOG}") | crontab - + (crontab -l 2>/dev/null; echo "*/${INPUT_AUTO_FREQ} * * * * ${BASH_PATH} ${LOCAL_FOLDR}/${GS_FILENAME} smart > ${LOG_PATH}/${CRONJOB_LOG}") | crontab - error_validate fi @@ -84,7 +84,7 @@ function task_automate { else MESSAGE="Saving New Backup Automation" echo_stat - (crontab -l 2>/dev/null; echo "0 ${INPUT_AUTO_BACKUP} * * * ${BASH_PATH} $HOME/${LOCAL_FOLDR}/${GS_FILENAME} backup >/dev/null 2>&1") | crontab - + (crontab -l 2>/dev/null; echo "0 ${INPUT_AUTO_BACKUP} * * * ${BASH_PATH} ${LOCAL_FOLDR}/${GS_FILENAME} backup >/dev/null 2>&1") | crontab - error_validate fi diff --git a/includes/gs-backup.sh b/includes/gs-backup.sh index c49c416..4987606 100644 --- a/includes/gs-backup.sh +++ b/includes/gs-backup.sh @@ -27,7 +27,7 @@ function backup_local_gravity { MESSAGE="Performing Backup of Local ${GRAVITY_FI}" echo_stat - sqlite3 ${PIHOLE_DIR}/${GRAVITY_FI} ".backup '$HOME/${LOCAL_FOLDR}/${BACKUP_FOLD}/${BACKUPTIMESTAMP}-${GRAVITY_FI}.backup'" + sqlite3 ${PIHOLE_DIR}/${GRAVITY_FI} ".backup '${LOCAL_FOLDR}/${BACKUP_FOLD}/${BACKUPTIMESTAMP}-${GRAVITY_FI}.backup'" error_validate } @@ -39,7 +39,7 @@ function backup_local_custom { MESSAGE="Performing Backup Up Local ${CUSTOM_DNS}" echo_stat - cp ${PIHOLE_DIR}/${CUSTOM_DNS} $HOME/${LOCAL_FOLDR}/${BACKUP_FOLD}/${BACKUPTIMESTAMP}-${CUSTOM_DNS}.backup + cp ${PIHOLE_DIR}/${CUSTOM_DNS} ${LOCAL_FOLDR}/${BACKUP_FOLD}/${BACKUPTIMESTAMP}-${CUSTOM_DNS}.backup error_validate fi fi @@ -50,7 +50,7 @@ function backup_remote_gravity { echo_stat CMD_TIMEOUT='60' - CMD_REQUESTED="sudo sqlite3 ${PIHOLE_DIR}/${GRAVITY_FI} \".backup '${PIHOLE_DIR}/${GRAVITY_FI}.backup'\"" + CMD_REQUESTED="sudo sqlite3 ${RIHOLE_DIR}/${GRAVITY_FI} \".backup '${RIHOLE_DIR}/${GRAVITY_FI}.backup'\"" create_sshcmd } @@ -61,7 +61,7 @@ function backup_remote_custom { echo_stat CMD_TIMEOUT='15' - CMD_REQUESTED="sudo cp ${PIHOLE_DIR}/${CUSTOM_DNS} ${PIHOLE_DIR}/${CUSTOM_DNS}.backup" + CMD_REQUESTED="sudo cp ${RIHOLE_DIR}/${CUSTOM_DNS} ${RIHOLE_DIR}/${CUSTOM_DNS}.backup" create_sshcmd fi } @@ -70,6 +70,6 @@ function backup_cleanup { MESSAGE="Cleaning Up Old Backups" echo_stat - find $HOME/${LOCAL_FOLDR}/${BACKUP_FOLD}/$(date +%Y)*.backup -mtime +${BACKUP_RETAIN} -type f -delete + find ${LOCAL_FOLDR}/${BACKUP_FOLD}/$(date +%Y)*.backup -mtime +${BACKUP_RETAIN} -type f -delete error_validate } \ No newline at end of file diff --git a/includes/gs-config.sh b/includes/gs-config.sh index 435a8fc..f66c659 100644 --- a/includes/gs-config.sh +++ b/includes/gs-config.sh @@ -10,147 +10,310 @@ function task_configure { MESSAGE="${MESSAGE}: ${TASKTYPE} Requested" echo_good - if [ -f $HOME/${LOCAL_FOLDR}/${CONFIG_FILE} ] + if [ -f ${LOCAL_FOLDR}/${CONFIG_FILE} ] then config_delete else - MESSAGE="No Active ${CONFIG_FILE}" - echo_warn - config_generate fi - backup_settime - backup_local_gravity - backup_local_custom - backup_cleanup + # backup_settime + # backup_local_gravity + # backup_local_custom + # backup_cleanup + + create_alias exit_withchange } ## Generate New Configuration function config_generate { - detect_ssh + # detect_ssh - MESSAGE="Creating ${CONFIG_FILE} from Template" + MESSAGE="Creating New ${CONFIG_FILE} from Template" echo_stat - cp $HOME/${LOCAL_FOLDR}/${CONFIG_FILE}.example $HOME/${LOCAL_FOLDR}/${CONFIG_FILE} + cp ${LOCAL_FOLDR}/${CONFIG_FILE}.example ${LOCAL_FOLDR}/${CONFIG_FILE} error_validate - - MESSAGE="Environment Customization" - echo_info - - MESSAGE="Enter a custom SSH port if required (Leave blank for default '22')" - echo_need - read INPUT_SSH_PORT - INPUT_SSH_PORT="${INPUT_SSH_PORT:-22}" - - if [ "${INPUT_SSH_PORT}" != "22" ] + + docker_detect + if [ "${DOCKERREADY}" == "1" ] then - MESSAGE="Saving Custom SSH Port to ${CONFIG_FILE}" - echo_stat - sed -i "/# SSH_PORT=''/c\SSH_PORT='${INPUT_SSH_PORT}'" $HOME/${LOCAL_FOLDR}/${CONFIG_FILE} - error_validate - fi - - MESSAGE="Perform PING tests between Pi-holes? (Leave blank for default 'Yes')" - echo_need - read INPUT_PING_AVOID - INPUT_PING_AVOID="${INPUT_PING_AVOID:-Y}" - - if [ "${INPUT_PING_AVOID}" != "Y" ] - then - MESSAGE="Saving Ping Avoidance to ${CONFIG_FILE}" - echo_stat - sed -i "/# PING_AVOID=''/c\PING_AVOID='1'" $HOME/${LOCAL_FOLDR}/${CONFIG_FILE} - error_validate - PING_AVOID=1 + MESSAGE="Advanced Configuration Required" + echo_info + advanced_config_generate + else + MESSAGE="Use Advanced Installation Options? (Leave blank for default 'No')" + echo_need + read INPUT_ADVANCED_INSTALL + INPUT_ADVANCED_INSTALL="${INPUT_ADVANCED_INSTALL:-N}" + + if [ "${INPUT_ADVANCED_INSTALL}" != "N" ] + then + MESSAGE="Advanced Configuration Selected" + echo_info + + advanced_config_generate + fi fi MESSAGE="Standard Settings" echo_info - MESSAGE="IP or DNS of Primary Pi-hole" + MESSAGE="Primary Pi-hole Address (IP or DNS)" echo_need read INPUT_REMOTE_HOST if [ "${PING_AVOID}" != "1" ] then - MESSAGE="Testing Network Connection (PING)" + MESSAGE="Testing Network Connection (ICMP)" echo_stat ping -c 3 ${INPUT_REMOTE_HOST} >/dev/null 2>&1 error_validate else - MESSAGE="Bypassing Network Testing (PING)" + MESSAGE="Bypassing Network Testing (ICMP)" echo_warn fi - MESSAGE="SSH User with SUDO rights" + MESSAGE="SSH User for ${INPUT_REMOTE_HOST}" echo_need read INPUT_REMOTE_USER MESSAGE="Saving Host to ${CONFIG_FILE}" echo_stat - sed -i "/REMOTE_HOST='192.168.1.10'/c\REMOTE_HOST='${INPUT_REMOTE_HOST}'" $HOME/${LOCAL_FOLDR}/${CONFIG_FILE} + sed -i "/REMOTE_HOST='192.168.1.10'/c\REMOTE_HOST='${INPUT_REMOTE_HOST}'" ${LOCAL_FOLDR}/${CONFIG_FILE} error_validate MESSAGE="Saving User to ${CONFIG_FILE}" echo_stat - sed -i "/REMOTE_USER='pi'/c\REMOTE_USER='${INPUT_REMOTE_USER}'" $HOME/${LOCAL_FOLDR}/${CONFIG_FILE} + sed -i "/REMOTE_USER='pi'/c\REMOTE_USER='${INPUT_REMOTE_USER}'" ${LOCAL_FOLDR}/${CONFIG_FILE} error_validate - if hash sshpass 2>/dev/null - then - MESSAGE="SSHPASS Utility Detected" - echo_warn - if hash ssh 2>/dev/null - then - MESSAGE="Please Reference Documentation" - echo_info - - MESSAGE="${BLUE}https://github.com/vmstan/gravity-sync/blob/master/ADVANCED.md#ssh-configuration${NC}" - echo_info - - MESSAGE="Leave password blank to use key-pair! (reccomended)" - echo_warn - - MESSAGE="SSH User Password" - echo_need - read INPUT_REMOTE_PASS - - MESSAGE="Saving Password to ${CONFIG_FILE}" - echo_stat - sed -i "/REMOTE_PASS=''/c\REMOTE_PASS='${INPUT_REMOTE_PASS}'" $HOME/${LOCAL_FOLDR}/${CONFIG_FILE} - error_validate - fi - fi - generate_sshkey MESSAGE="Importing New ${CONFIG_FILE}" echo_stat - source $HOME/${LOCAL_FOLDR}/${CONFIG_FILE} + source ${LOCAL_FOLDR}/${CONFIG_FILE} error_validate export_sshkey - MESSAGE="Testing Configuration" - echo_info + # MESSAGE="Testing Configuration" + # echo_info - validate_os_sshpass - validate_sqlite3 + # validate_os_sshpass + # validate_sqlite3 - detect_remotersync + # detect_remotersync +} + +## Advanced Configuration Options +function advanced_config_generate { + MESSAGE="Local Pi-hole in Docker Container? (Leave blank for default 'No')" + echo_need + read INPUT_PH_IN_TYPE + INPUT_PH_IN_TYPE="${INPUT_PH_IN_TYPE:-N}" + + if [ "${INPUT_PH_IN_TYPE}" != "N" ] + then + MESSAGE="Saving Local Docker Setting to ${CONFIG_FILE}" + echo_stat + sed -i "/# PH_IN_TYPE=''/c\PH_IN_TYPE='docker'" ${LOCAL_FOLDR}/${CONFIG_FILE} + error_validate + + MESSAGE="Local Docker Container Name? (Leave blank for default 'pihole')" + echo_need + read INPUT_DOCKER_CON + INPUT_DOCKER_CON="${INPUT_DOCKER_CON:-pihole}" + + if [ "${INPUT_DOCKER_CON}" != "pihole" ] + then + MESSAGE="Saving Local Container Name to ${CONFIG_FILE}" + echo_stat + sed -i "/# DOCKER_CON=''/c\DOCKER_CON='${INPUT_DOCKER_CON}'" ${LOCAL_FOLDR}/${CONFIG_FILE} + error_validate + fi + + MESSAGE="Local Pi-hole 'etc' Volume Path? (Required, no trailing slash)" + echo_need + read INPUT_PIHOLE_DIR + + if [ "${INPUT_PIHOLE_DIR}" != "" ] + then + MESSAGE="Saving Local Pi-hole Volume to ${CONFIG_FILE}" + echo_stat + sed -i "/# PIHOLE_DIR=''/c\PIHOLE_DIR='${INPUT_PIHOLE_DIR}'" ${LOCAL_FOLDR}/${CONFIG_FILE} + error_validate + SKIP_PIHOLE_DIR="1" + else + MESSAGE="This setting is required!" + echo_warn + exit_withchanges + fi + + MESSAGE="Saving Local Volume Ownership to ${CONFIG_FILE}" + echo_stat + sed -i "/# FILE_OWNER=''/c\FILE_OWNER='named:docker'" ${LOCAL_FOLDR}/${CONFIG_FILE} + error_validate + fi + + MESSAGE="Remote Pi-hole in Docker Container? (Leave blank for default 'No')" + echo_need + read INPUT_RH_IN_TYPE + INPUT_RH_IN_TYPE="${INPUT_RH_IN_TYPE:-N}" + + if [ "${INPUT_RH_IN_TYPE}" != "N" ] + then + MESSAGE="Saving Remote Docker Setting to ${CONFIG_FILE}" + echo_stat + sed -i "/# RH_IN_TYPE=''/c\RH_IN_TYPE='docker'" ${LOCAL_FOLDR}/${CONFIG_FILE} + error_validate + + MESSAGE="Remote Docker Container Name? (Leave blank for default 'pihole')" + echo_need + read INPUT_ROCKER_CON + INPUT_ROCKER_CON="${INPUT_ROCKER_CON:-pihole}" + + if [ "${INPUT_ROCKER_CON}" != "pihole" ] + then + MESSAGE="Saving Remote Container Name to ${CONFIG_FILE}" + echo_stat + sed -i "/# ROCKER_CON=''/c\ROCKER_CON='${INPUT_ROCKER_CON}'" ${LOCAL_FOLDR}/${CONFIG_FILE} + error_validate + fi + + MESSAGE="Remote Pi-hole 'etc' Volume Path? (Required, no trailing slash)" + echo_need + read INPUT_RIHOLE_DIR + + if [ "${INPUT_RIHOLE_DIR}" != "" ] + then + MESSAGE="Saving Remote Pi-hole Volume to ${CONFIG_FILE}" + echo_stat + sed -i "/# RIHOLE_DIR=''/c\RIHOLE_DIR='${INPUT_RIHOLE_DIR}'" ${LOCAL_FOLDR}/${CONFIG_FILE} + error_validate + SKIP_RIHOLE_DIR="1" + else + MESSAGE="This setting is required!" + echo_warn + exit_withchanges + fi + + MESSAGE="Saving Remote Volume Ownership to ${CONFIG_FILE}" + echo_stat + sed -i "/# RILE_OWNER=''/c\RILE_OWNER='named:docker'" ${LOCAL_FOLDR}/${CONFIG_FILE} + error_validate + fi + + + if [ $SKIP_PIHOLE_DIR != "1" ] + then + MESSAGE="Local Pi-hole Settings Directory Path? (Leave blank for default '/etc/pihole')" + echo_need + read INPUT_PIHOLE_DIR + INPUT_PIHOLE_DIR="${INPUT_PIHOLE_DIR:-/etc/pihole}" + + if [ "${INPUT_PIHOLE_DIR}" != "/etc/pihole" ] + then + MESSAGE="Saving Local Pi-hole Settings Directory Path to ${CONFIG_FILE}" + echo_stat + sed -i "/# PIHOLE_DIR=''/c\PIHOLE_DIR='${INPUT_PIHOLE_DIR}'" ${LOCAL_FOLDR}/${CONFIG_FILE} + error_validate + fi + fi + + if [ "$SKIP_RIHOLE_DIR" != "1" ] + then + MESSAGE="Remote Pi-hole Settings Directory Path? (Leave blank for default '/etc/pihole')" + echo_need + read INPUT_RIHOLE_DIR + INPUT_RIHOLE_DIR="${INPUT_RIHOLE_DIR:-/etc/pihole}" + + if [ "${INPUT_RIHOLE_DIR}" != "/etc/pihole" ] + then + MESSAGE="Saving Remote Pi-hole Settings Directory Path to ${CONFIG_FILE}" + echo_stat + sed -i "/# RIHOLE_DIR=''/c\RIHOLE_DIR='${INPUT_RIHOLE_DIR}'" ${LOCAL_FOLDR}/${CONFIG_FILE} + error_validate + fi + fi + + MESSAGE="Use Custom SSH Port? (Leave blank for default '22')" + echo_need + read INPUT_SSH_PORT + INPUT_SSH_PORT="${INPUT_SSH_PORT:-22}" + SSH_PORT="${INPUT_SSH_PORT}" + + if [ "${INPUT_SSH_PORT}" != "22" ] + then + MESSAGE="Saving Custom SSH Port to ${CONFIG_FILE}" + echo_stat + sed -i "/# SSH_PORT=''/c\SSH_PORT='${INPUT_SSH_PORT}'" ${LOCAL_FOLDR}/${CONFIG_FILE} + error_validate + fi + + MESSAGE="Enable ICMP Check? (Leave blank for default 'Yes')" + echo_need + read INPUT_PING_AVOID + INPUT_PING_AVOID="${INPUT_PING_AVOID:-Y}" + + if [ "${INPUT_PING_AVOID}" != "Y" ] + then + MESSAGE="Saving ICMP Avoidance to ${CONFIG_FILE}" + echo_stat + sed -i "/# PING_AVOID=''/c\PING_AVOID='1'" ${LOCAL_FOLDR}/${CONFIG_FILE} + error_validate + PING_AVOID=1 + fi + + MESSAGE="Use Custom SSH PKIF Location? (Leave blank for default '.ssh/id_rsa')" + echo_need + read INPUT_CUSTOM_PKIF + INPUT_CUSTOM_PKIF="${INPUT_CUSTOM_PKIF:-.ssh/id_rsa}" + + if [ "${INPUT_CUSTOM_PKIF}" != ".ssh/id_rsa" ] + then + MESSAGE="Saving Custom PKIF to ${CONFIG_FILE}" + echo_stat + sed -i "/# SSH_PKIF=''/c\SSH_PKIF='${INPUT_CUSTOM_PKIF}'" ${LOCAL_FOLDR}/${CONFIG_FILE} + error_validate + fi + + MESSAGE="Enable Replicate 'Local DNS Records' Feature? (Leave blank for default 'Yes')" + echo_need + read INPUT_SKIP_CUSTOM + INPUT_SKIP_CUSTOM="${INPUT_SKIP_CUSTOM:-Y}" + + if [ "${INPUT_SKIP_CUSTOM}" != "Y" ] + then + MESSAGE="Saving Local DNS Preference to ${CONFIG_FILE}" + echo_stat + sed -i "/# SKIP_CUSTOM=''/c\SKIP_CUSTOM='1'" ${LOCAL_FOLDR}/${CONFIG_FILE} + error_validate + fi + + MESSAGE="Change Backup Retention in Days? (Leave blank for default '7')" + echo_need + read INPUT_BACKUP_RETAIN + INPUT_BACKUP_RETAIN="${INPUT_BACKUP_RETAIN:-7}" + + if [ "${INPUT_BACKUP_RETAIN}" != "7" ] + then + MESSAGE="Saving Backup Retention to ${CONFIG_FILE}" + echo_stat + sed -i "/# BACKUP_RETAIN=''/c\BACKUP_RETAIN='1'" ${LOCAL_FOLDR}/${CONFIG_FILE} + error_validate + fi } ## Delete Existing Configuration function config_delete { - source $HOME/${LOCAL_FOLDR}/${CONFIG_FILE} + source ${LOCAL_FOLDR}/${CONFIG_FILE} MESSAGE="Configuration File Exists" echo_warn echo -e "========================================================" - cat $HOME/${LOCAL_FOLDR}/${CONFIG_FILE} + cat ${LOCAL_FOLDR}/${CONFIG_FILE} echo -e "========================================================" MESSAGE="Are you sure you want to erase this configuration?" @@ -160,8 +323,29 @@ function config_delete { MESSAGE="Erasing Existing Configuration" echo_stat - rm -f $HOME/${LOCAL_FOLDR}/${CONFIG_FILE} + rm -f ${LOCAL_FOLDR}/${CONFIG_FILE} error_validate config_generate +} + +## Detect Docker +function docker_detect { + if hash docker 2>/dev/null + then + FTLCHECK=$(sudo docker container ls | grep 'pihole/pihole') + if [ "$FTLCHECK" != "" ] + then + DOCKERREADY="1" + fi + fi +} + +## Create Bash Alias +function create_alias { + MESSAGE="Creating Bash Alias" + echo_stat + + echo -e "alias gravity-sync='${GS_FILEPATH}'" | sudo tee -a /etc/bash.bashrc > /dev/null + error_validate } \ No newline at end of file diff --git a/includes/gs-core.sh b/includes/gs-core.sh index b4bd81e..de9766a 100644 --- a/includes/gs-core.sh +++ b/includes/gs-core.sh @@ -8,9 +8,9 @@ function import_gs { MESSAGE="Importing ${CONFIG_FILE} Settings" echo -en "${STAT} $MESSAGE" - if [ -f $HOME/${LOCAL_FOLDR}/${CONFIG_FILE} ] + if [ -f ${LOCAL_FOLDR}/${CONFIG_FILE} ] then - source $HOME/${LOCAL_FOLDR}/${CONFIG_FILE} + source ${LOCAL_FOLDR}/${CONFIG_FILE} error_validate # MESSAGE="Targeting ${REMOTE_USER}@${REMOTE_HOST}" @@ -45,19 +45,39 @@ function error_validate { fi } +function ph_type { + if [ "$PH_IN_TYPE" == "default" ] + then + PH_EXEC="${PIHOLE_BIN}" + elif [ "$PH_IN_TYPE" == "docker" ] + then + PH_EXEC="${DOCKER_BIN} exec -it ${DOCKER_CON} pihole" + fi + + if [ "$RH_IN_TYPE" == "default" ] + then + RH_EXEC="${RIHOLE_BIN}" + elif [ "$RH_IN_TYPE" == "docker" ] + then + RH_EXEC="${ROCKER_BIN} exec -it ${DOCKER_CON} pihole" + fi +} + # Standard Output function start_gs { MESSAGE="${PROGRAM} ${VERSION} Executing" echo_info + cd ${LOCAL_FOLDR} import_gs + ph_type MESSAGE="Evaluating Arguments" echo_stat if [ "${ROOT_CHECK_AVOID}" != "1" ] then - root_check + new_root_check fi } @@ -65,6 +85,7 @@ function start_gs { function start_gs_noconfig { MESSAGE="${PROGRAM} ${VERSION} Executing" echo_info + cd ${LOCAL_FOLDR} MESSAGE="Evaluating Arguments" echo_stat diff --git a/includes/gs-hashing.sh b/includes/gs-hashing.sh index e6f2dc4..8eed765 100644 --- a/includes/gs-hashing.sh +++ b/includes/gs-hashing.sh @@ -10,7 +10,7 @@ function md5_compare { MESSAGE="Analyzing ${GRAVITY_FI} on ${REMOTE_HOST}" echo_stat - primaryDBMD5=$(${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "md5sum ${PIHOLE_DIR}/${GRAVITY_FI}" | sed 's/\s.*$//') + primaryDBMD5=$(${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "md5sum ${RIHOLE_DIR}/${GRAVITY_FI}" | sed 's/\s.*$//') error_validate MESSAGE="Analyzing ${GRAVITY_FI} on $HOSTNAME" @@ -31,13 +31,13 @@ function md5_compare { then if [ -f ${PIHOLE_DIR}/${CUSTOM_DNS} ] then - if ${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${PIHOLE_DIR}/${CUSTOM_DNS} + if ${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${RIHOLE_DIR}/${CUSTOM_DNS} then REMOTE_CUSTOM_DNS="1" MESSAGE="Analyzing ${CUSTOM_DNS} on ${REMOTE_HOST}" echo_stat - primaryCLMD5=$(${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "md5sum ${PIHOLE_DIR}/${CUSTOM_DNS} | sed 's/\s.*$//'") + primaryCLMD5=$(${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "md5sum ${RIHOLE_DIR}/${CUSTOM_DNS} | sed 's/\s.*$//'") error_validate MESSAGE="Analyzing ${CUSTOM_DNS} on $HOSTNAME" @@ -58,7 +58,7 @@ function md5_compare { echo_info fi else - if ${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${PIHOLE_DIR}/${CUSTOM_DNS} + if ${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${RIHOLE_DIR}/${CUSTOM_DNS} then REMOTE_CUSTOM_DNS="1" MESSAGE="${REMOTE_HOST} has ${CUSTOM_DNS}" @@ -105,7 +105,7 @@ function md5_recheck { MESSAGE="Reanalyzing ${GRAVITY_FI} on ${REMOTE_HOST}" echo_stat - primaryDBMD5=$(${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "md5sum ${PIHOLE_DIR}/${GRAVITY_FI}" | sed 's/\s.*$//') + primaryDBMD5=$(${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "md5sum ${RIHOLE_DIR}/${GRAVITY_FI}" | sed 's/\s.*$//') error_validate MESSAGE="Reanalyzing ${GRAVITY_FI} on $HOSTNAME" @@ -117,13 +117,13 @@ function md5_recheck { then if [ -f ${PIHOLE_DIR}/${CUSTOM_DNS} ] then - if ${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${PIHOLE_DIR}/${CUSTOM_DNS} + if ${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${RIHOLE_DIR}/${CUSTOM_DNS} then REMOTE_CUSTOM_DNS="1" MESSAGE="Reanalyzing ${CUSTOM_DNS} on ${REMOTE_HOST}" echo_stat - primaryCLMD5=$(${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "md5sum ${PIHOLE_DIR}/${CUSTOM_DNS} | sed 's/\s.*$//'") + primaryCLMD5=$(${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "md5sum ${RIHOLE_DIR}/${CUSTOM_DNS} | sed 's/\s.*$//'") error_validate MESSAGE="Reanalyzing ${CUSTOM_DNS} on $HOSTNAME" @@ -135,7 +135,7 @@ function md5_recheck { echo_info fi else - if ${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${PIHOLE_DIR}/${CUSTOM_DNS} + if ${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${RIHOLE_DIR}/${CUSTOM_DNS} then REMOTE_CUSTOM_DNS="1" MESSAGE="${REMOTE_HOST} has ${CUSTOM_DNS}" diff --git a/includes/gs-pull.sh b/includes/gs-pull.sh index 951ac07..def9d0b 100644 --- a/includes/gs-pull.sh +++ b/includes/gs-pull.sh @@ -29,35 +29,44 @@ function pull_gs_grav { MESSAGE="Pulling ${GRAVITY_FI} from ${REMOTE_HOST}" echo_stat RSYNC_REPATH="rsync" - RSYNC_SOURCE="${REMOTE_USER}@${REMOTE_HOST}:${PIHOLE_DIR}/${GRAVITY_FI}.backup" - RSYNC_TARGET="$HOME/${LOCAL_FOLDR}/${BACKUP_FOLD}/${GRAVITY_FI}.pull" + RSYNC_SOURCE="${REMOTE_USER}@${REMOTE_HOST}:${RIHOLE_DIR}/${GRAVITY_FI}.backup" + RSYNC_TARGET="${LOCAL_FOLDR}/${BACKUP_FOLD}/${GRAVITY_FI}.pull" create_rsynccmd MESSAGE="Replacing ${GRAVITY_FI} on $HOSTNAME" echo_stat - sudo cp $HOME/${LOCAL_FOLDR}/${BACKUP_FOLD}/${GRAVITY_FI}.pull ${PIHOLE_DIR}/${GRAVITY_FI} >/dev/null 2>&1 + sudo cp ${LOCAL_FOLDR}/${BACKUP_FOLD}/${GRAVITY_FI}.pull ${PIHOLE_DIR}/${GRAVITY_FI} >/dev/null 2>&1 error_validate - MESSAGE="Validating Settings of ${GRAVITY_FI}" - echo_stat - - GRAVDB_OWN=$(ls -ld ${PIHOLE_DIR}/${GRAVITY_FI} | awk 'OFS=":" {print $3,$4}') - if [ "$GRAVDB_OWN" != "$FILE_OWNER" ] - then - MESSAGE="Validating Ownership on ${GRAVITY_FI}" - echo_fail - - MESSAGE="Attempting to Compensate" - echo_warn - - MESSAGE="Setting Ownership on ${GRAVITY_FI}" - echo_stat - sudo chown ${FILE_OWNER} ${PIHOLE_DIR}/${GRAVITY_FI} >/dev/null 2>&1 - error_validate - - MESSAGE="Continuing Validation of ${GRAVITY_FI}" - echo_stat - fi + if [ "$FILE_OWNER" != "named:docker" ] + then + MESSAGE="Validating Settings of ${GRAVITY_FI}" + echo_stat + + GRAVDB_OWN=$(ls -ld ${PIHOLE_DIR}/${GRAVITY_FI} | awk 'OFS=":" {print $3,$4}') + if [ "$GRAVDB_OWN" != "$FILE_OWNER" ] + then + MESSAGE="Validating Ownership on ${GRAVITY_FI}" + echo_fail + + MESSAGE="Attempting to Compensate" + echo_warn + + MESSAGE="Setting Ownership on ${GRAVITY_FI}" + echo_stat + sudo chown ${FILE_OWNER} ${PIHOLE_DIR}/${GRAVITY_FI} >/dev/null 2>&1 + error_validate + + MESSAGE="Continuing Validation of ${GRAVITY_FI}" + echo_stat + fi + else + MESSAGE="Setting Ownership on ${GRAVITY_FI}" + echo_stat + sudo chown ${FILE_OWNER} ${PIHOLE_DIR}/${GRAVITY_FI} >/dev/null 2>&1 + error_validate + fi + GRAVDB_RWE=$(namei -m ${PIHOLE_DIR}/${GRAVITY_FI} | grep -v f: | grep ${GRAVITY_FI} | awk '{print $1}') if [ "$GRAVDB_RWE" != "-rw-rw-r--" ] @@ -92,13 +101,13 @@ function pull_gs_cust { MESSAGE="Pulling ${CUSTOM_DNS} from ${REMOTE_HOST}" echo_stat RSYNC_REPATH="rsync" - RSYNC_SOURCE="${REMOTE_USER}@${REMOTE_HOST}:${PIHOLE_DIR}/${CUSTOM_DNS}.backup" - RSYNC_TARGET="$HOME/${LOCAL_FOLDR}/${BACKUP_FOLD}/${CUSTOM_DNS}.pull" + RSYNC_SOURCE="${REMOTE_USER}@${REMOTE_HOST}:${RIHOLE_DIR}/${CUSTOM_DNS}.backup" + RSYNC_TARGET="${LOCAL_FOLDR}/${BACKUP_FOLD}/${CUSTOM_DNS}.pull" create_rsynccmd MESSAGE="Replacing ${CUSTOM_DNS} on $HOSTNAME" echo_stat - sudo cp $HOME/${LOCAL_FOLDR}/${BACKUP_FOLD}/${CUSTOM_DNS}.pull ${PIHOLE_DIR}/${CUSTOM_DNS} >/dev/null 2>&1 + sudo cp ${LOCAL_FOLDR}/${BACKUP_FOLD}/${CUSTOM_DNS}.pull ${PIHOLE_DIR}/${CUSTOM_DNS} >/dev/null 2>&1 error_validate MESSAGE="Validating Settings on ${CUSTOM_DNS}" @@ -153,12 +162,12 @@ function pull_gs_reload { MESSAGE="Updating FTLDNS Configuration" echo_stat - ${PIHOLE_BIN} restartdns reloadlists >/dev/null 2>&1 + ${PH_EXEC} restartdns reloadlists >/dev/null 2>&1 error_validate MESSAGE="Reloading FTLDNS Services" echo_stat - ${PIHOLE_BIN} restartdns >/dev/null 2>&1 + ${PH_EXEC} restartdns >/dev/null 2>&1 error_validate } diff --git a/includes/gs-purge.sh b/includes/gs-purge.sh index 4b91eab..0cd00bc 100644 --- a/includes/gs-purge.sh +++ b/includes/gs-purge.sh @@ -19,10 +19,10 @@ function task_purge { MESSAGE="- Your ${CONFIG_FILE} file." echo_warn - if [ -f "$HOME/${LOCAL_FOLDR}/dev" ] + if [ -f "${LOCAL_FOLDR}/dev" ] then MESSAGE="- Your development branch updater." - elif [ -f "$HOME/${LOCAL_FOLDR}/beta" ] + elif [ -f "${LOCAL_FOLDR}/beta" ] then MESSAGE="- Your beta branch updater." fi diff --git a/includes/gs-push.sh b/includes/gs-push.sh index dd64617..4fccbf1 100644 --- a/includes/gs-push.sh +++ b/includes/gs-push.sh @@ -28,27 +28,27 @@ function push_gs_grav { MESSAGE="Copying ${GRAVITY_FI} from ${REMOTE_HOST}" echo_stat RSYNC_REPATH="rsync" - RSYNC_SOURCE="${REMOTE_USER}@${REMOTE_HOST}:${PIHOLE_DIR}/${GRAVITY_FI}.backup" - RSYNC_TARGET="$HOME/${LOCAL_FOLDR}/${BACKUP_FOLD}/${GRAVITY_FI}.push" + RSYNC_SOURCE="${REMOTE_USER}@${REMOTE_HOST}:${RIHOLE_DIR}/${GRAVITY_FI}.backup" + RSYNC_TARGET="${LOCAL_FOLDR}/${BACKUP_FOLD}/${GRAVITY_FI}.push" create_rsynccmd MESSAGE="Pushing ${GRAVITY_FI} to ${REMOTE_HOST}" echo_stat RSYNC_REPATH="sudo rsync" - RSYNC_SOURCE="$HOME/${LOCAL_FOLDR}/${BACKUP_FOLD}/${BACKUPTIMESTAMP}-${GRAVITY_FI}.backup" - RSYNC_TARGET="${REMOTE_USER}@${REMOTE_HOST}:${PIHOLE_DIR}/${GRAVITY_FI}" + RSYNC_SOURCE="${LOCAL_FOLDR}/${BACKUP_FOLD}/${BACKUPTIMESTAMP}-${GRAVITY_FI}.backup" + RSYNC_TARGET="${REMOTE_USER}@${REMOTE_HOST}:${RIHOLE_DIR}/${GRAVITY_FI}" create_rsynccmd MESSAGE="Setting Permissions on ${GRAVITY_FI}" echo_stat CMD_TIMEOUT='15' - CMD_REQUESTED="sudo chmod 664 ${PIHOLE_DIR}/${GRAVITY_FI}" + CMD_REQUESTED="sudo chmod 664 ${RIHOLE_DIR}/${GRAVITY_FI}" create_sshcmd MESSAGE="Setting Ownership on ${GRAVITY_FI}" echo_stat CMD_TIMEOUT='15' - CMD_REQUESTED="sudo chown ${REMOTE_FILE_OWNER} ${PIHOLE_DIR}/${GRAVITY_FI}" + CMD_REQUESTED="sudo chown ${RILE_OWNER} ${RIHOLE_DIR}/${GRAVITY_FI}" create_sshcmd } @@ -64,27 +64,27 @@ function push_gs_cust { MESSAGE="Copying ${CUSTOM_DNS} from ${REMOTE_HOST}" echo_stat RSYNC_REPATH="rsync" - RSYNC_SOURCE="${REMOTE_USER}@${REMOTE_HOST}:${PIHOLE_DIR}/${CUSTOM_DNS}.backup" - RSYNC_TARGET="$HOME/${LOCAL_FOLDR}/${BACKUP_FOLD}/${CUSTOM_DNS}.push" + RSYNC_SOURCE="${REMOTE_USER}@${REMOTE_HOST}:${RIHOLE_DIR}/${CUSTOM_DNS}.backup" + RSYNC_TARGET="${LOCAL_FOLDR}/${BACKUP_FOLD}/${CUSTOM_DNS}.push" create_rsynccmd MESSAGE="Pushing ${CUSTOM_DNS} to ${REMOTE_HOST}" echo_stat RSYNC_REPATH="sudo rsync" - RSYNC_SOURCE="$HOME/${LOCAL_FOLDR}/${BACKUP_FOLD}/${BACKUPTIMESTAMP}-${CUSTOM_DNS}.backup" - RSYNC_TARGET="${REMOTE_USER}@${REMOTE_HOST}:${PIHOLE_DIR}/${CUSTOM_DNS}" + RSYNC_SOURCE="${LOCAL_FOLDR}/${BACKUP_FOLD}/${BACKUPTIMESTAMP}-${CUSTOM_DNS}.backup" + RSYNC_TARGET="${REMOTE_USER}@${REMOTE_HOST}:${RIHOLE_DIR}/${CUSTOM_DNS}" create_rsynccmd MESSAGE="Setting Permissions on ${CUSTOM_DNS}" echo_stat CMD_TIMEOUT='15' - CMD_REQUESTED="sudo chmod 644 ${PIHOLE_DIR}/${CUSTOM_DNS}" + CMD_REQUESTED="sudo chmod 644 ${RIHOLE_DIR}/${CUSTOM_DNS}" create_sshcmd MESSAGE="Setting Ownership on ${CUSTOM_DNS}" echo_stat CMD_TIMEOUT='15' - CMD_REQUESTED="sudo chown root:root ${PIHOLE_DIR}/${CUSTOM_DNS}" + CMD_REQUESTED="sudo chown root:root ${RIHOLE_DIR}/${CUSTOM_DNS}" create_sshcmd fi fi @@ -99,13 +99,13 @@ function push_gs_reload { MESSAGE="Updating Remote FTLDNS Configuration" echo_stat CMD_TIMEOUT='15' - CMD_REQUESTED="${RIHOLE_BIN} restartdns reloadlists" + CMD_REQUESTED="${RH_EXEC} restartdns reloadlists" create_sshcmd MESSAGE="Reloading Remote FTLDNS Services" echo_stat CMD_TIMEOUT='15' - CMD_REQUESTED="${RIHOLE_BIN} restartdns" + CMD_REQUESTED="${RH_EXEC} restartdns" create_sshcmd } diff --git a/includes/gs-restore.sh b/includes/gs-restore.sh index f1f1db0..de3558d 100644 --- a/includes/gs-restore.sh +++ b/includes/gs-restore.sh @@ -26,13 +26,13 @@ function restore_gs { MESSAGE="PREVIOUS BACKUPS AVAILABLE FOR RESTORATION" echo_info - ls $HOME/${LOCAL_FOLDR}/${BACKUP_FOLD} | grep $(date +%Y) | grep ${GRAVITY_FI} | colrm 18 + ls ${LOCAL_FOLDR}/${BACKUP_FOLD} | grep $(date +%Y) | grep ${GRAVITY_FI} | colrm 18 MESSAGE="Select backup date to restore ${GRAVITY_FI} from" echo_need read INPUT_BACKUP_DATE - if [ -f $HOME/${LOCAL_FOLDR}/${BACKUP_FOLD}/${INPUT_BACKUP_DATE}-${GRAVITY_FI}.backup ] + if [ -f ${LOCAL_FOLDR}/${BACKUP_FOLD}/${INPUT_BACKUP_DATE}-${GRAVITY_FI}.backup ] then MESSAGE="Backup File Selected" else @@ -47,13 +47,13 @@ function restore_gs { if [ -f ${PIHOLE_DIR}/${CUSTOM_DNS} ] then - ls $HOME/${LOCAL_FOLDR}/${BACKUP_FOLD} | grep $(date +%Y) | grep ${CUSTOM_DNS} | colrm 18 + ls ${LOCAL_FOLDR}/${BACKUP_FOLD} | grep $(date +%Y) | grep ${CUSTOM_DNS} | colrm 18 MESSAGE="Select backup date to restore ${CUSTOM_DNS} from" echo_need read INPUT_DNSBACKUP_DATE - if [ -f $HOME/${LOCAL_FOLDR}/${BACKUP_FOLD}/${INPUT_DNSBACKUP_DATE}-${CUSTOM_DNS}.backup ] + if [ -f ${LOCAL_FOLDR}/${BACKUP_FOLD}/${INPUT_DNSBACKUP_DATE}-${CUSTOM_DNS}.backup ] then MESSAGE="Backup File Selected" else @@ -83,7 +83,7 @@ function restore_gs { MESSAGE="Restoring ${GRAVITY_FI} on $HOSTNAME" echo_stat - sudo cp $HOME/${LOCAL_FOLDR}/${BACKUP_FOLD}/${INPUT_BACKUP_DATE}-${GRAVITY_FI}.backup ${PIHOLE_DIR}/${GRAVITY_FI} >/dev/null 2>&1 + sudo cp ${LOCAL_FOLDR}/${BACKUP_FOLD}/${INPUT_BACKUP_DATE}-${GRAVITY_FI}.backup ${PIHOLE_DIR}/${GRAVITY_FI} >/dev/null 2>&1 error_validate MESSAGE="Validating Ownership on ${GRAVITY_FI}" @@ -126,11 +126,11 @@ function restore_gs { if [ "$SKIP_CUSTOM" != '1' ] then - if [ -f $HOME/${LOCAL_FOLDR}/${BACKUP_FOLD}/${INPUT_DNSBACKUP_DATE}-${CUSTOM_DNS}.backup ] + if [ -f ${LOCAL_FOLDR}/${BACKUP_FOLD}/${INPUT_DNSBACKUP_DATE}-${CUSTOM_DNS}.backup ] then MESSAGE="Restoring ${CUSTOM_DNS} on $HOSTNAME" echo_stat - sudo cp $HOME/${LOCAL_FOLDR}/${BACKUP_FOLD}/${INPUT_DNSBACKUP_DATE}-${CUSTOM_DNS}.backup ${PIHOLE_DIR}/${CUSTOM_DNS} >/dev/null 2>&1 + sudo cp ${LOCAL_FOLDR}/${BACKUP_FOLD}/${INPUT_DNSBACKUP_DATE}-${CUSTOM_DNS}.backup ${PIHOLE_DIR}/${CUSTOM_DNS} >/dev/null 2>&1 error_validate MESSAGE="Validating Ownership on ${CUSTOM_DNS}" @@ -173,20 +173,7 @@ function restore_gs { fi fi - MESSAGE="Evacuating Saucer Section" - echo_info - sleep 1 - - MESSAGE="Restarting FTLDNS Services" - echo_stat - sudo service pihole-FTL start >/dev/null 2>&1 - error_validate - - MESSAGE="Updating FTLDNS Configuration" - echo_stat - ${PIHOLE_BIN} restartdns reloadlists >/dev/null 2>&1 - error_validate - + pull_gs_reload MESSAGE="Do you want to push the restored configuration to the primary Pi-hole? (yes/no)" echo_need diff --git a/includes/gs-root.sh b/includes/gs-root.sh index 4ae6f98..2b959ca 100644 --- a/includes/gs-root.sh +++ b/includes/gs-root.sh @@ -14,13 +14,13 @@ function task_sudo { echo_stat NEW_SUDO_USER=$(whoami) - echo -e "${NEW_SUDO_USER} ALL=(ALL) NOPASSWD: ALL" > $HOME/${LOCAL_FOLDR}/templates/gs-nopasswd.sudo + echo -e "${NEW_SUDO_USER} ALL=(ALL) NOPASSWD: ALL" > ${LOCAL_FOLDR}/templates/gs-nopasswd.sudo error_validate MESSAGE="Installing Sudoer.d File" echo_stat - sudo install -m 0440 $HOME/${LOCAL_FOLDR}/templates/gs-nopasswd.sudo /etc/sudoers.d/gs-nopasswd + sudo install -m 0440 ${LOCAL_FOLDR}/templates/gs-nopasswd.sudo /etc/sudoers.d/gs-nopasswd error_validate exit_withchange @@ -37,6 +37,35 @@ function root_check { MESSAGE="${PROGRAM} Should Not Run As 'root'" echo_warn + exit_nochange + fi +} + +function new_root_check { + CURRENTUSER=$(whoami) + if [ ! "$EUID" -ne 0 ] + then + LOCALADMIN="" + else + # Check Sudo + SUDOCHECK=$(groups ${CURRENTUSER} | grep 'sudo') + if [ "$SUDOCHECK" == "" ] + then + LOCALADMIN="nosudo" + else + LOCALADMIN="sudo" + fi + fi + + if [ "$LOCALADMIN" == "nosudo" ] + then + TASKTYPE='ROOT' + MESSAGE="${MESSAGE} ${TASKTYPE}" + echo_fail + + MESSAGE="Insufficent User Rights" + echo_warn + exit_nochange fi } \ No newline at end of file diff --git a/includes/gs-smart.sh b/includes/gs-smart.sh index 8754a2d..ed3a03c 100644 --- a/includes/gs-smart.sh +++ b/includes/gs-smart.sh @@ -22,6 +22,9 @@ function task_smart { ## Smart Sync Function function smart_gs { + MESSAGE="Starting ${TASKTYPE} Analysis" + echo_info + previous_md5 md5_compare backup_settime @@ -45,22 +48,22 @@ function smart_gs { then if [ "${PRIDBCHANGE}" != "0" ] then - MESSAGE="Both ${GRAVITY_FI} Changed" + MESSAGE="Both ${GRAVITY_FI} Have Changed" echo_warn - PRIDBDATE=$(${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "stat -c %Y ${PIHOLE_DIR}/${GRAVITY_FI}") + PRIDBDATE=$(${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "stat -c %Y ${RIHOLE_DIR}/${GRAVITY_FI}") SECDBDATE=$(stat -c %Y ${PIHOLE_DIR}/${GRAVITY_FI}) - if [ "${PRIDBDATE}" -gt "$SECDBDATE" ] + if (( "$PRIDBDATE" >= "$SECDBDATE" )) then MESSAGE="Primary ${GRAVITY_FI} Last Changed" - echo_info + echo_warn pull_gs_grav PULLRESTART="1" else MESSAGE="Secondary ${GRAVITY_FI} Last Changed" - echo_info + echo_warn push_gs_grav PUSHRESTART="1" @@ -98,22 +101,22 @@ function smart_gs { then if [ "${PRICLCHANGE}" != "0" ] then - MESSAGE="Both ${CUSTOM_DNS} Changed" + MESSAGE="Both ${CUSTOM_DNS} Have Changed" echo_warn - PRICLDATE=$(${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "stat -c %Y ${PIHOLE_DIR}/${CUSTOM_DNS}") + PRICLDATE=$(${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "stat -c %Y ${RIHOLE_DIR}/${CUSTOM_DNS}") SECCLDATE=$(stat -c %Y ${PIHOLE_DIR}/${CUSTOM_DNS}) - if [ "${PRICLDATE}" -gt "${SECCLDATE}" ] + if (( "$PRICLDATE" >= "$SECCLDATE" )) then MESSAGE="Primary ${CUSTOM_DNS} Last Changed" - echo_info + echo_warn pull_gs_cust PULLRESTART="1" else MESSAGE="Secondary ${CUSTOM_DNS} Last Changed" - echo_info + echo_warn push_gs_cust PUSHRESTART="1" diff --git a/includes/gs-ssh.sh b/includes/gs-ssh.sh index e77828d..324df16 100644 --- a/includes/gs-ssh.sh +++ b/includes/gs-ssh.sh @@ -6,32 +6,32 @@ ## Determine SSH Pathways function create_sshcmd { - if hash ssh 2>/dev/null - then - if [ -z "$SSHPASSWORD" ] - then + # if hash ssh 2>/dev/null + # then + # if [ -z "$SSHPASSWORD" ] + # then timeout --preserve-status ${CMD_TIMEOUT} ${SSH_CMD} -p ${SSH_PORT} -i $HOME/${SSH_PKIF} -o StrictHostKeyChecking=no ${REMOTE_USER}@${REMOTE_HOST} "${CMD_REQUESTED}" error_validate - else - timeout --preserve-status ${CMD_TIMEOUT} ${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -o StrictHostKeyChecking=no ${REMOTE_USER}@${REMOTE_HOST} "${CMD_REQUESTED}" - error_validate - fi - fi + # else + # timeout --preserve-status ${CMD_TIMEOUT} ${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -o StrictHostKeyChecking=no ${REMOTE_USER}@${REMOTE_HOST} "${CMD_REQUESTED}" + # error_validate + # fi + # fi } ## Determine SSH Pathways function create_rsynccmd { - if hash ssh 2>/dev/null - then - if [ -z "$SSHPASSWORD" ] - then + # if hash ssh 2>/dev/null + # then + # if [ -z "$SSHPASSWORD" ] + # then rsync --rsync-path="${RSYNC_REPATH}" -e "${SSH_CMD} -p ${SSH_PORT} -i $HOME/${SSH_PKIF}" ${RSYNC_SOURCE} ${RSYNC_TARGET} >/dev/null 2>&1 error_validate - else - rsync --rsync-path="${RSYNC_REPATH}" -e "${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i $HOME/${SSH_PKIF}" ${RSYNC_SOURCE} ${RSYNC_TARGET} >/dev/null 2>&1 - error_validate - fi - fi + # else + # rsync --rsync-path="${RSYNC_REPATH}" -e "${SSHPASSWORD} ${SSH_CMD} -p ${SSH_PORT} -i $HOME/${SSH_PKIF}" ${RSYNC_SOURCE} ${RSYNC_TARGET} >/dev/null 2>&1 + # error_validate + # fi + # fi } ## Detect SSH-KEYGEN @@ -160,13 +160,13 @@ function detect_remotersync { RSYNC_REPATH="rsync" RSYNC_SOURCE="${REMOTE_USER}@${REMOTE_HOST}:~/gs.test" - RSYNC_TARGET="$HOME/${LOCAL_FOLDR}/gs.test" + RSYNC_TARGET="${LOCAL_FOLDR}/gs.test" create_rsynccmd MESSAGE="Cleaning Up Local Test File" echo_stat - rm $HOME/${LOCAL_FOLDR}/gs.test + rm ${LOCAL_FOLDR}/gs.test error_validate MESSAGE="Cleaning Up Remote Test File" diff --git a/includes/gs-update.sh b/includes/gs-update.sh index f6ae97e..be3a4e9 100644 --- a/includes/gs-update.sh +++ b/includes/gs-update.sh @@ -6,9 +6,9 @@ ## Master Branch function update_gs { - if [ -f "$HOME/${LOCAL_FOLDR}/dev" ] + if [ -f "${LOCAL_FOLDR}/dev" ] then - source $HOME/${LOCAL_FOLDR}/dev + source ${LOCAL_FOLDR}/dev else BRANCH='origin/master' fi @@ -46,10 +46,10 @@ function show_version { MESSAGE="${BLUE}https://github.com/vmstan/gravity-sync${NC}" echo_info - if [ -f $HOME/${LOCAL_FOLDR}/dev ] + if [ -f ${LOCAL_FOLDR}/dev ] then DEVVERSION="dev" - elif [ -f $HOME/${LOCAL_FOLDR}/beta ] + elif [ -f ${LOCAL_FOLDR}/beta ] then DEVVERSION="beta" else @@ -81,27 +81,27 @@ function task_devmode { MESSAGE="${MESSAGE}: ${TASKTYPE} Requested" echo_good - if [ -f $HOME/${LOCAL_FOLDR}/dev ] + if [ -f ${LOCAL_FOLDR}/dev ] then MESSAGE="Disabling ${TASKTYPE}" echo_stat - rm -f $HOME/${LOCAL_FOLDR}/dev + rm -f ${LOCAL_FOLDR}/dev error_validate - elif [ -f $HOME/${LOCAL_FOLDR}/beta ] + elif [ -f ${LOCAL_FOLDR}/beta ] then MESSAGE="Disabling BETA" echo_stat - rm -f $HOME/${LOCAL_FOLDR}/beta + rm -f ${LOCAL_FOLDR}/beta error_validate MESSAGE="Enabling ${TASKTYPE}" echo_stat - touch $HOME/${LOCAL_FOLDR}/dev + touch ${LOCAL_FOLDR}/dev error_validate else MESSAGE="Enabling ${TASKTYPE}" echo_stat - touch $HOME/${LOCAL_FOLDR}/dev + touch ${LOCAL_FOLDR}/dev error_validate MESSAGE="Updating Cache" @@ -115,7 +115,7 @@ function task_devmode { echo_need read INPUT_BRANCH - echo -e "BRANCH='${INPUT_BRANCH}'" >> $HOME/${LOCAL_FOLDR}/dev + echo -e "BRANCH='${INPUT_BRANCH}'" >> ${LOCAL_FOLDR}/dev fi update_gs diff --git a/includes/gs-validate.sh b/includes/gs-validate.sh index 96f90a8..fb4810f 100644 --- a/includes/gs-validate.sh +++ b/includes/gs-validate.sh @@ -8,16 +8,16 @@ function validate_gs_folders { MESSAGE="Validating ${PROGRAM} Folders on $HOSTNAME" echo_stat - if [ ! -d $HOME/${LOCAL_FOLDR} ] + if [ ! -d ${LOCAL_FOLDR} ] then - MESSAGE="Unable to Find $HOME/${LOCAL_FOLDR}" + MESSAGE="Unable to Validate ${PROGRAM} Folders on $HOSTNAME" echo_fail exit_nochange fi - if [ ! -d $HOME/${LOCAL_FOLDR}/${BACKUP_FOLD} ] + if [ ! -d ${LOCAL_FOLDR}/${BACKUP_FOLD} ] then - MESSAGE="Unable to Find $HOME/${LOCAL_FOLDR}/${BACKUP_FOLD}" + MESSAGE="Unable to Validate ${PROGRAM} Backup Folder on $HOSTNAME" echo_fail exit_nochange fi @@ -26,13 +26,26 @@ function validate_gs_folders { ## Validate Pi-hole Folders function validate_ph_folders { - MESSAGE="Validating Pi-hole Configuration on $HOSTNAME" + MESSAGE="Validating Pi-hole Configuration" echo_stat - if [ ! -f ${PIHOLE_BIN} ] + + if [ "$PH_IN_TYPE" == "default" ] then - MESSAGE="Unable to Validate Pi-Hole is Installed" - echo_fail - exit_nochange + if [ ! -f ${PIHOLE_BIN} ] + then + MESSAGE="Unable to Validate that Pi-Hole is Installed" + echo_fail + exit_nochange + fi + elif [ "$PH_IN_TYPE" == "docker" ] + then + FTLCHECK=$(sudo docker container ls | grep 'pihole/pihole') + if [ "$FTLCHECK" == "" ] + then + MESSAGE="Unable to Validate that Pi-Hole is Installed" + echo_fail + exit_nochange + fi fi if [ ! -d ${PIHOLE_DIR} ] @@ -50,10 +63,10 @@ function validate_sqlite3 { echo_stat if hash sqlite3 2>/dev/null then - MESSAGE="SQLITE3 Utility Detected" + # MESSAGE="SQLITE3 Utility Detected" echo_good else - MESSAGE="SQLITE3 Utility Missing" + MESSAGE="Unable to Validate SQLITE Install on $HOSTNAME" echo_warn MESSAGE="Installing SQLLITE3 with ${PKG_MANAGER}" @@ -66,36 +79,36 @@ function validate_sqlite3 { ## Validate SSHPASS function validate_os_sshpass { - SSHPASSWORD='' + # SSHPASSWORD='' - if hash sshpass 2>/dev/null - then - MESSAGE="SSHPASS Utility Detected" - echo_warn - if [ -z "$REMOTE_PASS" ] - then - MESSAGE="Using SSH Key-Pair Authentication" - echo_info - else - MESSAGE="Testing Authentication Options" - echo_stat + # if hash sshpass 2>/dev/null + # then + # MESSAGE="SSHPASS Utility Detected" + # echo_warn + # if [ -z "$REMOTE_PASS" ] + # then + # MESSAGE="Using SSH Key-Pair Authentication" + # echo_info + # else + # MESSAGE="Testing Authentication Options" + # echo_stat - timeout 5 ssh -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" -o StrictHostKeyChecking=no ${REMOTE_USER}@${REMOTE_HOST} 'exit' >/dev/null 2>&1 - if [ "$?" != "0" ] - then - SSHPASSWORD="sshpass -p ${REMOTE_PASS}" - MESSAGE="Using SSH Password Authentication" - echo_warn - else - MESSAGE="Valid Key-Pair Detected ${NC}(${RED}Password Ignored${NC})" - echo_info - fi - fi - else - SSHPASSWORD='' - MESSAGE="Using SSH Key-Pair Authentication" - echo_info - fi + # timeout 5 ssh -p ${SSH_PORT} -i "$HOME/${SSH_PKIF}" -o StrictHostKeyChecking=no ${REMOTE_USER}@${REMOTE_HOST} 'exit' >/dev/null 2>&1 + # if [ "$?" != "0" ] + # then + # SSHPASSWORD="sshpass -p ${REMOTE_PASS}" + # MESSAGE="Using SSH Password Authentication" + # echo_warn + # else + # MESSAGE="Valid Key-Pair Detected ${NC}(${RED}Password Ignored${NC})" + # echo_info + # fi + # fi + # else + # SSHPASSWORD='' + # MESSAGE="Using SSH Key-Pair Authentication" + # echo_info + # fi MESSAGE="Validating Connection to ${REMOTE_HOST}" echo_stat diff --git a/prep/gs-install.sh b/prep/gs-install.sh index acb73cc..0bc201c 100644 --- a/prep/gs-install.sh +++ b/prep/gs-install.sh @@ -20,96 +20,188 @@ NC='\033[0m' # Variables CROSSCOUNT="0" +PHFAILCOUNT="0" CURRENTUSER=$(whoami) # Header -echo -e "${YELLOW}Gravity Sync 3.0 - Installation Script${NC}" +echo -e "========================================================" +echo -e "${YELLOW}Gravity Sync by ${BLUE}@vmstan${YELLOW} - Online Installation${NC}" +echo -e "${CYAN}https://github.com/vmstan/gravity-sync${NC}" +echo -e "========================================================" +# echo -e "Initalizing Short Range Sensors" # Check Root +echo -e "[${YELLOW}i${NC}] ${YELLOW}Validating System Authorization${NC}" if [ ! "$EUID" -ne 0 ] then - echo -e "[${RED}✗${NC}] Running as Root" - CROSSCOUNT=$((CROSSCOUNT+1)) + echo -e "[${GREEN}✓${NC}] Current User (${CURRENTUSER}) is ROOT" + LOCALADMIN="root" else - echo -e "[${GREEN}✓${NC}] Not Running as Root" -fi - -# Check Sudo -sudo --validate -if [ "$?" != "0" ] -then - echo -e "[${RED}✗${NC}] No Sudo Powers for ${CURRENTUSER}" - CROSSCOUNT=$((CROSSCOUNT+1)) -else - echo -e "[${GREEN}✓${NC}] Sudo Powers Valid" + if hash sudo 2>/dev/null + then + echo -e "[${GREEN}✓${NC}] Sudo Utility Detected" + # Check Sudo + sudo --validate + if [ "$?" != "0" ] + then + echo -e "[${RED}✗${NC}] Current User (${CURRENTUSER}) Cannot SUDO" + CROSSCOUNT=$((CROSSCOUNT+1)) + LOCALADMIN="nosudo" + else + echo -e "[${GREEN}✓${NC}] Current User (${CURRENTUSER}) Has SUDO Powers" + LOCALADMIN="sudo" + fi + else + echo -e "[${RED}✗${NC}] Sudo Utility Not Detected" + CROSSCOUNT=$((CROSSCOUNT+1)) + LOCALADMIN="nosudo" + fi + + if [ "$LOCALADMIN" != "sudo" ] + then + echo -e "[${RED}✗${NC}] Current User (${CURRENTUSER}) Cannot SUDO" + CROSSCOUNT=$((CROSSCOUNT+1)) + LOCALADMIN="nosudo" + fi fi +echo -e "[${YELLOW}i${NC}] ${YELLOW}Scanning for Required Components${NC}" # Check OpenSSH if hash ssh 2>/dev/null then - echo -e "[${GREEN}✓${NC}] OpenSSH Detected" + echo -e "[${GREEN}✓${NC}] OpenSSH Binaries Detected" else - echo -e "[${RED}✗${NC}] OpenSSH Not Installed" + echo -e "[${RED}✗${NC}] OpenSSH Binaries Not Installed" CROSSCOUNT=$((CROSSCOUNT+1)) fi # Check Rsync if hash rsync 2>/dev/null then - echo -e "[${GREEN}✓${NC}] RSYNC Detected" + echo -e "[${GREEN}✓${NC}] RSYNC Binaries Detected" else - echo -e "[${RED}✗${NC}] RSYNC Not Installed" + echo -e "[${RED}✗${NC}] RSYNC Binaries Not Installed" + CROSSCOUNT=$((CROSSCOUNT+1)) +fi + +# Check Sudo +if hash sudo 2>/dev/null +then + echo -e "[${GREEN}✓${NC}] SUDO Binaries Detected" +else + echo -e "[${RED}✗${NC}] SUDO Binaries Not Installed" + CROSSCOUNT=$((CROSSCOUNT+1)) +fi + +# Check Crontab +if hash crontab 2>/dev/null +then + echo -e "[${GREEN}✓${NC}] CRONTAB Binaries Detected" +else + echo -e "[${RED}✗${NC}] CRONTAB Binaries Not Installed" CROSSCOUNT=$((CROSSCOUNT+1)) fi # Check SQLITE3 if hash sqlite3 2>/dev/null then - echo -e "[${GREEN}✓${NC}] SQLITE3 Detected" + echo -e "[${GREEN}✓${NC}] SQLITE3 Binaries Detected" else - echo -e "[${RED}✗${NC}] SQLITE3 Not Installed" + echo -e "[${RED}✗${NC}] SQLITE3 Binaries Not Installed" CROSSCOUNT=$((CROSSCOUNT+1)) fi # Check GIT if hash git 2>/dev/null then - echo -e "[${GREEN}✓${NC}] GIT Detected" + echo -e "[${GREEN}✓${NC}] GIT Binaries Detected" else - echo -e "[${RED}✗${NC}] GIT Not Installed" + echo -e "[${RED}✗${NC}] GIT Binaries Not Installed" CROSSCOUNT=$((CROSSCOUNT+1)) fi +echo -e "[${YELLOW}i${NC}] ${YELLOW}Performing Warp Core Diagnostics${NC}" # Check Pihole if hash pihole 2>/dev/null then - echo -e "[${GREEN}✓${NC}] Pi-Hole Detected" + echo -e "[${GREEN}✓${NC}] Local Pi-hole Install Detected" else - echo -e "[${RED}✗${NC}] Pi-hole Not Installed" + echo -e "[${PURPLE}!${NC}] ${PURPLE}No Local Pi-hole Install Detected${NC}" + # echo -e "[${PURPLE}!${NC}] ${PURPLE}Attempting To Compensate${NC}" + if hash docker 2>/dev/null + then + echo -e "[${GREEN}✓${NC}] Docker Binaries Detected" + + if [ "$LOCALADMIN" == "sudo" ] + then + FTLCHECK=$(sudo docker container ls | grep 'pihole/pihole') + elif [ "$LOCALADMIN" == "nosudo" ] + then + echo -e "[${PURPLE}!${NC}] ${PURPLE}No Docker Pi-hole Container Detected (unable to scan)${NC}" + # CROSSCOUNT=$((CROSSCOUNT+1)) + PHFAILCOUNT=$((PHFAILCOUNT+1)) + else + FTLCHECK=$(docker container ls | grep 'pihole/pihole') + fi + + if [ "$LOCALADMIN" != "nosudo" ] + then + if [ "$FTLCHECK" != "" ] + then + echo -e "[${GREEN}✓${NC}] Pi-Hole Docker Container Detected" + else + echo -e "[${PURPLE}!${NC}] ${PURPLE}No Docker Pi-hole Container Detected${NC}" + # CROSSCOUNT=$((CROSSCOUNT+1)) + PHFAILCOUNT=$((PHFAILCOUNT+1)) + fi + fi + else + # echo -e "[${RED}✗${NC}] No Local Pi-hole Install Detected" + echo -e "[${PURPLE}!${NC}] ${PURPLE}No Docker Pi-hole Alternative Detected${NC}" + # CROSSCOUNT=$((CROSSCOUNT+1)) + PHFAILCOUNT=$((PHFAILCOUNT+1)) + fi +fi + +if [ "$PHFAILCOUNT" != "0" ] +then + echo -e "[${RED}✗${NC}] No Usable Pi-hole Install Detected" CROSSCOUNT=$((CROSSCOUNT+1)) fi +echo -e "[${YELLOW}i${NC}] ${YELLOW}Status Report${NC}" # Combine Outputs if [ "$CROSSCOUNT" != "0" ] then - echo -e "[${PURPLE}!${NC}] ${RED}${CROSSCOUNT}${NC} failures detected, correct these errors before deploying Gravity Sync!" + echo -e "[${RED}⬣${NC}] ${RED}${CROSSCOUNT} Critical Issues Detected${NC}" + echo -e "[${PURPLE}!${NC}] ${PURPLE}Please Correct Failed Components${NC}" + echo -e "[${YELLOW}i${NC}] ${PURPLE}Installation Exiting (without changes)${NC}" else - echo -e "[${CYAN}>${NC}] Creating Sudoers.d File" - touch /tmp/gs-nopasswd.sudo - echo -e "${CURRENTUSER} ALL=(ALL) NOPASSWD: ALL" > /tmp/gs-nopasswd.sudo - sudo install -m 0440 /tmp/gs-nopasswd.sudo /etc/sudoers.d/gs-nopasswd + echo -e "[${YELLOW}i${NC}] ${YELLOW}Executing Gravity Sync Deployment${NC}" + + if [ "$LOCALADMIN" == "sudo" ] + then + echo -e "[${BLUE}>${NC}] Creating Sudoers.d File" + touch /tmp/gs-nopasswd.sudo + echo -e "${CURRENTUSER} ALL=(ALL) NOPASSWD: ALL" > /tmp/gs-nopasswd.sudo + sudo install -m 0440 /tmp/gs-nopasswd.sudo /etc/sudoers.d/gs-nopasswd + fi if [ "$GS_INSTALL" != "secondary" ] then - echo -e "[${YELLOW}i${NC}] This host is prepared to use Gravity Sync, you may log off now!" - echo -e "[${YELLOW}i${NC}] Run this script again on your secondary Pi-hole host to proceed." - echo -e "[${YELLOW}i${NC}] Visit https://github.com/vmstan/gravity-sync for more instructions." + echo -e "[${YELLOW}i${NC}] Gravity Sync Preperation Complete" + echo -e "[${YELLOW}i${NC}] Execute on Installer on Secondary" + echo -e "[${YELLOW}i${NC}] Check Documentation for Instructions" + echo -e "[${YELLOW}i${NC}] Installation Exiting (without changes)" else - echo -e "[${CYAN}>${NC}] Creating Gravity Sync Directories" - git clone https://github.com/vmstan/gravity-sync.git $HOME/gravity-sync - echo -e "[${YELLOW}i${NC}] This host is now prepared to configure Gravity Sync!" - echo -e "[${YELLOW}i${NC}] Please run './gravity-sync configure' from $HOME/gravity-sync" - echo -e "[${YELLOW}i${NC}] Visit https://github.com/vmstan/gravity-sync for more instructions." + echo -e "[${BLUE}>${NC}] Creating Gravity Sync Directories" + git clone https://github.com/vmstan/gravity-sync.git + echo -e "[${BLUE}>${NC}] Starting Gravity Sync Configuration" + echo -e "========================================================" + sh gravity-sync/gravity-sync.sh configure < /dev/tty + # echo -e "[${YELLOW}i${NC}] This host is now prepared to configure Gravity Sync!" + # echo -e "[${YELLOW}i${NC}] Please run './gravity-sync configure' from $HOME/gravity-sync" + # echo -e "[${YELLOW}i${NC}] Visit https://github.com/vmstan/gravity-sync for more instructions." fi fi