diff --git a/.github/workflows/10min-iiab-test-install.yml b/.github/workflows/10min-iiab-test-install.yml
index 2e567f984..d2b8bd056 100644
--- a/.github/workflows/10min-iiab-test-install.yml
+++ b/.github/workflows/10min-iiab-test-install.yml
@@ -1,4 +1,4 @@
-name: '"10 min" IIAB test install'
+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
@@ -18,7 +18,7 @@ on: [push, pull_request, workflow_dispatch]
jobs:
test-install:
- runs-on: ubuntu-latest
+ 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 }}."
@@ -27,7 +27,7 @@ jobs:
# GITHUB_CONTEXT: ${{ toJSON(github) }}
# run: echo "$GITHUB_CONTEXT"
- name: Check out repository code
- uses: actions/checkout@v3.1.0
+ uses: actions/checkout@v4
- run: echo "🍏 This job's status is ${{ job.status }}."
- name: GitHub Actions "runner" environment
run: |
diff --git a/.github/workflows/30min-iiab-test-install-deb12-on-rpi3.yml b/.github/workflows/30min-iiab-test-install-deb12-on-rpi3.yml
index 9940b2781..a8703346e 100644
--- a/.github/workflows/30min-iiab-test-install-deb12-on-rpi3.yml
+++ b/.github/workflows/30min-iiab-test-install-deb12-on-rpi3.yml
@@ -1,4 +1,4 @@
-name: '"30 min" IIAB test install deb12 on rpi3'
+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
@@ -18,7 +18,7 @@ on: [push, pull_request, workflow_dispatch]
jobs:
test-install:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-22.04
strategy:
matrix:
arch: [debian12]
diff --git a/.github/workflows/30min-iiab-test-install-raspios.yml b/.github/workflows/30min-iiab-test-install-raspios-on-zero2w.yml
similarity index 86%
rename from .github/workflows/30min-iiab-test-install-raspios.yml
rename to .github/workflows/30min-iiab-test-install-raspios-on-zero2w.yml
index ea89758ed..9b521fee6 100644
--- a/.github/workflows/30min-iiab-test-install-raspios.yml
+++ b/.github/workflows/30min-iiab-test-install-raspios-on-zero2w.yml
@@ -1,4 +1,4 @@
-name: '"30 min" IIAB test install raspios'
+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
@@ -18,7 +18,7 @@ on: [push, pull_request, workflow_dispatch]
jobs:
test-install:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-22.04
strategy:
matrix:
arch: [aarch64] #[zero_raspbian, zero_raspios, zero2_raspios, aarch64]
@@ -65,13 +65,13 @@ jobs:
uname -a # uname -srm
whoami # Typically 'root' instead of 'runner'
pwd # /home/runner/work/iiab/iiab == $GITHUB_WORKSPACE == ${{ github.workspace }}
- sudo apt-get update -y --allow-releaseinfo-change
- sudo apt-get install --no-install-recommends -y git
+ apt-get update -y --allow-releaseinfo-change
+ apt-get install --no-install-recommends -y git
ls /opt/iiab/iiab
- sudo mkdir /etc/iiab
- sudo cp /opt/iiab/iiab/vars/local_vars_none.yml /etc/iiab/local_vars.yml
- sudo /opt/iiab/iiab/scripts/ansible
- sudo ./iiab-install
+ 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 8b4a07b84..4ddde9b53 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,3 +1,3 @@
-# SEE THE NEW
[github.com/iiab/iiab/wiki/Technical-Contributors-Guide](https://github.com/iiab/iiab/wiki/Technical-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 33776a06e..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-2024, 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 2fcb5085c..fbfd30d35 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ You can build your own tiny, affordable server (an offline digital library) for
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)!*
@@ -18,7 +18,7 @@ FYI this [community product](https://en.wikipedia.org/wiki/Internet-in-a-Box) is
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 (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:
+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.
@@ -35,7 +35,7 @@ Finally, you can [customize your Internet-in-a-Box home page](https://wiki.iiab.
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)
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 7b8738c4d..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.14.13 # 2023-05-22: ansible-core 2.12 EOL 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.
+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 100%
rename from roles/openvpn/defaults/main.yml
rename to roles/0-DEPRECATED-ROLES/openvpn/defaults/main.yml
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 100%
rename from roles/openvpn/tasks/install.yml
rename to roles/0-DEPRECATED-ROLES/openvpn/tasks/install.yml
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 100%
rename from roles/openvpn/templates/iiab-support
rename to roles/0-DEPRECATED-ROLES/openvpn/templates/iiab-support
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/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 383f911a3..dee75addd 100644
--- a/roles/0-init/tasks/validate_vars.yml
+++ b/roles/0-init/tasks/validate_vars.yml
@@ -71,7 +71,8 @@
- dnsmasq
- bluetooth
- sshd
- - openvpn
+ #- openvpn # Deprecated
+ - tailscale
- remoteit
- admin_console
#- nginx # MANDATORY
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/2-common/tasks/packages.yml b/roles/2-common/tasks/packages.yml
index 95b227d95..681d8b83f 100644
--- a/roles/2-common/tasks/packages.yml
+++ b/roles/2-common/tasks/packages.yml
@@ -29,7 +29,6 @@
- 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/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/7-edu-apps/tasks/main.yml b/roles/7-edu-apps/tasks/main.yml
index c5f15e117..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:
diff --git a/roles/8-mgmt-tools/tasks/main.yml b/roles/8-mgmt-tools/tasks/main.yml
index 8771b66a0..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:
diff --git a/roles/calibre-web/README.rst b/roles/calibre-web/README.rst
index 807eba1b8..a29896573 100644
--- a/roles/calibre-web/README.rst
+++ b/roles/calibre-web/README.rst
@@ -25,9 +25,9 @@ download e-books using a
Teachers upload e-books, adjust e-book metadata, and create custom "bookshelf"
collections — to help students build the best local community library!
-**NEW AS OF DECEMBER 2023: If you install** `IIAB's new version of Calibre-Web `_
-**then you can also add YouTube and Vimeo videos (ETC) to your community or
-family's learning library!**
+**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
@@ -108,6 +108,10 @@ 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
@@ -153,26 +157,31 @@ as it contains your Calibre-Web content **and** configuration settings!
Upgrading
---------
-"Reinstalling" Calibre-Web automatically installs 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** configuration 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, as root**::
+**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
@@ -224,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 d4b2765a4..3e99725a9 100644
--- a/roles/calibre-web/defaults/main.yml
+++ b/roles/calibre-web/defaults/main.yml
@@ -14,7 +14,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!
-calibreweb_repo_url: https://github.com/janeczku/calibre-web
+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!)
diff --git a/roles/calibre-web/files/app.db b/roles/calibre-web/files/app.db
index 01c0f0383..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/install.yml b/roles/calibre-web/tasks/install.yml
index 75474a33c..d293afe23 100644
--- a/roles/calibre-web/tasks/install.yml
+++ b/roles/calibre-web/tasks/install.yml
@@ -1,13 +1,32 @@
+# 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: "Install packages: imagemagick, python3-netifaces"
+- 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-netifaces
+ #- 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
@@ -19,6 +38,13 @@
# 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
@@ -26,19 +52,9 @@
backrefs: yes
line: ' '
state: present
+ when: imagemagick6_policy_xml.stat.exists
-- name: "Remove previous virtual environment {{ calibreweb_venv_path }} -- if 'calibreweb_venv_wipe: True'"
- file:
- path: "{{ calibreweb_venv_path }}"
- state: absent
- when: calibreweb_venv_wipe
-
-- name: Does {{ calibreweb_venv_path }} exist?
- stat:
- path: "{{ calibreweb_venv_path }}" # /usr/local/calibre-web-py3
- register: calibreweb_venv
-
-- 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 }}"
@@ -47,7 +63,6 @@
with_items:
- "{{ calibreweb_home }}" # /library/calibre-web
- "{{ calibreweb_config }}" # /library/calibre-web/config
- - "{{ calibreweb_venv_path }}"
# FYI since May 2021, Calibre-Web (major releases) can be installed with pip:
# https://pypi.org/project/calibreweb/
@@ -56,28 +71,66 @@
# https://github.com/janeczku/calibre-web/pull/927
# https://github.com/janeczku/calibre-web/pull/1459
-- name: "Clone i.e. download Calibre-Web ({{ calibreweb_version }}) from {{ calibreweb_repo_url }} to {{ calibreweb_venv_path }} (~114 MB initially, ~210+ MB later) -- if {{ calibreweb_venv_path }} created just above"
+- 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: "{{ calibreweb_repo_url }}" # e.g. https://github.com/janeczku/calibre-web
+ 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 # 2023-11-04: Full clone for now, to help @deldesir & wider community testing
- version: "{{ calibreweb_version }}" # e.g. master, 0.6.21
+ #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
-- name: If Calibre-Web is being enhanced with audio/video "books" too, install/upgrade additional prereqs (CAN TAKE 3+ MINUTES, WIP)
+- 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
- pipx upgrade --include-injected xklb
+ if pipx list | grep -q 'xklb'; then
+ pipx uninstall xklb
+ pipx install library
+ else
+ pipx reinstall library
+ fi
else
- pipx install xklb
- ln -sf /root/.local/bin/lb /usr/local/bin/lb
- ln -sf /root/.local/share/pipx/venvs/xklb/bin/yt-dlp /usr/local/bin/yt-dlp
+ pipx install library
fi
- cp {{ calibreweb_venv_path }}/scripts/lb-wrapper {{ calibreweb_venv_path }}/scripts/lb-wrapper.greedy /usr/local/bin/
- chmod a+x /usr/local/bin/lb-wrapper /usr/local/bin/lb-wrapper.greedy
+ 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 }}
@@ -85,16 +138,19 @@
requirements: "{{ calibreweb_venv_path }}/requirements.txt"
virtualenv: "{{ calibreweb_venv_path }}" # /usr/local/calibre-web-py3
#virtualenv_site_packages: no
- virtualenv_command: python3 -m venv --system-site-packages {{ calibreweb_venv_path }}
+ #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#python-on-raspberry-pi
-# https://www.raspberrypi.com/documentation/computers/os.html#using-pip-with-virtual-environments
+# 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 (prepends '/usr/local/calibre-web-py3/bin' to yr PATH)
+# . 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
diff --git a/roles/cups/tasks/install.yml b/roles/cups/tasks/install.yml
index e4e2e04ed..55209a50b 100644
--- a/roles/cups/tasks/install.yml
+++ b/roles/cups/tasks/install.yml
@@ -58,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"
diff --git a/roles/firmware/templates/iiab-check-firmware b/roles/firmware/templates/iiab-check-firmware
index a7a36a626..f10cd752b 100644
--- a/roles/firmware/templates/iiab-check-firmware
+++ b/roles/firmware/templates/iiab-check-firmware
@@ -19,7 +19,7 @@
# 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#L23-L39
-# https://github.com/iiab/iiab/blob/master/roles/openvpn/templates/iiab-support READS AND WRITES, INCL NON-BOOLEAN
+# 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/")
@@ -60,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/gitea/defaults/main.yml b/roles/gitea/defaults/main.yml
index c318acfd7..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.21" # 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.
+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
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/pwd-warnings.yml b/roles/iiab-admin/tasks/pwd-warnings.yml
index 46d091bec..600a935bb 100644
--- a/roles/iiab-admin/tasks/pwd-warnings.yml
+++ b/roles/iiab-admin/tasks/pwd-warnings.yml
@@ -8,17 +8,17 @@
dest: /etc/profile.d/iiab-pwdwarn-profile.sh
mode: '0644'
-- name: Does /home/{{ iiab_admin_user }}/.config/wayfire.ini exist?
+- name: Does directory /home/{{ iiab_admin_user }}/.config/labwc/ exist?
stat:
- path: /home/{{ iiab_admin_user }}/.config/wayfire.ini
- register: wayfire_ini
+ path: /home/{{ iiab_admin_user }}/.config/labwc/
+ register: labwc_dir
-- name: "If so, install from template: /usr/local/sbin/iiab-pwdwarn-wayfire"
+- name: "If so, install from template: /usr/local/sbin/iiab-pwdwarn-labwc"
template:
- src: iiab-pwdwarn-wayfire.j2
- dest: /usr/local/sbin/iiab-pwdwarn-wayfire
+ src: iiab-pwdwarn-labwc.j2
+ dest: /usr/local/sbin/iiab-pwdwarn-labwc
mode: '0755'
- when: wayfire_ini.stat.exists
+ when: labwc_dir.stat.exists and labwc_dir.stat.isdir
# 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
@@ -28,10 +28,9 @@
# 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 /home/{{ iiab_admin_user }}/.config/wayfire.ini to trigger iiab-pwdwarn-wayfire (& pop-up as nec)
- ini_file:
- path: /home/{{ iiab_admin_user }}/.config/wayfire.ini # iiab-admin
- section: autostart
- option: iiab-pwdwarn-wayfire
- value: /usr/local/sbin/iiab-pwdwarn-wayfire
- when: wayfire_ini.stat.exists
+- name: ...and put a line in /home/{{ iiab_admin_user }}/.config/labwc/autostart to trigger iiab-pwdwarn-labwc (& pop-up as nec)
+ lineinfile:
+ 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/iiab-pwdwarn-wayfire.j2 b/roles/iiab-admin/templates/iiab-pwdwarn-labwc.j2
similarity index 100%
rename from roles/iiab-admin/templates/iiab-pwdwarn-wayfire.j2
rename to roles/iiab-admin/templates/iiab-pwdwarn-labwc.j2
diff --git a/roles/internetarchive/tasks/install.yml b/roles/internetarchive/tasks/install.yml
index b6df58f01..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 }}) <= 20.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('20.x', '<=')
- fail_msg: "Internet Archive install cannot proceed, as it currently requires Node.js 10.x - 20.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'"
diff --git a/roles/jupyterhub/tasks/install.yml b/roles/jupyterhub/tasks/install.yml
index 4e23f9ccc..57a503014 100644
--- a/roles/jupyterhub/tasks/install.yml
+++ b/roles/jupyterhub/tasks/install.yml
@@ -17,11 +17,11 @@
shell: df -B1 --output=used / | tail -1
register: df1
-
-- name: "Install package: python3-psutil"
- package:
- name: python3-psutil
- state: present
+# 2025-02-16
+#- name: "Install package: python3-psutil"
+# package:
+# name: python3-psutil
+# state: present
- name: Remove previous virtual environment {{ jupyterhub_venv }}
file:
@@ -43,15 +43,16 @@
global: yes
state: latest
-- name: "pip install 3 packages into virtual environment: {{ jupyterhub_venv }} (~326 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 --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_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 --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
@@ -67,8 +68,9 @@
- jupyterhub-systemdspawner
- ipywidgets
virtualenv: "{{ jupyterhub_venv }}"
- virtualenv_site_packages: no
- virtualenv_command: python3 -m venv --system-site-packages "{{ jupyterhub_venv }}"
+ #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"
diff --git a/roles/kalite/tasks/install.yml b/roles/kalite/tasks/install.yml
index bcf667d43..5738c7301 100644
--- a/roles/kalite/tasks/install.yml
+++ b/roles/kalite/tasks/install.yml
@@ -15,32 +15,20 @@
# 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 # 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: (is_debian_11 is defined and is_debian_11) or (is_ubuntu_2204 is defined and is_ubuntu_2204) # Covers is_raspbian_11 and is_linuxmint_21, and is more future-proof than...
- #when: not (is_debian_12 or is_ubuntu_2304 or is_ubuntu_2310)
- # 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: Install Ubuntu keyrings on Debian
-# get_url:
-# url:
-# dest: /etc/apt/keyrings/
-# mode: 0644
-# timeout: "{{ download_timeout }}"
-# when: is_debian_12
-
-# use key retrieval from mongodb
-- name: Use scripts/install_python2.sh to install python2 and virtualenv
+- 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: not ((is_debian_11 is defined and is_debian_11) or (is_ubuntu_2204 is defined and is_ubuntu_2204)) # Also avoids is_raspbian_11 and is_linuxmint_21, and is more future-proof than...
- #when: is_debian_12 or is_ubuntu_2304 or is_ubuntu_2310
+ when: is_debian_12 # Also covers is_raspbian_12
-- name: Use pip to pin setuptools to 44 in {{ kalite_venv }} # WAS: if Raspbian/Debian > 10 or Ubuntu > 19
+- 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
@@ -48,10 +36,9 @@
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 }}"
@@ -60,6 +47,14 @@
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:
@@ -70,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:
diff --git a/roles/kolibri/defaults/main.yml b/roles/kolibri/defaults/main.yml
index d1529fb60..80eb0c352 100644
--- a/roles/kolibri/defaults/main.yml
+++ b/roles/kolibri/defaults/main.yml
@@ -26,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
#
diff --git a/roles/kolibri/tasks/install.yml b/roles/kolibri/tasks/install.yml
index f0a06d292..d95f36044 100644
--- a/roles/kolibri/tasks/install.yml
+++ b/roles/kolibri/tasks/install.yml
@@ -76,17 +76,20 @@
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)
+# 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
+# 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 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:
@@ -121,6 +124,15 @@
# 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:
name: kolibri
diff --git a/roles/mediawiki/defaults/main.yml b/roles/mediawiki/defaults/main.yml
index 77a233ac1..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.41" # "1.40" quotes nec if trailing zero
+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/moodle/defaults/main.yml b/roles/moodle/defaults/main.yml
index 4597665b1..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!
-# 2023-04-25: Currently testing Moodle's master branch is mandatory if your
-# OS PHP >= 8.3, see moodle/tasks/install.yml for detail! OR, *IF* your
-# OS PHP < 8.3, then {{ moodle_version }} will be attempted:
-moodle_version: MOODLE_403_STABLE # Moodle 4.3
-#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 7a33421ae..00cf13066 100644
--- a/roles/moodle/tasks/install.yml
+++ b/roles/moodle/tasks/install.yml
@@ -96,21 +96,21 @@
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 }} (~403 MB initially, ~431 MB later) if OS PHP {{ php_version }} < 8.3
+- 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_403_STABLE (Moodle 4.3)
- when: php_version is version('8.3', '<')
+ 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 'master' to {{ moodle_base }} (~403 MB initially, ~431 MB later) if OS PHP {{ php_version }} >= 8.3"
+- 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: 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, 4.3dev in May 2023, 4.4dev in Oct 2023)
- when: php_version is version('8.3', '>=')
+ 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:
diff --git a/roles/munin/tasks/install.yml b/roles/munin/tasks/install.yml
index 3895b7bf9..89fe254cf 100644
--- a/roles/munin/tasks/install.yml
+++ b/roles/munin/tasks/install.yml
@@ -9,7 +9,7 @@
name: net.ipv6.conf.all.disable_ipv6
value: 0
-- name: "Install 5 packages: libcgi-fast-perl, munin, munin-node, munin-plugins-extra, python3-passlib"
+- name: "Install 4 packages: libcgi-fast-perl, munin, munin-node, munin-plugins-extra"
package:
name:
#- libapache2-mod-fcgid
@@ -17,9 +17,15 @@
- 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:
diff --git a/roles/mysql/tasks/install.yml b/roles/mysql/tasks/install.yml
index 87bcd9c1a..1b8a04388 100644
--- a/roles/mysql/tasks/install.yml
+++ b/roles/mysql/tasks/install.yml
@@ -3,16 +3,22 @@
register: df1
-- name: 'Install MySQL packages: mariadb-server, mariadb-client, php{{ php_version }}-mysql, python3-pymysql'
+- 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
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 9cb2cf1db..a0af7adcc 100644
--- a/roles/network/tasks/NM-debian.yml
+++ b/roles/network/tasks/NM-debian.yml
@@ -78,7 +78,7 @@
- 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/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 4d64bf843..c845bd637 100644
--- a/roles/network/tasks/hostapd.yml
+++ b/roles/network/tasks/hostapd.yml
@@ -3,28 +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 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
- when: wifi_up_down and can_be_ap and has_wifi_gateway is defined
-
-- name: Set Wifi Region country code for hostapd when present
- set_fact:
- host_country_code: "{{ REG_DOM.stdout }}"
- when: REG_DOM.stdout is defined and REG_DOM.stdout | length > 0
-
-- 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: Setting WiFi channel to {{ current_client_channel.stdout }}
set_fact:
host_channel: "{{ current_client_channel.stdout }}"
@@ -131,14 +115,3 @@
value: "{{ host_country_code }}"
- 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/install.yml b/roles/network/tasks/install.yml
index 680b95233..f7c1a5b9a 100644
--- a/roles/network/tasks/install.yml
+++ b/roles/network/tasks/install.yml
@@ -18,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
@@ -32,10 +32,18 @@
- 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?
- 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)
diff --git a/roles/network/tasks/main.yml b/roles/network/tasks/main.yml
index 7a1e6d5f5..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
@@ -68,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
@@ -101,6 +103,11 @@
# 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 2ce6aaac0..78aae19be 100644
--- a/roles/network/tasks/netwarn.yml
+++ b/roles/network/tasks/netwarn.yml
@@ -5,18 +5,17 @@
# shell / ssh logins (across all OS's/distros/window managers) might also make sense?
-- name: Does /home/{{ iiab_admin_user }}/.config/wayfire.ini exist?
+- name: Does directory /home/{{ iiab_admin_user }}/.config/labwc/ exist?
stat:
- path: /home/{{ iiab_admin_user }}/.config/wayfire.ini
- register: wayfire_ini
+ path: /home/{{ iiab_admin_user }}/.config/labwc/
+ register: labwc_dir
-- name: If so, add /usr/local/sbin/iiab-netwarn to /home/{{ iiab_admin_user }}/.config/wayfire.ini
- ini_file:
- path: /home/{{ iiab_admin_user }}/.config/wayfire.ini # iiab-admin
- section: autostart
- option: iiab-netwarn
- value: /usr/local/sbin/iiab-netwarn
- when: wayfire_ini.stat.exists
+- name: If so, add '/usr/local/sbin/iiab-netwarn &' to /home/{{ iiab_admin_user }}/.config/labwc/autostart
+ lineinfile:
+ 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
@@ -45,4 +44,4 @@
src: roles/network/templates/netwarn/iiab-netwarn # Invoked by 1-prep (so full path needed)
dest: /usr/local/sbin/
mode: 0755
- when: wayfire_ini.stat.exists 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 ec1dda7b6..d5de9e27d 100644
--- a/roles/network/tasks/restart.yml
+++ b/roles/network/tasks/restart.yml
@@ -12,7 +12,7 @@
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: Enable & Restart networkd-dispatcher.service
systemd:
@@ -28,12 +28,16 @@
state: restarted
when: wifi_up_down and can_be_ap and ansible_ap0 is undefined
-- name: Restart hostapd when WiFi is present but not when using WiFi as gateway with wifi_up_down False
+- 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
@@ -107,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 fc02dccd7..e85c673dd 100644
--- a/roles/network/tasks/rpi_debian.yml
+++ b/roles/network/tasks/rpi_debian.yml
@@ -53,10 +53,11 @@
line: country={{ host_country_code }}
when: country_code.stdout is defined and country_code.stdout | length == 0
-# This should go away, should only be unblocked by raspi-config
-- 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:
diff --git a/roles/network/templates/gateway/iiab-gen-iptables b/roles/network/templates/gateway/iiab-gen-iptables
index 0a8b6a80e..77717a748 100755
--- a/roles/network/templates/gateway/iiab-gen-iptables
+++ b/roles/network/templates/gateway/iiab-gen-iptables
@@ -39,7 +39,7 @@ IPTABLES_DATA=/etc/sysconfig/iptables
# 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#L23-L39
-# https://github.com/iiab/iiab/blob/master/roles/openvpn/templates/iiab-support READS AND WRITES, INCL NON-BOOLEAN
+# 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 25a5053be..fb45603a6 100755
--- a/roles/network/templates/hostapd/iiab-hotspot-off
+++ b/roles/network/templates/hostapd/iiab-hotspot-off
@@ -14,7 +14,7 @@ echo " IIAB hotspot access point Disabled"
#exit 0
{% else %}
echo " IIAB hotspot access point Disabled"
-{% if is_raspbian %}
+{% if dhcpcd_result == "enabled" %}
# hotspot-off before ap0_updown
sed -i "s/^denyinterfaces/#denyinterfaces/" /etc/dhcpcd.conf
#systemctl disable dnsmasq
@@ -37,7 +37,7 @@ fi
echo -e "\nIf you're enabling upstream WiFi, please reboot now.\n"
#exit 0
{% endif %}
-#is_raspbian
+#if dhcpcd_result == "enabled"
{% endif %}
#wifi_up_down
{% endif %}
diff --git a/roles/network/templates/hostapd/iiab-hotspot-on b/roles/network/templates/hostapd/iiab-hotspot-on
index 03ca2d4ae..35ccc7adf 100755
--- a/roles/network/templates/hostapd/iiab-hotspot-on
+++ b/roles/network/templates/hostapd/iiab-hotspot-on
@@ -16,7 +16,7 @@ systemctl enable hostapd
systemctl enable iiab-wifi-test.service
#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 "s/^#denyinterfaces/denyinterfaces/" /etc/dhcpcd.conf
@@ -44,7 +44,7 @@ fi
systemctl enable hostapd
#exit 0
{% endif %}
-#is_raspbian
+#if dhcpcd_result == "enabled"
{% endif %}
#wifi_up_down
{% endif %}
diff --git a/roles/network/templates/netwarn/iiab-netwarn b/roles/network/templates/netwarn/iiab-netwarn
index b20d18fc6..87865e0f1 100755
--- a/roles/network/templates/netwarn/iiab-netwarn
+++ b/roles/network/templates/netwarn/iiab-netwarn
@@ -3,7 +3,10 @@
# 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 Wayfire's ~/.config/wayfire.ini for RasPiOS 12+:
+# ...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.
diff --git a/roles/nextcloud/README.md b/roles/nextcloud/README.md
index e74518b32..c0eb0f9b3 100644
--- a/roles/nextcloud/README.md
+++ b/roles/nextcloud/README.md
@@ -42,7 +42,7 @@ Useful PHP recommendations for these settings (while largely tailored to WordPre
- 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/27/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
diff --git a/roles/nextcloud/tasks/install.yml b/roles/nextcloud/tasks/install.yml
index d82f040bb..37429ea0e 100644
--- a/roles/nextcloud/tasks/install.yml
+++ b/roles/nextcloud/tasks/install.yml
@@ -131,7 +131,7 @@
# 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 }} (~176 MB) to {{ nextcloud_root_dir }} (~616 MB initially, sometimes ~655 MB later, {{ apache_user }}:{{ apache_user }})
+- 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 }}"
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/templates/iiab.conf.j2 b/roles/nginx/templates/iiab.conf.j2
index df2fc6a94..20773967f 100644
--- a/roles/nginx/templates/iiab.conf.j2
+++ b/roles/nginx/templates/iiab.conf.j2
@@ -5,10 +5,25 @@ 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 {
diff --git a/roles/pbx/README.adoc b/roles/pbx/README.adoc
index a69906f01..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 December 2023, IIAB installs https://wiki.asterisk.org/wiki/display/AST/Asterisk+20+Documentation[Asterisk 20] 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 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]) — sadly this remains true in December 2023, and will likely remain true until https://github.com/FreePBX/framework/tree/release/17.0[FreePBX 17] is eventually released — so please consider installing on https://github.com/iiab/iiab/wiki/IIAB-Platforms#operating-systems[Debian 11 "Bullseye", or 64-bit Raspberry Pi OS versions based on "Bullseye"] (https://github.com/iiab/iiab/pull/3523[PR #3523]).*
+////
+*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"].
@@ -355,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/defaults/main.yml b/roles/pbx/defaults/main.yml
index 2cc6eece6..647ad700d 100644
--- a/roles/pbx/defaults/main.yml
+++ b/roles/pbx/defaults/main.yml
@@ -26,13 +26,13 @@
asterisk_url: https://downloads.asterisk.org/pub/telephony/asterisk
-asterisk_src_file: asterisk-20-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/tasks/freepbx.yml b/roles/pbx/tasks/freepbx.yml
index 8ca2cd83f..1bba7773c 100644
--- a/roles/pbx/tasks/freepbx.yml
+++ b/roles/pbx/tasks/freepbx.yml
@@ -256,19 +256,22 @@
args:
chdir: "{{ freepbx_src_dir }}"
#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/postgresql/tasks/install.yml b/roles/postgresql/tasks/install.yml
index f07cf943d..ce14600c5 100644
--- a/roles/postgresql/tasks/install.yml
+++ b/roles/postgresql/tasks/install.yml
@@ -3,14 +3,20 @@
register: df1
-- name: 'Install packages: postgresql, postgresql-client, python3-psycopg2'
+- 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
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 051d3b7f5..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 [2023](https://remote.it/pricing/), 5 IIAB devices can be managed for free (their personal / non-commercial plan) and larger numbers 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?"
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/sugarizer/defaults/main.yml b/roles/sugarizer/defaults/main.yml
index 925e087b6..ad5e48843 100644
--- a/roles/sugarizer/defaults/main.yml
+++ b/roles/sugarizer/defaults/main.yml
@@ -9,8 +9,8 @@
# 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.7.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_git_version: v1.7.0 # WAS: v1.0.1, master, v1.1.0, v1.2.0, v1.3.0, v1.4.0, v1.5.0, v1.6.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.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
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 727197b56..a851fe591 100644
--- a/roles/transmission/README.rst
+++ b/roles/transmission/README.rst
@@ -86,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
---------------
diff --git a/roles/usb_lib/README.rst b/roles/usb_lib/README.rst
index c27dc0e53..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 @@
+
+
+
+
+
+
+