From b8be4868f39a277b9a2e06e962eea4056eb26f16 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 19 Nov 2023 03:33:22 +0100 Subject: [PATCH 01/44] add ci workflow --- .dockerignore | 1 - .github/workflows/test_docker_debian.yml | 31 +++ .../test_docker_debian_codename_sub.yml | 183 ++++++++++++++++++ ci/ci-debian.Dockerfile | 102 ++++++++++ ci/installation/run_install_faststartup.sh | 41 ++++ ci/installation/run_install_test.sh | 45 +++++ ci/installation/run_install_user_not_pi.sh | 28 +++ ci/installation/run_install_webapp.sh | 43 ++++ 8 files changed, 473 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/test_docker_debian.yml create mode 100644 .github/workflows/test_docker_debian_codename_sub.yml create mode 100644 ci/ci-debian.Dockerfile create mode 100644 ci/installation/run_install_faststartup.sh create mode 100644 ci/installation/run_install_test.sh create mode 100644 ci/installation/run_install_user_not_pi.sh create mode 100644 ci/installation/run_install_webapp.sh diff --git a/.dockerignore b/.dockerignore index 55fe62a70..a587de477 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,7 +7,6 @@ # Application docker docs -installation shared # webapp diff --git a/.github/workflows/test_docker_debian.yml b/.github/workflows/test_docker_debian.yml new file mode 100644 index 000000000..928c3ce30 --- /dev/null +++ b/.github/workflows/test_docker_debian.yml @@ -0,0 +1,31 @@ +name: Test Install Scripts Debian v3 + +on: + schedule: + # run at 17:00 every sunday + - cron: '0 17 * * 0' + push: + pull_request: + # The branches below must be a subset of the branches above + branches: [ future3/develop ] + +# let only one instance run the test so cache is not corrupted. +# cancel already running instances as only the last run will be relevant +concurrency: + group: ${{ github.ref }}-test-debian-v3 + cancel-in-progress: true + +jobs: + + # Build container and run tests. Duplication of job intended for better visualization. + run_bookworm: + name: 'bookworm' + uses: ./.github/workflows/test_docker_debian_codename_sub.yml + with: + debian_codename: 'bookworm' + + run_bullseye: + name: 'bullseye' + uses: ./.github/workflows/test_docker_debian_codename_sub.yml + with: + debian_codename: 'bullseye' diff --git a/.github/workflows/test_docker_debian_codename_sub.yml b/.github/workflows/test_docker_debian_codename_sub.yml new file mode 100644 index 000000000..1ea59935a --- /dev/null +++ b/.github/workflows/test_docker_debian_codename_sub.yml @@ -0,0 +1,183 @@ +name: Subworkflow Test Install Scripts Debian V3 + +on: + workflow_call: + inputs: + debian_codename: + required: true + type: string + docker_image_name: + required: false + type: string + default: rpi-jukebox-rfid-v3 + platform: + required: false + type: string + default: linux/arm/v7 + cache_scope: + required: false + type: string + default: ${{ github.ref }}-test-debian-v3 + local_registry_port: + required: false + type: number + default: 5000 + runs_on: + required: false + type: string + default: ubuntu-latest + +# let only one instance run the test so cache is not corrupted. +# cancel already running instances as only the last run will be relevant +concurrency: + group: ${{ inputs.cache_scope }}-${{ inputs.debian_codename }} + cancel-in-progress: true + +jobs: + + # Build container for test execution + build: + runs-on: ${{ inputs.runs_on }} + + outputs: + 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 }} + + # create local docker registry to use locally build images + services: + registry: + image: registry:2 + ports: + - ${{ inputs.local_registry_port }}:5000 + + steps: + - uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3.0.0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3.0.0 + with: + # network=host driver-opt needed to push to local registry + driver-opts: network=host + + - name: Set Output pre-vars + id: pre-vars + env: + DEBIAN_CODENAME: ${{ inputs.debian_codename }} + DOCKER_IMAGE_NAME: ${{ inputs.docker_image_name }} + CACHE_SCOPE: ${{ inputs.cache_scope }} + run: | + echo "image_tag_name=${{ env.DOCKER_IMAGE_NAME }}:${{ env.DEBIAN_CODENAME }}-test" >> $GITHUB_OUTPUT + echo "image_file_name=${{ env.DOCKER_IMAGE_NAME }}-${{ env.DEBIAN_CODENAME }}.tar" >> $GITHUB_OUTPUT + echo "cache_scope=${{ env.CACHE_SCOPE }}-${{ env.DEBIAN_CODENAME }}" >> $GITHUB_OUTPUT + + - name: Set Output vars + id: vars + env: + LOCAL_REGISTRY_PORT: ${{ inputs.local_registry_port }} + 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 + echo "image_file_name=${{ steps.pre-vars.outputs.image_file_name }}" >> $GITHUB_OUTPUT + 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 + + # Build base image for debian version name. Layers will be cached and image pushes to local registry + - name: Build Image - Base + uses: docker/build-push-action@v5 + with: + context: . + load: false + push: true + file: ./ci/ci-debian.Dockerfile + target: test-code + platforms: ${{ inputs.platform }} + tags: ${{ steps.vars.outputs.image_tag_name_local_base }} + cache-from: type=gha,scope=${{ steps.vars.outputs.cache_scope }} + cache-to: type=gha,mode=max,scope=${{ steps.vars.outputs.cache_scope }} + build-args: | + DEBIAN_CODENAME=${{ inputs.debian_codename }} + GIT_BRANCH=${{ github.head_ref || github.ref_name }} + GIT_USER=${{ github.event.pull_request.head.user.login || github.repository_owner }} + + # Build new image with updates packages based on base image. Layers will NOT be chached. Result is written to file. + - name: Build Image - Update + uses: docker/build-push-action@v5 + with: + context: . + load: false + push: false + file: ./ci/ci-debian.Dockerfile + target: test-update + platforms: ${{ inputs.platform }} + tags: ${{ steps.vars.outputs.image_tag_name }} + cache-from: type=gha,scope=${{ steps.vars.outputs.cache_scope }} + # DON'T use 'cache-to' here as the layer is then cached and this build would be useless + outputs: type=docker,dest=${{ steps.vars.outputs.image_file_path }} + build-args: | + BASE_TEST_IMAGE=${{ steps.vars.outputs.image_tag_name_local_base }} + + - name: Artifact Upload Docker Image + uses: actions/upload-artifact@v3 + with: + name: ${{ steps.vars.outputs.image_file_name }} + path: ${{ steps.vars.outputs.image_file_path }} + retention-days: 1 + + + # Run tests with build image + test: + needs: [build] + runs-on: ${{ inputs.runs_on }} + + strategy: + fail-fast: false + matrix: + username: ['pi'] + test_script: ['run_install_test.sh', 'run_install_webapp.sh', 'run_install_faststartup.sh'] + include: + - username: hans + test_script: run_install_user_not_pi.sh + + steps: + - name: Set up QEMU + uses: docker/setup-qemu-action@v3.0.0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3.0.0 + + - name: Artifact Download Docker Image + uses: actions/download-artifact@v3 + with: + name: ${{ needs.build.outputs.image_file_name }} + + - name: Load Docker Image + run: | + docker load --input ${{ needs.build.outputs.image_file_name }} + + # Run test + - name: Run Test ${{ inputs.debian_codename }}-${{ matrix.username }}-${{ matrix.test_script }} + uses: tj-actions/docker-run@v2 + with: + image: ${{ needs.build.outputs.image_tag_name }} + options: --platform ${{ inputs.platform }} --user ${{ matrix.username }} --init + name: ${{ matrix.test_script }} + args: | + ./${{ matrix.test_script }} + + # cleanup after test execution + cleanup: + # run only if tests didn't fail: keep the artifact to make job reruns possible + if: ${{ !failure() }} + needs: [build, test] + runs-on: ${{ inputs.runs_on }} + + steps: + - name: Artifact Delete Docker Image + uses: geekyeggo/delete-artifact@v2 + with: + name: ${{ needs.build.outputs.image_file_name }} diff --git a/ci/ci-debian.Dockerfile b/ci/ci-debian.Dockerfile new file mode 100644 index 000000000..307a0a465 --- /dev/null +++ b/ci/ci-debian.Dockerfile @@ -0,0 +1,102 @@ +# Base Target to build and install all needed base configuration and packages. Specifie the needed platform with the docker '--platform XXX' option +ARG DEBIAN_CODENAME=bookworm +ARG BASE_TEST_IMAGE=test-code +FROM debian:${DEBIAN_CODENAME}-slim as base +ARG DEBIAN_CODENAME + +ENV CI_RUNNING=true TERM=xterm + +# create pi configs to test installation +RUN touch /boot/cmdline.txt +RUN touch /boot/config.txt + +RUN export DEBIAN_FRONTEND=noninteractive \ + && echo "--- install packages (1) ---" \ + && apt-get update \ + && apt-get -y install \ + apt-utils \ + curl \ + gnupg \ + && echo "--- add sources ---" \ + && curl -fsSL http://raspbian.raspberrypi.org/raspbian.public.key | gpg --dearmor > /usr/share/keyrings/raspberrypi-raspbian-keyring.gpg \ + && curl -fsSL http://archive.raspberrypi.org/debian/raspberrypi.gpg.key | gpg --dearmor > /usr/share/keyrings/raspberrypi-archive-debian-keyring.gpg \ + && echo "deb [signed-by=/usr/share/keyrings/raspberrypi-raspbian-keyring.gpg] http://raspbian.raspberrypi.org/raspbian/ ${DEBIAN_CODENAME} main contrib non-free rpi" > /etc/apt/sources.list.d/raspi.list \ + && echo "deb [signed-by=/usr/share/keyrings/raspberrypi-archive-debian-keyring.gpg] http://archive.raspberrypi.org/debian/ ${DEBIAN_CODENAME} main" >> /etc/apt/sources.list.d/raspi.list \ + && echo "--- install packages (2) ---" \ + && apt-get update \ + && apt-get -y upgrade \ + && apt-get -y install \ + alsa-utils \ + build-essential \ + locales \ + openssh-client \ + sudo \ + systemd \ + wireless-tools \ + wget \ + wpasupplicant \ + && rm -rf /var/lib/apt/lists/* +# ------ + +# Base Target for setting up the default user. user can be selected with the docker '--user YYY' option +FROM base as user +ARG USER_NAME=pi +ARG USER_GROUP=$USER_NAME +ARG USER_ID=1000 + +ENV TEST_USER_GROUP=test +RUN groupadd --gid 1002 $TEST_USER_GROUP + +RUN groupadd --gid 1000 $USER_GROUP \ + && useradd -u $USER_ID -g $USER_GROUP -G sudo,$TEST_USER_GROUP -d /home/$USER_NAME -m -s /bin/bash -p '$1$iV7TOwOe$6ojkJQXyEA9bHd/SqNLNj0' $USER_NAME \ + && echo "$USER_NAME ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/$USER_NAME + +ENV XDG_RUNTIME_DIR=/run/user/$USER_ID DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$USER_ID/bus +# ------ + + +# Target for setting up an alternativ user 'hans:wurst'. user can be selected with the docker '--user YYY' option +FROM user as test-user + +RUN export USER_ALT=hans \ + && export USER_ALT_GROUP=wurst \ + && groupadd --gid 1001 $USER_ALT_GROUP \ + && useradd -u 1001 -g $USER_ALT_GROUP -G sudo,$TEST_USER_GROUP -d /home/$USER_ALT -m -s /bin/bash -p '$1$iV7TOwOe$6ojkJQXyEA9bHd/SqNLNj0' $USER_ALT \ + && echo "$USER_ALT ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/$USER_ALT +# ------ + + +# Target for adding envs and scripts from the repo to test installation +FROM test-user as test-code +ARG GIT_BRANCH +ARG GIT_USER + +ENV GIT_BRANCH=$GIT_BRANCH GIT_USER=$GIT_USER + +# COPY --chown=root:$TEST_USER_GROUP --chmod=770 packages.txt packages-raspberrypi.txt ./ + +# RUN export DEBIAN_FRONTEND=noninteractive \ +# && echo "--- install internal packages ---" \ +# && apt-get update \ +# # remove resolvconf as installation will fail in container +# && sed 's/#.*//g' packages.txt | sed 's/resolvconf//' | xargs apt-get -y install \ +# && sed 's/#.*//g' packages-raspberrypi.txt | xargs apt-get -y install \ +# && rm -rf /var/lib/apt/lists/* + +ENV INSTALL_SCRIPT_PATH=/code + +WORKDIR ${INSTALL_SCRIPT_PATH} +COPY --chown=root:$TEST_USER_GROUP --chmod=770 installation/install-jukebox.sh ./ + +WORKDIR ${INSTALL_SCRIPT_PATH}/tests +COPY --chown=root:$TEST_USER_GROUP --chmod=770 ci/installation/*.sh ./ +# ------ + + +# Target for applying latest updates (should not be cached!) +FROM $BASE_TEST_IMAGE as test-update +RUN export DEBIAN_FRONTEND=noninteractive \ + && apt-get update \ + && apt-get -y upgrade \ + && rm -rf /var/lib/apt/lists/* +# ------ diff --git a/ci/installation/run_install_faststartup.sh b/ci/installation/run_install_faststartup.sh new file mode 100644 index 000000000..1cefbc8be --- /dev/null +++ b/ci/installation/run_install_faststartup.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +# Install Phoniebox and test it +# Used e.g. for tests on Docker + +# Objective: Test installation with script using a simple configuration + +local_install_script_path="${INSTALL_SCRIPT_PATH:-./../../installation/}" +local_install_script_path="${local_install_script_path%/}" + +# Preparations +# No interactive frontend +export DEBIAN_FRONTEND=noninteractive +echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections + +# Run installation (in interactive mode) +# y - start setup +# y - use static ip +# y - deactivate ipv6 +# n - setup autohotspot +# y - deactivate bluetooth +# y - disable on-chip audio +# - - mpd overwrite config (only with existing installation) +# n - setup rfid reader +# n - setup samba +# n - build local WebApp +# - - setup kiosk mode (only with WebApp = y) +# - - install node (only with WebApp = y) +# n - reboot + +"$local_install_script_path"/install-jukebox.sh <<< 'y +y +y +n +y +y +n +n +n +n +' diff --git a/ci/installation/run_install_test.sh b/ci/installation/run_install_test.sh new file mode 100644 index 000000000..6f2f07fdd --- /dev/null +++ b/ci/installation/run_install_test.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +# Install Phoniebox and test it +# Used e.g. for tests on Docker + +# Objective: Test installation with script using a simple configuration + +local_install_script_path="${INSTALL_SCRIPT_PATH:-./../../installation/}" +local_install_script_path="${local_install_script_path%/}" + +# Preparations +# No interactive frontend +export DEBIAN_FRONTEND=noninteractive +echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections + +# Run installation (in interactive mode) +# y - start setup +# n - use static ip +# n - deactivate ipv6 +# y - setup autohotspot +# n - use custom password +# n - deactivate bluetooth +# n - disable on-chip audio +# - - mpd overwrite config (only with existing installation) +# n - setup rfid reader +# y - setup samba +# y - build local WebApp +# n - setup kiosk mode +# y - install node +# n - reboot + +"$local_install_script_path"/install-jukebox.sh <<< 'y +n +n +y +n +n +n +n +y +y +n +y +n +' diff --git a/ci/installation/run_install_user_not_pi.sh b/ci/installation/run_install_user_not_pi.sh new file mode 100644 index 000000000..02cf2734c --- /dev/null +++ b/ci/installation/run_install_user_not_pi.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# Install Phoniebox and test it +# Used e.g. for tests on Docker + +# Objective: Test installation with script using a simple configuration + +local_install_script_path="${INSTALL_SCRIPT_PATH:-./../../installation/}" +local_install_script_path="${local_install_script_path%/}" + +# Preparations +# No interactive frontend +export DEBIAN_FRONTEND=noninteractive +echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections + +# Run installation (in interactive mode) +# - - Installation must abort early + +"$local_install_script_path"/install-jukebox.sh +INSTALLATION_EXITCODE=$? + +# only count abortion due to "not user pi" as success +if [ "${INSTALLATION_EXITCODE}" -eq 2 ]; then + INSTALLATION_EXITCODE=0 +else + INSTALLATION_EXITCODE=1 +fi +exit "${INSTALLATION_EXITCODE}" diff --git a/ci/installation/run_install_webapp.sh b/ci/installation/run_install_webapp.sh new file mode 100644 index 000000000..cc36fdeaf --- /dev/null +++ b/ci/installation/run_install_webapp.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +# Install Phoniebox and test it +# Used e.g. for tests on Docker + +# Objective: Test installation with script using a simple configuration + +local_install_script_path="${INSTALL_SCRIPT_PATH:-./../../installation/}" +local_install_script_path="${local_install_script_path%/}" + +# Preparations +# No interactive frontend +export DEBIAN_FRONTEND=noninteractive +echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections + +# Run installation (in interactive mode) +# y - start setup +# n - use static ip +# n - deactivate ipv6 +# n - setup autohotspot +# n - deactivate bluetooth +# n - disable on-chip audio +# - - mpd overwrite config (only with existing installation) +# n - setup rfid reader +# n - setup samba +# y - build local WebApp +# y - setup kiosk mode +# y - install node +# n - reboot + +"$local_install_script_path"/install-jukebox.sh <<< 'y +n +n +n +n +n +n +n +y +y +y +n +' From ba343877cc7df721236f814d8bfa413a9d66a179 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 19 Nov 2023 03:36:06 +0100 Subject: [PATCH 02/44] add check for user home --- installation/install-jukebox.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/installation/install-jukebox.sh b/installation/install-jukebox.sh index 44b03fca0..17294f32e 100755 --- a/installation/install-jukebox.sh +++ b/installation/install-jukebox.sh @@ -46,6 +46,13 @@ checkPrerequisite() { echo " Please check the wiki for further information" exit 2 fi + + if [ ! -d "${HOME_PATH}" ]; then + echo + echo "Warning: HomeDir ${HOME_PATH} does not exist." + echo " Please create it and start again." + exit 2 + fi } download_jukebox_source() { From 1e41c21b6be781f4bff9679f5b1eeb4c06231aa2 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 19 Nov 2023 03:36:28 +0100 Subject: [PATCH 03/44] changes for docker tests --- installation/install-jukebox.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/installation/install-jukebox.sh b/installation/install-jukebox.sh index 17294f32e..9382e6c62 100755 --- a/installation/install-jukebox.sh +++ b/installation/install-jukebox.sh @@ -20,7 +20,8 @@ GIT_URL="https://github.com/${GIT_USER}/${GIT_REPO_NAME}" echo GIT_BRANCH $GIT_BRANCH echo GIT_URL $GIT_URL -CURRENT_USER="${SUDO_USER:-$USER}" +CURRENT_USER="${SUDO_USER:-$(whoami)}" +CURRENT_USER_GROUP=$(id -gn "$CURRENT_USER") HOME_PATH=$(getent passwd "$CURRENT_USER" | cut -d: -f6) echo "Current User: $CURRENT_USER" echo "User home dir: $HOME_PATH" @@ -80,8 +81,13 @@ download_jukebox_source() { checkPrerequisite ### RUN INSTALLATION +cd "${HOME_PATH}" INSTALLATION_LOGFILE="${HOME_PATH}/INSTALL-${INSTALL_ID}.log" -exec 3>&1 1>>"${INSTALLATION_LOGFILE}" 2>&1 || { echo "Cannot create log file. Panic."; exit 1; } +if [ "$CI_RUNNING" == "true" ]; then + exec 3>&1 2>&1 +else + exec 3>&1 1>>"${INSTALLATION_LOGFILE}" 2>&1 || { echo "Cannot create log file. Panic."; exit 1; } +fi echo "Log start: ${INSTALL_ID}" clear 1>&3 From cc4beeaf9c1d7805b9ed2c3c222d358df0f23201 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 19 Nov 2023 03:37:35 +0100 Subject: [PATCH 04/44] added verify functions --- installation/includes/02_helpers.sh | 184 +++++++++++++++++++++++++++- 1 file changed, 183 insertions(+), 1 deletion(-) diff --git a/installation/includes/02_helpers.sh b/installation/includes/02_helpers.sh index 9ad8e71b8..74d7595d4 100644 --- a/installation/includes/02_helpers.sh +++ b/installation/includes/02_helpers.sh @@ -47,12 +47,194 @@ check_os_type() { echo -e "\nChecking OS type '$os_type'" | tee /dev/fd/3 - if [[ $os_type == "armv7l" || $os_type == "armv6l" ]]; then + if [[ $os_type == "armv7l" || $os_type == "armv6l" ]]; then echo -e " ... OK!\n" | tee /dev/fd/3 else echo "ERROR: Only 32 bit operating systems supported. Please use a 32bit version of RaspianOS!" | tee /dev/fd/3 echo "You can fix this problem for 64bit kernels: https://github.com/MiczFlor/RPi-Jukebox-RFID/issues/2041" | tee /dev/fd/3 exit 1 fi +} + + +##### Check helpers + +# Check if the file(s) exists +verify_files_exists() { + local files="$@" + echo "Verify '${files}' exists" + + for file in $files + do + test ! -f ${file} && exit_on_error "ERROR: '${file}' does not exists or is not a file!" + done + echo "CHECK" +} + +# Check if the dir(s) exists +verify_dirs_exists() { + local dirs="$@" + echo "Verify '${dirs}' exists" + + for dir in $dirs + do + test ! -d ${dir} && exit_on_error "ERROR: '${dir}' does not exists or is not a dir!" + done + echo "CHECK" +} + + +# Check if the file(s) has/have the expected owner and modifications +verify_files_chmod_chown() { + local mod_expected=$1 + local user_expected=$2 + local group_expected=$3 + local files="${@:4}" + echo "Verify '${mod_expected}' '${user_expected}:${group_expected}' is set for '${files}'" + + for file in $files + do + test ! -f ${file} && exit_on_error "ERROR: '${file}' does not exists or is not a file!" + + mod_actual=$(stat --format '%a' "${file}") + user_actual=$(stat -c '%U' "${file}") + group_actual=$(stat -c '%G' "${file}") + test ! "${mod_expected}" -eq "${mod_actual}" && exit_on_error "ERROR: '${file}' actual mod '${mod_actual}' differs from expected '${mod_expected}'!" + test ! "${user_expected}" == "${user_actual}" && exit_on_error "ERROR: '${file}' actual owner '${user_actual}' differs from expected '${user_expected}'!" + test ! "${group_expected}" == "${group_actual}" && exit_on_error "ERROR: '${file}' actual group '${group_actual}' differs from expected '${group_expected}'!" + done + echo "CHECK" +} + +# Check if the dir(s) has/have the expected owner and modifications +verify_dirs_chmod_chown() { + local mod_expected=$1 + local user_expected=$2 + local group_expected=$3 + local dirs="${@:4}" + echo "Verify '${mod_expected}' '${user_expected}:${group_expected}' is set for '${dirs}'" + + for dir in $dirs + do + test ! -d ${dir} && exit_on_error "ERROR: '${dir}' does not exists or is not a dir!" + + mod_actual=$(stat --format '%a' "${dir}") + user_actual=$(stat -c '%U' "${dir}") + group_actual=$(stat -c '%G' "${dir}") + test ! "${mod_expected}" -eq "${mod_actual}" && exit_on_error "ERROR: '${dir}' actual mod '${mod_actual}' differs from expected '${mod_expected}'!" + test ! "${user_expected}" == "${user_actual}" && exit_on_error "ERROR: '${dir}' actual owner '${user_actual}' differs from expected '${user_expected}'!" + test ! "${group_expected}" == "${group_actual}" && exit_on_error "ERROR: '${dir}' actual group '${group_actual}' differs from expected '${group_expected}'!" + done + echo "CHECK" +} + +verify_file_contains_string() { + local string="$1" + local file="$2" + echo "Verify '${string}' found in '${file}'" + + if [[ ! $(grep -iw "${string}" "${file}") ]]; then + exit_on_error "ERROR: '${string}' not found in '${file}'" + fi + echo "CHECK" +} + +verify_file_contains_string_once() { + local string="$1" + local file="$2" + echo "Verify '${string}' found in '${file}'" + + local file_contains_string_count=$(grep -oiw "${string}" "${file}" | wc -l) + if [ "$file_contains_string_count" -lt 1 ]; then + exit_on_error "ERROR: '${string}' not found in '${file}'" + elif [ "$file_contains_string_count" -gt 1 ]; then + exit_on_error "ERROR: '${string}' found more than once in '${file}'" + fi + echo "CHECK" +} + +check_service_state() { + local service="$1" + local desired_state="$2" + local option="${3:+$3 }" # optional, dont't quote in next call! + echo "Verify service '${option}${service}' is '${desired_state}'" + + local actual_state=$(systemctl is-active ${option}${service}) + if [[ ! "${actual_state}" == "${desired_state}" ]]; then + exit_on_error "ERROR: service '${option}${service}' is not '${desired_state}' (state: '${actual_state}')." + fi + echo "CHECK" +} + +check_service_enablement() { + local service="$1" + local desired_enablement="$2" + local option="${3:+$3 }" # optional, dont't quote in next call! + echo "Verify service ${option}${service} is ${desired_enablement}" + + local actual_enablement=$(systemctl is-enabled ${option}${service}) + if [[ ! "${actual_enablement}" == "${desired_enablement}" ]]; then + exit_on_error "ERROR: service ${option}${service} is not ${desired_enablement} (state: ${actual_enablement})." + fi + echo "CHECK" +} + +check_optional_service_enablement() { + local service="$1" + local desired_enablement="$2" + local option="${3:+$3 }" # optional, dont't quote in next call! + echo "Verify service ${option}${service} is ${desired_enablement}" + + local actual_enablement=$(systemctl is-enabled ${option}${service}) 2>/dev/null + if [[ -z "${actual_enablement}" ]]; then + echo "INFO: optional service ${option}${service} is not installed." + elif [[ "${actual_enablement}" == "static" ]]; then + echo "INFO: optional service ${option}${service} is set static." + elif [[ ! "${actual_enablement}" == "${desired_enablement}" ]]; then + exit_on_error "ERROR: service ${option}${service} is not ${desired_enablement} (state: ${actual_enablement})." + fi + echo "CHECK" +} + +# Reads a textfile and returns all lines as args. +# Does filter out comments, egg-prefixes and version suffixes +# Arguments: +# 1 : textfile to read +get_args_from_file() { + local package_file="$1" + sed 's/.*#egg=//g' ${package_file} | sed -E 's/(#|=|>|<).*//g' | xargs echo +} + +# Check if all passed packages are installed. Fail on first missing. +verify_apt_packages() { + local packages="$@" + echo "Verify packages are installed: '${packages}'" + + if [ -n "${packages}" ]; then + local apt_list_installed=$(apt -qq list --installed 2>/dev/null) + for package in ${packages} + do + if [[ ! $(echo "${apt_list_installed}" | grep -i "^${package}/.*installed") ]]; then + exit_on_error "ERROR: ${package} is not installed" + fi + done + fi + echo "CHECK" +} + +# Check if all passed modules are installed. Fail on first missing. +verify_pip_modules() { + local modules="$@" + echo "Verify modules are installed: '${modules}'" + if [ -n "${modules}" ]; then + local pip_list_installed=$(pip list 2>/dev/null) + for module in ${modules} + do + if [[ ! $(echo "${pip_list_installed}" | grep -i "^${module} ") ]]; then + exit_on_error "ERROR: ${module} is not installed" + fi + done + fi + echo "CHECK" } From 592f6613d460ac1a1f61799bb6a156f046646dbe Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 19 Nov 2023 03:40:21 +0100 Subject: [PATCH 05/44] exit on failed update --- installation/routines/update_raspi_os.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installation/routines/update_raspi_os.sh b/installation/routines/update_raspi_os.sh index b7c356454..4f3f2d3d1 100644 --- a/installation/routines/update_raspi_os.sh +++ b/installation/routines/update_raspi_os.sh @@ -3,7 +3,7 @@ update_raspi_os() { echo "Updating Raspberry Pi OS" | tee /dev/fd/3 - sudo apt-get -qq -y update; sudo apt-get -qq -y full-upgrade; sudo apt-get -qq -y autoremove + sudo apt-get -qq -y update && sudo apt-get -qq -y full-upgrade && sudo apt-get -qq -y autoremove || exit_on_error "Failed to Update Raspberry Pi OS" echo "DONE: update_raspi_os" } From 616f859f46e77b9ca72098d44ed0cbec04c8b94a Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 19 Nov 2023 03:41:14 +0100 Subject: [PATCH 06/44] add check for samba setup --- installation/routines/setup_samba.sh | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/installation/routines/setup_samba.sh b/installation/routines/setup_samba.sh index 0914439b7..59b99f277 100644 --- a/installation/routines/setup_samba.sh +++ b/installation/routines/setup_samba.sh @@ -1,5 +1,8 @@ #!/usr/bin/env bash +SMB_CONF="/etc/samba/smb.conf" +SMB_CONF_HEADER="## Jukebox Samba Config" + _samba_install_os_dependencies() { echo "Install Samba Core dependencies" sudo apt-get -qq -y update; sudo apt-get -qq -y install \ @@ -11,12 +14,11 @@ _samba_install_os_dependencies() { } _samba_set_user() { - local SMB_CONF="/etc/samba/smb.conf" local SMB_USER="pi" local SMB_PASSWD="raspberry" # Samba has not been configured - if grep -q "## Jukebox Samba Config" "$SMB_CONF"; then + if grep -q "$SMB_CONF_HEADER" "$SMB_CONF"; then echo " Skipping. Already set up!" | tee /dev/fd/3 else # Create Samba user @@ -27,7 +29,7 @@ _samba_set_user() { # Create Samba Mount Points sudo cat << EOF >> $SMB_CONF -## Jukebox Samba Config +${SMB_CONF_HEADER} [phoniebox] comment= Pi Jukebox path=${SHARED_PATH} @@ -43,6 +45,16 @@ EOF fi } +_samba_check () { + echo "Check Samba Installation" | tee /dev/fd/3 + verify_apt_packages samba samba-common-bin + + verify_files_chmod_chown 644 root root "${SMB_CONF}" + + verify_file_contains_string "${SMB_CONF_HEADER}" "${SMB_CONF}" + verify_file_contains_string "${SHARED_PATH}" "${SMB_CONF}" +} + setup_samba() { echo "Install Samba and configure user" | tee /dev/fd/3 @@ -50,6 +62,7 @@ setup_samba() { echo "samba-common samba-common/dhcp boolean false" | sudo debconf-set-selections _samba_install_os_dependencies _samba_set_user + _samba_check echo "DONE: setup_samba" } From fc7a652a673a95937189340568a4c52784eeadf0 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 19 Nov 2023 03:44:00 +0100 Subject: [PATCH 07/44] add check for mpd setup --- installation/includes/00_constants.sh | 2 + installation/includes/01_default_config.sh | 1 + installation/routines/customize_options.sh | 26 +++++++++++ installation/routines/setup_mpd.sh | 52 ++++++++++------------ 4 files changed, 52 insertions(+), 29 deletions(-) diff --git a/installation/includes/00_constants.sh b/installation/includes/00_constants.sh index e19dd1327..4f96a0d33 100644 --- a/installation/includes/00_constants.sh +++ b/installation/includes/00_constants.sh @@ -2,6 +2,8 @@ RPI_BOOT_CONFIG_FILE="/boot/config.txt" SHARED_PATH="${INSTALLATION_PATH}/shared" SETTINGS_PATH="${SHARED_PATH}/settings" SYSTEMD_USR_PATH="/usr/lib/systemd/user" +# Do not change this directory! It must match MPDs expectation where to find the user configuration +MPD_CONF_PATH="${HOME}/.config/mpd/mpd.conf" # The default upstream user, release branch, and develop branch # These are used to prepare the repo for developers diff --git a/installation/includes/01_default_config.sh b/installation/includes/01_default_config.sh index eb6e45a91..d11171359 100644 --- a/installation/includes/01_default_config.sh +++ b/installation/includes/01_default_config.sh @@ -11,6 +11,7 @@ DISABLE_SSH_QOS=true DISABLE_BOOT_SCREEN=true DISABLE_BOOT_LOGS_PRINT=true SETUP_MPD=true +ENABLE_MPD_OVERWRITE_INSTALL=true UPDATE_RASPI_OS=${UPDATE_RASPI_OS:-"true"} ENABLE_SAMBA=true ENABLE_WEBAPP=true diff --git a/installation/routines/customize_options.sh b/installation/routines/customize_options.sh index d5ac7c547..6c572b62e 100644 --- a/installation/routines/customize_options.sh +++ b/installation/routines/customize_options.sh @@ -118,6 +118,31 @@ Do you want to disable Bluetooth? [Y/n]" 1>&3 echo "DISABLE_BLUETOOTH=${DISABLE_BLUETOOTH}" } +_option_mpd() { + if [[ "$SETUP_MPD" == true ]]; then + if [[ -f "${MPD_CONF_PATH}" || -f "${SYSTEMD_USR_PATH}/mpd.service" ]]; then + echo "-------------------------- MPD -------------------------- + +It seems there is a MPD already installed. +Note: It is important that MPD runs as a user service! +Would you like to overwrite your configuration? [Y/n]" 1>&3 + read -r response + case "$response" in + [nN][oO]|[nN]) + ENABLE_MPD_OVERWRITE_INSTALL=false + ;; + *) + ;; + esac + fi + fi + + echo "SETUP_MPD=${SETUP_MPD}" + if [ "$SETUP_MPD" == true ]; then + echo "ENABLE_MPD_OVERWRITE_INSTALL=${ENABLE_MPD_OVERWRITE_INSTALL}" + fi +} + _option_samba() { # ENABLE_SAMBA clear 1>&3 @@ -277,6 +302,7 @@ customize_options() { _option_autohotspot _option_bluetooth _option_disable_onboard_audio + _option_mpd _option_samba _option_webapp if [[ $ENABLE_WEBAPP == true ]] ; then diff --git a/installation/routines/setup_mpd.sh b/installation/routines/setup_mpd.sh index 53b9ac01b..0b976d231 100644 --- a/installation/routines/setup_mpd.sh +++ b/installation/routines/setup_mpd.sh @@ -3,13 +3,10 @@ AUDIOFOLDERS_PATH="${SHARED_PATH}/audiofolders" PLAYLISTS_PATH="${SHARED_PATH}/playlists" -# Do not change this directory! It must match MPDs expectation where to find the user configuration -MPD_CONF_PATH="$HOME/.config/mpd/mpd.conf" - _mpd_install_os_dependencies() { sudo apt-get -y update echo "Install MPD OS dependencies" - echo "Note: Installing MPD will cause a message: 'Job failed. See journalctl -xe for details'" + echo "Note: Installing MPD might cause a message: 'Job failed. See journalctl -xe for details'" echo "It can be ignored! It's an artefact of the MPD installation - nothing we can do about it." sudo apt-get -y install \ mpd mpc \ @@ -21,38 +18,35 @@ _mpd_install_os_dependencies() { _mpd_configure() { # MPD will be setup as user process (rather than a system-wide process) - mkdir -p ~/.config/mpd + mkdir -p $(dirname "$MPD_CONF_PATH") cp -f "${INSTALLATION_PATH}/resources/default-settings/mpd.default.conf" "${MPD_CONF_PATH}" # Prepare new mpd.conf sed -i 's|%%JUKEBOX_AUDIOFOLDERS_PATH%%|'"$AUDIOFOLDERS_PATH"'|' "${MPD_CONF_PATH}" sed -i 's|%%JUKEBOX_PLAYLISTS_PATH%%|'"$PLAYLISTS_PATH"'|' "${MPD_CONF_PATH}" +} + +_mpd_check () { + echo "Check MPD Installation" | tee /dev/fd/3 + verify_apt_packages mpd mpc + + verify_files_chmod_chown 755 "${CURRENT_USER}" "${CURRENT_USER_GROUP}" "${MPD_CONF_PATH}" + + verify_file_contains_string "${AUDIOFOLDERS_PATH}" "${MPD_CONF_PATH}" + verify_file_contains_string "${PLAYLISTS_PATH}" "${MPD_CONF_PATH}" + check_service_enablement mpd.socket disabled + check_service_enablement mpd.service disabled + + check_service_enablement mpd.socket enabled --user + check_service_enablement mpd.service enabled --user } setup_mpd() { echo "Install MPD" | tee /dev/fd/3 - local MPD_EXECUTE_INSTALL=true - - if [[ -f ${MPD_CONF_PATH} || -f ${SYSTEMD_USR_PATH}/mpd.service ]]; then - echo "It seems there is a MPD already installed. -Note: It is important that MPD runs as a user service! -Would you like to overwrite your configuration? [Y/n]" 1>&3 - read -r response - case "$response" in - [nN][oO]|[nN]) - MPD_EXECUTE_INSTALL=false - ;; - *) - ;; - esac - fi - - echo "MPD_EXECUTE_INSTALL=${MPD_EXECUTE_INSTALL}" - - if [[ $MPD_EXECUTE_INSTALL == true ]] ; then + if [[ $ENABLE_MPD_OVERWRITE_INSTALL == true ]] ; then # Install/update only if enabled: do not stuff up any existing configuration _mpd_install_os_dependencies @@ -60,16 +54,16 @@ Would you like to overwrite your configuration? [Y/n]" 1>&3 # Make sure system-wide mpd is disabled echo "Configure MPD as user local service" | tee /dev/fd/3 sudo systemctl stop mpd.socket - sudo systemctl stop mpd + sudo systemctl stop mpd.service sudo systemctl disable mpd.socket - sudo systemctl disable mpd + sudo systemctl disable mpd.service _mpd_configure # Prepare user-service MPD to be started at next boot systemctl --user daemon-reload systemctl --user enable mpd.socket - systemctl --user enable mpd - # Start MPD now, but not the socket: MPD is already started and we expect a reboot anyway - systemctl --user start mpd + systemctl --user enable mpd.service + + _mpd_check fi echo "DONE: setup_mpd" From 56ebfb548753294a96d0bbf12e53421ae2336efa Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 19 Nov 2023 03:45:43 +0100 Subject: [PATCH 08/44] add check for jukebox core setup --- installation/includes/00_constants.sh | 1 + installation/routines/setup_jukebox_core.sh | 44 +++++++++++++++++---- requirements.txt | 3 +- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/installation/includes/00_constants.sh b/installation/includes/00_constants.sh index 4f96a0d33..90e529fd1 100644 --- a/installation/includes/00_constants.sh +++ b/installation/includes/00_constants.sh @@ -2,6 +2,7 @@ RPI_BOOT_CONFIG_FILE="/boot/config.txt" SHARED_PATH="${INSTALLATION_PATH}/shared" SETTINGS_PATH="${SHARED_PATH}/settings" SYSTEMD_USR_PATH="/usr/lib/systemd/user" +VIRTUAL_ENV="${INSTALLATION_PATH}/.venv" # Do not change this directory! It must match MPDs expectation where to find the user configuration MPD_CONF_PATH="${HOME}/.config/mpd/mpd.conf" diff --git a/installation/routines/setup_jukebox_core.sh b/installation/routines/setup_jukebox_core.sh index e6dfa6d8f..dfbed6b64 100644 --- a/installation/routines/setup_jukebox_core.sh +++ b/installation/routines/setup_jukebox_core.sh @@ -9,6 +9,9 @@ GD_ID_COMPILED_PYZMQ_ARMV6="1lDsV_pVcXbg6YReHb9AldMkyRZCpc6-n" # https://drive.g ZMQ_TMP_DIR="libzmq" ZMQ_PREFIX="/usr/local" +JUKEBOX_PULSE_CONFIG="${HOME_PATH}"/.config/pulse/default.pa +JUKEBOX_SERVICE_NAME="${SYSTEMD_USR_PATH}/jukebox-daemon.service" + _show_slow_hardware_message() { echo " -------------------------------------------------------------------- | Your hardware is a little slower so this step will take a while. | @@ -27,6 +30,7 @@ _jukebox_core_install_os_dependencies() { espeak ffmpeg mpg123 \ pulseaudio pulseaudio-module-bluetooth pulseaudio-utils caps \ libasound2-dev \ + rsync \ --no-install-recommends \ --allow-downgrades \ --allow-remove-essential \ @@ -38,7 +42,6 @@ _jukebox_core_install_python_requirements() { cd "${INSTALLATION_PATH}" || exit_on_error - VIRTUAL_ENV="${INSTALLATION_PATH}/.venv" python3 -m venv $VIRTUAL_ENV source "$VIRTUAL_ENV/bin/activate" @@ -48,8 +51,8 @@ _jukebox_core_install_python_requirements() { _jukebox_core_configure_pulseaudio() { echo "Copy PulseAudio configuration" - mkdir -p ~/.config/pulse - cp -f "${INSTALLATION_PATH}/resources/default-settings/pulseaudio.default.pa" ~/.config/pulse/default.pa + mkdir -p $(dirname "$JUKEBOX_PULSE_CONFIG") + cp -f "${INSTALLATION_PATH}/resources/default-settings/pulseaudio.default.pa" "${JUKEBOX_PULSE_CONFIG}" } _jukebox_core_build_libzmq_with_drafts() { @@ -125,15 +128,41 @@ _jukebox_core_install_settings() { _jukebox_core_register_as_service() { echo " Register Jukebox Core user service" - local jukebox_service="${SYSTEMD_USR_PATH}/jukebox-daemon.service" - sudo cp -f "${INSTALLATION_PATH}/resources/default-services/jukebox-daemon.service" "${jukebox_service}" - sudo sed -i "s|%%INSTALLATION_PATH%%|${INSTALLATION_PATH}|g" "${jukebox_service}" - sudo chmod 644 "${jukebox_service}" + sudo cp -f "${INSTALLATION_PATH}/resources/default-services/jukebox-daemon.service" "${JUKEBOX_SERVICE_NAME}" + sudo sed -i "s|%%INSTALLATION_PATH%%|${INSTALLATION_PATH}|g" "${JUKEBOX_SERVICE_NAME}" + sudo chmod 644 "${JUKEBOX_SERVICE_NAME}" systemctl --user daemon-reload systemctl --user enable jukebox-daemon.service } +_jukebox_core_check () { + echo "Check Jukebox Core Installation" | tee /dev/fd/3 + verify_apt_packages at \ + alsa-utils \ + python3 python3-venv python3-dev \ + espeak ffmpeg mpg123 \ + pulseaudio pulseaudio-module-bluetooth pulseaudio-utils caps \ + libasound2-dev \ + rsync + + verify_dirs_exists "${VIRTUAL_ENV}" + + local pip_modules=$(get_args_from_file "${INSTALLATION_PATH}/requirements.txt") + verify_pip_modules pyzmq $pip_modules + + verify_files_chmod_chown 644 "${CURRENT_USER}" "${CURRENT_USER_GROUP}" "${JUKEBOX_PULSE_CONFIG}" + + verify_files_chmod_chown 644 "${CURRENT_USER}" "${CURRENT_USER_GROUP}" "${SETTINGS_PATH}/jukebox.yaml" + verify_files_chmod_chown 644 "${CURRENT_USER}" "${CURRENT_USER_GROUP}" "${SETTINGS_PATH}/logger.yaml" + + verify_files_chmod_chown 644 root root "${SYSTEMD_USR_PATH}/jukebox-daemon.service" + + verify_file_contains_string "${INSTALLATION_PATH}" "${JUKEBOX_SERVICE_NAME}" + + check_service_enablement jukebox-daemon.service enabled --user +} + setup_jukebox_core() { echo "Install Jukebox Core" | tee /dev/fd/3 @@ -143,6 +172,7 @@ setup_jukebox_core() { _jukebox_core_build_and_install_pyzmq _jukebox_core_install_settings _jukebox_core_register_as_service + _jukebox_core_check echo "DONE: setup_jukebox_core" } diff --git a/requirements.txt b/requirements.txt index f9f452799..0f8c8c86d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,7 @@ wheel evdev pyalsaaudio pulsectl -python_mpd2 +python-mpd2 ruamel.yaml # For playlistgenerator requests @@ -28,7 +28,6 @@ gpiozero # On regular Linux PCs, Websocket is enabled in the Python package # pyzmq - # Code quality flake8>=4.0.0 pytest From 6b79d8fce3e976aff9fec113c2de99513189b4b6 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 19 Nov 2023 03:46:01 +0100 Subject: [PATCH 09/44] add check for git setup --- installation/routines/setup_git.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/installation/routines/setup_git.sh b/installation/routines/setup_git.sh index 740d43ae3..7c48ec7d1 100644 --- a/installation/routines/setup_git.sh +++ b/installation/routines/setup_git.sh @@ -115,7 +115,7 @@ _git_convert_tardir_git_repo() { if [[ "${HASH_BRANCH}" != "${HASH_HEAD}" ]]; then echo "*** IMPORTANT NOTICE *******************************" echo "* Your requested branch has moved on while you were installing." - echo "* Don't worry! We will stay within the the exact download version!" + echo "* Don't worry! We will stay within the exact download version!" echo "* But we set up the git repo to be ready for updating." echo "* To start updating (observe updating guidelines!), do:" echo "* $ git pull origin $GIT_BRANCH" @@ -137,12 +137,20 @@ _git_convert_tardir_git_repo() { unset HASH_BRANCH } +_git_repo_check () { + echo "Check Git & repository installation" | tee /dev/fd/3 + + verify_apt_packages git + verify_dirs_chmod_chown 755 "${CURRENT_USER}" "${CURRENT_USER_GROUP}" "${INSTALLATION_PATH}/.git" +} + init_git_repo_from_tardir() { echo "Install Git & init repository" | tee /dev/fd/3 cd "${INSTALLATION_PATH}" || exit_on_error _git_install_os_dependencies _git_convert_tardir_git_repo + _git_repo_check echo "DONE: init_git_repo_from_tardir" } From 36bbd528c218bc49c8a689ead1a7e8711d177e56 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 19 Nov 2023 03:47:17 +0100 Subject: [PATCH 10/44] add check for kiosk mode setup --- installation/routines/customize_options.sh | 1 - installation/routines/setup_kiosk_mode.sh | 41 ++++++++++++++++++---- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/installation/routines/customize_options.sh b/installation/routines/customize_options.sh index 6c572b62e..5de18cf17 100644 --- a/installation/routines/customize_options.sh +++ b/installation/routines/customize_options.sh @@ -158,7 +158,6 @@ Do you want to install Samba? [Y/n]" 1>&3 case "$response" in [nN][oO]|[nN]) ENABLE_SAMBA=false - ENABLE_KIOSK_MODE=false ;; *) ;; diff --git a/installation/routines/setup_kiosk_mode.sh b/installation/routines/setup_kiosk_mode.sh index b2857b624..7864e020a 100644 --- a/installation/routines/setup_kiosk_mode.sh +++ b/installation/routines/setup_kiosk_mode.sh @@ -1,5 +1,11 @@ #!/usr/bin/env bash +KIOSK_MODE_CONF_HEADER="## Jukebox Kiosk Mode" +KIOSK_MODE_XINITRC='/etc/xdg/openbox/autostart' +KIOSK_MODE_BASHRC="${HOME_PATH}/.bashrc" +KIOSK_MODE_CHROMIUM_CUSTOM_DISABLE_UPDATE_CHECK='/etc/chromium-browser/customizations/01-disable-update-check' +KIOSK_MODE_CHROMIUM_FLAG_UPDATE_INTERVAL='--check-for-update-interval=31536000' + _kiosk_mode_install_os_dependencies() { # Resource: # https://blog.r0b.io/post/minimal-rpi-kiosk/ @@ -14,17 +20,17 @@ _kiosk_mode_install_os_dependencies() { _kiosk_mode_set_autostart() { local _DISPLAY='$DISPLAY' local _XDG_VTNR='$XDG_VTNR' - cat << EOF >> /home/pi/.bashrc -## Jukebox kiosk autostart + tee -a "${KIOSK_MODE_BASHRC}" <<-EOF + +${KIOSK_MODE_CONF_HEADER} [[ -z $_DISPLAY && $_XDG_VTNR -eq 1 ]] && startx -- -nocursor EOF - local XINITRC='/etc/xdg/openbox/autostart' - cat << EOF | sudo tee -a $XINITRC + sudo tee -a "${KIOSK_MODE_XINITRC}" <<-EOF -## Jukebox Kiosk Mode +${KIOSK_MODE_CONF_HEADER} # Disable any form of screen saver / screen blanking / power management xset s off xset s noblank @@ -46,8 +52,30 @@ EOF _kiosk_mode_update_settings() { # Resource: https://github.com/Thyraz/Sonos-Kids-Controller/blob/d1f061f4662c54ae9b8dc8b545f9c3ba39f670eb/README.md#kiosk-mode-installation - sudo touch /etc/chromium-browser/customizations/01-disable-update-check;echo CHROMIUM_FLAGS=\"\$\{CHROMIUM_FLAGS\} --check-for-update-interval=31536000\" | sudo tee /etc/chromium-browser/customizations/01-disable-update-check + sudo mkdir -p $(dirname "${KIOSK_MODE_CHROMIUM_CUSTOM_DISABLE_UPDATE_CHECK}") + sudo rm -f "${KIOSK_MODE_CHROMIUM_CUSTOM_DISABLE_UPDATE_CHECK}" + sudo tee -a "${KIOSK_MODE_CHROMIUM_CUSTOM_DISABLE_UPDATE_CHECK}" <<-EOF +${KIOSK_MODE_CONF_HEADER} +CHROMIUM_FLAGS=\"\$\{CHROMIUM_FLAGS\} --check-for-update-interval=31536000\" +EOF +} + +_kiosk_mode_check () { + echo "Check Kiosk Mode Installation" | tee /dev/fd/3 + verify_apt_packages xserver-xorg \ + x11-xserver-utils \ + xinit \ + openbox \ + chromium-browser + + verify_files_exists "${KIOSK_MODE_BASHRC}" + verify_file_contains_string "${KIOSK_MODE_CONF_HEADER}" "${KIOSK_MODE_BASHRC}" + + verify_files_exists "${KIOSK_MODE_XINITRC}" + verify_file_contains_string "${KIOSK_MODE_CONF_HEADER}" "${KIOSK_MODE_XINITRC}" + verify_files_exists "${KIOSK_MODE_CHROMIUM_CUSTOM_DISABLE_UPDATE_CHECK}" + verify_file_contains_string "${KIOSK_MODE_CONF_HEADER}" "${KIOSK_MODE_CHROMIUM_CUSTOM_DISABLE_UPDATE_CHECK}" } setup_kiosk_mode() { @@ -56,6 +84,7 @@ setup_kiosk_mode() { _kiosk_mode_install_os_dependencies _kiosk_mode_set_autostart _kiosk_mode_update_settings + _kiosk_mode_check echo "DONE: setup_kiosk_mode" } From fec3c34905b52d48a5e1472d8a6e3c61537eea56 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 19 Nov 2023 03:54:15 +0100 Subject: [PATCH 11/44] add check for optimize boot setup --- installation/includes/00_constants.sh | 1 + installation/routines/optimize_boot_time.sh | 86 +++++++++++++++++---- 2 files changed, 73 insertions(+), 14 deletions(-) diff --git a/installation/includes/00_constants.sh b/installation/includes/00_constants.sh index 90e529fd1..380e1de2e 100644 --- a/installation/includes/00_constants.sh +++ b/installation/includes/00_constants.sh @@ -1,4 +1,5 @@ RPI_BOOT_CONFIG_FILE="/boot/config.txt" +RPI_BOOT_CMDLINE_FILE="/boot/cmdline.txt" SHARED_PATH="${INSTALLATION_PATH}/shared" SETTINGS_PATH="${SHARED_PATH}/settings" SYSTEMD_USR_PATH="/usr/lib/systemd/user" diff --git a/installation/routines/optimize_boot_time.sh b/installation/routines/optimize_boot_time.sh index 2fea66a86..29983930c 100644 --- a/installation/routines/optimize_boot_time.sh +++ b/installation/routines/optimize_boot_time.sh @@ -2,6 +2,12 @@ # Reference: https://panther.software/configuration-code/raspberry-pi-3-4-faster-boot-time-in-few-easy-steps/ +OPTIMIZE_DHCP_CONF="/etc/dhcpcd.conf" +OPTIMIZE_BOOT_CMDLINE_OPTIONS="consoleblank=1 logo.nologo quiet loglevel=0 plymouth.enable=0 vt.global_cursor_default=0 plymouth.ignore-serial-consoles splash fastboot noatime nodiratime noram" +OPTIMIZE_DHCP_CONF_HEADER="## Jukebox DHCP Config" +OPTIMIZE_IPV6_CONF_HEADER="## Jukebox IPV6 Config" +OPTIMIZE_BOOT_CONF_HEADER="## Jukebox Boot Config" + _optimize_disable_irrelevant_services() { echo " * Disable keyboard-setup.service" sudo systemctl disable keyboard-setup.service @@ -32,11 +38,9 @@ _optimize_handle_bluetooth() { # TODO: Allow options to enable/disable wifi, Dynamic/Static IP etc. _optimize_handle_network_connection() { # Static IP Address and DHCP optimizations - local DHCP_CONF="/etc/dhcpcd.conf" - if [ "$ENABLE_STATIC_IP" = true ] ; then echo " * Set static IP address" | tee /dev/fd/3 - if grep -q "## Jukebox DHCP Config" "$DHCP_CONF"; then + if grep -q "${OPTIMIZE_DHCP_CONF_HEADER}" "$OPTIMIZE_DHCP_CONF"; then echo " Skipping. Already set up!" | tee /dev/fd/3 else # DHCP has not been configured @@ -44,9 +48,9 @@ _optimize_handle_network_connection() { echo " * ${CURRENT_GATEWAY} is the Router Gateway address" | tee /dev/fd/3 echo " * Using ${CURRENT_IP_ADDRESS} as the static IP for now" | tee /dev/fd/3 - sudo tee -a $DHCP_CONF <<-EOF + sudo tee -a $OPTIMIZE_DHCP_CONF <<-EOF -## Jukebox DHCP Config +${OPTIMIZE_DHCP_CONF_HEADER} interface ${CURRENT_INTERFACE} static ip_address=${CURRENT_IP_ADDRESS}/24 static routers=${CURRENT_GATEWAY} @@ -63,16 +67,19 @@ EOF # TODO: Allow both Enable and Disable _optimize_ipv6_arp() { if [ "$DISABLE_IPv6" = true ] ; then - echo " * Disabling IPV6 and ARP" - sudo tee -a $DHCP_CONF <<-EOF + echo " * Disabling IPV6 and ARP" + if grep -q "${OPTIMIZE_IPV6_CONF_HEADER}" "$OPTIMIZE_DHCP_CONF"; then + echo " Skipping. Already set up!" | tee /dev/fd/3 + else + sudo tee -a $OPTIMIZE_DHCP_CONF <<-EOF -## Jukebox boot speed-up settings +${OPTIMIZE_IPV6_CONF_HEADER} noarp ipv4only noipv6 EOF - + fi fi } @@ -80,13 +87,16 @@ EOF _optimize_handle_boot_screen() { if [ "$DISABLE_BOOT_SCREEN" = true ] ; then echo " * Disable RPi rainbow screen" - BOOT_CONFIG='/boot/config.txt' - sudo tee -a $BOOT_CONFIG <<-EOF + if grep -q "${OPTIMIZE_BOOT_CONF_HEADER}" "$RPI_BOOT_CONFIG_FILE"; then + echo " Skipping. Already set up!" | tee /dev/fd/3 + else + sudo tee -a $RPI_BOOT_CONFIG_FILE <<-EOF -## Jukebox Settings +${OPTIMIZE_BOOT_CONF_HEADER} disable_splash=1 EOF + fi fi } @@ -94,11 +104,58 @@ EOF _optimize_handle_boot_logs() { if [ "$DISABLE_BOOT_LOGS_PRINT" = true ] ; then echo " * Disable boot logs" - BOOT_CMDLINE='/boot/cmdline.txt' - sudo sed -i "$ s/$/ consoleblank=1 logo.nologo quiet loglevel=0 plymouth.enable=0 vt.global_cursor_default=0 plymouth.ignore-serial-consoles splash fastboot noatime nodiratime noram/" $BOOT_CMDLINE + + if [ ! -s "${RPI_BOOT_CMDLINE_FILE}" ];then + sudo tee $RPI_BOOT_CMDLINE_FILE <<-EOF +${OPTIMIZE_BOOT_CMDLINE_OPTIONS} +EOF + else + for option in $OPTIMIZE_BOOT_CMDLINE_OPTIONS + do + if ! $(grep -iw "$option" "${RPI_BOOT_CMDLINE_FILE}") ; then + sudo sed -i "s/$/ $option/" "${RPI_BOOT_CMDLINE_FILE}" + fi + done + fi fi } + +_optimize_check () { + echo "Check Optimize boot time" | tee /dev/fd/3 + + check_optional_service_enablement keyboard-setup.service disabled + check_optional_service_enablement triggerhappy.service disabled + check_optional_service_enablement triggerhappy.socket disabled + check_optional_service_enablement raspi-config.service disabled + check_optional_service_enablement apt-daily.service disabled + check_optional_service_enablement apt-daily-upgrade.service disabled + check_optional_service_enablement apt-daily.timer disabled + check_optional_service_enablement apt-daily-upgrade.timer disabled + + if [ "$DISABLE_BLUETOOTH" = true ] ; then + check_optional_service_enablement hciuart.service disabled + check_optional_service_enablement bluetooth.service disabled + fi + + if [ "$ENABLE_STATIC_IP" = true ] ; then + verify_file_contains_string_once "${OPTIMIZE_DHCP_CONF_HEADER}" "${OPTIMIZE_DHCP_CONF}" + fi + if [ "$DISABLE_IPv6" = true ] ; then + verify_file_contains_string_once "${OPTIMIZE_IPV6_CONF_HEADER}" "${OPTIMIZE_DHCP_CONF}" + fi + if [ "$DISABLE_BOOT_SCREEN" = true ] ; then + verify_file_contains_string_once "${OPTIMIZE_BOOT_CONF_HEADER}" "${RPI_BOOT_CONFIG_FILE}" + fi + + if [ "$DISABLE_BOOT_LOGS_PRINT" = true ] ; then + for option in $OPTIMIZE_BOOT_CMDLINE_OPTIONS + do + verify_file_contains_string_once $option "${RPI_BOOT_CMDLINE_FILE}" + done + fi +} + optimize_boot_time() { echo "Optimize boot time" | tee /dev/fd/3 @@ -108,6 +165,7 @@ optimize_boot_time() { _optimize_ipv6_arp _optimize_handle_boot_screen _optimize_handle_boot_logs + _optimize_check echo "DONE: optimize_boot_time" } From 856af317b4cf4ab4f36baca5490c4c15e060891d Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 19 Nov 2023 03:55:00 +0100 Subject: [PATCH 12/44] add check for webapp setup --- installation/routines/customize_options.sh | 9 +++---- installation/routines/setup_jukebox_webapp.sh | 24 +++++++++++++++---- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/installation/routines/customize_options.sh b/installation/routines/customize_options.sh index 5de18cf17..22d6e45d6 100644 --- a/installation/routines/customize_options.sh +++ b/installation/routines/customize_options.sh @@ -261,13 +261,13 @@ Disable Pi's on-chip audio (headphone / jack output)? [y/N]" 1>&3 _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" ]]; then + if [[ "$GIT_BRANCH" != "${GIT_BRANCH_RELEASE}" || "$GIT_USER" != "$GIT_UPSTREAM_USER" || "$CI_RUNNING" == "true" ]]; then ENABLE_INSTALL_NODE=true # 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 + 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" == false ]]; then clear 1>&3 echo "--------------------- WEBAPP NODE --------------------- @@ -285,10 +285,11 @@ Do you want to install Node? [Y/n]" 1>&3 ;; esac # This message will be displayed at the end of the installation process - FIN_MESSAGE="$FIN_MESSAGE\nATTENTION: You need to build the web app locally with + 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}" fi fi } diff --git a/installation/routines/setup_jukebox_webapp.sh b/installation/routines/setup_jukebox_webapp.sh index a0e195622..d42dca916 100644 --- a/installation/routines/setup_jukebox_webapp.sh +++ b/installation/routines/setup_jukebox_webapp.sh @@ -2,6 +2,7 @@ # Constants GD_ID_COMPILED_WEBAPP="1EE_1MdneGtKL5V7GyYZC0nb6ODQWTsPb" # https://drive.google.com/file/d/1EE_1MdneGtKL5V7GyYZC0nb6ODQWTsPb/view?usp=sharing +WEBAPP_NGINX_SITE_DEFAULT_CONF="/etc/nginx/sites-available/default" # For ARMv7+ NODE_MAJOR=20 @@ -70,15 +71,27 @@ _jukebox_webapp_register_as_system_service_with_nginx() { sudo apt-get -y purge apache2 sudo apt-get -y install nginx - sudo service nginx start - - sudo mv -f /etc/nginx/sites-available/default /etc/nginx/sites-available/default.orig - sudo cp -f "${INSTALLATION_PATH}/resources/default-settings/nginx.default" /etc/nginx/sites-available/default + sudo mv -f "${WEBAPP_NGINX_SITE_DEFAULT_CONF}" "${WEBAPP_NGINX_SITE_DEFAULT_CONF}.orig" + sudo cp -f "${INSTALLATION_PATH}/resources/default-settings/nginx.default" "${WEBAPP_NGINX_SITE_DEFAULT_CONF}" # make sure nginx can access the home directory of the user sudo chmod o+x /home/pi +} + +_jukebox_webapp_check () { + echo "Check WebApp Installation" | tee /dev/fd/3 + + 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 + fi + + verify_apt_packages nginx + verify_files_exists "${WEBAPP_NGINX_SITE_DEFAULT_CONF}" - sudo service nginx restart + check_service_enablement nginx.service enabled } setup_jukebox_webapp() { @@ -94,6 +107,7 @@ setup_jukebox_webapp() { # _jukebox_webapp_build fi _jukebox_webapp_register_as_system_service_with_nginx + _jukebox_webapp_check echo "DONE: setup_jukebox_webapp" } From 87f3549450f8ad8da9ef493224accabdfc4e1d89 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 19 Nov 2023 03:55:50 +0100 Subject: [PATCH 13/44] add check for autohotspot setup --- installation/routines/setup_autohotspot.sh | 48 +++++++++++++++++----- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/installation/routines/setup_autohotspot.sh b/installation/routines/setup_autohotspot.sh index 214a90e0f..4279c1ca4 100644 --- a/installation/routines/setup_autohotspot.sh +++ b/installation/routines/setup_autohotspot.sh @@ -1,12 +1,18 @@ #!/usr/bin/env bash +AUTOHOTSPOT_HOSTAPD_CONF_FILE="/etc/hostapd/hostapd.conf" +AUTOHOTSPOT_HOSTAPD_DAEMON_CONF_FILE="/etc/default/hostapd" +AUTOHOTSPOT_DNSMASQ_CONF_FILE="/etc/dnsmasq.conf" +AUTOHOTSPOT_DHCPD_CONF_FILE="/etc/dhcpcd.conf" + +AUTOHOTSPOT_TARGET_PATH="/usr/bin/autohotspot" + _get_interface() { # interfaces may vary WIFI_INTERFACE=$(iw dev | grep "Interface"| awk '{ print $2 }') WIFI_REGION=$(iw reg get | grep country | awk '{ print $2}' | cut -d: -f1) } - _install_packages() { sudo apt-get -y install hostapd dnsmasq @@ -17,18 +23,18 @@ _install_packages() { } _configure_hostapd() { - HOSTAPD_CUSTOM_FILE="${INSTALLATION_PATH}"/resources/autohotspot/hostapd.conf - HOSTAPD_CONF_FILE="/etc/hostapd/hostapd.conf" + local HOSTAPD_CUSTOM_FILE="${INSTALLATION_PATH}"/resources/autohotspot/hostapd.conf + sed -i "s/WIFI_INTERFACE/${WIFI_INTERFACE}/g" "${HOSTAPD_CUSTOM_FILE}" sed -i "s/AUTOHOTSPOT_PASSWORD/${AUTOHOTSPOT_PASSWORD}/g" "${HOSTAPD_CUSTOM_FILE}" sed -i "s/WIFI_REGION/${WIFI_REGION}/g" "${HOSTAPD_CUSTOM_FILE}" - sudo cp "${HOSTAPD_CUSTOM_FILE}" "${HOSTAPD_CONF_FILE}" + sudo cp "${HOSTAPD_CUSTOM_FILE}" "${AUTOHOTSPOT_HOSTAPD_CONF_FILE}" - sudo sed -i "s@^#DAEMON_CONF=.*@DAEMON_CONF=\"${HOSTAPD_CONF_FILE}\"@g" /etc/default/hostapd + sudo sed -i "s@^#DAEMON_CONF=.*@DAEMON_CONF=\"${AUTOHOTSPOT_HOSTAPD_CONF_FILE}\"@g" "${AUTOHOTSPOT_HOSTAPD_DAEMON_CONF_FILE}" } _configure_dnsmasq() { - sudo tee -a /etc/dnsmasq.conf <<-EOF + sudo tee -a "${AUTOHOTSPOT_DNSMASQ_CONF_FILE}" <<-EOF #AutoHotspot Config #stop DNSmasq from using resolv.conf no-resolv @@ -42,7 +48,7 @@ EOF _other_configuration() { sudo mv /etc/network/interfaces /etc/network/interfaces.bak sudo touch /etc/network/interfaces - echo nohook wpa_supplicant | sudo tee -a /etc/dhcpcd.conf + echo nohook wpa_supplicant | sudo tee -a "${AUTOHOTSPOT_DHCPD_CONF_FILE}" } _install_service_and_timer() { @@ -52,9 +58,30 @@ _install_service_and_timer() { } _install_autohotspot_script() { - TARGET_PATH="/usr/bin/autohotspot" - sudo cp "${INSTALLATION_PATH}"/resources/autohotspot/autohotspot "${TARGET_PATH}" - sudo chmod +x "${TARGET_PATH}" + sudo cp "${INSTALLATION_PATH}"/resources/autohotspot/autohotspot "${AUTOHOTSPOT_TARGET_PATH}" + sudo chmod +x "${AUTOHOTSPOT_TARGET_PATH}" +} + + +_autohotspot_check () { + echo "Check AutoHotspot Installation" | tee /dev/fd/3 + + verify_apt_packages hostapd dnsmasq + + check_service_enablement hostapd.service disabled + check_service_enablement dnsmasq.service disabled + check_service_enablement autohotspot.service enabled + + verify_files_exists "/etc/cron.d/autohotspot" + verify_files_exists "${AUTOHOTSPOT_TARGET_PATH}" + + verify_file_contains_string "${WIFI_INTERFACE}" "${AUTOHOTSPOT_HOSTAPD_CONF_FILE}" + verify_file_contains_string "${AUTOHOTSPOT_PASSWORD}" "${AUTOHOTSPOT_HOSTAPD_CONF_FILE}" + verify_file_contains_string "${WIFI_REGION}" "${AUTOHOTSPOT_HOSTAPD_CONF_FILE}" + verify_file_contains_string "${AUTOHOTSPOT_HOSTAPD_CONF_FILE}" "${AUTOHOTSPOT_HOSTAPD_DAEMON_CONF_FILE}" + + verify_file_contains_string "${WIFI_INTERFACE}" "${AUTOHOTSPOT_DNSMASQ_CONF_FILE}" + verify_file_contains_string "nohook wpa_supplicant" "${AUTOHOTSPOT_DHCPD_CONF_FILE}" } setup_autohotspot() { @@ -69,6 +96,7 @@ setup_autohotspot() { _other_configuration _install_autohotspot_script _install_service_and_timer + _autohotspot_check echo "DONE: setup_autohotspot" } From 5687fa62b4bb5fe9561246f4b621b17e13132f11 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 19 Nov 2023 03:56:37 +0100 Subject: [PATCH 14/44] make rfid reader setup an optional step --- installation/includes/01_default_config.sh | 1 + installation/routines/customize_options.sh | 23 ++++++++++++++++++++++ installation/routines/install.sh | 2 +- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/installation/includes/01_default_config.sh b/installation/includes/01_default_config.sh index d11171359..b2f37a1de 100644 --- a/installation/includes/01_default_config.sh +++ b/installation/includes/01_default_config.sh @@ -13,6 +13,7 @@ DISABLE_BOOT_LOGS_PRINT=true SETUP_MPD=true ENABLE_MPD_OVERWRITE_INSTALL=true UPDATE_RASPI_OS=${UPDATE_RASPI_OS:-"true"} +ENABLE_RFID_READER=true ENABLE_SAMBA=true ENABLE_WEBAPP=true ENABLE_KIOSK_MODE=false diff --git a/installation/routines/customize_options.sh b/installation/routines/customize_options.sh index 22d6e45d6..ba9894661 100644 --- a/installation/routines/customize_options.sh +++ b/installation/routines/customize_options.sh @@ -143,6 +143,28 @@ Would you like to overwrite your configuration? [Y/n]" 1>&3 fi } +_option_rfid_reader() { + # ENABLE_RFID_READER + clear 1>&3 + echo "---------------------- RFID READER ---------------------- + +Phoniebox can be controlled with rfid cards/tags, if you +have a rfid reader connected. +Choose yes to setup a reader. You get prompted for +the type selection and configuration later on. + +Do you want to setup a rfid reader? [Y/n]" 1>&3 + read -r response + case "$response" in + [nN][oO]|[nN]) + ENABLE_RFID_READER=false + ;; + *) + ;; + esac + echo "ENABLE_RFID_READER=${ENABLE_RFID_READER}" +} + _option_samba() { # ENABLE_SAMBA clear 1>&3 @@ -303,6 +325,7 @@ customize_options() { _option_bluetooth _option_disable_onboard_audio _option_mpd + _option_rfid_reader _option_samba _option_webapp if [[ $ENABLE_WEBAPP == true ]] ; then diff --git a/installation/routines/install.sh b/installation/routines/install.sh index ca25a17a3..f00b2d1b8 100644 --- a/installation/routines/install.sh +++ b/installation/routines/install.sh @@ -12,7 +12,7 @@ install() { if [ "$ENABLE_SAMBA" = true ] ; then setup_samba; fi; if [ "$ENABLE_WEBAPP" = true ] ; then setup_jukebox_webapp; fi; if [ "$ENABLE_KIOSK_MODE" = true ] ; then setup_kiosk_mode; fi; - setup_rfid_reader + if [ "$ENABLE_RFID_READER" = true ] ; then setup_rfid_reader; fi; optimize_boot_time if [ "$ENABLE_AUTOHOTSPOT" = true ] ; then setup_autohotspot; fi; cleanup From e91a37eddf98ce2bbd7e14269d9df70b902a872c Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 19 Nov 2023 03:57:00 +0100 Subject: [PATCH 15/44] Add Option for No Rfid Reader --- .../components/rfid/configure/__init__.py | 60 ++++++++++++------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/src/jukebox/components/rfid/configure/__init__.py b/src/jukebox/components/rfid/configure/__init__.py index 7f9e232f2..88f5d6cb2 100755 --- a/src/jukebox/components/rfid/configure/__init__.py +++ b/src/jukebox/components/rfid/configure/__init__.py @@ -115,16 +115,18 @@ def query_user_for_reader(dependency_install='query') -> dict: package_dir = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + '/../hardware') logger.debug(f"Package location: {package_dir}") # For known included readers, specify manual order - included_readers = ['generic_usb', 'rdm6300_serial', 'rc522_spi', 'pn532_i2c_py532', 'fake_reader_gui'] + no_rfid_reader = 'No RFID Reader' + included_readers = [no_rfid_reader, 'generic_usb', 'rdm6300_serial', 'rc522_spi', 'pn532_i2c_py532', 'fake_reader_gui'] # Get all local directories (i.e subpackages) that conform to naming/structuring convention (except known readers) # Naming convention: modname/modname.py - reader_dirs = [x for x in os.listdir(package_dir) + additional_readers = [x for x in os.listdir(package_dir) if (os.path.isdir(package_dir + '/' + x) and os.path.exists(package_dir + '/' + x + '/' + x + '.py') and os.path.isfile(package_dir + '/' + x + '/' + x + '.py') and not x.endswith('template_new_reader') and x not in included_readers)] - reader_dirs = [*included_readers, *sorted(reader_dirs, key=lambda x: x.casefold())] + reader_dirs = [*included_readers, *sorted(additional_readers, key=lambda x: x.casefold())] + logger.debug(f"reader_dirs = {reader_dirs}") # Try to load the description modules from all valid directories (as this has no dependencies) @@ -132,22 +134,29 @@ def query_user_for_reader(dependency_install='query') -> dict: reader_description_modules = [] reader_descriptions = [] for reader_type in reader_dirs: - try: - reader_description_modules.append(importlib.import_module('components.rfid.hardware.' + reader_type - + '.description', 'pkg.subpkg')) - reader_descriptions.append(reader_description_modules[-1].DESCRIPTION) - except ModuleNotFoundError: - # The developer for this reader simply omitted to provide a description module - # Or there is no valid module in this directory, despite correct naming scheme. But this we will only find out - # later, because we want to be as lenient as possible and don't already load and check reader modules the user is - # not selecting (and thus no interested in) - logger.warning(f"No module 'description.py' available for reader subpackage '{reader_type}'") - reader_descriptions.append('(No description provided!)') - except AttributeError: - # The module loaded ok, but has no identifier 'DESCRIPTION' - logger.warning(f"Module 'description.py' of reader subpackage '{reader_type}' is missing 'DESCRIPTION'. " - f"Spelling error?") - reader_descriptions.append('(No description provided!)') + if reader_type == no_rfid_reader: + # Add Option to not add a RFid Reader + reader_description_modules.append(no_rfid_reader) + reader_descriptions.append(no_rfid_reader) + else: + reader_description_modules.append(f"{reader_type + '/' + reader_type + '.py'}") + try: + reader_description = (importlib.import_module('components.rfid.hardware.' + reader_type + + '.description', 'pkg.subpkg')) + reader_descriptions.append(reader_description.DESCRIPTION) + except ModuleNotFoundError: + # The developer for this reader simply omitted to provide a description module + # Or there is no valid module in this directory, despite correct naming scheme. + # But this we will only find out later, because we want to be as lenient as possible + # and don't already load and check reader modules the user is + # not selecting (and thus no interested in) + logger.warning(f"No module 'description.py' available for reader subpackage '{reader_type}'") + reader_descriptions.append('(No description provided!)') + except AttributeError: + # The module loaded ok, but has no identifier 'DESCRIPTION' + logger.warning(f"Module 'description.py' of reader subpackage '{reader_type}' is missing 'DESCRIPTION'. " + f"Spelling error?") + reader_descriptions.append('(No description provided!)') # Prepare the configuration collector with the base values config_dict = {'rfid': {'readers': {}}} @@ -157,14 +166,21 @@ def query_user_for_reader(dependency_install='query') -> dict: while True: # List all modules and query user print("Choose Reader Module from list:\n") - for idx, (des, mod) in enumerate(zip(reader_descriptions, reader_dirs)): + for idx, (des, mod) in enumerate(zip(reader_descriptions, reader_description_modules)): print(f" {Colors.lightgreen}{idx:2d}{Colors.reset}: {Colors.lightcyan}{Colors.bold}{des:40s}{Colors.reset} " - f"(Module: {mod + '/' + mod + '.py'})") + f"(Module: {mod})") print("") reader_id = pyil.input_int("Reader module number?", min=0, max=len(reader_descriptions) - 1, prompt_color=Colors.lightgreen, prompt_hint=True) + # The (short) name of the selected reader module, which is identical to the directory name - reader_select_name.append(reader_dirs[reader_id]) + reader_selected = reader_dirs[reader_id] + print(f"Reader selected: '{reader_selected}'") + if reader_selected == no_rfid_reader: + logger.debug(f"'{no_rfid_reader}' selected. skip") + break + + reader_select_name.append(reader_selected) # If this reader has not been selected before, auto install dependencies if reader_select_name[-1] not in reader_select_name[:-1]: From bbb72d08afd4b94e01166ca624a6c7a476c3fc27 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 19 Nov 2023 04:00:38 +0100 Subject: [PATCH 16/44] moved setup checks to individual scripts --- installation/routines/install.sh | 16 +++---- installation/routines/set_ssh_qos.sh | 12 +++-- installation/routines/setup_autohotspot.sh | 30 ++++++------ installation/routines/setup_jukebox_webapp.sh | 32 +++++++------ installation/routines/setup_kiosk_mode.sh | 14 +++--- installation/routines/setup_mpd.sh | 48 ++++++++++--------- installation/routines/setup_rfid_reader.sh | 8 ++-- installation/routines/setup_samba.sh | 16 ++++--- installation/routines/update_raspi_os.sh | 8 ++-- 9 files changed, 100 insertions(+), 84 deletions(-) diff --git a/installation/routines/install.sh b/installation/routines/install.sh index f00b2d1b8..3dfe14fe5 100644 --- a/installation/routines/install.sh +++ b/installation/routines/install.sh @@ -4,16 +4,16 @@ install() { customize_options clear 1>&3 set_raspi_config - if [ "$DISABLE_SSH_QOS" = true ] ; then set_ssh_qos; fi; - if [ "$UPDATE_RASPI_OS" = true ] ; then update_raspi_os; fi; + set_ssh_qos + update_raspi_os init_git_repo_from_tardir setup_jukebox_core - if [ "$SETUP_MPD" = true ] ; then setup_mpd; fi; - if [ "$ENABLE_SAMBA" = true ] ; then setup_samba; fi; - if [ "$ENABLE_WEBAPP" = true ] ; then setup_jukebox_webapp; fi; - if [ "$ENABLE_KIOSK_MODE" = true ] ; then setup_kiosk_mode; fi; - if [ "$ENABLE_RFID_READER" = true ] ; then setup_rfid_reader; fi; + setup_mpd + setup_samba + setup_jukebox_webapp + setup_kiosk_mode + setup_rfid_reader optimize_boot_time - if [ "$ENABLE_AUTOHOTSPOT" = true ] ; then setup_autohotspot; fi; + setup_autohotspot cleanup } diff --git a/installation/routines/set_ssh_qos.sh b/installation/routines/set_ssh_qos.sh index ad67ddc41..793d96e05 100644 --- a/installation/routines/set_ssh_qos.sh +++ b/installation/routines/set_ssh_qos.sh @@ -1,9 +1,11 @@ #!/usr/bin/env bash set_ssh_qos() { - # The latest version of SSH installed on the Raspberry Pi 3 uses QoS headers, which disagrees with some - # routers and other hardware. This causes immense delays when remotely accessing the RPi over ssh. - echo " * Set SSH QoS to best effort" - echo -e "IPQoS 0x00 0x00\n" | sudo tee -a /etc/ssh/sshd_config - echo -e "IPQoS 0x00 0x00\n" | sudo tee -a /etc/ssh/ssh_config + if [ "$DISABLE_SSH_QOS" == true ] ; then + # The latest version of SSH installed on the Raspberry Pi 3 uses QoS headers, which disagrees with some + # routers and other hardware. This causes immense delays when remotely accessing the RPi over ssh. + echo " * Set SSH QoS to best effort" + echo -e "IPQoS 0x00 0x00\n" | sudo tee -a /etc/ssh/sshd_config + echo -e "IPQoS 0x00 0x00\n" | sudo tee -a /etc/ssh/ssh_config + fi } diff --git a/installation/routines/setup_autohotspot.sh b/installation/routines/setup_autohotspot.sh index 4279c1ca4..b569ee4a7 100644 --- a/installation/routines/setup_autohotspot.sh +++ b/installation/routines/setup_autohotspot.sh @@ -85,18 +85,20 @@ _autohotspot_check () { } setup_autohotspot() { - echo "Install AutoHotspot functionality" | tee /dev/fd/3 - # inspired by - # https://www.raspberryconnect.com/projects/65-raspberrypi-hotspot-accesspoints/158-raspberry-pi-auto-wifi-hotspot-switch-direct-connection - - _get_interface - _install_packages - _configure_hostapd - _configure_dnsmasq - _other_configuration - _install_autohotspot_script - _install_service_and_timer - _autohotspot_check - - echo "DONE: setup_autohotspot" + if [ "$ENABLE_AUTOHOTSPOT" == true ] ; then + echo "Install AutoHotspot functionality" | tee /dev/fd/3 + # inspired by + # https://www.raspberryconnect.com/projects/65-raspberrypi-hotspot-accesspoints/158-raspberry-pi-auto-wifi-hotspot-switch-direct-connection + + _get_interface + _install_packages + _configure_hostapd + _configure_dnsmasq + _other_configuration + _install_autohotspot_script + _install_service_and_timer + _autohotspot_check + + echo "DONE: setup_autohotspot" + fi } diff --git a/installation/routines/setup_jukebox_webapp.sh b/installation/routines/setup_jukebox_webapp.sh index d42dca916..e623e8838 100644 --- a/installation/routines/setup_jukebox_webapp.sh +++ b/installation/routines/setup_jukebox_webapp.sh @@ -95,19 +95,21 @@ _jukebox_webapp_check () { } setup_jukebox_webapp() { - echo "Install web application" | tee /dev/fd/3 - - if [[ $ENABLE_WEBAPP_PROD_DOWNLOAD == true || $ENABLE_WEBAPP_PROD_DOWNLOAD == release-only ]] ; then - _jukebox_webapp_download - fi - if [[ $ENABLE_INSTALL_NODE == true ]] ; then - _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 - fi - _jukebox_webapp_register_as_system_service_with_nginx - _jukebox_webapp_check - - echo "DONE: setup_jukebox_webapp" + if [ "$ENABLE_WEBAPP" == true ] ; then + echo "Install web application" | tee /dev/fd/3 + + if [[ $ENABLE_WEBAPP_PROD_DOWNLOAD == true || $ENABLE_WEBAPP_PROD_DOWNLOAD == release-only ]] ; then + _jukebox_webapp_download + fi + if [[ $ENABLE_INSTALL_NODE == true ]] ; then + _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 + fi + _jukebox_webapp_register_as_system_service_with_nginx + _jukebox_webapp_check + + echo "DONE: setup_jukebox_webapp" + fi } diff --git a/installation/routines/setup_kiosk_mode.sh b/installation/routines/setup_kiosk_mode.sh index 7864e020a..ac367f569 100644 --- a/installation/routines/setup_kiosk_mode.sh +++ b/installation/routines/setup_kiosk_mode.sh @@ -79,12 +79,14 @@ _kiosk_mode_check () { } setup_kiosk_mode() { - echo "Setup Kiosk Mode" | tee /dev/fd/3 + if [ "$ENABLE_KIOSK_MODE" == true ] ; then + echo "Setup Kiosk Mode" | tee /dev/fd/3 - _kiosk_mode_install_os_dependencies - _kiosk_mode_set_autostart - _kiosk_mode_update_settings - _kiosk_mode_check + _kiosk_mode_install_os_dependencies + _kiosk_mode_set_autostart + _kiosk_mode_update_settings + _kiosk_mode_check - echo "DONE: setup_kiosk_mode" + echo "DONE: setup_kiosk_mode" + fi } diff --git a/installation/routines/setup_mpd.sh b/installation/routines/setup_mpd.sh index 0b976d231..32d58ad50 100644 --- a/installation/routines/setup_mpd.sh +++ b/installation/routines/setup_mpd.sh @@ -44,27 +44,29 @@ _mpd_check () { } setup_mpd() { - echo "Install MPD" | tee /dev/fd/3 - - if [[ $ENABLE_MPD_OVERWRITE_INSTALL == true ]] ; then - - # Install/update only if enabled: do not stuff up any existing configuration - _mpd_install_os_dependencies - - # Make sure system-wide mpd is disabled - echo "Configure MPD as user local service" | tee /dev/fd/3 - sudo systemctl stop mpd.socket - sudo systemctl stop mpd.service - sudo systemctl disable mpd.socket - sudo systemctl disable mpd.service - _mpd_configure - # Prepare user-service MPD to be started at next boot - systemctl --user daemon-reload - systemctl --user enable mpd.socket - systemctl --user enable mpd.service - - _mpd_check - fi - - echo "DONE: setup_mpd" + if [ "$SETUP_MPD" == true ] ; then + echo "Install MPD" | tee /dev/fd/3 + + if [[ $ENABLE_MPD_OVERWRITE_INSTALL == true ]] ; then + + # Install/update only if enabled: do not stuff up any existing configuration + _mpd_install_os_dependencies + + # Make sure system-wide mpd is disabled + echo "Configure MPD as user local service" | tee /dev/fd/3 + sudo systemctl stop mpd.socket + sudo systemctl stop mpd.service + sudo systemctl disable mpd.socket + sudo systemctl disable mpd.service + _mpd_configure + # Prepare user-service MPD to be started at next boot + systemctl --user daemon-reload + systemctl --user enable mpd.socket + systemctl --user enable mpd.service + + _mpd_check + fi + + echo "DONE: setup_mpd" + fi } diff --git a/installation/routines/setup_rfid_reader.sh b/installation/routines/setup_rfid_reader.sh index 4ae693076..bc95a0552 100644 --- a/installation/routines/setup_rfid_reader.sh +++ b/installation/routines/setup_rfid_reader.sh @@ -1,9 +1,11 @@ #!/usr/bin/env bash setup_rfid_reader() { - echo "Install RFID Reader" | tee /dev/fd/3 + if [ "$ENABLE_RFID_READER" == true ] ; then + echo "Install RFID Reader" | tee /dev/fd/3 - python "${INSTALLATION_PATH}/src/jukebox/run_register_rfid_reader.py" | tee /dev/fd/3 + python "${INSTALLATION_PATH}/src/jukebox/run_register_rfid_reader.py" | tee /dev/fd/3 - echo "DONE: setup_rfid_reader" + echo "DONE: setup_rfid_reader" + fi } diff --git a/installation/routines/setup_samba.sh b/installation/routines/setup_samba.sh index 59b99f277..75678f287 100644 --- a/installation/routines/setup_samba.sh +++ b/installation/routines/setup_samba.sh @@ -56,13 +56,15 @@ _samba_check () { } setup_samba() { - echo "Install Samba and configure user" | tee /dev/fd/3 + if [ "$ENABLE_SAMBA" == true ] ; then + echo "Install Samba and configure user" | tee /dev/fd/3 - # Skip interactive Samba WINS config dialog - echo "samba-common samba-common/dhcp boolean false" | sudo debconf-set-selections - _samba_install_os_dependencies - _samba_set_user - _samba_check + # Skip interactive Samba WINS config dialog + echo "samba-common samba-common/dhcp boolean false" | sudo debconf-set-selections + _samba_install_os_dependencies + _samba_set_user + _samba_check - echo "DONE: setup_samba" + echo "DONE: setup_samba" + fi } diff --git a/installation/routines/update_raspi_os.sh b/installation/routines/update_raspi_os.sh index 4f3f2d3d1..2d7b8b38f 100644 --- a/installation/routines/update_raspi_os.sh +++ b/installation/routines/update_raspi_os.sh @@ -1,9 +1,11 @@ #!/usr/bin/env bash update_raspi_os() { - echo "Updating Raspberry Pi OS" | tee /dev/fd/3 + if [ "$UPDATE_RASPI_OS" == true ] ; then + echo "Updating Raspberry Pi OS" | tee /dev/fd/3 - sudo apt-get -qq -y update && sudo apt-get -qq -y full-upgrade && sudo apt-get -qq -y autoremove || exit_on_error "Failed to Update Raspberry Pi OS" + sudo apt-get -qq -y update && sudo apt-get -qq -y full-upgrade && sudo apt-get -qq -y autoremove || exit_on_error "Failed to Update Raspberry Pi OS" - echo "DONE: update_raspi_os" + echo "DONE: update_raspi_os" + fi } From bd0801f48d5738a3d97555c05a5cd7b780274654 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 19 Nov 2023 04:17:51 +0100 Subject: [PATCH 17/44] fix missing iw package --- installation/routines/setup_autohotspot.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/installation/routines/setup_autohotspot.sh b/installation/routines/setup_autohotspot.sh index b569ee4a7..1e57d172f 100644 --- a/installation/routines/setup_autohotspot.sh +++ b/installation/routines/setup_autohotspot.sh @@ -14,7 +14,7 @@ _get_interface() { } _install_packages() { - sudo apt-get -y install hostapd dnsmasq + sudo apt-get -y install hostapd dnsmasq iw # disable services. We want to start them manually sudo systemctl unmask hostapd @@ -66,7 +66,7 @@ _install_autohotspot_script() { _autohotspot_check () { echo "Check AutoHotspot Installation" | tee /dev/fd/3 - verify_apt_packages hostapd dnsmasq + verify_apt_packages hostapd dnsmasq iw check_service_enablement hostapd.service disabled check_service_enablement dnsmasq.service disabled @@ -90,8 +90,8 @@ setup_autohotspot() { # inspired by # https://www.raspberryconnect.com/projects/65-raspberrypi-hotspot-accesspoints/158-raspberry-pi-auto-wifi-hotspot-switch-direct-connection - _get_interface _install_packages + _get_interface _configure_hostapd _configure_dnsmasq _other_configuration From ca0f5fb213c64f407ef7b7b03e10869b535f196f Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 00:06:10 +0100 Subject: [PATCH 18/44] refactored get_reader_descriptions into function. be more consistent by using same var for display and index access --- .../components/rfid/configure/__init__.py | 76 ++++++++++--------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/src/jukebox/components/rfid/configure/__init__.py b/src/jukebox/components/rfid/configure/__init__.py index 88f5d6cb2..369b67b3d 100755 --- a/src/jukebox/components/rfid/configure/__init__.py +++ b/src/jukebox/components/rfid/configure/__init__.py @@ -10,6 +10,8 @@ logger = logging.getLogger() +NO_RFID_READER = 'No RFID Reader' + def reader_install_dependencies(reader_path: str, dependency_install: str) -> None: """ @@ -80,6 +82,40 @@ def reader_load_module(reader_name): return reader_module +def _get_reader_descriptions(reader_dirs: list[str]) -> dict[str, tuple[str, str]]: + # Try to load the description modules from all valid directories (as this has no dependencies) + # If unavailable, use placeholder description + reader_descriptions = {} + for reader_type in reader_dirs: + reader_description_module_name = '' + reader_description = '' + if reader_type == NO_RFID_READER: + # Add Option to not add a RFid Reader + reader_description_module_name = reader_type + reader_description = reader_type + else: + reader_description_module_name = f"{reader_type + '/' + reader_type + '.py'}" + try: + reader_description_module = (importlib.import_module('components.rfid.hardware.' + reader_type + + '.description', 'pkg.subpkg')) + reader_description = reader_description_module.DESCRIPTION + except ModuleNotFoundError: + # The developer for this reader simply omitted to provide a description module + # Or there is no valid module in this directory, despite correct naming scheme. + # But this we will only find out later, because we want to be as lenient as possible + # and don't already load and check reader modules the user is + # not selecting (and thus no interested in) + logger.warning(f"No module 'description.py' available for reader subpackage '{reader_type}'") + reader_description = '(No description provided!)' + except AttributeError: + # The module loaded ok, but has no identifier 'DESCRIPTION' + logger.warning(f"Module 'description.py' of reader subpackage '{reader_type}' is missing 'DESCRIPTION'. " + f"Spelling error?") + reader_description = '(No description provided!)' + reader_descriptions[reader_type] = (reader_description, reader_description_module_name) + return reader_descriptions + + def query_user_for_reader(dependency_install='query') -> dict: """ Ask the user to select a RFID reader and prompt for the reader's configuration @@ -115,8 +151,7 @@ def query_user_for_reader(dependency_install='query') -> dict: package_dir = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + '/../hardware') logger.debug(f"Package location: {package_dir}") # For known included readers, specify manual order - no_rfid_reader = 'No RFID Reader' - included_readers = [no_rfid_reader, 'generic_usb', 'rdm6300_serial', 'rc522_spi', 'pn532_i2c_py532', 'fake_reader_gui'] + included_readers = [NO_RFID_READER, 'generic_usb', 'rdm6300_serial', 'rc522_spi', 'pn532_i2c_py532', 'fake_reader_gui'] # Get all local directories (i.e subpackages) that conform to naming/structuring convention (except known readers) # Naming convention: modname/modname.py additional_readers = [x for x in os.listdir(package_dir) @@ -129,34 +164,7 @@ def query_user_for_reader(dependency_install='query') -> dict: logger.debug(f"reader_dirs = {reader_dirs}") - # Try to load the description modules from all valid directories (as this has no dependencies) - # If unavailable, use placeholder description - reader_description_modules = [] - reader_descriptions = [] - for reader_type in reader_dirs: - if reader_type == no_rfid_reader: - # Add Option to not add a RFid Reader - reader_description_modules.append(no_rfid_reader) - reader_descriptions.append(no_rfid_reader) - else: - reader_description_modules.append(f"{reader_type + '/' + reader_type + '.py'}") - try: - reader_description = (importlib.import_module('components.rfid.hardware.' + reader_type - + '.description', 'pkg.subpkg')) - reader_descriptions.append(reader_description.DESCRIPTION) - except ModuleNotFoundError: - # The developer for this reader simply omitted to provide a description module - # Or there is no valid module in this directory, despite correct naming scheme. - # But this we will only find out later, because we want to be as lenient as possible - # and don't already load and check reader modules the user is - # not selecting (and thus no interested in) - logger.warning(f"No module 'description.py' available for reader subpackage '{reader_type}'") - reader_descriptions.append('(No description provided!)') - except AttributeError: - # The module loaded ok, but has no identifier 'DESCRIPTION' - logger.warning(f"Module 'description.py' of reader subpackage '{reader_type}' is missing 'DESCRIPTION'. " - f"Spelling error?") - reader_descriptions.append('(No description provided!)') + reader_descriptions = _get_reader_descriptions(reader_dirs) # Prepare the configuration collector with the base values config_dict = {'rfid': {'readers': {}}} @@ -166,7 +174,7 @@ def query_user_for_reader(dependency_install='query') -> dict: while True: # List all modules and query user print("Choose Reader Module from list:\n") - for idx, (des, mod) in enumerate(zip(reader_descriptions, reader_description_modules)): + for idx, (des, mod) in enumerate(reader_descriptions.values): print(f" {Colors.lightgreen}{idx:2d}{Colors.reset}: {Colors.lightcyan}{Colors.bold}{des:40s}{Colors.reset} " f"(Module: {mod})") print("") @@ -174,10 +182,10 @@ def query_user_for_reader(dependency_install='query') -> dict: prompt_color=Colors.lightgreen, prompt_hint=True) # The (short) name of the selected reader module, which is identical to the directory name - reader_selected = reader_dirs[reader_id] + reader_selected = list(reader_descriptions.keys())[reader_id] print(f"Reader selected: '{reader_selected}'") - if reader_selected == no_rfid_reader: - logger.debug(f"'{no_rfid_reader}' selected. skip") + if reader_selected == NO_RFID_READER: + logger.debug(f"Entry '{NO_RFID_READER}' selected. skip") break reader_select_name.append(reader_selected) From 4541ea626c4cad7743cda15e50427b874d5c395f Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 00:27:45 +0100 Subject: [PATCH 19/44] moved function to specific routine script --- installation/includes/02_helpers.sh | 9 --------- installation/routines/set_raspi_config.sh | 10 +++++++++- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/installation/includes/02_helpers.sh b/installation/includes/02_helpers.sh index 74d7595d4..39596c706 100644 --- a/installation/includes/02_helpers.sh +++ b/installation/includes/02_helpers.sh @@ -28,15 +28,6 @@ _download_file_from_google_drive() { echo "Downloaded from Google Drive ID ${GD_SHARING_ID} into ${TAR_FILENAME}" } -get_onboard_audio() { - if grep -q -E "^dtparam=([^,]*,)*audio=(on|true|yes|1).*" ${RPI_BOOT_CONFIG_FILE} - then - echo 1 - else - echo 0 - fi -} - check_os_type() { # Check if current distro is a 32 bit version # Support for 64 bit Distros has not been checked (or precisely: is known not to work) diff --git a/installation/routines/set_raspi_config.sh b/installation/routines/set_raspi_config.sh index 1b1c3ee55..46e41d9f4 100644 --- a/installation/routines/set_raspi_config.sh +++ b/installation/routines/set_raspi_config.sh @@ -1,5 +1,13 @@ #!/usr/bin/env bash +_get_onboard_audio() { + if grep -q -E "^dtparam=([^,]*,)*audio=(on|true|yes|1).*" ${RPI_BOOT_CONFIG_FILE} + then + echo 1 + else + echo 0 + fi +} set_raspi_config() { echo "Set default raspi-config" | tee /dev/fd/3 @@ -18,7 +26,7 @@ set_raspi_config() { sudo iwconfig wlan0 power off # On-board audio - if [[ $(get_onboard_audio) -eq 1 ]]; then + if [[ $(_get_onboard_audio) -eq 1 ]]; then DISABLE_ONBOARD_AUDIO=${DISABLE_ONBOARD_AUDIO:-false} if [[ $DISABLE_ONBOARD_AUDIO = true ]]; then echo " * Disable on-chip BCM audio" From c5d77719aa85ea8cbf214b6db8d5b53d65563721 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 01:26:42 +0100 Subject: [PATCH 20/44] make sure verify parameters are all set. fix functionnames --- installation/includes/02_helpers.sh | 82 ++++++++++++++----- installation/routines/optimize_boot_time.sh | 20 ++--- installation/routines/setup_autohotspot.sh | 6 +- installation/routines/setup_jukebox_core.sh | 2 +- installation/routines/setup_jukebox_webapp.sh | 2 +- installation/routines/setup_mpd.sh | 8 +- 6 files changed, 80 insertions(+), 40 deletions(-) diff --git a/installation/includes/02_helpers.sh b/installation/includes/02_helpers.sh index 39596c706..a4f3b8843 100644 --- a/installation/includes/02_helpers.sh +++ b/installation/includes/02_helpers.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Helpers +### Helpers # $1->start, $2->end calc_runtime_and_print() { @@ -48,13 +48,17 @@ check_os_type() { } -##### Check helpers +### Verify helpers # Check if the file(s) exists verify_files_exists() { local files="$@" echo "Verify '${files}' exists" + if [[ -z "${files}" ]]; then + exit_on_error "ERROR: at least one parameter value is missing!" + fi + for file in $files do test ! -f ${file} && exit_on_error "ERROR: '${file}' does not exists or is not a file!" @@ -67,6 +71,10 @@ verify_dirs_exists() { local dirs="$@" echo "Verify '${dirs}' exists" + if [[ -z "${dirs}" ]]; then + exit_on_error "ERROR: at least one parameter value is missing!" + fi + for dir in $dirs do test ! -d ${dir} && exit_on_error "ERROR: '${dir}' does not exists or is not a dir!" @@ -83,6 +91,10 @@ verify_files_chmod_chown() { local files="${@:4}" echo "Verify '${mod_expected}' '${user_expected}:${group_expected}' is set for '${files}'" + if [[ -z "${mod_expected}" || -z "${user_expected}" || -z "${group_expected}" || -z "${files}" ]]; then + exit_on_error "ERROR: at least one parameter value is missing!" + fi + for file in $files do test ! -f ${file} && exit_on_error "ERROR: '${file}' does not exists or is not a file!" @@ -105,6 +117,10 @@ verify_dirs_chmod_chown() { local dirs="${@:4}" echo "Verify '${mod_expected}' '${user_expected}:${group_expected}' is set for '${dirs}'" + if [[ -z "${mod_expected}" || -z "${user_expected}" || -z "${group_expected}" || -z "${dirs}" ]]; then + exit_on_error "ERROR: at least one parameter value is missing!" + fi + for dir in $dirs do test ! -d ${dir} && exit_on_error "ERROR: '${dir}' does not exists or is not a dir!" @@ -124,6 +140,10 @@ verify_file_contains_string() { local file="$2" echo "Verify '${string}' found in '${file}'" + if [[ -z "${string}" || -z "${file}" ]]; then + exit_on_error "ERROR: at least one parameter value is missing!" + fi + if [[ ! $(grep -iw "${string}" "${file}") ]]; then exit_on_error "ERROR: '${string}' not found in '${file}'" fi @@ -135,6 +155,10 @@ verify_file_contains_string_once() { local file="$2" echo "Verify '${string}' found in '${file}'" + if [[ -z "${string}" || -z "${file}" ]]; then + exit_on_error "ERROR: at least one parameter value is missing!" + fi + local file_contains_string_count=$(grep -oiw "${string}" "${file}" | wc -l) if [ "$file_contains_string_count" -lt 1 ]; then exit_on_error "ERROR: '${string}' not found in '${file}'" @@ -144,12 +168,16 @@ verify_file_contains_string_once() { echo "CHECK" } -check_service_state() { +verify_service_state() { local service="$1" local desired_state="$2" local option="${3:+$3 }" # optional, dont't quote in next call! echo "Verify service '${option}${service}' is '${desired_state}'" + if [[ -z "${service}" || -z "${desired_state}" ]]; then + exit_on_error "ERROR: at least one parameter value is missing!" + fi + local actual_state=$(systemctl is-active ${option}${service}) if [[ ! "${actual_state}" == "${desired_state}" ]]; then exit_on_error "ERROR: service '${option}${service}' is not '${desired_state}' (state: '${actual_state}')." @@ -157,12 +185,16 @@ check_service_state() { echo "CHECK" } -check_service_enablement() { +verify_service_enablement() { local service="$1" local desired_enablement="$2" local option="${3:+$3 }" # optional, dont't quote in next call! echo "Verify service ${option}${service} is ${desired_enablement}" + if [[ -z "${service}" || -z "${desired_enablement}" ]]; then + exit_on_error "ERROR: at least one parameter value is missing!" + fi + local actual_enablement=$(systemctl is-enabled ${option}${service}) if [[ ! "${actual_enablement}" == "${desired_enablement}" ]]; then exit_on_error "ERROR: service ${option}${service} is not ${desired_enablement} (state: ${actual_enablement})." @@ -170,12 +202,16 @@ check_service_enablement() { echo "CHECK" } -check_optional_service_enablement() { +verify_optional_service_enablement() { local service="$1" local desired_enablement="$2" local option="${3:+$3 }" # optional, dont't quote in next call! echo "Verify service ${option}${service} is ${desired_enablement}" + if [[ -z "${service}" || -z "${desired_enablement}" ]]; then + exit_on_error "ERROR: at least one parameter value is missing!" + fi + local actual_enablement=$(systemctl is-enabled ${option}${service}) 2>/dev/null if [[ -z "${actual_enablement}" ]]; then echo "INFO: optional service ${option}${service} is not installed." @@ -201,15 +237,17 @@ verify_apt_packages() { local packages="$@" echo "Verify packages are installed: '${packages}'" - if [ -n "${packages}" ]; then - local apt_list_installed=$(apt -qq list --installed 2>/dev/null) - for package in ${packages} - do - if [[ ! $(echo "${apt_list_installed}" | grep -i "^${package}/.*installed") ]]; then - exit_on_error "ERROR: ${package} is not installed" - fi - done + if [[ -z "${packages}" ]]; then + exit_on_error "ERROR: at least one parameter value is missing!" fi + + local apt_list_installed=$(apt -qq list --installed 2>/dev/null) + for package in ${packages} + do + if [[ ! $(echo "${apt_list_installed}" | grep -i "^${package}/.*installed") ]]; then + exit_on_error "ERROR: ${package} is not installed" + fi + done echo "CHECK" } @@ -218,14 +256,16 @@ verify_pip_modules() { local modules="$@" echo "Verify modules are installed: '${modules}'" - if [ -n "${modules}" ]; then - local pip_list_installed=$(pip list 2>/dev/null) - for module in ${modules} - do - if [[ ! $(echo "${pip_list_installed}" | grep -i "^${module} ") ]]; then - exit_on_error "ERROR: ${module} is not installed" - fi - done + if [[ -z "${modules}" ]]; then + exit_on_error "ERROR: at least one parameter value is missing!" fi + + local pip_list_installed=$(pip list 2>/dev/null) + for module in ${modules} + do + if [[ ! $(echo "${pip_list_installed}" | grep -i "^${module} ") ]]; then + exit_on_error "ERROR: ${module} is not installed" + fi + done echo "CHECK" } diff --git a/installation/routines/optimize_boot_time.sh b/installation/routines/optimize_boot_time.sh index 29983930c..c3b8287c2 100644 --- a/installation/routines/optimize_boot_time.sh +++ b/installation/routines/optimize_boot_time.sh @@ -124,18 +124,18 @@ EOF _optimize_check () { echo "Check Optimize boot time" | tee /dev/fd/3 - check_optional_service_enablement keyboard-setup.service disabled - check_optional_service_enablement triggerhappy.service disabled - check_optional_service_enablement triggerhappy.socket disabled - check_optional_service_enablement raspi-config.service disabled - check_optional_service_enablement apt-daily.service disabled - check_optional_service_enablement apt-daily-upgrade.service disabled - check_optional_service_enablement apt-daily.timer disabled - check_optional_service_enablement apt-daily-upgrade.timer disabled + verify_optional_service_enablement keyboard-setup.service disabled + verify_optional_service_enablement triggerhappy.service disabled + verify_optional_service_enablement triggerhappy.socket disabled + verify_optional_service_enablement raspi-config.service disabled + verify_optional_service_enablement apt-daily.service disabled + verify_optional_service_enablement apt-daily-upgrade.service disabled + verify_optional_service_enablement apt-daily.timer disabled + verify_optional_service_enablement apt-daily-upgrade.timer disabled if [ "$DISABLE_BLUETOOTH" = true ] ; then - check_optional_service_enablement hciuart.service disabled - check_optional_service_enablement bluetooth.service disabled + verify_optional_service_enablement hciuart.service disabled + verify_optional_service_enablement bluetooth.service disabled fi if [ "$ENABLE_STATIC_IP" = true ] ; then diff --git a/installation/routines/setup_autohotspot.sh b/installation/routines/setup_autohotspot.sh index 1e57d172f..9f2c98ce4 100644 --- a/installation/routines/setup_autohotspot.sh +++ b/installation/routines/setup_autohotspot.sh @@ -68,9 +68,9 @@ _autohotspot_check () { verify_apt_packages hostapd dnsmasq iw - check_service_enablement hostapd.service disabled - check_service_enablement dnsmasq.service disabled - check_service_enablement autohotspot.service enabled + verify_service_enablement hostapd.service disabled + verify_service_enablement dnsmasq.service disabled + verify_service_enablement autohotspot.service enabled verify_files_exists "/etc/cron.d/autohotspot" verify_files_exists "${AUTOHOTSPOT_TARGET_PATH}" diff --git a/installation/routines/setup_jukebox_core.sh b/installation/routines/setup_jukebox_core.sh index dfbed6b64..08eb75645 100644 --- a/installation/routines/setup_jukebox_core.sh +++ b/installation/routines/setup_jukebox_core.sh @@ -160,7 +160,7 @@ _jukebox_core_check () { verify_file_contains_string "${INSTALLATION_PATH}" "${JUKEBOX_SERVICE_NAME}" - check_service_enablement jukebox-daemon.service enabled --user + verify_service_enablement jukebox-daemon.service enabled --user } setup_jukebox_core() { diff --git a/installation/routines/setup_jukebox_webapp.sh b/installation/routines/setup_jukebox_webapp.sh index e623e8838..9680657aa 100644 --- a/installation/routines/setup_jukebox_webapp.sh +++ b/installation/routines/setup_jukebox_webapp.sh @@ -91,7 +91,7 @@ _jukebox_webapp_check () { verify_apt_packages nginx verify_files_exists "${WEBAPP_NGINX_SITE_DEFAULT_CONF}" - check_service_enablement nginx.service enabled + verify_service_enablement nginx.service enabled } setup_jukebox_webapp() { diff --git a/installation/routines/setup_mpd.sh b/installation/routines/setup_mpd.sh index 32d58ad50..583f162f0 100644 --- a/installation/routines/setup_mpd.sh +++ b/installation/routines/setup_mpd.sh @@ -36,11 +36,11 @@ _mpd_check () { verify_file_contains_string "${AUDIOFOLDERS_PATH}" "${MPD_CONF_PATH}" verify_file_contains_string "${PLAYLISTS_PATH}" "${MPD_CONF_PATH}" - check_service_enablement mpd.socket disabled - check_service_enablement mpd.service disabled + verify_service_enablement mpd.socket disabled + verify_service_enablement mpd.service disabled - check_service_enablement mpd.socket enabled --user - check_service_enablement mpd.service enabled --user + verify_service_enablement mpd.socket enabled --user + verify_service_enablement mpd.service enabled --user } setup_mpd() { From e0ccb3dad16d3a267ea8e4a1e996d3894bfd57de Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 01:55:16 +0100 Subject: [PATCH 21/44] added fix for not available interface in CI runs --- installation/routines/setup_autohotspot.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/installation/routines/setup_autohotspot.sh b/installation/routines/setup_autohotspot.sh index 9f2c98ce4..8cfcf5359 100644 --- a/installation/routines/setup_autohotspot.sh +++ b/installation/routines/setup_autohotspot.sh @@ -11,6 +11,16 @@ _get_interface() { # interfaces may vary WIFI_INTERFACE=$(iw dev | grep "Interface"| awk '{ print $2 }') WIFI_REGION=$(iw reg get | grep country | awk '{ print $2}' | cut -d: -f1) + + # fix for CI runs on docker + if [ "${CI_RUNNING}" == "true" ]; then + if [ -z "${WIFI_INTERFACE}" ]; then + WIFI_INTERFACE="CI TEST INTERFACE" + fi + if [ -z "${WIFI_REGION}" ]; then + WIFI_REGION="CI TEST REGION" + fi + fi } _install_packages() { From d07a996c27cb5bb8707ec30eb75e44604a46b8ae Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 01:43:09 +0100 Subject: [PATCH 22/44] check supported os type first --- installation/includes/02_helpers.sh | 19 ------------------- installation/install-jukebox.sh | 26 ++++++++++++++++++++++---- installation/routines/install.sh | 1 - 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/installation/includes/02_helpers.sh b/installation/includes/02_helpers.sh index a4f3b8843..077a85696 100644 --- a/installation/includes/02_helpers.sh +++ b/installation/includes/02_helpers.sh @@ -28,25 +28,6 @@ _download_file_from_google_drive() { echo "Downloaded from Google Drive ID ${GD_SHARING_ID} into ${TAR_FILENAME}" } -check_os_type() { - # Check if current distro is a 32 bit version - # Support for 64 bit Distros has not been checked (or precisely: is known not to work) - # All RaspianOS versions report as machine "armv6l" or "armv7l", if 32 bit (even the ARMv8 cores!) - - local os_type - os_type=$(uname -m) - - echo -e "\nChecking OS type '$os_type'" | tee /dev/fd/3 - - if [[ $os_type == "armv7l" || $os_type == "armv6l" ]]; then - echo -e " ... OK!\n" | tee /dev/fd/3 - else - echo "ERROR: Only 32 bit operating systems supported. Please use a 32bit version of RaspianOS!" | tee /dev/fd/3 - echo "You can fix this problem for 64bit kernels: https://github.com/MiczFlor/RPi-Jukebox-RFID/issues/2041" | tee /dev/fd/3 - exit 1 - fi -} - ### Verify helpers diff --git a/installation/install-jukebox.sh b/installation/install-jukebox.sh index 9382e6c62..a2c110de6 100755 --- a/installation/install-jukebox.sh +++ b/installation/install-jukebox.sh @@ -29,9 +29,26 @@ echo "User home dir: $HOME_PATH" INSTALLATION_PATH="${HOME_PATH}/${GIT_REPO_NAME}" INSTALL_ID=$(date +%s) -checkPrerequisite() { - #currently the user 'pi' is mandatory - #https://github.com/MiczFlor/RPi-Jukebox-RFID/issues/1785 +# Check if current distro is a 32 bit version +# Support for 64 bit Distros has not been checked (or precisely: is known not to work) +# All RaspianOS versions report as machine "armv6l" or "armv7l", if 32 bit (even the ARMv8 cores!) +_check_os_type() { + local os_type=$(uname -m) + + echo -e "\nChecking OS type '$os_type'" + + if [[ $os_type == "armv7l" || $os_type == "armv6l" ]]; then + echo -e " ... OK!\n" + else + echo "ERROR: Only 32 bit operating systems supported. Please use a 32bit version of RaspianOS!" + echo "You can fix this problem for 64bit kernels: https://github.com/MiczFlor/RPi-Jukebox-RFID/issues/2041" + exit 1 + fi +} + +# currently the user 'pi' is mandatory +# https://github.com/MiczFlor/RPi-Jukebox-RFID/issues/1785 +_check_user() { if [ "${CURRENT_USER}" != "pi" ]; then echo echo "ERROR: User must be 'pi'!" @@ -78,7 +95,8 @@ download_jukebox_source() { ### CHECK PREREQUISITE -checkPrerequisite +_check_os_type +_check_user ### RUN INSTALLATION cd "${HOME_PATH}" diff --git a/installation/routines/install.sh b/installation/routines/install.sh index 3dfe14fe5..d241658b6 100644 --- a/installation/routines/install.sh +++ b/installation/routines/install.sh @@ -1,5 +1,4 @@ install() { - check_os_type clear 1>&3 customize_options clear 1>&3 From d35a01eb0392db3ee6b1430bc51ce64e7ceb1688 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 01:47:44 +0100 Subject: [PATCH 23/44] moved exit_on_error function top level --- installation/includes/05_finish.sh | 21 -------------------- installation/install-jukebox.sh | 32 +++++++++++++++++++++++------- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/installation/includes/05_finish.sh b/installation/includes/05_finish.sh index 50c2f6d9d..266be6ac4 100644 --- a/installation/includes/05_finish.sh +++ b/installation/includes/05_finish.sh @@ -31,24 +31,3 @@ Do you want to reboot now? [Y/n]" 1>&3 ;; esac } - -# Generic emergency error handler that exits the script immediately -# Print additional custom message if passed as first argument -# Examples: -# cd some-dir || exit_on_error -# cd some-dir || exit_on_error "During installation of some" -exit_on_error () { - - echo -e "\n****************************************" | tee /dev/fd/3 - echo "ERROR OCCURRED! -A non-recoverable error occurred. -Check install log for details:" | tee /dev/fd/3 - echo "$INSTALLATION_LOGFILE" | tee /dev/fd/3 - echo "****************************************" | tee /dev/fd/3 - if [[ -n $1 ]]; then - echo "$1" | tee /dev/fd/3 - echo "****************************************" | tee /dev/fd/3 - fi - echo "Abort!" - exit 1 -} diff --git a/installation/install-jukebox.sh b/installation/install-jukebox.sh index a2c110de6..267e008a7 100755 --- a/installation/install-jukebox.sh +++ b/installation/install-jukebox.sh @@ -73,6 +73,26 @@ _check_user() { fi } +# Generic emergency error handler that exits the script immediately +# Print additional custom message if passed as first argument +# Examples: +# a command || exit_on_error +# a command || exit_on_error "Execution of command failed" +exit_on_error () { + echo -e "\n****************************************" | tee /dev/fd/3 + echo "ERROR OCCURRED! +A non-recoverable error occurred. +Check install log for details:" | tee /dev/fd/3 + echo "$INSTALLATION_LOGFILE" | tee /dev/fd/3 + echo "****************************************" | tee /dev/fd/3 + if [[ -n $1 ]]; then + echo "$1" | tee /dev/fd/3 + echo "****************************************" | tee /dev/fd/3 + fi + echo "Abort!" + exit 1 +} + download_jukebox_source() { wget -qO- "${GIT_URL}/tarball/${GIT_BRANCH}" | tar xz # Use case insensitive search/sed because user names in Git Hub are case insensitive @@ -81,13 +101,11 @@ download_jukebox_source() { GIT_HASH=$(echo "$GIT_REPO_DOWNLOAD" | sed -rn "s/.*${GIT_USER}-${GIT_REPO_NAME}-([0-9a-fA-F]+)/\1/ip") # Save the git hash for this particular download for later git repo initialization echo "GIT HASH = $GIT_HASH" - if [[ -z ${GIT_REPO_DOWNLOAD} ]]; then - echo "ERROR in finding git download. Panic." - exit 1 + if [[ -z "${GIT_REPO_DOWNLOAD}" ]]; then + exit_on_error "ERROR: Couldn't find git download." fi - if [[ -z ${GIT_HASH} ]]; then - echo "ERROR in determining git hash from download. Panic." - exit 1 + if [[ -z "${GIT_HASH}" ]]; then + exit_on_error "ERROR: Couldn't determine git hash from download." fi mv "$GIT_REPO_DOWNLOAD" "$GIT_REPO_NAME" unset GIT_REPO_DOWNLOAD @@ -113,8 +131,8 @@ echo "Downloading Phoniebox software from Github ..." 1>&3 echo "Download Source: ${GIT_URL}/${GIT_BRANCH}" | tee /dev/fd/3 download_jukebox_source -cd "${INSTALLATION_PATH}" || { echo "ERROR in changing to install dir. Panic."; exit 1; } +cd "${INSTALLATION_PATH}" || exit_on_error "ERROR: Changing to install dir failed." # Load / Source dependencies for i in "${INSTALLATION_PATH}"/installation/includes/*; do source "$i" From 66c4facd03c8e5660dccb273767708c80b30c2b7 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 01:49:33 +0100 Subject: [PATCH 24/44] moved logging setup to function and added usage --- installation/install-jukebox.sh | 42 +++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/installation/install-jukebox.sh b/installation/install-jukebox.sh index 267e008a7..f48df910c 100755 --- a/installation/install-jukebox.sh +++ b/installation/install-jukebox.sh @@ -28,6 +28,7 @@ echo "User home dir: $HOME_PATH" INSTALLATION_PATH="${HOME_PATH}/${GIT_REPO_NAME}" INSTALL_ID=$(date +%s) +INSTALLATION_LOGFILE="${HOME_PATH}/INSTALL-${INSTALL_ID}.log" # Check if current distro is a 32 bit version # Support for 64 bit Distros has not been checked (or precisely: is known not to work) @@ -73,6 +74,27 @@ _check_user() { fi } +# Manipulate file descriptor for logging +# Behavior: +# Write To logfile: +# default stdout will only write to logfile +# default stderr will only write to logfile +# e.g echo "write only to logfile" +# Write To console (user window): +# redirect to fd 3 will only write to the console +# e.g. echo "write only to console" 1>&3 +# Write To both: +# use tee to write output to logfile and console +# e.g. echo "write to both" | tee /dev/fd/3 +_setup_logging(){ + if [ "$CI_RUNNING" == "true" ]; then + exec 3>&1 2>&1 + else + exec 3>&1 1>>"${INSTALLATION_LOGFILE}" 2>&1 || { echo "ERROR: Cannot create log file."; exit 1; } + fi + echo "Log start: ${INSTALL_ID}" +} + # Generic emergency error handler that exits the script immediately # Print additional custom message if passed as first argument # Examples: @@ -94,6 +116,10 @@ Check install log for details:" | tee /dev/fd/3 } download_jukebox_source() { + echo "Downloading Phoniebox software from Github ..." 1>&3 + echo "Download Source: ${GIT_URL}/${GIT_BRANCH}" | tee /dev/fd/3 + + cd "${HOME_PATH}" || exit_on_error "ERROR: Changing to home dir failed." wget -qO- "${GIT_URL}/tarball/${GIT_BRANCH}" | tar xz # Use case insensitive search/sed because user names in Git Hub are case insensitive GIT_REPO_DOWNLOAD=$(find . -maxdepth 1 -type d -iname "${GIT_USER}-${GIT_REPO_NAME}-*") @@ -116,20 +142,10 @@ download_jukebox_source() { _check_os_type _check_user -### RUN INSTALLATION -cd "${HOME_PATH}" -INSTALLATION_LOGFILE="${HOME_PATH}/INSTALL-${INSTALL_ID}.log" -if [ "$CI_RUNNING" == "true" ]; then - exec 3>&1 2>&1 -else - exec 3>&1 1>>"${INSTALLATION_LOGFILE}" 2>&1 || { echo "Cannot create log file. Panic."; exit 1; } -fi -echo "Log start: ${INSTALL_ID}" - -clear 1>&3 -echo "Downloading Phoniebox software from Github ..." 1>&3 -echo "Download Source: ${GIT_URL}/${GIT_BRANCH}" | tee /dev/fd/3 +### SETUP LOGGING +_setup_logging +### RUN INSTALLATION download_jukebox_source cd "${INSTALLATION_PATH}" || exit_on_error "ERROR: Changing to install dir failed." From 0a906d41288d5ec2f7e912013552ca63c7c9ed28 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 02:05:22 +0100 Subject: [PATCH 25/44] moved load sources to function --- installation/install-jukebox.sh | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/installation/install-jukebox.sh b/installation/install-jukebox.sh index f48df910c..ffafe109e 100755 --- a/installation/install-jukebox.sh +++ b/installation/install-jukebox.sh @@ -137,6 +137,17 @@ download_jukebox_source() { unset GIT_REPO_DOWNLOAD } +_load_sources() { + # Load / Source dependencies + for i in "${INSTALLATION_PATH}"/installation/includes/*; do + source "$i" + done + + for j in "${INSTALLATION_PATH}"/installation/routines/*; do + source "$j" + done +} + ### CHECK PREREQUISITE _check_os_type @@ -147,16 +158,8 @@ _setup_logging ### RUN INSTALLATION download_jukebox_source - cd "${INSTALLATION_PATH}" || exit_on_error "ERROR: Changing to install dir failed." -# Load / Source dependencies -for i in "${INSTALLATION_PATH}"/installation/includes/*; do - source "$i" -done - -for j in "${INSTALLATION_PATH}"/installation/routines/*; do - source "$j" -done +_load_sources welcome run_with_timer install From e220f725db5eb703f1a69ca1712e6c58f7e9a008 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 02:06:40 +0100 Subject: [PATCH 26/44] change function name and var usage --- installation/install-jukebox.sh | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/installation/install-jukebox.sh b/installation/install-jukebox.sh index ffafe109e..6a7fa0fbf 100755 --- a/installation/install-jukebox.sh +++ b/installation/install-jukebox.sh @@ -115,26 +115,25 @@ Check install log for details:" | tee /dev/fd/3 exit 1 } -download_jukebox_source() { +_download_jukebox_source() { echo "Downloading Phoniebox software from Github ..." 1>&3 echo "Download Source: ${GIT_URL}/${GIT_BRANCH}" | tee /dev/fd/3 cd "${HOME_PATH}" || exit_on_error "ERROR: Changing to home dir failed." wget -qO- "${GIT_URL}/tarball/${GIT_BRANCH}" | tar xz # Use case insensitive search/sed because user names in Git Hub are case insensitive - GIT_REPO_DOWNLOAD=$(find . -maxdepth 1 -type d -iname "${GIT_USER}-${GIT_REPO_NAME}-*") - echo "GIT REPO DOWNLOAD = $GIT_REPO_DOWNLOAD" - GIT_HASH=$(echo "$GIT_REPO_DOWNLOAD" | sed -rn "s/.*${GIT_USER}-${GIT_REPO_NAME}-([0-9a-fA-F]+)/\1/ip") + local git_repo_download=$(find . -maxdepth 1 -type d -iname "${GIT_USER}-${GIT_REPO_NAME}-*") + echo "GIT REPO DOWNLOAD = $git_repo_download" + GIT_HASH=$(echo "$git_repo_download" | sed -rn "s/.*${GIT_USER}-${GIT_REPO_NAME}-([0-9a-fA-F]+)/\1/ip") # Save the git hash for this particular download for later git repo initialization echo "GIT HASH = $GIT_HASH" - if [[ -z "${GIT_REPO_DOWNLOAD}" ]]; then + if [[ -z "${git_repo_download}" ]]; then exit_on_error "ERROR: Couldn't find git download." fi if [[ -z "${GIT_HASH}" ]]; then exit_on_error "ERROR: Couldn't determine git hash from download." fi - mv "$GIT_REPO_DOWNLOAD" "$GIT_REPO_NAME" - unset GIT_REPO_DOWNLOAD + mv "$git_repo_download" "$GIT_REPO_NAME" } _load_sources() { @@ -157,7 +156,7 @@ _check_user _setup_logging ### RUN INSTALLATION -download_jukebox_source +_download_jukebox_source cd "${INSTALLATION_PATH}" || exit_on_error "ERROR: Changing to install dir failed." _load_sources From 0e2e1c56ceef6387ed02a56d7280ffce2ec56894 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 02:58:39 +0100 Subject: [PATCH 27/44] updated log output for better logfile readability --- installation/includes/02_helpers.sh | 19 +++++++ installation/includes/04_cleanup.sh | 8 +-- installation/install-jukebox.sh | 6 ++- installation/routines/customize_options.sh | 8 +-- installation/routines/optimize_boot_time.sh | 26 +++++----- installation/routines/set_raspi_config.sh | 10 ++-- installation/routines/setup_autohotspot.sh | 34 +++++++------ installation/routines/setup_git.sh | 28 ++++++---- installation/routines/setup_jukebox_core.sh | 27 +++++----- installation/routines/setup_jukebox_webapp.sh | 34 ++++++------- installation/routines/setup_kiosk_mode.sh | 22 ++++---- installation/routines/setup_mpd.sh | 51 ++++++++++--------- installation/routines/setup_rfid_reader.sh | 10 ++-- installation/routines/setup_samba.sh | 23 +++++---- installation/routines/update_raspi_os.sh | 10 ++-- 15 files changed, 177 insertions(+), 139 deletions(-) diff --git a/installation/includes/02_helpers.sh b/installation/includes/02_helpers.sh index 077a85696..eb4b1072e 100644 --- a/installation/includes/02_helpers.sh +++ b/installation/includes/02_helpers.sh @@ -21,6 +21,18 @@ run_with_timer() { echo "--------------------------------------" } +run_with_log_frame() { + local description="$2" + echo -e "\n\n" + echo "#########################################################" + echo "${description}" | tee /dev/fd/3 + + $1; # Executes the function passed as an argument + + echo -e "\nDONE: ${description}" + echo "#########################################################" +} + _download_file_from_google_drive() { GD_SHARING_ID=${1} TAR_FILENAME=${2} @@ -31,6 +43,13 @@ _download_file_from_google_drive() { ### Verify helpers +print_verify_installation() { + echo "" + echo "---------------------------------------------------------" + echo "Check installation" + echo "" +} + # Check if the file(s) exists verify_files_exists() { local files="$@" diff --git a/installation/includes/04_cleanup.sh b/installation/includes/04_cleanup.sh index fd714132f..d6e39266c 100644 --- a/installation/includes/04_cleanup.sh +++ b/installation/includes/04_cleanup.sh @@ -1,7 +1,9 @@ #!/usr/bin/env bash -cleanup() { - sudo rm -rf /var/lib/apt/lists/* +_run_cleanup() { + sudo rm -rf /var/lib/apt/lists/* +} - echo "DONE: cleanup" +cleanup() { + run_with_log_frame _run_cleanup "Cleanup" } diff --git a/installation/install-jukebox.sh b/installation/install-jukebox.sh index 6a7fa0fbf..547eec423 100755 --- a/installation/install-jukebox.sh +++ b/installation/install-jukebox.sh @@ -68,8 +68,8 @@ _check_user() { if [ ! -d "${HOME_PATH}" ]; then echo - echo "Warning: HomeDir ${HOME_PATH} does not exist." - echo " Please create it and start again." + echo "ERROR: HomeDir ${HOME_PATH} does not exist." + echo " Please create it and start again." exit 2 fi } @@ -116,6 +116,7 @@ Check install log for details:" | tee /dev/fd/3 } _download_jukebox_source() { + echo -e "\n\n#########################################################" echo "Downloading Phoniebox software from Github ..." 1>&3 echo "Download Source: ${GIT_URL}/${GIT_BRANCH}" | tee /dev/fd/3 @@ -134,6 +135,7 @@ _download_jukebox_source() { exit_on_error "ERROR: Couldn't determine git hash from download." fi mv "$git_repo_download" "$GIT_REPO_NAME" + echo -e "\nDONE: Downloading Phoniebox software from Github" } _load_sources() { diff --git a/installation/routines/customize_options.sh b/installation/routines/customize_options.sh index ba9894661..fd16e2cd0 100644 --- a/installation/routines/customize_options.sh +++ b/installation/routines/customize_options.sh @@ -316,9 +316,7 @@ Do you want to install Node? [Y/n]" 1>&3 fi } -customize_options() { - echo "Customize Options starts" - +_run_customize_options() { _option_ipv6 _option_static_ip _option_autohotspot @@ -335,6 +333,8 @@ customize_options() { # Bullseye is currently under active development and should be updated in any case. # Hence, removing the step below as it becomse mandatory # _options_update_raspi_os +} - echo "Customize Options ends" +customize_options() { + run_with_log_frame _run_customize_options "Customize Options" } diff --git a/installation/routines/optimize_boot_time.sh b/installation/routines/optimize_boot_time.sh index c3b8287c2..9a2670ac6 100644 --- a/installation/routines/optimize_boot_time.sh +++ b/installation/routines/optimize_boot_time.sh @@ -121,8 +121,8 @@ EOF } -_optimize_check () { - echo "Check Optimize boot time" | tee /dev/fd/3 +_optimize_check() { + print_verify_installation verify_optional_service_enablement keyboard-setup.service disabled verify_optional_service_enablement triggerhappy.service disabled @@ -156,16 +156,16 @@ _optimize_check () { fi } -optimize_boot_time() { - echo "Optimize boot time" | tee /dev/fd/3 - - _optimize_disable_irrelevant_services - _optimize_handle_bluetooth - _optimize_handle_network_connection - _optimize_ipv6_arp - _optimize_handle_boot_screen - _optimize_handle_boot_logs - _optimize_check +_run_optimize_boot_time() { + _optimize_disable_irrelevant_services + _optimize_handle_bluetooth + _optimize_handle_network_connection + _optimize_ipv6_arp + _optimize_handle_boot_screen + _optimize_handle_boot_logs + _optimize_check +} - echo "DONE: optimize_boot_time" +optimize_boot_time() { + run_with_log_frame _run_optimize_boot_time "Optimize boot time" } diff --git a/installation/routines/set_raspi_config.sh b/installation/routines/set_raspi_config.sh index 46e41d9f4..dcbc70dec 100644 --- a/installation/routines/set_raspi_config.sh +++ b/installation/routines/set_raspi_config.sh @@ -9,8 +9,7 @@ _get_onboard_audio() { fi } -set_raspi_config() { - echo "Set default raspi-config" | tee /dev/fd/3 +_run_set_raspi_config() { # Source: https://raspberrypi.stackexchange.com/a/66939 # Autologin @@ -30,12 +29,15 @@ set_raspi_config() { DISABLE_ONBOARD_AUDIO=${DISABLE_ONBOARD_AUDIO:-false} if [[ $DISABLE_ONBOARD_AUDIO = true ]]; then echo " * Disable on-chip BCM audio" - echo "Backup ${RPI_BOOT_CONFIG_FILE} --> ${DISABLE_ONBOARD_AUDIO_BACKUP}" + echo " Backup ${RPI_BOOT_CONFIG_FILE} --> ${DISABLE_ONBOARD_AUDIO_BACKUP}" sudo cp "${RPI_BOOT_CONFIG_FILE}" "${DISABLE_ONBOARD_AUDIO_BACKUP}" sudo sed -i "s/^\(dtparam=\([^,]*,\)*\)audio=\(on\|true\|yes\|1\)\(.*\)/\1audio=off\4/g" "${RPI_BOOT_CONFIG_FILE}" fi else - echo "On board audio seems to be off already. Not touching ${RPI_BOOT_CONFIG_FILE}" + echo " On board audio seems to be off already. Not touching ${RPI_BOOT_CONFIG_FILE}" fi +} +set_raspi_config() { + run_with_log_frame _run_set_raspi_config "Set default raspi-config" } diff --git a/installation/routines/setup_autohotspot.sh b/installation/routines/setup_autohotspot.sh index 8cfcf5359..a385352dd 100644 --- a/installation/routines/setup_autohotspot.sh +++ b/installation/routines/setup_autohotspot.sh @@ -1,5 +1,9 @@ #!/usr/bin/env bash +# inspired by +# https://www.raspberryconnect.com/projects/65-raspberrypi-hotspot-accesspoints/158-raspberry-pi-auto-wifi-hotspot-switch-direct-connection + + AUTOHOTSPOT_HOSTAPD_CONF_FILE="/etc/hostapd/hostapd.conf" AUTOHOTSPOT_HOSTAPD_DAEMON_CONF_FILE="/etc/default/hostapd" AUTOHOTSPOT_DNSMASQ_CONF_FILE="/etc/dnsmasq.conf" @@ -73,8 +77,8 @@ _install_autohotspot_script() { } -_autohotspot_check () { - echo "Check AutoHotspot Installation" | tee /dev/fd/3 +_autohotspot_check() { + print_verify_installation verify_apt_packages hostapd dnsmasq iw @@ -94,21 +98,19 @@ _autohotspot_check () { verify_file_contains_string "nohook wpa_supplicant" "${AUTOHOTSPOT_DHCPD_CONF_FILE}" } +_run_setup_autohotspot() { + _install_packages + _get_interface + _configure_hostapd + _configure_dnsmasq + _other_configuration + _install_autohotspot_script + _install_service_and_timer + _autohotspot_check +} + setup_autohotspot() { if [ "$ENABLE_AUTOHOTSPOT" == true ] ; then - echo "Install AutoHotspot functionality" | tee /dev/fd/3 - # inspired by - # https://www.raspberryconnect.com/projects/65-raspberrypi-hotspot-accesspoints/158-raspberry-pi-auto-wifi-hotspot-switch-direct-connection - - _install_packages - _get_interface - _configure_hostapd - _configure_dnsmasq - _other_configuration - _install_autohotspot_script - _install_service_and_timer - _autohotspot_check - - echo "DONE: setup_autohotspot" + run_with_log_frame _run_setup_autohotspot "Install AutoHotspot" fi } diff --git a/installation/routines/setup_git.sh b/installation/routines/setup_git.sh index 7c48ec7d1..f2a12e882 100644 --- a/installation/routines/setup_git.sh +++ b/installation/routines/setup_git.sh @@ -30,6 +30,7 @@ _git_convert_tardir_git_repo() { # We simply get everything from the beginning of future 3 development but excluding Version 2.X if [[ $GIT_USE_SSH == true ]]; then git remote add origin "git@github.com:${GIT_USER}/${GIT_REPO_NAME}.git" + echo "" echo "*** Git fetch (SSH) *******************************" # Prevent: The authenticity of host 'github.com (140.82.121.4)' can't be established. # Do only for this one command, so we do not disable the checks forever @@ -43,6 +44,7 @@ _git_convert_tardir_git_repo() { echo "* Defaulting to HTTPS protocol. You can change back to SSH later with" echo "* git remote set-url origin git@github.com:${GIT_USER}/${GIT_REPO_NAME}.git" echo "* git remote set-url upstream git@github.com:${GIT_UPSTREAM_USER}/${GIT_REPO_NAME}.git" + echo "" git remote remove origin GIT_USE_SSH=false else @@ -58,7 +60,8 @@ _git_convert_tardir_git_repo() { if [[ "$GIT_USER" != "$GIT_UPSTREAM_USER" ]]; then git remote add upstream "https://github.com/${GIT_UPSTREAM_USER}/${GIT_REPO_NAME}.git" fi - echo "*** Git fetch (HTTPS) *****************************" + echo "" + echo "*** Git fetch (HTTPS) *****************************" if ! git fetch origin --set-upstream --shallow-since=2021-04-21 --tags "${GIT_BRANCH}"; then echo "Error: Could not fetch repository!" echo -e "$GIT_ABORT_MSG" @@ -66,6 +69,7 @@ _git_convert_tardir_git_repo() { fi fi HASH_BRANCH=$(git rev-parse FETCH_HEAD) || { echo -e "$GIT_ABORT_MSG"; return; } + echo "" echo "*** FETCH_HEAD ($GIT_BRANCH) = $HASH_BRANCH" git add . @@ -113,12 +117,14 @@ _git_convert_tardir_git_repo() { # Provide some status outputs to the user if [[ "${HASH_BRANCH}" != "${HASH_HEAD}" ]]; then + echo "" echo "*** IMPORTANT NOTICE *******************************" echo "* Your requested branch has moved on while you were installing." echo "* Don't worry! We will stay within the exact download version!" echo "* But we set up the git repo to be ready for updating." echo "* To start updating (observe updating guidelines!), do:" echo "* $ git pull origin $GIT_BRANCH" + echo "" fi echo "*** Git remotes ************************************" @@ -137,20 +143,20 @@ _git_convert_tardir_git_repo() { unset HASH_BRANCH } -_git_repo_check () { - echo "Check Git & repository installation" | tee /dev/fd/3 +_git_repo_check() { + print_verify_installation verify_apt_packages git verify_dirs_chmod_chown 755 "${CURRENT_USER}" "${CURRENT_USER_GROUP}" "${INSTALLATION_PATH}/.git" } -init_git_repo_from_tardir() { - echo "Install Git & init repository" | tee /dev/fd/3 - - cd "${INSTALLATION_PATH}" || exit_on_error - _git_install_os_dependencies - _git_convert_tardir_git_repo - _git_repo_check +_run_init_git_repo_from_tardir() { + cd "${INSTALLATION_PATH}" || exit_on_error + _git_install_os_dependencies + _git_convert_tardir_git_repo + _git_repo_check +} - echo "DONE: init_git_repo_from_tardir" +init_git_repo_from_tardir() { + run_with_log_frame _run_init_git_repo_from_tardir "Install Git & init repository" } diff --git a/installation/routines/setup_jukebox_core.sh b/installation/routines/setup_jukebox_core.sh index 08eb75645..4f6d618dd 100644 --- a/installation/routines/setup_jukebox_core.sh +++ b/installation/routines/setup_jukebox_core.sh @@ -136,8 +136,9 @@ _jukebox_core_register_as_service() { systemctl --user enable jukebox-daemon.service } -_jukebox_core_check () { - echo "Check Jukebox Core Installation" | tee /dev/fd/3 +_jukebox_core_check() { + print_verify_installation + verify_apt_packages at \ alsa-utils \ python3 python3-venv python3-dev \ @@ -163,16 +164,16 @@ _jukebox_core_check () { verify_service_enablement jukebox-daemon.service enabled --user } -setup_jukebox_core() { - echo "Install Jukebox Core" | tee /dev/fd/3 - - _jukebox_core_install_os_dependencies - _jukebox_core_install_python_requirements - _jukebox_core_configure_pulseaudio - _jukebox_core_build_and_install_pyzmq - _jukebox_core_install_settings - _jukebox_core_register_as_service - _jukebox_core_check +_run_setup_jukebox_core() { + _jukebox_core_install_os_dependencies + _jukebox_core_install_python_requirements + _jukebox_core_configure_pulseaudio + _jukebox_core_build_and_install_pyzmq + _jukebox_core_install_settings + _jukebox_core_register_as_service + _jukebox_core_check +} - echo "DONE: setup_jukebox_core" +setup_jukebox_core() { + run_with_log_frame _run_setup_jukebox_core "Install Jukebox Core" } diff --git a/installation/routines/setup_jukebox_webapp.sh b/installation/routines/setup_jukebox_webapp.sh index 9680657aa..5c27a2e71 100644 --- a/installation/routines/setup_jukebox_webapp.sh +++ b/installation/routines/setup_jukebox_webapp.sh @@ -78,8 +78,8 @@ _jukebox_webapp_register_as_system_service_with_nginx() { sudo chmod o+x /home/pi } -_jukebox_webapp_check () { - echo "Check WebApp Installation" | tee /dev/fd/3 +_jukebox_webapp_check() { + print_verify_installation if [[ $ENABLE_WEBAPP_PROD_DOWNLOAD == true || $ENABLE_WEBAPP_PROD_DOWNLOAD == release-only ]] ; then verify_dirs_exists "${INSTALLATION_PATH}/src/webapp/build" @@ -94,22 +94,22 @@ _jukebox_webapp_check () { verify_service_enablement nginx.service enabled } +_run_setup_jukebox_webapp() { + if [[ $ENABLE_WEBAPP_PROD_DOWNLOAD == true || $ENABLE_WEBAPP_PROD_DOWNLOAD == release-only ]] ; then + _jukebox_webapp_download + fi + if [[ $ENABLE_INSTALL_NODE == true ]] ; then + _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 + fi + _jukebox_webapp_register_as_system_service_with_nginx + _jukebox_webapp_check +} + setup_jukebox_webapp() { if [ "$ENABLE_WEBAPP" == true ] ; then - echo "Install web application" | tee /dev/fd/3 - - if [[ $ENABLE_WEBAPP_PROD_DOWNLOAD == true || $ENABLE_WEBAPP_PROD_DOWNLOAD == release-only ]] ; then - _jukebox_webapp_download - fi - if [[ $ENABLE_INSTALL_NODE == true ]] ; then - _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 - fi - _jukebox_webapp_register_as_system_service_with_nginx - _jukebox_webapp_check - - echo "DONE: setup_jukebox_webapp" + run_with_log_frame _run_setup_jukebox_webapp "Install web application" fi } diff --git a/installation/routines/setup_kiosk_mode.sh b/installation/routines/setup_kiosk_mode.sh index ac367f569..ab5d9d301 100644 --- a/installation/routines/setup_kiosk_mode.sh +++ b/installation/routines/setup_kiosk_mode.sh @@ -60,8 +60,9 @@ CHROMIUM_FLAGS=\"\$\{CHROMIUM_FLAGS\} --check-for-update-interval=31536000\" EOF } -_kiosk_mode_check () { - echo "Check Kiosk Mode Installation" | tee /dev/fd/3 +_kiosk_mode_check() { + print_verify_installation + verify_apt_packages xserver-xorg \ x11-xserver-utils \ xinit \ @@ -78,15 +79,16 @@ _kiosk_mode_check () { verify_file_contains_string "${KIOSK_MODE_CONF_HEADER}" "${KIOSK_MODE_CHROMIUM_CUSTOM_DISABLE_UPDATE_CHECK}" } -setup_kiosk_mode() { - if [ "$ENABLE_KIOSK_MODE" == true ] ; then - echo "Setup Kiosk Mode" | tee /dev/fd/3 +_run_setup_kiosk_mode() { + _kiosk_mode_install_os_dependencies + _kiosk_mode_set_autostart + _kiosk_mode_update_settings + _kiosk_mode_check +} - _kiosk_mode_install_os_dependencies - _kiosk_mode_set_autostart - _kiosk_mode_update_settings - _kiosk_mode_check - echo "DONE: setup_kiosk_mode" +setup_kiosk_mode() { + if [ "$ENABLE_KIOSK_MODE" == true ] ; then + run_with_log_frame _run_setup_kiosk_mode "Setup Kiosk Mode" fi } diff --git a/installation/routines/setup_mpd.sh b/installation/routines/setup_mpd.sh index 583f162f0..08aca35c3 100644 --- a/installation/routines/setup_mpd.sh +++ b/installation/routines/setup_mpd.sh @@ -27,8 +27,9 @@ _mpd_configure() { sed -i 's|%%JUKEBOX_PLAYLISTS_PATH%%|'"$PLAYLISTS_PATH"'|' "${MPD_CONF_PATH}" } -_mpd_check () { - echo "Check MPD Installation" | tee /dev/fd/3 +_mpd_check() { + print_verify_installation + verify_apt_packages mpd mpc verify_files_chmod_chown 755 "${CURRENT_USER}" "${CURRENT_USER_GROUP}" "${MPD_CONF_PATH}" @@ -43,30 +44,30 @@ _mpd_check () { verify_service_enablement mpd.service enabled --user } +_run_setup_mpd() { + if [[ $ENABLE_MPD_OVERWRITE_INSTALL == true ]] ; then + + # Install/update only if enabled: do not stuff up any existing configuration + _mpd_install_os_dependencies + + # Make sure system-wide mpd is disabled + echo "Configure MPD as user local service" | tee /dev/fd/3 + sudo systemctl stop mpd.socket + sudo systemctl stop mpd.service + sudo systemctl disable mpd.socket + sudo systemctl disable mpd.service + _mpd_configure + # Prepare user-service MPD to be started at next boot + systemctl --user daemon-reload + systemctl --user enable mpd.socket + systemctl --user enable mpd.service + + _mpd_check + fi +} + setup_mpd() { if [ "$SETUP_MPD" == true ] ; then - echo "Install MPD" | tee /dev/fd/3 - - if [[ $ENABLE_MPD_OVERWRITE_INSTALL == true ]] ; then - - # Install/update only if enabled: do not stuff up any existing configuration - _mpd_install_os_dependencies - - # Make sure system-wide mpd is disabled - echo "Configure MPD as user local service" | tee /dev/fd/3 - sudo systemctl stop mpd.socket - sudo systemctl stop mpd.service - sudo systemctl disable mpd.socket - sudo systemctl disable mpd.service - _mpd_configure - # Prepare user-service MPD to be started at next boot - systemctl --user daemon-reload - systemctl --user enable mpd.socket - systemctl --user enable mpd.service - - _mpd_check - fi - - echo "DONE: setup_mpd" + run_with_log_frame _run_setup_mpd "Install MPD" fi } diff --git a/installation/routines/setup_rfid_reader.sh b/installation/routines/setup_rfid_reader.sh index bc95a0552..b5e8b4bbc 100644 --- a/installation/routines/setup_rfid_reader.sh +++ b/installation/routines/setup_rfid_reader.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash +_run_setup_rfid_reader() { + python "${INSTALLATION_PATH}/src/jukebox/run_register_rfid_reader.py" | tee /dev/fd/3 +} + setup_rfid_reader() { if [ "$ENABLE_RFID_READER" == true ] ; then - echo "Install RFID Reader" | tee /dev/fd/3 - - python "${INSTALLATION_PATH}/src/jukebox/run_register_rfid_reader.py" | tee /dev/fd/3 - - echo "DONE: setup_rfid_reader" + run_with_log_frame _run_setup_rfid_reader "Install RFID Reader" fi } diff --git a/installation/routines/setup_samba.sh b/installation/routines/setup_samba.sh index 75678f287..edefc33e2 100644 --- a/installation/routines/setup_samba.sh +++ b/installation/routines/setup_samba.sh @@ -45,8 +45,9 @@ EOF fi } -_samba_check () { - echo "Check Samba Installation" | tee /dev/fd/3 +_samba_check() { + print_verify_installation + verify_apt_packages samba samba-common-bin verify_files_chmod_chown 644 root root "${SMB_CONF}" @@ -55,16 +56,16 @@ _samba_check () { verify_file_contains_string "${SHARED_PATH}" "${SMB_CONF}" } +_run_setup_samba() { + # Skip interactive Samba WINS config dialog + echo "samba-common samba-common/dhcp boolean false" | sudo debconf-set-selections + _samba_install_os_dependencies + _samba_set_user + _samba_check +} + setup_samba() { if [ "$ENABLE_SAMBA" == true ] ; then - echo "Install Samba and configure user" | tee /dev/fd/3 - - # Skip interactive Samba WINS config dialog - echo "samba-common samba-common/dhcp boolean false" | sudo debconf-set-selections - _samba_install_os_dependencies - _samba_set_user - _samba_check - - echo "DONE: setup_samba" + run_with_log_frame _run_setup_samba "Install Samba and configure user" fi } diff --git a/installation/routines/update_raspi_os.sh b/installation/routines/update_raspi_os.sh index 2d7b8b38f..36092fcf9 100644 --- a/installation/routines/update_raspi_os.sh +++ b/installation/routines/update_raspi_os.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash +_run_update_raspi_os() { + sudo apt-get -qq -y update && sudo apt-get -qq -y full-upgrade && sudo apt-get -qq -y autoremove || exit_on_error "Failed to Update Raspberry Pi OS" +} + update_raspi_os() { if [ "$UPDATE_RASPI_OS" == true ] ; then - echo "Updating Raspberry Pi OS" | tee /dev/fd/3 - - sudo apt-get -qq -y update && sudo apt-get -qq -y full-upgrade && sudo apt-get -qq -y autoremove || exit_on_error "Failed to Update Raspberry Pi OS" - - echo "DONE: update_raspi_os" + run_with_log_frame _run_update_raspi_os "Updating Raspberry Pi OS" fi } From 2a0d42a9f84bc67bbf54458975b9a3d8197653ef Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 03:17:01 +0100 Subject: [PATCH 28/44] harmonize log output --- installation/includes/02_helpers.sh | 53 +++++++++---------- installation/includes/05_finish.sh | 4 +- installation/install-jukebox.sh | 4 +- installation/routines/customize_options.sh | 6 +-- installation/routines/optimize_boot_time.sh | 36 ++++++------- installation/routines/set_raspi_config.sh | 8 +-- installation/routines/set_ssh_qos.sh | 2 +- installation/routines/setup_git.sh | 2 +- installation/routines/setup_jukebox_core.sh | 14 ++--- installation/routines/setup_jukebox_webapp.sh | 2 +- installation/routines/setup_kiosk_mode.sh | 2 + installation/routines/setup_mpd.sh | 30 +++++------ installation/routines/setup_samba.sh | 7 +-- 13 files changed, 86 insertions(+), 84 deletions(-) diff --git a/installation/includes/02_helpers.sh b/installation/includes/02_helpers.sh index eb4b1072e..1e1f9c0a5 100644 --- a/installation/includes/02_helpers.sh +++ b/installation/includes/02_helpers.sh @@ -45,15 +45,15 @@ _download_file_from_google_drive() { print_verify_installation() { echo "" - echo "---------------------------------------------------------" - echo "Check installation" + echo " -------------------------------------------------------" + echo " Check installation" echo "" } # Check if the file(s) exists verify_files_exists() { local files="$@" - echo "Verify '${files}' exists" + echo " Verify '${files}' exists" if [[ -z "${files}" ]]; then exit_on_error "ERROR: at least one parameter value is missing!" @@ -63,13 +63,13 @@ verify_files_exists() { do test ! -f ${file} && exit_on_error "ERROR: '${file}' does not exists or is not a file!" done - echo "CHECK" + echo " CHECK" } # Check if the dir(s) exists verify_dirs_exists() { local dirs="$@" - echo "Verify '${dirs}' exists" + echo " Verify '${dirs}' exists" if [[ -z "${dirs}" ]]; then exit_on_error "ERROR: at least one parameter value is missing!" @@ -79,17 +79,16 @@ verify_dirs_exists() { do test ! -d ${dir} && exit_on_error "ERROR: '${dir}' does not exists or is not a dir!" done - echo "CHECK" + echo " CHECK" } - # Check if the file(s) has/have the expected owner and modifications verify_files_chmod_chown() { local mod_expected=$1 local user_expected=$2 local group_expected=$3 local files="${@:4}" - echo "Verify '${mod_expected}' '${user_expected}:${group_expected}' is set for '${files}'" + echo " Verify '${mod_expected}' '${user_expected}:${group_expected}' is set for '${files}'" if [[ -z "${mod_expected}" || -z "${user_expected}" || -z "${group_expected}" || -z "${files}" ]]; then exit_on_error "ERROR: at least one parameter value is missing!" @@ -106,7 +105,7 @@ verify_files_chmod_chown() { test ! "${user_expected}" == "${user_actual}" && exit_on_error "ERROR: '${file}' actual owner '${user_actual}' differs from expected '${user_expected}'!" test ! "${group_expected}" == "${group_actual}" && exit_on_error "ERROR: '${file}' actual group '${group_actual}' differs from expected '${group_expected}'!" done - echo "CHECK" + echo " CHECK" } # Check if the dir(s) has/have the expected owner and modifications @@ -115,7 +114,7 @@ verify_dirs_chmod_chown() { local user_expected=$2 local group_expected=$3 local dirs="${@:4}" - echo "Verify '${mod_expected}' '${user_expected}:${group_expected}' is set for '${dirs}'" + echo " Verify '${mod_expected}' '${user_expected}:${group_expected}' is set for '${dirs}'" if [[ -z "${mod_expected}" || -z "${user_expected}" || -z "${group_expected}" || -z "${dirs}" ]]; then exit_on_error "ERROR: at least one parameter value is missing!" @@ -132,13 +131,13 @@ verify_dirs_chmod_chown() { test ! "${user_expected}" == "${user_actual}" && exit_on_error "ERROR: '${dir}' actual owner '${user_actual}' differs from expected '${user_expected}'!" test ! "${group_expected}" == "${group_actual}" && exit_on_error "ERROR: '${dir}' actual group '${group_actual}' differs from expected '${group_expected}'!" done - echo "CHECK" + echo " CHECK" } verify_file_contains_string() { local string="$1" local file="$2" - echo "Verify '${string}' found in '${file}'" + echo " Verify '${string}' found in '${file}'" if [[ -z "${string}" || -z "${file}" ]]; then exit_on_error "ERROR: at least one parameter value is missing!" @@ -147,13 +146,13 @@ verify_file_contains_string() { if [[ ! $(grep -iw "${string}" "${file}") ]]; then exit_on_error "ERROR: '${string}' not found in '${file}'" fi - echo "CHECK" + echo " CHECK" } verify_file_contains_string_once() { local string="$1" local file="$2" - echo "Verify '${string}' found in '${file}'" + echo " Verify '${string}' found in '${file}'" if [[ -z "${string}" || -z "${file}" ]]; then exit_on_error "ERROR: at least one parameter value is missing!" @@ -165,14 +164,14 @@ verify_file_contains_string_once() { elif [ "$file_contains_string_count" -gt 1 ]; then exit_on_error "ERROR: '${string}' found more than once in '${file}'" fi - echo "CHECK" + echo " CHECK" } verify_service_state() { local service="$1" local desired_state="$2" local option="${3:+$3 }" # optional, dont't quote in next call! - echo "Verify service '${option}${service}' is '${desired_state}'" + echo " Verify service '${option}${service}' is '${desired_state}'" if [[ -z "${service}" || -z "${desired_state}" ]]; then exit_on_error "ERROR: at least one parameter value is missing!" @@ -182,14 +181,14 @@ verify_service_state() { if [[ ! "${actual_state}" == "${desired_state}" ]]; then exit_on_error "ERROR: service '${option}${service}' is not '${desired_state}' (state: '${actual_state}')." fi - echo "CHECK" + echo " CHECK" } verify_service_enablement() { local service="$1" local desired_enablement="$2" local option="${3:+$3 }" # optional, dont't quote in next call! - echo "Verify service ${option}${service} is ${desired_enablement}" + echo " Verify service ${option}${service} is ${desired_enablement}" if [[ -z "${service}" || -z "${desired_enablement}" ]]; then exit_on_error "ERROR: at least one parameter value is missing!" @@ -199,14 +198,14 @@ verify_service_enablement() { if [[ ! "${actual_enablement}" == "${desired_enablement}" ]]; then exit_on_error "ERROR: service ${option}${service} is not ${desired_enablement} (state: ${actual_enablement})." fi - echo "CHECK" + echo " CHECK" } verify_optional_service_enablement() { local service="$1" local desired_enablement="$2" local option="${3:+$3 }" # optional, dont't quote in next call! - echo "Verify service ${option}${service} is ${desired_enablement}" + echo " Verify service ${option}${service} is ${desired_enablement}" if [[ -z "${service}" || -z "${desired_enablement}" ]]; then exit_on_error "ERROR: at least one parameter value is missing!" @@ -214,13 +213,13 @@ verify_optional_service_enablement() { local actual_enablement=$(systemctl is-enabled ${option}${service}) 2>/dev/null if [[ -z "${actual_enablement}" ]]; then - echo "INFO: optional service ${option}${service} is not installed." + echo " INFO: optional service ${option}${service} is not installed." elif [[ "${actual_enablement}" == "static" ]]; then - echo "INFO: optional service ${option}${service} is set static." + echo " INFO: optional service ${option}${service} is set static." elif [[ ! "${actual_enablement}" == "${desired_enablement}" ]]; then exit_on_error "ERROR: service ${option}${service} is not ${desired_enablement} (state: ${actual_enablement})." fi - echo "CHECK" + echo " CHECK" } # Reads a textfile and returns all lines as args. @@ -235,7 +234,7 @@ get_args_from_file() { # Check if all passed packages are installed. Fail on first missing. verify_apt_packages() { local packages="$@" - echo "Verify packages are installed: '${packages}'" + echo " Verify packages are installed: '${packages}'" if [[ -z "${packages}" ]]; then exit_on_error "ERROR: at least one parameter value is missing!" @@ -248,13 +247,13 @@ verify_apt_packages() { exit_on_error "ERROR: ${package} is not installed" fi done - echo "CHECK" + echo " CHECK" } # Check if all passed modules are installed. Fail on first missing. verify_pip_modules() { local modules="$@" - echo "Verify modules are installed: '${modules}'" + echo " Verify modules are installed: '${modules}'" if [[ -z "${modules}" ]]; then exit_on_error "ERROR: at least one parameter value is missing!" @@ -267,5 +266,5 @@ verify_pip_modules() { exit_on_error "ERROR: ${module} is not installed" fi done - echo "CHECK" + echo " CHECK" } diff --git a/installation/includes/05_finish.sh b/installation/includes/05_finish.sh index 266be6ac4..55489ff46 100644 --- a/installation/includes/05_finish.sh +++ b/installation/includes/05_finish.sh @@ -14,8 +14,8 @@ Your SSH connection will disconnect. After the reboot, you can access the WebApp in your browser at http://${local_hostname}.local or http://${CURRENT_IP_ADDRESS} Don't forget to upload files. - -Do you want to reboot now? [Y/n]" 1>&3 +" | tee /dev/fd/3 +echo "Do you want to reboot now? [Y/n]" 1>&3 read -r response case "$response" in diff --git a/installation/install-jukebox.sh b/installation/install-jukebox.sh index 547eec423..b72dd32ff 100755 --- a/installation/install-jukebox.sh +++ b/installation/install-jukebox.sh @@ -116,7 +116,8 @@ Check install log for details:" | tee /dev/fd/3 } _download_jukebox_source() { - echo -e "\n\n#########################################################" + echo -e "\n\n" + echo "#########################################################" echo "Downloading Phoniebox software from Github ..." 1>&3 echo "Download Source: ${GIT_URL}/${GIT_BRANCH}" | tee /dev/fd/3 @@ -136,6 +137,7 @@ _download_jukebox_source() { fi mv "$git_repo_download" "$GIT_REPO_NAME" echo -e "\nDONE: Downloading Phoniebox software from Github" + echo "#########################################################" } _load_sources() { diff --git a/installation/routines/customize_options.sh b/installation/routines/customize_options.sh index fd16e2cd0..dc6572be0 100644 --- a/installation/routines/customize_options.sh +++ b/installation/routines/customize_options.sh @@ -308,9 +308,9 @@ Do you want to install Node? [Y/n]" 1>&3 esac # 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!" + $ 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}" fi fi diff --git a/installation/routines/optimize_boot_time.sh b/installation/routines/optimize_boot_time.sh index 9a2670ac6..13c78287a 100644 --- a/installation/routines/optimize_boot_time.sh +++ b/installation/routines/optimize_boot_time.sh @@ -9,17 +9,17 @@ OPTIMIZE_IPV6_CONF_HEADER="## Jukebox IPV6 Config" OPTIMIZE_BOOT_CONF_HEADER="## Jukebox Boot Config" _optimize_disable_irrelevant_services() { - echo " * Disable keyboard-setup.service" + echo " Disable keyboard-setup.service" sudo systemctl disable keyboard-setup.service - echo " * Disable triggerhappy.service" + echo " Disable triggerhappy.service" sudo systemctl disable triggerhappy.service sudo systemctl disable triggerhappy.socket - echo " * Disable raspi-config.service" + echo " Disable raspi-config.service" sudo systemctl disable raspi-config.service - echo " * Disable apt-daily.service & apt-daily-upgrade.service" + echo " Disable apt-daily.service & apt-daily-upgrade.service" sudo systemctl disable apt-daily.service sudo systemctl disable apt-daily-upgrade.service sudo systemctl disable apt-daily.timer @@ -29,24 +29,24 @@ _optimize_disable_irrelevant_services() { # TODO: If false, actually make sure bluetooth is enabled _optimize_handle_bluetooth() { if [ "$DISABLE_BLUETOOTH" = true ] ; then - echo " * Disable hciuart.service and bluetooth" + echo " Disable bluetooth" | tee /dev/fd/3 sudo systemctl disable hciuart.service sudo systemctl disable bluetooth.service fi } # TODO: Allow options to enable/disable wifi, Dynamic/Static IP etc. -_optimize_handle_network_connection() { +_optimize_static_ip() { # Static IP Address and DHCP optimizations if [ "$ENABLE_STATIC_IP" = true ] ; then - echo " * Set static IP address" | tee /dev/fd/3 + echo " Set static IP address" | tee /dev/fd/3 if grep -q "${OPTIMIZE_DHCP_CONF_HEADER}" "$OPTIMIZE_DHCP_CONF"; then - echo " Skipping. Already set up!" | tee /dev/fd/3 + echo " Skipping. Already set up!" else # DHCP has not been configured - echo " * ${CURRENT_INTERFACE} is the default network interface" | tee /dev/fd/3 - echo " * ${CURRENT_GATEWAY} is the Router Gateway address" | tee /dev/fd/3 - echo " * Using ${CURRENT_IP_ADDRESS} as the static IP for now" | tee /dev/fd/3 + echo " ${CURRENT_INTERFACE} is the default network interface" + echo " ${CURRENT_GATEWAY} is the Router Gateway address" + echo " Using ${CURRENT_IP_ADDRESS} as the static IP for now" sudo tee -a $OPTIMIZE_DHCP_CONF <<-EOF @@ -59,17 +59,15 @@ static domain_name_servers=${CURRENT_GATEWAY} EOF fi - else - echo " * Skipped static IP address" fi } # TODO: Allow both Enable and Disable _optimize_ipv6_arp() { if [ "$DISABLE_IPv6" = true ] ; then - echo " * Disabling IPV6 and ARP" + echo " Disabling IPV6" | tee /dev/fd/3 if grep -q "${OPTIMIZE_IPV6_CONF_HEADER}" "$OPTIMIZE_DHCP_CONF"; then - echo " Skipping. Already set up!" | tee /dev/fd/3 + echo " Skipping. Already set up!" else sudo tee -a $OPTIMIZE_DHCP_CONF <<-EOF @@ -86,9 +84,9 @@ EOF # TODO: Allow both Enable and Disable _optimize_handle_boot_screen() { if [ "$DISABLE_BOOT_SCREEN" = true ] ; then - echo " * Disable RPi rainbow screen" + echo " Disable RPi rainbow screen" if grep -q "${OPTIMIZE_BOOT_CONF_HEADER}" "$RPI_BOOT_CONFIG_FILE"; then - echo " Skipping. Already set up!" | tee /dev/fd/3 + echo " Skipping. Already set up!" else sudo tee -a $RPI_BOOT_CONFIG_FILE <<-EOF @@ -103,7 +101,7 @@ EOF # TODO: Allow both Enable and Disable _optimize_handle_boot_logs() { if [ "$DISABLE_BOOT_LOGS_PRINT" = true ] ; then - echo " * Disable boot logs" + echo " Disable boot logs" if [ ! -s "${RPI_BOOT_CMDLINE_FILE}" ];then sudo tee $RPI_BOOT_CMDLINE_FILE <<-EOF @@ -159,7 +157,7 @@ _optimize_check() { _run_optimize_boot_time() { _optimize_disable_irrelevant_services _optimize_handle_bluetooth - _optimize_handle_network_connection + _optimize_static_ip _optimize_ipv6_arp _optimize_handle_boot_screen _optimize_handle_boot_logs diff --git a/installation/routines/set_raspi_config.sh b/installation/routines/set_raspi_config.sh index dcbc70dec..da195b1bb 100644 --- a/installation/routines/set_raspi_config.sh +++ b/installation/routines/set_raspi_config.sh @@ -13,22 +13,22 @@ _run_set_raspi_config() { # Source: https://raspberrypi.stackexchange.com/a/66939 # Autologin - echo " * Enable Autologin for user" + echo " Enable Autologin for user" sudo raspi-config nonint do_boot_behaviour B2 # Wait for network at boot - # echo " * Enable 'Wait for network at boot'" + # echo " Enable 'Wait for network at boot'" # sudo raspi-config nonint do_boot_wait 1 # power management of wifi: switch off to avoid disconnecting - echo " * Disable Wifi power management to avoid disconnecting" + echo " Disable Wifi power management to avoid disconnecting" sudo iwconfig wlan0 power off # On-board audio if [[ $(_get_onboard_audio) -eq 1 ]]; then DISABLE_ONBOARD_AUDIO=${DISABLE_ONBOARD_AUDIO:-false} if [[ $DISABLE_ONBOARD_AUDIO = true ]]; then - echo " * Disable on-chip BCM audio" + echo " Disable on-chip BCM audio" echo " Backup ${RPI_BOOT_CONFIG_FILE} --> ${DISABLE_ONBOARD_AUDIO_BACKUP}" sudo cp "${RPI_BOOT_CONFIG_FILE}" "${DISABLE_ONBOARD_AUDIO_BACKUP}" sudo sed -i "s/^\(dtparam=\([^,]*,\)*\)audio=\(on\|true\|yes\|1\)\(.*\)/\1audio=off\4/g" "${RPI_BOOT_CONFIG_FILE}" diff --git a/installation/routines/set_ssh_qos.sh b/installation/routines/set_ssh_qos.sh index 793d96e05..eaca62fed 100644 --- a/installation/routines/set_ssh_qos.sh +++ b/installation/routines/set_ssh_qos.sh @@ -4,7 +4,7 @@ set_ssh_qos() { if [ "$DISABLE_SSH_QOS" == true ] ; then # The latest version of SSH installed on the Raspberry Pi 3 uses QoS headers, which disagrees with some # routers and other hardware. This causes immense delays when remotely accessing the RPi over ssh. - echo " * Set SSH QoS to best effort" + echo " Set SSH QoS to best effort" echo -e "IPQoS 0x00 0x00\n" | sudo tee -a /etc/ssh/sshd_config echo -e "IPQoS 0x00 0x00\n" | sudo tee -a /etc/ssh/ssh_config fi diff --git a/installation/routines/setup_git.sh b/installation/routines/setup_git.sh index f2a12e882..613062f43 100644 --- a/installation/routines/setup_git.sh +++ b/installation/routines/setup_git.sh @@ -2,7 +2,7 @@ GIT_ABORT_MSG="Aborting dir to git repo conversion. Your directory content is untouched, you simply cannot use git for updating / developing" _git_install_os_dependencies() { - echo "Install Git dependencies" + echo " Install Git dependencies" sudo apt-get -y update; sudo apt-get -y install \ git \ --no-install-recommends \ diff --git a/installation/routines/setup_jukebox_core.sh b/installation/routines/setup_jukebox_core.sh index 4f6d618dd..1e0c3a818 100644 --- a/installation/routines/setup_jukebox_core.sh +++ b/installation/routines/setup_jukebox_core.sh @@ -22,7 +22,7 @@ echo " -------------------------------------------------------------------- # Functions _jukebox_core_install_os_dependencies() { - echo " Install Jukebox OS dependencies" + echo " Install Jukebox OS dependencies" | tee /dev/fd/3 sudo apt-get -y update && sudo apt-get -y install \ at \ alsa-utils \ @@ -38,7 +38,7 @@ _jukebox_core_install_os_dependencies() { } _jukebox_core_install_python_requirements() { - echo " Install Python requirements" + echo " Install Python requirements" | tee /dev/fd/3 cd "${INSTALLATION_PATH}" || exit_on_error @@ -50,7 +50,7 @@ _jukebox_core_install_python_requirements() { } _jukebox_core_configure_pulseaudio() { - echo "Copy PulseAudio configuration" + echo " Copy PulseAudio configuration" | tee /dev/fd/3 mkdir -p $(dirname "$JUKEBOX_PULSE_CONFIG") cp -f "${INSTALLATION_PATH}/resources/default-settings/pulseaudio.default.pa" "${JUKEBOX_PULSE_CONFIG}" } @@ -90,7 +90,7 @@ _jukebox_core_build_and_install_pyzmq() { # Sources: # https://pyzmq.readthedocs.io/en/latest/howto/draft.html # https://github.com/MonsieurV/ZeroMQ-RPi/blob/master/README.md - echo " Build and install pyzmq with WebSockets Support" + echo " Build and install pyzmq with WebSockets Support" | tee /dev/fd/3 if ! pip list | grep -F pyzmq >> /dev/null; then # Download pre-compiled libzmq from Google Drive because RPi has trouble compiling it @@ -115,18 +115,18 @@ _jukebox_core_build_and_install_pyzmq() { ZMQ_PREFIX="${ZMQ_PREFIX}" ZMQ_DRAFT_API=1 \ pip install --no-cache-dir --no-binary "pyzmq" --pre pyzmq else - echo " Skipping. pyzmq already installed" + echo " Skipping. pyzmq already installed" | tee /dev/fd/3 fi } _jukebox_core_install_settings() { - echo " Register Jukebox settings" + echo " Register Jukebox settings" | tee /dev/fd/3 cp -f "${INSTALLATION_PATH}/resources/default-settings/jukebox.default.yaml" "${SETTINGS_PATH}/jukebox.yaml" cp -f "${INSTALLATION_PATH}/resources/default-settings/logger.default.yaml" "${SETTINGS_PATH}/logger.yaml" } _jukebox_core_register_as_service() { - echo " Register Jukebox Core user service" + echo " Register Jukebox Core user service" | tee /dev/fd/3 sudo cp -f "${INSTALLATION_PATH}/resources/default-services/jukebox-daemon.service" "${JUKEBOX_SERVICE_NAME}" sudo sed -i "s|%%INSTALLATION_PATH%%|${INSTALLATION_PATH}|g" "${JUKEBOX_SERVICE_NAME}" diff --git a/installation/routines/setup_jukebox_webapp.sh b/installation/routines/setup_jukebox_webapp.sh index 5c27a2e71..bd63f5653 100644 --- a/installation/routines/setup_jukebox_webapp.sh +++ b/installation/routines/setup_jukebox_webapp.sh @@ -47,7 +47,7 @@ _jukebox_webapp_install_node() { # TODO: Avoid building the app locally # Instead implement a Github Action that prebuilds on commititung a git tag _jukebox_webapp_build() { - echo " Building web application" + echo " Building web application" | tee /dev/fd/3 cd "${INSTALLATION_PATH}/src/webapp" || exit_on_error npm ci --prefer-offline --no-audit --production rm -rf build diff --git a/installation/routines/setup_kiosk_mode.sh b/installation/routines/setup_kiosk_mode.sh index ab5d9d301..f8d07971c 100644 --- a/installation/routines/setup_kiosk_mode.sh +++ b/installation/routines/setup_kiosk_mode.sh @@ -7,6 +7,7 @@ KIOSK_MODE_CHROMIUM_CUSTOM_DISABLE_UPDATE_CHECK='/etc/chromium-browser/customiza KIOSK_MODE_CHROMIUM_FLAG_UPDATE_INTERVAL='--check-for-update-interval=31536000' _kiosk_mode_install_os_dependencies() { + echo " Install Kiosk Mode dependencies" | tee /dev/fd/3 # Resource: # https://blog.r0b.io/post/minimal-rpi-kiosk/ sudo apt-get -qq -y install --no-install-recommends \ @@ -18,6 +19,7 @@ _kiosk_mode_install_os_dependencies() { } _kiosk_mode_set_autostart() { + echo " Configure Kiosk Mode" | tee /dev/fd/3 local _DISPLAY='$DISPLAY' local _XDG_VTNR='$XDG_VTNR' diff --git a/installation/routines/setup_mpd.sh b/installation/routines/setup_mpd.sh index 08aca35c3..da1f77337 100644 --- a/installation/routines/setup_mpd.sh +++ b/installation/routines/setup_mpd.sh @@ -4,8 +4,9 @@ AUDIOFOLDERS_PATH="${SHARED_PATH}/audiofolders" PLAYLISTS_PATH="${SHARED_PATH}/playlists" _mpd_install_os_dependencies() { + echo " Install MPD OS dependencies" sudo apt-get -y update - echo "Install MPD OS dependencies" + echo "Note: Installing MPD might cause a message: 'Job failed. See journalctl -xe for details'" echo "It can be ignored! It's an artefact of the MPD installation - nothing we can do about it." sudo apt-get -y install \ @@ -17,6 +18,13 @@ _mpd_install_os_dependencies() { } _mpd_configure() { + echo " Configure MPD as user local service" | tee /dev/fd/3 + + # Make sure system-wide mpd is disabled + sudo systemctl stop mpd.socket + sudo systemctl stop mpd.service + sudo systemctl disable mpd.socket + sudo systemctl disable mpd.service # MPD will be setup as user process (rather than a system-wide process) mkdir -p $(dirname "$MPD_CONF_PATH") @@ -25,6 +33,11 @@ _mpd_configure() { # Prepare new mpd.conf sed -i 's|%%JUKEBOX_AUDIOFOLDERS_PATH%%|'"$AUDIOFOLDERS_PATH"'|' "${MPD_CONF_PATH}" sed -i 's|%%JUKEBOX_PLAYLISTS_PATH%%|'"$PLAYLISTS_PATH"'|' "${MPD_CONF_PATH}" + + # Prepare user-service MPD to be started at next boot + systemctl --user daemon-reload + systemctl --user enable mpd.socket + systemctl --user enable mpd.service } _mpd_check() { @@ -45,23 +58,10 @@ _mpd_check() { } _run_setup_mpd() { + # Install/update only if enabled: do not stuff up any existing configuration if [[ $ENABLE_MPD_OVERWRITE_INSTALL == true ]] ; then - - # Install/update only if enabled: do not stuff up any existing configuration _mpd_install_os_dependencies - - # Make sure system-wide mpd is disabled - echo "Configure MPD as user local service" | tee /dev/fd/3 - sudo systemctl stop mpd.socket - sudo systemctl stop mpd.service - sudo systemctl disable mpd.socket - sudo systemctl disable mpd.service _mpd_configure - # Prepare user-service MPD to be started at next boot - systemctl --user daemon-reload - systemctl --user enable mpd.socket - systemctl --user enable mpd.service - _mpd_check fi } diff --git a/installation/routines/setup_samba.sh b/installation/routines/setup_samba.sh index edefc33e2..12f03797a 100644 --- a/installation/routines/setup_samba.sh +++ b/installation/routines/setup_samba.sh @@ -4,7 +4,7 @@ SMB_CONF="/etc/samba/smb.conf" SMB_CONF_HEADER="## Jukebox Samba Config" _samba_install_os_dependencies() { - echo "Install Samba Core dependencies" + echo " Install Samba Core dependencies" sudo apt-get -qq -y update; sudo apt-get -qq -y install \ samba samba-common-bin \ --no-install-recommends \ @@ -14,12 +14,13 @@ _samba_install_os_dependencies() { } _samba_set_user() { + echo " Configure Samba" | tee /dev/fd/3 local SMB_USER="pi" local SMB_PASSWD="raspberry" # Samba has not been configured if grep -q "$SMB_CONF_HEADER" "$SMB_CONF"; then - echo " Skipping. Already set up!" | tee /dev/fd/3 + echo " Skipping. Already set up!" | tee /dev/fd/3 else # Create Samba user (echo "${SMB_PASSWD}"; echo "${SMB_PASSWD}") | sudo smbpasswd -s -a $SMB_USER @@ -66,6 +67,6 @@ _run_setup_samba() { setup_samba() { if [ "$ENABLE_SAMBA" == true ] ; then - run_with_log_frame _run_setup_samba "Install Samba and configure user" + run_with_log_frame _run_setup_samba "Install Samba" fi } From 1ed72d5be0d4523fc3f284b95b7bcc26fe461262 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 08:46:34 +0100 Subject: [PATCH 29/44] refactored disable onboard audio. only execute if flag is true. inlined function --- installation/routines/set_raspi_config.sh | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/installation/routines/set_raspi_config.sh b/installation/routines/set_raspi_config.sh index da195b1bb..a9cb7b6f1 100644 --- a/installation/routines/set_raspi_config.sh +++ b/installation/routines/set_raspi_config.sh @@ -1,14 +1,5 @@ #!/usr/bin/env bash -_get_onboard_audio() { - if grep -q -E "^dtparam=([^,]*,)*audio=(on|true|yes|1).*" ${RPI_BOOT_CONFIG_FILE} - then - echo 1 - else - echo 0 - fi -} - _run_set_raspi_config() { # Source: https://raspberrypi.stackexchange.com/a/66939 @@ -25,16 +16,15 @@ _run_set_raspi_config() { sudo iwconfig wlan0 power off # On-board audio - if [[ $(_get_onboard_audio) -eq 1 ]]; then - DISABLE_ONBOARD_AUDIO=${DISABLE_ONBOARD_AUDIO:-false} - if [[ $DISABLE_ONBOARD_AUDIO = true ]]; then - echo " Disable on-chip BCM audio" + if [ "$DISABLE_ONBOARD_AUDIO" == true ]; then + echo " Disable on-chip BCM audio" + if grep -q -E "^dtparam=([^,]*,)*audio=(on|true|yes|1).*" "${RPI_BOOT_CONFIG_FILE}" ; then echo " Backup ${RPI_BOOT_CONFIG_FILE} --> ${DISABLE_ONBOARD_AUDIO_BACKUP}" sudo cp "${RPI_BOOT_CONFIG_FILE}" "${DISABLE_ONBOARD_AUDIO_BACKUP}" sudo sed -i "s/^\(dtparam=\([^,]*,\)*\)audio=\(on\|true\|yes\|1\)\(.*\)/\1audio=off\4/g" "${RPI_BOOT_CONFIG_FILE}" + else + echo " On board audio seems to be off already. Not touching ${RPI_BOOT_CONFIG_FILE}" fi - else - echo " On board audio seems to be off already. Not touching ${RPI_BOOT_CONFIG_FILE}" fi } From 1fb7c1d56f2a43aaf5c4a547406b948767d48843 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 08:56:09 +0100 Subject: [PATCH 30/44] add restart nginx.service again. use HOME_PATH --- installation/routines/setup_jukebox_webapp.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/installation/routines/setup_jukebox_webapp.sh b/installation/routines/setup_jukebox_webapp.sh index bd63f5653..2216caf32 100644 --- a/installation/routines/setup_jukebox_webapp.sh +++ b/installation/routines/setup_jukebox_webapp.sh @@ -75,7 +75,9 @@ _jukebox_webapp_register_as_system_service_with_nginx() { sudo cp -f "${INSTALLATION_PATH}/resources/default-settings/nginx.default" "${WEBAPP_NGINX_SITE_DEFAULT_CONF}" # make sure nginx can access the home directory of the user - sudo chmod o+x /home/pi + sudo chmod o+x "${HOME_PATH}" + + sudo systemctl restart nginx.service } _jukebox_webapp_check() { From 38c4f7cd204cc0def91a34407828601f364d56cd Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 10:52:01 +0100 Subject: [PATCH 31/44] fix and check adding samba user --- installation/routines/setup_samba.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/installation/routines/setup_samba.sh b/installation/routines/setup_samba.sh index 12f03797a..4b45b54e1 100644 --- a/installation/routines/setup_samba.sh +++ b/installation/routines/setup_samba.sh @@ -15,7 +15,6 @@ _samba_install_os_dependencies() { _samba_set_user() { echo " Configure Samba" | tee /dev/fd/3 - local SMB_USER="pi" local SMB_PASSWD="raspberry" # Samba has not been configured @@ -23,7 +22,7 @@ _samba_set_user() { echo " Skipping. Already set up!" | tee /dev/fd/3 else # Create Samba user - (echo "${SMB_PASSWD}"; echo "${SMB_PASSWD}") | sudo smbpasswd -s -a $SMB_USER + (echo "${SMB_PASSWD}"; echo "${SMB_PASSWD}") | sudo smbpasswd -s -a "${CURRENT_USER}" sudo chown root:root $SMB_CONF sudo chmod 777 $SMB_CONF @@ -55,6 +54,10 @@ _samba_check() { verify_file_contains_string "${SMB_CONF_HEADER}" "${SMB_CONF}" verify_file_contains_string "${SHARED_PATH}" "${SMB_CONF}" + + if ! (sudo pdbedit -L | grep -qw "^${CURRENT_USER}") ; then + exit_on_error "ERROR: samba user not found" + fi } _run_setup_samba() { From e3c84aaa382d39ac0054e7d41fc4317067ad7171 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 10:56:58 +0100 Subject: [PATCH 32/44] fix logging mpd setup routine --- installation/routines/setup_mpd.sh | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/installation/routines/setup_mpd.sh b/installation/routines/setup_mpd.sh index da1f77337..40ffe8aac 100644 --- a/installation/routines/setup_mpd.sh +++ b/installation/routines/setup_mpd.sh @@ -58,16 +58,14 @@ _mpd_check() { } _run_setup_mpd() { - # Install/update only if enabled: do not stuff up any existing configuration - if [[ $ENABLE_MPD_OVERWRITE_INSTALL == true ]] ; then - _mpd_install_os_dependencies - _mpd_configure - _mpd_check - fi + _mpd_install_os_dependencies + _mpd_configure + _mpd_check } setup_mpd() { - if [ "$SETUP_MPD" == true ] ; then + # Install/update only if enabled: do not stuff up any existing configuration + if [[ "$SETUP_MPD" == true && $ENABLE_MPD_OVERWRITE_INSTALL == true ]] ; then run_with_log_frame _run_setup_mpd "Install MPD" fi } From e71d0759ae5cfc9410d031aca353083b6684539e Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 11:10:22 +0100 Subject: [PATCH 33/44] fix Disable boot logs error on existing file --- ci/ci-debian.Dockerfile | 2 +- installation/routines/optimize_boot_time.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/ci-debian.Dockerfile b/ci/ci-debian.Dockerfile index 307a0a465..e7758d4c3 100644 --- a/ci/ci-debian.Dockerfile +++ b/ci/ci-debian.Dockerfile @@ -7,8 +7,8 @@ ARG DEBIAN_CODENAME ENV CI_RUNNING=true TERM=xterm # create pi configs to test installation -RUN touch /boot/cmdline.txt RUN touch /boot/config.txt +RUN echo "logo.nologo" > /boot/cmdline.txt RUN export DEBIAN_FRONTEND=noninteractive \ && echo "--- install packages (1) ---" \ diff --git a/installation/routines/optimize_boot_time.sh b/installation/routines/optimize_boot_time.sh index 13c78287a..0072e5a21 100644 --- a/installation/routines/optimize_boot_time.sh +++ b/installation/routines/optimize_boot_time.sh @@ -104,13 +104,13 @@ _optimize_handle_boot_logs() { echo " Disable boot logs" if [ ! -s "${RPI_BOOT_CMDLINE_FILE}" ];then - sudo tee $RPI_BOOT_CMDLINE_FILE <<-EOF + sudo tee "${RPI_BOOT_CMDLINE_FILE}" <<-EOF ${OPTIMIZE_BOOT_CMDLINE_OPTIONS} EOF else for option in $OPTIMIZE_BOOT_CMDLINE_OPTIONS do - if ! $(grep -iw "$option" "${RPI_BOOT_CMDLINE_FILE}") ; then + if ! grep -qiw "$option" "${RPI_BOOT_CMDLINE_FILE}" ; then sudo sed -i "s/$/ $option/" "${RPI_BOOT_CMDLINE_FILE}" fi done From 86babb699d9117a44426ec48adb82203f88dce65 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 11:15:48 +0100 Subject: [PATCH 34/44] added timer to log frame --- installation/includes/02_helpers.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/installation/includes/02_helpers.sh b/installation/includes/02_helpers.sh index 1e1f9c0a5..4a39ae07e 100644 --- a/installation/includes/02_helpers.sh +++ b/installation/includes/02_helpers.sh @@ -9,7 +9,7 @@ calc_runtime_and_print() { ((m=(${runtime}%3600)/60)) ((s=${runtime}%60)) - echo "Done in ${h}h ${m}m ${s}s." + echo "Done in ${h}h ${m}m ${s}s" } run_with_timer() { @@ -18,10 +18,10 @@ run_with_timer() { $1; # Executes the function passed as an argument calc_runtime_and_print time_start $(date +%s) | tee /dev/fd/3 - echo "--------------------------------------" } run_with_log_frame() { + local time_start=$(date +%s); local description="$2" echo -e "\n\n" echo "#########################################################" @@ -29,7 +29,8 @@ run_with_log_frame() { $1; # Executes the function passed as an argument - echo -e "\nDONE: ${description}" + local done_in=$(calc_runtime_and_print time_start $(date +%s)) + echo -e "\n${done_in} - ${description}" echo "#########################################################" } From bb3ea07ebb7ba1004ebbaf95422c0fa2dc586ced Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 10:21:22 +0100 Subject: [PATCH 35/44] add core package installation from file used also for ci optimization --- ci/ci-debian.Dockerfile | 17 +++++++---------- installation/routines/setup_jukebox_core.sh | 19 +++++-------------- installation/routines/setup_jukebox_webapp.sh | 1 - packages-core.txt | 17 +++++++++++++++++ 4 files changed, 29 insertions(+), 25 deletions(-) create mode 100644 packages-core.txt diff --git a/ci/ci-debian.Dockerfile b/ci/ci-debian.Dockerfile index e7758d4c3..f6acc4d36 100644 --- a/ci/ci-debian.Dockerfile +++ b/ci/ci-debian.Dockerfile @@ -26,9 +26,8 @@ RUN export DEBIAN_FRONTEND=noninteractive \ && apt-get update \ && apt-get -y upgrade \ && apt-get -y install \ - alsa-utils \ build-essential \ - locales \ + iproute2 \ openssh-client \ sudo \ systemd \ @@ -73,15 +72,13 @@ ARG GIT_USER ENV GIT_BRANCH=$GIT_BRANCH GIT_USER=$GIT_USER -# COPY --chown=root:$TEST_USER_GROUP --chmod=770 packages.txt packages-raspberrypi.txt ./ +COPY --chown=root:$TEST_USER_GROUP --chmod=770 packages-core.txt ./ -# RUN export DEBIAN_FRONTEND=noninteractive \ -# && echo "--- install internal packages ---" \ -# && apt-get update \ -# # remove resolvconf as installation will fail in container -# && sed 's/#.*//g' packages.txt | sed 's/resolvconf//' | xargs apt-get -y install \ -# && sed 's/#.*//g' packages-raspberrypi.txt | xargs apt-get -y install \ -# && rm -rf /var/lib/apt/lists/* +RUN export DEBIAN_FRONTEND=noninteractive \ + && echo "--- install internal packages ---" \ + && apt-get update \ + && sed 's/#.*//g' packages-core.txt | xargs apt-get -y install \ + && rm -rf /var/lib/apt/lists/* ENV INSTALL_SCRIPT_PATH=/code diff --git a/installation/routines/setup_jukebox_core.sh b/installation/routines/setup_jukebox_core.sh index 1e0c3a818..3daa53081 100644 --- a/installation/routines/setup_jukebox_core.sh +++ b/installation/routines/setup_jukebox_core.sh @@ -23,14 +23,10 @@ echo " -------------------------------------------------------------------- # Functions _jukebox_core_install_os_dependencies() { echo " Install Jukebox OS dependencies" | tee /dev/fd/3 + + local apt_packages=$(get_args_from_file "${INSTALLATION_PATH}/packages-core.txt") sudo apt-get -y update && sudo apt-get -y install \ - at \ - alsa-utils \ - python3 python3-venv python3-dev \ - espeak ffmpeg mpg123 \ - pulseaudio pulseaudio-module-bluetooth pulseaudio-utils caps \ - libasound2-dev \ - rsync \ + $apt_packages \ --no-install-recommends \ --allow-downgrades \ --allow-remove-essential \ @@ -139,13 +135,8 @@ _jukebox_core_register_as_service() { _jukebox_core_check() { print_verify_installation - verify_apt_packages at \ - alsa-utils \ - python3 python3-venv python3-dev \ - espeak ffmpeg mpg123 \ - pulseaudio pulseaudio-module-bluetooth pulseaudio-utils caps \ - libasound2-dev \ - rsync + local apt_packages=$(get_args_from_file "${INSTALLATION_PATH}/packages-core.txt") + verify_apt_packages $apt_packages verify_dirs_exists "${VIRTUAL_ENV}" diff --git a/installation/routines/setup_jukebox_webapp.sh b/installation/routines/setup_jukebox_webapp.sh index 2216caf32..d7a7b104b 100644 --- a/installation/routines/setup_jukebox_webapp.sh +++ b/installation/routines/setup_jukebox_webapp.sh @@ -40,7 +40,6 @@ _jukebox_webapp_install_node() { sudo apt-get update sudo apt-get install -y nodejs fi - fi } diff --git a/packages-core.txt b/packages-core.txt new file mode 100644 index 000000000..b2f6779a2 --- /dev/null +++ b/packages-core.txt @@ -0,0 +1,17 @@ +# Define packages for apt-get. These can be installed with +# 'sed 's/#.*//g' packages.txt | xargs sudo apt-get install' + +at +alsa-utils +caps +espeak +ffmpeg +libasound2-dev +mpg123 +pulseaudio +pulseaudio-module-bluetooth +pulseaudio-utils +python3 +python3-venv +python3-dev +rsync From 5e9207eae75aefd84e6f2e7e30bb16bef55cba4a Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:29:54 +0100 Subject: [PATCH 36/44] Dont let remove packages fail install. ignore for ci --- installation/routines/update_raspi_os.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/installation/routines/update_raspi_os.sh b/installation/routines/update_raspi_os.sh index 36092fcf9..f38e975ed 100644 --- a/installation/routines/update_raspi_os.sh +++ b/installation/routines/update_raspi_os.sh @@ -1,7 +1,10 @@ #!/usr/bin/env bash _run_update_raspi_os() { - sudo apt-get -qq -y update && sudo apt-get -qq -y full-upgrade && sudo apt-get -qq -y autoremove || exit_on_error "Failed to Update Raspberry Pi OS" + sudo apt-get -qq -y update && sudo apt-get -qq -y full-upgrade || exit_on_error "Failed to Update Raspberry Pi OS" + if [ "$CI_RUNNING" != "true" ]; then + sudo apt-get -qq -y autoremove + fi } update_raspi_os() { From b35f2cdac550d238e42c5f8aec092035f3d3620b Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 13:41:36 +0100 Subject: [PATCH 37/44] Update test scripts use robust path determination move noninteractive to dockerfile --- ci/ci-debian.Dockerfile | 15 ++++++++------- ci/installation/run_install_faststartup.sh | 13 +++++-------- ci/installation/run_install_test.sh | 13 +++++-------- ci/installation/run_install_user_not_pi.sh | 13 +++++-------- ci/installation/run_install_webapp.sh | 13 +++++-------- 5 files changed, 28 insertions(+), 39 deletions(-) diff --git a/ci/ci-debian.Dockerfile b/ci/ci-debian.Dockerfile index f6acc4d36..1a227755a 100644 --- a/ci/ci-debian.Dockerfile +++ b/ci/ci-debian.Dockerfile @@ -4,14 +4,14 @@ ARG BASE_TEST_IMAGE=test-code FROM debian:${DEBIAN_CODENAME}-slim as base ARG DEBIAN_CODENAME -ENV CI_RUNNING=true TERM=xterm +ENV TERM=xterm DEBIAN_FRONTEND=noninteractive +ENV CI_RUNNING=true # create pi configs to test installation RUN touch /boot/config.txt RUN echo "logo.nologo" > /boot/cmdline.txt -RUN export DEBIAN_FRONTEND=noninteractive \ - && echo "--- install packages (1) ---" \ +RUN echo "--- install packages (1) ---" \ && apt-get update \ && apt-get -y install \ apt-utils \ @@ -35,6 +35,9 @@ RUN export DEBIAN_FRONTEND=noninteractive \ wget \ wpasupplicant \ && rm -rf /var/lib/apt/lists/* + +# Set NonInteractive for sudo usage in container. 'sudo' package needed +RUN echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections # ------ # Base Target for setting up the default user. user can be selected with the docker '--user YYY' option @@ -74,8 +77,7 @@ ENV GIT_BRANCH=$GIT_BRANCH GIT_USER=$GIT_USER COPY --chown=root:$TEST_USER_GROUP --chmod=770 packages-core.txt ./ -RUN export DEBIAN_FRONTEND=noninteractive \ - && echo "--- install internal packages ---" \ +RUN echo "--- install internal packages ---" \ && apt-get update \ && sed 's/#.*//g' packages-core.txt | xargs apt-get -y install \ && rm -rf /var/lib/apt/lists/* @@ -92,8 +94,7 @@ COPY --chown=root:$TEST_USER_GROUP --chmod=770 ci/installation/*.sh ./ # Target for applying latest updates (should not be cached!) FROM $BASE_TEST_IMAGE as test-update -RUN export DEBIAN_FRONTEND=noninteractive \ - && apt-get update \ +RUN apt-get update \ && apt-get -y upgrade \ && rm -rf /var/lib/apt/lists/* # ------ diff --git a/ci/installation/run_install_faststartup.sh b/ci/installation/run_install_faststartup.sh index 1cefbc8be..7737f0d6e 100644 --- a/ci/installation/run_install_faststartup.sh +++ b/ci/installation/run_install_faststartup.sh @@ -5,13 +5,10 @@ # Objective: Test installation with script using a simple configuration -local_install_script_path="${INSTALL_SCRIPT_PATH:-./../../installation/}" -local_install_script_path="${local_install_script_path%/}" - -# Preparations -# No interactive frontend -export DEBIAN_FRONTEND=noninteractive -echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections +SOURCE="${BASH_SOURCE[0]}" +SCRIPT_DIR="$(dirname "$SOURCE")" +LOCAL_INSTALL_SCRIPT_PATH="${INSTALL_SCRIPT_PATH:-${SCRIPT_DIR}/../../installation}" +LOCAL_INSTALL_SCRIPT_PATH="${LOCAL_INSTALL_SCRIPT_PATH%/}" # Run installation (in interactive mode) # y - start setup @@ -28,7 +25,7 @@ echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selecti # - - install node (only with WebApp = y) # n - reboot -"$local_install_script_path"/install-jukebox.sh <<< 'y +"${LOCAL_INSTALL_SCRIPT_PATH}/install-jukebox.sh" <<< 'y y y n diff --git a/ci/installation/run_install_test.sh b/ci/installation/run_install_test.sh index 6f2f07fdd..d480434f2 100644 --- a/ci/installation/run_install_test.sh +++ b/ci/installation/run_install_test.sh @@ -5,13 +5,10 @@ # Objective: Test installation with script using a simple configuration -local_install_script_path="${INSTALL_SCRIPT_PATH:-./../../installation/}" -local_install_script_path="${local_install_script_path%/}" - -# Preparations -# No interactive frontend -export DEBIAN_FRONTEND=noninteractive -echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections +SOURCE="${BASH_SOURCE[0]}" +SCRIPT_DIR="$(dirname "$SOURCE")" +LOCAL_INSTALL_SCRIPT_PATH="${INSTALL_SCRIPT_PATH:-${SCRIPT_DIR}/../../installation}" +LOCAL_INSTALL_SCRIPT_PATH="${LOCAL_INSTALL_SCRIPT_PATH%/}" # Run installation (in interactive mode) # y - start setup @@ -29,7 +26,7 @@ echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selecti # y - install node # n - reboot -"$local_install_script_path"/install-jukebox.sh <<< 'y +"${LOCAL_INSTALL_SCRIPT_PATH}/install-jukebox.sh" <<< 'y n n y diff --git a/ci/installation/run_install_user_not_pi.sh b/ci/installation/run_install_user_not_pi.sh index 02cf2734c..76a8cd576 100644 --- a/ci/installation/run_install_user_not_pi.sh +++ b/ci/installation/run_install_user_not_pi.sh @@ -5,18 +5,15 @@ # Objective: Test installation with script using a simple configuration -local_install_script_path="${INSTALL_SCRIPT_PATH:-./../../installation/}" -local_install_script_path="${local_install_script_path%/}" - -# Preparations -# No interactive frontend -export DEBIAN_FRONTEND=noninteractive -echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections +SOURCE="${BASH_SOURCE[0]}" +SCRIPT_DIR="$(dirname "$SOURCE")" +LOCAL_INSTALL_SCRIPT_PATH="${INSTALL_SCRIPT_PATH:-${SCRIPT_DIR}/../../installation}" +LOCAL_INSTALL_SCRIPT_PATH="${LOCAL_INSTALL_SCRIPT_PATH%/}" # Run installation (in interactive mode) # - - Installation must abort early -"$local_install_script_path"/install-jukebox.sh +"${LOCAL_INSTALL_SCRIPT_PATH}/install-jukebox.sh" INSTALLATION_EXITCODE=$? # only count abortion due to "not user pi" as success diff --git a/ci/installation/run_install_webapp.sh b/ci/installation/run_install_webapp.sh index cc36fdeaf..263e5234e 100644 --- a/ci/installation/run_install_webapp.sh +++ b/ci/installation/run_install_webapp.sh @@ -5,13 +5,10 @@ # Objective: Test installation with script using a simple configuration -local_install_script_path="${INSTALL_SCRIPT_PATH:-./../../installation/}" -local_install_script_path="${local_install_script_path%/}" - -# Preparations -# No interactive frontend -export DEBIAN_FRONTEND=noninteractive -echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections +SOURCE="${BASH_SOURCE[0]}" +SCRIPT_DIR="$(dirname "$SOURCE")" +LOCAL_INSTALL_SCRIPT_PATH="${INSTALL_SCRIPT_PATH:-${SCRIPT_DIR}/../../installation}" +LOCAL_INSTALL_SCRIPT_PATH="${LOCAL_INSTALL_SCRIPT_PATH%/}" # Run installation (in interactive mode) # y - start setup @@ -28,7 +25,7 @@ echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selecti # y - install node # n - reboot -"$local_install_script_path"/install-jukebox.sh <<< 'y +"${LOCAL_INSTALL_SCRIPT_PATH}/install-jukebox.sh" <<< 'y n n n From 06bf8b743819f8273d92ad865b3616ccc66571b3 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 17:28:30 +0100 Subject: [PATCH 38/44] fix clear in mpd option --- installation/routines/customize_options.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/installation/routines/customize_options.sh b/installation/routines/customize_options.sh index dc6572be0..50df075fe 100644 --- a/installation/routines/customize_options.sh +++ b/installation/routines/customize_options.sh @@ -119,6 +119,7 @@ Do you want to disable Bluetooth? [Y/n]" 1>&3 } _option_mpd() { + clear 1>&3 if [[ "$SETUP_MPD" == true ]]; then if [[ -f "${MPD_CONF_PATH}" || -f "${SYSTEMD_USR_PATH}/mpd.service" ]]; then echo "-------------------------- MPD -------------------------- From d011faa898c9b8d3bf1b6a27207830bc00c25532 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 22:07:43 +0100 Subject: [PATCH 39/44] fix bug in rfid configure --- src/jukebox/components/rfid/configure/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jukebox/components/rfid/configure/__init__.py b/src/jukebox/components/rfid/configure/__init__.py index 369b67b3d..0a8ff7aca 100755 --- a/src/jukebox/components/rfid/configure/__init__.py +++ b/src/jukebox/components/rfid/configure/__init__.py @@ -174,7 +174,7 @@ def query_user_for_reader(dependency_install='query') -> dict: while True: # List all modules and query user print("Choose Reader Module from list:\n") - for idx, (des, mod) in enumerate(reader_descriptions.values): + for idx, (des, mod) in enumerate(reader_descriptions.values()): print(f" {Colors.lightgreen}{idx:2d}{Colors.reset}: {Colors.lightcyan}{Colors.bold}{des:40s}{Colors.reset} " f"(Module: {mod})") print("") From 82a847f500ce7268c4dfc6d428dd9f2cb74586a6 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 22:48:26 +0100 Subject: [PATCH 40/44] fix error on uninitialized rfid_reader settings --- .../components/rfid/reader/__init__.py | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/jukebox/components/rfid/reader/__init__.py b/src/jukebox/components/rfid/reader/__init__.py index 9245a127a..db0ccb1da 100644 --- a/src/jukebox/components/rfid/reader/__init__.py +++ b/src/jukebox/components/rfid/reader/__init__.py @@ -239,14 +239,22 @@ def run(self): # noqa: C901 @plugs.finalize def finalize(): - jukebox.cfghandler.load_yaml(cfg_rfid, cfg_main.getn('rfid', 'reader_config')) - - # Load all the required modules - # Start a ReaderRunner-Thread for each Reader - for reader_cfg_key in cfg_rfid['rfid']['readers'].keys(): - _READERS[reader_cfg_key] = ReaderRunner(reader_cfg_key) - for reader_cfg_key in cfg_rfid['rfid']['readers'].keys(): - _READERS[reader_cfg_key].start() + try: + reader_config_file = cfg_main.getn('rfid', 'reader_config') + jukebox.cfghandler.load_yaml(cfg_rfid, reader_config_file) + except FileNotFoundError: + cfg_rfid.config_dict({'rfid': {'readers': {}}}) + log.warning(f"rfid reader database file not found. Creating empty database: '{reader_config_file}'") + # Save the empty rfid reader database, to make sure we can create the file and have access to it + cfg_rfid.save(only_if_changed=False) + + if 'rfid' in cfg_rfid and 'readers' in cfg_rfid['rfid']: + # Load all the required modules + # Start a ReaderRunner-Thread for each Reader + for reader_cfg_key in cfg_rfid['rfid']['readers'].keys(): + _READERS[reader_cfg_key] = ReaderRunner(reader_cfg_key) + for reader_cfg_key in cfg_rfid['rfid']['readers'].keys(): + _READERS[reader_cfg_key].start() @plugs.atexit From 1b53fbe9a017f9decbe643c9c5d3f65151255d92 Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Mon, 20 Nov 2023 23:37:02 +0100 Subject: [PATCH 41/44] add checks for static ip config --- installation/routines/optimize_boot_time.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/installation/routines/optimize_boot_time.sh b/installation/routines/optimize_boot_time.sh index 0072e5a21..383f790c0 100644 --- a/installation/routines/optimize_boot_time.sh +++ b/installation/routines/optimize_boot_time.sh @@ -138,6 +138,9 @@ _optimize_check() { if [ "$ENABLE_STATIC_IP" = true ] ; then verify_file_contains_string_once "${OPTIMIZE_DHCP_CONF_HEADER}" "${OPTIMIZE_DHCP_CONF}" + verify_file_contains_string "${CURRENT_INTERFACE}" "${OPTIMIZE_DHCP_CONF}" + verify_file_contains_string "${CURRENT_IP_ADDRESS}" "${OPTIMIZE_DHCP_CONF}" + verify_file_contains_string "${CURRENT_GATEWAY}" "${OPTIMIZE_DHCP_CONF}" fi if [ "$DISABLE_IPv6" = true ] ; then verify_file_contains_string_once "${OPTIMIZE_IPV6_CONF_HEADER}" "${OPTIMIZE_DHCP_CONF}" From 6e1d33446484ab98294e6287a4eeed50b96620be Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Tue, 21 Nov 2023 08:49:17 +0100 Subject: [PATCH 42/44] Added test for webapp download in prod. Update test descriptions. --- .../test_docker_debian_codename_sub.yml | 2 +- ..._install_test.sh => run_install_common.sh} | 9 ++-- ci/installation/run_install_faststartup.sh | 9 ++-- .../run_install_webapp_download.sh | 41 +++++++++++++++++++ ..._webapp.sh => run_install_webapp_local.sh} | 6 ++- 5 files changed, 56 insertions(+), 11 deletions(-) rename ci/installation/{run_install_test.sh => run_install_common.sh} (80%) create mode 100644 ci/installation/run_install_webapp_download.sh rename ci/installation/{run_install_webapp.sh => run_install_webapp_local.sh} (83%) diff --git a/.github/workflows/test_docker_debian_codename_sub.yml b/.github/workflows/test_docker_debian_codename_sub.yml index 1ea59935a..54abd142a 100644 --- a/.github/workflows/test_docker_debian_codename_sub.yml +++ b/.github/workflows/test_docker_debian_codename_sub.yml @@ -138,7 +138,7 @@ jobs: fail-fast: false matrix: username: ['pi'] - test_script: ['run_install_test.sh', 'run_install_webapp.sh', 'run_install_faststartup.sh'] + test_script: ['run_install_common.sh', 'run_install_faststartup.sh', 'run_install_webapp_local.sh', 'run_install_webapp_download.sh'] include: - username: hans test_script: run_install_user_not_pi.sh diff --git a/ci/installation/run_install_test.sh b/ci/installation/run_install_common.sh similarity index 80% rename from ci/installation/run_install_test.sh rename to ci/installation/run_install_common.sh index d480434f2..102c71aa4 100644 --- a/ci/installation/run_install_test.sh +++ b/ci/installation/run_install_common.sh @@ -3,13 +3,15 @@ # Install Phoniebox and test it # Used e.g. for tests on Docker -# Objective: Test installation with script using a simple configuration +# Objective: +# Test for a common installation path. Including autohotspot SOURCE="${BASH_SOURCE[0]}" SCRIPT_DIR="$(dirname "$SOURCE")" LOCAL_INSTALL_SCRIPT_PATH="${INSTALL_SCRIPT_PATH:-${SCRIPT_DIR}/../../installation}" LOCAL_INSTALL_SCRIPT_PATH="${LOCAL_INSTALL_SCRIPT_PATH%/}" +export ENABLE_WEBAPP_PROD_DOWNLOAD=true # Run installation (in interactive mode) # y - start setup # n - use static ip @@ -21,9 +23,9 @@ LOCAL_INSTALL_SCRIPT_PATH="${LOCAL_INSTALL_SCRIPT_PATH%/}" # - - mpd overwrite config (only with existing installation) # n - setup rfid reader # y - setup samba -# y - build local WebApp +# y - setup webapp # n - setup kiosk mode -# y - install node +# - - install node (forced WebApp Download) # n - reboot "${LOCAL_INSTALL_SCRIPT_PATH}/install-jukebox.sh" <<< 'y @@ -37,6 +39,5 @@ n y y n -y n ' diff --git a/ci/installation/run_install_faststartup.sh b/ci/installation/run_install_faststartup.sh index 7737f0d6e..46cda25ec 100644 --- a/ci/installation/run_install_faststartup.sh +++ b/ci/installation/run_install_faststartup.sh @@ -3,7 +3,8 @@ # Install Phoniebox and test it # Used e.g. for tests on Docker -# Objective: Test installation with script using a simple configuration +# Objective: +# Test for disabling features (suggestions for faststartup). Skips installing all additionals. SOURCE="${BASH_SOURCE[0]}" SCRIPT_DIR="$(dirname "$SOURCE")" @@ -20,9 +21,9 @@ LOCAL_INSTALL_SCRIPT_PATH="${LOCAL_INSTALL_SCRIPT_PATH%/}" # - - mpd overwrite config (only with existing installation) # n - setup rfid reader # n - setup samba -# n - build local WebApp -# - - setup kiosk mode (only with WebApp = y) -# - - install node (only with WebApp = y) +# n - setup webapp +# - - setup kiosk mode (only with webapp = y) +# - - install node (only with webapp = y) # n - reboot "${LOCAL_INSTALL_SCRIPT_PATH}/install-jukebox.sh" <<< 'y diff --git a/ci/installation/run_install_webapp_download.sh b/ci/installation/run_install_webapp_download.sh new file mode 100644 index 000000000..69496e8e4 --- /dev/null +++ b/ci/installation/run_install_webapp_download.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +# Install Phoniebox and test it +# Used e.g. for tests on Docker + +# Objective: +# Test for the WebApp (download) and dependent features path. + +SOURCE="${BASH_SOURCE[0]}" +SCRIPT_DIR="$(dirname "$SOURCE")" +LOCAL_INSTALL_SCRIPT_PATH="${INSTALL_SCRIPT_PATH:-${SCRIPT_DIR}/../../installation}" +LOCAL_INSTALL_SCRIPT_PATH="${LOCAL_INSTALL_SCRIPT_PATH%/}" + +export ENABLE_WEBAPP_PROD_DOWNLOAD=true +# Run installation (in interactive mode) +# y - start setup +# n - use static ip +# n - deactivate ipv6 +# n - setup autohotspot +# n - deactivate bluetooth +# n - disable on-chip audio +# - - mpd overwrite config (only with existing installation) +# n - setup rfid reader +# n - setup samba +# y - setup webapp +# y - setup kiosk mode +# - - install node (forced webapp download) +# n - reboot + +"${LOCAL_INSTALL_SCRIPT_PATH}/install-jukebox.sh" <<< 'y +n +n +n +n +n +n +n +y +y +n +' diff --git a/ci/installation/run_install_webapp.sh b/ci/installation/run_install_webapp_local.sh similarity index 83% rename from ci/installation/run_install_webapp.sh rename to ci/installation/run_install_webapp_local.sh index 263e5234e..d4f122fd5 100644 --- a/ci/installation/run_install_webapp.sh +++ b/ci/installation/run_install_webapp_local.sh @@ -3,13 +3,15 @@ # Install Phoniebox and test it # Used e.g. for tests on Docker -# Objective: Test installation with script using a simple configuration +# Objective: +# Test for the WebApp (build locally) and dependent features path. SOURCE="${BASH_SOURCE[0]}" SCRIPT_DIR="$(dirname "$SOURCE")" LOCAL_INSTALL_SCRIPT_PATH="${INSTALL_SCRIPT_PATH:-${SCRIPT_DIR}/../../installation}" LOCAL_INSTALL_SCRIPT_PATH="${LOCAL_INSTALL_SCRIPT_PATH%/}" +export ENABLE_WEBAPP_PROD_DOWNLOAD=false # Run installation (in interactive mode) # y - start setup # n - use static ip @@ -20,7 +22,7 @@ LOCAL_INSTALL_SCRIPT_PATH="${LOCAL_INSTALL_SCRIPT_PATH%/}" # - - mpd overwrite config (only with existing installation) # n - setup rfid reader # n - setup samba -# y - build local WebApp +# y - setup webapp # y - setup kiosk mode # y - install node # n - reboot From 8dfa9426af5553583cca3d3d1aaa6058194693ec Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Tue, 21 Nov 2023 11:20:45 +0100 Subject: [PATCH 43/44] renamend workflow files to not interfere with develop branch --- ...odename_sub.yml => test_docker_debian_codename_sub_v3.yml} | 0 .../{test_docker_debian.yml => test_docker_debian_v3.yml} | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename .github/workflows/{test_docker_debian_codename_sub.yml => test_docker_debian_codename_sub_v3.yml} (100%) rename .github/workflows/{test_docker_debian.yml => test_docker_debian_v3.yml} (83%) diff --git a/.github/workflows/test_docker_debian_codename_sub.yml b/.github/workflows/test_docker_debian_codename_sub_v3.yml similarity index 100% rename from .github/workflows/test_docker_debian_codename_sub.yml rename to .github/workflows/test_docker_debian_codename_sub_v3.yml diff --git a/.github/workflows/test_docker_debian.yml b/.github/workflows/test_docker_debian_v3.yml similarity index 83% rename from .github/workflows/test_docker_debian.yml rename to .github/workflows/test_docker_debian_v3.yml index 928c3ce30..6cf1648aa 100644 --- a/.github/workflows/test_docker_debian.yml +++ b/.github/workflows/test_docker_debian_v3.yml @@ -20,12 +20,12 @@ jobs: # Build container and run tests. Duplication of job intended for better visualization. run_bookworm: name: 'bookworm' - uses: ./.github/workflows/test_docker_debian_codename_sub.yml + uses: ./.github/workflows/test_docker_debian_codename_sub_v3.yml with: debian_codename: 'bookworm' run_bullseye: name: 'bullseye' - uses: ./.github/workflows/test_docker_debian_codename_sub.yml + uses: ./.github/workflows/test_docker_debian_codename_sub_v3.yml with: debian_codename: 'bullseye' From e04ab616dca2b8e2366cbcef5aa660fa4da2782c Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Sun, 26 Nov 2023 00:39:59 +0100 Subject: [PATCH 44/44] Update install links --- README.md | 6 +----- installation/README.md | 8 ++------ 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 8b494698d..3731c7e06 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,4 @@ The documentation can be found [here](./documentation/README.md) ## Installation? -Run the following one-liner in a shell and follow the instructions - -~~~bash -cd; bash <(wget -qO- https://raw.githubusercontent.com/MiczFlor/RPi-Jukebox-RFID/future3/develop/installation/install-jukebox.sh) -~~~ +[Install Phoniebox software](documentation/builders/installation.md#install-phoniebox-software) diff --git a/installation/README.md b/installation/README.md index aff262bd8..b2a496348 100644 --- a/installation/README.md +++ b/installation/README.md @@ -11,10 +11,6 @@ No output to both console and logfile: "$ command > /dev/null" [Learn more about bash script outputs](https://stackoverflow.com/questions/18460186/writing-outputs-to-log-file-and-console) -## Quick Installation +## Installation -Note: Replace the branch in this command to be the one you like to install depending on your needs. Release branch is preset. - -```bash -cd; bash <(wget -qO- https://raw.githubusercontent.com/MiczFlor/RPi-Jukebox-RFID/future3/main/installation/install-jukebox.sh) -``` +[Install Phoniebox software](../documentation/builders/installation.md#install-phoniebox-software)