#!/bin/bash set -e # Function to set default values for environment variables set_defaults() { export CONFIG_DIR="${CONFIG_DIR:-/opt/config}" export CONFIG="$CONFIG_DIR/config.json" export NODEBB_INIT_VERB="${NODEBB_INIT_VERB:-install}" export NODEBB_BUILD_VERB="${NODEBB_BUILD_VERB:-build}" export START_BUILD="${START_BUILD:-${FORCE_BUILD_BEFORE_START:-false}}" export SETUP="${SETUP:-}" export PACKAGE_MANAGER="${PACKAGE_MANAGER:-npm}" export OVERRIDE_UPDATE_LOCK="${OVERRIDE_UPDATE_LOCK:-false}" } # Function to check if a directory exists and is writable check_directory() { local dir="$1" if [ ! -d "$dir" ]; then echo "Error: Directory $dir does not exist. Creating..." mkdir -p "$dir" || { echo "Error: Failed to create directory $dir" exit 1 } fi if [ ! -w "$dir" ]; then echo "Warning: No write permission for directory $dir, attempting to fix..." chown -R $USER:$USER "$dir" || true # attempt to change ownership, do not exit on failure chmod -R 760 "$dir" || true # attempt to change permissions, do not exit on failure if [ ! -w "$dir" ]; then echo "Error: No write permission for directory $dir. Exiting..." exit 1 fi fi } # Function to copy or link package.json and lock files based on package manager copy_or_link_files() { local src_dir="$1" local dest_dir="$2" local package_manager="$3" local lock_file case "$package_manager" in yarn) lock_file="yarn.lock" ;; npm) lock_file="package-lock.json" ;; pnpm) lock_file="pnpm-lock.yaml" ;; *) echo "Unknown package manager: $package_manager" exit 1 ;; esac # Check if source and destination files are the same if [ "$(realpath "$src_dir/package.json")" != "$(realpath "$dest_dir/package.json")" ] || [ "$OVERRIDE_UPDATE_LOCK" = true ]; then cp "$src_dir/package.json" "$dest_dir/package.json" fi if [ "$(realpath "$src_dir/$lock_file")" != "$(realpath "$dest_dir/$lock_file")" ] || [ "$OVERRIDE_UPDATE_LOCK" = true ]; then cp "$src_dir/$lock_file" "$dest_dir/$lock_file" fi # Remove unnecessary lock files in src_dir rm -f "$src_dir/"{yarn.lock,package-lock.json,pnpm-lock.yaml} # Symbolically link the copied files in src_dir to dest_dir ln -fs "$dest_dir/package.json" "$src_dir/package.json" ln -fs "$dest_dir/$lock_file" "$src_dir/$lock_file" } # Function to install dependencies using pnpm install_dependencies() { case "$PACKAGE_MANAGER" in yarn) yarn install || { echo "Failed to install dependencies with yarn" exit 1 } ;; npm) npm install || { echo "Failed to install dependencies with npm" exit 1 } ;; pnpm) pnpm install || { echo "Failed to install dependencies with pnpm" exit 1 } ;; *) echo "Unknown package manager: $PACKAGE_MANAGER" exit 1 ;; esac } # Function to start setup session start_setup_session() { local config="$1" echo "Starting setup session" exec /usr/src/app/nodebb setup --config="$config" } # Handle building and upgrading NodeBB build_forum() { local config="$1" local start_build="$2" local package_hash=$(md5sum install/package.json | head -c 32) if [ "$package_hash" != "$(cat $CONFIG_DIR/install_hash.md5 || true)" ]; then echo "package.json was updated. Upgrading..." /usr/src/app/nodebb upgrade --config="$config" || { echo "Failed to build NodeBB. Exiting..." exit 1 } elif [ "$start_build" = true ]; then echo "Build before start is enabled. Building..." /usr/src/app/nodebb "${NODEBB_BUILD_VERB}" --config="$config" || { echo "Failed to build NodeBB. Exiting..." exit 1 } else echo "No changes in package.json. Skipping build..." return fi echo -n $package_hash > $CONFIG_DIR/install_hash.md5 } # Function to start forum start_forum() { local config="$1" local start_build="$2" build_forum "$config" "$start_build" case "$PACKAGE_MANAGER" in yarn) yarn start --config="$config" --no-silent --no-daemon || { echo "Failed to start forum with yarn" exit 1 } ;; npm) npm start -- --config="$config" --no-silent --no-daemon || { echo "Failed to start forum with npm" exit 1 } ;; pnpm) pnpm start -- --config="$config" --no-silent --no-daemon || { echo "Failed to start forum with pnpm" exit 1 } ;; *) echo "Unknown package manager: $PACKAGE_MANAGER" exit 1 ;; esac } # Function to start installation session start_installation_session() { local nodebb_init_verb="$1" local config="$2" echo "Config file not found at $config" echo "Starting installation session" exec /usr/src/app/nodebb "$nodebb_init_verb" --config="$config" } # Function for debugging and logging debug_log() { local message="$1" echo "DEBUG: $message" } # Main function main() { set_defaults check_directory "$CONFIG_DIR" copy_or_link_files /usr/src/app "$CONFIG_DIR" "$PACKAGE_MANAGER" install_dependencies debug_log "PACKAGE_MANAGER: $PACKAGE_MANAGER" debug_log "CONFIG location: $CONFIG" debug_log "START_BUILD: $START_BUILD" if [ -n "$SETUP" ]; then start_setup_session "$CONFIG" fi if [ -f "$CONFIG" ]; then start_forum "$CONFIG" "$START_BUILD" else start_installation_session "$NODEBB_INIT_VERB" "$CONFIG" fi } # Execute main function main "$@"