From 6e9e4f7ae1db3a83ba9e147e320f1aaa6499de70 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 15 Jan 2024 07:35:36 +0100 Subject: [PATCH] Add swap file adjustment for webapp build (#2204) * adjust swapfile if memory is too low * add option for webapp build * update ci tests * Update run_install_webapp_local.sh * update ENABLE_WEBAPP_BUILD handling * updated logging * add build webapp test workflow * fix path * fix actions * fix: add shell * fix trigger path * adjust node mem calculation leave enough memory for the system. increase swap with min size * use shell script for builds * add env CI * use new action for release build * adjusted min sizes * remove obsolete code * update workflow name * move update dependencies entirely to rebuild script. update docs * move existing build folder to backup. update docs * increase swap with lower step size. minor fixes * refactor vars and logging. added verbose param. * update logging * fix indentation * update logging. moved NODEMEM check * refactor webapp build during installation removed unneccessay vars (only use ENABLE_WEBAPP_PROD_DOWNLOAD). trimmed webapp build option. updated messages. harmonized var access and queries * Update docs * Update messages * harmonize webapp wording * fix flake8 * fix flake8 * update node installation. update node version for armv6. use recommended setup from nodesource. removed update version on new installation run. * update docs * ci add platform linux/armv6 (deactivated) * reverted to https://deb.nodesource.com/ installation * update docs * align fin message * Update docs. Remove full URL references to branch * ignore stderr if node is not installed before * ignore stderr if node is not installed before * bugfix. removed additional char * add npm project config better network handling especially for armv6l devices * use performance optimized install command update warning for armv6l devices * Update docs Update installation steps. split for version. add tip from installation- Add webapp doc for developers. update docs and link to new webapp doc. eliminate duplications. merged developer-issues into new webapp doc * also raise fetch-retry-mintimeout * update docs harmonize wording for webapp. add build output. change ARMv6 installation note. * add note for webserver restart * update installation docs. add bullet list * change npm config values * show "slow hardware message" at installation start * update armv6l warning for webapp rebuild * make script return value more clear * Make local webapp build an optional step due to unpredictable npm connection errors. Show webapp fin message only if webapp build fails * use prebuilt webapp bundle also for develop * update docs * Update webapp.md * Update customize_options.sh (typos) * Update installation.md * Update system.md * Update installation.md * Update webapp.md * Update customize_options.sh * change npm config values * update docs * update welcome to match changes in wiki * update rebuild message * Add doc links * update ignorefiles for build.bak * Update doc and link for constributors * Update CONTRIBUTING.md --------- Co-authored-by: pabera <1260686+pabera@users.noreply.github.com> --- .dockerignore | 1 + .githooks/post-merge | 6 +- .github/actions/build-webapp/action.yml | 25 +++ .../bundle_webapp_and_release_v3.yml | 28 +-- .github/workflows/test_build_webapp_v3.yml | 33 ++++ .../test_docker_debian_codename_sub_v3.yml | 9 +- .github/workflows/test_docker_debian_v3.yml | 16 ++ CONTRIBUTING.md | 37 ++-- ci/installation/run_install_common.sh | 2 +- ci/installation/run_install_faststartup.sh | 2 +- ci/installation/run_install_libzmq_local.sh | 2 +- .../run_install_webapp_download.sh | 4 +- ci/installation/run_install_webapp_local.sh | 4 +- documentation/builders/autohotspot.md | 8 +- documentation/builders/concepts.md | 2 +- documentation/builders/installation.md | 38 +++- documentation/builders/system.md | 6 +- documentation/builders/update.md | 2 +- documentation/developers/README.md | 1 + documentation/developers/developer-issues.md | 86 -------- .../developers/development-environment.md | 32 +-- documentation/developers/docker.md | 4 +- documentation/developers/status.md | 2 +- documentation/developers/webapp.md | 149 ++++++++++++++ installation/includes/00_constants.sh | 3 + installation/includes/01_default_config.sh | 4 +- installation/includes/02_helpers.sh | 11 ++ installation/includes/03_welcome.sh | 14 +- installation/includes/05_finish.sh | 2 +- installation/routines/customize_options.sh | 46 ++--- installation/routines/install.sh | 1 + installation/routines/setup_jukebox_core.sh | 13 -- installation/routines/setup_jukebox_webapp.sh | 143 +++++++++----- resources/default-settings/gpio.example.yaml | 2 +- resources/html/404.html | 2 +- resources/html/runbuildui.html | 8 +- src/jukebox/components/playermpd/__init__.py | 9 +- src/webapp/.gitignore | 3 + src/webapp/.npmrc | 3 + src/webapp/public/index.html | 2 +- src/webapp/run_rebuild.sh | 187 ++++++++++++------ 41 files changed, 585 insertions(+), 367 deletions(-) create mode 100644 .github/actions/build-webapp/action.yml create mode 100644 .github/workflows/test_build_webapp_v3.yml delete mode 100644 documentation/developers/developer-issues.md create mode 100644 documentation/developers/webapp.md create mode 100644 src/webapp/.npmrc diff --git a/.dockerignore b/.dockerignore index a587de477..da30b5a97 100644 --- a/.dockerignore +++ b/.dockerignore @@ -14,3 +14,4 @@ shared src/webapp/node_modules src/webapp/npm-debug.log src/webapp/build +src/webapp/build.bak diff --git a/.githooks/post-merge b/.githooks/post-merge index 3b838c87c..6fc6e4f54 100755 --- a/.githooks/post-merge +++ b/.githooks/post-merge @@ -5,7 +5,7 @@ # TO ACTIVATE: cp .githooks/post-merge .git/hooks/. # # Checks: -# - Changes to web app +# - Changes to Web App # - Changes to web dependency # - Changes to python requirements # @@ -20,7 +20,7 @@ warn_npm_dependency() { echo "************************************************************" echo "ATTENTION: npm dependencies have changed since last pull!" echo "" - echo "To update dependencies and rebuilt WebApp run:" + echo "To update dependencies and rebuilt Web App run:" echo "$ cd src/webapp && ./run_rebuild.sh -u" echo "************************************************************" echo -e "\n" @@ -31,7 +31,7 @@ warn_webapp() { echo "************************************************************" echo "ATTENTION: Web App sources have changed since last pull!" echo "" - echo "To rebuilt the WebApp run:" + echo "To rebuilt the Web App run:" echo "$ cd src/webapp && ./run_rebuild.sh" echo "************************************************************" echo -e "\n" diff --git a/.github/actions/build-webapp/action.yml b/.github/actions/build-webapp/action.yml new file mode 100644 index 000000000..9f192105f --- /dev/null +++ b/.github/actions/build-webapp/action.yml @@ -0,0 +1,25 @@ +name: Build Web App +description: 'Build Web App with Node' +inputs: + webapp-root-path: + description: 'root path of the Web App sources' + required: false + default: './src/webapp' +outputs: + webapp-root-path: + description: 'used root path of the Web App sources' + value: ${{ inputs.webapp-root-path }} + +runs: + using: "composite" + steps: + - name: Setup Node.js 20.x + uses: actions/setup-node@v3 + with: + node-version: 20.x + - name: run build + working-directory: ${{ inputs.webapp-root-path }} + shell: bash + env: + CI: false + run: ./run_rebuild.sh -u \ No newline at end of file diff --git a/.github/workflows/bundle_webapp_and_release_v3.yml b/.github/workflows/bundle_webapp_and_release_v3.yml index 548f2b47a..13bffe472 100644 --- a/.github/workflows/bundle_webapp_and_release_v3.yml +++ b/.github/workflows/bundle_webapp_and_release_v3.yml @@ -1,4 +1,4 @@ -name: Bundle Webapp and Release +name: Bundle Web App and Release on: push: @@ -18,7 +18,7 @@ jobs: check_abort: ${{ steps.vars.outputs.check_abort }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set Output vars id: vars @@ -72,9 +72,6 @@ jobs: if: ${{ needs.check.outputs.check_abort == 'false' }} runs-on: ubuntu-latest - env: - WEBAPP_ROOT_PATH: ./src/webapp - outputs: tag_name: ${{ needs.check.outputs.tag_name }} release_type: ${{ needs.check.outputs.release_type }} @@ -83,7 +80,7 @@ jobs: webapp_bundle_name_latest: ${{ steps.vars.outputs.webapp_bundle_name_latest }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set Output vars id: vars @@ -94,21 +91,12 @@ jobs: echo "webapp_bundle_name=webapp-build-${COMMIT_SHA:0:10}.tar.gz" >> $GITHUB_OUTPUT echo "webapp_bundle_name_latest=webapp-build-latest.tar.gz" >> $GITHUB_OUTPUT - - name: Setup Node.js 20.x - uses: actions/setup-node@v3 - with: - node-version: 20.x - - name: npm install - working-directory: ${{ env.WEBAPP_ROOT_PATH }} - run: npm install - - name: npm build - working-directory: ${{ env.WEBAPP_ROOT_PATH }} - env: - CI: false - run: npm run build + - name: Build Web App + id: build-webapp + uses: ./.github/actions/build-webapp - name: Create Bundle - working-directory: ${{ env.WEBAPP_ROOT_PATH }} + working-directory: ${{ steps.build-webapp.outputs.webapp-root-path }} run: | tar -czvf ${{ steps.vars.outputs.webapp_bundle_name }} build @@ -116,7 +104,7 @@ jobs: uses: actions/upload-artifact@v3 with: name: ${{ steps.vars.outputs.webapp_bundle_name }} - path: ${{ env.WEBAPP_ROOT_PATH }}/${{ steps.vars.outputs.webapp_bundle_name }} + path: ${{ steps.build-webapp.outputs.webapp-root-path }}/${{ steps.vars.outputs.webapp_bundle_name }} retention-days: 5 release: diff --git a/.github/workflows/test_build_webapp_v3.yml b/.github/workflows/test_build_webapp_v3.yml new file mode 100644 index 000000000..426d01f04 --- /dev/null +++ b/.github/workflows/test_build_webapp_v3.yml @@ -0,0 +1,33 @@ +name: Test Build Web App v3 + +on: + schedule: + # run at 18:00 every sunday + - cron: '0 18 * * 0' + push: + branches: + - 'future3/**' + paths: + - '.github/workflows/test_build_webapp_v3.yml' + - '.github/actions/build-webapp/**' + - 'src/webapp/**' + pull_request: + # The branches below must be a subset of the branches above + branches: + - future3/develop + - future3/main + paths: + - '.github/workflows/test_build_webapp_v3.yml' + - '.github/actions/build-webapp/**' + - 'src/webapp/**' + +jobs: + + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Build Web App + uses: ./.github/actions/build-webapp \ No newline at end of file diff --git a/.github/workflows/test_docker_debian_codename_sub_v3.yml b/.github/workflows/test_docker_debian_codename_sub_v3.yml index dde60cb2a..a9ec217dc 100644 --- a/.github/workflows/test_docker_debian_codename_sub_v3.yml +++ b/.github/workflows/test_docker_debian_codename_sub_v3.yml @@ -1,4 +1,4 @@ -name: Subworkflow Test Install Scripts Debian V3 +name: Subworkflow Test Install Scripts Debian v3 on: workflow_call: @@ -46,6 +46,7 @@ jobs: cache_key: ${{ steps.vars.outputs.cache_key }} image_file_name: ${{ steps.vars.outputs.image_file_name }} image_tag_name: ${{ steps.vars.outputs.image_tag_name }} + docker_run_options: ${{ steps.vars.outputs.docker_run_options }} # create local docker registry to use locally build images services: @@ -83,6 +84,7 @@ jobs: id: vars env: LOCAL_REGISTRY_PORT: ${{ inputs.local_registry_port }} + PLATFORM: ${{ inputs.platform }} run: | echo "image_tag_name=${{ steps.pre-vars.outputs.image_tag_name }}" >> $GITHUB_OUTPUT echo "image_tag_name_local_base=localhost:${{ env.LOCAL_REGISTRY_PORT }}/${{ steps.pre-vars.outputs.image_tag_name }}-base" >> $GITHUB_OUTPUT @@ -90,6 +92,9 @@ jobs: echo "image_file_path=./${{ steps.pre-vars.outputs.image_file_name }}" >> $GITHUB_OUTPUT echo "cache_scope=${{ steps.pre-vars.outputs.cache_scope }}" >> $GITHUB_OUTPUT echo "cache_key=${{ steps.pre-vars.outputs.cache_scope }}-${{ github.sha }}#${{ github.run_attempt }}" >> $GITHUB_OUTPUT + if [ "${{ env.PLATFORM }}" == "linux/arm/v6" ] ; then + echo "docker_run_options=-e QEMU_CPU=arm1176" >> $GITHUB_OUTPUT + fi # Build base image for debian version name. Layers will be cached and image pushes to local registry - name: Build Image - Base @@ -167,7 +172,7 @@ jobs: uses: tj-actions/docker-run@v2 with: image: ${{ needs.build.outputs.image_tag_name }} - options: --platform ${{ inputs.platform }} --user ${{ env.TEST_USER_NAME }} --init + options: ${{ needs.build.outputs.docker_run_options }} --platform ${{ inputs.platform }} --user ${{ env.TEST_USER_NAME }} --init name: ${{ matrix.test_script }} args: | ./${{ matrix.test_script }} diff --git a/.github/workflows/test_docker_debian_v3.yml b/.github/workflows/test_docker_debian_v3.yml index 06718afba..673745db9 100644 --- a/.github/workflows/test_docker_debian_v3.yml +++ b/.github/workflows/test_docker_debian_v3.yml @@ -45,9 +45,25 @@ jobs: debian_codename: 'bookworm' platform: linux/arm/v7 + # # can be activate on test branches, currently failing + # run_bookworm_armv6: + # name: 'bookworm armv6' + # uses: ./.github/workflows/test_docker_debian_codename_sub_v3.yml + # with: + # debian_codename: 'bookworm' + # platform: linux/arm/v6 + run_bullseye_armv7: name: 'bullseye armv7' uses: ./.github/workflows/test_docker_debian_codename_sub_v3.yml with: debian_codename: 'bullseye' platform: linux/arm/v7 + + # # can be activate on test branches, currently failing + # run_bullseye_armv6: + # name: 'bullseye armv6' + # uses: ./.github/workflows/test_docker_debian_codename_sub_v3.yml + # with: + # debian_codename: 'bullseye' + # platform: linux/arm/v6 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dbf12f84d..f4ac9cd16 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -45,12 +45,17 @@ as local, temporary scratch areas. Contributors have played a bigger role over time to keep Phoniebox on the edge of innovation :) -We want to keep it as easy as possible to contribute changes that get things working in your environment. -There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things. +Our goal is to make it simple for you to contribute changes that improve functionality in your specific environment. +To achieve this, we have a set of guidelines that we kindly request contributors to adhere to. +These guidelines help us maintain a streamlined process and stay on top of incoming contributions. -Development for Version 3 is done on the git branch `future3/develop`. How to move to that branch, see below. +To report bug fixes and improvements, please follow the steps outlined below: +1. For bug fixes and minor improvements, simply open a new issue or pull request (PR). +2. If you intend to port a feature from Version 2.x to future3 or wish to implement a new feature, we recommend reaching out to us beforehand. + - In such cases, please create an issue outlining your plans and intentions. + - We will ensure that there are no ongoing efforts on the same topic. -For bug fixes and improvements just open an issue or PR as described below. If you plan to port a feature from Version 2.X or implement a new feature, it is advisable to contact us first. In this case, also open an issue describing what you are planning to do. We will just check that nobody else is already on the subject. We are looking forward to your work. Check the current [feature list](https://rpi-jukebox-rfid.readthedocs.io/en/latest/featurelist.html) for available features and work in progress. +We eagerly await your contributions! You can review the current [feature list](documentation/developers/status.md) to check for available features and ongoing work. ## Getting Started @@ -60,31 +65,21 @@ For bug fixes and improvements just open an issue or PR as described below. If y Version 2 will continue to live for quite a while. * Clearly describe the issue including steps to reproduce when it is a bug * Make sure you fill in the earliest version that you know has the issue -* By default this will get you to the `future3/main` branch. You will move to the `future3/develop` branch, do this: - -~~~bash -cd ~/RPi-Jukebox-RFID -git checkout future3/develop -git fetch origin -git reset --hard origin/future3/develop -git pull -~~~ The preferred way of code contributions are [pull requests (follow this link for a small howto)](https://www.digitalocean.com/community/tutorials/how-to-create-a-pull-request-on-github). -And, ideally pull requests use the "running code" on the `future3/develop` branch of your Phoniebox. +And ideally pull requests use the "running code" of your Phoniebox. Alternatively, feel free to post tweaks, suggestions and snippets in the ["issues" section](https://github.com/MiczFlor/RPi-Jukebox-RFID/issues). ## Making Changes +* Create a fork of this repository * Create a topic branch from where you want to base your work. - * This is usually the master branch or the develop branch. - * Only target release branches if you are certain your fix must be on that + * This is usually the `future3/develop` branch. + * Only target the `future3/main` branch if you are certain your fix must be on that branch. - * To quickly create a topic branch based on master, run `git checkout -b - fix/master/my_contribution master`. Please avoid working directly on the - `master` branch. * Make commits of logical and atomic units. * Check for unnecessary whitespace with `git diff --check` before committing. +* See also the [documentation for developers](documentation/developers/README.md) ## Making Trivial Changes @@ -168,8 +163,8 @@ The original contributor will be notified of the revert. ## Guidelines -* Phoniebox runs on Raspian **Buster**. Therefore, all Python code should work at least with **Python 3.7**. -* For GPIO all code should work with **RPi.GPIO**. gpiozero is currently not intended to use. +* Phoniebox runs on Raspberry Pi OS. +* Minimum python version is currently **Python 3.9**. ## Additional Resources diff --git a/ci/installation/run_install_common.sh b/ci/installation/run_install_common.sh index 3d4c59778..b8c641580 100644 --- a/ci/installation/run_install_common.sh +++ b/ci/installation/run_install_common.sh @@ -24,7 +24,7 @@ export ENABLE_WEBAPP_PROD_DOWNLOAD=true # n - setup rfid reader # y - setup samba # y - setup webapp -# - - install node (forced WebApp Download) +# - - build webapp (skipped due to forced webapp Download) # n - setup kiosk mode # n - reboot diff --git a/ci/installation/run_install_faststartup.sh b/ci/installation/run_install_faststartup.sh index 249d78ffc..134aeca71 100644 --- a/ci/installation/run_install_faststartup.sh +++ b/ci/installation/run_install_faststartup.sh @@ -22,7 +22,7 @@ LOCAL_INSTALL_SCRIPT_PATH="${LOCAL_INSTALL_SCRIPT_PATH%/}" # n - setup rfid reader # n - setup samba # n - setup webapp -# - - install node (only with webapp = y) +# - - build webapp (only with webapp = y) # - - setup kiosk mode (only with webapp = y) # n - reboot diff --git a/ci/installation/run_install_libzmq_local.sh b/ci/installation/run_install_libzmq_local.sh index aa3726b2f..335cb24a1 100644 --- a/ci/installation/run_install_libzmq_local.sh +++ b/ci/installation/run_install_libzmq_local.sh @@ -23,7 +23,7 @@ export BUILD_LIBZMQ_WITH_DRAFTS_ON_DEVICE=true # n - setup rfid reader # n - setup samba # n - setup webapp -# - - install node (only with webapp = y) +# - - build webapp (only with webapp = y) # - - setup kiosk mode (only with webapp = y) # n - reboot diff --git a/ci/installation/run_install_webapp_download.sh b/ci/installation/run_install_webapp_download.sh index 698e057b9..ded27ec54 100644 --- a/ci/installation/run_install_webapp_download.sh +++ b/ci/installation/run_install_webapp_download.sh @@ -4,7 +4,7 @@ # Used e.g. for tests on Docker # Objective: -# Test for the WebApp (download) and dependent features path. +# Test for the Web App (download) and dependent features path. SOURCE="${BASH_SOURCE[0]}" SCRIPT_DIR="$(dirname "$SOURCE")" @@ -22,7 +22,7 @@ LOCAL_INSTALL_SCRIPT_PATH="${LOCAL_INSTALL_SCRIPT_PATH%/}" # n - setup rfid reader # n - setup samba # y - setup webapp -# n - install node +# n - build webapp # y - setup kiosk mode # n - reboot diff --git a/ci/installation/run_install_webapp_local.sh b/ci/installation/run_install_webapp_local.sh index 917f985af..7af16df3a 100644 --- a/ci/installation/run_install_webapp_local.sh +++ b/ci/installation/run_install_webapp_local.sh @@ -4,7 +4,7 @@ # Used e.g. for tests on Docker # Objective: -# Test for the WebApp (build locally) and dependent features path. +# Test for the Web App (build locally) and dependent features path. SOURCE="${BASH_SOURCE[0]}" SCRIPT_DIR="$(dirname "$SOURCE")" @@ -23,7 +23,7 @@ export ENABLE_WEBAPP_PROD_DOWNLOAD=false # n - setup rfid reader # n - setup samba # y - setup webapp -# y - install node +# y - build webapp # y - setup kiosk mode # n - reboot diff --git a/documentation/builders/autohotspot.md b/documentation/builders/autohotspot.md index 69e6f4d6a..ecf996f81 100644 --- a/documentation/builders/autohotspot.md +++ b/documentation/builders/autohotspot.md @@ -2,7 +2,7 @@ The Auto-Hotspot function allows the Jukebox to switch between its connection between a known WiFi and an automatically generated hotspot -so that you can still access via SSH or Webapp. +so that you can still access via SSH or Web App. > [!IMPORTANT] > Please configure the WiFi connection to your home access point before enabling these feature! @@ -17,10 +17,10 @@ hotspot named `Phoniebox_Hotspot`. You will be able to connect to this hotspot using the given password in the installation or the default password: `PlayItLoud!` -### Webapp +### Web App After connecting to the `Phoniebox_Hotspot` you are able to connect to -the webapp accessing the website [10.0.0.5](http://10.0.0.5/). +the Web App accessing the website [10.0.0.5](http://10.0.0.5/). ### ssh @@ -69,7 +69,7 @@ ieee80211d=1 ## Disabling automatism -Auto-Hotspot can be enabled or disabled using the Webapp. +Auto-Hotspot can be enabled or disabled using the Web App. > [!IMPORTANT] > Disabling or enabling will keep the last state. diff --git a/documentation/builders/concepts.md b/documentation/builders/concepts.md index 37c13db89..0a4305cfe 100644 --- a/documentation/builders/concepts.md +++ b/documentation/builders/concepts.md @@ -12,7 +12,7 @@ The core app is centered around a plugin concept. This serves three purposes: ## Remote Procedure Call Server (RPC) -The Remote Procedure Call (RPC) server allows remotely triggering actions (e.g., from the Webapp) within the Jukebox core application. Only Python functions registered by the plugin interface can be called. This simplifies external APIs and lets us focus on the relevant user functions. +The Remote Procedure Call (RPC) server allows remotely triggering actions (e.g., from the Web App) within the Jukebox core application. Only Python functions registered by the plugin interface can be called. This simplifies external APIs and lets us focus on the relevant user functions. Why should you care? Because we use the same protocol when triggering actions from other inputs like a card swipe, a GPIO button press, etc. How that works is described in [RPC Commands](rpc-commands.md). diff --git a/documentation/builders/installation.md b/documentation/builders/installation.md index 945368480..7ce0e59c0 100644 --- a/documentation/builders/installation.md +++ b/documentation/builders/installation.md @@ -3,7 +3,7 @@ ## Install Raspberry Pi OS Lite > [!IMPORTANT] -> Currently, the installation does only work on Raspberry Pi's with ARMv7 and ARMv8 architecture, so 2, 3 and 4! Pi 1 and Zero's are currently unstable and will require a bit more work! Pi 4 and 5 are an excess ;-) +> All Raspberry Pi models are supported. For sufficient performance, **we recommend Pi 2, 3 or Zero 2** (`ARMv7` models). Because Pi 1 or Zero 1 (`ARMv6` models) have limited resources, they are slower (during installation and start up procedure) and might require a bit more work! Pi 4 and 5 are an excess ;-) Before you can install the Phoniebox software, you need to prepare your Raspberry Pi. @@ -79,30 +79,48 @@ You will need a terminal, like PuTTY for Windows or the Terminal app for Mac to ## Install Phoniebox software -Run the following command in your SSH terminal and follow the instructions +Choose a version, run the corresponding install command in your SSH terminal and follow the instructions. +* [Stable Release](#stable-release) +* [Pre-Release](#pre-release) +* [Development](#development) + +After a successful installation, [configure your Phoniebox](configuration.md). + +> [!TIP] +> Depending on your hardware, this installation might last around 60 minutes (usually it's faster, 20-30 min). It updates OS packages, installs Phoniebox dependencies and applies settings. Be patient and don't let your computer go to sleep. It might disconnect your SSH connection causing the interruption of the installation process. Consider starting the installation in a terminal multiplexer like 'screen' or 'tmux' to avoid this. + +### Stable Release +This will install the latest **stable release** from the *future3/main* branch. ```bash cd; bash <(wget -qO- https://raw.githubusercontent.com/MiczFlor/RPi-Jukebox-RFID/future3/main/installation/install-jukebox.sh) ``` -This will get the latest **stable release** from the branch *future3/main*. +### Pre-Release +This will install the latest **pre-release** from the *future3/develop* branch. -To install directly from a specific branch and/or a different repository -specify the variables like this: +```bash +cd; GIT_BRANCH='future3/develop' bash <(wget -qO- https://raw.githubusercontent.com/MiczFlor/RPi-Jukebox-RFID/future3/develop/installation/install-jukebox.sh) +``` + +### Development +You can also install a specific branch and/or a fork repository. Update the variables to refer to your desired location. (The URL must not necessarily be updated, unless you have actually updated the file being downloaded.) + +> [!IMPORTANT] +> A fork repository must be named '*RPi-Jukebox-RFID*' like the official repository ```bash cd; GIT_USER='MiczFlor' GIT_BRANCH='future3/develop' bash <(wget -qO- https://raw.githubusercontent.com/MiczFlor/RPi-Jukebox-RFID/future3/develop/installation/install-jukebox.sh) ``` -This will switch directly to the specified feature branch during installation. - > [!NOTE] -> For all branches *except* the current Release future3/main, you will need to build the Web App locally on the Pi. This is not part of the installation process due to memory limitation issues. See [Developer steps to install](../developers/development-environment.md#steps-to-install) +> The Installation of the official repository's release branches ([Stable Release](#stable-release) and [Pre-Release](#pre-release)) will deploy a pre-build bundle of the Web App. +> If you install another branch or from a fork repository, the Web App needs to be built locally. This is part of the installation process. See the the developers [Web App](../developers/webapp.md) documentation for further details. -If you suspect an error you can monitor the installation-process with +### Logs +To follow the installation closely, use this command in another terminal. ```bash cd; tail -f INSTALL-.log ``` -After successful installation, continue with [configuring your Phoniebox](configuration.md). diff --git a/documentation/builders/system.md b/documentation/builders/system.md index 2f7df8888..f6eeb7ba1 100644 --- a/documentation/builders/system.md +++ b/documentation/builders/system.md @@ -7,7 +7,7 @@ The system consists of 1. [Music Player Daemon (MPD)](system.md#music-player-daemon-mpd) which we use for all music playback (local, stream, podcast, ...) 2. [PulseAudio](system.md#pulseaudio) for flexible audio output support 3. [Jukebox Core Service](system.md#jukebox-core-service) for controlling MPD and PulseAudio and providing all the features -4. [Web UI](system.md#web-ui) which is served through an Nginx web server +4. [Web App](system.md#web-app-ui) as User Interface (UI) for a web browser 5. A set of [Configuration Tools](../developers/coreapps.md#configuration-tools) and a set of [Developer Tools](../developers/coreapps.md#developer-tools) > [!NOTE] The default install puts everything into the users home folder `~/RPi-Jukebox-RFID`. @@ -96,9 +96,9 @@ The `systemd` service file is located at the default location for user services: Starting and stopping the service can be useful for debugging or configuration checks. -## Web UI +## Web App (UI) -The Web UI is served using nginx. Nginx runs as a system service. The home directory is localed at +The [Web App](../developers/webapp.md) is served using nginx. Nginx runs as a system service. The home directory is located at ```text ./src/webapp/build diff --git a/documentation/builders/update.md b/documentation/builders/update.md index f6dab2c91..94baf0a93 100644 --- a/documentation/builders/update.md +++ b/documentation/builders/update.md @@ -29,7 +29,7 @@ $ git pull $ diff shared/settings/jukebox.yaml resources/default-settings/jukebox.default.yaml $ cd src/webapp -$ ./run_rebuild.sh +$ ./run_rebuild.sh -u ``` ## Migration Path from Version 2 diff --git a/documentation/developers/README.md b/documentation/developers/README.md index 64fee44c1..cfa389713 100644 --- a/documentation/developers/README.md +++ b/documentation/developers/README.md @@ -8,6 +8,7 @@ ## Reference * [Jukebox Apps](./coreapps.md) +* [Web App](./webapp.md) * [RFID Readers](./rfid) * [Feature Status](./status.md) * [Known Issues](./known-issues.md) diff --git a/documentation/developers/developer-issues.md b/documentation/developers/developer-issues.md deleted file mode 100644 index bcb4d491a..000000000 --- a/documentation/developers/developer-issues.md +++ /dev/null @@ -1,86 +0,0 @@ -# Developer Issues - -## Building the Webapp on the PI - -### JavaScript heap out of memory - -While (re-) building the Web App, you get the following output: - -``` {.bash emphasize-lines="12"} -pi@MusicPi:~/RPi-Jukebox-RFID/src/webapp $ npm run build - -> webapp@0.1.0 build -> react-scripts build - -Creating an optimized production build... - -[...] - -<--- JS stacktrace ---> - -FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory -``` - -#### Reason - -Not enough memory for Node - -#### Solution - -Prior to building set the node memory environment variable. - -1. Make sure the value is less than the total available space on the - system, or you may run into the next issue. (Not always though!) - Check memory availability with `free -mt`. -2. We also experience trouble, when the space is set too small a - value. 512 always works, 256 sometimes does, sometimes does not. - If your free memory is small, consider increasing the swap size of - your system! - -``` bash -export NODE_OPTIONS=--max-old-space-size=512 -npm run build -``` - -Alternatively, use the provided script, which sets the variable for you -(provided your swap size is large enough): - -``` bash -$ cd src/webapp -$ ./run_rebuild.sh -``` - -#### Changing Swap Size - -This will set the swapsize to 1024 MB (and will deactivate swapfactor). Change accordingly if you have a SD Card with small capacity. - -```bash -sudo dphys-swapfile swapoff -sudo sed -i "s|.*CONF_SWAPSIZE=.*|CONF_SWAPSIZE=1024|g" /etc/dphys-swapfile -sudo sed -i "s|^\s*CONF_SWAPFACTOR=|#CONF_SWAPFACTOR=|g" /etc/dphys-swapfile -sudo dphys-swapfile setup -sudo dphys-swapfile swapon -``` - -### Process exited too early // kill -9 - -``` {.bash emphasize-lines="8,9"} -pi@MusicPi:~/RPi-Jukebox-RFID/src/webapp $ npm run build - -> webapp@0.1.0 build -> react-scripts build - -... - -The build failed because the process exited too early. -This probably means the system ran out of memory or someone called 'kill -9' on the process. -``` - -#### Reason - -Node tried to allocate more memory than available on the system. - -#### Solution - -Adjust the node memory variable as described in [JavaScript heap out of memory](#javascript-heap-out-of-memory). But make sure to allocate less memory than the available memory. If that is not sufficient, increase the swap file size of your -system and try again. diff --git a/documentation/developers/development-environment.md b/documentation/developers/development-environment.md index 249f6263c..d2d995919 100644 --- a/documentation/developers/development-environment.md +++ b/documentation/developers/development-environment.md @@ -1,6 +1,6 @@ # Development Environment -You have 3 development options. Each option has its pros and cons. To interact with GPIO or other hardware, it's required to develop directly on a Raspberry Pi. For general development of Python code (Jukebox) or JavaScript (Webapp), we recommend Docker. Developing on your local machine (Linux, Mac, Windows) works as well and requires all dependencies to be installed locally. +You have 3 development options. Each option has its pros and cons. To interact with GPIO or other hardware, it's required to develop directly on a Raspberry Pi. For general development of Python code (Jukebox) or JavaScript (Web App), we recommend Docker. Developing on your local machine (Linux, Mac, Windows) works as well and requires all dependencies to be installed locally. - [Development Environment](#development-environment) - [Develop in Docker](#develop-in-docker) @@ -15,35 +15,15 @@ There is a complete [Docker setup](./docker.md). ## Develop on Raspberry Pi -The full setup is running on the RPi and you access files via SSH. Pretty easy to set up as you simply do a normal install and switch to the `future3/develop` branch. +The full setup is running on the RPi and you access files via SSH. ### Steps to install -We recommend to use at least a Pi 3 or Pi Zero 2 for development. This hardware won\'t be needed in production, but it can be slow while developing. +We recommend to use at least a Pi 3 or Pi Zero 2 for development. While this hardware won\'t be needed in production, it comes in helpful while developing. -1. Install the latest Pi OS on a SD card. -2. Boot up your Raspberry Pi. -3. [Install](../builders/installation.md) the Jukebox software as if you were building a Phoniebox. You can install from your own fork and feature branch you wish which can be changed later as well. The original repository will be set as `upstream`. -4. Once the installation has successfully ran, reboot your Pi. -5. Due to some resource constraints, the Webapp does not build the latest changes and instead consumes the latest official release. To change that, you need to install NodeJS and build the Webapp locally. -6. Install NodeJS using the existing installer - - ``` bash - cd ~/RPi-Jukebox-RFID/installation/routines; \ - source setup_jukebox_webapp.sh; \ - _jukebox_webapp_install_node - ``` - -7. To free up RAM, reboot your Pi. -8. Build the Webapp using the existing build command. If the build fails, you might have forgotten to reboot. - - ``` bash - cd ~/RPi-Jukebox-RFID/src/webapp; \ - ./run_rebuild.sh -u - ``` - -9. The Webapp should now be updated. -10. To continuously update Webapp, pull the latest changes from your repository and rerun the command above. +1. Follow the [installation preperation](../builders/installation.md#install-raspberry-pi-os-lite) steps +1. [Install](../builders/installation.md#development) your feature/fork branch of the Jukebox software. The official repository will be set as `upstream`. +1. If neccessary [build the Web App](./webapp.md) locally ## Develop on local machine diff --git a/documentation/developers/docker.md b/documentation/developers/docker.md index 80651ce84..3718373db 100644 --- a/documentation/developers/docker.md +++ b/documentation/developers/docker.md @@ -30,7 +30,7 @@ need to adapt some of those commands to your needs. $ cp ./resources/default-settings/jukebox.default.yaml ./shared/settings/jukebox.yaml ``` - * Override/Merge the values from the following [Override file](https://github.com/MiczFlor/RPi-Jukebox-RFID/blob/future3/develop/docker/config/jukebox.overrides.yaml) in your `jukebox.yaml`. + * Override/Merge the values from the following [Override file](../../docker/config/jukebox.overrides.yaml) in your `jukebox.yaml`. * **\[Currently required\]** Update all relative paths (`../..`) in to `/home/pi/RPi-Jukebox-RFID`. 4. Change directory into the `./shared/audiofolders` @@ -159,7 +159,7 @@ Read these threads for details: [thread 1](https://unix.stackexchange.com/questi The Dockerfile is defined to start all Phoniebox related services. -Open in your browser to see the web application. +Open in your browser to see the Web App. While the `webapp` container does not require a reload while working on it (hot-reload is enabled), you will have to restart your `jukebox` diff --git a/documentation/developers/status.md b/documentation/developers/status.md index 48c2b6c3b..0a40f8125 100644 --- a/documentation/developers/status.md +++ b/documentation/developers/status.md @@ -6,7 +6,7 @@ There are a few things that are specifically not integrated yet: playing streams In the following is the currently implemented feature list in more detail. It also shows some of the shortcomings. However, the list is _not complete in terms of planned features_, but probably _reflects more of where work is currently being put into_. -**For new contributors:** If you want to port a feature from version 2.X or implement a new feature, contact us. Open an issue or join us in the chat room. You may pick topics marked as open below, but also any other topic missing in the list below. As mentioned, that list is not complete in terms of open features. Check the [Contribution guide](https://github.com/MiczFlor/RPi-Jukebox-RFID/blob/future3/main/CONTRIBUTING.md). +**For new contributors:** If you want to port a feature from version 2.X or implement a new feature, contact us. Open an issue or join us in the chat room. You may pick topics marked as open below, but also any other topic missing in the list below. As mentioned, that list is not complete in terms of open features. Check the [Contribution guide](../../CONTRIBUTING.md). Topics marked _in progress_ are already in the process of implementation by community members. diff --git a/documentation/developers/webapp.md b/documentation/developers/webapp.md new file mode 100644 index 000000000..2e8504337 --- /dev/null +++ b/documentation/developers/webapp.md @@ -0,0 +1,149 @@ +# Web App + +The Web App sources are located in `src/webapp`. A pre-build bundle of the Web App is deployed when installing from an official release branch. If you install from a feature branch or a fork repository, the Web App needs to be built locally. This requires Node to be installed and is part of the installation process. + +## Install node manually + +If you installed from an official release branch, Node might not be installed. To install Node for local development, follow the [official setup](https://deb.nodesource.com/). + +``` bash +NODE_MAJOR=20 +sudo apt-get -y update && sudo apt-get -y install ca-certificates curl gnupg +sudo mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list +sudo apt-get -y update && sudo apt-get -y install nodejs +``` + +## Develop the Web App + +The Web App is a React application based on [Create React App](https://create-react-app.dev/). To start a development server, run the following command: + +``` +cd ~/RPi-Jukebox-RFID/src/webapp +npm install # Just the first time or when dependencies change +npm start +``` + +## Build the Web App + +To build your Web App after its source code has changed (e.g. through a local change or through a pull from the repository), it needs to be rebuilt manually. +Use the provided script to rebuild whenever required. The artifacts can be found in the folder `build`. + +```bash +cd ~/RPi-Jukebox-RFID/src/webapp; \ +./run_rebuild.sh -u +``` + +After a successfull build you might need to restart the web server. + +``` +sudo systemctl restart nginx.service +``` + +## Known Issues while building + +### JavaScript heap out of memory + +While (re-) building the Web App, you get the following output: + +``` {.bash emphasize-lines="12"} +> webapp@0.1.0 build +> react-scripts build + +Creating an optimized production build... + +[...] + +<--- JS stacktrace ---> + +FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory +``` + +#### Reason + +Not enough memory for Node + +#### Solution + +Use the [provided script](#build-the-web-app) to rebuild the Web App. It sets the needed node options and also checks and adjusts the swap size if there is not enough memory available. + +If you need to run the commands manually, make sure to have enough memory available (min. 512 MB). The following commands might help. + +Set the swapsize to 512 MB (and deactivate swapfactor). Adapt accordingly if you have a SD Card with small capacity. +```bash +sudo dphys-swapfile swapoff +sudo sed -i "s|.*CONF_SWAPSIZE=.*|CONF_SWAPSIZE=512|g" /etc/dphys-swapfile +sudo sed -i "s|^\s*CONF_SWAPFACTOR=|#CONF_SWAPFACTOR=|g" /etc/dphys-swapfile +sudo dphys-swapfile setup +sudo dphys-swapfile swapon +``` + +Set Node's maximum amount of memory. Memory must be available. +``` bash +export NODE_OPTIONS=--max-old-space-size=512 +npm run build +``` + +### Process exited too early // kill -9 + +``` {.bash emphasize-lines="8,9"} +> webapp@0.1.0 build +> react-scripts build + +[...] + +The build failed because the process exited too early. +This probably means the system ran out of memory or someone called 'kill -9' on the process. +``` + +#### Reason + +Node tried to allocate more memory than available on the system. + +#### Solution + +See [JavaScript heap out of memory](#javascript-heap-out-of-memory) + + +### Client network socket disconnected + +``` {.bash emphasize-lines="8,9"} +[...] + +npm ERR! code ECONNRESET +npm ERR! network Client network socket disconnected before secure TLS connection was established +npm ERR! network This is a problem related to network connectivity. +npm ERR! network In most cases you are behind a proxy or have bad network settings. +npm ERR! network +npm ERR! network If you are behind a proxy, please make sure that the +npm ERR! network 'proxy' config is set properly. See: 'npm help config' +``` + +#### Reason + +The network connection is too slow or has issues. +This tends to happen on `armv6l` devices where building takes significantly more time due to limited resources. + +#### Solution + +Try to use an ethernet connection. A reboot and/or running the script multiple times might also help ([Build produces EOF errors](#build-produces-eof-errors) might occur). + +If the error still persists, try to raise the timeout for npm package resolution. + +1. Open the npm config file in an editor +1. Increase the `fetch-retry-*` values by '30000' (30 seconds) and save +1. Retry the build + +### Build produces EOF errors + +#### Reason + +A previous run failed during installation and left a package corrupted. + +#### Solution + +Remove the mode packages and rerun again the script. +``` {.bash emphasize-lines="8,9"} +rm -rf node_modules +``` diff --git a/installation/includes/00_constants.sh b/installation/includes/00_constants.sh index 380e1de2e..89299989c 100644 --- a/installation/includes/00_constants.sh +++ b/installation/includes/00_constants.sh @@ -16,4 +16,7 @@ GIT_BRANCH_DEVELOP=${GIT_BRANCH_DEVELOP:-future3/develop} # This message will be displayed at the end of the installation process # Functions wanting to have something important printed at the end should APPEND to this variable +# example: +# local tmp_fin_message="A Message" +# FIN_MESSAGE="${FIN_MESSAGE:+$FIN_MESSAGE\n}${tmp_fin_message}" FIN_MESSAGE="" diff --git a/installation/includes/01_default_config.sh b/installation/includes/01_default_config.sh index fa1bafb61..ec7b67b66 100644 --- a/installation/includes/01_default_config.sh +++ b/installation/includes/01_default_config.sh @@ -26,8 +26,6 @@ GIT_USE_SSH=${GIT_USE_SSH:-"true"} # For non-production builds, the Wep App must be build locally # Valid values # - release-only: download in release branch only -# - true: force download even in non-release branch, +# - true: force download even in non-release branch # - false: never download ENABLE_WEBAPP_PROD_DOWNLOAD=${ENABLE_WEBAPP_PROD_DOWNLOAD:-"release-only"} -# Install Node during setup for Web App building. This is only needed for development builds -ENABLE_INSTALL_NODE=${ENABLE_INSTALL_NODE:-"false"} diff --git a/installation/includes/02_helpers.sh b/installation/includes/02_helpers.sh index 239a18ccf..e9ca7640e 100644 --- a/installation/includes/02_helpers.sh +++ b/installation/includes/02_helpers.sh @@ -2,6 +2,17 @@ ### Helpers +show_slow_hardware_message() { + if [[ $(uname -m) == "armv6l" ]]; then + print_c "-------------------------------------------------------------------- +| Your hardware is a little slower so this will take a while. | +| Go watch a movie but don't let your computer go to sleep for the | +| SSH connection to remain intact. | +-------------------------------------------------------------------- +" + fi +} + # $1->start, $2->end calc_runtime_and_print() { runtime=$(($2-$1)) diff --git a/installation/includes/03_welcome.sh b/installation/includes/03_welcome.sh index 5b3ee84be..62c4910c8 100644 --- a/installation/includes/03_welcome.sh +++ b/installation/includes/03_welcome.sh @@ -16,16 +16,16 @@ You are turning your Raspberry Pi into a Phoniebox. Good choice! Depending on your hardware, this installation might last -around 60 minutes (usually it's faster). It updates OS -packages, installs Phoniebox dependencies and registers -settings. Be patient and don't let your computer go to -sleep. It might disconnect your SSH connection causing -the interruption of the installation process. +around 60 minutes (usually it's faster, 20-30 min). It +updates OS packages, installs Phoniebox dependencies and +applies settings. Be patient and don't let your computer +go to sleep. It might disconnect your SSH connection +causing the interruption of the installation process. Consider starting the installation in a terminal multiplexer like 'screen' or 'tmux' to avoid this. -By the way, you can follow the installation details here -in a separate SSH session: +To follow the installation closely, use this command +in another terminal. cd; tail -f ${INSTALLATION_LOGFILE} Let's set up your Phoniebox. diff --git a/installation/includes/05_finish.sh b/installation/includes/05_finish.sh index 22ba6ae80..c48fc31d2 100644 --- a/installation/includes/05_finish.sh +++ b/installation/includes/05_finish.sh @@ -11,7 +11,7 @@ ${FIN_MESSAGE} In order to start, you need to reboot your Raspberry Pi. Your SSH connection will disconnect. -After the reboot, you can access the WebApp in your browser at +After the reboot, you can access the Web App in your browser at http://${local_hostname}.local or http://${CURRENT_IP_ADDRESS} Don't forget to upload files. " diff --git a/installation/routines/customize_options.sh b/installation/routines/customize_options.sh index 7409a6e07..3e94b07dc 100644 --- a/installation/routines/customize_options.sh +++ b/installation/routines/customize_options.sh @@ -189,12 +189,12 @@ Do you want to install Samba? [Y/n]" _option_webapp() { # ENABLE_WEBAPP clear_c - print_c "------------------------ WEBAPP ------------------------- + print_c "------------------------ WEB APP ------------------------ This is only required if you want to use a graphical interface to manage your Phoniebox! -Would you like to install the web application? [Y/n]" +Would you like to install the Web App? [Y/n]" read -r response case "$response" in [nN][oO]|[nN]) @@ -213,7 +213,7 @@ _option_kiosk_mode() { print_c "----------------------- KIOSK MODE ---------------------- If you have a screen attached to your RPi, -this will launch the web application right after boot. +this will launch the Web App right after boot. It will only install the necessary xserver dependencies and not the entire RPi desktop environment. @@ -282,48 +282,38 @@ Disable Pi's on-chip audio (headphone / jack output)? [y/N]" _option_webapp_devel_build() { # Let's detect if we are on the official release branch - if [[ "$GIT_BRANCH" != "${GIT_BRANCH_RELEASE}" || "$GIT_USER" != "$GIT_UPSTREAM_USER" || "$CI_RUNNING" == "true" ]]; then - ENABLE_INSTALL_NODE=true + if [[ "$GIT_BRANCH" != "${GIT_BRANCH_RELEASE}" && "$GIT_BRANCH" != "${GIT_BRANCH_DEVELOP}" ]] || [[ "$GIT_USER" != "$GIT_UPSTREAM_USER" ]] || [[ "$CI_RUNNING" == "true" ]] ; then # Unless ENABLE_WEBAPP_PROD_DOWNLOAD is forced to true by user override, do not download a potentially stale build if [[ "$ENABLE_WEBAPP_PROD_DOWNLOAD" == "release-only" ]]; then ENABLE_WEBAPP_PROD_DOWNLOAD=false fi - if [[ "$ENABLE_WEBAPP_PROD_DOWNLOAD" == false ]]; then + if [[ "$ENABLE_WEBAPP_PROD_DOWNLOAD" != true && "$ENABLE_WEBAPP_PROD_DOWNLOAD" != "release-only" ]]; then clear_c - print_c "--------------------- WEBAPP NODE --------------------- + print_c "--------------------- WEB APP BUILD --------------------- -You are installing from an unofficial branch. -Therefore a prebuilt web app is not available and -you will have to build it locally. +You are installing from a non-release branch +and/or an unofficial repository. +Therefore a pre-build Web App is not available +and it needs to be built locally. This requires Node to be installed. -You can choose to decline the Node installation and -the lastest prebuilt version from the main repository -will be installed. This can lead to incompatibilities. +If you decline, the lastest pre-build version +from the official repository will be installed. +This can lead to incompatibilities. -Do you want to install Node? [Y/n]" +Do you want to build the Web App? [Y/n]" read -r response case "$response" in [nN][oO]|[nN]) - ENABLE_INSTALL_NODE=false - ENABLE_WEBAPP_PROD_DOWNLOAD=true - ;; + ENABLE_WEBAPP_PROD_DOWNLOAD=true + ;; *) - # This message will be displayed at the end of the installation process - local tmp_fin_message="ATTENTION: You need to build the web app locally with - $ cd ~/RPi-Jukebox-RFID/src/webapp && ./run_rebuild.sh -u - This must be done after reboot, due to memory restrictions. - Read the documentation regarding local Web App builds!" - FIN_MESSAGE="${FIN_MESSAGE:+$FIN_MESSAGE\n}${tmp_fin_message}" - ;; + ;; esac fi fi - log "ENABLE_INSTALL_NODE=${ENABLE_INSTALL_NODE}" - if [ "$ENABLE_INSTALL_NODE" != true ]; then - log "ENABLE_WEBAPP_PROD_DOWNLOAD=${ENABLE_WEBAPP_PROD_DOWNLOAD}" - fi + log "ENABLE_WEBAPP_PROD_DOWNLOAD=${ENABLE_WEBAPP_PROD_DOWNLOAD}" } _run_customize_options() { diff --git a/installation/routines/install.sh b/installation/routines/install.sh index 62d602f17..f1f2a5f80 100644 --- a/installation/routines/install.sh +++ b/installation/routines/install.sh @@ -2,6 +2,7 @@ install() { clear_c customize_options clear_c + show_slow_hardware_message set_raspi_config set_ssh_qos update_raspi_os diff --git a/installation/routines/setup_jukebox_core.sh b/installation/routines/setup_jukebox_core.sh index 1c524abb0..d9c06b937 100644 --- a/installation/routines/setup_jukebox_core.sh +++ b/installation/routines/setup_jukebox_core.sh @@ -8,14 +8,6 @@ JUKEBOX_ZMQ_VERSION="4.3.5" JUKEBOX_PULSE_CONFIG="${HOME_PATH}"/.config/pulse/default.pa JUKEBOX_SERVICE_NAME="${SYSTEMD_USR_PATH}/jukebox-daemon.service" -_show_slow_hardware_message() { - print_c " -------------------------------------------------------------------- - | Your hardware is a little slower so this step will take a while. | - | Go watch a movie but don't let your computer go to sleep for the | - | SSH connection to remain intact. | - --------------------------------------------------------------------" -} - # Functions _jukebox_core_install_os_dependencies() { print_lc " Install Jukebox OS dependencies" @@ -86,11 +78,6 @@ _jukebox_core_build_and_install_pyzmq() { print_lc " Install pyzmq with libzmq-drafts to support WebSockets" if ! pip list | grep -F pyzmq >> /dev/null; then - - if [[ $(uname -m) == "armv6l" ]]; then - _show_slow_hardware_message - fi - mkdir -p "${JUKEBOX_ZMQ_TMP_DIR}" || exit_on_error if [ "$BUILD_LIBZMQ_WITH_DRAFTS_ON_DEVICE" = true ] ; then _jukebox_core_build_libzmq_with_drafts diff --git a/installation/routines/setup_jukebox_webapp.sh b/installation/routines/setup_jukebox_webapp.sh index 2884f18cb..7fcbce7ff 100644 --- a/installation/routines/setup_jukebox_webapp.sh +++ b/installation/routines/setup_jukebox_webapp.sh @@ -3,58 +3,87 @@ # Constants WEBAPP_NGINX_SITE_DEFAULT_CONF="/etc/nginx/sites-available/default" -# For ARMv7+ +# Node major version used. +# If changed also update in .github\actions\build-webapp\action.yml NODE_MAJOR=20 -# For ARMv6 -# To update version, follow these links -# https://github.com/sdesalas/node-pi-zero -# https://github.com/nodejs/unofficial-builds/ -NODE_SOURCE_EXPERIMENTAL="https://raw.githubusercontent.com/sdesalas/node-pi-zero/master/install-node-v16.3.0.sh" +# Node version for ARMv6 (unofficial builds) +NODE_ARMv6_VERSION=v20.10.0 -_jukebox_webapp_install_node() { - sudo apt-get -y update +OPTIONAL_WEBAPP_BUILD_FAILED=false - if which node > /dev/null; then - print_lc " Found existing NodeJS. Hence, updating NodeJS" - sudo npm cache clean -f - sudo npm install --silent -g n - sudo n --quiet latest - sudo npm update --silent -g - else +_jukebox_webapp_install_node() { print_lc " Install NodeJS" - # Zero and older versions of Pi with ARMv6 only - # support experimental NodeJS - if [[ $(uname -m) == "armv6l" ]]; then - wget -O - ${NODE_SOURCE_EXPERIMENTAL} | sudo bash - sudo apt-get -qq -y install nodejs - sudo npm install --silent -g npm + local node_version_installed=$(node -v 2>/dev/null) + local arch=$(uname -m) + if [[ "$arch" == "armv6l" ]]; then + if [ "$node_version_installed" == "$NODE_ARMv6_VERSION" ]; then + print_lc " Skipping. NodeJS already installed" + else + # For ARMv6 unofficial build + # https://github.com/nodejs/unofficial-builds/ + local node_tmp_dir="${HOME_PATH}/node" + local node_install_dir=/usr/local/lib/nodejs + local node_filename="node-${NODE_ARMv6_VERSION}-linux-${arch}" + local node_tar_filename="${node_filename}.tar.gz" + node_download_url="https://unofficial-builds.nodejs.org/download/release/${NODE_ARMv6_VERSION}/${node_tar_filename}" + + mkdir -p "${node_tmp_dir}" && cd "${node_tmp_dir}" || exit_on_error + download_from_url ${node_download_url} ${node_tar_filename} + tar -xzf ${node_tar_filename} + rm -rf ${node_tar_filename} + + # see https://github.com/nodejs/help/wiki/Installation + # Remove existing symlinks + sudo unlink /usr/bin/node 2>/dev/null + sudo unlink /usr/bin/npm 2>/dev/null + sudo unlink /usr/bin/npx 2>/dev/null + + # Clear existing nodejs and copy new files + sudo rm -rf "${node_install_dir}" + sudo mv "${node_filename}" "${node_install_dir}" + + sudo ln -s "${node_install_dir}/bin/node" /usr/bin/node + sudo ln -s "${node_install_dir}/bin/npm" /usr/bin/npm + sudo ln -s "${node_install_dir}/bin/npx" /usr/bin/npx + + cd "${HOME_PATH}" || exit_on_error + rm -rf "${node_tmp_dir}" + fi else - # install NodeJS and npm as recommended in - # https://github.com/nodesource/distributions - sudo apt-get install -y ca-certificates curl gnupg - sudo mkdir -p /etc/apt/keyrings - curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg - echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list - sudo apt-get update - sudo apt-get install -y nodejs + if [[ "$node_version_installed" == "v${NODE_MAJOR}."* ]]; then + print_lc " Skipping. NodeJS already installed" + else + sudo apt-get -y remove nodejs + # install NodeJS as recommended in + # https://deb.nodesource.com/ + sudo apt-get -y update && sudo apt-get -y install ca-certificates curl gnupg + sudo mkdir -p /etc/apt/keyrings + curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg + echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list + sudo apt-get -y update && sudo apt-get -y install nodejs + fi fi - fi } -# TODO: Avoid building the app locally -# Instead implement a Github Action that prebuilds on commititung a git tag _jukebox_webapp_build() { - print_lc " Building web application" - cd "${INSTALLATION_PATH}/src/webapp" || exit_on_error - npm ci --prefer-offline --no-audit --production - rm -rf build - # The build wrapper script checks available memory on system and sets Node options accordingly - ./run_rebuild.sh + print_lc " Building Web App" + cd "${INSTALLATION_PATH}/src/webapp" || exit_on_error + if ! ./run_rebuild.sh -u ; then + print_lc " Web App build failed! + Follow instructions shown at the end of installation!" + OPTIONAL_WEBAPP_BUILD_FAILED=true + # This message will be displayed at the end of the installation process + local tmp_fin_message="ATTENTION: The build of the Web App failed during installation. + Please run the build manually with the following command + $ cd ~/RPi-Jukebox-RFID/src/webapp && ./run_rebuild.sh -u + Read the documentation regarding local Web App builds!" + FIN_MESSAGE="${FIN_MESSAGE:+$FIN_MESSAGE\n}${tmp_fin_message}" + fi } _jukebox_webapp_download() { - print_lc " Downloading web application" + print_lc " Downloading Web App" local jukebox_version=$(python "${INSTALLATION_PATH}/src/jukebox/jukebox/version.py") local git_head_hash=$(git -C "${INSTALLATION_PATH}" rev-parse --verify --quiet HEAD) local git_head_hash_short=${git_head_hash:0:10} @@ -67,11 +96,11 @@ _jukebox_webapp_download() { if validate_url ${download_url_commit} ; then log " DOWNLOAD_URL ${download_url_commit}" download_from_url ${download_url_commit} ${tar_filename} - elif [[ $ENABLE_WEBAPP_PROD_DOWNLOAD == true ]] && validate_url ${download_url_latest} ; then + elif [[ "$ENABLE_WEBAPP_PROD_DOWNLOAD" == true ]] && validate_url ${download_url_latest} ; then log " DOWNLOAD_URL ${download_url_latest}" download_from_url ${download_url_latest} ${tar_filename} else - exit_on_error "No prebuild webapp bundle found!" + exit_on_error "No prebuild Web App bundle found!" fi tar -xzf ${tar_filename} rm -f ${tar_filename} @@ -80,7 +109,7 @@ _jukebox_webapp_download() { _jukebox_webapp_register_as_system_service_with_nginx() { print_lc " Install and configure nginx" - sudo apt-get -qq -y update + sudo apt-get -y update sudo apt-get -y purge apache2 sudo apt-get -y install nginx @@ -97,11 +126,22 @@ _jukebox_webapp_register_as_system_service_with_nginx() { _jukebox_webapp_check() { print_verify_installation - if [[ $ENABLE_WEBAPP_PROD_DOWNLOAD == true || $ENABLE_WEBAPP_PROD_DOWNLOAD == release-only ]] ; then + if [[ "$ENABLE_WEBAPP_PROD_DOWNLOAD" == true || "$ENABLE_WEBAPP_PROD_DOWNLOAD" == "release-only" ]] ; then verify_dirs_exists "${INSTALLATION_PATH}/src/webapp/build" - fi - if [[ $ENABLE_INSTALL_NODE == true ]] ; then - verify_apt_packages nodejs + else + local arch=$(uname -m) + if [[ "$arch" == "armv6l" ]]; then + local node_version_installed=$(node -v 2>/dev/null) + log " Verify 'node' is installed" + test ! "${node_version_installed}" == "${NODE_ARMv6_VERSION}" && exit_on_error "ERROR: 'node' not in expected version: '${node_version_installed}' instead of '${NODE_ARMv6_VERSION}'!" + log " CHECK" + else + verify_apt_packages nodejs + fi + + if [[ "$OPTIONAL_WEBAPP_BUILD_FAILED" == false ]]; then + verify_dirs_exists "${INSTALLATION_PATH}/src/webapp/build" + fi fi verify_apt_packages nginx @@ -111,14 +151,11 @@ _jukebox_webapp_check() { } _run_setup_jukebox_webapp() { - if [[ $ENABLE_WEBAPP_PROD_DOWNLOAD == true || $ENABLE_WEBAPP_PROD_DOWNLOAD == release-only ]] ; then + if [[ "$ENABLE_WEBAPP_PROD_DOWNLOAD" == true || "$ENABLE_WEBAPP_PROD_DOWNLOAD" == "release-only" ]] ; then _jukebox_webapp_download - fi - if [[ $ENABLE_INSTALL_NODE == true ]] ; then + else _jukebox_webapp_install_node - # Local Web App build during installation does not work at the moment - # Needs to be done after reboot! There will be a message at the end of the installation process - # _jukebox_webapp_build + _jukebox_webapp_build fi _jukebox_webapp_register_as_system_service_with_nginx _jukebox_webapp_check @@ -126,6 +163,6 @@ _run_setup_jukebox_webapp() { setup_jukebox_webapp() { if [ "$ENABLE_WEBAPP" == true ] ; then - run_with_log_frame _run_setup_jukebox_webapp "Install web application" + run_with_log_frame _run_setup_jukebox_webapp "Install Web App" fi } diff --git a/resources/default-settings/gpio.example.yaml b/resources/default-settings/gpio.example.yaml index f19b83c87..59793210f 100644 --- a/resources/default-settings/gpio.example.yaml +++ b/resources/default-settings/gpio.example.yaml @@ -1,6 +1,6 @@ # Provides a few selected examples of GPIO configuration # Check out the documentation for many more configuration recipes -# https://rpi-jukebox-rfid.readthedocs.io/en/latest/index.html +# documentation/builders/gpio.md pin_factory: type: rpigpio.RPiGPIOFactory output_devices: diff --git a/resources/html/404.html b/resources/html/404.html index 1a60d2415..a79decc6c 100755 --- a/resources/html/404.html +++ b/resources/html/404.html @@ -15,7 +15,7 @@

Ups! Requested file not found.

Why not try again from the top-level of

diff --git a/resources/html/runbuildui.html b/resources/html/runbuildui.html index 04f92c704..6ade7bb0a 100755 --- a/resources/html/runbuildui.html +++ b/resources/html/runbuildui.html @@ -12,11 +12,11 @@

Ups! Looks like your Web UI has not been build!

No reason to panic. Please run through the following steps:

    -
  • cd ~/RPi-Jukebox-RFID/src/webapp
  • -
  • ./run_rebuild.sh -u
  • -
  • Reload this page
  • +
  • cd ~/RPi-Jukebox-RFID/src/webapp

  • +
  • ./run_rebuild.sh -u

  • +
  • Reload this page

-

In case of trouble when building the Web UI, consult the documentation! +

In case of trouble when building the Web UI, consult the official documentation! diff --git a/src/jukebox/components/playermpd/__init__.py b/src/jukebox/components/playermpd/__init__.py index c77c21051..a2dbc914a 100644 --- a/src/jukebox/components/playermpd/__init__.py +++ b/src/jukebox/components/playermpd/__init__.py @@ -56,8 +56,9 @@ """ # noqa: E501 # Warum ist "Second Swipe" im Player und nicht im RFID Reader? # Second swipe ist abhängig vom Player State - nicht vom RFID state. -# Beispiel: RFID triggered Folder1, Webapp triggered Folder2, RFID Folder1: Dann muss das 2. Mal Folder1 auch als "first swipe" -# gewertet werden. Wenn der RFID das basierend auf IDs macht, kann der nicht unterscheiden und glaubt es ist 2. Swipe. +# Beispiel: RFID triggered Folder1, Web App triggered Folder2, RFID Folder1: +# Dann muss das 2. Mal Folder1 auch als "first swipe" gewertet werden. +# Wenn der RFID das basierend auf IDs macht, kann der nicht unterscheiden und glaubt es ist 2. Swipe. # Beispiel 2: Jemand hat RFID Reader (oder 1x RFID und 1x Barcode Scanner oder so) angeschlossen. Liest zuerst Karte mit # Reader 1 und dann mit Reader 2: Reader 2 weiß nicht, was bei Reader 1 passiert ist und denkt es ist 1. swipe. # Beispiel 3: RFID trigered Folder1, Playlist läuft durch und hat schon gestoppt, dann wird die Karte wieder vorgehalten. @@ -68,7 +69,7 @@ # # In der aktuellen Implementierung weiß der Player (der second "swipe" dekodiert) überhaupt nichts vom RFID. # Im Prinzip gibt es zwei "Play" Funktionen: (1) play always from start und (2) play with toggle action. -# Die Webapp ruft immer (1) auf und die RFID immer (2). Jetzt kann man sogar für einige Karten sagen +# Die Web App ruft immer (1) auf und die RFID immer (2). Jetzt kann man sogar für einige Karten sagen # immer (1) - also kein Second Swipe und für andere (2). # Sollte der Reader das Swcond swipe dekodieren, muss aber der Reader den Status des Player kennen. # Das ist allerdings ein Problem. In Version 2 ist das nicht aufgefallen, @@ -76,7 +77,7 @@ # # Beispiel: Second swipe bei anderen Funktionen, hier: WiFi on/off. # Was die Karte Action tut ist ein Toggle. Der Toggle hängt vom Wifi State ab, den der RFID Kartenleser nicht kennt. -# Den kann der Leser auch nicht tracken. Der State kann ja auch über die WebApp oder Kommandozeile geändert werden. +# Den kann der Leser auch nicht tracken. Der State kann ja auch über die Web App oder Kommandozeile geändert werden. # Toggle (und 2nd Swipe generell) ist immer vom Status des Zielsystems abhängig und kann damit nur vom Zielsystem geändert # werden. Bei Wifi also braucht man 3 Funktionen: on / off / toggle. Toggle ist dann first swipe / second swipe diff --git a/src/webapp/.gitignore b/src/webapp/.gitignore index 4d29575de..b32ff75cd 100644 --- a/src/webapp/.gitignore +++ b/src/webapp/.gitignore @@ -11,6 +11,9 @@ # production /build +# development +/build.bak + # misc .DS_Store .env.local diff --git a/src/webapp/.npmrc b/src/webapp/.npmrc new file mode 100644 index 000000000..f05c1e85f --- /dev/null +++ b/src/webapp/.npmrc @@ -0,0 +1,3 @@ +fetch-retries=10 +fetch-retry-mintimeout=20000 +fetch-retry-maxtimeout=120000 diff --git a/src/webapp/public/index.html b/src/webapp/public/index.html index 71ea85188..30c055a5e 100644 --- a/src/webapp/public/index.html +++ b/src/webapp/public/index.html @@ -7,7 +7,7 @@ diff --git a/src/webapp/run_rebuild.sh b/src/webapp/run_rebuild.sh index 870813d78..e8e4d06c0 100755 --- a/src/webapp/run_rebuild.sh +++ b/src/webapp/run_rebuild.sh @@ -1,30 +1,35 @@ #!/usr/bin/env bash usage() { - echo -e "\nRebuild the Web App\n" - echo "${BASH_SOURCE[0]} [-u] [-m SIZE]" - echo " -u : Update NPM dependencies before rebuild (only necessary if package.json changed)" - echo " -m SIZE : Set Node memory limit in MB (if omitted limit is deduced automatically)" - echo -e "\n\n" + echo -e "\nRebuild the Web App\n" + echo "${BASH_SOURCE[0]} [-u] [-m SIZE]" + echo " -u : Update NPM dependencies before rebuild (only necessary on first build or if package.json changed" + echo " -m SIZE : Set Node memory limit in MB (if omitted limit is deduced automatically and swap might be adjusted)" + echo " -v : Increase verbosity" + echo -e "\n\n" } UPDATE_DEPENDENCIES=false +VERBOSE=false -while getopts ":uhm:" opt; do - case ${opt} in - u) - UPDATE_DEPENDENCIES=true - ;; - m) - NODEMEM="${OPTARG}" - ;; - h) - usage - ;; - \?) - usage - ;; - esac +while getopts ":uhvm:" opt; do + case ${opt} in + u) + UPDATE_DEPENDENCIES=true + ;; + m) + NODEMEM="${OPTARG}" + ;; + v) + VERBOSE=true + ;; + h) + usage + ;; + \?) + usage + ;; + esac done # Change working directory to location of script @@ -32,44 +37,87 @@ SOURCE=${BASH_SOURCE[0]} SCRIPT_DIR="$(dirname "$SOURCE")" cd "$SCRIPT_DIR" || exit 1 -# Need to check free space and limit Node memory usage -# for PIs with little memory -MemTotal=$(grep MemTotal /proc/meminfo | awk '{print $2}') -MemFree=$(grep MemFree /proc/meminfo | awk '{print $2}') -SwapFree=$(grep SwapFree /proc/meminfo | awk '{print $2}') -TotalFree=$((SwapFree + MemFree)) - -MemTotal=$((MemTotal / 1024)) -MemFree=$((MemFree / 1024)) -SwapFree=$((SwapFree / 1024)) -TotalFree=$((TotalFree / 1024)) - -echo "Total phys memory: ${MemTotal} MB" -echo "Free phys memory : ${MemFree} MB" -echo "Free swap memory : ${SwapFree} MB" -echo "Free total memory: ${TotalFree} MB" - - -if [[ -z $NODEMEM ]]; then - # Keep a buffer of minimum 20 MB - if [[ $TotalFree -gt 1044 ]]; then - NODEMEM=1024 - elif [[ $TotalFree -gt 532 ]]; then - NODEMEM=512 - elif [[ $TotalFree -gt 276 ]]; then - NODEMEM=256 - else - echo "ERROR: Not enough memory available on system. Please increase swap size to give at least 276 MByte free memory." - echo "Current free memory = $TotalFree MB" - echo "Hint: if only a little memory is missing, stopping spocon, mpd, and jukebox-daemon might give you enough space" - exit 1 - fi -fi +change_swap() { + local new_swap_size="$1" + sudo dphys-swapfile swapoff || return 1 + sudo sed -i "s|.*CONF_SWAPSIZE=.*|CONF_SWAPSIZE=${new_swap_size}|g" /etc/dphys-swapfile || return 1 + sudo sed -i "s|^\s*CONF_SWAPFACTOR=|#CONF_SWAPFACTOR=|g" /etc/dphys-swapfile || return 1 + sudo dphys-swapfile setup 1&>/dev/null || return 1 + sudo dphys-swapfile swapon || return 1 +} -if [[ $NODEMEM -gt $TotalFree ]]; then - echo "ERROR: Requested node memory setting is larger than available free memory: $NODEMEM MB > $TotalFree MB" - exit 1 -fi +# Need to check free space and limit Node memory usage for PIs with little memory. +# Adjust swap if needed to have minimum memory available +calc_nodemem() { + echo "calculate usable memory" + # keep a buffer for the kernel etc. + local mem_buffer=256 + + local mem_total=$(grep MemTotal /proc/meminfo | awk '{print $2}') + local mem_free=$(grep MemFree /proc/meminfo | awk '{print $2}') + local swap_total=$(grep SwapTotal /proc/meminfo | awk '{print $2}') + local swap_free=$(grep SwapFree /proc/meminfo | awk '{print $2}') + local total_free=$((swap_free + mem_free)) + + mem_total=$((mem_total / 1024)) + mem_free=$((mem_free / 1024)) + swap_total=$((swap_total / 1024)) + swap_free=$((swap_free / 1024)) + total_free=$((total_free / 1024)) + + local free_to_use=$((total_free - mem_buffer)) + + if [ "$VERBOSE" == true ]; then + echo " Total phys memory : ${mem_total} MB" + echo " Free phys memory : ${mem_free} MB" + echo " Total swap memory : ${swap_total} MB" + echo " Free swap memory : ${swap_free} MB" + echo " Free total memory : ${total_free} MB" + echo " Keep as buffer : ${mem_buffer} MB" + echo -e " Free usable memory: ${free_to_use} MB\n" + fi + + if [[ -z $NODEMEM ]]; then + # mininum memory used for node + local mem_min=512 + if [[ $free_to_use -gt $mem_min ]]; then + NODEMEM=$free_to_use + else + echo " WARN: Not enough memory left on system for node (usable ${free_to_use} MB, min. ${mem_min} MB)." + echo " Trying to adjust swap size ..." + + local add_swap_size=$((mem_min / 2)) + local new_swap_size=$((swap_total + add_swap_size)) + + # keep a buffer on the filesystem + local filesystem_needed=$((add_swap_size + 512)) + local filesystem_free=$(df -BM -P / | tail -n 1 | awk '{print $4}') + filesystem_free=${filesystem_free//M} + + if [ "$VERBOSE" == true ]; then + echo " New swap size = $new_swap_size MB" + echo " Additional filesystem space needed = $filesystem_needed MB" + echo " Current free filesystem space = $filesystem_free MB" + fi + + if [ "${filesystem_free}" -lt "${filesystem_needed}" ]; then + echo " ERROR: Not enough space available on filesystem for swap (free ${filesystem_free} MB, min. ${filesystem_needed} MB). Abort!" + exit 1 + elif ! change_swap $new_swap_size ; then + echo " ERROR: failed to change swap size. Abort!" + exit 1 + fi + + calc_nodemem || return 1 + fi + + elif [[ $NODEMEM -gt $free_to_use ]]; then + echo " ERROR: Requested node memory setting is larger than usable free memory: ${NODEMEM} MB > ${free_to_use} MB (free ${total_free} MB - buffer ${mem_buffer} MB). Abort!" + exit 1 + fi +} + +calc_nodemem export NODE_OPTIONS=--max-old-space-size=${NODEMEM} @@ -77,16 +125,27 @@ echo "Setting Node Options:" env | grep NODE if [[ $(uname -m) == armv6l ]]; then - echo " You are running on a hardware with less resources. Building - the webapp might fail. If so, try to install the stable - release installation instead." + echo " +----------------------------------------------------------- +| You are running a hardware with limited resources. | +| Building the Web App takes significantly more time. | +| In case it fails, check the documentation | +| to trouble shoot. | +----------------------------------------------------------- +" fi -# In rare cases you will need to update the npm dependencies -# This is the case when the file package.json changed if [[ $UPDATE_DEPENDENCIES == true ]]; then - npm install + npm install --prefer-offline --no-audit fi +build_output_folder="build" # Rebuild Web App -npm run build +rm -rf "${build_output_folder}.bak" +if [ -d "${build_output_folder}" ]; then + mv -f "${build_output_folder}" "${build_output_folder}.bak" +fi +if ! npm run build ; then + echo "ERROR: rebuild of Web App failed!" + exit 1 +fi