adding script
This commit is contained in:
parent
d3dbb465d3
commit
8a6249c930
2 changed files with 206 additions and 0 deletions
16
scripts/README.md
Normal file
16
scripts/README.md
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
Make executable:
|
||||||
|
```
|
||||||
|
sudo chmod +x dccd.sh
|
||||||
|
```
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
./dccd.sh -b main -d /home/mafyuh/Auto-Homelab -p -f 'arrs'
|
||||||
|
```
|
||||||
|
Crontab:
|
||||||
|
```
|
||||||
|
*/30 * * * * /home/mafyuh/dccd.sh -b main -d /home/mafyuh/Auto-Homelab -l /tmp/dccd.txt -p -f 'arrs'
|
||||||
|
```
|
||||||
|
View Logs:
|
||||||
|
```
|
||||||
|
cat /tmp/dccd.txt
|
||||||
|
```
|
190
scripts/dccd.sh
Executable file
190
scripts/dccd.sh
Executable file
|
@ -0,0 +1,190 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# Default configuration values
|
||||||
|
########################################
|
||||||
|
BASE_DIR="" # Initialize empty variable
|
||||||
|
LOG_FILE="/tmp/dccd.log" # Default log file name
|
||||||
|
PRUNE=0 # Default prune setting
|
||||||
|
REMOTE_BRANCH="main" # Default remote branch name
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# Functions
|
||||||
|
########################################
|
||||||
|
log_message() {
|
||||||
|
local message="$1"
|
||||||
|
echo "$(date +'%Y-%m-%d %H:%M:%S') - $message" | tee -a "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
update_compose_files() {
|
||||||
|
local dir="$1"
|
||||||
|
local folder_pattern="$2" # Added parameter for folder pattern
|
||||||
|
|
||||||
|
cd "$dir" || { log_message "ERROR: Directory doesn't exist, exiting..."; exit 127; }
|
||||||
|
|
||||||
|
# Make sure we're in a git repo
|
||||||
|
if [ ! -d .git ]; then
|
||||||
|
log_message "ERROR: Directory is not a git repository, exiting..."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
log_message "INFO: Git repository found!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if there are any changes in the Git repository
|
||||||
|
if ! git fetch origin; then
|
||||||
|
log_message "ERROR: Unable to fetch changes from the remote repository (the server may be offline or unreachable)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local_hash=$(git rev-parse HEAD)
|
||||||
|
remote_hash=$(git rev-parse "origin/$REMOTE_BRANCH")
|
||||||
|
log_message "INFO: Local hash is $local_hash"
|
||||||
|
log_message "INFO: Remote hash is $remote_hash"
|
||||||
|
|
||||||
|
# Check for uncommitted local changes
|
||||||
|
uncommitted_changes=$(git status --porcelain)
|
||||||
|
if [ -n "$uncommitted_changes" ]; then
|
||||||
|
log_message "ERROR: Uncommitted changes detected in $dir, exiting..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if the local hash matches the remote hash
|
||||||
|
if [ "$local_hash" != "$remote_hash" ]; then
|
||||||
|
log_message "STATE: Hashes don't match, updating..."
|
||||||
|
|
||||||
|
# Pull any changes in the Git repository
|
||||||
|
if ! git pull --quiet origin "$REMOTE_BRANCH"; then
|
||||||
|
log_message "ERROR: Unable to pull changes from the remote repository (the server may be offline or unreachable)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Loop through directories matching the specified pattern
|
||||||
|
find "$dir" -type d -name "$folder_pattern" | while IFS= read -r folder; do
|
||||||
|
log_message "INFO: Found folder matching pattern: $folder"
|
||||||
|
|
||||||
|
# If EXCLUDE is set and the directory matches the exclude pattern, skip
|
||||||
|
if [ -n "$EXCLUDE" ] && [[ "$folder" == *"$EXCLUDE"* ]]; then
|
||||||
|
log_message "INFO: Excluding directory $folder"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Go into the directory
|
||||||
|
cd "$folder" || { log_message "ERROR: Failed to enter directory $folder"; continue; }
|
||||||
|
|
||||||
|
# Redeploy compose file in this directory
|
||||||
|
log_message "STATE: Redeploying compose file in directory: $folder"
|
||||||
|
docker compose up -d --quiet-pull
|
||||||
|
|
||||||
|
# Go back to the original directory
|
||||||
|
cd "$dir" || { log_message "ERROR: Failed to return to directory $dir"; exit 1; }
|
||||||
|
done
|
||||||
|
else
|
||||||
|
log_message "STATE: Hashes match, so nothing to do"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if PRUNE is provided
|
||||||
|
if [ $PRUNE -eq 1 ]; then
|
||||||
|
log_message "STATE: Pruning images"
|
||||||
|
docker image prune --all --force
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_message "STATE: Done!"
|
||||||
|
}
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
printf "
|
||||||
|
Usage: $0 [OPTIONS]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-b <name> Specify the remote branch to track (default: main)
|
||||||
|
-d <path> Specify the base directory of the git repository (required)
|
||||||
|
-h Show this help message
|
||||||
|
-l <path> Specify the path to the log file (default: /tmp/dccd.log)
|
||||||
|
-p Specify if you want to prune docker images (default: don't prune)
|
||||||
|
-x <path> Exclude directories matching the specified pattern (relative to the base directory)
|
||||||
|
-f <pattern> Specify the pattern for folder names to match
|
||||||
|
|
||||||
|
Example: /path/to/dccd.sh -b master -d /path/to/git_repo -l /tmp/dccd.txt -p -f 'arrs'
|
||||||
|
|
||||||
|
"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# Options
|
||||||
|
########################################
|
||||||
|
|
||||||
|
while getopts ":b:d:hl:px:f:" opt; do
|
||||||
|
case "$opt" in
|
||||||
|
b)
|
||||||
|
REMOTE_BRANCH="$OPTARG"
|
||||||
|
;;
|
||||||
|
d)
|
||||||
|
BASE_DIR="$OPTARG"
|
||||||
|
;;
|
||||||
|
h)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
l)
|
||||||
|
LOG_FILE="$OPTARG"
|
||||||
|
;;
|
||||||
|
p)
|
||||||
|
PRUNE=1
|
||||||
|
;;
|
||||||
|
x)
|
||||||
|
EXCLUDE="$OPTARG"
|
||||||
|
;;
|
||||||
|
f)
|
||||||
|
FOLDER_PATTERN="$OPTARG"
|
||||||
|
;;
|
||||||
|
\?)
|
||||||
|
echo "Invalid option: -$OPTARG" >&2
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
:)
|
||||||
|
echo "Option -$OPTARG requires an argument." >&2
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# Script starts here
|
||||||
|
########################################
|
||||||
|
|
||||||
|
touch "$LOG_FILE"
|
||||||
|
{
|
||||||
|
echo "########################################"
|
||||||
|
echo "# Starting!"
|
||||||
|
echo "########################################"
|
||||||
|
} >> "$LOG_FILE"
|
||||||
|
|
||||||
|
# Check if BASE_DIR is provided
|
||||||
|
if [ -z "$BASE_DIR" ]; then
|
||||||
|
log_message "ERROR: The base directory (-d) is required, exiting..."
|
||||||
|
usage
|
||||||
|
else
|
||||||
|
log_message "INFO: Base directory is set to $BASE_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if REMOTE_BRANCH is provided
|
||||||
|
if [ -z "$REMOTE_BRANCH" ]; then
|
||||||
|
log_message "INFO: The remote branch isn't specified, so using $REMOTE_BRANCH"
|
||||||
|
else
|
||||||
|
log_message "INFO: The remote branch is set to $REMOTE_BRANCH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if EXCLUDE is provided
|
||||||
|
if [ -n "$EXCLUDE" ]; then
|
||||||
|
log_message "INFO: Will be excluding pattern $EXCLUDE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if FOLDER_PATTERN is provided
|
||||||
|
if [ -z "$FOLDER_PATTERN" ]; then
|
||||||
|
log_message "ERROR: The folder pattern (-f) is required, exiting..."
|
||||||
|
usage
|
||||||
|
else
|
||||||
|
log_message "INFO: Folder pattern is set to $FOLDER_PATTERN"
|
||||||
|
fi
|
||||||
|
|
||||||
|
update_compose_files "$BASE_DIR" "$FOLDER_PATTERN"
|
Reference in a new issue