diff --git a/.github/workflows/10min-iiab-test-install.yml b/.github/workflows/10min-iiab-test-install.yml index 24dfc6c79..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 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/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/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-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 e39bea703..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: -# allow_www_data_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/firmware/templates/iiab-check-firmware b/roles/firmware/templates/iiab-check-firmware index b2f7a1cce..f10cd752b 100644 --- a/roles/firmware/templates/iiab-check-firmware +++ b/roles/firmware/templates/iiab-check-firmware @@ -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/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/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/main.yml b/roles/network/tasks/main.yml index 7e2f1eabb..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 @@ -108,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/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/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/nextcloud/tasks/install.yml b/roles/nextcloud/tasks/install.yml index d0588aac9..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 }} (~180 MB) to {{ nextcloud_root_dir }} (~687 MB initially, sometimes ~721 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/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/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/usb_lib/README.rst b/roles/usb_lib/README.rst index 22fd711d2..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 https://FAQ.IIAB.IO FOR UP-TO-DATE DOCUMENTATION.** +**PLEASE SEE** `"Can teachers display their own content?" `_ **AND** `"Can students upload their own work?" `_ **WITHIN https://FAQ.IIAB.IO FOR UP-TO-DATE DOCUMENTATION!** -This role implements functionality similar to LibraryBox, to mount "teacher content" from USB drives. +This role (1) implements functionality similar to LibraryBox, to mount "teacher content" from USB sticks / drives for students, and (2) allows students to upload their work to the teacher's USB stick / drive: -Users should have nearly immediate access to this "teacher content" (on all inserted USB drives) by browsing to http://box/usb +#. Students should have nearly immediate access to "teacher content" (on all inserted USB sticks) by browsing to http://box/usb. +#. Students can also click the "Upload to USB" button on top of this same page (http://box/usb), to upload their work to the teacher's USB stick. (FYI student uploads appear in folders like ``UPLOADS.YYYY-MM-DD`` within the root of the teacher's USB stick). -Automount is handled by usbmount, and scripts in this role look in the root of the mounted drive for... +As of January 2025, automount is handled by usbmount: (`devmon included with udevil `_ might be considered in future) -* /usb -* /USB -* /share -* /Share -* /Piratebox/Share +* A script in this role (/etc/usbmount/mount.d/70-usb-library) looks in the root of the mounted USB stick for folder /PUBLIC and if found, creates a symlink of the form /library/www/html/local_content/USBn pointing to /media/usbn/PUBLIC — where n is generally one of {0, 1, 2, 3, 4, 5, 6, 7}. *RESULT: Only documents within /PUBLIC are browsable by students.* This option is very useful to **prevent students from copying uploaded homework!** +* If however folder /PUBLIC is not found, the symlink is created to the root of the mounted USB stick. *RESULT: EVERYTHING on the USB stick is browsable by students — just like with a traditional community bulletin board.* This option is very useful when students are uploading artwork, photo essays, personal audio recordings and **science projects that are intended to be shared!** -...and if found, creates a symlink of the form /library/www/html/local_content/USBn pointing to /media/usbn — where n is generally one of {0, 1, 2, 3, 4, 5, 6, 7}. +Technical Details: -USB drives must be formatted with one of the filesystems listed under "FILESYSTEMS=" at ``/etc/usbmount/usbmount.conf`` — these are specified on/around Line 76 of: `/opt/iiab/iiab/roles/usb_lib/tasks/install.yml `_ +* USB sticks / drives must be formatted with one of the filesystems listed under "FILESYSTEMS=" at ``/etc/usbmount/usbmount.conf`` — these are specified on/around Line 17 of: `/opt/iiab/iiab/roles/usb_lib/files/usbmount/usbmount.conf `_ -IIAB will generally mount USB drives 'rw' allowing root to both read and write to them. In addition, in March 2021 (`PR #2715 `_) Kolibri exports were enabled by also giving non-root users read and write access to VFAT/FAT32, NTFS and exFAT USB drives, using ``umask=0000`` (in /etc/usbmount/usbmount.conf) to override the ``umask=0022`` default. If however you prefer to restore usbmount's default, set ``usb_lib_umask0000_for_kolibri: False`` in `/etc/iiab/local_vars.yml `_ (preferably do this prior to installing IIAB). +* If your IIAB was built on a Graphical Desktop OS (instead of a headless OS, like Raspberry Pi OS Lite), USB sticks will problematically be mounted twice by default, once by usbmount and once by the desktop. You must disable the automount function in the Desktop in order to use the "Upload to USB" functionality, which allows students to upload their work to your USB stick. -Official `usbmount 0.0.22 (2011-08-08) `_ documentation: + * EXAMPLE: To disable Desktop automount within "Raspberry Pi OS with desktop", go to File Manager (pcmanfm) → Edit → Preferences → Volume Management, and uncheck "Mount removable media automatically when they are inserted". -* https://github.com/hfuchs/usbmount/blob/master/README (2010-08-11) -* https://github.com/rbrito/usbmount/blob/master/README.md (2018-08-10) -* https://github.com/rbrito/usbmount/blob/master/usbmount.conf (2010-04-25) +* IIAB will generally mount USB sticks / drives 'rw' allowing root to both read and write to them. In addition, in March 2021 (`PR #2715 `_) Kolibri exports were enabled, by also giving non-root users read and write access to VFAT/FAT32, NTFS and exFAT USB sticks — using ``umask=0000`` (in /etc/usbmount/usbmount.conf) to override the ``umask=0022`` default. This ``umask=0000`` is also required for students to upload to the teachers's VFAT/FAT32, NTFS and exFAT USB sticks, as introduced in January 2025 (`PR #3875 `_). If, however, you prefer to restore usbmount's default, set ``usb_lib_writable_sticks: False`` in `/etc/iiab/local_vars.yml `_ — please do this prior to installing IIAB — so you don't have to run: ``cd /opt/iiab/iiab ; ./runrole --reinstall usb_lib`` -Legacy warning: There is also a patch for problems with automount on Fedora 21+. Please note that as of 4.1.8-200.fc22.x86_64 not all USB drives will mount, even with this patch. +* Official `usbmount 0.0.22 (2011-08-08) `_ documentation: + + * https://github.com/hfuchs/usbmount/blob/master/README (2010-08-11) + * https://github.com/rbrito/usbmount/blob/master/README.md (2018-08-10) + * https://github.com/rbrito/usbmount/blob/master/usbmount.conf (2010-04-25) + +* Dev Notes at the top of: https://github.com/iiab/iiab/blob/master/roles/usb_lib/tasks/install.yml + + * January 2025 work to improve automount reliability during boot: `PR #3916 `_ diff --git a/roles/usb_lib/defaults/main.yml b/roles/usb_lib/defaults/main.yml index 2a4b19308..f7cbf10b6 100644 --- a/roles/usb_lib/defaults/main.yml +++ b/roles/usb_lib/defaults/main.yml @@ -1,12 +1,9 @@ # usb_lib_install: True # usb_lib_enabled: True -# Show entire contents of USB sticks/drives (at http://box/usb) -# iiab_usb_lib_show_all: True - -# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf so -# Kolibri can export & import channels to USB sticks/drive: -# usb_lib_umask0000_for_kolibri: True +# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf for +# Kolibri exports, and student uploads to teacher's USB stick (http://box/usb) +# usb_lib_writable_sticks: True # All above are set in: github.com/iiab/iiab/blob/master/vars/default_vars.yml # If nec, change them by editing /etc/iiab/local_vars.yml prior to installing! diff --git a/roles/usb_lib/files/upload2usb/button.html b/roles/usb_lib/files/upload2usb/button.html new file mode 100644 index 000000000..52cc493ce --- /dev/null +++ b/roles/usb_lib/files/upload2usb/button.html @@ -0,0 +1,19 @@ + +Upload to USB diff --git a/roles/usb_lib/files/upload2usb/error.php b/roles/usb_lib/files/upload2usb/error.php new file mode 100644 index 000000000..46dd0e667 --- /dev/null +++ b/roles/usb_lib/files/upload2usb/error.php @@ -0,0 +1,15 @@ + +ERROR: Please make sure one and ONLY one (no more, no less) removable USB stick is plugged into your Internet-in-a-Box. Please see IIAB FAQ, "Can students upload their own work?", for additional support. + +

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

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

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

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

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

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

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

