Refactor user input prompts in scripts to use whiptail for better UX

- Replaced standard input prompts with whiptail dialogs in 03_generate_secrets.sh and 05_configure_services.sh for domain, email, OpenAI API key, and n8n worker count.
- Added validation messages using whiptail for empty inputs and invalid formats.
- Introduced new utility functions in utils.sh for whiptail integration, ensuring the script checks for whiptail availability.
This commit is contained in:
Yury Kossakovsky
2025-09-17 14:15:12 -06:00
parent 09491c01bf
commit 4d65382e92
3 changed files with 105 additions and 64 deletions

View File

@@ -98,6 +98,7 @@ if ! command -v caddy &> /dev/null; then
exit 1
fi
require_whiptail
# Prompt for the domain name
DOMAIN="" # Initialize DOMAIN variable
@@ -110,73 +111,52 @@ if [[ -v existing_env_vars[USER_DOMAIN_NAME] && -n "${existing_env_vars[USER_DOM
generated_values["USER_DOMAIN_NAME"]="$DOMAIN"
else
while true; do
echo ""
prompt_text="Enter the primary domain name for your services (e.g., example.com): " # Simplified prompt
read -p "$prompt_text" DOMAIN_INPUT
DOMAIN_INPUT=$(wt_input "Primary Domain" "Enter the primary domain name for your services (e.g., example.com)." "") || true
DOMAIN_TO_USE="$DOMAIN_INPUT" # Direct assignment, no default fallback
# Validate domain input
if [[ -z "$DOMAIN_TO_USE" ]]; then
log_error "Domain name cannot be empty. This field is mandatory." >&2 # Clarified error
continue # Ask again
wt_msg "Validation" "Domain name cannot be empty."
continue
fi
# Basic check for likely invalid domain characters (very permissive)
if [[ "$DOMAIN_TO_USE" =~ [^a-zA-Z0-9.-] ]]; then
log_warning "Warning: Domain name contains potentially invalid characters: '$DOMAIN_TO_USE'" >&2
wt_msg "Validation" "Warning: Domain contains potentially invalid characters: '$DOMAIN_TO_USE'"
fi
echo ""
read -p "Are you sure '$DOMAIN_TO_USE' is correct? (y/N): " confirm_domain
if [[ "$confirm_domain" =~ ^[Yy]$ ]]; then
if wt_yesno "Confirm Domain" "Use '$DOMAIN_TO_USE' as the primary domain?" "no"; then
DOMAIN="$DOMAIN_TO_USE" # Set the final DOMAIN variable
generated_values["USER_DOMAIN_NAME"]="$DOMAIN" # Using USER_DOMAIN_NAME
log_info "Domain set to '$DOMAIN'. It will be saved in .env."
break # Confirmed, exit loop
else
log_info "Please try entering the domain name again."
# No default domain suggestion to retry with.
fi
done
fi
# Prompt for user email
if [[ -z "${existing_env_vars[LETSENCRYPT_EMAIL]}" ]]; then
echo ""
echo "Please enter your email address. This email will be used for:"
echo " - Login to Flowise"
echo " - Login to Supabase"
echo " - Login to SearXNG"
echo " - Login to Grafana"
echo " - Login to Prometheus"
echo " - SSL certificate generation with Let\'s Encrypt"
wt_msg "Email Required" "Please enter your email address. It will be used for logins and Let's Encrypt SSL."
fi
if [[ -n "${existing_env_vars[LETSENCRYPT_EMAIL]}" ]]; then
USER_EMAIL="${existing_env_vars[LETSENCRYPT_EMAIL]}"
else
while true; do
echo ""
read -p "Email: " USER_EMAIL
USER_EMAIL=$(wt_input "Email" "Enter your email address." "") || true
# Validate email input
if [[ -z "$USER_EMAIL" ]]; then
log_error "Email cannot be empty." >&2
continue # Ask again
wt_msg "Validation" "Email cannot be empty."
continue
fi
# Basic email format validation
if [[ ! "$USER_EMAIL" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
log_warning "Warning: Email format appears to be invalid: '$USER_EMAIL'" >&2
wt_msg "Validation" "Warning: Email format appears to be invalid: '$USER_EMAIL'"
fi
echo ""
read -p "Are you sure '$USER_EMAIL' is correct? (y/N): " confirm_email
if [[ "$confirm_email" =~ ^[Yy]$ ]]; then
if wt_yesno "Confirm Email" "Use '$USER_EMAIL' as your email?" "no"; then
break # Confirmed, exit loop
else
log_info "Please try entering the email address again."
fi
done
fi

View File

@@ -44,13 +44,8 @@ log_info "Configuring service options in .env..."
EXISTING_OPENAI_API_KEY="$(read_env_var OPENAI_API_KEY)"
OPENAI_API_KEY=""
if [[ -z "$EXISTING_OPENAI_API_KEY" ]]; then
echo ""
echo "OpenAI API Key (optional). This key will be used for:"
echo " - Supabase: AI services to help with writing SQL queries, statements, and policies"
echo " - Crawl4AI: Default LLM configuration for web crawling capabilities"
echo " You can skip this by leaving it empty."
echo ""
read -p "OpenAI API Key: " OPENAI_API_KEY
require_whiptail
OPENAI_API_KEY=$(wt_input "OpenAI API Key" "Optional: Used by Supabase AI (SQL assistance) and Crawl4AI. Leave empty to skip." "") || true
if [[ -n "$OPENAI_API_KEY" ]]; then
write_env_var "OPENAI_API_KEY" "$OPENAI_API_KEY"
fi
@@ -64,13 +59,8 @@ fi
# Logic for n8n workflow import (RUN_N8N_IMPORT)
# ----------------------------------------------------------------
final_run_n8n_import_decision="false"
echo ""
echo "Do you want to import 300 ready-made workflows for n8n? This process may take about 30 minutes to complete."
echo ""
read -p "Import workflows? (y/n): " import_workflow_choice
if [[ "$import_workflow_choice" =~ ^[Yy]$ ]]; then
require_whiptail
if wt_yesno "Import n8n Workflows" "Import ~300 ready-made n8n workflows now? This can take ~30 minutes." "no"; then
final_run_n8n_import_decision="true"
else
final_run_n8n_import_decision="false"
@@ -86,24 +76,22 @@ write_env_var "RUN_N8N_IMPORT" "$final_run_n8n_import_decision"
echo "" # Add a newline for better formatting
log_info "Configuring n8n worker count..."
EXISTING_N8N_WORKER_COUNT="$(read_env_var N8N_WORKER_COUNT)"
require_whiptail
if [[ -n "$EXISTING_N8N_WORKER_COUNT" ]]; then
N8N_WORKER_COUNT_CURRENT="$EXISTING_N8N_WORKER_COUNT"
echo ""
read -p "Do you want to change the number of n8n workers? Current: $N8N_WORKER_COUNT_CURRENT. (Enter new number, or press Enter to keep current): " N8N_WORKER_COUNT_INPUT_RAW
N8N_WORKER_COUNT_INPUT_RAW=$(wt_input "n8n Workers (instances)" "Enter new number of n8n workers, or leave as current ($N8N_WORKER_COUNT_CURRENT)." "") || true
if [[ -z "$N8N_WORKER_COUNT_INPUT_RAW" ]]; then
N8N_WORKER_COUNT="$N8N_WORKER_COUNT_CURRENT"
else
if [[ "$N8N_WORKER_COUNT_INPUT_RAW" =~ ^0*[1-9][0-9]*$ ]]; then
N8N_WORKER_COUNT_TEMP="$((10#$N8N_WORKER_COUNT_INPUT_RAW))"
if [[ "$N8N_WORKER_COUNT_TEMP" -ge 1 ]]; then
echo ""
read -p "Update n8n workers to $N8N_WORKER_COUNT_TEMP? (y/N): " confirm_change
if [[ "$confirm_change" =~ ^[Yy]$ ]]; then
if wt_yesno "Confirm Workers" "Update n8n workers to $N8N_WORKER_COUNT_TEMP?" "no"; then
N8N_WORKER_COUNT="$N8N_WORKER_COUNT_TEMP"
else
else
N8N_WORKER_COUNT="$N8N_WORKER_COUNT_CURRENT"
log_info "Change declined. Keeping N8N_WORKER_COUNT at $N8N_WORKER_COUNT."
fi
fi
else
log_warning "Invalid input '$N8N_WORKER_COUNT_INPUT_RAW'. Number must be positive. Keeping $N8N_WORKER_COUNT_CURRENT."
N8N_WORKER_COUNT="$N8N_WORKER_COUNT_CURRENT"
@@ -115,20 +103,14 @@ if [[ -n "$EXISTING_N8N_WORKER_COUNT" ]]; then
fi
else
while true; do
echo ""
read -p "Enter the number of n8n workers to run (e.g., 1, 2, 3; default is 1): " N8N_WORKER_COUNT_INPUT_RAW
N8N_WORKER_COUNT_INPUT_RAW=$(wt_input "n8n Workers" "Enter number of n8n workers to run (default 1)." "1") || true
N8N_WORKER_COUNT_CANDIDATE="${N8N_WORKER_COUNT_INPUT_RAW:-1}"
if [[ "$N8N_WORKER_COUNT_CANDIDATE" =~ ^0*[1-9][0-9]*$ ]]; then
N8N_WORKER_COUNT_VALIDATED="$((10#$N8N_WORKER_COUNT_CANDIDATE))"
if [[ "$N8N_WORKER_COUNT_VALIDATED" -ge 1 ]]; then
echo ""
read -p "Run $N8N_WORKER_COUNT_VALIDATED n8n worker(s)? (y/N): " confirm_workers
if [[ "$confirm_workers" =~ ^[Yy]$ ]]; then
if wt_yesno "Confirm Workers" "Run $N8N_WORKER_COUNT_VALIDATED n8n worker(s)?" "no"; then
N8N_WORKER_COUNT="$N8N_WORKER_COUNT_VALIDATED"
break
else
log_info "Please try entering the number of workers again."
fi
else
log_error "Number of workers must be a positive integer." >&2
@@ -165,9 +147,8 @@ if [ $cloudflare_selected -eq 1 ]; then
log_info "Cloudflare Tunnel token found in .env; reusing it."
# Do not prompt; keep existing token as-is
else
log_info "Cloudflare Tunnel selected. Please provide your Cloudflare Tunnel token."
echo ""
read -p "Cloudflare Tunnel Token: " input_cf_token
require_whiptail
input_cf_token=$(wt_input "Cloudflare Tunnel Token" "Enter your Cloudflare Tunnel token (leave empty to skip)." "") || true
token_to_write="$input_cf_token"
# Update the .env with the token (may be empty if user skipped)
@@ -187,6 +168,25 @@ if [ $cloudflare_selected -eq 1 ]; then
fi
# ----------------------------------------------------------------
# Safety: If Supabase is present, remove Dify from COMPOSE_PROFILES (no prompts)
# ----------------------------------------------------------------
if [[ -n "$COMPOSE_PROFILES_VALUE" && "$COMPOSE_PROFILES_VALUE" == *"supabase"* ]]; then
IFS=',' read -r -a profiles_array <<< "$COMPOSE_PROFILES_VALUE"
new_profiles=()
for p in "${profiles_array[@]}"; do
if [[ "$p" != "dify" ]]; then
new_profiles+=("$p")
fi
done
COMPOSE_PROFILES_VALUE_UPDATED=$(IFS=','; echo "${new_profiles[*]}")
if [[ "$COMPOSE_PROFILES_VALUE_UPDATED" != "$COMPOSE_PROFILES_VALUE" ]]; then
write_env_var "COMPOSE_PROFILES" "$COMPOSE_PROFILES_VALUE_UPDATED"
log_info "Supabase present: removed 'dify' from COMPOSE_PROFILES due to conflict with Supabase."
COMPOSE_PROFILES_VALUE="$COMPOSE_PROFILES_VALUE_UPDATED"
fi
fi
# ----------------------------------------------------------------
# Ensure Supabase Analytics targets the correct Postgres service name used by Supabase docker compose
# ----------------------------------------------------------------

View File

@@ -49,3 +49,64 @@ log_info() {
local combined_message="[INFO] ${timestamp}: ${message}"
log_message "${combined_message}"
}
# --- Whiptail helpers ---
# Ensure whiptail is available
require_whiptail() {
if ! command -v whiptail >/dev/null 2>&1; then
log_error "'whiptail' is not installed. Install with: sudo apt-get install -y whiptail"
exit 1
fi
}
# Input box. Usage: wt_input "Title" "Prompt" "default"
# Echoes the input on success; returns 0 on OK, 1 on Cancel
wt_input() {
local title="$1"
local prompt="$2"
local default_value="$3"
local result
result=$(whiptail --title "$title" --inputbox "$prompt" 15 80 "$default_value" 3>&1 1>&2 2>&3)
local status=$?
if [ $status -ne 0 ]; then
return 1
fi
echo "$result"
return 0
}
# Password box. Usage: wt_password "Title" "Prompt"
# Echoes the input on success; returns 0 on OK, 1 on Cancel
wt_password() {
local title="$1"
local prompt="$2"
local result
result=$(whiptail --title "$title" --passwordbox "$prompt" 15 80 3>&1 1>&2 2>&3)
local status=$?
if [ $status -ne 0 ]; then
return 1
fi
echo "$result"
return 0
}
# Yes/No box. Usage: wt_yesno "Title" "Prompt" "default" (default: yes|no)
# Returns 0 for Yes, 1 for No/Cancel
wt_yesno() {
local title="$1"
local prompt="$2"
local default_choice="$3"
if [ "$default_choice" = "yes" ]; then
whiptail --title "$title" --yesno "$prompt" 10 80
else
whiptail --title "$title" --defaultno --yesno "$prompt" 10 80
fi
}
# Message box. Usage: wt_msg "Title" "Message"
wt_msg() {
local title="$1"
local message="$2"
whiptail --title "$title" --msgbox "$message" 10 80
}