Merge pull request #580 from crhultay/patch-5

Installation Script Enhancement and Startup Script
This commit is contained in:
Bryan Ashby
2024-11-27 09:16:09 -07:00
committed by GitHub
4 changed files with 274 additions and 60 deletions

3
.gitignore vendored
View File

@@ -18,3 +18,6 @@ www/*
www/assets/*
!www/otp_register_template.html
!www/reset_password.template.html
# Runtime Environment
.venv

90
autoexec.sh Normal file
View File

@@ -0,0 +1,90 @@
#!/usr/bin/env bash
# Environment
ENIGMA_INSTALL_DIR=${ENIGMA_INSTALL_DIR:=$HOME/enigma-bbs}
AUTOEXEC_LOGFILE="$ENIGMA_INSTALL_DIR/logs/autoexec.log"
TIME_FORMAT=`date "+%Y-%m-%d %H:%M:%S"`
# Mise en place
~/.local/bin/mise activate bash >> bash
# Environment Versions
ENIGMA_NODE_VERSION=${ENIGMA_NODE_VERSION:=$(toml get --toml-path=$ENIGMA_INSTALL_DIR/mise.toml tools.node)}
ENIGMA_PYTHON_VERSION=${ENIGMA_PYTHON_VERSION:=$(toml get --toml-path=$ENIGMA_INSTALL_DIR/mise.toml tools.python)}
# Validate Environment
DEPENDENCIES_VALIDATED=1
# Shared Functions
log() {
echo "${TIME_FORMAT} " "$*" >> $AUTOEXEC_LOGFILE
}
# If this is a first run, the log path will not yet exist and must be created
if [ ! -d "$ENIGMA_INSTALL_DIR/logs" ]
then
mkdir -p $ENIGMA_INSTALL_DIR/logs
fi
log "START:"
log "- PATH: $PATH"
log "- CURRENT DIR: ${PWD##}"
if ! command -v "mise" 2>&1 >/dev/null
then
log "mise is not in your PATH, activating"
eval "$(~/.local/bin/mise activate bash)"
fi
if ! command -v "node" 2>&1 >/dev/null
then
log "Node environment is not in your PATH"
log "ERROR END"
exit 1
else
NODE_VERSION=$(node --version | tee /dev/null)
log "- NODE VERSION: $NODE_VERSION"
if [[ $NODE_VERSION != "v$ENIGMA_NODE_VERSION."* ]]; then
log "Node version found in your PATH is $NODE_VERSION, was expecting v$ENIGMA_NODE_VERSION.*; you may encounter compatibility issues"
DEPENDENCIES_VALIDATED=0
fi
fi
if ! command -v "python" 2>&1 >/dev/null
then
log "Python environment is not in your PATH"
log "ERROR END"
exit 1
else
PYTHON_VERSION=$(python --version | tee /dev/null)
log "- PYTHON VERSION: $PYTHON_VERSION"
if [[ $PYTHON_VERSION != "Python $ENIGMA_PYTHON_VERSION"* ]]; then
log "Python version found in your PATH is $PYTHON_VERSION, was expecting Python $ENIGMA_PYTHON_VERSION.*; you may encounter compatibility issues"
DEPENDENCIES_VALIDATED=0
fi
fi
# Validate whether we are good to Start
if [ "$DEPENDENCIES_VALIDATED" == "0" ]; then
if [ -v ENIGMA_IGNORE_DEPENDENCIES ] && [ "${ENIGMA_IGNORE_DEPENDENCIES}" == "1" ]; then
log "ENIGMA_IGNORE_DEPENDENCIES=1 detected, starting up..."
else
log "NOTE: Please re-run with 'ENIGMA_IGNORE_DEPENDENCIES=1 /path/to/autoexec.sh' to force startup"
log "ERROR END"
exit 1
fi
fi
# Start BBS
log "Starting ENiGMA½"
~/enigma-bbs/main.js
result=$?
# Determine whether a Startup Crash Occurred
# if [ $result -eq 0 ]; then
# # TODO: Notify via SMS / Email of Startup Failure
# fi
log "ENiGMA½ exited with $result"
log "END"
exit $result

View File

@@ -1,16 +1,52 @@
#!/usr/bin/env bash
{ # this ensures the entire script is downloaded before execution
ENIGMA_NODE_VERSION=${ENIGMA_NODE_VERSION:=18}
ENIGMA_BRANCH=${ENIGMA_BRANCH:=master}
ENIGMA_INSTALL_DIR=${ENIGMA_INSTALL_DIR:=$HOME/enigma-bbs}
ENIGMA_SOURCE=${ENIGMA_SOURCE:=https://github.com/NuSkooler/enigma-bbs.git}
TIME_FORMAT=`date "+%Y-%m-%d %H:%M:%S"`
WAIT_BEFORE_INSTALL=10
# ANSI Codes
RESET="\e[0m"
BOLD="\e[1m"
UNDERLINE="\e[4m"
INVERSE="\e7m"
FOREGROUND_BLACK="\e[30m"
FOREGROUND_RED="\e[31m"
FOREGROUND_GREEN="\e[32m"
FOREGROUND_YELLOW="\e[33m"
FOREGROUND_BLUE="\e[34m"
FOREGROUND_MAGENTA="\e[35m"
FOREGROUND_CYAN="\e[36m"
FOREGROUND_WHITE="\e[37m"
BACKGROUND_BLACK="\e[40m"
BACKGROUND_RED="\e[41m"
BACKGROUND_GREEN="\e[42m"
BACKGROUND_YELLOW="\e[43m"
BACKGROUND_BLUE="\e[44m"
BACKGROUND_MAGENTA="\e[45m"
BACKGROUND_CYAN="\e[46m"
BACKGROUND_WHITE="\e[47m"
FOREGROUND_STRONG_WHITE="\e[90m"
FOREGROUND_STRONG_RED="\e[91m"
FOREGROUND_STRONG_GREEN="\e[92m"
FOREGROUND_STRONG_YELLOW="\e[93m"
FOREGROUND_STRONG_BLUE="\e[94m"
FOREGROUND_STRONG_MAGENTA="\e[95m"
FOREGROUND_STRONG_CYAN="\e[96m"
FOREGROUND_STRONG_WHITE="\e[97m"
BACKGROUND_STRONG_BLACK="\e[100m"
BACKGROUND_STRONG_RED="\e[101m"
BACKGROUND_STRONG_GREEN="\e[102m"
BACKGROUND_STRONG_YELLOW="\e[103m"
BACKGROUND_STRONG_BLUE="\w[104m"
BACKGROUND_STRONG_MAGENTA="\e[105m"
BACKGROUND_STRONG_CYAN="\e[106m"
BACKGROUND_STRONG_WHITE="\e[107m"
enigma_header() {
clear
printf "$FOREGROUND_STRONG_WHITE"
cat << EndOfMessage
______
_____________________ _____ ____________________ __________\\_ /
@@ -22,27 +58,16 @@ _____________________ _____ ____________________ __________\\_ /
<*> ENiGMA½ // https://github.com/NuSkooler/enigma-bbs <*> /__/
Installing ENiGMA½:
ENiGMA½:
Source : ${ENIGMA_SOURCE} (${ENIGMA_BRANCH} branch)
Destination: ${ENIGMA_INSTALL_DIR}
Node.js : ${ENIGMA_NODE_VERSION}.x via NVM (If you have NVM it will be updated to the latest version)
>> If this isn't what you were expecting, hit CTRL-C now!
>> Installation will continue in ${WAIT_BEFORE_INSTALL} seconds...
EndOfMessage
SECS=10
while [ $SECS -gt 0 ]; do
echo -ne "${SECS}... "
sleep 1
((SECS --))
done
echo ""
printf "$RESET"
}
fatal_error() {
printf "${TIME_FORMAT} \e[41mERROR:\033[0m %b\n" "$*" >&2;
log "${TIME_FORMAT} ERROR: %b\n $*" >&2;
exit 1
}
@@ -51,52 +76,68 @@ check_exists() {
}
enigma_install_needs_ex() {
echo -ne "Checking for '$1'..."
log "Checking for '$1'...${RESET}"
if check_exists $1 ; then
echo " Found!"
log " Found!"
else
echo ""
fatal_error "ENiGMA½ requires '$1' but it was not found. Please install it and/or make sure it is in your path then restart the installer.\n\n$2"
fi
}
enigma_install_needs_python() {
echo -ne "Checking for a suitable Python installation..."
if check_exists "python" || check_exists "python7" || check_exists "python3" ; then
echo " Found!"
else
echo ""
fatal_error "ENiGMA½ requires Python for node-gyp to build binaries. Please see https://www.npmjs.com/package/node-gyp for details."
fi
}
enigma_install_needs() {
enigma_install_needs_ex $1 "Examples:\n sudo apt install $1 # Debian/Ubuntu\n sudo yum install $1 # CentOS"
}
log() {
printf "${TIME_FORMAT} %b\n" "$*";
enigma_has_mise() {
log "Checking for an installation of mise-en-place (https://mise.jdx.dev/)"
if check_exists "mise"; then
log "Found!"
else
log ""
fatal_error "ENiGMA½ requires mise-enplace to install dependencies."
fi
}
log() {
local LOG_CONTENT=$1
local COLOUR=""
case $LOG_CONTENT in
"ERROR")
COLOUR="${FOREGROUND_STRONG_RED}"
;;
*)
COLOUR="${FOREGROUND_GREEN}"
;;
esac
printf "${TIME_FORMAT} %b\n" "${COLOUR}${LOG_CONTENT}${RESET}";
}
enigma_install_init() {
enigma_install_needs git
enigma_install_needs curl
enigma_install_needs_python
enigma_install_needs_ex make "Examples:\n sudo apt install build-essential # Debian/Ubuntu\n sudo yum groupinstall 'Development Tools' # CentOS"
enigma_install_needs make
enigma_install_needs gcc
}
install_nvm() {
log "Installing nvm"
curl -o- https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
install_mise_en_place() {
curl https://mise.run | sh
# ~/.local/bin/mise activate bash >> bash
eval "$(~/.local/bin/mise activate bash)"
cd $ENIGMA_INSTALL_DIR
mise install
export PATH="$HOME/.local/share/mise/shims:$PATH"
}
configure_nvm() {
log "Installing Node ${ENIGMA_NODE_VERSION} via nvm"
. ~/.nvm/nvm.sh
nvm install ${ENIGMA_NODE_VERSION}
nvm use ${ENIGMA_NODE_VERSION}
install_tools() {
# Used to read toml files from bash scripts
python -m pip install toml-cli
}
download_enigma_source() {
@@ -104,7 +145,7 @@ download_enigma_source() {
INSTALL_DIR=${ENIGMA_INSTALL_DIR}
if [ -d "$INSTALL_DIR/.git" ]; then
log "ENiGMA½ is already installed in $INSTALL_DIR, trying to update using git"
log "ENiGMA½ is already installed in $INSTALL_DIR, trying to update using git..."
command git --git-dir="$INSTALL_DIR"/.git --work-tree="$INSTALL_DIR" fetch 2> /dev/null ||
fatal_error "Failed to update ENiGMA½, run 'git fetch' in $INSTALL_DIR yourself."
else
@@ -126,19 +167,21 @@ is_arch_arm() {
extra_npm_install_args() {
if is_arch_arm ; then
echo "--build-from-source"
printf "--build-from-source"
else
echo ""
printf ""
fi
}
install_node_packages() {
log "Installing required Node packages..."
log "Note that on some systems such as RPi, this can take a VERY long time. Be patient!"
printf "Note that on some systems such as RPi, this can take a VERY long time. Be patient!"
cd ${ENIGMA_INSTALL_DIR}
local EXTRA_NPM_ARGS=$(extra_npm_install_args)
git checkout ${ENIGMA_BRANCH} && npm install ${EXTRA_NPM_ARGS}
git checkout ${ENIGMA_BRANCH}
npm install ${EXTRA_NPM_ARGS}
if [ $? -eq 0 ]; then
log "npm package installation complete"
else
@@ -147,21 +190,22 @@ install_node_packages() {
}
copy_template_files() {
if [[ ! -f "./gopher/gophermap" ]]; then
cp "./misc/gophermap" "./gopher/gophermap"
log "Copying Template Files to ${ENIGMA_INSTALL_DIR}/misc/gophermap"
if [[ ! -f "$ENIGMA_INSTALL_DIR/gopher/gophermap" ]]; then
cp "$ENIGMA_INSTALL_DIR/misc/gophermap" "$ENIGMA_INSTALL_DIR/gopher/gophermap"
fi
}
enigma_footer() {
log "ENiGMA½ installation complete!"
echo -e "\e[1;33m"
printf "${FOREGROUND_YELLOW}"
cat << EndOfMessage
ADDITIONAL ACTIONS ARE REQUIRED!
--------------------------------
1 - If you did not have Node.js and/or NVM installed previous to this please open a new shell/terminal now!
(!) Not doing so will prevent 'nvm' or 'node' commands from functioning!
1 - If you did not have Node.js and/or mise installed previous to this please open a new shell/terminal now!
(!) Not doing so will prevent 'nvm', 'node', or 'python' commands from functioning!
2 - If this is the first time you've installed ENiGMA½, you now need to generate a minimal configuration:
@@ -185,17 +229,94 @@ ADDITIONAL ACTIONS ARE REQUIRED!
See docs for more information including other useful binaries!
4 - Start ENiGMA½ BBS!
./autoexec.sh
5 - Enable Automated Startup on Boot (optional)
Create a file in /etc/systemd/system/bbs.service with the following contents:
[Unit]
Description=Enigma½ BBS
[Install]
WantedBy=multi-user.target
[Service]
ExecStart=/home/<YOUR_USERNAME>/enigma-bbs/autoexec.sh
Type=simple
User=<YOUR_USERNAME>
Group=<YOUR_USERNAME>
WorkingDirectory=/home/<YOUR_USERNAME>/enigma-bbs/
Restart=on-failure
Run 'sudo systemctl enable bbs.service'
EndOfMessage
echo -e "\e[39m"
printf "${RESET}"
}
post_install() {
MISE_SHIM_PATH_COMMAND='export PATH="$HOME/.local/share/mise/shims:$PATH"'
if grep -Fxq "$MISE_SHIM_PATH_COMMAND" ~/.bashrc
then
log "Mise Shims found in your ~/.bashrc"
else
echo $MISE_SHIM_PATH_COMMAND >> ~/.bashrc
log "Installed Mise Shims into your ~/.bashrc"
fi
}
install_dependencies() {
log "Installing Dependencies..."
enigma_install_init
install_mise_en_place
install_tools
install_node_packages
post_install
}
install_bbs() {
log "Installing ENiGMA½..."
download_enigma_source
copy_template_files
}
install_everything() {
log "Installing Everything..."
download_enigma_source
install_dependencies
copy_template_files
}
menu() {
title="Installation Options"
prompt="Select>"
options=(
"Install Dependencies"
"Install ENiGMA½"
"Install Everything"
)
echo "$title"
PS3="$prompt "
select opt in "${options[@]}" "Quit"; do
case "$REPLY" in
1) enigma_install_init; install_dependencies; break;;
2) install_bbs; break;;
3) enigma_install_init; install_everything; break;;
$((${#options[@]}+1))) printf "Goodbye!"; exit 0;;
*) printf "${FOREGROUND_STRONG_RED}Invalid option.${RESET}\n";continue;;
esac
done < /dev/tty
unset PS3
}
enigma_header
enigma_install_init
install_nvm
configure_nvm
download_enigma_source
install_node_packages
copy_template_files
menu
enigma_footer
} # this ensures the entire script is downloaded before execution

View File

@@ -1,6 +1,6 @@
[tools]
node = "18"
python = "3.10"
node = '18'
python = '3.10'
[env]
NODE_ENV = 'production'