"); + } + return $target_folder_path; +} + +//return number of files within a specified folder +function getFileCount ($folder_path) { + return count(glob($folder_path . "/*")); +} + +//check if file mimetype is acceptable for upload +function isFileMimeTypeAcceptable ($file) { + $mimetype = strtolower(mime_content_type($file)); + $invalid_mimetypes_str = array ("compress", "image/svg+xml", "octet", "text/xml", "xhtml+xml"); + foreach ($invalid_mimetypes_str as $invalid_mt_str) { + if (str_contains($mimetype, $invalid_mt_str)) { + error_log('UPLOAD2USB ERROR - MIMETYPE: ' . $mimetype); + return false; + } + } + return true; +} + +//check file content to see if it's unique or not +function isFileContentUnique ($target_folder_path, $file) { + $file_to_upload_md5 = md5_file($file); + $usb_dir = array_diff(scandir($target_folder_path), array('..', '.')); + foreach ($usb_dir as $dir_file) { + $dir_file = $target_folder_path . "/" . $dir_file; + + if (!is_dir($dir_file)) { + $dir_file_md5 = md5_file($dir_file); + if ($file_to_upload_md5 == $dir_file_md5) { + return false; + } + } + } + return true; +} + +//return unique filename +function getUniqueFileName ($target_folder_path, $filename) { + $new_filename = $filename; + $counter = 1; + while (file_exists($target_folder_path . "/" . $new_filename)) { + $counter++; + $new_filename = pathinfo($filename,8) . '-'. $counter . "." . pathinfo($filename,4); + } + return $new_filename; +} + +// Check file size - we are not going to check file size for now. +// elseif ($_FILES["uploaded_file"]["size"] > 5000000) { +// $upload_msg = "Your file is too large."; +// $upload_ok = 0; +// } + + +?> diff --git a/roles/usb_lib/files/usbmount/copyright b/roles/usb_lib/files/usbmount/copyright new file mode 100644 index 000000000..75fae2dde --- /dev/null +++ b/roles/usb_lib/files/usbmount/copyright @@ -0,0 +1,17 @@ +Format: http://dep.debian.net/deps/dep5/ +Upstream-Name: usbmount +Upstream-Contact: Martin Dickopp , Rogério Brito +Source: git://git.debian.org/usbmount/usbmount.git + +Files: * +Copyright: 2004-2007, Martin Dickopp + 2008-2011, Rogério Brito +License: BSD-2 + This package is free software; the copyright holder gives unlimited + permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + . + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY, to the extent permitted by law; without + even the implied warranty of MERCHANTABILITY or FITNESS FOR A + PARTICULAR PURPOSE. diff --git a/roles/usb_lib/files/usbmount/usbmount b/roles/usb_lib/files/usbmount/usbmount new file mode 100644 index 000000000..8104564e7 --- /dev/null +++ b/roles/usb_lib/files/usbmount/usbmount @@ -0,0 +1,235 @@ +#!/bin/sh +# This script mounts USB mass storage devices when they are plugged in +# and unmounts them when they are removed. +# Copyright © 2004, 2005 Martin Dickopp +# Copyright © 2008, 2009, 2010 Rogério Theodoro de Brito +# Copyright © 2025, Jerry Vonau +# +# This file is free software; the copyright holder gives unlimited +# permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This file is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. +# https://github.com/iiab/iiab/blob/master/roles/usb_lib/files/usbmount/copyright +# https://github.com/rbrito/usbmount/blob/master/debian/copyright +#set -e +exec > /dev/null 2>&1 + +###################################################################### +# Auxiliary functions + +# Log a string via the syslog facility. +log() +{ + if [ $1 != debug ] || expr "$VERBOSE" : "[yY]" > /dev/null; then + logger -p user.$1 -t "usbmount[$$]" -- "$2" + fi +} + + +# Test if the first parameter is in the list given by the second +# parameter. +in_list() +{ + for v in $2; do + [ "$1" != "$v" ] || return 0 + done + return 1 +} + + +###################################################################### +# Main program + +# Default values for configuration variables. +ENABLED=1 +MOUNTPOINTS= +FILESYSTEMS= +MOUNTOPTIONS= +FS_MOUNTOPTIONS= +VERBOSE=no + +if [ -r /etc/usbmount/usbmount.conf ]; then + . /etc/usbmount/usbmount.conf + log debug "loaded usbmount configurations" +fi + +if [ "${ENABLED:-1}" -eq 0 ]; then + log info "usbmount is disabled, see /etc/usbmount/usbmount.conf" + exit 0 +fi + +if [ ! -x /sbin/blkid ]; then + log err "cannot execute /sbin/blkid" + exit 1 +fi + +if [ "$1" = add ]; then + + # Per Policy 9.3.2, directories under /var/run have to be created + # after every reboot. + if [ ! -e /var/run/usbmount ]; then + mkdir -p /var/run/usbmount + log debug "creating /var/run/usbmount directory" + else + log debug "/var/run/usbmount exists" + fi + + umask 022 + + # Acquire lock. + log debug "trying to acquire lock /var/run/usbmount/.mount.lock" + lockfile-create --retry 6 /var/run/usbmount/.mount || \ + { log err "cannot acquire lock /var/run/usbmount/.mount.lock"; exit 1; } + trap '( lockfile-remove /var/run/usbmount/.mount )' 0 + log debug "acquired lock /var/run/usbmount/.mount.lock" + + # Grab device information from device and "divide it" + # FIXME: improvement: implement mounting by label (notice that labels + # can contain spaces, which makes things a little bit less comfortable). + DEVINFO=$(/sbin/blkid -p $DEVNAME) + FSTYPE=$(echo "$DEVINFO" | sed 's/.*[[:blank:]]TYPE="\([^"]*\)".*/\1/g; s/[[:blank:]]*//g;') + UUID=$(echo "$DEVINFO" | sed 's/.*[[:blank:]]UUID="\([^"]*\)".*/\1/g; s/[[:blank:]]*//g;') + USAGE=$(echo "$DEVINFO" | sed 's/.*[[:blank:]]USAGE="\([^"]*\)".*/\1/g; s/[[:blank:]]*//g;') + + if ! echo $USAGE | egrep -q "(filesystem|disklabel)"; then + log debug "/$DEVNAME does not contain a filesystem or disklabel" + lockfile-remove /var/run/usbmount/.mount + exit + fi + + log debug "/$DEVNAME contains filesystem type $FSTYPE" + BOOTFW_DEV=$(/usr/bin/findmnt -no source /boot/firmware) + log debug "BOOTFW_DEV $BOOTFW_DEV" + ROOT_DEV=$(/usr/bin/findmnt -no source /) + log debug "ROOT_DEV $ROOT_DEV" + BOOT_DEV=$(/usr/bin/findmnt -no source /boot) + log debug "BOOT_DEV $BOOT_DEV" + + if [ $BOOTFW_DEV = /$DEVNAME ]; then + log debug "skipping BOOTFS_DEV $BOOTFS_DEV mounted at /boot/firmware" + lockfile-remove /var/run/usbmount/.mount + exit + elif [ $ROOT_DEV = /$DEVNAME ]; then + log debug "skipping ROOT_DEV $ROOT_DEV mounted at /" + lockfile-remove /var/run/usbmount/.mount + exit + elif [ $BOOT_DEV = /$DEVNAME ]; then + log debug "skipping BOOT_DEV $BOOT_DEV mount as /boot" + lockfile-remove /var/run/usbmount/.mount + exit + fi + + # Try to use specifications in /etc/fstab to skip. + if egrep -q "^[[:blank:]]*$DEVNAME" /etc/fstab; then + log debug "skipping /$DEVNAME exit" + lockfile-remove /var/run/usbmount/.mount + exit + elif grep -q "^[[:blank:]]*UUID=$UUID" /etc/fstab; then + log debug "skipping $UUID" + lockfile-remove /var/run/usbmount/.mount + exit + else + log debug "/$DEVNAME contains filesystem type $FSTYPE" + fstype=$FSTYPE + # Test if the filesystem type is in the list of filesystem + # types to mount. + if in_list "$fstype" "$FILESYSTEMS"; then + # Search an available mountpoint. + for v in $MOUNTPOINTS; do + if [ -d "$v" ] && ! grep -q "^[^ ][^ ]* *$v " /proc/mounts; then + mountpoint="$v" + log debug "mountpoint $mountpoint is available for /$DEVNAME" + break + fi + done + if [ -n "$mountpoint" ]; then + # Determine mount options. + options= + for v in $FS_MOUNTOPTIONS; do + if expr "$v" : "-fstype=$fstype,."; then + options="$(echo "$v" | sed 's/^[^,]*,//')" + break + fi + done + if [ -n "$MOUNTOPTIONS" ]; then + options="$MOUNTOPTIONS${options:+,$options}" + fi + + # Mount the filesystem. + log info "executing command: mount -t$fstype ${options:+-o$options} $DEVNAME $mountpoint" + mount "-t$fstype" "${options:+-o$options}" "$DEVNAME" "$mountpoint" + + # Determine vendor and model. + vendor= + if [ -r "/sys$DEVPATH/device/vendor" ]; then + vendor="`cat \"/sys$DEVPATH/device/vendor\"`" + elif [ -r "/sys$DEVPATH/../device/vendor" ]; then + vendor="`cat \"/sys$DEVPATH/../device/vendor\"`" + elif [ -r "/sys$DEVPATH/device/../manufacturer" ]; then + vendor="`cat \"/sys$DEVPATH/device/../manufacturer\"`" + elif [ -r "/sys$DEVPATH/../device/../manufacturer" ]; then + vendor="`cat \"/sys$DEVPATH/../device/../manufacturer\"`" + fi + vendor="$(echo "$vendor" | sed 's/^[[:blank:]]\+//; s/[[:blank:]]\+$//')" + + model= + if [ -r "/sys$DEVPATH/device/model" ]; then + model="`cat \"/sys$DEVPATH/device/model\"`" + elif [ -r "/sys$DEVPATH/../device/model" ]; then + model="`cat \"/sys$DEVPATH/../device/model\"`" + elif [ -r "/sys$DEVPATH/device/../product" ]; then + model="`cat \"/sys$DEVPATH/device/../product\"`" + elif [ -r "/sys$DEVPATH/../device/../product" ]; then + model="`cat \"/sys$DEVPATH/../device/../product\"`" + fi + model="$(echo "$model" | sed 's/^[[:blank:]]\+//; s/[[:blank:]]\+$//')" + + # Run hook scripts; ignore errors. + export UM_DEVICE="$DEVNAME" + export UM_MOUNTPOINT="$mountpoint" + export UM_FILESYSTEM="$fstype" + export UM_MOUNTOPTIONS="$options" + export UM_VENDOR="$vendor" + export UM_MODEL="$model" + log info "executing command: run-parts /etc/usbmount/mount.d" + run-parts /etc/usbmount/mount.d || : + else + # No suitable mount point found. + log warning "no mountpoint found for $DEVNAME" + exit 1 + fi + fi +fi +elif [ "$1" = remove ]; then + + # A block or partition device has been removed. + # Test if it is mounted. + while read device mountpoint fstype remainder; do + if [ "$DEVNAME" = "$device" ]; then + # If the mountpoint and filesystem type are maintained by + # this script, unmount the filesystem. + if in_list "$mountpoint" "$MOUNTPOINTS" && + in_list "$fstype" "$FILESYSTEMS"; then + log info "executing command: umount -l $mountpoint" + umount -l "$mountpoint" + + # Run hook scripts; ignore errors. + export UM_DEVICE="$DEVNAME" + export UM_MOUNTPOINT="$mountpoint" + export UM_FILESYSTEM="$fstype" + log info "executing command: run-parts /etc/usbmount/umount.d" + run-parts /etc/usbmount/umount.d || : + fi + break + fi + done < /proc/mounts +else + log err "unexpected: action '$1'" + exit 1 +fi + +log debug "usbmount execution finished" diff --git a/roles/usb_lib/files/usbmount/usbmount.conf b/roles/usb_lib/files/usbmount/usbmount.conf new file mode 100644 index 000000000..7bd194873 --- /dev/null +++ b/roles/usb_lib/files/usbmount/usbmount.conf @@ -0,0 +1,53 @@ +# Configuration file for the usbmount package, which mounts removable +# storage devices when they are plugged in and unmounts them when they +# are removed. + +# Change to zero to disable usbmount +ENABLED=1 + +# Mountpoints: These directories are eligible as mointpoints for +# removable storage devices. A newly plugged in device is mounted on +# the first directory in this list that exists and on which nothing is +# mounted yet. +MOUNTPOINTS="/media/usb0 /media/usb1 /media/usb2 /media/usb3 + /media/usb4 /media/usb5 /media/usb6 /media/usb7" + +# Filesystem types: removable storage devices are only mounted if they +# contain a filesystem type which is in this list. +FILESYSTEMS="vfat ext2 ext3 ext4 hfsplus exfat fuseblk ntfs" + +############################################################################# +# WARNING! # +# # +# The "sync" option may not be a good choice to use with flash drives, as # +# it forces a greater amount of writing operating on the drive. This makes # +# the writing speed considerably lower and also leads to a faster wear out # +# of the disk. # +# # +# If you omit it, don't forget to use the command "sync" to synchronize the # +# data on your disk before removing the drive or you may experience data # +# loss. # +# # +# It is highly recommended that you use the pumount command (as a regular # +# user) before unplugging the device. It makes calling the "sync" command # +# and mounting with the sync option unnecessary---this is similar to other # +# operating system's "safely disconnect the device" option. # +############################################################################# +# Mount options: Options passed to the mount command with the -o flag. +# See the warning above regarding removing "sync" from the options. +MOUNTOPTIONS="sync,noexec,nodev,noatime,nodiratime" + +# Filesystem type specific mount options: This variable contains a space +# separated list of strings, each which the form "-fstype=TYPE,OPTIONS". +# +# If a filesystem with a type listed here is mounted, the corresponding +# options are appended to those specificed in the MOUNTOPTIONS variable. +# +# For example, "-fstype=vfat,gid=floppy,dmask=0007,fmask=0117" would add +# the options "gid=floppy,dmask=0007,fmask=0117" when a vfat filesystem +# is mounted. +FS_MOUNTOPTIONS="" + +# If set to "yes", more information will be logged via the syslog +# facility. +VERBOSE=yes diff --git a/roles/usb_lib/tasks/install.yml b/roles/usb_lib/tasks/install.yml index e0699a652..660df7eb2 100644 --- a/roles/usb_lib/tasks/install.yml +++ b/roles/usb_lib/tasks/install.yml @@ -7,6 +7,10 @@ # https://github.com/rbrito/usbmount/blob/master/README.md (2018-08-10) # https://github.com/rbrito/usbmount/blob/master/usbmount.conf (2010-04-25) +# The variable, usb_lib_writable_sticks (e.g., in /etc/iiab/local_vars.yml), must be set to true +# in order for non-root users to be able to write to VFAT/FAT32, NTFS and exFAT USB sticks. +# If you are still not able to write to a mounted USB stick, try unmounting the drive +# (sudo umount ) and then remount it setting umask to 0000 manually (sudo mount -o umask=0000 ). - name: Record (initial) disk space used shell: df -B1 --output=used / | tail -1 @@ -44,27 +48,53 @@ when: udev_unit.stat.exists is defined and udev_unit.stat.exists # http://raspbian.raspberrypi.org/raspbian/pool/main/u/usbmount/usbmount_0.0.22_all.deb -- name: Install {{ iiab_download_url }}/usbmount_0.0.22_all.deb, no longer supported by {RasPiOS, Debian, Ubuntu} - apt: - deb: "{{ iiab_download_url }}/usbmount_0.0.22_all.deb" - # when: is_debian +#- name: Install {{ iiab_download_url }}/usbmount_0.0.22_all.deb, no longer supported by {RasPiOS, Debian, Ubuntu} +# apt: +# deb: "{{ iiab_download_url }}/usbmount_0.0.22_all.deb" +# # when: is_debian -# check status of usbmount on mintlinux - should be ok Ubuntu variant -# - name: Install usbmount from OS repo for Ubuntu variants -# package: -# name: usbmount -# state: present -# when: is_ubuntu +- name: Install lockfile-progs and util-linux (findmnt blkid) for usbmount from OS repo + package: + name: + - lockfile-progs + - util-linux + state: present -- name: Add dir {{ doc_root }}/local_content, where USB drive links can appear (0775) +- name: Add dir {{ doc_root }}/local_content, where USB drive links can appear (0775) owned by {{ apache_user }}:{{ apache_user }} file: state: directory - path: "{{ doc_root }}/local_content" - owner: "{{ apache_user }}" + path: "{{ doc_root }}/local_content" # /library/www/html + owner: "{{ apache_user }}" # www-data group: "{{ apache_user }}" # 2020-02-13: changed from iiab_admin_user, after discussion on weekly call (#1228, #2222) mode: 0775 -- name: 'Install from template: /etc/udev/rules.d/usbmount.rules, /etc/systemd/system/usbmount@.service, /usr/bin/iiab-usb_lib-show-all-on, /usr/bin/iiab-usb_lib-show-all-off, /usr/sbin/iiab-clean-usb.sh' +- name: Set up dirs /etc/usbmount/mount.d, /etc/usbmount/umount.d, /media/usb0-7 + file: + state: directory + path: "{{ item }}" + mode: 0755 + with_items: + - /etc/usbmount/mount.d + - /etc/usbmount/umount.d + - /media/usb0 + - /media/usb1 + - /media/usb2 + - /media/usb3 + - /media/usb4 + - /media/usb5 + - /media/usb6 + - /media/usb7 + +- name: Copy files from files/usbmount to filesystem + copy: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + mode: "{{ item.mode }}" + with_items: + - { src: 'usbmount/usbmount.conf', dest: '/etc/usbmount/', mode: '0644' } + - { src: 'usbmount/usbmount', dest: '/usr/local/sbin/', mode: '0755' } + +- name: 'Install from template: /etc/udev/rules.d/usbmount.rules, /etc/systemd/system/usbmount@.service, /usr/local/sbin/iiab-clean-usb.sh' template: src: "{{ item.src }}" dest: "{{ item.dest }}" @@ -72,23 +102,36 @@ with_items: - { src: 'usbmount.rules.j2', dest: '/etc/udev/rules.d/usbmount.rules', mode: '0644' } - { src: 'usbmount@.service.j2', dest: '/etc/systemd/system/usbmount@.service', mode: '0644' } - - { src: 'iiab-usb_lib-show-all-on', dest: '/usr/bin/', mode: '0755' } - - { src: 'iiab-usb_lib-show-all-off', dest: '/usr/bin/', mode: '0755' } - - { src: 'iiab-clean-usb.sh', dest: '/usr/sbin/', mode: '0755' } + - { src: 'iiab-clean-usb.sh', dest: '/usr/local/sbin/', mode: '0755' } + +- name: Add dir {{ doc_root }}/upload2usb (0775) owned by {{ apache_user }}:{{ apache_user }} + file: + state: directory + path: "{{ doc_root }}/upload2usb" + owner: "{{ apache_user }}" + group: "{{ apache_user }}" + mode: 0755 + +- name: Copy files from files/upload2usb/ into {{ doc_root }}/upload2usb/ + copy: + src: "{{ item }}" + dest: "{{ doc_root }}/upload2usb/" + with_fileglob: + - upload2usb/* # 2021-03-21: If usbmount is repackaged by apt as a result of Linux kernel 5.4+ # supporting exFAT, the stanza below (might) in future no longer be needed... # SEE ALSO: https://github.com/iiab/iiab/blob/586bfc5cb1abf6b4333a21d3fa89695f115432dc/roles/2-common/tasks/packages.yml#L11-L12 -- name: Add ' exfat fuseblk ntfs' to FILESYSTEMS var in /etc/usbmount/usbmount.conf - lineinfile: - regexp: '^FILESYSTEMS=.*' - line: 'FILESYSTEMS="vfat ext2 ext3 ext4 hfsplus exfat fuseblk ntfs"' - path: /etc/usbmount/usbmount.conf +#- name: Add ' exfat fuseblk ntfs' to FILESYSTEMS var in /etc/usbmount/usbmount.conf +# lineinfile: +# regexp: '^FILESYSTEMS=.*' +# line: 'FILESYSTEMS="vfat ext2 ext3 ext4 hfsplus exfat fuseblk ntfs"' +# path: /etc/usbmount/usbmount.conf -- name: Remove /etc/usbmount/mount.d/00_create_model_symlink - file: - path: /etc/usbmount/mount.d/00_create_model_symlink - state: absent +#- name: Remove /etc/usbmount/mount.d/00_create_model_symlink +# file: +# path: /etc/usbmount/mount.d/00_create_model_symlink +# state: absent # RECORD 'USB_LIB' AS INSTALLED diff --git a/roles/usb_lib/tasks/main.yml b/roles/usb_lib/tasks/main.yml index 7836f2d3a..ee4bd18ea 100644 --- a/roles/usb_lib/tasks/main.yml +++ b/roles/usb_lib/tasks/main.yml @@ -1,7 +1,7 @@ # TO DO: (2020-02-13) # - Look at analogous NGINX logic for http://box/usb in # nginx/templates/iiab.conf.j2 and make that visually meaningful for teachers: -# https://github.com/iiab/iiab/blob/master/roles/nginx/templates/iiab.conf.j2#L5-L8 +# https://github.com/iiab/iiab/blob/master/roles/nginx/templates/iiab.conf.j2#L5-L9 # "How do i fail a task in Ansible if the variable contains a boolean value? @@ -32,12 +32,12 @@ # If setup.yml becomes the norm in future, put the 2-3 stanzas below in there: -- name: "Set 'umask=0000' for {VFAT/FAT32, NTFS, exFAT} using var FS_MOUNTOPTIONS in /etc/usbmount/usbmount.conf, so Kolibri exports work" +- name: "Set 'umask=0000' for {VFAT/FAT32, NTFS, exFAT} using var FS_MOUNTOPTIONS in /etc/usbmount/usbmount.conf -- for Kolibri exports AND student uploads to teacher's USB stick (using http://box/usb)" lineinfile: regexp: '^FS_MOUNTOPTIONS=.*' line: 'FS_MOUNTOPTIONS="-fstype=vfat,umask=0000 -fstype=ntfs,umask=0000 -fstype=exfat,umask=0000"' path: /etc/usbmount/usbmount.conf - when: usb_lib_umask0000_for_kolibri + when: usb_lib_writable_sticks # Setting 'umask=0000' for all filesystems: (much the same thing as above, as # the mount command does not use this umask setting for filesystems like ext4) @@ -46,14 +46,14 @@ # regexp: '^MOUNTOPTIONS=.*' # line: 'MOUNTOPTIONS="sync,noexec,nodev,noatime,nodiratime,umask=0000"' # path: /etc/usbmount/usbmount.conf -# when: usb_lib_umask0000_for_kolibri +# when: usb_lib_writable_sticks -- name: 'Set FS_MOUNTOPTIONS="" in /etc/usbmount/usbmount.conf, e.g. if Kolibri will not be used' +- name: 'Set FS_MOUNTOPTIONS="" in /etc/usbmount/usbmount.conf -- e.g. if Kolibri exports AND student uploads to teacher USB stick are not needed' lineinfile: regexp: '^FS_MOUNTOPTIONS=.*' line: 'FS_MOUNTOPTIONS=""' # Restore apt pkg default, e.g. for runrole path: /etc/usbmount/usbmount.conf - when: not usb_lib_umask0000_for_kolibri + when: not usb_lib_writable_sticks - name: Enable/Disable/Restart NGINX @@ -66,12 +66,6 @@ path: /etc/usbmount/mount.d/00_create_model_symlink state: absent -- name: Put variable in iiab.env that enables display of content at root of USB - lineinfile: - path: "{{ iiab_env_file }}" - regexp: "^IIAB_USB_LIB_SHOW_ALL.*" - line: "IIAB_USB_LIB_SHOW_ALL={{ iiab_usb_lib_show_all }}" - - name: Add 'usb_lib' variable values to {{ iiab_ini_file }} ini_file: @@ -83,10 +77,10 @@ - option: name value: USB_LIB - option: description - value: '"USB_LIB automounts Teacher Content on USB drives to /library/www/html/local_content, so students can browse it almost immediately at http://box/usb"' + value: '"USB_LIB (1) automounts teacher content on USB sticks to /library/www/html/local_content, so students can browse the USB; AND (2) allows students to upload their work to USB sticks / drives, all from http://box/usb"' - option: usb_lib_install value: "{{ usb_lib_install }}" - option: usb_lib_enabled value: "{{ usb_lib_enabled }}" - - option: usb_lib_umask0000_for_kolibri - value: "{{ usb_lib_umask0000_for_kolibri }}" + - option: usb_lib_writable_sticks + value: "{{ usb_lib_writable_sticks }}" diff --git a/roles/usb_lib/tasks/nginx.yml b/roles/usb_lib/tasks/nginx.yml index 7e572142a..1e6be6d21 100644 --- a/roles/usb_lib/tasks/nginx.yml +++ b/roles/usb_lib/tasks/nginx.yml @@ -1,20 +1,21 @@ - name: Install /etc/usbmount/mount.d/70-usb-library from template, if usb_lib_enabled template: - src: mount.d/70-usb-library - dest: /etc/usbmount/mount.d/ + src: mount.d/70-usb-library.j2 + dest: /etc/usbmount/mount.d/70-usb-library owner: root group: root mode: '0751' when: usb_lib_enabled -- name: Install /etc/usbmount/umount.d/70-usb-library from template, if usb_lib_enabled - template: - src: umount.d/70-usb-library - dest: /etc/usbmount/umount.d - owner: root - group: root - mode: '0751' - when: usb_lib_enabled +# 20250125: commenting out stale file, superseded by iiab-clean-usb.sh +# - name: Install /etc/usbmount/umount.d/70-usb-library from template, if usb_lib_enabled +# template: +# src: umount.d/70-usb-library +# dest: /etc/usbmount/umount.d +# owner: root +# group: root +# mode: '0751' +# when: usb_lib_enabled - name: Remove /etc/usbmount/mount.d/70-usb-library if not usb_lib_enabled file: @@ -22,11 +23,12 @@ state: absent when: not usb_lib_enabled -- name: Remove /etc/usbmount/umount.d/70-usb-library if not usb_lib_enabled - file: - path: /etc/usbmount/umount.d/70-usb-library - state: absent - when: not usb_lib_enabled +# 20250125: commenting out stale file, superseded by iiab-clean-usb.sh +# - name: Remove /etc/usbmount/umount.d/70-usb-library if not usb_lib_enabled +# file: +# path: /etc/usbmount/umount.d/70-usb-library +# state: absent +# when: not usb_lib_enabled - name: Restart 'nginx' systemd service systemd: diff --git a/roles/usb_lib/templates/content_dir.conf b/roles/usb_lib/templates/content_dir.conf.unused similarity index 100% rename from roles/usb_lib/templates/content_dir.conf rename to roles/usb_lib/templates/content_dir.conf.unused diff --git a/roles/usb_lib/templates/iiab-clean-usb.sh b/roles/usb_lib/templates/iiab-clean-usb.sh index a1876551c..360d737f4 100644 --- a/roles/usb_lib/templates/iiab-clean-usb.sh +++ b/roles/usb_lib/templates/iiab-clean-usb.sh @@ -1,14 +1,14 @@ #!/bin/bash -# Remove symlink in /library/content to automounted usb drive -# -DEVICE=`echo $@ | sed -s 's|-|/|'` -MNT_POINT=`findmnt -n /$DEVICE | awk '{print $1}'` -CONTENT_LINK_USB=`basename $MNT_POINT | awk '{print toupper($0)}'` +# Remove symlink in /library/www/html/local_content to automounted USB drive + +DEVICE="/$(echo $1 | sed 's|-|/|')" +MNT_POINT=$(findmnt -no target $DEVICE) +CONTENT_LINK_USB=$(basename $MNT_POINT | awk '{print toupper($0)}') CONTENT_LINK="/library/www/html/local_content/$CONTENT_LINK_USB" -logger -p user.notice -t "usbmount" -- "Attempting to remove link $CONTENT_LINK." + +logger -t "usb_lib (iiab-clean-usb.sh)" "Attempting to remove symlink $CONTENT_LINK, as auto-created earlier by usbmount." if [ -L $CONTENT_LINK ]; then - /bin/rm $CONTENT_LINK - logger -p user.notice -t "usbmount" -- "$CONTENT_LINK removed." + /usr/bin/rm $CONTENT_LINK + logger -t "usb_lib (iiab-clean-usb.sh)" "Symlink $CONTENT_LINK removed, as auto-created earlier by usbmount." fi - diff --git a/roles/usb_lib/templates/iiab-usb_lib-show-all-off b/roles/usb_lib/templates/iiab-usb_lib-show-all-off.unused similarity index 100% rename from roles/usb_lib/templates/iiab-usb_lib-show-all-off rename to roles/usb_lib/templates/iiab-usb_lib-show-all-off.unused diff --git a/roles/usb_lib/templates/iiab-usb_lib-show-all-on b/roles/usb_lib/templates/iiab-usb_lib-show-all-on.unused similarity index 100% rename from roles/usb_lib/templates/iiab-usb_lib-show-all-on rename to roles/usb_lib/templates/iiab-usb_lib-show-all-on.unused diff --git a/roles/usb_lib/templates/mount.d/70-usb-library b/roles/usb_lib/templates/mount.d/70-usb-library deleted file mode 100644 index 5b9cfefe8..000000000 --- a/roles/usb_lib/templates/mount.d/70-usb-library +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/bash -# Create symlink in DocumentRoot/content to autmounted usb drive -# -# based on a similar script in the xs-rsync package -# by Martin Langhoff -# -# and the adaptation for xs-activity-server by Douglas Bagnall -# -# -# by Tim Moody tim@timmoody.com - -source {{ iiab_env_file }} -case $IIAB_USB_LIB_SHOW_ALL in -'True'|'true'|'TRUE') - logger -p user.notice -t "70-usb-library" -- "Display entire USB drive is True. Checking for rootfs or /library on $UM_MOUNTPOINT." - # regularize the variable - IIAB_USB_LIB_SHOW_ALL=True - ;; -*) - logger -p user.notice -t "70-usb-library" -- "Looking for /share, /Share, /Piratebox/Share, /USB, or /usb on $UM_MOUNTPOINT." - ;; -esac - -VERBOSE=yes - -SHARE_DIR="" -# Only show content if in these directories - -if [ -d $UM_MOUNTPOINT/share ]; then - SHARE_DIR="$UM_MOUNTPOINT/share" -fi -if [ -d $UM_MOUNTPOINT/Share ]; then - SHARE_DIR="$UM_MOUNTPOINT/Share" -fi -if [ -d $UM_MOUNTPOINT/Piratebox/Share ]; then - SHARE_DIR="$UM_MOUNTPOINT/Piratebox/Share" -fi -if [ -d $UM_MOUNTPOINT/USB ]; then - SHARE_DIR="$UM_MOUNTPOINT/USB" -fi -if [ -d $UM_MOUNTPOINT/usb ]; then - SHARE_DIR="$UM_MOUNTPOINT/usb" -fi - -if [ "$IIAB_USB_LIB_SHOW_ALL" == "True" ]; then - UM_DEV=`findmnt $UM_MOUNTPOINT | grep / | awk '{print $2}'` - LIB_DEV=`findmnt /library | grep / | awk '{print $2}' |awk -F '[' '{print $1}'` - ROOT_DEV=`findmnt / | grep / | awk '{print $2}'` - if [ "$UM_DEV" == "$LIB_DEV" ]; then - logger -p user.notice -t "70-usb-library" -- "skipping $UM_MOUNTPOINT containing /library" - #echo "lib on dev" - elif [ "$UM_DEV" == "$ROOT_DEV" ]; then - logger -p user.notice -t "70-usb-library" -- "skipping $UM_MOUNTPOINT containing rootfs" - #echo "rootfs on dev" - else - SHARE_DIR="$UM_MOUNTPOINT" - fi -fi - -if [ ! -z "$SHARE_DIR" ]; then - logger -p user.notice -t "70-usb-library" -- "Found Share Directory $SHARE_DIR." -else - logger -p user.notice -t "70-usb-library" -- "did not find /share, /Share, /Piratebox/Share, /USB, or /usb on USB" -fi - - -if [ "$SHARE_DIR" != "" ];then - CONTENT_LINK_USB=`basename $UM_MOUNTPOINT | awk '{print toupper($0)}'` - CONTENT_LINK="{{ doc_root }}/local_content/$CONTENT_LINK_USB" - logger -p user.notice -t "70-usb-library" -- "Creating link to $CONTENT_LINK." - ln -s $SHARE_DIR $CONTENT_LINK -fi diff --git a/roles/usb_lib/templates/mount.d/70-usb-library.j2 b/roles/usb_lib/templates/mount.d/70-usb-library.j2 new file mode 100644 index 000000000..8263bde1f --- /dev/null +++ b/roles/usb_lib/templates/mount.d/70-usb-library.j2 @@ -0,0 +1,67 @@ +#!/bin/bash +# Create symlink in DocumentRoot/content to automounted usb drive +# +# based on a similar script in the xs-rsync package +# by Martin Langhoff +# +# and the adaptation for xs-activity-server by Douglas Bagnall +# +# +# by Tim Moody tim@timmoody.com + +# Better to set this in /etc/usbmount/usbmount.conf +# VERBOSE=yes + +# UM_MOUNTPOINT is documented at: https://github.com/rbrito/usbmount#hook-scripts +UM_DEV=$(findmnt -no source $UM_MOUNTPOINT) + +# 2022-06-16 better security thanks to @tim-moody and @jvonau: +# https://github.com/iiab/iiab/pull/3254 +LIB_DEV=$(findmnt -no source /library | cut -d '[' -f 1) +ROOT_DEV=$(findmnt -no source /) +BOOT_DEV=$(findmnt -no source /boot) +BOOTFW_DEV=$(findmnt -no source /boot/firmware) + +# Verbose logging to illuminate occasional boot bugginess: +logger -t "usb_lib (70-usb-library)" "UM_DEV is: $UM_DEV" +logger -t "usb_lib (70-usb-library)" "LIB_DEV is: $LIB_DEV" +logger -t "usb_lib (70-usb-library)" "ROOT_DEV is: $ROOT_DEV" +logger -t "usb_lib (70-usb-library)" "BOOT_DEV is: $BOOT_DEV" +logger -t "usb_lib (70-usb-library)" "BOOTFW_DEV is: $BOOTFW_DEV" + +if [ "$UM_DEV" == "$LIB_DEV" ]; then + logger -t "usb_lib (70-usb-library)" "Skipping $UM_MOUNTPOINT containing /library" + exit 1 +elif [ "$UM_DEV" == "$ROOT_DEV" ]; then + logger -t "usb_lib (70-usb-library)" "Skipping $UM_MOUNTPOINT containing rootfs" + exit 1 +elif [ "$UM_DEV" == "$BOOT_DEV" ]; then + logger -t "usb_lib (70-usb-library)" "Skipping $UM_MOUNTPOINT containing /boot" + exit 1 +elif [ "$UM_DEV" == "$BOOTFW_DEV" ]; then + logger -t "usb_lib (70-usb-library)" "Skipping $UM_MOUNTPOINT containing /boot/firmware" + exit 1 +fi + +# 2025-01-25: Check for existence of folder PUBLIC on USB stick: if found, the stick will not be completely browsable. +# Teachers can set their stick for 1 of 2 two "personalities" — students can either upload "confidential homework" or +# "public artwork" — as summarized here: https://github.com/iiab/iiab/blob/master/roles/usb_lib/README.rst +if [ -d $UM_MOUNTPOINT/PUBLIC ]; then + SHARE_DIR=$UM_MOUNTPOINT/PUBLIC + logger -t "usb_lib (70-usb-library)" "Found /PUBLIC on $UM_MOUNTPOINT" +else + SHARE_DIR=$UM_MOUNTPOINT + logger -t "usb_lib (70-usb-library)" "Did not find /PUBLIC on $UM_MOUNTPOINT" +fi + +CONTENT_LINK_USB=$(basename $UM_MOUNTPOINT | awk '{print toupper($0)}') +if [ -z "$CONTENT_LINK_USB" ]; then + logger -t "usb_lib (70-usb-library)" 'ERROR: Var CONTENT_LINK_USB is empty ("rm -rf /library/www/html/local_content/" would be dangerous!)' + exit 1 +fi +CONTENT_LINK="{{ doc_root }}/local_content/$CONTENT_LINK_USB" +# 'rm -rf' even stronger than 'ln -nsf' and 'ln -Tsf' +# https://serverfault.com/questions/147787/how-to-update-a-symbolic-link-target-ln-f-s-not-working/522483#522483 +logger -t "usb_lib (70-usb-library)" "Creating link from $CONTENT_LINK to $SHARE_DIR" +rm -rf $CONTENT_LINK +ln -s $SHARE_DIR $CONTENT_LINK diff --git a/roles/usb_lib/templates/umount.d/70-usb-library b/roles/usb_lib/templates/umount.d.unused/70-usb-library similarity index 75% rename from roles/usb_lib/templates/umount.d/70-usb-library rename to roles/usb_lib/templates/umount.d.unused/70-usb-library index 5af914c01..d8e095008 100644 --- a/roles/usb_lib/templates/umount.d/70-usb-library +++ b/roles/usb_lib/templates/umount.d.unused/70-usb-library @@ -12,7 +12,7 @@ CONTENT_LINK_USB=`basename $UM_MOUNTPOINT | awk '{print toupper($0)}'` CONTENT_LINK="{{ doc_root }}/local_content/$CONTENT_LINK_USB" -logger -p user.notice -t "70-usb-library" -- "Attempting to remove link $CONTENT_LINK." +logger -p user.notice -t "usb_lib (70-usb-library)" -- "Attempting to remove link $CONTENT_LINK." if [ -L $CONTENT_LINK ]; then {% if is_debuntu %} @@ -20,5 +20,5 @@ if [ -L $CONTENT_LINK ]; then {% else %} /usr/bin/rm -f $CONTENT_LINK {% endif %} - logger -p user.notice -t "70-usb-library" -- "$CONTENT_LINK removed." + logger -p user.notice -t "usb_lib (70-usb-library)" -- "$CONTENT_LINK removed." fi diff --git a/roles/usb_lib/templates/usbmount.rules.j2 b/roles/usb_lib/templates/usbmount.rules.j2 index 564186c5a..939a31041 100644 --- a/roles/usb_lib/templates/usbmount.rules.j2 +++ b/roles/usb_lib/templates/usbmount.rules.j2 @@ -1,5 +1,3 @@ -KERNEL=="sd*", DRIVERS=="sbp2", ACTION=="add", PROGRAM="/bin/systemd-escape -p --template=usbmount@.service $env{DEVNAME}", ENV{SYSTEMD_WANTS}+="%c" -KERNEL=="sd*", SUBSYSTEMS=="usb", ACTION=="add", PROGRAM="/bin/systemd-escape -p --template=usbmount@.service $env{DEVNAME}", ENV{SYSTEMD_WANTS}+="%c" -KERNEL=="ub*", SUBSYSTEMS=="usb", ACTION=="add", PROGRAM="/bin/systemd-escape -p --template=usbmount@.service $env{DEVNAME}", ENV{SYSTEMD_WANTS}+="%c" -KERNEL=="sd*", SUBSYSTEMS=="usb", ACTION=="remove", PROGRAM="/usr/share/usbmount/usbmount remove" +ACTION=="add", SUBSYSTEMS=="usb", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="filesystem" PROGRAM="/bin/systemd-escape -p --template=usbmount@.service $env{DEVNAME}", ENV{SYSTEMD_WANTS}+="%c" +ACTION=="remove", SUBSYSTEMS=="usb", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="filesystem" PROGRAM="/bin/systemd-escape -p /usr/share/usbmount/usbmount remove" diff --git a/roles/usb_lib/templates/usbmount@.service.j2 b/roles/usb_lib/templates/usbmount@.service.j2 index 34d75d9f3..6cf1f990b 100644 --- a/roles/usb_lib/templates/usbmount@.service.j2 +++ b/roles/usb_lib/templates/usbmount@.service.j2 @@ -1,14 +1,15 @@ [Unit] BindTo=%i.device After=%i.device -After=rc-local.service +After=systemd-udev-trigger.service +ConditionPathExists=/var/run [Service] #Type=oneshot TimeoutStartSec=0 Environment=DEVNAME=%I -ExecStart=/usr/share/usbmount/usbmount add -ExecStop=/usr/sbin/iiab-clean-usb.sh %I +ExecStart=/usr/local/sbin/usbmount add +ExecStop=/usr/local/sbin/iiab-clean-usb.sh %I ExecStopPost=/bin/umount /%I RemainAfterExit=yes - +RuntimeDirectory=usbmount diff --git a/roles/www_options/tasks/main.yml b/roles/www_options/tasks/main.yml index 2319c58f5..f157abb26 100644 --- a/roles/www_options/tasks/main.yml +++ b/roles/www_options/tasks/main.yml @@ -69,7 +69,8 @@ # WordPress) so './runrole ' and similar are fully self-sufficient! - name: "Run php-settings.yml -- allows post-install toggling of nginx_high_php_limits in /etc/iiab/local_vars.yml -- if you run './runrole www_options'" include_tasks: php-settings.yml - when: nginx_high_php_limits or matomo_install or moodle_install or nextcloud_install or pbx_install or wordpress_install + # 2025-01-29: PHP's own defaults (presumably from the 1990s?) were Way Too Low -- for usb-lib's upload2usb, and in general -- so let's run php-settings.yml every time! + # when: nginx_high_php_limits or matomo_install or moodle_install or nextcloud_install or pbx_install or wordpress_install # 'Is a "Rapid Power Off" button possible for low-electricity environments?' @@ -77,22 +78,22 @@ # COMPARE nginx_high_php_limits further above. -# 2020-03-08: DOES THE FLAG BELOW (allow_www_data_sudo) PRESUMABLY WORK +# 2020-03-08: DOES THE FLAG BELOW (allow_www_data_poweroff) PRESUMABLY WORK # WITH NGINX TOO ? (The single-click poweroff button on IIAB's home # page certainly does still work with NGINX.) -- name: Give {{ apache_user }} (per variable apache_user) permission to poweroff, installing /etc/sudoers.d/020_apache_poweroff from template +- name: Give {{ apache_user }} (per variable apache_user) permission to poweroff, installing /etc/sudoers.d/020_www_data_poweroff from template template: - src: 020_apache_poweroff.j2 - dest: /etc/sudoers.d/020_apache_poweroff + src: 020_www_data_poweroff.j2 + dest: /etc/sudoers.d/020_www_data_poweroff mode: '0440' - when: allow_www_data_sudo + when: allow_www_data_poweroff -- name: Remove {{ apache_user }} (per variable apache_user) permission to poweroff, removing /etc/sudoers.d/020_apache_poweroff +- name: Remove {{ apache_user }} (per variable apache_user) permission to poweroff, removing /etc/sudoers.d/020_www_data_poweroff file: - path: /etc/sudoers.d/020_apache_poweroff + path: /etc/sudoers.d/020_www_data_poweroff state: absent - when: not allow_www_data_sudo + when: not allow_www_data_poweroff # 2022-06-30: internet_available var removed diff --git a/roles/www_options/tasks/php-settings.yml b/roles/www_options/tasks/php-settings.yml index 184c07b21..7109ccfeb 100644 --- a/roles/www_options/tasks/php-settings.yml +++ b/roles/www_options/tasks/php-settings.yml @@ -21,11 +21,19 @@ # # This takes care of essentially everything (e.g. output "America/New_York") # by checking (1) symlink /etc/localtime then (2) text file /etc/timezone if -# nec, then (3) if neither exist, "UTC" is declated (correctly!) Potential +# nec, then (3) if neither exist, "UTC" is declared (correctly!) Potential # drawback: timedatectl is not easily usable within chroot environments. -- name: Extract Time Zone from symlink /etc/localtime &/or text file /etc/timezone (or lack thereof!) - command: timedatectl show -p Timezone --value +# 2025-01-29: Current GitHub Actions chroot environments for RPi (using guyot/arm-runner-action@v2) surface this error, after PR #3927 mainlined php-settings.yml... +# "System has not been booted with systemd as init system (PID 1). Can't operate.\nFailed to connect to bus: Host is down" +# ...which might be mitigated in 2 ways: +# 1) Try spawning these "guyot/arm-runner-action@v2" GHA workflows with... use_systemd_nspawn: true +# 2) Weaken timedatectl command just below, trying this instead... shell: readlink /etc/localtime | sed 's#^/usr/share/zoneinfo/##' + +- name: Extract Time Zone from symlink /etc/localtime, text file /etc/timezone, or if all else fails declare Etc/UTC + # command: timedatectl show -p Timezone --value + # 2025-02-01: "guyot/arm-runner-action@v2" GHA workflows don't seem to work with "use_systemd_nspawn: true", so hack in the equivalent of timedatectl... + shell: tmp=$(readlink /etc/localtime) && echo $tmp | sed 's|^/usr/share/zoneinfo/||' || cat /etc/timezone || echo Etc/UTC register: tz_cli - name: Store 'date.timezone = {{ tz_cli.stdout }}' (from above) in /etc/php/{{ php_version }}/fpm/php.ini and /etc/php/{{ php_version }}/cli/php.ini @@ -207,4 +215,4 @@ # name: php{{ php_version }}-fpm # state: restarted -# when: matomo_install or moodle_install or nextcloud_install or pbx_install or wordpress_install # 5-STANZA BLOCK ENDS. COMPARE allow_www_data_sudo conditionals below. +# when: matomo_install or moodle_install or nextcloud_install or pbx_install or wordpress_install # 5-STANZA BLOCK ENDS. COMPARE allow_www_data_poweroff conditionals below. diff --git a/roles/www_options/templates/020_apache_poweroff.j2 b/roles/www_options/templates/020_www_data_poweroff.j2 similarity index 100% rename from roles/www_options/templates/020_apache_poweroff.j2 rename to roles/www_options/templates/020_www_data_poweroff.j2 diff --git a/scripts/ansible b/scripts/ansible index 968819464..22c8cbacd 100755 --- a/scripts/ansible +++ b/scripts/ansible @@ -7,8 +7,8 @@ # https://github.com/iiab/iiab/wiki/Technical-Contributors-Guide#female_detective-understanding-ansible APT_PATH=/usr/bin # Avoids problematic /usr/local/bin/apt on Linux Mint -CURR_VER=undefined # Ansible version you have installed, e.g. [core 2.18.1] -GOOD_VER=2.18.1 # Orig for 'yum install [rpm]' & XO laptops (pip install) +CURR_VER=undefined # Ansible version you have installed, e.g. [core 2.18.3] +GOOD_VER=2.18.3 # Orig for 'yum install [rpm]' & XO laptops (pip install) # 2021-06-22: The apt approach (with PPA source in /etc/apt/sources.list.d/ and # .gpg key etc) are commented out with ### below. Associated guidance/comments diff --git a/scripts/iiab-diagnostics b/scripts/iiab-diagnostics index 47a1ae015..193ba4fc7 100755 --- a/scripts/iiab-diagnostics +++ b/scripts/iiab-diagnostics @@ -101,10 +101,18 @@ function cat_cmd() { # $1 = command + params, $2 = explanation spc_params=$(echo "$1" | sed 's/^\s*\S\S*\s*/ /;s/\s*$//') # Drop command on left; Keep a single space + params on right; RTrim #spc_params=$(echo "$1" | sed 's/^\s*\S*//;s/\s*$//;s/^\s\s*/ /') # LTrim + drop original path + command on left; RTrim; Compress whitespace in between #spc_params=$(echo "$1" | sed 's/^[[:blank:]]*[^[:blank:]]*//;s/[[:blank:]]*$//;s/^[[:blank:]][[:blank:]]*/ /') # Equivalent (POSIX compliant) - if [[ $2 == "" ]]; then - echo "COMMAND: $path_cmd$spc_params" >> $outfile + if [[ $path_cmd == "" ]]; then + if [[ $2 == "" ]]; then + echo "COMMAND: $1" >> $outfile + else + echo "COMMAND: $1 # $2" >> $outfile + fi else - echo "COMMAND: $path_cmd$spc_params # $2" >> $outfile + if [[ $2 == "" ]]; then + echo "COMMAND: $path_cmd$spc_params" >> $outfile + else + echo "COMMAND: $path_cmd$spc_params # $2" >> $outfile + fi fi echo >> $outfile if [[ $path_cmd == "" ]]; then @@ -154,20 +162,24 @@ for f in "$@"; do done if [ $# -eq 0 ]; then - echo -e " 2. Regular Files:\n" + echo -e " 2. Regular Files etc:\n" else - echo -e "\n 2. Regular Files:\n" + echo -e "\n 2. Regular Files etc:\n" fi -echo -e "\n\n\n2. REGULAR FILES\n" >> $outfile +echo -e "\n\n\n2. REGULAR FILES ETC\n" >> $outfile #cat_file /dev/sda # Device "file" test #cat_file /nonsense # Non-existence test #cat_file /opt/iiab/iiab # Directory test #cat_file /tmp/empty-file # Empty file test #cat_file /usr/bin/iiab-support-on # Symlink test cat_file /.iiab-image +cat_file /etc/default/locale # e.g. on Debian 12 +cat_file /etc/locale.conf # e.g. on Debian 13+ and Ubuntu +cat_cmd 'localectl' 'Locale settings' +cat_cmd 'locale -a' 'Available locales' cat_file /etc/iiab/iiab.env cat_file /etc/iiab/iiab.ini -cat_file /etc/iiab/local_vars.yml # Redacts most passwords above +cat_file /etc/iiab/local_vars.yml # Redacts most passwords above cat_file /etc/iiab/iiab_state.yml cat_file /etc/resolv.conf cat_file /etc/network/interfaces @@ -193,8 +205,10 @@ cat_dir /etc/netplan # Redacts most passwords above echo -e "\n 4. Output of Commands:\n" echo -e "\n\n\n\n4. OUTPUT OF COMMANDS\n" >> $outfile cat_cmd 'uname -a' 'Linux kernel' +cat_cmd 'sudo dmesg | grep -i "command line:"' 'Kernel boot parameters' cat_cmd 'free' 'RAM memory' cat_cmd 'lscpu' 'CPU details' +cat_cmd 'rpi-eeprom-update' 'RPi Bootloader EEPROM' cat_cmd 'df -h' 'Disk usage' cat_cmd 'df -ah' 'Disk usage detail' cat_cmd 'lsblk' 'Partition mount points' @@ -219,11 +233,14 @@ cat_cmd 'iw list' 'List capabilities of all wireless devices' cat_cmd 'systemctl status hostapd' 'Downstream Wi-Fi: Is hostapd running?' cat_cmd 'ls -l /etc/wpa_supplicant' 'Upstream Wi-Fi' cat_cmd 'ps -AH' 'Process hierarchy: staging of hostapd & wpa_supplicant?' -#cat_cmd 'dmesg | grep brcm' 'Diagnostic messages: RPi Wi-Fi firmware' -cat_cmd 'dmesg | grep -i -e 80211 -e 802\.11 -e wireless -e wifi -e wlan -e broadcom -e brcm -e bcm -e realtek | head -100' 'Wi-Fi firmware/driver msgs' +cat_cmd 'sudo journalctl -b | grep wpa_supplicant' 'wpa_supplicant log since boot' +cat_cmd 'sudo journalctl -b | grep NetworkManager | head -100' 'NetworkManager log since boot' +#cat_cmd 'sudo dmesg | grep brcm' 'Diagnostic messages: RPi Wi-Fi firmware' +cat_cmd 'sudo dmesg | grep Firmware:' '(Wi-Fi) firmware boot diagnostics' +cat_cmd 'ls -l /lib/firmware/cypress/*43430*' 'WiFi firmware for: RPi Zero W, Zero 2 W & 3' +cat_cmd 'ls -l /lib/firmware/cypress/*43455*' 'WiFi firmware for: RPi 3 B+, 4, 5 & 500' +cat_cmd 'sudo dmesg | grep -i -e 80211 -e 802\.11 -e wireless -e wifi -e wlan -e broadcom -e brcm -e bcm -e realtek | head -100' 'Wi-Fi firmware/driver msgs' cat_cmd 'lspci -nn' 'Devices on PCI buses' -cat_cmd 'ls -l /lib/firmware/cypress/*43430*' 'RPi Zero W & 3 WiFi firmware' -cat_cmd 'ls -l /lib/firmware/cypress/*43455*' 'RPi 3 B+ & 4 WiFi firmware' cat_cmd 'env' 'Environment variables' cat_cmd 'node -v' 'Node.js version' cat_cmd 'npm -v' 'npm version' @@ -232,10 +249,10 @@ cat_cmd 'cd /usr/local/calibre-web-py3; sudo git log --graph --oneline --decorat cat_cmd 'sudo lb --version' 'xklb version' cat_cmd 'sudo yt-dlp --version' 'yt-dlp version' cat_cmd 'systemctl status calibre-web' 'Is Calibre-Web running?' -cat_cmd 'journalctl -u calibre-web | tail -100' 'Calibre-Web systemd log' +cat_cmd 'sudo journalctl -u calibre-web | tail -100' 'Calibre-Web systemd log' cat_tail /var/log/calibre-web.log 100 cat_tail /var/log/xklb.log 300 -cat_cmd 'journalctl -t IIAB-CMDSRV' 'Admin Console CMDSRV log' +cat_cmd 'sudo journalctl -t IIAB-CMDSRV' 'Admin Console CMDSRV log' #cat_cmd 'ansible localhost -m setup 2>/dev/null' 'All Ansible facts' # For cleaner scraping of Ansible vars, consider "./runrole all-vars /tmp/all-ansible-vars" 27-31 lines above? echo -e "\n 5. Firewall Rules:\n" diff --git a/scripts/iiab-diagnostics.README.md b/scripts/iiab-diagnostics.README.md index fa6c560e5..7c064b757 100644 --- a/scripts/iiab-diagnostics.README.md +++ b/scripts/iiab-diagnostics.README.md @@ -66,4 +66,4 @@ But first off, the file is compiled by harvesting 1 + 6 kinds of things: ## Source Code -Please look over the bottom of [iiab-diagnostics](iiab-diagnostics) (lines 127-256 especially) to learn more about which common IIAB files and commands make this rapid troubleshooting possible. +Please look over the bottom of [iiab-diagnostics](iiab-diagnostics) (lines 135-273 especially) to learn more about which common IIAB files and commands make this rapid troubleshooting possible. diff --git a/vars/default_vars.yml b/vars/default_vars.yml index 1e84fd3e0..a45384e1e 100644 --- a/vars/default_vars.yml +++ b/vars/default_vars.yml @@ -13,7 +13,7 @@ # IIAB (PRE-)release version number, for {{ iiab_env_file }} -iiab_base_ver: 8.2 +iiab_base_ver: 8.3 iiab_revision: 0 # 2022-06-23: ./iiab-install (with 'sudo iiab') follow the traditional linear @@ -274,7 +274,7 @@ nginx_port: 80 nginx_interface: 0.0.0.0 nginx_conf_dir: /etc/nginx/conf.d nginx_log_dir: /var/log/nginx -# SEE BELOW: nginx_high_php_limits, allow_www_data_sudo +# SEE BELOW: nginx_high_php_limits, allow_www_data_poweroff # roles/www_base runs here (mandatory) @@ -307,11 +307,9 @@ bluetooth_term_enabled: False # USB_LIB usb_lib_install: True usb_lib_enabled: True -# Show entire contents of USB sticks/drives (at http://box/usb) -iiab_usb_lib_show_all: True -# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf so -# Kolibri can export & import channels to USB sticks/drive: -usb_lib_umask0000_for_kolibri: True +# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf for +# Kolibri exports, and student uploads to teacher's USB stick (http://box/usb) +usb_lib_writable_sticks: True systemd_location: /lib/systemd/system # 2-common iiab-startup also uses # Common UNIX Printing System (CUPS) @@ -341,7 +339,7 @@ nginx_high_php_limits: False # ALSO: ADJUST "client_max_body_size 10000M;" AS NEC, IN: /etc/nginx/server.conf # Make this True to enable http://box/js-menu/menu-files/services/power_off.php and set-server-time.php -allow_www_data_sudo: True +allow_www_data_poweroff: False apache_service: apache2 apache_user: www-data # Admin Console uses diff --git a/vars/local_vars_large.yml b/vars/local_vars_large.yml index ac2e78128..7228bb506 100644 --- a/vars/local_vars_large.yml +++ b/vars/local_vars_large.yml @@ -172,7 +172,7 @@ pi_swap_file_size: 1024 # roles/nginx runs here (mandatory) # roles/www_base runs here (mandatory) -# SEE BELOW: nginx_high_php_limits, allow_www_data_sudo +# SEE BELOW: nginx_high_php_limits, allow_www_data_poweroff # 4-SERVER-OPTIONS @@ -192,11 +192,9 @@ bluetooth_install: True bluetooth_enabled: False bluetooth_term_enabled: False -# Show entire contents of USB sticks/drives (at http://box/usb) -iiab_usb_lib_show_all: True -# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf so -# Kolibri can export & import channels to USB sticks/drive: -usb_lib_umask0000_for_kolibri: True +# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf for +# Kolibri exports, and student uploads to teacher's USB stick (http://box/usb) +usb_lib_writable_sticks: True # Common UNIX Printing System (CUPS) cups_install: True @@ -219,7 +217,7 @@ nginx_high_php_limits: False # ALSO: ADJUST "client_max_body_size 10000M;" AS NEC, IN: /etc/nginx/server.conf # Make this True to enable http://box/js-menu/menu-files/services/power_off.php and set-server-time.php -allow_www_data_sudo: True +allow_www_data_poweroff: False # Toggle iiab-refresh-wiki-docs scraping for offline docs (http://box/info) nodocs: False diff --git a/vars/local_vars_medical.yml b/vars/local_vars_medical.yml index 45d6db53f..445c9bb2f 100644 --- a/vars/local_vars_medical.yml +++ b/vars/local_vars_medical.yml @@ -12,8 +12,8 @@ munin_install: True munin_enabled: True vnstat_install: True vnstat_enabled: True -usb_lib_umask0000_for_kolibri: False -allow_www_data_sudo: True +usb_lib_writable_sticks: False +allow_www_data_poweroff: False # By default # kiwix # awstats diff --git a/vars/local_vars_medium.yml b/vars/local_vars_medium.yml index c12fcb04f..153401d26 100644 --- a/vars/local_vars_medium.yml +++ b/vars/local_vars_medium.yml @@ -172,7 +172,7 @@ pi_swap_file_size: 1024 # roles/nginx runs here (mandatory) # roles/www_base runs here (mandatory) -# SEE BELOW: nginx_high_php_limits, allow_www_data_sudo +# SEE BELOW: nginx_high_php_limits, allow_www_data_poweroff # 4-SERVER-OPTIONS @@ -192,11 +192,9 @@ bluetooth_install: True bluetooth_enabled: False bluetooth_term_enabled: False -# Show entire contents of USB sticks/drives (at http://box/usb) -iiab_usb_lib_show_all: True -# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf so -# Kolibri can export & import channels to USB sticks/drive: -usb_lib_umask0000_for_kolibri: True +# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf for +# Kolibri exports, and student uploads to teacher's USB stick (http://box/usb) +usb_lib_writable_sticks: True # Common UNIX Printing System (CUPS) cups_install: False @@ -219,7 +217,7 @@ nginx_high_php_limits: False # ALSO: ADJUST "client_max_body_size 10000M;" AS NEC, IN: /etc/nginx/server.conf # Make this True to enable http://box/js-menu/menu-files/services/power_off.php and set-server-time.php -allow_www_data_sudo: True +allow_www_data_poweroff: False # Toggle iiab-refresh-wiki-docs scraping for offline docs (http://box/info) nodocs: False diff --git a/vars/local_vars_small.yml b/vars/local_vars_small.yml index 88253e035..b17fcc9ae 100644 --- a/vars/local_vars_small.yml +++ b/vars/local_vars_small.yml @@ -172,7 +172,7 @@ pi_swap_file_size: 1024 # roles/nginx runs here (mandatory) # roles/www_base runs here (mandatory) -# SEE BELOW: nginx_high_php_limits, allow_www_data_sudo +# SEE BELOW: nginx_high_php_limits, allow_www_data_poweroff # 4-SERVER-OPTIONS @@ -192,11 +192,9 @@ bluetooth_install: True bluetooth_enabled: False bluetooth_term_enabled: False -# Show entire contents of USB sticks/drives (at http://box/usb) -iiab_usb_lib_show_all: True -# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf so -# Kolibri can export & import channels to USB sticks/drive: -usb_lib_umask0000_for_kolibri: True +# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf for +# Kolibri exports, and student uploads to teacher's USB stick (http://box/usb) +usb_lib_writable_sticks: True # Common UNIX Printing System (CUPS) cups_install: False @@ -219,7 +217,7 @@ nginx_high_php_limits: False # ALSO: ADJUST "client_max_body_size 10000M;" AS NEC, IN: /etc/nginx/server.conf # Make this True to enable http://box/js-menu/menu-files/services/power_off.php and set-server-time.php -allow_www_data_sudo: True +allow_www_data_poweroff: False # Toggle iiab-refresh-wiki-docs scraping for offline docs (http://box/info) nodocs: False diff --git a/vars/local_vars_unittest.yml b/vars/local_vars_unittest.yml index 39d8cf05c..840d0d9b8 100644 --- a/vars/local_vars_unittest.yml +++ b/vars/local_vars_unittest.yml @@ -178,7 +178,7 @@ pi_swap_file_size: 1024 # roles/nginx runs here (mandatory) # roles/www_base runs here (mandatory) -# SEE BELOW: nginx_high_php_limits, allow_www_data_sudo +# SEE BELOW: nginx_high_php_limits, allow_www_data_poweroff # 4-SERVER-OPTIONS @@ -198,11 +198,9 @@ bluetooth_install: False bluetooth_enabled: False bluetooth_term_enabled: False -# Show entire contents of USB sticks/drives (at http://box/usb) -iiab_usb_lib_show_all: True -# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf so -# Kolibri can export & import channels to USB sticks/drive: -usb_lib_umask0000_for_kolibri: True +# Set umask=0000 for VFAT, NTFS and exFAT in /etc/usbmount/usbmount.conf for +# Kolibri exports, and student uploads to teacher's USB stick (http://box/usb) +usb_lib_writable_sticks: True # Common UNIX Printing System (CUPS) cups_install: False @@ -225,7 +223,7 @@ nginx_high_php_limits: False # ALSO: ADJUST "client_max_body_size 10000M;" AS NEC, IN: /etc/nginx/server.conf # Make this True to enable http://box/js-menu/menu-files/services/power_off.php and set-server-time.php -allow_www_data_sudo: True +allow_www_data_poweroff: False # Toggle iiab-refresh-wiki-docs scraping for offline docs (http://box/info) nodocs: True