Compare commits

...

7 Commits

Author SHA1 Message Date
Michael Stanclift
54ddeb6666
Final commit 2024-07-26 13:45:33 -05:00
Michael Stanclift
50c786eb9d
4.0.7 (#433)
* fix: typo in dns cname permission change (#431)

This typo prevents gravity-sync from continuing and calculating hashes resulting in always considering there are changes to sync

* Update VERSION

* Branding and typos

* 4.0.7

---------

Co-authored-by: Alexandre Perrault <alexperrault@users.noreply.github.com>
2024-01-15 09:21:24 -06:00
Michael Stanclift
ccb89624f7
v4.0.6 (#424)
* Updates to respect configured options (#413)

- remote pihole detection uses configured docker/podman binaries
- file permission updates use configured local/remote file owners

Also fixes https://github.com/vmstan/gravity-sync/issues/392

---------

Co-authored-by: Eric Roch <emroch@users.noreply.github.com>
2024-01-07 12:32:39 -06:00
Sam Mingo
4402ff0d73
Update README.md (#403) 2023-10-13 22:14:14 -05:00
Michael Stanclift
ad783f1385
4.0.5 (#400)
* Simple fix for podman to work; whitespace clean up (#396)

* Fix set_pihole_exec to match full container names (#390)

Fix set_pihole_exec to match full container names, rather
than their substrings, by adding begin and end anchors to
the 'docker ps -qf name=PATTERN' being used.

Signed-off-by: William Blew <william@kulian.org>

* Fix the detect_xxx_pihole routines. (#389)

Fix the detect_xxx_pihole routines to respect the configurable
PIHOLE_CONTAINER_IMAGE variable.

The ghcr.io/pi-hole/pihole image is also released by the Pi-hole
project, just as the pihole/pihole image.

This commit enables ghcr.io image usage by adding the following
to the /etc/gravity-sync.conf file:

PIHOLE_CONTAINER_IMAGE='ghcr.io/pi-hole/pihole'

Signed-off-by: William Blew <william@kulian.org>
Co-authored-by: Michael Stanclift <mx@vmstan.com>

* Make check for sudo privileges more accurate (#375)

* Make check for sudo privileges more accurate

The existing method of checking if the Gravity Sync user has sudo rights is flawed, in that it will break if the user is not in the `sudo` group (on Debian based distros) or the `wheel` group (on CentOS/RHEL distros).

A more accurate way of checking if a user has sudo privileges is using `sudo --validate` or `sudo -n true`; both of which return `0` if the user has sudo privileges.

This commit updates the `validate_sudo_status` function to use `sudo --validate` so that Gravity Sync is actually checking if a user has sudo privileges, rather than just checking group memberships.

* Fix bug in patch

---------

Co-authored-by: llamalump <29816026+llamalump@users.noreply.github.com>

* Fix: GS_SSH_PORT can be changed now via  'gravity-sync config <NEW_PORT>' when already set in gravity-sync.conf. Fix: Initial sync of static DHCP and CNAME to 'empty pihole' now works. Enhancement: Various settings now settable via ENV vars (for Docker) (#384)

* SSH custom port: Fixed bug, where GS_SSH_PORT is overwritten by gravity-sync.conf (if set) when calling 'gravity-sync config NEW_SSH_PORT'. Docker enhancements: Made many config-variables settable via ENV vars

* Fixing initial push of CNAME and Static DHCP entries to an 'empty' remote (fixes https://github.com/vmstan/gravity-sync/issues/377)

* Removing unecessary 'export' keyword

* Fixed 'md5_recheck' for the bug https://github.com/vmstan/gravity-sync/issues/377

* Adding ENV documentation

* Fixing typo

* Fixed type and nicely formatted tables with emacs

---------

Co-authored-by: Michael Stanclift <mx@vmstan.com>

* Update VERSION

* Update gravity-sync

---------

Signed-off-by: William Blew <william@kulian.org>
Co-authored-by: Matt Woodson <mwoodson@gmail.com>
Co-authored-by: William Blew <william@kulian.org>
Co-authored-by: Seb Thomson <29816026+rst-ack@users.noreply.github.com>
Co-authored-by: llamalump <29816026+llamalump@users.noreply.github.com>
Co-authored-by: Klaus Zipfel <30482165+systemofapwne@users.noreply.github.com>
2023-07-10 11:46:11 -05:00
Michael Stanclift
183190e4bb
Update VERSION 2023-07-10 11:43:35 -05:00
Michael Stanclift
9fc48413fe
Update VERSION 2023-07-10 11:43:18 -05:00
5 changed files with 467 additions and 267 deletions

85
ENV.md Normal file
View File

@ -0,0 +1,85 @@
<p align="center">
<img src="images/gs-logo.svg" width="300" alt="Gravity Sync">
</p>
<span align="center">
# Gravity Sync ENVs
</span>
These tables are a list of all Gravity Sync settings, that can be tweaked via ENVs. Keep in mind that some of them are stored in `/etc/gravity-sync/gravity-sync.conf` after running `gravity-sync configure` and that `gravity-sync.conf` has higher priority than ENVs.
### Local and remote paths & settings
These settings will determine, from where (locally) to where (remotely) will be synced and with which account/permissions
| Variable | Default | Value | Description |
|----------------------------|------------------|------------|----------------------------------------------------|
| `LOCAL_PIHOLE_DIRECTORY` | `/etc/pihole` | path | Path to local pi-hole instance in the filesystem |
| `REMOTE_PIHOLE_DIRECTORY` | `/etc/pihole` | path | Path to remote pi-hole instance in the filesystem |
| `LOCAL_DNSMASQ_DIRECTORY` | `/etc/dnsmasq.d` | path | Path to local dnsmasqd instance in the filesystem |
| `REMOTE_DNSMASQ_DIRECTORY` | `/etc/dnsmasq.d` | path | Path to remote dnsmasqd instance in the filesystem |
| `LOCAL_FILE_OWNER` | `pihole:pihole` | user:group | Local owner and group of the pi-hole config |
| `REMOTE_FILE_OWNER` | `pihole:pihole` | user:group | Remote owner and group of the pi-hole config |
### Docker specific settings
Gravity-sync will check your system for a native Pi-hole install first (on local and remote site) and if does not detect any, tests against Docker/Podman Pi-hole instances.
Here, you can specific the Docker or Podman container name, that Gravity Sync should interact with.
| Variable | Default | Value | Description |
|---------------------------|----------|----------------|--------------------------------------------|
| `LOCAL_DOCKER_CONTAINER` | `pihole` | container name | Container name of pi-hole running locally |
| `REMOTE_DOCKER_CONTAINER` | `pihole` | container name | Container name of pi-hole running remotely |
### Paths to standard files and folders
These settings are most likely the same on all systems. No need to touch them but nice to be able to touch them, if necessary.
| Variable | Default | Value | Description |
|----------------------------|-------------------------|-------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `DEFAULT_PIHOLE_DIRECTORY` | `/etc/pihole` | path | Docker/Podman: Path to Pi-hole instance within a Docker/Podman container. Don't mix up with `LOCAL_PIHOLE_DIRECTORY`, which is only used against local Pi-hole instances (non-dockerized). |
| `LOCAL_PIHOLE_BINARY` | `/usr/local/bin/pihole` | path | Path to `pihole` binary on local system |
| `REMOTE_PIHOLE_BINARY` | `/usr/local/bin/pihole` | path | Path to `pihole` binary on remote system |
| `LOCAL_FTL_BINARY` | `/usr/bin/pihole-FTL` | path | Path to `pihole-FTL` binary on local system |
| `REMOTE_FTL_BINARY` | `/usr/bin/pihole-FTL` | path | Path to `pihole-FTL` binary on remote system |
| `LOCAL_DOCKER_BINARY` | `/usr/bin/docker` | path | Path to `docker` binary on local system |
| `REMOTE_DOCKER_BINARY` | `/usr/bin/docker` | path | Path to `docker` binary on remote system |
| `LOCAL_PODMAN_BINARY` | `/usr/bin/podman` | path | Path to `podman` binary on local system |
| `REMOTE_PODMAN_BINARY` | `/usr/bin/podman` | path | Path to `podman` binary on remote system |
| `PIHOLE_CONTAINER_IMAGE` | `pihole/pihole` | path | Name of the default pi-hole docker image |
### Nitty-gritty finetuning the target files
Here, you can specifiy the Gravity, DNS (A, CNAME) and DHCP settings file of Pi-hole. It is almost certain, that these filenames do never change (except if upstream Pi-hole decides so).
| Variable | Default | Value | Description |
|-----------------|-------------------------------|-------|--------------------------------------------|
| `PH_GRAVITY_FI` | `gravity.db` | file | The gravity filename (blocklist) of pihole |
| `PH_CUSTOM_DNS` | `custom.list` | file | The custom DNS (A) filename of pihole |
| `PH_CNAME_CONF` | `05-pihole-custom-cname.conf` | file | The custom DNS (CNAME) filename of pihole |
| `PH_SDHCP_CONF` | `04-pihole-static-dhcp.conf` | file | The custom DHCP filename of pihole |
### Backup Customization
| Variable | Default | Value | Description |
|----------------------------|---------|----------------|-----------------------------------------------------------------------------------------------|
| `GS_BACKUP_TIMEOUT` | `240` | seconds | How long shall we allow a gravity.db backup task to run, before it is deemed to be timed out? |
| `GS_BACKUP_INTEGRITY_WAIT` | `5` | seconds | Some wait time, before integrity checks are performed on gravity.db |
| `GS_BACKUP_EXT` | `gsb` | file-extension | Local and remote gravity.db backup files will get this file-extension added before merge. |
### GS Folder/File Locations
| Variable | Default | Value | Description |
|-------------------------|-----------------------------------|-------|--------------------------------------------------------------------------------------------|
| `GS_ETC_PATH` | `/etc/gravity-sync` | path | Path to the gravity-sync work & config directory |
| `GS_CONFIG_FILE` | `gravity-sync.conf` | file | Name of the gravity.sync config file |
| `GS_SYNCING_LOG` | `gs-sync.log` | file | Logfile for gravity-sync |
| `GS_GRAVITY_FI_MD5_LOG` | `gs-gravity.md5` | file | Filename for storing `PH_GRAVITY_FI` hash (used for sync comparison locally and on remote) |
| `GS_CUSTOM_DNS_MD5_LOG` | `gs-clist.md5` | file | Filename for storing `PH_CUSTOM_DNS` hash (used for sync comparison locally and on remote) |
| `GS_CNAME_CONF_MD5_LOG` | `05-pihole-custom-cname.conf.md5` | file | Filename for storing `PH_CNAME_CONF` hash (used for sync comparison locally and on remote) |
| `GS_SDHCP_CONF_MD5_LOG` | `04-pihole-static-dhcp.conf.md5` | file | Filename for storing `PH_SDHCP_CONF` hash (used for sync comparison locally and on remote) |
### Remote SSH config
Customize parameters for accessing the remote end via SSH
| Variable | Default | Value | Description |
|---------------|----------------------------------|-------|---------------------------------------------------------------------------------------------------------|
| `GS_SSH_PORT` | `22` | port | Port of the remote gravity-sync container/host |
| `GS_SSH_PKIF` | `<GS_ETC_PATH>/gravity-sync.rsa` | file | Path to the local SSH private key of gravity-sync, that will be used for pubkey auth against the remote |
### Upgrade: Gravity Sync sourcecode location
Gravity Sync is locally installed as a GitHub repo. In order to upgrade your local Gravity Sync instance via `gravity-sync upgrade` to the latest version, the path to that git repo must be known and can be specified below.
| Variable | Default | Value | Description |
|-----------------|---------------------|-------|---------------------------------------------|
| `GS_LOCAL_REPO` | `<GS_ETC_PATH>/.gs` | path | Local install path of the gravity-sync repo |

View File

@ -1,5 +1,5 @@
<p align="center"> <p align="center">
<img src="https://vmstan.com/content/images/2021/02/gs-logo.svg" width="300" alt="Gravity Sync"> <img src="images/gs-logo.svg" width="300" alt="Gravity Sync">
</p> </p>
<span align="center"> <span align="center">
@ -8,7 +8,9 @@
</span> </span>
### [Find out what's new in version 4.0!](https://github.com/vmstan/gravity-sync/wiki/4.0) ### Effective July 26, 2024, this project has been retired. Thank you for your use and enthusiasm for a project that began as a few lines of bash in a Slack channel and envolved into something far more complex, and used by many thousands of Pi-hole enthusiasts over the last four years.
### The last released version of Gravity Sync (4.0.7) should continue to work with Pi-hole 5.x, but not with Pi-hole 6+ due to architecture changes.
What is better than a [Pi-hole](https://github.com/pi-hole/pi-hole) blocking trackers, advertisements, and other malicious domains on your network? That's right, **two** Pi-hole blocking all that junk on your network! What is better than a [Pi-hole](https://github.com/pi-hole/pi-hole) blocking trackers, advertisements, and other malicious domains on your network? That's right, **two** Pi-hole blocking all that junk on your network!

View File

@ -1 +1 @@
4.0.4 4.0.7

View File

@ -4,7 +4,7 @@ GS_RUN_START=$SECONDS
# GRAVITY SYNC BY VMSTAN ##################### # GRAVITY SYNC BY VMSTAN #####################
PROGRAM='Gravity Sync' PROGRAM='Gravity Sync'
GS_VERSION='4.0.4' GS_VERSION='4.0.7'
# For documentation or the changelog/updates visit https://github.com/vmstan/gravity-sync # For documentation or the changelog/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 # Requires Pi-Hole 5.x or higher already be installed, for help visit https://pi-hole.net
@ -19,61 +19,61 @@ GS_VERSION='4.0.4'
# CUSTOM VARIABLES ########################### # CUSTOM VARIABLES ###########################
# Pi-hole Folder/File Customization - Only need to be customized when using containers # Pi-hole Folder/File Customization - Only need to be customized when using containers
LOCAL_PIHOLE_DIRECTORY='/etc/pihole' # replace in gravity-sync.conf to overwrite LOCAL_PIHOLE_DIRECTORY=${LOCAL_PIHOLE_DIRECTORY:-'/etc/pihole'} # replace in gravity-sync.conf to overwrite
REMOTE_PIHOLE_DIRECTORY='/etc/pihole' # replace in gravity-sync.conf to overwrite REMOTE_PIHOLE_DIRECTORY=${REMOTE_PIHOLE_DIRECTORY:-'/etc/pihole'} # replace in gravity-sync.conf to overwrite
LOCAL_DNSMASQ_DIRECTORY='/etc/dnsmasq.d' # replace in gravity-sync.conf to overwrite LOCAL_DNSMASQ_DIRECTORY=${LOCAL_DNSMASQ_DIRECTORY:-'/etc/dnsmasq.d'} # replace in gravity-sync.conf to overwrite
REMOTE_DNSMASQ_DIRECTORY='/etc/dnsmasq.d' # replace in gravity-sync.conf to overwrite REMOTE_DNSMASQ_DIRECTORY=${REMOTE_DNSMASQ_DIRECTORY:-'/etc/dnsmasq.d'} # replace in gravity-sync.conf to overwrite
LOCAL_FILE_OWNER='pihole:pihole' # replace in gravity-sync.conf to overwrite LOCAL_FILE_OWNER=${LOCAL_FILE_OWNER:-'pihole:pihole'} # replace in gravity-sync.conf to overwrite
REMOTE_FILE_OWNER='pihole:pihole' # replace in gravity-sync.conf to overwrite REMOTE_FILE_OWNER=${REMOTE_FILE_OWNER:-'pihole:pihole'} # replace in gravity-sync.conf to overwrite
# Pi-hole Docker/Podman container name - Docker will pattern match anything set below # Pi-hole Docker/Podman container name - Docker will pattern match anything set below
LOCAL_DOCKER_CONTAINER='pihole' # replace in gravity-sync.conf to overwrite LOCAL_DOCKER_CONTAINER=${LOCAL_DOCKER_CONTAINER:-'pihole'} # replace in gravity-sync.conf to overwrite
REMOTE_DOCKER_CONTAINER='pihole' # replace in gravity-sync.conf to overwrite REMOTE_DOCKER_CONTAINER=${REMOTE_DOCKER_CONTAINER:-'pihole'} # replace in gravity-sync.conf to overwrite
# STANDARD VARIABLES ######################### # STANDARD VARIABLES #########################
DEFAULT_PIHOLE_DIRECTORY='/etc/pihole' # Default Pi-hole data directory DEFAULT_PIHOLE_DIRECTORY=${DEFAULT_PIHOLE_DIRECTORY:-'/etc/pihole'} # Default Pi-hole data directory
LOCAL_PIHOLE_BINARY='/usr/local/bin/pihole' # Local Pi-hole binary directory (default) LOCAL_PIHOLE_BINARY=${LOCAL_PIHOLE_BINARY:-'/usr/local/bin/pihole'} # Local Pi-hole binary directory (default)
REMOTE_PIHOLE_BINARY='/usr/local/bin/pihole' # Remote Pi-hole binary directory (default) REMOTE_PIHOLE_BINARY=${REMOTE_PIHOLE_BINARY:-'/usr/local/bin/pihole'} # Remote Pi-hole binary directory (default)
LOCAL_FTL_BINARY='/usr/bin/pihole-FTL' # Local FTL binary directory (default) LOCAL_FTL_BINARY=${LOCAL_FTL_BINARY:-'/usr/bin/pihole-FTL'} # Local FTL binary directory (default)
REMOTE_FTL_BINARY='/usr/bin/pihole-FTL' # Remote FTL binary directory (default) REMOTE_FTL_BINARY=${REMOTE_FTL_BINARY:-'/usr/bin/pihole-FTL'} # Remote FTL binary directory (default)
LOCAL_DOCKER_BINARY='/usr/bin/docker' # Local Docker binary directory (default) LOCAL_DOCKER_BINARY=${LOCAL_DOCKER_BINARY:-'/usr/bin/docker'} # Local Docker binary directory (default)
REMOTE_DOCKER_BINARY='/usr/bin/docker' # Remote Docker binary directory (default) REMOTE_DOCKER_BINARY=${REMOTE_DOCKER_BINARY:-'/usr/bin/docker'} # Remote Docker binary directory (default)
LOCAL_PODMAN_BINARY='/usr/bin/podman' # Local Podman binary directory (default) LOCAL_PODMAN_BINARY=${LOCAL_PODMAN_BINARY:-'/usr/bin/podman'} # Local Podman binary directory (default)
REMOTE_PODMAN_BINARY='/usr/bin/podman' # Remote Podman binary directory (default) REMOTE_PODMAN_BINARY=${REMOTE_PODMAN_BINARY:-'/usr/bin/podman'} # Remote Podman binary directory (default)
PIHOLE_CONTAINER_IMAGE='pihole/pihole' # Official Pi-hole container image name PIHOLE_CONTAINER_IMAGE=${PIHOLE_CONTAINER_IMAGE:-'pihole/pihole'} # Official Pi-hole container image name
############################################### ###############################################
####### THE NEEDS OF THE MANY, OUTWEIGH ####### ####### THE NEEDS OF THE MANY, OUTWEIGH #######
############ THE NEEDS OF THE FEW ############# ############ THE NEEDS OF THE FEW #############
############################################### ###############################################
PH_GRAVITY_FI='gravity.db' # Pi-hole database file name PH_GRAVITY_FI=${PH_GRAVITY_FI:-'gravity.db'} # Pi-hole database file name
PH_CUSTOM_DNS='custom.list' # Pi-hole DNS lookup filename PH_CUSTOM_DNS=${PH_CUSTOM_DNS:-'custom.list'} # Pi-hole DNS lookup filename
PH_CNAME_CONF='05-pihole-custom-cname.conf' # DNSMASQ CNAME alias file PH_CNAME_CONF=${PH_CNAME_CONF:-'05-pihole-custom-cname.conf'} # DNSMASQ CNAME alias file
PH_SDHCP_CONF='04-pihole-static-dhcp.conf' # DNSMASQ Static DHCP file PH_SDHCP_CONF=${PH_SDHCP_CONF:-'04-pihole-static-dhcp.conf'} # DNSMASQ Static DHCP file
# Backup Customization # Backup Customization
GS_BACKUP_TIMEOUT='240' # replace in gravity-sync.conf to overwrite GS_BACKUP_TIMEOUT=${GS_BACKUP_TIMEOUT:-'240'} # replace in gravity-sync.conf to overwrite
GS_BACKUP_INTEGRITY_WAIT='5' # replace in gravity-sync.conf to overwrite GS_BACKUP_INTEGRITY_WAIT=${GS_BACKUP_INTEGRITY_WAIT:-'5'} # replace in gravity-sync.conf to overwrite
GS_BACKUP_EXT='gsb' # replace in gravity-sync.conf to overwrite GS_BACKUP_EXT=${GS_BACKUP_EXT:-'gsb'} # replace in gravity-sync.conf to overwrite
# GS Folder/File Locations # GS Folder/File Locations
GS_FILEPATH='/usr/local/bin/gravity-sync' GS_FILEPATH='/usr/local/bin/gravity-sync'
GS_ETC_PATH="/etc/gravity-sync" # replace in gravity-sync.conf to overwrite GS_ETC_PATH=${GS_ETC_PATH:-"/etc/gravity-sync"} # replace in gravity-sync.conf to overwrite
GS_CONFIG_FILE='gravity-sync.conf' # replace in gravity-sync.conf to overwrite GS_CONFIG_FILE=${GS_CONFIG_FILE:-'gravity-sync.conf'} # replace in gravity-sync.conf to overwrite
GS_SYNCING_LOG='gs-sync.log' # replace in gravity-sync.conf to overwrite GS_SYNCING_LOG=${GS_SYNCING_LOG:-'gs-sync.log'} # replace in gravity-sync.conf to overwrite
GS_GRAVITY_FI_MD5_LOG='gs-gravity.md5' # replace in gravity-sync.conf to overwrite GS_GRAVITY_FI_MD5_LOG=${GS_GRAVITY_FI_MD5_LOG:-'gs-gravity.md5'} # replace in gravity-sync.conf to overwrite
GS_CUSTOM_DNS_MD5_LOG='gs-clist.md5' # replace in gravity-sync.conf to overwrite GS_CUSTOM_DNS_MD5_LOG=${GS_CUSTOM_DNS_MD5_LOG:-'gs-clist.md5'} # replace in gravity-sync.conf to overwrite
GS_CNAME_CONF_MD5_LOG='05-pihole-custom-cname.conf.md5' # replace in gravity-sync.conf to overwrite GS_CNAME_CONF_MD5_LOG=${GS_CNAME_CONF_MD5_LOG:-'05-pihole-custom-cname.conf.md5'} # replace in gravity-sync.conf to overwrite
GS_SDHCP_CONF_MD5_LOG='04-pihole-static-dhcp.conf.md5' # replace in gravity-sync.conf to overwrite GS_SDHCP_CONF_MD5_LOG=${GS_SDHCP_CONF_MD5_LOG:-'04-pihole-static-dhcp.conf.md5'} # replace in gravity-sync.conf to overwrite
# SSH Customization # SSH Customization
GS_SSH_PORT='22' # replace in gravity-sync.conf to overwrite GS_SSH_PORT=${GS_SSH_PORT:-'22'} # replace in gravity-sync.conf to overwrite
GS_SSH_PKIF="${GS_ETC_PATH}/gravity-sync.rsa" # replace in gravity-sync.conf to overwrite GS_SSH_PKIF=${GS_SSH_PKIF:-"${GS_ETC_PATH}/gravity-sync.rsa"} # replace in gravity-sync.conf to overwrite
# Github Customization # Github Customization
GS_LOCAL_REPO="${GS_ETC_PATH}/.gs" # replace in gravity-sync.conf to overwrite GS_LOCAL_REPO=${GS_LOCAL_REPO:-"${GS_ETC_PATH}/.gs"} # replace in gravity-sync.conf to overwrite
# OS Settings # OS Settings
OS_DAEMON_PATH='/etc/systemd/system' OS_DAEMON_PATH='/etc/systemd/system'
@ -272,8 +272,8 @@ function set_pihole_exec {
PH_EXEC="${LOCAL_PIHOLE_BINARY}" PH_EXEC="${LOCAL_PIHOLE_BINARY}"
FTL_EXEC="${LOCAL_FTL_BINARY}" FTL_EXEC="${LOCAL_FTL_BINARY}"
elif [ "$LOCAL_PIHOLE_TYPE" == "docker" ]; then elif [ "$LOCAL_PIHOLE_TYPE" == "docker" ]; then
PH_EXEC="sudo ${LOCAL_DOCKER_BINARY} exec $(sudo ${LOCAL_DOCKER_BINARY} ps -qf name=${LOCAL_DOCKER_CONTAINER}) pihole" PH_EXEC="sudo ${LOCAL_DOCKER_BINARY} exec $(sudo ${LOCAL_DOCKER_BINARY} ps -qf name=^${LOCAL_DOCKER_CONTAINER}$) pihole"
FTL_EXEC="sudo ${LOCAL_DOCKER_BINARY} exec $(sudo ${LOCAL_DOCKER_BINARY} ps -qf name=${LOCAL_DOCKER_CONTAINER}) pihole-FTL" FTL_EXEC="sudo ${LOCAL_DOCKER_BINARY} exec $(sudo ${LOCAL_DOCKER_BINARY} ps -qf name=^${LOCAL_DOCKER_CONTAINER}$) pihole-FTL"
elif [ "$LOCAL_PIHOLE_TYPE" == "podman" ]; then elif [ "$LOCAL_PIHOLE_TYPE" == "podman" ]; then
PH_EXEC="sudo ${LOCAL_PODMAN_BINARY} exec ${LOCAL_DOCKER_CONTAINER} pihole" PH_EXEC="sudo ${LOCAL_PODMAN_BINARY} exec ${LOCAL_DOCKER_CONTAINER} pihole"
FTL_EXEC="sudo ${LOCAL_PODMAN_BINARY} exec ${LOCAL_DOCKER_CONTAINER} pihole-FTL" FTL_EXEC="sudo ${LOCAL_PODMAN_BINARY} exec ${LOCAL_DOCKER_CONTAINER} pihole-FTL"
@ -283,11 +283,11 @@ function set_pihole_exec {
RH_EXEC="${REMOTE_PIHOLE_BINARY}" RH_EXEC="${REMOTE_PIHOLE_BINARY}"
RFTL_EXEC="${REMOTE_FTL_BINARY}" RFTL_EXEC="${REMOTE_FTL_BINARY}"
elif [ "$REMOTE_PIHOLE_TYPE" == "docker" ]; then elif [ "$REMOTE_PIHOLE_TYPE" == "docker" ]; then
RH_EXEC="sudo ${REMOTE_DOCKER_BINARY} exec \$(sudo ${REMOTE_DOCKER_BINARY} ps -qf name=${REMOTE_DOCKER_CONTAINER}) pihole" RH_EXEC="sudo ${REMOTE_DOCKER_BINARY} exec \$(sudo ${REMOTE_DOCKER_BINARY} ps -qf name=^${REMOTE_DOCKER_CONTAINER}$) pihole"
RFTL_EXEC="sudo ${REMOTE_DOCKER_BINARY} exec \$(sudo ${REMOTE_DOCKER_BINARY} ps -qf name=${REMOTE_DOCKER_CONTAINER}) pihole-FTL" RFTL_EXEC="sudo ${REMOTE_DOCKER_BINARY} exec \$(sudo ${REMOTE_DOCKER_BINARY} ps -qf name=^${REMOTE_DOCKER_CONTAINER}$) pihole-FTL"
elif [ "$REMOTE_PIHOLE_TYPE" == "podman" ]; then elif [ "$REMOTE_PIHOLE_TYPE" == "podman" ]; then
RH_EXEC="sudo ${REMOTE_PODMAN_BINARY} exec ${REMOTE_DOCKER_CONTAINER} pihole" RH_EXEC="sudo ${REMOTE_PODMAN_BINARY} exec ${REMOTE_DOCKER_CONTAINER} pihole"
RFTL_EXEC="sudo ${REMOTE_PODMAN_BINARY} exec ${REMOTE_DOCKER_CONTAINER} pihole" RFTL_EXEC="sudo ${REMOTE_PODMAN_BINARY} exec ${REMOTE_DOCKER_CONTAINER} pihole-FTL"
fi fi
} }
@ -504,7 +504,7 @@ function push_gs_custom {
MESSAGE="${UI_SET_LOCAL_FILE_OWNERSHIP} ${UI_CUSTOM_NAME}" MESSAGE="${UI_SET_LOCAL_FILE_OWNERSHIP} ${UI_CUSTOM_NAME}"
echo_stat echo_stat
CMD_TIMEOUT=$GS_BACKUP_TIMEOUT CMD_TIMEOUT=$GS_BACKUP_TIMEOUT
CMD_REQUESTED="sudo chown root:root ${REMOTE_PIHOLE_DIRECTORY}/${PH_CUSTOM_DNS}" CMD_REQUESTED="sudo chown ${REMOTE_FILE_OWNER} ${REMOTE_PIHOLE_DIRECTORY}/${PH_CUSTOM_DNS}"
create_ssh_cmd create_ssh_cmd
MESSAGE="${UI_SET_FILE_PERMISSION} ${UI_CUSTOM_NAME}" MESSAGE="${UI_SET_FILE_PERMISSION} ${UI_CUSTOM_NAME}"
@ -531,7 +531,7 @@ function push_gs_cname {
MESSAGE="${UI_SET_LOCAL_FILE_OWNERSHIP} ${UI_CNAME_NAME}" MESSAGE="${UI_SET_LOCAL_FILE_OWNERSHIP} ${UI_CNAME_NAME}"
echo_stat echo_stat
CMD_TIMEOUT=$GS_BACKUP_TIMEOUT CMD_TIMEOUT=$GS_BACKUP_TIMEOUT
CMD_REQUESTED="sudo chown root:root ${REMOTE_DNSMASQ_DIRECTORY}/${PH_CNAME_CONF}" CMD_REQUESTED="sudo chown ${REMOTE_FILE_OWNER} ${REMOTE_DNSMASQ_DIRECTORY}/${PH_CNAME_CONF}"
create_ssh_cmd create_ssh_cmd
@ -559,7 +559,7 @@ function push_gs_sdhcp {
MESSAGE="${UI_SET_LOCAL_FILE_OWNERSHIP} ${UI_SDHCP_NAME}" MESSAGE="${UI_SET_LOCAL_FILE_OWNERSHIP} ${UI_SDHCP_NAME}"
echo_stat echo_stat
CMD_TIMEOUT=$GS_BACKUP_TIMEOUT CMD_TIMEOUT=$GS_BACKUP_TIMEOUT
CMD_REQUESTED="sudo chown root:root ${REMOTE_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF}" CMD_REQUESTED="sudo chown ${REMOTE_FILE_OWNER} ${REMOTE_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF}"
create_ssh_cmd create_ssh_cmd
@ -1069,7 +1069,11 @@ function md5_compare {
fi fi
if [ -f ${LOCAL_DNSMASQ_DIRECTORY}/${PH_CNAME_CONF} ]; then if [ -f ${LOCAL_DNSMASQ_DIRECTORY}/${PH_CNAME_CONF} ]; then
if ${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${REMOTE_DNSMASQ_DIRECTORY}/${PH_CNAME_CONF}; then if ${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${REMOTE_DNSMASQ_DIRECTORY}; then
CMD_TIMEOUT=$GS_BACKUP_TIMEOUT
CMD_REQUESTED="sudo touch ${REMOTE_DNSMASQ_DIRECTORY}/${PH_CNAME_CONF}"
create_ssh_cmd
REMOTE_CNAME_DNS="1" REMOTE_CNAME_DNS="1"
MESSAGE="${UI_HASHING_HASHING} ${UI_CNAME_NAME}" MESSAGE="${UI_HASHING_HASHING} ${UI_CNAME_NAME}"
echo_stat echo_stat
@ -1106,7 +1110,11 @@ function md5_compare {
fi fi
if [ -f ${LOCAL_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF} ]; then if [ -f ${LOCAL_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF} ]; then
if ${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${REMOTE_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF}; then if ${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${REMOTE_DNSMASQ_DIRECTORY}; then
CMD_TIMEOUT=$GS_BACKUP_TIMEOUT
CMD_REQUESTED="sudo touch ${REMOTE_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF}"
create_ssh_cmd
REMOTE_SDHCP_DNS="1" REMOTE_SDHCP_DNS="1"
MESSAGE="${UI_HASHING_HASHING} ${UI_SDHCP_NAME}" MESSAGE="${UI_HASHING_HASHING} ${UI_SDHCP_NAME}"
echo_stat echo_stat
@ -1231,7 +1239,11 @@ function md5_recheck {
fi fi
if [ -f ${LOCAL_DNSMASQ_DIRECTORY}/${PH_CNAME_CONF} ]; then if [ -f ${LOCAL_DNSMASQ_DIRECTORY}/${PH_CNAME_CONF} ]; then
if ${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${REMOTE_DNSMASQ_DIRECTORY}/${PH_CNAME_CONF}; then if ${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${REMOTE_DNSMASQ_DIRECTORY}; then
CMD_TIMEOUT=$GS_BACKUP_TIMEOUT
CMD_REQUESTED="sudo touch ${REMOTE_DNSMASQ_DIRECTORY}/${PH_CNAME_CONF}"
create_ssh_cmd
REMOTE_CNAME_DNS="1" REMOTE_CNAME_DNS="1"
MESSAGE="${UI_HASHING_REHASHING} ${UI_CNAME_NAME}" MESSAGE="${UI_HASHING_REHASHING} ${UI_CNAME_NAME}"
echo_stat echo_stat
@ -1259,7 +1271,11 @@ function md5_recheck {
fi fi
if [ -f ${LOCAL_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF} ]; then if [ -f ${LOCAL_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF} ]; then
if ${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${REMOTE_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF}; then if ${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} test -e ${REMOTE_DNSMASQ_DIRECTORY}; then
CMD_TIMEOUT=$GS_BACKUP_TIMEOUT
CMD_REQUESTED="sudo touch ${REMOTE_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF}"
create_ssh_cmd
REMOTE_SDHCP_DNS="1" REMOTE_SDHCP_DNS="1"
MESSAGE="${UI_HASHING_REHASHING} ${UI_SDHCP_NAME}" MESSAGE="${UI_HASHING_REHASHING} ${UI_SDHCP_NAME}"
echo_stat echo_stat
@ -1471,7 +1487,7 @@ function detect_local_pihole {
LOCAL_PIHOLE_TYPE="default" LOCAL_PIHOLE_TYPE="default"
echo_good echo_good
elif hash docker 2>/dev/null; then elif hash docker 2>/dev/null; then
PH_FTL_CHECK=$(sudo docker container ls | grep 'pihole/pihole') PH_FTL_CHECK=$(sudo docker container ls | grep ${PIHOLE_CONTAINER_IMAGE})
if [ "$PH_FTL_CHECK" != "" ]; then if [ "$PH_FTL_CHECK" != "" ]; then
LOCAL_PIHOLE_TYPE="docker" LOCAL_PIHOLE_TYPE="docker"
echo_good echo_good
@ -1480,7 +1496,7 @@ function detect_local_pihole {
echo_fail echo_fail
fi fi
elif hash podman 2>/dev/null; then elif hash podman 2>/dev/null; then
PH_FTL_CHECK=$(sudo podman container ls | grep 'pihole/pihole') PH_FTL_CHECK=$(sudo podman container ls | grep ${PIHOLE_CONTAINER_IMAGE})
if [ "$PH_FTL_CHECK" != "" ]; then if [ "$PH_FTL_CHECK" != "" ]; then
LOCAL_PIHOLE_TYPE="podman" LOCAL_PIHOLE_TYPE="podman"
echo_good echo_good
@ -1502,14 +1518,16 @@ function detect_remote_pihole {
REMOTE_PIHOLE_TYPE="default" REMOTE_PIHOLE_TYPE="default"
echo_good echo_good
else else
REMOTE_DETECT_DOCKER=$(${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "sudo docker container ls | grep 'pihole/pihole'" 2>/dev/null) REMOTE_DETECT_DOCKER=$(${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "sudo ${REMOTE_DOCKER_BINARY} container ls | grep ${PIHOLE_CONTAINER_IMAGE}" 2>/dev/null)
REMOTE_DETECT_PODMAN=$(${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "sudo podman container ls | grep 'pihole/pihole'" 2>/dev/null) REMOTE_DETECT_PODMAN=$(${OS_SSH_CMD} -p ${GS_SSH_PORT} -i "${GS_SSH_PKIF}" ${REMOTE_USER}@${REMOTE_HOST} "sudo ${REMOTE_PODMAN_BINARY} container ls | grep ${PIHOLE_CONTAINER_IMAGE}" 2>/dev/null)
if [ "${REMOTE_DETECT_DOCKER}" != "" ]; then if [ "${REMOTE_DETECT_DOCKER}" != "" ]; then
REMOTE_PIHOLE_TYPE="docker" REMOTE_PIHOLE_TYPE="docker"
echo_good MESSAGE="${MESSAGE} - docker"
echo_good
elif [ "${REMOTE_DETECT_PODMAN}" != "" ]; then elif [ "${REMOTE_DETECT_PODMAN}" != "" ]; then
REMOTE_PIHOLE_TYPE="podman" REMOTE_PIHOLE_TYPE="podman"
MESSAGE="${MESSAGE} - podman"
echo_good echo_good
else else
REMOTE_PIHOLE_TYPE="none" REMOTE_PIHOLE_TYPE="none"
@ -1565,7 +1583,7 @@ function validate_gravity_permissions {
function validate_custom_permissions { function validate_custom_permissions {
MESSAGE="${UI_SET_LOCAL_FILE_OWNERSHIP} ${UI_CUSTOM_NAME}" MESSAGE="${UI_SET_LOCAL_FILE_OWNERSHIP} ${UI_CUSTOM_NAME}"
echo_stat echo_stat
sudo chown root:root ${LOCAL_PIHOLE_DIRECTORY}/${PH_CUSTOM_DNS} >/dev/null 2>&1 sudo chown ${LOCAL_FILE_OWNER} ${LOCAL_PIHOLE_DIRECTORY}/${PH_CUSTOM_DNS} >/dev/null 2>&1
error_validate error_validate
MESSAGE="${UI_SET_FILE_PERMISSION} ${UI_CUSTOM_NAME}" MESSAGE="${UI_SET_FILE_PERMISSION} ${UI_CUSTOM_NAME}"
@ -1578,7 +1596,7 @@ function validate_custom_permissions {
function validate_cname_permissions { function validate_cname_permissions {
MESSAGE="${UI_SET_LOCAL_FILE_OWNERSHIP} ${UI_CNAME_NAME}" MESSAGE="${UI_SET_LOCAL_FILE_OWNERSHIP} ${UI_CNAME_NAME}"
echo_stat echo_stat
sudo chown root:root ${LOCAL_DNSMASQ_DIRECTORY}/${PH_CNAME_CONF} >/dev/null 2>&1 sudo chown ${LOCAL_FILE_OWNER} ${LOCAL_DNSMASQ_DIRECTORY}/${PH_CNAME_CONF} >/dev/null 2>&1
error_validate error_validate
MESSAGE="${UI_SET_FILE_PERMISSION} ${UI_CNAME_NAME}" MESSAGE="${UI_SET_FILE_PERMISSION} ${UI_CNAME_NAME}"
@ -1590,7 +1608,7 @@ function validate_cname_permissions {
function validate_sdhcp_permissions { function validate_sdhcp_permissions {
MESSAGE="${UI_SET_LOCAL_FILE_OWNERSHIP} ${UI_SDHCP_NAME}" MESSAGE="${UI_SET_LOCAL_FILE_OWNERSHIP} ${UI_SDHCP_NAME}"
echo_stat echo_stat
sudo chown root:root ${LOCAL_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF} >/dev/null 2>&1 sudo chown ${LOCAL_FILE_OWNER} ${LOCAL_DNSMASQ_DIRECTORY}/${PH_SDHCP_CONF} >/dev/null 2>&1
error_validate error_validate
MESSAGE="${UI_SET_FILE_PERMISSION} ${UI_SDHCP_NAME}" MESSAGE="${UI_SET_FILE_PERMISSION} ${UI_SDHCP_NAME}"
@ -1653,8 +1671,9 @@ function validate_sudo_status {
if [ ! "$EUID" -ne 0 ]; then if [ ! "$EUID" -ne 0 ]; then
OS_LOCAL_ADMIN="" OS_LOCAL_ADMIN=""
else else
OS_SUDO_CHECK=$(groups ${OS_CURRENT_USER} | grep -e 'sudo' -e 'wheel') /usr/bin/sudo -u ${OS_CURRENT_USER} --validate
if [ "$OS_SUDO_CHECK" == "" ]; then OS_SUDO_CHECK=$?
if [ $OS_SUDO_CHECK -ne 0 ]; then
OS_LOCAL_ADMIN="nosudo" OS_LOCAL_ADMIN="nosudo"
else else
OS_LOCAL_ADMIN="sudo" OS_LOCAL_ADMIN="sudo"
@ -1802,7 +1821,7 @@ function config_generate {
elif [ "${REMOTE_PIHOLE_TYPE}" == "podman" ]; then elif [ "${REMOTE_PIHOLE_TYPE}" == "podman" ]; then
MESSAGE="Remote Podman container of ${UI_CORE_APP} detected" MESSAGE="Remote Podman container of ${UI_CORE_APP} detected"
echo_good_clean echo_good_clean
elif [ "${LOCAL_PIHOLE_TYPE}" == "none" ]; then elif [ "${REMOTE_PIHOLE_TYPE}" == "none" ]; then
MESSAGE="No remote ${UI_CORE_APP} installed detected" MESSAGE="No remote ${UI_CORE_APP} installed detected"
echo_warn echo_warn
end_config_no_pi end_config_no_pi
@ -1996,7 +2015,13 @@ function advanced_config_generate {
## Delete Existing Configuration ## Delete Existing Configuration
function config_delete { function config_delete {
# shellcheck source=/etc/gravity-sync/gravity-sync.conf # shellcheck source=/etc/gravity-sync/gravity-sync.conf
if [ -n "${GS_SSH_PORT}" ]; then
_GS_SSH_PORT=${GS_SSH_PORT}
fi
source ${GS_ETC_PATH}/${GS_CONFIG_FILE} source ${GS_ETC_PATH}/${GS_CONFIG_FILE}
if [ -n "${_GS_SSH_PORT}" ]; then
GS_SSH_PORT=${_GS_SSH_PORT}
fi
MESSAGE="${GS_CONFIG_FILE} ${UI_CONFIG_ALREADY}" MESSAGE="${GS_CONFIG_FILE} ${UI_CONFIG_ALREADY}"
echo_warn echo_warn

88
images/gs-logo.svg Normal file
View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="406px" height="180px" viewBox="0 0 406 180" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<!-- Generated by Pixelmator Pro 2.0.5 -->
<path id="Rounded-Rectangle-copy-3" d="M96.934 82.929 C93.029 86.834 93.029 93.166 96.934 97.071 L146.431 146.569 C150.337 150.474 156.668 150.474 160.574 146.569 L210.071 97.071 C213.976 93.166 213.976 86.834 210.071 82.929 L160.574 33.431 C156.668 29.526 150.337 29.526 146.431 33.431 Z" fill="#00a2ff" fill-opacity="1" stroke="none"/>
<defs>
<linearGradient id="linear-gradient" gradientUnits="userSpaceOnUse" x1="1.648" y1="84.65" x2="180.328" y2="88.78">
<stop offset="0" stop-color="#0ec9b0" stop-opacity="1"/>
<stop offset="1" stop-color="#22a5fb" stop-opacity="1"/>
</linearGradient>
</defs>
<path id="Ellipse-copy-3" d="M153.503 26.36 C118.355 -8.787 61.37 -8.787 26.223 26.36 -8.924 61.508 -8.924 118.492 26.223 153.64 61.37 188.787 118.355 188.787 153.503 153.64 188.65 118.492 188.65 61.508 153.503 26.36 Z" fill-opacity="1" fill="url(#linear-gradient)" stroke="none"/>
<g id="New-Group-copy-5">
<path id="Rounded-Rectangle-copy-1" d="M96.934 82.929 C93.029 86.834 93.029 93.166 96.934 97.071 L146.431 146.569 C150.337 150.474 156.668 150.474 160.574 146.569 L210.071 97.071 C213.976 93.166 213.976 86.834 210.071 82.929 L160.574 33.431 C156.668 29.526 150.337 29.526 146.431 33.431 Z" fill="#00a2ff" fill-opacity="1" stroke="none"/>
<defs>
<linearGradient id="linear-gradient-1" gradientUnits="userSpaceOnUse" x1="1.648" y1="84.65" x2="180.328" y2="88.78">
<stop offset="0" stop-color="#0ec9b0" stop-opacity="1"/>
<stop offset="1" stop-color="#22a5fb" stop-opacity="1"/>
</linearGradient>
</defs>
<path id="Ellipse-copy" d="M153.503 26.36 C118.355 -8.787 61.37 -8.787 26.223 26.36 -8.924 61.508 -8.924 118.492 26.223 153.64 61.37 188.787 118.355 188.787 153.503 153.64 188.65 118.492 188.65 61.508 153.503 26.36 Z" fill-opacity="1" fill="url(#linear-gradient-1)" stroke="none"/>
</g>
<path id="Rounded-Rectangle-copy" d="M96.934 82.929 C93.029 86.834 93.029 93.166 96.934 97.071 L132.289 132.426 C136.195 136.332 142.526 136.332 146.431 132.426 L181.787 97.071 C185.692 93.166 185.692 86.834 181.787 82.929 L146.431 47.574 C142.526 43.668 136.195 43.668 132.289 47.574 Z" fill="#ffffff" fill-opacity="1" stroke="none"/>
<path id="Ellipse-copy-2" d="M139.36 40.503 C112.024 13.166 67.702 13.166 40.365 40.503 13.029 67.839 13.029 112.161 40.365 139.497 67.702 166.834 112.024 166.834 139.36 139.497 166.697 112.161 166.697 67.839 139.36 40.503 Z" fill="#ffffff" fill-opacity="1" stroke="none"/>
<g id="New-Group-copy-4">
<path id="Path" d="M96.934 82.929 C93.029 86.834 93.029 93.166 96.934 97.071 L132.289 132.426 C136.195 136.332 142.526 136.332 146.431 132.426 L181.787 97.071 C185.692 93.166 185.692 86.834 181.787 82.929 L146.431 47.574 C142.526 43.668 136.195 43.668 132.289 47.574 Z" fill="#ffffff" fill-opacity="1" stroke="none"/>
<path id="Path-1" d="M139.36 40.503 C112.024 13.166 67.702 13.166 40.365 40.503 13.029 67.839 13.029 112.161 40.365 139.497 67.702 166.834 112.024 166.834 139.36 139.497 166.697 112.161 166.697 67.839 139.36 40.503 Z" fill="#ffffff" fill-opacity="1" stroke="none"/>
</g>
<path id="Rounded-Rectangle-copy-2" d="M309.066 97.071 C312.971 93.166 312.971 86.834 309.066 82.929 L259.569 33.431 C255.663 29.526 249.332 29.526 245.426 33.431 L195.929 82.929 C192.024 86.834 192.024 93.166 195.929 97.071 L245.426 146.569 C249.332 150.474 255.663 150.474 259.569 146.569 Z" fill="#00a2ff" fill-opacity="1" stroke="none"/>
<defs>
<linearGradient id="linear-gradient-2" gradientUnits="userSpaceOnUse" x1="283.044" y1="86.126" x2="405.807" y2="89.926">
<stop offset="0" stop-color="#21a9ff" stop-opacity="1"/>
<stop offset="1" stop-color="#fa3ebe" stop-opacity="1"/>
</linearGradient>
</defs>
<path id="Ellipse-copy-1" d="M252.497 153.64 C287.645 188.787 344.63 188.787 379.777 153.64 414.924 118.492 414.924 61.508 379.777 26.36 344.63 -8.787 287.645 -8.787 252.497 26.36 217.35 61.508 217.35 118.492 252.497 153.64 Z" fill-opacity="1" fill="url(#linear-gradient-2)" stroke="none"/>
<g id="New-Group-copy-2">
<path id="Rounded-Rectangle-copy-1-1" d="M309.066 97.071 C312.971 93.166 312.971 86.834 309.066 82.929 L259.569 33.431 C255.663 29.526 249.332 29.526 245.426 33.431 L195.929 82.929 C192.024 86.834 192.024 93.166 195.929 97.071 L245.426 146.569 C249.332 150.474 255.663 150.474 259.569 146.569 Z" fill="#00a2ff" fill-opacity="1" stroke="none"/>
<defs>
<linearGradient id="linear-gradient-3" gradientUnits="userSpaceOnUse" x1="283.044" y1="86.126" x2="405.807" y2="89.926">
<stop offset="0" stop-color="#21a9ff" stop-opacity="1"/>
<stop offset="1" stop-color="#fa3ebe" stop-opacity="1"/>
</linearGradient>
</defs>
<path id="Ellipse-copy-1" d="M252.497 153.64 C287.645 188.787 344.63 188.787 379.777 153.64 414.924 118.492 414.924 61.508 379.777 26.36 344.63 -8.787 287.645 -8.787 252.497 26.36 217.35 61.508 217.35 118.492 252.497 153.64 Z" fill-opacity="1" fill="url(#linear-gradient-3)" stroke="none"/>
</g>
<g id="New-Group-copy-1">
<path id="Path-2" d="M309.066 97.071 C312.971 93.166 312.971 86.834 309.066 82.929 L273.711 47.574 C269.805 43.668 263.474 43.668 259.569 47.574 L224.213 82.929 C220.308 86.834 220.308 93.166 224.213 97.071 L259.569 132.426 C263.474 136.332 269.805 136.332 273.711 132.426 Z" fill="#ffffff" fill-opacity="1" stroke="none"/>
<path id="Path-3" d="M266.64 139.497 C293.976 166.834 338.298 166.834 365.635 139.497 392.971 112.161 392.971 67.839 365.635 40.503 338.298 13.166 293.976 13.166 266.64 40.503 239.303 67.839 239.303 112.161 266.64 139.497 Z" fill="#ffffff" fill-opacity="1" stroke="none"/>
</g>
<defs>
<linearGradient id="linear-gradient-4" gradientUnits="userSpaceOnUse" x1="217.142" y1="75.858" x2="259.569" y2="33.431">
<stop offset="0" stop-color="#00a2ff" stop-opacity="1"/>
<stop offset="1" stop-color="#003758" stop-opacity="1"/>
</linearGradient>
</defs>
<path id="Rectangle-copy" d="M224.213 82.929 L266.64 40.503 252.497 26.36 210.071 68.787 Z" fill-opacity="1" fill="url(#linear-gradient-4)" stroke="none"/>
<path id="Ellipse-copy-2" d="M267.347 25.653 C263.441 21.748 257.11 21.748 253.205 25.653 249.299 29.559 249.299 35.89 253.205 39.795 257.11 43.701 263.441 43.701 267.347 39.795 271.252 35.89 271.252 29.559 267.347 25.653 Z" fill="#003758" fill-opacity="1" stroke="none"/>
<g id="New-Group">
<defs>
<radialGradient id="radial-gradient" gradientUnits="userSpaceOnUse" cx="89.863" cy="89.707" r="70" fx="89.863" fy="89.707">
<stop offset="0" stop-color="#fdbe2e" stop-opacity="1"/>
<stop offset="1" stop-color="#fe594d" stop-opacity="1"/>
</radialGradient>
</defs>
<path id="Path-4" d="M139.153 138.997 L139.36 40.209 40.573 40.417 40.365 139.204 Z" fill-opacity="1" fill="url(#radial-gradient)" stroke="none"/>
<g id="New-Group-1">
<path id="Path-copy-3" d="M40.791 40.198 C42.655 38.558 59.617 22.823 78.978 40.198 90.941 50.554 90.349 67.616 101.174 78.441 130.199 103.448 163.051 63.9 139.383 40.232 133.482 34.301 125.463 30.964 117.097 30.958 L63.143 30.947 C54.777 30.958 46.758 34.289 40.847 40.209" fill="#ffffff" fill-opacity="1" stroke="none"/>
<path id="Path-copy-2" d="M40.814 138.778 C39.162 136.926 23.439 119.953 40.814 100.592 51.158 88.618 68.209 89.22 79.045 78.385 104.064 49.371 64.527 16.529 40.858 40.198 34.925 46.096 31.588 54.117 31.585 62.483 L31.563 116.449 C31.569 124.82 34.91 132.843 40.847 138.745" fill="#ffffff" fill-opacity="1" stroke="none"/>
<path id="Path-copy-1" d="M139.371 138.778 C137.519 140.43 120.546 156.153 101.185 138.778 89.211 128.434 89.802 111.371 78.978 100.547 49.964 75.528 17.123 115.065 40.791 138.734 46.692 144.664 54.711 148.001 63.077 148.007 L117.053 148.018 C125.417 148.002 133.432 144.666 139.338 138.745" fill="#ffffff" fill-opacity="1" stroke="none"/>
<path id="Path-copy" d="M139.282 40.31 C140.934 42.162 156.657 59.135 139.282 78.496 128.926 90.459 111.875 89.856 101.04 100.692 76.032 129.717 115.569 162.558 139.238 138.89 145.171 132.991 148.508 124.971 148.511 116.605 L148.522 62.628 C148.516 54.262 145.179 46.244 139.249 40.343" fill="#ffffff" fill-opacity="1" stroke="none"/>
</g>
</g>
<g id="New-Group-copy">
<defs>
<radialGradient id="radial-gradient-1" gradientUnits="userSpaceOnUse" cx="317.138" cy="89.293" r="70" fx="317.138" fy="89.293">
<stop offset="0" stop-color="#fdbe2e" stop-opacity="1"/>
<stop offset="1" stop-color="#fe594d" stop-opacity="1"/>
</radialGradient>
</defs>
<path id="Path-5" d="M267.847 40.003 L267.64 138.79 366.428 138.583 366.635 39.795 Z" fill-opacity="1" fill="url(#radial-gradient-1)" stroke="none"/>
<g id="New-Group-2">
<path id="Path-copy-3-1" d="M366.209 138.801 C364.346 140.442 347.384 156.176 328.022 138.801 316.06 128.446 316.651 111.383 305.827 100.559 276.802 75.551 243.949 115.099 267.618 138.768 273.519 144.699 281.538 148.035 289.903 148.041 L343.857 148.052 C352.223 148.042 360.242 144.71 366.153 138.79" fill="#ffffff" fill-opacity="1" stroke="none"/>
<path id="Path-copy-2-1" d="M366.187 40.221 C367.838 42.074 383.562 59.047 366.187 78.408 355.842 90.382 338.791 89.779 327.955 100.615 302.937 129.629 342.474 162.47 366.142 138.801 372.075 132.903 375.413 124.883 375.415 116.517 L375.438 62.551 C375.432 54.18 372.09 46.156 366.153 40.255" fill="#ffffff" fill-opacity="1" stroke="none"/>
<path id="Path-copy-1-1" d="M267.629 40.221 C269.481 38.57 286.454 22.847 305.816 40.221 317.789 50.566 317.198 67.628 328.022 78.453 357.036 103.472 389.878 63.935 366.209 40.266 360.308 34.335 352.289 30.999 343.924 30.993 L289.947 30.982 C281.584 30.998 273.569 34.333 267.662 40.255" fill="#ffffff" fill-opacity="1" stroke="none"/>
<path id="Path-copy-1" d="M267.718 138.69 C266.067 136.837 250.343 119.864 267.718 100.503 278.074 88.541 295.125 89.143 305.961 78.308 330.968 49.283 291.431 16.441 267.763 40.11 261.83 46.008 258.492 54.028 258.49 62.395 L258.478 116.372 C258.485 124.737 261.821 132.756 267.752 138.656" fill="#ffffff" fill-opacity="1" stroke="none"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB