install.sh
Rama main · réplica de lectura del repositorio original.
#!/bin/bash
INTERACTIVE=1
ARCH=""
PUBLIC_ACCESS="false"
DATA_DIR="$PWD/data"
PORT="8080"
HOST="127.0.0.1"
VERSION=""
JWT_SECRET=""
ADMIN_PASSWORD=""
ENV_FILE=".env"
ENV_FILE_PATH="/etc/leafwiki/.env"
ENABLE_LINK_REFACTORING="false"
ENABLE_REVISION="false"
MAX_REVISION_HISTORY="100"
RELEASE_LINK="https://github.com/perber/leafwiki/"
PATH_TO_BINARY="/usr/local/bin/leafwiki"
# Usage function
usage() {
echo "Usage: $0 [--non-interactive [options]] | [interactive mode]"
echo ""
echo "Interactive mode (default):"
echo " $0"
echo ""
echo "Non-interactive mode:"
echo " $0 --non-interactive -env-file|--env-file <path to an env file> "
echo ""
echo "Environment file:"
echo " You can specify an env file with --env-file."
echo " See .env.example for available variables."
echo ""
echo " -help, --help Display this help message"
exit 1
}
check_dependencies() {
if ! command -v $1 &> /dev/null; then
echo "Error: ${1} is not installed. Please install ${1} and try again."
exit 1
fi
}
validate_architecture(){
if [[ "$ARCH" != "amd64" && "$ARCH" != "arm64" ]]; then
echo "Error: Unsupported architecture '$ARCH'. Supported values are: amd64, arm64"
usage
exit 1
fi
}
validate_port(){
if ! [[ "$PORT" =~ ^[0-9]+$ ]] || [ "$PORT" -lt 1 ] || [ "$PORT" -gt 65535 ]; then
echo "Error: --port requires a valid port number (1-65535)."
usage
exit 1
fi
}
validate_requirements_non_interactive(){
local var_value="$1"
local var_name="$2"
if [[ -z "$var_value" ]]; then
echo "Error: $var_name environment variable is required in non-interactive mode (set it in the env file used with --env-file)."
usage
exit 1
fi
}
validate_version(){
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Error: Invalid VERSION format '$VERSION'. Expected format: X.Y.Z"
exit 1
fi
}
get_version(){
if [[ -z "$VERSION" ]]; then
LATEST_VERSION=$(curl -s https://api.github.com/repos/perber/leafwiki/releases/latest \
| grep '"tag_name":' \
| sed -E 's/.*"v([^"]+)".*/\1/')
VERSION=$LATEST_VERSION
fi
validate_version
}
# verify_checksum <file> <url>: compare <file> against the hash published at
# <url>.sha256. Only the hash field is compared, so checksum files that name
# the binary with a "releases/" prefix (older releases) work too.
verify_checksum(){
local file="$1" url="$2" expected actual
expected=$(wget -qO- "${url}.sha256" | awk '{print $1}')
if [[ -z "$expected" ]]; then
echo "Error: Could not download checksum from ${url}.sha256" >&2
return 1
fi
actual=$(sha256sum "$file" | awk '{print $1}')
if [[ "$expected" != "$actual" ]]; then
echo "Error: Checksum mismatch for $(basename "$file") (expected ${expected}, got ${actual})" >&2
return 1
fi
}
download_binary(){
local name="leafwiki-v${VERSION}-linux-${ARCH}"
local url="${RELEASE_LINK}releases/download/v${VERSION}/${name}"
wget -O "$name" "$url" || exit 1
if ! verify_checksum "$name" "$url"; then
rm -f "$name"
exit 1
fi
cp "$name" $PATH_TO_BINARY
rm "$name"
chmod +x $PATH_TO_BINARY
}
check_dependencies "systemctl"
check_dependencies "wget"
check_dependencies "sha256sum"
# Check if --non-interactive flag is present
if [[ "$*" == *"--non-interactive"* || "$*" == *"-non-interactive"* ]]; then
INTERACTIVE=0
fi
if [[ "$INTERACTIVE" -eq 0 && "$*" != *"--env-file"* && "$*" != *"-env-file"* ]]; then
echo "Error: In non-interactive mode, --env-file is required"
usage
exit 1
fi
if [[ "$INTERACTIVE" == 0 ]]; then
while [[ $# -gt 0 ]]; do
case "$1" in
-non-interactive|--non-interactive)
shift
;;
-env-file|--env-file)
if [[ -z "$2" ]]; then
echo "Error: --env-file requires a path argument"
usage
fi
if [[ ! -f "$2" ]]; then
echo "Error: Environment file '$2' does not exist or is not a regular file"
exit 1
fi
ENV_FILE_PATH="$(realpath "$2")"
ENV_FILE="$(basename "$2")"
if [[ ! -r "$ENV_FILE_PATH" ]]; then
echo "Error: Cannot read env file '$ENV_FILE_PATH'"
exit 1
fi
# Source the environment file and parse each variable
while IFS= read -r line || [[ -n "$line" ]]; do
# Skip empty lines and comments
[[ "$line" =~ ^[[:space:]]*$ || "$line" =~ ^[[:space:]]*# ]] && continue
# Extract key=value pairs
[[ "$line" =~ ^([A-Za-z_][A-Za-z0-9_]*)=(.*)$ ]] || continue
key="${BASH_REMATCH[1]}"
value="${BASH_REMATCH[2]}"
# Remove surrounding quotes (both single and double)
value="${value%\"}"
value="${value#\"}"
value="${value%\'}"
value="${value#\'}"
# Export the variable
export "$key=$value"
done < "$ENV_FILE_PATH"
shift 2
;;
*)
echo "Error: Unknown option '$1'"
usage
;;
esac
done
ARCH="${LEAFWIKI_ARCH:-$ARCH}"
PUBLIC_ACCESS="${LEAFWIKI_PUBLIC_ACCESS:-$PUBLIC_ACCESS}"
DATA_DIR="${LEAFWIKI_DATA_DIR:-$DATA_DIR}"
PORT="${LEAFWIKI_PORT:-$PORT}"
HOST="${LEAFWIKI_HOST:-$HOST}"
VERSION="${LEAFWIKI_VERSION:-$VERSION}"
JWT_SECRET="${LEAFWIKI_JWT_SECRET:-$JWT_SECRET}"
ADMIN_PASSWORD="${LEAFWIKI_ADMIN_PASSWORD:-$ADMIN_PASSWORD}"
ALLOW_INSECURE=${LEAFWIKI_ALLOW_INSECURE:-false}
DISABLE_AUTH=${LEAFWIKI_DISABLE_AUTH:-false}
ENABLE_REVISION=${LEAFWIKI_ENABLE_REVISION:-false}
MAX_REVISION_HISTORY=${LEAFWIKI_MAX_REVISION_HISTORY:-"100"}
ENABLE_LINK_REFACTORING=${LEAFWIKI_ENABLE_LINK_REFACTOR:-false}
validate_architecture
validate_requirements_non_interactive "$ARCH" "LEAFWIKI_ARCH"
validate_requirements_non_interactive "$JWT_SECRET" "LEAFWIKI_JWT_SECRET"
validate_requirements_non_interactive "$ADMIN_PASSWORD" "LEAFWIKI_ADMIN_PASSWORD"
validate_port
else
echo "___________________________________________________"
echo "| __ _____ ___ __ _ |";
echo "| / / ___ ____ _/ __/ | / (_) /__(_). |";
echo "| / / / _ \\/ __ \`/ /_ | | /| / / / //_/ / |";
echo "| / /___/ __/ /_/ / __/ | |/ |/ / / ,< / / |";
echo "|. /_____/\\___/\\__,_/_/ |__/|__/_/_/|_/_/ |";
echo "|_________________________________________________|";
echo ""
echo "========================================"
echo " LeafWiki — Installer"
echo "========================================"
echo ""
echo ""
read -rp "Which architecture do you want to use? (amd64/arm64): " ARCH
echo
read -rsp "Which JWT secret do you want to use: " JWT_SECRET
echo
read -rsp "Which admin password do you want to use: " ADMIN_PASSWORD
echo
read -rp "Which host do you want to use: " HOST
echo
read -rp "Which port do you want to use: " PORT
echo
read -rp "Should people without an account have read access? (default: n) y/N: " RESPONSE
if [[ $RESPONSE == "y" || $RESPONSE == "Y" ]]; then
PUBLIC_ACCESS="true"
else
PUBLIC_ACCESS="false"
fi
read -p "Where should the data be saved? (default: $DATA_DIR): " RESPONSE_DATA_DIR
if [[ -n "$RESPONSE_DATA_DIR" ]]; then
DATA_DIR="$RESPONSE_DATA_DIR"
fi
read -rp "Do you want to enable revision history? (default: n) y/N: " RESPONSE_REVISION
if [[ $RESPONSE_REVISION == "y" || $RESPONSE_REVISION == "Y" ]]; then
ENABLE_REVISION="true"
while true; do
read -p "Would you specify a max revision number? (default: $MAX_REVISION_HISTORY): " RESPONSE_MAX_REVISION
if [[ -z "$RESPONSE_MAX_REVISION" ]]; then
break
elif [[ "$RESPONSE_MAX_REVISION" =~ ^[0-9]+$ ]]; then
MAX_REVISION_HISTORY="$RESPONSE_MAX_REVISION"
break
else
echo "Invalid max revision number. Please
enter an integer greater than or equal to 0, or press Enter to
keep the default."
fi
done
else
ENABLE_REVISION="false"
fi
validate_port
validate_architecture
mkdir -p "$(dirname "$ENV_FILE_PATH")"
echo "LEAFWIKI_ARCH=\"$ARCH\"" > "$ENV_FILE_PATH"
echo "LEAFWIKI_PUBLIC_ACCESS=\"$PUBLIC_ACCESS\"" >> "$ENV_FILE_PATH"
echo "LEAFWIKI_DATA_DIR=\"$DATA_DIR\"" >> "$ENV_FILE_PATH"
echo "LEAFWIKI_PORT=\"$PORT\"" >> "$ENV_FILE_PATH"
echo "LEAFWIKI_HOST=\"$HOST\"" >> "$ENV_FILE_PATH"
echo "LEAFWIKI_JWT_SECRET=\"$JWT_SECRET\"" >> "$ENV_FILE_PATH"
echo "LEAFWIKI_ADMIN_PASSWORD=\"$ADMIN_PASSWORD\"" >> "$ENV_FILE_PATH"
echo "LEAFWIKI_ENABLE_REVISION=\"$ENABLE_REVISION\"" >> "$ENV_FILE_PATH"
echo "LEAFWIKI_MAX_REVISION_HISTORY=\"$MAX_REVISION_HISTORY\"" >> "$ENV_FILE_PATH"
fi
get_version
download_binary
mkdir -p "$DATA_DIR"
RUN_USER="${SUDO_USER:-$USER}"
chown -R "$RUN_USER:$RUN_USER" "$DATA_DIR"
echo "[Unit]
Description=LeafWiki
After=network.target
[Service]
User=$RUN_USER
EnvironmentFile=-${ENV_FILE_PATH:-$(realpath $PWD)/$ENV_FILE}
ExecStart=${PATH_TO_BINARY}
Restart=on-failure
[Install]
WantedBy=multi-user.target
" > /etc/systemd/system/leafwiki.service
systemctl enable leafwiki
systemctl start leafwiki
IS_ACTIVE=$(systemctl is-active leafwiki)
if [[ "$IS_ACTIVE" == "failed" ]]; then
echo "Installation failed: "
systemctl status leafwiki
else
echo "======================================="
echo "== LeafWiki installation completed! =="
echo "== =="
printf "== %-33s ==\n" "Host: $HOST"
printf "== %-33s ==\n" "Port: $PORT"
printf "== %-33s ==\n" "DataDirectory: $DATA_DIR"
printf "== %-33s ==\n" "Status: $IS_ACTIVE"
echo "== =="
echo "======================================="
fi