Updated manager.sh and README files

This commit is contained in:
2025-03-20 05:34:10 +03:00
parent 4c844bcee3
commit 61a8179b79
3 changed files with 342 additions and 110 deletions

View File

@@ -7,4 +7,16 @@
3. Install & Manage Script
### Getting Started:
Run this command:
Install required dependencies:
```bash
sudo apt-get update && sudo apt-get upgrade && sudo apt-get install wget git docker.io -y
```
Run the setup script:
```bash
wget -qO- https://gitea.abdulhade.com/abdulhade/db-middleware/raw/branch/main/scripts/setup.sh | bash
```

View File

@@ -9,4 +9,5 @@ IMAGE_NAME="db-middleware"
CONTAINER_NAME="con-db-middleware"
# Databases settings
HAS_LOCAL_DBS=1
HAS_LOCAL_DBS=0

View File

@@ -4,10 +4,14 @@ APP_DIR="$HOME/.db-middleware"
CODE_DIR="$APP_DIR/code"
CONFIG_DIR="$APP_DIR/configs"
CONFIG_FILE="$CONFIG_DIR/app.conf"
REPO_URL="https://gitea.abdulhade.com/abdulhade/db-middleware.git"
LOADED_CONFIG=0
# Default values
APP_NAME="Database Middleware"
IMAGE_NAME="db-middleware"
CONTAINER_NAME="con-db-middleware"
REPO_URL="https://gitea.abdulhade.com/abdulhade/db-middleware.git"
EXECUTION_MESSAGE="NO-RETURN"
@@ -25,6 +29,7 @@ print_header() {
local BORDER_LENGTH=$((MAX_LENGTH + 2)) # Add 4 for padding (2 spaces)
echo
# Print the top border
printf '+%*s+\n' "$BORDER_LENGTH" "" | tr ' ' '-'
@@ -35,9 +40,14 @@ print_header() {
# Print the bottom border
printf '+%*s+\n' "$BORDER_LENGTH" "" | tr ' ' '-'
echo
}
build_docker_image() {
if ! cd "$CODE_DIR"; then
print_header "Failed to navigate to $CODE_DIR."
return 1
fi
echo "Building Docker image..."
if docker build -t "$IMAGE_NAME" .; then
echo "Docker image built successfully."
@@ -47,6 +57,24 @@ build_docker_image() {
return 1
fi
}
set_up_middleware() {
print_header "Rebuilding the Docker Container..."
if ! build_docker_image; then
print_header "Can't build the Docker image."
return 1 # Error
fi
if ! set_up_scripts; then
print_header "Failed to set up scripts."
return 1 # Error
fi
print_header "Rebuild the Docker Container."
return 0
}
test() {
echo "I am here"
return 1
@@ -58,7 +86,7 @@ exec_in_container() {
local COMMAND="$1"
# Check if the container is running
if ! docker ps --format '{{.Names}}' | grep -q "^$CONTAINER_NAME$"; then
echo "Error: Container '$CONTAINER_NAME' is not running."
print_header "Error: Container '$CONTAINER_NAME' is not running."
return 1
fi
@@ -71,8 +99,8 @@ exec_in_container() {
EXECUTION_MESSAGE="$OUTPUT" # Return the output
return 0
else
echo "Error: Command failed in container '$CONTAINER_NAME' with exit code $EXIT_CODE."
echo "Output: $OUTPUT"
print_header "Error: Command failed in container '$CONTAINER_NAME' with exit code $EXIT_CODE.
Output: $OUTPUT"
return $EXIT_CODE
fi
}
@@ -82,13 +110,13 @@ set_up_scripts() {
# Copy scripts
if ! cp "$CODE_DIR/scripts/"* "$APP_DIR/scripts/"; then
echo "Failed to copy scripts."
print_header "Failed to copy scripts."
return 1
fi
# Give execution permission
if ! chmod +x "$APP_DIR/scripts/"*; then
echo "Failed to set execution permissions."
print_header "Failed to set execution permissions."
return 1
fi
@@ -97,7 +125,7 @@ set_up_scripts() {
# Create symlink
if ! ln -sf "$APP_DIR/scripts/manager.sh" "$HOME/.local/bin/db-middleware"; then
echo "Failed to create symlink."
print_header "Failed to create symlink."
# TODO Here we should handle the case of having the symlink created previously.
return 1
fi
@@ -109,7 +137,7 @@ set_up_scripts() {
# Reload bashrc
if ! source ~/.bashrc; then
echo "Failed to reload ~/.bashrc."
print_header "Failed to reload ~/.bashrc."
return 1
fi
@@ -117,6 +145,71 @@ set_up_scripts() {
return 0
}
update_config() {
print_header "Update configs."
echo "Key: API_PORT, Current value: \`$API_PORT\`"
read -p " > Enter new value (leave empty to pass): " NEW_API_PORT
echo
if [[ $NEW_API_PORT == "" ]]; then
NEW_API_PORT=$API_PORT
fi
echo "Key: CONTAINER_NAME, Current value: \`$CONTAINER_NAME\`"
read -p " > Enter new value (leave empty to pass): " NEW_CONTAINER_NAME
echo
if [[ $NEW_CONTAINER_NAME == "" ]]; then
NEW_CONTAINER_NAME=$CONTAINER_NAME
fi
echo "Key: HAS_LOCAL_DBS, Current value: \`$HAS_LOCAL_DBS\`"
read -p " > Enter new value (leave empty to pass): " NEW_HAS_LOCAL_DBS
echo
if [[ $NEW_HAS_LOCAL_DBS == "" ]]; then
NEW_HAS_LOCAL_DBS=$HAS_LOCAL_DBS
fi
print_header "Here are the old and new values:
API_PORT: \`$API_PORT > $NEW_API_PORT\`
CONTAINER_NAME: \`$CONTAINER_NAME > $NEW_CONTAINER_NAME\`
HAS_LOCAL_DBS: \`$HAS_LOCAL_DBS > $NEW_HAS_LOCAL_DBS\`"
read -p " > To confirm these changes, enter (y) otherwise enter anything: " CONFIRM_CHANGES
if [[ $CONFIRM_CHANGES == "y" ]]; then
API_PORT=$NEW_API_PORT
CONTAINER_NAME=$NEW_CONTAINER_NAME
HAS_LOCAL_DBS=$NEW_HAS_LOCAL_DBS
write_config
print_header "Saved the new configs! You can now rebuild the docker container."
return 0
fi
print_header "Discarded the changes."
}
write_config() {
CONFIG_TEXT="
# Application settings
APP_NAME=\"$APP_NAME\"
API_PORT=\"$API_PORT\"
# Docker Container settings
IMAGE_NAME=\"$IMAGE_NAME\"
CONTAINER_NAME=\"$CONTAINER_NAME\"
# Databases settings
HAS_LOCAL_DBS=\"$HAS_LOCAL_DBS\"
"
echo "$CONFIG_TEXT" > "$CONFIG_FILE"
}
load_config() {
if [[ -f "$CONFIG_FILE" ]]; then
if source "$CONFIG_FILE"; then
@@ -124,32 +217,42 @@ load_config() {
echo "Config file loaded successfully."
return 0
else
echo "Failed to load config file."
print_header "Failed to load config file."
return 1
fi
else
echo "Config file not found: $CONFIG_FILE"
print_header "Config file not found: $CONFIG_FILE"
return 1
fi
}
get_run_command() {
local RUN_COMMAND="docker run -d --name $CONTAINER_NAME"
if [[ $HAS_LOCAL_DBS -eq 1 || $HAS_LOCAL_DBS == "1" ]]; then
RUN_COMMAND+=" --network host"
else
RUN_COMMAND+=" -p ${API_PORT:-8080}:8080"
fi
RUN_COMMAND+=" $IMAGE_NAME"
echo $RUN_COMMAND
}
show_config() {
if [[ $LOADED_CONFIG -eq 0 ]]; then
echo "Config not loaded. Please load the config file first."
print_header "Config not loaded. Please load the config file first."
return 1
fi
echo "Current Config:"
echo "CONTAINER_NAME: ${CONTAINER_NAME:-Not set}"
echo "API_PORT: ${API_PORT:-Not set}"
echo "HAS_LOCAL_DBS: ${HAS_LOCAL_DBS:-Not set}"
local RUN_COMMAND="docker run --name $CONTAINER_NAME"
if [[ $HAS_LOCAL_DBS -eq 1 ]]; then
RUN_COMMAND+=" --network host"
fi
RUN_COMMAND+=" -p ${API_PORT:-8080}:8080 $IMAGE_NAME"
echo "Run Command: $RUN_COMMAND"
local RUN_COMMAND=$(get_run_command)
print_header "Current Config:
CONTAINER_NAME: ${CONTAINER_NAME:-Not set}
API_PORT: ${API_PORT:-Not set}
HAS_LOCAL_DBS: ${HAS_LOCAL_DBS:-Not set}
Run Command: $RUN_COMMAND"
return 0
}
@@ -181,36 +284,30 @@ convert_ports_to_docker_args() {
}
install() {
echo
echo "+------------------------------+"
echo "| Installing the Middleware... |"
echo "+------------------------------+"
echo
print_header "Installing the Middleware..."
if ! cd "$CODE_DIR"; then
echo "Failed to navigate to $CODE_DIR."
print_header "Failed to navigate to $CODE_DIR."
return 1
fi
if ! build_docker_image; then
echo "Failed to build Docker image."
print_header "Failed to build Docker image."
return 1
fi
echo
echo "+----------------------------------------+"
echo "| Installed the Middleware Successfully! |"
echo "+----------------------------------------+"
echo
echo "- You can run the middleware simply using the manager:"
echo " >>> db-middleware start"
echo "- Or directly by running the docker container:"
echo " >>> docker run $IMAGE_NAME -p <port>:<port> -v /path/to/app/directory/"
print_header "Installed the Middleware Successfully!
- You can run the middleware simply using the manager:
>>> db-middleware start
- Or directly by running the docker container:
>>> $(get_run_command)"
return 0
}
pull_clone_repo() {
local UPDATED=-1 # Default: No changes
local UP_TO_DATE=-1 # Default: No changes
echo "Setting up repository..."
@@ -231,7 +328,7 @@ pull_clone_repo() {
return 1 # Error
fi
echo "Repository cloned successfully."
UPDATED=0 # Changes were applied
UP_TO_DATE=0 # Changes were applied
else
# Check if the directory contains a Git repository
if [[ -d ".git" ]]; then
@@ -244,6 +341,7 @@ pull_clone_repo() {
fi
# Get the local and remote HEAD commit hashes
echo
LOCAL_HEAD=$(git rev-parse HEAD)
REMOTE_HEAD=$(git rev-parse origin/main)
exec_in_container "git rev-parse HEAD"
@@ -264,24 +362,27 @@ pull_clone_repo() {
echo
if [[ "$CONTAINER_HEAD" == "$LOCAL_HEAD" && "$LOCAL_HEAD" == "$REMOTE_HEAD" ]]; then
echo "Repo is up to date."
UPDATED=-1
UP_TO_DATE=-1
elif [[ "$LOCAL_HEAD" != "$REMOTE_HEAD" ]]; then
echo "Remote repository has new changes. Pulling latest changes..."
echo
if ! git pull "$REPO_URL"; then
echo "Failed to pull changes."
return 1 # Error
fi
echo
echo "Local Repository updated successfully."
LOCAL_HEAD=$(git rev-parse HEAD)
UPDATED=0 # Changes were applied
UP_TO_DATE=0 # Changes were applied
else
echo "Local Repository is already up to date."
UPDATED=-1 # No changes
# echo $UPDATED
UP_TO_DATE=-1 # No changes
# echo $UP_TO_DATE
fi
if [[ "$LOCAL_HEAD" != "$CONTAINER_HEAD" ]]; then
echo "Container Repository is not up to date."
UP_TO_DATE=0
fi
else
@@ -293,27 +394,27 @@ pull_clone_repo() {
echo "Repository setup completed successfully."
return $UPDATED # -1 = No changes, 0 = Changes applied
return $UP_TO_DATE # -1 = No changes, 0 = Changes applied
}
update_code() {
print_header "Checking for updates..."
echo
pull_clone_repo
local UPDATED=$?
echo
case $UPDATED in
pull_clone_repo
local UP_TO_DATE=$?
case $UP_TO_DATE in
# 255 is -1, because Bash return codes are unsigned 8-bit integer, limited to the range 0 to 255.
-1|255)
print_header "No changes detected."
return -1 # No changes
;;
-0)
print_header "Changes were detected and applied to local repo.
0)
print_header "Changes were detected and applied to local repo, but not to the container.
Need to rebuild the container, run:
>>> db-middleware upgrade
"
return 0 # Changes applied
@@ -323,18 +424,15 @@ Need to rebuild the container, run:
return 1 # Error
;;
*)
print_header "Wrong return code: \`$UPDATED\` from pull_clone_repo."
print_header "Wrong return code: \`$UP_TO_DATE\` from pull_clone_repo."
return 1
;;
esac
}
upgrade() {
echo
echo "+-----------------------------+"
echo "| Upgrading the Middleware... |"
echo "+-----------------------------+"
echo
print_header "Upgrading the Middleware..."
update_code
local UPDATE_RESULT=$?
@@ -342,83 +440,201 @@ upgrade() {
case $UPDATE_RESULT in
# 255 is -1, because Bash return codes are unsigned 8-bit integer, limited to the range 0 to 255.
-1|255)
echo
echo "+------------------------------------------+"
echo "| No changes detected. Skipping upgrade... |"
echo "+------------------------------------------+"
echo
print_header "No changes detected. Skipping upgrade..."
;;
0)
echo
echo "+--------------------------------+"
echo "| Rebuilding the Docker Image... |"
echo "+--------------------------------+"
echo
if ! build_docker_image; then
echo "Failed to rebuild Docker image."
return 1 # Error
fi
if ! set_up_scripts; then
echo "Failed to set up scripts."
return 1 # Error
fi
echo
echo "+---------------------------------------+"
echo "| Upgraded the Middleware Successfully! |"
echo "+---------------------------------------+"
echo
if ! set_up_middleware; then
print_header "Failed to rebuild Docker image."
return 1 # Error
fi
;;
1)
echo "Failed to update code. Upgrade aborted."
print_header "Failed to update code. Upgrade aborted."
return 1 # Error
;;
esac
print_header "Upgraded the Middleware Successfully!"
return 0
}
status() {
echo "Checking container status..."
if docker ps --filter "name=$CONTAINER_NAME" --format "{{.Status}}"; then
print_header "Checking container status..."
# Check if the container exists
if ! docker ps -a --format '{{.Names}}' | grep -q "^$CONTAINER_NAME$"; then
print_header "Container '$CONTAINER_NAME' does not exist."
return 1
fi
# Get container status
local CONTAINER_STATUS
CONTAINER_STATUS=$(docker ps --filter "name=$CONTAINER_NAME" --format "{{.Status}}")
if [[ -z "$CONTAINER_STATUS" ]]; then
print_header "Container '$CONTAINER_NAME' is not running."
return 0
fi
# Get detailed container information using `docker inspect`
local CONTAINER_INFO
CONTAINER_INFO=$(docker inspect "$CONTAINER_NAME" 2>/dev/null)
if [[ -z "$CONTAINER_INFO" ]]; then
print_header "Failed to inspect container '$CONTAINER_NAME'."
return 1
fi
# Extract useful information
local CPU_PERCENT MEM_USAGE MEM_PERCENT NET_IO BLOCK_IO IP_ADDRESS PORTS RUN_COMMAND NETWORK_MODE
# Resource usage (CPU, memory, storage)
STATS_OUTPUT=$(docker stats --no-stream --format "{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}" "$CONTAINER_NAME")
# Split the output into individual variables
IFS=$'\t' read -r CPU_PERCENT MEM_USAGE MEM_PERCENT NET_IO BLOCK_IO <<< "$STATS_OUTPUT"
# Network information
NETWORK_MODE=$(echo "$CONTAINER_INFO" | grep -oP '"NetworkMode": "\K[^"]+')
if [[ "$NETWORK_MODE" == "host" ]]; then
IP_ADDRESS="Host Network (No separate IP)"
PORTS="Host Network (Ports are directly bound to host)"
else
echo "Failed to check container status."
return 1
fi
}
IP_ADDRESS=$(echo "$CONTAINER_INFO" | grep -oP '"IPAddress": "\K[^"]+')
start() {
echo "+---------------------------+"
echo "| Starting the Container... |"
echo "+---------------------------+"
echo
if ! docker run --name "$CONTAINER_NAME" -p "${API_PORT:-8080}:8080" "$IMAGE_NAME"; then
echo "Failed to start container."
return 1
# Extract port mappings from docker ps --no-trunc
PORTS=$(docker ps --filter "name=$CONTAINER_NAME" --no-trunc --format "{{.Ports}}")
if [[ -z "$PORTS" ]]; then
PORTS="No port mappings"
fi
fi
# Run command (from docker ps --no-trunc)
RUN_COMMAND=$(docker ps --filter "name=$CONTAINER_NAME" --no-trunc --format "{{.Command}}")
# Build the output string
local OUTPUT
OUTPUT="Database Middleware Status:
[Container]
Name: $CONTAINER_NAME
Status: $CONTAINER_STATUS
[Performance]
CPU Usage: $CPU_PERCENT
Memory Usage: $MEM_USAGE ($MEM_PERCENT)
Block I/O: $BLOCK_IO
Network I/O: $NET_IO
[Network]
Network Mode: $NETWORK_MODE
IP Address: $IP_ADDRESS
Ports: $PORTS
[App]
Run Command: $RUN_COMMAND"
print_header "$OUTPUT"
return 0
}
stop() {
echo "Stopping the container..."
if docker stop "$CONTAINER_NAME"; then
echo "Container stopped successfully."
return 0
start() {
RUN_COMMAND=$(get_run_command)
print_header "Starting the Container...
With run command:
>>> $RUN_COMMAND"
# Check if a container with the same name already exists
if docker ps -a --format '{{.Names}}' | grep -q "^$CONTAINER_NAME$"; then
# Check if the container is already running
if docker ps --format '{{.Names}}' | grep -q "^$CONTAINER_NAME$"; then
print_header "Container '$CONTAINER_NAME' is already running.
You can restart it with:
>>> $0 restart"
return 0
else
# Start the existing container
if docker start "$CONTAINER_NAME"; then
print_header "Started the existing container '$CONTAINER_NAME' successfully."
return 0
else
print_header "Failed to start the existing container '$CONTAINER_NAME'."
return 1
fi
fi
else
echo "Failed to stop container."
# Run a new container
if eval "$RUN_COMMAND"; then
print_header "Started the container '$CONTAINER_NAME' successfully."
return 0
else
print_header "Failed to start the container '$CONTAINER_NAME'."
return 1
fi
fi
}
restart() {
print_header "Restarting the Container..."
# Check if a container with the same name exists (running or stopped)
if docker ps -a --format '{{.Names}}' | grep -q "^$CONTAINER_NAME$"; then
# Restart the container
if docker restart "$CONTAINER_NAME"; then
print_header "Restarted the container '$CONTAINER_NAME' successfully."
return 0
else
print_header "Failed to restart the container '$CONTAINER_NAME'."
return 1
fi
else
print_header "Container '$CONTAINER_NAME' does not exist. Cannot restart.
You can start it with:
>>> $0 start"
return 1
fi
}
stop() {
print_header "Stopping the Container..."
# Check if the container exists (running or stopped)
if docker ps -a --format '{{.Names}}' | grep -q "^$CONTAINER_NAME$"; then
# Check if the container is running
if docker ps --format '{{.Names}}' | grep -q "^$CONTAINER_NAME$"; then
# Stop the container
if docker stop "$CONTAINER_NAME"; then
print_header "Stopped the container '$CONTAINER_NAME' successfully."
return 0
else
print_header "Failed to stop the container '$CONTAINER_NAME'."
return 1
fi
else
print_header "Container '$CONTAINER_NAME' is not running."
return 0
fi
else
print_header "Container '$CONTAINER_NAME' does not exist. Cannot stop."
return 1
fi
}
usage() {
print_header "Usage:
>>> $0 {install|upgrade|update_code|status|start|stop|show_config}"
>>> $0 {install|upgrade|rebuild|update_code|status|start|stop|show_config}"
exit 1
}
@@ -430,16 +646,18 @@ main() {
fi
if ! load_config; then
echo "Failed to load config. Exiting."
print_header "Failed to load config. Exiting."
exit 1
fi
# Handle the argument
case "$1" in
install) install ;;
update_code) update_code ;;
rebuild) set_up_middleware;;
upgrade) upgrade ;;
status) status ;;
start) start ;;
restart) restart;;
status) status ;;
show_config) show_config ;;
stop) stop ;;
*) echo "Invalid argument: $1"; usage ;;
@@ -447,7 +665,8 @@ main() {
}
# Run the script with the provided arguments
load_config
update_config
main "$@"