Add configuration files for Ghost, MariaDB, Nextcloud, Postgres, and Redis; implement generate-config script and enhance load-env script for dependency management
This commit is contained in:
13
apps/ghost/config/example.env
Normal file
13
apps/ghost/config/example.env
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
GHOST_NAMESPACE=ghost
|
||||||
|
GHOST_HOST=blog.${DOMAIN}
|
||||||
|
GHOST_TITLE="My Blog"
|
||||||
|
GHOST_EMAIL=
|
||||||
|
GHOST_STORAGE_SIZE=10Gi
|
||||||
|
GHOST_MARIADB_STORAGE_SIZE=8Gi
|
||||||
|
GHOST_DATABASE_HOST=mariadb.mariadb.svc.cluster.local
|
||||||
|
GHOST_DATABASE_USER=ghost
|
||||||
|
GHOST_DATABASE_NAME=ghost
|
||||||
|
|
||||||
|
# Secrets
|
||||||
|
GHOST_PASSWORD=
|
||||||
|
GHOST_DATABASE_PASSWORD=
|
11
apps/mysql/config/example.env
Normal file
11
apps/mysql/config/example.env
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
MARIADB_NAMESPACE=mariadb
|
||||||
|
MARIADB_RELEASE_NAME=mariadb
|
||||||
|
MARIADB_USER=app
|
||||||
|
MARIADB_DATABASE=app_database
|
||||||
|
MARIADB_STORAGE=8Gi
|
||||||
|
MARIADB_TAG=11.4.5
|
||||||
|
MARIADB_PORT=3306
|
||||||
|
|
||||||
|
# Secrets
|
||||||
|
MARIADB_PASSWORD=
|
||||||
|
MARIADB_ROOT_PASSWORD=
|
20
apps/nextcloud/config/example.env
Normal file
20
apps/nextcloud/config/example.env
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Config
|
||||||
|
NEXTCLOUD_ADMIN_USER=admin
|
||||||
|
NEXTCLOUD_TRUSTED_DOMAINS=$DOMAIN
|
||||||
|
NEXTCLOUD_DOMAIN=nextcloud.$DOMAIN
|
||||||
|
NEXTCLOUD_STORAGE=5Gi
|
||||||
|
NEXTCLOUD_NFS_STORAGE=100Gi
|
||||||
|
PHP_MEMORY_LIMIT=4G
|
||||||
|
PHP_UPLOAD_LIMIT=1G
|
||||||
|
|
||||||
|
NEXTCLOUD_IMAGE=nextcloud:26
|
||||||
|
NEXTCLOUD_DB_TYPE=postgres
|
||||||
|
NEXTCLOUD_DB_HOST=postgres.postgres.svc.cluster.local
|
||||||
|
NEXTCLOUD_DB_USER=nextcloud
|
||||||
|
NEXTCLOUD_DB_NAME=nextcloud
|
||||||
|
POSTGRES_ADMIN_USER=$POSTGRES_USER
|
||||||
|
|
||||||
|
# Secrets
|
||||||
|
NEXTCLOUD_ADMIN_PASSWORD=
|
||||||
|
NEXTCLOUD_DB_PASSWORD=
|
||||||
|
POSTGRES_ADMIN_PASSWORD=$POSTGRES_PASSWORD
|
4
apps/postgres/config/example.env
Normal file
4
apps/postgres/config/example.env
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
POSTGRES_DB=postgres
|
||||||
|
POSTGRES_USER=postgres
|
||||||
|
POSTGRES_PASSWORD=OhPostgres!
|
||||||
|
POSTGRES_STORAGE=10Gi
|
0
apps/redis/config/example.env
Normal file
0
apps/redis/config/example.env
Normal file
74
bin/generate-config
Executable file
74
bin/generate-config
Executable file
@@ -0,0 +1,74 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# This script generates config.env and secrets.env files for an app
|
||||||
|
# by evaluating variables in the app's .env file and splitting them
|
||||||
|
# into regular config and secret variables based on the "# Secrets" marker
|
||||||
|
#
|
||||||
|
# Usage: bin/generate-config <app-name>
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Verify that an app name was provided
|
||||||
|
if [ $# -lt 1 ]; then
|
||||||
|
echo "Error: Missing app name"
|
||||||
|
echo "Usage: $(basename "$0") <app-name>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Source environment variables from load-env.sh
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REPO_DIR="$(dirname "$SCRIPT_DIR")"
|
||||||
|
if [ -f "$REPO_DIR/load-env.sh" ]; then
|
||||||
|
source "$REPO_DIR/load-env.sh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
APP_NAME="$1"
|
||||||
|
APP_DIR="$APPS_DIR/$APP_NAME"
|
||||||
|
ENV_FILE="$APP_DIR/config/.env"
|
||||||
|
CONFIG_FILE="$APP_DIR/config/config.env"
|
||||||
|
SECRETS_FILE="$APP_DIR/config/secrets.env"
|
||||||
|
|
||||||
|
# Check if the app exists
|
||||||
|
if [ ! -d "$APP_DIR" ]; then
|
||||||
|
echo "Error: App '$APP_NAME' not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if the .env file exists
|
||||||
|
if [ ! -f "$ENV_FILE" ]; then
|
||||||
|
echo "Error: Environment file not found: $ENV_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Process the .env file
|
||||||
|
echo "Generating config files for $APP_NAME..."
|
||||||
|
|
||||||
|
# Create temporary files for processed content
|
||||||
|
TMP_FILE="$APP_DIR/config/processed.env" # $(mktemp)
|
||||||
|
|
||||||
|
# Process the file with envsubst to expand variables
|
||||||
|
envsubst < "$ENV_FILE" > $TMP_FILE
|
||||||
|
|
||||||
|
# Initialize header for output files
|
||||||
|
echo "# Generated by \`generate-config\` on $(date)" > "$CONFIG_FILE"
|
||||||
|
echo "# Generated by \`generate-config\` on $(date)" > "$SECRETS_FILE"
|
||||||
|
|
||||||
|
# Find the line number of the "# Secrets" marker
|
||||||
|
SECRETS_LINE=$(grep -n "^# Secrets" $TMP_FILE | cut -d':' -f1)
|
||||||
|
|
||||||
|
if [ -n "$SECRETS_LINE" ]; then
|
||||||
|
# Extract non-comment lines with "=" before the "# Secrets" marker
|
||||||
|
head -n $((SECRETS_LINE - 1)) $TMP_FILE | grep -v "^#" | grep "=" >> "$CONFIG_FILE"
|
||||||
|
|
||||||
|
# Extract non-comment lines with "=" after the "# Secrets" marker
|
||||||
|
tail -n +$((SECRETS_LINE + 1)) $TMP_FILE | grep -v "^#" | grep "=" >> "$SECRETS_FILE"
|
||||||
|
else
|
||||||
|
# No secrets marker found, put everything in config
|
||||||
|
grep -v "^#" $TMP_FILE | grep "=" >> "$CONFIG_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
rm -f "$TMP_FILE"
|
||||||
|
|
||||||
|
echo "Generated:"
|
||||||
|
echo " - $CONFIG_FILE"
|
||||||
|
echo " - $SECRETS_FILE"
|
@@ -8,8 +8,30 @@ cd "$SCRIPT_DIR"
|
|||||||
# Install gomplate
|
# Install gomplate
|
||||||
if command -v gomplate &> /dev/null; then
|
if command -v gomplate &> /dev/null; then
|
||||||
echo "gomplate is already installed."
|
echo "gomplate is already installed."
|
||||||
exit 0
|
else
|
||||||
|
curl -sSL https://github.com/hairyhenderson/gomplate/releases/latest/download/gomplate_linux-amd64 -o $HOME/.local/bin/gomplate
|
||||||
|
chmod +x $HOME/.local/bin/gomplate
|
||||||
|
echo "gomplate installed successfully."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install kustomize
|
||||||
|
if command -v kustomize &> /dev/null; then
|
||||||
|
echo "kustomize is already installed."
|
||||||
|
else
|
||||||
|
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
|
||||||
|
mv kustomize $HOME/.local/bin/
|
||||||
|
echo "kustomize installed successfully."
|
||||||
|
fi
|
||||||
|
|
||||||
|
## Install yq
|
||||||
|
if command -v yq &> /dev/null; then
|
||||||
|
echo "yq is already installed."
|
||||||
|
else
|
||||||
|
VERSION=v4.45.4
|
||||||
|
BINARY=yq_linux_amd64
|
||||||
|
wget https://github.com/mikefarah/yq/releases/download/${VERSION}/${BINARY}.tar.gz -O - | tar xz
|
||||||
|
mv ${BINARY} $HOME/.local/bin/yq
|
||||||
|
chmod +x $HOME/.local/bin/yq
|
||||||
|
rm yq.1
|
||||||
|
echo "yq installed successfully."
|
||||||
fi
|
fi
|
||||||
curl -sSL https://github.com/hairyhenderson/gomplate/releases/latest/download/gomplate_linux-amd64 -o $HOME/.local/bin/gomplate
|
|
||||||
chmod +x $HOME/.local/bin/gomplate
|
|
||||||
echo "gomplate installed successfully."
|
|
||||||
|
162
load-env.sh
162
load-env.sh
@@ -1,16 +1,178 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
# This script sources environment variables from:
|
||||||
|
# 1. The root .env file
|
||||||
|
# 2. App-specific .env files from enabled apps (with install=true in manifest.yaml)
|
||||||
|
# Dependencies are respected - if app A requires app B, app B's .env is sourced first
|
||||||
|
# set -e
|
||||||
|
|
||||||
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
ENV_FILE="$PROJECT_DIR/.env"
|
ENV_FILE="$PROJECT_DIR/.env"
|
||||||
BIN_DIR="$PROJECT_DIR/bin"
|
BIN_DIR="$PROJECT_DIR/bin"
|
||||||
|
APPS_DIR="$PROJECT_DIR/apps"
|
||||||
|
|
||||||
|
# Check if yq is installed
|
||||||
|
if ! command -v yq &> /dev/null; then
|
||||||
|
echo "Error: yq is not installed. Please install it first."
|
||||||
|
echo "You can install it with: wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/local/bin/yq && chmod +x /usr/local/bin/yq"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Source the main .env file
|
||||||
if [ ! -f "$ENV_FILE" ]; then
|
if [ ! -f "$ENV_FILE" ]; then
|
||||||
echo "Error: Environment file not found: $ENV_FILE"
|
echo "Error: Environment file not found: $ENV_FILE"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Turn on allexport to automatically export all variables
|
||||||
set -a
|
set -a
|
||||||
source "$ENV_FILE"
|
source "$ENV_FILE"
|
||||||
set +a
|
set +a
|
||||||
|
|
||||||
|
# Function to parse YAML using yq
|
||||||
|
parse_yaml() {
|
||||||
|
local yaml_file=$1
|
||||||
|
|
||||||
|
# Extract the values we need using yq
|
||||||
|
local name=$(yq eval '.name' "$yaml_file")
|
||||||
|
local install=$(yq eval '.install' "$yaml_file")
|
||||||
|
|
||||||
|
# Convert boolean to 1/0 for consistency
|
||||||
|
if [ "$install" = "true" ]; then
|
||||||
|
install="1"
|
||||||
|
elif [ "$install" = "false" ]; then
|
||||||
|
install="0"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get dependencies as space-separated string
|
||||||
|
local requires=""
|
||||||
|
if yq eval 'has("requires")' "$yaml_file" | grep -q "true"; then
|
||||||
|
requires=$(yq eval '.requires[].name' "$yaml_file" | tr '\n' ' ' | sed 's/ $//')
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Return the parsed data as a single line
|
||||||
|
echo "$name|$install|$requires"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Resolve dependencies and create a list of apps to source in the right order
|
||||||
|
resolve_dependencies() {
|
||||||
|
local apps=()
|
||||||
|
local apps_to_install=()
|
||||||
|
local deps_map=()
|
||||||
|
|
||||||
|
# Parse all manifest files
|
||||||
|
for manifest in "$APPS_DIR"/*/manifest.yaml; do
|
||||||
|
local app_dir=$(dirname "$manifest")
|
||||||
|
local app_name=$(basename "$app_dir")
|
||||||
|
|
||||||
|
local parsed_data=$(parse_yaml "$manifest")
|
||||||
|
IFS='|' read -r name install requires <<< "$parsed_data"
|
||||||
|
|
||||||
|
# Add to our arrays
|
||||||
|
apps+=("$name")
|
||||||
|
if [ "$install" = "1" ] || [ "$install" = "true" ]; then
|
||||||
|
apps_to_install+=("$name")
|
||||||
|
deps_map+=("$name:$requires")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Create an ordered list with dependencies first
|
||||||
|
local ordered=()
|
||||||
|
|
||||||
|
# First add apps with no dependencies
|
||||||
|
for app in "${apps_to_install[@]}"; do
|
||||||
|
local has_deps=false
|
||||||
|
for dep_entry in "${deps_map[@]}"; do
|
||||||
|
local app_name=$(echo "$dep_entry" | cut -d':' -f1)
|
||||||
|
local deps=$(echo "$dep_entry" | cut -d':' -f2)
|
||||||
|
|
||||||
|
if [ "$app_name" = "$app" ] && [ -n "$deps" ]; then
|
||||||
|
has_deps=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$has_deps" = false ]; then
|
||||||
|
ordered+=("$app")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Now add apps with resolved dependencies
|
||||||
|
local remaining=()
|
||||||
|
for app in "${apps_to_install[@]}"; do
|
||||||
|
if ! echo " ${ordered[*]} " | grep -q " $app "; then
|
||||||
|
remaining+=("$app")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
while [ ${#remaining[@]} -gt 0 ]; do
|
||||||
|
local progress=false
|
||||||
|
|
||||||
|
for app in "${remaining[@]}"; do
|
||||||
|
local all_deps_resolved=true
|
||||||
|
|
||||||
|
# Find the dependencies for this app
|
||||||
|
local app_deps=""
|
||||||
|
for dep_entry in "${deps_map[@]}"; do
|
||||||
|
local app_name=$(echo "$dep_entry" | cut -d':' -f1)
|
||||||
|
local deps=$(echo "$dep_entry" | cut -d':' -f2)
|
||||||
|
|
||||||
|
if [ "$app_name" = "$app" ]; then
|
||||||
|
app_deps="$deps"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Check if all dependencies are in the ordered list
|
||||||
|
if [ -n "$app_deps" ]; then
|
||||||
|
for dep in $app_deps; do
|
||||||
|
if ! echo " ${ordered[*]} " | grep -q " $dep "; then
|
||||||
|
all_deps_resolved=false
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$all_deps_resolved" = true ]; then
|
||||||
|
ordered+=("$app")
|
||||||
|
progress=true
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# If no progress was made, we have a circular dependency
|
||||||
|
if [ "$progress" = false ]; then
|
||||||
|
echo "Warning: Circular dependency detected in app manifests"
|
||||||
|
# Add remaining apps to avoid getting stuck
|
||||||
|
ordered+=("${remaining[@]}")
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update remaining list
|
||||||
|
local new_remaining=()
|
||||||
|
for app in "${remaining[@]}"; do
|
||||||
|
if ! echo " ${ordered[*]} " | grep -q " $app "; then
|
||||||
|
new_remaining+=("$app")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
remaining=("${new_remaining[@]}")
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "${ordered[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get ordered list of apps to source
|
||||||
|
ordered_apps=($(resolve_dependencies))
|
||||||
|
|
||||||
|
# Source app .env files in dependency order
|
||||||
|
# echo "Sourcing app environment files..."
|
||||||
|
for app in "${ordered_apps[@]}"; do
|
||||||
|
app_env_file="$APPS_DIR/$app/config/.env"
|
||||||
|
if [ -f "$app_env_file" ]; then
|
||||||
|
# echo " - $app"
|
||||||
|
set -a
|
||||||
|
source "$app_env_file"
|
||||||
|
set +a
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Add bin directory to PATH
|
||||||
export PATH="$BIN_DIR:$PATH"
|
export PATH="$BIN_DIR:$PATH"
|
Reference in New Issue
Block a user