diff --git a/.github/workflows/10min-iiab-test-install.yml b/.github/workflows/10min-iiab-test-install.yml new file mode 100644 index 000000000..d2b8bd056 --- /dev/null +++ b/.github/workflows/10min-iiab-test-install.yml @@ -0,0 +1,58 @@ +name: '"10 min" IIAB on Ubuntu 24.04 on x86-64' +# run-name: ${{ github.actor }} is testing out GitHub Actions 🚀 + +# https://michaelcurrin.github.io/dev-cheatsheets/cheatsheets/ci-cd/github-actions/triggers.html +on: [push, pull_request, workflow_dispatch] + +# on: +# push: +# +# pull_request: +# +# # Allows you to run this workflow manually from the Actions tab +# workflow_dispatch: +# +# # Set your workflow to run every day of the week from Monday to Friday at 6:00 UTC +# schedule: +# - cron: "0 6 * * 1-5" + +jobs: + test-install: + runs-on: ubuntu-24.04 + steps: + - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event." + - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." + #- name: Dump GitHub context (typically almost 500 lines) + # env: + # GITHUB_CONTEXT: ${{ toJSON(github) }} + # run: echo "$GITHUB_CONTEXT" + - name: Check out repository code + uses: actions/checkout@v4 + - run: echo "🍏 This job's status is ${{ job.status }}." + - name: GitHub Actions "runner" environment + run: | + uname -a # uname -srm + whoami # Typically 'runner' instead of 'root' + pwd # /home/runner/work/iiab/iiab == $GITHUB_WORKSPACE == ${{ github.workspace }} + # ls + # ls $GITHUB_WORKSPACE + # ls ${{ github.workspace }} + # ls -la /opt # az, containerd, google, hostedtoolcache, microsoft, mssql-tools, pipx, pipx_bin, post-generation, runner, vsts + # apt update + # apt dist-upgrade -y + # apt autoremove -y + - name: Set up /opt/iiab/iiab + run: | + mkdir /opt/iiab + mv $GITHUB_WORKSPACE /opt/iiab + mkdir $GITHUB_WORKSPACE # OR SUBSEQUENT STEPS WILL FAIL ('working-directory: /opt/iiab/iiab' hacks NOT worth it!) + - name: Set up /etc/iiab/local_vars.yml + run: | + sudo mkdir /etc/iiab + # touch /etc/iiab/local_vars.yml + sudo cp /opt/iiab/iiab/vars/local_vars_none.yml /etc/iiab/local_vars.yml + - run: sudo /opt/iiab/iiab/scripts/ansible + - run: sudo ./iiab-install + working-directory: /opt/iiab/iiab + - run: iiab-summary + - run: cat /etc/iiab/iiab_state.yml diff --git a/.github/workflows/30min-iiab-test-install-deb12-on-rpi3.yml b/.github/workflows/30min-iiab-test-install-deb12-on-rpi3.yml new file mode 100644 index 000000000..a8703346e --- /dev/null +++ b/.github/workflows/30min-iiab-test-install-deb12-on-rpi3.yml @@ -0,0 +1,65 @@ +name: '"30 min" IIAB on Debian 12 on RPi 3' +# run-name: ${{ github.actor }} is testing out GitHub Actions 🚀 + +# https://michaelcurrin.github.io/dev-cheatsheets/cheatsheets/ci-cd/github-actions/triggers.html +on: [push, pull_request, workflow_dispatch] + +# on: +# push: +# +# pull_request: +# +# # Allows you to run this workflow manually from the Actions tab +# workflow_dispatch: +# +# # Set your workflow to run every day of the week from Monday to Friday at 6:00 UTC +# schedule: +# - cron: "0 6 * * 1-5" + +jobs: + test-install: + runs-on: ubuntu-22.04 + strategy: + matrix: + arch: [debian12] + include: + - arch: debian12 + cpu: cortex-a7 + cpu_info: cpuinfo/raspberrypi_3b + base_image: https://raspi.debian.net/daily/raspi_3_bookworm.img.xz + # source https://raspi.debian.net/daily-images/ + steps: + #- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event." + #- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." + #- name: Dump GitHub context (typically almost 500 lines) + # env: + # GITHUB_CONTEXT: ${{ toJSON(github) }} + # run: echo "$GITHUB_CONTEXT" + - name: Dump matrix context + env: + MATRIX_CONTEXT: ${{ toJSON(matrix) }} + run: echo "$MATRIX_CONTEXT" + - uses: actions/checkout@v3.1.0 + - uses: pguyot/arm-runner-action@v2 + with: + image_additional_mb: 1024 + base_image: ${{ matrix.base_image }} + cpu: ${{ matrix.cpu }} + cpu_info: ${{ matrix.cpu_info }} + copy_repository_path: /opt/iiab/iiab + commands: | + echo "🍏 This job's status is ${{ job.status }}." + grep Model /proc/cpuinfo + uname -a # uname -srm + whoami # Typically 'root' instead of 'runner' + pwd # /home/runner/work/iiab/iiab == $GITHUB_WORKSPACE == ${{ github.workspace }} + apt-get update -y --allow-releaseinfo-change + apt-get install --no-install-recommends -y git + ls /opt/iiab/iiab + mkdir /etc/iiab + cp /opt/iiab/iiab/vars/local_vars_none.yml /etc/iiab/local_vars.yml + /opt/iiab/iiab/scripts/ansible + ./iiab-install + cd /opt/iiab/iiab + iiab-summary + cat /etc/iiab/iiab_state.yml diff --git a/.github/workflows/30min-iiab-test-install-raspios-on-zero2w.yml b/.github/workflows/30min-iiab-test-install-raspios-on-zero2w.yml new file mode 100644 index 000000000..9b521fee6 --- /dev/null +++ b/.github/workflows/30min-iiab-test-install-raspios-on-zero2w.yml @@ -0,0 +1,77 @@ +name: '"30 min" IIAB on RasPiOS on Zero 2 W' +# run-name: ${{ github.actor }} is testing out GitHub Actions 🚀 + +# https://michaelcurrin.github.io/dev-cheatsheets/cheatsheets/ci-cd/github-actions/triggers.html +on: [push, pull_request, workflow_dispatch] + +# on: +# push: +# +# pull_request: +# +# # Allows you to run this workflow manually from the Actions tab +# workflow_dispatch: +# +# # Set your workflow to run every day of the week from Monday to Friday at 6:00 UTC +# schedule: +# - cron: "0 6 * * 1-5" + +jobs: + test-install: + runs-on: ubuntu-22.04 + strategy: + matrix: + arch: [aarch64] #[zero_raspbian, zero_raspios, zero2_raspios, aarch64] + include: + #- arch: zero_raspbian + # cpu: arm1176 + # cpu_info: cpuinfo/raspberrypi_zero_w + # base_image: raspbian_lite:latest + #- arch: zero_raspios + # cpu: arm1176 + # cpu_info: cpuinfo/raspberrypi_zero_w + # base_image: raspios_lite:latest + #- arch: zero2_raspios + # cpu: cortex-a7 + # cpu_info: cpuinfo/raspberrypi_zero2_w + # base_image: raspios_lite:latest + - arch: aarch64 + cpu: cortex-a53 + cpu_info: cpuinfo/raspberrypi_zero2_w_arm64 + base_image: raspios_lite_arm64:latest + steps: + #- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event." + #- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." + #- name: Dump GitHub context (typically almost 500 lines) + # env: + # GITHUB_CONTEXT: ${{ toJSON(github) }} + # run: echo "$GITHUB_CONTEXT" + - name: Dump matrix context + env: + MATRIX_CONTEXT: ${{ toJSON(matrix) }} + run: echo "$MATRIX_CONTEXT" + - uses: actions/checkout@v3.1.0 + - uses: pguyot/arm-runner-action@v2 + with: + image_additional_mb: 1024 + base_image: ${{ matrix.base_image }} + cpu: ${{ matrix.cpu }} + cpu_info: ${{ matrix.cpu_info }} + copy_repository_path: /opt/iiab/iiab + commands: | + echo "🍏 This job's status is ${{ job.status }}." + #test `uname -m` = ${{ matrix.arch }} + grep Model /proc/cpuinfo + uname -a # uname -srm + whoami # Typically 'root' instead of 'runner' + pwd # /home/runner/work/iiab/iiab == $GITHUB_WORKSPACE == ${{ github.workspace }} + apt-get update -y --allow-releaseinfo-change + apt-get install --no-install-recommends -y git + ls /opt/iiab/iiab + mkdir /etc/iiab + cp /opt/iiab/iiab/vars/local_vars_none.yml /etc/iiab/local_vars.yml + /opt/iiab/iiab/scripts/ansible + ./iiab-install + cd /opt/iiab/iiab + iiab-summary + cat /etc/iiab/iiab_state.yml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index caf8b425b..4ddde9b53 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,3 @@ -# SEE THE NEW
[github.com/iiab/iiab/wiki/IIAB-Contributors-Guide](https://github.com/iiab/iiab/wiki/IIAB-Contributors-Guide) +# SEE THE NEW
[github.com/iiab/iiab/wiki/Contributors-Guide-(EN)](https://github.com/iiab/iiab/wiki/Contributors-Guide-(EN)) # THANKS! diff --git a/LICENSING.md b/LICENSING.md index 53bc9d1ef..77c1ed0b9 100644 --- a/LICENSING.md +++ b/LICENSING.md @@ -15,6 +15,6 @@ this is to include the following two lines at the top of the file: Licensed under the terms of the GNU GPL v2 or later; see LICENSE for details. All files not containing an explicit copyright notice or terms of license in -the file are Copyright © 2015-2022, Unleash Kids, and are licensed under the +the file are Copyright © 2015-2025, Unleash Kids, and are licensed under the terms of the GPLv2 license in the file named LICENSE in the root of the repository. diff --git a/README.md b/README.md index 64b577547..fbfd30d35 100644 --- a/README.md +++ b/README.md @@ -2,26 +2,26 @@ # Internet-in-a-Box (IIAB) -[Internet-in-a-Box (IIAB)](https://internet-in-a-box.org) is a "learning hotspot" that brings the Internet's crown jewels -(Wikipedia in any language, thousands of Khan Academy videos, zoomable OpenStreetMap, electronic books, WordPress journaling, Toys from Trash electronics projects, ETC) to those without Internet. +[Internet-in-a-Box (IIAB)](https://internet-in-a-box.org) is a “learning hotspot” that brings the Internet's crown jewels +(Wikipedia in any language, thousands of Khan Academy videos, zoomable OpenStreetMap, electronic books, WordPress journaling, “Toys from Trash” electronics projects, ETC) to those without Internet. You can build your own tiny, affordable server (an offline digital library) for your school, your medical clinic, your prison, your region and/or your very own family — accessible with any nearby smartphone, tablet or laptop. Internet-in-a-Box gives you the DIY tools to: 1. Download then drag-and-drop to arrange the [very best of the World’s Free Knowledge](https://internet-in-a-box.org/#quality-content). -2. Choose among [30+ powerful educational apps](https://wiki.iiab.io/go/FAQ#What_services_.28IIAB_apps.29_are_suggested_during_installation.3F) for your school or learning/teaching community, optionally with a complete LMS (learning management system). +2. Choose among [30+ powerful educational apps](https://wiki.iiab.io/go/FAQ#What_services_%28IIAB_apps%29_are_suggested_during_installation%3F) for your school or learning/teaching community, optionally with a complete LMS (learning management system). 3. Exchange local/indigenous knowledge with nearby communities, using our [Manage Content](https://github.com/iiab/iiab-admin-console/blob/master/roles/console/files/help/InstContent.rst#manage-content) interface and possible mesh networking. -FYI this [community product](https://en.wikipedia.org/wiki/Internet-in-a-Box) is enabled by professional volunteers working [side-by-side](https://wiki.iiab.io/go/FAQ#What_are_the_best_places_for_community_support.3F) with schools, clinics and libraries around the world. *Thank you for being a part of our http://OFF.NETWORK grassroots technology [movement](https://meta.wikimedia.org/wiki/Internet-in-a-Box)!* +FYI this [community product](https://en.wikipedia.org/wiki/Internet-in-a-Box) is enabled by professional volunteers working [side-by-side](https://wiki.iiab.io/go/FAQ#What_are_the_best_places_for_community_support%3F) with schools, clinics and libraries around the world. *Thank you for being a part of our http://OFF.NETWORK grassroots technology [movement](https://meta.wikimedia.org/wiki/Internet-in-a-Box)!* ## Installation -Install Internet-in-a-Box (IIAB) from [download.iiab.io](https://download.iiab.io/) +Install Internet-in-a-Box (IIAB) from: [**download.iiab.io**](https://download.iiab.io/) -Please see [FAQ.IIAB.IO](https://wiki.iiab.io/go/FAQ) which has 40+ questions and answers to help you along the way, as you put together the "local learning hotspot" most suitable for your own teaching/learning community. Here are 2 ways to install IIAB: +Please see [FAQ.IIAB.IO](https://wiki.iiab.io/go/FAQ) which has 50+ questions and answers to help you along the way (e.g. [“Is a quick installation possible?”](https://wiki.iiab.io/go/FAQ#Is_a_quick_installation_possible%3F)) as you put together the “local learning hotspot” most suitable for your own teaching/learning community. Here are 2 ways to install IIAB: - Our [1-line installer](https://download.iiab.io/) gets you the very latest, typically within about an hour, on [different Linux distributions](https://github.com/iiab/iiab/wiki/IIAB-Platforms#operating-systems). -- [Prefab disk images](https://github.com/iiab/iiab/wiki/Raspberry-Pi-Images:-Summary#iiab-images-for-raspberry-pi) ([.img files](https://archive.org/search.php?query=iiab%20.img&sort=-publicdate)) are sometimes a few months out of date, but can be flashed directly onto a microSD card, for insertion into Raspberry Pi. +- [Prefab disk images](https://github.com/iiab/iiab/wiki/Raspberry-Pi-Images-~-Summary#iiab-images-for-raspberry-pi) ([.img files](https://archive.org/search.php?query=iiab%20.img&sort=-publicdate)) are sometimes a few months out of date, but can be flashed directly onto a microSD card, for insertion into Raspberry Pi. Our [HOW-TO videos](https://www.youtube.com/channel/UC0cBGCxr_WPBPa3IqPVEe3g) can be very helpful and the [Installation](https://github.com/iiab/iiab/wiki/IIAB-Installation) wiki page has more intricate details e.g. if you're trying to install Internet-in-a-Box (IIAB) onto a [another Linux](https://github.com/iiab/iiab/wiki/IIAB-Platforms) that has not yet been tried. @@ -29,22 +29,22 @@ See our [Tech Docs Wiki](https://github.com/iiab/iiab/wiki) for more about the u After you've installed the software, you should [add content](https://github.com/iiab/iiab/wiki/IIAB-Installation#add-content), which can of course take time when downloading multi-gigabyte Content Packs! -Finally, you can [customize your Internet-in-a-Box home page](https://wiki.iiab.io/go/FAQ#How_do_I_customize_my_Internet-in-a-Box_home_page.3F) (typically http://box or http://box.lan) using our **drag-and-drop** Admin Console (http://box.lan/admin) — to arrange Content Packs and IIAB Apps (services) for your local community's needs. +Finally, you can [customize your Internet-in-a-Box home page](https://wiki.iiab.io/go/FAQ#How_do_I_customize_my_Internet-in-a-Box_home_page%3F) (typically http://box or http://box.lan) using our **drag-and-drop** Admin Console (http://box.lan/admin) — to arrange Content Packs and IIAB Apps (services) for your local community's needs. ## Community Global community updates and videos are regularly posted to: **[@internet_in_box](https://twitter.com/internet_in_box)** -_Internet-in-a-Box (IIAB) greatly welcomes contributions from educators, librarians and [IT/UX/QA people](https://github.com/iiab/iiab/wiki/Technical-Contributors-Guide) of all kinds!_ +_Internet-in-a-Box (IIAB) greatly welcomes contributions from educators, librarians and [IT/UX/QA people](https://github.com/iiab/iiab/wiki/Contributors-Guide-(EN)) ([versión en español](https://github.com/iiab/iiab/wiki/Gu%C3%ADa-para-Contribuidores-(ES))) of all kinds!_ -If you would like to volunteer, please [make contact](https://internet-in-a-box.org/contributing.html) after looking over "[How can I help?](https://wiki.iiab.io/go/FAQ#How_can_I_help.3F)" at: [FAQ.IIAB.IO](https://wiki.iiab.io/go/FAQ) +If you would like to volunteer, please [make contact](https://internet-in-a-box.org/contributing.html) after looking over [“How can I help?”](https://wiki.iiab.io/go/FAQ#How_can_I_help%3F) at: [FAQ.IIAB.IO](https://wiki.iiab.io/go/FAQ) -To learn more about our open community architecture for "offline" learning, check out "[What technical documentation exists?](https://wiki.iiab.io/go/FAQ#What_technical_documentation_exists.3F)" -FYI we use [Ansible](https://wiki.iiab.io/go/FAQ#What_is_Ansible_and_what_version_should_I_use.3F) to install, deploy, configure and manage the various software components. +To learn more about our open community architecture for “offline” learning, check out [“What technical documentation exists?”](https://wiki.iiab.io/go/FAQ#What_technical_documentation_exists%3F) +FYI we use [Ansible](https://wiki.iiab.io/go/FAQ#What_is_Ansible_and_what_version_should_I_use%3F) to install, deploy, configure and manage the various software components. -*Thank you for helping us enable offline access to the Internet's free/open knowledge jewels, as well as "Sneakernet-of-Alexandria" distribution of local/indigenous content, when mass media channels do not serve grassroots voices.* +*Thank you for helping us enable offline access to the Internet's free/open knowledge jewels, as well as “Sneakernet-of-Alexandria” distribution of local/indigenous content, when mass media channels do not serve grassroots voices.* ## Versions diff --git a/ansible.cfg b/ansible.cfg index 4030a931e..deb5328ed 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -5,4 +5,4 @@ # Disallowed by Ansible 2.11+ -- see https://docs.ansible.com/ansible/devel/porting_guides/porting_guide_2.7.html#using-a-loop-on-a-package-module-via-squash-actions #squash_actions = apk, apt, dnf, homebrew, openbsd_pkg, pacman, pkgng, yum, zypper, package [defaults] -interpreter_python=/usr/bin/python3 +interpreter_python=/usr/local/ansible/bin/python3 diff --git a/iiab-install b/iiab-install index 532cbf81d..45e637c2a 100755 --- a/iiab-install +++ b/iiab-install @@ -11,7 +11,7 @@ CWD=`pwd` OS=`grep ^ID= /etc/os-release | cut -d= -f2` OS=${OS//\"/} # Remove all '"' MIN_RPI_KERN=5.4.0 # Do not use 'rpi-update' unless absolutely necessary: https://github.com/iiab/iiab/issues/1993 -MIN_ANSIBLE_VER=2.11.12 # 2022-11-09: Raspberry Pi 3 (and 3 B+ etc?) apparently install (and require?) ansible-core 2.11 for now -- @deldesir can explain more on PR #3419. Historical: Ansible 2.8.3 and 2.8.6 had serious bugs, preventing their use with IIAB. +MIN_ANSIBLE_VER=2.16.14 # 2024-11-08: ansible-core 2.15 EOL is November 2024 per https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix 2022-11-09: Raspberry Pi 3 (and 3 B+ etc?) apparently install (and require?) ansible-core 2.11 for now -- @deldesir can explain more on PR #3419. Historical: Ansible 2.8.3 and 2.8.6 had serious bugs, preventing their use with IIAB. REINSTALL=false DEBUG=false diff --git a/iiab-network b/iiab-network index 5dc831b8e..c888c27bf 100755 --- a/iiab-network +++ b/iiab-network @@ -42,7 +42,7 @@ fi echo "Ansible will now run iiab-network.yml -- log file is iiab-network.log" Start=`date` ansible -m setup -i ansible_hosts localhost --connection=local | grep python -ansible-playbook -i ansible_hosts iiab-network.yml --connection=local +ansible-playbook -i ansible_hosts iiab-network.yml --extra-vars "{\"skip_role_on_error\":false}" --connection=local End=`date` diff --git a/roles/0-DEPRECATED-ROLES/httpd/defaults/main.yml b/roles/0-DEPRECATED-ROLES/httpd/defaults/main.yml index f728ffca8..a28c2da61 100644 --- a/roles/0-DEPRECATED-ROLES/httpd/defaults/main.yml +++ b/roles/0-DEPRECATED-ROLES/httpd/defaults/main.yml @@ -8,7 +8,7 @@ # apache_interface: 127.0.0.1 # Make this False to disable http://box/common/services/power_off.php button: -# apache_allow_sudo: True +# allow_www_data_poweroff: False # All above are set in: github.com/iiab/iiab/blob/master/vars/default_vars.yml # If nec, change them by editing /etc/iiab/local_vars.yml prior to installing! diff --git a/roles/openvpn/defaults/main.yml b/roles/0-DEPRECATED-ROLES/openvpn/defaults/main.yml similarity index 62% rename from roles/openvpn/defaults/main.yml rename to roles/0-DEPRECATED-ROLES/openvpn/defaults/main.yml index adc23ec2b..136e01f5d 100644 --- a/roles/openvpn/defaults/main.yml +++ b/roles/0-DEPRECATED-ROLES/openvpn/defaults/main.yml @@ -1,13 +1,17 @@ +# SECURITY WARNING: https://wiki.iiab.io/go/Security + # openvpn_install: True # openvpn_enabled: False -# For /etc/iiab/openvpn_handle +# Empty string on purpose since ~2016, for /etc/iiab/uuid +# SEE https://github.com/iiab/iiab/blob/master/roles/openvpn/tasks/main.yml#L5-L20 # openvpn_handle: "" # cron seems necessary on CentOS: # openvpn_cron_enabled: False # openvpn_server: xscenet.net +# openvpn_server_real_ip: 3.89.148.185 # openvpn_server_virtual_ip: 10.8.0.1 # openvpn_server_port: 1194 diff --git a/roles/openvpn/tasks/enable-or-disable.yml b/roles/0-DEPRECATED-ROLES/openvpn/tasks/enable-or-disable.yml similarity index 100% rename from roles/openvpn/tasks/enable-or-disable.yml rename to roles/0-DEPRECATED-ROLES/openvpn/tasks/enable-or-disable.yml diff --git a/roles/openvpn/tasks/install.yml b/roles/0-DEPRECATED-ROLES/openvpn/tasks/install.yml similarity index 92% rename from roles/openvpn/tasks/install.yml rename to roles/0-DEPRECATED-ROLES/openvpn/tasks/install.yml index cbe2e36af..53f5dc7f2 100644 --- a/roles/openvpn/tasks/install.yml +++ b/roles/0-DEPRECATED-ROLES/openvpn/tasks/install.yml @@ -1,3 +1,8 @@ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: "Install packages: ncat, nmap, openvpn, sudo" package: name: @@ -100,6 +105,17 @@ # RECORD OpenVPN AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'openvpn_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: openvpn + option: openvpn_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'openvpn_installed: True'" set_fact: openvpn_installed: True diff --git a/roles/openvpn/tasks/main.yml b/roles/0-DEPRECATED-ROLES/openvpn/tasks/main.yml similarity index 100% rename from roles/openvpn/tasks/main.yml rename to roles/0-DEPRECATED-ROLES/openvpn/tasks/main.yml diff --git a/roles/openvpn/templates/15-openvpn.unused b/roles/0-DEPRECATED-ROLES/openvpn/templates/15-openvpn.unused similarity index 100% rename from roles/openvpn/templates/15-openvpn.unused rename to roles/0-DEPRECATED-ROLES/openvpn/templates/15-openvpn.unused diff --git a/roles/openvpn/templates/announce b/roles/0-DEPRECATED-ROLES/openvpn/templates/announce similarity index 100% rename from roles/openvpn/templates/announce rename to roles/0-DEPRECATED-ROLES/openvpn/templates/announce diff --git a/roles/openvpn/templates/announcer b/roles/0-DEPRECATED-ROLES/openvpn/templates/announcer similarity index 100% rename from roles/openvpn/templates/announcer rename to roles/0-DEPRECATED-ROLES/openvpn/templates/announcer diff --git a/roles/openvpn/templates/ca.crt b/roles/0-DEPRECATED-ROLES/openvpn/templates/ca.crt similarity index 100% rename from roles/openvpn/templates/ca.crt rename to roles/0-DEPRECATED-ROLES/openvpn/templates/ca.crt diff --git a/roles/openvpn/templates/client1.crt b/roles/0-DEPRECATED-ROLES/openvpn/templates/client1.crt similarity index 100% rename from roles/openvpn/templates/client1.crt rename to roles/0-DEPRECATED-ROLES/openvpn/templates/client1.crt diff --git a/roles/openvpn/templates/client1.key b/roles/0-DEPRECATED-ROLES/openvpn/templates/client1.key similarity index 100% rename from roles/openvpn/templates/client1.key rename to roles/0-DEPRECATED-ROLES/openvpn/templates/client1.key diff --git a/roles/openvpn/templates/iiab-remote-off b/roles/0-DEPRECATED-ROLES/openvpn/templates/iiab-remote-off similarity index 100% rename from roles/openvpn/templates/iiab-remote-off rename to roles/0-DEPRECATED-ROLES/openvpn/templates/iiab-remote-off diff --git a/roles/openvpn/templates/iiab-remote-on.j2 b/roles/0-DEPRECATED-ROLES/openvpn/templates/iiab-remote-on.j2 similarity index 100% rename from roles/openvpn/templates/iiab-remote-on.j2 rename to roles/0-DEPRECATED-ROLES/openvpn/templates/iiab-remote-on.j2 diff --git a/roles/openvpn/templates/iiab-support b/roles/0-DEPRECATED-ROLES/openvpn/templates/iiab-support similarity index 98% rename from roles/openvpn/templates/iiab-support rename to roles/0-DEPRECATED-ROLES/openvpn/templates/iiab-support index 4ba4d70a3..1d88a66b4 100755 --- a/roles/openvpn/templates/iiab-support +++ b/roles/0-DEPRECATED-ROLES/openvpn/templates/iiab-support @@ -10,11 +10,11 @@ DEBUG=false # Using /usr/bin/true or /usr/bin/false PLAYBOOK="install-support.yml" INVENTORY="ansible_hosts" -# 2021-08-18: bash scripts using default_vars.yml &/or local_vars.yml +# 2023-02-25: bash scripts using default_vars.yml &/or local_vars.yml # https://github.com/iiab/iiab-factory/blob/master/iiab # https://github.com/iiab/iiab/blob/master/roles/firmware/templates/iiab-check-firmware#L10-14 # https://github.com/iiab/iiab/blob/master/roles/network/templates/gateway/iiab-gen-iptables#L48-L52 -# https://github.com/iiab/maps/blob/master/osm-source/pages/viewer/scripts/iiab-install-map-region#L25-L34 +# https://github.com/iiab/maps/blob/master/osm-source/pages/viewer/scripts/iiab-install-map-region#L23-L39 # https://github.com/iiab/iiab/blob/master/roles/openvpn/templates/iiab-support READS AND WRITES, INCL NON-BOOLEAN # PARSE local_vars.yml JUST AS Ansible & /etc/openvpn/scripts/announcer DO: diff --git a/roles/openvpn/templates/iiab-support.older b/roles/0-DEPRECATED-ROLES/openvpn/templates/iiab-support.older similarity index 100% rename from roles/openvpn/templates/iiab-support.older rename to roles/0-DEPRECATED-ROLES/openvpn/templates/iiab-support.older diff --git a/roles/openvpn/templates/openvpn_handle.j2.unused b/roles/0-DEPRECATED-ROLES/openvpn/templates/openvpn_handle.j2.unused similarity index 100% rename from roles/openvpn/templates/openvpn_handle.j2.unused rename to roles/0-DEPRECATED-ROLES/openvpn/templates/openvpn_handle.j2.unused diff --git a/roles/openvpn/templates/silence b/roles/0-DEPRECATED-ROLES/openvpn/templates/silence similarity index 100% rename from roles/openvpn/templates/silence rename to roles/0-DEPRECATED-ROLES/openvpn/templates/silence diff --git a/roles/openvpn/templates/xscenet.conf.j2 b/roles/0-DEPRECATED-ROLES/openvpn/templates/xscenet.conf.j2 similarity index 100% rename from roles/openvpn/templates/xscenet.conf.j2 rename to roles/0-DEPRECATED-ROLES/openvpn/templates/xscenet.conf.j2 diff --git a/roles/0-init/tasks/create_iiab_ini.yml b/roles/0-init/tasks/create_iiab_ini.yml index 239ce570d..75b2b338f 100644 --- a/roles/0-init/tasks/create_iiab_ini.yml +++ b/roles/0-init/tasks/create_iiab_ini.yml @@ -1,13 +1,26 @@ -# workaround for fact that auto create does not work on iiab_ini_file (/etc/iiab/iiab.ini) +- name: Record disk_used_a_priori (permanently, into {{ iiab_ini_file }} below) to later estimate iiab_software_disk_usage + shell: df -B1 --output=used / | tail -1 + register: df1 + +# workaround for fact that auto create does not work on iiab_ini_file - name: Create {{ iiab_ini_file }} file: - path: "{{ iiab_ini_file }}" + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini state: touch -- name: Add 'location' variable values to {{ iiab_ini_file }} +- name: Run command 'dpkg --print-architecture' to identify OS architecture (CPU arch as revealed by ansible_architecture ~= ansible_machine is NOT enough!) + command: dpkg --print-architecture + register: dpkg_arch + +- name: Run command 'dpkg --print-foreign-architectures' (secondary OS arch, if available) + command: dpkg --print-foreign-architectures + register: dpkg_foreign_arch + + +- name: Add 'summary' variable values to {{ iiab_ini_file }} ini_file: path: "{{ iiab_ini_file }}" - section: location + section: summary option: "{{ item.option }}" value: "{{ item.value | string }}" with_items: @@ -15,18 +28,30 @@ value: "{{ iiab_base }}" - option: iiab_dir value: "{{ iiab_dir }}" + - option: disk_used_a_priori + value: "{{ df1.stdout }}" -- name: Add 'version' variable values to {{ iiab_ini_file }} +- name: Add 'initial' variable values to {{ iiab_ini_file }} ini_file: path: "{{ iiab_ini_file }}" - section: version + section: initial option: "{{ item.option }}" value: "{{ item.value | string }}" with_items: + - option: os_ver + value: "{{ os_ver }}" - option: distribution - value: "{{ ansible_distribution }}" + value: "{{ ansible_facts['distribution'] }}" - option: arch value: "{{ ansible_architecture }}" + - option: dpkg_arch + value: "{{ dpkg_arch.stdout }}" + - option: dpkg_foreign_arch + value: "{{ dpkg_foreign_arch.stdout }}" + - option: rpi_model + value: "{{ rpi_model }}" + - option: devicetree_model + value: "{{ devicetree_model }}" - option: iiab_base_ver value: "{{ iiab_base_ver }}" - option: iiab_remote_url @@ -39,7 +64,3 @@ value: "{{ ansible_local.local_facts.iiab_recent_tag }}" - option: install_date value: "{{ ansible_date_time.iso8601 }}" - - option: rpi_model - value: "{{ rpi_model }}" - - option: devicetree_model - value: "{{ devicetree_model }}" diff --git a/roles/0-init/tasks/main.yml b/roles/0-init/tasks/main.yml index 4c02c6ca5..8eb1668eb 100644 --- a/roles/0-init/tasks/main.yml +++ b/roles/0-init/tasks/main.yml @@ -34,14 +34,23 @@ # Copies the latest/known version of iiab-diagnostics into /usr/bin (so it can # be run even if local source tree /opt/iiab/iiab is deleted to conserve disk). -- name: Copy iiab-summary & iiab-diagnostics from /opt/iiab/iiab/scripts/ to /usr/bin/ +- name: Copy iiab-update & iiab-summary & iiab-diagnostics & iiab-root-login from /opt/iiab/iiab/scripts/ to /usr/bin/ copy: src: "{{ iiab_dir }}/scripts/{{ item }}" dest: /usr/bin/ mode: '0755' with_items: + - iiab-update - iiab-summary - iiab-diagnostics + - iiab-root-login + +- name: Symlink /usr/bin/iiab-upgrade -> /usr/bin/iiab-update + file: + src: /usr/bin/iiab-update + path: /usr/bin/iiab-upgrade + state: link + #force: yes - name: Create globally-writable directory /etc/iiab/diag (0777) so non-root users can run 'iiab-diagnostics' file: diff --git a/roles/0-init/tasks/validate_vars.yml b/roles/0-init/tasks/validate_vars.yml index f5277d2d9..dee75addd 100644 --- a/roles/0-init/tasks/validate_vars.yml +++ b/roles/0-init/tasks/validate_vars.yml @@ -64,19 +64,19 @@ # 2020-11-04: Fix validation of 5 [now 4] core dependencies, for ./runrole etc -- name: Set vars_checklist for 44 + 44 + 40 vars ("XYZ_install" + "XYZ_enabled" + "XYZ_installed") to be checked +- name: Set vars_checklist for 45 + 45 + 40 vars ("XYZ_install" + "XYZ_enabled" + "XYZ_installed") to be checked set_fact: vars_checklist: - hostapd - dnsmasq - bluetooth - sshd - - openvpn + #- openvpn # Deprecated + - tailscale - remoteit - admin_console #- nginx # MANDATORY #- apache # Unmaintained - former dependency - #- mysql # MANDATORY - squid - cups - samba @@ -85,6 +85,7 @@ - gitea - jupyterhub - lokole + - mysql # Dependency - excluded from _installed check below - mediawiki - mosquitto - nodejs # Dependency - excluded from _installed check below @@ -155,23 +156,41 @@ that: "{{ item }}_install or {{ item }}_installed is undefined" fail_msg: "DISALLOWED: '{{ item }}_install: False' (e.g. in /etc/iiab/local_vars.yml) WHEN '{{ item }}_installed' is defined (e.g. in /etc/iiab/iiab_state.yml) -- IIAB DOES NOT SUPPORT UNINSTALLS -- please verify those 2 files especially, and other places variables are defined?" quiet: yes - when: item != 'nodejs' and item != 'postgresql' and item != 'mongodb' and item != 'yarn' # Exclude auto-installed dependencies + when: item != 'mysql' and item != 'postgresql' and item != 'mongodb' and item != 'nodejs' and item != 'yarn' # Exclude auto-installed dependencies loop: "{{ vars_checklist }}" + +- name: Set vars_deprecated_list for 4+ vars ("XYZ_install") to be checked + set_fact: + vars_deprecated_list: + - dhcpd # Deprecated + - named # Deprecated + - wondershaper # Deprecated + - dansguardian # Deprecated + #- xo_services # Unmaintained + #- activity_server # Unmaintained + #- ejabberd_xs # Unmaintained + #- idmgr # Unmaintained + #- dokuwiki # Unmaintained + #- ejabberd # Unmaintained + #- elgg # Unmaintained + - name: 'DISALLOW "XYZ_install: True" if deprecated' assert: that: "{{ item }}_install is undefined or not {{ item }}_install" fail_msg: "DISALLOWED: '{{ item }}_install: True' (e.g. in /etc/iiab/local_vars.yml)" quiet: yes - with_items: - - dhcpd # Deprecated - - named # Deprecated - - wondershaper # Deprecated - - dansguardian # Deprecated - #- xo_services # Unmaintained - #- activity_server # Unmaintained - #- ejabberd_xs # Unmaintained - #- idmgr # Unmaintained - #- dokuwiki # Unmaintained - #- ejabberd # Unmaintained - #- elgg # Unmaintained + loop: "{{ vars_deprecated_list }}" + # 2023-12-04: ansible-core 2.16.1 suddenly no longer allows 'assert' with + # 'with_items' below (whereas 'loop' construct above works!) BACKGROUND: + # + # 'due to mitigation of security issue CVE-2023-5764 in ansible-core 2.16.1, + # conditional expressions with embedded template blocks can fail with the + # message “Conditional is marked as unsafe, and cannot be evaluated.”' + # https://docs.ansible.com/ansible-core/2.16/porting_guides/porting_guide_core_2.16.html#playbook + # + # with_items: + # - dhcpd # Deprecated + # - named # Deprecated + # - wondershaper # Deprecated + # - dansguardian # Deprecated diff --git a/roles/1-prep/README.adoc b/roles/1-prep/README.adoc index 9d0154d73..997ec812b 100644 --- a/roles/1-prep/README.adoc +++ b/roles/1-prep/README.adoc @@ -6,7 +6,7 @@ https://github.com/iiab/iiab/wiki/IIAB-Contributors-Guide#ansible[stage] hardware, low-level OS quirks, and basic security: * SSHD -* OpenVPN if/as needed later for remote support +* Tailscale if/as needed later for remote support * https://github.com/iiab/iiab/tree/master/roles/iiab-admin#iiab-admin-readme[iiab-admin] username and group, to log into Admin Console * dnsmasq (install now, configure later!) diff --git a/roles/1-prep/tasks/hardware.yml b/roles/1-prep/tasks/hardware.yml index 89efd2453..52ef34a97 100644 --- a/roles/1-prep/tasks/hardware.yml +++ b/roles/1-prep/tasks/hardware.yml @@ -7,17 +7,18 @@ when: first_run and rpi_model != "none" -- name: Check if the identifier for Intel's NUC6 built-in WiFi is present - shell: "lsusb | grep 8087:0a2b | wc | awk '{print $1}'" - register: usb_NUC6 - ignore_errors: True - -- name: Download {{ iiab_download_url }}/iwlwifi-8000C-13.ucode to /lib/firmware for built-in WiFi on NUC6 - get_url: - url: "{{ iiab_download_url }}/iwlwifi-8000C-13.ucode" # https://download.iiab.io/packages - dest: /lib/firmware - timeout: "{{ download_timeout }}" - when: usb_NUC6.stdout|int > 0 +# 2024-02-09: Code below appears stale for Shanti's #3707 hardware +#- name: Check if the identifier for Intel's NUC6 built-in WiFi is present +# shell: "lsusb | grep 8087:0a2b | wc | awk '{print $1}'" +# register: usb_NUC6 +# ignore_errors: True +# +#- name: Download {{ iiab_download_url }}/iwlwifi-8000C-13.ucode to /lib/firmware for built-in WiFi on NUC6 +# get_url: +# url: "{{ iiab_download_url }}/Old/iwlwifi-8000C-13.ucode" # https://download.iiab.io/packages +# dest: /lib/firmware +# timeout: "{{ download_timeout }}" +# when: usb_NUC6.stdout|int > 0 - name: "Look for any WiFi devices present: ls -la /sys/class/net/*/phy80211 | cut -d/ -f5" diff --git a/roles/1-prep/tasks/main.yml b/roles/1-prep/tasks/main.yml index 929dd04da..16cf5976e 100644 --- a/roles/1-prep/tasks/main.yml +++ b/roles/1-prep/tasks/main.yml @@ -3,22 +3,22 @@ - name: ...IS BEGINNING ============================================ meta: noop -- name: SSHD -- required by OpenVPN below -- also run by roles/4-server-options/tasks/main.yml +- name: SSHD include_role: name: sshd when: sshd_install -- name: OPENVPN +- name: TAILSCALE (VPN) include_role: - name: openvpn - when: openvpn_install + name: tailscale + when: tailscale_install - name: REMOTE.IT include_role: name: remoteit when: remoteit_install -- name: IIAB-ADMIN -- includes roles/iiab-admin/tasks/access.yml +- name: IIAB-ADMIN -- includes {lynx, screen, sudo-prereqs.yml, admin-user.yml, pwd-warnings.yml} include_role: name: iiab-admin #when: iiab_admin_install # Flag might be created in future? diff --git a/roles/1-prep/templates/iiab-expand-rootfs b/roles/1-prep/templates/iiab-expand-rootfs index a1fd06772..89d2bd552 100644 --- a/roles/1-prep/templates/iiab-expand-rootfs +++ b/roles/1-prep/templates/iiab-expand-rootfs @@ -8,12 +8,21 @@ # Verifies that rootfs is the last partition. +# RELATED: +# 1. https://github.com/iiab/iiab-factory/blob/master/box/rpi/min-sd +# 2. https://github.com/iiab/iiab-factory/blob/master/box/rpi/cp-sd +# 3. https://github.com/iiab/iiab-factory/blob/master/box/rpi/xz-json-sd +# OR https://github.com/iiab/iiab-factory/blob/master/box/rpi/exp-sd + if [ -f /.expand-rootfs ] || [ -f /.resize-rootfs ]; then echo "$0: Expanding rootfs partition" - if [ -x /usr/bin/raspi-config ]; then # Raspberry Pi OS + if [ -x /usr/bin/raspi-config ]; then # Raspberry Pi OS -- WARNING: their fdisk-centric approach of course FAILS with "Hybrid MBR" or GPT partition tables, as required by any drive > 2TB :/ # 2022-02-17: Uses do_expand_rootfs() from: # https://github.com/RPi-Distro/raspi-config/blob/master/raspi-config + # 2023-10-05: Official new RPi instructions: + # sudo raspi-config nonint do_expand_rootfs + # https://www.raspberrypi.com/documentation/computers/configuration.html#expand-filesystem-nonint raspi-config --expand-rootfs # REQUIRES A REBOOT rm -f /.expand-rootfs /.resize-rootfs reboot # In future, we might warn interactive users that a reboot is coming? @@ -32,7 +41,7 @@ if [ -f /.expand-rootfs ] || [ -f /.resize-rootfs ]; then fi # Expand partition - growpart $ROOT_DEV $ROOT_PART_NUM || true # raspi-config instead uses fdisk. WARNING: growpart RC 2 is more severe than RC 1, and should possibly be handled separately in future? + growpart $ROOT_DEV $ROOT_PART_NUM || true # raspi-config instead uses fdisk (assuming MBR). They really should transition to gdisk, as required by any drive > 2TB. WARNING: growpart RC 2 is more severe than RC 1, and should possibly be handled separately in future? rc=$? # Make Return Code visible, for 'bash -x' resize2fs $ROOT_PART rc=$? # Make RC visible (as above) diff --git a/roles/2-common/tasks/packages.yml b/roles/2-common/tasks/packages.yml index 0b33dd637..681d8b83f 100644 --- a/roles/2-common/tasks/packages.yml +++ b/roles/2-common/tasks/packages.yml @@ -1,6 +1,6 @@ # 2022-03-16: 'apt show | grep Size' revealed download sizes, on 64-bit RasPiOS with desktop. -- name: "Install 17 common packages: acpid, bzip2, cron, curl, gawk, htop, i2c-tools, logrotate, plocate, pandoc, pastebinit, rsync, sqlite3, tar, unzip, usbutils, wget" +- name: "Install 19 common packages: acpid, bzip2, cron, curl, gawk, gpg, htop, i2c-tools, logrotate, lshw, pandoc, pastebinit, plocate, rsync, sqlite3, tar, unzip, usbutils, wget" package: name: - acpid # 55kB download: Daemon for ACPI (power mgmt) events @@ -11,23 +11,24 @@ #- exfat-fuse # 28kB download: 2021-07-27: Should no longer be nec with 5.4+ kernels, so let's try commenting it out #- exfat-utils # 41kB download: Ditto! See also 'ntfs-3g' below - gawk # 533kB download + - gpg # 884kB download: Debian 12+ (especially!) require this for apt installs of gitea, kolibri, mongodb, yarn - htop # 109kB download: RasPiOS installs this regardless - - i2c-tools # 78kB download: RasPiOS installs this regardless -- Low-level bus/chip/register/EEPROM tools e.g. for RTC + - i2c-tools # 78kB download: Low-level bus/chip/register/EEPROM tools e.g. for RTC - logrotate # 67kB download: RasPiOS installs this regardless + - lshw # 257kB download: For 'lshw -C network' in iiab-diagnostics #- lynx # 505kB download: Installed by 1-prep's roles/iiab-admin/tasks/main.yml #- make # 376kB download: 2021-07-27: Currently used by roles/pbx and no other roles - #- mlocate # 92kB download - - plocate # 97kB download: Faster & smaller than locate & mlocate #- ntfs-3g # 379kB download: RasPiOS installs this regardless -- 2021-07-31: But this should no longer be nec with 5.4+ kernels, similar to exfat packages above -- however, see also this symlink warning: https://superuser.com/questions/1050544/mount-with-kernel-ntfs-and-not-ntfs-3g -- and upcoming kernel 5.15 improvements: https://www.phoronix.com/scan.php?page=news_item&px=New-NTFS-Likely-For-Linux-5.15 #- openssh-server # 318kB download: RasPiOS installs this regardless -- this is also installed by 1-prep's roles/sshd/tasks/main.yml to cover all OS's - pandoc # 19kB download: For /usr/bin/iiab-refresh-wiki-docs - pastebinit # 47kB download: For /usr/bin/iiab-diagnostics - #- python3-pip # 337kB download: RasPiOS installs this regardless -- 2021-07-29: And already installed by /opt/iiab/iiab/scripts/ansible -- this auto-installs 'python3-setuptools' and 'python3' etc - #- python3-venv # 1188kB download: RasPiOS installs this regardless -- 2021-07-30: For Ansible module 'pip' used in roles like {calibre-web, jupyterhub, lokole} -- whereas roles/kalite uses (virtual) package 'virtualenv' for Python 2 -- all these 3+1 IIAB roles install 'python3-venv' for themselves. FYI: Debian 11 auto-installs 'python3-venv' when you install 'python3' -- whereas Ubuntu (e.g. 20.04 & 21.10) and RasPiOS 10 did not. + #- mlocate # 92kB download + - plocate # 97kB download: Faster & smaller than locate & mlocate + #- python3-pip # 337kB download: 2023-03-22: Used to be installed by /opt/iiab/iiab/scripts/ansible -- which would auto-install 'python3-setuptools' and 'python3' etc + #- python3-venv # 1188kB download: 2023-03-22: Already installed by /opt/iiab/iiab/scripts/ansible -- used by roles like {calibre-web, jupyterhub, lokole} -- whereas roles/kalite uses (virtual) package 'virtualenv' for Python 2 -- all these 3+1 IIAB roles install 'python3-venv' for themselves. FYI: Debian 11 no longer auto-installs 'python3-venv' when you install 'python3' - rsync # 351kB download: RasPiOS installs this regardless #- screen # 551kB download: Installed by 1-prep's roles/iiab-admin/tasks/main.yml - sqlite3 # 1054kB download - #- sudo # 991kB download: RasPiOS installs this regardless -- (2) Can also be installed by roles/1-prep's roles/openvpn/tasks/install.yml, (3) Is definitely installed by 1-prep's roles/iiab-admin/tasks/sudo-prereqs.yml - tar # 799kB download: RasPiOS installs this regardless - unzip # 151kB download: RasPiOS installs this regardless #- usbmount # 18kB download: Moved to roles/usb_lib/tasks/install.yml diff --git a/roles/3-base-server/README.rst b/roles/3-base-server/README.rst index e458d7be0..1f22db3a2 100644 --- a/roles/3-base-server/README.rst +++ b/roles/3-base-server/README.rst @@ -1,10 +1,21 @@ +.. |ss| raw:: html + + + +.. |se| raw:: html + + + +.. |nbsp| unicode:: 0xA0 + :trim: + ==================== 3-base-server README ==================== This 3rd `stage `_ installs base server infra that `Internet-in-a-Box (IIAB) `_ requires, including: -- `MySQL `_ (database underlying many/most user-facing apps). This IIAB role also installs apt package: +- |ss| `MySQL `_ (database underlying many/most user-facing apps). |se| |nbsp| *As of 2023-11-05, MySQL / MariaDB is NO LONGER INSTALLED by 3-base-server — instead it's installed on-demand — as a dependency of Matomo, MediaWiki, Nextcloud, PBX (for FreePBX), WordPress &/or Admin Console.* This IIAB role (roles/mysql) also installs apt package: - **php{{ php_version }}-mysql** — which forcibly installs **php{{ php_version }}-common** - `NGINX `_ web server (with Apache in some lingering cases). This IIAB role also installs apt package: - **php{{ php_version }}-fpm** — which forcibly installs **php{{ php_version }}-cli**, **php{{ php_version }}-common** and **libsodium23** diff --git a/roles/3-base-server/tasks/main.yml b/roles/3-base-server/tasks/main.yml index 5e2e7355d..efe1c93e2 100644 --- a/roles/3-base-server/tasks/main.yml +++ b/roles/3-base-server/tasks/main.yml @@ -3,10 +3,13 @@ - name: ...IS BEGINNING ===================================== meta: noop -- name: MYSQL + CORE PHP - include_role: - name: mysql - #when: mysql_install +# 2023-11-05: MySQL (actually MariaDB) had been mandatory, installed on every +# IIAB by 3-base-server. Now installed on demand -- as a dependency of Matomo, +# MediaWiki, Nextcloud, PBX (for FreePBX), WordPress &/or Admin Console. +# - name: MYSQL + CORE PHP +# include_role: +# name: mysql +# #when: mysql_install # 2021-05-21: Apache role 'httpd' is installed as nec by any of these 6 roles: # diff --git a/roles/4-server-options/README.rst b/roles/4-server-options/README.rst index 6355f85e7..11458d97e 100644 --- a/roles/4-server-options/README.rst +++ b/roles/4-server-options/README.rst @@ -2,7 +2,7 @@ 4-server-options README ======================= -Whereas 3-base-server installs critical packages needed by all, this 4th `stage `_ installs a broad array of *options* ⁠— depending on which server apps will be installed in later stages ⁠— as specified in `/etc/iiab/local_vars.yml `_ +Whereas 3-base-server installs critical packages needed by all, this 4th `stage `_ installs a broad array of *options* ⁠— depending on which server apps will be installed in later stages ⁠— as specified in `/etc/iiab/local_vars.yml `_ This includes more networking fundamentals, that may further be configured later on. @@ -11,7 +11,7 @@ Specifically, these might be installed: - Python libraries - SSH daemon - Bluetooth for Raspberry Pi -- Instant-sharing of `USB stick content `_ +- Instant-sharing of `USB stick content `_ - CUPS Printing - Samba for Windows filesystems - `www_options `_ diff --git a/roles/4-server-options/tasks/main.yml b/roles/4-server-options/tasks/main.yml index 9bed4e5e8..583cb763d 100644 --- a/roles/4-server-options/tasks/main.yml +++ b/roles/4-server-options/tasks/main.yml @@ -19,11 +19,6 @@ #when: pylibs_installed is undefined #when: pylibs_install # Flag might be created in future? -- name: SSHD -- also run by roles/1-prep/tasks/main.yml as required by OpenVPN - include_role: - name: sshd - when: sshd_install - - name: Install Bluetooth - only on Raspberry Pi include_role: name: bluetooth diff --git a/roles/6-generic-apps/tasks/main.yml b/roles/6-generic-apps/tasks/main.yml index 648991a4f..f43e878f3 100644 --- a/roles/6-generic-apps/tasks/main.yml +++ b/roles/6-generic-apps/tasks/main.yml @@ -29,7 +29,7 @@ - name: JUPYTERHUB include_role: name: jupyterhub - when: jupyterhub_install and ansible_machine is search("64") # 2022-11-10: Avoid installing on 32-bit, until RasPiOS fixes Rust (PR #3421) + when: jupyterhub_install # UNMAINTAINED - name: LOKOLE diff --git a/roles/7-edu-apps/tasks/main.yml b/roles/7-edu-apps/tasks/main.yml index 8f223b1fd..69d1b0788 100644 --- a/roles/7-edu-apps/tasks/main.yml +++ b/roles/7-edu-apps/tasks/main.yml @@ -6,12 +6,13 @@ - name: KALITE include_role: name: kalite - when: kalite_install + when: kalite_install and (is_ubuntu_2204 or is_ubuntu_2310 or is_debian_12) # Also covers is_linuxmint_21 and is_raspbian_12 - name: KOLIBRI include_role: name: kolibri when: kolibri_install + #when: kolibri_install and python_version is version('3.12', '<') # Debian 13 still uses Python 3.11 (for now!) so really this just avoids Ubuntu 24.04 and 24.10 pre-releases during initial iiab-install. CLARIF: This is all TEMPORARY until learningequality/kolibri#11316 brings Python 3.12 support to Kolibri 0.17 pre-releases (expected very soon). - name: KIWIX include_role: @@ -40,10 +41,23 @@ name: pathagar when: pathagar_install is defined and pathagar_install +# WARNING: Since March 2023, 32-bit RasPiOS can act as 64-bit on RPi 4 and +# RPi 400 (unlike RPi 3!) SEE: https://github.com/iiab/iiab/pull/3422 and #3516 +- name: Run command 'dpkg --print-architecture' to identify OS architecture (CPU arch as revealed by ansible_architecture ~= ansible_machine is NO LONGER enough!) + command: dpkg --print-architecture + register: dpkg_arch + when: sugarizer_install + +- name: Explain bypassing of Sugarizer install if 32-bit OS + fail: # FORCE IT RED THIS ONCE! + msg: "BYPASSING SUGARIZER INSTALL ATTEMPT, as Sugarizer Server 1.5.0 requires MongoDB 3.2+ which is NO LONGER SUPPORTED on 32-bit Raspberry Pi OS. 'dpkg --print-architecture' output for your OS: {{ dpkg_arch.stdout }}" + when: sugarizer_install and not dpkg_arch.stdout is search("64") + ignore_errors: True + - name: SUGARIZER include_role: name: sugarizer - when: sugarizer_install + when: sugarizer_install and dpkg_arch.stdout is search("64") - name: Recording STAGE 7 HAS COMPLETED ======================== lineinfile: diff --git a/roles/8-mgmt-tools/tasks/main.yml b/roles/8-mgmt-tools/tasks/main.yml index 61ac785ad..c6d497f15 100644 --- a/roles/8-mgmt-tools/tasks/main.yml +++ b/roles/8-mgmt-tools/tasks/main.yml @@ -6,7 +6,7 @@ - name: TRANSMISSION include_role: name: transmission - when: transmission_install + when: transmission_install and not (is_ubuntu_2404 or is_ubuntu_2410 or is_ubuntu_2504) # Also excludes is_linuxmint_22, for #3756 (whereas Debian 13 works great!) - name: AWSTATS include_role: @@ -23,11 +23,6 @@ name: monit when: monit_install -- name: MUNIN - include_role: - name: munin - when: munin_install - - name: PHPMYADMIN include_role: name: phpmyadmin diff --git a/roles/9-local-addons/tasks/main.yml b/roles/9-local-addons/tasks/main.yml index e8ab5d14b..337a74445 100644 --- a/roles/9-local-addons/tasks/main.yml +++ b/roles/9-local-addons/tasks/main.yml @@ -14,10 +14,23 @@ name: captiveportal when: captiveportal_install +# WARNING: Since March 2023, 32-bit RasPiOS can act as 64-bit on RPi 4 and +# RPi 400 (unlike RPi 3!) SEE: https://github.com/iiab/iiab/pull/3516 +- name: Run command 'dpkg --print-architecture' to identify OS architecture (CPU arch as revealed by ansible_architecture ~= ansible_machine is NO LONGER enough!) + command: dpkg --print-architecture + register: dpkg_arch + when: internetarchive_install + +- name: Explain bypassing of Internet Archive install if 32-bit OS + fail: # FORCE IT RED THIS ONCE! + msg: "BYPASSING INTERNET ARCHIVE PER https://github.com/iiab/iiab/issues/3641 -- 'dpkg --print-architecture' output for your OS: {{ dpkg_arch.stdout }}" + when: internetarchive_install and not dpkg_arch.stdout is search("64") + ignore_errors: True + - name: INTERNETARCHIVE include_role: name: internetarchive - when: internetarchive_install + when: internetarchive_install and dpkg_arch.stdout is search("64") - name: MINETEST include_role: @@ -27,7 +40,7 @@ - name: CALIBRE-WEB include_role: name: calibre-web - when: calibreweb_install and ansible_machine is search("64") # 2022-11-10: Avoid installing on 32-bit, until RasPiOS fixes Rust (PR #3421) + when: calibreweb_install # KEEP NEAR THE VERY END as this installs dependencies from Debian's 'testing' branch! - name: CALIBRE @@ -42,6 +55,46 @@ name: pbx when: pbx_install + +- name: '2023-11-05 / TEMPORARY UNTIL ADMIN CONSOLE DECLARES ITS DEPENDENCY: Install MySQL (MariaDB) if admin_console_install (for setup-feedback and record_feedback.php)' + set_fact: + mysql_install: True + mysql_enabled: True + when: admin_console_install + +- name: '2023-11-05 / TEMPORARY UNTIL ADMIN CONSOLE DECLARES ITS DEPENDENCY: Install MySQL (MariaDB) if admin_console_install (for setup-feedback and record_feedback.php)' + include_role: + name: mysql + when: admin_console_install + +- name: '2023-11-05 / TEMPORARY UNTIL ADMIN CONSOLE DECLARES ITS DEPENDENCY: Install MySQL (MariaDB) if admin_console_install (for setup-feedback and record_feedback.php)' + fail: + msg: "Admin Console install cannot proceed, as MySQL / MariaDB is not installed." + when: admin_console_install and mysql_installed is undefined + + +# 2023-11-05: Moved from Stage 8, as it acts on mysql_installed (that might be set just above!) +- name: MUNIN + include_role: + name: munin + when: munin_install + + +- name: Read 'disk_used_a_priori' from /etc/iiab/iiab.ini + set_fact: + df1: "{{ lookup('ansible.builtin.ini', 'disk_used_a_priori', section='summary', file=iiab_ini_file) }}" + +- name: Record currently used disk space, to compare with original 'disk_used_a_priori' + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add ESTIMATED 'iiab_software_disk_usage = {{ df2.stdout|int - df1|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: summary + option: iiab_software_disk_usage + value: "{{ df2.stdout|int - df1|int }}" + - name: Recording STAGE 9 HAS COMPLETED ==================== lineinfile: path: "{{ iiab_env_file }}" diff --git a/roles/awstats/tasks/install.yml b/roles/awstats/tasks/install.yml index f88e7174c..24a005c74 100644 --- a/roles/awstats/tasks/install.yml +++ b/roles/awstats/tasks/install.yml @@ -1,3 +1,8 @@ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: 'Install package: awstats' package: name: awstats @@ -93,6 +98,17 @@ # RECORD AWStats AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'awstats_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: awstats + option: awstats_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'awstats_installed: True'" set_fact: awstats_installed: True diff --git a/roles/azuracast/tasks/install.yml b/roles/azuracast/tasks/install.yml index 8ce9474d2..bd25d96fb 100644 --- a/roles/azuracast/tasks/install.yml +++ b/roles/azuracast/tasks/install.yml @@ -25,6 +25,11 @@ # 5. Run './runrole --reinstall azuracast' in /opt/iiab/iiab +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: AzuraCast - Make config directory {{ azuracast_host_dir }} file: path: "{{ azuracast_host_dir }}" @@ -102,6 +107,17 @@ # RECORD AzuraCast AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'azuracast_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: azuracast + option: azuracast_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'azuracast_installed: True'" set_fact: azuracast_installed: True diff --git a/roles/calibre-web/README.rst b/roles/calibre-web/README.rst index 44df76aa4..a29896573 100644 --- a/roles/calibre-web/README.rst +++ b/roles/calibre-web/README.rst @@ -13,98 +13,175 @@ Calibre-Web README ================== -Calibre-Web provides a clean interface for browsing, reading and downloading -e-books using an existing Calibre database. Teachers can upload e-books, -adjust e-book metadata, and create custom e-book collections ("bookshelves"): -https://github.com/janeczku/calibre-web#about +This Ansible role installs +`Calibre-Web `_ as a modern +client-server alternative to Calibre, for your +`Internet-in-a-Box (IIAB) `_. -This Ansible role installs Calibre-Web as part of your Internet-in-a-Box (IIAB) -as a possible alternative to Calibre. +Calibre-Web provides a clean web interface for students to browse, read and +download e-books using a +`Calibre-compatible database `_. -*WARNING: Calibre-Web depends on Calibre's own* ``/usr/bin/ebook-convert`` *program, -so we strongly recommend you also install Calibre during your IIAB -installation!* +Teachers upload e-books, adjust e-book metadata, and create custom "bookshelf" +collections — to help students build the best local community library! -Please note Calibre-Web's Ansible playbook is ``/opt/iiab/iiab/roles/calibre-web`` -whereas its Ansible variables ``calibreweb_*`` do **not** include the dash, -per Ansible recommendations. +**NEW AS OF JANUARY 2024:** `IIAB's experimental new version of Calibre-Web `_ +**also lets you add YouTube and Vimeo videos (and local videos, e.g. from +teachers' phones) to expand your indigenous/local/family learning library!** + +.. image:: https://www.yankodesign.com/images/design_news/2019/05/221758/luo_beetle_library_8.jpg + +🍒 GURU TIPS 🍒 + +* Calibre-Web takes advantage of Calibre's own `/usr/bin/ebook-convert + `_ program + if that's installed — so consider also installing + `Calibre `_ during your IIAB + installation — *if you tolerate the weighty ~1 GB (of graphical OS libraries) + that Calibre mandates!* + +* If you choose to also install Calibre (e.g. by running + ``sudo apt install calibre``) then you'll get useful e-book + importing/organizing tools like + `/usr/bin/calibredb `_. + +Install It +---------- + +Install Calibre-Web by setting these 2 variables in +`/etc/iiab/local_vars.yml `_:: + + calibreweb_install: True + calibreweb_enabled: True + +Then install IIAB (`download.iiab.io `_). Or if +IIAB's already installed, run:: + + cd /opt/iiab/iiab + sudo ./runrole calibre-web + +NOTE: Calibre-Web's Ansible role (playbook) in +`/opt/iiab/iiab/roles `_ is +``calibre-web`` which contains a hyphen — *whereas its Ansible variables* +``calibreweb_*`` *do NOT contain a hyphen!* Using It -------- -After installation, try out Calibre-Web at http://box/books (or box.lan/books). +Try Calibre-Web on your own IIAB by browsing to http://box/books (or +http://box.lan/books). -Typically students access it without a password (to read and download books) -whereas teachers add books using an administrative account, as follows:: +*Students* access it without a password (to read and download books). + +*Teachers* add and arrange books using an administrative account, by clicking +**Guest** then logging in with:: Username: Admin Password: changeme -If the default configuration is not found, the Calibre-Web server creates a -new settings file with calibre-web's own default administrative account:: +🍒 GURU TIPS 🍒 - Username: admin - Password: admin123 +* If Calibre-Web's configuration file (app.db) goes missing, the administrative + account will revert to:: -Backend -------- + Username: admin + Password: admin123 -You can manage the backend Calibre-Web server with these systemd commands:: - - systemctl enable calibre-web - systemctl restart calibre-web - systemctl status calibre-web - systemctl stop calibre-web +* If you lose your password, you can change it with the + ``-s [username]:[newpassword]`` command-line option: + https://github.com/janeczku/calibre-web/wiki/FAQ#what-do-i-do-if-i-lose-my-admin-password Configuration ------------- -To configure Calibre-Web, log in as user 'Admin' then click 'Admin' on top. -Check 'Configuration' options near the bottom of the page. +To configure Calibre-Web browse to http://box/books then click **Guest** to log +in as user **Admin** (default passwords above!) -Critical settings are stored in:: +Then click the leftmost **Admin** button to administer — considering all 3 +**Configuration** buttons further below. + +These critical settings are stored in:: /library/calibre-web/config/app.db -Your e-book metadata is stored in a Calibre-style database:: +Whereas your e-book metadata is stored in a Calibre-style database:: /library/calibre-web/metadata.db +Videos' metadata is stored in database:: + + /library/calibre-web/xklb-metadata.db + See also:: /library/calibre-web/metadata_db_prefs_backup.json -Finally, take note of Calibre-Web's `FAQ `_ and official docs on its `Runtime Configuration Options `_ and `Command Line Interface `_. +Finally, take note of Calibre-Web's +`FAQ `_ and official docs on +its +`Runtime Configuration Options `_ +and +`Command Line Interface `_. + +Backend +------- + +You can manage the backend Calibre-Web server with systemd commands like:: + + systemctl status calibre-web + systemctl stop calibre-web + systemctl restart calibre-web + +Run all commands +`as root `_. + +Errors and warnings can be seen if you run:: + + journalctl -u calibre-web + +Log verbosity level can be +`adjusted `_ +within Calibre-Web's **Configuration > Basic Configuration > Logfile +Configuration**. + +Finally, http://box/live/stats (Calibre-Web's **About** page) can be a very +useful list of ~42 `Calibre-Web dependencies `_ +(mostly Python packages, and the version number of each that's installed). Back Up Everything ------------------ Please back up the entire folder ``/library/calibre-web`` before upgrading — -as it contains your Calibre-Web content **and** settings! +as it contains your Calibre-Web content **and** configuration settings! Upgrading --------- -Reinstalling Calibre-Web automatically upgrades to the latest version if your -Internet-in-a-Box (IIAB) is online. +Please see our `new/automated upgrade technique (iiab-update) `_ +introduced in July 2024. -But first: back up your content **and** settings, as explained above. +But first: back up your content **and** configuration settings, as outlined +above! -**Also move your /library/calibre-web/config/app.db AND/OR -/library/calibre-web/metadata.db out of the way — if you're sure you want to -fully reset your Calibre-Web settings (to install defaults) AND/OR remove all -e-book metadata! Then run**:: +**Conversely if you're sure you want to fully reset your Calibre-Web settings, +and remove all existing e-book/video/media metadata — then move your +/library/calibre-web/config/app.db, /library/calibre-web/metadata.db and +/library/calibre-web/xklb-metadata.db out of the way.** + +RECAP: Either way, "reinstalling" Calibre-Web automatically installs the latest +version — so long as your Internet-in-a-Box (IIAB) is online. Most people +should stick with the new ``iiab-update`` technique above. However if you must +use the older/manual approach, you would need to run, as root:: cd /opt/iiab/iiab ./runrole --reinstall calibre-web -Or, if you just want to upgrade Calibre-Web code alone, prior to proceeding -manually:: +Or, if there's a need to try updating Calibre-Web's code alone:: cd /usr/local/calibre-web-py3 git pull -This older way *is no longer recommended*:: +Finally, this much older way is *no longer recommended*:: cd /opt/iiab/iiab ./iiab-install --reinstall # OR: ./iiab-configure @@ -156,5 +233,5 @@ Known Issues * |ss| Upload of not supported file formats gives no feedback to the user: `janeczku/calibre-web#828 `_ |se| |nbsp| Fixed by `361a124 `_ on 2019-02-27. -* *Please assist us in reporting serious issues here:* - https://github.com/janeczku/calibre-web/issues +* *Please report serious issues here:* + https://github.com/iiab/calibre-web/issues diff --git a/roles/calibre-web/defaults/main.yml b/roles/calibre-web/defaults/main.yml index 7abab0bd8..3e99725a9 100644 --- a/roles/calibre-web/defaults/main.yml +++ b/roles/calibre-web/defaults/main.yml @@ -14,8 +14,10 @@ # All above are set in: github.com/iiab/iiab/blob/master/vars/default_vars.yml # If nec, change them by editing /etc/iiab/local_vars.yml prior to installing! +calibreweb_repo_url: https://github.com/iiab/calibre-web # Or use upstream: https://github.com/janeczku/calibre-web calibreweb_version: master # WAS: master, 0.6.4, 0.6.5, 0.6.6, 0.6.7, 0.6.8, 0.6.9 +calibreweb_venv_wipe: False # 2023-12-04: NEW default TDD (Test-Driven Dev!) calibreweb_venv_path: /usr/local/calibre-web-py3 calibreweb_exec_path: "{{ calibreweb_venv_path }}/cps.py" diff --git a/roles/calibre-web/files/app.db b/roles/calibre-web/files/app.db index 31a8b716a..3183544da 100644 Binary files a/roles/calibre-web/files/app.db and b/roles/calibre-web/files/app.db differ diff --git a/roles/calibre-web/tasks/enable-or-disable.yml b/roles/calibre-web/tasks/enable-or-disable.yml index b196176f9..493703dc7 100644 --- a/roles/calibre-web/tasks/enable-or-disable.yml +++ b/roles/calibre-web/tasks/enable-or-disable.yml @@ -23,12 +23,29 @@ dest: "{{ nginx_conf_dir }}/calibre-web-nginx.conf" # /etc/nginx/conf.d when: calibreweb_enabled +- name: If enabling with Calibre-Web enhanced for large audio/video "books" too, also append onto calibre-web-nginx.conf AND symlink /library/www/html/calibre-web -> /library/calibre-web (WIP) + shell: | + if [ -f {{ calibreweb_venv_path }}/scripts/calibre-web-nginx.conf ]; then + cat {{ calibreweb_venv_path }}/scripts/calibre-web-nginx.conf >> {{ nginx_conf_dir }}/calibre-web-nginx.conf + # 2023-12-05: Not needed as a result of PR iiab/calibre-web#57 + # ln -sf {{ calibreweb_home }} {{ doc_root }}/calibre-web + fi + when: calibreweb_enabled + + - name: Disable http://box{{ calibreweb_url1 }} via NGINX, by removing {{ nginx_conf_dir }}/calibre-web-nginx.conf file: - path: "{{ nginx_conf_dir }}/calibre-web-nginx.conf" # /etc/nginx/conf.d + path: "{{ nginx_conf_dir }}/calibre-web-nginx.conf" state: absent when: not calibreweb_enabled +- name: If disabling, also remove symlink /library/www/html/calibre-web (WIP) + file: + path: "{{ doc_root }}/calibre-web" # /library/www/html + state: absent + when: not calibreweb_enabled + + - name: Restart 'nginx' systemd service systemd: name: nginx diff --git a/roles/calibre-web/tasks/install.yml b/roles/calibre-web/tasks/install.yml index 65a88168c..d293afe23 100644 --- a/roles/calibre-web/tasks/install.yml +++ b/roles/calibre-web/tasks/install.yml @@ -1,10 +1,50 @@ -- name: "Install packages: imagemagick, python3-venv" +# Or try 'iiab-update -f' for a more rapid upgrade of IIAB Calibre-Web: +# +# https://wiki.iiab.io/go/FAQ#Can_I_upgrade_IIAB_software%3F +# https://github.com/iiab/calibre-web/wiki#upgrading +# https://github.com/iiab/iiab/blob/master/scripts/iiab-update +# https://github.com/iiab/iiab/tree/master/roles/calibre-web#upgrading + + +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + +- name: Stop 'calibre-web' systemd service for safety (RED ERROR CAN BE IGNORED!) + systemd: + name: calibre-web + state: stopped + ignore_errors: True # Shows red errors, and continue... + #failed_when: False # Hides red errors, and continue... + +# Official upstream instructions: +# apt install python3-pip python3-venv +# https://github.com/janeczku/calibre-web/wiki/Manual-installation +- name: "Install package: imagemagick" package: name: - imagemagick - - python3-venv + #- python3-cryptography # Was needed on Raspberry Pi OS (SEE iiab/calibre-web#260, janeczku/calibre-web#3183) + #- python3-netifaces state: present +# https://github.com/iiab/iiab/pull/3496#issuecomment-1475094542 +#- name: "Install packages: python3-dev, gcc to compile 'netifaces'" +# package: +# name: +# - python3-dev # header files +# - gcc # compiler +# state: present +# when: python_version is version('3.10', '>=') + +- name: Does /etc/ImageMagick-6/policy.xml exist? + stat: + path: /etc/ImageMagick-6/policy.xml + register: imagemagick6_policy_xml + +# 2024-12-16: Debian 13 uses /etc/ImageMagick-7/policy.xml instead, which doesn't need this lineinfile surgery: +# https://stackoverflow.com/questions/52998331/imagemagick-security-policy-pdf-blocking-conversion - name: Allow ImageMagick to read PDFs, per /etc/ImageMagick-6/policy.xml, to create book cover thumbnails lineinfile: path: /etc/ImageMagick-6/policy.xml @@ -12,8 +52,9 @@ backrefs: yes line: ' ' state: present + when: imagemagick6_policy_xml.stat.exists -- name: "Create 3 Calibre-Web folders to store data and config files: {{ calibreweb_home }}, {{ calibreweb_venv_path }}, {{ calibreweb_config }} (all set to {{ calibreweb_user }}:{{ apache_user }}) (default to 0755)" +- name: "Create 2 Calibre-Web folders to store data and config files: {{ calibreweb_home }}, {{ calibreweb_config }} (each set to {{ calibreweb_user }}:{{ apache_user }}, default to 0755)" file: state: directory path: "{{ item }}" @@ -22,40 +63,100 @@ with_items: - "{{ calibreweb_home }}" # /library/calibre-web - "{{ calibreweb_config }}" # /library/calibre-web/config - - "{{ calibreweb_venv_path }}" # /usr/local/calibre-web-py3 -## TODO: Calibre-web future release might get into pypi https://github.com/janeczku/calibre-web/issues/456 -- name: Clone i.e. download Calibre-Web ({{ calibreweb_version }}) from https://github.com/janeczku/calibre-web.git to {{ calibreweb_venv_path }} (~94 MB initially, ~115+ MB later) +# FYI since May 2021, Calibre-Web (major releases) can be installed with pip: +# https://pypi.org/project/calibreweb/ +# https://github.com/janeczku/calibre-web/issues/456 +# https://github.com/janeczku/calibre-web/issues/677 +# https://github.com/janeczku/calibre-web/pull/927 +# https://github.com/janeczku/calibre-web/pull/1459 + +- name: "Remove previous virtual environment {{ calibreweb_venv_path }} -- if 'calibreweb_venv_wipe: True'" + file: + path: "{{ calibreweb_venv_path }}" # /usr/local/calibre-web-py3 + state: absent + when: calibreweb_venv_wipe + +- name: Does {{ calibreweb_venv_path }} exist? + stat: + path: "{{ calibreweb_venv_path }}" + register: calibreweb_venv + +- name: git clone Calibre-Web ({{ calibreweb_version }}) from {{ calibreweb_repo_url }} to {{ calibreweb_venv_path }} (~122 MB initially, ~191+ or ~203+ MB later) -- if {{ calibreweb_venv_path }} doesns't exist git: - repo: https://github.com/janeczku/calibre-web.git + repo: "{{ calibreweb_repo_url }}" # e.g. https://github.com/iiab/calibre-web or https://github.com/janeczku/calibre-web dest: "{{ calibreweb_venv_path }}" - force: yes - depth: 1 - version: "{{ calibreweb_version }}" # e.g. master, 0.6.17 + #force: True # CLAIM: "If true, any modified files in the working repository will be discarded" -- REALITY: even if `force: no`, Ansible destructively reclones (also removing all test branch commits etc!) -- unless a git credential is provided to Ansible? + #depth: 1 # 2023-11-04: Full clone for now, to help @deldesir & wider community testing + version: "{{ calibreweb_version }}" # e.g. master, 0.6.22 + when: not calibreweb_venv.stat.exists -## Ansible Pip Bug: Cannot use 'chdir' with 'env' https://github.com/ansible/ansible/issues/37912 (Patch landed) -#- name: Download calibre-web dependencies into vendor subdirectory. -# pip: -# requirements: "{{ calibreweb_path }}/requirements.txt" -# chdir: "{{ calibreweb_path }}" -# extra_args: '--target vendor' -# ignore_errors: True -## -# Implementing this with Ansible command module for now. -- name: Download Calibre-Web dependencies (using pip) into python3 virtual environment {{ calibreweb_venv_path }} +- name: cd {{ calibreweb_venv_path }} ; git pull {{ calibreweb_repo_url }} {{ calibreweb_version }} --no-rebase --no-edit -- if {{ calibreweb_venv_path }} exists + command: git pull "{{ calibreweb_repo_url }}" "{{ calibreweb_version }}" --no-rebase --no-edit + args: + chdir: "{{ calibreweb_venv_path }}" + when: calibreweb_venv.stat.exists + +- debug: + msg: + - "NEED BETTER/EXPERIMENTAL YouTube SCRAPING? RUN THE NEXT LINE -- for the latest yt-dlp 'nightly' release:" + - sudo pipx inject --pip-args='--upgrade --pre' -f library yt-dlp[default] + +- name: If Calibre-Web is being enhanced with audio/video "books" too, install/upgrade additional prereqs -- SEE https://github.com/iiab/calibre-web/wiki + shell: | + if [ -f {{ calibreweb_venv_path }}/scripts/lb-wrapper ]; then + apt install ffmpeg pipx -y + if lb --version; then + if pipx list | grep -q 'xklb'; then + pipx uninstall xklb + pipx install library + else + pipx reinstall library + fi + else + pipx install library + fi + ln -sf /root/.local/bin/lb /usr/local/bin/lb + if [ -f /root/.local/share/pipx/venvs/library/bin/yt-dlp ]; then + ln -sf /root/.local/share/pipx/venvs/library/bin/yt-dlp /usr/local/bin/yt-dlp + elif [ -f /root/.local/pipx/venvs/library/bin/yt-dlp ]; then + ln -sf /root/.local/pipx/venvs/library/bin/yt-dlp /usr/local/bin/yt-dlp + else + echo "ERROR: yt-dlp NOT FOUND" + fi + # NEED BETTER/EXPERIMENTAL YouTube SCRAPING? UNCOMMENT THE NEXT LINE -- for the latest yt-dlp "nightly" release: + # pipx inject --pip-args="--upgrade --pre" -f library yt-dlp[default] + # + # https://github.com/yt-dlp/yt-dlp-nightly-builds/releases + # https://pypi.org/project/yt-dlp/#history + cp {{ calibreweb_venv_path }}/scripts/lb-wrapper /usr/local/bin/ + chmod a+x /usr/local/bin/lb-wrapper + fi + +- name: Download Calibre-Web dependencies from 'requirements.txt' into python3 virtual environment {{ calibreweb_venv_path }} pip: requirements: "{{ calibreweb_venv_path }}/requirements.txt" virtualenv: "{{ calibreweb_venv_path }}" # /usr/local/calibre-web-py3 - virtualenv_site_packages: no + #virtualenv_site_packages: no + #virtualenv_command: python3 -m venv --system-site-packages {{ calibreweb_venv_path }} virtualenv_command: python3 -m venv {{ calibreweb_venv_path }} + extra_args: --prefer-binary # 2023-10-01: Lifesaver when recent wheels (e.g. piwheels.org) are inevitably not yet built! SEE #3560 + +# 2023-10-11: RasPiOS Bookworm doc for Python with venv (PEP 668 now enforced!) +# https://www.raspberrypi.com/documentation/computers/os.html#use-python-on-a-raspberry-pi +# https://www.raspberrypi.com/documentation/computers/os.html#install-python-packages-using-apt +# https://www.raspberrypi.com/documentation/computers/os.html#install-python-libraries-using-pip + # VIRTUALENV EXAMPLE COMMANDS: +# python3 -m venv /usr/local/calibre-web-py3 (create venv) # cd /usr/local/calibre-web-py3 -# source bin/activate -# python3 -m pip list ('pip list' probably sufficient, likewise below) +# . bin/activate (or 'source bin/activate' -- this prepends '/usr/local/calibre-web-py3/bin' to yr PATH) +# python3 -m pip list ('pip list' sufficient *IF* path set above!) # python3 -m pip freeze > /tmp/requirements.txt # python3 -m pip install -r requirements.txt # deactivate -# https://pip.pypa.io/en/latest/user_guide/#requirements-files +# https://pip.pypa.io/en/stable/user_guide/#requirements-files +# https://pip.pypa.io/en/latest/reference/requirements-file-format/ - name: Install /etc/systemd/system/calibre-web.service from template template: @@ -96,6 +197,17 @@ # RECORD Calibre-Web AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'calibreweb_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: calibre-web + option: calibreweb_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'calibreweb_installed: True'" set_fact: calibreweb_installed: True diff --git a/roles/calibre-web/templates/calibre-web-nginx.conf.j2 b/roles/calibre-web/templates/calibre-web-nginx.conf.j2 index d1f2da25b..2ebfe47fe 100644 --- a/roles/calibre-web/templates/calibre-web-nginx.conf.j2 +++ b/roles/calibre-web/templates/calibre-web-nginx.conf.j2 @@ -5,7 +5,7 @@ location {{ calibreweb_url1 }}/ { proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Scheme $scheme; - proxy_set_header X-Script-Name {{ calibreweb_url1 }}; + proxy_set_header X-Script-Name "{{ calibreweb_url1 }}"; proxy_pass http://127.0.0.1:8083; } @@ -14,7 +14,7 @@ location {{ calibreweb_url2 }}/ { proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Scheme $scheme; - proxy_set_header X-Script-Name {{ calibreweb_url2 }}; + proxy_set_header X-Script-Name "{{ calibreweb_url2 }}"; proxy_pass http://127.0.0.1:8083; } @@ -23,6 +23,6 @@ location {{ calibreweb_url3 }}/ { proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Scheme $scheme; - proxy_set_header X-Script-Name {{ calibreweb_url3 }}; + proxy_set_header X-Script-Name "{{ calibreweb_url3 }}"; proxy_pass http://127.0.0.1:8083; } diff --git a/roles/calibre/tasks/install.yml b/roles/calibre/tasks/install.yml index 6a435c968..82218ada0 100644 --- a/roles/calibre/tasks/install.yml +++ b/roles/calibre/tasks/install.yml @@ -1,3 +1,8 @@ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + # 1. APT INSTALL CALIBRE 4.12+ or 5.12+ (calibre, calibredb, calibre-server etc) ON ALL OS'S - name: "Install OS's latest packages: calibre, calibre-bin" @@ -79,6 +84,17 @@ # 5. RECORD Calibre AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'calibre_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: calibre + option: calibre_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'calibre_installed: True'" set_fact: calibre_installed: True diff --git a/roles/captiveportal/tasks/install.yml b/roles/captiveportal/tasks/install.yml index ab25d50b6..b76ad39b0 100644 --- a/roles/captiveportal/tasks/install.yml +++ b/roles/captiveportal/tasks/install.yml @@ -1,3 +1,8 @@ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: "Install packages: python3-dateutil, python3-jinja2" package: name: @@ -51,6 +56,17 @@ # RECORD Captive Portal AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'captiveportal_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: captiveportal + option: captiveportal_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'captiveportal_installed: True'" set_fact: captiveportal_installed: True diff --git a/roles/cups/README.md b/roles/cups/README.md index 6cf926c88..cd727be5f 100644 --- a/roles/cups/README.md +++ b/roles/cups/README.md @@ -8,7 +8,7 @@ This can be useful if a printer is attached to your IIAB — so student/teac ## Using it -Make sure your IIAB was installed with these 2 lines in [/etc/iiab/local_vars.yml](http://faq.iiab.io/#What_is_local_vars.yml_and_how_do_I_customize_it.3F) : +Make sure your IIAB was installed with these 2 lines in [/etc/iiab/local_vars.yml](http://faq.iiab.io/#What_is_local_vars.yml_and_how_do_I_customize_it%3F) : ``` cups_install: True diff --git a/roles/cups/tasks/install.yml b/roles/cups/tasks/install.yml index 12296cfe5..55209a50b 100644 --- a/roles/cups/tasks/install.yml +++ b/roles/cups/tasks/install.yml @@ -2,6 +2,11 @@ # (OR ANY MEMBER OF LINUX GROUP 'lpadmin') AS SET UP BELOW... +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: Install 'cups' package package: name: cups @@ -53,15 +58,30 @@ AuthType Default Require user @SYSTEM -- name: "CUPS web administration: Create Linux username 'Admin' with password 'changeme' in Linux group 'lpadmin' (shell: /usr/sbin/nologin, create_home: no)" +- name: "CUPS web administration: Create Linux username 'Admin' in Linux group 'lpadmin' (shell: /usr/sbin/nologin, create_home: no)" user: name: Admin append: yes # Don't clobber other groups, that other IIAB Apps might need. groups: lpadmin - password: "{{ 'changeme' | password_hash('sha512') }}" # Random salt. Presumably runs 5000 rounds of SHA-512 per /etc/login.defs & /etc/pam.d/common-password -- https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#encrypting-and-checksumming-strings-and-passwords + #password: "{{ 'changeme' | password_hash('sha512') }}" # Random salt. Presumably runs 5000 rounds of SHA-512 per /etc/login.defs & /etc/pam.d/common-password -- https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_filters.html#hashing-and-encrypting-strings-and-passwords create_home: no shell: /usr/sbin/nologin # Debian/Ubuntu norm -- instead of /sbin/nologin, /bin/false +# 2024-05-01: Above password-setting approach no longer works w/ Ansible 2.17 RC1 (#3727). +# Ansible STOPS with this error... +# +# "[DEPRECATION WARNING]: Encryption using the Python crypt module is deprecated. The Python crypt module is +# deprecated and will be removed from Python 3.13. Install the passlib library for continued encryption +# functionality. This feature will be removed in version 2.17. Deprecation warnings can be disabled by +# setting deprecation_warnings=False in ansible.cfg." +# +# ...so we instead use Linux's "chpasswd" command (below!) + +- name: Use chpasswd to set Linux username 'Admin' password to 'changeme' + command: chpasswd + args: + stdin: Admin:changeme + # - name: Add user '{{ iiab_admin_user }}' to Linux group 'lpadmin' -- for CUPS web administration (or modify default 'SystemGroup lpadmin' in /etc/cups/cups-files.conf -- in coordination with ~14 -> ~15 '@SYSTEM' lines in /etc/cups/cupsd.conf) # #command: "gpasswd -a {{ iiab_admin_user | quote }} lpadmin" # #command: "gpasswd -d {{ iiab_admin_user | quote }} lpadmin" @@ -124,6 +144,17 @@ # RECORD CUPS AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'cups_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: cups + option: cups_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'cups_installed: True'" set_fact: cups_installed: True diff --git a/roles/cups/tasks/main.yml b/roles/cups/tasks/main.yml index 2c9531814..a709ac090 100644 --- a/roles/cups/tasks/main.yml +++ b/roles/cups/tasks/main.yml @@ -23,26 +23,33 @@ quiet: yes -- name: Install CUPS if 'cups_installed' not defined, e.g. in {{ iiab_state_file }} # /etc/iiab/iiab_state.yml - include_tasks: install.yml - when: cups_installed is undefined +- block: + - name: Install CUPS if 'cups_installed' not defined, e.g. in {{ iiab_state_file }} # /etc/iiab/iiab_state.yml + include_tasks: install.yml + when: cups_installed is undefined -- include_tasks: enable-or-disable.yml + - include_tasks: enable-or-disable.yml + - name: Add 'cups' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: cups + option: "{{ item.option }}" + value: "{{ item.value | string }}" + with_items: + - option: name + value: CUPS + - option: description + value: '"CUPS (Common UNIX Printing System) is a modular printing system that allows a computer to act as a print server. A computer running CUPS is a host that can accept print jobs from client computers, process them, and send them to the appropriate printer."' + - option: cups_install + value: "{{ cups_install }}" + - option: cups_enabled + value: "{{ cups_enabled }}" -- name: Add 'cups' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini - section: cups - option: "{{ item.option }}" - value: "{{ item.value | string }}" - with_items: - - option: name - value: CUPS - - option: description - value: '"CUPS (Common UNIX Printing System) is a modular printing system that allows a computer to act as a print server. A computer running CUPS is a host that can accept print jobs from client computers, process them, and send them to the appropriate printer."' - - option: cups_install - value: "{{ cups_install }}" - - option: cups_enabled - value: "{{ cups_enabled }}" + rescue: + + - name: 'SEE ERROR ABOVE (skip_role_on_error: {{ skip_role_on_error }})' + fail: + msg: "" + when: not skip_role_on_error diff --git a/roles/firmware/tasks/download.yml b/roles/firmware/tasks/download.yml index 949ad3583..abda2e6b4 100644 --- a/roles/firmware/tasks/download.yml +++ b/roles/firmware/tasks/download.yml @@ -1,23 +1,44 @@ -- name: Back up 4 OS-provided WiFi firmware files (or symlinks) to /lib/firmware/brcm/*.orig - copy: - src: /lib/firmware/brcm/{{ item }} - dest: /lib/firmware/brcm/{{ item }}.orig +# 2023-02-25: MONITOR FIRMWARE UPDATES in 3 places especially... +# +# 1. apt changelog firmware-brcm80211 +# https://github.com/RPi-Distro/firmware-nonfree -> debian/config/brcm80211 (brcm, cypress) +# https://archive.raspberrypi.org/debian/dists/bullseye/main/binary-arm64/Packages (1.1MB text file, look inside for summary of latest firmware-brcm80211) +# https://archive.raspberrypi.org/debian/pool/main/f/firmware-nonfree/ -> firmware-brcm80211_* e.g.: +# https://archive.raspberrypi.org/debian/pool/main/f/firmware-nonfree/firmware-brcm80211_20190114-1+rpt11_all.deb from 2021-01-25 +# https://archive.raspberrypi.org/debian/pool/main/f/firmware-nonfree/firmware-brcm80211_20210315-3+rpt4_all.deb from 2021-12-06 +# https://archive.raspberrypi.org/debian/pool/main/f/firmware-nonfree/firmware-brcm80211_20221012-1~bpo11+1+rpt1_all.deb from 2022-11-17 +# 2. apt changelog linux-firmware-raspi +# https://packages.ubuntu.com/search?keywords=linux-firmware-raspi +# 3. https://github.com/moodlebox/moodlebox/blob/main/roles/accesspoint/tasks/main.yml + +#- name: Back up 4 OS-provided WiFi firmware files (incl symlink contents) to /lib/firmware/cypress/*.orig +- name: Back up 4 OS-provided WiFi firmware files (replicate any symlinks) to /lib/firmware/cypress/*.orig -- /usr/bin/iiab-check-firmware will later do similar (e.g. as firmware install completes) -- moving 2-or-4 of these to .YYYY-MM-DD-HH:MM:SS ("doubly timestamping" to preserve BOTH last-modif & moving date) + # copy: + # src: /lib/firmware/cypress/{{ item }} + # dest: /lib/firmware/cypress/{{ item }}.orig + # #local_follow: False # FAILS TO PRESERVE LINKS (ansible/ansible#74777) e.g. /lib/firmware/cypress/cyfmac43455-sdio.bin -> /etc/alternatives/cyfmac43455-sdio.bin -> ... + # 2023-05-01 CLARIF OF BELOW: + # 1) Even if 'mv' fails, no matter it'll continue to 'cp' below + # 2) 'cp -P' == 'cp --no-dereference' sufficient to replicate these symlinks and files ('cp -d' & 'cp -a' are incrementally stronger, and so probably can't hurt) + shell: | + mv /lib/firmware/cypress/{{ item }}.orig /lib/firmware/cypress/{{ item }}.orig.$(date +%F-%T) + cp -a /lib/firmware/cypress/{{ item }} /lib/firmware/cypress/{{ item }}.orig with_items: - - brcmfmac43430-sdio.bin - - brcmfmac43430-sdio.clm_blob - - brcmfmac43455-sdio.bin - - brcmfmac43455-sdio.clm_blob - ignore_errors: yes + - cyfmac43430-sdio.bin + - cyfmac43430-sdio.clm_blob + - cyfmac43455-sdio.bin + - cyfmac43455-sdio.clm_blob + #ignore_errors: yes # 2023-02-25: Let's INTENTIONALLY surface any errors, e.g. if any future RasPiOS or Ubuntu-on-Rpi lack some of the above 4 files/links? - name: Download higher-capacity firmwares (for RPi internal WiFi, per https://github.com/iiab/iiab/issues/823#issuecomment-662285202 and https://github.com/iiab/iiab/issues/2853) get_url: url: "{{ iiab_download_url }}/{{ item }}" - dest: /lib/firmware/brcm/ + dest: /lib/firmware/cypress/ timeout: "{{ download_timeout }}" with_items: - - brcmfmac43455-sdio.bin_2021-11-30_minimal # 19 -- from https://github.com/RPi-Distro/firmware-nonfree/blob/feeeda21e930c2e182484e8e1269b61cca2a8451/debian/config/brcm80211/cypress/cyfmac43455-sdio-minimal.bin + - brcmfmac43455-sdio.bin_2021-11-30_minimal # 19 -- SAME AS RASPIOS & UBUNTU'S https://github.com/RPi-Distro/firmware-nonfree/blob/feeeda21e930c2e182484e8e1269b61cca2a8451/debian/config/brcm80211/cypress/cyfmac43455-sdio-minimal.bin - brcmfmac43455-sdio.bin_2021-10-05_3rd-trial-minimal # 24 -- from https://github.com/iiab/iiab/issues/2853#issuecomment-934293015 - - brcmfmac43455-sdio.clm_blob_2021-11-17_rpi # Works w/ both above -- from https://github.com/RPi-Distro/firmware-nonfree/blob/dc406650e840705957f8403efeacf71d2d7543b3/debian/config/brcm80211/cypress/cyfmac43455-sdio.clm_blob + - brcmfmac43455-sdio.clm_blob_2021-11-17_rpi # Works w/ both above -- SAME AS RASPIOS & UBUNTU'S https://github.com/RPi-Distro/firmware-nonfree/blob/dc406650e840705957f8403efeacf71d2d7543b3/debian/config/brcm80211/cypress/cyfmac43455-sdio.clm_blob - brcmfmac43455-sdio.bin_2015-03-01_7.45.18.0_ub19.10.1 # 32 -- from https://github.com/iiab/iiab/issues/823#issuecomment-662285202 - brcmfmac43455-sdio.clm_blob_2018-02-26_rpi - brcmfmac43430-sdio.bin_2018-09-11_7.45.98.65 # 30 -- from https://github.com/iiab/iiab/issues/823#issuecomment-662285202 diff --git a/roles/firmware/tasks/install.yml b/roles/firmware/tasks/install.yml index c0fcfa532..4f323ca72 100644 --- a/roles/firmware/tasks/install.yml +++ b/roles/firmware/tasks/install.yml @@ -4,61 +4,69 @@ # Set 2 symlinks for RPi 3 B+ and 4 (43455) +# COMPARE: update-alternatives --display cyfmac43455-sdio.bin +# https://github.com/moodlebox/moodlebox/blob/main/roles/accesspoint/tasks/main.yml#L3-L6 -- name: Populate rpi3bplus_rpi4_wifi_firmwares dictionary (lookup table for operator-chosen .bin and .clm_blob files in /lib/firmware/brcm) +- name: Populate rpi3bplus_rpi4_wifi_firmwares dictionary (lookup table for operator-chosen .bin and .clm_blob files in /lib/firmware/cypress) set_fact: rpi3bplus_rpi4_wifi_firmwares: # Dictionary keys (left side) are always strings, e.g. "19" os: - - brcmfmac43455-sdio.bin.orig - - brcmfmac43455-sdio.clm_blob.orig + - cyfmac43455-sdio.bin.orig # 2023-02-25: 7.45.241 from 2021-11-01 on Ubuntu 22.04.2 too (cyfmac43455-sdio-standard.bin) + - cyfmac43455-sdio.clm_blob.orig # On Ubuntu 22.04.2 too (brcmfmac43455-sdio.clm_blob_2021-11-17_rpi) + ub: + - cyfmac43455-sdio.bin.distrib # 2023-02-25: STALE 7.45.234 from 2021-04-15; on Ubuntu 22.04.2 NOT RasPiOS + - cyfmac43455-sdio.clm_blob.distrib # 4.7K instead of 2.7K w/ above "os" 19: - - brcmfmac43455-sdio.bin_2021-11-30_minimal - - brcmfmac43455-sdio.clm_blob_2021-11-17_rpi + - brcmfmac43455-sdio.bin_2021-11-30_minimal # On Ubuntu 22.04.2 too (cyfmac43455-sdio-minimal.bin) + - brcmfmac43455-sdio.clm_blob_2021-11-17_rpi # On Ubuntu 22.04.2 too (cyfmac43455-sdio.clm_blob) 24: - brcmfmac43455-sdio.bin_2021-10-05_3rd-trial-minimal - - brcmfmac43455-sdio.clm_blob_2021-11-17_rpi + - brcmfmac43455-sdio.clm_blob_2021-11-17_rpi # On Ubuntu 22.04.2 too (cyfmac43455-sdio.clm_blob) 32: - brcmfmac43455-sdio.bin_2015-03-01_7.45.18.0_ub19.10.1 - - brcmfmac43455-sdio.clm_blob_2018-02-26_rpi + - brcmfmac43455-sdio.clm_blob_2018-02-26_rpi # 14K instead of 2.7K w/ above "os" -- name: Symlink /lib/firmware/brcm/brcmfmac43455-sdio.bin.iiab -> {{ rpi3bplus_rpi4_wifi_firmwares[rpi3bplus_rpi4_wifi_firmware][0] }} (as rpi3bplus_rpi4_wifi_firmware is "{{ rpi3bplus_rpi4_wifi_firmware }}") +- name: Symlink /lib/firmware/cypress/cyfmac43455-sdio.bin.iiab -> {{ rpi3bplus_rpi4_wifi_firmwares[rpi3bplus_rpi4_wifi_firmware][0] }} (as rpi3bplus_rpi4_wifi_firmware is "{{ rpi3bplus_rpi4_wifi_firmware }}") file: src: "{{ rpi3bplus_rpi4_wifi_firmwares[rpi3bplus_rpi4_wifi_firmware][0] }}" - path: /lib/firmware/brcm/brcmfmac43455-sdio.bin.iiab + path: /lib/firmware/cypress/cyfmac43455-sdio.bin.iiab state: link force: yes -- name: Symlink /lib/firmware/brcm/brcmfmac43455-sdio.clm_blob.iiab -> {{ rpi3bplus_rpi4_wifi_firmwares[rpi3bplus_rpi4_wifi_firmware][1] }} (as rpi3bplus_rpi4_wifi_firmware is "{{ rpi3bplus_rpi4_wifi_firmware }}") +- name: Symlink /lib/firmware/cypress/cyfmac43455-sdio.clm_blob.iiab -> {{ rpi3bplus_rpi4_wifi_firmwares[rpi3bplus_rpi4_wifi_firmware][1] }} (as rpi3bplus_rpi4_wifi_firmware is "{{ rpi3bplus_rpi4_wifi_firmware }}") file: src: "{{ rpi3bplus_rpi4_wifi_firmwares[rpi3bplus_rpi4_wifi_firmware][1] }}" - path: /lib/firmware/brcm/brcmfmac43455-sdio.clm_blob.iiab + path: /lib/firmware/cypress/cyfmac43455-sdio.clm_blob.iiab state: link force: yes # Set 2 symlinks for RPi Zero W and 3 (43430) -- name: Populate rpizerow_rpi3_wifi_firmwares dictionary (lookup table for operator-chosen .bin and .clm_blob files in /lib/firmware/brcm) +- name: Populate rpizerow_rpi3_wifi_firmwares dictionary (lookup table for operator-chosen .bin and .clm_blob files in /lib/firmware/cypress) set_fact: rpizerow_rpi3_wifi_firmwares: os: - - brcmfmac43430-sdio.bin.orig - - brcmfmac43430-sdio.clm_blob.orig + - cyfmac43430-sdio.bin.orig # 2023-02-25: 7.45.98 from 2021-07-19 on Ubuntu 22.04.2 too + - cyfmac43430-sdio.clm_blob.orig # On Ubuntu 22.04.2 too + ub: + - cyfmac43430-sdio.bin.distrib # 2023-02-25: STALE 7.45.98.118 from 2021-03-30; on Ubuntu 22.04.2 NOT RasPiOS + - cyfmac43430-sdio.clm_blob.distrib # Identical to above 4.7K cyfmac43430-sdio.clm_blob 30: - brcmfmac43430-sdio.bin_2018-09-11_7.45.98.65 - - brcmfmac43430-sdio.clm_blob_2018-09-11_7.45.98.65 + - brcmfmac43430-sdio.clm_blob_2018-09-11_7.45.98.65 # 14K instead of 4.7K w/ above "os" & "ub" -- name: Symlink /lib/firmware/brcm/brcmfmac43430-sdio.bin.iiab -> {{ rpizerow_rpi3_wifi_firmwares[rpizerow_rpi3_wifi_firmware][0] }} (as rpizerow_rpi3_wifi_firmware is "{{ rpizerow_rpi3_wifi_firmware }}") +- name: Symlink /lib/firmware/cypress/cyfmac43430-sdio.bin.iiab -> {{ rpizerow_rpi3_wifi_firmwares[rpizerow_rpi3_wifi_firmware][0] }} (as rpizerow_rpi3_wifi_firmware is "{{ rpizerow_rpi3_wifi_firmware }}") file: src: "{{ rpizerow_rpi3_wifi_firmwares[rpizerow_rpi3_wifi_firmware][0] }}" - path: /lib/firmware/brcm/brcmfmac43430-sdio.bin.iiab + path: /lib/firmware/cypress/cyfmac43430-sdio.bin.iiab state: link force: yes -- name: Symlink /lib/firmware/brcm/brcmfmac43430-sdio.clm_blob.iiab -> {{ rpizerow_rpi3_wifi_firmwares[rpizerow_rpi3_wifi_firmware][1] }} (as rpizerow_rpi3_wifi_firmware is "{{ rpizerow_rpi3_wifi_firmware }}") +- name: Symlink /lib/firmware/cypress/cyfmac43430-sdio.clm_blob.iiab -> {{ rpizerow_rpi3_wifi_firmwares[rpizerow_rpi3_wifi_firmware][1] }} (as rpizerow_rpi3_wifi_firmware is "{{ rpizerow_rpi3_wifi_firmware }}") file: src: "{{ rpizerow_rpi3_wifi_firmwares[rpizerow_rpi3_wifi_firmware][1] }}" - path: /lib/firmware/brcm/brcmfmac43430-sdio.clm_blob.iiab + path: /lib/firmware/cypress/cyfmac43430-sdio.clm_blob.iiab state: link force: yes @@ -73,7 +81,7 @@ - { src: 'iiab-check-firmware.service', dest: '/etc/systemd/system/', mode: '0644' } - { src: 'iiab-firmware-warn.sh', dest: '/etc/profile.d/', mode: '0644' } -- name: Enable & (Re)Start iiab-check-firmware.service (also runs on each boot) +- name: Enable & (Re)Start iiab-check-firmware.service (also runs on each boot) -- finalizing 2-or-4 symlink chains e.g. /lib/firmware/cypress/X.{bin|blob} -> /lib/firmware/cypress/X.{bin|blob}.iiab -> CHOSEN-FIRMWARE-FILE-OR-LINK systemd: name: iiab-check-firmware.service daemon_reload: yes diff --git a/roles/firmware/tasks/main.yml b/roles/firmware/tasks/main.yml index 3e33890ba..dfd094acb 100644 --- a/roles/firmware/tasks/main.yml +++ b/roles/firmware/tasks/main.yml @@ -3,18 +3,22 @@ # client devices that can access your Raspberry Pi's internal WiFi hotspot. # If IIAB's already installed, you should then run 'cd /opt/iiab/iiab' and -# then 'sudo ./runrole firmware' (do run iiab-check-firmware for more tips!) - -# BACKGROUND AS OF 2022-01-10: -# https://github.com/iiab/iiab/issues/823#issuecomment-662285202 -# https://github.com/iiab/iiab/issues/2853#issuecomment-957836892 -# https://github.com/iiab/iiab/pull/3103 -# https://github.com/RPi-Distro/firmware-nonfree/tree/bullseye/debian/config/brcm80211 (brcm, cypress) -# https://archive.raspberrypi.org/debian/pool/main/f/firmware-nonfree/firmware-brcm80211_20190114-1+rpt11_all.deb from 2021-01-25 -# https://archive.raspberrypi.org/debian/pool/main/f/firmware-nonfree/firmware-brcm80211_20210315-3+rpt4_all.deb from 2021-12-06 +# then 'sudo ./runrole firmware' (DO RUN iiab-check-firmware FOR MORE TIPS!) +# 2018-2023 Background & Progress: +# +# Raspberry Pi 3 used to support 32 WiFi connections but is now limited to [4-10] +# https://github.com/iiab/iiab/issues/823#issuecomment-662285202 +# Opinions about Pi 4B/3B+ WiFi features [practical AP firmware for schools!] +# https://github.com/iiab/iiab/issues/2853#issuecomment-957836892 +# RPi WiFi hotspot firmware reliability fix, incl new/better choices for 3B+ & 4 +# https://github.com/iiab/iiab/pull/3103 +# Set WiFi firmware in /lib/firmware/cypress due to RasPiOS & Ubuntu changes +# https://github.com/iiab/iiab/pull/3482 # RISK: What USB 3.0 stick/drive patterns degrade a Raspberry Pi's 2.4GHz WiFi? -# https://github.com/iiab/iiab/issues/2638 +# https://github.com/iiab/iiab/issues/2638 + +# ► SEE "MONITOR FIRMWARE UPDATES in 3 places especially" in tasks/download.yml ◄ - name: Install firmware (for RPi internal WiFi) include_tasks: install.yml diff --git a/roles/firmware/templates/iiab-check-firmware b/roles/firmware/templates/iiab-check-firmware index b26810440..f10cd752b 100644 --- a/roles/firmware/templates/iiab-check-firmware +++ b/roles/firmware/templates/iiab-check-firmware @@ -1,11 +1,25 @@ #!/bin/bash -# 2021-08-18: bash scripts using default_vars.yml &/or local_vars.yml +# The 1st time /usr/bin/iiab-check-firmware runs (at the end of +# firmware/tasks/install.yml) 2-4 lynchpin top links are put in place, +# finalizing symlink chains like: +# +# /lib/firmware/cypress/X.{bin|blob} -> +# /lib/firmware/cypress/X.{bin|blob}.iiab -> +# CHOSEN-FIRMWARE-FILE-OR-LINK +# +# Also backing up top-of-chain originals (file or link!) by moving these to: +# +# /lib/firmware/cypress/.YYYY-MM-DD-HH:MM:SS +# +# NOTE these are "doubly timestamped" to preserve BOTH last-modif & moving date. + +# 2023-02-25: bash scripts using default_vars.yml &/or local_vars.yml # https://github.com/iiab/iiab-factory/blob/master/iiab # https://github.com/iiab/iiab/blob/master/roles/firmware/templates/iiab-check-firmware#L10-14 # https://github.com/iiab/iiab/blob/master/roles/network/templates/gateway/iiab-gen-iptables#L48-L52 -# https://github.com/iiab/maps/blob/master/osm-source/pages/viewer/scripts/iiab-install-map-region#L25-L34 -# https://github.com/iiab/iiab/blob/master/roles/openvpn/templates/iiab-support READS AND WRITES, INCL NON-BOOLEAN +# https://github.com/iiab/maps/blob/master/osm-source/pages/viewer/scripts/iiab-install-map-region#L23-L39 +# https://github.com/iiab/iiab/blob/master/roles/0-DEPRECATED-ROLES/openvpn/templates/iiab-support READS AND WRITES, INCL NON-BOOLEAN iiab_var_value() { v1=$(grep "^$1:\s" /opt/iiab/iiab/vars/default_vars.yml | tail -1 | sed "s/^$1:\s\+//; s/#.*//; s/\s*$//; s/^\(['\"]\)\(.*\)\1$/\2/") @@ -14,29 +28,29 @@ iiab_var_value() { } link_fw() { - if [[ $(readlink /lib/firmware/brcm/$1) != $1.iiab ]] ; then - echo - mv /lib/firmware/brcm/$1 /lib/firmware/brcm/$1.$(date +%F-%T) - ln -s $1.iiab /lib/firmware/brcm/$1 - echo -e "\e[1mSymlinked /lib/firmware/brcm/$1 -> $1.iiab\e[0m" - touch /tmp/.fw_modified + if [[ $(readlink /lib/firmware/cypress/$1) != $1.iiab ]] ; then + echo + mv /lib/firmware/cypress/$1 /lib/firmware/cypress/$1.$(date +%F-%T) + ln -s $1.iiab /lib/firmware/cypress/$1 + echo -e "\e[1mSymlinked /lib/firmware/cypress/$1 -> $1.iiab\e[0m" + touch /tmp/.fw_modified fi } if [[ $(iiab_var_value rpi3bplus_rpi4_wifi_firmware) != "os" ]] ; then - link_fw brcmfmac43455-sdio.bin - link_fw brcmfmac43455-sdio.clm_blob + link_fw cyfmac43455-sdio.bin + link_fw cyfmac43455-sdio.clm_blob fi if [[ $(iiab_var_value rpizerow_rpi3_wifi_firmware) != "os" ]] ; then - link_fw brcmfmac43430-sdio.bin - link_fw brcmfmac43430-sdio.clm_blob + link_fw cyfmac43430-sdio.bin + link_fw cyfmac43430-sdio.clm_blob fi if [ -f /tmp/.fw_modified ]; then bash /etc/profile.d/iiab-firmware-warn.sh else - echo -e "\n\e[1mWiFi Firmware links in /lib/firmware/brcm appear \e[92mCORRECT\e[0m\e[1m, per iiab/iiab#2853.\e[0m" + echo -e "\n\e[1mWiFi Firmware links in /lib/firmware/cypress appear \e[92mCORRECT\e[0m\e[1m, per iiab/iiab#3482\e[0m" echo echo -e "\e[100;1m(No reboot appears necessary!)\e[0m" echo @@ -46,7 +60,7 @@ else echo -e " cd /opt/iiab/iiab" echo -e " sudo iiab-hotspot-off # NO LONGER NEC? eg to restore 'wifi_up_down: True'" echo -e " sudo ./runrole --reinstall firmware" - echo -e " sudo ./iiab-network # SOMETIMES NECESSARY" + echo -e " sudo iiab-network # SOMETIMES NECESSARY" echo -e " sudo iiab-hotspot-on # NO LONGER NEC? eg to restore 'wifi_up_down: True'" echo -e " sudo reboot\n" #echo diff --git a/roles/firmware/templates/iiab-firmware-warn.sh b/roles/firmware/templates/iiab-firmware-warn.sh index dd2c34dba..f9507496b 100644 --- a/roles/firmware/templates/iiab-firmware-warn.sh +++ b/roles/firmware/templates/iiab-firmware-warn.sh @@ -1,7 +1,7 @@ #!/bin/bash if [ -f /tmp/.fw_modified ]; then - echo -e "\n\e[41;1mWiFi Firmware link(s) modified, per iiab/iiab#2853: PLEASE REBOOT!\e[0m" + echo -e "\n\e[41;1mWiFi Firmware link(s) modified, per iiab/iiab#3482: PLEASE REBOOT!\e[0m" echo echo -e "If you want this warning to stop, reboot to remove /tmp/.fw_modified\n" fi diff --git a/roles/gitea/defaults/main.yml b/roles/gitea/defaults/main.yml index 2a620f8cc..0032f1d3d 100644 --- a/roles/gitea/defaults/main.yml +++ b/roles/gitea/defaults/main.yml @@ -9,7 +9,7 @@ # Info needed to install Gitea: -gitea_version: 1.18 # 2022-01-30: Grabs latest from this MAJOR/MINOR release branch. Rather than exhaustively hard-coding point releases (e.g. 1.14.5) every few weeks. +gitea_version: "1.22" # 2022-01-30: Grabs latest from this MAJOR/MINOR release branch. Rather than exhaustively hard-coding point releases (e.g. 1.14.5) every few weeks. Quotes nec if trailing zero. iset_suffixes: i386: 386 x86_64: amd64 @@ -17,9 +17,9 @@ iset_suffixes: armv6l: arm-6 armv7l: arm-6 # "arm-7" used to work, but no longer since 2019-04-20's Gitea 1.8.0: https://github.com/iiab/iiab/issues/1673 https://github.com/iiab/iiab/pull/1713 -- 2019-07-31: ARM7 support will return at some point, according to: https://github.com/go-gitea/gitea/pull/7037#issuecomment-516735216 (what about ARM8 support for RPi 4?) -gitea_iset_suffix: "{{ iset_suffixes[ansible_architecture] | default('unknown') }}" +gitea_iset_suffix: "{{ iset_suffixes[ansible_machine] | default('unknown') }}" # A bit safer than ansible_architecture (see kiwix/defaults/main.yml) -gitea_download_url: "https://dl.gitea.io/gitea/{{ gitea_version }}/gitea-{{ gitea_version }}-linux-{{ gitea_iset_suffix }}" +gitea_download_url: "https://dl.gitea.com/gitea/{{ gitea_version }}/gitea-{{ gitea_version }}-linux-{{ gitea_iset_suffix }}" gitea_integrity_url: "{{ gitea_download_url }}.asc" gitea_root_directory: "{{ content_base }}/gitea" # /library/gitea diff --git a/roles/gitea/tasks/install.yml b/roles/gitea/tasks/install.yml index 02dfa7cda..eed1559f8 100644 --- a/roles/gitea/tasks/install.yml +++ b/roles/gitea/tasks/install.yml @@ -1,3 +1,8 @@ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + # 1. Prepare to install Gitea: create user and directory structure - name: Shut down existing Gitea instance (if we're reinstalling) @@ -43,10 +48,10 @@ msg: "Could not find a binary for the CPU architecture \"{{ ansible_architecture }}\"" when: gitea_iset_suffix == "unknown" -- name: Download Gitea binary {{ gitea_download_url }} to {{ gitea_install_path }} (0775, ~108 MB, SLOW DOWNLOAD CAN TAKE ~15 MIN) +- name: Download Gitea binary {{ gitea_download_url }} to {{ gitea_install_path }} (0775, ~134 MB, SLOW DOWNLOAD CAN TAKE ~15 MIN) get_url: url: "{{ gitea_download_url }}" - dest: "{{ gitea_install_path }}" # e.g. /library/gitea/bin/gitea-1.16 + dest: "{{ gitea_install_path }}" # e.g. /library/gitea/bin/gitea-1.21 mode: 0775 timeout: "{{ download_timeout }}" @@ -56,9 +61,9 @@ dest: "{{ gitea_checksum_path }}" timeout: "{{ download_timeout }}" -- name: Verify Gitea binary with GPG signature +- name: Verify Gitea binary with GPG signature ("BAD signature" FALSE ALARMS continue as of 2023-07-16, despite their claims at https://docs.gitea.com/installation/install-from-binary#verify-gpg-signature) shell: | - gpg --keyserver pgp.mit.edu --recv {{ gitea_gpg_key }} + gpg --keyserver keys.openpgp.org --recv {{ gitea_gpg_key }} gpg --verify {{ gitea_checksum_path }} {{ gitea_install_path }} ignore_errors: yes @@ -105,6 +110,17 @@ # 5. RECORD Gitea AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'gitea_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: gitea + option: gitea_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'gitea_installed: True'" set_fact: gitea_installed: True diff --git a/roles/gitea/tasks/main.yml b/roles/gitea/tasks/main.yml index 4fbd7359e..335911c96 100644 --- a/roles/gitea/tasks/main.yml +++ b/roles/gitea/tasks/main.yml @@ -27,7 +27,7 @@ - include_tasks: enable-or-disable.yml - - name: Add 'gitea' to list of services at {{ iiab_ini_file }} + - name: Add 'gitea' variable values to {{ iiab_ini_file }} ini_file: path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini section: gitea diff --git a/roles/gitea/templates/app.ini.j2 b/roles/gitea/templates/app.ini.j2 index 00d503fdb..98add8b15 100644 --- a/roles/gitea/templates/app.ini.j2 +++ b/roles/gitea/templates/app.ini.j2 @@ -2,7 +2,8 @@ ; Copy required sections to your own app.ini (default is custom/conf/app.ini) ; and modify as needed. -; see https://docs.gitea.io/en-us/config-cheat-sheet/ for additional documentation. +; see https://docs.gitea.com/administration/config-cheat-sheet for additional documentation. +; https://docs.gitea.com/next/administration/config-cheat-sheet ; App name that shows in every page title APP_NAME = {{ gitea_display_name }} @@ -23,9 +24,11 @@ DEFAULT_PRIVATE = last ; Global limit of repositories per user, applied at creation time. -1 means no limit MAX_CREATION_LIMIT = -1 ; Mirror sync queue length, increase if mirror syncing starts hanging -MIRROR_QUEUE_LENGTH = 1000 +; 2023-07-16 ERROR: MIRROR_QUEUE_LENGTH = 1000 +; `[repository].MIRROR_QUEUE_LENGTH`. Use new options in `[queue.mirror]` ; Patch test queue length, increase if pull request patch testing starts hanging -PULL_REQUEST_QUEUE_LENGTH = 1000 +; 2023-07-16 ERROR: PULL_REQUEST_QUEUE_LENGTH = 1000 +; `[repository].PULL_REQUEST_QUEUE_LENGTH`. Use new options in `[queue.pr_patch_checker]` ; Preferred Licenses to place at the top of the List ; The name here must match the filename in conf/license or custom/conf/license PREFERRED_LICENSES = Apache License 2.0,MIT License @@ -201,13 +204,22 @@ PPROF_DATA_PATH = data/tmp/pprof LANDING_PAGE = home ; Enables git-lfs support. true or false, default is false. LFS_START_SERVER = false -; Where your lfs files reside, default is data/lfs. -LFS_CONTENT_PATH = {{ gitea_lfs_root }} ; LFS authentication secret, change this yourself LFS_JWT_SECRET = ; LFS authentication validity period (in time.Duration), pushes taking longer than this may fail. LFS_HTTP_AUTH_EXPIRY = 20m +; lfs [Large File Storage] storage will override storage +; +[lfs] +;STORAGE_TYPE = local +; +; Where your lfs files reside, default is data/lfs. +PATH = {{ gitea_lfs_root }} +; +; override the minio base path if storage type is minio +;MINIO_BASE_PATH = lfs/ + ; Define allowed algorithms and their minimum key length (use -1 to disable a type) [ssh.minimum_key_sizes] ED25519 = 256 @@ -240,7 +252,8 @@ ISSUE_INDEXER_PATH = indexers/issues.bleve ; repo indexer by default disabled, since it uses a lot of disk space REPO_INDEXER_ENABLED = false REPO_INDEXER_PATH = indexers/repos.bleve -UPDATE_BUFFER_LEN = 20 +; 2023-07-16 ERROR: UPDATE_BUFFER_LEN = 20 +; `[indexer].UPDATE_BUFFER_LEN`. Use new options in `[queue.issue_indexer]` MAX_FILE_SIZE = 1048576 [admin] @@ -360,7 +373,8 @@ PAGING_NUM = 10 [mailer] ENABLED = false ; Buffer length of channel, keep it as it is if you don't know what it is. -SEND_BUFFER_LEN = 100 +; 2023-07-16 ERROR: SEND_BUFFER_LEN = 100 +; `[mailer].SEND_BUFFER_LEN`. Use new options in `[queue.mailer]` ; Name displayed in mail title SUBJECT = %(APP_NAME)s ; Mail server diff --git a/roles/iiab-admin/README.rst b/roles/iiab-admin/README.rst index 5017e4186..2dbadaa62 100644 --- a/roles/iiab-admin/README.rst +++ b/roles/iiab-admin/README.rst @@ -36,7 +36,7 @@ Security #. ``iiab-admin`` (specified by ``admin_console_group`` in `/opt/iiab/iiab/vars/default_vars.yml <../../vars/default_vars.yml>`_ and `/opt/iiab/iiab-admin-console/vars/default_vars.yml `_) #. ``sudo`` * Please read much more about what escalated (root) actions are authorized when you log into IIAB's Admin Console, and how this works: https://github.com/iiab/iiab-admin-console/blob/master/Authentication.md -* If your IIAB includes OpenVPN, ``/root/.ssh/authorized_keys`` should be installed by `roles/openvpn/tasks/install.yml <../openvpn/tasks/install.yml>`_ to facilitate remote community support. Feel free to remove this as mentioned here: https://wiki.iiab.io/go/Security +* If your IIAB includes Tailscale (VPN), ``/root/.ssh/authorized_keys`` should be installed by `roles/tailscale/tasks/install.yml <../tailscale/tasks/install.yml>`_ to facilitate remote community support. Feel free to remove this as mentioned here: https://wiki.iiab.io/go/Security * Auto-checking for the default/published password (as specified by ``iiab_admin_published_pwd`` in `/opt/iiab/iiab/vars/default_vars.yml <../../vars/default_vars.yml>`_) is implemented in `/etc/profile.d `_ (and `/etc/xdg/lxsession/LXDE-pi `_ when it exists, i.e. on Raspberry Pi OS with desktop). Example @@ -56,16 +56,16 @@ Historical Notes Remote Support Tools -------------------- -The `iiab-diagnostics <../../scripts/iiab-diagnostics.README.md>`_ and `OpenVPN `_ options mentioned above can greatly help you empower your community, typically during the implementation phase of your project, even if Linux is new to you. +The `iiab-diagnostics <../../scripts/iiab-diagnostics.README.md>`_ and `Tailscale (VPN) `_ options mentioned above can greatly help you empower your community, typically during the implementation phase of your project, even if Linux is new to you. -Similarly, `access.yml `_ adds a couple text mode tools — extremely helpful over expensive / low-bandwidth connections: +Similarly, `tasks/main.yml `_ adds a couple text mode tools — extremely helpful over expensive / low-bandwidth connections: * `lynx `_ * `screen `_ *More great tools to help you jumpstart community action at a distance:* -* http://FAQ.IIAB.IO > "How can I remotely manage my Internet-in-a-Box?" +* `FAQ.IIAB.IO `_ > "How can I remotely manage my Internet-in-a-Box?" Admin Console ------------- diff --git a/roles/iiab-admin/tasks/main.yml b/roles/iiab-admin/tasks/main.yml index 09a408aa4..fabe0bffe 100644 --- a/roles/iiab-admin/tasks/main.yml +++ b/roles/iiab-admin/tasks/main.yml @@ -2,6 +2,11 @@ # https://github.com/iiab/iiab/blob/master/roles/iiab-admin/README.rst +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: "Install text-mode packages, useful during remote access: lynx, screen" package: name: @@ -35,6 +40,17 @@ # RECORD iiab-admin AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'iiab_admin_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: iiab-admin + option: iiab_admin_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'iiab_admin_installed: True'" set_fact: iiab_admin_installed: True diff --git a/roles/iiab-admin/tasks/pwd-warnings.yml b/roles/iiab-admin/tasks/pwd-warnings.yml index e63c8841b..600a935bb 100644 --- a/roles/iiab-admin/tasks/pwd-warnings.yml +++ b/roles/iiab-admin/tasks/pwd-warnings.yml @@ -2,34 +2,35 @@ # AND roles/network/tasks/netwarn.yml FOR iiab-network -- name: Install /etc/profile.d/sshpwd-profile-iiab.sh from template, to issue warnings (during shell/ssh logins) if iiab-admin password is the default +- name: Install /etc/profile.d/iiab-pwdwarn-profile.sh from template, to issue warnings (during shell/ssh logins) if iiab-admin password is the default template: - src: sshpwd-profile-iiab.sh.j2 - dest: /etc/profile.d/sshpwd-profile-iiab.sh + src: iiab-pwdwarn-profile.sh.j2 + dest: /etc/profile.d/iiab-pwdwarn-profile.sh mode: '0644' -- name: Is /etc/xdg/lxsession/LXDE-pi a directory? +- name: Does directory /home/{{ iiab_admin_user }}/.config/labwc/ exist? stat: - path: /etc/xdg/lxsession/LXDE-pi - register: lx + path: /home/{{ iiab_admin_user }}/.config/labwc/ + register: labwc_dir -- name: "If so, install from template: /etc/xdg/lxsession/LXDE-pi/sshpwd-lxde-iiab.sh" +- name: "If so, install from template: /usr/local/sbin/iiab-pwdwarn-labwc" template: - src: sshpwd-lxde-iiab.sh.j2 - dest: /etc/xdg/lxsession/LXDE-pi/sshpwd-lxde-iiab.sh + src: iiab-pwdwarn-labwc.j2 + dest: /usr/local/sbin/iiab-pwdwarn-labwc mode: '0755' - when: lx.stat.isdir is defined and lx.stat.isdir # and is_raspbian + when: labwc_dir.stat.exists and labwc_dir.stat.isdir -# 2019-03-07: This popup (/etc/xdg/lxsession/LXDE-pi/sshpwd-lxde-iiab.sh) does +# 2019-03-07: This pop-up (/etc/xdg/lxsession/LXDE-pi/sshpwd-lxde-iiab.sh) did # not actually appear when triggered by /etc/xdg/autostart/pprompt-iiab.desktop # (or pprompt.desktop as Raspbian has working since 2018-11-13!) Too bad as it -# would be really nice to standardize this popup across Ubermix & all distros.. +# would be really nice to standardize pop-ups across Ubermix & all distros... # Is this a permissions/security issue presumably? Official autostart spec is: # https://specifications.freedesktop.org/autostart-spec/autostart-spec-latest.html # Raspbian's 2016-2018 evolution here: https://github.com/iiab/iiab/issues/1537 -- name: ...and put a line in /etc/xdg/lxsession/LXDE-pi/autostart to trigger popups +- name: ...and put a line in /home/{{ iiab_admin_user }}/.config/labwc/autostart to trigger iiab-pwdwarn-labwc (& pop-up as nec) lineinfile: - path: /etc/xdg/lxsession/LXDE-pi/autostart - line: "@/etc/xdg/lxsession/LXDE-pi/sshpwd-lxde-iiab.sh" - when: lx.stat.isdir is defined and lx.stat.isdir # and is_raspbian + path: /home/{{ iiab_admin_user }}/.config/labwc/autostart # iiab-admin + create: yes + line: '/usr/local/sbin/iiab-pwdwarn-labwc &' + when: labwc_dir.stat.exists and labwc_dir.stat.isdir diff --git a/roles/iiab-admin/tasks/sudo-prereqs.yml b/roles/iiab-admin/tasks/sudo-prereqs.yml index 1b608fef1..9370666b2 100644 --- a/roles/iiab-admin/tasks/sudo-prereqs.yml +++ b/roles/iiab-admin/tasks/sudo-prereqs.yml @@ -1,6 +1,6 @@ - name: 'Install package: sudo' package: - name: sudo # (1) Should be installed prior to installing IIAB, (2) Can also be installed by roles/1-prep's roles/openvpn/tasks/install.yml, (3) Is definitely installed by 1-prep here, (4) Used to be installed by roles/2-common/tasks/packages.yml (but that's too late!) + name: sudo # (1) Should be installed prior to installing IIAB, (2) Can be installed by 1-prep's roles/tailscale/tasks/install.yml, (3) Can be installed by 1-prep's roles/iiab-admin/tasks/sudo-prereqs.yml here, (4) Used to be installed by roles/2-common/tasks/packages.yml (but that's too late!) - name: Temporarily make file /etc/sudoers editable (0640) file: diff --git a/roles/iiab-admin/templates/sshpwd-lxde-iiab.sh.j2 b/roles/iiab-admin/templates/iiab-pwdwarn-labwc.j2 similarity index 100% rename from roles/iiab-admin/templates/sshpwd-lxde-iiab.sh.j2 rename to roles/iiab-admin/templates/iiab-pwdwarn-labwc.j2 diff --git a/roles/iiab-admin/templates/sshpwd-profile-iiab.sh.j2 b/roles/iiab-admin/templates/iiab-pwdwarn-profile.sh.j2 similarity index 100% rename from roles/iiab-admin/templates/sshpwd-profile-iiab.sh.j2 rename to roles/iiab-admin/templates/iiab-pwdwarn-profile.sh.j2 diff --git a/roles/internetarchive/tasks/install.yml b/roles/internetarchive/tasks/install.yml index 4ed845706..2821a9ffd 100644 --- a/roles/internetarchive/tasks/install.yml +++ b/roles/internetarchive/tasks/install.yml @@ -9,10 +9,10 @@ include_role: name: nodejs -- name: Assert that 10.x <= nodejs_version ({{ nodejs_version }}) <= 18.x +- name: Assert that 10.x <= nodejs_version ({{ nodejs_version }}) <= 22.x assert: - that: nodejs_version is version('10.x', '>=') and nodejs_version is version('18.x', '<=') - fail_msg: "Internet Archive install cannot proceed, as it currently requires Node.js 10.x - 18.x, and your nodejs_version is set to {{ nodejs_version }}. Please check the value of nodejs_version in /opt/iiab/iiab/vars/default_vars.yml and possibly also /etc/iiab/local_vars.yml" + that: nodejs_version is version('10.x', '>=') and nodejs_version is version('22.x', '<=') + fail_msg: "Internet Archive install cannot proceed, as it currently requires Node.js 10.x - 22.x, and your nodejs_version is set to {{ nodejs_version }}. Please check the value of nodejs_version in /opt/iiab/iiab/vars/default_vars.yml and possibly also /etc/iiab/local_vars.yml" quiet: yes - name: "Set 'yarn_install: True' and 'yarn_enabled: True'" @@ -30,6 +30,11 @@ state: present +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + # 2. CREATE 2 DIRS, WIPE /opt/iiab/internetarchive/node_modules & RUN YARN - name: mkdir {{ internetarchive_dir }} @@ -64,6 +69,17 @@ # 4. RECORD Internet Archive AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'internetarchive_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: internetarchive + option: internetarchive_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'internetarchive_installed: True'" set_fact: internetarchive_installed: True diff --git a/roles/jupyterhub/README.md b/roles/jupyterhub/README.md index 583466e04..6a48cacf5 100644 --- a/roles/jupyterhub/README.md +++ b/roles/jupyterhub/README.md @@ -1,5 +1,7 @@ ## JupyterHub programming environment with student Notebooks +### CAUTION: Internet-in-a-Box (IIAB) does not support JupyterHub on 32-bit OS's, where installation will likely fail ([#3639](https://github.com/iiab/iiab/issues/3639)). + #### Secondary schools may want to consider JupyterHub to integrate coding with dynamic interactive graphing — A New Way to Think About Programming — allowing students to integrate science experiment results and program output within their own blog-like "Jupyter Notebooks." * Jupyter Notebooks are widely used in the scientific community: @@ -9,10 +11,11 @@ * [JupyterHub changelog](https://jupyterhub.readthedocs.io/en/stable/changelog.html#changelog) * Students create their own accounts on first use — e.g. at http://box.lan/jupyterhub — just as if they're logging in regularly (unfortunately the login screen doesn't make that clear, but the teacher _does not_ need to be involved!) * A student can then sign in with their username and password, to gain access to their files (Jupyter Notebooks). - * The teacher should set and protect JupyterHub's overall `Admin` password, just in case. As with student accounts, the login screen doesn't make that clear — so just log in with username `Admin` — using any password that you want to become permanent. -* Individual student folders are created in `/var/lib/private/` on the Internet-in-a-Box (IIAB) server: + * The teacher should set and protect JupyterHub's overall `Admin` password, just in case. As with student accounts, the login screen unfortunately doesn't make that clear — so just log in with username `Admin` — using any password that you want to become permanent. +* Individual student folders are created in `/var/lib/private/` on your Internet-in-a-Box (IIAB) server: * A student will only be able to see their own work — they do not have privileges outside of their own folder. * Students may upload Jupyter Notebooks to the IIAB server, and download the current state of their work via a normal browser. + * Linux administrators can read more about JupyterHub's [Local Users](https://github.com/jupyterhub/systemdspawner#local-users) and [c.SystemdSpawner.dynamic_users = True](https://github.com/jupyterhub/systemdspawner#dynamic_users) ### Settings @@ -26,10 +29,11 @@ In some rare circumstances, it may be necessary to restart JupyterHub's systemd sudo systemctl restart jupyterhub ``` -FYI `/opt/iiab/jupyterhub` is a Python 3 virtual environment, that can be activated with the usual formula: +FYI `/opt/iiab/jupyterhub` is a Python 3 virtual environment, that can be activated (and deactivated) with the usual: ``` source /opt/iiab/jupyterhub/bin/activate +(jupyterhub) root@box:~# deactivate ``` Passwords are hashed using 4096 rounds of the latest Blowfish (bcrypt's $2b$ algorithm) and stored in: @@ -42,19 +46,19 @@ Passwords are hashed using 4096 rounds of the latest Blowfish (bcrypt's $2b$ alg Users can change their password by logging in, and then visiting URL: http://box.lan/jupyterhub/auth/change-password -NOTE: This is the only way to change the password for user 'Admin', because Control Panel > Admin (below) does not permit deletion of this account. +NOTE: This is the only way to change the password for user `Admin`, because **File > Hub Control Panel > Admin** (below) does not permit deletion of this account. -### Control Panel > Admin page, to manage other accounts +### File > Hub Control Panel > Admin, to manage accounts The `Admin` user (and any users given `Admin` privilege) can reset user passwords by deleting the user from JupyterHub's **Admin** page (below). This logs the user out, but does not remove any of their data or home directories. The user can then set a new password in the usual way — simply by logging in. Example: -1. As a user with `Admin` privilege, click **Control Panel** in the top right of your JupyterHub: +1. As a user with `Admin` privilege, click **File > Hub Control Panel** in your JupyterHub: - ![Control panel button in notebook, top right](control-panel-button1.png) + ![image](https://user-images.githubusercontent.com/2458907/217602766-ab6a9d3c-9f92-496e-a0e8-6c18a084e960.png) -2. In the Control Panel, open the **Admin** link in the top left: +2. At the top of the Control Panel, click **Admin**: - ![Admin button in control panel, top left](admin-access-button1.png) + ![image](https://user-images.githubusercontent.com/2458907/217602473-f4f9fd40-b4c1-45e1-88c5-54c6d4b604ff.png) This opens up the JupyterHub Admin page, where you can add / delete users, start / stop peoples’ servers and see who is online. @@ -70,6 +74,20 @@ The `Admin` user (and any users given `Admin` privilege) can reset user password _WARNING: If on login users see "500 : Internal Server Error", you may need to remove ALL files of the form_ `/run/jupyter-johndoe-singleuser` +### Logging + +To see JupyterHub's (typically very long!) log, run: + +``` +journalctl -u jupyterhub +``` + +Sometimes other logs might also be available, e.g.: + +``` +journalctl -u jupyter-admin-singleuser +``` + ### PAWS/Jupyter Notebooks for Python Beginners While PAWS is a little bit off topic, if you have an interest in Wikipedia, please do see this 23m 42s video ["Intro to PAWS/Jupyter notebooks for Python beginners"](https://www.youtube.com/watch?v=AUZkioRI-aA&list=PLeoTcBlDanyNQXBqI1rVXUqUTSSiuSIXN&index=8) by Chico Venancio, from 2021-06-01. diff --git a/roles/jupyterhub/tasks/install.yml b/roles/jupyterhub/tasks/install.yml index 68f909ea7..57a503014 100644 --- a/roles/jupyterhub/tasks/install.yml +++ b/roles/jupyterhub/tasks/install.yml @@ -13,10 +13,20 @@ when: nodejs_installed is undefined -- name: "Install package: python3-venv" - package: - name: python3-venv - state: present +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + +# 2025-02-16 +#- name: "Install package: python3-psutil" +# package: +# name: python3-psutil +# state: present + +- name: Remove previous virtual environment {{ jupyterhub_venv }} + file: + path: "{{ jupyterhub_venv }}" + state: absent - name: Make 3 directories to hold JupyterHub config file: @@ -33,17 +43,18 @@ global: yes state: latest -- name: "pip install 3 packages into virtual environment: {{ jupyterhub_venv }} (~271 MB total, after 2 Ansible calls)" +- name: "pip install 3 packages into virtual environment: {{ jupyterhub_venv }} (~316 MB total, after 2 Ansible calls)" pip: name: - pip - wheel - jupyterhub virtualenv: "{{ jupyterhub_venv }}" # /opt/iiab/jupyterhub - virtualenv_site_packages: no - virtualenv_command: python3 -m venv "{{ jupyterhub_venv }}" # 2021-07-29: This works on RasPiOS 10, Debian 11, Ubuntu 20.04 and Mint 20 -- however if you absolutely must use the older Debian 10 -- you can work around errors "can't find Rust compiler" and "This package requires Rust >=1.41.0" if you (1) revert this line to 'virtualenv_command: virtualenv' AND (2) uncomment the line just below + #virtualenv_site_packages: no + virtualenv_command: python3 -m venv "{{ jupyterhub_venv }}" # 2025-02-16 + #virtualenv_command: python3 -m venv --system-site-packages "{{ jupyterhub_venv }}" # 2021-07-29: This works on RasPiOS 10, Debian 11, Ubuntu 20.04 and Mint 20 -- however if you absolutely must use the older Debian 10 -- you can work around errors "can't find Rust compiler" and "This package requires Rust >=1.41.0" if you (1) revert this line to 'virtualenv_command: virtualenv' AND (2) uncomment the line just below #virtualenv_python: python3 # 2021-07-29: Was needed when above line was 'virtualenv_command: virtualenv' (generally for Python 2) - extra_args: "--no-cache-dir" # 2021-11-30, 2022-07-07: The "--pre" flag had earlier been needed, for beta-like pre-releases of JupyterHub 2.0.0 + extra_args: "--no-cache-dir --prefer-binary" # 2021-11-30, 2022-07-07: The "--pre" flag had earlier been needed, for beta-like pre-releases of JupyterHub 2.0.0 # 2022-07-07: Attempting to "pip install" all 7 together (3 above + 4 below) # fails on OS's like 64-bit RasPiOS (but interestingly works on Ubuntu 22.04!) @@ -57,9 +68,10 @@ - jupyterhub-systemdspawner - ipywidgets virtualenv: "{{ jupyterhub_venv }}" - virtualenv_site_packages: no - virtualenv_command: python3 -m venv "{{ jupyterhub_venv }}" - extra_args: "--no-cache-dir" + #virtualenv_site_packages: no + virtualenv_command: python3 -m venv "{{ jupyterhub_venv }}" # 2025-02-16 + #virtualenv_command: python3 -m venv --system-site-packages "{{ jupyterhub_venv }}" + extra_args: "--no-cache-dir --prefer-binary" # 2023-10-01: Lifesaver when recent wheels (e.g. piwheels.org) are inevitably not yet built! SEE #3560 - name: "Install from template: {{ jupyterhub_venv }}/etc/jupyterhub/jupyterhub_config.py" template: @@ -99,6 +111,17 @@ # RECORD JupyterHub AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'jupyterhub_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: jupyterhub + option: jupyterhub_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'jupyterhub_installed: True'" set_fact: jupyterhub_installed: True diff --git a/roles/jupyterhub/templates/jupyterhub_config.py.j2 b/roles/jupyterhub/templates/jupyterhub_config.py.j2 index a3c5b077f..5abc7deb5 100644 --- a/roles/jupyterhub/templates/jupyterhub_config.py.j2 +++ b/roles/jupyterhub/templates/jupyterhub_config.py.j2 @@ -1,5 +1,18 @@ +# 2023-02-10 /opt/iiab/jupyterhub/etc/jupyterhub/jupyterhub_config.py update: +# https://jupyterhub.readthedocs.io/en/stable/getting-started/config-basics.html +# +# 1) To generate this 1500+ line stub, I first ran JupyterHub 3.1.1's: +# /opt/iiab/jupyterhub/bin/jupyterhub --generate-config +# 2) Then I manually inserted 8 of IIAB's 10 legacy custom lines below, from: +# grep ^c /opt/iiab/iiab/roles/jupyterhub/templates/jupyterhub_config.py.j2 +# 3) Finally I added the following line on @jvonau's suggestion: (#3475) +# c.ConfigurableHTTPProxy.pid_file = "/run/jupyterhub-proxy.pid" + + # Configuration file for jupyterhub. +c = get_config() #noqa + #------------------------------------------------------------------------------ # Application(SingletonConfigurable) configuration #------------------------------------------------------------------------------ @@ -18,6 +31,53 @@ # Default: 30 # c.Application.log_level = 30 +## Configure additional log handlers. +# +# The default stderr logs handler is configured by the log_level, log_datefmt +# and log_format settings. +# +# This configuration can be used to configure additional handlers (e.g. to +# output the log to a file) or for finer control over the default handlers. +# +# If provided this should be a logging configuration dictionary, for more +# information see: +# https://docs.python.org/3/library/logging.config.html#logging-config- +# dictschema +# +# This dictionary is merged with the base logging configuration which defines +# the following: +# +# * A logging formatter intended for interactive use called +# ``console``. +# * A logging handler that writes to stderr called +# ``console`` which uses the formatter ``console``. +# * A logger with the name of this application set to ``DEBUG`` +# level. +# +# This example adds a new handler that writes to a file: +# +# .. code-block:: python +# +# c.Application.logging_config = { +# 'handlers': { +# 'file': { +# 'class': 'logging.FileHandler', +# 'level': 'DEBUG', +# 'filename': '', +# } +# }, +# 'loggers': { +# '': { +# 'level': 'DEBUG', +# # NOTE: if you don't list the default "console" +# # handler here then it will be disabled +# 'handlers': ['console', 'file'], +# }, +# } +# } +# Default: {} +# c.Application.logging_config = {} + ## Instead of starting the Application, dump configuration to stdout # Default: False # c.Application.show_config = False @@ -60,11 +120,13 @@ # Default: 30 # c.JupyterHub.activity_resolution = 30 -## Grant admin users permission to access single-user servers. +## DEPRECATED since version 2.0.0. # -# Users should be properly informed if this is enabled. +# The default admin role has full permissions, use custom RBAC scopes instead to +# create restricted administrator roles. +# https://jupyterhub.readthedocs.io/en/stable/rbac/index.html # Default: False -c.JupyterHub.admin_access = True +# c.JupyterHub.admin_access = False ## DEPRECATED since version 0.7.2, use Authenticator.admin_users instead. # Default: set() @@ -78,14 +140,23 @@ c.JupyterHub.admin_access = True # Default: False # c.JupyterHub.answer_yes = False +## The default amount of records returned by a paginated endpoint +# Default: 50 +# c.JupyterHub.api_page_default_limit = 50 + +## The maximum amount of records that can be returned at once +# Default: 200 +# c.JupyterHub.api_page_max_limit = 200 + ## PENDING DEPRECATION: consider using services # -# Dict of token:username to be loaded into the database. +# Dict of token:username to be loaded into the database. # -# Allows ahead-of-time generation of API tokens for use by externally managed -# services, which authenticate as JupyterHub users. +# Allows ahead-of-time generation of API tokens for use by externally managed services, +# which authenticate as JupyterHub users. # -# Consider using services for general services that talk to the JupyterHub API. +# Consider using services for general services that talk to the +# JupyterHub API. # Default: {} # c.JupyterHub.api_tokens = {} @@ -112,49 +183,53 @@ c.JupyterHub.admin_access = True # Currently installed: # - default: jupyterhub.auth.PAMAuthenticator # - dummy: jupyterhub.auth.DummyAuthenticator +# - null: jupyterhub.auth.NullAuthenticator # - pam: jupyterhub.auth.PAMAuthenticator # Default: 'jupyterhub.auth.PAMAuthenticator' +# c.JupyterHub.authenticator_class = 'jupyterhub.auth.PAMAuthenticator' c.JupyterHub.authenticator_class = 'firstuseauthenticator.FirstUseAuthenticator' ## The base URL of the entire application. # -# Add this to the beginning of all JupyterHub URLs. Use base_url to run -# JupyterHub within an existing website. +# Add this to the beginning of all JupyterHub URLs. +# Use base_url to run JupyterHub within an existing website. # -# .. deprecated: 0.9 -# Use JupyterHub.bind_url +# .. deprecated: 0.9 +# Use JupyterHub.bind_url # Default: '/' +# c.JupyterHub.base_url = '/' c.JupyterHub.base_url = '/jupyterhub' ## The public facing URL of the whole JupyterHub application. # -# This is the address on which the proxy will bind. Sets protocol, ip, base_url +# This is the address on which the proxy will bind. +# Sets protocol, ip, base_url # Default: 'http://:8000' # c.JupyterHub.bind_url = 'http://:8000' ## Whether to shutdown the proxy when the Hub shuts down. # -# Disable if you want to be able to teardown the Hub while leaving the proxy -# running. +# Disable if you want to be able to teardown the Hub while leaving the +# proxy running. # -# Only valid if the proxy was starting by the Hub process. +# Only valid if the proxy was starting by the Hub process. # -# If both this and cleanup_servers are False, sending SIGINT to the Hub will -# only shutdown the Hub, leaving everything else running. +# If both this and cleanup_servers are False, sending SIGINT to the Hub will +# only shutdown the Hub, leaving everything else running. # -# The Hub should be able to resume from database state. +# The Hub should be able to resume from database state. # Default: True # c.JupyterHub.cleanup_proxy = True ## Whether to shutdown single-user servers when the Hub shuts down. # -# Disable if you want to be able to teardown the Hub while leaving the single- -# user servers running. +# Disable if you want to be able to teardown the Hub while leaving the +# single-user servers running. # -# If both this and cleanup_proxy are False, sending SIGINT to the Hub will only -# shutdown the Hub, leaving everything else running. +# If both this and cleanup_proxy are False, sending SIGINT to the Hub will +# only shutdown the Hub, leaving everything else running. # -# The Hub should be able to resume from database state. +# The Hub should be able to resume from database state. # Default: True # c.JupyterHub.cleanup_servers = True @@ -184,33 +259,54 @@ c.JupyterHub.base_url = '/jupyterhub' # Default: False # c.JupyterHub.confirm_no_ssl = False -## Number of days for a login cookie to be valid. Default is two weeks. +## Number of days for a login cookie to be valid. +# Default is two weeks. # Default: 14 # c.JupyterHub.cookie_max_age_days = 14 ## The cookie secret to use to encrypt cookies. # -# Loaded from the JPY_COOKIE_SECRET env variable by default. +# Loaded from the JPY_COOKIE_SECRET env variable by default. # -# Should be exactly 256 bits (32 bytes). -# Default: b'' +# Should be exactly 256 bits (32 bytes). +# Default: traitlets.Undefined +# c.JupyterHub.cookie_secret = traitlets.Undefined c.JupyterHub.cookie_secret = b'helloiiabitsrainingb123456789012' ## File in which to store the cookie secret. # Default: 'jupyterhub_cookie_secret' # c.JupyterHub.cookie_secret_file = 'jupyterhub_cookie_secret' -## The location of jupyterhub data files (e.g. /usr/local/share/jupyterhub) -# Default: '/opt/iiab/jupyter/share/jupyterhub' -# c.JupyterHub.data_files_path = '/opt/iiab/jupyter/share/jupyterhub' +## Custom scopes to define. +# +# For use when defining custom roles, +# to grant users granular permissions +# +# All custom scopes must have a description, +# and must start with the prefix `custom:`. +# +# For example:: +# +# custom_scopes = { +# "custom:jupyter_server:read": { +# "description": "read-only access to a single-user server", +# }, +# } +# Default: {} +# c.JupyterHub.custom_scopes = {} -## Include any kwargs to pass to the database connection. See -# sqlalchemy.create_engine for details. +## The location of jupyterhub data files (e.g. /usr/local/share/jupyterhub) +# Default: '/opt/iiab/jupyterhub/share/jupyterhub' +# c.JupyterHub.data_files_path = '/opt/iiab/jupyterhub/share/jupyterhub' + +## Include any kwargs to pass to the database connection. +# See sqlalchemy.create_engine for details. # Default: {} # c.JupyterHub.db_kwargs = {} ## url for the database. e.g. `sqlite:///jupyterhub.sqlite` # Default: 'sqlite:///jupyterhub.sqlite' +# c.JupyterHub.db_url = 'sqlite:///jupyterhub.sqlite' c.JupyterHub.db_url = 'sqlite:///{{ jupyterhub_venv }}/jupyterhub.sqlite' ## log all database transactions. This has A LOT of output @@ -221,8 +317,13 @@ c.JupyterHub.db_url = 'sqlite:///{{ jupyterhub_venv }}/jupyterhub.sqlite' # Default: False # c.JupyterHub.debug_proxy = False -## If named servers are enabled, default name of server to spawn or open, e.g. by -# user-redirect. +## If named servers are enabled, default name of server to spawn or open when no +# server is specified, e.g. by user-redirect. +# +# Note: This has no effect if named servers are not enabled, and does _not_ +# change the existence or behavior of the default server named `''` (the empty +# string). This only affects which named server is launched when no server is +# specified, e.g. by links to `/hub/user-redirect/lab/tree/mynotebook.ipynb`. # Default: '' # c.JupyterHub.default_server_name = '' @@ -245,30 +346,28 @@ c.JupyterHub.db_url = 'sqlite:///{{ jupyterhub_venv }}/jupyterhub.sqlite' # Default: traitlets.Undefined # c.JupyterHub.default_url = traitlets.Undefined -## Dict authority:dict(files). Specify the key, cert, and/or ca file for an -# authority. This is useful for externally managed proxies that wish to use -# internal_ssl. +## Dict authority:dict(files). Specify the key, cert, and/or +# ca file for an authority. This is useful for externally managed +# proxies that wish to use internal_ssl. # -# The files dict has this format (you must specify at least a cert):: +# The files dict has this format (you must specify at least a cert):: # -# { -# 'key': '/path/to/key.key', -# 'cert': '/path/to/cert.crt', -# 'ca': '/path/to/ca.crt' -# } +# { +# 'key': '/path/to/key.key', +# 'cert': '/path/to/cert.crt', +# 'ca': '/path/to/ca.crt' +# } # -# The authorities you can override: 'hub-ca', 'notebooks-ca', 'proxy-api-ca', -# 'proxy-client-ca', and 'services-ca'. +# The authorities you can override: 'hub-ca', 'notebooks-ca', +# 'proxy-api-ca', 'proxy-client-ca', and 'services-ca'. # -# Use with internal_ssl +# Use with internal_ssl # Default: {} # c.JupyterHub.external_ssl_authorities = {} -## Register extra tornado Handlers for jupyterhub. +## DEPRECATED. # -# Should be of the form ``("", Handler)`` -# -# The Hub prefix will be added, so `/my-page` will be served at `/hub/my-page`. +# If you need to register additional HTTP endpoints please use services instead. # Default: [] # c.JupyterHub.extra_handlers = [] @@ -282,6 +381,14 @@ c.JupyterHub.db_url = 'sqlite:///{{ jupyterhub_venv }}/jupyterhub.sqlite' # Default: [] # c.JupyterHub.extra_log_handlers = [] +## Alternate header to use as the Host (e.g., X-Forwarded-Host) +# when determining whether a request is cross-origin +# +# This may be useful when JupyterHub is running behind a proxy that rewrites +# the Host header. +# Default: '' +# c.JupyterHub.forwarded_host_header = '' + ## Generate certs used for internal ssl # Default: False # c.JupyterHub.generate_certs = False @@ -303,19 +410,19 @@ c.JupyterHub.db_url = 'sqlite:///{{ jupyterhub_venv }}/jupyterhub.sqlite' # Default: '' # c.JupyterHub.hub_bind_url = '' -## The ip or hostname for proxies and spawners to use for connecting to the Hub. +## The ip or hostname for proxies and spawners to use +# for connecting to the Hub. # -# Use when the bind address (`hub_ip`) is 0.0.0.0, :: or otherwise different -# from the connect address. +# Use when the bind address (`hub_ip`) is 0.0.0.0, :: or otherwise different +# from the connect address. # -# Default: when `hub_ip` is 0.0.0.0 or ::, use `socket.gethostname()`, otherwise -# use `hub_ip`. +# Default: when `hub_ip` is 0.0.0.0 or ::, use `socket.gethostname()`, +# otherwise use `hub_ip`. # -# Note: Some spawners or proxy implementations might not support hostnames. -# Check your spawner or proxy documentation to see if they have extra -# requirements. +# Note: Some spawners or proxy implementations might not support hostnames. Check your +# spawner or proxy documentation to see if they have extra requirements. # -# .. versionadded:: 0.8 +# .. versionadded:: 0.8 # Default: '' # c.JupyterHub.hub_connect_ip = '' @@ -346,39 +453,59 @@ c.JupyterHub.db_url = 'sqlite:///{{ jupyterhub_venv }}/jupyterhub.sqlite' ## The ip address for the Hub process to *bind* to. # -# By default, the hub listens on localhost only. This address must be accessible -# from the proxy and user servers. You may need to set this to a public ip or '' -# for all interfaces if the proxy or user servers are in containers or on a -# different host. +# By default, the hub listens on localhost only. This address must be accessible from +# the proxy and user servers. You may need to set this to a public ip or '' for all +# interfaces if the proxy or user servers are in containers or on a different host. # -# See `hub_connect_ip` for cases where the bind and connect address should -# differ, or `hub_bind_url` for setting the full bind URL. +# See `hub_connect_ip` for cases where the bind and connect address should differ, +# or `hub_bind_url` for setting the full bind URL. # Default: '127.0.0.1' # c.JupyterHub.hub_ip = '127.0.0.1' ## The internal port for the Hub process. # -# This is the internal port of the hub itself. It should never be accessed -# directly. See JupyterHub.port for the public port to use when accessing -# jupyterhub. It is rare that this port should be set except in cases of port -# conflict. +# This is the internal port of the hub itself. It should never be accessed directly. +# See JupyterHub.port for the public port to use when accessing jupyterhub. +# It is rare that this port should be set except in cases of port conflict. # -# See also `hub_ip` for the ip and `hub_bind_url` for setting the full bind URL. +# See also `hub_ip` for the ip and `hub_bind_url` for setting the full +# bind URL. # Default: 8081 # c.JupyterHub.hub_port = 8081 +## The routing prefix for the Hub itself. +# +# Override to send only a subset of traffic to the Hub. Default is to use the +# Hub as the default route for all requests. +# +# This is necessary for normal jupyterhub operation, as the Hub must receive +# requests for e.g. `/user/:name` when the user's server is not running. +# +# However, some deployments using only the JupyterHub API may want to handle +# these events themselves, in which case they can register their own default +# target with the proxy and set e.g. `hub_routespec = /hub/` to serve only the +# hub's own pages, or even `/hub/api/` for api-only operation. +# +# Note: hub_routespec must include the base_url, if any. +# +# .. versionadded:: 1.4 +# Default: '/' +# c.JupyterHub.hub_routespec = '/' + ## Trigger implicit spawns after this many seconds. # -# When a user visits a URL for a server that's not running, they are shown a -# page indicating that the requested server is not running with a button to -# spawn the server. +# When a user visits a URL for a server that's not running, +# they are shown a page indicating that the requested server +# is not running with a button to spawn the server. # -# Setting this to a positive value will redirect the user after this many -# seconds, effectively clicking this button automatically for the users, -# automatically beginning the spawn process. +# Setting this to a positive value will redirect the user +# after this many seconds, effectively clicking this button +# automatically for the users, +# automatically beginning the spawn process. # -# Warning: this can result in errors and surprising behavior when sharing access -# URLs to actual servers, since the wrong server is likely to be started. +# Warning: this can result in errors and surprising behavior +# when sharing access URLs to actual servers, +# since the wrong server is likely to be started. # Default: 0 # c.JupyterHub.implicit_spawn_seconds = 0 @@ -398,29 +525,30 @@ c.JupyterHub.db_url = 'sqlite:///{{ jupyterhub_venv }}/jupyterhub.sqlite' # Default: 10 # c.JupyterHub.init_spawners_timeout = 10 -## The location to store certificates automatically created by JupyterHub. +## The location to store certificates automatically created by +# JupyterHub. # -# Use with internal_ssl +# Use with internal_ssl # Default: 'internal-ssl' # c.JupyterHub.internal_certs_location = 'internal-ssl' ## Enable SSL for all internal communication # -# This enables end-to-end encryption between all JupyterHub components. -# JupyterHub will automatically create the necessary certificate authority and -# sign notebook certificates as they're created. +# This enables end-to-end encryption between all JupyterHub components. +# JupyterHub will automatically create the necessary certificate +# authority and sign notebook certificates as they're created. # Default: False # c.JupyterHub.internal_ssl = False -## The public facing ip of the whole JupyterHub application (specifically -# referred to as the proxy). +## The public facing ip of the whole JupyterHub application +# (specifically referred to as the proxy). # -# This is the address on which the proxy will listen. The default is to listen -# on all interfaces. This is the only address through which JupyterHub should be -# accessed by users. +# This is the address on which the proxy will listen. The default is to +# listen on all interfaces. This is the only address through which JupyterHub +# should be accessed by users. # -# .. deprecated: 0.9 -# Use JupyterHub.bind_url +# .. deprecated: 0.9 +# Use JupyterHub.bind_url # Default: '' # c.JupyterHub.ip = '' @@ -434,14 +562,36 @@ c.JupyterHub.db_url = 'sqlite:///{{ jupyterhub_venv }}/jupyterhub.sqlite' ## Dict of 'group': ['usernames'] to load at startup. # -# This strictly *adds* groups and users to groups. +# This strictly *adds* groups and users to groups. # -# Loading one set of groups, then starting JupyterHub again with a different set -# will not remove users or groups from previous launches. That must be done -# through the API. +# Loading one set of groups, then starting JupyterHub again with a different +# set will not remove users or groups from previous launches. +# That must be done through the API. # Default: {} # c.JupyterHub.load_groups = {} +## List of predefined role dictionaries to load at startup. +# +# For instance:: +# +# load_roles = [ +# { +# 'name': 'teacher', +# 'description': 'Access to users' information and group membership', +# 'scopes': ['users', 'groups'], +# 'users': ['cyclops', 'gandalf'], +# 'services': [], +# 'groups': [] +# } +# ] +# +# All keys apart from 'name' are optional. +# See all the available scopes in the JupyterHub REST API documentation. +# +# Default roles are defined in roles.py. +# Default: [] +# c.JupyterHub.load_roles = [] + ## The date format used by logging formatters for %(asctime)s # See also: Application.log_datefmt # c.JupyterHub.log_datefmt = '%Y-%m-%d %H:%M:%S' @@ -454,6 +604,10 @@ c.JupyterHub.db_url = 'sqlite:///{{ jupyterhub_venv }}/jupyterhub.sqlite' # See also: Application.log_level # c.JupyterHub.log_level = 30 +## +# See also: Application.logging_config +# c.JupyterHub.logging_config = {} + ## Specify path to a logo image to override the Jupyter logo in the banner. # Default: '' # c.JupyterHub.logo_file = '' @@ -464,20 +618,62 @@ c.JupyterHub.db_url = 'sqlite:///{{ jupyterhub_venv }}/jupyterhub.sqlite' # Setting this can limit the total resources a user can consume. # # If set to 0, no limit is enforced. +# +# Can be an integer or a callable/awaitable based on the handler object: +# +# :: +# +# def named_server_limit_per_user_fn(handler): +# user = handler.current_user +# if user and user.admin: +# return 0 +# return 5 +# +# c.JupyterHub.named_server_limit_per_user = named_server_limit_per_user_fn # Default: 0 # c.JupyterHub.named_server_limit_per_user = 0 -## File to write PID Useful for daemonizing JupyterHub. +## Expiry (in seconds) of OAuth access tokens. +# +# The default is to expire when the cookie storing them expires, +# according to `cookie_max_age_days` config. +# +# These are the tokens stored in cookies when you visit +# a single-user server or service. +# When they expire, you must re-authenticate with the Hub, +# even if your Hub authentication is still valid. +# If your Hub authentication is valid, +# logging in may be a transparent redirect as you refresh the page. +# +# This does not affect JupyterHub API tokens in general, +# which do not expire by default. +# Only tokens issued during the oauth flow +# accessing services and single-user servers are affected. +# +# .. versionadded:: 1.4 +# OAuth token expires_in was not previously configurable. +# .. versionchanged:: 1.4 +# Default now uses cookie_max_age_days so that oauth tokens +# which are generally stored in cookies, +# expire when the cookies storing them expire. +# Previously, it was one hour. +# Default: 0 +# c.JupyterHub.oauth_token_expires_in = 0 + +## File to write PID +# Useful for daemonizing JupyterHub. # Default: '' # c.JupyterHub.pid_file = '' +c.ConfigurableHTTPProxy.pid_file = "/run/jupyterhub-proxy.pid" ## The public facing port of the proxy. # -# This is the port on which the proxy will listen. This is the only port through -# which JupyterHub should be accessed by users. +# This is the port on which the proxy will listen. +# This is the only port through which JupyterHub +# should be accessed by users. # -# .. deprecated: 0.9 -# Use JupyterHub.bind_url +# .. deprecated: 0.9 +# Use JupyterHub.bind_url # Default: 8000 # c.JupyterHub.port = 8000 @@ -493,9 +689,9 @@ c.JupyterHub.db_url = 'sqlite:///{{ jupyterhub_venv }}/jupyterhub.sqlite' # Default: '' # c.JupyterHub.proxy_auth_token = '' -## Interval (in seconds) at which to check if the proxy is running. -# Default: 30 -# c.JupyterHub.proxy_check_interval = 30 +## DEPRECATED since version 0.8: Use ConfigurableHTTPProxy.check_running_interval +# Default: 5 +# c.JupyterHub.proxy_check_interval = 5 ## The class to use for configuring the JupyterHub proxy. # @@ -517,9 +713,9 @@ c.JupyterHub.db_url = 'sqlite:///{{ jupyterhub_venv }}/jupyterhub.sqlite' ## Recreate all certificates used within JupyterHub on restart. # -# Note: enabling this feature requires restarting all notebook servers. +# Note: enabling this feature requires restarting all notebook servers. # -# Use with internal_ssl +# Use with internal_ssl # Default: False # c.JupyterHub.recreate_internal_certs = False @@ -538,29 +734,29 @@ c.JupyterHub.db_url = 'sqlite:///{{ jupyterhub_venv }}/jupyterhub.sqlite' ## Dict of token:servicename to be loaded into the database. # -# Allows ahead-of-time generation of API tokens for use by externally managed -# services. +# Allows ahead-of-time generation of API tokens for use by externally +# managed services. # Default: {} # c.JupyterHub.service_tokens = {} ## List of service specification dictionaries. # -# A service +# A service # -# For instance:: +# For instance:: # -# services = [ -# { -# 'name': 'cull_idle', -# 'command': ['/path/to/cull_idle_servers.py'], -# }, -# { -# 'name': 'formgrader', -# 'url': 'http://127.0.0.1:1234', -# 'api_token': 'super-secret', -# 'environment': -# } -# ] +# services = [ +# { +# 'name': 'cull_idle', +# 'command': ['/path/to/cull_idle_servers.py'], +# }, +# { +# 'name': 'formgrader', +# 'url': 'http://127.0.0.1:1234', +# 'api_token': 'super-secret', +# 'environment': +# } +# ] # Default: [] # c.JupyterHub.services = [] @@ -585,21 +781,25 @@ c.JupyterHub.db_url = 'sqlite:///{{ jupyterhub_venv }}/jupyterhub.sqlite' # e.g. `c.JupyterHub.spawner_class = 'localprocess'` # # Currently installed: +# - systemd: systemdspawner.SystemdSpawner +# - systemdspawner: systemdspawner.SystemdSpawner # - default: jupyterhub.spawner.LocalProcessSpawner # - localprocess: jupyterhub.spawner.LocalProcessSpawner # - simple: jupyterhub.spawner.SimpleLocalProcessSpawner # Default: 'jupyterhub.spawner.LocalProcessSpawner' +# c.JupyterHub.spawner_class = 'jupyterhub.spawner.LocalProcessSpawner' c.JupyterHub.spawner_class = 'systemdspawner.SystemdSpawner' +c.SystemdSpawner.dynamic_users = True ## Path to SSL certificate file for the public facing interface of the proxy # -# When setting this, you should also set ssl_key +# When setting this, you should also set ssl_key # Default: '' # c.JupyterHub.ssl_cert = '' ## Path to SSL key file for the public facing interface of the proxy # -# When setting this, you should also set ssl_cert +# When setting this, you should also set ssl_cert # Default: '' # c.JupyterHub.ssl_key = '' @@ -618,17 +818,18 @@ c.JupyterHub.spawner_class = 'systemdspawner.SystemdSpawner' ## Run single-user servers on subdomains of this host. # -# This should be the full `https://hub.domain.tld[:port]`. +# This should be the full `https://hub.domain.tld[:port]`. # -# Provides additional cross-site protections for javascript served by single- -# user servers. +# Provides additional cross-site protections for javascript served by +# single-user servers. # -# Requires `.hub.domain.tld` to resolve to the same host as +# Requires `.hub.domain.tld` to resolve to the same host as # `hub.domain.tld`. # -# In general, this is most easily achieved with wildcard DNS. +# In general, this is most easily achieved with wildcard DNS. # -# When using SSL (i.e. always) this also requires a wildcard SSL certificate. +# When using SSL (i.e. always) this also requires a wildcard SSL +# certificate. # Default: '' # c.JupyterHub.subdomain_host = '' @@ -644,54 +845,69 @@ c.JupyterHub.spawner_class = 'systemdspawner.SystemdSpawner' # Default: {} # c.JupyterHub.tornado_settings = {} -## Trust user-provided tokens (via JupyterHub.service_tokens) to have good -# entropy. +## Trust user-provided tokens (via JupyterHub.service_tokens) +# to have good entropy. # -# If you are not inserting additional tokens via configuration file, this flag -# has no effect. +# If you are not inserting additional tokens via configuration file, +# this flag has no effect. # -# In JupyterHub 0.8, internally generated tokens do not pass through additional -# hashing because the hashing is costly and does not increase the entropy of -# already-good UUIDs. +# In JupyterHub 0.8, internally generated tokens do not +# pass through additional hashing because the hashing is costly +# and does not increase the entropy of already-good UUIDs. # -# User-provided tokens, on the other hand, are not trusted to have good entropy -# by default, and are passed through many rounds of hashing to stretch the -# entropy of the key (i.e. user-provided tokens are treated as passwords instead -# of random keys). These keys are more costly to check. +# User-provided tokens, on the other hand, are not trusted to have good entropy by default, +# and are passed through many rounds of hashing to stretch the entropy of the key +# (i.e. user-provided tokens are treated as passwords instead of random keys). +# These keys are more costly to check. # -# If your inserted tokens are generated by a good-quality mechanism, e.g. -# `openssl rand -hex 32`, then you can set this flag to True to reduce the cost -# of checking authentication tokens. +# If your inserted tokens are generated by a good-quality mechanism, +# e.g. `openssl rand -hex 32`, then you can set this flag to True +# to reduce the cost of checking authentication tokens. # Default: False # c.JupyterHub.trust_user_provided_tokens = False ## Names to include in the subject alternative name. # -# These names will be used for server name verification. This is useful if -# JupyterHub is being run behind a reverse proxy or services using ssl are on -# different hosts. +# These names will be used for server name verification. This is useful +# if JupyterHub is being run behind a reverse proxy or services using ssl +# are on different hosts. # -# Use with internal_ssl +# Use with internal_ssl # Default: [] # c.JupyterHub.trusted_alt_names = [] ## Downstream proxy IP addresses to trust. # -# This sets the list of IP addresses that are trusted and skipped when -# processing the `X-Forwarded-For` header. For example, if an external proxy is -# used for TLS termination, its IP address should be added to this list to -# ensure the correct client IP addresses are recorded in the logs instead of the -# proxy server's IP address. +# This sets the list of IP addresses that are trusted and skipped when processing +# the `X-Forwarded-For` header. For example, if an external proxy is used for TLS +# termination, its IP address should be added to this list to ensure the correct +# client IP addresses are recorded in the logs instead of the proxy server's IP +# address. # Default: [] # c.JupyterHub.trusted_downstream_ips = [] ## Upgrade the database automatically on start. # -# Only safe if database is regularly backed up. Only SQLite databases will be -# backed up to a local file automatically. +# Only safe if database is regularly backed up. +# Only SQLite databases will be backed up to a local file automatically. # Default: False # c.JupyterHub.upgrade_db = False +## Return 503 rather than 424 when request comes in for a non-running server. +# +# Prior to JupyterHub 2.0, we returned a 503 when any request came in for a user +# server that was currently not running. By default, JupyterHub 2.0 will return +# a 424 - this makes operational metric dashboards more useful. +# +# JupyterLab < 3.2 expected the 503 to know if the user server is no longer +# running, and prompted the user to start their server. Set this config to true +# to retain the old behavior, so JupyterLab < 3.2 can continue to show the +# appropriate UI when the user server is stopped. +# +# This option will be removed in a future release. +# Default: False +# c.JupyterHub.use_legacy_stopped_server_status_code = False + ## Callable to affect behavior of /user-redirect/ # # Receives 4 parameters: 1. path - URL path that was provided after /user- @@ -709,13 +925,17 @@ c.JupyterHub.spawner_class = 'systemdspawner.SystemdSpawner' #------------------------------------------------------------------------------ ## Base class for spawning single-user notebook servers. # -# Subclass this, and override the following methods: +# Subclass this, and override the following methods: # -# - load_state - get_state - start - stop - poll +# - load_state +# - get_state +# - start +# - stop +# - poll # -# As JupyterHub supports multiple users, an instance of the Spawner subclass is -# created for each user. If there are 20 JupyterHub users, there will be 20 -# instances of the subclass. +# As JupyterHub supports multiple users, an instance of the Spawner subclass +# is created for each user. If there are 20 JupyterHub users, there will be 20 +# instances of the subclass. ## Extra arguments to be passed to the single-user server. # @@ -862,12 +1082,32 @@ c.JupyterHub.spawner_class = 'systemdspawner.SystemdSpawner' # Default: 30 # c.Spawner.http_timeout = 30 +## The URL the single-user server should connect to the Hub. +# +# If the Hub URL set in your JupyterHub config is not reachable from spawned +# notebooks, you can set differnt URL by this config. +# +# Is None if you don't need to change the URL. +# Default: None +# c.Spawner.hub_connect_url = None + ## The IP address (or hostname) the single-user server should listen on. # +# Usually either '127.0.0.1' (default) or '0.0.0.0'. +# # The JupyterHub proxy implementation should be able to send packets to this # interface. -# Default: '' -# c.Spawner.ip = '' +# +# Subclasses which launch remotely or in containers should override the default +# to '0.0.0.0'. +# +# .. versionchanged:: 2.0 +# Default changed to '127.0.0.1', from ''. +# In most cases, this does not result in a change in behavior, +# as '' was interpreted as 'unspecified', +# which used the subprocesses' own default, itself usually '127.0.0.1'. +# Default: '127.0.0.1' +# c.Spawner.ip = '127.0.0.1' ## Minimum number of bytes a single-user notebook server is guaranteed to have # available. @@ -918,6 +1158,35 @@ c.JupyterHub.spawner_class = 'systemdspawner.SystemdSpawner' # Default: '' # c.Spawner.notebook_dir = '' +## Allowed scopes for oauth tokens issued by this server's oauth client. +# +# This sets the maximum and default scopes +# assigned to oauth tokens issued by a single-user server's +# oauth client (i.e. tokens stored in browsers after authenticating with the server), +# defining what actions the server can take on behalf of logged-in users. +# +# Default is an empty list, meaning minimal permissions to identify users, +# no actions can be taken on their behalf. +# +# If callable, will be called with the Spawner as a single argument. +# Callables may be async. +# Default: traitlets.Undefined +# c.Spawner.oauth_client_allowed_scopes = traitlets.Undefined + +## Allowed roles for oauth tokens. +# +# Deprecated in 3.0: use oauth_client_allowed_scopes +# +# This sets the maximum and default roles +# assigned to oauth tokens issued by a single-user server's +# oauth client (i.e. tokens stored in browsers after authenticating with the server), +# defining what actions the server can take on behalf of logged-in users. +# +# Default is an empty list, meaning minimal permissions to identify users, +# no actions can be taken on their behalf. +# Default: traitlets.Undefined +# c.Spawner.oauth_roles = traitlets.Undefined + ## An HTML form for options a user can specify on launching their server. # # The surrounding `
` element and the submit button are already provided. @@ -1021,8 +1290,8 @@ c.JupyterHub.spawner_class = 'systemdspawner.SystemdSpawner' ## List of SSL alt names # -# May be set in config if all spawners should have the same value(s), or set at -# runtime by Spawner that know their names. +# May be set in config if all spawners should have the same value(s), +# or set at runtime by Spawner that know their names. # Default: [] # c.Spawner.ssl_alt_names = [] @@ -1046,6 +1315,9 @@ c.JupyterHub.spawner_class = 'systemdspawner.SystemdSpawner' ## Set of users that will have admin rights on this JupyterHub. # +# Note: As of JupyterHub 2.0, full admin rights should not be required, and more +# precise permissions can be managed via roles. +# # Admin users have extra privileges: # - Use the admin panel to see list of users logged in # - Add / remove users in some authenticators @@ -1057,6 +1329,7 @@ c.JupyterHub.spawner_class = 'systemdspawner.SystemdSpawner' # # Defaults to an empty set, in which case no user has admin access. # Default: set() +# c.Authenticator.admin_users = set() c.Authenticator.admin_users = set(['admin']) c.Authenticator.dbm_path = "{{ jupyterhub_venv }}/etc/passwords.dbm" @@ -1064,7 +1337,8 @@ c.Authenticator.dbm_path = "{{ jupyterhub_venv }}/etc/passwords.dbm" # # Use this with supported authenticators to restrict which users can log in. # This is an additional list that further restricts users, beyond whatever -# restrictions the authenticator has in place. +# restrictions the authenticator has in place. Any user in this list is granted +# the 'user' role on hub startup. # # If empty, does not perform any additional restriction. # @@ -1073,28 +1347,43 @@ c.Authenticator.dbm_path = "{{ jupyterhub_venv }}/etc/passwords.dbm" # Default: set() # c.Authenticator.allowed_users = set() -## The max age (in seconds) of authentication info before forcing a refresh of -# user auth info. +## The max age (in seconds) of authentication info +# before forcing a refresh of user auth info. # -# Refreshing auth info allows, e.g. requesting/re-validating auth tokens. +# Refreshing auth info allows, e.g. requesting/re-validating auth +# tokens. # -# See :meth:`.refresh_user` for what happens when user auth info is refreshed -# (nothing by default). +# See :meth:`.refresh_user` for what happens when user auth info is refreshed +# (nothing by default). # Default: 300 # c.Authenticator.auth_refresh_age = 300 ## Automatically begin the login process # -# rather than starting with a "Login with..." link at `/hub/login` +# rather than starting with a "Login with..." link at `/hub/login` # -# To work, `.login_url()` must give a URL other than the default `/hub/login`, -# such as an oauth handler or another automatic login handler, registered with -# `.get_handlers()`. +# To work, `.login_url()` must give a URL other than the default `/hub/login`, +# such as an oauth handler or another automatic login handler, +# registered with `.get_handlers()`. # -# .. versionadded:: 0.8 +# .. versionadded:: 0.8 # Default: False # c.Authenticator.auto_login = False +## Automatically begin login process for OAuth2 authorization requests +# +# When another application is using JupyterHub as OAuth2 provider, it sends +# users to `/hub/api/oauth2/authorize`. If the user isn't logged in already, and +# auto_login is not set, the user will be dumped on the hub's home page, without +# any context on what to do next. +# +# Setting this to true will automatically redirect users to login if they aren't +# logged in *only* on the `/hub/api/oauth2/authorize` endpoint. +# +# .. versionadded:: 1.5 +# Default: False +# c.Authenticator.auto_login_oauth2_authorize = False + ## Set of usernames that are not allowed to log in. # # Use this with supported authenticators to restrict which users can not log in. @@ -1112,36 +1401,48 @@ c.Authenticator.dbm_path = "{{ jupyterhub_venv }}/etc/passwords.dbm" ## Delete any users from the database that do not pass validation # -# When JupyterHub starts, `.add_user` will be called on each user in the -# database to verify that all users are still valid. +# When JupyterHub starts, `.add_user` will be called +# on each user in the database to verify that all users are still valid. # -# If `delete_invalid_users` is True, any users that do not pass validation will -# be deleted from the database. Use this if users might be deleted from an -# external system, such as local user accounts. +# If `delete_invalid_users` is True, +# any users that do not pass validation will be deleted from the database. +# Use this if users might be deleted from an external system, +# such as local user accounts. # -# If False (default), invalid users remain in the Hub's database and a warning -# will be issued. This is the default to avoid data loss due to config changes. +# If False (default), invalid users remain in the Hub's database +# and a warning will be issued. +# This is the default to avoid data loss due to config changes. # Default: False # c.Authenticator.delete_invalid_users = False ## Enable persisting auth_state (if available). # -# auth_state will be encrypted and stored in the Hub's database. This can -# include things like authentication tokens, etc. to be passed to Spawners as -# environment variables. +# auth_state will be encrypted and stored in the Hub's database. +# This can include things like authentication tokens, etc. +# to be passed to Spawners as environment variables. # -# Encrypting auth_state requires the cryptography package. +# Encrypting auth_state requires the cryptography package. # -# Additionally, the JUPYTERHUB_CRYPT_KEY environment variable must contain one -# (or more, separated by ;) 32B encryption keys. These can be either base64 or -# hex-encoded. +# Additionally, the JUPYTERHUB_CRYPT_KEY environment variable must +# contain one (or more, separated by ;) 32B encryption keys. +# These can be either base64 or hex-encoded. # -# If encryption is unavailable, auth_state cannot be persisted. +# If encryption is unavailable, auth_state cannot be persisted. # -# New in JupyterHub 0.8 +# New in JupyterHub 0.8 # Default: False # c.Authenticator.enable_auth_state = False +## Let authenticator manage user groups +# +# If True, Authenticator.authenticate and/or .refresh_user +# may return a list of group names in the 'groups' field, +# which will be assigned to the user. +# +# All group-assignment APIs are disabled if this is True. +# Default: False +# c.Authenticator.manage_groups = False + ## An optional hook function that you can implement to do some bootstrapping work # during authentication. For example, loading user account details from an # external system. @@ -1176,20 +1477,20 @@ c.Authenticator.dbm_path = "{{ jupyterhub_venv }}/etc/passwords.dbm" ## Force refresh of auth prior to spawn. # -# This forces :meth:`.refresh_user` to be called prior to launching a server, to -# ensure that auth state is up-to-date. +# This forces :meth:`.refresh_user` to be called prior to launching +# a server, to ensure that auth state is up-to-date. # -# This can be important when e.g. auth tokens that may have expired are passed -# to the spawner via environment variables from auth_state. +# This can be important when e.g. auth tokens that may have expired +# are passed to the spawner via environment variables from auth_state. # -# If refresh_user cannot refresh the user auth data, launch will fail until the -# user logs in again. +# If refresh_user cannot refresh the user auth data, +# launch will fail until the user logs in again. # Default: False # c.Authenticator.refresh_pre_spawn = False ## Dictionary mapping authenticator usernames to JupyterHub users. # -# Primarily used to normalize OAuth user names to local users. +# Primarily used to normalize OAuth user names to local users. # Default: {} # c.Authenticator.username_map = {} @@ -1211,29 +1512,11 @@ c.Authenticator.dbm_path = "{{ jupyterhub_venv }}/etc/passwords.dbm" #------------------------------------------------------------------------------ ## Encapsulate encryption configuration # -# Use via the encryption_config singleton below. +# Use via the encryption_config singleton below. # Default: [] # c.CryptKeeper.keys = [] ## The number of threads to allocate for encryption -# Default: 4 -# c.CryptKeeper.n_threads = 4 - -#------------------------------------------------------------------------------ -# Pagination(Configurable) configuration -#------------------------------------------------------------------------------ -## Default number of entries per page for paginated results. -# Default: 100 -# c.Pagination.default_per_page = 100 - -## Maximum number of entries per page for paginated results. -# Default: 250 -# c.Pagination.max_per_page = 250 - -#------------------------------------------------------------------------------ -# Systemdspawner config -#------------------------------------------------------------------------------ -c.SystemdSpawner.dynamic_users = True -c.SystemdSpawner.user_workingdir = '/opt/iiab/notebooks/{USERNAME}' - +# Default: 2 +# c.CryptKeeper.n_threads = 2 diff --git a/roles/kalite/tasks/install.yml b/roles/kalite/tasks/install.yml index 6f359395d..5738c7301 100644 --- a/roles/kalite/tasks/install.yml +++ b/roles/kalite/tasks/install.yml @@ -1,3 +1,8 @@ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: Download {{ kalite_requirements }} to {{ pip_packages_dir }}/kalite.txt get_url: url: "{{ kalite_requirements }}" @@ -10,36 +15,46 @@ # ignore_errors: yes # when: is_raspbian -- name: 'Install packages: python2, python-setuptools, virtualenv (for Python 2)' +- name: 'Install packages: python2, python-setuptools, virtualenv (for Python 2) -- if Ubuntu 22.04 / Mint 21' package: name: - python2 - python-setuptools # Provides setuptools-44 on recent OS's (last version compatible with python2) - - virtualenv # For Ansible module 'pip' when used with 'virtualenv_command: /usr/bin/virtualenv' and 'virtualenv_python: python2.7' -- compare package 'python3-venv' used by roles {calibre-web, jupyterhub, lokole} + - virtualenv # Drags in 'python3-virtualenv' which in turn drags in 'python3-pip' -- for Ansible module 'pip' when used with 'virtualenv_command: /usr/bin/virtualenv' and 'virtualenv_python: python2.7' -- compare package 'python3-venv' used by roles {calibre-web, jupyterhub, lokole} state: present - #when: not (is_debian_9 or is_debian_10 or is_ubuntu_16 or is_ubuntu_17 or is_ubuntu_18 or is_ubuntu_19) - # 2020-03-31: Testing for {is_raspbian_9, is_raspbian_10} is not currently nec, as testing for {is_debian_9, is_debian_10} covers that already. + when: is_ubuntu_2204 # Also covers is_linuxmint_21 -- name: Use pip to pin setuptools to 44 in {{ kalite_venv }} # WAS: if Raspbian/Debian > 10 or Ubuntu > 19 +- name: Run scripts/install_python2.sh to install python2 and virtualenv -- if Debian 12 or RasPiOS 12 + command: "{{ iiab_dir }}/scripts/install_python2.sh" + when: is_debian_12 # Also covers is_raspbian_12 + +- name: Use pip to pin setuptools to 44 in {{ kalite_venv }} -- if Ubuntu 22.04 / Mint 21, Ubuntu 23.10, Debian 12 or RasPiOS 12 pip: name: setuptools==44 virtualenv: "{{ kalite_venv }}" # /usr/local/kalite/venv virtualenv_site_packages: no - virtualenv_command: /usr/bin/virtualenv + virtualenv_command: virtualenv # Traditionally /usr/bin/virtual/env -- but install_python2.sh (for Ubuntu 23.10+) sets up /usr/local/bin/virtualenv virtualenv_python: python2.7 extra_args: "--no-use-pep517 --no-cache-dir --no-python-version-warning" - #when: not (is_debian_9 or is_debian_10 or is_ubuntu_16 or is_ubuntu_17 or is_ubuntu_18 or is_ubuntu_19) - # long form of (is_debian_11+ or is_ubuntu_20+) + when: is_ubuntu_2204 or is_ubuntu_2310 or is_debian_12 # Also covers is_linuxmint_21 and is_raspbian_12 -- name: Use pip to install ka-lite-static to {{ kalite_venv }} +- name: Use pip to install ka-lite-static to {{ kalite_venv }} -- if Ubuntu 22.04 / Mint 21, Ubuntu 23.10, Debian 12 or RasPiOS 12 pip: name: ka-lite-static version: "{{ kalite_version }}" virtualenv: "{{ kalite_venv }}" virtualenv_site_packages: no - virtualenv_command: /usr/bin/virtualenv + virtualenv_command: virtualenv virtualenv_python: python2.7 extra_args: "--no-cache-dir" + when: is_ubuntu_2204 or is_ubuntu_2310 or is_debian_12 # Also covers is_linuxmint_21 and is_raspbian_12 + +# 2024-04-30: Sadly no longer works with Ubuntu 24.04 LTS final release (#3731). +# So roles/kalite is OS-restricted during initial install, SEE: roles/7-edu-apps/tasks/main.yml +# CLARIF: If install_python2_kalite-venv_u2404.sh proves no longer useful, it will deprecated in coming months. +- name: Run scripts/install_python2_kalite-venv_u2404.sh -- if Ubuntu 24.04+ or Mint 22 + command: bash "{{ iiab_dir }}/scripts/install_python2_kalite-venv_u2404.sh" + when: is_ubuntu and not is_linuxmint and os_ver is version('ubuntu-2404', '>=') or is_linuxmint_22 - name: "Install from templates: venv wrapper /usr/bin/kalite, unit file /etc/systemd/system/kalite-serve.service" template: @@ -50,30 +65,11 @@ - { src: 'kalite.sh.j2', dest: '/usr/bin/kalite', mode: '0755' } - { src: 'kalite-serve.service.j2', dest: '/etc/systemd/system/kalite-serve.service', mode: '0644' } -# Useless stanza, for 2 reasons: (1) http://box/kalite was never made to work -# (2) /etc/apache2/sites-available does not exist on many IIAB's w/o Apache -# - name: "Install from template: /etc/{{ apache_conf_dir }}/kalite.conf (useless, as http://box/kalite was never made to work)" -# template: -# src: kalite.conf -# dest: "/etc/{{ apache_conf_dir }}" # apache2/sites-available on debuntu -# when: apache_installed is defined - - name: Fix KA Lite bug in regex parsing ifconfig output (ifcfg/parser.py) for @m-anish's network names that contain dashes # WAS: if Raspbian/Debian > 10 or Ubuntu > 19 replace: path: "{{ kalite_venv }}/lib/python2.7/site-packages/kalite/packages/dist/ifcfg/parser.py" # /usr/local/kalite/venv regexp: 'a-zA-Z0-9' replace: 'a-zA-Z0-9\-' - #when: not (is_debian_9 or is_debian_10 or is_ubuntu_16 or is_ubuntu_17 or is_ubuntu_18 or is_ubuntu_19) - # 2020-03-31: Testing for {is_raspbian_9, is_raspbian_10} is not currently nec, as testing for {is_debian_9, is_debian_10} covers that already. - # JV: why not just is_ubuntu_20? AH: to make this work on Ubuntu 21+ and ideally Debian/RasPiOS 11+ too? - -# - name: Fix KA Lite bug in regex parsing ifconfig output (ifcfg/parser.py) for @m-anish's network names that contain dashes, if Raspbian/Debian < 11 or Ubuntu < 20 -# replace: -# path: "{{ kalite_venv }}/local/lib/python2.7/site-packages/kalite/packages/dist/ifcfg/parser.py" -# regexp: 'a-zA-Z0-9' -# replace: 'a-zA-Z0-9\-' -# when: is_debian_9 or is_debian_10 or is_ubuntu_16 or is_ubuntu_17 or is_ubuntu_18 or is_ubuntu_19 -# # 2020-03-31: Testing for {is_raspbian_9, is_raspbian_10} is not currently nec, as testing for {is_debian_9, is_debian_10} covers that already. - name: Create dir {{ kalite_root }} file: @@ -90,6 +86,17 @@ # RECORD KA Lite AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'kalite_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: kalite + option: kalite_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'kalite_installed: True'" set_fact: kalite_installed: True diff --git a/roles/kiwix/README.rst b/roles/kiwix/README.rst index e635be2de..db77fd05e 100644 --- a/roles/kiwix/README.rst +++ b/roles/kiwix/README.rst @@ -14,7 +14,7 @@ Locations - Your ZIM files go in ``/library/zims/content`` - Your ZIM index files used to go in directories under ``/library/zims/index`` (these index files are increasingly no longer necessary, as most ZIM files produced since 2017 contain an internal search index instead!) -- The URL is http://box/kiwix or http://box.lan/kiwix (both proxied for AWStats) +- The URL is http://box/kiwix or http://box.lan/kiwix (both proxied for AWStats, Matomo, ETC) - Use URL http://box:3000/kiwix if you want to avoid the proxy Your ``/library/zims/library.xml`` (containing essential metadata for the ZIM files you've installed) can be regenerated if necessary, by running: diff --git a/roles/kiwix/defaults/main.yml b/roles/kiwix/defaults/main.yml index 2696974fd..52e881796 100644 --- a/roles/kiwix/defaults/main.yml +++ b/roles/kiwix/defaults/main.yml @@ -8,11 +8,11 @@ # If nec, change them by editing /etc/iiab/local_vars.yml prior to installing! -# INSTRUCTIONS TO REINSTALL Kiwix: -# (1) VERIFY THESE VARS IN /etc/iiab/local_vars.yml +# ONLINE UPGRADE INSTRUCTIONS: +# (1) VERIFY VARS IN /etc/iiab/local_vars.yml # kiwix_install: True # kiwix_enabled: True -# (2) RUN: cd /opt/iiab/iiab; ./runrole --reinstall kiwix +# (2) RUN: cd /opt/iiab/iiab; sudo ./runrole --reinstall kiwix # FYI /library/zims contains 3 important things: @@ -25,13 +25,13 @@ kiwix_base_url: https://download.kiwix.org/release/kiwix-tools/ #kiwix_base_url: https://download.kiwix.org/nightly/2022-10-04/ #kiwix_base_url: "{{ iiab_download_url }}/" # e.g. https://download.iiab.io/packages/ -kiwix_arch_dict: - #i386: - i686: i586 - x86_64: x86_64 - armv6l: armhf - armv7l: armhf - aarch64: armhf +kiwix_arch_dict: # 'dpkg --print-architecture' key would be: (to mitigate #3516 in future, if truly nec?) + #i386: # ? + i686: i586 # ? + x86_64: x86_64 # amd64 + armv6l: armv6 # armhf + armv7l: armv8 # armhf BEWARE: armhf version of kiwix-tools suddenly FAILS on 64-bit RasPiOS, since 3.5.0 released 2023-04-28 -- #3574, PR #3576 + aarch64: aarch64 # arm64 BEWARE: "32-bit" RasPiOS suddenly boots 64-bit kernel since March 2023 -- #3516, explained at https://github.com/iiab/iiab/pull/3422#issuecomment-1533441463 # ansible_architecture might also work, if not quite as well: # https://stackoverflow.com/questions/66828315/what-is-the-difference-between-ansible-architecture-and-ansible-machine-on-a/66828837#66828837 @@ -42,6 +42,7 @@ kiwix_arch: "{{ kiwix_arch_dict[ansible_machine] | default('unsupported') }}" # Latest official kiwix-tools release, per Kiwix permalink redirects: # https://www.kiwix.org/en/downloads/kiwix-serve/ # https://github.com/kiwix/container-images/issues/236 +# https://github.com/kiwix/kiwix-tools/issues/623 kiwix_tar_gz: "kiwix-tools_linux-{{ kiwix_arch }}.tar.gz" #kiwix_tar_gz: "kiwix-tools_linux-{{ kiwix_arch }}-3.3.0-1.tar.gz" # Version can be hard-coded if you prefer (as was done til 2022-10-04) diff --git a/roles/kiwix/tasks/install.yml b/roles/kiwix/tasks/install.yml index 8a95d52ba..a78f71d21 100644 --- a/roles/kiwix/tasks/install.yml +++ b/roles/kiwix/tasks/install.yml @@ -6,6 +6,11 @@ when: kiwix_arch == "unsupported" +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + # 1. PUT IN PLACE: /opt/iiab/downloads/kiwix-tools_linux-*.tar.gz, move /opt/iiab/kiwix/bin aside if nec, create essential dirs, and test.zim if nec (library.xml is created later, by enable-or-disable.yml) # 2022-10-04: get_url might be removed in future (unarchive below can handle @@ -19,6 +24,24 @@ timeout: "{{ download_timeout }}" register: kiwix_dl # PATH /opt/iiab/downloads + ACTUAL filename put in kiwix_dl.dest, for unarchive ~28 lines below +# - name: "2023-05-14: TEMPORARY PATCH REVERTING TO KIWIX-TOOLS 3.4.0 IF BUGGY 32-BIT (armhf) VERSION 3.5.0 IS DETECTED -- #3574" +# get_url: +# url: https://download.kiwix.org/release/kiwix-tools/kiwix-tools_linux-armhf-3.4.0.tar.gz +# dest: "{{ downloads_dir }}" +# timeout: "{{ download_timeout }}" +# #register: kiwix_dl # CLOBBERS kiwix_dl.dest WHEN THIS STANZA DOES NOT RUN :/ +# when: kiwix_dl.dest == "/opt/iiab/downloads/kiwix-tools_linux-armhf-3.5.0.tar.gz" +# +# # Ansible does not allow changing individuals subfields in a dictionary, but +# # this crude hack works, overwriting the entire kiwix_dl dictionary var with +# # the single (needed) key/value pair. (Or "register: tmp_dl" could be set +# # above, if its other [subfields, key/value pairs, etc] really mattered...) +# - name: "2023-05-15: TEMPORARY PATCH REVERTING TO KIWIX-TOOLS 3.4.0 IF BUGGY 32-BIT (armhf) VERSION 3.5.0 IS DETECTED -- #3574" +# set_fact: +# kiwix_dl: +# dest: /opt/iiab/downloads/kiwix-tools_linux-armhf-3.4.0.tar.gz +# when: kiwix_dl.dest == "/opt/iiab/downloads/kiwix-tools_linux-armhf-3.5.0.tar.gz" + - name: Does {{ kiwix_path }}/bin already exist? (as a directory, symlink or file) stat: path: "{{ kiwix_path }}/bin" # /opt/iiab/kiwix @@ -58,6 +81,8 @@ src: "{{ kiwix_dl.dest }}" # See ~28 lines above, e.g. /opt/iiab/downloads/kiwix-tools_linux-x86_64-3.3.0-1.tar.gz dest: "{{ kiwix_path }}/bin" extra_opts: --strip-components=1 + owner: root # 2023-05-14: When unpacking let's avoid bogus owner/group, + group: root # arising from UID/GID on Kiwix's build machine. # 3. ENABLE MODS FOR APACHE PROXY IF DEBUNTU @@ -98,6 +123,17 @@ # 5. RECORD Kiwix AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'kiwix_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: kiwix + option: kiwix_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'kiwix_installed: True'" set_fact: kiwix_installed: True diff --git a/roles/kolibri/README.rst b/roles/kolibri/README.rst index 803ad433e..ff3777519 100644 --- a/roles/kolibri/README.rst +++ b/roles/kolibri/README.rst @@ -24,7 +24,7 @@ Please look in `/opt/iiab/iiab/roles/kolibri/defaults/main.yml `_) the installation will set up the following defaults:: +When kolibri_provision is enabled (e.g. in `/etc/iiab/local_vars.yml `_) the installation will set up the following defaults:: kolibri_facility: Kolibri-in-a-Box kolibri_language: en # See KOLIBRI_SUPPORTED_LANGUAGES at the bottom of https://github.com/learningequality/kolibri/blob/develop/kolibri/utils/i18n.py diff --git a/roles/kolibri/defaults/main.yml b/roles/kolibri/defaults/main.yml index 43f412f79..80eb0c352 100644 --- a/roles/kolibri/defaults/main.yml +++ b/roles/kolibri/defaults/main.yml @@ -3,11 +3,21 @@ # kolibri_language: en # See KOLIBRI_SUPPORTED_LANGUAGES at the bottom of https://github.com/learningequality/kolibri/blob/develop/kolibri/utils/i18n.py +# Kolibri folder to store its data and configuration files. +# kolibri_home: "{{ content_base }}/kolibri" # /library/kolibri + +# kolibri_user: kolibri # Whereas a vanilla install of Kolibri auto-identifies +# and saves a 'desktop-like' user like {iiab-admin, pi} to /etc/kolibri/username +# (generally the user with lowest UID >= 1000) to allow access to USB devices: +# https://kolibri.readthedocs.io/en/latest/install/ubuntu-debian.html#changing-the-owner-of-kolibri-system-service +# https://github.com/learningequality/kolibri-installer-debian/issues/115 + # kolibri_http_port: 8009 # All above are set in: github.com/iiab/iiab/blob/master/vars/default_vars.yml # If nec, change them by editing /etc/iiab/local_vars.yml prior to installing! + # 2019-09-27: Pinning to a particular version is unfortunately NOT supported # with our new apt approach (.deb installer) at this time. # 2019-06-21: Uncomment this pinning line if you want a particular version of @@ -16,8 +26,12 @@ # https://github.com/iiab/iiab/issues/1675 # https://github.com/learningequality/kolibri/issues/5664 -# 2022-07-30: UNCOMMENT THE FOLLOWING LINE TO TEST A PARTICULAR .deb INSTALL +# 2024-04-08: Kolibri 0.16.1+ restores install via apt +# https://github.com/learningequality/kolibri/issues/11892#issuecomment-2043073998 +# 2022-07-30: UNCOMMENT ONE OF THE FOLLOWING LINES TO TEST A PARTICULAR .deb INSTALL # kolibri_deb_url: https://learningequality.org/r/kolibri-deb-latest +# 2024-02-17: https://github.com/learningequality/kolibri/issues/11892 +# kolibri_deb_url: https://learningequality.org/r/kolibri-deb-next # 2019-11-21 issue #2045 - above URL had redirected to this broken Kolibri 0.12.9 release: # https://storage.googleapis.com/le-releases/downloads/kolibri/v0.12.9/kolibri_0.12.9-0ubuntu1_all.deb # @@ -30,19 +44,11 @@ # Corresponding to: # https://launchpad.net/~learningequality/+archive/ubuntu/kolibri -# Kolibri folder to store its data and configuration files. -kolibri_home: "{{ content_base }}/kolibri" # /library/kolibri - kolibri_url_without_slash: /kolibri kolibri_url: "{{ kolibri_url_without_slash }}/" # /kolibri/ kolibri_exec_path: /usr/bin/kolibri -kolibri_user: kolibri # Whereas a vanilla install of Kolibri auto-identifies -# and saves a 'desktop' user like {iiab-admin, pi} to /etc/kolibri/username, -# towards guaranteeing access to USB devices, per: -# https://kolibri.readthedocs.io/en/latest/install.html#changing-the-owner-of-kolibri-system-service - # To populate /library/kolibri with essential/minimum files and dirs. This # provisions Kolibri with facility name, admin acnt / password, preset type, # and language. You can set this to 'False' when reinstalling Kolibri: diff --git a/roles/kolibri/tasks/install.yml b/roles/kolibri/tasks/install.yml index 94a8d4949..d95f36044 100644 --- a/roles/kolibri/tasks/install.yml +++ b/roles/kolibri/tasks/install.yml @@ -4,16 +4,40 @@ # https://github.com/learningequality/pi-gen/blob/master/stage2/04-hostapd/offline.yml # https://github.com/learningequality/pi-gen/blob/master/stage2/04-hostapd/online.yml +# Install Kolibri » Debian/Ubuntu +# https://kolibri.readthedocs.io/en/latest/install/ubuntu-debian.html + +# Advanced management +# https://kolibri.readthedocs.io/en/latest/manage/advanced.html + +# Working with Kolibri from the command line +# https://kolibri.readthedocs.io/en/latest/manage/command_line.html + +# Customize Kolibri settings with the [ /library/kolibri/options.ini ] file +# https://kolibri.readthedocs.io/en/latest/manage/options_ini.html + +# Test Kolibri server performance +# https://kolibri.readthedocs.io/en/latest/manage/performance.html + +# Provisioning many servers +# https://kolibri.readthedocs.io/en/latest/install/provision.html + + +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: Create Linux user {{ kolibri_user }} and add it to groups {{ apache_user }}, disk user: name: "{{ kolibri_user }}" - groups: - - "{{ apache_user }}" - - disk + groups: "{{ apache_user }}" # 2023-03-29: Not really necessary (Kolibri is demonstrated to work without group 'www-data'). But it likely doesn't hurt. + #- disk # 2023-03-29: Tested to be unnec with USB sticks (with 64-bit RasPiOS). FWIW group 'disk' is "Mostly equivalent to root access" according to https://wiki.debian.org/SystemGroups state: present shell: /bin/false system: yes create_home: no + home: "{{ kolibri_home }}" - name: Create directory {{ kolibri_home }} for Kolibri content, configuration, sqlite3 databases ({{ kolibri_user }}:{{ apache_user }}, by default 0755) file: @@ -38,83 +62,98 @@ dest: /etc/kolibri/daemon.conf -- name: apt install latest Kolibri .deb from {{ kolibri_deb_url }} (populates {{ kolibri_home }}, migrates database) # i.e. /library/kolibri +# https://kolibri.readthedocs.io/en/latest/install/ubuntu-debian.html claims: +# "When you use the PPA installation method, upgrades to newer versions +# will be automatic, provided there is internet access available." +# +# IN REALITY: apt upgrading Kolibri is messy, as up-to-5 debconf screens prompt +# PPL WHO DON'T KNOW with the wrong default username, instead of 'kolibri' :/ +# https://github.com/learningequality/kolibri-installer-debian/pull/117 + +# 2022-08-31: keyring /etc/apt/trusted.gpg DEPRECATED as detailed on #3343 +- name: Download Kolibri's apt key to /usr/share/keyrings/learningequality-kolibri.gpg + shell: | + gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys DC5BAA93F9E4AE4F0411F97C74F88ADB3194DD81 + gpg --yes --output /usr/share/keyrings/learningequality-kolibri.gpg --export DC5BAA93F9E4AE4F0411F97C74F88ADB3194DD81 + +# 2024-06-25: Strongly consider PPA "kolibri-proposed" in future... +# https://github.com/learningequality/kolibri/issues/11892 +# https://kolibri.readthedocs.io/en/latest/install/ubuntu-debian.html +- name: Add signed Kolibri PPA 'jammy' + apt_repository: + repo: "deb [signed-by=/usr/share/keyrings/learningequality-kolibri.gpg] http://ppa.launchpad.net/learningequality/kolibri/ubuntu jammy main" +# when: is_ubuntu and os_ver is version('ubuntu-2204', '>=') or is_linuxmint_21 or is_debian_12 +# #when: is_ubuntu_2204 or is_ubuntu_2210 or is_debian_12 # MINT 21 COVERED BY is_ubuntu_2204 + +# - name: Add signed Kolibri PPA 'focal' (if other/older OS's) +# apt_repository: +# repo: "deb [signed-by=/usr/share/keyrings/learningequality-kolibri.gpg] http://ppa.launchpad.net/learningequality/kolibri/ubuntu focal main" +# when: not (is_ubuntu and os_ver is version('ubuntu-2204', '>=') or is_linuxmint_21 or is_debian_12) +# #when: not (is_ubuntu_2204 or is_ubuntu_2210 or is_debian_12) + +# - name: Add Kolibri PPA repo 'ppa:learningequality/kolibri' (if is_ubuntu and not is_linuxmint) +# apt_repository: +# repo: ppa:learningequality/kolibri +# when: is_ubuntu and not is_linuxmint + +# 2022-08-19: 'add-apt-repository ppa:learningequality/kolibri' works at CLI on +# Mint 21 (creating /etc/apt/sources.list.d/learningequality-kolibri-jammy.list) +# BUT equivalent Ansible command (STANZA ABOVE) failed with error... +# "Failed to update apt cache: E:The repository 'http://ppa.launchpad.net/learningequality/kolibri/ubuntu vanessa Release' does not have a Release file." +# ...so for now we special case Mint, similar to Debian (BOTH STANZAS BELOW!) + +# 2022-08-19: https://github.com/learningequality/kolibri/issues/9647 also asks +# about the warning below, arising no matter if codename is 'focal' or 'jammy' +# with Kolibri 0.15.6 on Mint 21 -- if you run '/usr/bin/kolibri --version': +# +# /usr/lib/python3/dist-packages/pkg_resources/__init__.py:116: PkgResourcesDeprecationWarning: 0.1.43ubuntu1 is an invalid version and will not be supported in a future release +# warnings.warn( + +# 2022-08-19: 'apt-key list' & 'apt-key del 3194 DD81' are useful if you also +# want to clear out Kolibri's key from the DEPRECATED /etc/apt/trusted.gpg + +# - name: Add Kolibri PPA repo 'ppa:learningequality/kolibri' with codename 'jammy' (if is_linuxmint_21) +# apt_repository: +# repo: ppa:learningequality/kolibri +# codename: jammy # CONSOLIDATE THIS SPECIAL CASE STANZA WITH UBUNTU ABOVE IN FUTURE? +# when: is_linuxmint_21 + +# - name: Add Kolibri PPA repo 'ppa:learningequality/kolibri' with codename 'focal' (if is_debian or is_linuxmint_20) +# apt_repository: +# repo: ppa:learningequality/kolibri +# codename: focal # UPDATE THIS TO 'jammy' AFTER "RasPiOS Bookworm" (based on Debian 12) IS RELEASED! (ETA Q3 2023) +# when: is_debian or is_linuxmint_20 + + +# 2024-08-07: Hack no longer needed! As Kolibri 0.17.0 now installs via "kolibri" PPA (https://launchpad.net/~learningequality/+archive/ubuntu/kolibri). +# Hopefully "kolibri-proposed" PPA will install 0.18 pre-releases soon, on Python 3.13 too! https://github.com/learningequality/kolibri/issues/11892 + +# - name: '2024-06-25 TEMPORARY HACK: Hard code kolibri_deb_url to Kolibri 0.17.x (pre-release or final release) if Python >= 3.12 -- kolibri-proposed PPA should do this automatically in future!' +# set_fact: +# kolibri_deb_url: https://github.com/learningequality/kolibri/releases/download/v0.17.0/kolibri_0.17.0-0ubuntu1_all.deb +# when: python_version is version('3.12', '>=') # For Ubuntu 24.04, Mint 22, pre-releases of Ubuntu 24.10, and Debian 13 (even if/when "Trixie" changes from Python 3.12 to 3.13!) Regarding PPA kolibri-proposed not quite being ready yet, see: learningequality/kolibri#11316 -> learningequality/kolibri#11892 + +- name: apt install kolibri (using apt source specified above, if kolibri_deb_url ISN'T defined) apt: - deb: "{{ kolibri_deb_url }}" # https://learningequality.org/r/kolibri-deb-latest - environment: - KOLIBRI_HOME: "{{ kolibri_home }}" # These don't do a thing for now but - KOLIBRI_USER: "{{ kolibri_user }}" # both can't hurt & Might Help Later - when: kolibri_deb_url is defined - -- block: # ELSE... - - # https://kolibri.readthedocs.io/en/latest/install/ubuntu-debian.html says: - # "When you use the PPA installation method, upgrades to newer versions - # will be automatic, provided there is internet access available." - # - # IN REALITY: apt upgrading Kolibri is risky, as 3 pink/blue screens prompt - # PPL WHO DON'T KNOW TO TYPE IN things like Linux username 'kolibri' :/ #3356 - - # 2022-08-31: keyring /etc/apt/trusted.gpg DEPRECATED as detailed on #3343 - - name: Download Kolibri's apt key to /usr/share/keyrings/learningequality-kolibri.gpg - shell: | - gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys DC5BAA93F9E4AE4F0411F97C74F88ADB3194DD81 - gpg --yes --output /usr/share/keyrings/learningequality-kolibri.gpg --export DC5BAA93F9E4AE4F0411F97C74F88ADB3194DD81 - - - name: Add signed Kolibri PPA 'jammy' (if Ubuntu 22.04+ or Mint 21 or Debian 12) - apt_repository: - repo: "deb [signed-by=/usr/share/keyrings/learningequality-kolibri.gpg] http://ppa.launchpad.net/learningequality/kolibri/ubuntu jammy main" - when: is_ubuntu and os_ver is version('ubuntu-2204', '>=') or is_linuxmint_21 or is_debian_12 - #when: is_ubuntu_2204 or is_ubuntu_2210 or is_debian_12 # MINT 21 COVERED BY is_ubuntu_2204 - - - name: Add signed Kolibri PPA 'focal' (if other/older OS's) - apt_repository: - repo: "deb [signed-by=/usr/share/keyrings/learningequality-kolibri.gpg] http://ppa.launchpad.net/learningequality/kolibri/ubuntu focal main" - when: not (is_ubuntu and os_ver is version('ubuntu-2204', '>=') or is_linuxmint_21 or is_debian_12) - #when: not (is_ubuntu_2204 or is_ubuntu_2210 or is_debian_12) - - # - name: Add Kolibri PPA repo 'ppa:learningequality/kolibri' (if is_ubuntu and not is_linuxmint) - # apt_repository: - # repo: ppa:learningequality/kolibri - # when: is_ubuntu and not is_linuxmint - - # 2022-08-19: 'add-apt-repository ppa:learningequality/kolibri' works at CLI on - # Mint 21 (creating /etc/apt/sources.list.d/learningequality-kolibri-jammy.list) - # BUT equivalent Ansible command (STANZA ABOVE) failed with error... - # "Failed to update apt cache: E:The repository 'http://ppa.launchpad.net/learningequality/kolibri/ubuntu vanessa Release' does not have a Release file." - # ...so for now we special case Mint, similar to Debian (BOTH STANZAS BELOW!) - - # 2022-08-19: https://github.com/learningequality/kolibri/issues/9647 also asks - # about the warning below, arising no matter if codename is 'focal' or 'jammy' - # with Kolibri 0.15.6 on Mint 21 -- if you run '/usr/bin/kolibri --version': - # - # /usr/lib/python3/dist-packages/pkg_resources/__init__.py:116: PkgResourcesDeprecationWarning: 0.1.43ubuntu1 is an invalid version and will not be supported in a future release - # warnings.warn( - - # 2022-08-19: 'apt-key list' & 'apt-key del 3194 DD81' are useful if you also - # want to clear out Kolibri's key from the DEPRECATED /etc/apt/trusted.gpg - - # - name: Add Kolibri PPA repo 'ppa:learningequality/kolibri' with codename 'jammy' (if is_linuxmint_21) - # apt_repository: - # repo: ppa:learningequality/kolibri - # codename: jammy # CONSOLIDATE THIS SPECIAL CASE STANZA WITH UBUNTU ABOVE IN FUTURE? - # when: is_linuxmint_21 - - # - name: Add Kolibri PPA repo 'ppa:learningequality/kolibri' with codename 'focal' (if is_debian or is_linuxmint_20) - # apt_repository: - # repo: ppa:learningequality/kolibri - # codename: focal # UPDATE THIS TO 'jammy' AFTER "RasPiOS Bookworm" (based on Debian 12) IS RELEASED! (ETA Q3 2023) - # when: is_debian or is_linuxmint_20 - - - name: apt install kolibri (populates {{ kolibri_home }}, migrates database) # i.e. /library/kolibri - apt: - name: kolibri - environment: - KOLIBRI_HOME: "{{ kolibri_home }}" # These don't do a thing for now but - KOLIBRI_USER: "{{ kolibri_user }}" # both can't hurt & Might Help Later - + name: kolibri when: kolibri_deb_url is undefined + # environment: + # KOLIBRI_HOME: "{{ kolibri_home }}" # 2023-03-27: These don't do a thing + # KOLIBRI_USER: "{{ kolibri_user }}" # for now. +- name: apt install {{ kolibri_deb_url }} (if kolibri_deb_url IS defined) + apt: + deb: "{{ kolibri_deb_url }}" # e.g. https://learningequality.org/r/kolibri-deb-latest + when: kolibri_deb_url is defined + # environment: + # KOLIBRI_HOME: "{{ kolibri_home }}" # 2023-03-27: These don't do a thing + # KOLIBRI_USER: "{{ kolibri_user }}" # for now. + + +- name: Run 'rm -rf /root/.kolibri' to remove "unavoidable" pollution created above + file: + state: absent + path: /root/.kolibri - name: 'Install from template: /etc/systemd/system/kolibri.service' template: @@ -123,8 +162,8 @@ - name: Stop 'kolibri' systemd service, for Kolibri provisioning (after daemon_reload) systemd: - name: kolibri daemon_reload: yes + name: kolibri state: stopped @@ -145,9 +184,13 @@ # become_user: "{{ kolibri_user }}" # when: kolibri_provision +# Run "kolibri manage help provisiondevice" to see CLI options, e.g.: +# --facility_settings FACILITY_SETTINGS +# JSON file containing facility settings +# --device_settings DEVICE_SETTINGS +# JSON file containing device settings - name: 'Provision Kolibri, while setting: facility name, admin acnt / password, preset type, and language' shell: > - export KOLIBRI_HOME="{{ kolibri_home }}" && "{{ kolibri_exec_path }}" manage provisiondevice --facility "{{ kolibri_facility }}" --superusername "{{ kolibri_admin_user }}" --superuserpassword "{{ kolibri_admin_password }}" --preset "{{ kolibri_preset }}" --language_id "{{ kolibri_language }}" @@ -156,15 +199,22 @@ become: yes become_user: "{{ kolibri_user }}" when: kolibri_provision + environment: + KOLIBRI_HOME: "{{ kolibri_home }}" # 2023-03-27: Required! + #KOLIBRI_USER: "{{ kolibri_user }}" # 2023-03-27: Not nec due to /etc/kolibri/username ? -- name: chown -R {{ kolibri_user }}:{{ apache_user }} {{ kolibri_home }} for good measure? - file: - path: "{{ kolibri_home }}" # /library/kolibri - owner: "{{ kolibri_user }}" # kolibri - group: "{{ apache_user }}" # www-data (on Debian/Ubuntu/Raspbian) - recurse: yes - when: kolibri_provision +# 2023-03-25: Likely overkill (let's strongly consider removing this stanza?) +# Certainly, setting owner (recursively) is advised when moving /library/kolibri : +# https://kolibri.readthedocs.io/en/latest/install/ubuntu-debian.html#changing-the-owner-of-kolibri-system-service +# 2023-03-27: Commented out on a provisional basis (Spring Cleaning) +# - name: chown -R {{ kolibri_user }}:{{ apache_user }} {{ kolibri_home }} for good measure? +# file: +# path: "{{ kolibri_home }}" # /library/kolibri +# owner: "{{ kolibri_user }}" # kolibri +# group: "{{ apache_user }}" # www-data (on Debian/Ubuntu/Raspbian) +# recurse: yes +# when: kolibri_provision # 2019-10-07: Moved to roles/httpd/tasks/main.yml # 2019-09-29: roles/kiwix/tasks/kiwix_install.yml installs 4 Apache modules @@ -176,6 +226,17 @@ # RECORD Kolibri AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'kolibri_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: kolibri + option: kolibri_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'kolibri_installed: True'" set_fact: kolibri_installed: True diff --git a/roles/lokole/tasks/install.yml b/roles/lokole/tasks/install.yml index a1ea1d357..a002268fc 100644 --- a/roles/lokole/tasks/install.yml +++ b/roles/lokole/tasks/install.yml @@ -2,12 +2,16 @@ # https://github.com/iiab/iiab/blob/master/roles/www_base/templates/iiab-refresh-wiki-docs.sh#L51-L52 -- name: Install 14 packages for Lokole +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + +- name: Install 12 packages for Lokole apt: name: #- python3 # 2022-12-21: IIAB pre-req, see scripts/local_facts.fact - - python3-pip - - python3-venv + #- python3-pip - python3-dev - python3-bcrypt # 2019-10-14: Should work across modern Linux OS's #- bcrypt does not exist on Ubuntu 19.10 @@ -134,6 +138,17 @@ # RECORD Lokole AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'lokole_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: lokole + option: lokole_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'lokole_installed: True'" set_fact: lokole_installed: True diff --git a/roles/matomo/README.adoc b/roles/matomo/README.adoc index 7bef1f07e..88a558407 100644 --- a/roles/matomo/README.adoc +++ b/roles/matomo/README.adoc @@ -4,7 +4,7 @@ https://matomo.org/[Matomo] is a web analytics alternative to Google Analytics, == Install it -Prior to installing Matomo with IIAB, the default URL (http://box.lan/matomo) can be customized in https://wiki.iiab.io/go/FAQ#What_is_local_vars.yml_and_how_do_I_customize_it.3F[/etc/iiab/local_vars.yml] +Prior to installing Matomo with IIAB, the default URL (http://box.lan/matomo) can be customized in https://wiki.iiab.io/go/FAQ#What_is_local_vars.yml_and_how_do_I_customize_it%3F[/etc/iiab/local_vars.yml] One way to do that is by changing these 2 lines: diff --git a/roles/matomo/tasks/install.yml b/roles/matomo/tasks/install.yml index 56439de3e..7de697f49 100644 --- a/roles/matomo/tasks/install.yml +++ b/roles/matomo/tasks/install.yml @@ -12,6 +12,26 @@ # fatal: [127.0.0.1]: FAILED! => {"cache_control": "private, no-cache, no-store", "changed": false, "connection": "close", "content_type": "text/html; charset=utf-8", "date": "Wed, 15 Jun 2022 05:07:41 GMT", "elapsed": 0, "expires": "Thu, 19 Nov 1981 08:52:00 GMT", "msg": "Status code was 500 and not [200]: HTTP Error 500: Internal Server Error", "pragma": "no-cache", "redirected": false, "server": "nginx/1.18.0 (Ubuntu)", "set_cookie": "MATOMO_SESSID=psak3aem27vrdrt8t2f016600f; path=/; HttpOnly; SameSite=Lax", "status": 500, "transfer_encoding": "chunked", "url": "http://box.lan/matomo/index.php?action=welcome", "x_matomo_request_id": "fbfd2"} +- name: "Set 'mysql_install: True' and 'mysql_enabled: True'" + set_fact: + mysql_install: True + mysql_enabled: True + +- name: MYSQL - run 'mysql' role (attempt to install & enable MySQL / MariaDB) + include_role: + name: mysql + +- name: FAIL (STOP THE INSTALL) IF 'mysql_installed is undefined' + fail: + msg: "Matomo install cannot proceed, as MySQL / MariaDB is not installed." + when: mysql_installed is undefined + + +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + # https://matomo.org/faq/on-premise/matomo-requirements/ - name: Install Matomo's recommended PHP extensions package: @@ -47,7 +67,7 @@ priv: "{{ matomo_db_name }}.*:ALL" #login_unix_socket: /var/run/mysqld/mysqld.sock -- name: Download and Extract Matomo (~1 min) +- name: Download and Extract Matomo (~3 min) unarchive: src: "{{ matomo_dl_url }}" # e.g. https://builds.matomo.org/matomo.tar.gz dest: "{{ matomo_path }}" # e.g. /library/www @@ -239,6 +259,17 @@ # RECORD Matomo AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'matomo_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: matomo + option: matomo_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'matomo_installed: True'" set_fact: matomo_installed: True diff --git a/roles/matomo/tasks/main.yml b/roles/matomo/tasks/main.yml index eec80e81a..b99de06e7 100644 --- a/roles/matomo/tasks/main.yml +++ b/roles/matomo/tasks/main.yml @@ -21,7 +21,7 @@ - block: - - name: Enable/Disable/Reload NGINX for OSM, if nginx_enabled + - name: Enable/Disable/Reload NGINX for Matomo include_tasks: nginx.yml - name: Install Matomo if 'matomo_installed' not defined, e.g. in {{ iiab_state_file }} # /etc/iiab/iiab_state.yml diff --git a/roles/matomo/tasks/nginx.yml b/roles/matomo/tasks/nginx.yml index 8d432ee8c..46465dffb 100644 --- a/roles/matomo/tasks/nginx.yml +++ b/roles/matomo/tasks/nginx.yml @@ -1,10 +1,10 @@ -- name: Enable http://box/maps & http://box/matomo via NGINX, by installing {{ nginx_conf_dir }}/matomo-nginx.conf from template +- name: Enable http://box/matomo via NGINX, by installing {{ nginx_conf_dir }}/matomo-nginx.conf from template template: src: matomo-nginx.conf.j2 dest: "{{ nginx_conf_dir }}/matomo-nginx.conf" # /etc/nginx/conf.d when: matomo_enabled -- name: Disable http://box/maps & http://box/matomo via NGINX, by removing {{ nginx_conf_dir }}/matomo-nginx.conf +- name: Disable http://box/matomo via NGINX, by removing {{ nginx_conf_dir }}/matomo-nginx.conf file: path: "{{ nginx_conf_dir }}/matomo-nginx.conf" # /etc/nginx/conf.d state: absent diff --git a/roles/matomo/templates/matomo-nginx.conf.j2 b/roles/matomo/templates/matomo-nginx.conf.j2 index 0a7b91609..a5fdce030 100644 --- a/roles/matomo/templates/matomo-nginx.conf.j2 +++ b/roles/matomo/templates/matomo-nginx.conf.j2 @@ -1,3 +1,5 @@ +location ~ ^/matomo/(config|tmp|core|lang) { deny all; return 403; } + location ~ ^/matomo(.*)\.php(.*)$ { alias /library/www/matomo$1.php$2; # /library/www/matomo proxy_set_header X-Real-IP $remote_addr; diff --git a/roles/mediawiki/defaults/main.yml b/roles/mediawiki/defaults/main.yml index 68a13ca74..5c37610af 100644 --- a/roles/mediawiki/defaults/main.yml +++ b/roles/mediawiki/defaults/main.yml @@ -4,7 +4,7 @@ # All above are set in: github.com/iiab/iiab/blob/master/vars/default_vars.yml # If nec, change them by editing /etc/iiab/local_vars.yml prior to installing! -mediawiki_major_version: 1.39 # "1.35" also works +mediawiki_major_version: "1.43" # "1.40" quotes nec if trailing zero mediawiki_minor_version: 0 mediawiki_version: "{{ mediawiki_major_version }}.{{ mediawiki_minor_version }}" diff --git a/roles/mediawiki/tasks/install.yml b/roles/mediawiki/tasks/install.yml index 145c1dc3d..e89afdcd9 100644 --- a/roles/mediawiki/tasks/install.yml +++ b/roles/mediawiki/tasks/install.yml @@ -1,3 +1,23 @@ +- name: "Set 'mysql_install: True' and 'mysql_enabled: True'" + set_fact: + mysql_install: True + mysql_enabled: True + +- name: MYSQL - run 'mysql' role (attempt to install & enable MySQL / MariaDB) + include_role: + name: mysql + +- name: FAIL (STOP THE INSTALL) IF 'mysql_installed is undefined' + fail: + msg: "MediaWiki install cannot proceed, as MySQL / MariaDB is not installed." + when: mysql_installed is undefined + + +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + # https://www.mediawiki.org/wiki/Manual:Installation_requirements#PHP - name: 'Install packages: php{{ php_version }}-intl, php{{ php_version }}-mbstring, php{{ php_version }}-xml' package: @@ -95,6 +115,17 @@ # RECORD MediaWiki AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'mediawiki_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: mediawiki + option: mediawiki_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'mediawiki_installed: True'" set_fact: mediawiki_installed: True diff --git a/roles/minetest/tasks/install.yml b/roles/minetest/tasks/install.yml index 1850eda84..9c00a10c2 100644 --- a/roles/minetest/tasks/install.yml +++ b/roles/minetest/tasks/install.yml @@ -1,3 +1,8 @@ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: Check for Minetest world file ({{ minetest_world_dir }}/world.mt) stat: path: "{{ minetest_world_dir }}/world.mt" @@ -7,9 +12,6 @@ file: state: directory path: /library/games - # owner: root - # group: root - # mode: '0755' - include_tasks: minetest_install.yml when: not minetest_world.stat.exists @@ -35,8 +37,20 @@ url: https://content.minetest.net/packages/sfan5/worldedit/releases/13367/download/ when: minetest_default_game == "minetest" + # RECORD Minetest AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'minetest_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: minetest + option: minetest_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'minetest_installed: True'" set_fact: minetest_installed: True diff --git a/roles/mongodb/defaults/main.yml b/roles/mongodb/defaults/main.yml index 0cace8905..a5e2455d3 100644 --- a/roles/mongodb/defaults/main.yml +++ b/roles/mongodb/defaults/main.yml @@ -20,7 +20,18 @@ # All above are set in: github.com/iiab/iiab/blob/master/vars/default_vars.yml # If nec, change them by editing /etc/iiab/local_vars.yml prior to installing! -mongodb_64bit_version: 6.0 # 2022-10-23: 4.4 fails on Debian 12 x86_64: +mongodb_arch_dict: + armv6l: unsupported # WAS: 3.0 + armv7l: unsupported # WAS: 3.0 + aarch64: 5.0 + i386: unsupported + x86_64: 6.0 + +mongodb_version: "{{ mongodb_arch_dict[ansible_machine] | default('unknown') }}" # A bit safer than ansible_architecture (see kiwix/defaults/main.yml) + +#mongodb_arm64_version: 5.0 # 2023-02-24: MongoDB 6.0.4 fails to install on +# # 64-bit RasPiOS 11, as it doesn't offer libssl3. +#mongodb_amd64_version: 6.0 # 2022-10-23: 4.4 fails on Debian 12 x86_64: # "No package matching 'mongodb-org' is available". 5.0+ fail on "pre-2011" # CPU's w/o AVX, and on RPi due to MongoDB compiling these for v8.2-A (RPi 4 is # ARM v8-A). SO IIAB ALWAYS OVERLAYS andyfelong.com's 5.0.5 IF 5.0+ SPECIFIED. diff --git a/roles/mongodb/tasks/install.yml b/roles/mongodb/tasks/install.yml index 54b93c71e..10c2f39f5 100644 --- a/roles/mongodb/tasks/install.yml +++ b/roles/mongodb/tasks/install.yml @@ -1,8 +1,14 @@ # MongoDB Install Docs: +# https://www.mongodb.com/community/forums/t/installing-mongodb-over-ubuntu-22-04/159931/90 # https://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-ubuntu/ # https://www.mongodb.com/docs/manual/installation/ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + # 1. INSTALL MongoDB PACKAGES AND/OR BINARIES # 2019-02-02: Sugarizer with Node.js 10.x requires MongoDB 2.6+ so @@ -15,232 +21,316 @@ # CLARIF: mongodb_stretch_3_0_14_core.zip IS IN FACT 3.0.14 (core) BUT... # mongodb_stretch_3_0_14_tools.zip IS REALLY 3.0.15 (tools) -- block: - - name: Create dir /tmp/mongodb-3.0.1x (aarch32) - file: - path: /tmp/mongodb-3.0.1x - state: directory +# - debug: +# msg: '9-STANZA BLOCK BELOW, RUNS *IF* 32-BIT -- i.e. not (ansible_architecture == "aarch64" or ansible_architecture == "x86_64") -- WILL LIKELY BE REMOVED SOON IN 2023, as MongoDB 3.0.1 is insufficient for Sugarizer Server 1.5.0''s new MongoDB 3.2+ REQUIREMENT: https://github.com/iiab/iiab/pull/3478#issuecomment-1444395170' - - name: Download & unzip 20MB https://download.iiab.io/packages/mongodb_stretch_3_0_14_core.zip to /tmp/mongodb-3.0.1x (aarch32) - unarchive: - remote_src: yes - src: "{{ iiab_download_url }}/mongodb_stretch_3_0_14_core.zip" # https://download.iiab.io/packages - dest: /tmp/mongodb-3.0.1x +# - block: +# - name: Create dir /tmp/mongodb-3.0.1x (aarch32) +# file: +# path: /tmp/mongodb-3.0.1x +# state: directory - - name: Install (move) its 3 CORE binaries from /tmp/mongodb-3.0.1x/core to /usr/bin (aarch32) - shell: mv /tmp/mongodb-3.0.1x/core/* /usr/bin +# - name: Download & unzip 20MB https://download.iiab.io/packages/mongodb_stretch_3_0_14_core.zip to /tmp/mongodb-3.0.1x (aarch32) +# unarchive: +# remote_src: yes +# src: "{{ iiab_download_url }}/mongodb_stretch_3_0_14_core.zip" # https://download.iiab.io/packages +# dest: /tmp/mongodb-3.0.1x - - name: Download & unzip 15MB https://download.iiab.io/packages/mongodb_stretch_3_0_14_tools.zip [IN FACT THIS ONE'S 3.0.15] to /tmp/mongodb-3.0.1x (aarch32) - unarchive: - remote_src: yes - src: "{{ iiab_download_url }}/mongodb_stretch_3_0_14_tools.zip" - dest: /tmp/mongodb-3.0.1x +# - name: Install (move) its 3 CORE binaries from /tmp/mongodb-3.0.1x/core to /usr/bin (aarch32) +# shell: mv /tmp/mongodb-3.0.1x/core/* /usr/bin - - name: Install (move) its 9 TOOLS binaries from /opt/iiab/downloads/mongodb-3.0.1x/tools to /usr/bin (aarch32) - shell: mv /tmp/mongodb-3.0.1x/tools/* /usr/bin +# - name: Download & unzip 15MB https://download.iiab.io/packages/mongodb_stretch_3_0_14_tools.zip [IN FACT THIS ONE'S 3.0.15] to /tmp/mongodb-3.0.1x (aarch32) +# unarchive: +# remote_src: yes +# src: "{{ iiab_download_url }}/mongodb_stretch_3_0_14_tools.zip" +# dest: /tmp/mongodb-3.0.1x - - name: Create Linux group mongodb (aarch32) - group: - name: mongodb - state: present +# - name: Install (move) its 9 TOOLS binaries from /opt/iiab/downloads/mongodb-3.0.1x/tools to /usr/bin (aarch32) +# shell: mv /tmp/mongodb-3.0.1x/tools/* /usr/bin - - name: Create Linux user mongodb (aarch32) - user: - name: mongodb - group: mongodb # primary group - groups: mongodb - home: /var/lib/mongodb - shell: /usr/sbin/nologin +# - name: Create Linux group mongodb (aarch32) +# group: +# name: mongodb +# state: present - - name: Install {{ mongodb_conf }} from template (aarch32) - template: - src: mongod.conf.j2 - dest: "{{ mongodb_conf }}" # /etc/mongod.conf +# - name: Create Linux user mongodb (aarch32) +# user: +# name: mongodb +# group: mongodb # primary group +# groups: mongodb +# home: /var/lib/mongodb +# shell: /usr/sbin/nologin - - name: 'Create 2 dirs: /var/lib/mongodb, /var/log/mongodb (mongodb:mongodb)' - file: - state: directory - path: "{{ item }}" - owner: mongodb - group: mongodb - with_items: - - /var/lib/mongodb - - /var/log/mongodb +# - name: Install {{ mongodb_conf }} from template (aarch32) +# template: +# src: mongod.conf.j2 +# dest: "{{ mongodb_conf }}" # /etc/mongod.conf - # end block - when: not (ansible_architecture == "x86_64" or ansible_architecture == "aarch64") +# - name: 'Create 2 dirs: /var/lib/mongodb, /var/log/mongodb (mongodb:mongodb)' +# file: +# state: directory +# path: "{{ item }}" +# owner: mongodb +# group: mongodb +# with_items: +# - /var/lib/mongodb +# - /var/log/mongodb -# 32-bit OS's are handled above: this should handle aarch32 including 32-bit +# # end block +# when: not (ansible_architecture == "x86_64" or ansible_architecture == "aarch64") # ansible_machine is a bit safer than ansible_architecture (see kiwix/defaults/main.yml) + +# - debug: +# msg: 9-STANZA BLOCK ABOVE, RAN *IF* 32-BIT -- i.e. not (ansible_architecture == "aarch64" or ansible_architecture == "x86_64") + +# 32-bit OS's [WERE] handled above: this should handle aarch32 including 32-bit # Ubuntu from https://ubuntu.com/download/raspberry-pi but Ubuntu 20.04+ and # 22.04+ 32-bit might fail untested, and 32-bit Intel might puke as this was # orginally deployed for Raspbian. (Haven't seen bootable 32-bit Intel # installers for a while now.) 64-bit OS's proceed below. + +# - debug: +# msg: 16-STANZA BLOCK BELOW, RUNS *IF* 64-BIT -- i.e. ansible_architecture == "aarch64" or ansible_architecture == "x86_64" + +# - block: +- name: Add mongodb.org signing key (only 64-bit available) for MongoDB version {{ mongodb_version }} + # https://www.mongodb.com/community/forums/t/installing-mongodb-over-ubuntu-22-04/159931/90 + shell: wget -qO - https://www.mongodb.org/static/pgp/server-{{ mongodb_version }}.asc | gpg --dearmor > /usr/share/keyrings/mongodb.gpg + #shell: wget -qO - https://www.mongodb.org/static/pgp/server-{{ mongodb_version }}.asc | apt-key add - + #shell: wget -qO - https://pgp.mongodb.com/server-{{ mongodb_version }}.asc | apt-key add - + #args: + # warn: no + # Ansible 2.14 ERROR: + # "Unsupported parameters for (ansible.legacy.command) module: warn. + # Supported parameters include: removes, strip_empty_ends, _raw_params, + # _uses_shell, stdin_add_newline, creates, chdir, executable, argv, stdin." + +# 2023-01-19: MongoDB only offers x86_64 for Debian, AND IN ANY CASE all their +# MongoDB 6.0's are ONLY COMPILED FOR ARM v8.2-A i.e. FAIL ON ARM v8-A RPi 4, +# LIKE THEIR MongoDB 5.0 tested 2022-06-07 ~137 lines below. Tested on Deb 11. +# -> DELETE THIS STANZA AFTER DEBIAN 12 IS SOLID -- USING UBUNTU REPO BELOW ? +- name: Install mongodb-org's Debian bullseye source/repo [ arch=amd64 ] for MongoDB version {{ mongodb_version }}, if x86_64 Debian < 12 + apt_repository: + # 2020-10-28 and 2022-06-09: https://repo.mongodb.org/apt/debian/dists/ + # supports only {Buster 10, Stretch 9, Jessie 8, Wheezy 7}. So Bullseye + # 11 and Bookworm 12 (testing branch) revert to buster for now: + # 2022-09-27: Changed from 'buster' to 'bullseye' (i.e. Debian 11) as + # this was recently added to https://repo.mongodb.org/apt/debian/dists/ + repo: deb [ arch=amd64 signed-by=/usr/share/keyrings/mongodb.gpg ] https://repo.mongodb.org/apt/debian bullseye/mongodb-org/{{ mongodb_version }} main + #repo: deb https://repo.mongodb.org/apt/debian bullseye/mongodb-org/{{ mongodb_version }} main + #repo: deb https://repo.mongodb.org/apt/debian {{ ansible_distribution_release }}/mongodb-org/4.4 main + #filename: mongodb-org + when: is_debian and os_ver is version('debian-12', '<') and ansible_architecture == "x86_64" + +- name: Install mongodb-org's Ubuntu jammy source/repo [ arch=amd64 ] for MongoDB version {{ mongodb_version }}, if other x86_64 OS + apt_repository: + repo: deb [ arch=amd64 signed-by=/usr/share/keyrings/mongodb.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/{{ mongodb_version }} multiverse + when: not (is_debian and os_ver is version('debian-12', '<')) and ansible_architecture == "x86_64" + +# 2023-01-19: Tested on x86_64 VM's with Ubuntu 22.04 & Debian 12. Based on +# MongoDB 6.0.3 (released 2022-11-15) instructions here: +# https://www.mongodb.com/community/forums/t/installing-mongodb-over-ubuntu-22-04/159931/90 +# WHEREAS 64-bit Raspberry Pi is likely NOT supported for now, as MongoDB 6.0 +# IS ONLY COMPILED FOR ARM v8.2-A i.e. FAIL ON ARM v8-A RPi 4 (JUST LIKE THEIR +# MongoDB 5.0, tested 2022-06-07 ~116 lines below). Though MongoDB 6.0.3+ on +# 64-bit Ubuntu on Raspberry Pi hardware (MIGHT) hypothetically be possible: +# https://www.mongodb.com/developer/products/mongodb/mongodb-on-raspberry-pi/ +# So IIAB overlays MongoDB 5.0.5 64-bit RPi binaries for now (~141 LINES BELOW!) +- name: Otherwise, install mongodb-org's Ubuntu focal source/repo [ arch=arm64 ] for MongoDB version {{ mongodb_version }} + apt_repository: + repo: deb [ arch=arm64 signed-by=/usr/share/keyrings/mongodb.gpg ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/{{ mongodb_version }} multiverse + #repo: deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb.gpg ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/{{ mongodb_version }} multiverse + #repo: deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/{{ mongodb_version }} multiverse + #filename: mongodb-org + when: not ansible_architecture == "x86_64" + #when: is_ubuntu or is_debian and os_ver is version('debian-12', '>=') + #when: is_ubuntu and os_ver is version('ubuntu-2204', '>=') or is_linuxmint and os_ver is version('linuxmint-12', '>=') or is_debian and os_ver is version('debian-12', '>=') + #when: not (is_debian and ansible_architecture == "x86_64") + + +# 2022-10-23: Force-install MongoDB on Ubuntu 22.04+, Mint 21 & Debian 12; +# as each includes libssl3 not libssl1.1 (#3190). LATER REMOVE ALL 7 STANZAS +# BELOW, IF/WHEN MongoDB ONE DAY FINALLY SUPPORTS libssl3 ? (MongoDB 6.2 fix +# may be backported to 6.0, according to 2022-09-29 "official" gossip here...) +# https://www.mongodb.com/community/forums/t/installing-mongodb-over-ubuntu-22-04/159931/58 +# https://askubuntu.com/questions/1403619/mongodb-install-fails-on-ubuntu-22-04-depends-on-libssl1-1-but-it-is-not-insta/1403683#1403683 +# echo "deb http://security.ubuntu.com/ubuntu focal-security main" | sudo tee /etc/apt/sources.list.d/focal-security.list +# sudo apt-get update +# sudo apt-get install libssl1.1 +# rm /etc/apt/sources.list.d/focal-security.list + +# 2023-02-25: RETROFITTING libssl1.1 STILL NEC on Ubuntu 22.04+ and Debian 12+ +# *IF* MongoDB < 6.0 (e.g. RPi, where MongoDB 6.0 is a complete non-starter!) +# +# Whereas libssl1.1 is thankfully NO LONGER NEC on x86_64, where MongoDB can +# finally use libssl3 instead, since 2022-11-15: +# https://www.mongodb.com/community/forums/t/installing-mongodb-over-ubuntu-22-04/159931/90 + +- debug: + msg: 5-STANZA BLOCK FOLLOWS, TO FORCE INSTALL libssl1.1 -- runs *IF* mandated mongodb_version ({{ mongodb_version }}) < 6.0 (i.e. for aarch64/arm64) on Ubuntu 22.04+ or Debian 12+ -- whereas Linux Mint should never need libssl1.1 + - block: - - name: Add mongodb.org signing key (only 64-bit support available) for MongoDB version {{ mongodb_64bit_version }} - shell: wget -qO - https://www.mongodb.org/static/pgp/server-{{ mongodb_64bit_version }}.asc | apt-key add - - #shell: wget -qO - https://pgp.mongodb.com/server-{{ mongodb_64bit_version }}.asc | apt-key add - - #args: - # warn: no - # Ansible 2.14 ERROR: - # "Unsupported parameters for (ansible.legacy.command) module: warn. - # Supported parameters include: removes, strip_empty_ends, _raw_params, - # _uses_shell, stdin_add_newline, creates, chdir, executable, argv, stdin." - # 2022-10-23: MongoDB only allows auto-install of Debian's x86_64, AND IN ANY - # CASE all their MongoDB 6.0's are ONLY COMPILED FOR ARM v8.2-A i.e. FAIL ON - # ARM v8-A RPi 4, LIKE THEIR MongoDB 5.0 tested 2022-06-07 ~120 lines below. - # -> CAN THIS ENTIRE STANZA BE *DELETED* -- ALWAYS USING UBUNTU REPO BELOW ? - - name: Install mongodb-org's Debian bullseye source/repo [ arch=amd64 ] for MongoDB version {{ mongodb_64bit_version }} - apt_repository: - # 2020-10-28 and 2022-06-09: https://repo.mongodb.org/apt/debian/dists/ - # supports only {Buster 10, Stretch 9, Jessie 8, Wheezy 7}. So Bullseye - # 11 and Bookworm 12 (testing branch) revert to buster for now: - # 2022-09-27: Changed from 'buster' to 'bullseye' (i.e. Debian 11) as - # this was recently added to https://repo.mongodb.org/apt/debian/dists/ - repo: deb https://repo.mongodb.org/apt/debian bullseye/mongodb-org/{{ mongodb_64bit_version }} main - #repo: deb https://repo.mongodb.org/apt/debian {{ ansible_distribution_release }}/mongodb-org/4.4 main - #filename: mongodb-org - when: is_debian and ansible_architecture == "x86_64" - - # 2022-10-23: RasPiOS Bullseye *MAY* FAIL when 'focal' changed to 'jammy' ? - - name: Otherwise install mongodb-org's Ubuntu focal source/repo [ arch=amd64,arm64 ] for MongoDB version {{ mongodb_64bit_version }} - apt_repository: - repo: deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/{{ mongodb_64bit_version }} multiverse - #filename: mongodb-org - when: not (is_debian and ansible_architecture == "x86_64") - - # 2022-10-23: Force-install MongoDB on Ubuntu 22.04+, Mint 21 & Debian 12; - # as each includes libssl3 not libssl1.1 (#3190). LATER REMOVE ALL 7 STANZAS - # BELOW, IF/WHEN MongoDB ONE DAY FINALLY SUPPORTS libssl3 ? (MongoDB 6.2 fix - # may be backported to 6.0, according to 2022-09-29 "official" gossip here...) - # https://www.mongodb.com/community/forums/t/installing-mongodb-over-ubuntu-22-04/159931/58 - # https://askubuntu.com/questions/1403619/mongodb-install-fails-on-ubuntu-22-04-depends-on-libssl1-1-but-it-is-not-insta/1403683#1403683 - # echo "deb http://security.ubuntu.com/ubuntu focal-security main" | sudo tee /etc/apt/sources.list.d/focal-security.list - # sudo apt-get update - # sudo apt-get install libssl1.1 - # rm /etc/apt/sources.list.d/focal-security.list - - - name: Install source/repo "deb http://security.ubuntu.com/ubuntu focal-security main" at /etc/apt/sources.list.d/security_ubuntu_com_ubuntu.list if Ubuntu 22.04+ x86_64 or Mint 21 - apt_repository: - repo: deb http://security.ubuntu.com/ubuntu focal-security main - #filename: focal-security # If filename focal-security.list is preferred - when: is_ubuntu and os_ver is version('ubuntu-2204', '>=') and ansible_architecture == "x86_64" or is_linuxmint_21 - - - name: Install source/repo "deb http://ports.ubuntu.com/ubuntu-ports focal-security main" at /etc/apt/sources.list.d/ports_ubuntu_com_ubuntu_ports.list if ubuntu 22.04+ aarch64 + - name: Install OLD source/repo "deb http://ports.ubuntu.com/ubuntu-ports focal-security main" at /etc/apt/sources.list.d/ports_ubuntu_com_ubuntu_ports.list if Ubuntu apt_repository: repo: deb http://ports.ubuntu.com/ubuntu-ports focal-security main - when: is_ubuntu and os_ver is version('ubuntu-2204', '>=') and ansible_architecture == "aarch64" + when: is_ubuntu - - name: Install source/repo "deb http://security.debian.org/debian-security bullseye-security main" at /etc/apt/sources.list.d/security_debian_org_debian_security.list if Debian 12 + - name: Install OLD source/repo "deb http://security.debian.org/debian-security bullseye-security main" at /etc/apt/sources.list.d/security_debian_org_debian_security.list if Debian apt_repository: repo: deb http://security.debian.org/debian-security bullseye-security main #repo: deb https://deb.debian.org/debian-security bullseye-security main # New way, likely equivalent - when: is_debian_12 + when: is_debian - - name: Install libssl1.1 if Ubuntu 22.04+ or Mint 21 or Debian 12 (required by MongoDB below) + - name: Force install libssl1.1 package: name: libssl1.1 state: present - when: is_ubuntu and os_ver is version('ubuntu-2204', '>=') or is_linuxmint_21 or is_debian_12 - - name: Remove source/repo "deb http://security.debian.org/debian-security bullseye-security main" at /etc/apt/sources.list.d/security_debian_org_debian_security.list if Debian 12 + - name: Remove OLD source/repo "deb http://security.debian.org/debian-security bullseye-security main" at /etc/apt/sources.list.d/security_debian_org_debian_security.list if Debian apt_repository: repo: deb http://security.debian.org/debian-security bullseye-security main #repo: deb https://deb.debian.org/debian-security bullseye-security main # New way, likely equivalent state: absent - when: is_debian_12 + when: is_debian - - name: Remove source/repo "deb http://ports.ubuntu.com/ubuntu-ports focal-security main" at /etc/apt/sources.list.d/ports_ubuntu_com_ubuntu_ports.list if ubuntu 22.04+ aarch64 + - name: Remove OLD source/repo "deb http://ports.ubuntu.com/ubuntu-ports focal-security main" at /etc/apt/sources.list.d/ports_ubuntu_com_ubuntu_ports.list if Ubuntu apt_repository: repo: deb http://ports.ubuntu.com/ubuntu-ports focal-security main state: absent - when: is_ubuntu and os_ver is version('ubuntu-2204', '>=') and ansible_architecture == "aarch64" + when: is_ubuntu - - name: Remove source/repo "deb http://security.ubuntu.com/ubuntu focal-security main" at /etc/apt/sources.list.d/security_ubuntu_com_ubuntu.list if Ubuntu 22.04+ x86_64 or Mint 21 - apt_repository: - repo: deb http://security.ubuntu.com/ubuntu focal-security main - state: absent - #filename: focal-security # 100% IGNORED during repo deletion - when: is_ubuntu and os_ver is version('ubuntu-2204', '>=') and ansible_architecture == "x86_64" or is_linuxmint_21 + when: mongodb_version is version('6.0', '<') and (is_ubuntu and os_ver is version('ubuntu-2204', '>=') or is_debian and os_ver is version('debian-12', '>=')) - # # Debian 10 aarch64 might work below but is blocked in main.yml - # - name: Use mongodb-org's Ubuntu focal repo for RasPiOS-aarch64 - # apt_repository: - # repo: deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse - # filename: mongodb-org - # when: is_raspbian and ansible_architecture == "aarch64" +- debug: + msg: 5-STANZA BLOCK ABOVE, RAN *IF* FORCED INSTALL OF libssl1.1 WAS NEEDED - # - name: Use mongodb-org's Ubuntu focal repo for Linux Mint - 64bit only - # apt_repository: - # repo: deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse - # filename: mongodb-org - # when: is_linuxmint +# - name: Install source/repo "deb http://security.ubuntu.com/ubuntu focal-security main" at /etc/apt/sources.list.d/security_ubuntu_com_ubuntu.list if Ubuntu 22.04+ x86_64 or Mint 21 +# apt_repository: +# repo: deb http://security.ubuntu.com/ubuntu focal-security main +# #filename: focal-security # If filename focal-security.list is preferred +# when: is_ubuntu and os_ver is version('ubuntu-2204', '>=') and ansible_architecture == "x86_64" or is_linuxmint_21 - # - name: Use mongodb-org's Ubuntu repo for all non-Mint Ubuntu - 64bit only - # apt_repository: - # # 2020-10-27: https://repo.mongodb.org/apt/ubuntu/dists/ supports only - # # {focal 20.04, bionic 18.04, xenial 16.04, trusty 14.04, precise 12.04} - # # so other Ubuntu's like groovy 20.10 need to revert to recent LTS repo: - # repo: deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse - # #repo: deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu {{ ansible_distribution_release }}/mongodb-org/4.4 multiverse - # filename: mongodb-org - # when: is_ubuntu and not is_linuxmint +# - name: Install source/repo "deb http://ports.ubuntu.com/ubuntu-ports focal-security main" at /etc/apt/sources.list.d/ports_ubuntu_com_ubuntu_ports.list if ubuntu 22.04+ aarch64 +# apt_repository: +# repo: deb http://ports.ubuntu.com/ubuntu-ports focal-security main +# when: is_ubuntu and os_ver is version('ubuntu-2204', '>=') and ansible_architecture == "aarch64" - - name: "Install packages: mongodb-org, mongodb-org-server" - package: - name: - - mongodb-org # Meta-package that's auto-installed anyway (SO PROB UNNEC HERE?) - - mongodb-org-server - state: present +# - name: Install source/repo "deb http://security.debian.org/debian-security bullseye-security main" at /etc/apt/sources.list.d/security_debian_org_debian_security.list if Debian 12 +# apt_repository: +# repo: deb http://security.debian.org/debian-security bullseye-security main +# #repo: deb https://deb.debian.org/debian-security bullseye-security main # New way, likely equivalent +# when: is_debian_12 - - name: Establish {{ mongodb_conf }} dbPath {{ mongodb_db_path }} -- instead of /var/lib/mongodb default -- takes effect on next (re)start of mongodb.service -- via enable-or-disable.yml or via sugarizer.service auto-starting MongoDB on demand - lineinfile: - path: "{{ mongodb_conf }}" # /etc/mongod.conf - regexp: '^\s*dbPath:' # \s = any whitespace char. stackoverflow.com/a/38491899 - line: " dbPath: {{ mongodb_db_path }}" # /library/dbdata/mongodb +# - name: Install libssl1.1 if Ubuntu 22.04+ or Mint 21 or Debian 12 (required by MongoDB below) +# package: +# name: libssl1.1 +# state: present +# when: is_ubuntu and os_ver is version('ubuntu-2204', '>=') or is_linuxmint_21 or is_debian_12 - # GRATUITOUS (port 27017 is already the default) - - name: Establish {{ mongodb_conf }} port {{ mongodb_port }} -- takes effect on next (re)start of mongodb.service -- via enable-or-disable.yml or via sugarizer.service auto-starting MongoDB on demand - lineinfile: - path: "{{ mongodb_conf }}" - regexp: '^\s*port:' - line: " port: {{ mongodb_port }}" # 27017 +# - name: Remove source/repo "deb http://security.debian.org/debian-security bullseye-security main" at /etc/apt/sources.list.d/security_debian_org_debian_security.list if Debian 12 +# apt_repository: +# repo: deb http://security.debian.org/debian-security bullseye-security main +# #repo: deb https://deb.debian.org/debian-security bullseye-security main # New way, likely equivalent +# state: absent +# when: is_debian_12 - # 2022-06-07 #3236 MongoDB 5.0.9 "Illegal instruction" on RPi 4... - # https://www.mongodb.com/community/forums/t/core-dump-on-mongodb-5-0-on-rpi-4/115291/14 - # ...as ARM v8-A < ARM v8.2-A ...also reveals: - # - # (1) For Intel x86_64, MongoDB 5.x requires Sandy Bridge or later. - # For AMD x86_64, MongoDB 5.x requires Bulldozer or later. - # Roughly speaking, this means post-2011 CPUs with AVX instructions: - # https://github.com/docker-library/mongo/issues/485#issuecomment-891991814 - # (2) dbPath needed fixing in /etc/mongod.conf (~16 lines above) from - # /var/lib/mongodb to /library/dbdata/mongodb - # (3) mongod.lock is effectively NO LONGER A LOCK FILE -- but rather a PID - # file (it may be zero bytes, but never goes away) as confirmed with - # MongoDB 4.4.14 on RPi 4 and 5.0.9 Ubuntu 22.04 on x86_64. And now - # 'mongod --repair --dbpath /library/dbdata/mongodb/' IGNORES mongod.lock - # (4) mongodb.service needed a more graceful way to shut down than - # 'killall mongod' (MongoDB 5+ shuts down w/ 15sec quiesce period). - # (5) MongoDB 6.0 is likely imminent; meantime a 2022-01-12 option (~12 - # lines below) is MongoDB 5.0.5 compiled for 64-bit RPi 4 and RPi 400: - # https://andyfelong.com/downloads/raspbian_mongodb_5.0.5.gz - # https://andyfelong.com/2021/08/mongodb-4-4-under-raspberry-pi-os-64-bit-raspbian64/ +# - name: Remove source/repo "deb http://ports.ubuntu.com/ubuntu-ports focal-security main" at /etc/apt/sources.list.d/ports_ubuntu_com_ubuntu_ports.list if ubuntu 22.04+ aarch64 +# apt_repository: +# repo: deb http://ports.ubuntu.com/ubuntu-ports focal-security main +# state: absent +# when: is_ubuntu and os_ver is version('ubuntu-2204', '>=') and ansible_architecture == "aarch64" - - name: If hardware is Raspberry Pi and mongodb_64bit_version >= 5.0, run 'apt-mark hold mongodb-org mongodb-org-server' -- so MongoDB 5.0.5 binaries {mongo, mongod, mongos} can be installed without apt interfering in future - command: apt-mark hold mongodb-org mongodb-org-server - when: rpi_model != "none" and mongodb_64bit_version is version('5.0', '>=') +# - name: Remove source/repo "deb http://security.ubuntu.com/ubuntu focal-security main" at /etc/apt/sources.list.d/security_ubuntu_com_ubuntu.list if Ubuntu 22.04+ x86_64 or Mint 21 +# apt_repository: +# repo: deb http://security.ubuntu.com/ubuntu focal-security main +# state: absent +# #filename: focal-security # 100% IGNORED during repo deletion +# when: is_ubuntu and os_ver is version('ubuntu-2204', '>=') and ansible_architecture == "x86_64" or is_linuxmint_21 - - name: If hardware is Raspberry Pi and mongodb_64bit_version >= 5.0, unarchive 76MB {{ iiab_download_url }}//packages/raspbian_mongodb_5.0.5.gz OVERWRITING 5.0.9+ {mongo, mongod, mongos} in /usr/bin - unarchive: - remote_src: yes - src: "{{ iiab_download_url }}/raspbian_mongodb_5.0.5.gz" - dest: /usr/bin - when: rpi_model != "none" and mongodb_64bit_version is version('5.0', '>=') - # end block - when: ansible_architecture == "aarch64" or ansible_architecture == "x86_64" +# # Debian 10 aarch64 might work below but is blocked in main.yml +# - name: Use mongodb-org's Ubuntu focal repo for RasPiOS-aarch64 +# apt_repository: +# repo: deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse +# filename: mongodb-org +# when: is_raspbian and ansible_architecture == "aarch64" + +# - name: Use mongodb-org's Ubuntu focal repo for Linux Mint - 64bit only +# apt_repository: +# repo: deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse +# filename: mongodb-org +# when: is_linuxmint + +# - name: Use mongodb-org's Ubuntu repo for all non-Mint Ubuntu - 64bit only +# apt_repository: +# # 2020-10-27: https://repo.mongodb.org/apt/ubuntu/dists/ supports only +# # {focal 20.04, bionic 18.04, xenial 16.04, trusty 14.04, precise 12.04} +# # so other Ubuntu's like groovy 20.10 need to revert to recent LTS repo: +# repo: deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse +# #repo: deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu {{ ansible_distribution_release }}/mongodb-org/4.4 multiverse +# filename: mongodb-org +# when: is_ubuntu and not is_linuxmint + + +- name: "Install packages: mongodb-org, mongodb-org-server" + package: + name: + - mongodb-org # Meta-package that's auto-installed anyway (SO PROB UNNEC HERE?) + - mongodb-org-server + state: present + +- name: Establish {{ mongodb_conf }} dbPath {{ mongodb_db_path }} -- instead of /var/lib/mongodb default -- takes effect on next (re)start of mongodb.service -- via enable-or-disable.yml or via sugarizer.service auto-starting MongoDB on demand + lineinfile: + path: "{{ mongodb_conf }}" # /etc/mongod.conf + regexp: '^\s*dbPath:' # \s = any whitespace char. stackoverflow.com/a/38491899 + line: " dbPath: {{ mongodb_db_path }}" # /library/dbdata/mongodb + +# GRATUITOUS (port 27017 is already the default) +- name: Establish {{ mongodb_conf }} port {{ mongodb_port }} -- takes effect on next (re)start of mongodb.service -- via enable-or-disable.yml or via sugarizer.service auto-starting MongoDB on demand + lineinfile: + path: "{{ mongodb_conf }}" + regexp: '^\s*port:' + line: " port: {{ mongodb_port }}" # 27017 + + +# 2022-06-07 #3236 MongoDB 5.0.9 "Illegal instruction" on RPi 4... +# https://www.mongodb.com/community/forums/t/core-dump-on-mongodb-5-0-on-rpi-4/115291/14 +# ...as ARM v8-A < ARM v8.2-A ...also reveals: +# +# (1) For Intel x86_64, MongoDB 5.x requires Sandy Bridge or later. +# For AMD x86_64, MongoDB 5.x requires Bulldozer or later. +# Roughly speaking, this means post-2011 CPUs with AVX instructions: +# https://github.com/docker-library/mongo/issues/485#issuecomment-891991814 +# (2) dbPath needed fixing in /etc/mongod.conf (~16 lines above) from +# /var/lib/mongodb to /library/dbdata/mongodb +# (3) mongod.lock is effectively NO LONGER A LOCK FILE -- but rather a PID +# file (it may be zero bytes, but never goes away) as confirmed with +# MongoDB 4.4.14 on RPi 4 and 5.0.9 Ubuntu 22.04 on x86_64. And now +# 'mongod --repair --dbpath /library/dbdata/mongodb/' IGNORES mongod.lock +# (4) mongodb.service needed a more graceful way to shut down than +# 'killall mongod' (MongoDB 5+ shuts down w/ 15sec quiesce period). +# (5) MongoDB 6.0 is likely imminent; meantime a 2022-01-12 option (~12 +# lines below) is MongoDB 5.0.5 compiled for 64-bit RPi 4 and RPi 400: +# https://andyfelong.com/downloads/raspbian_mongodb_5.0.5.gz +# https://andyfelong.com/2021/08/mongodb-4-4-under-raspberry-pi-os-64-bit-raspbian64/ + +- name: If hardware is Raspberry Pi and mongodb_version >= 5.0, run 'apt-mark hold mongodb-org mongodb-org-server' -- so MongoDB 5.0.5 binaries {mongo, mongod, mongos} can be installed without apt interfering in future + command: apt-mark hold mongodb-org mongodb-org-server + when: rpi_model != "none" and mongodb_version is version('5.0', '>=') + +- name: If hardware is Raspberry Pi and mongodb_version >= 5.0, unarchive 76MB {{ iiab_download_url }}//packages/raspbian_mongodb_5.0.5.gz OVERWRITING 5.0.9+ {mongo, mongod, mongos} in /usr/bin + unarchive: + remote_src: yes + src: "{{ iiab_download_url }}/raspbian_mongodb_5.0.5.gz" + dest: /usr/bin + when: rpi_model != "none" and mongodb_version is version('5.0', '>=') + +# # end block +# when: ansible_architecture == "aarch64" or ansible_architecture == "x86_64" + +# - debug: +# msg: 16-STANZA BLOCK ABOVE, RAN *IF* 64-BIT -- i.e. ansible_architecture == "aarch64" or ansible_architecture == "x86_64" # ansible_machine is a bit safer than ansible_architecture (see kiwix/defaults/main.yml) # 2. CONFIGURE MongoDB FOR IIAB @@ -282,6 +372,17 @@ # 3. RECORD MongoDB AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'mongodb_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: mongodb + option: mongodb_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'mongodb_installed: True'" set_fact: mongodb_installed: True diff --git a/roles/mongodb/tasks/main.yml b/roles/mongodb/tasks/main.yml index 748493c68..1dc712a0a 100644 --- a/roles/mongodb/tasks/main.yml +++ b/roles/mongodb/tasks/main.yml @@ -34,19 +34,25 @@ var: is_debian - debug: var: is_raspbian +- debug: + var: mongodb_version -# # might be able to lift this once we know using bionic would work -# - name: EXIT 'mongodb' ROLE & CONTINUE, IF 'is_debian_10 and aarch64 and not is_raspbian' i.e. TRUE DEBIAN with arch64 -# fail: # FORCE IT RED THIS ONCE! -# msg: ATTEMPTED MongoDB INSTALLATION WITH (TRUE) DEBIAN aarch64, which is not supported upstream. Nevertheless IIAB will continue (consider this a warning!) -# when: (ansible_architecture == "aarch64") and is_debian_10 and not is_raspbian -# ignore_errors: yes - -# ELSE... - +# WARNING: Since March 2023, 32-bit RasPiOS can act as 64-bit on RPi 4 and +# RPi 400 (unlike RPi 3!) SEE: https://github.com/iiab/iiab/pull/3422 and #3516 +- name: Run command 'dpkg --print-architecture' to identify OS architecture (CPU arch as revealed by ansible_architecture ~= ansible_machine is NO LONGER enough!) + command: dpkg --print-architecture + register: dpkg_arch +- debug: + msg: "'dpkg --print-architecture' output: {{ dpkg_arch.stdout }}" - block: + - name: EXIT 'mongodb' ROLE, if 'dpkg --print-architecture' appears to be 32-bit (i.e. does not contain "64") or mongodb_version == "unsupported" or ansible_machine not found + fail: # FORCE IT RED THIS ONCE! + msg: MongoDB 3.2+ (as needed by Sugarizer Server 1.5.0) is NO LONGER SUPPORTED on 32-bit Raspberry Pi OS. + when: not dpkg_arch.stdout is search("64") or mongodb_version == "unsupported" or mongodb_version == "unknown" + #when: dpkg_arch.stdout == "armhf" or mongodb_version == "unsupported" or mongodb_version == "unknown" + - name: Install MongoDB if 'mongodb_installed' not defined, e.g. in {{ iiab_state_file }} # /etc/iiab/iiab_state.yml include_tasks: install.yml when: mongodb_installed is undefined diff --git a/roles/monit/tasks/install.yml b/roles/monit/tasks/install.yml index bc6173468..8d523c653 100644 --- a/roles/monit/tasks/install.yml +++ b/roles/monit/tasks/install.yml @@ -1,3 +1,8 @@ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: Install 'monit' package package: name: monit @@ -35,6 +40,17 @@ # RECORD Monit AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'monit_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: monit + option: monit_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'monit_installed: True'" set_fact: monit_installed: True diff --git a/roles/moodle/defaults/main.yml b/roles/moodle/defaults/main.yml index 6c3e6db16..a687dc4b4 100644 --- a/roles/moodle/defaults/main.yml +++ b/roles/moodle/defaults/main.yml @@ -8,11 +8,11 @@ # If nec, change them by editing /etc/iiab/local_vars.yml prior to installing! -# 2022-11-27: Currently testing Moodle's master branch is mandatory if your -# OS PHP >= 8.2, see moodle/tasks/install.yml for detail! OR, *IF* your -# OS PHP < 8.2, then {{ moodle_version }} will be attempted: -moodle_version: MOODLE_401_STABLE # Moodle 4.1 LTS -#moodle_version: master # e.g. to try Moodle's "weekly" 4.2dev pre-release *EVEN IF* OS PHP < 8.2 +# October 2024: Currently testing Moodle's main branch is mandatory if your +# OS PHP >= 8.4, see moodle/tasks/install.yml for detail! OR, *IF* your +# OS PHP < 8.4, then {{ moodle_version }} will be attempted: +moodle_version: MOODLE_405_STABLE # Moodle 4.5 +#moodle_version: main # e.g. to try Moodle's "weekly" 5.0dev pre-release *EVEN IF* OS PHP < 8.4 moodle_repo_url: https://github.com/moodle/moodle #moodle_repo_url: git://git.moodle.org/moodle.git # 2020-10-16: VERY Slow! diff --git a/roles/moodle/tasks/install.yml b/roles/moodle/tasks/install.yml index ec30d7f34..00cf13066 100644 --- a/roles/moodle/tasks/install.yml +++ b/roles/moodle/tasks/install.yml @@ -6,6 +6,20 @@ # 2021-06-28: This ALSO now happens in /etc/php/{{ php_version }}/cli/php.ini # (as required by Moodle's CLI installer, DESPITE it using fpm/php.ini later!) +# 2023-12-17: Upgrade instructions via CLI +# https://docs.moodle.org/en/Administration_via_command_line +# +# EXAMPLE: +# cd /opt/iiab/moodle +# sudo -u www-data /usr/bin/php admin/cli/maintenance.php --enable +# cd /opt/iiab +# mv moodle moodle.bkp +# git clone https://github.com/moodle/moodle -b MOODLE_403_STABLE --depth 1 # As a regular 'git pull' will likely fail, due to original clone's '--depth 1' -- but no worries: total clone download is just ~100 MB, which expands to ~400 MB +# cp moodle.bkp/config.php moodle/ +# cd moodle +# sudo -u www-data /usr/bin/php admin/cli/upgrade.php # Or later log in to Moodle, to complete the upgrade (i.e. click "Continue" 4-5 times) +# sudo -u www-data /usr/bin/php admin/cli/maintenance.php --disable + - name: "Set 'postgresql_install: True' and 'postgresql_enabled: True'" set_fact: @@ -17,6 +31,11 @@ name: postgresql +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + # 2021-07-02: Let's monitor & learn from these 2 pages year-by-year: # https://docs.moodle.org/19/en/PHP_settings_by_Moodle_version#PHP_Extensions_and_libraries # https://github.com/moodlebox/moodlebox/blob/master/roles/packages/vars/main.yml @@ -30,7 +49,7 @@ #- php{{ php_version }}-common # 2021-06-27: Auto-installed as an apt dependency. REGARDLESS: php{{ php_version }}-common superset php{{ php_version }}-cli is auto-installed by php{{ php_version }}-fpm in nginx/tasks/install.yml #- php{{ php_version }}-cli # 2021-06-27: Compare to php{{ php_version }}-common just above! 2020-06-15: In the past this included (below) mbstring? However this is not true on Ubuntu Server 20.04 LTS. - php{{ php_version }}-curl # 2021-06-27: Likewise installed in nextcloud/tasks/install.yml, pbx/tasks/freepbx_dependencies.yml, wordpress/tasks/install.yml - #- php{{ php_version }}-exif # 2022-11-27: Recommended by Moodle 4.1, required by Moodle 4.2 (for image metadata, rotation, etc?) apt package(s) NOT REQUIRED as it's somehow already installed with PHP's core, as confirmed by 'php -m' & 'php -i' on Ubuntu 22.04 and RasPiOS. + #- php{{ php_version }}-exif # 2022-11-27: Recommended by Moodle 4.1, possibly required by Moodle 4.2 (for image metadata, rotation, etc?) apt package(s) NOT REQUIRED as it's somehow already installed with PHP's core, as confirmed by 'php -m' & 'php -i' on Ubuntu 22.04 and RasPiOS. - php{{ php_version }}-gd # 2021-06-27: Likewise installed in nextcloud/tasks/install.yml, pbx/tasks/freepbx_dependencies.yml - php{{ php_version }}-intl # 2020-12-03: Required by Moodle 3.10+ -- Likewise installed in mediawiki/tasks/install.yml, nextcloud/tasks/install.yml, wordpress/tasks/install.yml - php{{ php_version }}-mbstring # 2020-06-15: Required by Moodle 3.9+ -- Likewise installed in mediawiki/tasks/install.yml, nextcloud/tasks/install.yml, pbx/tasks/freepbx_dependencies.yml, wordpress/tasks/install.yml @@ -49,21 +68,49 @@ when: php_settings_done is undefined -- name: "MOODLE PRE-RELEASE TESTING: Download (clone) {{ moodle_repo_url }} branch 'master' to {{ moodle_base }} (~389 MB initially, ~416 MB later) if OS PHP {{ php_version }} >= 8.2" - git: - repo: "{{ moodle_repo_url }}" # https://github.com/moodle/moodle - dest: "{{ moodle_base }}" # /opt/iiab/moodle - depth: 1 - version: master # For "weekly" Moodle pre-releases: https://download.moodle.org/releases/development/ (e.g. 3.5beta+ in May 2018, 4.1dev in Sept 2022, 4.2dev in Dec 2022) - when: php_version is version('8.2', '>=') +- name: Does /opt/iiab/moodle exist? + stat: + path: /opt/iiab/moodle + register: opt_iiab_moodle -- name: Download (clone) {{ moodle_repo_url }} branch '{{ moodle_version }}' to {{ moodle_base }} (~389 MB initially, ~416 MB later) if OS PHP {{ php_version }} < 8.2 +# 2023-04-30: Allows re-running (e.g. 'sudo iiab') if git clone was already +# begun, avoiding this error: (arises from 'www-data' ownership) +# "Failed to set a new url https://github.com/moodle/moodle for origin: +# fatal: detected dubious ownership in repository at '/opt/iiab/moodle' +# To add an exception for this directory, call: +# git config --global --add safe.directory /opt/iiab/moodle" + +- name: If /opt/iiab/moodle exists, move it to /tmp/opt-iiab-moodle.old (TO BE DELETED ON NEXT BOOT) -- allows re-running if git clone (below) was already begun + shell: rm -rf /tmp/opt-iiab-moodle.old && mv /opt/iiab/moodle /tmp/opt-iiab-moodle.old + when: opt_iiab_moodle.stat.exists + + +# WARNING: Since March 2023, 32-bit RasPiOS can act as 64-bit on RPi 4 and +# RPi 400 (unlike RPi 3!) SEE: https://github.com/iiab/iiab/pull/3516 +- name: Run command 'dpkg --print-architecture' to identify OS architecture (CPU arch as revealed by ansible_architecture ~= ansible_machine is NO LONGER enough!) + command: dpkg --print-architecture + register: dpkg_arch + +- name: "2023-04-30: MOODLE 4.2+ REQUIRES PHP 8 AND *FULL* 64-BIT OPERATION -- SO WE REVERT TO TRYING THE OLDER MOODLE 4.1 LTS WHEN NECESSARY -- NOTE PHP 7.x END-OF-LIFE WAS NOVEMBER 2022" + set_fact: + moodle_version: MOODLE_401_STABLE # i.e. Moodle 4.1 LTS + when: php_version is version('8.0', '<') or not dpkg_arch.stdout is search("64") + +- name: Download (clone) {{ moodle_repo_url }} branch '{{ moodle_version }}' to {{ moodle_base }} (~476 MB initially, ~504 MB later) if OS PHP {{ php_version }} < 8.4 git: repo: "{{ moodle_repo_url }}" # https://github.com/moodle/moodle dest: "{{ moodle_base }}" # /opt/iiab/moodle depth: 1 - version: "{{ moodle_version }}" # e.g. MOODLE_401_STABLE (Moodle 4.1) - when: php_version is version('8.2', '<') + version: "{{ moodle_version }}" # e.g. MOODLE_404_STABLE (Moodle 4.4) + when: php_version is version('8.4', '<') + +- name: "MOODLE PRE-RELEASE TESTING: Download (clone) {{ moodle_repo_url }} branch 'main' to {{ moodle_base }} (~476 MB initially, ~504 MB later) if OS PHP {{ php_version }} >= 8.4" + git: + repo: "{{ moodle_repo_url }}" + dest: "{{ moodle_base }}" + depth: 1 + version: main # For "weekly" Moodle pre-releases: https://download.moodle.org/releases/development/ (e.g. 3.5beta+ in May 2018, 4.1dev in Sept 2022, 4.2dev in Dec 2022, 4.3dev in May 2023, 4.4dev in Oct 2023, 4.5dev in Apr 2024, 5.0dev in Oct 2024) + when: php_version is version('8.4', '>=') - name: chown -R {{ apache_user }}:{{ apache_user }} {{ moodle_base }} (by default dirs 755 & files 644) file: @@ -141,7 +188,7 @@ # 2021-11-19: Resolves Moodle error https://github.com/iiab/iiab/issues/3024 - name: Set cron job to run /opt/iiab/moodle/admin/cli/cron.php every minute (* * * * *) in /var/spool/cron/crontabs/www-data -- per https://docs.moodle.org/310/en/Cron cron: - name: https://docs.moodle.org/310/en/Cron + name: https://docs.moodle.org/en/Cron user: www-data job: "/usr/bin/php /opt/iiab/moodle/admin/cli/cron.php >/dev/null" @@ -167,6 +214,17 @@ # RECORD Moodle AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'moodle_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: moodle + option: moodle_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'moodle_installed: True'" set_fact: moodle_installed: True diff --git a/roles/moodle/templates/moodle-nginx.conf.j2 b/roles/moodle/templates/moodle-nginx.conf.j2 index 135096c5b..f6077f50c 100644 --- a/roles/moodle/templates/moodle-nginx.conf.j2 +++ b/roles/moodle/templates/moodle-nginx.conf.j2 @@ -29,7 +29,7 @@ location ~ ^/moodle(.*)\.php(.*)$ { # Uncomment to override /etc/php//fpm/php.ini -- FYI Stage 4's # roles/www_options/tasks/main.yml FORCES these same settings and more # (equivalent to 'nginx_high_php_limits: True') when 'moodle_install: True' - #fastcgi_param PHP_VALUE "max_execution_time=300\n upload_max_filesize=500M\n post_max_size=500M\n max_input_vars=5000"; + #fastcgi_param PHP_VALUE "max_execution_time=300\n upload_max_filesize=10000M\n post_max_size=10000M\n max_input_vars=5000"; } location ~ ^/moodle { diff --git a/roles/mosquitto/tasks/install.yml b/roles/mosquitto/tasks/install.yml index 6ba7fd0d0..d4b7271a0 100644 --- a/roles/mosquitto/tasks/install.yml +++ b/roles/mosquitto/tasks/install.yml @@ -1,3 +1,8 @@ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: "Install packages: mosquitto, mosquitto-clients" package: name: "{{ item }}" @@ -32,6 +37,17 @@ # RECORD Mosquitto AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'mosquitto_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: mosquitto + option: mosquitto_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'mosquitto_installed: True'" set_fact: mosquitto_installed: True diff --git a/roles/munin/tasks/enable-or-disable.yml b/roles/munin/tasks/enable-or-disable.yml index 1b0d3ac28..fce74cae5 100644 --- a/roles/munin/tasks/enable-or-disable.yml +++ b/roles/munin/tasks/enable-or-disable.yml @@ -1,3 +1,9 @@ +# SEE ALSO roles/network/tasks/install.yml +- name: TEMPORARILY REVERT net.ipv6.conf.all.disable_ipv6 to 0 in /etc/sysctl.conf for #3434 + sysctl: + name: net.ipv6.conf.all.disable_ipv6 + value: 0 + - name: Enable & Start 'munin-node' systemd service systemd: name: munin-node @@ -6,6 +12,12 @@ state: started when: munin_enabled +# SEE ALSO roles/network/tasks/install.yml +- name: RESTORE net.ipv6.conf.all.disable_ipv6 to 1 in /etc/sysctl.conf for #3434 + sysctl: + name: net.ipv6.conf.all.disable_ipv6 + value: 1 + - name: Disable & Stop 'munin-node' systemd service systemd: name: munin-node diff --git a/roles/munin/tasks/install.yml b/roles/munin/tasks/install.yml index 7d439ff5a..89fe254cf 100644 --- a/roles/munin/tasks/install.yml +++ b/roles/munin/tasks/install.yml @@ -1,4 +1,15 @@ -- name: "Install 5 packages: libcgi-fast-perl, munin, munin-node, munin-plugins-extra, python3-passlib" +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + +# SEE ALSO roles/network/tasks/install.yml +- name: "TEMPORARILY REVERT net.ipv6.conf.all.disable_ipv6 to 0 in /etc/sysctl.conf for #3434" + sysctl: + name: net.ipv6.conf.all.disable_ipv6 + value: 0 + +- name: "Install 4 packages: libcgi-fast-perl, munin, munin-node, munin-plugins-extra" package: name: #- libapache2-mod-fcgid @@ -6,16 +17,28 @@ - munin - munin-node - munin-plugins-extra - - python3-passlib # For Ansible module 'htpasswd' in Ansible collection community.general -- used just below + #- python3-passlib # For Ansible module 'htpasswd' in Ansible collection community.general -- used just below state: present +- name: pip install 'passlib' into venv /usr/local/ansible -- for Ansible module 'htpasswd' in Ansible collection community.general -- used just below + pip: + name: passlib + virtualenv: /usr/local/ansible + extra_args: "--upgrade --no-cache-dir --prefer-binary" # 2023-10-01: Lifesaver when recent wheels (e.g. piwheels.org) are inevitably not yet built! SEE #3560 + +# SEE ALSO roles/network/tasks/install.yml +- name: RESTORE net.ipv6.conf.all.disable_ipv6 to 1 in /etc/sysctl.conf for #3434 + sysctl: + name: net.ipv6.conf.all.disable_ipv6 + value: 1 + - name: Establish username/password Admin/changeme in /etc/munin/munin-htpasswd htpasswd: path: /etc/munin/munin-htpasswd name: "{{ munin_username}}" # Admin password: "{{ munin_password }}" # changeme -- name: If MySQL is enabled, let Munin monitor it +- name: If MySQL is installed, let Munin monitor it copy: src: "{{ item }}" dest: /etc/munin/plugins/ @@ -27,11 +50,23 @@ - /usr/share/munin/plugins/mysql_queries - /usr/share/munin/plugins/mysql_slowqueries - /usr/share/munin/plugins/mysql_threads - when: mysql_enabled + when: mysql_installed + #when: mysql_enabled # RECORD Munin AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'munin_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: munin + option: munin_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'munin_installed: True'" set_fact: munin_installed: True diff --git a/roles/mysql/tasks/enable-or-disable.yml b/roles/mysql/tasks/enable-or-disable.yml new file mode 100644 index 000000000..ac06c0c8c --- /dev/null +++ b/roles/mysql/tasks/enable-or-disable.yml @@ -0,0 +1,15 @@ +- name: Enable & Start MySQL ({{ mysql_service }}) systemd service, if mysql_enabled + systemd: + name: "{{ mysql_service }}" + daemon_reload: yes + state: started + enabled: yes + when: mysql_enabled + +# We had to start MySQL in order to configure it, now turn if off if not enabled +- name: Disable & Stop MySQL ({{ mysql_service }}) systemd service, if not mysql_enabled + systemd: + name: "{{ mysql_service }}" + enabled: no + state: stopped + when: not mysql_enabled diff --git a/roles/mysql/tasks/install.yml b/roles/mysql/tasks/install.yml index ceff65c66..1b8a04388 100644 --- a/roles/mysql/tasks/install.yml +++ b/roles/mysql/tasks/install.yml @@ -1,13 +1,24 @@ -- name: 'Install MySQL packages: mariadb-server, mariadb-client, php{{ php_version }}-mysql, python3-pymysql' +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + +- name: 'Install MySQL packages: mariadb-server, mariadb-client, php{{ php_version }}-mysql' package: name: - mariadb-server - mariadb-client #- php{{ php_version }}-common # Auto-installed as an apt dependency. REGARDLESS: php{{ php_version }}-common superset php{{ php_version }}-cli is auto-installed by php{{ php_version }}-fpm in nginx/tasks/install.yml - php{{ php_version }}-mysql # Likewise installed in nextcloud/tasks/install.yml, pbx/tasks/freepbx.yml, wordpress/tasks/install.yml - - python3-pymysql # For Ansible modules {mysql_db, mysql_user} in Ansible collection community.mysql -- used in MySQL roles {mediawiki, nextcloud, wordpress} and possibly {elgg, pbx} + #- python3-pymysql # For Ansible modules {mysql_db, mysql_user} in Ansible collection community.mysql -- used in MySQL roles {mediawiki, nextcloud, wordpress} and possibly {elgg, pbx} state: present +- name: pip install 'PyMySQL' into venv /usr/local/ansible -- for Ansible modules {mysql_db, mysql_user} in Ansible collection community.mysql -- used in roles {mediawiki, nextcloud, wordpress, matomo, pbx} + pip: + name: PyMySQL + virtualenv: /usr/local/ansible + extra_args: "--upgrade --no-cache-dir --prefer-binary" # 2023-10-01: Lifesaver when recent wheels (e.g. piwheels.org) are inevitably not yet built! SEE #3560 + # 2020-07-11: 10 PHP package installs moved to roles/www_base/tasks/main.yml # php{{ php_version }}-sqlite3 install moved to roles/osm-vector-maps/tasks/install.yml @@ -61,6 +72,17 @@ # RECORD MySQL AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'mysql_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: mysql + option: mysql_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'mysql_installed: True'" set_fact: mysql_installed: True diff --git a/roles/mysql/tasks/main.yml b/roles/mysql/tasks/main.yml index 789d406c1..d91bbce14 100644 --- a/roles/mysql/tasks/main.yml +++ b/roles/mysql/tasks/main.yml @@ -26,40 +26,33 @@ var: mysql_installed -- name: Install MySQL if 'mysql_installed' not defined, e.g. in {{ iiab_state_file }} # /etc/iiab/iiab_state.yml - include_tasks: install.yml - when: mysql_installed is undefined +- block: + - name: Install MySQL if 'mysql_installed' not defined, e.g. in {{ iiab_state_file }} # /etc/iiab/iiab_state.yml + include_tasks: install.yml + when: mysql_installed is undefined -- name: Enable & Start MySQL ({{ mysql_service }}) systemd service, if mysql_enabled - systemd: - name: "{{ mysql_service }}" - daemon_reload: yes - state: started - enabled: yes - when: mysql_enabled + - include_tasks: enable-or-disable.yml -# We had to start MySQL in order to configure it, now turn if off if not enabled -- name: Disable & Stop MySQL ({{ mysql_service }}) systemd service, if not mysql_enabled - systemd: - name: "{{ mysql_service }}" - enabled: no - state: stopped - when: not mysql_enabled + - name: Add 'mysql' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: mysql + option: "{{ item.option }}" + value: "{{ item.value | string }}" + with_items: + - option: name + value: MySQL + - option: description + value: '"MySQL is a widely used free and open source (GPLv2) database, offered by most web hosting services, on a diversity of platforms."' + - option: mysql_install + value: "{{ mysql_install }}" + - option: mysql_enabled + value: "{{ mysql_enabled }}" + rescue: -- name: Add 'mysql' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini - section: mysql - option: "{{ item.option }}" - value: "{{ item.value | string }}" - with_items: - - option: name - value: MySQL - - option: description - value: '"MySQL is a widely used free and open source (GPLv2) database, offered by most web hosting services, on a diversity of platforms."' - - option: mysql_install - value: "{{ mysql_install }}" - - option: mysql_enabled - value: "{{ mysql_enabled }}" + - name: 'SEE ERROR ABOVE (skip_role_on_error: {{ skip_role_on_error }})' + fail: + msg: "" + when: not skip_role_on_error diff --git a/roles/network/defaults/main.yml b/roles/network/defaults/main.yml index 82de51aff..593f14922 100644 --- a/roles/network/defaults/main.yml +++ b/roles/network/defaults/main.yml @@ -55,7 +55,7 @@ strict_networking: False iiab_demo_mode: False gui_static_wan: False wan_cidr: "" -virtual_network_devices: "-e wwlan -e ppp -e ap0 -e lo -e br0 -e tun -e br- -e docker -e bridge0 -e veth" +virtual_network_devices: "-e wwlan -e ppp -e ap0 -e lo -e br0 -e tun -e br- -e docker -e bridge0 -e veth -e tailscale0" # Set defaults for discovery process as strings wifi1: "not found-1" @@ -71,6 +71,8 @@ iiab_lan_iface: none discovered_lan_iface: none discovered_wired_iface: none discovered_wireless_iface: none +# use the same case as what `iw reg get` would return with 00 present +host_country_code_found: UNSET # Red Hat #iiab_wired_lan_iface: "none" diff --git a/roles/network/tasks/NM-debian.yml b/roles/network/tasks/NM-debian.yml index d5dad9ffc..a0af7adcc 100644 --- a/roles/network/tasks/NM-debian.yml +++ b/roles/network/tasks/NM-debian.yml @@ -22,7 +22,7 @@ dest: /etc/NetworkManager/conf.d/ap0-manage.conf src: network/ap0-manage.conf mode: 0644 - when: wifi_up_down + when: discovered_wireless_iface != "none" and wifi_up_down - name: Copy manage.conf for NetworkManager when wifi_up_down False template: @@ -71,13 +71,14 @@ when: wan_ip != "dhcp" - name: Use systemd-networkd to handle br0 - include_tasks: sysd-netd-debian.yml - when: iiab_lan_iface == "br0" and not systemd_networkd_active + set_fact: + systemd_networkd_active: True + when: iiab_lan_iface == "br0" - name: Reload systemd systemd: daemon_reload: yes - when: not iiab_lan_iface == "br0" + when: not no_net_restart or not iiab_lan_iface == "br0" - name: Restart the NetworkManager service systemd: diff --git a/roles/network/tasks/computed_services.yml b/roles/network/tasks/computed_services.yml index 9527ed7d3..2a113ce15 100644 --- a/roles/network/tasks/computed_services.yml +++ b/roles/network/tasks/computed_services.yml @@ -81,22 +81,3 @@ value: "{{ dnsmasq_enabled }}" - option: no_net_restart value: "{{ no_net_restart }}" - - option: hostapd_enabled - value: "{{ hostapd_enabled }}" - - option: host_ssid - value: "{{ host_ssid }}" - - option: host_wifi_mode - value: "{{ host_wifi_mode }}" - - option: host_channel - value: "{{ host_channel }}" - -- name: Add 'network' variable 'current_client_channel' value if defined, to {{ iiab_ini_file }} - ini_file: - dest: "{{ iiab_ini_file }}" - section: network - option: "{{ item.option }}" - value: "{{ item.value | string }}" - with_items: - - option: client_wifi_channel - value: "{{ current_client_channel.stdout }}" - when: current_client_channel.stdout is defined diff --git a/roles/network/tasks/detected_network.yml b/roles/network/tasks/detected_network.yml index 0fe997598..c72028d53 100644 --- a/roles/network/tasks/detected_network.yml +++ b/roles/network/tasks/detected_network.yml @@ -239,6 +239,41 @@ iiab_lan_iface: "{{ iiab_wireless_lan_iface }}" when: iiab_wireless_lan_iface is defined and nobridge is defined +- name: Detect WiFi country code in use + shell: iw reg get | grep country | grep -v UNSET | awk '{print $2}' | sed "s|:||" + register: REG_DOM + ignore_errors: True + +- name: Set host_country_code_found + set_fact: + host_country_code_found: "{{ REG_DOM.stdout }}" + when: REG_DOM.stdout is defined and REG_DOM.stdout | length > 0 + +- name: Set Wifi Region country to {{ REG_DOM.stdout }} for hostapd when present + set_fact: + host_country_code: "{{ REG_DOM.stdout }}" + when: REG_DOM.stdout is defined and REG_DOM.stdout | length > 0 and wifi_up_down and can_be_ap and has_wifi_gateway is defined + +- name: Detect current Wifi channel + shell: iw {{ discovered_wireless_iface }} info | grep channel | cut -d' ' -f2 + register: current_client_channel + when: wifi_up_down and can_be_ap and has_wifi_gateway is defined + +- name: Forcing wifi_up_down to False based on firmware selection "24" + set_fact: + wifi_up_down: False + when: rpi3bplus_rpi4_wifi_firmware == "24" + +- name: Detect "Firmware rejected country setting" in dmesg (invert return code, for intentional red error) + shell: '! dmesg | grep ieee80211 | grep "Firmware rejected country setting"' + register: FW_rejected_country + ignore_errors: True + +- name: Detect country code passed from cmdline in dmesg + shell: dmesg | grep -om1 'cfg80211\.ieee80211_regdom=\S*' | cut -d= -f2 + register: cmdline_country_code + ignore_errors: True + - name: In VM disable LAN - needs local_vars entry to activate set_fact: iiab_lan_iface: none @@ -295,6 +330,36 @@ value: "{{ iiab_wan_iface }}" - option: can_be_ap value: "{{ can_be_ap }}" + - option: host_country_code_found + value: "{{ host_country_code_found }}" + - option: wifi_firmware_43430 + value: "{{ rpizerow_rpi3_wifi_firmware }}" + - option: wifi_firmware_43455 + value: "{{ rpi3bplus_rpi4_wifi_firmware }}" + +- name: Add 'detected_network' variable 'current_client_channel_found' stdout value ({{ current_client_channel.stdout }}) if defined and non-empty, to {{ iiab_ini_file }} + ini_file: + dest: "{{ iiab_ini_file }}" + section: detected_network + option: client_wifi_channel_found + value: "{{ current_client_channel.stdout }}" + when: current_client_channel.stdout is defined and current_client_channel.stdout != "" + +- name: Add 'detected_network' variable 'FW_rejected_country' stdout value ({{ FW_rejected_country.stdout }}) if defined and non-empty, to {{ iiab_ini_file }} + ini_file: + dest: "{{ iiab_ini_file }}" + section: detected_network + option: FW_rejected_country + value: "{{ FW_rejected_country.stdout }}" + when: FW_rejected_country.stdout is defined and FW_rejected_country.stdout != "" + +- name: Add 'detected_network' variable 'cmdline_country_code' stdout value ({{ cmdline_country_code.stdout }}) if defined and non-empty, to {{ iiab_ini_file }} + ini_file: + dest: "{{ iiab_ini_file }}" + section: detected_network + option: cmdline_country_code + value: "{{ cmdline_country_code.stdout }}" + when: cmdline_country_code.stdout is defined and cmdline_country_code.stdout != "" # well if there ever was a point to tell the user things are FUBAR this is it. # limit 2 network adapters wifi wired diff --git a/roles/network/tasks/hostapd.yml b/roles/network/tasks/hostapd.yml index 3df0f2c36..c845bd637 100644 --- a/roles/network/tasks/hostapd.yml +++ b/roles/network/tasks/hostapd.yml @@ -3,17 +3,12 @@ hostapd_enabled: False when: (not wifi_up_down and discovered_wireless_iface == iiab_wan_iface) or discovered_wireless_iface == "none" or not can_be_ap -- name: Disable the Access Point 'hostapd' service +- name: Disable the Access Point 'hostapd' service if hostapd_enabled False systemd: name: hostapd enabled: no when: not hostapd_enabled -- name: Detect current Wifi channel - shell: iw {{ discovered_wireless_iface }} info | grep channel | cut -d' ' -f2 - register: current_client_channel - when: discovered_wireless_iface != "none" - - name: Setting WiFi channel to {{ current_client_channel.stdout }} set_fact: host_channel: "{{ current_client_channel.stdout }}" @@ -88,3 +83,35 @@ regexp: '^HOSTAPD_ENABLED=*' line: 'HOSTAPD_ENABLED={{ hostapd_enabled }}' state: present + +- name: Create /etc/hostapd/hostapd.conf and backup .iiab from template if needed + template: + owner: root + group: root + mode: 0644 + src: "{{ item.src }}" + dest: "{{ item.dest }}" + with_items: + - { src: 'hostapd/hostapd.conf.j2', dest: '/etc/hostapd/hostapd.conf' } + - { src: 'hostapd/hostapd.conf.j2', dest: '/etc/hostapd/hostapd.conf.iiab' } + when: can_be_ap + +- name: Record host_country_code_applied and host_channel in network of {{ iiab_ini_file }} + ini_file: + dest: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: network + option: "{{ item.option }}" + value: "{{ item.value | string }}" + with_items: + - option: hostapd_enabled + value: "{{ hostapd_enabled }}" + - option: host_ssid + value: "{{ host_ssid }}" + - option: host_wifi_mode + value: "{{ host_wifi_mode }}" + - option: wifi_up_down + value: "{{ wifi_up_down }}" + - option: host_country_code_applied + value: "{{ host_country_code }}" + - option: host_channel + value: "{{ host_channel }}" diff --git a/roles/network/tasks/install.yml b/roles/network/tasks/install.yml index 08a749707..f7c1a5b9a 100644 --- a/roles/network/tasks/install.yml +++ b/roles/network/tasks/install.yml @@ -1,3 +1,8 @@ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + # 2022-03-16: 'apt show | grep Size' revealed download sizes, on 64-bit RasPiOS with desktop. - name: Install dnsmasq -- configure LATER in 'network', after Stage 9 @@ -13,7 +18,7 @@ # total download size) and they can help IIAB field operators with BOTH # (1) internal WiFi AND (2) USB WiFi devices inserted anytime/later. -- name: 'Install 12 network packages: avahi-daemon, hostapd, iproute2, iptables-persistent, iw, libnss-mdns, netmask, net-tools, networkd-dispatcher, rfkill, wireless-tools, wpasupplicant -- later used by https://github.com/iiab/iiab/tree/master/roles/network' +- name: 'Install 11 network packages: avahi-daemon, hostapd, iproute2, iptables-persistent, iw, libnss-mdns, netmask, net-tools, networkd-dispatcher, rfkill, wpasupplicant -- later used by https://github.com/iiab/iiab/tree/master/roles/network' package: name: - avahi-daemon # 97kB download: RasPiOS (and package libnss-mnds, below) install this regardless -- holdover from the XO days and used to advertise ssh/admin-console being available via avahi-daemon -- used with https://github.com/iiab/iiab/blob/master/roles/network/tasks/avahi.yml @@ -26,12 +31,19 @@ - libnss-mdns # 27kB download: RasPiOS (and package avahi-daemon, above) install this regardless -- client-side library -- provides name resolution via mDNS (Multicast DNS) using Zeroconf/Bonjour e.g. Avahi - netmask # 25kB download: Handy utility -- helps determine network masks - net-tools # 248kB download: RasPiOS installs this regardless -- @jvonau suggests possibly deleting this...unless oldtimers really want these older commands in iiab-diagnostics output? - - networkd-dispatcher # 15kB download: Dispatcher service for systemd-networkd connection status changes - rfkill # 87kB download: RasPiOS installs this regardless -- enable & disable wireless devices - - wireless-tools # 112kB download: RasPiOS installs this regardless -- manipulate Linux Wireless Extensions - wpasupplicant # 1188kB download: RasPiOS installs this regardless -- client library for connections to a WiFi AP state: present +# 2024-10-02: Legacy apt package 'wireless-tools' no longer offered by Ubuntu +# 24.10+ (#3805) but FYI: https://en.wikipedia.org/wiki/Wireless_tools_for_Linux +- name: "Install legacy apt package wireless-tools, if OS still supports it -- or intentionally show (HARMLESS!) red error -- helping to monitor Linux's evolution" + package: + name: wireless-tools # 112kB download: RasPiOS installs this regardless -- manipulate Linux Wireless Extensions + state: present + ignore_errors: True # Intentionally show red error, and continue. + #failed_when: False # Hides red errors (stronger than 'ignore_errors: yes') + # 2021-08-17: Debian ignores this, according to 2013 post: # https://serverfault.com/questions/511099/debian-ignores-etc-network-if-pre-up-d-iptables # - name: Install /etc/network/if-pre-up.d/iptables from template (0755) @@ -55,11 +67,11 @@ name: "{{ item.name }}" value: "{{ item.value }}" with_items: - - { name: 'net.ipv4.ip_forward', value: '1' } # Masquerading LAN->Internet - - { name: 'net.ipv4.conf.default.rp_filter', value: '1' } - - { name: 'net.ipv4.conf.default.accept_source_route', value: '0' } - #- { name: 'net.ipv4.tcp_syncookies', value: '1' } # Very standard in 2020 - - { name: 'net.ipv6.conf.all.disable_ipv6', value: '1' } # IPv6 disabled + - { name: 'net.ipv4.ip_forward', value: '1' } # Default: 0. Masquerading LAN->Internet + - { name: 'net.ipv4.conf.default.rp_filter', value: '1' } # Default: 2. Enable Spoof protection (reverse-path filter) + - { name: 'net.ipv4.conf.default.accept_source_route', value: '0' } # Default: 1. Do not accept IP source route packets (we are not a router) + #- { name: 'net.ipv4.tcp_syncookies', value: '1' } # Very standard in 2020 + - { name: 'net.ipv6.conf.all.disable_ipv6', value: '1' } # Default: 0. Disable IPv6. SEE ALSO: roles/munin/tasks/install.yml & enable-and-disable.yml #- { name: 'net.ipv6.conf.default.disable_ipv6', value: '1' } # AUTO-SET #- { name: 'net.ipv6.conf.lo.disable_ipv6', value: '1' } # BY ABOVE @@ -95,12 +107,23 @@ - roles/network/templates/gateway/iiab-internet-on # Invoked by 1-prep (so full path needed) - roles/network/templates/gateway/iiab-internet-off # Invoked by 1-prep (so full path needed) -- name: 'Install /usr/local/sbin/netwarn for pop-ups on boot, if iiab-network should be run' +- name: 'Install /usr/local/sbin/iiab-netwarn for pop-ups on boot, if iiab-network should be run' include_tasks: roles/network/tasks/netwarn.yml # Invoked by 1-prep (so full path needed) # RECORD Network AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'network_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: network + option: network_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'network_installed: True'" set_fact: network_installed: True diff --git a/roles/network/tasks/main.yml b/roles/network/tasks/main.yml index f00939911..bb05482f5 100644 --- a/roles/network/tasks/main.yml +++ b/roles/network/tasks/main.yml @@ -1,8 +1,3 @@ -- name: Select RPi firmware mode - include_role: - name: firmware - when: rpi_model != "none" - - name: detected_network include_tasks: detected_network.yml @@ -61,8 +56,6 @@ # when: squid_install and FQDN_changed and iiab_stage|int == 9 #### Start services - - name: hostapd - include_tasks: hostapd.yml - name: computed_services include_tasks: computed_services.yml - name: enable_services @@ -70,6 +63,13 @@ #### End services #### Start network layout + + # 2024-12-18: As `rfkill unblock wifi` formerly in rpi_debian.yml wasn't enough, especially with NM (NetworkManager) + - name: Run 'raspi-config nonint do_wifi_country {{ host_country_code }}' (using var host_country_code) to unblock WiFi, if RasPiOS + command: raspi-config nonint do_wifi_country {{ host_country_code }} + when: is_raspbian + #ignore_errors: True + #- name: Redhat networking # include_tasks: ifcfg_mods.yml # when: is_redhat @@ -77,13 +77,13 @@ - name: NetworkManager in use include_tasks: NM-debian.yml when: network_manager_active - #when: is_debuntu and network_manager_active - name: systemd-networkd in use include_tasks: sysd-netd-debian.yml when: systemd_networkd_active - #when: is_debuntu and systemd_networkd_active + #when: systemd_networkd_active and not network_manager_active # 2023-10-11: NOT the right way to solve #3657 (systemd-resolved issue on RasPiOS 12+) as this would damage Ubuntu/Mint. + # 2023-10-11: Should rpi_debian.yml go away in future, now that RasPiOS Bookworm uses NetworkManager? - name: Raspbian can use dhcpcd only with no N-M or SYS-NETD active include_tasks: rpi_debian.yml when: is_raspbian and not network_manager_active @@ -94,12 +94,20 @@ #when: (not is_raspbian and not network_manager_active and not systemd_networkd_active and is_debuntu) or is_ubuntu_16 #### end network layout + - name: hostapd + include_tasks: hostapd.yml + - name: Restart services include_tasks: restart.yml # end block when: network_installed is defined and network_enabled +- name: Select RPi firmware mode + include_role: + name: firmware + when: rpi_model != "none" + - name: Create {{ iiab_etc_path }}/install-flags/iiab-network-complete on second pass of network role. file: diff --git a/roles/network/tasks/netwarn.yml b/roles/network/tasks/netwarn.yml index c1f687e28..78aae19be 100644 --- a/roles/network/tasks/netwarn.yml +++ b/roles/network/tasks/netwarn.yml @@ -1,21 +1,21 @@ # 2022-07-22: SIMILAR TO roles/iiab-admin/tasks/pwd-warnings.yml FOR passwords # AND roles/www_options/tasks/main.yml FOR browser -# 2022-07-22: An /etc/profile.d/ version like /etc/local/sbin/netwarn but for -# ssh sessions (across all OS's/distros/window managers) might also make sense? +# 2022-07-22: An /etc/profile.d/ version like /etc/local/sbin/iiab-netwarn but for +# shell / ssh logins (across all OS's/distros/window managers) might also make sense? -- name: Does /etc/xdg/lxsession/LXDE-pi/autostart exist? +- name: Does directory /home/{{ iiab_admin_user }}/.config/labwc/ exist? stat: - path: /etc/xdg/lxsession/LXDE-pi/autostart - register: lxde_pi_autostart_present + path: /home/{{ iiab_admin_user }}/.config/labwc/ + register: labwc_dir -- name: If so, add /usr/local/sbin/netwarn to /etc/xdg/lxsession/LXDE-pi/autostart +- name: If so, add '/usr/local/sbin/iiab-netwarn &' to /home/{{ iiab_admin_user }}/.config/labwc/autostart lineinfile: - path: /etc/xdg/lxsession/LXDE-pi/autostart - regexp: '^/usr/local/sbin/netwarn$' - line: '/usr/local/sbin/netwarn' - when: lxde_pi_autostart_present.stat.exists + path: /home/{{ iiab_admin_user }}/.config/labwc/autostart # iiab-admin + create: yes + line: '/usr/local/sbin/iiab-netwarn &' + when: labwc_dir.stat.exists and labwc_dir.stat.isdir # mate desktop detection based on 'register: nd_dir' in enable_services @@ -39,9 +39,9 @@ # (Let's insert those here if so, and refine the 'when:' line below.) -- name: 'If a supported graphical OS is detected, install from template: /usr/local/sbin/netwarn' +- name: 'If a supported graphical OS is detected, install from template: /usr/local/sbin/iiab-netwarn' template: - src: roles/network/templates/netwarn/netwarn # Invoked by 1-prep (so full path needed) + src: roles/network/templates/netwarn/iiab-netwarn # Invoked by 1-prep (so full path needed) dest: /usr/local/sbin/ mode: 0755 - when: lxde_pi_autostart_present or (mate_dir.stat.exists and mate_dir.stat.isdir) + when: (labwc_dir.stat.exists and labwc_dir.stat.isdir) or (mate_dir.stat.exists and mate_dir.stat.isdir) diff --git a/roles/network/tasks/restart.yml b/roles/network/tasks/restart.yml index 1576a2af3..d5de9e27d 100644 --- a/roles/network/tasks/restart.yml +++ b/roles/network/tasks/restart.yml @@ -12,26 +12,32 @@ state: restarted with_items: - wpa_supplicant - when: wifi_up_down and hostapd_enabled + when: wifi_up_down and hostapd_enabled and not network_manager_active -- name: Create /etc/hostapd/hostapd.conf and backup .iiab from template if needed - template: - owner: root - group: root - mode: 0644 - src: "{{ item.src }}" - dest: "{{ item.dest }}" - with_items: - - { src: 'hostapd/hostapd.conf.j2', dest: '/etc/hostapd/hostapd.conf' } - - { src: 'hostapd/hostapd.conf.j2', dest: '/etc/hostapd/hostapd.conf.iiab' } - when: can_be_ap +- name: Enable & Restart networkd-dispatcher.service + systemd: + name: networkd-dispatcher + state: restarted + enabled: yes + masked: no + when: systemd_networkd_active -- name: Restart hostapd when WiFi is present but not when using WiFi as gateway with wifi_up_down False +- name: Clone wifi if needed + systemd: + name: iiab-clone-wifi + state: restarted + when: wifi_up_down and can_be_ap and ansible_ap0 is undefined + +- name: Waiting {{ hostapd_wait }} seconds for network to stabilize for ap0 + shell: sleep {{ hostapd_wait }} + when: ansible_ap0 is undefined + +- name: Restart hostapd when WiFi is present but not when using WiFi as gateway systemd: name: hostapd state: restarted daemon_reload: yes - when: hostapd_enabled and (wifi_up_down or not no_net_restart) + when: hostapd_enabled and not no_net_restart # 2022-07-22: @jvonau suggests commenting this out as: "we really don't touch # any of the config files... netplan.yml renames one file if it's a container @@ -105,7 +111,7 @@ systemd: name: hostapd state: restarted - when: hostapd_enabled and wifi_slave.stdout is defined and wifi_slave.stdout == 0 + when: hostapd_enabled and not no_net_restart and wifi_slave.stdout is defined and wifi_slave.stdout == 0 #both interfaces.d and systemd-networkd should have br0 available and Appliance lacks br0 #keep an eye on legacy wifi installs where br0 is present but not 'online' with an ip address diff --git a/roles/network/tasks/rpi_debian.yml b/roles/network/tasks/rpi_debian.yml index 4dbcd97ee..e85c673dd 100644 --- a/roles/network/tasks/rpi_debian.yml +++ b/roles/network/tasks/rpi_debian.yml @@ -39,22 +39,25 @@ shell: grep country /etc/wpa_supplicant/wpa_supplicant.conf | awk -F = '{print $2}' register: country_code ignore_errors: True + when: wifi_up_down and can_be_ap - name: Set country code for hostapd to value found in /etc/wpa_supplicant/wpa_supplicant.conf set_fact: host_country_code: "{{ country_code.stdout }}" - when: country_code is defined and country_code.stdout | length > 0 + when: country_code.stdout is defined and country_code.stdout | length > 0 - name: Put country code ({{ host_country_code }}) in /etc/wpa_supplicant/wpa_supplicant.conf if nec lineinfile: path: /etc/wpa_supplicant/wpa_supplicant.conf regexp: "^country.*" line: country={{ host_country_code }} - when: country_code is defined and country_code.stdout | length == 0 + when: country_code.stdout is defined and country_code.stdout | length == 0 -- name: Enable the WiFi with rfkill - shell: rfkill unblock 0 - ignore_errors: True +# 2024-12-18: SEE 'raspi-config nonint do_wifi_country {{ host_country_code }}' in roles/network/tasks/main.yml +# # This should go away, should only be unblocked by raspi-config +# - name: Enable the WiFi with rfkill +# shell: rfkill unblock wifi +# ignore_errors: True - name: Copy the bridge script for RPi template: @@ -76,12 +79,6 @@ systemd: daemon_reload: yes -- name: Clone wifi if needed - systemd: - name: iiab-clone-wifi - state: restarted - when: wifi_up_down and can_be_ap and ansible_ap0 is undefined - - name: Restart the networking service if appropriate systemd: name: networking diff --git a/roles/network/tasks/sysd-netd-debian.yml b/roles/network/tasks/sysd-netd-debian.yml index f1b860d85..9868d5b96 100644 --- a/roles/network/tasks/sysd-netd-debian.yml +++ b/roles/network/tasks/sysd-netd-debian.yml @@ -1,4 +1,20 @@ # sysd-netd-debian.yml +- name: Install networkd-dispatcher + package: + name: networkd-dispatcher # 15kB download: Dispatcher service for systemd-networkd connection status changes + +# 2023-10-14 #3657, #3658, #3659: New RasPiOS 12/Bookworm issue. +# FWIW Ubuntu >= 22.10 offers 'systemd-resolved' as a distinct apt package. +# Whereas Ubuntu <= 22.04 bundled the functionality within apt package 'systemd' +# Debian 12/Bookworm (like Ubuntu >= 22.10) offers it as a distinct package: +# https://www.debian.org/releases/bookworm/amd64/release-notes/ch-information.en.html#systemd-resolved +- name: Install systemd-resolved (or intentionally show red error then continue, if apt package not available) + package: + name: systemd-resolved # 278kB download: For RasPiOS 12/Bookworm + ignore_errors: yes + #shell: apt -y install systemd-resolved || true + #when: is_raspbian and os_ver is version('raspbian-12', '>=') + - name: Copy the bridge script - Creates br0 template: dest: /etc/systemd/network/IIAB-Bridge.netdev @@ -87,12 +103,6 @@ systemd: daemon_reload: yes -- name: Clone wifi if needed - systemd: - name: iiab-clone-wifi - state: restarted - when: wifi_up_down and can_be_ap and ansible_ap0 is undefined - - name: Enable & Restart systemd-networkd.service systemd: name: systemd-networkd @@ -106,10 +116,3 @@ state: restarted enabled: yes masked: no - -- name: Enable & Restart networkd-dispatcher.service - systemd: - name: networkd-dispatcher - state: restarted - enabled: yes - masked: no diff --git a/roles/network/templates/gateway/iiab-gen-iptables b/roles/network/templates/gateway/iiab-gen-iptables index b11cd4fca..77717a748 100755 --- a/roles/network/templates/gateway/iiab-gen-iptables +++ b/roles/network/templates/gateway/iiab-gen-iptables @@ -34,12 +34,12 @@ IPTABLES=/usr/sbin/iptables IPTABLES_DATA=/etc/sysconfig/iptables {% endif %} -# 2021-08-18: bash scripts using default_vars.yml &/or local_vars.yml +# 2023-02-25: bash scripts using default_vars.yml &/or local_vars.yml # https://github.com/iiab/iiab-factory/blob/master/iiab # https://github.com/iiab/iiab/blob/master/roles/firmware/templates/iiab-check-firmware#L10-14 # https://github.com/iiab/iiab/blob/master/roles/network/templates/gateway/iiab-gen-iptables#L48-L52 -# https://github.com/iiab/maps/blob/master/osm-source/pages/viewer/scripts/iiab-install-map-region#L25-L34 -# https://github.com/iiab/iiab/blob/master/roles/openvpn/templates/iiab-support READS AND WRITES, INCL NON-BOOLEAN +# https://github.com/iiab/maps/blob/master/osm-source/pages/viewer/scripts/iiab-install-map-region#L23-L39 +# https://github.com/iiab/iiab/blob/master/roles/0-DEPRECATED-ROLES/openvpn/templates/iiab-support READS AND WRITES, INCL NON-BOOLEAN # "awk '{print $2}'" almost works, but: (1) Fails to remove outer quotes, and # (2) Chops up Ansible vars containing multiple words w/o surrounding quotes. diff --git a/roles/network/templates/hostapd/iiab-hotspot-off b/roles/network/templates/hostapd/iiab-hotspot-off index eb5951c6b..fb45603a6 100755 --- a/roles/network/templates/hostapd/iiab-hotspot-off +++ b/roles/network/templates/hostapd/iiab-hotspot-off @@ -3,7 +3,7 @@ echo -e "Networking role disabled\n" echo -e "For details, see: https://github.com/iiab/iiab/pull/3302\n" {% else %} -sed -i -e "s/^HOSTAPD_ENABLED.*/HOSTAPD_ENABLED=False/" {{ iiab_env_file }} +sed -i "s/^HOSTAPD_ENABLED.*/HOSTAPD_ENABLED=False/" {{ iiab_env_file }} systemctl disable hostapd systemctl stop hostapd {% if wifi_up_down %} @@ -11,13 +11,12 @@ systemctl disable iiab-clone-wifi.service systemctl disable iiab-wifi-test.service systemctl stop iiab-clone-wifi.service echo " IIAB hotspot access point Disabled" -exit 0 +#exit 0 {% else %} -{% if is_raspbian %} +echo " IIAB hotspot access point Disabled" +{% if dhcpcd_result == "enabled" %} # hotspot-off before ap0_updown -sed -i -e "s/^denyinterfaces/#denyinterfaces/" /etc/dhcpcd.conf -systemctl disable hostapd -systemctl stop hostapd +sed -i "s/^denyinterfaces/#denyinterfaces/" /etc/dhcpcd.conf #systemctl disable dnsmasq #systemctl stop dnsmasq systemctl daemon-reload @@ -31,13 +30,15 @@ systemctl restart dhcpcd # ip link set dev wlan0 promisc on #fi {% else %} -#ubuntu +#ubuntu (or Mint, or pure Debian?) if [ -f /etc/NetworkManager/conf.d/wifi-manage.conf ]; then - sed -i -e "s|managed=0|managed=1|" /etc/NetworkManager/conf.d/wifi-manage.conf + sed -i "s|managed=0|managed=1|" /etc/NetworkManager/conf.d/wifi-manage.conf fi -echo -e "\nPlease reboot to enable upstream WiFi access.\n" -exit 0 +echo -e "\nIf you're enabling upstream WiFi, please reboot now.\n" +#exit 0 +{% endif %} +#if dhcpcd_result == "enabled" {% endif %} #wifi_up_down {% endif %} -{% endif %} +#network_enabled diff --git a/roles/network/templates/hostapd/iiab-hotspot-on b/roles/network/templates/hostapd/iiab-hotspot-on index 04d551774..35ccc7adf 100755 --- a/roles/network/templates/hostapd/iiab-hotspot-on +++ b/roles/network/templates/hostapd/iiab-hotspot-on @@ -9,18 +9,17 @@ echo -e "If you add Wi-Fi hardware, run 'cd /opt/iiab/iiab' then 'sudo ./iiab-ne echo -e "For details, see: https://github.com/iiab/iiab/pull/3179\n" exit 1 {% else %} -sed -i -e "s/^HOSTAPD_ENABLED.*/HOSTAPD_ENABLED=True/" {{ iiab_env_file }} +sed -i "s/^HOSTAPD_ENABLED.*/HOSTAPD_ENABLED=True/" {{ iiab_env_file }} {% if wifi_up_down %} systemctl enable iiab-clone-wifi.service systemctl enable hostapd systemctl enable iiab-wifi-test.service -echo -e "\nPlease reboot to activate hostapd feature.\n" -exit 0 +#exit 0 {% else %} -{% if is_raspbian %} +{% if dhcpcd_result == "enabled" %} # just do what we have always done in hotspot-on cp -f /etc/hostapd/hostapd.conf.iiab /etc/hostapd/hostapd.conf -sed -i -e "s/^#denyinterfaces/denyinterfaces/" /etc/dhcpcd.conf +sed -i "s/^#denyinterfaces/denyinterfaces/" /etc/dhcpcd.conf # shut down wlan0 in case connected to network ip link set wlan0 down systemctl enable hostapd @@ -38,15 +37,19 @@ systemctl start dnsmasq # ip link set dev wlan0 promisc off #fi {% else %} -#ubuntu +#ubuntu (or Mint, or pure Debian?) if [ -f /etc/NetworkManager/conf.d/wifi-manage.conf ]; then - sed -i -e "s|managed=1|managed=0|" /etc/NetworkManager/conf.d/wifi-manage.conf + sed -i "s|managed=1|managed=0|" /etc/NetworkManager/conf.d/wifi-manage.conf fi systemctl enable hostapd -echo -e "\nPlease reboot to activate hostapd feature.\n" -exit 0 +#exit 0 +{% endif %} +#if dhcpcd_result == "enabled" {% endif %} #wifi_up_down {% endif %} +#can_be_ap {% endif %} -{% endif %} +#network_enabled + +echo -e "\nPlease reboot to activate hostapd feature.\n" diff --git a/roles/network/templates/hostapd/iiab-test-wifi.j2 b/roles/network/templates/hostapd/iiab-test-wifi.j2 index 6757846d3..709a92fbb 100755 --- a/roles/network/templates/hostapd/iiab-test-wifi.j2 +++ b/roles/network/templates/hostapd/iiab-test-wifi.j2 @@ -1,91 +1,132 @@ -#!/bin/bash +#!/bin/sh + +# 2023-04-24 PR #3542 / PR #3549 context: +# "systemd-network" "RasPiOS" have files with the client wifi info within them, +# those can be parsed for the ssid without needing the related service running +# first. +# "Netplan systemd" "NetworkManager" need to be running to be able to parse for +# the ssid, from the generated config file for "Netplan systemd" and from the +# running environment for "NetworkManager". +# "iiab-wifi-test.service" acts as a bit of a traffic cop keeping the ordering +# of the services more deterministic when active and tries to catch a channel +# mismatch between client wifi's current setting and what is contained within +# hostapd.conf early in the boot process. + IFACE={{ discovered_wireless_iface }} -RASPBIAN=0 NETPLAN=0 -SSID="NA" -# when we get here br0 should be available and dbus wpa_supplicant was started if enabled. None -# of the backends that use wpa_supplicant should be active yet based on the Before= After= lines -# in the iiab-wifi-test.service unit file. +SSID="" +# when we get here br0 should be available and dbus wpa_supplicant was started if enabled. Some +# of the backends that use wpa_supplicant should be active based on the Before= After= lines in +# the iiab-wifi-test.service unit file. +# https://github.com/iiab/iiab/pull/3542#issuecomment-1519647266 + +echo "iiab-test-wifi called" +echo "running pid $$" # covers systemd-networkd if [ -f /etc/wpa_supplicant/wpa_supplicant-$IFACE.conf ]; then - SSID=`grep ssid /etc/wpa_supplicant/wpa_supplicant-$IFACE.conf | awk -F = '{print $2}' | sed -r s/\"// | sed -r s/\"//` + echo "systemd-network" + SSID=$(grep ssid /etc/wpa_supplicant/wpa_supplicant-$IFACE.conf | awk -F = '{print $2}' | sed -r s/\"// | sed -r s/\"//) fi -# covers raspbian -if [ -f /etc/wpa_supplicant/wpa_supplicant.conf ]; then - RASPBIAN=1 - if /usr/sbin/rfkill list wifi | grep -q "Soft blocked: yes" ; then - echo "unblocking WiFi" - rfkill unblock wifi - fi - SSID=`grep ssid /etc/wpa_supplicant/wpa_supplicant.conf | awk -F = '{print $2}' | sed -r s/\"// | sed -r s/\"//` +# covers stock raspbian +if [ -f /etc/wpa_supplicant/wpa_supplicant.conf ] && [ -n "$(pgrep dhcpcd)" ]; then + echo "RasPiOS" + SSID=$(grep ssid /etc/wpa_supplicant/wpa_supplicant.conf | awk -F = '{print $2}' | sed -r s/\"// | sed -r s/\"//) fi -# covers netplan's bugs workaround # https://bugs.launchpad.net/ubuntu/+source/linux-firmware/+bug/1862760 # https://bugs.launchpad.net/netplan/+bug/1951586 # WiFi country code progress on arm64 OS's discussed on #3078 +# covers netplan systemd use on server with bug workarounds if [ -f /run/netplan/wpa-$IFACE.conf ]; then NETPLAN=1 - SSID=`grep ssid /run/netplan/wpa-$IFACE.conf | awk -F = '{print $2}' | sed -r s/\"// | sed -r s/\"//` - echo "cover netplan lack of country=" - sed -i 's|ctrl_interface=/run/wpa_supplicant|&\ncountry=US|' /run/netplan/wpa-$IFACE.conf -fi -# IIAB hint for NetworkManager -# could scrape /etc/NetworkManager/system-connections/ looking for ssid -if [ -f /etc/iiab/iiab.env ]; then - source /etc/iiab/iiab.env - if [ ! -z $CLIENT_SSID ]; then - SSID=$CLIENT_SSID + echo "Netplan systemd" + SSID=$(grep ssid /run/netplan/wpa-$IFACE.conf | awk -F = '{print $2}' | sed -r s/\"// | sed -r s/\"//) + REG_DOM=$(grep country /run/netplan/wpa-$IFACE.conf | awk -F = '{ print $2 }') + if [ -z "$REG_DOM" ]; then + NETPLAN=2 + echo "cover netplan wifi client lack of country= setting to {{ host_country_code }}" + sed -i "s|ctrl_interface=/run/wpa_supplicant|&\ncountry={{ host_country_code }}|" /run/netplan/wpa-$IFACE.conf + else + echo "set hostapd wifi country to $REG_DOM" + if [ -f /etc/hostapd/hostapd.conf.iiab ]; then + sed -i "s|^country.*|country_code=$REG_DOM|" /etc/hostapd/hostapd.conf.iiab + cp /etc/hostapd/hostapd.conf.iiab /etc/hostapd/hostapd.conf + fi fi fi + +# NetworkManager +if [ -z "$SSID" ] && [ -n "$(pgrep NetworkManager)" ]; then + echo "NetworkManager" + sleep 15 + SSID=$(iw $IFACE info | grep ssid | awk '{print $2}' ) +fi echo "ssid is $SSID" -if [[ $SSID == "" ]] || [[ $SSID == "NA" ]]; then - echo "Couldn't find ssid $SSID to use exiting" - if [ $NETPLAN -eq 1 ]; then + +if [ -z "$SSID" ]; then + echo "Couldn't find an UPSTREAM SSID in files like wpa_supplicant.conf -- so exiting." + echo "CLARIF: This is normal when UPSTREAM WIFI is not active, as there would be no" + echo "UPSTREAM SSID to extract, e.g. if 'wifi_up_down: False'" + if [ $NETPLAN -gt 0 ]; then echo "Netplan1" fi exit 0 fi + +if [ $NETPLAN -gt 0 ]; then + echo "Netplan2 sleep 10" + sleep 10 + wifi_processes=$(ps -A | grep wpa_supplicant | wc -l) + if [ $wifi_processes -eq 1 ]; then + # This is more of a netplan workaround should go away. + echo "Problem - Now Starting netplan wifi" + NETPLAN=2 + else + echo "Not Restarting netplan wifi sleep 20" + sleep 20 + fi + # This one handles the changing of the country code from above + if [ $NETPLAN -eq 2 ]; then + echo "Restarting netplan-wpa-$IFACE sleep 20" + /bin/systemctl --no-block restart netplan-wpa-$IFACE.service + sleep 20 + fi +fi +sleep 10 wpa_cli -i $IFACE scan > /dev/null sleep 2 -FREQ=`wpa_cli -i $IFACE scan_results | grep $SSID | awk '{print $2}'` +FREQ=$(wpa_cli -i $IFACE scan_results | grep "$SSID" | awk '{print $2}') for result in $FREQ; do echo "frequency is $result for $SSID" - if [ $result -lt 2485 ] && [ $result -gt 2407 ]; then + if [ "$result" -lt 2485 ] && [ "$result" -gt 2407 ]; then FREQ2=$result break else echo "channel $result is 5Ghz - ignoring" fi done + echo "Using $FREQ2 for $SSID" -if [[ $FREQ2 == "" ]]; then + +if [ -z "$FREQ2" ]; then echo "Couldn't find frequency to use exiting" - if [ $NETPLAN -eq 1 ]; then - echo "Netplan2" + if [ $NETPLAN -gt 0 ]; then + echo "Netplan3" fi exit 0 fi -# ubuntu on boot exits at this point timing - issue with wpa_cli and scanning -CHAN=$(($FREQ2 - 2407 )) -CHAN=$(($CHAN / 5 )) + +CHAN=$((FREQ2 - 2407)) +CHAN=$((CHAN / 5)) echo "channel is $CHAN for $SSID" -HOSTAPD=`grep channel /etc/hostapd/hostapd.conf | awk -F = '{print $2}'` +HOSTAPD=$(grep channel /etc/hostapd/hostapd.conf | awk -F = '{print $2}') echo "Hostapd set for $HOSTAPD" -if [ $CHAN -ne $HOSTAPD ]; then +if [ "$CHAN" -ne "$HOSTAPD" ]; then echo "Editing Hostapd for channel $CHAN" cp /etc/hostapd/hostapd.conf.iiab /etc/hostapd/hostapd.conf sed -i -e "s/^channel.*/channel=$CHAN/" /etc/hostapd/hostapd.conf + /bin/systemctl --no-block restart hostapd + echo "Restarted hostapd" fi -systemctl stop wpa_supplicant -systemctl stop hostapd -systemctl start hostapd -systemctl start wpa_supplicant -if [ $NETPLAN -eq 1 ]; then - echo "Netplan3" - # This is more of a netplan workaround should go away. - systemctl restart netplan-wpa-$IFACE.service -fi -exit 0 diff --git a/roles/network/templates/hostapd/iiab-wifi-test.service.j2 b/roles/network/templates/hostapd/iiab-wifi-test.service.j2 index 682680a07..baa73eed6 100644 --- a/roles/network/templates/hostapd/iiab-wifi-test.service.j2 +++ b/roles/network/templates/hostapd/iiab-wifi-test.service.j2 @@ -1,15 +1,27 @@ [Unit] Description=IIAB find channel freq for ssid -After=wpa_supplicant.service -Wants=wpa_supplicant.service -Before=hostapd.service +Requisite=sys-subsystem-net-devices-{{ discovered_wireless_iface }}.device +Requisite=iiab-clone-wifi.service +Requisite=wpa_supplicant.service + +# 2023-04-24 PR #3549: c49adcf went too far and broke netplan-systemd +#Requires=network-pre.target +#BindsTo=sys-subsystem-net-devices-{{ discovered_wireless_iface }}.device +#After=sys-subsystem-net-devices-{{ discovered_wireless_iface }}.device +#After=iiab-clone-wifi.service + +#After=network-pre.target +#After=wpa_supplicant.service +#Wants=wpa_supplicant.service + +After=NetworkManager.service +After=netplan-wpa-{{ discovered_wireless_iface }}.service Before=dhcpcd.service Before=wpa_supplicant@{{ discovered_wireless_iface }}.service -Before=NetworkManager.service -Before=netplan-wpa-{{ discovered_wireless_iface }}.service -Before=network.target +#Before=network.target [Service] +TimeoutStartSec=120 Type=oneshot RemainAfterExit=yes ExecStart=/usr/sbin/iiab-test-wifi diff --git a/roles/network/templates/hostapd/netd-disp2 b/roles/network/templates/hostapd/netd-disp2 index 78e258627..2e39b26c2 100644 --- a/roles/network/templates/hostapd/netd-disp2 +++ b/roles/network/templates/hostapd/netd-disp2 @@ -2,17 +2,15 @@ if [ "$IFACE" == "{{ discovered_wireless_iface }}" ]; then echo "NET-DISP-WiFi $IFACE $STATE" # If we are here we have a dhcp ip address - CHAN=`iw $IFACE info|grep channel|cut -d' ' -f2` + CHAN=$(iw "$IFACE" info|grep channel|cut -d' ' -f2) echo "Using channel $CHAN for carrier" - HOSTAPD=`grep channel /etc/hostapd/hostapd.conf | awk -F = '{print $2}'` + HOSTAPD=$(grep channel /etc/hostapd/hostapd.conf | awk -F = '{print $2}') echo "Hostapd set for $HOSTAPD" if [ $CHAN -ne $HOSTAPD ] && [ $CHAN -lt 14 ]; then echo "Editing Hostapd for channel $CHAN" cp /etc/hostapd/hostapd.conf.iiab /etc/hostapd/hostapd.conf - sed -i -e "s/^channel.*/channel=$CHAN/" /etc/hostapd/hostapd.conf - systemctl stop wpa_supplicant + sed -i "s/^channel.*/channel=$CHAN/" /etc/hostapd/hostapd.conf systemctl restart hostapd - systemctl start wpa_supplicant else echo "Upstream Channel greater than 13 or is the same - not changing hostapd.conf" fi diff --git a/roles/network/templates/netwarn/netwarn b/roles/network/templates/netwarn/iiab-netwarn similarity index 58% rename from roles/network/templates/netwarn/netwarn rename to roles/network/templates/netwarn/iiab-netwarn index a8f7a7916..87865e0f1 100755 --- a/roles/network/templates/netwarn/netwarn +++ b/roles/network/templates/netwarn/iiab-netwarn @@ -1,14 +1,21 @@ #!/bin/bash -# CONFUSING BUT FYI: Commands below run *strictly sequentially* when this -# script (/usr/local/sbin/netwarn) is invoked by autostart during OS boot. -# This allows return codes to be meaningful, at each successive step. +# CONFUSING BUT FYI: Steps below run *strictly sequentially* when this script +# (/usr/local/sbin/iiab-netwarn) is run on boot, triggered by either autostart: +# https://specifications.freedesktop.org/autostart-spec/autostart-spec-latest.html +# ...or by Wayland compositor's ~/.config/labwc/autostart in new RasPiOS 12+: +# https://forums.raspberrypi.com/viewtopic.php?t=379321 +# (Prior to Dec 2024, RasPiOS compositor Wayfire did the same...) +# https://github.com/iiab/iiab/pull/3685 +# https://github.com/WayfireWM/wayfire/wiki/Configuration#autostart +# +# This allows return codes ($rc) to be meaningful, at each successive step. # (As of July 2022, this is tested to work well with Ubuntu Mate and "Raspberry # Pi OS with desktop" on Raspberry Pi 4!) # # IN CONTRAST: return codes below are NOT MEANINGFUL when this script is -# invoked from a regularly graphical desktop session -- so make sure to test -# during an actual OS boot-up, with autostart! +# invoked manually after boot from a regular graphical desktop session -- so +# make sure to test (either kind of) "autostart" during actual OS boot-up! if [ -f /etc/iiab/install-flags/iiab-network-complete ]; then exit diff --git a/roles/network/templates/netwarn/netwarn-iiab-network.desktop b/roles/network/templates/netwarn/netwarn-iiab-network.desktop index 35547ee41..f109f88b0 100644 --- a/roles/network/templates/netwarn/netwarn-iiab-network.desktop +++ b/roles/network/templates/netwarn/netwarn-iiab-network.desktop @@ -4,7 +4,7 @@ Comment[en_US]=iiab-network Name[en_CA]=iiab-network Comment[en_CA]=iiab-network Type=Application -Exec=/usr/local/sbin/netwarn +Exec=/usr/local/sbin/iiab-netwarn Hidden=false Name=iiab-network Comment=iiab-network diff --git a/roles/network/templates/network/dnsmasq.sh.j2 b/roles/network/templates/network/dnsmasq.sh.j2 index 00df42bf3..6a7f7179a 100755 --- a/roles/network/templates/network/dnsmasq.sh.j2 +++ b/roles/network/templates/network/dnsmasq.sh.j2 @@ -1,7 +1,6 @@ #!/bin/bash if [ "$IFACE" == "{{ iiab_lan_iface }}" ]; then - echo "Restarting dnsmasq in 5 seconds" - /bin/sleep 5 && /bin/systemctl --no-block restart dnsmasq.service - echo "Restarted dnsmasq" + /bin/systemctl --no-block start dnsmasq.service + echo "Started dnsmasq" fi diff --git a/roles/nextcloud/README.md b/roles/nextcloud/README.md index 28aed5472..c0eb0f9b3 100644 --- a/roles/nextcloud/README.md +++ b/roles/nextcloud/README.md @@ -14,7 +14,7 @@ The Nextcloud suite is divided into three main categories: ## Install It -(1) Set these 2 variable in [/etc/iiab/local_vars.yml](http://FAQ.IIAB.IO#What_is_local_vars.yml_and_how_do_I_customize_it.3F) prior to installing Internet-in-a-Box: +(1) Set these 2 variable in [/etc/iiab/local_vars.yml](http://FAQ.IIAB.IO#What_is_local_vars.yml_and_how_do_I_customize_it%3F) prior to installing Internet-in-a-Box: nextcloud_install: True nextcloud_enabled: True @@ -25,7 +25,7 @@ The Nextcloud suite is divided into three main categories: To further refine Nextcloud access controls based on IPv4 addresses, you can edit `/etc/apache2/sites-available/nextcloud.conf` _after_ it's created by this template: [/opt/iiab/iiab/roles/nextcloud/templates/nextcloud.conf.j2](https://github.com/iiab/iiab/blob/master/roles/nextcloud/templates/nextcloud.conf.j2) -(3) Strongly consider also setting `nginx_high_php_limits: True` in your /etc/iiab/local_vars.yml, to allocate important RAM/resources to PHP. Of course, enabling this might cause excess use of RAM/disk or other resources if not calibrated to your hardware and network! So _after_ install is complete, verify and evaluate these 6 settings in /etc/php/[ACTUAL PHP VERSION]/fpm/php.ini: +(3) Be aware of `nginx_high_php_limits: True` in your /etc/iiab/local_vars.yml, which allocates important RAM/resources to PHP, and is effectively auto-enabled for Nextcloud ([PR #3624](https://github.com/iiab/iiab/pull/3624)). Verify that your Internet-in-a-Box server has enough RAM and disk! And _after_ Nextcloud is installed, verify and evaluate these 6 settings in `/etc/php/[ACTUAL PHP VERSION]/fpm/php.ini` to be sure: - upload_max_filesize - post_max_size @@ -34,12 +34,15 @@ To further refine Nextcloud access controls based on IPv4 addresses, you can edi - max_input_time - max_input_vars (Moodle 3.11+ requires 5000+ with PHP 8+) -Useful PHP recommendations for these settings (while largely tailored to WordPress, and aimed at very low-end hardware) can be found here: [/opt/iiab/iiab/roles/www_options/tasks/main.yml#L53-L133](../www_options/tasks/main.yml#L53-L133) +FYI IIAB will also update `/etc/php/[ACTUAL PHP VERSION]/cli/php.in` (as Moodle requires). -(4) If you're running Nextcloud 22+ in production, carefully check that Nextcloud's latest formal prereqs (required AND recommended) are included per your community's needs. In places like these: +Useful PHP recommendations for these settings (while largely tailored to WordPress, and aimed at very low-end hardware) can be found here: [/opt/iiab/iiab/roles/www_options/tasks/php-settings.yml#L55-L110](../www_options/tasks/php-settings.yml#L55-L110) +(4) Verify system requirements and recommendations for the [latest version Nextcloud](https://github.com/nextcloud/server/wiki/Maintenance-and-Release-Schedule): + +- https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html - https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation -- https://docs.nextcloud.com/server/22/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation +- https://docs.nextcloud.com/server/30/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation - https://github.com/iiab/iiab/blob/master/roles/nextcloud/tasks/install.yml ## Using It @@ -57,8 +60,8 @@ Do not install the [Nextcloud News](https://apps.nextcloud.com/apps/news) app (a Going forward, should Internet-in-a-Box consider integrating optimizations (or more!) from these below? -- https://ownyourbits.com/nextcloudpi/ -- https://ownyourbits.com/2017/02/13/nextcloud-ready-raspberry-pi-image/ +- ~https://ownyourbits.com/nextcloudpi/~ +- ~https://ownyourbits.com/2017/02/13/nextcloud-ready-raspberry-pi-image/~ - https://github.com/nextcloud/nextcloudpi Please [contact us](https://internet-in-a-box.org/contributing.html) if you can help! diff --git a/roles/nextcloud/tasks/install.yml b/roles/nextcloud/tasks/install.yml index 8fc25cd08..37429ea0e 100644 --- a/roles/nextcloud/tasks/install.yml +++ b/roles/nextcloud/tasks/install.yml @@ -1,3 +1,23 @@ +- name: "Set 'mysql_install: True' and 'mysql_enabled: True'" + set_fact: + mysql_install: True + mysql_enabled: True + +- name: MYSQL - run 'mysql' role (attempt to install & enable MySQL / MariaDB) + include_role: + name: mysql + +- name: FAIL (STOP THE INSTALL) IF 'mysql_installed is undefined' + fail: + msg: "Nextcloud install cannot proceed, as MySQL / MariaDB is not installed." + when: mysql_installed is undefined + + +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + # CHECK FOR PHP VERSION AUTOMATICALLY, TO DETERMINE WHICH NEXTCLOUD TO INSTALL. # INSPIRED BY: github.com/iiab/iiab/blob/master/roles/nodejs/tasks/main.yml @@ -41,10 +61,18 @@ # February 2020: See @m-anish's PR #2119 and follow-up PR #2258. -# 2021-07-06: If you're running Nextcloud 22+ in production, carefully check the latest required AND recommended prereqs: +# December 2023: Check latest required AND recommended prereqs below! +# e.g. Nextcloud 26 works with PHP 8.2; Nextcloud 27 deprecates PHP 8.0; Nextcloud 28 works with PHP 8.3 +# https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html # https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation -# https://docs.nextcloud.com/server/25/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation -# https://docs.nextcloud.com/server/24/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation +# https://docs.nextcloud.com/server/latest/admin_manual/installation/php_configuration.html +# https://docs.nextcloud.com/server/28/admin_manual/installation/ + +# 2023-12-15: Lifesaver manual upgrade instructions below! As Nextcloud OFTEN +# gets badly stuck (PHP timeouts, leading to FALSE instructions erroneously +# asking you to wait) if its web-based upgrade process is attempted :/ +# https://docs.nextcloud.com/server/latest/admin_manual/maintenance/manual_upgrade.html + - name: Install ffmpeg + libxml2 + 11 PHP packages (run 'php -m' or 'php -i' to verify) package: name: @@ -86,7 +114,7 @@ # state: present # when: php_version is version('8.0', '<') -- name: "Run roles/www_options/tasks/php-settings.yml with 'nginx_high_php_limits: False' by default" +- name: "Run roles/www_options/tasks/php-settings.yml with 'nginx_high_php_limits: True' by default" include_tasks: roles/www_options/tasks/php-settings.yml when: php_settings_done is undefined @@ -96,7 +124,14 @@ state: directory path: "{{ nextcloud_root_dir }}" # /library/www/nextcloud -- name: Unarchive {{ nextcloud_dl_url }} (~140 MB) to {{ nextcloud_root_dir }} (~519 MB initially, sometimes ~543 MB later, {{ apache_user }}:{{ apache_user }}) +# Nextcloud 25 EOL was 2023-10-01: https://endoflife.date/nextcloud +# https://github.com/nextcloud/server/wiki/Maintenance-and-Release-Schedule#eol-versions +#- name: "2023-03-24: NEXTCLOUD 26 REQUIRES PHP 8 -- SO THIS TEMPORARY PATCH INSTALLS THE OLDER NEXTCLOUD 25 ON OS's WITH PHP 7.x -- WHOSE END-OF-LIFE WAS NOVEMBER 2022" +# set_fact: +# nextcloud_dl_url: https://download.nextcloud.com/server/releases/latest-25.tar.bz2 +# when: php_version is version('8.0', '<') + +- name: Unarchive {{ nextcloud_dl_url }} (~216 MB) to {{ nextcloud_root_dir }} (~844 MB initially, sometimes ~878 MB later, {{ apache_user }}:{{ apache_user }}) unarchive: remote_src: yes # Overwrite even if "already exists on the target" src: "{{ nextcloud_dl_url }}" @@ -112,6 +147,17 @@ # RECORD Nextcloud AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'nextcloud_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: nextcloud + option: nextcloud_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'nextcloud_installed: True'" set_fact: nextcloud_installed: True diff --git a/roles/nextcloud/tasks/main.yml b/roles/nextcloud/tasks/main.yml index d98ae5b27..1308da347 100644 --- a/roles/nextcloud/tasks/main.yml +++ b/roles/nextcloud/tasks/main.yml @@ -31,7 +31,7 @@ - name: Add 'nextcloud' variable values to {{ iiab_ini_file }} ini_file: path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini - section: Nextcloud + section: nextcloud option: "{{ item.option }}" value: "{{ item.value | string }}" with_items: diff --git a/roles/nextcloud/templates/nextcloud-nginx.conf.j2 b/roles/nextcloud/templates/nextcloud-nginx.conf.j2 index a1d1a53b3..9b7e8ee5f 100644 --- a/roles/nextcloud/templates/nextcloud-nginx.conf.j2 +++ b/roles/nextcloud/templates/nextcloud-nginx.conf.j2 @@ -59,7 +59,7 @@ location ^~ {{ nextcloud_url }} { } # set max upload size - client_max_body_size 512M; + client_max_body_size 10000M; fastcgi_buffers 64 4K; # Enable gzip but do not remove ETag headers @@ -85,7 +85,7 @@ location ^~ {{ nextcloud_url }} { deny all; } - location ~ ^\/nextcloud\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) { + location ~ ^\/nextcloud\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+)\.php(?:$|\/) { fastcgi_split_path_info ^(.+?\.php)(\/.*|)$; set $path_info $fastcgi_path_info; try_files $fastcgi_script_name =404; @@ -102,7 +102,7 @@ location ^~ {{ nextcloud_url }} { fastcgi_request_buffering off; } - location ~ ^\/nextcloud\/(?:updater|oc[ms]-provider)(?:$|\/) { + location ~ ^\/nextcloud\/(?:updater|ocs-provider)(?:$|\/) { try_files $uri/ =404; index index.php; } diff --git a/roles/nginx/README.md b/roles/nginx/README.md index dd2311a15..2c5f65590 100644 --- a/roles/nginx/README.md +++ b/roles/nginx/README.md @@ -52,11 +52,11 @@ * kalite (menu goes directly to ports 8006-8008) * minetest * mosquitto - * openvpn * pbx [FreePBX is usable with _both_ NGINX and Apache as of 2021-08-18, thanks to PR [#2954](https://github.com/iiab/iiab/pull/2954)] * phpmyadmin [*, requires Apache for now, as in Section iii.] * samba [*, [PR #2923](https://github.com/iiab/iiab/pull/2923)] * sshd + * tailscale * transmission * vnstat diff --git a/roles/nginx/tasks/install.yml b/roles/nginx/tasks/install.yml index d9f3c4dda..b45920dd1 100644 --- a/roles/nginx/tasks/install.yml +++ b/roles/nginx/tasks/install.yml @@ -1,3 +1,8 @@ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: Stop & Disable '{{ apache_service }}' systemd service, in case it exists systemd: name: "{{ apache_service }}" # apache2 or httpd, per /opt/iiab/iiab/vars/.yml @@ -66,6 +71,17 @@ # RECORD NGINX AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'nginx_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: nginx + option: nginx_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'nginx_installed: True'" set_fact: nginx_installed: True diff --git a/roles/nginx/templates/iiab.conf.j2 b/roles/nginx/templates/iiab.conf.j2 index b66f69cfa..20773967f 100644 --- a/roles/nginx/templates/iiab.conf.j2 +++ b/roles/nginx/templates/iiab.conf.j2 @@ -5,10 +5,30 @@ location / { location /usb { alias /library/www/html/local_content/; fancyindex on; # autoindex on; + add_before_body /upload2usb/button.html; +} + +location ~ ^/upload2usb/(.*)\.php$ { + alias /library/www/html/upload2usb/$1.php; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Host $host; + fastcgi_pass php; + fastcgi_index index.php; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param SCRIPT_NAME $fastcgi_script_name; + include fastcgi_params; } location /local_content/ { fancyindex on; # autoindex on; + add_before_body /upload2usb/button.html; +} + +location /info { + fancyindex on; # Directory listing for http://box/info/admin-console/ + fancyindex_exact_size off; # Output human-readable file sizes. } location /modules/ { diff --git a/roles/nginx/templates/server.conf.j2 b/roles/nginx/templates/server.conf.j2 index 84413f4e7..9b6aeaaba 100644 --- a/roles/nginx/templates/server.conf.j2 +++ b/roles/nginx/templates/server.conf.j2 @@ -8,13 +8,13 @@ server { index index.php index.html index.htm; # NGINX's 1MB default is far too low for Calibre-Web and LMS-like apps. - # So IIAB sets this to 500M, roughly aligning with similar settings... - # 1. 'upload_max_filesize = 500M' and 'post_max_size = 500M' are SOMETIMES set in: - # https://github.com/iiab/iiab/blob/master/roles/www_options/tasks/main.yml#L106-L107 - # https://github.com/iiab/iiab/blob/master/roles/www_options/tasks/main.yml#L120-L121 - # 2. 'client_max_body_size 512M;' is set in: + # So IIAB sets this to 10000M, roughly aligning with similar settings... + # 1. 'upload_max_filesize = 10000M' and 'post_max_size = 10000M' are SOMETIMES set in: + # https://github.com/iiab/iiab/blob/master/roles/www_options/tasks/php-settings.yml#L90-L91 + # https://github.com/iiab/iiab/blob/master/roles/www_options/tasks/php-settings.yml#L104-L105 + # 2. 'client_max_body_size 10000M;' is set in: # https://github.com/iiab/iiab/blob/master/roles/nextcloud/templates/nextcloud-nginx.conf.j2#L62 - client_max_body_size 500M; + client_max_body_size 10000M; # let individual services drop location blocks in conf.d include {{ nginx_conf_dir }}/*; diff --git a/roles/nodejs/README.md b/roles/nodejs/README.md index 7a151adc6..7e2716bc9 100644 --- a/roles/nodejs/README.md +++ b/roles/nodejs/README.md @@ -8,15 +8,15 @@ Nodesource.com often supports Debian long before each Debian release, whereas fo For late-breaking details on Nodesource.com support for your particular Linux OS, keep an eye on: - https://github.com/nodesource/distributions#deb -- https://deb.nodesource.com/node_18.x/dists/ - - https://deb.nodesource.com/node_18.x/pool/main/n/nodejs/ - - https://nodejs.org/dist/latest-v18.x/ +- https://deb.nodesource.com/node_20.x/dists/ + - https://deb.nodesource.com/node_20.x/pool/main/n/nodejs/ + - https://nodejs.org/dist/latest-v20.x/ - https://deb.nodesource.com/node_19.x/dists/ - https://deb.nodesource.com/node_19.x/pool/main/n/nodejs/ - https://nodejs.org/dist/latest-v19.x/ - _ETC!_ -If Nodesource.com does not yet support your Linux OS and IIAB's asked to install Node.js — IIAB will then [fall back](https://github.com/iiab/iiab/blob/15a689e30b4eea325e4bb8d35e19990dd8062fbc/roles/nodejs/tasks/install.yml#L103-L107) to: (running the equivalent of) +If Nodesource.com does not yet support your Linux OS and IIAB's asked to install Node.js — IIAB will then [fall back](https://github.com/iiab/iiab/blob/91a5cd33f34d5d2a55e75bf0cdc85bcd9d7b4821/roles/nodejs/tasks/install.yml#L103-L107) to: (running the equivalent of) ``` sudo apt install nodejs npm @@ -35,13 +35,13 @@ sudo ./runrole --reinstall nodejs Raspberry Pi Zero W Warning --------------------------- -UPDATE: The Zero 2 W released 2021-10-28 is 64-bit (ARMv7) so may or may not have such serious problems... +UPDATE: The Zero 2 W released 2021-10-28 is 64-bit (ARMv7) so may not have such serious problems... On the original Raspberry Pi Zero W (ARMv6) however: Node.js applications like Internet Archive, JupyterHub, Node-RED, PBX (Asterisk/FreePBX) and Sugarizer won't work — if you installed Node.js while on Raspberry Pi 3, 3 B+ (ARMv7) or Raspberry Pi 4 (ARMv8). If necessary, run `sudo apt purge nodejs npm` then `sudo rm /etc/apt/sources.list.d/nodesource.list` then `sudo apt update` and then attempt to [install Node.js](https://github.com/iiab/iiab/blob/master/roles/nodejs/tasks/install.yml) _on the Raspberry Pi Zero W itself_ (`cd /opt/iiab/iiab` then `sudo ./runrole --reinstall nodejs`). -Earlier, some preferred installing the tar file version mentioned at [#2082](https://github.com/iiab/iiab/issues/2082#issuecomment-569344617) — if that is your preference, consider a more recent version like: https://nodejs.org/dist/latest-v18.x/ +Earlier, some preferred installing the tar file version mentioned at [#2082](https://github.com/iiab/iiab/issues/2082#issuecomment-569344617) — if that is your preference, consider a more recent version like: https://nodejs.org/dist/latest-v20.x/ Either way, you'll (likely) then also need to run: `sudo apt install npm` diff --git a/roles/nodejs/tasks/install.yml b/roles/nodejs/tasks/install.yml index 3990e10b3..96e1ec9df 100644 --- a/roles/nodejs/tasks/install.yml +++ b/roles/nodejs/tasks/install.yml @@ -1,3 +1,12 @@ +# Lokole PDF (User's Guide) gets copied for offline use (http://box/info) here: +# https://github.com/iiab/iiab/blob/master/roles/www_base/templates/iiab-refresh-wiki-docs.sh#L51-L52 + + +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + # 1. TEST IF Node.js ALEADY INSTALLED & IF SO WARN IT'LL BE REPLACED # 2019-02-03: BELOW TESTS IF 'nodejs' VERSION IS ALREADY INSTALLED: @@ -86,21 +95,39 @@ # apt install ./nodejs_18.11.0-deb-1nodesource1_amd64.deb # SMARTER + CLEANER THAN: dpkg -i nodejs_18... # echo 'nodejs_installed: True' >> /etc/iiab/iiab_state.yml -- name: Try 'curl -fsSL https://deb.nodesource.com/setup_{{ nodejs_version }} | bash -' to overwrite /etc/apt/sources.list.d/nodesource.list - shell: curl -fsSL https://deb.nodesource.com/setup_{{ nodejs_version }} | bash - +- name: Try NEW (since August 2023) approach setting up /etc/apt/keyrings/nodesource.gpg and /etc/apt/sources.list.d/nodesource.list -- per https://github.com/nodesource/distributions#installation-instructions + shell: | + mkdir -p /etc/apt/keyrings + rm -f /etc/apt/keyrings/nodesource.gpg + curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg + echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_{{ nodejs_version }} nodistro main" > /etc/apt/sources.list.d/nodesource.list register: curl_nodesource ignore_errors: yes - #args: - # warn: no - # creates: /etc/apt/sources.list.d/nodesource.list -- name: Install latest Node.js -- includes /usr/bin/npm if nodesource installed above - package: +# 2023-09-06: OBSOLETE as nodesource.com no longer supports https://deb.nodesource.com/node_{{ nodejs_version }}/dists/ +# - name: Try 'curl -fsSL https://deb.nodesource.com/setup_{{ nodejs_version }} | bash -' to overwrite /etc/apt/sources.list.d/nodesource.list +# shell: curl -fsSL https://deb.nodesource.com/setup_{{ nodejs_version }} | bash - +# register: curl_nodesource +# ignore_errors: yes +# #args: +# # warn: no +# # creates: /etc/apt/sources.list.d/nodesource.list + +- name: Remove /etc/apt/sources.list.d/nodesource.list if above failed + file: + path: /etc/apt/sources.list.d/nodesource.list + state: absent + when: curl_nodesource.failed + +- name: Install Node.js -- also includes /usr/bin/npm if nodesource.list installed above + apt: #name: nodejs={{ nodejs_version }} name: nodejs state: latest # Equivalent to 'state: present' ? + update_cache: yes -- name: Also install latest npm (OS's) if nodesource failed to install above -- i.e. if OS not yet supported by https://github.com/nodesource/distributions#deb and https://deb.nodesource.com/node_{{ nodejs_version }}/dists/ +# Also run 'npm install -g npm' later, if you truly want the LATEST! +- name: Also install latest npm (OS's) if nodesource failed to install above -- i.e. if OS not yet supported by https://github.com/nodesource/distributions package: name: npm state: latest # Equivalent to 'state: present' ? @@ -155,6 +182,17 @@ # 3. RECORD Node.js AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'nodejs_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: nodejs + option: nodejs_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'nodejs_installed: True'" set_fact: nodejs_installed: True diff --git a/roles/nodered/README.rst b/roles/nodered/README.rst index aa3dc3236..769905f7f 100644 --- a/roles/nodered/README.rst +++ b/roles/nodered/README.rst @@ -9,7 +9,7 @@ Node-RED is a flow-based development tool for visual programming developed origi Using It -------- -Prior to installing IIAB, make sure your `/etc/iiab/local_vars.yml `_ contains:: +Prior to installing IIAB, make sure your `/etc/iiab/local_vars.yml `_ contains:: nodered_install: True nodered_enabled: True diff --git a/roles/nodered/tasks/install.yml b/roles/nodered/tasks/install.yml index 7ee0a7d73..b7c711ac5 100644 --- a/roles/nodered/tasks/install.yml +++ b/roles/nodered/tasks/install.yml @@ -23,6 +23,11 @@ # when: nodejs_version != "12.x" +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + # BRUTAL but ensures consistency across OS's / distros like Raspbian Desktop & # Ubermix that often include an older version of Node-RED. Brutal, as this # removes customizations on graphical desktop OS's e.g. Raspbian Desktop's: @@ -138,6 +143,17 @@ # RECORD Node-RED AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'nodered_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: nodered + option: nodered_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'nodered_installed: True'" set_fact: nodered_installed: True diff --git a/roles/osm-vector-maps/README.md b/roles/osm-vector-maps/README.md index b87a11dd1..030c411b8 100644 --- a/roles/osm-vector-maps/README.md +++ b/roles/osm-vector-maps/README.md @@ -18,8 +18,8 @@ 3. Multiple Hi-Res Satellite Photo Regions can be downloaded/installed (one "square" region at a time, thankfully duplicate disk space is avoided when such "squares" overlap!) 4. Some variables have newer meanings: - 1. `osm_vector_maps_install` in [/etc/iiab/local_vars.yml](https://wiki.iiab.io/go/FAQ#What_is_local_vars.yml_and_how_do_I_customize_it.3F) means install the map program and 7 basic levels of zoom (48MB for OSM + 25 MB for satellite photos). - 2. `osm_vector_maps_enabled` in [/etc/iiab/local_vars.yml](https://wiki.iiab.io/go/FAQ#What_is_local_vars.yml_and_how_do_I_customize_it.3F) is once again standardized, solving #2484 install delays. + 1. `osm_vector_maps_install` in [/etc/iiab/local_vars.yml](https://wiki.iiab.io/go/FAQ#What_is_local_vars.yml_and_how_do_I_customize_it%3F) means install the map program and 7 basic levels of zoom (48MB for OSM + 25 MB for satellite photos). + 2. `osm_vector_maps_enabled` in [/etc/iiab/local_vars.yml](https://wiki.iiab.io/go/FAQ#What_is_local_vars.yml_and_how_do_I_customize_it%3F) is once again standardized, solving #2484 install delays. 3. `osm_vector_maps_installed` in `/etc/iiab/iiab_state.yml` means a functioning world map with 7 levels of zoom (z0-z6) has been installed — i.e. a preview of IIAB's mapping system that helps you select Maps Pack(s) and Hi-Res Satellite Photo Region(s) to download and install on your IIAB. (SEE 1. ABOVE) 5. **Drag-and-Drop Map Overlays** — try this by dragging and dropping any relevant GeoJSON file onto the IIAB Maps (http://box/maps) in your browser! For example try this GeoJSON file, to explore the shape of gerrymandered US Congressional districts: https://eric.clst.org/assets/wiki/uploads/Stuff/gz_2010_us_500_11_20m.json diff --git a/roles/osm-vector-maps/tasks/install.yml b/roles/osm-vector-maps/tasks/install.yml index ab28c7cd6..f46016ebc 100644 --- a/roles/osm-vector-maps/tasks/install.yml +++ b/roles/osm-vector-maps/tasks/install.yml @@ -1,3 +1,8 @@ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: "Install packages for map installation: python3-geojson, python3-pil, python3-wget, php{{ php_version }}-sqlite3 (can also be installed by www_base/tasks/php-stem.yml)" package: state: present @@ -29,7 +34,7 @@ - name: Download {{ osm_repo_url }}/{{ maps_branch }}/2020/map-catalog.json to {{ iiab_etc_path }} get_url: - url: "{{ osm_repo_url }}/{{ maps_branch }}/2020/map-catalog.json" + url: "{{ osm_repo_url }}/{{ maps_branch }}/2020/map-catalog.json" # e.g. https://raw.githubusercontent.com/iiab/maps/master dest: "{{ iiab_etc_path }}" # /etc/iiab timeout: "{{ download_timeout }}" @@ -196,6 +201,17 @@ # RECORD OSM Vector Maps AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'osm_vector_maps_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: osm-vector-maps + option: osm_vector_maps_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'osm_vector_maps_installed: True'" set_fact: osm_vector_maps_installed: True diff --git a/roles/pbx/README.adoc b/roles/pbx/README.adoc index bef5c3924..99791114e 100644 --- a/roles/pbx/README.adoc +++ b/roles/pbx/README.adoc @@ -4,9 +4,11 @@ https://internet-in-a-box.org[Internet-in-a-Box (IIAB)] can install https://asterisk.org/[Asterisk] and https://freepbx.org/[FreePBX] for Voice over IP (VoIP) calls using regular Android and iPhone softphone (SIP) apps — e.g. for low-cost and rural telephony. -As of May 2022, IIAB installs https://wiki.asterisk.org/wiki/display/AST/Asterisk+19+Documentation[Asterisk 19] and https://www.freepbx.org/freepbx-16-is-now-released-for-general-availability/[FreePBX 16]. +As of December 2024, IIAB supports https://www.asterisk.org/asterisk-news/asterisk-22-0-0-now-available/[Asterisk 22] and https://sangomakb.atlassian.net/wiki/spaces/FP/pages/222101505/FreePBX+17[FreePBX 17] (https://www.freepbx.org/freepbx-17-is-now-ga/[announcement]). A https://github.com/iiab/iiab/wiki/IIAB-Platforms#operating-systems[modern OS with PHP 8.x] is required (https://github.com/iiab/iiab/pull/3675[PR #3675]). -PHP 7.4 is REQUIRED (https://github.com/iiab/iiab/pull/2899[PR #2899]) and PHP 8.x does not yet work (https://github.com/iiab/iiab/pull/3019#issuecomment-962469346[PR #3109]) — so please consider installing this on https://github.com/iiab/iiab/wiki/IIAB-Platforms#operating-systems[Ubuntu 20.04, Debian 11, or Raspberry Pi OS 11 "Bullseye"]. +//// +*PHP 7.4 is unfortunately REQUIRED (https://github.com/iiab/iiab/pull/2899[PR #2899]) and PHP 8.x does not yet work (https://github.com/iiab/iiab/issues/3556[#3556], https://github.com/iiab/iiab/pull/3675[#3675]) — sadly this remains true as of 2024-01-13 with https://www.freepbx.org/freepbx-17-beta-release-and-debian-future/[FreePBX 17 BETA], and may remain true until https://github.com/FreePBX/framework/tree/release/17.0[FreePBX 17] is eventually released — so if you really must try to force an install onto dangerously EOL'd (end-of-life as of November 2022) PHP 7.4, consider an older OS like https://github.com/iiab/iiab/wiki/IIAB-Platforms#operating-systems[Ubuntu 20.04, Debian 11 "Bullseye", or 64-bit Raspberry Pi OS versions based on "Bullseye"] (https://github.com/iiab/iiab/pull/3523[PR #3523]). RECAP: IIAB does _NOT_ support such dangerous/older OS's!* +//// //// As of August 2021, IIAB installs https://wiki.asterisk.org/wiki/display/AST/Asterisk+18+Documentation[Asterisk 18] and https://www.freepbx.org/freepbx-16-beta-is-here/[FreePBX 16 Beta], as required by the latest PHP 7.4 Linux OS's (https://github.com/iiab/iiab/pull/2899[PR #2899]). Please consider installing this on https://github.com/iiab/iiab/wiki/IIAB-Platforms#operating-systems[Ubuntu 20.04+, Debian 11 — or the imminent Raspberry Pi OS 11 "Bullseye"]. @@ -34,22 +36,22 @@ https://en.wikipedia.org/wiki/FreePBX[FreePBX] is a web-based open source GUI (g Edit /etc/iiab/local_vars.yml to customize your Internet-in-a-Box? [Y/n] ---- + -Accept the challenge! Make sure your IIAB configuration file (https://wiki.iiab.io/go/FAQ#What_is_local_vars.yml_and_how_do_I_customize_it.3F[/etc/iiab/local_vars.yml]) contains: +Accept the challenge! Make sure your IIAB configuration file (https://wiki.iiab.io/go/FAQ#What_is_local_vars.yml_and_how_do_I_customize_it%3F[/etc/iiab/local_vars.yml]) contains: + ---- pbx_install: True pbx_enabled: True ---- + -FreePBX can be used with either or both web servers, NGINX on port 80 (as is new) and/or Apache on port 83 (as is traditional). +FreePBX can be used with either or both web servers — NGINX on port 80 (http://box/freepbx) and/or using the old approach with Apache on port 83 (http://box:83/freepbx). + -If you don't want Apache installed on your IIAB, and you prefer NGINX's shorter URL (http://box/freepbx), optionally set this line in your https://wiki.iiab.io/go/FAQ#What_is_local_vars.yml_and_how_do_I_customize_it.3F[/etc/iiab/local_vars.yml] prior to installing IIAB: +If you still want the older Apache approach, set this line in your https://wiki.iiab.io/go/FAQ#What_is_local_vars.yml_and_how_do_I_customize_it%3F[/etc/iiab/local_vars.yml] prior to installing IIAB: + ---- -pbx_use_apache: False +pbx_use_apache: True ---- + -Or, if you want to use FreePBX with Apache alone (http://box:83/freepbx), optionally set this line in your /etc/iiab/local_vars.yml: +If you want to disable to new NGINX approach, set this line in your /etc/iiab/local_vars.yml: + ---- pbx_use_nginx: False @@ -61,6 +63,14 @@ If using PBX intensively, please adjust `/etc/php/X.Y/apache2/php.ini`, `/etc/ph nginx_high_php_limits: True ---- + +//// +As of April 2023 (https://github.com/iiab/iiab/pull/3523[PR #3523]) IIAB will patch Asterisk automatically (https://github.com/asterisk/asterisk/pull/32[PR asterisk/asterisk#32]) so it can be run experimentally on Raspberry Pi, so long as you keep this default settings: ++ +---- +asterisk_rpi_patch: True +---- ++ +//// Optionally, you may want to enable https://github.com/wdoekes/asterisk-chan-dongle[chan_dongle], which is a channel driver for Huawei UMTS cards (e.g. 3G USB dongles) allowing regular voice calls over GSM mobile networks. You will need to configure a dongle post-install, for it to be recognized properly: + ---- @@ -150,6 +160,26 @@ image::files/linphone_setup.jpg[width='33%'] image::files/linphone_connected.jpg[width='33%'] * _If you've created more than one extension, make a call to another extension!_ If you've not yet made more than one extension, try calling an arbitrary extension, or try calling your own extension (your own phone number). ++ +Due to Linphone's inability for phones to ring when the screen is locked, you can alternatively use a softphone (SIP) app on your smartphone or laptop called Wave Lite. In this example we will use the [https://wiki.zenitel.com/wiki/Grandstream_Wave_Lite_mobile_app], on an Android phone. After you open the app, follow these steps: + +** Connect your smartphone or laptop to the *Internet in a Box* WiFi hotspot +** Go to Account Settings +** Add new account +** Select *SIP ACCOUNT* + +*** *Account name* is your name, e.g. John Doe +*** *Sip Server* is your IIAB server's IP address +*** *SIP User ID* is your extension number, e.g. 301 +*** *SIP Authentification ID* is your extension number, e.g. 301 +*** *Password* is the same as above *Secret* +*** *Confirm by clicking tick symbol ✓ (top right) ++ +image::files/wave_sip settings.png[width='33%'] + +** If the connection is successful, you will see a green circle next to your name [John Doe]. ++ +image::files/Wave_sip_phone_connected.png[width='33%'] ** You should see activity in the *FreePBX Statistics* applet at http://box/freebx (or http://box:83/freebx) > *Dashboard* ** Connection details may also be seen in the Asterisk logs at: `/var/logs/asterisk/full` @@ -289,6 +319,8 @@ Please also check the "Known Issues" at the bottom of https://github.com/iiab/ii _If there's a bug or serious problem with IIAB, please do https://internet-in-a-box.org/contributing.html[make contact] and post an issue here: https://github.com/iiab/iiab/issues_ +. Please see Asterisk's Security Advisories: https://www.asterisk.org/downloads/security-advisories/ + . Apache's `/var/lib/php/asterisk_sessions/` directory might also be needed for NGINX? + If not, the link:tasks/freepbx.yml#L175-L187[configuration of /var/lib/php/asterisk_sessions/] might be made conditional upon `when: not pbx_use_apache` @@ -305,9 +337,9 @@ Node.js applications like Asterisk/FreePBX, Node-RED and Sugarizer won't work on //// == Raspberry Pi Known Issues -As of 2019-02-14, "systemctl restart freepbx" failed more than 50% of the time when run on a https://wiki.iiab.io/go/FAQ#What_services_.28IIAB_apps.29_are_suggested_during_installation.3F[LARGE-sized] install of IIAB 6.7 on RPi 3 or RPi 3 B+. +As of 2019-02-14, "systemctl restart freepbx" failed more than 50% of the time when run on a https://wiki.iiab.io/go/FAQ#What_services_.28IIAB_apps.29_are_suggested_during_installation%3F[LARGE-sized] install of IIAB 6.7 on RPi 3 or RPi 3 B+. -It is possible that FreePBX restarts much more reliably when run on a SMALL-sized install of IIAB? Please https://wiki.iiab.io/go/FAQ#What_are_the_best_places_for_community_support.3F[contact us] if you can assist here in any way: https://github.com/iiab/iiab/issues/1493[#1493] +It is possible that FreePBX restarts much more reliably when run on a SMALL-sized install of IIAB? Please https://wiki.iiab.io/go/FAQ#What_are_the_best_places_for_community_support%3F[contact us] if you can assist here in any way: https://github.com/iiab/iiab/issues/1493[#1493] //// @@ -325,4 +357,10 @@ In May 2022, installation of FreePBX was made more resilient in https://github.c * Ron Raikes' routine to install FreePBX from GitHub: https://community.freepbx.org/t/asterisk-19-1-0-and-freepbx-install/81029/15 +In 2024, see also the official: + +* https://sangomakb.atlassian.net/wiki/spaces/FP/pages/222101505/FreePBX+17[FreePBX 17] Installation Script (for Debian 12): https://github.com/FreePBX/sng_freepbx_debian_install +* FreePBX 17 Installation: https://sangomakb.atlassian.net/wiki/spaces/FP/pages/230326391/FreePBX+17+Installation +* Step By Step Debian 12 Installation: https://sangomakb.atlassian.net/wiki/spaces/FP/pages/295403538/Step+By+Step+Debian+12+Installation + Thank you to _ALL_ who've contributed — including Lemuel D'Souza, Jerry Vonau, Adam Holt and Anish Mangal! diff --git a/roles/pbx/README.rst.unused b/roles/pbx/README.rst.unused index 19371b11e..867b7e876 100644 --- a/roles/pbx/README.rst.unused +++ b/roles/pbx/README.rst.unused @@ -33,7 +33,7 @@ FreePBX is a web-based open source GUI (graphical user interface) that controls Using It -------- -Prior to installing IIAB, make sure your `/etc/iiab/local_vars.yml `_ contains:: +Prior to installing IIAB, make sure your `/etc/iiab/local_vars.yml `_ contains:: pbx_install: True pbx_enabled: True @@ -159,9 +159,9 @@ Some useful asterisk commands and information Raspberry Pi Known Issues ------------------------- -|ss| As of 2019-02-14, "systemctl restart freepbx" failed more than 50% of the time when run on a `BIG-sized `_ install of IIAB 6.7 on RPi 3 or RPi 3 B+. +|ss| As of 2019-02-14, "systemctl restart freepbx" failed more than 50% of the time when run on a `BIG-sized `_ install of IIAB 6.7 on RPi 3 or RPi 3 B+. -It is possible that FreePBX restarts much more reliably when run on a MIN-sized install of IIAB? Please `contact us `_ if you can assist here in any way: `#1493 `_ |se| +It is possible that FreePBX restarts much more reliably when run on a MIN-sized install of IIAB? Please `contact us `_ if you can assist here in any way: `#1493 `_ |se| Raspberry Pi Zero W Warning --------------------------- diff --git a/roles/pbx/defaults/main.yml b/roles/pbx/defaults/main.yml index 1ef7b8125..647ad700d 100644 --- a/roles/pbx/defaults/main.yml +++ b/roles/pbx/defaults/main.yml @@ -8,9 +8,12 @@ # pbx_install: False # pbx_enabled: False -# pbx_use_apache: True # 2021-08-17: Set either to 'False' if nec -- please +# pbx_use_apache: False # 2023-04-03: Set to 'True' if nec -- please also # pbx_use_nginx: True # read github.com/iiab/iiab/issues/2914 & #2916, THX! +# 2023-04-03: For EXPERIMENTAL testing on Raspberry Pi... (#3489, PR #3523) +# asterisk_rpi_patch: True + # asterisk_chan_dongle: False # pbx_signaling_ports_chan_sip: 5160:5161 @@ -21,14 +24,15 @@ # All above are set in: github.com/iiab/iiab/blob/master/vars/default_vars.yml # If nec, change them by editing /etc/iiab/local_vars.yml prior to installing! + asterisk_url: https://downloads.asterisk.org/pub/telephony/asterisk -asterisk_src_file: asterisk-19-current.tar.gz +asterisk_src_file: asterisk-22-current.tar.gz asterisk_src_dir: "{{ iiab_base }}/asterisk" # /opt/iiab # freepbx_url: https://mirror.freepbx.org/modules/packages/freepbx/7.4 # freepbx_src_file: freepbx-16.0-latest.tgz # 2022-05-25 #3228: Filename has become bogus (as it's not really the latest!) Manually unpacking the latest .tar.gz for FreePBX 16.x from https://github.com/FreePBX/framework/tags to /opt/iiab/freepbx can work if absolutely nec. freepbx_git_url: https://github.com/FreePBX/framework -freepbx_git_branch: release/16.0 # EMERGING OPTION AS OF MAY 2022: https://github.com/FreePBX/framework/tree/release/17.0 +freepbx_git_branch: release/17.0 # STILL IN FLUX AS OF FEB 2024: https://github.com/FreePBX/framework/tree/release/17.0 freepbx_src_dir: "{{ iiab_base }}/freepbx" freepbx_install_dir: /var/www/html/freepbx diff --git a/roles/pbx/files/Wave_sip_phone_connected.png b/roles/pbx/files/Wave_sip_phone_connected.png new file mode 100644 index 000000000..88d85b1cd Binary files /dev/null and b/roles/pbx/files/Wave_sip_phone_connected.png differ diff --git a/roles/pbx/files/install_prereq.diff b/roles/pbx/files/install_prereq.diff new file mode 100644 index 000000000..0428b339a --- /dev/null +++ b/roles/pbx/files/install_prereq.diff @@ -0,0 +1,17 @@ +--- install_prereq.orig 2023-04-01 01:41:56.859545082 -0500 ++++ install_prereq 2023-04-01 01:44:28.744269701 -0500 +@@ -193,8 +193,13 @@ + tocheck="${tocheck} ^${pack}$ ~P^${pack}$" + done + pkgs=$(aptitude -F '%c %p' search ${tocheck} 2>/dev/null | awk '/^p/{print $2}') ++ arch=$(uname -m) + if [ ${#pkgs} -ne 0 ]; then +- echo $pkgs | sed -r -e "s/ ?[^ :]+:i386//g" ++ if [ "$arch" = "x86_64" ]; then ++ echo $pkgs | sed -r -e "s/ ?[^ :]+:i386//g" ++ elif [ "$arch" = "aarch64" ]; then ++ echo $pkgs | sed -r -e "s/ ?[^ :]+:armhf//g" ++ fi + fi + } + diff --git a/roles/pbx/files/wave_sip settings.png b/roles/pbx/files/wave_sip settings.png new file mode 100644 index 000000000..f5a75e4b3 Binary files /dev/null and b/roles/pbx/files/wave_sip settings.png differ diff --git a/roles/pbx/tasks/apache.yml b/roles/pbx/tasks/apache.yml index 5462a5ca5..dd05b7dc9 100644 --- a/roles/pbx/tasks/apache.yml +++ b/roles/pbx/tasks/apache.yml @@ -39,3 +39,14 @@ dest: /etc/{{ apache_service }}/sites-available/freepbx.conf # apache2 owner: "{{ apache_user }}" # www-data group: "{{ apache_user }}" + + +- name: "Set 'apache_installed: True'" + set_fact: + apache_installed: True + +- name: "Add 'apache_installed: True' to {{ iiab_state_file }}" + lineinfile: + path: "{{ iiab_state_file }}" # /etc/iiab/iiab_state.yml + regexp: '^apache_installed' + line: 'apache_installed: True' diff --git a/roles/pbx/tasks/asterisk.yml b/roles/pbx/tasks/asterisk.yml index 7c52248bf..1721d69d2 100644 --- a/roles/pbx/tasks/asterisk.yml +++ b/roles/pbx/tasks/asterisk.yml @@ -40,8 +40,6 @@ unarchive: src: "{{ downloads_dir }}/{{ asterisk_src_file }}" dest: "{{ asterisk_src_dir }}" - # owner: root - # group: root extra_opts: [--strip-components=1] creates: "{{ asterisk_src_dir }}/Makefile" @@ -55,6 +53,13 @@ # name: aptitude # state: latest +# https://github.com/iiab/iiab/issues/3489 +- name: "Asterisk - Apply patch to {{ asterisk_src_dir }}/contrib/scripts/install_prereq for Raspberry Pi (#3489) if 'asterisk_rpi_patch: True'" + ansible.posix.patch: + src: install_prereq.diff + dest: "{{ asterisk_src_dir }}/contrib/scripts/install_prereq" + when: asterisk_rpi_patch + - name: Asterisk - Run 'install_prereq install' for dependencies - CAN TAKE 2-5 MIN OR LONGER! shell: export DEBIAN_FRONTEND=noninteractive && ./contrib/scripts/install_prereq install args: @@ -78,8 +83,8 @@ creates: menuselect.makeopts - name: Asterisk - Do a bit of menuselect configuration - command: menuselect/menuselect --enable app_macro --enable format_mp3 menuselect.makeopts - # 2021-08-06: Let's standardize (ABOVE) if 6 others (BELOW) aren't needed? + command: menuselect/menuselect --enable format_mp3 menuselect.makeopts + # 2021-08-06 & 2023-11-19: Let's standardize (ABOVE) if 7 others (BELOW) aren't needed? # command: > # menuselect/menuselect --enable app_macro --enable format_mp3 # --enable CORE-SOUNDS-EN-WAV --enable CORE-SOUNDS-EN-G722 @@ -181,3 +186,14 @@ path: /etc/asterisk/asterisk.conf regexp: 'rungroup =' line: 'rungroup = asterisk' + + +- name: "Set 'asterisk_installed: True'" + set_fact: + asterisk_installed: True + +- name: "Add 'asterisk_installed: True' to {{ iiab_state_file }}" + lineinfile: + path: "{{ iiab_state_file }}" # /etc/iiab/iiab_state.yml + regexp: '^asterisk_installed' + line: 'asterisk_installed: True' diff --git a/roles/pbx/tasks/enable-or-disable.yml b/roles/pbx/tasks/enable-or-disable.yml index 2abc11405..6b1639a37 100644 --- a/roles/pbx/tasks/enable-or-disable.yml +++ b/roles/pbx/tasks/enable-or-disable.yml @@ -1,43 +1,42 @@ - name: JUST 1 SETTING TO TURN ON/OFF FOR APACHE - whereas NGINX below has 4... meta: noop -- name: EITHER - Create symlink /etc/{{ apache_service }}/sites-enabled/freepbx.conf to enable Apache's http://box:{{ pbx_http_port }}/freepbx - if pbx_use_apache and pbx_enabled # http://box:83/freepbx +- name: EITHER - Create symlink /etc/{{ apache_service }}/sites-enabled/freepbx.conf to enable Apache's http://box:{{ pbx_http_port }}/freepbx - if apache_installed is defined and pbx_use_apache and pbx_enabled # http://box:83/freepbx command: a2ensite freepbx.conf - when: pbx_use_apache and pbx_enabled + when: apache_installed is defined and pbx_use_apache and pbx_enabled -- name: OR ELSE - Delete symlink /etc/{{ apache_service }}/sites-enabled/freepbx.conf to disable Apache's http://box:{{ pbx_http_port }}/freepbx - if not (pbx_use_apache and pbx_enabled) +- name: OR ELSE - Delete symlink /etc/{{ apache_service }}/sites-enabled/freepbx.conf to disable Apache's http://box:{{ pbx_http_port }}/freepbx - if not (apache_installed is defined and pbx_use_apache and pbx_enabled) file: # As 'a2dissite freepbx.conf' might not be installed path: /etc/{{ apache_service }}/sites-enabled/freepbx.conf # apache2 state: absent - when: not (pbx_use_apache and pbx_enabled) + when: not (apache_installed is defined and pbx_use_apache and pbx_enabled) - name: "ENACT ABOVE SETTING FOR APACHE - 'pbx_use_apache: False' might arise later, so best ALWAYS run..." meta: noop -- name: EITHER - Restart & Enable '{{ apache_service }}' systemd service - if pbx_use_apache and pbx_enabled +- name: EITHER - Restart & Enable '{{ apache_service }}' systemd service - if apache_installed is defined and pbx_use_apache and pbx_enabled systemd: daemon_reload: yes name: "{{ apache_service }}" # apache2 state: restarted enabled: yes - when: pbx_use_apache and pbx_enabled - ignore_errors: yes # In case Apache not installed + when: apache_installed is defined and pbx_use_apache and pbx_enabled -- name: OR ELSE - Stop & Disable '{{ apache_service }}' systemd service - if not (pbx_use_apache and pbx_enabled) +- name: OR ELSE - Stop & Disable '{{ apache_service }}' systemd service - if not (apache_installed is defined and pbx_use_apache and pbx_enabled) systemd: daemon_reload: yes name: "{{ apache_service }}" state: stopped enabled: no - when: not (pbx_use_apache and pbx_enabled) - ignore_errors: yes # In case Apache not installed + when: not (apache_installed is defined and pbx_use_apache and pbx_enabled) + ignore_errors: yes # If Apache not installed, HIGHLIGHT IN RED FOR IMPLEMENTER/OPERATOR - name: Open-or-Close Asterix ports (including Apache port {{ pbx_http_port }}) in iptables firewall, depending on pbx_enabled [{{ pbx_enabled }}] in local_vars.yml - in support of './runrole pbx' command: /usr/bin/iiab-gen-iptables - ignore_errors: yes # iptables installed in 2-common, but iiab-gen-tables may not be set up until roles/network runs later - - + when: iiab_stage|int == 9 and network_enabled +# iptables installed in 1-prep via roles/network/tasks/install.yml, but +# iiab-gen-tables may not be set up, until/if roles/network runs later. - block: diff --git a/roles/pbx/tasks/freepbx.yml b/roles/pbx/tasks/freepbx.yml index df541cd96..1bba7773c 100644 --- a/roles/pbx/tasks/freepbx.yml +++ b/roles/pbx/tasks/freepbx.yml @@ -11,6 +11,9 @@ # 2021-08-12: Let's try to track the "official" init.d / update-rc.d # instructions ('update-rc.d -f asterisk remove') but using systemd instead, # to be more future-proof? +# 2023-04-02: Disagreement remains the same as 2 years ago: +# @jvonau wants to stop service asterisk (from the asterisk install). +# @holta prefers we track Asterisk/FreePBX community's mainline/consensus. - name: "FreePBX - Disable 'asterisk' systemd service, giving FreePBX full control during boot - similar to officially recommended 'update-rc.d -f asterisk remove' at: https://wiki.freepbx.org/display/FOP/Installing+FreePBX+16+on+Debian+10.9" systemd: daemon_reload: yes @@ -62,13 +65,13 @@ # state: present # when: php_version is version('8.0', '<') -- name: "Run roles/www_options/tasks/php-settings.yml with 'nginx_high_php_limits: False' by default" +- name: "FreePBX - Run roles/www_options/tasks/php-settings.yml with 'nginx_high_php_limits: False' by default" include_tasks: roles/www_options/tasks/php-settings.yml when: php_settings_done is undefined - name: FreePBX - Install and configure Apache - if pbx_use_apache include_tasks: apache.yml - when: pbx_use_apache + when: pbx_use_apache and apache_installed is undefined # - name: FreePBX - Download {{ freepbx_url }}/{{ freepbx_src_file }} to {{ downloads_dir }} @@ -229,28 +232,46 @@ dest: /etc/asterisk/cdr_mysql.conf -- name: FreePBX - 2-step install - won't run if {{ freepbx_install_dir }} already exists - FAST W/ GITHUB (OR freepbx-16.0-latest.tgz CAN TAKE 3-12 MIN OR LONGER!) - command: "{{ item }}" +# 2023-05-21: Asterisk is in fact normally OFF at this point (shouldn't matter!) +# - name: FreePBX - Spawn 'nohup ./start_asterisk start' in {{ freepbx_src_dir }} +# command: nohup ./start_asterisk start +# args: +# chdir: "{{ freepbx_src_dir }}" + +# 2023-06-21: Interim use of 'nohup' didn't quite solve ansible 2.15.x +# regression ansible/ansible#80863, which led to PR's #3588 and #3604. +- name: FreePBX - INTERIM USE OF 'systemctl start asterisk' TIL ANSIBLE FIXES 2.15.x REGRESSION ansible/ansible#80863 -- AS EVEN 'nohup ./start_asterisk start' DOESN'T WORK WITH 2.15.0 AND 2.15.1 + systemd: + name: asterisk + state: started + #enabled: yes + +# 2023-06-21: Commands to try, to see if Asterisk has started & stabilized? +# pidof asterisk +# /usr/sbin/asterisk -rx 'core show version' +# journalctl -eu asterisk + +- name: FreePBX - WAIT 5 SECONDS TO SIMULATE './start_asterisk start' (REQUIRED DUE TO ABOVE ANSIBLE BUG) THEN... install FreePBX to {{ freepbx_install_dir }} - FAST W/ GITHUB (OR freepbx-16.0-latest.tgz CAN TAKE 3-12 MIN OR LONGER!) + shell: sleep 5 && ./install -n --webroot {{ freepbx_install_dir }} --dbuser {{ asterisk_db_user }} --dbpass {{ asterisk_db_password }} args: chdir: "{{ freepbx_src_dir }}" - creates: "{{ freepbx_install_dir }}" # /var/www/html/freepbx - with_items: - - ./start_asterisk start - - ./install -n --webroot {{ freepbx_install_dir }} --dbuser {{ asterisk_db_user }} --dbpass {{ asterisk_db_password }} - # - ./install -n --webroot {{ freepbx_install_dir }} --dbuser {{ asterisk_db_user }} --dbpass {{ asterisk_db_password }} --dbname {{ asterisk_db_dbname }} --cdrdbname {{ asterisk_db_cdrdbname }} + #creates: "{{ freepbx_install_dir }}" # /var/www/html/freepbx + ignore_errors: yes # 2024-02-25: UGLY / TEMPORARY WORKAROUND #1 OF 2, to bypass "You have successfully installed FreePBX" w/ exit code 1 -- https://github.com/iiab/iiab/pull/3675#issuecomment-1890590227 # 2022-05-25 BACKGROUND: https://github.com/iiab/iiab/pull/3229#issuecomment-1138061460 - name: FreePBX - Revert the above just-installed FreePBX 'framework' module by a few weeks-or-so from GitHub's bleeding edge, to a more official version (which can help to install the ~15 modules below!) command: fwconsole ma downloadinstall framework -# ERROR IF RUN BELOW: "Unable to connect to remote asterisk" -- name: FreePBX - Run 'fwconsole reload' - as an additional precaution, per Ron Raikes @ https://community.freepbx.org/t/asterisk-19-1-0-and-freepbx-install/81029/15 - command: fwconsole reload +# 2024-02-25: UGLY / TEMPORARY WORKAROUND #2 OF 2, to bypass... 'In DialplanHooks.class.php line 163: Undefined array key "DialplanHooks"' -- https://github.com/iiab/iiab/pull/3675#issuecomment-1890590227 +## ERROR IF RUN BELOW: "Unable to connect to remote asterisk" +#- name: FreePBX - Run 'fwconsole reload' - as an additional precaution, per Ron Raikes @ https://community.freepbx.org/t/asterisk-19-1-0-and-freepbx-install/81029/15 +# command: fwconsole reload # DEFAULT MODULE LIST AUG 2021: https://github.com/iiab/iiab/pull/2916#issuecomment-894601522 # YIELDS 2 MORE AS OF MAY 2022: https://github.com/iiab/iiab/pull/3229#issuecomment-1138566339 -- name: FreePBX - Download + Install 15 additional FreePBX default modules (of about 70 total) as if we were installing freepbx-16.0-latest.tgz - THIS CAN TAKE SEVERAL MIN! +# NOTHING CHANGED (?) FEB 2024: https://github.com/iiab/iiab/pull/3675#issuecomment-1963081323 +- name: FreePBX - Download + Install 15 additional FreePBX default modules (of about 70 total) as if we were installing freepbx-17.0-latest.tgz - THIS CAN TAKE SEVERAL MIN! command: fwconsole ma downloadinstall callrecording cdr conferences core customappsreg dashboard featurecodeadmin infoservices logfiles music pm2 recordings sipsettings soundlang voicemail diff --git a/roles/pbx/tasks/install.yml b/roles/pbx/tasks/install.yml index 474ddb58d..5c49dfa14 100644 --- a/roles/pbx/tasks/install.yml +++ b/roles/pbx/tasks/install.yml @@ -22,6 +22,26 @@ # when: nodejs_version != "12.x" +- name: "Set 'mysql_install: True' and 'mysql_enabled: True'" + set_fact: + mysql_install: True + mysql_enabled: True + +- name: MYSQL - run 'mysql' role (attempt to install & enable MySQL / MariaDB) + include_role: + name: mysql + +- name: FAIL (STOP THE INSTALL) IF 'mysql_installed is undefined' + fail: + msg: "PBX install cannot proceed, as MySQL / MariaDB is not installed." + when: mysql_installed is undefined + + +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + # 2021-08-09: Moved to roles/pbx/tasks/apache.yml # - name: "Set 'apache_install: True' and 'apache_enabled: True'" @@ -36,6 +56,7 @@ - name: Install Asterisk include_tasks: asterisk.yml + when: asterisk_installed is undefined - name: Install FreePBX include_tasks: freepbx.yml @@ -43,6 +64,17 @@ # RECORD PBX AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'pbx_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: pbx + option: pbx_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'pbx_installed: True'" set_fact: pbx_installed: True diff --git a/roles/pbx/tasks/main.yml b/roles/pbx/tasks/main.yml index 81a9dcebd..669f05277 100644 --- a/roles/pbx/tasks/main.yml +++ b/roles/pbx/tasks/main.yml @@ -21,6 +21,12 @@ - block: + - name: If PHP >= 8 is detected, loudly warn that FreePBX does not support PHP 8+ (as of April 2023) + fail: # FORCE IT RED, allowing adventurous/testing people to proceed at their own risk! + msg: 'FreePBX DOES NOT SUPPORT PHP 8+ AS OF APRIL 2023. YOU ARE PROCEEDING ENTIRELY AT YOUR OWN RISK.' + when: php_version is version('8.0', '>=') + ignore_errors: yes + - name: Install PBX if pbx_installed is not defined, e.g. in {{ iiab_state_file }} # /etc/iiab/iiab_state.yml include_tasks: install.yml when: pbx_installed is undefined @@ -47,6 +53,10 @@ value: "{{ pbx_install }}" - option: pbx_enabled value: "{{ pbx_enabled }}" + - option: pbx_use_apache + value: "{{ pbx_use_apache }}" + - option: pbx_use_nginx + value: "{{ pbx_use_nginx }}" rescue: diff --git a/roles/phpmyadmin/README.md b/roles/phpmyadmin/README.md index a742f8c9d..379812957 100644 --- a/roles/phpmyadmin/README.md +++ b/roles/phpmyadmin/README.md @@ -8,7 +8,7 @@ 2. phpMyAdmin, because it is a browser-based HTML PHP application, is limited in what it can do, and what it can access — until the "root" user creates users and access privileges, as mentioned above. (HTML servers always run with very low privileges) #### Installing phpMyAdmin -1. First, a user will need to set `phpmyadmin_install: True` and `phpmyadmin_enabled: True` in [/etc/iiab/local_vars.yml](http://wiki.laptop.org/go/IIAB/FAQ#What_is_local_vars.yml_and_how_do_I_customize_it.3F) +1. First, a user will need to set `phpmyadmin_install: True` and `phpmyadmin_enabled: True` in [/etc/iiab/local_vars.yml](http://wiki.laptop.org/go/IIAB/FAQ#What_is_local_vars.yml_and_how_do_I_customize_it%3F) 2. Then install IIAB. Or if IIAB is already installed, run: ``` cd /opt/iiab/iiab diff --git a/roles/phpmyadmin/defaults/main.yml b/roles/phpmyadmin/defaults/main.yml index ff6343c56..b898ae5bd 100644 --- a/roles/phpmyadmin/defaults/main.yml +++ b/roles/phpmyadmin/defaults/main.yml @@ -4,7 +4,7 @@ # All above are set in: github.com/iiab/iiab/blob/master/vars/default_vars.yml # If nec, change them by editing /etc/iiab/local_vars.yml prior to installing! -phpmyadmin_version: 5.2.0 +phpmyadmin_version: 5.2.1 phpmyadmin_name: "phpMyAdmin-{{ phpmyadmin_version }}-all-languages" phpmyadmin_dl_url: "https://files.phpmyadmin.net/phpMyAdmin/{{ phpmyadmin_version }}/{{ phpmyadmin_name }}.tar.xz" phpmyadmin_name_zip: "{{ phpmyadmin_version }}/{{ phpmyadmin_name }}.tar.xz" diff --git a/roles/phpmyadmin/tasks/install.yml b/roles/phpmyadmin/tasks/install.yml index 345927a04..7d510de69 100644 --- a/roles/phpmyadmin/tasks/install.yml +++ b/roles/phpmyadmin/tasks/install.yml @@ -1,3 +1,8 @@ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: Download {{ phpmyadmin_dl_url }} to {{ downloads_dir }} get_url: url: "{{ phpmyadmin_dl_url }}" # e.g. https://files.phpmyadmin.net/phpMyAdmin/5.0.4/phpMyAdmin-5.0.4-all-languages.zip @@ -48,6 +53,17 @@ # RECORD phpMyAdmin AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'phpmyadmin_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: phpmyadmin + option: phpmyadmin_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'phpmyadmin_installed: True'" set_fact: phpmyadmin_installed: True diff --git a/roles/postgresql/tasks/install.yml b/roles/postgresql/tasks/install.yml index 214f8b028..ce14600c5 100644 --- a/roles/postgresql/tasks/install.yml +++ b/roles/postgresql/tasks/install.yml @@ -1,11 +1,22 @@ -- name: 'Install packages: postgresql, postgresql-client, python3-psycopg2' +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + +- name: 'Install packages: postgresql, postgresql-client' package: name: - postgresql - postgresql-client - - python3-psycopg2 # For Ansible modules {postgresql_db, postgresql_user} in Ansible collection community.postgresql -- used in moodle/tasks/install.yml + #- python3-psycopg2 # For Ansible modules {postgresql_db, postgresql_user} in Ansible collection community.postgresql -- used in moodle/tasks/install.yml state: present +- name: pip install 'psycopg' (NEW Psycopg 3) into venv /usr/local/ansible -- for Ansible modules {postgresql_db, postgresql_user} in Ansible collection community.postgresql -- used in moodle/tasks/install.yml + pip: + name: psycopg + virtualenv: /usr/local/ansible + extra_args: "--upgrade --no-cache-dir --prefer-binary" # 2023-10-01: Lifesaver when recent wheels (e.g. piwheels.org) are inevitably not yet built! SEE #3560 + - name: Run shell command "pg_config --version" to extract MAJOR version number -- strip off MINOR/PATCH version number(s) shell: pg_config --version | sed 's/^[^0-9]*//; s/[^0-9].*//' register: pg_config_version @@ -90,6 +101,17 @@ # RECORD PostgreSQL AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'postgresql_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: postgresql + option: postgresql_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'postgresql_installed: True'" set_fact: postgresql_installed: True diff --git a/roles/pylibs/tasks/main.yml b/roles/pylibs/tasks/main.yml index f7ffa0f1d..9283c44f3 100644 --- a/roles/pylibs/tasks/main.yml +++ b/roles/pylibs/tasks/main.yml @@ -1,3 +1,8 @@ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: Install iiab lib files template: src: "{{ item.src }}" @@ -13,6 +18,17 @@ # RECORD pylibs AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'pylibs_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: pylibs + option: pylibs_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'pylibs_installed: True'" set_fact: pylibs_installed: True diff --git a/roles/pylibs/templates/iiab_lib.py b/roles/pylibs/templates/iiab_lib.py index ef9da7e82..13044c0c2 100644 --- a/roles/pylibs/templates/iiab_lib.py +++ b/roles/pylibs/templates/iiab_lib.py @@ -6,6 +6,7 @@ import os import json import subprocess import shlex +import re import xml.etree.ElementTree as ET import iiab.iiab_const as CONST @@ -46,11 +47,17 @@ def get_zim_list(path): if filename in CONST.old_zim_map: # handle old names that don't parse perma_ref = CONST.old_zim_map[filename] else: - ulpos = filename.rfind("_") - # but old gutenberg and some other names are not canonical - if filename.rfind("-") < 0: # non-canonical name - ulpos = filename[:ulpos].rfind("_") - perma_ref = filename[:ulpos] + # handle various zim name patterns: + # 1. canonical zim ending in _YYYY-MM + # as of 10/16/2024 it looks like all Kiwix zims fit this pattern + # 2. otherwise assume no versioning and perma_ref = filename + + match = re.search("_[0-5][0-9][0-5][0-9]-[0-5][0-9]$", filename) + if match: + perma_ref = filename[: match.span()[0]] + else: + perma_ref = filename + zim_info['file_name'] = filename zim_versions[perma_ref] = zim_info # if there are multiples, last should win return files_processed, zim_versions diff --git a/roles/remoteit/README.md b/roles/remoteit/README.md index 5a7cf8bbb..910f55409 100644 --- a/roles/remoteit/README.md +++ b/roles/remoteit/README.md @@ -2,7 +2,7 @@ Remote.it can be a [great way](https://docs.remote.it/introduction/get-started/readme) to remotely support an Internet-in-a-Box (IIAB). -As of [October 2022](https://remote.it/pricing/), 5 IIAB devices can be managed for free, and an unlimited number can be managed for $10/month. +As of [2024](https://remote.it/pricing/), 5 IIAB devices can be managed for free (their personal / non-commercial plan) and larger numbers for $10+/month. For other approaches, please see [FAQ.IIAB.IO](https://wiki.iiab.io/go/FAQ) -> "How can I remotely manage my Internet-in-a-Box?" @@ -14,13 +14,13 @@ For other approaches, please see [FAQ.IIAB.IO](https://wiki.iiab.io/go/FAQ) -> " 2. Consider downloading and installing the remote.it [desktop application](https://remote.it/download/) (e.g. for Windows, macOS or Linux) on your own laptop/computer. Their https://remote.it Web Portal and [mobile apps](https://docs.remote.it/introduction/get-started/readme#installation-packages) are also sometimes sufficient, but less functional. - COMPARISON: "The Desktop and [CLI](https://docs.remote.it/software/cli) can [each] support both peer to peer connections and proxy connections [whereas] the Web Portal and API can only support proxy connections" according to https://docs.remote.it/software/device-package/usage + 2023-07-26 WARNING: IIAB no longer installs the `/usr/bin/remoteit` [command-line interface (CLI)](https://docs.remote.it/software/cli), as it can [no longer coexist](https://github.com/iiab/iiab/blob/9d27ff04184fc971b0a8737ba0d14b69d433a5ad/roles/remoteit/tasks/install.yml#L116-L132) with the core `remoteit` Device Package. Whereas in the past the remote.it CLI had offered [a few more features](https://support.remote.it/hc/en-us/articles/4412786750861-Install-the-remoteit-agent-on-your-device): "The Desktop and [CLI](https://docs.remote.it/software/cli) can [each] support both peer to peer connections and proxy connections [whereas] the Web Portal and API can only support proxy connections" according to https://docs.remote.it/software/device-package/usage ### OPTION #1: Generate a remote.it claim code for your IIAB + register it + authorize services/ports -Prerequisite: Find any IIAB with `remoteit_installed: True` in `/etc/iiab/iiab_state.yml` (this is the default!) This means that the remote.it [Device Package](https://docs.remote.it/software/device-package) is already installed on your IIAB, most important. It also means the _strictly optional_ `/usr/bin/remoteit` [command-line interface (CLI)](https://docs.remote.it/software/cli) is installed, offering [a few more features](https://support.remote.it/hc/en-us/articles/4412786750861-Install-the-remoteit-agent-on-your-device) than the Device Package. +Prerequisite: Find any IIAB with `remoteit_installed: True` in `/etc/iiab/iiab_state.yml` (this is the default!) This means that the remote.it [Device Package](https://docs.remote.it/software/device-package) is already installed on your IIAB, most important. 1. Run `sudo iiab-remoteit` to enable remote.it on your IIAB: @@ -43,7 +43,7 @@ Prerequisite: Find any IIAB with `remoteit_installed: True` in `/etc/iiab/iiab_s 2. If your IIAB software is already installed, run `sudo iiab-remoteit` then skip to Step 5. below. -3. If your IIAB software isn't yet installed, set `remoteit_install` and `remoteit_enabled` to `True` in its [/etc/iiab/local_vars.yml](https://wiki.iiab.io/go/FAQ#What_is_local_vars.yml_and_how_do_I_customize_it.3F) +3. If your IIAB software isn't yet installed, set `remoteit_install` and `remoteit_enabled` to `True` in its [/etc/iiab/local_vars.yml](https://wiki.iiab.io/go/FAQ#What_is_local_vars.yml_and_how_do_I_customize_it%3F) Install [IIAB software](https://download.iiab.io/) e.g. by running `sudo iiab` then follow any on-screen instructions — until "INTERNET-IN-A-BOX (IIAB) SOFTWARE INSTALL IS COMPLETE" eventually appears on screen. --> @@ -98,7 +98,7 @@ Prerequisite: Find any IIAB with `remoteit_installed: True` in `/etc/iiab/iiab_s 1. Copy your remote.it account _license key_ from their Desktop Application (https://remote.it/download/) or from their Web Portal (https://remote.it) — as shown in this [screenshot](https://docs.remote.it/oem-and-bulk-provisioning/registration-into-a-users-account#3.-user-receives-the-device-and-registers-his-account). - Paste it into your IIAB's [/etc/iiab/local_vars.yml](https://wiki.iiab.io/go/FAQ#What_is_local_vars.yml_and_how_do_I_customize_it.3F) as in this example: + Paste it into your IIAB's [/etc/iiab/local_vars.yml](https://wiki.iiab.io/go/FAQ#What_is_local_vars.yml_and_how_do_I_customize_it%3F) as in this example: ``` remoteit_license_key: 592AA9BB-XXXX-YYYY-ZZZZ-6E27654C3DF6 @@ -158,7 +158,7 @@ Prerequisite: Find any IIAB with `remoteit_installed: True` in `/etc/iiab/iiab_s - https://docs.remote.it - - https://docs.remote.it/developer-tools/cli-usage + - ~https://docs.remote.it/developer-tools/cli-usage~ - https://docs.remote.it/oem-and-bulk-provisioning/registration-into-a-users-account - https://support.remote.it - https://support.remote.it/hc/en-us/categories/360003417511-Getting-Started diff --git a/roles/remoteit/defaults/main.yml b/roles/remoteit/defaults/main.yml index 5acf6b379..0011567bd 100644 --- a/roles/remoteit/defaults/main.yml +++ b/roles/remoteit/defaults/main.yml @@ -41,16 +41,19 @@ # SEE https://www.remote.it/download-list # https://www.remote.it/download-list?products=cli to refine arch/URL below # BUT https://docs.remote.it/software/cli/overview can be useful OR stale :/ -remoteit_arch_dict: - armv6: arm-v6 - armv6l: arm-v6 - armv7: arm-v7 - armv7l: arm-v7 - armv8: aarch64 - aarch64: aarch64 - x86_64: x86_64 -remoteit_arch: "{{ remoteit_arch_dict[ansible_machine] | default('unknown') }}" # A bit safer than ansible_architecture (see kiwix/defaults/main.yml) -remoteit_cli_url: https://downloads.remote.it/cli/latest/remoteit.{{ remoteit_arch }}-linux +# +# 2023-07-26: Remote.It CLI can no longer coexist with their "Device Package" +# SEE remoteit/tasks/install.yml Line ~121. +# remoteit_arch_dict: +# armv6: arm-v6 +# armv6l: arm-v6 +# armv7: arm-v7 +# armv7l: arm-v7 +# armv8: aarch64 +# aarch64: aarch64 +# x86_64: x86_64 +# remoteit_arch: "{{ remoteit_arch_dict[ansible_machine] | default('unknown') }}" # A bit safer than ansible_architecture (see kiwix/defaults/main.yml) +# remoteit_cli_url: https://downloads.remote.it/cli/latest/remoteit.{{ remoteit_arch }}-linux # OPTION #1: Run 'sudo iiab-remoteit' after IIAB is installed. diff --git a/roles/remoteit/tasks/enable-or-disable.yml b/roles/remoteit/tasks/enable-or-disable.yml index 5fba120ca..0023e0b17 100644 --- a/roles/remoteit/tasks/enable-or-disable.yml +++ b/roles/remoteit/tasks/enable-or-disable.yml @@ -33,7 +33,7 @@ # service, that they removed from 4.15.2 device packages on 2022-09-07. # (Either way, the job below never deletes /etc/remoteit/registration) -- name: 'Run /usr/share/remoteit/refresh.sh to put a claim code in /etc/remoteit/config.json (if you don''t already have a license key in /etc/remoteit/registration) -- FYI this spawns 2 "child" services/daemons: schannel & e.g. remoteit@80:00:01:7F:7E:00:56:36.service' +- name: 'Run /usr/share/remoteit/refresh.sh to put a claim code in /etc/remoteit/config.json (if you don''t already have a license key in /etc/remoteit/registration) -- FYI this should spawn 2 "child" services/daemons: schannel & e.g. remoteit@80:00:01:7F:7E:00:56:36.service' command: /usr/share/remoteit/refresh.sh when: remoteit_enabled @@ -59,6 +59,7 @@ name: schannel enabled: no state: stopped + ignore_errors: yes # 2023-06-12: Let's make these rare-but-unavoidable errors RED very intentionally, as below. Thanks to @neomatrixcode for surfacing this GitHub Actions problem, likely arising from inbound ICMP being blocked during remote.it install and/or above refresh.sh setup: https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#cloud-hosts-used-by-github-hosted-runners when: not remoteit_enabled - name: Stop & Disable "Remote tcp connection services" remoteit@* found in /etc/systemd/system/multi-user.target.wants/ e.g. remoteit@80:00:01:7F:7E:00:56:36.service diff --git a/roles/remoteit/tasks/install.yml b/roles/remoteit/tasks/install.yml index 360cb7397..8d8874f2e 100644 --- a/roles/remoteit/tasks/install.yml +++ b/roles/remoteit/tasks/install.yml @@ -1,3 +1,8 @@ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + # - name: Fail if architecture remoteit_device_suffix == "unknown" # fail: # msg: "Could not find a remote.it Device Package (.deb) for CPU architecture \"{{ ansible_architecture }}\"" @@ -108,22 +113,38 @@ mode: 0755 -- name: Fail if architecture remoteit_arch == "unknown" - fail: - msg: "Could not find a remote.it CLI binary for CPU architecture \"{{ ansible_architecture }}\"" - when: remoteit_arch == "unknown" - -- name: Download OPTIONAL {{ remoteit_cli_url }} (CLI) to /usr/bin/remoteit (755) - get_url: - url: "{{ remoteit_cli_url }}" - dest: /usr/bin/remoteit - mode: 0755 - force: yes - timeout: "{{ download_timeout }}" +# 2023-07-26: Remote.It CLI used to coexist fine with their "Device Package" +# e.g. it worked with remoteit apt package 4.17.12 in Q2 2023. +# But no longer--with remoteit apt package 4.18.4 (in Q3 2023) which fails to +# install with error: "Device Package cannot coexist with Remote.It CLI" +# +# - name: Fail if architecture remoteit_arch == "unknown" +# fail: +# msg: "Could not find a remote.it CLI binary for CPU architecture \"{{ ansible_architecture }}\"" +# when: remoteit_arch == "unknown" +# +# - name: Download OPTIONAL {{ remoteit_cli_url }} (CLI) to /usr/bin/remoteit (755) +# get_url: +# url: "{{ remoteit_cli_url }}" # e.g. https://downloads.remote.it/cli/latest/remoteit.{{ remoteit_arch }}-linux +# dest: /usr/bin/remoteit +# mode: 0755 +# force: yes +# timeout: "{{ download_timeout }}" # RECORD remote.it AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'remoteit_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: remoteit + option: remoteit_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'remoteit_installed: True'" set_fact: remoteit_installed: True diff --git a/roles/samba/README.rst b/roles/samba/README.rst index ff9296f4c..197448760 100644 --- a/roles/samba/README.rst +++ b/roles/samba/README.rst @@ -3,7 +3,7 @@ Samba README Do you want your Internet-in-a-Box (IIAB) to act as a file server for your classroom or school? -If `Samba `_ is installed and enabled as part of your IIAB's `/etc/iiab/local_vars.yml `_, your IIAB server can advertise a shared "public" folder, available to Windows PC's and laptops on your network. +If `Samba `_ is installed and enabled as part of your IIAB's `/etc/iiab/local_vars.yml `_, your IIAB server can advertise a shared "public" folder, available to Windows PC's and laptops on your network. Default Permissions ------------------- diff --git a/roles/samba/tasks/install.yml b/roles/samba/tasks/install.yml index 4b804168f..1ebc623ed 100644 --- a/roles/samba/tasks/install.yml +++ b/roles/samba/tasks/install.yml @@ -1,3 +1,8 @@ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: "Create smb user: {{ smbuser }}" user: name: "{{ smbuser }}" @@ -31,6 +36,17 @@ # RECORD Samba AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'samba_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: samba + option: samba_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'samba_installed: True'" set_fact: samba_installed: True diff --git a/roles/samba/tasks/main.yml b/roles/samba/tasks/main.yml index 801d725f4..12d06f2d4 100755 --- a/roles/samba/tasks/main.yml +++ b/roles/samba/tasks/main.yml @@ -19,26 +19,33 @@ quiet: yes -- name: Install Samba if 'samba_installed' not defined, e.g. in {{ iiab_state_file }} # /etc/iiab/iiab_state.yml - include_tasks: install.yml - when: samba_installed is undefined +- block: + - name: Install Samba if 'samba_installed' not defined, e.g. in {{ iiab_state_file }} # /etc/iiab/iiab_state.yml + include_tasks: install.yml + when: samba_installed is undefined -- include_tasks: enable-or-disable.yml + - include_tasks: enable-or-disable.yml + - name: Add 'samba' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: samba + option: "{{ item.option }}" + value: "{{ item.value | string }}" + with_items: + - option: name + value: Samba + - option: description + value: '"Samba is a Microsoft-compatible network file system that re-implements SMB/CIFS (Common Internet File System)."' + - option: samba_install + value: "{{ samba_install }}" + - option: samba_enabled + value: "{{ samba_enabled }}" -- name: Add 'samba' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini - section: samba - option: "{{ item.option }}" - value: "{{ item.value | string }}" - with_items: - - option: name - value: Samba - - option: description - value: '"Samba is a Microsoft-compatible network file system that re-implements SMB/CIFS (Common Internet File System)."' - - option: samba_install - value: "{{ samba_install }}" - - option: samba_enabled - value: "{{ samba_enabled }}" + rescue: + + - name: 'SEE ERROR ABOVE (skip_role_on_error: {{ skip_role_on_error }})' + fail: + msg: "" + when: not skip_role_on_error diff --git a/roles/sshd/defaults/main.yml b/roles/sshd/defaults/main.yml index 5c9c5dc17..83a3cf36a 100644 --- a/roles/sshd/defaults/main.yml +++ b/roles/sshd/defaults/main.yml @@ -1,4 +1,4 @@ -# sshd_install: True # Required by OpenVPN +# sshd_install: True # sshd_enabled: True # sshd_port: 22 # Not fully functional. SEE: roles/sshd/tasks/install.yml diff --git a/roles/sshd/tasks/install.yml b/roles/sshd/tasks/install.yml index 86d1e9360..b5b3271bc 100644 --- a/roles/sshd/tasks/install.yml +++ b/roles/sshd/tasks/install.yml @@ -9,6 +9,12 @@ # # 2) Use Ansible handler to reload ssh? + +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: "Install ssh daemon using package: {{ sshd_package }}" package: name: "{{ sshd_package }}" @@ -41,6 +47,17 @@ # RECORD sshd AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'sshd_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: sshd + option: sshd_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'sshd_installed: True'" set_fact: sshd_installed: True diff --git a/roles/sugarizer/defaults/main.yml b/roles/sugarizer/defaults/main.yml index f43f85374..ad5e48843 100644 --- a/roles/sugarizer/defaults/main.yml +++ b/roles/sugarizer/defaults/main.yml @@ -9,11 +9,11 @@ # All above are set in: github.com/iiab/iiab/blob/master/vars/default_vars.yml # If nec, change them by editing /etc/iiab/local_vars.yml prior to installing! -sugarizer_dir_version: sugarizer-1.6.0 # WAS: sugarizer-1.0, sugarizer-master, sugarizer-1.1.0, sugarizer-1.2.0, sugarizer-1.3.0, sugarizer-1.4.0, sugarizer-1.5.0 -sugarizer_git_version: v1.6.0 # WAS: v1.0.1, master, v1.1.0, v1.2.0, v1.3.0, v1.4.0, v1.5.0 +sugarizer_dir_version: sugarizer-1.8.0 # WAS: sugarizer-1.0, sugarizer-master, sugarizer-1.1.0, sugarizer-1.2.0, sugarizer-1.3.0, sugarizer-1.4.0, sugarizer-1.5.0, sugarizer-1.6.0, sugarizer-1.7.0 +sugarizer_git_version: v1.8.0 # WAS: v1.0.1, master, v1.1.0, v1.2.0, v1.3.0, v1.4.0, v1.5.0, v1.6.0, v1.7.0 # PLEASE HELP MONITOR https://github.com/llaske/sugarizer/releases -sugarizer_server_dir_version: sugarizer-server-1.4.0 # WAS: sugarizer-server-1.0, sugarizer-server-master, sugarizer-server-dev, sugarizer-server-1.1.0, sugarizer-server-1.1.1, sugarizer-server-1.2.0, sugarizer-server-1.3.0 -sugarizer_server_git_version: v1.4.0 # WAS: v1.0.1, master, dev, f27bf6acd56aba6d99116ef471ca713b0f0dfed3, v1.1.0, v1.1.1, v1.2.0, v1.3.0 +sugarizer_server_dir_version: sugarizer-server-1.5.0 # WAS: sugarizer-server-1.0, sugarizer-server-master, sugarizer-server-dev, sugarizer-server-1.1.0, sugarizer-server-1.1.1, sugarizer-server-1.2.0, sugarizer-server-1.3.0, sugarizer-server-1.4.0 +sugarizer_server_git_version: v1.5.0 # WAS: v1.0.1, master, dev, f27bf6acd56aba6d99116ef471ca713b0f0dfed3, v1.1.0, v1.1.1, v1.2.0, v1.3.0, v1.4.0 # PLEASE HELP MONITOR https://github.com/llaske/sugarizer-server/commits/dev # AND https://github.com/llaske/sugarizer-server/releases diff --git a/roles/sugarizer/tasks/install.yml b/roles/sugarizer/tasks/install.yml index 948c128b7..c37b4c6de 100644 --- a/roles/sugarizer/tasks/install.yml +++ b/roles/sugarizer/tasks/install.yml @@ -27,9 +27,14 @@ # when: nodejs_version != "12.x" +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + # 2. DOWNLOAD+LINK /opt/iiab/sugarizer -- name: Clone llaske/sugarizer ({{ sugarizer_git_version }} branch/version) from GitHub to /opt/iiab/{{ sugarizer_dir_version }} (DOWNLOADS ~740 MB) +- name: Clone llaske/sugarizer ({{ sugarizer_git_version }} branch/version) from GitHub to /opt/iiab/{{ sugarizer_dir_version }} (DOWNLOADS ~748 MB) git: repo: https://github.com/llaske/sugarizer dest: "{{ iiab_base }}/{{ sugarizer_dir_version }}" @@ -61,7 +66,7 @@ # CLARIF: during repeat runs of "./runrole sugarizer", this git sync shows # "changed" (whereas above git sync shows "ok"). Reason: "npm install" # (below) modifies /opt/iiab/sugarizer-server/node_modules -- name: Clone llaske/sugarizer-server ({{ sugarizer_server_git_version }} branch/version) from GitHub to /opt/iiab/{{ sugarizer_server_dir_version }} (~9 MB initially, ~195+ MB later) +- name: Clone llaske/sugarizer-server ({{ sugarizer_server_git_version }} branch/version) from GitHub to /opt/iiab/{{ sugarizer_server_dir_version }} (~16 MB initially, ~227+ MB later) git: repo: https://github.com/llaske/sugarizer-server dest: "{{ iiab_base }}/{{ sugarizer_server_dir_version }}" @@ -232,6 +237,17 @@ # 6. RECORD Sugarizer AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'sugarizer_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: sugarizer + option: sugarizer_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'sugarizer_installed: True'" set_fact: sugarizer_installed: True diff --git a/roles/tailscale/tasks/install.yml b/roles/tailscale/tasks/install.yml new file mode 100644 index 000000000..97e939a84 --- /dev/null +++ b/roles/tailscale/tasks/install.yml @@ -0,0 +1,113 @@ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + +- name: "Set up apt source (jammy) in /etc/apt/sources.list.d/tailscale.list and its key /usr/share/keyrings/tailscale-archive-keyring.gpg, to install Tailscale" + shell: | + curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/jammy.noarmor.gpg > /usr/share/keyrings/tailscale-archive-keyring.gpg + curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/jammy.tailscale-keyring.list > /etc/apt/sources.list.d/tailscale.list + +- name: "Install packages: jq, sudo, tailscale" + package: + name: + #- ncat # Newer versions of NMap do not include NCat, WAS needed to announce openvpn_handle (if Debian > 9 or Ubuntu > 18) + #- nmap + - jq # JSON parser used by /usr/bin/iiab-support == /usr/bin/iiab-vpn + - sudo # (1) Should be installed prior to installing IIAB, (2) Can also be installed by 1-prep here, (3) Is definitely installed by 1-prep's roles/iiab-admin/tasks/sudo-prereqs.yml, (4) Used to be installed by roles/2-common/tasks/packages.yml (but that's too late!) + - tailscale + update_cache: yes + +- name: Set up tab completion for 'tailscale' at the command-line + shell: mkdir -p /etc/bash_completion.d && tailscale completion bash > /etc/bash_completion.d/tailscale + +- name: "Install ssh public keys for remote support (only runs if 'tailscale_install: True')" + lineinfile: + line: "{{ item.pubkey }}" + regexp: "{{ item.regexp }}" + path: /root/.ssh/authorized_keys + with_items: + - regexp: "LvCSAAcfYIdZPR4ePVpVUZ/IbkGjpQSoRMa5HuVjMO3cZNR27ptqjNjq2husJOyhMFCOBTzo4thioGyTpBr4u3s=$" # Tim Moody + pubkey: "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAhlQIh8ZPx4awdM0O6QNcPbx3qIZ39FHjF2YJ2SX3z7iLnYiz03Ek6Bux9P4HvaVAqlApiz2I68Vq8TfU2s/+LvCSAAcfYIdZPR4ePVpVUZ/IbkGjpQSoRMa5HuVjMO3cZNR27ptqjNjq2husJOyhMFCOBTzo4thioGyTpBr4u3s=" + - regexp: "tUM4hl009fbXY4Yy3bAadWL1CquVrZmKfBBWhyhz8zLD6TQ== ghunt@ip-192-168-123-123.ec2.internal$" + pubkey: "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxAmjU7VojyK+0Pjp2p8CCGTNBtE565A/L8IVbAT8MIucRE9LN1g5LjGnOHUShFJpwuTR1JLX2r9EDRMsf9MmyTgUAnuyP005giWVHXLPtjyjTzbsJ1DEtXRytulmF+GlCOaqPWNde6EOmReqPHbmjIQpRZ/Sc8hziS4jVSQuBA9EhaBmZ62CPqK33mPJvnpwMtdd6nHXAcXsZhStd3NhVDm27+B3sHI6mr2w7ExdBXE5DKiZL2po8n2y4hJYZreJopbjcQmv4oWdDWvPu5I92xDgYCsqcE7zSrv1um+tUM4hl009fbXY4Yy3bAadWL1CquVrZmKfBBWhyhz8zLD6TQ== ghunt@ip-192-168-123-123.ec2.internal" + - regexp: "heOMXXNU6skxdPh2fcHh0bzQcaCSQ== holt@crank$" + pubkey: "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEApHPly+EA1M4bispl3AulTLjyYCjcJzh6s779K3epDkqh600a+fHsdIiddWCAfIonRq+9MJyOiaNQ+WYLOuajI1IiFZWFt45xDAiyCUnyuT+ytAX+IA3TgTwgTZPfzDOzI8rDRV9Sgl+LZLfPno7T3qxcGx2l51bRk+koRK+Txpph//M3jGvsFmTKhjvfxgEIUmMH9SkASxEdyqASr0+/+uLR92MnT+8CT1pOYYoJyZp9Lta5eGqJvbEmd3Dn7MXqD3vXE57o4rBJ0bR3q5LK59WVNxNQbulJ9z5V7aTJ4AbBFQWxm0fH0gBx+heOMXXNU6skxdPh2fcHh0bzQcaCSQ== holt@crank" + +# CLARIF: plus signs (+) in public keys cause duplicate key additions (above) +# and failure during removal (below) as "+" has a special meaning as +# interpreted in a Python regexp, as implemented by Ansible's lineinfile module: +# https://docs.python.org/2/library/re.html + +# WORKAROUND: the tail end of each public key (after the last plus sign) is +# being used (instead of the full key) as an abbreviated regexp for now. +# A backslash in front of each plus sign (+) would also work. + +# - name: Remove those ssh public keys, if not tailscale_enabled +# lineinfile: +# regexp: "{{ item }}" +# path: /root/.ssh/authorized_keys +# state: absent +# with_items: +# - "LvCSAAcfYIdZPR4ePVpVUZ/IbkGjpQSoRMa5HuVjMO3cZNR27ptqjNjq2husJOyhMFCOBTzo4thioGyTpBr4u3s=$" +# - "tUM4hl009fbXY4Yy3bAadWL1CquVrZmKfBBWhyhz8zLD6TQ== ghunt@ip-192-168-123-123.ec2.internal$" +# - "heOMXXNU6skxdPh2fcHh0bzQcaCSQ== holt@crank$" +# when: not tailscale_enabled + +- name: Install /usr/bin/iiab-vpn & /usr/bin/iiab-vpn-off (BACKS UP FILES IF CHANGED) + template: + src: "{{ item }}" + dest: /usr/bin/ + mode: '0755' + backup: yes + with_items: + - iiab-vpn + - iiab-vpn-off + +- name: Symlink /usr/bin/iiab-vpn-on -> /usr/bin/iiab-vpn + file: + src: /usr/bin/iiab-vpn + path: /usr/bin/iiab-vpn-on + state: link + +- name: Symlink /usr/bin/iiab-support -> /usr/bin/iiab-vpn + file: + src: /usr/bin/iiab-vpn + path: /usr/bin/iiab-support + state: link + +- name: Symlink /usr/bin/iiab-support-on -> /usr/bin/iiab-vpn + file: + src: /usr/bin/iiab-vpn + path: /usr/bin/iiab-support-on + state: link + +- name: Symlink /usr/bin/iiab-support-off -> /usr/bin/iiab-vpn-off + file: + src: /usr/bin/iiab-vpn-off + path: /usr/bin/iiab-support-off + state: link + + +# RECORD Tailscale AS INSTALLED + +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'tailscale_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: tailscale + option: tailscale_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + +- name: "Set 'tailscale_installed: True'" + set_fact: + tailscale_installed: True + +- name: "Add 'tailscale_installed: True' to {{ iiab_state_file }}" + lineinfile: + path: "{{ iiab_state_file }}" # /etc/iiab/iiab_state.yml + regexp: '^tailscale_installed' + line: 'tailscale_installed: True' diff --git a/roles/tailscale/tasks/main.yml b/roles/tailscale/tasks/main.yml new file mode 100644 index 000000000..fc8af13e5 --- /dev/null +++ b/roles/tailscale/tasks/main.yml @@ -0,0 +1,47 @@ +# http://FAQ.IIAB.IO -> "How can I remotely manage my Internet-in-a-Box?" + + +# "How do i fail a task in Ansible if the variable contains a boolean value? +# I want to perform input validation for Ansible playbooks" +# https://stackoverflow.com/questions/46664127/how-do-i-fail-a-task-in-ansible-if-the-variable-contains-a-boolean-value-i-want/46667499#46667499 + +# We assume 0-init/tasks/validate_vars.yml has DEFINITELY been run, so no need +# to re-check whether vars are defined here. As Ansible vars cannot be unset: +# https://serverfault.com/questions/856729/how-to-destroy-delete-unset-a-variable-value-in-ansible + +- name: Assert that "tailscale_install is sameas true" (boolean not string etc) + assert: + that: tailscale_install is sameas true + fail_msg: "PLEASE SET 'tailscale_install: True' e.g. IN: /etc/iiab/local_vars.yml" + quiet: yes + +- name: Assert that "tailscale_enabled | type_debug == 'bool'" (boolean not string etc) + assert: + that: tailscale_enabled | type_debug == 'bool' + fail_msg: "PLEASE GIVE VARIABLE 'tailscale_enabled' A PROPER (UNQUOTED) ANSIBLE BOOLEAN VALUE e.g. IN: /etc/iiab/local_vars.yml" + quiet: yes + + +- name: Install Tailscale if 'tailscale_installed' not defined, e.g. in {{ iiab_state_file }} # /etc/iiab/iiab_state.yml + include_tasks: install.yml + when: tailscale_installed is undefined + + +#- include_tasks: enable-or-disable.yml + + +- name: Add 'tailscale' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: tailscale + option: "{{ item.option }}" + value: "{{ item.value | string }}" + with_items: + - option: name + value: Tailscale (VPN) + - option: description + value: '"Tailscale enables live/remote support by connecting machines anywhere on the Internet, using a software-defined mesh virtual private network (VPN), and optional web-based management service."' + - option: tailscale_install + value: "{{ tailscale_install }}" + - option: tailscale_enabled + value: "{{ tailscale_enabled }}" diff --git a/roles/tailscale/templates/iiab-vpn b/roles/tailscale/templates/iiab-vpn new file mode 100755 index 000000000..77e8c13be --- /dev/null +++ b/roles/tailscale/templates/iiab-vpn @@ -0,0 +1,71 @@ +#!/bin/bash + +# USEFUL DOCS: +# https://tailscale.com/kb/1080/cli#status +# https://headscale.net/stable/usage/connect/android/ +# https://headscale.net/stable/usage/connect/apple/ +# https://headscale.net/stable/usage/connect/windows/ + +VPN_URL=https://iiab.net +VPN_KEY="$1" + +# if tailscale status > /dev/null; then # MANY IMPERFECT TESTS OF TAILNET CONNECTIVITY: tailscale0 CAN lose its IP address, as shown by 'ip a' and 'hostname -I' (testing 'systemctl is-active tailscaled' is likely no better!) Unclear if 'tailscale status --json | jq -r .Self.Online' is much better? Maybe explore 'tailscale debug --help' and 'tailscale debug prefs' for a cleaner/authoritative verdict? Or use + display string output of 'systemctl show tailscaled --property=StatusText' e.g. 'StatusText=Connected; iiab; 100.64.0.4' ? (OR JUST DON'T WORRY ABOUT IT, AS THE ~3 'tailscale up' COMMANDS BELOW ARE MORE PROACTIVE... AND APPEAR FAST + SAFE!) +# echo -e "\n\033[1;33mAlready connected to VPN!?\033[0m" +# else +# [NEST ~20 LINES OF IF STATEMENTS FURTHER BELOW?] + +# Check that current profile key still exists in /var/lib/tailscale/tailscaled.state ? (As 'tailscale logout' wipes it!) In the end, these are 3 lousy tests... +# if [ -f /var/lib/tailscale/tailscaled.state ] && [[ $(grep -c $(jq -r '."_current-profile"' /var/lib/tailscale/tailscaled.state) /var/lib/tailscale/tailscaled.state) > 1 ]]; then +# if ! [[ $(tailscale status | tr '[:upper:]' '[:lower:]') =~ "logged out" ]]; then +# if [[ $(tailscale status --json | jq -r .CurrentTailnet.Name) = "iiab.community" ]]; then + +# UX Optimization: {iiab-vpn, iiab-support} can be run WITHOUT key *IF* .BackendState is "Stopped" or "Running" *AND* .ControlURL is $VPN_URL (avoid their default, https://controlplane.tailscale.com !) +if [[ $(tailscale status --json | jq -r .BackendState) != "NeedsLogin" && $(tailscale debug prefs | jq -r .ControlURL) = $VPN_URL ]]; then + if ! tailscale up --login-server "$VPN_URL" --timeout 8s; then # (Re-)passing $VPN_URL is overkill on this line, but can't hurt! + echo -e "\n\033[41;1mERROR $?: Failed to connect to VPN\033[0m\n" + exit 1 + fi +elif [ -z $VPN_KEY ]; then + echo -e "\n\033[1;33mVPN key required!\033[0m\n\nEmail holt@unleashkids.org to explain your need?\n" + exit 1 +else + if ! tailscale up --login-server "$VPN_URL" --auth-key "$VPN_KEY" --timeout 8s; then + echo -e "\n\033[41;1mERROR $?: Failed to connect to VPN, so let's try --force-reauth\033[0m\n" + # If 'tailscale up' just above fails w/ exit code 1 ~= "can't change --login-server without --force-reauth" (i.e. if switching login server, e.g. to/from their default (https://controlplane.tailscale.com) -- SEE ALSO: 'tailscale switch -h' and https://tailscale.com/blog/fast-user-switching) then more "brute force" is attempted below... + # https://github.com/tailscale/tailscale/issues/3849 "Please warn that --force-reauth immediately disconnects" (brute force, only as a last resort!) + # https://github.com/tailscale/tailscale/issues/4854 "Tailscale CLI has poor UX with expiring keys" (long-term node keys thankfully mitigate this!) + if ! tailscale up --login-server "$VPN_URL" --auth-key "$VPN_KEY" --force-reauth --timeout 8s; then + echo -e "\n\033[41;1mERROR $?: Failed to connect to VPN, even with --force-reauth\033[0m\n" + exit 1 + fi + fi +fi + +# jq 1.7 (2023-09-05) on new OS's also allows new syntax... jq -r .Node.Tags.[] +# Can also work: tailscale whois --json $(tailscale ip -1) | jq -r .Node.Tags[]) +echo -e "\n\033[44;37mCheck that VPN ($(tailscale status --json | jq -r .Self.Tags[])) is now live:\033[0m\n" +echo -e " hostname -I" +echo -e " tailscale ip" +echo -e " tailscale status" +echo -e " tailscale whois $(tailscale ip -1)" +echo -e " tailscale whois --json $(tailscale ip -1) | jq .Node.Endpoints,.Node.Hostinfo" +echo -e " tailscale ping --verbose [IP or HOSTNAME]" +echo -e " tailscale status --json | jq" +echo -e " systemctl status tailscaled\n" +echo -e "\033[4mTo disconnect from VPN:\033[0m\n" +echo -e " tailscale down\n" +echo -e "\033[4mTo permanently log out of VPN:\033[0m\n" +echo -e " tailscale logout\n" + +# More useful table of IPs/usernames/etc than 'tailscale status' +#echo -e "\033[44;37mVPN peers: (rightmost column = online/offline)\033[0m\n" +#tailscale status --json | jq -r '.Self,.Peer[] | .Tags[] + " " + .TailscaleIPs[] + " " + .HostName + " " + .DNSName + " " + .OS + " " + .Relay + " " + (.Online|tostring)' | sort -V | column -t +#echo -e '\033[44;37mVPN peers: ("true" in 6th column means online)\033[0m\n' +echo -e '\033[44;37mVPN peers: (6th column = online/offline)\033[0m\n' +# (try .Tags[] catch "-") is safer than (.Tags[]? // "-") according to: https://stackoverflow.com/questions/54794749/jq-error-at-stdin0-cannot-iterate-over-null-null +tailscale status --json | jq -r '.Self,.Peer[] | (try .Tags[] catch "-") + " " + .TailscaleIPs[] + " " + .HostName + " " + .DNSName + " " + (if .Relay == "" then "-" else .Relay end) + " XXX" + (.Online|tostring) + "XXX " + .OS' | sort -V | column -t | \ + while read l; do + line=$(echo "$l" | sed 's/ XXXtrueXXX /\\033[0;32m ✅\\033[0m/ ; s/ XXXfalseXXX /\\033[0;31m ❌ \\033[0m/') + echo -e "$line" $(tailscale whois --json $(echo $line | cut -d' ' -f2) | jq -r '.Node.Hostinfo | .Distro + " " + .DistroVersion + " " + .DeviceModel'); + done +echo diff --git a/roles/tailscale/templates/iiab-vpn-off b/roles/tailscale/templates/iiab-vpn-off new file mode 100755 index 000000000..75ea5c0f3 --- /dev/null +++ b/roles/tailscale/templates/iiab-vpn-off @@ -0,0 +1,7 @@ +#!/bin/bash + +tailscale down + +echo -e "\n\e[44;1mDisconnecting from VPN...\e[0m\n" +echo -e "\e[4mTo permanently log out of VPN:\e[0m\n" # Expires machine node key, from /var/lib/tailscale/tailscaled.state +echo -e " tailscale logout\n" # ...as seen by 'tailscale status --json' (related: 'tailscale debug prefs') diff --git a/roles/transmission/README.rst b/roles/transmission/README.rst index 40f6e38fc..a851fe591 100644 --- a/roles/transmission/README.rst +++ b/roles/transmission/README.rst @@ -15,20 +15,25 @@ Transmission README Transmission is a set of lightweight BitTorrent clients (in GUI, CLI and daemon form). All these incarnations feature a very simple and intuitive interface, on top on an efficient, cross-platform backend: https://transmissionbt.com -Transmission is intended to download KA Lite content to Internet-in-a-Box (IIAB) from places like https://pantry.learningequality.org/downloads/ka-lite/0.17/content/ — and also to seed content, assisting others. +Transmission is intended to download content like KA Lite to Internet-in-a-Box (IIAB), from places like https://pantry.learningequality.org/downloads/ka-lite/0.17/content/ — and also to seed content, assisting others. For example, once KA Lite videos and thumbnails are confirmed downloaded, copy them (carefully!) from ``/library/transmission`` into ``/library/ka-lite/content`` as outlined by "KA Lite Administration: What tips & tricks exist?" at http://FAQ.IIAB.IO -Caution -------- +Transmission 4.x Preview (Optional) +----------------------------------- -Usage of Transmission consumes significant Internet data and system resources. -Caveat emptor! (That's Latin for "Buyer Beware") +2023-12-31: To make the `latest Transmission features `_ available to you, Internet-in-a-Box can compile the very latest (above and beyond `Transmission 4.x+ official releases `_). Just note this can take most of an hour, and is not without risk! + +If you decide you want this, set ``transmission_compile_latest: True`` in `/etc/iiab/local_vars.yml `_ prior to installing Transmission, as explained below. + +NOTE: Later in 2024, fast auto-installation of `Transmission 4.1+ `_ should once again hopefully become mainline (`#5585 `_, `PR #5866 `_) just as in recent years with Transmission 3.0 (originally from May, 2020). + +.. Transmission can consume significant Internet data and system resources. Caveat emptor! (That's Latin for "Buyer Beware") Using It -------- -Install Transmission by setting 'transmission_install' and 'transmission_enabled' to True in `/etc/iiab/local_vars.yml `_ — carefully choosing language(s) for KA Lite videos you want to download — and then install IIAB. Or, if IIAB is already installed, run as root:: +Install Transmission by setting ``transmission_install: True`` and ``transmission_enabled: True`` in `/etc/iiab/local_vars.yml `_ — carefully choosing language(s) for KA Lite videos you want to download — and then install IIAB. Or, if IIAB is already installed, run as root:: cd /opt/iiab/iiab ./runrole transmission @@ -81,6 +86,8 @@ Known Issues * Random Ports: Currently it is not possible to use random ports in the range 49152-65535, as it's difficult to open multiple ports in IIAB's `iptables-based firewall `_. +* transmission-daemon (4.0.6 or 4.1-dev) install onto Ubuntu 24.04 or 24.10, but (1) its systemd service times out (fails to start) (2) rebooting kinda helps, but service then crashes on 1st visit to http://box:9091 `#3756 `_ + Troubleshooting --------------- @@ -103,19 +110,36 @@ More advanced configuration and status are in directory ``/var/lib/transmission- stats.json torrents/ -These are further explained in https://github.com/transmission/transmission/wiki/Configuration-Files (to align with the above, apt package transmission-daemon sets user debian-transmission's home directory to ``/var/lib/transmission-daemon`` in /etc/passwd). +These are further explained in |ss| https://github.com/transmission/transmission/wiki/Configuration-Files |se| (to align with the above, apt package transmission-daemon sets user debian-transmission's home directory to ``/var/lib/transmission-daemon`` in /etc/passwd). + +Docs +---- + +As of June 2023, these docs appear to be the most up-to-date: + +- https://github.com/transmission/transmission/tree/main/docs + - https://github.com/transmission/transmission/blob/main/docs/Building-Transmission.md + - https://github.com/transmission/transmission/blob/main/docs/Configuration-Files.md + - https://github.com/transmission/transmission/blob/main/docs/Editing-Configuration-Files.md + - https://github.com/transmission/transmission/blob/main/docs/Headless-Usage.md + - https://github.com/transmission/transmission/blob/main/docs/rpc-spec.md + - https://transmission-rpc.readthedocs.io +- https://cli-ck.io/transmission-cli-user-guide/ (2016 but still useful) + - https://github.com/transmission/transmission#command-line-interface-notes ("``transmission-cli`` is deprecated and exists primarily to support older hardware dependent upon it. In almost all instances, ``transmission-remote`` should be used instead.") +- https://wiki.archlinux.org/title/transmission (updated regularly) +- https://trac.transmissionbt.com/wiki (2006-2019) Logging ------- -To turn on logging and/or record the Process ID (PID), follow these instructions: https://pawelrychlicki.pl/Home/Details/59/transmission-daemon-doesnt-create-a-log-file-nor-a-pid-file-ubuntu-server-1804 +Increase logging by changing transmission-daemon's ``--log-level=error`` to ``--log-level=debug`` in ``/lib/systemd/system/transmission-daemon.service`` -This gives permissions to user ``debian-transmission`` — if you use these 3 lines in ``/lib/systemd/system/transmission-daemon.service`` : +(Options are: ``critical``, ``error``, ``warn``, ``info``, ``debug`` or ``trace``) -:: +Then run:: - RuntimeDirectory=transmission-daemon - LogsDirectory=transmission-daemon - ExecStart=/usr/bin/transmission-daemon -f --log-error --log-debug --logfile /var/log/transmission-daemon/transmission.log --pid-file /run/transmission-daemon/transmission.pid + systemctl daemon-reload + systemctl restart transmission-daemon + journalctl -eu transmission-daemon Noting that one should not normally edit files in ``/lib`` or ``/usr/lib`` — systemd has a command for customizing unit files: ``systemctl edit --full transmission-daemon.service`` diff --git a/roles/transmission/defaults/main.yml b/roles/transmission/defaults/main.yml index f6763f593..ab6c3211b 100644 --- a/roles/transmission/defaults/main.yml +++ b/roles/transmission/defaults/main.yml @@ -1,6 +1,7 @@ # Transmission is a BitTorrent downloader for large Content Packs etc # transmission_install: False # transmission_enabled: False +# transmission_compile_latest: False # transmission_username: Admin # transmission_password: changeme diff --git a/roles/transmission/tasks/install.yml b/roles/transmission/tasks/install.yml index 015116b82..ae3c8cd72 100644 --- a/roles/transmission/tasks/install.yml +++ b/roles/transmission/tasks/install.yml @@ -1,3 +1,8 @@ +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: "Install BitTorrent packages: transmission-daemon, transmission-cli" package: name: @@ -5,13 +10,59 @@ - transmission-cli state: present + +- block: + + - name: "TRY TO COMPILE & INSTALL very latest Transmission, installing ~5 binaries in /usr/local/bin to take precedence over above ~6 binaries in /usr/bin (attempt surgery on systemd unit file from apt install above!)" + meta: noop + + # https://github.com/transmission/transmission/blob/main/docs/Building-Transmission.md#on-unix + # https://github.com/transmission/transmission/issues/5362 tips thanks to @tearfur + - name: apt install build-essential cmake libcurl4-openssl-dev libssl-dev libsystemd-dev # git python3 + package: + name: + - build-essential + - cmake + - libcurl4-openssl-dev + - libssl-dev + - libsystemd-dev + state: present + + - name: Git clone https://github.com/transmission/transmission to /opt/iiab/transmission + git: + repo: https://github.com/transmission/transmission + dest: /opt/iiab/transmission + #version: 4.0.x # Otherwise default branch 'main' + depth: 1 + force: yes + + # https://github.com/transmission/transmission/blob/main/docs/Building-Transmission.md#building-transmission-from-git-first-time + - name: Compile, install & remove detritus (CAN TAKE 60+ MINUTES ON RASPBERRY PI 4!) + shell: | + cd /opt/iiab/transmission + git submodule update --init --recursive + mkdir build + cd build + cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo .. + make + make install + cd + rm -rf /opt/iiab/transmission # 2023-06-12: Frees up 1.1 GB on 32-bit RasPiOS. Frees up 1.6 GB on 64-bit RasPiOS. + + - name: Attempt surgery on /lib/systemd/system/transmission-daemon.service (1) changing --log-error to --log-level=error (2) changing /usr/bin/transmission* to /usr/local/bin/transmission* + shell: | + sed -i 's/--log-error/--log-level=error/' /lib/systemd/system/transmission-daemon.service # --log-error deprecated since ~2020 + sed -i 's#/usr/bin/transmission#/usr/local/bin/transmission#' /lib/systemd/system/transmission-daemon.service # daemon_reload handled by enable-or-disable.yml + + when: transmission_compile_latest + + - name: Create download dir {{ transmission_download_dir }}, owned by {{ transmission_user }}:{{ transmission_group }} file: state: directory path: "{{ transmission_download_dir }}" # /library/transmission owner: "{{ transmission_user }}" # debian-transmission group: "{{ transmission_group }}" # debian-transmission - # mode: '0755' - name: Stop 'transmission-daemon' systemd service, before modifying its settings systemd: @@ -19,7 +70,10 @@ state: stopped ignore_errors: yes -- name: Back up prior /etc/transmission-daemon/settings.json (original file from apt, or new symlink contents) to /etc/transmission-daemon/settings.json.old* +# 'transmission-daemon -d' (--dump-settings) CAN GENERATE A NEW settings.json +# ...then customize ~8 var lines to create a new templates/settings.json.j2 + +- name: Back up prior /etc/transmission-daemon/settings.json (file originally from apt, or new symlink contents) to /etc/transmission-daemon/settings.json.old* copy: src: /etc/transmission-daemon/settings.json dest: /etc/transmission-daemon/settings.json.old @@ -48,13 +102,24 @@ - name: "Reverse Transmission's fragile OOTB symlink -- instead we establish /etc/transmission-daemon/settings.json -> /var/lib/transmission-daemon/.config/transmission-daemon/settings.json -- REASON: /etc/transmission-daemon/settings.json was intermittently being IGNORED, as Transmission sometimes breaks its own symlink from /var/lib/transmission-daemon/.config/transmission-daemon/settings.json (by turning it into a file instead)" file: path: /etc/transmission-daemon/settings.json - src: /var/lib/transmission-daemon/.config/transmission-daemon/settings.json + src: /var/lib/transmission-daemon/.config/transmission-daemon/settings.json # Symlink /var/lib/transmission-daemon/home/settings.json also points to this state: link force: yes # RECORD Transmission AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'transmission_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: transmission + option: transmission_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'transmission_installed: True'" set_fact: transmission_installed: True diff --git a/roles/usb_lib/README.rst b/roles/usb_lib/README.rst index 439fa9c86..b7536387c 100644 --- a/roles/usb_lib/README.rst +++ b/roles/usb_lib/README.rst @@ -2,30 +2,34 @@ usb_lib README ============== -**PLEASE SEE "Can teachers display their own content?" WITHIN http://FAQ.IIAB.IO FOR UP-TO-DATE DOCUMENTATION.** +**PLEASE SEE** `"Can teachers display their own content?" `_ **AND** `"Can students upload their own work?" `_ **WITHIN https://FAQ.IIAB.IO FOR UP-TO-DATE DOCUMENTATION!** -This role implements functionality similar to LibraryBox, to mount "teacher content" from USB drives. +This role (1) implements functionality similar to LibraryBox, to mount "teacher content" from USB sticks / drives for students, and (2) allows students to upload their work to the teacher's USB stick / drive: -Users should have nearly immediate access to this "teacher content" (on all inserted USB drives) by browsing to http://box/usb +#. Students should have nearly immediate access to "teacher content" (on all inserted USB sticks) by browsing to http://box/usb. +#. Students can also click the "Upload to USB" button on top of this same page (http://box/usb), to upload their work to the teacher's USB stick. (FYI student uploads appear in folders like ``UPLOADS.YYYY-MM-DD`` within the root of the teacher's USB stick). -Automount is handled by usbmount, and scripts in this role look in the root of the mounted drive for... +As of January 2025, automount is handled by usbmount: (`devmon included with udevil `_ might be considered in future) -* /usb -* /USB -* /share -* /Share -* /Piratebox/Share +* A script in this role (/etc/usbmount/mount.d/70-usb-library) looks in the root of the mounted USB stick for folder /PUBLIC and if found, creates a symlink of the form /library/www/html/local_content/USBn pointing to /media/usbn/PUBLIC — where n is generally one of {0, 1, 2, 3, 4, 5, 6, 7}. *RESULT: Only documents within /PUBLIC are browsable by students.* This option is very useful to **prevent students from copying uploaded homework!** +* If however folder /PUBLIC is not found, the symlink is created to the root of the mounted USB stick. *RESULT: EVERYTHING on the USB stick is browsable by students — just like with a traditional community bulletin board.* This option is very useful when students are uploading artwork, photo essays, personal audio recordings and **science projects that are intended to be shared!** -...and if found, creates a symlink of the form /library/www/html/local_content/USBn pointing to /media/usbn — where n is generally one of {0, 1, 2, 3, 4, 5, 6, 7}. +Technical Details: -USB drives must be formatted with one of the filesystems listed under "FILESYSTEMS=" at ``/etc/usbmount/usbmount.conf`` — these are specified on/around Line 76 of: `/opt/iiab/iiab/roles/usb_lib/tasks/install.yml `_ +* USB sticks / drives must be formatted with one of the filesystems listed under "FILESYSTEMS=" at ``/etc/usbmount/usbmount.conf`` — these are specified on/around Line 17 of: `/opt/iiab/iiab/roles/usb_lib/files/usbmount/usbmount.conf `_ -IIAB will generally mount USB drives 'rw' allowing root to both read and write to them. In addition, in March 2021 (`PR #2715 `_) Kolibri exports were enabled by also giving non-root users read and write access to VFAT/FAT32, NTFS and exFAT USB drives, using ``umask=0000`` (in /etc/usbmount/usbmount.conf) to override the ``umask=0022`` default. If however you prefer to restore usbmount's default, set ``usb_lib_umask0000_for_kolibri: False`` in `/etc/iiab/local_vars.yml `_ (preferably do this prior to installing IIAB). +* If your IIAB was built on a Graphical Desktop OS (instead of a headless OS, like Raspberry Pi OS Lite), USB sticks will problematically be mounted twice by default, once by usbmount and once by the desktop. You must disable the automount function in the Desktop in order to use the "Upload to USB" functionality, which allows students to upload their work to your USB stick. -Official `usbmount 0.0.22 (2011-08-08) `_ documentation: + * EXAMPLE: To disable Desktop automount within "Raspberry Pi OS with desktop", go to File Manager (pcmanfm) → Edit → Preferences → Volume Management, and uncheck "Mount removable media automatically when they are inserted". -* https://github.com/hfuchs/usbmount/blob/master/README (2010-08-11) -* https://github.com/rbrito/usbmount/blob/master/README.md (2018-08-10) -* https://github.com/rbrito/usbmount/blob/master/usbmount.conf (2010-04-25) +* IIAB will generally mount USB sticks / drives 'rw' allowing root to both read and write to them. In addition, in March 2021 (`PR #2715 `_) Kolibri exports were enabled, by also giving non-root users read and write access to VFAT/FAT32, NTFS and exFAT USB sticks — using ``umask=0000`` (in /etc/usbmount/usbmount.conf) to override the ``umask=0022`` default. This ``umask=0000`` is also required for students to upload to the teachers's VFAT/FAT32, NTFS and exFAT USB sticks, as introduced in January 2025 (`PR #3875 `_). If, however, you prefer to restore usbmount's default, set ``usb_lib_writable_sticks: False`` in `/etc/iiab/local_vars.yml `_ — please do this prior to installing IIAB — so you don't have to run: ``cd /opt/iiab/iiab ; ./runrole --reinstall usb_lib`` -Legacy warning: There is also a patch for problems with automount on Fedora 21+. Please note that as of 4.1.8-200.fc22.x86_64 not all USB drives will mount, even with this patch. +* Official `usbmount 0.0.22 (2011-08-08) `_ documentation: + + * https://github.com/hfuchs/usbmount/blob/master/README (2010-08-11) + * https://github.com/rbrito/usbmount/blob/master/README.md (2018-08-10) + * https://github.com/rbrito/usbmount/blob/master/usbmount.conf (2010-04-25) + +* Dev Notes at the top of: https://github.com/iiab/iiab/blob/master/roles/usb_lib/tasks/install.yml + + * January 2025 work to improve automount reliability during boot: `PR #3916 `_ diff --git a/roles/usb_lib/defaults/main.yml b/roles/usb_lib/defaults/main.yml index 2a4b19308..f7cbf10b6 100644 --- a/roles/usb_lib/defaults/main.yml +++ b/roles/usb_lib/defaults/main.yml @@ -1,12 +1,9 @@ # usb_lib_install: True # usb_lib_enabled: True -# Show entire contents of USB sticks/drives (at http://box/usb) -# iiab_usb_lib_show_all: True - -# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf so -# Kolibri can export & import channels to USB sticks/drive: -# usb_lib_umask0000_for_kolibri: True +# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf for +# Kolibri exports, and student uploads to teacher's USB stick (http://box/usb) +# usb_lib_writable_sticks: True # All above are set in: github.com/iiab/iiab/blob/master/vars/default_vars.yml # If nec, change them by editing /etc/iiab/local_vars.yml prior to installing! diff --git a/roles/usb_lib/files/upload2usb/button.html b/roles/usb_lib/files/upload2usb/button.html new file mode 100644 index 000000000..52cc493ce --- /dev/null +++ b/roles/usb_lib/files/upload2usb/button.html @@ -0,0 +1,19 @@ + +Upload to USB diff --git a/roles/usb_lib/files/upload2usb/error.php b/roles/usb_lib/files/upload2usb/error.php new file mode 100644 index 000000000..46dd0e667 --- /dev/null +++ b/roles/usb_lib/files/upload2usb/error.php @@ -0,0 +1,15 @@ + +ERROR: Please make sure one and ONLY one (no more, no less) removable USB stick is plugged into your Internet-in-a-Box. Please see IIAB FAQ, "Can students upload their own work?", for additional support. + +

+ +
+ + + diff --git a/roles/usb_lib/files/upload2usb/footer.php b/roles/usb_lib/files/upload2usb/footer.php new file mode 100644 index 000000000..2e1fef0f7 --- /dev/null +++ b/roles/usb_lib/files/upload2usb/footer.php @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/roles/usb_lib/files/upload2usb/header.php b/roles/usb_lib/files/upload2usb/header.php new file mode 100644 index 000000000..ef75c2c01 --- /dev/null +++ b/roles/usb_lib/files/upload2usb/header.php @@ -0,0 +1,32 @@ + + + + + + + <?php echo $title ?> + + + + + + + + + + +
+
+
+ + +

diff --git a/roles/usb_lib/files/upload2usb/index.php b/roles/usb_lib/files/upload2usb/index.php new file mode 100644 index 000000000..6eab98dbf --- /dev/null +++ b/roles/usb_lib/files/upload2usb/index.php @@ -0,0 +1,24 @@ + + + +
+

+ + +
+ files have been uploaded today! + + + \ No newline at end of file diff --git a/roles/usb_lib/files/upload2usb/uk-swing.png b/roles/usb_lib/files/upload2usb/uk-swing.png new file mode 100644 index 000000000..c5470365e Binary files /dev/null and b/roles/usb_lib/files/upload2usb/uk-swing.png differ diff --git a/roles/usb_lib/files/upload2usb/upload-file.php b/roles/usb_lib/files/upload2usb/upload-file.php new file mode 100644 index 000000000..8c81c731d --- /dev/null +++ b/roles/usb_lib/files/upload2usb/upload-file.php @@ -0,0 +1,58 @@ +". htmlspecialchars( $uploaded_filename ). " was successfully uploaded!"; + } else { + $upload_ok = 0; + throw new RuntimeException('There was an error uploading your file.

'); + } +} + +$file_count = getFileCount($target_folder_path); + +?> + +
+ files have been uploaded today! + + + + diff --git a/roles/usb_lib/files/upload2usb/upload2usb.php b/roles/usb_lib/files/upload2usb/upload2usb.php new file mode 100644 index 000000000..555a40f5a --- /dev/null +++ b/roles/usb_lib/files/upload2usb/upload2usb.php @@ -0,0 +1,101 @@ +1 otherwise return upload path + + # error if 1<>usb sticks are installed + $rmv_usb_path_count = shell_exec('lsblk --output NAME,TRAN,RM,MOUNTPOINT --pairs | cut -d " " -f 4 | grep "^MOUNTPOINT=\"/media" | wc -l'); + + if ($rmv_usb_path_count == 0) { + throw new RuntimeException('0 USB sticks found.

'); + } elseif ($rmv_usb_path_count > 1) { + throw new RuntimeException('More than 1 USB sticks installed.

'); + } + + $rmv_usb_path = trim(str_replace('"', '', shell_exec('lsblk --output NAME,TRAN,RM,MOUNTPOINT --pairs | cut -d " " -f 4 | grep "^MOUNTPOINT=\"/media" | cut -d "=" -f 2'))); + + if (empty($rmv_usb_path)) { + throw new RuntimeException('Not able to find USB stick.

'); + } else { + return $rmv_usb_path . "/"; + } +} + +//returns folder path where file will be stored, if create_folder_p = 1, it will create the folder if it doesn't exist +function getTargetFolderPath ($create_folder_p) { + $parent_dir = getTargetUSBDriveLocation(); + + $today_folder_name = "UPLOADS." . date("Y-m-d"); + $target_folder_path = $parent_dir . $today_folder_name; + + if (!file_exists($target_folder_path) && $create_folder_p) { + mkdir($target_folder_path, 0777) or throw new RuntimeException("Not able to create upload directory.
Make sure 'usb_lib_writable_sticks' is set to 'True'.

"); + } + return $target_folder_path; +} + +//return number of files within a specified folder +function getFileCount ($folder_path) { + return count(glob($folder_path . "/*")); +} + +//check if file mimetype is acceptable for upload +function isFileMimeTypeAcceptable ($file) { + $mimetype = strtolower(mime_content_type($file)); + $invalid_mimetypes_str = array ("compress", "image/svg+xml", "octet", "text/xml", "xhtml+xml"); + foreach ($invalid_mimetypes_str as $invalid_mt_str) { + if (str_contains($mimetype, $invalid_mt_str)) { + error_log('UPLOAD2USB ERROR - MIMETYPE: ' . $mimetype); + return false; + } + } + return true; +} + +//check file content to see if it's unique or not +function isFileContentUnique ($target_folder_path, $file) { + $file_to_upload_md5 = md5_file($file); + $usb_dir = array_diff(scandir($target_folder_path), array('..', '.')); + foreach ($usb_dir as $dir_file) { + $dir_file = $target_folder_path . "/" . $dir_file; + + if (!is_dir($dir_file)) { + $dir_file_md5 = md5_file($dir_file); + if ($file_to_upload_md5 == $dir_file_md5) { + return false; + } + } + } + return true; +} + +//return unique filename +function getUniqueFileName ($target_folder_path, $filename) { + $new_filename = $filename; + $counter = 1; + while (file_exists($target_folder_path . "/" . $new_filename)) { + $counter++; + $new_filename = pathinfo($filename,8) . '-'. $counter . "." . pathinfo($filename,4); + } + return $new_filename; +} + +// Check file size - we are not going to check file size for now. +// elseif ($_FILES["uploaded_file"]["size"] > 5000000) { +// $upload_msg = "Your file is too large."; +// $upload_ok = 0; +// } + + +?> diff --git a/roles/usb_lib/files/usbmount/copyright b/roles/usb_lib/files/usbmount/copyright new file mode 100644 index 000000000..75fae2dde --- /dev/null +++ b/roles/usb_lib/files/usbmount/copyright @@ -0,0 +1,17 @@ +Format: http://dep.debian.net/deps/dep5/ +Upstream-Name: usbmount +Upstream-Contact: Martin Dickopp , Rogério Brito +Source: git://git.debian.org/usbmount/usbmount.git + +Files: * +Copyright: 2004-2007, Martin Dickopp + 2008-2011, Rogério Brito +License: BSD-2 + This package is free software; the copyright holder gives unlimited + permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + . + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY, to the extent permitted by law; without + even the implied warranty of MERCHANTABILITY or FITNESS FOR A + PARTICULAR PURPOSE. diff --git a/roles/usb_lib/files/usbmount/usbmount b/roles/usb_lib/files/usbmount/usbmount new file mode 100644 index 000000000..8104564e7 --- /dev/null +++ b/roles/usb_lib/files/usbmount/usbmount @@ -0,0 +1,235 @@ +#!/bin/sh +# This script mounts USB mass storage devices when they are plugged in +# and unmounts them when they are removed. +# Copyright © 2004, 2005 Martin Dickopp +# Copyright © 2008, 2009, 2010 Rogério Theodoro de Brito +# Copyright © 2025, Jerry Vonau +# +# This file is free software; the copyright holder gives unlimited +# permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This file is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. +# https://github.com/iiab/iiab/blob/master/roles/usb_lib/files/usbmount/copyright +# https://github.com/rbrito/usbmount/blob/master/debian/copyright +#set -e +exec > /dev/null 2>&1 + +###################################################################### +# Auxiliary functions + +# Log a string via the syslog facility. +log() +{ + if [ $1 != debug ] || expr "$VERBOSE" : "[yY]" > /dev/null; then + logger -p user.$1 -t "usbmount[$$]" -- "$2" + fi +} + + +# Test if the first parameter is in the list given by the second +# parameter. +in_list() +{ + for v in $2; do + [ "$1" != "$v" ] || return 0 + done + return 1 +} + + +###################################################################### +# Main program + +# Default values for configuration variables. +ENABLED=1 +MOUNTPOINTS= +FILESYSTEMS= +MOUNTOPTIONS= +FS_MOUNTOPTIONS= +VERBOSE=no + +if [ -r /etc/usbmount/usbmount.conf ]; then + . /etc/usbmount/usbmount.conf + log debug "loaded usbmount configurations" +fi + +if [ "${ENABLED:-1}" -eq 0 ]; then + log info "usbmount is disabled, see /etc/usbmount/usbmount.conf" + exit 0 +fi + +if [ ! -x /sbin/blkid ]; then + log err "cannot execute /sbin/blkid" + exit 1 +fi + +if [ "$1" = add ]; then + + # Per Policy 9.3.2, directories under /var/run have to be created + # after every reboot. + if [ ! -e /var/run/usbmount ]; then + mkdir -p /var/run/usbmount + log debug "creating /var/run/usbmount directory" + else + log debug "/var/run/usbmount exists" + fi + + umask 022 + + # Acquire lock. + log debug "trying to acquire lock /var/run/usbmount/.mount.lock" + lockfile-create --retry 6 /var/run/usbmount/.mount || \ + { log err "cannot acquire lock /var/run/usbmount/.mount.lock"; exit 1; } + trap '( lockfile-remove /var/run/usbmount/.mount )' 0 + log debug "acquired lock /var/run/usbmount/.mount.lock" + + # Grab device information from device and "divide it" + # FIXME: improvement: implement mounting by label (notice that labels + # can contain spaces, which makes things a little bit less comfortable). + DEVINFO=$(/sbin/blkid -p $DEVNAME) + FSTYPE=$(echo "$DEVINFO" | sed 's/.*[[:blank:]]TYPE="\([^"]*\)".*/\1/g; s/[[:blank:]]*//g;') + UUID=$(echo "$DEVINFO" | sed 's/.*[[:blank:]]UUID="\([^"]*\)".*/\1/g; s/[[:blank:]]*//g;') + USAGE=$(echo "$DEVINFO" | sed 's/.*[[:blank:]]USAGE="\([^"]*\)".*/\1/g; s/[[:blank:]]*//g;') + + if ! echo $USAGE | egrep -q "(filesystem|disklabel)"; then + log debug "/$DEVNAME does not contain a filesystem or disklabel" + lockfile-remove /var/run/usbmount/.mount + exit + fi + + log debug "/$DEVNAME contains filesystem type $FSTYPE" + BOOTFW_DEV=$(/usr/bin/findmnt -no source /boot/firmware) + log debug "BOOTFW_DEV $BOOTFW_DEV" + ROOT_DEV=$(/usr/bin/findmnt -no source /) + log debug "ROOT_DEV $ROOT_DEV" + BOOT_DEV=$(/usr/bin/findmnt -no source /boot) + log debug "BOOT_DEV $BOOT_DEV" + + if [ $BOOTFW_DEV = /$DEVNAME ]; then + log debug "skipping BOOTFS_DEV $BOOTFS_DEV mounted at /boot/firmware" + lockfile-remove /var/run/usbmount/.mount + exit + elif [ $ROOT_DEV = /$DEVNAME ]; then + log debug "skipping ROOT_DEV $ROOT_DEV mounted at /" + lockfile-remove /var/run/usbmount/.mount + exit + elif [ $BOOT_DEV = /$DEVNAME ]; then + log debug "skipping BOOT_DEV $BOOT_DEV mount as /boot" + lockfile-remove /var/run/usbmount/.mount + exit + fi + + # Try to use specifications in /etc/fstab to skip. + if egrep -q "^[[:blank:]]*$DEVNAME" /etc/fstab; then + log debug "skipping /$DEVNAME exit" + lockfile-remove /var/run/usbmount/.mount + exit + elif grep -q "^[[:blank:]]*UUID=$UUID" /etc/fstab; then + log debug "skipping $UUID" + lockfile-remove /var/run/usbmount/.mount + exit + else + log debug "/$DEVNAME contains filesystem type $FSTYPE" + fstype=$FSTYPE + # Test if the filesystem type is in the list of filesystem + # types to mount. + if in_list "$fstype" "$FILESYSTEMS"; then + # Search an available mountpoint. + for v in $MOUNTPOINTS; do + if [ -d "$v" ] && ! grep -q "^[^ ][^ ]* *$v " /proc/mounts; then + mountpoint="$v" + log debug "mountpoint $mountpoint is available for /$DEVNAME" + break + fi + done + if [ -n "$mountpoint" ]; then + # Determine mount options. + options= + for v in $FS_MOUNTOPTIONS; do + if expr "$v" : "-fstype=$fstype,."; then + options="$(echo "$v" | sed 's/^[^,]*,//')" + break + fi + done + if [ -n "$MOUNTOPTIONS" ]; then + options="$MOUNTOPTIONS${options:+,$options}" + fi + + # Mount the filesystem. + log info "executing command: mount -t$fstype ${options:+-o$options} $DEVNAME $mountpoint" + mount "-t$fstype" "${options:+-o$options}" "$DEVNAME" "$mountpoint" + + # Determine vendor and model. + vendor= + if [ -r "/sys$DEVPATH/device/vendor" ]; then + vendor="`cat \"/sys$DEVPATH/device/vendor\"`" + elif [ -r "/sys$DEVPATH/../device/vendor" ]; then + vendor="`cat \"/sys$DEVPATH/../device/vendor\"`" + elif [ -r "/sys$DEVPATH/device/../manufacturer" ]; then + vendor="`cat \"/sys$DEVPATH/device/../manufacturer\"`" + elif [ -r "/sys$DEVPATH/../device/../manufacturer" ]; then + vendor="`cat \"/sys$DEVPATH/../device/../manufacturer\"`" + fi + vendor="$(echo "$vendor" | sed 's/^[[:blank:]]\+//; s/[[:blank:]]\+$//')" + + model= + if [ -r "/sys$DEVPATH/device/model" ]; then + model="`cat \"/sys$DEVPATH/device/model\"`" + elif [ -r "/sys$DEVPATH/../device/model" ]; then + model="`cat \"/sys$DEVPATH/../device/model\"`" + elif [ -r "/sys$DEVPATH/device/../product" ]; then + model="`cat \"/sys$DEVPATH/device/../product\"`" + elif [ -r "/sys$DEVPATH/../device/../product" ]; then + model="`cat \"/sys$DEVPATH/../device/../product\"`" + fi + model="$(echo "$model" | sed 's/^[[:blank:]]\+//; s/[[:blank:]]\+$//')" + + # Run hook scripts; ignore errors. + export UM_DEVICE="$DEVNAME" + export UM_MOUNTPOINT="$mountpoint" + export UM_FILESYSTEM="$fstype" + export UM_MOUNTOPTIONS="$options" + export UM_VENDOR="$vendor" + export UM_MODEL="$model" + log info "executing command: run-parts /etc/usbmount/mount.d" + run-parts /etc/usbmount/mount.d || : + else + # No suitable mount point found. + log warning "no mountpoint found for $DEVNAME" + exit 1 + fi + fi +fi +elif [ "$1" = remove ]; then + + # A block or partition device has been removed. + # Test if it is mounted. + while read device mountpoint fstype remainder; do + if [ "$DEVNAME" = "$device" ]; then + # If the mountpoint and filesystem type are maintained by + # this script, unmount the filesystem. + if in_list "$mountpoint" "$MOUNTPOINTS" && + in_list "$fstype" "$FILESYSTEMS"; then + log info "executing command: umount -l $mountpoint" + umount -l "$mountpoint" + + # Run hook scripts; ignore errors. + export UM_DEVICE="$DEVNAME" + export UM_MOUNTPOINT="$mountpoint" + export UM_FILESYSTEM="$fstype" + log info "executing command: run-parts /etc/usbmount/umount.d" + run-parts /etc/usbmount/umount.d || : + fi + break + fi + done < /proc/mounts +else + log err "unexpected: action '$1'" + exit 1 +fi + +log debug "usbmount execution finished" diff --git a/roles/usb_lib/files/usbmount/usbmount.conf b/roles/usb_lib/files/usbmount/usbmount.conf new file mode 100644 index 000000000..7bd194873 --- /dev/null +++ b/roles/usb_lib/files/usbmount/usbmount.conf @@ -0,0 +1,53 @@ +# Configuration file for the usbmount package, which mounts removable +# storage devices when they are plugged in and unmounts them when they +# are removed. + +# Change to zero to disable usbmount +ENABLED=1 + +# Mountpoints: These directories are eligible as mointpoints for +# removable storage devices. A newly plugged in device is mounted on +# the first directory in this list that exists and on which nothing is +# mounted yet. +MOUNTPOINTS="/media/usb0 /media/usb1 /media/usb2 /media/usb3 + /media/usb4 /media/usb5 /media/usb6 /media/usb7" + +# Filesystem types: removable storage devices are only mounted if they +# contain a filesystem type which is in this list. +FILESYSTEMS="vfat ext2 ext3 ext4 hfsplus exfat fuseblk ntfs" + +############################################################################# +# WARNING! # +# # +# The "sync" option may not be a good choice to use with flash drives, as # +# it forces a greater amount of writing operating on the drive. This makes # +# the writing speed considerably lower and also leads to a faster wear out # +# of the disk. # +# # +# If you omit it, don't forget to use the command "sync" to synchronize the # +# data on your disk before removing the drive or you may experience data # +# loss. # +# # +# It is highly recommended that you use the pumount command (as a regular # +# user) before unplugging the device. It makes calling the "sync" command # +# and mounting with the sync option unnecessary---this is similar to other # +# operating system's "safely disconnect the device" option. # +############################################################################# +# Mount options: Options passed to the mount command with the -o flag. +# See the warning above regarding removing "sync" from the options. +MOUNTOPTIONS="sync,noexec,nodev,noatime,nodiratime" + +# Filesystem type specific mount options: This variable contains a space +# separated list of strings, each which the form "-fstype=TYPE,OPTIONS". +# +# If a filesystem with a type listed here is mounted, the corresponding +# options are appended to those specificed in the MOUNTOPTIONS variable. +# +# For example, "-fstype=vfat,gid=floppy,dmask=0007,fmask=0117" would add +# the options "gid=floppy,dmask=0007,fmask=0117" when a vfat filesystem +# is mounted. +FS_MOUNTOPTIONS="" + +# If set to "yes", more information will be logged via the syslog +# facility. +VERBOSE=yes diff --git a/roles/usb_lib/tasks/install.yml b/roles/usb_lib/tasks/install.yml index 6510ab336..660df7eb2 100644 --- a/roles/usb_lib/tasks/install.yml +++ b/roles/usb_lib/tasks/install.yml @@ -7,6 +7,16 @@ # https://github.com/rbrito/usbmount/blob/master/README.md (2018-08-10) # https://github.com/rbrito/usbmount/blob/master/usbmount.conf (2010-04-25) +# The variable, usb_lib_writable_sticks (e.g., in /etc/iiab/local_vars.yml), must be set to true +# in order for non-root users to be able to write to VFAT/FAT32, NTFS and exFAT USB sticks. +# If you are still not able to write to a mounted USB stick, try unmounting the drive +# (sudo umount ) and then remount it setting umask to 0000 manually (sudo mount -o umask=0000 ). + +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + - name: Does systemd-udevd.service exist stat: path: "{{ systemd_location }}/systemd-udevd.service" @@ -38,27 +48,53 @@ when: udev_unit.stat.exists is defined and udev_unit.stat.exists # http://raspbian.raspberrypi.org/raspbian/pool/main/u/usbmount/usbmount_0.0.22_all.deb -- name: Install {{ iiab_download_url }}/usbmount_0.0.22_all.deb, no longer supported by {RasPiOS, Debian, Ubuntu} - apt: - deb: "{{ iiab_download_url }}/usbmount_0.0.22_all.deb" - # when: is_debian +#- name: Install {{ iiab_download_url }}/usbmount_0.0.22_all.deb, no longer supported by {RasPiOS, Debian, Ubuntu} +# apt: +# deb: "{{ iiab_download_url }}/usbmount_0.0.22_all.deb" +# # when: is_debian -# check status of usbmount on mintlinux - should be ok Ubuntu variant -# - name: Install usbmount from OS repo for Ubuntu variants -# package: -# name: usbmount -# state: present -# when: is_ubuntu +- name: Install lockfile-progs and util-linux (findmnt blkid) for usbmount from OS repo + package: + name: + - lockfile-progs + - util-linux + state: present -- name: Add dir {{ doc_root }}/local_content, where USB drive links can appear (0775) +- name: Add dir {{ doc_root }}/local_content, where USB drive links can appear (0775) owned by {{ apache_user }}:{{ apache_user }} file: state: directory - path: "{{ doc_root }}/local_content" - owner: "{{ apache_user }}" + path: "{{ doc_root }}/local_content" # /library/www/html + owner: "{{ apache_user }}" # www-data group: "{{ apache_user }}" # 2020-02-13: changed from iiab_admin_user, after discussion on weekly call (#1228, #2222) mode: 0775 -- name: 'Install from template: /etc/udev/rules.d/usbmount.rules, /etc/systemd/system/usbmount@.service, /usr/bin/iiab-usb_lib-show-all-on, /usr/bin/iiab-usb_lib-show-all-off, /usr/sbin/iiab-clean-usb.sh' +- name: Set up dirs /etc/usbmount/mount.d, /etc/usbmount/umount.d, /media/usb0-7 + file: + state: directory + path: "{{ item }}" + mode: 0755 + with_items: + - /etc/usbmount/mount.d + - /etc/usbmount/umount.d + - /media/usb0 + - /media/usb1 + - /media/usb2 + - /media/usb3 + - /media/usb4 + - /media/usb5 + - /media/usb6 + - /media/usb7 + +- name: Copy files from files/usbmount to filesystem + copy: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + mode: "{{ item.mode }}" + with_items: + - { src: 'usbmount/usbmount.conf', dest: '/etc/usbmount/', mode: '0644' } + - { src: 'usbmount/usbmount', dest: '/usr/local/sbin/', mode: '0755' } + +- name: 'Install from template: /etc/udev/rules.d/usbmount.rules, /etc/systemd/system/usbmount@.service, /usr/local/sbin/iiab-clean-usb.sh' template: src: "{{ item.src }}" dest: "{{ item.dest }}" @@ -66,27 +102,51 @@ with_items: - { src: 'usbmount.rules.j2', dest: '/etc/udev/rules.d/usbmount.rules', mode: '0644' } - { src: 'usbmount@.service.j2', dest: '/etc/systemd/system/usbmount@.service', mode: '0644' } - - { src: 'iiab-usb_lib-show-all-on', dest: '/usr/bin/', mode: '0755' } - - { src: 'iiab-usb_lib-show-all-off', dest: '/usr/bin/', mode: '0755' } - - { src: 'iiab-clean-usb.sh', dest: '/usr/sbin/', mode: '0755' } + - { src: 'iiab-clean-usb.sh', dest: '/usr/local/sbin/', mode: '0755' } + +- name: Add dir {{ doc_root }}/upload2usb (0775) owned by {{ apache_user }}:{{ apache_user }} + file: + state: directory + path: "{{ doc_root }}/upload2usb" + owner: "{{ apache_user }}" + group: "{{ apache_user }}" + mode: 0755 + +- name: Copy files from files/upload2usb/ into {{ doc_root }}/upload2usb/ + copy: + src: "{{ item }}" + dest: "{{ doc_root }}/upload2usb/" + with_fileglob: + - upload2usb/* # 2021-03-21: If usbmount is repackaged by apt as a result of Linux kernel 5.4+ # supporting exFAT, the stanza below (might) in future no longer be needed... -# SEE ALSO: https://github.com/iiab/iiab/blob/master/roles/2-common/tasks/packages.yml#L22-L23 -- name: Add ' exfat fuseblk ntfs' to FILESYSTEMS var in /etc/usbmount/usbmount.conf - lineinfile: - regexp: '^FILESYSTEMS=.*' - line: 'FILESYSTEMS="vfat ext2 ext3 ext4 hfsplus exfat fuseblk ntfs"' - path: /etc/usbmount/usbmount.conf +# SEE ALSO: https://github.com/iiab/iiab/blob/586bfc5cb1abf6b4333a21d3fa89695f115432dc/roles/2-common/tasks/packages.yml#L11-L12 +#- name: Add ' exfat fuseblk ntfs' to FILESYSTEMS var in /etc/usbmount/usbmount.conf +# lineinfile: +# regexp: '^FILESYSTEMS=.*' +# line: 'FILESYSTEMS="vfat ext2 ext3 ext4 hfsplus exfat fuseblk ntfs"' +# path: /etc/usbmount/usbmount.conf -- name: Remove /etc/usbmount/mount.d/00_create_model_symlink - file: - path: /etc/usbmount/mount.d/00_create_model_symlink - state: absent +#- name: Remove /etc/usbmount/mount.d/00_create_model_symlink +# file: +# path: /etc/usbmount/mount.d/00_create_model_symlink +# state: absent # RECORD 'USB_LIB' AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'usb_lib_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: usb_lib + option: usb_lib_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'usb_lib_installed: True'" set_fact: usb_lib_installed: True diff --git a/roles/usb_lib/tasks/main.yml b/roles/usb_lib/tasks/main.yml index 7836f2d3a..ee4bd18ea 100644 --- a/roles/usb_lib/tasks/main.yml +++ b/roles/usb_lib/tasks/main.yml @@ -1,7 +1,7 @@ # TO DO: (2020-02-13) # - Look at analogous NGINX logic for http://box/usb in # nginx/templates/iiab.conf.j2 and make that visually meaningful for teachers: -# https://github.com/iiab/iiab/blob/master/roles/nginx/templates/iiab.conf.j2#L5-L8 +# https://github.com/iiab/iiab/blob/master/roles/nginx/templates/iiab.conf.j2#L5-L9 # "How do i fail a task in Ansible if the variable contains a boolean value? @@ -32,12 +32,12 @@ # If setup.yml becomes the norm in future, put the 2-3 stanzas below in there: -- name: "Set 'umask=0000' for {VFAT/FAT32, NTFS, exFAT} using var FS_MOUNTOPTIONS in /etc/usbmount/usbmount.conf, so Kolibri exports work" +- name: "Set 'umask=0000' for {VFAT/FAT32, NTFS, exFAT} using var FS_MOUNTOPTIONS in /etc/usbmount/usbmount.conf -- for Kolibri exports AND student uploads to teacher's USB stick (using http://box/usb)" lineinfile: regexp: '^FS_MOUNTOPTIONS=.*' line: 'FS_MOUNTOPTIONS="-fstype=vfat,umask=0000 -fstype=ntfs,umask=0000 -fstype=exfat,umask=0000"' path: /etc/usbmount/usbmount.conf - when: usb_lib_umask0000_for_kolibri + when: usb_lib_writable_sticks # Setting 'umask=0000' for all filesystems: (much the same thing as above, as # the mount command does not use this umask setting for filesystems like ext4) @@ -46,14 +46,14 @@ # regexp: '^MOUNTOPTIONS=.*' # line: 'MOUNTOPTIONS="sync,noexec,nodev,noatime,nodiratime,umask=0000"' # path: /etc/usbmount/usbmount.conf -# when: usb_lib_umask0000_for_kolibri +# when: usb_lib_writable_sticks -- name: 'Set FS_MOUNTOPTIONS="" in /etc/usbmount/usbmount.conf, e.g. if Kolibri will not be used' +- name: 'Set FS_MOUNTOPTIONS="" in /etc/usbmount/usbmount.conf -- e.g. if Kolibri exports AND student uploads to teacher USB stick are not needed' lineinfile: regexp: '^FS_MOUNTOPTIONS=.*' line: 'FS_MOUNTOPTIONS=""' # Restore apt pkg default, e.g. for runrole path: /etc/usbmount/usbmount.conf - when: not usb_lib_umask0000_for_kolibri + when: not usb_lib_writable_sticks - name: Enable/Disable/Restart NGINX @@ -66,12 +66,6 @@ path: /etc/usbmount/mount.d/00_create_model_symlink state: absent -- name: Put variable in iiab.env that enables display of content at root of USB - lineinfile: - path: "{{ iiab_env_file }}" - regexp: "^IIAB_USB_LIB_SHOW_ALL.*" - line: "IIAB_USB_LIB_SHOW_ALL={{ iiab_usb_lib_show_all }}" - - name: Add 'usb_lib' variable values to {{ iiab_ini_file }} ini_file: @@ -83,10 +77,10 @@ - option: name value: USB_LIB - option: description - value: '"USB_LIB automounts Teacher Content on USB drives to /library/www/html/local_content, so students can browse it almost immediately at http://box/usb"' + value: '"USB_LIB (1) automounts teacher content on USB sticks to /library/www/html/local_content, so students can browse the USB; AND (2) allows students to upload their work to USB sticks / drives, all from http://box/usb"' - option: usb_lib_install value: "{{ usb_lib_install }}" - option: usb_lib_enabled value: "{{ usb_lib_enabled }}" - - option: usb_lib_umask0000_for_kolibri - value: "{{ usb_lib_umask0000_for_kolibri }}" + - option: usb_lib_writable_sticks + value: "{{ usb_lib_writable_sticks }}" diff --git a/roles/usb_lib/tasks/nginx.yml b/roles/usb_lib/tasks/nginx.yml index 7e572142a..1e6be6d21 100644 --- a/roles/usb_lib/tasks/nginx.yml +++ b/roles/usb_lib/tasks/nginx.yml @@ -1,20 +1,21 @@ - name: Install /etc/usbmount/mount.d/70-usb-library from template, if usb_lib_enabled template: - src: mount.d/70-usb-library - dest: /etc/usbmount/mount.d/ + src: mount.d/70-usb-library.j2 + dest: /etc/usbmount/mount.d/70-usb-library owner: root group: root mode: '0751' when: usb_lib_enabled -- name: Install /etc/usbmount/umount.d/70-usb-library from template, if usb_lib_enabled - template: - src: umount.d/70-usb-library - dest: /etc/usbmount/umount.d - owner: root - group: root - mode: '0751' - when: usb_lib_enabled +# 20250125: commenting out stale file, superseded by iiab-clean-usb.sh +# - name: Install /etc/usbmount/umount.d/70-usb-library from template, if usb_lib_enabled +# template: +# src: umount.d/70-usb-library +# dest: /etc/usbmount/umount.d +# owner: root +# group: root +# mode: '0751' +# when: usb_lib_enabled - name: Remove /etc/usbmount/mount.d/70-usb-library if not usb_lib_enabled file: @@ -22,11 +23,12 @@ state: absent when: not usb_lib_enabled -- name: Remove /etc/usbmount/umount.d/70-usb-library if not usb_lib_enabled - file: - path: /etc/usbmount/umount.d/70-usb-library - state: absent - when: not usb_lib_enabled +# 20250125: commenting out stale file, superseded by iiab-clean-usb.sh +# - name: Remove /etc/usbmount/umount.d/70-usb-library if not usb_lib_enabled +# file: +# path: /etc/usbmount/umount.d/70-usb-library +# state: absent +# when: not usb_lib_enabled - name: Restart 'nginx' systemd service systemd: diff --git a/roles/usb_lib/templates/content_dir.conf b/roles/usb_lib/templates/content_dir.conf.unused similarity index 100% rename from roles/usb_lib/templates/content_dir.conf rename to roles/usb_lib/templates/content_dir.conf.unused diff --git a/roles/usb_lib/templates/iiab-clean-usb.sh b/roles/usb_lib/templates/iiab-clean-usb.sh index a1876551c..360d737f4 100644 --- a/roles/usb_lib/templates/iiab-clean-usb.sh +++ b/roles/usb_lib/templates/iiab-clean-usb.sh @@ -1,14 +1,14 @@ #!/bin/bash -# Remove symlink in /library/content to automounted usb drive -# -DEVICE=`echo $@ | sed -s 's|-|/|'` -MNT_POINT=`findmnt -n /$DEVICE | awk '{print $1}'` -CONTENT_LINK_USB=`basename $MNT_POINT | awk '{print toupper($0)}'` +# Remove symlink in /library/www/html/local_content to automounted USB drive + +DEVICE="/$(echo $1 | sed 's|-|/|')" +MNT_POINT=$(findmnt -no target $DEVICE) +CONTENT_LINK_USB=$(basename $MNT_POINT | awk '{print toupper($0)}') CONTENT_LINK="/library/www/html/local_content/$CONTENT_LINK_USB" -logger -p user.notice -t "usbmount" -- "Attempting to remove link $CONTENT_LINK." + +logger -t "usb_lib (iiab-clean-usb.sh)" "Attempting to remove symlink $CONTENT_LINK, as auto-created earlier by usbmount." if [ -L $CONTENT_LINK ]; then - /bin/rm $CONTENT_LINK - logger -p user.notice -t "usbmount" -- "$CONTENT_LINK removed." + /usr/bin/rm $CONTENT_LINK + logger -t "usb_lib (iiab-clean-usb.sh)" "Symlink $CONTENT_LINK removed, as auto-created earlier by usbmount." fi - diff --git a/roles/usb_lib/templates/iiab-usb_lib-show-all-off b/roles/usb_lib/templates/iiab-usb_lib-show-all-off.unused similarity index 100% rename from roles/usb_lib/templates/iiab-usb_lib-show-all-off rename to roles/usb_lib/templates/iiab-usb_lib-show-all-off.unused diff --git a/roles/usb_lib/templates/iiab-usb_lib-show-all-on b/roles/usb_lib/templates/iiab-usb_lib-show-all-on.unused similarity index 100% rename from roles/usb_lib/templates/iiab-usb_lib-show-all-on rename to roles/usb_lib/templates/iiab-usb_lib-show-all-on.unused diff --git a/roles/usb_lib/templates/mount.d/70-usb-library b/roles/usb_lib/templates/mount.d/70-usb-library deleted file mode 100644 index 5b9cfefe8..000000000 --- a/roles/usb_lib/templates/mount.d/70-usb-library +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/bash -# Create symlink in DocumentRoot/content to autmounted usb drive -# -# based on a similar script in the xs-rsync package -# by Martin Langhoff -# -# and the adaptation for xs-activity-server by Douglas Bagnall -# -# -# by Tim Moody tim@timmoody.com - -source {{ iiab_env_file }} -case $IIAB_USB_LIB_SHOW_ALL in -'True'|'true'|'TRUE') - logger -p user.notice -t "70-usb-library" -- "Display entire USB drive is True. Checking for rootfs or /library on $UM_MOUNTPOINT." - # regularize the variable - IIAB_USB_LIB_SHOW_ALL=True - ;; -*) - logger -p user.notice -t "70-usb-library" -- "Looking for /share, /Share, /Piratebox/Share, /USB, or /usb on $UM_MOUNTPOINT." - ;; -esac - -VERBOSE=yes - -SHARE_DIR="" -# Only show content if in these directories - -if [ -d $UM_MOUNTPOINT/share ]; then - SHARE_DIR="$UM_MOUNTPOINT/share" -fi -if [ -d $UM_MOUNTPOINT/Share ]; then - SHARE_DIR="$UM_MOUNTPOINT/Share" -fi -if [ -d $UM_MOUNTPOINT/Piratebox/Share ]; then - SHARE_DIR="$UM_MOUNTPOINT/Piratebox/Share" -fi -if [ -d $UM_MOUNTPOINT/USB ]; then - SHARE_DIR="$UM_MOUNTPOINT/USB" -fi -if [ -d $UM_MOUNTPOINT/usb ]; then - SHARE_DIR="$UM_MOUNTPOINT/usb" -fi - -if [ "$IIAB_USB_LIB_SHOW_ALL" == "True" ]; then - UM_DEV=`findmnt $UM_MOUNTPOINT | grep / | awk '{print $2}'` - LIB_DEV=`findmnt /library | grep / | awk '{print $2}' |awk -F '[' '{print $1}'` - ROOT_DEV=`findmnt / | grep / | awk '{print $2}'` - if [ "$UM_DEV" == "$LIB_DEV" ]; then - logger -p user.notice -t "70-usb-library" -- "skipping $UM_MOUNTPOINT containing /library" - #echo "lib on dev" - elif [ "$UM_DEV" == "$ROOT_DEV" ]; then - logger -p user.notice -t "70-usb-library" -- "skipping $UM_MOUNTPOINT containing rootfs" - #echo "rootfs on dev" - else - SHARE_DIR="$UM_MOUNTPOINT" - fi -fi - -if [ ! -z "$SHARE_DIR" ]; then - logger -p user.notice -t "70-usb-library" -- "Found Share Directory $SHARE_DIR." -else - logger -p user.notice -t "70-usb-library" -- "did not find /share, /Share, /Piratebox/Share, /USB, or /usb on USB" -fi - - -if [ "$SHARE_DIR" != "" ];then - CONTENT_LINK_USB=`basename $UM_MOUNTPOINT | awk '{print toupper($0)}'` - CONTENT_LINK="{{ doc_root }}/local_content/$CONTENT_LINK_USB" - logger -p user.notice -t "70-usb-library" -- "Creating link to $CONTENT_LINK." - ln -s $SHARE_DIR $CONTENT_LINK -fi diff --git a/roles/usb_lib/templates/mount.d/70-usb-library.j2 b/roles/usb_lib/templates/mount.d/70-usb-library.j2 new file mode 100644 index 000000000..8263bde1f --- /dev/null +++ b/roles/usb_lib/templates/mount.d/70-usb-library.j2 @@ -0,0 +1,67 @@ +#!/bin/bash +# Create symlink in DocumentRoot/content to automounted usb drive +# +# based on a similar script in the xs-rsync package +# by Martin Langhoff +# +# and the adaptation for xs-activity-server by Douglas Bagnall +# +# +# by Tim Moody tim@timmoody.com + +# Better to set this in /etc/usbmount/usbmount.conf +# VERBOSE=yes + +# UM_MOUNTPOINT is documented at: https://github.com/rbrito/usbmount#hook-scripts +UM_DEV=$(findmnt -no source $UM_MOUNTPOINT) + +# 2022-06-16 better security thanks to @tim-moody and @jvonau: +# https://github.com/iiab/iiab/pull/3254 +LIB_DEV=$(findmnt -no source /library | cut -d '[' -f 1) +ROOT_DEV=$(findmnt -no source /) +BOOT_DEV=$(findmnt -no source /boot) +BOOTFW_DEV=$(findmnt -no source /boot/firmware) + +# Verbose logging to illuminate occasional boot bugginess: +logger -t "usb_lib (70-usb-library)" "UM_DEV is: $UM_DEV" +logger -t "usb_lib (70-usb-library)" "LIB_DEV is: $LIB_DEV" +logger -t "usb_lib (70-usb-library)" "ROOT_DEV is: $ROOT_DEV" +logger -t "usb_lib (70-usb-library)" "BOOT_DEV is: $BOOT_DEV" +logger -t "usb_lib (70-usb-library)" "BOOTFW_DEV is: $BOOTFW_DEV" + +if [ "$UM_DEV" == "$LIB_DEV" ]; then + logger -t "usb_lib (70-usb-library)" "Skipping $UM_MOUNTPOINT containing /library" + exit 1 +elif [ "$UM_DEV" == "$ROOT_DEV" ]; then + logger -t "usb_lib (70-usb-library)" "Skipping $UM_MOUNTPOINT containing rootfs" + exit 1 +elif [ "$UM_DEV" == "$BOOT_DEV" ]; then + logger -t "usb_lib (70-usb-library)" "Skipping $UM_MOUNTPOINT containing /boot" + exit 1 +elif [ "$UM_DEV" == "$BOOTFW_DEV" ]; then + logger -t "usb_lib (70-usb-library)" "Skipping $UM_MOUNTPOINT containing /boot/firmware" + exit 1 +fi + +# 2025-01-25: Check for existence of folder PUBLIC on USB stick: if found, the stick will not be completely browsable. +# Teachers can set their stick for 1 of 2 two "personalities" — students can either upload "confidential homework" or +# "public artwork" — as summarized here: https://github.com/iiab/iiab/blob/master/roles/usb_lib/README.rst +if [ -d $UM_MOUNTPOINT/PUBLIC ]; then + SHARE_DIR=$UM_MOUNTPOINT/PUBLIC + logger -t "usb_lib (70-usb-library)" "Found /PUBLIC on $UM_MOUNTPOINT" +else + SHARE_DIR=$UM_MOUNTPOINT + logger -t "usb_lib (70-usb-library)" "Did not find /PUBLIC on $UM_MOUNTPOINT" +fi + +CONTENT_LINK_USB=$(basename $UM_MOUNTPOINT | awk '{print toupper($0)}') +if [ -z "$CONTENT_LINK_USB" ]; then + logger -t "usb_lib (70-usb-library)" 'ERROR: Var CONTENT_LINK_USB is empty ("rm -rf /library/www/html/local_content/" would be dangerous!)' + exit 1 +fi +CONTENT_LINK="{{ doc_root }}/local_content/$CONTENT_LINK_USB" +# 'rm -rf' even stronger than 'ln -nsf' and 'ln -Tsf' +# https://serverfault.com/questions/147787/how-to-update-a-symbolic-link-target-ln-f-s-not-working/522483#522483 +logger -t "usb_lib (70-usb-library)" "Creating link from $CONTENT_LINK to $SHARE_DIR" +rm -rf $CONTENT_LINK +ln -s $SHARE_DIR $CONTENT_LINK diff --git a/roles/usb_lib/templates/umount.d/70-usb-library b/roles/usb_lib/templates/umount.d.unused/70-usb-library similarity index 75% rename from roles/usb_lib/templates/umount.d/70-usb-library rename to roles/usb_lib/templates/umount.d.unused/70-usb-library index 5af914c01..d8e095008 100644 --- a/roles/usb_lib/templates/umount.d/70-usb-library +++ b/roles/usb_lib/templates/umount.d.unused/70-usb-library @@ -12,7 +12,7 @@ CONTENT_LINK_USB=`basename $UM_MOUNTPOINT | awk '{print toupper($0)}'` CONTENT_LINK="{{ doc_root }}/local_content/$CONTENT_LINK_USB" -logger -p user.notice -t "70-usb-library" -- "Attempting to remove link $CONTENT_LINK." +logger -p user.notice -t "usb_lib (70-usb-library)" -- "Attempting to remove link $CONTENT_LINK." if [ -L $CONTENT_LINK ]; then {% if is_debuntu %} @@ -20,5 +20,5 @@ if [ -L $CONTENT_LINK ]; then {% else %} /usr/bin/rm -f $CONTENT_LINK {% endif %} - logger -p user.notice -t "70-usb-library" -- "$CONTENT_LINK removed." + logger -p user.notice -t "usb_lib (70-usb-library)" -- "$CONTENT_LINK removed." fi diff --git a/roles/usb_lib/templates/usbmount.rules.j2 b/roles/usb_lib/templates/usbmount.rules.j2 index 564186c5a..939a31041 100644 --- a/roles/usb_lib/templates/usbmount.rules.j2 +++ b/roles/usb_lib/templates/usbmount.rules.j2 @@ -1,5 +1,3 @@ -KERNEL=="sd*", DRIVERS=="sbp2", ACTION=="add", PROGRAM="/bin/systemd-escape -p --template=usbmount@.service $env{DEVNAME}", ENV{SYSTEMD_WANTS}+="%c" -KERNEL=="sd*", SUBSYSTEMS=="usb", ACTION=="add", PROGRAM="/bin/systemd-escape -p --template=usbmount@.service $env{DEVNAME}", ENV{SYSTEMD_WANTS}+="%c" -KERNEL=="ub*", SUBSYSTEMS=="usb", ACTION=="add", PROGRAM="/bin/systemd-escape -p --template=usbmount@.service $env{DEVNAME}", ENV{SYSTEMD_WANTS}+="%c" -KERNEL=="sd*", SUBSYSTEMS=="usb", ACTION=="remove", PROGRAM="/usr/share/usbmount/usbmount remove" +ACTION=="add", SUBSYSTEMS=="usb", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="filesystem" PROGRAM="/bin/systemd-escape -p --template=usbmount@.service $env{DEVNAME}", ENV{SYSTEMD_WANTS}+="%c" +ACTION=="remove", SUBSYSTEMS=="usb", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="filesystem" PROGRAM="/bin/systemd-escape -p /usr/share/usbmount/usbmount remove" diff --git a/roles/usb_lib/templates/usbmount@.service.j2 b/roles/usb_lib/templates/usbmount@.service.j2 index 34d75d9f3..6cf1f990b 100644 --- a/roles/usb_lib/templates/usbmount@.service.j2 +++ b/roles/usb_lib/templates/usbmount@.service.j2 @@ -1,14 +1,15 @@ [Unit] BindTo=%i.device After=%i.device -After=rc-local.service +After=systemd-udev-trigger.service +ConditionPathExists=/var/run [Service] #Type=oneshot TimeoutStartSec=0 Environment=DEVNAME=%I -ExecStart=/usr/share/usbmount/usbmount add -ExecStop=/usr/sbin/iiab-clean-usb.sh %I +ExecStart=/usr/local/sbin/usbmount add +ExecStop=/usr/local/sbin/iiab-clean-usb.sh %I ExecStopPost=/bin/umount /%I RemainAfterExit=yes - +RuntimeDirectory=usbmount diff --git a/roles/vnstat/tasks/install.yml b/roles/vnstat/tasks/install.yml index 84bec243c..46db71ddd 100644 --- a/roles/vnstat/tasks/install.yml +++ b/roles/vnstat/tasks/install.yml @@ -1,8 +1,6 @@ -# Similar code block in roles/network/tasks/detected_network.yml -- name: "Setting iiab_wan_iface to '{{ ansible_default_ipv4.alias }}' -- using ansible_default_ipv4.alias if detected" - set_fact: - iiab_wan_iface: "{{ ansible_default_ipv4.alias }}" - when: ansible_default_ipv4.gateway is defined +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 - name: Install 'vnstat' package @@ -10,12 +8,34 @@ name: vnstat state: present -- name: Install /etc/vnstat.conf from template - template: - src: vnstat.conf.j2 - dest: /etc/vnstat.conf - mode: '0744' +# Similar code block in roles/network/tasks/detected_network.yml (line ~35) and roles/network/tasks/computed_network.yml (lines ~74 and ~110) +- name: "Setting iiab_wan_iface to '{{ ansible_default_ipv4.alias }}' -- using ansible_default_ipv4.alias if detected" + set_fact: + iiab_wan_iface: "{{ ansible_default_ipv4.alias }}" + when: ansible_default_ipv4.gateway is defined + +# 2023-05-01: Probably no longer nec, as line 'Interface ""' in /etc/vnstat.conf (as installed by apt) automatically selects the default interface +- name: Insert 'Interface "{{ iiab_wan_iface }}"' into /etc/vnstat.conf + lineinfile: + path: /etc/vnstat.conf + regexp: '^Interface ' + line: 'Interface "{{ iiab_wan_iface }}"' + +# - name: Install /etc/vnstat.conf from template +# template: +# src: vnstat.conf.j2 +# dest: /etc/vnstat.conf +# mode: '0744' + + +# 2023-05-01: https://github.com/vergoh/vnstat/issues/134#issuecomment-663836557 +- name: 'Precautionary Start & Enable of vnstat.service, to mitigate intermittent #3539 (''Failed to open database "/var/lib/vnstat/vnstat.db" in read-only mode'') during WAN db creation just below' + systemd: + name: vnstat + daemon_reload: true + state: started + enabled: true - name: Create database for WAN to collect vnStat data shell: /usr/bin/vnstat -i {{ iiab_wan_iface }} @@ -27,6 +47,17 @@ # RECORD vnStat AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'vnstat_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: vnstat + option: vnstat_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'vnstat_installed: True'" set_fact: vnstat_installed: True diff --git a/roles/vnstat/templates/vnstat.conf.j2 b/roles/vnstat/templates/vnstat.conf.j2.unused similarity index 100% rename from roles/vnstat/templates/vnstat.conf.j2 rename to roles/vnstat/templates/vnstat.conf.j2.unused diff --git a/roles/wordpress/tasks/install.yml b/roles/wordpress/tasks/install.yml index cfab49cc0..fb4aca021 100644 --- a/roles/wordpress/tasks/install.yml +++ b/roles/wordpress/tasks/install.yml @@ -12,6 +12,30 @@ # can arise without warning when WordPress is online, since WordPress ~4.8 +- name: "Set 'mysql_install: True' and 'mysql_enabled: True'" + set_fact: + mysql_install: True + mysql_enabled: True + +- name: MYSQL - run 'mysql' role (attempt to install & enable MySQL / MariaDB) + include_role: + name: mysql + +- name: FAIL (STOP THE INSTALL) IF 'mysql_installed is undefined' + fail: + msg: "WordPress install cannot proceed, as MySQL / MariaDB is not installed." + when: mysql_installed is undefined + + +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + +- name: Provision MySQL DB + include_tasks: setup.yml + + # 2021-06-29: PHP modules, covering "RECOMMENDED" and "OPTIONAL" sections here: # https://make.wordpress.org/hosting/handbook/server-environment/ - name: Install libsodium23 + 8 PHP packages (run 'php -m' or 'php -i' to verify) @@ -131,6 +155,17 @@ # RECORD WordPress AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'wordpress_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: wordpress + option: wordpress_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'wordpress_installed: True'" set_fact: wordpress_installed: True diff --git a/roles/wordpress/tasks/main.yml b/roles/wordpress/tasks/main.yml index aa93c6672..106343a84 100644 --- a/roles/wordpress/tasks/main.yml +++ b/roles/wordpress/tasks/main.yml @@ -23,19 +23,13 @@ - block: - - name: Provision MySQL DB for WordPress, if 'wordpress_installed' not defined, e.g. in {{ iiab_state_file }} # /etc/iiab/iiab_state.yml - include_tasks: setup.yml - when: wordpress_installed is undefined # and not installing - - name: Install WordPress if 'wordpress_installed' not defined, e.g. in {{ iiab_state_file }} # /etc/iiab/iiab_state.yml include_tasks: install.yml when: wordpress_installed is undefined - - name: Enable/Disable/Restart NGINX include_tasks: nginx.yml - - name: Add 'wordpress' variable values to {{ iiab_ini_file }} ini_file: path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini diff --git a/roles/www_base/tasks/main.yml b/roles/www_base/tasks/main.yml index 0f557148f..8efe11472 100644 --- a/roles/www_base/tasks/main.yml +++ b/roles/www_base/tasks/main.yml @@ -1,6 +1,12 @@ # Role "www_base" runs here, probably in 3-BASE-SERVER. # Role "www_options" runs later, likely in 4-SERVER-OPTIONS. + +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + # 2021-06-27: Antifragile roles can become less brittle by fully declaring # their own dependencies (i.e. for modularity, separation-of-concerns, # encapsulation, compartmentalization, scope sanity, etc). @@ -54,6 +60,17 @@ # RECORD www_base AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'www_base_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: www_base + option: www_base_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'www_base_installed: True'" set_fact: www_base_installed: True diff --git a/roles/www_base/templates/iiab-refresh-wiki-docs.sh b/roles/www_base/templates/iiab-refresh-wiki-docs.sh index 5cc9b3f54..9ff61e654 100755 --- a/roles/www_base/templates/iiab-refresh-wiki-docs.sh +++ b/roles/www_base/templates/iiab-refresh-wiki-docs.sh @@ -15,23 +15,34 @@ INPUT=/tmp/iiab-wiki OUTPUT=/tmp/iiab-wiki.out DESTPATH={{ doc_root }}/info # /library/www/html/info DOCSPATH=$DESTPATH/docs # /library/www/html/info/docs +ADMINDOCSPATH=$DESTPATH/admin-console # /library/www/html/info/admin-console +# Note 1: sed (below) shortens URLs to 'admin-console' +# Note 2: Depends on "fancyindex on;" in roles/nginx/templates/iiab.conf.j2 rm -rf $INPUT rm -rf $OUTPUT mkdir -p $INPUT mkdir -p $OUTPUT mkdir -p $DOCSPATH +mkdir -p $ADMINDOCSPATH git clone https://github.com/iiab/iiab.wiki.git $INPUT - -for f in `ls $INPUT`; do +for f in `ls $INPUT`; do # Unlike further below, $f does NOT include path FTRIMMED=${f%.md} if [ $FTRIMMED = "Home" ]; then FTRIMMED=index; fi pandoc -s $INPUT/$f -o $OUTPUT/$FTRIMMED.html done - rsync -av $OUTPUT/ $DESTPATH +if [ -d /opt/iiab/iiab-admin-console/docs ]; then + cp /opt/iiab/iiab-admin-console/docs/*.md $ADMINDOCSPATH + for f in $ADMINDOCSPATH/*.md; do # Unlike above, $f INCLUDES path + FTRIMMED=${f%.md} + pandoc -s $f -o $FTRIMMED.html + rm $f + done +fi + # Download FAQ etc lynx -reload -source https://wiki.iiab.io/go/FAQ > $DESTPATH/FAQ.html lynx -reload -source https://wiki.iiab.io/go/Security > $DESTPATH/Security.html @@ -54,42 +65,45 @@ cp -p "{{ iiab_dir }}/roles/lokole/Lokole-IIAB_Users_Manual.pdf" $DOCSPATH # # MAKE LINKS REFER TO LOCAL ITEMS... # ...on main page (http://box/info) -sed -i -r "s|https://magazines-attachments.raspberrypi.org/books/full_pdfs/000/000/038/original/BeginnersGuide-4thEd-Eng_v2.pdf|docs/BeginnersGuide-4thEd-Eng_v2.pdf|g" $DESTPATH/index.html -sed -i -r "s|https://.*archive.org/15/items/other_doc/other_doc.pdf|docs/Raspberry_Pi_User_Guide_v4.pdf|g" $DESTPATH/index.html -sed -i -r "s|https://github.com/iiab/iiab/blob/master/roles/lokole/Lokole-IIAB_Users_Manual.pdf|docs/Lokole-IIAB_Users_Manual.pdf|g" $DESTPATH/index.html +sed -i "s|https://magazines-attachments.raspberrypi.org/books/full_pdfs/000/000/038/original/BeginnersGuide-4thEd-Eng_v2.pdf|docs/BeginnersGuide-4thEd-Eng_v2.pdf|g" $DESTPATH/index.html +sed -i "s|https://.*archive.org/15/items/other_doc/other_doc.pdf|docs/Raspberry_Pi_User_Guide_v4.pdf|g" $DESTPATH/index.html +sed -i "s|https://github.com/iiab/iiab/blob/master/roles/lokole/Lokole-IIAB_Users_Manual.pdf|docs/Lokole-IIAB_Users_Manual.pdf|g" $DESTPATH/index.html # ...and within subpages -for f in $DESTPATH/*.html; do - sed -i -r "s|https://github.com/iiab/iiab/wiki/([-.A-Za-z0-9]*)|\1.html|g" $f +for f in $(find $DESTPATH -name "*.html"); do # Recursive (even if not yet nec, as of 2023-01-11) +#for f in $DESTPATH/*.html; do # Non-recursive (omits subdirs) + sed -i -r "s|https://github.com/iiab/iiab/wiki/([-.~A-Za-z0-9]*)|\1.html|g" $f - sed -i -e "s|https://github.com/xsce/xsce/blob/release-6.2/\(.*\)\.md\">|\1.html\">|g" $f - sed -i -e "s|https://github.com/xsce/xsce/wiki/\(.*\)\">|\1.html\">|g" $f + sed -i "s|https://github.com/iiab/iiab-admin-console/tree/master/docs|admin-console|g" $f - sed -i -e "s|https://wiki.iiab.io/go/FAQ|FAQ.html|g" $f - sed -i -e "s|http://wiki.laptop.org/go/IIAB/FAQ|FAQ.html|g" $f - sed -i -e "s|/go/IIAB/FAQ|FAQ.html|g" $f - sed -i -e "s|http://wiki.iiab.io/FAQ|FAQ.html|g" $f - sed -i -e "s|http://FAQ.IIAB.IO|FAQ.html|g" $f - sed -i -e "s|http://faq.iiab.io|FAQ.html|g" $f - sed -i -e "s|http://schoolserver.org/FAQ|FAQ.html|g" $f - sed -i -e "s|http://schoolserver.org/faq|FAQ.html|g" $f - sed -i -e "s|http://wiki.laptop.org/go/XS_Community_Edition/FAQ|FAQ.html|g" $f + sed -i "s|https://github.com/xsce/xsce/blob/release-6.2/\(.*\)\.md\">|\1.html\">|g" $f + sed -i "s|https://github.com/xsce/xsce/wiki/\(.*\)\">|\1.html\">|g" $f - sed -i -e "s|http://wiki.laptop.org/go/IIAB/Security|Security.html|g" $f - sed -i -e "s|/go/IIAB/Security|Security.html|g" $f - sed -i -e "s|http://wiki.iiab.io/Security|Security.html|g" $f + sed -i "s|https://wiki.iiab.io/go/FAQ|FAQ.html|g" $f + #sed -i "s|http://wiki.laptop.org/go/IIAB/FAQ|FAQ.html|g" $f + sed -i "s|/go/IIAB/FAQ|FAQ.html|g" $f + sed -i "s|http://wiki.iiab.io/FAQ|FAQ.html|g" $f + sed -i "s|http://FAQ.IIAB.IO|FAQ.html|g" $f + sed -i "s|http://faq.iiab.io|FAQ.html|g" $f + #sed -i "s|http://schoolserver.org/FAQ|FAQ.html|g" $f + #sed -i "s|http://schoolserver.org/faq|FAQ.html|g" $f + #sed -i "s|http://wiki.laptop.org/go/XS_Community_Edition/FAQ|FAQ.html|g" $f - sed -i -e "s|http://wiki.laptop.org/go/IIAB/local_vars.yml|local_vars.yml|g" $f - sed -i -e "s|/go/IIAB/local_vars.yml|local_vars.yml|g" $f - sed -i -e "s|http://wiki.iiab.io/local_vars.yml|local_vars.yml|g" $f + #sed -i "s|http://wiki.laptop.org/go/IIAB/Security|Security.html|g" $f + sed -i "s|/go/IIAB/Security|Security.html|g" $f + sed -i "s|http://wiki.iiab.io/Security|Security.html|g" $f - sed -i -e "s|http://wiki.laptop.org/go/IIAB/local_vars_min.yml|local_vars_min.yml|g" $f - sed -i -e "s|/go/IIAB/local_vars_min.yml|local_vars_min.yml|g" $f - sed -i -e "s|http://wiki.iiab.io/local_vars_min.yml|local_vars_min.yml|g" $f + #sed -i "s|http://wiki.laptop.org/go/IIAB/local_vars.yml|local_vars.yml|g" $f + sed -i "s|/go/IIAB/local_vars.yml|local_vars.yml|g" $f + sed -i "s|https://wiki.iiab.io/local_vars.yml|local_vars.yml|g" $f - sed -i -e "s|http://wiki.laptop.org/go/IIAB/local_vars_big.yml|local_vars_big.yml|g" $f - sed -i -e "s|/go/IIAB/local_vars_big.yml|local_vars_big.yml|g" $f - sed -i -e "s|http://wiki.iiab.io/local_vars_big.yml|local_vars_big.yml|g" $f + #sed -i "s|http://wiki.laptop.org/go/IIAB/local_vars_min.yml|local_vars_min.yml|g" $f + #sed -i "s|/go/IIAB/local_vars_min.yml|local_vars_min.yml|g" $f + #sed -i "s|http://wiki.iiab.io/local_vars_min.yml|local_vars_min.yml|g" $f + + #sed -i "s|http://wiki.laptop.org/go/IIAB/local_vars_big.yml|local_vars_big.yml|g" $f + #sed -i "s|/go/IIAB/local_vars_big.yml|local_vars_big.yml|g" $f + #sed -i "s|http://wiki.iiab.io/local_vars_big.yml|local_vars_big.yml|g" $f done exit 0 diff --git a/roles/www_options/tasks/main.yml b/roles/www_options/tasks/main.yml index fba3379ac..f157abb26 100644 --- a/roles/www_options/tasks/main.yml +++ b/roles/www_options/tasks/main.yml @@ -2,20 +2,25 @@ # Role "www_options" runs here, probably in 4-SERVER-OPTIONS. +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 + + # HOMEPAGE - name: Create dir {{ doc_root }}{{ iiab_home_url }} just in case variable iiab_home_url was customized. (Standard path {{doc_root}}/home was created earlier.) file: state: directory - path: "{{ doc_root }}{{ iiab_home_url }}" # /library/www/html/home + path: "{{ doc_root }}{{ iiab_home_url }}" # e.g. /library/www/html/home owner: "{{ apache_user }}" group: "{{ apache_user }}" mode: '0755' # Used to be run by httpd/tasks/install.yml -- name: "IN CASE NGINX IS DISABLED: Enable IIAB pages via Apache (e.g. on port 80) if apache_install" - include_tasks: roles/httpd/tasks/homepage.yml - when: apache_installed is defined +#- name: "IN CASE NGINX IS DISABLED: Enable IIAB pages via Apache (e.g. on port 80) if apache_install" +# include_tasks: roles/httpd/tasks/homepage.yml +# when: apache_installed is defined # Used to be run by nginx/tasks/install.yml - name: Enable IIAB pages via NGINX (e.g. on port 80) if nginx_install @@ -26,29 +31,37 @@ # 2022-07-22: SIMILAR TO roles/iiab-admin/tasks/pwd-warnings.yml FOR passwords # AND roles/network/tasks/netwarn.yml FOR iiab-network -- name: Does /etc/xdg/lxsession/LXDE-pi/autostart exist? (if so, auto-launch browser on boot, displaying http://box/home IIAB home page) +# 2024-12-12: RasPiOS changed compositor from wayfire to labwc: https://forums.raspberrypi.com/viewtopic.php?t=379321 +- name: Does directory /home/{{ iiab_admin_user }}/.config/labwc/ exist? stat: - path: /etc/xdg/lxsession/LXDE-pi/autostart - register: lxde_pi_autostart_present + path: /home/{{ iiab_admin_user }}/.config/labwc/ + register: labwc_dir -- name: Does /usr/bin/chromium exist? (check for browser filename change) +- name: Does /usr/bin/chromium-browser exist? stat: - path: /usr/bin/chromium - register: chromium_present + path: /usr/bin/chromium-browser + register: chromium_browser -- name: Add chromium-browser to /etc/xdg/lxsession/LXDE-pi/autostart - lineinfile: - path: /etc/xdg/lxsession/LXDE-pi/autostart - regexp: '^/usr/bin/chromium-browser' - line: '/usr/bin/chromium-browser --disable-restore-session-state http://box/home' - when: lxde_pi_autostart_present.stat.exists and not chromium_present.stat.exists +# - name: Does /usr/bin/chromium exist? (check for browser filename change) +# stat: +# path: /usr/bin/chromium +# register: chromium_present -- name: Add chromium to /etc/xdg/lxsession/LXDE-pi/autostart +# 2024-12-12: RasPiOS changed compositor from wayfire to labwc: https://forums.raspberrypi.com/viewtopic.php?t=379321 +- name: If both above exist, add '/usr/bin/chromium-browser --disable-restore-session-state http://box/home &' to /home/{{ iiab_admin_user }}/.config/labwc/autostart lineinfile: - path: /etc/xdg/lxsession/LXDE-pi/autostart + path: /home/{{ iiab_admin_user }}/.config/labwc/autostart # iiab-admin + create: yes regexp: '^/usr/bin/chromium' - line: '/usr/bin/chromium --disable-restore-session-state http://box/home' - when: lxde_pi_autostart_present.stat.exists and chromium_present.stat.exists + line: '/usr/bin/chromium-browser --disable-restore-session-state http://box/home &' + when: labwc_dir.stat.exists and labwc_dir.stat.isdir and chromium_browser.stat.exists + +# - name: Add chromium to /etc/xdg/lxsession/LXDE-pi/autostart +# lineinfile: +# path: /etc/xdg/lxsession/LXDE-pi/autostart +# regexp: '^/usr/bin/chromium' +# line: '/usr/bin/chromium --disable-restore-session-state http://box/home' +# when: lxde_pi_autostart_present.stat.exists and chromium_present.stat.exists # 2022-12-29: php-settings.yml is ALSO attempted (on demand) by every @@ -56,7 +69,8 @@ # WordPress) so './runrole ' and similar are fully self-sufficient! - name: "Run php-settings.yml -- allows post-install toggling of nginx_high_php_limits in /etc/iiab/local_vars.yml -- if you run './runrole www_options'" include_tasks: php-settings.yml - when: matomo_install or moodle_install or nextcloud_install or pbx_install or wordpress_install + # 2025-01-29: PHP's own defaults (presumably from the 1990s?) were Way Too Low -- for usb-lib's upload2usb, and in general -- so let's run php-settings.yml every time! + # when: nginx_high_php_limits or matomo_install or moodle_install or nextcloud_install or pbx_install or wordpress_install # 'Is a "Rapid Power Off" button possible for low-electricity environments?' @@ -64,29 +78,31 @@ # COMPARE nginx_high_php_limits further above. -# 2020-03-08: DOES THE FLAG BELOW (apache_allow_sudo) PRESUMABLY WORK +# 2020-03-08: DOES THE FLAG BELOW (allow_www_data_poweroff) PRESUMABLY WORK # WITH NGINX TOO ? (The single-click poweroff button on IIAB's home # page certainly does still work with NGINX.) -- name: Give {{ apache_user }} (per variable apache_user) permission to poweroff, installing /etc/sudoers.d/020_apache_poweroff from template +- name: Give {{ apache_user }} (per variable apache_user) permission to poweroff, installing /etc/sudoers.d/020_www_data_poweroff from template template: - src: 020_apache_poweroff.j2 - dest: /etc/sudoers.d/020_apache_poweroff + src: 020_www_data_poweroff.j2 + dest: /etc/sudoers.d/020_www_data_poweroff mode: '0440' - when: apache_allow_sudo + when: allow_www_data_poweroff -- name: Remove {{ apache_user }} (per variable apache_user) permission to poweroff, removing /etc/sudoers.d/020_apache_poweroff +- name: Remove {{ apache_user }} (per variable apache_user) permission to poweroff, removing /etc/sudoers.d/020_www_data_poweroff file: - path: /etc/sudoers.d/020_apache_poweroff + path: /etc/sudoers.d/020_www_data_poweroff state: absent - when: not apache_allow_sudo + when: not allow_www_data_poweroff # 2022-06-30: internet_available var removed -- name: 'Test for Internet access, using: {{ iiab_download_url }}/heart-beat.txt' +- name: 'Test for Internet access, using: https://wiki.iiab.io' get_url: - url: "{{ iiab_download_url }}/heart-beat.txt" - dest: /tmp/heart-beat.txt + #url: "{{ iiab_download_url }}/heart-beat.txt" + url: https://wiki.iiab.io + #dest: /tmp/heart-beat.txt + dest: /tmp/internet_access_test.html #timeout: "{{ download_timeout }}" # @jvonau recommends: 100sec is too much (keep 10sec default) ignore_errors: True @@ -94,9 +110,9 @@ #poll: 2 register: internet_access_test -- name: Remove downloaded Internet test file /tmp/heart-beat.txt +- name: Remove downloaded Internet test file /tmp/internet_access_test.html file: - path: /tmp/heart-beat.txt + path: /tmp/internet_access_test.html state: absent - name: Run /usr/bin/iiab-refresh-wiki-docs (scraper script) to create http://box/info offline documentation. (This script was installed in Stage 3 = roles/3-base-server/tasks/main.yml, which ran roles/www_base/tasks/main.yml) @@ -119,6 +135,17 @@ # RECORD www_options AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'www_options_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: www_options + option: www_options_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'www_options_installed: True'" set_fact: www_options_installed: True diff --git a/roles/www_options/tasks/php-settings.yml b/roles/www_options/tasks/php-settings.yml index 39a2a0bce..7109ccfeb 100644 --- a/roles/www_options/tasks/php-settings.yml +++ b/roles/www_options/tasks/php-settings.yml @@ -21,11 +21,19 @@ # # This takes care of essentially everything (e.g. output "America/New_York") # by checking (1) symlink /etc/localtime then (2) text file /etc/timezone if -# nec, then (3) if neither exist, "UTC" is declated (correctly!) Potential +# nec, then (3) if neither exist, "UTC" is declared (correctly!) Potential # drawback: timedatectl is not easily usable within chroot environments. -- name: Extract Time Zone from symlink /etc/localtime &/or text file /etc/timezone (or lack thereof!) - command: timedatectl show -p Timezone --value +# 2025-01-29: Current GitHub Actions chroot environments for RPi (using guyot/arm-runner-action@v2) surface this error, after PR #3927 mainlined php-settings.yml... +# "System has not been booted with systemd as init system (PID 1). Can't operate.\nFailed to connect to bus: Host is down" +# ...which might be mitigated in 2 ways: +# 1) Try spawning these "guyot/arm-runner-action@v2" GHA workflows with... use_systemd_nspawn: true +# 2) Weaken timedatectl command just below, trying this instead... shell: readlink /etc/localtime | sed 's#^/usr/share/zoneinfo/##' + +- name: Extract Time Zone from symlink /etc/localtime, text file /etc/timezone, or if all else fails declare Etc/UTC + # command: timedatectl show -p Timezone --value + # 2025-02-01: "guyot/arm-runner-action@v2" GHA workflows don't seem to work with "use_systemd_nspawn: true", so hack in the equivalent of timedatectl... + shell: tmp=$(readlink /etc/localtime) && echo $tmp | sed 's|^/usr/share/zoneinfo/||' || cat /etc/timezone || echo Etc/UTC register: tz_cli - name: Store 'date.timezone = {{ tz_cli.stdout }}' (from above) in /etc/php/{{ php_version }}/fpm/php.ini and /etc/php/{{ php_version }}/cli/php.ini @@ -52,7 +60,7 @@ # And in the past it used: .../apache2/php.ini -- name: "Enact 'nginx_high_php_limits: False' in /etc/php/{{ php_version }}/fpm/php.ini for LIGHTWEIGHT use of Matomo/Nextcloud/PBX/WordPress (allow photos/docs up to 100MB, 100s timeouts, with 2 PHP system defaults: memory_limit = 128M, max_input_vars = 1000)" +- name: "Enact 'nginx_high_php_limits: False' in /etc/php/{{ php_version }}/fpm/php.ini for LIGHTWEIGHT use of Matomo/Nextcloud/PBX/WordPress (allow file size up to 100MB, 100s timeouts, with 2 PHP system defaults: memory_limit = 128M, max_input_vars = 1000)" lineinfile: path: /etc/php/{{ php_version }}/fpm/php.ini # COMPARE /etc/php/{{ php_version }}/cli/php.ini AND /etc/php/{{ php_version }}/apache2/php.ini regexp: "{{ item.regexp }}" @@ -64,9 +72,9 @@ - { regexp: '^max_input_time', line: 'max_input_time = 100 ; default is 60' } - { regexp: '^memory_limit', line: 'memory_limit = 128M ; default is 128M / Nextcloud requests 512M' } - { regexp: '^max_input_vars', line: 'max_input_vars = 1000 ; default is 1000 / Moodle 3.11+ requires 5000+ with PHP 8+' } - when: not nginx_high_php_limits and not moodle_install + when: not nginx_high_php_limits and not moodle_install and not nextcloud_install -- name: "Enact 'nginx_high_php_limits: False' in /etc/php/{{ php_version }}/cli/php.ini for LIGHTWEIGHT use of Matomo/Nextcloud/PBX/WordPress (allow photos/docs up to 100MB, 100s timeouts, with 2 PHP system defaults: memory_limit = 128M, max_input_vars = 1000)" +- name: "Enact 'nginx_high_php_limits: False' in /etc/php/{{ php_version }}/cli/php.ini for LIGHTWEIGHT use of Matomo/Nextcloud/PBX/WordPress (allow file size up to 100MB, 100s timeouts, with 2 PHP system defaults: memory_limit = 128M, max_input_vars = 1000)" lineinfile: path: /etc/php/{{ php_version }}/cli/php.ini # COMPARE /etc/php/{{ php_version }}/fpm/php.ini AND /etc/php/{{ php_version }}/apache2/php.ini regexp: "{{ item.regexp }}" @@ -78,36 +86,36 @@ - { regexp: '^max_input_time', line: 'max_input_time = 100 ; default is 60' } - { regexp: '^memory_limit', line: 'memory_limit = 128M ; default is -1 (i.e. no limit) / Nextcloud requests 512M' } - { regexp: '^max_input_vars', line: 'max_input_vars = 1000 ; default is 1000 / Moodle 3.11+ requires 5000+ with PHP 8+' } - when: not nginx_high_php_limits and not moodle_install + when: not nginx_high_php_limits and not moodle_install and not nextcloud_install -- name: "Enact 'nginx_high_php_limits: True' in /etc/php/{{ php_version }}/fpm/php.ini for Moodle or INTENSIVE use of Matomo/Nextcloud/PBX/WordPress (allow photos/docs up to 500MB, 300s timeouts, memory_limit = 512M for Nextcloud, max_input_vars = 5000 for Moodle)" +- name: "Enact 'nginx_high_php_limits: True' in /etc/php/{{ php_version }}/fpm/php.ini for Moodle/Nextcloud or INTENSIVE use of Matomo/PBX/WordPress (allow file size up to 10000MB, 300s timeouts, memory_limit = 512M for Nextcloud, max_input_vars = 5000 for Moodle)" lineinfile: path: /etc/php/{{ php_version }}/fpm/php.ini # COMPARE /etc/php/{{ php_version }}/cli/php.ini AND /etc/php/{{ php_version }}/apache2/php.ini regexp: "{{ item.regexp }}" line: "{{ item.line }}" with_items: - - { regexp: '^upload_max_filesize', line: 'upload_max_filesize = 500M ; default is 2M' } - - { regexp: '^post_max_size', line: 'post_max_size = 500M ; default is 8M' } + - { regexp: '^upload_max_filesize', line: 'upload_max_filesize = 10000M ; default is 2M' } + - { regexp: '^post_max_size', line: 'post_max_size = 10000M ; default is 8M' } - { regexp: '^max_execution_time', line: 'max_execution_time = 300 ; default is 30' } - { regexp: '^max_input_time', line: 'max_input_time = 300 ; default is 60' } - { regexp: '^memory_limit', line: 'memory_limit = 512M ; default is 128M / Nextcloud requests 512M' } - { regexp: '^max_input_vars', line: 'max_input_vars = 5000 ; default is 1000 / Moodle 3.11+ requires 5000+ with PHP 8+' } - when: nginx_high_php_limits or moodle_install + when: nginx_high_php_limits or moodle_install or nextcloud_install -- name: "Enact 'nginx_high_php_limits: True' in /etc/php/{{ php_version }}/cli/php.ini for Moodle or INTENSIVE use of Matomo/Nextcloud/PBX/WordPress (allow photos/docs up to 500MB, 300s timeouts, memory_limit = 512M for Nextcloud, max_input_vars = 5000 for Moodle)" +- name: "Enact 'nginx_high_php_limits: True' in /etc/php/{{ php_version }}/cli/php.ini for Moodle/Nextcloud or INTENSIVE use of Matomo/PBX/WordPress (allow file size up to 10000MB, 300s timeouts, memory_limit = 512M for Nextcloud, max_input_vars = 5000 for Moodle)" lineinfile: path: /etc/php/{{ php_version }}/cli/php.ini # COMPARE /etc/php/{{ php_version }}/fpm/php.ini AND /etc/php/{{ php_version }}/apache2/php.ini regexp: "{{ item.regexp }}" line: "{{ item.line }}" with_items: - - { regexp: '^upload_max_filesize', line: 'upload_max_filesize = 500M ; default is 2M' } - - { regexp: '^post_max_size', line: 'post_max_size = 500M ; default is 8M' } + - { regexp: '^upload_max_filesize', line: 'upload_max_filesize = 10000M ; default is 2M' } + - { regexp: '^post_max_size', line: 'post_max_size = 10000M ; default is 8M' } - { regexp: '^max_execution_time', line: 'max_execution_time = 300 ; default is 30' } - { regexp: '^max_input_time', line: 'max_input_time = 300 ; default is 60' } - { regexp: '^memory_limit', line: 'memory_limit = 512M ; default is -1 (i.e. no limit) / Nextcloud requests 512M' } - { regexp: '^max_input_vars', line: 'max_input_vars = 5000 ; default is 1000 / Moodle 3.11+ requires 5000+ with PHP 8+' } - when: nginx_high_php_limits or moodle_install + when: nginx_high_php_limits or moodle_install or nextcloud_install # To tweak .ini files, Ansible's ini_file is normally better than lineinfile: @@ -207,4 +215,4 @@ # name: php{{ php_version }}-fpm # state: restarted -# when: matomo_install or moodle_install or nextcloud_install or pbx_install or wordpress_install # 5-STANZA BLOCK ENDS. COMPARE apache_allow_sudo conditionals below. +# when: matomo_install or moodle_install or nextcloud_install or pbx_install or wordpress_install # 5-STANZA BLOCK ENDS. COMPARE allow_www_data_poweroff conditionals below. diff --git a/roles/www_options/templates/020_apache_poweroff.j2 b/roles/www_options/templates/020_www_data_poweroff.j2 similarity index 100% rename from roles/www_options/templates/020_apache_poweroff.j2 rename to roles/www_options/templates/020_www_data_poweroff.j2 diff --git a/roles/yarn/tasks/install.yml b/roles/yarn/tasks/install.yml index 48628d688..331a10474 100644 --- a/roles/yarn/tasks/install.yml +++ b/roles/yarn/tasks/install.yml @@ -1,34 +1,61 @@ -- name: "Yarn | GPG" - apt_key: - url: https://dl.yarnpkg.com/debian/pubkey.gpg - state: present +- name: Record (initial) disk space used + shell: df -B1 --output=used / | tail -1 + register: df1 -- name: "Yarn | Ensure Debian sources list file exists" - file: - path: /etc/apt/sources.list.d/yarn.list - owner: root - mode: '0644' - state: touch -- name: "Yarn | Ensure Debian package is in sources list" - lineinfile: - dest: /etc/apt/sources.list.d/yarn.list - regexp: 'deb https://dl.yarnpkg.com/debian/ stable main' - line: 'deb https://dl.yarnpkg.com/debian/ stable main' - state: present +- name: Yarn | Download apt key to /usr/share/keyrings/yarn.gpg + shell: curl https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor > /usr/share/keyrings/yarn.gpg -- name: "Yarn | Update APT cache" +- name: Yarn | Add signed Yarn PPA to /etc/apt/sources.list.d/dl_yarnpkg_com_debian.list + apt_repository: + repo: "deb [signed-by=/usr/share/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" + #filename: yarn # If legacy filename yarn.list is preferred + +# 2023-04-01 above avoids DEPRECATED apt-key command & associated problems: +# https://github.com/iiab/iiab/wiki/IIAB-Platforms#etcapttrustedgpg-legacy-keyring-warnings + +# - name: "Yarn | GPG" +# apt_key: +# url: https://dl.yarnpkg.com/debian/pubkey.gpg +# state: present + +# - name: "Yarn | Ensure Debian sources list file exists" +# file: +# path: /etc/apt/sources.list.d/yarn.list +# owner: root +# mode: '0644' +# state: touch + +# - name: "Yarn | Ensure Debian package is in sources list" +# lineinfile: +# dest: /etc/apt/sources.list.d/yarn.list +# regexp: 'deb https://dl.yarnpkg.com/debian/ stable main' +# line: 'deb https://dl.yarnpkg.com/debian/ stable main' +# state: present + +- name: Yarn | Update APT cache apt: update_cache: yes -- name: "Yarn | Install" +- name: Yarn | Install package: name: yarn - state: latest + #state: latest # No need to mention it, with apt # RECORD Yarn AS INSTALLED +- name: Record (final) disk space used + shell: df -B1 --output=used / | tail -1 + register: df2 + +- name: Add 'yarn_disk_usage = {{ df2.stdout|int - df1.stdout|int }}' to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" # /etc/iiab/iiab.ini + section: yarn + option: yarn_disk_usage + value: "{{ df2.stdout|int - df1.stdout|int }}" + - name: "Set 'yarn_installed: True'" set_fact: yarn_installed: True diff --git a/runrole b/runrole index ad1387e2c..4e8657208 100755 --- a/runrole +++ b/runrole @@ -39,7 +39,7 @@ fi mkdir -p /etc/iiab # -p avoids errors, effectively like '|| true' if [ ! -f /etc/iiab/local_vars.yml ]; then - echo -e "\n\e[1mEXITING: /opt/iiab/iiab/iiab-install REQUIRES /etc/iiab/local_vars.yml\e[0m\n" >&2 + echo -e "\n\e[1mEXITING: /opt/iiab/iiab/runrole REQUIRES /etc/iiab/local_vars.yml\e[0m\n" >&2 echo -e "(1) See http://FAQ.IIAB.IO -> What is local_vars.yml and how do I customize it?" >&2 echo -e "(2) SMALL/MEDIUM/LARGE samples are included in /opt/iiab/iiab/vars" >&2 diff --git a/scripts/ansible b/scripts/ansible index 2766aec7b..22c8cbacd 100755 --- a/scripts/ansible +++ b/scripts/ansible @@ -4,11 +4,11 @@ # https://stackoverflow.com/questions/9952177/whats-the-meaning-of-the-parameter-e-for-bash-shell-command-line/9952249 # PLZ SEE http://FAQ.IIAB.IO > "What is Ansible and what version should I use?" -# https://github.com/iiab/iiab/wiki/Technical-Contributors-Guide#understanding-ansible +# https://github.com/iiab/iiab/wiki/Technical-Contributors-Guide#female_detective-understanding-ansible APT_PATH=/usr/bin # Avoids problematic /usr/local/bin/apt on Linux Mint -CURR_VER=undefined # Ansible version you have installed, e.g. [core 2.14.1] -GOOD_VER=2.14.1 # Orig for 'yum install [rpm]' & XO laptops (pip install) +CURR_VER=undefined # Ansible version you have installed, e.g. [core 2.18.3] +GOOD_VER=2.18.3 # Orig for 'yum install [rpm]' & XO laptops (pip install) # 2021-06-22: The apt approach (with PPA source in /etc/apt/sources.list.d/ and # .gpg key etc) are commented out with ### below. Associated guidance/comments @@ -25,31 +25,39 @@ GOOD_VER=2.14.1 # Orig for 'yum install [rpm]' & XO laptops (pip install) # 'lsb_release -sc' gives Mint 20 codename 'ulyana' etc: (TOO FINE-GRAINED) ###if grep -q buster /etc/os-release /etc/debian_version; then -### CODENAME=bionic # Debian 10, RaspiOS 10 & Buster-like distros +### CODENAME=bionic # Debian 10, RasPiOS 10 & Buster-like distros ###else -### CODENAME=focal # Debian 11+, RaspiOS 11+, Ubuntu 20.04+, Mint 20+ (ETC) +### CODENAME=focal # Debian 11+, RasPiOS 11+, Ubuntu 20.04+, Mint 20+ (ETC) ###fi # APRIL 2021 - ansible-base (2.10) was renamed to ansible-core (2.11+): # https://www.ansible.com/blog/ansible-3.0.0-qa # https://github.com/ansible/ansible/tags -# https://github.com/ansible/ansible/releases (OLD) +# https://github.com/ansible/ansible/releases +# https://github.com/ansible/ansible/commits/stable-2.18 +# https://github.com/ansible/ansible/blob/stable-2.18/changelogs/CHANGELOG-v2.18.rst +# https://github.com/ansible/ansible/commits/stable-2.17 +# https://github.com/ansible/ansible/blob/stable-2.17/changelogs/CHANGELOG-v2.17.rst +# https://github.com/ansible/ansible/commits/stable-2.16 +# https://github.com/ansible/ansible/blob/stable-2.16/changelogs/CHANGELOG-v2.16.rst +# https://github.com/ansible/ansible/commits/stable-2.15 +# https://github.com/ansible/ansible/blob/stable-2.15/changelogs/CHANGELOG-v2.15.rst # https://github.com/ansible/ansible/commits/stable-2.14 # https://github.com/ansible/ansible/blob/stable-2.14/changelogs/CHANGELOG-v2.14.rst # https://github.com/ansible/ansible/commits/stable-2.13 # https://github.com/ansible/ansible/blob/stable-2.13/changelogs/CHANGELOG-v2.13.rst # https://github.com/ansible/ansible/commits/stable-2.12 # https://github.com/ansible/ansible/blob/stable-2.12/changelogs/CHANGELOG-v2.12.rst -# https://github.com/ansible/ansible/blob/devel/docs/docsite/rst/roadmap/ROADMAP_2_12.rst # https://pypi.org/project/ansible-core/ -# https://pypi.org/project/ansible-base/ -# https://releases.ansible.com/ansible-core/ +# https://pypi.org/project/ansible-base/ (OLD) +# https://releases.ansible.com/ansible-core/ (OLD) # https://releases.ansible.com/ansible-base/ (OLD) # https://launchpad.net/~ansible # https://launchpad.net/~ansible-gha # https://launchpad.net/~ansible/+archive/ubuntu/ansible +# https://launchpad.net/~ansible/+archive/ubuntu/ansible/+packages # https://launchpad.net/~ansible/+archive/ubuntu/ansible-2.10 (OLD) -# http://ppa.launchpad.net/ansible/ansible/ubuntu/pool/main/a/ansible/ +# http://ppa.launchpad.net/ansible/ansible/ubuntu/pool/main/a/ansible/ (OLD) # http://ppa.launchpad.net/ansible/ansible/ubuntu/pool/main/a/ansible-core/ # FYI .travis.yml installs ansible-core in a slightly different way (PRs #2689 & #2743) @@ -88,15 +96,15 @@ echo -e "RECOMMENDED PREREQUISITES:" echo -e "(1) Verify you're online" echo -e "(2) Remove all prior versions of Ansible using..." echo -e " 'apt purge ansible-core' and/or 'pip3 uninstall ansible-core' and/or" -echo -e " 'apt purge ansible-base' and/or 'pip3 uninstall ansible-base' and/or" +#echo -e " 'apt purge ansible-base' and/or 'pip3 uninstall ansible-base' and/or" echo -e " 'apt purge ansible' and/or 'pip3 uninstall ansible'" -echo -e "(3) Remove all lines containing 'ansible' from..." -echo -e " /etc/apt/sources.list and /etc/apt/sources.list.d/*\n" +#echo -e "(3) Remove all lines containing 'ansible' from..." +#echo -e " /etc/apt/sources.list and /etc/apt/sources.list.d/*\n" -echo -e "IIAB INSTALL INSTRUCTIONS: (OLDER, MANUAL APPROACH)" -echo -e "https://github.com/iiab/iiab/wiki/IIAB-Installation#do-everything-from-scratch\n" +#echo -e "IIAB INSTALL INSTRUCTIONS: (OLDER, MANUAL APPROACH)" +#echo -e "https://github.com/iiab/iiab/wiki/IIAB-Installation#do-everything-from-scratch\n" -if [ $(command -v ansible) ]; then # "command -v" is POSIX compliant; also catches built-in commands like "cd" +if [ "$(command -v ansible)" ]; then # "command -v" is POSIX compliant; also catches built-in commands like "cd" CURR_VER=$(ansible --version | head -1 | cut -f 2- -d " ") # Above works with 'ansible [core 2.11.0rc2]' -- these old ways do not: #CURR_VER=$(ansible --version | head -1 | awk '{print $2}') @@ -109,7 +117,7 @@ echo -e "(Internet-in-a-Box requests ansible-core $GOOD_VER or higher)\n" # Code above designed to work on all Linux distributions, to preserve options, # in support of any volunteer(s) wanting to port IIAB to a new Linux/distro. -if [ ! -f /etc/debian_version ]; then # e.g. RaspiOS, Ubuntu, Mint & Debian +if [ ! -f /etc/debian_version ]; then # e.g. RasPiOS, Ubuntu, Mint & Debian echo -e "\nEXITING: /etc/debian_version FILE NOT FOUND. Linux OS support info here:" echo -e " https://github.com/iiab/iiab/wiki/IIAB-Platforms\n" exit 1 @@ -129,8 +137,8 @@ fi ### > /etc/apt/sources.list.d/iiab-ansible.list # 2022-11-09: ansible-core 2.12.10+ PPA works on 32-bit RasPiOS, until upstream wheels -> cryptography is fixed (PR #3421) -echo "deb [signed-by=/usr/share/keyrings/iiab-ansible-keyring.gpg] http://ppa.launchpad.net/ansible/ansible/ubuntu focal main" \ - > /etc/apt/sources.list.d/iiab-ansible.list +#echo "deb [signed-by=/usr/share/keyrings/iiab-ansible-keyring.gpg] http://ppa.launchpad.net/ansible/ansible/ubuntu focal main" \ +# > /etc/apt/sources.list.d/iiab-ansible.list # In future we might instead consider 'add-apt-repository ppa:ansible/ansible' # or 'apt-add-repository ppa:ansible/bionic/ansible' etc, e.g. for streamlined @@ -140,7 +148,7 @@ echo "deb [signed-by=/usr/share/keyrings/iiab-ansible-keyring.gpg] http://ppa.la # 2020-08-20: TEMP WORKAROUND (REVERT TO ANSIBLE 2.9.6) MITIGATING # iiab/iiab#2481 (Ansible 2.9.12 and 2.10.0's 666-TO-600 file permissions -# problem). This workaround installs 2.9.6-1ppa~disco onto RaspiOS, from +# problem). This workaround installs 2.9.6-1ppa~disco onto RasPiOS, from # https://launchpad.net/~ansible/+archive/ubuntu/ansible #echo "deb http://ppa.launchpad.net/ansible/ansible/ubuntu disco main" \ # > /etc/apt/sources.list.d/iiab-ansible.list @@ -152,7 +160,7 @@ echo "deb [signed-by=/usr/share/keyrings/iiab-ansible-keyring.gpg] http://ppa.la #chmod 644 /usr/share/keyrings/iiab-ansible-keyring.gpg # 2022-11-09: ansible-core 2.12.10+ PPA works on 32-bit RasPiOS, until upstream wheels -> cryptography is fixed (PR #3421) -cp /opt/iiab/iiab/scripts/iiab-ansible-keyring.gpg /usr/share/keyrings/iiab-ansible-keyring.gpg +#cp /opt/iiab/iiab/scripts/iiab-ansible-keyring.gpg /usr/share/keyrings/iiab-ansible-keyring.gpg ###echo -e 'PPA source "deb [signed-by=/usr/share/keyrings/iiab-ansible-keyring.gpg] http://ppa.launchpad.net/ansible/ansible/ubuntu '$CODENAME' main"' ###echo -e "successfully saved to /etc/apt/sources.list.d/iiab-ansible.list\n" @@ -160,10 +168,10 @@ cp /opt/iiab/iiab/scripts/iiab-ansible-keyring.gpg /usr/share/keyrings/iiab-ansi ###echo -e 'ENSURE ANSIBLE UPDATES CLEANLY: (then re-run this script to be sure!)\n' ###grep '^deb .*ansible' /etc/apt/sources.list /etc/apt/sources.list.d/*.list | grep -v '^/etc/apt/sources.list.d/iiab-ansible.list:' || true # Override bash -e (instead of aborting at 1st error) -echo -e "\napt update; apt install python3-pip # Also installs 'python3-setuptools' and 'python3' etc" +#echo -e "\napt update; apt install python3-pip # Also installs 'python3-setuptools' and 'python3' etc" #echo -e "https://github.com/iiab/iiab/blob/master/scripts/ansible.md\n" -$APT_PATH/apt update -$APT_PATH/apt -y install python3-pip +#$APT_PATH/apt update +#$APT_PATH/apt -y install python3-pip # 2021-07-29: # 'python3-packaging' dropped for now @@ -179,17 +187,104 @@ $APT_PATH/apt -y install python3-pip #$APT_PATH/apt -y --allow-downgrades install ansible-core -if uname -m | grep -q 64; then - # 2021-10-30: Using pip is messy, leaving behind cached files, so turn off pip - # cache system-wide before installing: - # https://stackoverflow.com/questions/9510474/removing-pips-cache/61762308#61762308 - # https://github.com/iiab/iiab/pull/3022 - pip3 config --global set global.no-cache-dir false - echo -e "\n\n'pip3 install --upgrade ansible-core' will now run:\n" - pip3 install --upgrade ansible-core # ansible-core 2.12 (released 2021-11-08) requires Python >= 3.8 +# 2021-10-30: Using pip is messy, leaving behind cached files, so turn off pip +# cache system-wide before installing: +# https://stackoverflow.com/questions/9510474/removing-pips-cache/61762308#61762308 +# https://github.com/iiab/iiab/pull/3022 +#pip3 config --global set global.no-cache-dir false + +#if ! uname -m | grep -q 64; then + # echo "2022-11-09: ansible-core 2.12.10+ PPA works on 32-bit RasPiOS, using /etc/apt/sources.list.d/iiab-ansible.list, until upstream wheels -> cryptography is fixed (PR #3421)" + # $APT_PATH/apt -y --allow-downgrades install ansible-core +# echo -e "\n\n'pip3 install cryptography==39.0.2' will now run:\n" +# pip3 install --break-system-packages cryptography==39.0.2 || pip3 install cryptography==39.0.2 # PR #3459 https://www.piwheels.org/project/cryptography/ -- WAS 37.0.4 which as of 2023-01-06 was the "latest compatible with ansible-core available via piwheels.org" +#fi + +#echo -e "\n\n'pip3 install --upgrade ansible-core' will now run:\n" # REMINDER: ansible-core 2.12 (released 2021-11-08) requires Python >= 3.8 +#pip3 install --break-system-packages --upgrade ansible-core || pip3 install --upgrade ansible-core # PR #3493: Revert to old syntax if pip < 23.0.1, as flag --break-system-packages (for Python 3.11+ / PEP 668) is brand new in Feb 2023: https://github.com/pypa/pip/pull/11780 + +echo -e "\napt update; apt install python3-venv" +$APT_PATH/apt update +$APT_PATH/apt -y install python3-venv + +# 2023-09-08 PR #3634: 'apt install ansible-core' is overweight, but works on +# "32-bit" RasPiOS 12 (@EMG70 set 'arm_64bit=0' in /boot/config.txt per #3516 +# to force boot its 32-bit kernel; its 64-bit kernel should work too!) +# IN SHORT: This ugly hack appears sufficient for all "32-bit" Bookworm+ OS's +# (similar to 32-bit Debian 12 on AMD/Intel a month ago, i.e. PR #3617). +# 2023-09-10 PR #3637: Even safer test than querying for Debian 12+ -- verify +# that apt package ansible-core is truly available: +#if ! dpkg --print-architecture | grep -q 64 && apt-cache show ansible-core > /dev/null; then +#if ! dpkg --print-architecture | grep -q 64 && ! grep -q ^11 /etc/debian_version; then +# 2023-09-10 PR #3632: Revert above #3634 and #3637 trying /etc/pip.conf w/ cryptography 41.0.3 +if [[ $(dpkg --print-architecture) == "i386" ]] && apt-cache show ansible-core > /dev/null; then + # 2023-08-10 #3613/#3615/#3617: apt-not-pip kludge for legacy 32-bit i386 + # (DEBIAN 12+ ETC) avoids #3547 rust/wheels/cryptography compiling mess! + $APT_PATH/apt -y install ansible-core # Bookworm ~= ansible-core 2.14.3 else - echo "2022-11-09: ansible-core 2.12.10+ PPA works on 32-bit RasPiOS, using /etc/apt/sources.list.d/iiab-ansible.list, until upstream wheels -> cryptography is fixed (PR #3421)" - $APT_PATH/apt -y --allow-downgrades install ansible-core + # 2023-03-22: OS's like Ubuntu 23.04 and Debian 12 (e.g. with Python 3.11+) ask + # that virtual environments (venv) be used to safely isolate pip installs: + # https://peps.python.org/pep-0668 + + # 2023-09-08: NEW WAY ANSIBLE RECOMMENDS? https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html + # $APT_PATH/apt -y install pipx # Typically adds 50+ packages! + # pipx install ansible-core + # pipx ensurepath # Adds /root/.local/bin to $PATH -- next time you open a shell -- e.g. for /root/.local/bin/ansible -> /root/.local/pipx/venvs/ansible-core/bin/ansible + # Or, to install package globally for multi-user access: (pypa/pipx#754) + # PIPX_HOME=/opt/pipx PIPX_BIN_DIR=/usr/local/bin pipx install ansible-core + + # 2023-10-11: RasPiOS Bookworm doc for Python with venv (PEP 668 now enforced!) + # https://www.raspberrypi.com/documentation/computers/os.html#python-on-raspberry-pi + # https://www.raspberrypi.com/documentation/computers/os.html#using-pip-with-virtual-environments + + echo -e "\nCreate virtual environment for Ansible" + python3 -m venv /usr/local/ansible + + # 2023-09-10: Work around #3526 "32-bit" RasPiOS 12 pre-release issue... + # 'Package issue: cryptography 41.0.3 leads to cffi 1.15.1 failure on + # "32-bit" Raspberry Pi OS [REASON: /etc/pip.conf missing on some Bookworm + # pre-releases' == https://github.com/piwheels/packages/issues/390 + if ! [ -f /etc/pip.conf ] && [ -f /etc/rpi-issue ]; then + cat > /etc/pip.conf << EOF +[global] +extra-index-url=https://www.piwheels.org/simple +EOF + fi + + # "if not ubuntu" (covers RasPiOS & Debian) would also work, but is overbroad: + # if ! grep -qi ubuntu /etc/os-release; then + # + # if [ -f /etc/rpi-issue ] && [[ $(dpkg --print-architecture) == armhf ]]; then + # + # 2023-03-24 #3547 similar to #3459 re: cryptography, piwheels, rust. + # Release problems chart: https://www.piwheels.org/project/cryptography/ + # if ! dpkg --print-architecture | grep -q 64; then # 32-bit in general! + # 2023-09-07: Commenting out cryptography 40.0.1 below, as @EMG70 evaluates + # new upstream piwheels fix (e.g. cryptography 41.0.3 for now) + # on pre-release 32-bit RasPiOS 12... (#3526) + # if [[ $(dpkg --print-architecture) == armhf ]]; then # 32-bit ARM + # # 2023-09-30: cryptography 40.0.1 and 41.0.4 both fail for now, see #3650 + # $APT_PATH/apt -y install libffi-dev python3-dev + # /usr/local/ansible/bin/python3 -m pip install cryptography==41.0.3 + # # else + # # 2023-08-10: 'apt install rustc pkg-config libssl-dev' was not enough! + # # So we use apt to install cryptography 38.0.4 for Debian 12.1 -- where + # # `dpkg --print-architecture` was i386 and `uname -m` was i686: + # # $APT_PATH/apt -y install python3-cryptography + # fi + + # 2023-05-22: 2.14.6 was better than 2.15.0 for FreePBX (#3588, ansible/ansible#80863) + # 2023-10-01 #3650: --prefer-binary or --only-binary ensure you get wheels, + # even if they're not the very latest release -- thereby avoiding compiling + # messes -- and obviating the need for these 2: (above, both commented out) + # - 'apt -y install libffi-dev python3-dev' + # - painstaking pinning of cryptography or cffi (etc) to older version #s + /usr/local/ansible/bin/python3 -m pip install --prefer-binary --upgrade ansible-core + echo -e "\nCreate symlinks /usr/local/bin/ansible* -> /usr/local/ansible/bin/ansible*" + cd /usr/local/ansible/bin + for bin in ansible*; do + ln -sf /usr/local/ansible/bin/"$bin" /usr/local/bin/"$bin" + done fi # (Re)running collection installs appears safe, with --force-with-deps to force @@ -213,7 +308,7 @@ ansible-galaxy collection install --force-with-deps \ echo -e "\n\nSUCCESS! PLEASE VERIFY ANSIBLE WITH COMMANDS LIKE:\n" echo -e " ansible --version" -echo -e " pip3 show ansible-core" +echo -e " /usr/local/ansible/bin/pip3 show ansible-core" echo -e ' apt -a list "ansible*"' -echo -e " ansible-galaxy collection list\n" -echo -e "WARNING: Start a new Linux shell, if it changed from /usr/bin to /usr/local/bin\n\n" +echo -e " ansible-galaxy collection list\n\n" +#echo -e "WARNING: Start a new Linux shell, if it changed from /usr/bin to /usr/local/bin\n\n" diff --git a/scripts/iiab-diagnostics b/scripts/iiab-diagnostics index 7361e5621..193ba4fc7 100755 --- a/scripts/iiab-diagnostics +++ b/scripts/iiab-diagnostics @@ -49,11 +49,11 @@ function cat_file_raw() { # $1 = path/filename; $2 = # of lines, for tail elif [ $# -eq 1 ]; then echo >> $outfile # Redact (mask) most passwords from /etc/iiab/local_vars.yml, /etc/hostapd/hostapd.conf, /etc/wpa_supplicant/wpa_supplicant.conf, /etc/netplan/*, /etc/network/interfaces, /etc/network/interfaces.d/*, /etc/NetworkManager/system-connections/* ETC -- not much to worry about in /etc/iiab/iiab.ini (' = ') - cat "$1" | sed 's/^\(\s*[[:alnum:]#_-]*\(psk\|passphrase\|password\|wep-key[0-3]\):\).*/\1 [REDACTED]/; s/^\(\s*[[:alnum:]#_-]*\(psk\|passphrase\|password\|wep-key[0-3]\)[= \t]\).*/\1[REDACTED]/' | iconv -t UTF-8//IGNORE >> $outfile + sed 's/^\(\s*[[:alnum:]#_-]*\(psk\|passphrase\|password\|wep-key[0-3]\):\).*/\1 [REDACTED]/; s/^\(\s*[[:alnum:]#_-]*\(psk\|passphrase\|password\|wep-key[0-3]\)[= \t]\).*/\1[REDACTED]/' "$1" | iconv -t UTF-8//IGNORE | cat -v >> $outfile else # e.g. last 100 lines, maximum echo " ...ITS LAST $2 LINES FOLLOW..." >> $outfile echo >> $outfile - tail -$2 "$1" | sed 's/^\(\s*[[:alnum:]#_-]*\(psk\|passphrase\|password\|wep-key[0-3]\):\).*/\1 [REDACTED]/; s/^\(\s*[[:alnum:]#_-]*\(psk\|passphrase\|password\|wep-key[0-3]\)[= \t]\).*/\1[REDACTED]/' | iconv -t UTF-8//IGNORE >> $outfile + tail -$2 "$1" | sed 's/^\(\s*[[:alnum:]#_-]*\(psk\|passphrase\|password\|wep-key[0-3]\):\).*/\1 [REDACTED]/; s/^\(\s*[[:alnum:]#_-]*\(psk\|passphrase\|password\|wep-key[0-3]\)[= \t]\).*/\1[REDACTED]/' | iconv -t UTF-8//IGNORE | cat -v >> $outfile fi echo >> $outfile elif [ -h "$1" ]; then @@ -101,19 +101,27 @@ function cat_cmd() { # $1 = command + params, $2 = explanation spc_params=$(echo "$1" | sed 's/^\s*\S\S*\s*/ /;s/\s*$//') # Drop command on left; Keep a single space + params on right; RTrim #spc_params=$(echo "$1" | sed 's/^\s*\S*//;s/\s*$//;s/^\s\s*/ /') # LTrim + drop original path + command on left; RTrim; Compress whitespace in between #spc_params=$(echo "$1" | sed 's/^[[:blank:]]*[^[:blank:]]*//;s/[[:blank:]]*$//;s/^[[:blank:]][[:blank:]]*/ /') # Equivalent (POSIX compliant) - if [[ $2 == "" ]]; then - echo "COMMAND: $path_cmd$spc_params" >> $outfile + if [[ $path_cmd == "" ]]; then + if [[ $2 == "" ]]; then + echo "COMMAND: $1" >> $outfile + else + echo "COMMAND: $1 # $2" >> $outfile + fi else - echo "COMMAND: $path_cmd$spc_params # $2" >> $outfile + if [[ $2 == "" ]]; then + echo "COMMAND: $path_cmd$spc_params" >> $outfile + else + echo "COMMAND: $path_cmd$spc_params # $2" >> $outfile + fi fi echo >> $outfile if [[ $path_cmd == "" ]]; then echo "COMMAND NOT FOUND: $1" >> $outfile else - bash -c "$1" >> $outfile # Works with | (pipes) and 'ls -l /lib/firmware/brcm/*43455*' etc! - #(exec $1 >> $outfile) # Works with | (pipes) and 'ls -l /lib/firmware/brcm/*43455*' etc! Subshell needed (parens) as exec then exits entire shell. + bash -c "$1" >> $outfile # Works with | (pipes) and 'ls -l /lib/firmware/cypress/*43455*' etc! + #(exec $1 >> $outfile) # Works with | (pipes) and 'ls -l /lib/firmware/cypress/*43455*' etc! Subshell needed (parens) as exec then exits entire shell. #eval $1 >> $outfile # Should be identical to below, i.e. insufficient -- "eval" combine ARGs into a single string. - #$(echo "eval $1") >> $outfile # "eval" works with | (pipes) per https://stackoverflow.com/a/7184782 BUT globbing like 'ls -l /lib/firmware/brcm/*43455*' FAILS to output lines w/ filenames that contain spaces (ugly IFS issues!) + #$(echo "eval $1") >> $outfile # "eval" works with | (pipes) per https://stackoverflow.com/a/7184782 BUT globbing like 'ls -l /lib/firmware/cypress/*43455*' FAILS to output lines w/ filenames that contain spaces (ugly IFS issues!) fi echo >> $outfile } @@ -132,7 +140,7 @@ echo "This is: $outfile" >> $outfile echo >> $outfile echo -e "\n\n\n0. HW + SW Quick Summary" >> $outfile echo >> $outfile -/opt/iiab/iiab/scripts/iiab-summary >> $outfile +/opt/iiab/iiab/scripts/iiab-summary | iconv -t UTF-8//IGNORE | cat -v >> $outfile # Make odd chars visible, just in case (e.g. dpaste.com pastebin disallows null chars) if [ -f /etc/rpi-issue ]; then echo "stage2 = Raspberry Pi OS Lite" >> $outfile echo "stage4 = Raspberry Pi OS with desktop" >> $outfile @@ -145,6 +153,7 @@ if [ -s /tmp/iiab-apps-to-be-installed ]; then cat /tmp/iiab-apps-to-be-installed >> $outfile echo >> $outfile fi +cat_cmd 'ls -ltr /etc/iiab/install-flags' 'IIAB install flags' echo -e '\n 1. Files Specially Requested: (from "iiab-diagnostics PATH/FILE1 PATH/FILE2")\n' echo -e '\n\n\n1. FILES SPECIALLY REQUESTED (FROM "iiab-diagnostics PATH/FILE1 PATH/FILE2")\n' >> $outfile @@ -153,20 +162,24 @@ for f in "$@"; do done if [ $# -eq 0 ]; then - echo -e " 2. Regular Files:\n" + echo -e " 2. Regular Files etc:\n" else - echo -e "\n 2. Regular Files:\n" + echo -e "\n 2. Regular Files etc:\n" fi -echo -e "\n\n\n2. REGULAR FILES\n" >> $outfile +echo -e "\n\n\n2. REGULAR FILES ETC\n" >> $outfile #cat_file /dev/sda # Device "file" test #cat_file /nonsense # Non-existence test #cat_file /opt/iiab/iiab # Directory test #cat_file /tmp/empty-file # Empty file test #cat_file /usr/bin/iiab-support-on # Symlink test cat_file /.iiab-image +cat_file /etc/default/locale # e.g. on Debian 12 +cat_file /etc/locale.conf # e.g. on Debian 13+ and Ubuntu +cat_cmd 'localectl' 'Locale settings' +cat_cmd 'locale -a' 'Available locales' cat_file /etc/iiab/iiab.env cat_file /etc/iiab/iiab.ini -cat_file /etc/iiab/local_vars.yml # Redacts most passwords above +cat_file /etc/iiab/local_vars.yml # Redacts most passwords above cat_file /etc/iiab/iiab_state.yml cat_file /etc/resolv.conf cat_file /etc/network/interfaces @@ -192,13 +205,16 @@ cat_dir /etc/netplan # Redacts most passwords above echo -e "\n 4. Output of Commands:\n" echo -e "\n\n\n\n4. OUTPUT OF COMMANDS\n" >> $outfile cat_cmd 'uname -a' 'Linux kernel' +cat_cmd 'sudo dmesg | grep -i "command line:"' 'Kernel boot parameters' cat_cmd 'free' 'RAM memory' cat_cmd 'lscpu' 'CPU details' +cat_cmd 'rpi-eeprom-update' 'RPi Bootloader EEPROM' cat_cmd 'df -h' 'Disk usage' cat_cmd 'df -ah' 'Disk usage detail' cat_cmd 'lsblk' 'Partition mount points' cat_cmd 'blkid' 'Mount point details' cat_file /etc/fstab +cat_cmd 'lshw -C network' 'Network hardware/interfaces' cat_cmd 'ip addr' 'Network interfaces' cat_cmd 'ifconfig' 'Network interfaces (old view)' cat_cmd 'ip route' 'Routing table' @@ -217,14 +233,26 @@ cat_cmd 'iw list' 'List capabilities of all wireless devices' cat_cmd 'systemctl status hostapd' 'Downstream Wi-Fi: Is hostapd running?' cat_cmd 'ls -l /etc/wpa_supplicant' 'Upstream Wi-Fi' cat_cmd 'ps -AH' 'Process hierarchy: staging of hostapd & wpa_supplicant?' -#cat_cmd 'dmesg | grep brcm' 'Diagnostic messages: RPi Wi-Fi firmware' -cat_cmd 'dmesg | grep -i -e 80211 -e 802\.11 -e wireless -e wifi -e wlan -e broadcom -e brcm -e bcm -e realtek | head -100' 'Wi-Fi firmware/driver msgs' +cat_cmd 'sudo journalctl -b | grep wpa_supplicant' 'wpa_supplicant log since boot' +cat_cmd 'sudo journalctl -b | grep NetworkManager | head -100' 'NetworkManager log since boot' +#cat_cmd 'sudo dmesg | grep brcm' 'Diagnostic messages: RPi Wi-Fi firmware' +cat_cmd 'sudo dmesg | grep Firmware:' '(Wi-Fi) firmware boot diagnostics' +cat_cmd 'ls -l /lib/firmware/cypress/*43430*' 'WiFi firmware for: RPi Zero W, Zero 2 W & 3' +cat_cmd 'ls -l /lib/firmware/cypress/*43455*' 'WiFi firmware for: RPi 3 B+, 4, 5 & 500' +cat_cmd 'sudo dmesg | grep -i -e 80211 -e 802\.11 -e wireless -e wifi -e wlan -e broadcom -e brcm -e bcm -e realtek | head -100' 'Wi-Fi firmware/driver msgs' cat_cmd 'lspci -nn' 'Devices on PCI buses' -cat_cmd 'ls -l /lib/firmware/brcm/*43430*' 'RPi Zero W & 3 WiFi firmware' -cat_cmd 'ls -l /lib/firmware/brcm/*43455*' 'RPi 3 B+ & 4 WiFi firmware' cat_cmd 'env' 'Environment variables' +cat_cmd 'node -v' 'Node.js version' +cat_cmd 'npm -v' 'npm version' cat_cmd '/opt/iiab/kiwix/bin/kiwix-serve --version' 'kiwix-tools' -cat_cmd 'journalctl -t IIAB-CMDSRV' 'Admin Console CMDSRV log' +cat_cmd 'cd /usr/local/calibre-web-py3; sudo git log --graph --oneline --decorate | head -50' 'Calibre-Web version' +cat_cmd 'sudo lb --version' 'xklb version' +cat_cmd 'sudo yt-dlp --version' 'yt-dlp version' +cat_cmd 'systemctl status calibre-web' 'Is Calibre-Web running?' +cat_cmd 'sudo journalctl -u calibre-web | tail -100' 'Calibre-Web systemd log' +cat_tail /var/log/calibre-web.log 100 +cat_tail /var/log/xklb.log 300 +cat_cmd 'sudo journalctl -t IIAB-CMDSRV' 'Admin Console CMDSRV log' #cat_cmd 'ansible localhost -m setup 2>/dev/null' 'All Ansible facts' # For cleaner scraping of Ansible vars, consider "./runrole all-vars /tmp/all-ansible-vars" 27-31 lines above? echo -e "\n 5. Firewall Rules:\n" @@ -262,12 +290,15 @@ echo echo -e "\e[1m" #if [ "$ans" == "" ] || [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then if ! [[ $ans =~ ^[nNqQ]$ ]]; then - echo -ne "PUBLISHING TO URL... " - #pastebinit -b dpaste.com < $outfile - pastebinit -b sprunge.us < $outfile # Run 'pastebinit -l' to list other possible pastebin site URLs + echo -ne "PUBLISHING TO URL... " # Run 'pastebinit -l' to list other possible pastebin site URLs. ASIDE: Quirky pastebin-like https://temp.sh can sometimes work (like a file transfer service) for larger files. + pastebinit -b paste.centos.org $outfile # 2024-08-10: Basic line numbers & "4 weeks" good enough? + #nc termbin.com 9999 < $outfile # 2024-08-10: No line numbers & limited to 7 days (rudimentary but reliable option if nec in future?!) + #pastebinit -b dpaste.com $outfile # 2024-08-10: Unfortunately limited to 30 days by default. Claims 1,000,000 character maximum pastebin size (or usage quota within N days?) But newly restricted to LESS THAN 500 LINES (e.g. after IP address blocks & email appeals kinda work, but take almost 24h each time!) + #pastebinit -b sprunge.us $outfile # Stopped working for many weeks (mid-2023, and again in mid-2024) + #pastebinit -b paste2.org $outfile # Spammy/dangerous pastebins else echo -e "If you later decide to publish it, run:" echo - echo -e " pastebinit -b sprunge.us < $outfile" + echo -e " pastebinit -b paste.centos.org $outfile" fi echo -e "\e[0m" diff --git a/scripts/iiab-diagnostics.README.md b/scripts/iiab-diagnostics.README.md index be341bb4f..7c064b757 100644 --- a/scripts/iiab-diagnostics.README.md +++ b/scripts/iiab-diagnostics.README.md @@ -55,7 +55,7 @@ But first off, the file is compiled by harvesting 1 + 6 kinds of things: Or, you can later/manually upload it using the ``pastebinit`` command: ``` - pastebinit -b sprunge.us < /etc/iiab/diag/NEW-FILE-NAME + pastebinit -b dpaste.com /etc/iiab/diag/NEW-FILE-NAME ``` Either way, this will generate an actual web link (URL). @@ -64,8 +64,6 @@ But first off, the file is compiled by harvesting 1 + 6 kinds of things: Include a description of the symptoms, and how to reproduce the problem. -4. If you don't understand Step 3, email everything to bugs@iiab.io instead. - ## Source Code -Please look over the bottom of [iiab-diagnostics](iiab-diagnostics) (lines 127-245 especially) to learn more about which common IIAB files and commands make this rapid troubleshooting possible. +Please look over the bottom of [iiab-diagnostics](iiab-diagnostics) (lines 135-273 especially) to learn more about which common IIAB files and commands make this rapid troubleshooting possible. diff --git a/scripts/iiab-item-size.py b/scripts/iiab-item-size.py new file mode 100755 index 000000000..6e1261ba3 --- /dev/null +++ b/scripts/iiab-item-size.py @@ -0,0 +1,183 @@ +#!/usr/bin/python3 +# Auto-calculate IIAB + EduPack disk space needs, in advance [& design review] +# https://github.com/iiab/iiab/pull/3594 + +import os, sys, syslog +from datetime import date +import pwd, grp +import shutil +import argparse +import sqlite3 +import iiab.iiab_lib as iiab +import iiab.adm_lib as adm +import requests +import json + +all_menu_defs = adm.get_all_menu_defs() + +def main(): + parser = argparse.ArgumentParser(description="Get size for item.") + parser.add_argument("name", help="Name item.") + + # menu_dir + args = parser.parse_args() + + name = args.name + + content= get_item_size(name) + + #print('size: ',iiab.human_readable(content["size"])) + print(f'content ', content) + + sys.exit() + +def get_zims_size_from_header(url): + #url = 'https://download.kiwix.org/zim/other/mdwiki_en_all_2023-03.zim' + response = requests.head(url, allow_redirects=True) + size = 0 + if (response.status_code == 200): + size = int(response.headers.get('Content-Length', 0)) + return size + +def get_zims_size_from_file(name): + data_output = {} + data_output['download_url']= '' + data_output['size'] = 0 + + with open('/etc/iiab/kiwix_catalog.json') as json_file: + data = json.load(json_file)['zims'] + result = { data[element]['perma_ref']: data[element] for element in list(data.keys())} + if result.get(name) is not None: + data_output['download_url']= result[name]['download_url'] + data_output['size']= (int(result[name].get('size',0)) * 1024) + 1023 + return data_output + +def get_zims_size(name): + data = get_zims_size_from_file(name) + #if data['size'] <= 1023: + # data['size'] = get_zims_size_from_header(data['download_url']) + return data + +def get_oer2go_size_from_file(name): + data_output = {} + data_output['download_url']= '' + data_output['size'] = 0 + + with open('/etc/iiab/oer2go_catalog.json') as json_file: + data = json.load(json_file)['modules'] + if data.get(name) is not None: + data_output['download_url']= data[name]['rsync_url'] + data_output['size']= (int(data[name].get('ksize',0)) * 1024) + 1023 + return data_output + +def get_map_size_from_file(name): + data_output = {} + data_output['download_url']= '' + data_output['size'] = 0 + + with open('/etc/iiab/map-catalog.json') as json_file: + data = json.load(json_file)['base'] + result = { data[element]['perma_ref']: data[element] for element in list(data.keys())} + if result.get(name) is not None: + data_output['download_url']= result[name]['archive_url'] + data_output['size']= (int(result[name].get('size',0))) + 1023 + return data_output + + +def get_item_size(name_input): + return [get_size(element) for element in [name_input]] + +def get_items_size(name_input): + return [get_size(element) for element in name_input] + +def element_unknown(name): + return {"size":0} + +def build_otput(name, type_element, function): + data = function(name) + if data['size']== 0: + print(name, ": the size of this",type_element,"element is unknown") + + return { + "name": name + ,"type": type_element + ,"size": data['size'] + } + + +intended_use_dict = { + "azuracast":{ + "name":"name" + ,"type":"azuracast" + ,"function":element_unknown + } + ,"calibre":{ + "name":"name" + ,"type":"calibre" + ,"function":element_unknown + } + ,"external":{ + "name":"name" + ,"type":"external" + ,"function":element_unknown + } + ,"html":{ + "name":"moddir" + ,"type":"module" + ,"function":get_oer2go_size_from_file + } + ,"info":{ + "name":"name" + ,"type":"info" + ,"function":element_unknown + } + ,"internetarchive":{ + "name":"name" + ,"type":"internetarchive" + ,"function":element_unknown + } + ,"kalite":{ + "name":"name" + ,"type":"kalite" + ,"function":element_unknown + } + ,"kolibri":{ + "name":"name" + ,"type":"kolibri" + ,"function":element_unknown + } + ,"map":{ + "name":"name" + ,"type":"map" + ,"function":get_map_size_from_file + } + ,"webroot":{ + "name":"name" + ,"type":"webroot" + ,"function":element_unknown + } + ,"zim":{ + "name":"zim_name" + ,"type":"zim" + ,"function":get_zims_size + } +} + + +def get_size(name_input): + if name_input in all_menu_defs: + info = all_menu_defs[name_input] + intended_use = info["intended_use"] + + try: + data_intend = intended_use_dict[intended_use] + name_element = info[data_intend["name"]] + return build_otput(name_element, data_intend["type"], data_intend["function"]) + except: + pass + + return build_otput(name_input, "unknown", element_unknown) + +# Now start the application +if __name__ == "__main__": + main() diff --git a/scripts/iiab-network b/scripts/iiab-network old mode 100644 new mode 100755 diff --git a/scripts/iiab-root-login b/scripts/iiab-root-login new file mode 100755 index 000000000..2d968e857 --- /dev/null +++ b/scripts/iiab-root-login @@ -0,0 +1,60 @@ +#!/bin/bash -e +# "-e" tries to exit right away on error. + +# Enable (and set!) root login password for ssh and sftp. +# To help everyday IIAB implementers upload content with FileZilla: +# https://wiki.iiab.io/go/FAQ#How_do_I_add_my_own_content%3F + +# AT YOUR OWN RISK. If this absolutely must be run non-interactively, use: +# sudo iiab-root-login + +if [ ! -f /etc/ssh/sshd_config ]; then + echo -e '\n\e[41;1mERROR: /etc/ssh/sshd_config is missing (is openssh-server installed?)\e[0m\n' + exit 1 +fi + +if ! systemctl is-active ssh > /dev/null; then + echo -e "\n\e[41;1mERROR: ssh service is not active (run 'systemctl status ssh' ?)\e[0m\n" + exit 1 +fi + +if [ $# -eq 0 ]; then + echo -e '\n\e[1;33mPICK A STRONG PASSWORD TO PROTECT YOUR IIAB!\e[0m' + echo -en '\nWhat ssh and sftp password do you want for user "root" ? ' + read ans < /dev/tty +else + ans=$1 + echo +fi + +if [[ $ans == "" ]]; then + echo -e '\n\e[41;1mEXITING: User "root" cannot have an empty password.\e[0m\n' + exit 1 +else + echo root:"$ans" | chpasswd + echo -e 'Password changed, for user "root".\n' +fi + +# Comment out problematic line(s) in file(s) like... +# /etc/ssh/sshd_config.d/60-cloudimg-settings.conf +# ...that appear in Multipass VMs, etc: +sed -i 's/^PermitRootLogin[[:blank:]].*/# &/' /etc/ssh/sshd_config.d/* || true +sed -i 's/^PasswordAuthentication[[:blank:]].*/# &/' /etc/ssh/sshd_config.d/* || true + +if grep -q '^PermitRootLogin[[:blank:]]' /etc/ssh/sshd_config; then + sed -i 's/^PermitRootLogin[[:blank:]].*/PermitRootLogin yes/' /etc/ssh/sshd_config +else + echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config +fi + +if grep -q '^PasswordAuthentication[[:blank:]]' /etc/ssh/sshd_config; then + sed -i 's/^PasswordAuthentication[[:blank:]].*/PasswordAuthentication yes/' /etc/ssh/sshd_config +else + echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config +fi + +if systemctl reload ssh; then + echo -e '\e[44;1mUser "root" can now upload to IIAB using FileZilla!\e[0m\n' +else + echo -e '\e[41;1mERROR: Unable to reload ssh service.\e[0m\n' +fi diff --git a/scripts/iiab-size.py b/scripts/iiab-size.py new file mode 100755 index 000000000..c44e7034b --- /dev/null +++ b/scripts/iiab-size.py @@ -0,0 +1,45 @@ +#!/usr/bin/python3 +# Auto-calculate IIAB + EduPack disk space needs, in advance [& design review] +# https://github.com/iiab/iiab/pull/3594 + +import os, sys, syslog +from datetime import date +import pwd, grp +import shutil +import argparse +import sqlite3 +import iiab.iiab_lib as iiab +import iiab.adm_lib as adm +import requests +import json +import importlib +from functools import reduce +iiab_item_size = importlib.import_module("iiab-item-size") + +def main(): + parser = argparse.ArgumentParser(description="Read menu file for get size.") + parser.add_argument("menuFile", help="Is the menu file.") + # menu_dir + args = parser.parse_args() + + menu_file = args.menuFile + if not os.path.exists(menu_file): + print('Menu file ' + menu_file + ' not found.') + exit(1) + + total_size= content_from_menu(menu_file) + + print('total: ',iiab.human_readable(total_size)) + print(f'total (bytes): ', total_size) + + sys.exit() + +def content_from_menu(menu_file): + menu = adm.read_json(menu_file) + items = iiab_item_size.get_items_size(menu["menu_items_1"]) + total_size = reduce(lambda accumulator,item: accumulator+int(item['size']), items, 0) + return total_size + +# Now start the application +if __name__ == "__main__": + main() diff --git a/scripts/iiab-summary b/scripts/iiab-summary index 2e1da90a7..73bcc9693 100755 --- a/scripts/iiab-summary +++ b/scripts/iiab-summary @@ -64,10 +64,10 @@ else echo "$(cat /etc/issue.net) $(cat /etc/debian_version)" fi echo "display-manager? $(systemctl is-active display-manager.service) Arch1: $(dpkg --print-architecture) Arch2: $(dpkg --print-foreign-architectures)" -uname -rvp +uname -nrvm echo "$(lscpu | grep '^Model name:' | sed 's/^Model name:\s*//') $(lscpu | grep '^CPU(s):' | tr -s ' ') "$(free -m | tail -2 | tr -s ' ' | cut -d' ' -f1-2) if [ -f /proc/device-tree/model ]; then - cat /proc/device-tree/model ; echo # MORE RPi DETAIL: tail -4 /proc/cpuinfo + cat /proc/device-tree/model | tr -d '\000' ; echo # dpaste.com pastebin doesn't allow null chars! MORE RPi DETAIL: tail -4 /proc/cpuinfo fi if [ -f /sys/class/thermal/thermal_zone0/temp ]; then echo "Temperature(s): "$(cat /sys/class/thermal/thermal_zone*/temp) # Prettier if avail: vcgencmd measure_temp @@ -79,8 +79,14 @@ echo /opt/iiab/iiab/scripts/iiab-apps-to-be-installed > /dev/null echo "$(df -h /) ZIMs: $(ls /library/zims/content/ | wc -l) OER2Go: $(ls /library/www/html/modules/ | wc -l) Apps2B: $(cat /tmp/iiab-apps-to-be-installed | wc -l)" echo +#grep "^openvpn_handle:" /etc/iiab/local_vars.yml +#grep "^tailscale_installed:" /etc/iiab/iiab_state.yml +#if [[ $(command -v /usr/bin/tailscale) ]]; then +if tailscale ip &> /dev/null; then + #echo "VPN: $(tailscale ip) $(tailscale whois --json $(tailscale ip -1) | jq -r .Node.Tags[])" + echo "VPN: $(tailscale ip) $(tailscale status --json | jq -r .Self.Tags[])" +fi echo $(ip -o link show | awk -F': ' '{print $2}') # Better order than: ls -rt /sys/class/net -grep "^openvpn_enabled:" /etc/iiab/local_vars.yml -grep "^openvpn_handle:" /etc/iiab/local_vars.yml +echo $(echo $(hostname -A) $(hostname -a) | xargs -n1 | sort | uniq) hostname -I echo diff --git a/scripts/iiab-update b/scripts/iiab-update new file mode 100755 index 000000000..2e3f9e4f3 --- /dev/null +++ b/scripts/iiab-update @@ -0,0 +1,148 @@ +#!/bin/bash -e +# "-e" tries to exit right away on error. + +# Upgrade IIAB core software (apt updates, Ansible, Admin Console, etc). + +# Also with a focus on upgrading IIAB Calibre-Web, if that's installed: +# https://github.com/iiab/calibre-web/wiki + +# 2024-07-18 fixes underway, thanks to: +# https://stackoverflow.com/questions/21096478/overwrite-executing-bash-script-files +# https://stackoverflow.com/questions/2285403/how-to-make-shell-scripts-robust-to-source-being-changed-as-they-run +# https://stackoverflow.com/questions/2336977/can-a-shell-script-indicate-that-its-lines-be-loaded-into-memory-initially + +{ + if [[ $(id -un) != "root" ]]; then + echo -e "\nPlease run: sudo iiab-update\n" + exit 1 + fi + + if [[ $1 == "-f" || $1 == "--fast" ]]; then + echo -e "\n\n\e[44;1mAttempting a FAST upgrade of IIAB Calibre-Web...\e[0m\n" + echo -e "\n\e[33m'iiab-update -f' DOES NOT apply apt updates.\e[0m" + else + echo -e "\n\n\e[44;1mUpgrading IIAB core software: (apt updates, Ansible, Admin Console, etc)\e[0m\n" + echo -e "\n\e[44;1mOr try 'iiab-update -f' for a FAST upgrade of IIAB Calibre-Web!\e[0m\n\n" + echo -e "\e[4mNow running: apt update\e[0m\n" + apt update + echo -e "\n\e[4mNow running: apt dist-upgrade -y\e[0m\n" + apt dist-upgrade -y + echo -e "\n\e[4mNow running: apt autoremove -y\e[0m\n" + apt autoremove -y + fi + + cd /opt/iiab/iiab + if [[ $(git branch --show-current) != "master" || $(git status --porcelain --untracked-files=no) != "" ]]; then # Permit detritus, e.g. untracked files like adm-run-roles-tmp.yml + echo -e "\n\n\e[41;1mIn /opt/iiab/iiab, (1) 'git branch' MUST show current branch 'master' and (2) 'git status' must show NO MODIFIED FILES.\e[0m\n\n" + exit 1 + fi + echo -e "\n\n\e[4mNow running: git pull https://github.com/iiab/iiab --no-rebase --no-edit\e[0m\n" + git pull https://github.com/iiab/iiab --no-rebase --no-edit + echo + if grep -q 'tailscale_installed: True' /etc/iiab/iiab_state.yml; then + echo -e "\e[4mNow running: cp -u roles/tailscale/templates/iiab-vpn /usr/bin\e[0m\n" + cp -u roles/tailscale/templates/iiab-vpn /usr/bin + fi + if [[ $1 == "-f" || $1 == "--fast" ]]; then # Otherwise ./runrole does it below! (as Ansible runs roles/0-init) + cd scripts + echo -e "\e[4mNow running: cp -u iiab-update iiab-summary iiab-diagnostics iiab-root-login /usr/bin\e[0m\n" + cp -u iiab-update iiab-summary iiab-diagnostics iiab-root-login /usr/bin + fi + + if [[ $1 == "-f" || $1 == "--fast" ]]; then + echo -e "\n\e[33m'iiab-update -f' DOES NOT upgrade Ansible.\e[0m\n\n" + else + echo -e "\n\n\e[4mNow running: scripts/ansible\e[0m" + scripts/ansible + fi + + if grep -q 'calibreweb_installed: True' /etc/iiab/iiab_state.yml; then + if [[ $1 == "-f" || $1 == "--fast" ]]; then + echo -e "\e[4mChecking if an older version of 'library' (formerly 'xklb') exists...\e[0m" + if pipx list | grep -q 'xklb'; then + echo -e "\e[4mOlder version 'xklb' detected. Now running: pipx uninstall xklb\e[0m" + pipx uninstall xklb + fi + echo -e "\e[4mNow running: pipx uninstall library # THIS ALSO UNINSTALLS yt-dlp\e[0m\n" + pipx uninstall library || true + echo -e "\n\e[4mNow running: pipx install library # THIS ALSO INSTALLS yt-dlp\e[0m\n" + pipx install library + echo -e "\n\e[4mNow running: yt-dlp --version\e[0m\n" + yt-dlp --version + echo -e '\n\e[4mNeed better YouTube scraping? Run this for the latest yt-dlp "nightly" release:\e[0m\n\n\e[1mpipx inject --pip-args="--upgrade --pre" -f library yt-dlp[default]\e[0m\n' + # NEED BETTER/EXPERIMENTAL YouTube SCRAPING? UNCOMMENT THE NEXT LINE: + # pipx inject --pip-args="--upgrade --pre" -f library yt-dlp[default] + # + # https://github.com/yt-dlp/yt-dlp-nightly-builds/releases + # https://pypi.org/project/yt-dlp/#history + cd /usr/local/calibre-web-py3 + if [[ $(git branch --show-current) != "master" || $(git status --porcelain --untracked-files=no) != "" ]]; then # Permit venv detritus, e.g. untracked files like these 5: bin/ include/ lib/ lib64 pyvenv.cfg + echo -e "\n\e[41;1mIn /usr/local/calibre-web-py3, (1) 'git branch' MUST show current branch 'master' and (2) 'git status' must show NO MODIFIED FILES.\e[0m\n\n" + exit 1 + fi + echo -e "\e[4mNow running: systemctl stop calibre-web\e[0m\n" + systemctl stop calibre-web + echo -e "\e[4mNow running: git pull https://github.com/iiab/calibre-web --no-rebase --no-edit\e[0m\n" + git pull https://github.com/iiab/calibre-web --no-rebase --no-edit + echo -e "\n\e[4mNow running: bin/pip install -r requirements.txt --prefer-binary\e[0m\n" + bin/pip install -r requirements.txt --prefer-binary > /dev/null + echo -e "\e[4mNow running: systemctl restart calibre-web\e[0m\n" + systemctl restart calibre-web + else + cd /opt/iiab/iiab + echo -e "\n\e[4mNow running: ./runrole --reinstall calibre-web\e[0m\n" + ./runrole --reinstall calibre-web + fi + fi + + # 2024-07-17: Run Admin Console stanza last for safety -- it failed ~50% of the + # time over 20 tests for me -- leading to 3+ different kinds of errors right + # after "(Restarting CMDSRV" e.g. "syntax error near unexpected token" was the + # most common error -- once the error was "command not found" -- and another + # time Admin Console's ./install VERY MYSTERIOUSLY RAN TWICE! + # + # Any chance this get_oer2go_catalog error ~15 lines up...might be related ? + # + # ... + # Finished writing to /etc/iiab/kiwix_catalog.json + # SUCCESS/opt/admin/cmdsrv/scripts/get_oer2go_catalog:52: SyntaxWarning: invalid escape sequence '\<' + # php_parser = re.compile('\<\?php echo .+? \?>') + # Skipping module not needed by Internet in a Box 12 en-PhET + # ... + # [ ~15 lines ] + # ... + # (Restarting CMDSRV + # ... + # [ VARIOUS ERRORS SOMETIMES HAPPEN HERE ] + + if [ -d /opt/admin ]; then + if [[ $1 == "-f" || $1 == "--fast" ]]; then + echo -e "\n\e[33m'iiab-update -f' DOES NOT upgrade Admin Console.\e[0m" + else + cd /opt/iiab/iiab-admin-console + if [[ $(git branch --show-current) != "master" || $(git status --porcelain) != "" ]]; then + echo -e "\n\n\e[41;1mIn /opt/iiab/iiab-admin-console, (1) 'git branch' MUST show current branch 'master' and (2) 'git status' must show NO MODIFIED FILES.\e[0m\n\n" + exit 1 + fi + GITHASH1=$(git rev-parse HEAD) + echo -e "\n\e[4mNow running: git pull https://github.com/iiab/iiab-admin-console --no-rebase --no-edit\e[0m\n" + git pull https://github.com/iiab/iiab-admin-console --no-rebase --no-edit + GITHASH2=$(git rev-parse HEAD) + if [[ $GITHASH1 != $GITHASH2 ]]; then + echo -e "\n\e[4mNow running: ./install\e[0m\n" + ./install + else + echo -e "\n\e[33mSkipping Admin Console './install' — as it appears up-to-date!\e[0m" + fi + fi + fi + + if [[ $1 == "-f" || $1 == "--fast" ]]; then + echo -e "\n\n\e[44;1m'iiab-update -f' COMPLETE!\e[0m\n" + echo -e "\e[44;1mIf Calibre-Web fails, please try 'iiab-update' WITHOUT '-f'\e[0m\n\n" # \e[7m == reverse video (e.g. black on white) + else + echo -e "\n\n\e[44;1miiab-update COMPLETE!\e[0m\n\n" + fi + + exit # https://stackoverflow.com/questions/2285403/how-to-make-shell-scripts-robust-to-source-being-changed-as-they-run +} diff --git a/scripts/install_python2.sh b/scripts/install_python2.sh new file mode 100755 index 000000000..b9d0d2bed --- /dev/null +++ b/scripts/install_python2.sh @@ -0,0 +1,101 @@ +#!/bin/bash +# https://packages.debian.org/search?keywords=libpython2.7-stdlib&searchon=names&suite=all§ion=all +# https://packages.debian.org/bullseye/libpython2.7-stdlib +# https://packages.ubuntu.com/search?keywords=libpython2.7-stdlib&searchon=names&suite=all§ion=all +# https://packages.ubuntu.com/jammy-updates/libpython2.7-stdlib + +# payload to be installed: +# libpython2-stdlib +# libpython2.7-minimal +# libpython2.7-stdlib +# python2-minimal +# python2.7-minimal +# python2.7 +# python2 + +export DEBIAN_FRONTEND=noninteractive +ARCH=$(dpkg --print-architecture) + +# 2023-05-19: #3573 -> PR #3582: Ubuntu 23.10's virtualenv 20.23 no longer +# supports Python 2. Root cause is virtualenv 20.22.0 (2023-04-19) which +# removed Python 2 support: https://virtualenv.pypa.io/en/latest/changelog.html +# Unfortunately older versions from Ubuntu 22.04 (#3583) & 23.04 like... +# http://launchpadlibrarian.net/651276954/virtualenv_20.19.0+ds-1_all.deb +# ...can drag in newer 20.23+ version of python3-virtualenv, leaving +# us with /usr/bin/virtualenv 20.23 once again, i.e. preventing Python 2. +# Whereas pip (which installs /usr/local/bin/virtualvenv) at least works: +# +#iif grep -qi ubuntu /etc/os-release; then # Ubuntu 23.10+ (and Mint 22+ ?) needs this. Ubuntu 23.04 tolerates it. +# apt -y install python3-pip +# pip install virtualenv==20.21.1 --break-system-packages +#else +# apt -y install virtualenv # Debian 12 & RasPiOS 12 are A-Ok with built-in virtualenv 20.17.1 (<= 20.21.1) +#fi +# +#apt -y install virtualenv +# https://github.com/iiab/iiab/pull/3535#issuecomment-1503626474 +#apt -y install media-types libffi8 libssl3 + +# libpython2.7-stdlib from ubuntu-22.04 used in amd64|arm64|armhf is compiled against libssl3 and libffi8 +# `apt info libpython2.7-stdlib` +#cd /tmp + +case $ARCH in + "amd64") + # works on U23.04 x86_64 VM + cat << EOF > /etc/apt/sources.list.d/python2.list +deb [trusted=yes] http://archive.ubuntu.com/ubuntu jammy main universe +deb [trusted=yes] http://archive.ubuntu.com/ubuntu jammy-updates main universe +EOF + ;; + + "arm64") + # gave 404 errors on U23.04 x86_64 VM need to circle back to U23.04 arm64 and confirm + cat << EOF > /etc/apt/sources.list.d/python2.list +deb [trusted=yes] http://ports.ubuntu.com/ jammy main universe +deb [trusted=yes] http://ports.ubuntu.com/ jammy-updates main universe +EOF + ;; + + "armhf") + # armhf compile flags differ between RasPiOS and Ubuntu + if [ -f /etc/rpi-issue ] && ! grep -q 11 /etc/issue; then # RasPiOS 12+ / Bookworm+ + cat << EOF > /etc/apt/sources.list.d/python2.list +deb [trusted=yes] http://ports.ubuntu.com/ jammy main universe +deb [trusted=yes] http://ports.ubuntu.com/ jammy-updates main universe +EOF +# elif ! [ -f /etc/rpi-issue ]; then # Ubuntu/Debian on armhf not supported +# cat << EOF > /etc/apt/sources.list.d/python2.list +# deb http://ports.ubuntu.com/ jammy main universe +# deb http://ports.ubuntu.com/ jammy-updates main universe +# EOF + fi + ;; + + "i386") + # Building on scripts/ansible fix PR #3615 + if grep -q '^ID=debian$' /etc/os-release; then + cat << EOF > /etc/apt/sources.list.d/python2.list +deb http://deb.debian.org/debian bullseye main contrib non-free +deb http://deb.debian.org/debian bullseye-updates main contrib non-free +EOF + fi + ;; +esac + +apt update +if grep -qi ubuntu /etc/os-release; then # Ubuntu 23.10+ (and Mint 22+ ?) needs this. Ubuntu 23.04 tolerates it. + # 2023-05-20: 4 lines below borrow from Ubuntu 22.04: (Is this really less + # fragile than the pip approach ~40 lines above, in preparing for 24.04 ?) + apt -y install python3-platformdirs=2.5.1-1 + apt-mark hold python3-platformdirs + apt -y install python3-virtualenv=20.13.0+ds-2 + apt-mark hold python3-virtualenv # 2023-09-26: 'apt-mark hold virtualenv' was definitely insufficient on Ubuntu 23.10 + # 2023-05-21 PR #3587: Above 4 lines should really install a more recent + # version of virtualenv, probably from 'lunar' (Ubuntu 23.04) ? +else + apt -y install virtualenv # Debian 12 & RasPiOS 12 are A-Ok with built-in virtualenv 20.17.1 (<= 20.21.1) +fi +apt -y install python2 +rm /etc/apt/sources.list.d/python2.list || true +apt update diff --git a/scripts/install_python2_kalite-venv_u2404.sh b/scripts/install_python2_kalite-venv_u2404.sh new file mode 100755 index 000000000..cc40edcc2 --- /dev/null +++ b/scripts/install_python2_kalite-venv_u2404.sh @@ -0,0 +1,51 @@ +#!/bin/bash +export DEBIAN_FRONTEND=noninteractive + +cat << EOF > /etc/apt/sources.list.d/python2.list +deb [trusted=yes] http://archive.ubuntu.com/ubuntu jammy main universe +deb [trusted=yes] http://archive.ubuntu.com/ubuntu jammy-updates main universe +EOF + +apt update + +apt -y --allow-downgrades install python3.11=3.11.0~rc1-1~22.04 python3.11-minimal=3.11.0~rc1-1~22.04 libpython3.11-stdlib=3.11.0~rc1-1~22.04 libpython3.11-minimal=3.11.0~rc1-1~22.04 +apt-mark hold python3.11 python3.11-minimal libpython3.11-stdlib libpython3.11-minimal + +apt -y --allow-downgrades install python3-platformdirs=2.5.1-1 +apt-mark hold python3-platformdirs + +apt -y install python2 python2-pip-whl python2-setuptools-whl + +apt -y --allow-downgrades install python3-pip-whl=22.0.2+dfsg-1 +apt-mark hold python3-pip-whl + +apt -y --no-install-recommends install python3-pip=22.0.2+dfsg-1 +apt-mark hold python3-pip + +apt -y --allow-downgrades install python3-virtualenv=20.13.0+ds-2 +apt-mark hold python3-virtualenv + +apt -y --allow-downgrades install virtualenv=20.13.0+ds-2 +apt-mark hold virtualenv + +virtualenv --always-copy --pip 20.3.4 --setuptools 44.1.1 --no-wheel -p python2.7 /usr/local/kalite/venv + +cd /usr/local/kalite/venv +source bin/activate +bin/pip install ka-lite-static --no-python-version-warning --no-cache-dir +deactivate + +#apt -y remove `apt list *python2* | grep installed | awk -F / '{ print $1 }'` +apt-mark unhold $(apt-mark showhold) || true + +rm /etc/apt/sources.list.d/python2.list + +apt -y remove libmpdec3 python3-pip python3-wheel + +apt update +apt -y upgrade # Why 'apt upgrade' here? + +# python3-venv is needed for other venv's like roles/jupyterhub, e.g. #3716. +# So we restore python3-venv originally installed by scripts/ansible -- this +# is nec b/c python3-pip-whl downgrade to 22.0.2 (line ~19 above) removes it: +apt -y install python3-venv diff --git a/scripts/local_facts.fact b/scripts/local_facts.fact index e68aa93d5..e9f1fdb19 100755 --- a/scripts/local_facts.fact +++ b/scripts/local_facts.fact @@ -63,6 +63,7 @@ OS_VER="$OS-$VERSION_ID" #"debian-8" | \ #"debian-9" | \ #"debian-10" | \ + #"debian-11" | \ #"ubuntu-16" | \ #"ubuntu-17" | \ #"ubuntu-18" | \ @@ -70,22 +71,29 @@ OS_VER="$OS-$VERSION_ID" #"ubuntu-2004" | \ #"ubuntu-2104" | \ #"ubuntu-2110" | \ + #"ubuntu-2210" | \ + #"ubuntu-2204" | \ + #"ubuntu-2304" | \ + #"ubuntu-2310" | \ #"linuxmint-20" | \ + #"linuxmint-21" | \ #"raspbian-8" | \ #"raspbian-9" | \ #"raspbian-10" | \ + #"raspbian-11" | \ -# 2021-09-27: With Debian 12 (Bookworm) pre-releases, please manually add -# this line to its /etc/os-release before installing IIAB: VERSION_ID="12" +# 2023-12-31: With Debian 13 (Trixie) pre-releases, please manually add +# this line to its /etc/os-release before installing IIAB: VERSION_ID="13" case $OS_VER in - "debian-11" | \ "debian-12" | \ - "ubuntu-2204" | \ - "ubuntu-2210" | \ - "ubuntu-2304" | \ - "linuxmint-21" | \ - "raspbian-11") + "debian-13" | \ + "ubuntu-2404" | \ + "ubuntu-2410" | \ + "ubuntu-2504" | \ + "linuxmint-22" | \ + "raspbian-12" | \ + "raspbian-13") ;; *) echo -e "\n\e[41;1mOS '$OS_VER' IS NOT SUPPORTED. Please read:\e[0m\n\n\e[1mhttps://github.com/iiab/iiab/wiki/IIAB-Platforms\e[0m\n" ; exit 1 # Used by /opt/iiab/iiab/iiab-install ;; @@ -111,8 +119,9 @@ tmp=$(git rev-parse --verify HEAD) && IIAB_COMMIT=$tmp -grep -iq raspberry /proc/device-tree/model && - RPI_MODEL=$(grep -ai raspberry /proc/device-tree/model | tr -d '\0') +grep -iq raspberry /proc/cpuinfo && + RPI_MODEL=$(grep -i raspberry /proc/cpuinfo | sed 's/.*: //') + #RPI_MODEL=$(grep -ai raspberry /proc/device-tree/model | tr -d '\0') # /proc/device-tree/model e.g. 'Parallels ARM Virtual Machine' identical to... # /sys/firmware/devicetree/base/model (also true on RPi hardware!) diff --git a/test.yml b/test.yml index ab0aeac9c..067b7cddd 100644 --- a/test.yml +++ b/test.yml @@ -1,6 +1,13 @@ # TEST ANSIBLE COMMANDS/MODULES IN SECONDS -- BY RUNNING: # ansible-playbook -i ansible_hosts test.yml --connection=local +# TEST A SINGLE ANSIBLE COMMAND/MODULE: +# ansible localhost -m ansible.builtin.setup | grep -e "ansible_machine\b" -e ansible_architecture +# ansible localhost -m ansible.builtin.shell -a 'echo $TERM' +# ansible localhost -m ansible.builtin.copy -a "src=/etc/hosts dest=/tmp/hosts" +# ansible localhost -m ansible.builtin.systemd -a "name=nginx state=restarted" +# https://docs.ansible.com/ansible/latest/command_guide/intro_adhoc.html + - hosts: all become: yes # Optional privilege escalation @@ -19,19 +26,30 @@ #- include_role: # name: 0-init - - debug: - msg: "{{ 'changeme' | password_hash('sha512') }}" + # 2024-08-15: Still not working with ansible-core 2.17.3 -- instead of + # migrating from Python's crypt library to passlib, Ansible is deprecating: + # https://github.com/ansible/ansible/issues/81949 + # https://github.com/iiab/iiab/blob/485a619bfa082716ec848b5b34893dd3046175a8/roles/cups/tasks/install.yml#L70-L78 + #- debug: + # msg: "{{ 'changeme' | password_hash('sha512') }}" # msg: "{{ 'changeme' | password_hash('yescrypt') }}" # crypt.crypt STILL doesn't support 'yescrypt' algorithm ? #- pause: + - debug: + var: "'3.12.3' is version('3.12', '<')" + - name: DOUBLE UP to escape single quotes... '"''"' e.g. iiab.ini descriptions for azuracast, captiveportal, mosquitto, munin, nodejs, osm-vector-maps, sshd debug: - msg: '"''"' # FAILS: '"\'"' + msg: '"''"' # OR: '''' FAILS: '"\'"' - name: BACKSLASH to escape double quotes... "'\"'" e.g. cups/tasks/install.yml debug: - msg: "'\"'" # FAILS: "'""'" + msg: "'\"'" # OR: "\"" FAILS: "'""'" + + - name: "Entire string must be enclosed in quotes if using ' #' Space-then-Pound/Hash sequence -- or right side will be a comment! e.g. roles/vnstat/install.yml" + debug: + msg: "Left side # Right side" - name: a shows "VARIABLE IS NOT DEFINED!" -- whereas b (w/o whitespace) AND c (with space) AND d (with tab, STRICTLY DISALLOWED IN YAML BY ansible-core 2.11.6) showed null (without quotes!) -- whereas e (singlequotes) and f (doublequotes) show "" empty string set_fact: @@ -91,5 +109,15 @@ - debug: var: ansible_machine + - command: dpkg --print-architecture + register: cmd + - debug: + msg: "'dpkg --print-architecture' output: {{ cmd.stdout }}" + + - command: dpkg --print-foreign-architectures + register: cmd + - debug: + msg: "'dpkg --print-foreign-architectures' output: {{ cmd.stdout }}" + # TEST ANSIBLE COMMANDS/MODULES HERE! diff --git a/tests/inventory b/tests.unused/inventory similarity index 100% rename from tests/inventory rename to tests.unused/inventory diff --git a/tests/test.yml b/tests.unused/test.yml similarity index 100% rename from tests/test.yml rename to tests.unused/test.yml diff --git a/unmaintained-roles.txt b/unmaintained-roles.txt index c30178fbc..3573e6f75 100644 --- a/unmaintained-roles.txt +++ b/unmaintained-roles.txt @@ -13,6 +13,7 @@ httpd-enable idmgr moodle-1.9 nodogsplash +openvpn osm owncloud pathagar diff --git a/vars/debian-11.yml b/vars/debian-11.yml.unused similarity index 100% rename from vars/debian-11.yml rename to vars/debian-11.yml.unused diff --git a/vars/debian-12.yml b/vars/debian-12.yml index abdbf891b..d06a61285 100644 --- a/vars/debian-12.yml +++ b/vars/debian-12.yml @@ -3,18 +3,3 @@ is_debuntu: True is_debian: True # Opposite of is_ubuntu for now is_debian_12: True - -# proxy: squid -# proxy_user: proxy -# apache_service: apache2 -# apache_user: www-data -# smb_service: smbd -# nmb_service: nmbd -# systemctl_program: /bin/systemctl -# mysql_service: mariadb -# sshd_package: openssh-server -# sshd_service: ssh -# systemd_location: /lib/systemd/system -# php_version: "8.1" -# postgresql_version: 15 -# python_version: "3.10" diff --git a/vars/debian-13.yml b/vars/debian-13.yml new file mode 100644 index 000000000..09ef89f68 --- /dev/null +++ b/vars/debian-13.yml @@ -0,0 +1,5 @@ +# Every is_ var is initially set to 'False' at the bottom of +# /opt/iiab/iiab/vars/default_vars.yml -- these 'True' lines override that: +is_debuntu: True +is_debian: True # Opposite of is_ubuntu for now +is_debian_13: True diff --git a/vars/default_vars.yml b/vars/default_vars.yml index 9236e0899..a45384e1e 100644 --- a/vars/default_vars.yml +++ b/vars/default_vars.yml @@ -13,7 +13,7 @@ # IIAB (PRE-)release version number, for {{ iiab_env_file }} -iiab_base_ver: 8.0 +iiab_base_ver: 8.3 iiab_revision: 0 # 2022-06-23: ./iiab-install (with 'sudo iiab') follow the traditional linear @@ -131,9 +131,10 @@ hostapd_enabled: True # Raspberry Pi 3 B+ and 4 OS's don't allow more than ~4 students to use the # internal WiFi hotspot. Increase this to 19 or 24 student WiFi devices (or -# 32 on older OS's from 2020) using EXACTLY 1 of the 4 lines below: +# 32 on older OS's from 2020) using EXACTLY 1 of the 5 lines below: # #rpi3bplus_rpi4_wifi_firmware: os # Use your OS's WiFi firmware e.g. 7.45.241 +#rpi3bplus_rpi4_wifi_firmware: ub # Ubuntu-only OLD firmware e.g. 7.45.234 rpi3bplus_rpi4_wifi_firmware: 19 # SEE: github.com/iiab/iiab/issues/2853 #rpi3bplus_rpi4_wifi_firmware: 24 # REQUIRES "wifi_up_down: False" BELOW! #rpi3bplus_rpi4_wifi_firmware: 32 # UNRELIABLE (INTERMITTENT) with 2021+ OS's @@ -143,7 +144,8 @@ rpi3bplus_rpi4_wifi_firmware: 19 # SEE: github.com/iiab/iiab/issues/2853 # Raspberry Pi Zero W and 3 OS's don't allow more than ~10 students to use the # internal WiFi hotspot. Or try increasing this to 30 student WiFi devices: # -rpizerow_rpi3_wifi_firmware: os # Use yr OS WiFi firmware e.g. 7.45.98.118 +rpizerow_rpi3_wifi_firmware: os # Use yr OS WiFi firmware e.g. 7.45.98 +#rpizerow_rpi3_wifi_firmware: ub # Ubuntu-only OLD firmware e.g. 7.45.98.118 #rpizerow_rpi3_wifi_firmware: 30 # Or firmware 7.45.98.65 from 2018-09-28 wifi_up_down: True # AP+STA mode: Uses "ap0" WiFi adapter for upstream WiFi @@ -168,7 +170,7 @@ wan_netmask: # wan_netmask: 255.255.255.0 wan_gateway: # wan_gateway: 192.168.1.254 # If nec wan_nameserver can override ISP-provided DNS servers via dnsmasq: # /etc/resolv.conf dictates which backend is used for the machine itself, so -# 127.0.0.1 means you get dnsmasq (so it works right away on RaspiOS) while +# 127.0.0.1 means you get dnsmasq (so it works right away on RasPiOS) while # 127.0.0.53 gives you systemd-networkd (so Ubuntu itself does NOT use this # dnsmasq-specified upstream DNS [e.g. wan_nameserver] but its LAN clients do!) wan_nameserver: # wan_nameserver: 192.168.1.254 or 8.8.8.8 or 1.1.1.1 @@ -191,7 +193,7 @@ ports_externally_visible: 3 # ssh + http-or-https + common IIAB services # # Or further customize your iptables firewall by editing: # /opt/iiab/iiab/roles/network/templates/gateway/iiab-gen-iptables -# And then run: cd /opt/iiab/iiab; ./iiab-network +# And then run: sudo iiab-network # dnsmasq - handles DHCP and DNS dnsmasq_install: True @@ -207,7 +209,7 @@ dnsmasq_enabled: True #named_enabled: False block_DNS: False -# Enable in local_vars.yml AFTER installing IIAB! Then run "cd /opt/iiab/iiab; ./iiab-network" +# Enable in local_vars.yml AFTER installing IIAB! Then run: sudo iiab-network dns_jail_enabled: False # UNMAINTAINED as of October 2017: https://github.com/iiab/iiab/pull/382 @@ -217,8 +219,8 @@ dns_jail_enabled: False # 1-PREP -# SSHD runs here & also below in 4-SERVER-OPTIONS -sshd_install: True # Required by OpenVPN +# OPENSSH-SERVER +sshd_install: True sshd_enabled: True sshd_port: 22 # Not fully functional. SEE: roles/sshd/tasks/install.yml @@ -230,17 +232,9 @@ remoteit_enabled: False # remoteit_license_key: 592AA9BB-XXXX-YYYY-ZZZZ-6E27654C3DF6 # SECURITY WARNING: https://wiki.iiab.io/go/Security -openvpn_install: True -openvpn_enabled: False -openvpn_handle: "" # Empty string on purpose since ~2016, for /etc/iiab/uuid -# SEE https://github.com/iiab/iiab/blob/master/roles/openvpn/tasks/main.yml#L5-L20 -# cron seemed necessary on CentOS: -openvpn_cron_enabled: False -# General OpenVPN settings -openvpn_server: xscenet.net -openvpn_server_real_ip: 3.89.148.185 -openvpn_server_virtual_ip: 10.8.0.1 -openvpn_server_port: 1194 +# New VPN replaced OpenVPN in Sept 2024: +tailscale_install: True +tailscale_enabled: False # Stub var, doesn't yet do anything! # IIAB-ADMIN runs here - see its vars near top of this file: # e.g. iiab_admin_user, iiab_admin_user_install, iiab_admin_can_sudo, @@ -248,7 +242,7 @@ openvpn_server_port: 1194 # dnsmasq is installed here -- configure LATER in 'network', after Stage 9. # (The full network stage runs after 9-LOCAL-ADDONS. Or manually run -# "cd /opt/iiab/iiab; sudo ./iiab-network"). Design under discussion: #2876 +# "sudo iiab-network"). Design under discussion: #2876 # Some prefer 512MB for Zero W, others prefer 2048MB or higher for RPi 3 and 4. # Please see recommendations at: https://itsfoss.com/swap-size/ @@ -263,12 +257,12 @@ pi_swap_file_size: 1024 # 3-BASE-SERVER -# 2020-09-24: MySQL / MariaDB is MANDATORY but still evolving - please see: -# https://github.com/iiab/iiab/blob/master/roles/mysql/tasks/install.yml -# https://github.com/iiab/iiab/blob/master/roles/3-base-server/tasks/main.yml -# THESE 2 LEGACY VARS ARE PRESERVED BUT HAVE NO EFFECT: -mysql_install: True -mysql_enabled: True +# 2023-11-05: MySQL (actually MariaDB) had been mandatory, installed on every +# IIAB by 3-base-server. Now installed on demand -- as a dependency of Matomo, +# MediaWiki, Nextcloud, PBX (for FreePBX), WordPress &/or Admin Console. +# SO BOTH VALUES BELOW ARE INITIALLY IGNORED: +mysql_install: False +mysql_enabled: False mysql_service: mariadb # 2020-09-24: NGINX is MANDATORY but still evolving - please see: @@ -280,15 +274,13 @@ nginx_port: 80 nginx_interface: 0.0.0.0 nginx_conf_dir: /etc/nginx/conf.d nginx_log_dir: /var/log/nginx -# SEE BELOW: nginx_high_php_limits, apache_allow_sudo +# SEE BELOW: nginx_high_php_limits, allow_www_data_poweroff # roles/www_base runs here (mandatory) # 4-SERVER-OPTIONS -# SSHD runs here & also above in 1-PREP - # DNS prep (named &/or dhcpd) used to run here. See dnsmasq in 1-PREP above. # Proxy Cache & basic site blocking using /etc/squid allowlists: (whitelists) @@ -315,11 +307,9 @@ bluetooth_term_enabled: False # USB_LIB usb_lib_install: True usb_lib_enabled: True -# Show entire contents of USB sticks/drives (at http://box/usb) -iiab_usb_lib_show_all: True -# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf so -# Kolibri can export & import channels to USB sticks/drive: -usb_lib_umask0000_for_kolibri: True +# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf for +# Kolibri exports, and student uploads to teacher's USB stick (http://box/usb) +usb_lib_writable_sticks: True systemd_location: /lib/systemd/system # 2-common iiab-startup also uses # Common UNIX Printing System (CUPS) @@ -338,17 +328,18 @@ nmb_service: nmbd # Could move to roles/samba/defaults/main.yml # roles/www_options HANDLES THE 3 VARS BELOW: -# For schools using Moodle, or intensively using Matomo/Nextcloud/PBX/WordPress: +# Set to True if intensively using Matomo/PBX/WordPress: nginx_high_php_limits: False -# WARNING: Enabling this might cause excess use of RAM/disk or other resources! -# roles/www_options & roles/moodle FORCE high limits if 'moodle_install: True' -# REGARDLESS: AFTER INSTALLING IIAB, PLEASE VERIFY THESE 6 SETTINGS... +# SIMILARLY: 'moodle_install: True' and 'nextcloud_install: True' effectively +# force this, via roles/www_options & roles/moodle & roles/nextcloud +# WARNING: This might cause excess use of RAM/disk or other resources! +# WARNING: AFTER INSTALLING IIAB, PLEASE VERIFY THESE 6 SETTINGS... # https://github.com/iiab/iiab/blob/master/roles/www_options/tasks/php-settings.yml # ...ARE SUITABLE FOR YOUR HARDWARE, as saved in: /etc/php//*/php.ini -# ALSO: ADJUST "client_max_body_size 500M;" AS NEC, IN: /etc/nginx/server.conf +# ALSO: ADJUST "client_max_body_size 10000M;" AS NEC, IN: /etc/nginx/server.conf -# Make this True to enable http://box/js-menu/menu-files/services/power_off.php -apache_allow_sudo: False +# Make this True to enable http://box/js-menu/menu-files/services/power_off.php and set-server-time.php +allow_www_data_poweroff: False apache_service: apache2 apache_user: www-data # Admin Console uses @@ -419,9 +410,9 @@ jupyterhub_enabled: False jupyterhub_venv: /opt/iiab/jupyterhub jupyterhub_port: 8000 -# Lokole (email for rural communities) from https://ascoderu.ca -lokole_install: False -lokole_enabled: False +# UNMAINTAINED: Lokole (email for rural communities) from https://ascoderu.ca +lokole_install: False # 2022-03-13: Python 3.9+ work +lokole_enabled: False # https://github.com/iiab/iiab/issues/3132 # lokole_sim_type can be: 'hologram', 'Ethernet', 'LocalOnly', or 'mkwvconf' # Details: https://github.com/ascoderu/lokole/blob/master/install.py#L35 lokole_sim_type: LocalOnly @@ -441,7 +432,7 @@ mosquitto_port: 1883 # JupyterHub, nodered (Node-RED), pbx (Asterix, FreePBX) &/or Sugarizer: nodejs_install: False nodejs_enabled: False -nodejs_version: 18.x # was 8.x til 2019-02-02, 10.x til 2019-12-21, 12.x til 2020-10-29, 14.x til 2021-06-17, 16.x til 2022-04-20 +nodejs_version: 22.x # was 8.x til 2019-02-02, 10.x til 2019-12-21, 12.x til 2020-10-29, 14.x til 2021-06-17, 16.x til 2022-04-20, 18.x til 2023-05-20, 20.x til 2024-05-03 # Flow-based visual programming for wiring together IoT hardware devices etc nodered_install: False @@ -473,15 +464,17 @@ wordpress_enabled: False # 7-EDU-APPS # KA Lite - SEE THE "Transmission" BITTORRENT DOWNLOADER FURTHER BELOW, TO INSTALL THOUSANDS OF VIDEOS -kalite_install: True -kalite_enabled: True +kalite_install: False +kalite_enabled: False kalite_server_port: 8008 kalite_root: "{{ content_base }}/ka-lite" # /library/ka-lite # Successor to KA Lite, for offline-first teaching and learning - from learningequality.org -kolibri_install: False -kolibri_enabled: False -kolibri_language: en # See KOLIBRI_SUPPORTED_LANGUAGES at the bottom of https://github.com/learningequality/kolibri/blob/develop/kolibri/utils/i18n.py +kolibri_install: True +kolibri_enabled: True +kolibri_language: en # See KOLIBRI_SUPPORTED_LANGUAGES at the bottom of https://github.com/learningequality/kolibri/blob/develop/kolibri/utils/i18n.py +kolibri_home: "{{ content_base }}/kolibri" # /library/kolibri +kolibri_user: kolibri # WARNING: https://github.com/learningequality/kolibri-installer-debian/issues/115 kolibri_http_port: 8009 # kiwix_install: True is REQUIRED, if you install IIAB's Admin Console @@ -498,7 +491,7 @@ kiwix_apk_src: https://download.kiwix.org/release/kiwix-android/kiwix.apk postgresql_install: False postgresql_enabled: False -# Warning: Moodle is a serious LMS, that takes a while to install. +# Warning: Moodle is a serious LMS, that takes a while to install moodle_install: False moodle_enabled: False # FYI 'nginx_high_php_limits: True' (explained above) is mandated with Moodle, @@ -539,6 +532,7 @@ sugarizer_port: 8089 # Transmission is a BitTorrent downloader for large Content Packs etc transmission_install: False transmission_enabled: False +transmission_compile_latest: False transmission_username: Admin transmission_password: changeme @@ -648,8 +642,8 @@ minetest_game_dir: "{{ minetest_working_dir }}/games/{{ minetest_default_game }} minetest_flat_world: False # Calibre-Web E-Book Library -- Alternative to Calibre, offers a clean/modern UX -calibreweb_install: False -calibreweb_enabled: False +calibreweb_install: True +calibreweb_enabled: True calibreweb_port: 8083 # PORT VARIABLE HAS NO EFFECT (as of January 2019) # http://box/books works. Add {box/libros, box/livres, box/livros, box/liv} etc? calibreweb_url1: /books # For SHORT URL http://box/books (English) @@ -678,13 +672,14 @@ calibre_web_path: calibre #NEEDS WORK: https://github.com/iiab/iiab/issues/529 # Avoid URL collisions w/ calibreweb_url1, calibreweb_url2, calibreweb_url3 below! # A full-featured PBX (for rural telephony, etc) based on Asterisk and FreePBX. -# REQUIRES PHP 7.4 e.g. Ubuntu 20.04, Debian 11 -- RaspiOS 11 might also work. # INSTRUCTIONS: https://github.com/iiab/iiab/tree/master/roles/pbx#readme # If using PBX intensively, investigate nginx_high_php_limits further above. pbx_install: False pbx_enabled: False -pbx_use_apache: True # 2021-08-17: Set either to 'False' if nec -- please +pbx_use_apache: False # 2023-04-03: Set to 'True' if nec -- please also pbx_use_nginx: True # read github.com/iiab/iiab/issues/2914 & #2916, THX! +# 2023-04-03: For EXPERIMENTAL testing on Raspberry Pi... (#3489, PR #3523) +asterisk_rpi_patch: False asterisk_chan_dongle: False pbx_signaling_ports_chan_sip: 5160:5161 pbx_signaling_ports_chan_pjsip: 5060 @@ -767,30 +762,38 @@ pbx_http_port: 83 is_debuntu: False # Covers all 4: Ubuntu, Linux Mint, Debian, Raspberry Pi OS (Raspbian) is_ubuntu: False # Covers: Ubuntu, Linux Mint -is_ubuntu_2304: False -is_ubuntu_2210: False +is_ubuntu_2504: False +is_ubuntu_2410: False +is_ubuntu_2404: False +is_ubuntu_2310: False +#is_ubuntu_2304: False +#is_ubuntu_2210: False is_ubuntu_2204: False #is_ubuntu_2110: False #is_ubuntu_2104: False -is_ubuntu_2004: False +#is_ubuntu_2004: False #is_ubuntu_19: False #is_ubuntu_18: False #is_ubuntu_17: False #is_ubuntu_16: False is_linuxmint: False # Subset of is_ubuntu -is_linuxmint_21: False -is_linuxmint_20: False +is_linuxmint_22: False +#is_linuxmint_21: False +#is_linuxmint_20: False is_debian: False # Covers both: Debian, Raspberry Pi OS (Raspbian) +is_debian_13: False is_debian_12: False -is_debian_11: False +#is_debian_11: False #is_debian_10: False #is_debian_9: False #is_debian_8: False is_raspbian: False # Covers both: RPi HW + non-RPi HW versions of Raspberry Pi OS (Raspbian) -is_raspbian_11: False +is_raspbian_13: False +is_raspbian_12: False +#is_raspbian_11: False #is_raspbian_10: False #is_raspbian_9: False #is_raspbian_8: False diff --git a/vars/linuxmint-21.yml b/vars/linuxmint-21.yml.unused similarity index 100% rename from vars/linuxmint-21.yml rename to vars/linuxmint-21.yml.unused diff --git a/vars/linuxmint-22.yml b/vars/linuxmint-22.yml new file mode 100644 index 000000000..53af5a21c --- /dev/null +++ b/vars/linuxmint-22.yml @@ -0,0 +1,7 @@ +# Every is_ var is initially set to 'False' at the bottom of +# /opt/iiab/iiab/vars/default_vars.yml -- these 'True' lines override that: +is_debuntu: True +is_ubuntu: True # Opposite of is_debian for now +is_ubuntu_2404: True +is_linuxmint: True +is_linuxmint_22: True diff --git a/vars/local_vars_large.yml b/vars/local_vars_large.yml index 3f6371a41..7228bb506 100644 --- a/vars/local_vars_large.yml +++ b/vars/local_vars_large.yml @@ -74,9 +74,10 @@ hostapd_password: changeme # espec if WiFi firmware patched below? #2696 # Raspberry Pi 3 B+ and 4 OS's don't allow more than ~4 students to use the # internal WiFi hotspot. Increase this to 19 or 24 student WiFi devices (or -# 32 on older OS's from 2020) using EXACTLY 1 of the 4 lines below: +# 32 on older OS's from 2020) using EXACTLY 1 of the 5 lines below: # #rpi3bplus_rpi4_wifi_firmware: os # Use your OS's WiFi firmware e.g. 7.45.241 +#rpi3bplus_rpi4_wifi_firmware: ub # Ubuntu-only OLD firmware e.g. 7.45.234 rpi3bplus_rpi4_wifi_firmware: 19 # SEE: github.com/iiab/iiab/issues/2853 #rpi3bplus_rpi4_wifi_firmware: 24 # REQUIRES "wifi_up_down: False" BELOW! #rpi3bplus_rpi4_wifi_firmware: 32 # UNRELIABLE (INTERMITTENT) with 2021+ OS's @@ -86,7 +87,8 @@ rpi3bplus_rpi4_wifi_firmware: 19 # SEE: github.com/iiab/iiab/issues/2853 # Raspberry Pi Zero W and 3 OS's don't allow more than ~10 students to use the # internal WiFi hotspot. Or try increasing this to 30 student WiFi devices: # -rpizerow_rpi3_wifi_firmware: os # Use yr OS WiFi firmware e.g. 7.45.98.118 +rpizerow_rpi3_wifi_firmware: os # Use yr OS WiFi firmware e.g. 7.45.98 +#rpizerow_rpi3_wifi_firmware: ub # Ubuntu-only OLD firmware e.g. 7.45.98.118 #rpizerow_rpi3_wifi_firmware: 30 # Or firmware 7.45.98.65 from 2018-09-28 wifi_up_down: True # AP+STA mode: Uses "ap0" WiFi adapter for upstream WiFi @@ -102,7 +104,7 @@ wan_netmask: # wan_netmask: 255.255.255.0 wan_gateway: # wan_gateway: 192.168.1.254 # If nec wan_nameserver can override ISP-provided DNS servers via dnsmasq: # /etc/resolv.conf dictates which backend is used for the machine itself, so -# 127.0.0.1 means you get dnsmasq (so it works right away on RaspiOS) while +# 127.0.0.1 means you get dnsmasq (so it works right away on RasPiOS) while # 127.0.0.53 gives you systemd-networkd (so Ubuntu itself does NOT use this # dnsmasq-specified upstream DNS [e.g. wan_nameserver] but its LAN clients do!) wan_nameserver: # wan_nameserver: 192.168.1.254 or 8.8.8.8 or 1.1.1.1 @@ -122,16 +124,16 @@ ports_externally_visible: 3 # ssh + http-or-https + common IIAB services # # Or further customize your iptables firewall by editing: # /opt/iiab/iiab/roles/network/templates/gateway/iiab-gen-iptables -# And then run: cd /opt/iiab/iiab; ./iiab-network +# And then run: sudo iiab-network -# Enable AFTER installing IIAB! Then run "cd /opt/iiab/iiab; ./iiab-network" +# Enable AFTER installing IIAB! Then run: sudo iiab-network dns_jail_enabled: False # 1-PREP -# SSHD runs here & also below in 4-SERVER-OPTIONS -sshd_install: True # Required by OpenVPN +# OPENSSH-SERVER +sshd_install: True sshd_enabled: True # https://remote.it can help you remotely maintain an IIAB. @@ -142,17 +144,16 @@ remoteit_enabled: False # remoteit_license_key: 592AA9BB-XXXX-YYYY-ZZZZ-6E27654C3DF6 # SECURITY WARNING: https://wiki.iiab.io/go/Security -openvpn_install: True -openvpn_enabled: False -# 2021-08-18 SSOT: Please set it here, no longer in /etc/iiab/openvpn_handle -openvpn_handle: LARGE - Put Your Name Here +# New VPN replaced OpenVPN in Sept 2024: +tailscale_install: True +tailscale_enabled: False # Stub var, doesn't yet do anything! # IIAB-ADMIN runs here - see its vars near top of this file: # e.g. iiab_admin_user, iiab_admin_user_install, iiab_admin_can_sudo # dnsmasq is installed here -- configure LATER in 'network', after Stage 9. # (The full network stage runs after 9-LOCAL-ADDONS. Or manually run -# "cd /opt/iiab/iiab; sudo ./iiab-network"). Design under discussion: #2876 +# "sudo iiab-network"). Design under discussion: #2876 # Some prefer 512MB for Zero W, others prefer 2048MB or higher for RPi 3 and 4. # Please see recommendations at: https://itsfoss.com/swap-size/ @@ -171,13 +172,11 @@ pi_swap_file_size: 1024 # roles/nginx runs here (mandatory) # roles/www_base runs here (mandatory) -# SEE BELOW: nginx_high_php_limits, apache_allow_sudo +# SEE BELOW: nginx_high_php_limits, allow_www_data_poweroff # 4-SERVER-OPTIONS -# SSHD runs here & also above in 1-PREP - # DNS prep (named &/or dhcpd) used to run here. See dnsmasq in 1-PREP above. # Proxy Cache & basic site blocking using /etc/squid allowlists: (whitelists) @@ -193,11 +192,9 @@ bluetooth_install: True bluetooth_enabled: False bluetooth_term_enabled: False -# Show entire contents of USB sticks/drives (at http://box/usb) -iiab_usb_lib_show_all: True -# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf so -# Kolibri can export & import channels to USB sticks/drive: -usb_lib_umask0000_for_kolibri: True +# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf for +# Kolibri exports, and student uploads to teacher's USB stick (http://box/usb) +usb_lib_writable_sticks: True # Common UNIX Printing System (CUPS) cups_install: True @@ -209,17 +206,18 @@ samba_enabled: False # roles/www_options HANDLES THE 3 VARS BELOW: -# For schools using Moodle, or intensively using Matomo/Nextcloud/PBX/WordPress: +# Set to True if intensively using Matomo/PBX/WordPress: nginx_high_php_limits: False -# WARNING: Enabling this might cause excess use of RAM/disk or other resources! -# roles/www_options & roles/moodle FORCE high limits if 'moodle_install: True' -# REGARDLESS: AFTER INSTALLING IIAB, PLEASE VERIFY THESE 6 SETTINGS... +# SIMILARLY: 'moodle_install: True' and 'nextcloud_install: True' effectively +# force this, via roles/www_options & roles/moodle & roles/nextcloud +# WARNING: This might cause excess use of RAM/disk or other resources! +# WARNING: AFTER INSTALLING IIAB, PLEASE VERIFY THESE 6 SETTINGS... # https://github.com/iiab/iiab/blob/master/roles/www_options/tasks/php-settings.yml # ...ARE SUITABLE FOR YOUR HARDWARE, as saved in: /etc/php//*/php.ini -# ALSO: ADJUST "client_max_body_size 500M;" AS NEC, IN: /etc/nginx/server.conf +# ALSO: ADJUST "client_max_body_size 10000M;" AS NEC, IN: /etc/nginx/server.conf -# Make this True to enable http://box/js-menu/menu-files/services/power_off.php -apache_allow_sudo: False +# Make this True to enable http://box/js-menu/menu-files/services/power_off.php and set-server-time.php +allow_www_data_poweroff: False # Toggle iiab-refresh-wiki-docs scraping for offline docs (http://box/info) nodocs: False @@ -241,9 +239,9 @@ gitea_enabled: True jupyterhub_install: True jupyterhub_enabled: True -# Lokole (email for rural communities) from https://ascoderu.ca -lokole_install: False # 2022-03-13: Needs work with Python 3.9+ -lokole_enabled: False # https://github.com/iiab/iiab/issues/3132 +# UNMAINTAINED: Lokole (email for rural communities) from https://ascoderu.ca +lokole_install: False # 2023-09-06: wheel for mkwvconf still +lokole_enabled: False # missing from Ubuntu 23.10 (#3572) # Wikipedia's community editing platform - from MediaWiki.org mediawiki_install: True @@ -287,7 +285,7 @@ kalite_enabled: True # Successor to KA Lite, for offline-first teaching and learning - from learningequality.org kolibri_install: True kolibri_enabled: True -kolibri_language: en # ar,bg-bg,bn-bd,de,el,en,es-es,es-419,fa,fr-fr,ff-cm,gu-in,ha,hi-in,id,it,ka,km,ko,mr,my,nyn,pt-br,pt-mz,sw-tz,te,uk,ur-pk,vi,yo,zh-hans +kolibri_language: en # ar,bg-bg,bn-bd,de,el,en,es-es,es-419,fa,fr-fr,ff-cm,gu-in,ha,hi-in,ht,id,it,ka,km,ko,mr,my,nyn,pt-br,pt-mz,sw-tz,te,uk,ur-pk,vi,yo,zh-hans # kiwix_install: True is REQUIRED, if you install IIAB's Admin Console kiwix_install: True @@ -318,6 +316,7 @@ sugarizer_enabled: True # BitTorrent downloader for large Content Packs etc transmission_install: True transmission_enabled: True +transmission_compile_latest: False # A. UNCOMMENT LANGUAGE(S) TO DOWNLOAD KA Lite VIDEOS TO /library/transmission # using https://pantry.learningequality.org/downloads/ka-lite/0.17/content/ transmission_kalite_languages: @@ -413,11 +412,12 @@ calibre_web_path: calibre #NEEDS WORK: https://github.com/iiab/iiab/issues/529 # Avoid URL collisions w/ calibreweb_url1, calibreweb_url2, calibreweb_url3 below! # A full-featured PBX (for rural telephony, etc) based on Asterisk and FreePBX. -# REQUIRES PHP 7.4 e.g. Ubuntu 20.04, Debian 11 -- RaspiOS 11 might also work. # INSTRUCTIONS: https://github.com/iiab/iiab/tree/master/roles/pbx#readme # If using PBX intensively, investigate nginx_high_php_limits further above. pbx_install: False pbx_enabled: False -pbx_use_apache: True # 2021-08-17: Set either to 'False' if nec -- please +pbx_use_apache: False # 2023-04-03: Set to 'True' if nec -- please also pbx_use_nginx: True # read github.com/iiab/iiab/issues/2914 & #2916, THX! +# 2023-04-03: For EXPERIMENTAL testing on Raspberry Pi... (#3489, PR #3523) +asterisk_rpi_patch: False asterisk_chan_dongle: False diff --git a/vars/local_vars_medical.yml b/vars/local_vars_medical.yml index f97113d63..445c9bb2f 100644 --- a/vars/local_vars_medical.yml +++ b/vars/local_vars_medical.yml @@ -1,7 +1,7 @@ # Default overrides kiwix_incl_apk: True -kalite_install: False -kalite_enabled: False +kolibri_install: False +kolibri_enabled: False captiveportal_install: True captiveportal_enabled: True mediawiki_install: True @@ -12,9 +12,8 @@ munin_install: True munin_enabled: True vnstat_install: True vnstat_enabled: True -openvpn_handle: "MEDICAL - Put Your Name Here" -usb_lib_umask0000_for_kolibri: False -apache_allow_sudo: True +usb_lib_writable_sticks: False +allow_www_data_poweroff: False # By default # kiwix # awstats diff --git a/vars/local_vars_medium.yml b/vars/local_vars_medium.yml index 7be767773..153401d26 100644 --- a/vars/local_vars_medium.yml +++ b/vars/local_vars_medium.yml @@ -74,9 +74,10 @@ hostapd_password: changeme # espec if WiFi firmware patched below? #2696 # Raspberry Pi 3 B+ and 4 OS's don't allow more than ~4 students to use the # internal WiFi hotspot. Increase this to 19 or 24 student WiFi devices (or -# 32 on older OS's from 2020) using EXACTLY 1 of the 4 lines below: +# 32 on older OS's from 2020) using EXACTLY 1 of the 5 lines below: # #rpi3bplus_rpi4_wifi_firmware: os # Use your OS's WiFi firmware e.g. 7.45.241 +#rpi3bplus_rpi4_wifi_firmware: ub # Ubuntu-only OLD firmware e.g. 7.45.234 rpi3bplus_rpi4_wifi_firmware: 19 # SEE: github.com/iiab/iiab/issues/2853 #rpi3bplus_rpi4_wifi_firmware: 24 # REQUIRES "wifi_up_down: False" BELOW! #rpi3bplus_rpi4_wifi_firmware: 32 # UNRELIABLE (INTERMITTENT) with 2021+ OS's @@ -86,7 +87,8 @@ rpi3bplus_rpi4_wifi_firmware: 19 # SEE: github.com/iiab/iiab/issues/2853 # Raspberry Pi Zero W and 3 OS's don't allow more than ~10 students to use the # internal WiFi hotspot. Or try increasing this to 30 student WiFi devices: # -rpizerow_rpi3_wifi_firmware: os # Use yr OS WiFi firmware e.g. 7.45.98.118 +rpizerow_rpi3_wifi_firmware: os # Use yr OS WiFi firmware e.g. 7.45.98 +#rpizerow_rpi3_wifi_firmware: ub # Ubuntu-only OLD firmware e.g. 7.45.98.118 #rpizerow_rpi3_wifi_firmware: 30 # Or firmware 7.45.98.65 from 2018-09-28 wifi_up_down: True # AP+STA mode: Uses "ap0" WiFi adapter for upstream WiFi @@ -102,7 +104,7 @@ wan_netmask: # wan_netmask: 255.255.255.0 wan_gateway: # wan_gateway: 192.168.1.254 # If nec wan_nameserver can override ISP-provided DNS servers via dnsmasq: # /etc/resolv.conf dictates which backend is used for the machine itself, so -# 127.0.0.1 means you get dnsmasq (so it works right away on RaspiOS) while +# 127.0.0.1 means you get dnsmasq (so it works right away on RasPiOS) while # 127.0.0.53 gives you systemd-networkd (so Ubuntu itself does NOT use this # dnsmasq-specified upstream DNS [e.g. wan_nameserver] but its LAN clients do!) wan_nameserver: # wan_nameserver: 192.168.1.254 or 8.8.8.8 or 1.1.1.1 @@ -122,16 +124,16 @@ ports_externally_visible: 3 # ssh + http-or-https + common IIAB services # # Or further customize your iptables firewall by editing: # /opt/iiab/iiab/roles/network/templates/gateway/iiab-gen-iptables -# And then run: cd /opt/iiab/iiab; ./iiab-network +# And then run: sudo iiab-network -# Enable AFTER installing IIAB! Then run "cd /opt/iiab/iiab; ./iiab-network" +# Enable AFTER installing IIAB! Then run: sudo iiab-network dns_jail_enabled: False # 1-PREP -# SSHD runs here & also below in 4-SERVER-OPTIONS -sshd_install: True # Required by OpenVPN +# OPENSSH-SERVER +sshd_install: True sshd_enabled: True # https://remote.it can help you remotely maintain an IIAB. @@ -142,17 +144,16 @@ remoteit_enabled: False # remoteit_license_key: 592AA9BB-XXXX-YYYY-ZZZZ-6E27654C3DF6 # SECURITY WARNING: https://wiki.iiab.io/go/Security -openvpn_install: True -openvpn_enabled: False -# 2021-08-18 SSOT: Please set it here, no longer in /etc/iiab/openvpn_handle -openvpn_handle: MEDIUM-sized - Put Your Name Here +# New VPN replaced OpenVPN in Sept 2024: +tailscale_install: True +tailscale_enabled: False # Stub var, doesn't yet do anything! # IIAB-ADMIN runs here - see its vars near top of this file: # e.g. iiab_admin_user, iiab_admin_user_install, iiab_admin_can_sudo # dnsmasq is installed here -- configure LATER in 'network', after Stage 9. # (The full network stage runs after 9-LOCAL-ADDONS. Or manually run -# "cd /opt/iiab/iiab; sudo ./iiab-network"). Design under discussion: #2876 +# "sudo iiab-network"). Design under discussion: #2876 # Some prefer 512MB for Zero W, others prefer 2048MB or higher for RPi 3 and 4. # Please see recommendations at: https://itsfoss.com/swap-size/ @@ -171,13 +172,11 @@ pi_swap_file_size: 1024 # roles/nginx runs here (mandatory) # roles/www_base runs here (mandatory) -# SEE BELOW: nginx_high_php_limits, apache_allow_sudo +# SEE BELOW: nginx_high_php_limits, allow_www_data_poweroff # 4-SERVER-OPTIONS -# SSHD runs here & also above in 1-PREP - # DNS prep (named &/or dhcpd) used to run here. See dnsmasq in 1-PREP above. # Proxy Cache & basic site blocking using /etc/squid allowlists: (whitelists) @@ -193,11 +192,9 @@ bluetooth_install: True bluetooth_enabled: False bluetooth_term_enabled: False -# Show entire contents of USB sticks/drives (at http://box/usb) -iiab_usb_lib_show_all: True -# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf so -# Kolibri can export & import channels to USB sticks/drive: -usb_lib_umask0000_for_kolibri: True +# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf for +# Kolibri exports, and student uploads to teacher's USB stick (http://box/usb) +usb_lib_writable_sticks: True # Common UNIX Printing System (CUPS) cups_install: False @@ -209,17 +206,18 @@ samba_enabled: False # roles/www_options HANDLES THE 3 VARS BELOW: -# For schools using Moodle, or intensively using Matomo/Nextcloud/PBX/WordPress: +# Set to True if intensively using Matomo/PBX/WordPress: nginx_high_php_limits: False -# WARNING: Enabling this might cause excess use of RAM/disk or other resources! -# roles/www_options & roles/moodle FORCE high limits if 'moodle_install: True' -# REGARDLESS: AFTER INSTALLING IIAB, PLEASE VERIFY THESE 6 SETTINGS... +# SIMILARLY: 'moodle_install: True' and 'nextcloud_install: True' effectively +# force this, via roles/www_options & roles/moodle & roles/nextcloud +# WARNING: This might cause excess use of RAM/disk or other resources! +# WARNING: AFTER INSTALLING IIAB, PLEASE VERIFY THESE 6 SETTINGS... # https://github.com/iiab/iiab/blob/master/roles/www_options/tasks/php-settings.yml # ...ARE SUITABLE FOR YOUR HARDWARE, as saved in: /etc/php//*/php.ini -# ALSO: ADJUST "client_max_body_size 500M;" AS NEC, IN: /etc/nginx/server.conf +# ALSO: ADJUST "client_max_body_size 10000M;" AS NEC, IN: /etc/nginx/server.conf -# Make this True to enable http://box/js-menu/menu-files/services/power_off.php -apache_allow_sudo: False +# Make this True to enable http://box/js-menu/menu-files/services/power_off.php and set-server-time.php +allow_www_data_poweroff: False # Toggle iiab-refresh-wiki-docs scraping for offline docs (http://box/info) nodocs: False @@ -241,8 +239,8 @@ gitea_enabled: False jupyterhub_install: False jupyterhub_enabled: False -# Lokole (email for rural communities) from https://ascoderu.ca -lokole_install: False # 2022-03-13: Needs work with Python 3.9+ +# UNMAINTAINED: Lokole (email for rural communities) from https://ascoderu.ca +lokole_install: False # 2022-03-13: Python 3.9+ work lokole_enabled: False # https://github.com/iiab/iiab/issues/3132 # Wikipedia's community editing platform - from MediaWiki.org @@ -281,13 +279,13 @@ wordpress_enabled: True # 7-EDU-APPS # KA Lite - SEE THE "Transmission" BITTORRENT DOWNLOADER FURTHER BELOW, TO INSTALL THOUSANDS OF VIDEOS -kalite_install: True -kalite_enabled: True +kalite_install: False +kalite_enabled: False # Successor to KA Lite, for offline-first teaching and learning - from learningequality.org kolibri_install: True kolibri_enabled: True -kolibri_language: en # ar,bg-bg,bn-bd,de,el,en,es-es,es-419,fa,fr-fr,ff-cm,gu-in,ha,hi-in,id,it,ka,km,ko,mr,my,nyn,pt-br,pt-mz,sw-tz,te,uk,ur-pk,vi,yo,zh-hans +kolibri_language: en # ar,bg-bg,bn-bd,de,el,en,es-es,es-419,fa,fr-fr,ff-cm,gu-in,ha,hi-in,ht,id,it,ka,km,ko,mr,my,nyn,pt-br,pt-mz,sw-tz,te,uk,ur-pk,vi,yo,zh-hans # kiwix_install: True is REQUIRED, if you install IIAB's Admin Console kiwix_install: True @@ -318,6 +316,7 @@ sugarizer_enabled: True # BitTorrent downloader for large Content Packs etc transmission_install: True transmission_enabled: True +transmission_compile_latest: False # A. UNCOMMENT LANGUAGE(S) TO DOWNLOAD KA Lite VIDEOS TO /library/transmission # using https://pantry.learningequality.org/downloads/ka-lite/0.17/content/ transmission_kalite_languages: @@ -413,11 +412,12 @@ calibre_web_path: calibre #NEEDS WORK: https://github.com/iiab/iiab/issues/529 # Avoid URL collisions w/ calibreweb_url1, calibreweb_url2, calibreweb_url3 below! # A full-featured PBX (for rural telephony, etc) based on Asterisk and FreePBX. -# REQUIRES PHP 7.4 e.g. Ubuntu 20.04, Debian 11 -- RaspiOS 11 might also work. # INSTRUCTIONS: https://github.com/iiab/iiab/tree/master/roles/pbx#readme # If using PBX intensively, investigate nginx_high_php_limits further above. pbx_install: False pbx_enabled: False -pbx_use_apache: True # 2021-08-17: Set either to 'False' if nec -- please +pbx_use_apache: False # 2023-04-03: Set to 'True' if nec -- please also pbx_use_nginx: True # read github.com/iiab/iiab/issues/2914 & #2916, THX! +# 2023-04-03: For EXPERIMENTAL testing on Raspberry Pi... (#3489, PR #3523) +asterisk_rpi_patch: False asterisk_chan_dongle: False diff --git a/vars/local_vars_none.yml b/vars/local_vars_none.yml index 871068689..1e5c03ead 100644 --- a/vars/local_vars_none.yml +++ b/vars/local_vars_none.yml @@ -1,8 +1,8 @@ # turn off defaults remoteit_install: False -openvpn_install: False -kalite_install: False -kalite_enabled: False +tailscale_install: False +kolibri_install: False +kolibri_enabled: False kiwix_install: False kiwix_enabled: False osm_vector_maps_install: False @@ -11,3 +11,5 @@ awstats_enabled: False matomo_install: False matomo_enabled: False captiveportal_install: False +calibreweb_install: False +calibreweb_enabled: False diff --git a/vars/local_vars_small.yml b/vars/local_vars_small.yml index aa084cf88..b17fcc9ae 100644 --- a/vars/local_vars_small.yml +++ b/vars/local_vars_small.yml @@ -74,9 +74,10 @@ hostapd_password: changeme # espec if WiFi firmware patched below? #2696 # Raspberry Pi 3 B+ and 4 OS's don't allow more than ~4 students to use the # internal WiFi hotspot. Increase this to 19 or 24 student WiFi devices (or -# 32 on older OS's from 2020) using EXACTLY 1 of the 4 lines below: +# 32 on older OS's from 2020) using EXACTLY 1 of the 5 lines below: # #rpi3bplus_rpi4_wifi_firmware: os # Use your OS's WiFi firmware e.g. 7.45.241 +#rpi3bplus_rpi4_wifi_firmware: ub # Ubuntu-only OLD firmware e.g. 7.45.234 rpi3bplus_rpi4_wifi_firmware: 19 # SEE: github.com/iiab/iiab/issues/2853 #rpi3bplus_rpi4_wifi_firmware: 24 # REQUIRES "wifi_up_down: False" BELOW! #rpi3bplus_rpi4_wifi_firmware: 32 # UNRELIABLE (INTERMITTENT) with 2021+ OS's @@ -86,7 +87,8 @@ rpi3bplus_rpi4_wifi_firmware: 19 # SEE: github.com/iiab/iiab/issues/2853 # Raspberry Pi Zero W and 3 OS's don't allow more than ~10 students to use the # internal WiFi hotspot. Or try increasing this to 30 student WiFi devices: # -rpizerow_rpi3_wifi_firmware: os # Use yr OS WiFi firmware e.g. 7.45.98.118 +rpizerow_rpi3_wifi_firmware: os # Use yr OS WiFi firmware e.g. 7.45.98 +#rpizerow_rpi3_wifi_firmware: ub # Ubuntu-only OLD firmware e.g. 7.45.98.118 #rpizerow_rpi3_wifi_firmware: 30 # Or firmware 7.45.98.65 from 2018-09-28 wifi_up_down: True # AP+STA mode: Uses "ap0" WiFi adapter for upstream WiFi @@ -102,7 +104,7 @@ wan_netmask: # wan_netmask: 255.255.255.0 wan_gateway: # wan_gateway: 192.168.1.254 # If nec wan_nameserver can override ISP-provided DNS servers via dnsmasq: # /etc/resolv.conf dictates which backend is used for the machine itself, so -# 127.0.0.1 means you get dnsmasq (so it works right away on RaspiOS) while +# 127.0.0.1 means you get dnsmasq (so it works right away on RasPiOS) while # 127.0.0.53 gives you systemd-networkd (so Ubuntu itself does NOT use this # dnsmasq-specified upstream DNS [e.g. wan_nameserver] but its LAN clients do!) wan_nameserver: # wan_nameserver: 192.168.1.254 or 8.8.8.8 or 1.1.1.1 @@ -122,16 +124,16 @@ ports_externally_visible: 3 # ssh + http-or-https + common IIAB services # # Or further customize your iptables firewall by editing: # /opt/iiab/iiab/roles/network/templates/gateway/iiab-gen-iptables -# And then run: cd /opt/iiab/iiab; ./iiab-network +# And then run: sudo iiab-network -# Enable AFTER installing IIAB! Then run "cd /opt/iiab/iiab; ./iiab-network" +# Enable AFTER installing IIAB! Then run: sudo iiab-network dns_jail_enabled: False # 1-PREP -# SSHD runs here & also below in 4-SERVER-OPTIONS -sshd_install: True # Required by OpenVPN +# OPENSSH-SERVER +sshd_install: True sshd_enabled: True # https://remote.it can help you remotely maintain an IIAB. @@ -142,17 +144,16 @@ remoteit_enabled: False # remoteit_license_key: 592AA9BB-XXXX-YYYY-ZZZZ-6E27654C3DF6 # SECURITY WARNING: https://wiki.iiab.io/go/Security -openvpn_install: True -openvpn_enabled: False -# 2021-08-18 SSOT: Please set it here, no longer in /etc/iiab/openvpn_handle -openvpn_handle: SMALL - Put Your Name Here +# New VPN replaced OpenVPN in Sept 2024: +tailscale_install: True +tailscale_enabled: False # Stub var, doesn't yet do anything! # IIAB-ADMIN runs here - see its vars near top of this file: # e.g. iiab_admin_user, iiab_admin_user_install, iiab_admin_can_sudo # dnsmasq is installed here -- configure LATER in 'network', after Stage 9. # (The full network stage runs after 9-LOCAL-ADDONS. Or manually run -# "cd /opt/iiab/iiab; sudo ./iiab-network"). Design under discussion: #2876 +# "sudo iiab-network"). Design under discussion: #2876 # Some prefer 512MB for Zero W, others prefer 2048MB or higher for RPi 3 and 4. # Please see recommendations at: https://itsfoss.com/swap-size/ @@ -171,13 +172,11 @@ pi_swap_file_size: 1024 # roles/nginx runs here (mandatory) # roles/www_base runs here (mandatory) -# SEE BELOW: nginx_high_php_limits, apache_allow_sudo +# SEE BELOW: nginx_high_php_limits, allow_www_data_poweroff # 4-SERVER-OPTIONS -# SSHD runs here & also above in 1-PREP - # DNS prep (named &/or dhcpd) used to run here. See dnsmasq in 1-PREP above. # Proxy Cache & basic site blocking using /etc/squid allowlists: (whitelists) @@ -193,11 +192,9 @@ bluetooth_install: True bluetooth_enabled: False bluetooth_term_enabled: False -# Show entire contents of USB sticks/drives (at http://box/usb) -iiab_usb_lib_show_all: True -# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf so -# Kolibri can export & import channels to USB sticks/drive: -usb_lib_umask0000_for_kolibri: True +# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf for +# Kolibri exports, and student uploads to teacher's USB stick (http://box/usb) +usb_lib_writable_sticks: True # Common UNIX Printing System (CUPS) cups_install: False @@ -209,17 +206,18 @@ samba_enabled: False # roles/www_options HANDLES THE 3 VARS BELOW: -# For schools using Moodle, or intensively using Matomo/Nextcloud/PBX/WordPress: +# Set to True if intensively using Matomo/PBX/WordPress: nginx_high_php_limits: False -# WARNING: Enabling this might cause excess use of RAM/disk or other resources! -# roles/www_options & roles/moodle FORCE high limits if 'moodle_install: True' -# REGARDLESS: AFTER INSTALLING IIAB, PLEASE VERIFY THESE 6 SETTINGS... +# SIMILARLY: 'moodle_install: True' and 'nextcloud_install: True' effectively +# force this, via roles/www_options & roles/moodle & roles/nextcloud +# WARNING: This might cause excess use of RAM/disk or other resources! +# WARNING: AFTER INSTALLING IIAB, PLEASE VERIFY THESE 6 SETTINGS... # https://github.com/iiab/iiab/blob/master/roles/www_options/tasks/php-settings.yml # ...ARE SUITABLE FOR YOUR HARDWARE, as saved in: /etc/php//*/php.ini -# ALSO: ADJUST "client_max_body_size 500M;" AS NEC, IN: /etc/nginx/server.conf +# ALSO: ADJUST "client_max_body_size 10000M;" AS NEC, IN: /etc/nginx/server.conf -# Make this True to enable http://box/js-menu/menu-files/services/power_off.php -apache_allow_sudo: False +# Make this True to enable http://box/js-menu/menu-files/services/power_off.php and set-server-time.php +allow_www_data_poweroff: False # Toggle iiab-refresh-wiki-docs scraping for offline docs (http://box/info) nodocs: False @@ -241,8 +239,8 @@ gitea_enabled: False jupyterhub_install: False jupyterhub_enabled: False -# Lokole (email for rural communities) from https://ascoderu.ca -lokole_install: False # 2022-03-13: Needs work with Python 3.9+ +# UNMAINTAINED: Lokole (email for rural communities) from https://ascoderu.ca +lokole_install: False # 2022-03-13: Python 3.9+ work lokole_enabled: False # https://github.com/iiab/iiab/issues/3132 # Wikipedia's community editing platform - from MediaWiki.org @@ -281,19 +279,19 @@ wordpress_enabled: False # 7-EDU-APPS # KA Lite - SEE THE "Transmission" BITTORRENT DOWNLOADER FURTHER BELOW, TO INSTALL THOUSANDS OF VIDEOS -kalite_install: True -kalite_enabled: True +kalite_install: False +kalite_enabled: False # Successor to KA Lite, for offline-first teaching and learning - from learningequality.org -kolibri_install: False -kolibri_enabled: False -kolibri_language: en # ar,bg-bg,bn-bd,de,el,en,es-es,es-419,fa,fr-fr,ff-cm,gu-in,ha,hi-in,id,it,ka,km,ko,mr,my,nyn,pt-br,pt-mz,sw-tz,te,uk,ur-pk,vi,yo,zh-hans +kolibri_install: True +kolibri_enabled: True +kolibri_language: en # ar,bg-bg,bn-bd,de,el,en,es-es,es-419,fa,fr-fr,ff-cm,gu-in,ha,hi-in,ht,id,it,ka,km,ko,mr,my,nyn,pt-br,pt-mz,sw-tz,te,uk,ur-pk,vi,yo,zh-hans # kiwix_install: True is REQUIRED, if you install IIAB's Admin Console kiwix_install: True kiwix_enabled: True -# Warning: Moodle is a serious LMS, that takes a while to install. +# Warning: Moodle is a serious LMS, that takes a while to install moodle_install: False moodle_enabled: False # FYI 'nginx_high_php_limits: True' (explained above) is mandated with Moodle, @@ -318,6 +316,7 @@ sugarizer_enabled: False # BitTorrent downloader for large Content Packs etc transmission_install: False transmission_enabled: False +transmission_compile_latest: False # A. UNCOMMENT LANGUAGE(S) TO DOWNLOAD KA Lite VIDEOS TO /library/transmission # using https://pantry.learningequality.org/downloads/ka-lite/0.17/content/ transmission_kalite_languages: @@ -389,8 +388,8 @@ minetest_install: False minetest_enabled: False # Calibre-Web E-Book Library -- Alternative to Calibre, offers a clean/modern UX -calibreweb_install: False -calibreweb_enabled: False +calibreweb_install: True +calibreweb_enabled: True calibreweb_port: 8083 # PORT VARIABLE HAS NO EFFECT (as of January 2019) # http://box/books works. Add {box/libros, box/livres, box/livros, box/liv} etc? calibreweb_url1: /books # For SHORT URL http://box/books (English) @@ -413,11 +412,12 @@ calibre_web_path: calibre #NEEDS WORK: https://github.com/iiab/iiab/issues/529 # Avoid URL collisions w/ calibreweb_url1, calibreweb_url2, calibreweb_url3 below! # A full-featured PBX (for rural telephony, etc) based on Asterisk and FreePBX. -# REQUIRES PHP 7.4 e.g. Ubuntu 20.04, Debian 11 -- RaspiOS 11 might also work. # INSTRUCTIONS: https://github.com/iiab/iiab/tree/master/roles/pbx#readme # If using PBX intensively, investigate nginx_high_php_limits further above. pbx_install: False pbx_enabled: False -pbx_use_apache: True # 2021-08-17: Set either to 'False' if nec -- please +pbx_use_apache: False # 2023-04-03: Set to 'True' if nec -- please also pbx_use_nginx: True # read github.com/iiab/iiab/issues/2914 & #2916, THX! +# 2023-04-03: For EXPERIMENTAL testing on Raspberry Pi... (#3489, PR #3523) +asterisk_rpi_patch: False asterisk_chan_dongle: False diff --git a/vars/local_vars_unittest.yml b/vars/local_vars_unittest.yml index b26a793b7..840d0d9b8 100644 --- a/vars/local_vars_unittest.yml +++ b/vars/local_vars_unittest.yml @@ -12,6 +12,12 @@ # CONNECTING TO YOUR IIAB'S INTERNAL HOTSPOT. See "wifi_up_down: True" below. +# We SKIP roles/network, for FASTER UNIT TESTING! (so IF an internal hotspot +# is later desired, change these two lines to 'True', then run 'iiab-network') +network_install: False +network_enabled: False + + # Ansible's default timeout for "get_url:" downloads (10 seconds) often fails download_timeout: 100 @@ -74,9 +80,10 @@ hostapd_password: changeme # espec if WiFi firmware patched below? #2696 # Raspberry Pi 3 B+ and 4 OS's don't allow more than ~4 students to use the # internal WiFi hotspot. Increase this to 19 or 24 student WiFi devices (or -# 32 on older OS's from 2020) using EXACTLY 1 of the 4 lines below: +# 32 on older OS's from 2020) using EXACTLY 1 of the 5 lines below: # #rpi3bplus_rpi4_wifi_firmware: os # Use your OS's WiFi firmware e.g. 7.45.241 +#rpi3bplus_rpi4_wifi_firmware: ub # Ubuntu-only OLD firmware e.g. 7.45.234 rpi3bplus_rpi4_wifi_firmware: 19 # SEE: github.com/iiab/iiab/issues/2853 #rpi3bplus_rpi4_wifi_firmware: 24 # REQUIRES "wifi_up_down: False" BELOW! #rpi3bplus_rpi4_wifi_firmware: 32 # UNRELIABLE (INTERMITTENT) with 2021+ OS's @@ -86,7 +93,8 @@ rpi3bplus_rpi4_wifi_firmware: 19 # SEE: github.com/iiab/iiab/issues/2853 # Raspberry Pi Zero W and 3 OS's don't allow more than ~10 students to use the # internal WiFi hotspot. Or try increasing this to 30 student WiFi devices: # -rpizerow_rpi3_wifi_firmware: os # Use yr OS WiFi firmware e.g. 7.45.98.118 +rpizerow_rpi3_wifi_firmware: os # Use yr OS WiFi firmware e.g. 7.45.98 +#rpizerow_rpi3_wifi_firmware: ub # Ubuntu-only OLD firmware e.g. 7.45.98.118 #rpizerow_rpi3_wifi_firmware: 30 # Or firmware 7.45.98.65 from 2018-09-28 wifi_up_down: True # AP+STA mode: Uses "ap0" WiFi adapter for upstream WiFi @@ -102,7 +110,7 @@ wan_netmask: # wan_netmask: 255.255.255.0 wan_gateway: # wan_gateway: 192.168.1.254 # If nec wan_nameserver can override ISP-provided DNS servers via dnsmasq: # /etc/resolv.conf dictates which backend is used for the machine itself, so -# 127.0.0.1 means you get dnsmasq (so it works right away on RaspiOS) while +# 127.0.0.1 means you get dnsmasq (so it works right away on RasPiOS) while # 127.0.0.53 gives you systemd-networkd (so Ubuntu itself does NOT use this # dnsmasq-specified upstream DNS [e.g. wan_nameserver] but its LAN clients do!) wan_nameserver: # wan_nameserver: 192.168.1.254 or 8.8.8.8 or 1.1.1.1 @@ -122,16 +130,16 @@ ports_externally_visible: 3 # ssh + http-or-https + common IIAB services # # Or further customize your iptables firewall by editing: # /opt/iiab/iiab/roles/network/templates/gateway/iiab-gen-iptables -# And then run: cd /opt/iiab/iiab; ./iiab-network +# And then run: sudo iiab-network -# Enable AFTER installing IIAB! Then run "cd /opt/iiab/iiab; ./iiab-network" +# Enable AFTER installing IIAB! Then run: sudo iiab-network dns_jail_enabled: False # 1-PREP -# SSHD runs here & also below in 4-SERVER-OPTIONS -sshd_install: True # Required by OpenVPN +# OPENSSH-SERVER +sshd_install: True sshd_enabled: True # https://remote.it can help you remotely maintain an IIAB. @@ -142,17 +150,16 @@ remoteit_enabled: False # remoteit_license_key: 592AA9BB-XXXX-YYYY-ZZZZ-6E27654C3DF6 # SECURITY WARNING: https://wiki.iiab.io/go/Security -openvpn_install: True -openvpn_enabled: True -# 2021-08-18 SSOT: Please set it here, no longer in /etc/iiab/openvpn_handle -openvpn_handle: UNITTEST - Put Your Name Here +# New VPN replaced OpenVPN in Sept 2024: +tailscale_install: True +tailscale_enabled: False # Stub var, doesn't yet do anything! # IIAB-ADMIN runs here - see its vars near top of this file: # e.g. iiab_admin_user, iiab_admin_user_install, iiab_admin_can_sudo # dnsmasq is installed here -- configure LATER in 'network', after Stage 9. # (The full network stage runs after 9-LOCAL-ADDONS. Or manually run -# "cd /opt/iiab/iiab; sudo ./iiab-network"). Design under discussion: #2876 +# "sudo iiab-network"). Design under discussion: #2876 # Some prefer 512MB for Zero W, others prefer 2048MB or higher for RPi 3 and 4. # Please see recommendations at: https://itsfoss.com/swap-size/ @@ -171,13 +178,11 @@ pi_swap_file_size: 1024 # roles/nginx runs here (mandatory) # roles/www_base runs here (mandatory) -# SEE BELOW: nginx_high_php_limits, apache_allow_sudo +# SEE BELOW: nginx_high_php_limits, allow_www_data_poweroff # 4-SERVER-OPTIONS -# SSHD runs here & also above in 1-PREP - # DNS prep (named &/or dhcpd) used to run here. See dnsmasq in 1-PREP above. # Proxy Cache & basic site blocking using /etc/squid allowlists: (whitelists) @@ -193,11 +198,9 @@ bluetooth_install: False bluetooth_enabled: False bluetooth_term_enabled: False -# Show entire contents of USB sticks/drives (at http://box/usb) -iiab_usb_lib_show_all: True -# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf so -# Kolibri can export & import channels to USB sticks/drive: -usb_lib_umask0000_for_kolibri: True +# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf for +# Kolibri exports, and student uploads to teacher's USB stick (http://box/usb) +usb_lib_writable_sticks: True # Common UNIX Printing System (CUPS) cups_install: False @@ -209,20 +212,21 @@ samba_enabled: False # roles/www_options HANDLES THE 3 VARS BELOW: -# For schools using Moodle, or intensively using Matomo/Nextcloud/PBX/WordPress: +# Set to True if intensively using Matomo/PBX/WordPress: nginx_high_php_limits: False -# WARNING: Enabling this might cause excess use of RAM/disk or other resources! -# roles/www_options & roles/moodle FORCE high limits if 'moodle_install: True' -# REGARDLESS: AFTER INSTALLING IIAB, PLEASE VERIFY THESE 6 SETTINGS... +# SIMILARLY: 'moodle_install: True' and 'nextcloud_install: True' effectively +# force this, via roles/www_options & roles/moodle & roles/nextcloud +# WARNING: This might cause excess use of RAM/disk or other resources! +# WARNING: AFTER INSTALLING IIAB, PLEASE VERIFY THESE 6 SETTINGS... # https://github.com/iiab/iiab/blob/master/roles/www_options/tasks/php-settings.yml # ...ARE SUITABLE FOR YOUR HARDWARE, as saved in: /etc/php//*/php.ini -# ALSO: ADJUST "client_max_body_size 500M;" AS NEC, IN: /etc/nginx/server.conf +# ALSO: ADJUST "client_max_body_size 10000M;" AS NEC, IN: /etc/nginx/server.conf -# Make this True to enable http://box/js-menu/menu-files/services/power_off.php -apache_allow_sudo: False +# Make this True to enable http://box/js-menu/menu-files/services/power_off.php and set-server-time.php +allow_www_data_poweroff: False # Toggle iiab-refresh-wiki-docs scraping for offline docs (http://box/info) -nodocs: False +nodocs: True # 5-XO-SERVICES @@ -241,9 +245,9 @@ gitea_enabled: False jupyterhub_install: False jupyterhub_enabled: False -# Lokole (email for rural communities) from https://ascoderu.ca -lokole_install: False -lokole_enabled: False +# UNMAINTAINED: Lokole (email for rural communities) from https://ascoderu.ca +lokole_install: False # 2022-03-13: Python 3.9+ work +lokole_enabled: False # https://github.com/iiab/iiab/issues/3132 # Wikipedia's community editing platform - from MediaWiki.org mediawiki_install: False @@ -287,13 +291,13 @@ kalite_enabled: False # Successor to KA Lite, for offline-first teaching and learning - from learningequality.org kolibri_install: False kolibri_enabled: False -kolibri_language: en # ar,bg-bg,bn-bd,de,el,en,es-es,es-419,fa,fr-fr,ff-cm,gu-in,ha,hi-in,id,it,ka,km,ko,mr,my,nyn,pt-br,pt-mz,sw-tz,te,uk,ur-pk,vi,yo,zh-hans +kolibri_language: en # ar,bg-bg,bn-bd,de,el,en,es-es,es-419,fa,fr-fr,ff-cm,gu-in,ha,hi-in,ht,id,it,ka,km,ko,mr,my,nyn,pt-br,pt-mz,sw-tz,te,uk,ur-pk,vi,yo,zh-hans # kiwix_install: True is REQUIRED, if you install IIAB's Admin Console kiwix_install: False kiwix_enabled: False -# Warning: Moodle is a serious LMS, that takes a while to install. +# Warning: Moodle is a serious LMS, that takes a while to install moodle_install: False moodle_enabled: False # FYI 'nginx_high_php_limits: True' (explained above) is mandated with Moodle, @@ -318,6 +322,7 @@ sugarizer_enabled: False # BitTorrent downloader for large Content Packs etc transmission_install: False transmission_enabled: False +transmission_compile_latest: False # A. UNCOMMENT LANGUAGE(S) TO DOWNLOAD KA Lite VIDEOS TO /library/transmission # using https://pantry.learningequality.org/downloads/ka-lite/0.17/content/ transmission_kalite_languages: @@ -413,11 +418,12 @@ calibre_web_path: calibre #NEEDS WORK: https://github.com/iiab/iiab/issues/529 # Avoid URL collisions w/ calibreweb_url1, calibreweb_url2, calibreweb_url3 below! # A full-featured PBX (for rural telephony, etc) based on Asterisk and FreePBX. -# REQUIRES PHP 7.4 e.g. Ubuntu 20.04, Debian 11 -- RaspiOS 11 might also work. # INSTRUCTIONS: https://github.com/iiab/iiab/tree/master/roles/pbx#readme # If using PBX intensively, investigate nginx_high_php_limits further above. pbx_install: False pbx_enabled: False -pbx_use_apache: True # 2021-08-17: Set either to 'False' if nec -- please +pbx_use_apache: False # 2023-04-03: Set to 'True' if nec -- please also pbx_use_nginx: True # read github.com/iiab/iiab/issues/2914 & #2916, THX! +# 2023-04-03: For EXPERIMENTAL testing on Raspberry Pi... (#3489, PR #3523) +asterisk_rpi_patch: False asterisk_chan_dongle: False diff --git a/vars/raspbian-11.yml b/vars/raspbian-11.yml.unused similarity index 100% rename from vars/raspbian-11.yml rename to vars/raspbian-11.yml.unused diff --git a/vars/raspbian-12.yml b/vars/raspbian-12.yml new file mode 100644 index 000000000..53858b6af --- /dev/null +++ b/vars/raspbian-12.yml @@ -0,0 +1,7 @@ +# Every is_ var is initially set to 'False' at the bottom of +# /opt/iiab/iiab/vars/default_vars.yml -- these 'True' lines override that: +is_debuntu: True +is_debian: True # Opposite of is_ubuntu for now +is_debian_12: True +is_raspbian: True +is_raspbian_12: True diff --git a/vars/raspbian-13.yml b/vars/raspbian-13.yml new file mode 100644 index 000000000..74c906488 --- /dev/null +++ b/vars/raspbian-13.yml @@ -0,0 +1,7 @@ +# Every is_ var is initially set to 'False' at the bottom of +# /opt/iiab/iiab/vars/default_vars.yml -- these 'True' lines override that: +is_debuntu: True +is_debian: True # Opposite of is_ubuntu for now +is_debian_13: True +is_raspbian: True +is_raspbian_13: True diff --git a/vars/ubuntu-2210.yml b/vars/ubuntu-2210.yml.unused similarity index 100% rename from vars/ubuntu-2210.yml rename to vars/ubuntu-2210.yml.unused diff --git a/vars/ubuntu-2304.yml b/vars/ubuntu-2304.yml.unused similarity index 91% rename from vars/ubuntu-2304.yml rename to vars/ubuntu-2304.yml.unused index 07ed43529..72bb3d960 100644 --- a/vars/ubuntu-2304.yml +++ b/vars/ubuntu-2304.yml.unused @@ -16,5 +16,5 @@ is_ubuntu_2304: True # sshd_service: ssh # systemd_location: /lib/systemd/system # php_version: "8.1" -# postgresql_version: 14 -# python_version: "3.10" +# postgresql_version: 15 +# python_version: "3.11" diff --git a/vars/ubuntu-2310.yml.unused b/vars/ubuntu-2310.yml.unused new file mode 100644 index 000000000..165a64a46 --- /dev/null +++ b/vars/ubuntu-2310.yml.unused @@ -0,0 +1,5 @@ +# Every is_ var is initially set to 'False' at the bottom of +# /opt/iiab/iiab/vars/default_vars.yml -- these 'True' lines override that: +is_debuntu: True +is_ubuntu: True # Opposite of is_debian for now +is_ubuntu_2310: True diff --git a/vars/ubuntu-2404.yml b/vars/ubuntu-2404.yml new file mode 100644 index 000000000..d5355dcd0 --- /dev/null +++ b/vars/ubuntu-2404.yml @@ -0,0 +1,5 @@ +# Every is_ var is initially set to 'False' at the bottom of +# /opt/iiab/iiab/vars/default_vars.yml -- these 'True' lines override that: +is_debuntu: True +is_ubuntu: True # Opposite of is_debian for now +is_ubuntu_2404: True diff --git a/vars/ubuntu-2410.yml b/vars/ubuntu-2410.yml new file mode 100644 index 000000000..6120c89a9 --- /dev/null +++ b/vars/ubuntu-2410.yml @@ -0,0 +1,5 @@ +# Every is_ var is initially set to 'False' at the bottom of +# /opt/iiab/iiab/vars/default_vars.yml -- these 'True' lines override that: +is_debuntu: True +is_ubuntu: True # Opposite of is_debian for now +is_ubuntu_2410: True diff --git a/vars/ubuntu-2504.yml b/vars/ubuntu-2504.yml new file mode 100644 index 000000000..a548ba9a1 --- /dev/null +++ b/vars/ubuntu-2504.yml @@ -0,0 +1,5 @@ +# Every is_ var is initially set to 'False' at the bottom of +# /opt/iiab/iiab/vars/default_vars.yml -- these 'True' lines override that: +is_debuntu: True +is_ubuntu: True # Opposite of is_debian for now +is_ubuntu_2504: True