10 Commits

Author SHA1 Message Date
962b1628c2 Update Joomla SMTP host port number #11
The port number for the JOOMLA_SMTP_HOST has been updated from 1080 to 1025. This change has been made in two places in the code - under VDM_EXTRA_JOOMLA_ENV. This will correct the SMTP settings and ensure emails from Joomla are correctly routed through the mailcatcher service.
2024-06-13 14:24:06 +02:00
b666db9f33 Add functionality to clone containers and volumes #9
The commit introduces a new feature that allows users to clone both containers and volumes. Functions have been added to facilitate the cloning process, including joomla__TRuST__clone, cloneContainer, and clonePersistentVolume. Adjustments have also been made in the main program to include this new cloning option into the interactive menu.
2024-06-13 14:22:12 +02:00
ed147ece9e Update OctoJoom version and improve password validation #10
The OctoJoom version was updated to 3.6.2. Changes were also made to the password validation process to increase the minimum required length of the password from 4 to 11 characters for the correct error message.
2024-06-01 15:23:19 +02:00
8cf856b35e Set LC_ALL to C in octojoom script #10
This commit sets the enviroment variable LC_ALL to 'C' in the octojoom script. This ensures the use of ASCII character set and standardizes behavior across different environments for consistency.
2024-06-01 15:17:05 +02:00
1a83002c9d Add automatic whiptail installation and error notices for missing software dependencies #8
This commit modifies the script to automatically install 'whiptail' on Linux, macOS, and Windows if it's not already installed. It also adds error notices instructing the user to install other software dependencies if they're missing. This makes the script more user-friendly and reduces the likelihood of script failure due to missing dependencies.
2024-06-01 15:15:42 +02:00
e627e7f4cd Remove Docker Compose version from YML files and set networks to external
The Docker Compose version definition was removed from traefikContainer, portainerContainer, and opensshContainer functions. The "external" attribute was also added to "traefik" and "openssh" networks. These changes aim to improve the versatility and compatibility of network settings and remove unnecessary version constraints.
2024-06-01 15:11:16 +02:00
eaa5b217c8 Update shebang for shell compatibility #6
Changed the shebang in the octojoom script. This change improves portability by allowing the script to run in environments where /bin/bash may not be available.
2024-06-01 15:08:38 +02:00
b7973a0011 We want the function to be called function. 2024-05-27 10:03:36 +02:00
0d2649601a Add better host management for OSs 2024-05-27 09:58:41 +02:00
9566019630 Add MACOS and WIN compatibility. 2024-05-27 09:36:24 +02:00

View File

@ -1,8 +1,11 @@
#!/bin/bash #!/usr/bin/env bash
# The most recent program version. # The most recent program version.
_VERSION="3.5.1" _VERSION="3.6.3"
_V="3.5" _V="3.6"
# Bash version required
_bash_v=4
# The program full name # The program full name
PROGRAM_NAME="Octojoom" PROGRAM_NAME="Octojoom"
@ -13,75 +16,216 @@ SERVER_HOSTNAME="$(hostname)"
# Set the back title # Set the back title
BACK_TITLE=" Octoleo | ${USER}@${SERVER_HOSTNAME}" BACK_TITLE=" Octoleo | ${USER}@${SERVER_HOSTNAME}"
# make sure whiptail is installed #####################################################################################################################VDM
command -v whiptail >/dev/null 2>&1 || { ######################################## The environment preparation
echo >&2 "ERROR: ${PROGRAM_NAME} v${_VERSION} script require whiptail."
exit 1
}
# make sure curl is installed # make sure curl is installed
command -v curl >/dev/null 2>&1 || { command -v curl >/dev/null 2>&1 || {
echo >&2 "ERROR: ${PROGRAM_NAME} v${_VERSION} script require curl." echo >&2 "ERROR: ${PROGRAM_NAME} v${_VERSION} script require curl."
echo >&2 "NOTICE: Please install curl first and then re-run this script again."
exit 1 exit 1
} }
# Set OS number
OS_NUMBER=0 # Unknown
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
OS_NUMBER=1
elif [[ "$OSTYPE" == "darwin"* ]]; then
OS_NUMBER=2
elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" ]]; then
OS_NUMBER=3
fi
# Check Bash version
function check_bash_version() {
local bash_version="$1"
local version_string="$BASH_VERSION"
local major_version="${version_string%%.*}"
local rest="${version_string#*.}"
local minor_version="${rest%%.*}"
if (( major_version < bash_version )) || (( major_version == bash_version && minor_version < 0 )); then
echo >&2 "ERROR: ${PROGRAM_NAME} v${_VERSION} script requires Bash version ${bash_version}.0 or above."
exit 1
fi
}
# Check for the appropriate version of Bash
check_bash_version "$_bash_v"
# Install whiptail on Ubuntu
function install_whiptail_linux() {
sudo apt-get update
sudo apt-get install whiptail -y
}
# Install whiptail on macOS
function install_whiptail_macos() {
if ! command -v brew >/dev/null 2>&1; then
echo >&2 "ERROR: ${PROGRAM_NAME} v${_VERSION} script require Homebrew to install whiptail on macOS."
echo >&2 "NOTICE: Please install Homebrew first and then re-run this script."
exit 1
fi
brew install newt
}
# Install whiptail on Windows using Chocolatey
function install_whiptail_windows() {
if ! command -v choco >/dev/null 2>&1; then
echo >&2 "ERROR: ${PROGRAM_NAME} v${_VERSION} script require Chocolatey to install whiptail on Windows."
echo >&2 "NOTICE: Please install Chocolatey first and then re-run this script."
exit 1
fi
choco install newt
}
# Main script
if ! command -v whiptail >/dev/null 2>&1; then
echo "Whiptail is not installed. Do you want to install it now? (y/n)"
read -r response
if [[ "$response" =~ ^[Yy]$ ]]; then
# If the user chooses Yes, install Docker based on the OS
case "$OS_NUMBER" in
1)
install_whiptail_linux
;;
2)
install_whiptail_macos
;;
3)
install_whiptail_windows
;;
*)
echo >&2 "ERROR: Unsupported operating system."
exit 1
;;
esac
else
echo >&2 "ERROR: ${PROGRAM_NAME} v${_VERSION} script require whiptail."
echo >&2 "NOTICE: Please install whiptail first and then re-run this script again."
exit 1
fi
fi
# make sure awk is installed # make sure awk is installed
command -v awk >/dev/null 2>&1 || { command -v awk >/dev/null 2>&1 || {
echo >&2 "ERROR: ${PROGRAM_NAME} v${_VERSION} script require awk." echo >&2 "ERROR: ${PROGRAM_NAME} v${_VERSION} script require awk."
echo >&2 "NOTICE: Please install awk first and then re-run this script again."
exit 1 exit 1
} }
# Check if Docker is installed. # make sure rsync is installed (hmmm not always)
#command -v rsync >/dev/null 2>&1 || {
# echo >&2 "ERROR: ${PROGRAM_NAME} v${_VERSION} script require rsync."
# exit 1
#}
# Check and install Docker on Linux
function install_docker_linux() {
echo "Installing Docker on Linux..."
# Add Docker GPG key and repository to sources.list.
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Update package index and install Docker.
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io -y
# Add the current user to the docker group.
sudo groupadd docker
sudo usermod -aG docker "$USER"
# Enable and start the Docker service.
sudo systemctl enable docker.service
sudo systemctl start docker.service
echo "Docker is installed."
}
# Check and install Docker on macOS
function install_docker_macos() {
echo "Installing Docker on macOS..."
brew install --cask docker
open /Applications/Docker.app
echo "Docker is installed. Please follow the prompts to complete the installation."
}
# Check and install Docker on Windows (MSYS/Cygwin)
function install_docker_windows() {
echo "Please download and install Docker Desktop from https://www.docker.com/products/docker-desktop"
echo "Docker Desktop is required for Windows environments."
exit 0
}
# Check if Docker is installed
if ! command -v docker &>/dev/null; then if ! command -v docker &>/dev/null; then
# If Docker is not installed, ask the user if they want to install it. # If Docker is not installed, ask the user if they want to install it
if whiptail --yesno "Docker is not installed. Do you want to install it now?" \ if whiptail --yesno "Docker is not installed. Do you want to install it now?" \
--backtitle "${BACK_TITLE}" 10 60; then --backtitle "${BACK_TITLE}" 10 60; then
# If the user chooses Yes, install Docker. # If the user chooses Yes, install Docker based on the OS
echo "Installing Docker..." case "$OS_NUMBER" in
1)
# Add Docker GPG key and repository to sources.list. install_docker_linux
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg ;;
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null 2)
install_docker_macos
# Update package index and install Docker. ;;
sudo apt-get update 3)
sudo apt-get install docker-ce docker-ce-cli containerd.io -y install_docker_windows
;;
# Add the current user to the docker group. *)
sudo groupadd docker echo >&2 "ERROR: Unsupported operating system."
sudo usermod -aG docker "$USER" exit 1
;;
# Enable and start the Docker service. esac
sudo systemctl enable docker.service
sudo systemctl start docker.service
echo "Docker is installed."
else else
# If the user chooses No, exit the script with an error message. # If the user chooses No, exit the script with an error message
echo >&2 "ERROR: ${PROGRAM_NAME} v${_VERSION} script require docker." echo >&2 "ERROR: ${PROGRAM_NAME} v${_VERSION} script requires Docker."
echo >&2 "NOTICE: Please install Docker first and then re-run this script again."
exit 1 exit 1
fi fi
fi fi
# Check if Docker Compose is installed. # Install Docker Compose on Linux
function install_docker_compose_linux() {
echo "Installing Docker Compose on Linux..."
# Download the latest Docker Compose binary.
COMPOSE_VERSION=$(curl --silent https://api.github.com/repos/docker/compose/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
sudo curl -SL "https://github.com/docker/compose/releases/download/$COMPOSE_VERSION/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# Make the Docker Compose binary executable.
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
echo "Docker Compose is installed."
}
# Install Docker Compose on macOS
function install_docker_compose_macos() {
echo "Installing Docker Compose on macOS..."
# Download the latest Docker Compose binary.
COMPOSE_VERSION=$(curl --silent https://api.github.com/repos/docker/compose/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
sudo curl -SL "https://github.com/docker/compose/releases/download/$COMPOSE_VERSION/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# Make the Docker Compose binary executable.
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/local/bin/docker-compose
echo "Docker Compose is installed."
}
# Install Docker Compose on Windows (MSYS/Cygwin)
function install_docker_compose_windows() {
echo "Please download Docker Compose from https://github.com/docker/compose/releases"
echo "and place it in a directory included in your PATH."
exit 0
}
# Check if Docker Compose is installed
if ! command -v docker-compose &>/dev/null; then if ! command -v docker-compose &>/dev/null; then
# If Docker Compose is not installed, ask the user if they want to install it. # If Docker Compose is not installed, ask the user if they want to install it
if whiptail --yesno "Docker Compose is not installed. Do you want to install it now?" \ if whiptail --yesno "Docker Compose is not installed. Do you want to install it now?" \
--backtitle "${BACK_TITLE}" 10 60; then --backtitle "${BACK_TITLE}" 10 60; then
# If the user chooses Yes, install Docker Compose. # If the user chooses Yes, install Docker Compose based on the OS
echo "Installing Docker Compose..." case "$OS_NUMBER" in
1)
# Download the latest Docker Compose binary. install_docker_compose_linux
COMPOSE_VERSION=$(curl --silent https://api.github.com/repos/docker/compose/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') ;;
sudo curl -SL "https://github.com/docker/compose/releases/download/$COMPOSE_VERSION/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose 2)
install_docker_compose_macos
# Make the Docker Compose binary executable. ;;
sudo chmod +x /usr/local/bin/docker-compose 3)
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose install_docker_compose_windows
;;
echo "Docker Compose is installed." *)
echo >&2 "ERROR: Unsupported operating system."
exit 1
;;
esac
else else
# If the user chooses No, exit the script with an error message. # If the user chooses No, exit the script with an error message
echo >&2 "ERROR: ${PROGRAM_NAME} v${_VERSION} script require docker-compose." echo >&2 "ERROR: ${PROGRAM_NAME} v${_VERSION} script requires docker-compose."
echo >&2 "NOTICE: Please install docker-compose first and then re-run this script again."
exit 1 exit 1
fi fi
fi fi
# Setting the LC_ALL with respect to language, regional settings, to use POSIX locale,
# so ASCII character set and standardizes behavior is used for consistent across different environments
export LC_ALL=C
# just clear the screen # just clear the screen
clear clear
@ -170,15 +314,13 @@ function traefik__TRuST__setup() {
function traefikContainer() { function traefikContainer() {
# we build the yml file # we build the yml file
cat <<EOF cat <<EOF
version: "3.3"
services: services:
traefik: traefik:
container_name: traefik container_name: traefik
image: "traefik:latest" image: "traefik:latest"
command: command:
${VDM_REMOVE_SECURE} - --entrypoints.web.address=:80 - --entrypoints.web.address=:80
${VDM_REMOVE_SECURE} - --entrypoints.websecure.address=:443 - --entrypoints.websecure.address=:443
# - --api.dashboard=true # - --api.dashboard=true
# - --api.insecure=true # - --api.insecure=true
- --providers.docker - --providers.docker
@ -211,6 +353,7 @@ ${VDM_REMOVE_SECURE} - "traefik.http.middlewares.redirect-to-me.redirectsch
networks: networks:
traefik: traefik:
external: true
name: ${VDM_TRAEFIK_GATEWAY:-traefik_webgateway} name: ${VDM_TRAEFIK_GATEWAY:-traefik_webgateway}
EOF EOF
} }
@ -284,8 +427,6 @@ function portainer__TRuST__setup() {
function portainerContainer() { function portainerContainer() {
# we build the yml file # we build the yml file
cat <<EOF cat <<EOF
version: "3.3"
services: services:
portainer: portainer:
image: portainer/portainer-ce:latest image: portainer/portainer-ce:latest
@ -487,7 +628,7 @@ function joomla__TRuST__setup() {
fi fi
VDM_EXTRA_CONTAINER_STUFF+=$(getYMLine3 "- \"traefik.http.routers.mailcatcher${VDM_KEY}.service=mailcatcher${VDM_KEY}\"") VDM_EXTRA_CONTAINER_STUFF+=$(getYMLine3 "- \"traefik.http.routers.mailcatcher${VDM_KEY}.service=mailcatcher${VDM_KEY}\"")
VDM_EXTRA_CONTAINER_STUFF+=$(getYMLine3 "- \"traefik.http.services.mailcatcher${VDM_KEY}.loadbalancer.server.port=1080\"") VDM_EXTRA_CONTAINER_STUFF+=$(getYMLine3 "- \"traefik.http.services.mailcatcher${VDM_KEY}.loadbalancer.server.port=1080\"")
VDM_EXTRA_JOOMLA_ENV+=$(getYMLine3 "- JOOMLA_SMTP_HOST=mailcatcher${VDM_KEY}:1080") VDM_EXTRA_JOOMLA_ENV+=$(getYMLine3 "- JOOMLA_SMTP_HOST=mailcatcher${VDM_KEY}:1025")
fi fi
# if this is our octoleo images we can also set the user ID and user-group ID # if this is our octoleo images we can also set the user ID and user-group ID
setContainerUser "$(id -u)" setContainerUser "$(id -u)"
@ -640,7 +781,6 @@ function joomlaContainer() {
fi fi
# we build the yml file # we build the yml file
cat <<EOF cat <<EOF
version: '2'
services: services:
mariadb${VDM_KEY}: mariadb${VDM_KEY}:
image: mariadb:latest image: mariadb:latest
@ -932,7 +1072,7 @@ function joomla__TRuST__bulk() {
fi fi
VDM_EXTRA_CONTAINER_STUFF+=$(getYMLine3 "- \"traefik.http.routers.mailcatcher${VDM_KEY}.service=mailcatcher${VDM_KEY}\"") VDM_EXTRA_CONTAINER_STUFF+=$(getYMLine3 "- \"traefik.http.routers.mailcatcher${VDM_KEY}.service=mailcatcher${VDM_KEY}\"")
VDM_EXTRA_CONTAINER_STUFF+=$(getYMLine3 "- \"traefik.http.services.mailcatcher${VDM_KEY}.loadbalancer.server.port=1080\"") VDM_EXTRA_CONTAINER_STUFF+=$(getYMLine3 "- \"traefik.http.services.mailcatcher${VDM_KEY}.loadbalancer.server.port=1080\"")
VDM_EXTRA_JOOMLA_ENV+=$(getYMLine3 "- JOOMLA_SMTP_HOST=mailcatcher${VDM_KEY}:1080") VDM_EXTRA_JOOMLA_ENV+=$(getYMLine3 "- JOOMLA_SMTP_HOST=mailcatcher${VDM_KEY}:1025")
fi fi
# setup letsencrypt stuff # setup letsencrypt stuff
VDM_JOOMLA_SECURE_LABELS='' VDM_JOOMLA_SECURE_LABELS=''
@ -1225,7 +1365,6 @@ function openssh__TRuST__setup() {
function opensshContainer() { function opensshContainer() {
# we build the yml file # we build the yml file
cat <<EOF cat <<EOF
version: "2.1"
services: services:
openssh-server-${VDM_KEY}: openssh-server-${VDM_KEY}:
image: lscr.io/linuxserver/openssh-server image: lscr.io/linuxserver/openssh-server
@ -1247,6 +1386,7 @@ services:
networks: networks:
openssh: openssh:
external: true
name: ${VDM_OPENSSH_GATEWAY:-openssh_gateway} name: ${VDM_OPENSSH_GATEWAY:-openssh_gateway}
EOF EOF
} }
@ -1769,6 +1909,42 @@ function openssh__TRuST__down() {
fi fi
} }
#####################################################################################################################VDM
######################################## CLONE JOOMLA
function joomla__TRuST__clone() {
# check if this type have available containers
if ! hasDirectories "${VDM_CONTAINER_TYPE}/available/"; then
showError "The path ${VDM_REPO_PATH}/${VDM_CONTAINER_TYPE}/available/ does not exist or is empty, first run a ${VDM_CONTAINER_TYPE^} setup."
else
# ask if they want to clone a volume
if (whiptail --yesno "Would you like to clone a persistent volume found in (${VDM_PROJECT_PATH})?" \
--title "Continue To Clone Persistent Volume" --backtitle "${BACK_TITLE}" 12 112); then
# trigger the volumes clone script
clonePersistentVolume
fi
# ask if they want to clone a container
if (whiptail --yesno "Would you like to clone a ${VDM_CONTAINER_TYPE^} container?" \
--title "Continue To Clone Container (feature not ready)" --defaultno --backtitle "${BACK_TITLE}" 12 112); then
# set some local variables
local vdm_clone_me
local container
# list containers... and allow selection to edit
container=$(getSelectedDirectory "Select a container you would like to clone." \
"${VDM_REPO_PATH}/${VDM_CONTAINER_TYPE}/available/" '' "Clone ${VDM_CONTAINER_TYPE^} Container (feature not ready)")
# check that we have something, else return to main menu
if [ ${#container} -ge 1 ]; then
# add the parent dir back
vdm_clone_me="${VDM_REPO_PATH}/${VDM_CONTAINER_TYPE}/available/${container}/docker-compose.yml"
# check if this docker-composer.yml exist
if [ -f "${vdm_clone_me}" ]; then
# give little heads-up
showNotice "Feature not ready!!\nYou have selected: ${vdm_clone_me}" 13
fi
fi
fi
fi
}
#####################################################################################################################VDM #####################################################################################################################VDM
######################################## DELETE JOOMLA ######################################## DELETE JOOMLA
function joomla__TRuST__delete() { function joomla__TRuST__delete() {
@ -2092,6 +2268,15 @@ function upContainers() {
main main
} }
# clone a container
function cloneContainer() {
# make sure of our container type
VDM_CONTAINER_TYPE="${1}"
VDM_TASK="clone"
# execute the task
main
}
# delete a container # delete a container
function deleteContainer() { function deleteContainer() {
# make sure of our container type # make sure of our container type
@ -2307,6 +2492,44 @@ function deletePersistentVolumes() {
fi fi
} }
# clone persistent volume
function clonePersistentVolume() {
# we first check if we have some volumes
if hasDirectories '' "${VDM_PROJECT_PATH}"; then
# set some local variables
local vdm_clone_volume
local persistent
local new_persistent
# get containers to enable
vdm_clone_volume=$(getSelectedDirectory "Select persistent volume\s to delete." \
"${VDM_PROJECT_PATH}" "Select Persistent Volume to Clone")
# check that we have something, else return to main menu
if [ ${#vdm_clone_volume} -ge 1 ]; then
# remove the " from the string
persistent="${vdm_clone_volume//\"/}"
# last serious check and then its gone
if [ -d "${VDM_PROJECT_PATH}/${persistent}" ]; then
# set the new persistent volume name
new_persistent="${persistent}"
while [ -d "${VDM_PROJECT_PATH}/${new_persistent}" ]; do
# get the value
new_persistent=$(getInput "Enter a new persistent volume name\n[do not use (${persistent}) or any other existing volume names]" '' 'Enter Persistent Name')
# keep asking
if [ -d "${VDM_PROJECT_PATH}/${new_persistent}" ]; then
showError "You must enter a persistent volume name that does not already exist.\n\n${new_persistent} already exist."
fi
done
# create this new folder
mkdir -p "${VDM_PROJECT_PATH}/${new_persistent}"
# clone or (copy) the files to a new directory.
sudo cp -af "${VDM_PROJECT_PATH}/${persistent}/"* "${VDM_PROJECT_PATH}/${new_persistent}"
fi
fi
else
showError "There are no persistent volumes found in ${VDM_PROJECT_PATH}."
fi
}
# reset persistent Joomla volume # reset persistent Joomla volume
function resetPersistentJoomlaVolumes() { function resetPersistentJoomlaVolumes() {
# we first check if we have some volumes # we first check if we have some volumes
@ -2621,6 +2844,9 @@ function showJoomla() {
hasDirectories '' "${VDM_PROJECT_PATH}" && hasDirectories '' "${VDM_PROJECT_PATH}" &&
menu_options+=("fix" "Fix permissions of folders and files of a container") && menu_options+=("fix" "Fix permissions of folders and files of a container") &&
i=$((i + 1)) i=$((i + 1))
# clone a container & volume
hasDirectories 'joomla/available' &&
menu_options+=("clone" "Clone a container") && i=$((i + 1))
# delete a container # delete a container
hasDirectories 'joomla/available' && hasDirectories 'joomla/available' &&
menu_options+=("delete" "Delete a container") && i=$((i + 1)) menu_options+=("delete" "Delete a container") && i=$((i + 1))
@ -2665,6 +2891,9 @@ function showJoomla() {
"fix") "fix")
fixContainersPermissions fixContainersPermissions
;; ;;
"clone")
cloneContainer 'joomla'
;;
"delete") "delete")
deleteContainer 'joomla' deleteContainer 'joomla'
;; ;;
@ -2682,7 +2911,7 @@ function showJoomla() {
# menu loop # menu loop
case $CHOICE in case $CHOICE in
"setup" | "edit" | "enable" | "disable" | "down" | "up" | "fix" | "delete" | "reset" | "joomla_env" | "bulk") "setup" | "edit" | "enable" | "disable" | "down" | "up" | "fix" | "clone" | "delete" | "reset" | "joomla_env" | "bulk")
showJoomla showJoomla
;; ;;
esac esac
@ -3925,7 +4154,7 @@ function setJoomlaPassword() {
'joomla-17082005' 'Enter Joomla User Password') 'joomla-17082005' 'Enter Joomla User Password')
# keep asking if empty # keep asking if empty
if [ ${#VDM_J_PASSWORD} -le 12 ]; then if [ ${#VDM_J_PASSWORD} -le 12 ]; then
showError "You must enter a password with more than 4 characters!" showError "You must enter a password with more than 11 characters!"
fi fi
done done
# make sure it is available # make sure it is available
@ -4502,8 +4731,8 @@ function isFunc() {
declare -F "$1" >/dev/null declare -F "$1" >/dev/null
} }
# update the host file # Update the host file for Linux and macOS
function updateHostFile() { function updateHostFile_unix() {
# check if we should add to host file # check if we should add to host file
if allowEditHostFile; then if allowEditHostFile; then
# check if already in host file # check if already in host file
@ -4519,8 +4748,8 @@ function updateHostFile() {
fi fi
} }
# the manually edit the host file # Manually edit the host file for Linux and macOS
function editHostFile() { function editHostFile_unix() {
# check if we should add to host file # check if we should add to host file
if allowEditHostFile; then if allowEditHostFile; then
# if this container is enabled ask if it should be redeployed # if this container is enabled ask if it should be redeployed
@ -4534,6 +4763,68 @@ function editHostFile() {
fi fi
} }
# Update the host file for Windows (MSYS/Cygwin)
function updateHostFile_windows() {
local subdomain=${1:-$VDM_SUBDOMAIN}
local domain=${2:-$VDM_DOMAIN}
local host_file="/c/Windows/System32/drivers/etc/hosts"
if allowEditHostFile; then
if grep -q "${subdomain}.${domain}" "$host_file"; then
showNotice "${USER^}, ${subdomain}.${domain} is already in the hosts file."
elif (whiptail --yesno "${USER^}, to add the ${subdomain}.${domain} entry to your host file we need administrative privileges." \
--title "Give administrative Privileges" --backtitle "${BACK_TITLE}" 8 112); then
echo "127.0.0.1 ${subdomain}.${domain}" | sudo tee -a "$host_file" >/dev/null
showNotice "${USER^}, ${subdomain}.${domain} was added to the hosts file."
fi
fi
}
# Manually edit the host file for Windows (MSYS/Cygwin)
function editHostFile_windows() {
local host_file="/c/Windows/System32/drivers/etc/hosts"
if allowEditHostFile; then
if (whiptail --yesno "To edit the host file we need administrative privileges.\n[Only continue if you know what you're doing!]" \
--title "Give administrative Privileges" --backtitle "${BACK_TITLE}" 15 112); then
showNotice "${USER^}, to save the changes you've made or to just close the file again press:\n\n[ctrl+x] with nano." 13
sudo "${EDITOR:-nano}" "$host_file"
fi
fi
}
# Update the host file (dynamically calls the correct OS function)
function updateHostFile() {
case "$OS_NUMBER" in
1|2)
updateHostFile_unix "$@"
;;
3)
updateHostFile_windows "$@"
;;
*)
echo >&2 "ERROR: Unsupported operating system."
exit 1
;;
esac
}
# Manually edit the host file (dynamically calls the correct OS function)
function editHostFile() {
case "$OS_NUMBER" in
1|2)
editHostFile_unix
;;
3)
editHostFile_windows
;;
*)
echo >&2 "ERROR: Unsupported operating system."
exit 1
;;
esac
}
# the manually edit the config file # the manually edit the config file
function editConfigFile() { function editConfigFile() {
# check if the file exist # check if the file exist
@ -4570,9 +4861,9 @@ function openEnv() {
# Check if any hosts are set in the SSH config file # Check if any hosts are set in the SSH config file
function hasRemoteSystemSet() { function hasRemoteSystemSet() {
local ssh_config="/home/${USER}/.ssh/config" local ssh_config="${VDM_HOME_PATH}/.ssh/config"
if [ ! -d "/home/${USER}/.ssh" ] || [ ! -f "${ssh_config}" ] || if [ ! -d "${VDM_HOME_PATH}/.ssh" ] || [ ! -f "${ssh_config}" ] ||
[[ $(grep -i -c '^host' "${ssh_config}") -eq 0 ]]; then [[ $(grep -i -c '^host' "${ssh_config}") -eq 0 ]]; then
showError "To use this feature you must first set up the needed remote host details in (~/.ssh/config) to allow easy and secure SSH access." showError "To use this feature you must first set up the needed remote host details in (~/.ssh/config) to allow easy and secure SSH access."
return 1 return 1
@ -4586,7 +4877,7 @@ function getRemoteSystem() {
# The selected folder # The selected folder
local answer local answer
if [ -f "/home/${USER}/.ssh/config" ]; then if [ -f "${VDM_HOME_PATH}/.ssh/config" ]; then
# We start the selection array # We start the selection array
local selected=() local selected=()
# Our counter # Our counter
@ -4599,7 +4890,7 @@ function getRemoteSystem() {
if [ "$i" -le 10 ]; then if [ "$i" -le 10 ]; then
i=$((i + 1)) i=$((i + 1))
fi fi
done < <(grep -i '^host' "/home/${USER}/.ssh/config" | awk '{print $2}' | sort) done < <(grep -i '^host' "${VDM_HOME_PATH}/.ssh/config" | awk '{print $2}' | sort)
# Add manual input option # Add manual input option
selected+=("Enter manually" "Enter manually" "OFF") selected+=("Enter manually" "Enter manually" "OFF")
@ -4645,7 +4936,7 @@ function remoteEnvFileExists() {
# Check if the file exists on the remote system # Check if the file exists on the remote system
# shellcheck disable=SC2029 # shellcheck disable=SC2029
ssh "${remote_system}" "[ -f \"/home/${USER}/.config/octojoom/.env\" ]" ssh "${remote_system}" "[ -f \"${VDM_HOME_PATH}/.config/octojoom/.env\" ]"
} }
# Get a specific value from the remote .env file # Get a specific value from the remote .env file
@ -4656,7 +4947,7 @@ function getRemoteEnvValue() {
if remoteEnvFileExists "${remote_system}"; then if remoteEnvFileExists "${remote_system}"; then
# shellcheck disable=SC2029 # shellcheck disable=SC2029
remote_env_value=$(ssh "${remote_system}" "grep '^${env_key}=' \"/home/${USER}/.config/octojoom/.env\"" | cut -d '=' -f 2-) remote_env_value=$(ssh "${remote_system}" "grep '^${env_key}=' \"${VDM_HOME_PATH}/.config/octojoom/.env\"" | cut -d '=' -f 2-)
fi fi
# Remove any double quotes from the returned value # Remove any double quotes from the returned value
@ -4929,8 +5220,8 @@ function moveTarToRemote() {
local remote_path="$2" local remote_path="$2"
local remote="$3" local remote="$3"
if [ -f "/home/${USER}/.ssh/config" ]; then if [ -f "${VDM_HOME_PATH}/.ssh/config" ]; then
scp -F "/home/${USER}/.ssh/config" "${local_path}" "${remote}:${remote_path}" scp -F "${VDM_HOME_PATH}/.ssh/config" "${local_path}" "${remote}:${remote_path}"
else else
scp "${local_path}" "${remote}:${remote_path}" scp "${local_path}" "${remote}:${remote_path}"
fi fi
@ -5430,9 +5721,26 @@ fi
#####################################################################################################################VDM #####################################################################################################################VDM
######################################## SETUP KEY PATHS ######################################## SETUP KEY PATHS
# the src folder path is where we store the script global env # we set a home path based on OS
VDM_SRC_PATH="/home/${USER}/.config/octojoom" VDM_HOME_PATH=''
# create the folder if not set case "$OS_NUMBER" in
1) # Linux
VDM_HOME_PATH="/home/${USER}"
;;
2) # macOS
VDM_HOME_PATH="/Users/${USER}"
;;
3) # Windows (MSYS/Cygwin)
VDM_HOME_PATH="/c/Users/${USER}"
;;
*)
echo >&2 "ERROR: Unsupported operating system."
exit 1
;;
esac
# Set the src folder path based on OS
VDM_SRC_PATH="${VDM_HOME_PATH}/.config/octojoom"
# Create the folder if not set
# shellcheck disable=SC2174 # shellcheck disable=SC2174
mkdir -p -m '700' "${VDM_SRC_PATH}" mkdir -p -m '700' "${VDM_SRC_PATH}"
# first run switch # first run switch
@ -5449,7 +5757,7 @@ while [ ${#VDM_REPO_PATH} -le 1 ] || [ ! -d "${VDM_REPO_PATH}" ]; do
else else
# get the value # get the value
VDM_REPO_PATH=$(getInput "Enter the repository path where we can store the containers' docker-composer.yml deployment files." \ VDM_REPO_PATH=$(getInput "Enter the repository path where we can store the containers' docker-composer.yml deployment files." \
"/home/${USER}/Docker" 'Enter Repository Path') "${VDM_HOME_PATH}/Docker" 'Enter Repository Path')
# keep asking if empty or does exist # keep asking if empty or does exist
if [ ${#VDM_REPO_PATH} -ge 1 ] && [ ! -d "${VDM_REPO_PATH}" ] && (whiptail --yesno "Can we create the ${VDM_REPO_PATH} repository folder" \ if [ ${#VDM_REPO_PATH} -ge 1 ] && [ ! -d "${VDM_REPO_PATH}" ] && (whiptail --yesno "Can we create the ${VDM_REPO_PATH} repository folder" \
--title "Create the Path" --backtitle "${BACK_TITLE}" 8 112); then --title "Create the Path" --backtitle "${BACK_TITLE}" 8 112); then
@ -5472,7 +5780,7 @@ while [ ${#VDM_PROJECT_PATH} -le 1 ] || [ ! -d "${VDM_PROJECT_PATH}" ]; do
else else
# get the value # get the value
VDM_PROJECT_PATH=$(getInput "Enter the projects' path where we can store the containers' persistent volumes." \ VDM_PROJECT_PATH=$(getInput "Enter the projects' path where we can store the containers' persistent volumes." \
"/home/${USER}/Projects" "Enter Projects' Path") "${VDM_HOME_PATH}/Projects" "Enter Projects' Path")
# keep asking if empty or does exist # keep asking if empty or does exist
if [ ${#VDM_PROJECT_PATH} -ge 1 ] && [ ! -d "${VDM_PROJECT_PATH}" ] && (whiptail --yesno "Can we create the ${VDM_PROJECT_PATH} projects folder" \ if [ ${#VDM_PROJECT_PATH} -ge 1 ] && [ ! -d "${VDM_PROJECT_PATH}" ] && (whiptail --yesno "Can we create the ${VDM_PROJECT_PATH} projects folder" \
--title "Create the Path" --backtitle "${BACK_TITLE}" 8 112); then --title "Create the Path" --backtitle "${BACK_TITLE}" 8 112); then