diff --git a/changelog.json b/changelog.json index f725fb2..54fc2bc 100644 --- a/changelog.json +++ b/changelog.json @@ -1,81 +1,11 @@ { "releases": [ { - "version": "0.3.10", - "date": "2026-02-08", - "maturity": "ALPHA", + "version": "0.1.0", + "date": "2026-06-28", + "maturity": "INIT", "summary": "", "notes": "" - }, - { - "version": "0.3.9", - "date": "2026-02-08", - "maturity": "ALPHA", - "summary": "", - "notes": "" - }, - { - "version": "0.3.8", - "date": "2026-02-01", - "maturity": "ALPHA", - "summary": "", - "notes": "" - }, - { - "version": "0.3.7", - "date": "2026-02-01", - "maturity": "ALPHA", - "summary": "sdl-wkr Telemetry", - "notes": "" - }, - { - "version": "0.3.6", - "date": "2026-02-01", - "maturity": "ALPHA", - "summary": "Light/Dark Mode, Wkr Install, Cluster Stats", - "notes": "" - }, - { - "version": "0.3.5", - "date": "2026-02-01", - "maturity": "ALPHA", - "summary": "", - "notes": "" - }, - { - "version": "0.3.4", - "date": "2026-01-31", - "maturity": "ALPHA", - "summary": "", - "notes": "" - }, - { - "version": "0.3.3", - "date": "2026-01-31", - "maturity": "ALPHA", - "summary": "", - "notes": "" - }, - { - "version": "0.3.2", - "date": "2026-01-31", - "maturity": "ALPHA", - "summary": "", - "notes": "" - }, - { - "version": "0.3.1", - "date": "2026-01-31", - "maturity": "ALPHA", - "summary": "README Cleanup", - "notes": "" - }, - { - "version": "0.3.0", - "date": "2026-01-31", - "maturity": "ALPHA", - "summary": "Initial Codebase", - "notes": "Initial GitHub Release" } ] } diff --git a/docs/projects/new-project/project.json b/docs/projects/new-project/project.json deleted file mode 100644 index 307f7a6..0000000 --- a/docs/projects/new-project/project.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "Project Name", - "desc": "Project Description", - "parameters" : { - "parm1": { - "name": "Parameter Name", - "desc": "Parameter Description", - "type": "integer", - "min": 0, - "max": 100 - }, - "parm2": { - "name": "Parameter Name", - "desc": "Parameter Description", - "type": "integer", - "min": 0, - "max": 100 - } - }, - "iterations": 1000 -} \ No newline at end of file diff --git a/docs/projects/nks/project.json b/docs/projects/nks/project.json deleted file mode 100644 index 9942bb0..0000000 --- a/docs/projects/nks/project.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "id": "nks-ca", - "name": "NKS 1D CA", - "desc": "Exploration of 1D elementary New Kind of Science (NKS) Cellular Automata (CA)", - "date": "2026-02-09", - "version": "0.0.0", - "parameters" : { - "x": { - "name": "X Cells", - "desc": "Number of Binary Cells on the X Dimension", - "type": "integer", - "min": 3, - "max": 15 - }, - "rule": { - "name": "Rule", - "desc": "Update Rule Index", - "type": "integer", - "min": 0, - "max": 255 - }, - "init": { - "name": "Initial State", - "desc": "Initial Binary State", - "type": "integer", - "min": 0, - "max": "2^x" - } - }, - "iterations": 100 -} \ No newline at end of file diff --git a/docs/projects/ssl/project.json b/docs/projects/ssl/project.json deleted file mode 100644 index 1bf3d07..0000000 --- a/docs/projects/ssl/project.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "id": "ssl-evo-rnd", - "name": "SSL Random Evolution", - "desc": "State Space Locality (SSL) Random Perturbation Evolution Update Rule", - "date": "2026-02-09", - "version": "0.0.0", - "parameters" : { - "N": { - "name": "Nodes", - "desc": "N Node Directional Graph", - "type": "integer", - "min": 1, - "max": 1000 - }, - "rule": { - "name": "Rule", - "desc": "Proximity Update Rule", - "type": "text", - "eunum": [ - "Pii", - "Poo", - "Pio", - "Poi" - ] - }, - "init": { - "name": "Initial State", - "desc": "NxN Adjacency Matrix", - "type": "matrix" - } - }, - "iterations": 1000, - "permutations": {} -} \ No newline at end of file diff --git a/install.sh b/install.sh index c3f889e..07f0633 100755 --- a/install.sh +++ b/install.sh @@ -14,12 +14,12 @@ resolve_dirs() { raw["$key"]="$val" done < <(jq -r '.DIRS | to_entries[] | "\(.key)=\(.value)"' "$json") - if [[ -z "${raw[HOME]:-}" ]]; then - echo "ERROR: DIRS.HOME is not defined in config.json" + if [[ -z "${raw[SITE]:-}" ]]; then + echo "ERROR: DIRS.SITE is not defined in nwa-deploy-config.json" exit 1 fi - resolved["HOME"]="${raw[HOME]/#\~/$HOME}" + resolved["SITE"]="${raw[SITE]/#\~/$HOME}" local changed=true while $changed; do @@ -32,7 +32,21 @@ resolve_dirs() { val="${val/$rkey/${resolved[$rkey]:-}}" done - if [[ "$val" != ** ]]; then + # if [[ "$val" != ** ]]; then + # resolved["$key"]="$val" + # changed=true + # fi + + local unresolved=false + + for unresolved_key in "${!raw[@]}"; do + if [[ -z "${resolved[$unresolved_key]:-}" && "$val" == *"$unresolved_key"* ]]; then + unresolved=true + break + fi + done + + if [[ "$unresolved" == false ]]; then resolved["$key"]="$val" changed=true fi @@ -61,6 +75,93 @@ use_systemd() { return 1 # Use manual scripts } + +install_nodejs() { + NODE_TARGET="${OS_PLATFORM}:${OS_ARCH}" + NODE_PLATFORM="${OS_PLATFORM}-${OS_ARCH}" + + echo "" + echo "Target NodeJS:" + echo " Target: $NODE_TARGET" + echo " Platform: $NODE_PLATFORM" + + if ! jq -e --arg target "$NODE_TARGET" '.NODEJS.TARGETS[] | select(. == $target)' "$CONFIG_FILE" >/dev/null; then + echo "ERROR: NodeJS target not listed in config: $NODE_TARGET" + exit 1 + fi + + case "$OS_PLATFORM" in + linux) + EXT="tar.xz" + TAR_OPTS="-xJf" + ;; + darwin) + EXT="tar.gz" + TAR_OPTS="-xzf" + ;; + win) + echo "ERROR: win32 host install not supported by this installer" + exit 1 + ;; + *) + echo "ERROR: Unsupported OS platform: $OS_PLATFORM" + exit 1 + ;; + esac + + NODE_DIR="node-v${NODE_VERSION}-${NODE_PLATFORM}" + NODE_TARBALL="${NODE_DIR}.${EXT}" + NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/${NODE_TARBALL}" + SHASUM_URL="https://nodejs.org/dist/v${NODE_VERSION}/SHASUMS256.txt" + + NODE_BIN="$NODEJS/current/bin/node" + + if [[ -e "$NODE_BIN" ]]; then + NODE_BIN_VERSION="$("$NODE_BIN" --version)" + + if [[ "$NODE_BIN_VERSION" == "v$NODE_VERSION" ]]; then + echo "" + echo "NodeJS $NODE_PLATFORM v$NODE_VERSION already installed" + return 0 + fi + fi + + TMP_DIR="$(mktemp -d)" + trap 'rm -rf "$TMP_DIR"' RETURN + + echo "" + echo "Installing NodeJS:" + echo " Version: $NODE_VERSION" + echo " Archive: $NODE_TARBALL" + echo " To: $NODEJS" + + curl -sSL "$SHASUM_URL" -o "$TMP_DIR/SHASUMS256.txt" + curl -sSL "$NODE_URL" -o "$TMP_DIR/$NODE_TARBALL" + + EXPECTED_SHA="$(grep " $NODE_TARBALL\$" "$TMP_DIR/SHASUMS256.txt" | awk '{print $1}')" + + if [[ -z "$EXPECTED_SHA" ]]; then + echo "ERROR: SHA256 not found for $NODE_TARBALL" + exit 1 + fi + + ACTUAL_SHA="$(sha256sum "$TMP_DIR/$NODE_TARBALL" | awk '{print $1}')" + + if [[ "$ACTUAL_SHA" != "$EXPECTED_SHA" ]]; then + echo "ERROR: SHA mismatch for $NODE_TARBALL" + exit 1 + fi + + rm -rf "$NODEJS/$NODE_DIR" + tar $TAR_OPTS "$TMP_DIR/$NODE_TARBALL" -C "$NODEJS" + + ln -sfn "$NODEJS/$NODE_DIR" "$NODEJS/current" + + echo "NodeJS installed:" + echo " $NODEJS/current/bin/node" +} + + # ------------------------------------------------------------ # Main # ------------------------------------------------------------ @@ -89,7 +190,7 @@ done SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT="$(cd "$SCRIPT_DIR" && pwd)" -CONFIG_FILE="$ROOT/config.json" +CONFIG_FILE="$ROOT/nwa-deploy-config.json" META_FILE="$ROOT/metadata.json" [[ -f "$CONFIG_FILE" ]] || { echo "ERROR: config.json not found"; exit 1; } @@ -175,7 +276,7 @@ VERSION_DATE="$(jq -r '.METADATA.version_date' "$META_FILE")" COPYRIGHT="$(jq -r '.METADATA.copyright' "$META_FILE")" AUTHOR="$(jq -r '.METADATA.author' "$META_FILE")" LICENSE="$(jq -r '.METADATA.license' "$META_FILE")" -HOMEPAGE="$(jq -r '.METADATA.homepage' "$META_FILE")" +SITEPAGE="$(jq -r '.METADATA.SITEpage' "$META_FILE")" REPO="$(jq -r '.METADATA.git_repo' "$META_FILE")" @@ -195,7 +296,7 @@ echo " Version Date: $VERSION_DATE" echo " Copyright: (C) $COPYRIGHT" echo " Author: $AUTHOR" echo " License: $LICENSE" -echo " Homepage: $HOMEPAGE" +echo " SITEpage: $SITEPAGE" echo " Repository: $REPO" echo "" @@ -223,109 +324,83 @@ if [[ "$OS_PLATFORM" == "win32" ]]; then fi echo "Directories:" -echo " ROOT: $ROOT" +echo " ROOT: $ROOT" resolve_dirs "$CONFIG_FILE" - # ------------------------------------------------------------ -# Build sdl-mgr tarball to DIST -# Always rebuild sdl-mgr_version.tgz from source +# Copy nwa to Prod Dir # ------------------------------------------------------------ echo "" -echo "Generating: $DIST/sdl-mgr_$VERSION.tgz" -tar -czf "$DIST/sdl-mgr_$VERSION.tgz" -C "$ROOT" sdl-mgr -sha256sum "$DIST/sdl-mgr_$VERSION.tgz" | awk '{sub(".*/","",$2); print}' > "$DIST/sdl-mgr_$VERSION.tgz.sha256" - -# ------------------------------------------------------------ -# Build sdl-wkr tarball to DIST -# Always rebuild sdl-wkr_version.tgz from source -# ------------------------------------------------------------ -echo "" -echo "Generating: $DIST/sdl-wkr_$VERSION.tgz" -tar -czf "$DIST/sdl-wkr_$VERSION.tgz" -C "$ROOT" sdl-wkr -sha256sum "$DIST/sdl-wkr_$VERSION.tgz" | awk '{sub(".*/","",$2); print}' > "$DIST/sdl-wkr_$VERSION.tgz.sha256" - -# ------------------------------------------------------------ -# Copy install-sdl-wkr.sh to DIST -# ------------------------------------------------------------ -echo "" -echo "Copying: $DIST/install-sdl-wkr.sh" -cp "$ROOT/sdl-wkr/scripts/install-sdl-wkr.sh" "$DIST/install-sdl-wkr.sh" -sha256sum "$DIST/install-sdl-wkr.sh" | awk '{sub(".*/","",$2); print}' > "$DIST/install-sdl-wkr.sh.sha256" +echo "Installing nwa version $VERSION to $VERSIONS/nwa_$VERSION" +rsync -av $ROOT/nwa --exclude='node_modules' $VERSIONS/nwa_$VERSION +# ln -s $VERSIONS/nwa_$VERSION $VERSIONS/current +ln -sfnT "$VERSIONS/nwa_$VERSION" "$VERSIONS/current" +NWA="$VERSIONS/current/nwa" # ------------------------------------------------------------ # Fetch NodeJS Tarballs / Zips to DIST # ------------------------------------------------------------ -echo "" -echo "Fetching NodeJS Binaries to $DIST" -SHASUM_URL="https://nodejs.org/dist/v${NODE_VERSION}/SHASUMS256.txt" -curl -sSL "$SHASUM_URL" -o "$DIST/NODE_SHASUMS256.txt" +install_nodejs -# Download NodeJS tarball +# echo "" +# echo "Fetching NodeJS Binaries to $DIST" +# SHASUM_URL="https://nodejs.org/dist/v${NODE_VERSION}/SHASUMS256.txt" +# curl -sSL "$SHASUM_URL" -o "$DIST/NODE_SHASUMS256.txt" -for np in $NODE_PLATFORMS; do - IFS=":" read -r OS ARCH <<< "$np" +# # Download NodeJS tarball - case "$OS" in - linux) EXT="tar.xz" ;; - darwin) EXT="tar.gz" ;; - win) EXT="zip" ;; - *) echo "ERROR: Unknown NodeJS target OS: $OS"; exit 1 ;; - esac +# for np in $NODE_PLATFORMS; do +# IFS=":" read -r OS ARCH <<< "$np" - PLATFORM="${OS}-${ARCH}" - NODE_DIR="node-v${NODE_VERSION}-${PLATFORM}" - NODE_TARBALL="${NODE_DIR}.$EXT" - NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/${NODE_TARBALL}" +# case "$OS" in +# linux) EXT="tar.xz" ;; +# darwin) EXT="tar.gz" ;; +# win) EXT="zip" ;; +# *) echo "ERROR: Unknown NodeJS target OS: $OS"; exit 1 ;; +# esac - echo " $np: $NODE_TARBALL" +# PLATFORM="${OS}-${ARCH}" +# NODE_DIR="node-v${NODE_VERSION}-${PLATFORM}" +# NODE_TARBALL="${NODE_DIR}.$EXT" +# NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/${NODE_TARBALL}" - if [ ! -e "$DIST/$NODE_TARBALL" ]; then +# echo " $np: $NODE_TARBALL" - curl -sSL "$NODE_URL" -o "$DIST/$NODE_TARBALL" +# if [ ! -e "$DIST/$NODE_TARBALL" ]; then - EXPECTED_SHA="$(grep " $NODE_TARBALL\$" "$DIST/NODE_SHASUMS256.txt" | awk '{print $1}')" +# curl -sSL "$NODE_URL" -o "$DIST/$NODE_TARBALL" - if [[ -z "$EXPECTED_SHA" ]]; then - echo "Error: SHA256 not found for $NODE_TARBALL" - exit 1 - fi +# EXPECTED_SHA="$(grep " $NODE_TARBALL\$" "$DIST/NODE_SHASUMS256.txt" | awk '{print $1}')" - ACTUAL_SHA="$(sha256sum "$DIST/$NODE_TARBALL" | awk '{print $1}')" +# if [[ -z "$EXPECTED_SHA" ]]; then +# echo "Error: SHA256 not found for $NODE_TARBALL" +# exit 1 +# fi - if [[ "$ACTUAL_SHA" != "$EXPECTED_SHA" ]]; then - echo "SHA mismatch $NODE_TARBALL" - rm -f "$DIST/$NODE_TARBALL" - exit 1 - fi +# ACTUAL_SHA="$(sha256sum "$DIST/$NODE_TARBALL" | awk '{print $1}')" - echo "$EXPECTED_SHA $NODE_TARBALL" > "$DIST/$NODE_TARBALL.sha256" - fi -done +# if [[ "$ACTUAL_SHA" != "$EXPECTED_SHA" ]]; then +# echo "SHA mismatch $NODE_TARBALL" +# rm -f "$DIST/$NODE_TARBALL" +# exit 1 +# fi + +# echo "$EXPECTED_SHA $NODE_TARBALL" > "$DIST/$NODE_TARBALL.sha256" +# fi +# done unset OS ARCH - # ------------------------------------------------------------ -# Extract sdl-mgr-VERSION tarball from DIST to MGR -# Symlink to MGR/current -# ------------------------------------------------------------ -echo "" -echo "Extracting: $DIST/sdl-mgr_$VERSION.tgz to $MGR/sdl-mgr_$VERSION" -rm -rf "$MGR/sdl-mgr_$VERSION" -tar -xzf "$DIST/sdl-mgr_$VERSION.tgz" -C "$MGR" -mv "$MGR/sdl-mgr" "$MGR/sdl-mgr_$VERSION" -# rm "$MGR/current" -ln -sfn "$MGR/sdl-mgr_$VERSION" "$MGR/current" - -# ------------------------------------------------------------ -# Copy MGR/current/conf/efault-sdl-mgr-config.json to CONF/sdl-mgr-config.json +# Copy NWA/current/conf/efault-nwa-config.json to CONF/nwa-config.json # ------------------------------------------------------------ -if [ ! -e "$CONF/sdl-mgr-config.json" ]; then +if [ ! -e "$CONF/nwa-config.json" ]; then echo "" - echo "Copying: $MGR/current/conf/default-sdl-mgr-config.json to $CONF/sdl-mgr-config.json" - cp "$MGR/current/conf/default-sdl-mgr-config.json" "$CONF/sdl-mgr-config.json" + # echo "Copying: $NWA/current/conf/default-nwa-config.json to $CONF/nwa-config.json" + # cp "$NWA/current/conf/default-nwa-config.json" "$CONF/nwa-config.json" + echo "Copying: $NWA/conf/nwa-config.json to $CONF/nwa-config.json" + rsync -av "$NWA/conf/nwa-config.json" "$CONF/nwa-config.json" fi # ------------------------------------------------------------ @@ -333,56 +408,56 @@ fi # Symlink to NODEJS/current # ------------------------------------------------------------ -# Check if NodeJS is already installed +# # Check if NodeJS is already installed NODE_BIN="$NODEJS/current/bin/node" NPM_BIN="$NODEJS/current/bin/npm" # echo "NodeJS binary: $NODE_BIN" -if [ -e "$NODE_BIN" ]; then - NODE_BIN_VERSION="$("$NODE_BIN" --version)" - # echo "NodeJS bin version: $NODE_BIN_VERSION" - # echo "NodeJS version: v$NODE_VERSION" - case "$OS_PLATFORM" in - linux) EXT="tar.xz"; TAR_OPTS="-xJf" ;; - darwin) EXT="tar.gz"; TAR_OPTS="-xzf" ;; - win) EXT="zip" ;; - *) echo "ERROR: Unsupported OS platform: $OS_PLATFORM"; exit 1 ;; - esac +# if [ -e "$NODE_BIN" ]; then +# NODE_BIN_VERSION="$("$NODE_BIN" --version)" +# # echo "NodeJS bin version: $NODE_BIN_VERSION" +# # echo "NodeJS version: v$NODE_VERSION" +# case "$OS_PLATFORM" in +# linux) EXT="tar.xz"; TAR_OPTS="-xJf" ;; +# darwin) EXT="tar.gz"; TAR_OPTS="-xzf" ;; +# win) EXT="zip" ;; +# *) echo "ERROR: Unsupported OS platform: $OS_PLATFORM"; exit 1 ;; +# esac - if [ "$NODE_BIN_VERSION" != "v$NODE_VERSION" ]; then - echo "" - echo "Installing NodeJS: node-v${NODE_VERSION}-${OS_PLATFORM}-${OS_ARCH}" +# if [ "$NODE_BIN_VERSION" != "v$NODE_VERSION" ]; then +# echo "" +# echo "Installing NodeJS: node-v${NODE_VERSION}-${OS_PLATFORM}-${OS_ARCH}" - echo "Extracting: $DIST/node-v${NODE_VERSION}-${OS_PLATFORM}-${OS_ARCH}.$EXT" - if [ $OS_PLATFORM == "win32" ]; then - echo "ERROR: win32 host install not supported by this installer" - exit 1 - # unzip "$DIST/node-v${NODE_VERSION}-${OS_PLATFORM}-${OS_ARCH}.$EXT" -d "$NODEJS" - else - tar $TAR_OPTS "$DIST/node-v${NODE_VERSION}-${OS_PLATFORM}-${OS_ARCH}.$EXT" -C "$NODEJS" - fi - # rm "$NODEJS/current" - ln -sfn "$NODEJS/node-v${NODE_VERSION}-${OS_PLATFORM}-${OS_ARCH}" "$NODEJS/current" - else - echo "" - echo "NodeJS $OS_PLATFORM-$OS_ARCH v$NODE_VERSION already installed" - fi -else - echo "" - echo "Installing NodeJS $NODE_VERSION" +# echo "Extracting: $DIST/node-v${NODE_VERSION}-${OS_PLATFORM}-${OS_ARCH}.$EXT" +# if [ $OS_PLATFORM == "win32" ]; then +# echo "ERROR: win32 host install not supported by this installer" +# exit 1 +# # unzip "$DIST/node-v${NODE_VERSION}-${OS_PLATFORM}-${OS_ARCH}.$EXT" -d "$NODEJS" +# else +# tar $TAR_OPTS "$DIST/node-v${NODE_VERSION}-${OS_PLATFORM}-${OS_ARCH}.$EXT" -C "$NODEJS" +# fi +# # rm "$NODEJS/current" +# ln -sfn "$NODEJS/node-v${NODE_VERSION}-${OS_PLATFORM}-${OS_ARCH}" "$NODEJS/current" +# else +# echo "" +# echo "NodeJS $OS_PLATFORM-$OS_ARCH v$NODE_VERSION already installed" +# fi +# else +# echo "" +# echo "Installing NodeJS $NODE_VERSION" - echo "Extracting: $DIST/node-v${NODE_VERSION}-${OS_PLATFORM}-${OS_ARCH}.tar.xz" - tar -xJf "$DIST/node-v${NODE_VERSION}-${OS_PLATFORM}-${OS_ARCH}.tar.xz" -C "$NODEJS" - ln -sfn "$NODEJS/node-v${NODE_VERSION}-${OS_PLATFORM}-${OS_ARCH}" "$NODEJS/current" -fi +# echo "Extracting: $DIST/node-v${NODE_VERSION}-${OS_PLATFORM}-${OS_ARCH}.tar.xz" +# tar -xJf "$DIST/node-v${NODE_VERSION}-${OS_PLATFORM}-${OS_ARCH}.tar.xz" -C "$NODEJS" +# ln -sfn "$NODEJS/node-v${NODE_VERSION}-${OS_PLATFORM}-${OS_ARCH}" "$NODEJS/current" +# fi # ------------------------------------------------------------ -# Install sdl-mgr Node Dependencies +# Install nwa Node Dependencies # ------------------------------------------------------------ echo "" echo "Installing NodeJS Dependencies" -cd "$MGR/current/app" +cd "$NWA/app" export PATH="$NODEJS/current/bin:$PATH" $NPM_BIN install @@ -390,40 +465,40 @@ $NPM_BIN install # ------------------------------------------------------------ # Copy Start / Stop Scripts # ------------------------------------------------------------ -mkdir -p "$HOME/scripts/" -cp "$MGR/current/scripts/start-sdl-mgr.sh" "$HOME/scripts/" -cp "$MGR/current/scripts/stop-sdl-mgr.sh" "$HOME/scripts/" -cp "$MGR/current/scripts/status-sdl-mgr.sh" "$HOME/scripts/" -chmod u+x "$HOME/scripts/"* +mkdir -p "$SITE/scripts/" +cp "$NWA/scripts/start-nwa.sh" "$SITE/scripts/" +cp "$NWA/scripts/stop-nwa.sh" "$SITE/scripts/" +cp "$NWA/scripts/status-nwa.sh" "$SITE/scripts/" +chmod u+x "$SITE/scripts/"* # ------------------------------------------------------------ # Install Systemd Unit Files -# Copy MGR/current/scripts/sdl-mgr.service to ~/.config/systemd/user +# Copy NWA/current/scripts/nwa.service to ~/.config/systemd/user # ------------------------------------------------------------ if use_systemd; then echo "" echo "Installing SystemD Unit Files" mkdir -p ~/.config/systemd/user - cp "$MGR/current/scripts/sdl-mgr.service" ~/.config/systemd/user/ + cp "$NWA/scripts/nwa.service" ~/.config/systemd/user/ - "${HOME}/scripts/stop-sdl-mgr.sh" + "${SITE}/scripts/stop-nwa.sh" sleep 1 systemctl --user daemon-reload --no-pager fi # ------------------------------------------------------------ -# Start SDL Manager +# Start NWA # ------------------------------------------------------------ -"${HOME}/scripts/start-sdl-mgr.sh" +"${SITE}/scripts/start-nwa.sh" sleep 2 -"${HOME}/scripts/status-sdl-mgr.sh" +"${SITE}/scripts/status-nwa.sh" if [ $? -ne 0 ]; then echo "" - echo "ERROR: SDL Manager failed to start" + echo "ERROR: NWA failed to start" exit 1 fi @@ -432,6 +507,6 @@ fi echo "" -echo "SDL Manager deployed:" -echo " to: $HOME" +echo "NWA deployed:" +echo " to: $SITE" diff --git a/metadata.json b/metadata.json index dcb20a0..f81fac3 100644 --- a/metadata.json +++ b/metadata.json @@ -4,14 +4,14 @@ "description": "Node Web App", "abbr": "NWA", "version": "0.1.0", - "version_date": "2026-02-08", + "version_date": "2026-06-28", "maturity": "PROD", "author": "John Haverlack", "copyright": "2026 John Haverlack", "license": "MIT", "license_url": "https://opensource.org/license/MIT", - "homepage": "https://github.com/jehaverlack/sdl", - "git_repo": "https://github.com/jehaverlack/sdl.git" + "homepage": "https://github.com/jehaverlack/nwa", + "git_repo": "https://github.com/jehaverlack/nwa.git" }, "META_MAPS": { "package.json": { diff --git a/config.json b/nwa-deploy-config.json similarity index 51% rename from config.json rename to nwa-deploy-config.json index 96223d4..de00d01 100644 --- a/config.json +++ b/nwa-deploy-config.json @@ -1,12 +1,13 @@ { "DIRS": { - "HOME": "~/.nwa", - "CONF": "HOME/conf", - "DOCS": "HOME/docs", - "LOGS": "HOME/logs", - "DATA": "HOME/data", - "SCRIPTS": "HOME/scripts", - "NODEJS": "HOME/nodejs" + "SITE": "~/.nwa", + "CONF": "SITE/conf", + "DOCS": "SITE/docs", + "LOGS": "SITE/logs", + "DATA": "SITE/data", + "SCRIPTS": "SITE/scripts", + "NODEJS": "SITE/nodejs", + "VERSIONS": "SITE/versions" }, "NODEJS": { "VERSION": "24.18.0", diff --git a/nwa/app/modules/nwa-lib/index.js b/nwa/app/modules/nwa-lib/index.js index f7c1dfe..974a1d0 100644 --- a/nwa/app/modules/nwa-lib/index.js +++ b/nwa/app/modules/nwa-lib/index.js @@ -34,11 +34,14 @@ function load_config() { .argv; // console.log("DEBUG: dirname: " + __dirname); - let home = path.join(__dirname, '..', '..', '..'); // HOME Default - let mgr_cfg_file = path.join(home, 'conf', 'nwa-config.json'); + let site = path.join(__dirname, '..', '..', '..', '..', '..', '..'); // site Default + // let base = path.join(__dirname, '..', '..', '..', '..'); // base Default + // let mgr_cfg_file = path.join(base, 'nwa', 'conf', 'nwa-config.json'); + let mgr_cfg_file = path.join(site, 'conf', 'nwa-config.json'); - // console.log("DEBUG: HOME: " + home); + // console.log("DEBUG: site: " + site); // console.log("DEBUG: MGR_CFG_FILE: " + mgr_cfg_file); + try { fs.accessSync(mgr_cfg_file, fs.constants.R_OK); } catch (err) { @@ -46,38 +49,6 @@ function load_config() { process.exit(1); } - // // Load from ENV - // if (process.env.HOME) { - // home = process.env.HOME; - // mgr_cfg_file = path.join(home, 'conf', '-mgr-config.json'); - // // console.log("DEBUG3: HOME: " + home); - // // console.log("DEBUG3: MGR_CFG_FILE: " + mgr_cfg_file); - // try { - // fs.accessSync(mgr_cfg_file, fs.constants.R_OK); - // } catch (err) { - // console.error(err); - // process.exit(1); - // } - // } - - // // Load from ARGV - // if (argv.configfile) { - // home = path.dirname(argv.configfile); - // mgr_cfg_file = path.join(home, 'conf', '-mgr-config.json'); - // // console.log("DEBUG4: HOME: " + home); - // // console.log("DEBUG4: MGR_CFG_FILE: " + mgr_cfg_file); - // try { - // fs.accessSync(mgr_cfg_file, fs.constants.R_OK); - // } catch (err) { - // console.error(err); - // process.exit(1); - // } - // } - - // console.log("DEBUG: HOME: " + home); - // console.log("DEBUG: MGR_CFG_FILE: " + mgr_cfg_file); - - // Load Config try { @@ -87,13 +58,13 @@ function load_config() { console.error(err); } - // console.log("DEBUG: home: " + home); + // console.log("DEBUG: site: " + site); // Expand Data Directory let search_replace = {} search_replace['DIRNAME'] = __dirname - // search_replace['HOME'] = home - config.dirs['home'] = home + // search_replace['site'] = site + config.dirs['site'] = site for (let d in config.dirs) { search_replace[d.toUpperCase()] = d } @@ -131,23 +102,13 @@ function load_config() { fs.mkdirSync(config.dirs[d], { recursive: true }); } } - // for (let k in config.dependencies[d]) { - // // if k matches case insensitive "dependencies" the remove elemend k. - // if (k.match(/[Dd]ependencies/)) { - // delete config.dependencies[d][k] - // } - - // if (k.match(/scripts/)) { - // delete config.dependencies[d][k] - // } - // } // Load Package Info config.package = JSON.parse(fs.readFileSync(path.join(config.dirs.app, 'package.json'), 'utf8')); config.dependencies = {} // Version - config.cluster.version = config.package.version + // config.nwa.version = config.package.version for (let d in config.package.dependencies) { config.dependencies[d] = JSON.parse(fs.readFileSync(path.join(config.dirs.app, 'node_modules', d, 'package.json'), 'utf8')); @@ -186,7 +147,8 @@ function load_config() { }; config.nwa = { - version: config.package.version + version: config.package.version, + config_file: mgr_cfg_file } config.identity = { @@ -271,7 +233,7 @@ function load_config() { try { // console.log(JSON.stringify(config.dirs, null, 2)); - const idinfo = load_or_create_id(config.dirs.home); + const idinfo = load_or_create_id(config.dirs.site); config.identity.id = idinfo.id; config.identity.created_at = idinfo.created_at; config.identity.hostname = config.host.hostname; @@ -381,9 +343,9 @@ function computeBroadcast(address, netmask) { } } -function load_or_create_id(home) { - // console.log('DEBUG: load_or_create_id() home: ' + home); - const id_dir = path.join(home, 'conf'); +function load_or_create_id(site) { + // console.log('DEBUG: load_or_create_id() site: ' + site); + const id_dir = path.join(site, 'conf'); const id_file = path.join(id_dir, 'nwa-id.json'); try { diff --git a/nwa/conf/nwa-config.json b/nwa/conf/nwa-config.json index 4a56434..cd773f0 100644 --- a/nwa/conf/nwa-config.json +++ b/nwa/conf/nwa-config.json @@ -1,19 +1,16 @@ { - "cluster": { - "id": "haverlab", - "name": "Haverlab", - "desc": "John Haverlack's Home Lab" + "site": { + "id": "nwa", + "name": "Node Web App", + "desc": "A Node.json Web App Template" }, "dirs": { "base": "DIRNAME/../..", "app": "BASE/app", "modules": "APP/modules", - "logs": "HOME/logs", - "data": "HOME/data", - "clstr": "DATA/cluster", - "proj": "DATA/proj", - "jobs": "DATA/jobs", - "conf": "HOME/conf", + "logs": "SITE/logs", + "data": "SITE/data", + "conf": "SITE/conf", "modconf": "BASE/conf/modules", "html": "BASE/html" }, diff --git a/nwa/scripts/sdl-uninstall.sh b/nwa/scripts/nwa-uninstall.sh similarity index 100% rename from nwa/scripts/sdl-uninstall.sh rename to nwa/scripts/nwa-uninstall.sh diff --git a/nwa/scripts/nwa.service b/nwa/scripts/nwa.service new file mode 100644 index 0000000..bc1bb94 --- /dev/null +++ b/nwa/scripts/nwa.service @@ -0,0 +1,31 @@ +[Unit] +Description=Node Web App +After=network.target + +[Service] +Type=simple + +# Environment +Environment=NWA_HOME=%h/.nwa +Environment=NODE_ENV=production + +# Paths +WorkingDirectory=%h/.nwa/versions/current/nwa/app + +# Start command +ExecStart=%h/.nwa/nodejs/current/bin/node index.js + +# Restart behavior +Restart=on-failure +RestartSec=3 + +# Logging +StandardOutput=append:%h/.nwa/logs/nwa.log +StandardError=append:%h/.nwa/logs/nwa.log + +# Clean shutdown +KillSignal=SIGTERM +TimeoutStopSec=15 + +[Install] +WantedBy=default.target \ No newline at end of file diff --git a/nwa/scripts/sdl-mgr.service b/nwa/scripts/sdl-mgr.service deleted file mode 100644 index 8812223..0000000 --- a/nwa/scripts/sdl-mgr.service +++ /dev/null @@ -1,29 +0,0 @@ -[Unit] -Description=SDL Manager -After=network.target - -[Service] -Type=simple - -# Paths -Environment=SDL_HOME=%h/.sdl - -WorkingDirectory=%h/.sdl/sdl-mgr/current/app - -# Start command -ExecStart=%h/.sdl/nodejs/current/bin/node index.js - -# Restart behavior -Restart=on-failure -RestartSec=3 - -# Logging -StandardOutput=append:%h/.sdl/logs/sdl-mgr.out.log -StandardError=append:%h/.sdl/logs/sdl-mgr.err.log - -# Clean shutdown -KillSignal=SIGTERM -TimeoutStopSec=15 - -[Install] -WantedBy=default.target \ No newline at end of file diff --git a/nwa/scripts/start-nwa.sh b/nwa/scripts/start-nwa.sh new file mode 100755 index 0000000..3f1fe5b --- /dev/null +++ b/nwa/scripts/start-nwa.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +# start-nwa.sh - Script to start Node Web App +set -euo pipefail + +use_systemd() { + # Check if systemd user mode is available and service exists + if systemctl --user status >/dev/null 2>&1; then + # Check if our service file exists + if systemctl --user list-unit-files | grep -q "^nwa.service"; then + return 0 # Use systemd + fi + fi + return 1 # Use manual scripts +} + +# Get $NWA_HOME directory from SCRIPT PATH +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +NWA_HOME="$(cd "$SCRIPT_DIR/.." && pwd)" + +if use_systemd; then + # Systemd mode - let systemd handle it + echo "Starting NWA (systemd)..." + systemctl --user start nwa + exit 0 +fi + +# Manual mode - continue with checks +NODE_BIN_DIR="${NWA_HOME}/nodejs/current/bin" +NODE_BIN="${NODE_BIN_DIR}/node" +NPM_BIN="${NODE_BIN_DIR}/npm" + +NWA_APP_DIR="${NWA_HOME}/current/app" + +# Check that nwa is not already running +NWA_PID="" +for pid in $(pgrep -f 'node' 2>/dev/null || true); do + cwd=$(readlink /proc/$pid/cwd 2>/dev/null || true) + if [[ "$cwd" == *"nwa"* ]]; then + NWA_PID="$pid" + break + fi +done + +if [[ -n "$NWA_PID" ]]; then + echo "ERROR: NWA is already running with PID ${NWA_PID}" + echo " Stop it first: ${NWA_HOME}/scripts/stop-nwa.sh" + exit 1 +fi + +# Verify paths exist +if [[ ! -f "$NODE_BIN" ]]; then + echo "ERROR: Node.js not found at: $NODE_BIN" + echo " Run install.sh first" + exit 1 +fi + +if [[ ! -d "$NWA_APP_DIR" ]]; then + echo "ERROR: NWA app not found at: $NWA_APP_DIR" + echo " Run install.sh first" + exit 1 +fi + +echo "Starting NWA..." +echo " App Dir: ${NWA_APP_DIR}" +echo " Node: \ No newline at end of file diff --git a/nwa/scripts/start-sdl-mgr.sh b/nwa/scripts/start-sdl-mgr.sh deleted file mode 100755 index 5903030..0000000 --- a/nwa/scripts/start-sdl-mgr.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env bash -# start-sdl-mgr.sh - Script to start SDL Manager -set -euo pipefail - -use_systemd() { - # Check if systemd user mode is available and service exists - if systemctl --user status >/dev/null 2>&1; then - # Check if our service file exists - if systemctl --user list-unit-files | grep -q "^sdl-mgr.service"; then - return 0 # Use systemd - fi - fi - return 1 # Use manual scripts -} - -# Get $SDL_HOME directory from SCRIPT PATH -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -SDL_HOME="$(cd "$SCRIPT_DIR/.." && pwd)" - -if use_systemd; then - # Systemd mode - let systemd handle it - echo "Starting SDL Manager (systemd)..." - systemctl --user start sdl-mgr - exit 0 -fi - -# Manual mode - continue with checks -NODE_BIN_DIR="${SDL_HOME}/nodejs/current/bin" -NODE_BIN="${NODE_BIN_DIR}/node" -NPM_BIN="${NODE_BIN_DIR}/npm" - -SDL_MGR_APP_DIR="${SDL_HOME}/sdl-mgr/current/app" - -# Check that sdl-mgr is not already running -SDL_MGR_PID="" -for pid in $(pgrep -f 'node' 2>/dev/null || true); do - cwd=$(readlink /proc/$pid/cwd 2>/dev/null || true) - if [[ "$cwd" == *"sdl-mgr"* ]]; then - SDL_MGR_PID="$pid" - break - fi -done - -if [[ -n "$SDL_MGR_PID" ]]; then - echo "ERROR: SDL Manager is already running with PID ${SDL_MGR_PID}" - echo " Stop it first: ${SDL_HOME}/scripts/stop-sdl-mgr.sh" - exit 1 -fi - -# Verify paths exist -if [[ ! -f "$NODE_BIN" ]]; then - echo "ERROR: Node.js not found at: $NODE_BIN" - echo " Run install-sdl.sh first" - exit 1 -fi - -if [[ ! -d "$SDL_MGR_APP_DIR" ]]; then - echo "ERROR: SDL Manager app not found at: $SDL_MGR_APP_DIR" - echo " Run install-sdl.sh first" - exit 1 -fi - -echo "Starting SDL Manager..." -echo " App Dir: ${SDL_MGR_APP_DIR}" -echo " Node: \ No newline at end of file diff --git a/nwa/scripts/status-sdl-mgr.sh b/nwa/scripts/status-nwa.sh similarity index 52% rename from nwa/scripts/status-sdl-mgr.sh rename to nwa/scripts/status-nwa.sh index a69a4cf..bf8c1dd 100755 --- a/nwa/scripts/status-sdl-mgr.sh +++ b/nwa/scripts/status-nwa.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash -# status-sdl-mgr.sh - Script to show status of SDL Manager +# status-nwa.sh - Script to show status of NWA set -euo pipefail use_systemd() { # Check if systemd user mode is available and service exists if systemctl --user status >/dev/null 2>&1; then # Check if our service file exists - if systemctl --user list-unit-files | grep -q "^sdl-mgr.service"; then + if systemctl --user list-unit-files | grep -q "^nwa.service"; then return 0 # Use systemd fi fi @@ -14,28 +14,28 @@ use_systemd() { } if use_systemd; then - systemctl --user status sdl-mgr + systemctl --user status nwa else - # Get sdl-mgr PID - SDL_MGR_PID="" + # Get nwa PID + NWA_PID="" for pid in $(pgrep -f 'node' 2>/dev/null || true); do cwd=$(readlink /proc/$pid/cwd 2>/dev/null || true) - if [[ "$cwd" == *"sdl-mgr"* ]]; then - SDL_MGR_PID="$pid" + if [[ "$cwd" == *"nwa"* ]]; then + NWA_PID="$pid" break fi done - if [[ -z "$SDL_MGR_PID" ]]; then - echo "SDL Manager is not running" + if [[ -z "$NWA_PID" ]]; then + echo "NWA is not running" exit 0 fi # Get process uptime - PROCESS_START=$(ps -p "$SDL_MGR_PID" -o lstart= 2>/dev/null || echo "unknown") + PROCESS_START=$(ps -p "$NWA_PID" -o lstart= 2>/dev/null || echo "unknown") - echo "SDL Manager is running" - echo " PID: ${SDL_MGR_PID}" + echo "NWA is running" + echo " PID: ${NWA_PID}" echo " Started: ${PROCESS_START}" exit 0 fi \ No newline at end of file diff --git a/nwa/scripts/stop-sdl-mgr.sh b/nwa/scripts/stop-nwa.sh similarity index 52% rename from nwa/scripts/stop-sdl-mgr.sh rename to nwa/scripts/stop-nwa.sh index 454f4d8..96da4b3 100755 --- a/nwa/scripts/stop-sdl-mgr.sh +++ b/nwa/scripts/stop-nwa.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash -# stop-sdl-mgr.sh - Script to stop SDL Manager +# stop-nwa.sh - Script to stop NWA set -euo pipefail use_systemd() { # Check if systemd user mode is available and service exists if systemctl --user status >/dev/null 2>&1; then # Check if our service file exists - if systemctl --user list-unit-files | grep -q "^sdl-mgr.service"; then + if systemctl --user list-unit-files | grep -q "^nwa.service"; then return 0 # Use systemd fi fi @@ -15,51 +15,51 @@ use_systemd() { if use_systemd; then # Systemd mode - let systemd handle it - echo "Stopping SDL Manager (systemd)..." - systemctl --user stop sdl-mgr --quiet 2>/dev/null || true - echo "SDL Manager stopped" + echo "Stopping NWA (systemd)..." + systemctl --user stop nwa --quiet 2>/dev/null || true + echo "NWA stopped" exit 0 fi # Manual mode - find and kill process -SDL_MGR_PID="" +NWA_PID="" for pid in $(pgrep -f 'node' 2>/dev/null || true); do cwd=$(readlink /proc/$pid/cwd 2>/dev/null || true) - if [[ "$cwd" == *"sdl-mgr"* ]]; then - SDL_MGR_PID="$pid" + if [[ "$cwd" == *"nwa"* ]]; then + NWA_PID="$pid" break fi done -if [[ -z "$SDL_MGR_PID" ]]; then - echo "SDL Manager is not running" +if [[ -z "$NWA_PID" ]]; then + echo "NWA is not running" exit 0 fi -echo "Stopping SDL Manager (PID: ${SDL_MGR_PID})..." +echo "Stopping NWA (PID: ${NWA_PID})..." # Send SIGTERM for graceful shutdown -kill "$SDL_MGR_PID" +kill "$NWA_PID" # Wait up to 10 seconds for process to exit for i in {1..10}; do - if ! kill -0 "$SDL_MGR_PID" 2>/dev/null; then - echo "SDL Manager stopped successfully" + if ! kill -0 "$NWA_PID" 2>/dev/null; then + echo "NWA stopped successfully" exit 0 fi sleep 1 done # If still running after 10 seconds, force kill -if kill -0 "$SDL_MGR_PID" 2>/dev/null; then +if kill -0 "$NWA_PID" 2>/dev/null; then echo "WARNING: Graceful shutdown failed, forcing kill..." - kill -9 "$SDL_MGR_PID" + kill -9 "$NWA_PID" sleep 1 - if kill -0 "$SDL_MGR_PID" 2>/dev/null; then - echo "ERROR: Failed to stop SDL Manager" + if kill -0 "$NWA_PID" 2>/dev/null; then + echo "ERROR: Failed to stop NWA" exit 1 fi fi -echo "SDL Manager stopped" \ No newline at end of file +echo "NWA stopped" \ No newline at end of file diff --git a/tools/udp-bcast-listen.py b/tools/udp-bcast-listen.py deleted file mode 100644 index 7771f2a..0000000 --- a/tools/udp-bcast-listen.py +++ /dev/null @@ -1,33 +0,0 @@ -import socket -import sys - -def main(): - if len(sys.argv) != 2: - print("Usage: python udp_listener.py ") - return - - port = int(sys.argv[1]) - - # Create a datagram socket - try: - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - except socket.error as msg: - print('Failed to create socket. ' + str(msg)) - return - - # Enable broadcasting mode - sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - - try: - # Bind the socket to a specific port - sock.bind(('', port)) - except socket.error as msg: - print('Bind failed. ' + str(msg)) - return - - while True: - data, addr = sock.recvfrom(1024) - print(data.decode()) - -if __name__ == "__main__": - main()