1
0
Fork 0
mirror of https://github.com/iiab/iiab.git synced 2025-03-09 15:40:17 +00:00

Merge branch 'master' into gitea

This commit is contained in:
Aidan Fitzgerald 2019-03-02 03:28:09 -05:00 committed by GitHub
commit 96940be8b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
233 changed files with 6582 additions and 2784 deletions

View file

@ -1,37 +1,49 @@
*Sharing the World's Free Knowledge*
# Internet-in-a-Box (IIAB) # Internet-in-a-Box (IIAB)
Welcome to the Git repository for Internet-in-a-Box (IIAB). Internet-in-a-Box (IIAB) is a small, inexpensive device which provides essential Internet resources (Wikipedia, OpenStreetMap, Khan Academy and others) without any Internet connection. [Internet-in-a-Box (IIAB)](http://internet-in-a-box.org) is a "learning hotspot" that brings the Internet's crown jewels
(Wikipedia in any language, thousands of Khan Academy videos, zoomable OpenStreetMap, electronic books, WordPress journaling, Toys from Trash electronics projects, ETC) to those without Internet.
You are encouraged to customize this local content hotspot or server with the best of the worlds Free Knowledge — to suit your own region, your school, your medical clinic, your library and/or for your very own family. You can build your own tiny, affordable server (an offline digital library) for your school, your medical clinic, your prison, your region and/or your very own family — accessible with any nearby smartphone, tablet or laptop.
FYI this community product is enabled by professional volunteers working side-by-side with schools, clinics and libraries around the world. Thank you for being a part of our grassroots technology movement! Internet-in-a-Box gives you the DIY tools to:
1. Download then drag-and-drop to arrange the [very best of the Worlds Free Knowledge](http://internet-in-a-box.org/#quality-content).
2. Choose among [30 powerful educational apps](http://wiki.laptop.org/go/IIAB/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](http://wiki.laptop.org/go/IIAB/FAQ#What_are_the_best_places_for_community_support.3F) with schools, clinics and libraries around the world. *Thank you for being a part of our http://OFF.NETWORK grassroots technology [movement](https://meta.wikimedia.org/wiki/Internet-in-a-Box)!*
## Installation ## Installation
Pre-releases of Internet-in-a-Box (IIAB) are available from http://download.iiab.io — click on the highest version number and then launch the 1-line installer. Install Internet-in-a-Box (IIAB) from [download.iiab.io](http://download.iiab.io/)
Please see "What are the best places for community support?" at http://FAQ.IIAB.IO which has 40+ questions and answers to help you along the way, as you put together the digital knowledge hotspot most suitable for your own community. Please see [FAQ.IIAB.IO](http://FAQ.IIAB.IO) which has 40+ questions and answers to help you along the way, as you put together the <!--digital--> "local learning hotspot" most suitable for your own teaching/learning community.
The [Installation](https://github.com/iiab/iiab/wiki/IIAB-Installation) wiki page has more intricate details e.g. if you're trying to install Internet-in-a-Box (IIAB) on a [different platform](https://github.com/iiab/iiab/wiki/IIAB-Platforms) that has not yet been tried. Our [HOW-TO videos](https://www.youtube.com/channel/UC0cBGCxr_WPBPa3IqPVEe3g) can be very helpful and the [Installation](https://github.com/iiab/iiab/wiki/IIAB-Installation) wiki page has more intricate details e.g. if you're trying to install Internet-in-a-Box (IIAB) onto a [different Linux](https://github.com/iiab/iiab/wiki/IIAB-Platforms) that has not yet been tried.
#### Built with Ansible After you've installed the software, you should [add content](https://github.com/iiab/iiab/wiki/IIAB-Installation#add-content), which can of course take time when downloading multi-gigabyte Content Packs!
FYI we use [Ansible](http://wiki.laptop.org/go/IIAB/FAQ#What_is_Ansible_and_what_version_should_I_use.3F) as the underlying technology to install, deploy, configure and manage the various software components. Finally, you can [customize your Internet-in-a-Box home page](http://wiki.laptop.org/go/IIAB/FAQ#How_do_I_customize_my_Internet-in-a-Box_home_page.3F) (typically http://box or http://box.lan) using our **drag-and-drop** Admin Console (http://box.lan/admin) &mdash; to arrange Content Packs and IIAB Apps (services) for your local community's needs.
## Contributing ## Community
We greatly welcome contributions from educators, librarians *and* IT/UX/QA people of all kinds! Internet-in-a-Box (IIAB) greatly welcomes contributions from educators, librarians *and* IT/UX/QA people of all kinds!
Please see "How can I help?" at http://FAQ.IIAB.IO Please see "[How can I help?](http://wiki.laptop.org/go/IIAB/FAQ#How_can_I_help.3F)" at: [FAQ.IIAB.IO](http://FAQ.IIAB.IO)
Check out our [Contributors Guide](https://github.com/iiab/iiab/wiki/IIAB-Contributors-Guide) to learn more about contributing directly to Internet-in-a-Box (IIAB) software and its open community architecture for education. To learn about our software architecture, check out our [Contributors Guide](https://github.com/iiab/iiab/wiki/IIAB-Contributors-Guide). FYI we use [Ansible](http://wiki.laptop.org/go/IIAB/FAQ#What_is_Ansible_and_what_version_should_I_use.3F) <!--as the underlying technology--> to install, deploy, configure and manage the various software components.
*Thank you for helping us enable offline access to the Internet's open knowledge jewels, as well as "Sneakernet-of-Alexandria" distribution of local/indigenous content, when mass media channels do not serve grassroots voices.* To learn more about our open community architecture for "offline" education, start by reviewing "[What technical documentation exists?](http://wiki.laptop.org/go/IIAB/FAQ#What_technical_documentation_exists.3F)"
## Versioning *Thank you for helping us enable offline access to the Internet's free/open knowledge jewels, as well as "Sneakernet-of-Alexandria" distribution of local/indigenous content, when mass media channels do not serve grassroots voices.*
Pre-releases of Internet-in-a-Box (IIAB) are available from http://download.iiab.io — click on the highest version number and then launch the 1-line installer. ## Versions
You can also track the latest Internet-in-a-Box (IIAB) [official releases here](https://github.com/iiab/iiab/releases). Pre-releases of Internet-in-a-Box (IIAB) undergo continuous QA / continuous deployment and are strongly recommended.
Finally older versions are also available, from [github.com/xsce](http://github.com/xsce) and [schoolserver.org](http://schoolserver.org). Install our latest pre-release using the 1-line installer at: [download.iiab.io](http://download.iiab.io/)
You can also consider the <!--latest Internet-in-a-Box (IIAB)--> official releases at: [github.com/iiab/iiab/releases](https://github.com/iiab/iiab/releases)
For older versions, see: [github.com/xsce](http://github.com/xsce), [schoolserver.org](http://schoolserver.org)

View file

@ -1,5 +1,6 @@
# Future overrides of /etc/ansible/ansible.cfg belong in this file. # Future overrides of /etc/ansible/ansible.cfg belong in this file.
# Also used by https://github.com/iiab/iiab-admin-console # Also used by https://github.com/iiab/iiab-admin-console
[defaults] #[defaults]
squash_actions = apk, apt, dnf, homebrew, openbsd_pkg, pacman, pkgng, yum, zypper, package # 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

View file

@ -10,7 +10,7 @@ CWD=`pwd`
OS=`grep ^ID= /etc/*release|cut -d= -f2` OS=`grep ^ID= /etc/*release|cut -d= -f2`
OS=${OS//\"/} OS=${OS//\"/}
MIN_RPI_KERN=4.9.59-v7+ MIN_RPI_KERN=4.9.59-v7+
MIN_ANSIBLE_VER=2.6.5 MIN_ANSIBLE_VER=2.6.14
if [ ! -f /etc/iiab/local_vars.yml ]; then if [ ! -f /etc/iiab/local_vars.yml ]; then
@ -30,19 +30,8 @@ if [ ! -f /etc/iiab/local_vars.yml ]; then
echo -e "(2) MIN/MEDIUM/BIG samples are included in /opt/iiab/iiab/vars" >&2 echo -e "(2) MIN/MEDIUM/BIG samples are included in /opt/iiab/iiab/vars" >&2
echo -e "(3) NO TIME FOR DETAILS? RUN INTERNET-IN-A-BOX'S FRIENDLY 1-LINE INSTALLER:\n" >&2 echo -e "(3) NO TIME FOR DETAILS? RUN INTERNET-IN-A-BOX'S FRIENDLY 1-LINE INSTALLER:\n" >&2
echo -e ' http://download.iiab.io (click on "6.6" or a more recent version!)\n' >&2 echo -e ' http://download.iiab.io (click on "6.7" or a more recent version!)\n' >&2
#case $OS in
# OLPC | fedora)
# echo -e "Please examine /opt/iiab/iiab/vars/local_vars_olpc.yml for XO laptops.\n" >&2
# ;;
# centos | debian | ubuntu | raspbian)
# echo -e "Please consider /opt/iiab/iiab/vars/local_vars_medium.yml or similar.\n" >&2
# ;;
# *)
# echo -e "EXITING: IIAB requires Raspbian, Debian, Ubuntu, CentOS or OLPC/Fedora.\n" >&2
# ;;
#esac
exit 1 exit 1
fi fi
@ -74,7 +63,7 @@ fi
# Subroutine compares software version numbers. Generates rare false positives # Subroutine compares software version numbers. Generates rare false positives
# like "1.0 > 1" and "2.4.0 > 2.4". Avoid risks by structuring conditionals w/ # like "1.0 > 1" and "2.4.0 > 2.4". Avoid risks by structuring conditionals w/
# a consistent # of decimal points e.g. "if version_gt w.x.y.z a.b.c.d; then" # a consistent # of decimal points e.g. "if version_gt w.x.y.z a.b.c.d; then"
function version_gt() { [ "$(printf '%s\n' "$@" | sort -V | head -1)" != "$1" ]; } version_gt() { [ "$(printf '%s\n' "$@" | sort -V | head -1)" != "$1" ]; }
# Verify that Raspbian is running a recent enough kernel. As Raspbian # Verify that Raspbian is running a recent enough kernel. As Raspbian
# updates on 4.9.41-v7+ broke bridging, WiFi AP & OpenVPN in Oct/Nov 2017. # updates on 4.9.41-v7+ broke bridging, WiFi AP & OpenVPN in Oct/Nov 2017.

9
roles/0-init/README.rst Normal file
View file

@ -0,0 +1,9 @@
=============
0-init README
=============
For a higher-level view, please see `IIAB Installation <https://github.com/iiab/iiab/wiki/IIAB-Installation>`_ and http://FAQ.IIAB.IO
This 0th stage literally sets the stage for Internet-in-a-Box (IIAB) installation, prior to Ansible running `Stages 1-to-9 <.>`_ and then the `network <../network>`_ stage.
This serves to confirm low-level Ansible facts from the OS — e.g. for housekeeping tasks related to TZ (time zone), hostname, FQDN (fully-qualified domain name), unusual systemwide dependencies etc — and whether Internet is live so that IIAB installation can proceed.

View file

@ -1,5 +1,5 @@
# Use these to tag a release at a point in time, for {{ iiab_env_file }} # Use these to tag a release at a point in time, for {{ iiab_env_file }}
iiab_base_ver: 6.7 iiab_base_ver: 7.0
iiab_revision: 0 iiab_revision: 0
# These entries should never be changed in this file. # These entries should never be changed in this file.

View file

@ -1,5 +1,2 @@
- name: Create the directory structure for IIAB - name: Create {{ iiab_ini_file }}
include_tasks: fl.yml
- name: Write iiab_ini.yml for the first time
include_tasks: iiab_ini.yml include_tasks: iiab_ini.yml

View file

@ -1,21 +1,21 @@
- name: Is ubuntu-18 server - name: Does /etc/cloud/cloud.cfg exist i.e. is this ubuntu-18 server?
stat: stat:
path: /etc/cloud/cloud.cfg path: /etc/cloud/cloud.cfg
register: U18_server register: U18_server
- name: Edit cloud.cfg yaml - name: 'Put "preserve_hostname: true" in /etc/cloud/cloud.cfg (ubuntu-18 server)'
lineinfile: lineinfile:
dest: /etc/cloud/cloud.cfg path: /etc/cloud/cloud.cfg
regexp: '^preserve_hostname*' regexp: '^preserve_hostname*'
line: 'preserve_hostname: true' line: 'preserve_hostname: true'
state: present state: present
when: U18_server is defined and U18_server.stat.exists when: U18_server is defined and U18_server.stat.exists
- name: Turn the crank for systemd (debuntu) - name: 'Turn the crank for systemd: hostnamectl set-hostname "{{ iiab_hostname }}.{{ iiab_domain }}" (debuntu)'
shell: hostnamectl set-hostname "{{ iiab_hostname }}.{{ iiab_domain }}" shell: hostnamectl set-hostname "{{ iiab_hostname }}.{{ iiab_domain }}"
when: is_debuntu when: is_debuntu
- name: Configure /etc/sysconfig/network (redhat) - name: Install /etc/sysconfig/network from template (redhat)
template: template:
src: roles/network/templates/network/sysconfig.network.j2 src: roles/network/templates/network/sysconfig.network.j2
dest: /etc/sysconfig/network dest: /etc/sysconfig/network
@ -24,9 +24,9 @@
mode: 0644 mode: 0644
when: is_redhat when: is_redhat
- name: Configure short hostname in /etc/hosts - name: Put hostnames "127.0.0.1 localhost.localdomain localhost box {{ iiab_hostname }}" in /etc/hosts
lineinfile: lineinfile:
dest: /etc/hosts path: /etc/hosts
regexp: '^127\.0\.0\.1' regexp: '^127\.0\.0\.1'
line: '127.0.0.1 localhost.localdomain localhost box {{ iiab_hostname }}' line: '127.0.0.1 localhost.localdomain localhost box {{ iiab_hostname }}'
owner: root owner: root

View file

@ -1,12 +1,12 @@
# workaround for fact that auto create does not work on iiab_ini_file (/etc/iiab/iiab.ini) # workaround for fact that auto create does not work on iiab_ini_file (/etc/iiab/iiab.ini)
- name: Create {{ iiab_ini_file }} - name: Create {{ iiab_ini_file }}
file: file:
dest: "{{ iiab_ini_file }}" path: "{{ iiab_ini_file }}"
state: touch state: touch
- name: Add location section to config file - name: Add 'location' variable values to {{ iiab_ini_file }}
ini_file: ini_file:
dest: "{{ iiab_ini_file }}" path: "{{ iiab_ini_file }}"
section: location section: location
option: "{{ item.option }}" option: "{{ item.option }}"
value: "{{ item.value }}" value: "{{ item.value }}"
@ -18,7 +18,7 @@
- name: Add 'version' variable values to {{ iiab_ini_file }} - name: Add 'version' variable values to {{ iiab_ini_file }}
ini_file: ini_file:
dest: "{{ iiab_ini_file }}" path: "{{ iiab_ini_file }}"
section: version section: version
option: "{{ item.option }}" option: "{{ item.option }}"
value: "{{ item.value }}" value: "{{ item.value }}"

View file

@ -5,14 +5,14 @@
path: "{{ iiab_env_file }}" path: "{{ iiab_env_file }}"
register: NewInstall register: NewInstall
- name: Setting first run flag - name: Set first_run flag
set_fact: set_fact:
first_run: True first_run: True
when: not NewInstall.stat.exists when: not NewInstall.stat.exists
# We need to inialize the ini file and only write the location and version # We need to inialize the ini file and only write the location and version
# sections once and only once to preserve the install date and git hash. # sections once and only once to preserve the install date and git hash.
- name: Write iiab_ini.yml for the first time - name: Create IIAB directory structure and {{ iiab_ini_file }}, if first_run
include_tasks: first_run.yml include_tasks: first_run.yml
when: first_run when: first_run
@ -36,30 +36,30 @@
# nobridge: True # nobridge: True
when: ansible_local.local_facts.os == "raspbian" when: ansible_local.local_facts.os == "raspbian"
- name: Set exFAT enabled for XO laptops - name: Set exFAT_enabled if xo_model != "none"
set_fact: set_fact:
exFAT_enabled: True exFAT_enabled: True
when: xo_model != "none" when: xo_model != "none"
# Discover: do we have a gateway? # Discover: do we have a gateway?
# If Ansible detects gateway, becomes WAN candidate. # If Ansible detects gateway, becomes WAN candidate.
- name: Finding gateway - name: "Do we have a gateway? If so set discovered_wan_iface: {{ ansible_default_ipv4.alias }}, iiab_wan_iface: {{ discovered_wan_iface }}"
set_fact: set_fact:
discovered_wan_iface: "{{ ansible_default_ipv4.alias }}" discovered_wan_iface: "{{ ansible_default_ipv4.alias }}"
iiab_wan_iface: "{{ discovered_wan_iface }}" iiab_wan_iface: "{{ discovered_wan_iface }}"
when: ansible_default_ipv4.gateway is defined when: ansible_default_ipv4.gateway is defined
- name: Verify gateway present - name: "Verify gateway active: ping -c4 {{ ansible_default_ipv4.gateway }}"
shell: ping -c4 "{{ ansible_default_ipv4.gateway }}" | grep icmp_seq=4 | wc -l shell: ping -c4 "{{ ansible_default_ipv4.gateway }}" | grep icmp_seq=4 | wc -l
when: discovered_wan_iface != "none" when: discovered_wan_iface != "none"
register: gw_active_test register: gw_active_test
- name: Recording gateway response - name: If so, set gw_active
set_fact: set_fact:
gw_active: True gw_active: True
when: discovered_wan_iface != "none" and gw_active_test.stdout == "1" when: discovered_wan_iface != "none" and gw_active_test.stdout == "1"
- name: Test for Internet access - name: Test for Internet access ({{ iiab_download_url }}/heart-beat.txt)
get_url: get_url:
url: "{{ iiab_download_url }}/heart-beat.txt" url: "{{ iiab_download_url }}/heart-beat.txt"
dest: /tmp/heart-beat.txt dest: /tmp/heart-beat.txt
@ -70,12 +70,12 @@
# poll: 2 # poll: 2
register: internet_access_test register: internet_access_test
- name: Set internet_available true if wget succeeded - name: Set internet_available if download succeeded and not disregard_network
set_fact: set_fact:
internet_available: True internet_available: True
when: not internet_access_test.failed and not disregard_network when: not internet_access_test.failed and not disregard_network
- name: Remove Internet test file - name: Remove downloaded Internet test file /tmp/heart-beat.txt
file: file:
path: /tmp/heart-beat.txt path: /tmp/heart-beat.txt
state: absent state: absent
@ -84,17 +84,17 @@
- name: If the TZ is not set in env, set it to UTC - name: If the TZ is not set in env, set it to UTC
include_tasks: tz.yml include_tasks: tz.yml
- name: Set port 80 for Admin Console - name: Set port 80 for Admin Console if not adm_cons_force_ssl
set_fact: set_fact:
gui_port: 80 gui_port: 80
when: not adm_cons_force_ssl when: not adm_cons_force_ssl
- name: Set port 443 for Admin Console - name: Set port 443 for Admin Console if adm_cons_force_ssl
set_fact: set_fact:
gui_port: 443 gui_port: 443
when: adm_cons_force_ssl when: adm_cons_force_ssl
- name: Require MySQL to be on (mandatory in Stage 3!) - name: Turn on both vars for MySQL (mandatory in Stage 3!)
set_fact: set_fact:
mysql_install: True mysql_install: True
mysql_enabled: True mysql_enabled: True
@ -102,19 +102,21 @@
# We decided to enable mysql unconditionally. # We decided to enable mysql unconditionally.
# when: elgg_enabled or rachel_enabled or owncloud_enabled or phpmyadmin_enabled or wordpress_enabled or iiab_menu_install # when: elgg_enabled or rachel_enabled or owncloud_enabled or phpmyadmin_enabled or wordpress_enabled or iiab_menu_install
# Late 2017: Had commented out MongoDB on a trial basis, for a more basic/lightweight Sugarizer, per https://github.com/iiab/iiab/pull/427 # MongoDB is auto-included by Sugarizer as of Feb 2019, thanks to: roles/sugarizer/meta/main.yml
- name: Turn on vars for MongoDB if Sugarizer enabled #
set_fact: ## Late 2017: Had commented out MongoDB on a trial basis, for a more basic/lightweight Sugarizer, per https://github.com/iiab/iiab/pull/427
mongodb_install: True #- name: Turn on both vars for MongoDB if sugarizer_enabled
mongodb_enabled: True # set_fact:
when: sugarizer_enabled # mongodb_install: True
# mongodb_enabled: True
# when: sugarizer_enabled
# There might be other db's # There might be other db's
- name: Turn on vars for PostgreSQL if Moodle or Pathagar enabled - name: Turn on both vars for PostgreSQL if moodle_enabled or pathagar_enabled
set_fact: set_fact:
postgresql_install: True postgresql_install: True
postgresql_enabled: True postgresql_enabled: True
when: moodle_enabled or (pathagar is defined and pathagar_enabled) when: moodle_enabled or (pathagar_enabled is defined and pathagar_enabled)
#- name: Turn on vars for Docker if SchoolTool is to be installed #- name: Turn on vars for Docker if SchoolTool is to be installed
# set_fact: # set_fact:
@ -122,12 +124,12 @@
# docker_enabled: True # docker_enabled: True
# when: schooltool_enabled or schooltool_install # when: schooltool_enabled or schooltool_install
- name: Set python_path (redhat) - name: "Set python_path: /lib/python2.7/site-packages/ (redhat)"
set_fact: set_fact:
python_path: /lib/python2.7/site-packages/ python_path: /lib/python2.7/site-packages/
when: is_redhat when: is_redhat
- name: Set python_path (debuntu) - name: "Set python_path: /usr/local/lib/python2.7/dist-packages/ (debuntu)"
set_fact: set_fact:
python_path: /usr/local/lib/python2.7/dist-packages/ python_path: /usr/local/lib/python2.7/dist-packages/
when: is_debuntu when: is_debuntu
@ -135,28 +137,31 @@
# For various reasons the mysql service cannot be enabled on Fedora 20, but # For various reasons the mysql service cannot be enabled on Fedora 20, but
# 'mariadb', which is its real name can. On Fedora 18 we need to use 'mysqld'. # 'mariadb', which is its real name can. On Fedora 18 we need to use 'mysqld'.
- name: Set mysql_service to mariadb by default # BETTER TO USE /opt/iiab/iiab/vars/<OS>.yml
set_fact: #- name: "Set mysql_service: mariadb by default"
mysql_service: mariadb # set_fact:
# mysql_service: mariadb
- name: Set mysql_service to mysqld etc (Fedora 18) - name: "Set mysql_service: mysqld etc (Fedora 18)"
set_fact: set_fact:
mysql_service: mysqld # BETTER TO USE /opt/iiab/iiab/vars/<OS>.yml
#mysql_service: mysqld
no_NM_reload: True no_NM_reload: True
is_F18: True is_F18: True
when: (ansible_distribution_release == "based on Fedora 18" or ansible_distribution_version == "18") and ansible_distribution == "Fedora" when: (ansible_distribution_release == "based on Fedora 18" or ansible_distribution_version == "18") and ansible_distribution == "Fedora"
- name: Set mysql_service to mysql (debuntu) # BETTER TO USE /opt/iiab/iiab/vars/<OS>.yml
set_fact: #- name: "Set mysql_service: mysql (debuntu)"
mysql_service: mysql # set_fact:
when: is_debuntu # mysql_service: mysql
# when: is_debuntu
- name: Set FQDN - name: "Set iiab_fqdn: {{ iiab_hostname }}.{{ iiab_domain }}"
set_fact: set_fact:
iiab_fqdn: "{{ iiab_hostname }}.{{ iiab_domain }}" iiab_fqdn: "{{ iiab_hostname }}.{{ iiab_domain }}"
FQDN_changed: False FQDN_changed: False
- name: FQDN changed - name: Set FQDN_changed when iiab_fqdn != ansible_fqdn ({{ ansible_fqdn }})
set_fact: set_fact:
FQDN_changed: True FQDN_changed: True
when: iiab_fqdn != ansible_fqdn when: iiab_fqdn != ansible_fqdn
@ -206,6 +211,10 @@
value: "{{ first_run }}" value: "{{ first_run }}"
- option: local_tz - option: local_tz
value: "{{ local_tz }}" value: "{{ local_tz }}"
- option: no_NM_reload
value: "{{ no_NM_reload }}"
- option: is_F18
value: "{{ is_F18 }}"
- option: FQDN_changed - option: FQDN_changed
value: "{{ FQDN_changed }}" value: "{{ FQDN_changed }}"

View file

@ -0,0 +1,3 @@
d /var/log/apache2 1750 www-data www-data
d /var/log/munin 1755 munin adm
d /var/log/mongodb 1755 mongodb root

View file

@ -3,40 +3,65 @@
- name: ...IS BEGINNING ============================================ - name: ...IS BEGINNING ============================================
command: echo command: echo
- name: Install uuidgen program (debuntu) - name: Install uuid-runtime package (debuntu)
package: package:
name: uuid-runtime name:
- uuid-runtime
- sudo
state: present state: present
when: is_debuntu when: is_debuntu
- name: Test for /etc/iiab/uuid file - name: Does /etc/iiab/uuid file exist?
stat: stat:
path: /etc/iiab/uuid path: /etc/iiab/uuid
register: uuid_file register: uuid_file
- name: Create folder to hold uuid
file:
path: /etc/iiab
state: directory
when: not uuid_file.stat.exists
- name: If no uuid exists, create one - name: If no uuid exists, create one
shell: uuidgen shell: uuidgen
register: uuid_response register: uuid_response
when: not uuid_file.stat.exists when: not uuid_file.stat.exists
- name: Put the uuid in place - name: Put uuid in place at /etc/iiab/uuid
shell: echo {{ uuid_response.stdout_lines[0] }} > /etc/iiab/uuid shell: echo {{ uuid_response.stdout_lines[0] }} > /etc/iiab/uuid
when: not uuid_file.stat.exists when: not uuid_file.stat.exists
- name: Get the uuid - name: Grab the uuid from /etc/iiab/uuid, into register stored_uuid
command: cat /etc/iiab/uuid command: cat /etc/iiab/uuid
register: stored_uuid register: stored_uuid
- name: Get the value into a variable - name: Place the uuid from register into variable/fact "uuid"
set_fact: set_fact:
uuid: "{{ stored_uuid.stdout_lines[0] }}" uuid: "{{ stored_uuid.stdout_lines[0] }}"
#- name: Does directory /ro exist? (indicating OS is Ubermix)
# stat:
# path: /ro
# register: ro_dir
#- debug:
# var: ro_dir
- name: Does 'ubermix' exist in /etc/lsb-release?
shell: grep -i ubermix /etc/lsb-release # Pipe to cat to avoid red errors?
register: grep_ubermix
failed_when: false # Universal way to hide alarmist red errors!
#ignore_errors: true
#check_mode: no
#- debug:
# var: grep_ubermix
- name: If so, install /etc/tmpfiles.d/iiab.conf to create /var/log subdirs on each boot, so {Apache, MongoDB, Munin} run on Ubermix
copy:
src: roles/1-prep/files/iiab.conf
dest: /etc/tmpfiles.d/
owner: root
group: root
mode: 0644
force: yes
when: grep_ubermix.rc == 0 # 1 if absent in file, 2 if file doesn't exist
#when: ro_dir.stat.exists
- name: SSHD - name: SSHD
include_role: include_role:
name: sshd name: sshd
@ -56,21 +81,19 @@
tags: openvpn tags: openvpn
# for rpi, without rtc, we need time as soon as possible # for rpi, without rtc, we need time as soon as possible
- name: Install chrony package - name: Install chrony (an NTP package) especially for RPi's lacking RTC
package: package:
name: "{{ item }}" name: chrony
state: present state: present
with_items:
- chrony
tags: tags:
- download - download
#TODO: Use regexp filter instead of hard-code ip #TODO: Use regexp filter instead of hard-code ip
- name: Update chrony config file - name: Install /etc/chrony.conf from template
template: template:
backup: no
dest: /etc/chrony.conf
src: chrony.conf.j2 src: chrony.conf.j2
dest: /etc/chrony.conf
backup: no
- name: Disable AppArmor -- override OS default (ubuntu) - name: Disable AppArmor -- override OS default (ubuntu)
service: service:
@ -95,12 +118,12 @@
- include_tasks: raspberry_pi.yml - include_tasks: raspberry_pi.yml
when: first_run and rpi_model != "none" when: first_run and rpi_model != "none"
- name: Check if the identifier for Intel's NUC6 builtin WiFi is present - name: Check if the identifier for Intel's NUC6 built-in WiFi is present
shell: "lsusb | grep 8087:0a2b | wc | awk '{print $1}'" shell: "lsusb | grep 8087:0a2b | wc | awk '{print $1}'"
register: usb_NUC6 register: usb_NUC6
ignore_errors: true ignore_errors: true
- name: Download the firmware for built-in WiFi on NUC6 - name: Download {{ iiab_download_url }}/iwlwifi-8000C-13.ucode to /lib/firmware for built-in WiFi on NUC6 # iiab_download_url is http://download.iiab.io/packages
get_url: get_url:
url: "{{ iiab_download_url }}/iwlwifi-8000C-13.ucode" url: "{{ iiab_download_url }}/iwlwifi-8000C-13.ucode"
dest: /lib/firmware dest: /lib/firmware

View file

@ -1,6 +1,6 @@
# Setup specific to the Raspberry Pi # Specific to Raspberry Pi
- name: Add a udev rule to transfer hwclock to system clock at dev creation - name: Install udev rule /etc/udev/rules.d/92-rtc-i2c.rules from template, to transfer hwclock to system clock at dev creation, if rtc_id is defined and rtc_id != "none"
template: template:
src: 92-rtc-i2c.rules src: 92-rtc-i2c.rules
dest: /etc/udev/rules.d/92-rtc-i2c.rules dest: /etc/udev/rules.d/92-rtc-i2c.rules
@ -10,42 +10,43 @@
when: rtc_id is defined and rtc_id != "none" when: rtc_id is defined and rtc_id != "none"
# RTC requires a change to the device tree (and reboot) # RTC requires a change to the device tree (and reboot)
- name: Check for needing to enable i2c rtc device in config.txt - name: Enable i2c-rtc device (with "dtoverlay=i2c-rtc,{{ rtc_id }}=on" in /boot/config.txt, requires reboot!) if rtc_id is defined and rtc_id != "none"
lineinfile: lineinfile:
dest: /boot/config.txt path: /boot/config.txt
line: "dtoverlay=i2c-rtc,{{ rtc_id }}=on" line: "dtoverlay=i2c-rtc,{{ rtc_id }}=on"
state: present state: present
register: rpiconfig register: rpiconfig # HMMM REGISTER "rpiconfig" IS *COMPLETELY UNUSED* AS OF 2018-11-02
when: rtc_id != "none" when: rtc_id is defined and rtc_id != "none"
- name: Add a udev rule to transfer hwclock to system clock at dev creation #- name: Install udev rule /etc/udev/rules.d/92-rtc-i2c.rules from template, to transfer hwclock to system clock at dev creation, if rtc_id != "none"
template: # template:
src: 92-rtc-i2c.rules # src: 92-rtc-i2c.rules
dest: /etc/udev/rules.d/92-rtc-i2c.rules # dest: /etc/udev/rules.d/92-rtc-i2c.rules
owner: root # owner: root
group: root # group: root
mode: 0644 # mode: 0644
when: rtc_id != "none" # when: rtc_id != "none"
- name: Pre-install packages - name: Install latest ntp package
package: package:
name: "{{ item }}" name: ntp
state: latest state: latest
with_items:
- ntp
- name: Increase the swap file size, as kalite pip download fails (debuntu) - name: Increase swap file size (to CONF_SWAPSIZE=500 in /etc/dphys-swapfile) as kalite pip download fails (debuntu)
lineinfile: lineinfile:
path: /etc/dphys-swapfile
regexp: "^CONF_SWAPSIZE" regexp: "^CONF_SWAPSIZE"
line: CONF_SWAPSIZE=500 line: CONF_SWAPSIZE=500
dest: /etc/dphys-swapfile
when: is_debuntu when: is_debuntu
- name: Restart the swap service (debuntu) - name: Restart swap service "dphys-swapfile" (debuntu)
command: /etc/init.d/dphys-swapfile restart #command: /etc/init.d/dphys-swapfile restart
service: # A rare/legacy service that is NOT systemd
name: dphys-swapfile
state: restarted
when: is_debuntu when: is_debuntu
- name: Add RPi rootfs resizing service - name: Install RPi rootfs resizing (iiab-rpi-max-rootfs.sh) and its systemd service (iiab-rpi-root-resize.service), from templates
template: template:
src: "{{ item.src }}" src: "{{ item.src }}"
dest: "{{ item.dest }}" dest: "{{ item.dest }}"
@ -56,7 +57,7 @@
- { src: 'iiab-rpi-max-rootfs.sh', dest: '/usr/sbin/iiab-rpi-max-rootfs.sh', mode: '0755'} - { src: 'iiab-rpi-max-rootfs.sh', dest: '/usr/sbin/iiab-rpi-max-rootfs.sh', mode: '0755'}
- { src: 'iiab-rpi-root-resize.service', dest: '/etc/systemd/system/iiab-rpi-root-resize.service', mode: '0644'} - { src: 'iiab-rpi-root-resize.service', dest: '/etc/systemd/system/iiab-rpi-root-resize.service', mode: '0644'}
- name: Enable rootfs resizing service - name: Enable RPi rootfs resizing (systemd service iiab-rpi-root-resize.service)
service: systemd:
name: iiab-rpi-root-resize name: iiab-rpi-root-resize
enabled: yes enabled: yes

View file

@ -1,4 +1,6 @@
- name: Create various library directories # fl.yml signifies "file layout"
- name: Create 19 directories with ownership root:root and permissions 0755 (1 in /etc, 3 in {{ iiab_base }} and 15 in /library) # iiab_base is /opt/iiab
file: file:
path: "{{ item }}" path: "{{ item }}"
owner: root owner: root
@ -6,7 +8,7 @@
mode: 0755 mode: 0755
state: directory state: directory
with_items: with_items:
- /etc/iiab - /etc/sysconfig/olpc-scripts/setup.d/installed/
- "{{ yum_packages_dir }}" - "{{ yum_packages_dir }}"
- "{{ pip_packages_dir }}" - "{{ pip_packages_dir }}"
- "{{ downloads_dir }}" - "{{ downloads_dir }}"
@ -25,10 +27,8 @@
- "{{ doc_root }}/common/images" - "{{ doc_root }}/common/images"
- "{{ doc_root }}/common/assets" - "{{ doc_root }}/common/assets"
- "{{ doc_root }}/common/services" - "{{ doc_root }}/common/services"
- /etc/sysconfig/olpc-scripts/
- /etc/sysconfig/olpc-scripts/setup.d/installed/
- name: Create symlink from webfonts to fonts - name: Symlink from {{ doc_root }}/common/webfonts to {{ doc_root }}/common/fonts
file: file:
src: "{{ doc_root }}/common/fonts" src: "{{ doc_root }}/common/fonts"
path: "{{ doc_root }}/common/webfonts" path: "{{ doc_root }}/common/webfonts"

View file

@ -3,20 +3,20 @@
path: /usr/libexec/iiab-startup.sh path: /usr/libexec/iiab-startup.sh
register: startup_script register: startup_script
- name: Copy template script to /usr/libexec/iiab-startup.sh - name: If not, install /usr/libexec/iiab-startup.sh from template
template: template:
src: iiab-startup.sh src: iiab-startup.sh
dest: /usr/libexec/ dest: /usr/libexec/
mode: 0755 mode: 0755
when: not startup_script.stat.exists when: not startup_script.stat.exists
- name: Copy iiab-startup.service to {{ systemd_location }} - name: Install {{ systemd_location }}/iiab-startup.service from template
template: template:
src: iiab-startup.service src: iiab-startup.service
dest: "{{ systemd_location }}" dest: "{{ systemd_location }}"
when: not startup_script.stat.exists when: not startup_script.stat.exists
- name: Enable & restart the systemd service after daemon-reload - name: Enable & restart systemd service (iiab-startup) after daemon-reload
# shell: systemctl daemon-reload # shell: systemctl daemon-reload
# shell: systemctl restart iiab-startup.service # shell: systemctl restart iiab-startup.service
# shell: systemctl enable iiab-startup.service # shell: systemctl enable iiab-startup.service

View file

@ -4,12 +4,13 @@
enabled: no enabled: no
when: not is_debuntu when: not is_debuntu
- name: Use larger hammer to disable firewalld -- 2 symbolic links involved (OS's other than debuntu) # Likely no longer nec as of 2019
shell: "systemctl disable firewalld.service" - name: Use larger hammer -- systemctl disable firewalld -- 2 symbolic links involved (OS's other than debuntu)
shell: systemctl disable firewalld.service
when: not is_debuntu when: not is_debuntu
- name: Mask firewalld service (OS's other than debuntu) - name: Mask firewalld service (OS's other than debuntu)
shell: 'systemctl mask firewalld' shell: systemctl mask firewalld
ignore_errors: yes ignore_errors: yes
when: not installing and not is_debuntu when: not installing and not is_debuntu
@ -20,17 +21,17 @@
ignore_errors: yes ignore_errors: yes
when: not installing and not is_debuntu when: not installing and not is_debuntu
- name: Remove iptables.service file from /etc - name: Remove /etc/systemd/system/iptables.service
file: file:
path: /etc/systemd/system/iptables.service path: /etc/systemd/system/iptables.service
state: absent state: absent
- name: Remove iptables-xs.service file from /etc #- name: Remove iptables-xs.service file from /etc
file: # file:
path: /etc/systemd/system/iptables-xs.service # path: /etc/systemd/system/iptables-xs.service
state: absent # state: absent
- name: Install iptables service package (debuntu) - name: Install package iptables-persistent (debuntu)
package: package:
name: iptables-persistent name: iptables-persistent
state: present state: present
@ -38,7 +39,7 @@
tags: tags:
- download - download
- name: Install iptables service package (OS's other than debuntu) - name: Install package iptables-services (OS's other than debuntu)
package: package:
name: iptables-services name: iptables-services
state: present state: present
@ -46,17 +47,15 @@
tags: tags:
- download - download
- name: Install iptables services - name: Install /etc/sysconfig/iptables-config from template
template: template:
src: "{{ item.0 }}" src: iptables-config
dest: "{{ item.1 }}" dest: /etc/sysconfig/iptables-config
owner: root owner: root
group: root group: root
mode: "{{ item.2 }}" mode: 0644
with_items:
- { 0: 'iptables-config', 1: '/etc/sysconfig/iptables-config', 2: '0644' }
- name: Install Debian config (debuntu) - name: Install /etc/network/if-pre-up.d/iptables from template (debuntu)
template: template:
src: iptables src: iptables
dest: /etc/network/if-pre-up.d/iptables dest: /etc/network/if-pre-up.d/iptables

View file

@ -3,6 +3,9 @@
- name: ...IS BEGINNING ========================================== - name: ...IS BEGINNING ==========================================
command: echo command: echo
- name: Create IIAB directory structure ("file layout")
include_tasks: fl.yml
- include_tasks: centos.yml - include_tasks: centos.yml
when: ansible_distribution == "CentOS" when: ansible_distribution == "CentOS"
@ -72,7 +75,7 @@
value: 1 value: 1
state: present state: present
- name: Install custom profile file - name: Install custom /etc/profile.d/zzz_iiab.sh from template
template: template:
dest: /etc/profile.d/zzz_iiab.sh dest: /etc/profile.d/zzz_iiab.sh
src: zzz_iiab.sh src: zzz_iiab.sh

View file

@ -1,124 +1,73 @@
- name: Install yum packages (redhat) - name: "Install 10 yum/dnf packages: avahi, avahi-tools, createrepo, linux-firmware, nss-mdns, openssl, syslog, wpa_supplicant, xml-common, yum-utils (redhat)"
package: package:
name: "{{ item }}" name:
state: present
with_items:
- yum-utils
- createrepo
- wpa_supplicant
- linux-firmware
- syslog
- xml-common
- nss-mdns
- avahi - avahi
- avahi-tools - avahi-tools
- createrepo
- linux-firmware
- nss-mdns
- openssl # FC 18 does not supply, but pear requires
- syslog
- wpa_supplicant
- xml-common
- yum-utils
state: present
when: is_redhat when: is_redhat
- name: Download & install usbmount, missing from Debian Stretch (debian-9) - name: Install {{ iiab_download_url }}/usbmount_0.0.14.1_all.deb, missing from Debian (debian-9 or debian-10, if NOT rpi)
apt: apt:
deb: "{{ iiab_download_url }}/usbmount_0.0.14.1_all.deb" deb: "{{ iiab_download_url }}/usbmount_0.0.14.1_all.deb"
#timeout: "{{ download_timeout }}" # Ansible's apt module doesn't support timeout parameter; that's ok as usbmount_0.0.14.1_all.deb is only 10KB #timeout: "{{ download_timeout }}" # Ansible's apt module doesn't support timeout parameter; that's ok as usbmount_0.0.14.1_all.deb is only 10KB
when: internet_available and is_debian_9 when: internet_available and (is_debian_9 or is_debian_10) and not is_rpi
#- name: Download usbmount -- not in Debian Stretch (debian-9) - name: "Install 7 deb/apt packages: avahi-daemon, avahi-discover, exfat-fuse, exfat-utils, inetutils-syslogd, libnss-mdns, wpasupplicant (debuntu)"
# get_url:
# url: "{{ iiab_download_url }}/usbmount_0.0.14.1_all.deb"
# dest: "{{ downloads_dir }}"
# timeout: "{{ download_timeout }}"
# when: internet_available and is_debian_9
#
#- name: Install usbmount (debian-9)
# command: apt install -y {{ downloads_dir }}/usbmount_0.0.14.1_all.deb
# when: is_debian_9
- name: Install packages (debuntu)
package: package:
name: "{{ item }}" name:
state: present
with_items:
- inetutils-syslogd
- wpasupplicant
- libnss-mdns
- avahi-daemon - avahi-daemon
- avahi-discover - avahi-discover
- exfat-fuse - exfat-fuse
- exfat-utils - exfat-utils
- inetutils-syslogd
- libnss-mdns
- wpasupplicant
state: present
when: is_debuntu when: is_debuntu
- name: Install common packages - name: "Install 22 common packages: acpid, bridge-utils, bzip2, curl, gawk, hostapd, htop, i2c-tools, logrotate, make, mlocate, netmask, net-tools, ntfs-3g, pandoc, rsync, sudo, tar, unzip, usbmount, usbutils, wget"
package: package:
name: "{{ item }}" name:
state: present
with_items:
- acpid - acpid
- mlocate - bridge-utils
- rsync - bzip2
- htop - curl
#- etckeeper # "nobody is really using etckeeper and it's bloating the filesystem every time apt runs" per @jvonau at https://github.com/iiab/iiab/issues/1146 #- etckeeper # "nobody is really using etckeeper and it's bloating the filesystem every time apt runs" per @jvonau at https://github.com/iiab/iiab/issues/1146
- python-passlib - gawk
- usbmount - hostapd
- net-tools - htop
- openssh-server - i2c-tools
- sudo
- logrotate - logrotate
#- lynx # already installed by 1-prep's roles/iiab-admin/tasks/access.yml
- make - make
- mlocate
- netmask
- net-tools
- ntfs-3g
#- openssh-server # ssh (Raspbian) or openssh-server (other OS's) already installed by 1-prep's roles/sshd/tasks/main.yml
- pandoc
- rsync
- sudo
- tar - tar
- unzip - unzip
- bzip2 - usbmount
- i2c-tools
- bridge-utils
- netmask
- usbutils - usbutils
- hostapd
- wget - wget
- openssl # FC 18 does not supply, but pear requires
- gawk
- curl
- pandoc
- lynx
- ntfs-3g
#- name: Install pip as a commonly required package management system
# command: curl https://bootstrap.pypa.io/get-pip.py -o {{ downloads_dir }}/get-pip.py
#- name: Run the install script for pip
# command: python {{ downloads_dir }}/get-pip.py
- name: Install common Python packages
package:
name: "{{ item }}"
state: present state: present
with_items:
- name: "Install 4 common Python packages: python-passlib, python-pip, python-setuptools, python-virtualenv"
package:
name:
- python-passlib
- python-pip - python-pip
- python-setuptools - python-setuptools
- python-virtualenv - python-virtualenv
state: present
# instructions state to start with a fully updated system before starting, stop using
# ansible as a crutch for developers not following the directions and taking short-cuts
#- name: Update common packages (not Debian)
# package: name={{ item }}
# state=latest
# with_items:
# - NetworkManager
# - glibc # CVE-2015-7547
# - bash
# - iptables
# when: is_redhat
# Consensus decision to try to slim down https://github.com/iiab/iiab/issues/518 (per 2017-11-20 community/team call @ http://minutes.iiab.io)
#- name: Update common packages (debuntu)
# package: name={{ item }}
# state=latest
# with_items:
# - libc6
# - bash
# - iptables
# when: is_debuntu
#- name: If version of Network manager has changed, subsequent nmcli commands will fail,restart now
# service: name=NetworkManager
# state=restarted
# when: not installing
# the above should use a handler - all reboots should wait until all
# mods are preformed

View file

@ -15,12 +15,17 @@
# has no "when: XXXXX_install" flag # has no "when: XXXXX_install" flag
tags: base, mysql tags: base, mysql
- name: Restart httpd - name: Restart Apache systemd service ({{ apache_service }})
service: systemd:
name: "{{ apache_service }}" name: "{{ apache_service }}"
state: restarted state: restarted
when: not installing when: not installing
- name: Create a Python interface to iiab.env
template:
src: roles/1-prep/templates/iiab_env.py.j2
dest: /etc/iiab/iiab_env.py
- name: Recording STAGE 3 HAS COMPLETED ===================== - name: Recording STAGE 3 HAS COMPLETED =====================
lineinfile: lineinfile:
dest: "{{ iiab_env_file }}" dest: "{{ iiab_env_file }}"

View file

@ -3,26 +3,34 @@
- name: ...IS BEGINNING ================================== - name: ...IS BEGINNING ==================================
command: echo command: echo
- name: Installing dnsmasq - name: Install dnsmasq
include_tasks: roles/network/tasks/dnsmasq.yml include_tasks: roles/network/tasks/dnsmasq.yml
when: dnsmasq_install when: dnsmasq_install
tags: base, domain, dnsmasq, network tags: base, domain, dnsmasq, network
- name: Installing named - name: Install named / BIND
include_tasks: roles/network/tasks/named.yml include_tasks: roles/network/tasks/named.yml
when: named_install when: named_install
tags: base, named, network, domain tags: base, named, network, domain
- name: Installing captive portal
include_tasks: roles/captive-portal/tasks/main.yml
when: captive_portal_install
tags: base, captive-portal, network, domain
- name: Installing dhcpd - name: Installing dhcpd
include_tasks: roles/network/tasks/dhcpd.yml include_tasks: roles/network/tasks/dhcpd.yml
when: dhcpd_install when: dhcpd_install
tags: base, dhcpd, network, domain tags: base, dhcpd, network, domain
- name: Installing Squid - name: Install Squid (and DansGuardian if dansguardian_install)
include_tasks: roles/network/tasks/squid.yml include_tasks: roles/network/tasks/squid.yml
when: squid_install when: squid_install
tags: base, squid, network, domain tags: base, squid, network, domain
# NETWORK moved to the very end, after Stage 9 (9-LOCAL-ADDONS)
# It can also be run manually using: cd /opt/iiab/iiab; ./iiab-network
#
#- name: NETWORK #- name: NETWORK
# include_role: # include_role:
# name: network # name: network
@ -42,10 +50,11 @@
when: postgresql_install when: postgresql_install
tags: postgresql, pathagar, moodle tags: postgresql, pathagar, moodle
# UNMAINTAINED
- name: AUTHSERVER - name: AUTHSERVER
include_role: include_role:
name: authserver name: authserver
when: authserver_install when: authserver_install is defined and authserver_install
tags: olpc, authserver tags: olpc, authserver
- name: CUPS - name: CUPS
@ -66,13 +75,7 @@
when: usb_lib_install when: usb_lib_install
tags: usb-lib tags: usb-lib
# MANDATORY SO PERHAPS THIS BELONGS IN 3-BASE-SERVER ? - name: Run /usr/bin/iiab-refresh-wiki-docs (scraper script) to create http://box/info offline documentation. (This script was installed at the beginning of Stage 3 = roles/3-base-server/tasks/main.yml, which ran Apache playbook = roles/httpd/tasks/main.yml)
- name: Create a Python interface to iiab.env
template:
src: roles/1-prep/templates/iiab_env.py.j2
dest: /etc/iiab/iiab_env.py
- name: Run /usr/bin/iiab-refresh-wiki-docs (scraper script) to create http://box/info offline documentation (script was installed at the beginning of Stage 3 = roles/3-base-server/tasks/main.yml, which runs the HTTPD playbook = roles/httpd/tasks/main.yml)
command: /usr/bin/iiab-refresh-wiki-docs command: /usr/bin/iiab-refresh-wiki-docs
when: not nodocs when: not nodocs

View file

@ -27,6 +27,24 @@
when: ejabberd_install when: ejabberd_install
tags: ejabberd tags: ejabberd
- name: LOKOLE
include_role:
name: lokole
when: lokole_install
tags: lokole
- name: MOSQUITTO
include_role:
name: mosquitto
when: mosquitto_install
tags: mosquitto
- name: NODE-RED
include_role:
name: nodered
when: nodered_install
tags: nodered
- name: NEXTCLOUD - name: NEXTCLOUD
include_role: include_role:
name: nextcloud name: nextcloud
@ -39,6 +57,12 @@
# when: owncloud_install # when: owncloud_install
# tags: owncloud # tags: owncloud
- name: PBX
include_role:
name: pbx
when: pbx_install
tags: pbx
- name: WORDPRESS - name: WORDPRESS
include_role: include_role:
name: wordpress name: wordpress

View file

@ -27,12 +27,14 @@
when: moodle_install when: moodle_install
tags: olpc, moodle tags: olpc, moodle
# UNMAINTAINED
- name: OSM - name: OSM
include_role: include_role:
name: osm name: osm
when: osm_install is defined and osm_install when: osm_install is defined and osm_install
tags: osm tags: osm
# UNMAINTAINED
- name: PATHAGAR - name: PATHAGAR
include_role: include_role:
name: pathagar name: pathagar

View file

@ -33,12 +33,14 @@
when: phpmyadmin_install when: phpmyadmin_install
tags: phpmyadmin tags: phpmyadmin
# UNMAINTAINED
- name: SUGAR-STATS - name: SUGAR-STATS
include_role: include_role:
name: sugar-stats name: sugar-stats
when: sugar_stats_install is defined and sugar_stats_install and ansible_distribution != "CentOS" when: sugar_stats_install is defined and sugar_stats_install and ansible_distribution != "CentOS"
tags: olpc, sugar-stats tags: olpc, sugar-stats
# UNMAINTAINED
- name: TEAMVIEWER - name: TEAMVIEWER
include_role: include_role:
name: teamviewer name: teamviewer
@ -51,6 +53,7 @@
when: vnstat_install when: vnstat_install
tags: vnstat tags: vnstat
# UNMAINTAINED
- name: XOVIS - name: XOVIS
include_role: include_role:
name: xovis name: xovis

View file

@ -15,6 +15,12 @@
when: calibreweb_install when: calibreweb_install
tags: calibre-web tags: calibre-web
- name: MINETEST
include_role:
name: minetest
when: minetest_install
tags: minetest
- name: Recording STAGE 9 HAS COMPLETED ==================== - name: Recording STAGE 9 HAS COMPLETED ====================
lineinfile: lineinfile:
dest: "{{ iiab_env_file }}" dest: "{{ iiab_env_file }}"

View file

@ -116,11 +116,12 @@
enabled=yes enabled=yes
state=restarted state=restarted
- name: add xs-activity-server to service list - name: Add 'activity-server' variable values to {{ iiab_ini_file }}
ini_file: dest='{{ iiab_ini_file }}' ini_file:
section=activity-server path: "{{ iiab_ini_file }}"
option='{{ item.option }}' section: activity-server
value='{{ item.value }}' option: "{{ item.option }}"
value: "{{ item.value }}"
with_items: with_items:
- option: name - option: name
value: "Activity Server" value: "Activity Server"

View file

@ -47,11 +47,12 @@
state=restarted state=restarted
when: ajenti_enabled when: ajenti_enabled
- name: Add ajenti to service list - name: Add 'ajenti' variable values to {{ iiab_ini_file }}
ini_file: dest='{{ iiab_ini_file }}' ini_file:
section=ajenti path: "{{ iiab_ini_file }}"
option='{{ item.option }}' section: ajenti
value='{{ item.value }}' option: "{{ item.option }}"
value: "{{ item.value }}"
with_items: with_items:
- option: name - option: name
value: ajenti value: ajenti

View file

@ -50,18 +50,19 @@
enabled=yes enabled=yes
when: authserver_enabled when: authserver_enabled
- name: add xs-authserver to service list - name: Add 'authserver' variable values to {{ iiab_ini_file }}
ini_file: dest='{{ iiab_ini_file }}' ini_file:
section=xs-authserver path: "{{ iiab_ini_file }}"
option='{{ item.option }}' section: authserver
value='{{ item.value }}' option: "{{ item.option }}"
value: "{{ item.value }}"
with_items: with_items:
- option: name - option: name
value: XS-authserver value: XS-authserver
- option: description - option: description
value: '"xs-authserver implements a seamless web authentication service value: '"authserver (xs-authserver) implements a seamless web authentication
using XO laptop registration capabilities. It is heavily inspired service using XO laptop registration capabilities. It is heavily
by the Moodle OLPC-XS authentication plugin"' inspired by the Moodle OLPC-XS authentication plugin"'
- option: port - option: port
value: 5000 value: 5000
- option: path - option: path

View file

@ -1,21 +1,19 @@
- name: Install AWStats package - name: 'Install 3 packages: awstats, openssl, pwauth'
package: package:
name: "{{ item }}" name:
state: present
with_items:
- awstats - awstats
- pwauth - pwauth
- openssl - openssl
state: present
tags: tags:
- download - download
- name: Install AWStats package (debuntu) - name: 'Install 2 packages: apache2-utils, libapache2-mod-authnz-external (debuntu)'
package: package:
name: "{{ item }}" name:
state: present
with_items:
- libapache2-mod-authnz-external - libapache2-mod-authnz-external
- apache2-utils - apache2-utils
state: present
when: is_debuntu when: is_debuntu
tags: tags:
- download - download
@ -24,7 +22,7 @@
command: a2enmod cgi command: a2enmod cgi
when: is_debuntu when: is_debuntu
- name: Create directory for AWStats to use as intermediate summary storage - name: 'Mandate {{ apache_user }}:{{ apache_user }} perm 0750 dirs: {{ awstats_data_dir }} (intermediate summary storage) & {{ apache_log_dir }}' # /library/awstats & /var/log/apache2 typically
file: file:
path: "{{ item }}" path: "{{ item }}"
mode: 0750 mode: 0750
@ -37,7 +35,7 @@
- "{{ awstats_data_dir }}" - "{{ awstats_data_dir }}"
- "{{ apache_log_dir }}" - "{{ apache_log_dir }}"
- name: Install the Apache config for AWStats (debuntu) - name: Install Apache's awstats.conf from template (debuntu)
template: template:
src: apache.conf src: apache.conf
dest: "/etc/{{ apache_config_dir }}/awstats.conf" dest: "/etc/{{ apache_config_dir }}/awstats.conf"
@ -46,7 +44,7 @@
mode: 0644 mode: 0644
when: awstats_enabled and is_debuntu when: awstats_enabled and is_debuntu
- name: Install the Apache config for AWStats (OS's other than debuntu) - name: Install Apache's awstats.conf from template (OS's other than debuntu)
template: template:
src: apache-awstats.conf src: apache-awstats.conf
dest: "/etc/{{ apache_config_dir }}/awstats.conf" dest: "/etc/{{ apache_config_dir }}/awstats.conf"
@ -55,35 +53,41 @@
mode: 0644 mode: 0644
when: awstats_enabled and not is_debuntu when: awstats_enabled and not is_debuntu
- name: Make sure logrotate does not make logs unreadable (debuntu) - name: Ensure logrotate doesn't make logs unreadable (debuntu)
template: template:
src: logrotate.d.apache2 src: logrotate.d.apache2
dest: /etc/logrotate.d/apache2 dest: /etc/logrotate.d/apache2
when: is_debuntu when: is_debuntu
- name: See if AWStats package installed a config file - name: Check if package installed /etc/awstats/awstats.conf
stat: stat:
path: /etc/awstats/awstats.conf path: /etc/awstats/awstats.conf
register: awstats register: awstats
- name: If there was a config file installed by package, move it aside - name: If so, move it aside to /etc/awstats/awstats.conf.dist
command: mv /etc/awstats/awstats.conf /etc/awstats/awstats.conf.dist command: mv /etc/awstats/awstats.conf /etc/awstats/awstats.conf.dist
when: awstats.stat.islnk is defined and not awstats.stat.islnk when: awstats.stat.islnk is defined and not awstats.stat.islnk
- name: Enable AWStats (debuntu) - name: Create symlink awstats.conf from sites-enabled to sites-available (debuntu)
file: file:
src: /etc/apache2/sites-available/awstats.conf src: /etc/apache2/sites-available/awstats.conf
path: /etc/apache2/sites-enabled/awstats.conf path: /etc/apache2/sites-enabled/awstats.conf
state: link state: link
when: awstats_enabled and is_debuntu when: awstats_enabled and is_debuntu
- name: Disable AWStats (debuntu) - name: Remove symlink from sites-enabled, to disable AWStats (debuntu)
file: file:
path: /etc/apache2/sites-enabled/awstats.conf path: /etc/apache2/sites-enabled/awstats.conf
state: absent state: absent
when: not awstats_enabled and is_debuntu when: not awstats_enabled and is_debuntu
- name: Install the AWStats config - name: Restart Apache service ({{ apache_service }})
systemd:
name: "{{ apache_service }}"
state: restarted
- name: Install /etc/awstats/awstats.schoolserver.conf
template: template:
src: awstats.schoolserver.conf.j2 src: awstats.schoolserver.conf.j2
dest: /etc/awstats/awstats.schoolserver.conf dest: /etc/awstats/awstats.schoolserver.conf
@ -92,10 +96,10 @@
mode: 0644 mode: 0644
when: awstats_enabled when: awstats_enabled
- name: Create a symbolic link to use when access is by IP address - name: Create a symlink /etc/awstats/awstats.conf for access by IP address
file: file:
src: /etc/awstats/awstats.schoolserver.conf src: /etc/awstats/awstats.schoolserver.conf
dest: /etc/awstats/awstats.conf path: /etc/awstats/awstats.conf
state: link state: link
when: awstats_enabled when: awstats_enabled

View file

@ -1,9 +1,10 @@
- include_tasks: install.yml - name: Install AWStats if awstats_install
include_tasks: install.yml
when: awstats_install when: awstats_install
- name: Add 'awstats' to list of services at {{ iiab_ini_file }} - name: Add 'awstats' variable values to {{ iiab_ini_file }}
ini_file: ini_file:
dest: "{{ iiab_ini_file }}" path: "{{ iiab_ini_file }}"
section: awstats section: awstats
option: "{{ item.option }}" option: "{{ item.option }}"
value: "{{ item.value }}" value: "{{ item.value }}"

View file

@ -74,6 +74,8 @@ See also::
/library/calibre-web/metadata_db_prefs_backup.json /library/calibre-web/metadata_db_prefs_backup.json
See the official docs on Calibre-Web's `Runtime Configuration Options <https://github.com/janeczku/calibre-web/wiki/Configuration>`_.
Back Up Everything Back Up Everything
------------------ ------------------

View file

@ -5,7 +5,7 @@
calibreweb_install: False calibreweb_install: False
calibreweb_enabled: False calibreweb_enabled: False
calibreweb_port: 8083 calibreweb_port: 8083 # PORT VARIABLE HAS NO EFFECT (as of January 2019)
calibreweb_url: /books calibreweb_url: /books
calibreweb_venv_path: /usr/local/calibre-web calibreweb_venv_path: /usr/local/calibre-web
calibreweb_exec_path: "{{ calibreweb_venv_path }}/cps.py" calibreweb_exec_path: "{{ calibreweb_venv_path }}/cps.py"

View file

@ -1,4 +1,4 @@
- name: Create Calibre-Web folders to store data and configuration files - name: Create 3 Calibre-Web folders to store data and configuration files
file: file:
path: "{{ item }}" path: "{{ item }}"
owner: "{{ calibreweb_user }}" owner: "{{ calibreweb_user }}"
@ -11,7 +11,7 @@
- "{{ calibreweb_config }}" - "{{ calibreweb_config }}"
## TODO: Calibre-web future release might get into pypi https://github.com/janeczku/calibre-web/issues/456 ## TODO: Calibre-web future release might get into pypi https://github.com/janeczku/calibre-web/issues/456
- name: Download Calibre-Web github repository - name: Download Calibre-Web github repository to {{ calibreweb_venv_path }}
git: git:
repo: https://github.com/janeczku/calibre-web.git repo: https://github.com/janeczku/calibre-web.git
dest: "{{ calibreweb_venv_path }}" dest: "{{ calibreweb_venv_path }}"
@ -30,29 +30,29 @@
# ignore_errors: True # ignore_errors: True
## ##
# Implementing this with Ansible command module for now. # Implementing this with Ansible command module for now.
- name: Download Calibre-Web dependencies into virtual environment - name: Download Calibre-Web dependencies (using pip) into virtual environment
pip: pip:
requirements: "{{ calibreweb_venv_path }}/requirements.txt" requirements: "{{ calibreweb_venv_path }}/requirements.txt"
virtualenv: "{{ calibreweb_venv_path }}" virtualenv: "{{ calibreweb_venv_path }}"
virtualenv_site_packages: no virtualenv_site_packages: no
when: internet_available when: internet_available
- name: Symlink 'vendor' to site-packages for python to keep cps.py happy - name: Symlink {{ calibreweb_venv_path }}/vendor to {{ calibreweb_venv_path }}/lib/python2.7/site-packages to keep cps.py happy
file: file:
state: link
src: "{{ calibreweb_venv_path }}/lib/python2.7/site-packages" src: "{{ calibreweb_venv_path }}/lib/python2.7/site-packages"
dest: "{{ calibreweb_venv_path }}/vendor" dest: "{{ calibreweb_venv_path }}/vendor"
state: link
- name: Create Calibre-Web systemd service unit file and calibre-web.conf for Apache - name: Install unit file /etc/systemd/system/calibre-web.service & /etc/apache2/sites-available/calibre-web.conf for http://box{{ calibreweb_url }}, from templates
template: template:
src: "{{ item.src }}" src: "{{ item.src }}"
dest: "{{ item.dest }}" dest: "{{ item.dest }}"
mode: "{{ item.mode }}" owner: root
owner: "{{ calibreweb_user }}" group: root
group: "{{ apache_user }}" mode: 0644
with_items: with_items:
- { src: 'calibre-web.service.j2', dest: '/etc/systemd/system/calibre-web.service', mode: '0644' } - { src: 'calibre-web.service.j2', dest: '/etc/systemd/system/calibre-web.service' }
- { src: 'calibre-web.conf.j2', dest: '/etc/apache2/sites-available/calibre-web.conf', mode: '0644' } - { src: 'calibre-web.conf.j2', dest: '/etc/apache2/sites-available/calibre-web.conf' }
- name: Does /library/calibre-web/metadata.db exist? - name: Does /library/calibre-web/metadata.db exist?
stat: stat:
@ -73,7 +73,7 @@
when: not metadatadb.stat.exists when: not metadatadb.stat.exists
#when: calibreweb_provision #when: calibreweb_provision
- name: Provision/Copy default admin settings to /library/calibre-web/config/app.db IF metadata.db did not exist - name: Provision/Copy default admin settings to {{ calibreweb_config }}/app.db IF metadata.db did not exist # {{ calibreweb_config }} is /library/calibre-web/config
copy: copy:
src: roles/calibre-web/files/app.db src: roles/calibre-web/files/app.db
dest: "{{ calibreweb_config }}" dest: "{{ calibreweb_config }}"
@ -84,7 +84,7 @@
when: not metadatadb.stat.exists when: not metadatadb.stat.exists
#when: calibreweb_provision #when: calibreweb_provision
- name: Enable and restart 'calibre-web' service - name: Enable & Restart 'calibre-web' systemd service
systemd: systemd:
name: calibre-web name: calibre-web
daemon_reload: yes daemon_reload: yes
@ -101,7 +101,7 @@
# command: apachectl -k graceful # command: apachectl -k graceful
# when: calibreweb_enabled # when: calibreweb_enabled
- name: Disable 'calibre-web' service - name: Disable 'calibre-web' systemd service
systemd: systemd:
name: calibre-web name: calibre-web
daemon_reload: yes daemon_reload: yes
@ -117,14 +117,14 @@
# command: apachectl -k graceful # command: apachectl -k graceful
# when: not calibreweb_enabled # when: not calibreweb_enabled
- name: Restart Apache - name: Restart Apache systemd service ({{ apache_service }})
systemd: systemd:
name: "{{ apache_service }}" # httpd or apache2 name: "{{ apache_service }}" # httpd or apache2
state: restarted state: restarted
- name: Add 'calibre-web' to list of services at {{ iiab_ini_file }} - name: Add 'calibre-web' variable values to {{ iiab_ini_file }}
ini_file: ini_file:
dest: "{{ iiab_ini_file }}" path: "{{ iiab_ini_file }}"
section: calibre-web section: calibre-web
option: "{{ item.option }}" option: "{{ item.option }}"
value: "{{ item.value }}" value: "{{ item.value }}"

View file

@ -11,7 +11,9 @@ RequestHeader set X-SCHEME http
ProxyPass {{ calibreweb_url }} http://localhost:{{ calibreweb_port }}/ ProxyPass {{ calibreweb_url }} http://localhost:{{ calibreweb_port }}/
# Appears unnec: # Possibly unnec? (ProxyPassReverse rewrites internal links, that come back
# from Apache proxy. Whereas e.g. kiwix.conf doesn't need this, as kiwix itself
# prefixes URLs, thanks to --urlRootLocation=/kiwix/ in its systemd file.)
ProxyPassReverse {{ calibreweb_url }} http://localhost:{{ calibreweb_port }}/ ProxyPassReverse {{ calibreweb_url }} http://localhost:{{ calibreweb_port }}/
# </Location> # </Location>

View file

@ -21,20 +21,10 @@ calibre_src_url: "https://raw.githubusercontent.com/kovidgoyal/calibre/master/se
calibre_deb_url: "{{ iiab_download_url }}" # http://download.iiab.io/packages calibre_deb_url: "{{ iiab_download_url }}" # http://download.iiab.io/packages
# Above URL must offer both .deb files below: (for scripts/calibre-install-pinned-rpi.sh to run) # Above URL must offer both .deb files below: (for scripts/calibre-install-pinned-rpi.sh to run)
calibre_deb_pin_version: 3.31.0+dfsg-1 # for calibre-bin_3.31.0+dfsg-1_armhf.deb (747K, 2018-09-12) calibre_deb_pin_version: 3.33.1+dfsg-1 # for calibre_3.33.1+dfsg-1_all.deb (24M, 2018-10-21)
calibre_bin_deb_pin_version: "{{ calibre_deb_pin_version }}" # for calibre-bin_3.31.0+dfsg-1+b1_armhf.deb (24M, 2018-09-07) calibre_bin_deb_pin_version: "{{ calibre_deb_pin_version }}" # for calibre-bin_3.33.1+dfsg-1_armhf.deb (706K, 2018-10-23)
#calibre_deb_pin_version: 3.32.0+dfsg-1 # for calibre_3.32.0+dfsg-1_all.deb (25M, 2018-09-28)
##calibre_bin_deb_pin_version: "{{ calibre_deb_pin_version }}" # for calibre-bin_3.32.0+dfsg-1_armhf.deb (707K, 2018-10-08) HAD WORKED 2018-10-08 BUT NO LONGER on 2018-10-10:
## The following packages have unmet dependencies:
## calibre-bin : Depends: libpodofo0.9.5 (>= 0.9.5-7) but it is not installable
## E: Unable to correct problems, you have held broken packages.
#calibre_bin_deb_pin_version: 3.32.0+dfsg-1+b1 # for calibre-bin_3.32.0+dfsg-1+b1_armhf.deb (706K, 2018-10-08) FAILED ON 2018-10-08 (ERROR ABOVE), MYSTERIOUSLY WORKED ON 2018-10-10, FAILED ON 2018-10-12 -- THIS LATEST ERROR MIGHT RELATE TO SAMBA AND/OR THE NEW RASPBIAN 2018-10-09:
# The following packages have unmet dependencies:
# pkg-config : Depends: libdpkg-perl but it is not going to be installed
# samba : Depends: update-inetd but it is not going to be installed
# E: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify a solution).
# USE TO TEST debs.yml (RASPBIAN APPROACH!) ON DEBIAN 9.X: (now handled by calibre_via_debs in /opt/iiab/iiab/vars/*) # USE TO TEST debs.yml (RASPBIAN APPROACH!) ON DEBIAN 9.X: (now handled by calibre_via_debs in each /opt/iiab/iiab/vars/<OS>.yml)
#calibre_debs_on_debian: True #calibre_debs_on_debian: True
# Enable unstable .deb's, not just testing .deb's: (moved to /etc/iiab/local_vars.yml & /opt/iiab/iiab/vars/default_vars.yml) # Enable unstable .deb's, not just testing .deb's: (moved to /etc/iiab/local_vars.yml & /opt/iiab/iiab/vars/default_vars.yml)
#calibre_unstable_debs: False #calibre_unstable_debs: False

View file

@ -1,54 +1,48 @@
# roles/calibre/tasks/main.yml requires calibre_via_debs (to be True) before calling this script. # roles/calibre/tasks/main.yml requires calibre_via_debs (to be True) before
# calling this script. As of 2018-10-23 this is set in only 3 places:
#
# vars/raspbian-9.yml
# vars/raspbian-8.yml
# vars/debian-10.yml
# MOVED UP TO roles/calibre/tasks/main.yml # If you want the latest Calibre, run the appropriate script below, standalone.
#- name: Start by installing OS's Calibre package # HOWEVER: it's strongly suggested you wait for apt (blessed by your OS!) to
# package: # avoid ongoing dependency problems, as Calibre frequently demands the very
# name: "{{ item }}" # latest/unstable dependencies.
# state: latest
# with_items:
# - calibre
# - calibre-bin
# when: internet_available
# April/May 2018: Raspbian .deb's for the latest Calibre now appear # FYI Raspbian .deb's for the latest Calibre can be downloaded from either:
# (http://raspbian.raspberrypi.org/raspbian/pool/main/c/calibre/) # http://raspbian.raspberrypi.org/raspbian/pool/main/c/calibre/
# within about 10 days of Calibre's quasi-monthly releases # http://archive.raspbian.org/raspbian/pool/main/c/calibre/
# (https://calibre-ebook.com/whats-new). # ...within about 10 days after Calibre's quasi-monthly releases at:
# https://calibre-ebook.com/whats-new
# If you want the latest Calibre, run the appropriate below script, standalone.
# HOWEVER: it's strongly suggested you wait for apt (blessed by your OS!)
#- name: Install packages that Raspbian .deb's had installed for Calibre 3.23 (rpi) #- name: Install packages that Raspbian .deb's had installed for Calibre 3.23 (rpi)
# #command: scripts/calibre-install-latest-rpi.sh # FAILS with Calibre 3.24+ ("calibre : Depends: python-pyqt5 (>= 5.10.1+dfsg-2) but 5.10.1+dfsg-1+rpi1 is to be installed") since June 2018.
# command: scripts/calibre-install-packages.sh # BORROWED package list from /var/log/apt/history.log (that resulted from 2018-05-22 install of Calibre 3.23 using calibre-install-latest-rpi.sh). # command: scripts/calibre-install-packages.sh # BORROWED package list from /var/log/apt/history.log (that resulted from 2018-05-22 install of Calibre 3.23 using calibre-install-latest-rpi.sh).
# when: is_rpi and internet_available # when: is_rpi and internet_available
#- name: Upgrade to latest Calibre using Debian's own .deb's from testing (rpi) #- name: Upgrade to latest Calibre using Debian's own .deb's from testing (rpi)
# command: scripts/calibre-install-latest.sh # NECESSARY since Calibre 3.24 (BEWARE installing libc6 will prevent boot in RPi Zero W, i.e. if calibre-install-packages.sh isn't run above!) # command: scripts/calibre-install-latest.sh # WAS NEC with Calibre 3.24+ & Calibre 3.29 on 2018-08-21 (PR #1015), as all above strategies failed (only script that was not attempted: Sid-like calibre-install-unstable.sh). CLARIF: RESULTING microSD's ARE NOT BOOTABLE IN Zero W (#952) due to libc6 or similar.e.g. if calibre-install-packages.sh isn't run above?
# #command: scripts/calibre-install-latest-rpi-plus.sh # WORKED for Calibre 3.27.1 on 2018-07-22 (#948 -> PR #950) THO NOT BOOTABLE IN Zero W (#952). Similar to Calibre 3.24.x & 3.25 in June 2018, which had used calibre-install-packages.sh then Debian's own calibre-install-latest.sh
# when: is_rpi and internet_available # when: is_rpi and internet_available
#- name: Upgrade to latest Calibre using .deb's from testing (rpi) - name: Upgrade to latest Calibre using .deb's from testing (rpi)
# #command: scripts/calibre-install-latest-rpi-plus.sh # WORKS for Calibre 3.27.1 on 2018-07-22 (#948 -> PR #950) THO NOT BOOTABLE IN Zero W (#952). Similar to Calibre 3.24.x & 3.25 in June 2018, which had used calibre-install-packages.sh then Debian's own calibre-install-latest.sh command: scripts/calibre-install-latest-rpi.sh # WORKED for Calibre 3.33.1 on 2018-10-23. And Calibre 3.28 on 2018-07-26 (PR #971). Likewise for Calibre 3.26.x. FAILED with Calibre 3.24+ ("calibre : Depends: python-pyqt5 (>= 5.10.1+dfsg-2) but 5.10.1+dfsg-1+rpi1 is to be installed") since June 2018.
# #command: scripts/calibre-install-latest-rpi.sh # WORKS for Calibre 3.28 on 2018-07-26 (PR #971). Likewise for Calibre 3.26.x when: is_rpi and internet_available
# command: scripts/calibre-install-latest.sh # REQUIRED for Calibre 3.29 on 2018-08-21 (PR #1015), as all above strategies failed (only script that was not attempted: Sid-like calibre-install-unstable.sh). CLARIF: RESULTING microSD's ARE NOT BOOTABLE IN Zero W (#952)
#- name: Download PINNED version {{ calibre_deb_pin_version }} of calibre & calibre-bin (rpi)
# get_url:
# url: "{{ calibre_deb_url }}/{{ item }}"
# dest: "{{ downloads_dir }}/{{ item }}"
# mode: 0644
# timeout: "{{ download_timeout }}"
# with_items:
# - calibre_{{ calibre_deb_pin_version }}_all.deb
# - calibre-bin_{{ calibre_bin_deb_pin_version }}_armhf.deb
# when: is_rpi and internet_available
#
#- name: Install/Upgrade both, to PINNED version {{ calibre_deb_pin_version }} using additional .deb's from testing (rpi)
# command: scripts/calibre-install-pinned-rpi.sh # Worked for Calibre 3.33.1 on 2018-10-23, e.g. so IIAB microSD bootable in RPi Zero W
# when: is_rpi and internet_available # when: is_rpi and internet_available
- name: Download PINNED version {{ calibre_deb_pin_version }} of calibre & calibre-bin (rpi)
get_url:
url: "{{ calibre_deb_url }}/{{ item }}"
dest: "{{ downloads_dir }}/{{ item }}"
mode: 0644
#force: no
#backup: no
timeout: "{{ download_timeout }}"
with_items:
- calibre_{{ calibre_deb_pin_version }}_all.deb
- calibre-bin_{{ calibre_bin_deb_pin_version }}_armhf.deb
when: is_rpi and internet_available
- name: Install/Upgrade both, to PINNED version {{ calibre_deb_pin_version }} while using additional .deb's from testing (rpi)
command: scripts/calibre-install-pinned-rpi.sh # RECOMMENDED for Calibre 3.30 on 2018-08-30, so IIAB microSD will be bootable in RPi Zero W
when: is_rpi and internet_available
- name: Install/Upgrade to Calibre testing .deb's - target Ubuntu 16.04 (not rpi and not ubuntu_18) - name: Install/Upgrade to Calibre testing .deb's - target Ubuntu 16.04 (not rpi and not ubuntu_18)
command: scripts/calibre-install-latest.sh command: scripts/calibre-install-latest.sh

View file

@ -1,17 +1,16 @@
# 1. INSTALL THE LATEST CALIBRE 3.X+ (calibre, calibredb, calibre-server etc) ON ALL OS'S # 1. INSTALL THE LATEST CALIBRE 3.X+ (calibre, calibredb, calibre-server etc) ON ALL OS'S
- name: Check if /usr/bin/calibre exists - name: Does /usr/bin/calibre exist?
stat: stat:
path: "/usr/bin/calibre" path: "/usr/bin/calibre"
register: calib_executable register: calib_executable
- name: Install Calibre via OS's package installer (IF /usr/bin/calibre MISSING) - name: "Install OS's latest packages: calibre, calibre-bin (IF not rpi AND /usr/bin/calibre MISSING)"
package: package:
name: "{{ item }}" name:
state: latest
with_items:
- calibre - calibre
- calibre-bin - calibre-bin
state: latest
when: internet_available and not is_rpi and (not calib_executable.stat.exists) when: internet_available and not is_rpi and (not calib_executable.stat.exists)
- name: Install Calibre .debs IF calibre_via_debs (AND /usr/bin/calibre WAS MISSING) - name: Install Calibre .debs IF calibre_via_debs (AND /usr/bin/calibre WAS MISSING)
@ -52,16 +51,15 @@
when: (not calib_executable.stat.exists) when: (not calib_executable.stat.exists)
#when: calibre_config.changed #when: calibre_config.changed
# 2. STOP CALIBRE SERVICE IF IT EXISTS (REQUIRED FOR DB ACTIVITY...AND IF not calibre_enabled) # 2. STOP CALIBRE SERVICE (REQUIRED FOR DB ACTIVITY...AND IF not calibre_enabled)
#- name: Check if Calibre systemd service exists #- name: Check if Calibre systemd service exists
# stat: # stat:
# path: /etc/systemd/system/calibre-serve.service # path: /etc/systemd/system/calibre-serve.service
# register: calibre_svc # register: calibre_svc
- name: Stop Calibre service -- calibre-server by Kovid Goyal - name: Stop service 'calibre-serve' (/usr/bin/calibre-server by Kovid Goyal)
# systemd: systemd:
service:
name: calibre-serve name: calibre-serve
state: stopped state: stopped
#enabled: no #enabled: no
@ -88,7 +86,7 @@
# 4. CREATE CONTENT DATABASE WITH A SAMPLE BOOK (REQUIRED AS OF CALIBRE 3.x) # 4. CREATE CONTENT DATABASE WITH A SAMPLE BOOK (REQUIRED AS OF CALIBRE 3.x)
- name: Check if /library/calibre/metadata.db exists - name: Does /library/calibre/metadata.db exist?
stat: stat:
path: "{{ calibre_dbpath }}/metadata.db" path: "{{ calibre_dbpath }}/metadata.db"
register: calibre_db register: calibre_db
@ -105,20 +103,20 @@
# https://github.com/iiab/iiab/tree/master/roles/calibre-web/templates/calibre-web.conf.j2 # https://github.com/iiab/iiab/tree/master/roles/calibre-web/templates/calibre-web.conf.j2
# (anyway this works great for calibre-web, allowing http://box/books # (anyway this works great for calibre-web, allowing http://box/books
# to work even better than http://box:8083 when box == 192.168.0.x !) # to work even better than http://box:8083 when box == 192.168.0.x !)
- name: Create calibre.conf link for UNTESTED http://box/calibre etc (debuntu) - name: Create symlink calibre.conf from sites-enabled to sites-available, for UNTESTED http://box/calibre etc (debuntu)
file: file:
src: /etc/apache2/sites-available/calibre.conf src: /etc/apache2/sites-available/calibre.conf
dest: /etc/apache2/sites-enabled/calibre.conf dest: /etc/apache2/sites-enabled/calibre.conf
state: link state: link
when: calibre_enabled and is_debuntu when: calibre_enabled and is_debuntu
- name: Remove calibre.conf link if disabled (debuntu) - name: Remove symlink /etc/apache2/sites-enabled/calibre.conf (debuntu)
file: file:
dest: /etc/apache2/sites-enabled/calibre.conf dest: /etc/apache2/sites-enabled/calibre.conf
state: absent state: absent
when: (not calibre_enabled) and is_debuntu when: (not calibre_enabled) and is_debuntu
- name: Enable Calibre service -- runs calibre-server by Kovid Goyal - name: Enable & Start service 'calibre-serve' (/usr/bin/calibre-server by Kovid Goyal)
service: service:
name: calibre-serve name: calibre-serve
enabled: yes enabled: yes
@ -127,14 +125,14 @@
#async: 900 #async: 900
#poll: 5 #poll: 5
- name: Forcing apache to reread configs - name: Reload Apache service ({{ apache_service }})
service: systemd:
name: "{{ apache_service }}" name: "{{ apache_service }}"
state: reloaded state: reloaded
- name: Add 'calibre' to list of services at {{ iiab_ini_file }} - name: Add 'calibre' variable values to {{ iiab_ini_file }}
ini_file: ini_file:
dest: "{{ iiab_ini_file }}" path: "{{ iiab_ini_file }}"
section: calibre section: calibre
option: "{{ item.option }}" option: "{{ item.option }}"
value: "{{ item.value }}" value: "{{ item.value }}"
@ -149,5 +147,5 @@
value: "{{ calibre_dbpath }}" value: "{{ calibre_dbpath }}"
- option: port - option: port
value: "{{ calibre_port }}" value: "{{ calibre_port }}"
- option: enabled - option: calibre_enabled
value: "{{ calibre_enabled }}" value: "{{ calibre_enabled }}"

View file

@ -0,0 +1 @@
captive_portal_port: 9090

View file

@ -48,7 +48,7 @@
<br><br> <br><br>
<br><br> <br><br>
<br><br> <br><br>
<a class="button" href="http://iiab-server.lan/home">{{ btn1 }}</a> <a class="button" href="http://{{ FQDN }}">{{ btn1 }}</a>
</div> </div>
</body> </body>
</html> </html>

View file

@ -69,7 +69,7 @@
<script> <script>
var w = window.innerWidth; var w = window.innerWidth;
function homeclick(){ function homeclick(){
window.open("http://iiab-server.lan/home","_system"); window.open("http://{{ FQDN }}","_system");
$.ajax("/home_selected"); $.ajax("/home_selected");
} }

View file

@ -0,0 +1,146 @@
- name: Download & install python-dateutil, sqlite3
package:
name: "{{ item }}"
state: present
with_items:
- python-dateutil
- sqlite3 # @georgejhunt hopes to move this to 2-common (or more likely 3-base-server, alongside MySQL) in October 2018
- name: Install libapache2-mod-wsgi (debuntu)
package:
name: libapache2-mod-wsgi
state: present
when: is_debuntu
- name: Install mod_wsgi (not debuntu)
package:
name: mod_wsgi
state: present
when: not is_debuntu
- name: Create directory /opt/iiab/captive-portal for scripts & templates
file:
path: /opt/iiab/captive-portal
state: directory
owner: "{{ apache_user }}"
- name: 'Copy scripts: checkurls, capture-wsgi.py'
template:
src: "{{ item.src }}"
dest: /opt/iiab/captive-portal/
mode: "{{ item.mode }}"
with_items:
- { src: roles/captive-portal/templates/checkurls, mode: '0644' }
- { src: roles/captive-portal/templates/capture-wsgi.py, mode: '0755' }
- name: 'Copy templates: simple.template, mac.template'
copy:
src: "{{ item }}"
dest: /opt/iiab/captive-portal/
with_items:
- roles/captive-portal/files/simple.template
- roles/captive-portal/files/mac.template
- name: Copy iiab-catch & iiab-uncatch into /usr/bin/
template:
src: "{{ item }}"
dest: /usr/bin/
owner: root
group: root
mode: 0755
with_items:
- roles/captive-portal/templates/iiab-catch
- roles/captive-portal/templates/iiab-uncatch
- name: Run iiab-uncatch to generate diversion lists for dnsmasq and apache2
shell: /usr/bin/iiab-uncatch
#- name: Install systemd unit file captive-portal.service from template
# template:
# src: roles/captive-portal/templates/captive-portal.service.j2
# dest: /etc/systemd/system/captive-portal.service
# owner: root
# group: root
# mode: 0644
- name: Install Apache's captive-portal.conf from template if captive_portal_enabled
template:
src: roles/captive-portal/templates/001-captive-portal.conf
dest: /etc/{{ apache_config_dir }}/001-captive-portal.conf
owner: root
group: root
mode: 0644
when: captive_portal_enabled
- name: Enable Apache's captive-portal.conf if captive_portal_enabled (debuntu)
file:
src: /etc/apache2/sites-available/001-captive-portal.conf
path: /etc/apache2/sites-enabled/001-captive-portal.conf
state: link
when: captive_portal_enabled and is_debuntu
- name: Enable Apache's default-ssl.conf if captive_portal_enabled (debuntu)
file:
src: /etc/apache2/sites-available/default-ssl.conf
path: /etc/apache2/sites-enabled/default-ssl.conf
state: link
when: captive_portal_enabled and is_debuntu
#- name: Enable & Start systemd service captive-portal.service if captive_portal_enabled
# systemd:
# name: captive-portal.service
# daemon-reload: yes
# enabled: yes
# state: started
# when: captive_portal_enabled
#- name: Disable & Stop captive-portal.service if not captive_portal_enabled
# systemd:
# name: captive-portal.service
# enabled: no
# state: stopped
# when: not captive_portal_enabled
- name: Disable Apache's captive-portal.conf if not captive_portal_enabled (debuntu)
file:
path: /etc/apache2/sites-enabled/001-captive-portal.conf
state: absent
when: not captive_portal_enabled and is_debuntu
- name: Disable Apache's default-ssl.conf if not captive_portal_enabled (debuntu)
file:
path: /etc/apache2/sites-enabled/default-ssl.conf
state: absent
when: not captive_portal_enabled and is_debuntu
- name: Make sure dnsmasq is not diverting if not captive_portal_enabled
file:
path: /etc/dnsmasq.d/capture
state: absent
when: not captive_portal_enabled
- name: Restart Apache service ({{ apache_service }}) # i.e. apache2 on most distros
systemd:
name: "{{ apache_service }}"
state: restarted
#- name: Restart dnsmasq
# systemd:
# name: dnsmasq
# state: restarted
# when: dnsmasq_enabled
# ABOVE DOES NOT WORK ON UBUNTU 16.04 -- what follows is a crude hack (seems to work!)
- name: Stop dnsmasq
systemd:
name: dnsmasq
state: stopped
when: dnsmasq_enabled
- name: Start dnsmasq
systemd:
name: dnsmasq
state: started
when: dnsmasq_enabled

View file

@ -0,0 +1,43 @@
<VirtualHost _default_:80>
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
<Directory {{ doc_root }}>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
ServerName iiab.io
Include /etc/apache2/capture
# ProxyPreserveHost On
# ProxyPass / http://box.lan:{{ captive_portal_port }}/
# ProxyPassReverse / http://box.lan:{{ captive_portal_port }}/
ErrorLog /var/log/apache2/cp_error.log
WSGIScriptAlias / /opt/iiab/captive-portal/capture-wsgi.py
#WSGIScriptAlias / /opt/iiab/captive-portal/test.py
WSGIScriptReloading On
<Directory /opt/iiab/captive-portal>
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
<VirtualHost 127.0.0.1:80>
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
<Directory /library/www/html>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>

View file

@ -7,7 +7,7 @@ Type=simple
User=root User=root
Group=root Group=root
WorkingDirectory=/opt/iiab/captive-portal WorkingDirectory=/opt/iiab/captive-portal
ExecStart=/opt/iiab/captive-portal/capture-wsgi.py ExecStart=/opt/iiab/captive-portal/capture-wsgi.py -l
StandardOutput=syslog StandardOutput=syslog
StandardError=syslog StandardError=syslog

View file

@ -28,7 +28,7 @@ j2_env = Environment(loader=FileSystemLoader(CAPTIVE_PORTAL_BASE),trim_blocks=Tr
# Define time outs # Define time outs
INACTIVITY_TO = 30 INACTIVITY_TO = 30
PORTAL_TO = 0 # delay after triggered by ajax upon click of link to home page PORTAL_TO = 20 # delay after triggered by ajax upon click of link to home page
# I had hoped that returning 204 status after some delay # I had hoped that returning 204 status after some delay
# would dispense with android's "sign-in to network" (no work) # would dispense with android's "sign-in to network" (no work)
@ -37,15 +37,8 @@ PORTAL_TO = 0 # delay after triggered by ajax upon click of link to home page
sys.path.append('/etc/iiab/') sys.path.append('/etc/iiab/')
from iiab_env import get_iiab_env from iiab_env import get_iiab_env
doc_root = get_iiab_env("WWWROOT") doc_root = get_iiab_env("WWWROOT")
fully_qualified_domain_name = get_iiab_env("FQDN")
# make a way to find new URLs queried by new clients
# CATCH substitues this server for apache at port 80
CATCH = False
if len(sys.argv) > 1 and sys.argv[1] == '-d':
CATCH = True
PORT=80
else:
PORT=9090
# set up some logging -- selectable for diagnostics # set up some logging -- selectable for diagnostics
# Create dummy iostream to capture stderr and stdout # Create dummy iostream to capture stderr and stdout
@ -62,30 +55,33 @@ class StreamToLogger(object):
for line in buf.rstrip().splitlines(): for line in buf.rstrip().splitlines():
self.logger.log(self.log_level, line.rstrip()) self.logger.log(self.log_level, line.rstrip())
if len(sys.argv) > 1 and sys.argv[1] == '-l': #if len(sys.argv) > 1 and sys.argv[1] == '-l':
if True:
loggingLevel = logging.DEBUG loggingLevel = logging.DEBUG
try:
os.remove('/var/log/apache2/portal.log')
except:
pass
else: else:
loggingLevel = logging.ERROR loggingLevel = logging.ERROR
# divert stdout and stderr to logger
logging.basicConfig(filename='/var/log/apache2/portal.log',format='%(asctime)s.%(msecs)03d:%(name)s:%(message)s', datefmt='%M:%S',level=loggingLevel) logging.basicConfig(filename='/var/log/apache2/portal.log',format='%(asctime)s.%(msecs)03d:%(name)s:%(message)s', datefmt='%M:%S',level=loggingLevel)
logger = logging.getLogger('/var/log/apache2/portal.log') logger = logging.getLogger('/var/log/apache2/portal.log')
handler = RotatingFileHandler("/var/log/apache2/portal.log", maxBytes=100000, backupCount=2) handler = RotatingFileHandler("/var/log/apache2/portal.log", maxBytes=100000, backupCount=2)
logger.addHandler(handler) logger.addHandler(handler)
# divert stdout and stderr to logger
stdout_logger = logging.getLogger('STDOUT') stdout_logger = logging.getLogger('STDOUT')
sl = StreamToLogger(stdout_logger, logging.ERROR) sl = StreamToLogger(stdout_logger, logging.ERROR)
#sys.stdout = sl sys.stdout = sl
stderr_logger = logging.getLogger('STDERR') stderr_logger = logging.getLogger('STDERR')
sl = StreamToLogger(stderr_logger, logging.ERROR) sl = StreamToLogger(stderr_logger, logging.ERROR)
sys.stderr = sl sys.stderr = sl
PORT={{ captive_portal_port }}
# Define globals # Define globals
MAC_SUCCESS=False
ANDROID_TRIGGERED=False ANDROID_TRIGGERED=False
logger.debug("") logger.debug("")
@ -145,6 +141,8 @@ def timeout_info(ip):
def is_inactive(ip): def is_inactive(ip):
ts=tstamp(datetime.datetime.now(tzutc())) ts=tstamp(datetime.datetime.now(tzutc()))
current_ts, last_ts, send204after = timeout_info(ip) current_ts, last_ts, send204after = timeout_info(ip)
logger.debug("In is_inactive. current_ts:%s. last_ts:%s. send204after:%s"%\
(current_ts,last_ts,send204after,))
if not last_ts: if not last_ts:
return True return True
if ts - int(last_ts) > INACTIVITY_TO: if ts - int(last_ts) > INACTIVITY_TO:
@ -180,34 +178,48 @@ def set_lasttimestamp(ip):
# ################### Action routines based on OS ################3 # ################### Action routines based on OS ################3
def microsoft(environ,start_response): def microsoft(environ,start_response):
#logger.debug("sending microsoft response") # firefox -- seems both mac and Windows use it
en_txt={ 'message':"Click on the button to go to the IIAB home page",\ agent = environ.get('HTTP_USER_AGENT','default_agent')
'btn1':"GO TO IIAB HOME PAGE",'doc_root':get_iiab_env("WWWROOT")} if agent.startswith('Mozilla'):
es_txt={ 'message':"Haga clic en el botón para ir a la página de inicio de IIAB",\ return home(environ, start_response)
'btn1':"IIAB",'doc_root':get_iiab_env("WWWROOT")} logger.debug("sending microsoft redirect")
if lang == "en": response_body = ""
txt = en_txt status = '302 Moved Temporarily'
elif lang == "es": response_headers = [('Location','http://box.lan/home'),
txt = es_txt ('Content-type','text/html'),
response_body = str(j2_env.get_template("simple.template").render(**txt)) ('Content-Length',str(len(response_body)))]
status = '200 OK' start_response(status, response_headers)
response_headers = [('Content-type','text/html'), return [response_body]
def home(environ,start_response):
logger.debug("sending direct to home")
response_body = ""
status = '302 Moved Temporarily'
response_headers = [('Location','http://' + fully_qualified_domain_name + '/home'),
('Content-type','text/html'),
('Content-Length',str(len(response_body)))] ('Content-Length',str(len(response_body)))]
start_response(status, response_headers) start_response(status, response_headers)
return [response_body] return [response_body]
def android(environ, start_response): def android(environ, start_response):
global ANDROID_TRIGGERED global ANDROID_TRIGGERED
if environ.get('HTTP_X_FORWARDED_FOR'):
ip = environ['HTTP_X_FORWARDED_FOR'].strip() ip = environ['HTTP_X_FORWARDED_FOR'].strip()
else:
ip = environ['REMOTE_ADDR'].strip()
system,system_version = platform_info(ip) system,system_version = platform_info(ip)
if system_version is None:
return put_302(environ, start_response)
if system_version[0:1] < '6': if system_version[0:1] < '6':
logger.debug("system < 6:%s"%system_version) logger.debug("system < 6:%s"%system_version)
location = '/android_splash' location = '/android_splash'
set_204after(ip,0) set_204after(ip,0)
elif system_version[:1] >= '7':
location = "http://" + fully_qualified_domain_name + "/home"
else: else:
set_204after(ip,20) #set_204after(ip,20)
location = '/android_https' location = '/android_https'
agent = environ['HTTP_USER_AGENT'] agent = environ.get('HTTP_USER_AGENT','default_agent')
response_body = "hello" response_body = "hello"
status = '302 Moved Temporarily' status = '302 Moved Temporarily'
response_headers = [('Location',location)] response_headers = [('Location',location)]
@ -217,9 +229,12 @@ def android(environ, start_response):
def android_splash(environ, start_response): def android_splash(environ, start_response):
en_txt={ 'message':"Click on the button to go to the IIAB home page",\ en_txt={ 'message':"Click on the button to go to the IIAB home page",\
'btn1':"GO TO IIAB HOME PAGE", \ 'btn1':"GO TO IIAB HOME PAGE", \
"FQDN": fully_qualified_domain_name, \
'doc_root':get_iiab_env("WWWROOT") } 'doc_root':get_iiab_env("WWWROOT") }
es_txt={ 'message':"Haga clic en el botón para ir a la página de inicio de IIAB",\ es_txt={ 'message':"Haga clic en el botón para ir a la página de inicio de IIAB",\
"FQDN": fully_qualified_domain_name, \
'btn1':"IIAB",'doc_root':get_iiab_env("WWWROOT")} 'btn1':"IIAB",'doc_root':get_iiab_env("WWWROOT")}
txt = en_txt
if lang == "en": if lang == "en":
txt = en_txt txt = en_txt
elif lang == "es": elif lang == "es":
@ -235,9 +250,12 @@ def android_https(environ, start_response):
en_txt={ 'message':"""Please ignore the SECURITY warning which appears after clicking the first button""",\ en_txt={ 'message':"""Please ignore the SECURITY warning which appears after clicking the first button""",\
'btn2':'Click this first Go to the browser we need',\ 'btn2':'Click this first Go to the browser we need',\
'btn1':'Then click this to go to IIAB home page',\ 'btn1':'Then click this to go to IIAB home page',\
"FQDN": fully_qualified_domain_name, \
'doc_root':get_iiab_env("WWWROOT") } 'doc_root':get_iiab_env("WWWROOT") }
es_txt={ 'message':"Haga clic en el botón para ir a la página de inicio de IIAB",\ es_txt={ 'message':"Haga clic en el botón para ir a la página de inicio de IIAB",\
"FQDN": fully_qualified_domain_name, \
'btn1':"IIAB",'doc_root':get_iiab_env("WWWROOT")} 'btn1':"IIAB",'doc_root':get_iiab_env("WWWROOT")}
txt = en_txt
if lang == "en": if lang == "en":
txt = en_txt txt = en_txt
elif lang == "es": elif lang == "es":
@ -253,9 +271,12 @@ def mac_splash(environ,start_response):
logger.debug("in function mac_splash") logger.debug("in function mac_splash")
en_txt={ 'message':"Click on the button to go to the IIAB home page",\ en_txt={ 'message':"Click on the button to go to the IIAB home page",\
'btn1':"GO TO IIAB HOME PAGE",'success_token': 'Success', 'btn1':"GO TO IIAB HOME PAGE",'success_token': 'Success',
"FQDN": fully_qualified_domain_name, \
'doc_root':get_iiab_env("WWWROOT")} 'doc_root':get_iiab_env("WWWROOT")}
es_txt={ 'message':"Haga clic en el botón para ir a la página de inicio de IIAB",\ es_txt={ 'message':"Haga clic en el botón para ir a la página de inicio de IIAB",\
"FQDN": fully_qualified_domain_name, \
'btn1':"IIAB",'doc_root':get_iiab_env("WWWROOT")} 'btn1':"IIAB",'doc_root':get_iiab_env("WWWROOT")}
txt = en_txt
if lang == "en": if lang == "en":
txt = en_txt txt = en_txt
elif lang == "es": elif lang == "es":
@ -271,6 +292,7 @@ def mac_splash(environ,start_response):
def macintosh(environ, start_response): def macintosh(environ, start_response):
global ip global ip
logger.debug("in function mcintosh") logger.debug("in function mcintosh")
#print >> sys.stderr , "Geo Print to stderr" + environ['HTTP_HOST']
if not is_inactive(ip): if not is_inactive(ip):
set_lasttimestamp(ip) set_lasttimestamp(ip)
return success(environ,start_response) return success(environ,start_response)
@ -298,7 +320,7 @@ def banner(environ, start_response):
status = '200 OK' status = '200 OK'
headers = [('Content-type', 'image/png')] headers = [('Content-type', 'image/png')]
start_response(status, headers) start_response(status, headers)
image = open("%s/iiab-menu/menu-files/images/iiab_banner6.png"%doc_root, "rb").read() image = open("%s/js-menu/menu-files/images/iiab_banner6.png"%doc_root, "rb").read()
return [image] return [image]
def bootstrap(environ, start_response): def bootstrap(environ, start_response):
@ -326,7 +348,7 @@ def bootstrap_css(environ, start_response):
return [boot] return [boot]
def null(environ, start_response): def null(environ, start_response):
status = '200 ok' status = '404 Not Found'
headers = [('Content-type', 'text/html')] headers = [('Content-type', 'text/html')]
start_response(status, headers) start_response(status, headers)
return [""] return [""]
@ -347,6 +369,17 @@ def put_204(environ, start_response):
logger.debug("in function put_204: sending 204 html response") logger.debug("in function put_204: sending 204 html response")
return [response_body] return [response_body]
def put_302(environ, start_response):
status = '302 Moved Temporarily'
response_body = ''
location = "http://" + fully_qualified_domain_name + "/home"
response_headers = [('Content-type','text/html'),
('Location',location),
('Content-Length',str(len(response_body)))]
start_response(status, response_headers)
logger.debug("in function put_302: sending 302 html response")
return [response_body]
def parse_agent(agent): def parse_agent(agent):
system = '' system = ''
system_version = '' system_version = ''
@ -366,6 +399,10 @@ def parse_agent(agent):
if match: if match:
system = match.group(1) system = match.group(1)
system_version = match.group(2) system_version = match.group(2)
match = re.search(r"(Microsoft NCSI)",agent)
if match:
system = match.group(1)
system_version = "8"
return (system, system_version) return (system, system_version)
# #
@ -377,45 +414,6 @@ def application (environ, start_response):
global INACTIVITY_TO global INACTIVITY_TO
global ANDROID_TRIGGERED global ANDROID_TRIGGERED
# Log the URLs that are not in checkurls
# This "CATCH" mode substitutes this server for apache at port 80
# CATCH mode is started by "iiab-catch" and turned off by "iiab-uncath".
if CATCH:
logger.debug("Checking for url %s. USER_AGENT:%s"%(environ['HTTP_HOST'],\
environ['HTTP_USER_AGENT'],))
if environ['HTTP_HOST'] == '/box.lan':
return
if 'HTTP_X_FORWARDED_FOR' in environ:
ip = environ['HTTP_X_FORWARDED_FOR'].strip()
else:
ip = environ['HTTP_HOST'].strip()
cmd="arp -an %s|gawk \'{print $4}\'" % ip
mac = subprocess.check_output(cmd, shell=True)
data = []
data.append("host: %s\n"%environ['HTTP_HOST'])
data.append("path: %s\n"%environ['PATH_INFO'])
data.append("query: %s\n"%environ['QUERY_STRING'])
data.append("ip: %s\n"%ip)
agent = environ['HTTP_USER_AGENT']
data.append("AGENT: %s\n"%agent)
#print(data)
found = False
url_list = os.path.join(CAPTIVE_PORTAL_BASE,"checkurls")
if os.path.exists(url_list):
with open(url_list,"r") as checkers:
for line in checkers:
if line.find(environ['HTTP_HOST']) > -1:
found = True
break
if not found:
with open(url_list,"a") as checkers:
outstr ="%s\n" % (environ['HTTP_HOST'])
checkers.write(outstr)
data = ['%s: %s\n' % (key, value) for key, value in sorted(environ.items()) ]
logger.debug("This url was missing from checkurls:%s"%data)
# Normal query for captive portal
else:
if 'HTTP_X_FORWARDED_FOR' in environ: if 'HTTP_X_FORWARDED_FOR' in environ:
ip = environ['HTTP_X_FORWARDED_FOR'].strip() ip = environ['HTTP_X_FORWARDED_FOR'].strip()
else: else:
@ -429,7 +427,7 @@ def application (environ, start_response):
data.append("path: %s\n"%environ['PATH_INFO']) data.append("path: %s\n"%environ['PATH_INFO'])
data.append("query: %s\n"%environ['QUERY_STRING']) data.append("query: %s\n"%environ['QUERY_STRING'])
data.append("ip: %s\n"%ip) data.append("ip: %s\n"%ip)
agent = environ['HTTP_USER_AGENT'] agent = environ.get('HTTP_USER_AGENT','default_agent')
data.append("AGENT: %s\n"%agent) data.append("AGENT: %s\n"%agent)
logger.debug(data) logger.debug(data)
#print(data) #print(data)
@ -493,7 +491,6 @@ def application (environ, start_response):
if environ['HTTP_HOST'] == "captive.apple.com" or\ if environ['HTTP_HOST'] == "captive.apple.com" or\
environ['HTTP_HOST'] == "appleiphonecell.com" or\ environ['HTTP_HOST'] == "appleiphonecell.com" or\
environ['HTTP_HOST'] == "detectportal.firefox.com" or\
environ['HTTP_HOST'] == "*.apple.com.edgekey.net" or\ environ['HTTP_HOST'] == "*.apple.com.edgekey.net" or\
environ['HTTP_HOST'] == "gsp1.apple.com" or\ environ['HTTP_HOST'] == "gsp1.apple.com" or\
environ['HTTP_HOST'] == "apple.com" or\ environ['HTTP_HOST'] == "apple.com" or\
@ -514,31 +511,33 @@ def application (environ, start_response):
environ['HTTP_HOST'] == "alt7-mtalk.google.com" or\ environ['HTTP_HOST'] == "alt7-mtalk.google.com" or\
environ['HTTP_HOST'] == "alt6-mtalk.google.com" or\ environ['HTTP_HOST'] == "alt6-mtalk.google.com" or\
environ['HTTP_HOST'] == "connectivitycheck.android.com" or\ environ['HTTP_HOST'] == "connectivitycheck.android.com" or\
environ['PATH_INFO'] == "/gen_204" or\
environ['HTTP_HOST'] == "connectivitycheck.gstatic.com": environ['HTTP_HOST'] == "connectivitycheck.gstatic.com":
current_ts, last_ts, send204after = timeout_info(ip) current_ts, last_ts, send204after = timeout_info(ip)
logger.debug("current_ts: %s laat_ts: %s send204after: %s"%(current_ts, last_ts, send204after,)) logger.debug("current_ts: %s last_ts: %s send204after: %s"%(current_ts, last_ts, send204after,))
if not last_ts or (ts - int(last_ts) > INACTIVITY_TO): if not last_ts or (ts - int(last_ts) > INACTIVITY_TO):
return android(environ, start_response) return android(environ, start_response)
elif is_after204_timeout(ip): elif is_after204_timeout(ip):
return put_204(environ,start_response) return put_204(environ,start_response)
return null(environ,start_response) #return without doing anything return android(environ, start_response)
# microsoft # microsoft
if environ['PATH_INFO'] == "/connecttest.txt" and not is_inactive(ip):
return microsoft_connect(environ, start_response)
if environ['HTTP_HOST'] == "ipv6.msftncsi.com" or\ if environ['HTTP_HOST'] == "ipv6.msftncsi.com" or\
environ['HTTP_HOST'] == "detectportal.firefox.com" or\
environ['HTTP_HOST'] == "ipv6.msftncsi.com.edgesuite.net" or\ environ['HTTP_HOST'] == "ipv6.msftncsi.com.edgesuite.net" or\
environ['HTTP_HOST'] == "www.msftncsi.com" or\ environ['HTTP_HOST'] == "www.msftncsi.com" or\
environ['HTTP_HOST'] == "www.msftncsi.com.edgesuite.net" or\ environ['HTTP_HOST'] == "www.msftncsi.com.edgesuite.net" or\
environ['HTTP_HOST'] == "www.msftconnecttest.com" or\ environ['HTTP_HOST'] == "www.msftconnecttest.com" or\
environ['HTTP_HOST'] == "www.msn.com" or\
environ['HTTP_HOST'] == "teredo.ipv6.microsoft.com" or\ environ['HTTP_HOST'] == "teredo.ipv6.microsoft.com" or\
environ['HTTP_HOST'] == "teredo.ipv6.microsoft.com.nsatc.net": environ['HTTP_HOST'] == "teredo.ipv6.microsoft.com.nsatc.net":
return microsoft(environ, start_response) return microsoft(environ, start_response)
logger.debug("executing the defaut 204 response. [%s"%data) logger.debug("executing the default 302 response. [%s"%data)
return put_204(environ,start_response) return put_302(environ,start_response)
# Instantiate the server # Instantiate the server
if __name__ == "__main__":
httpd = make_server ( httpd = make_server (
"", # The host name "", # The host name
PORT, # A port number where to wait for the request PORT, # A port number where to wait for the request

View file

@ -10,6 +10,7 @@ ipv6.msftncsi.com.edgesuite.net
www.msftncsi.com www.msftncsi.com
www.msftncsi.com.edgesuite.net www.msftncsi.com.edgesuite.net
www.msftconnecttest.com www.msftconnecttest.com
www.msn.com
teredo.ipv6.microsoft.com teredo.ipv6.microsoft.com
teredo.ipv6.microsoft.com.nsatc.net teredo.ipv6.microsoft.com.nsatc.net
captive.apple.com captive.apple.com

View file

@ -1,8 +1,8 @@
#!/bin/bash -x #!/bin/bash -x
# substitute our own server to catch OS connectivity checking URL's # substitute our own server to catch OS connectivity checking URL's
systemctl stop apache2 systemctl stop {{ apache_service }}
systemctl stop py-captive-portal # systemctl stop captive-portal
echo address=/#/172.18.96.1 > /etc/dnsmasq.d/capture echo address=/#/172.18.96.1 > /etc/dnsmasq.d/capture
/opt/iiab/captive-portal/capture-wsgi.py -d & /opt/iiab/captive-portal/capture-wsgi.py -d &
# write the pid just started # write the pid just started

View file

@ -8,6 +8,8 @@ if [ -n "$pid" ]; then
kill $pid kill $pid
fi fi
awk '{print("address=/" $1 "/172.18.96.1")}' /opt/iiab/captive-portal/checkurls > /etc/dnsmasq.d/capture awk '{print("address=/" $1 "/172.18.96.1")}' /opt/iiab/captive-portal/checkurls > /etc/dnsmasq.d/capture
echo "#following tells windows 7 that captive portal is active" >>/etc/dnsmasq.d/capture
echo "address=/dns.msftncsi.com/131.107.255.255" >> /etc/dnsmasq.d/capture
awk '{print("ServerAlias ",$1)}' /opt/iiab/captive-portal/checkurls > /etc/apache2/capture awk '{print("ServerAlias ",$1)}' /opt/iiab/captive-portal/checkurls > /etc/apache2/capture
systemctl start py-captive-portal # systemctl start captive-portal
systemctl start apache2 systemctl start {{ apache_service }}

View file

@ -1,32 +1,30 @@
# administer this service by browsing to localhost:631 # administer this service by browsing to localhost:631
- name: Get the CUPS package installed - name: Install 'cups' package
package: package:
name: "{{ item }}" name: cups
state: present state: present
with_items:
- cups
when: cups_install when: cups_install
tags: tags:
- download - download
- name: Put our own /etc/cups/cupsd.conf in place, to permit local LAN admin - name: Install our own /etc/cups/cupsd.conf from template, to permit local LAN admin
template: template:
src: cupsd.conf src: cupsd.conf
dest: /etc/cups/cupsd.conf dest: /etc/cups/cupsd.conf
- name: Put an apache2 config file in place - name: Install /etc/{{ apache_config_dir }}/cups.conf from template
template: template:
src: cups.conf src: cups.conf
dest: "/etc/{{ apache_config_dir }}/" dest: "/etc/{{ apache_config_dir }}/"
- name: Create the link for sites-enabled (debuntu) - name: Create symlink cups.conf from sites-enabled to sites-available (debuntu)
file: file:
src: /etc/apache2/sites-available/cups.conf src: /etc/apache2/sites-available/cups.conf
dest: /etc/apache2/sites-enabled/cups.conf dest: /etc/apache2/sites-enabled/cups.conf
state: link state: link
when: cups_enabled and is_debuntu when: cups_enabled and is_debuntu
- name: Enable services for CUPS (OS's other than Fedora 18) - name: Enable & Start services 'cups' and 'cups-browsed' (OS's other than Fedora 18)
service: service:
name: "{{ item }}" name: "{{ item }}"
state: started state: started
@ -36,8 +34,8 @@
- cups-browsed - cups-browsed
when: cups_enabled and not is_F18 when: cups_enabled and not is_F18
- name: Enable services for CUPS (Fedora 18, for XO laptops) - name: Enable & Start service 'cups' (Fedora 18, for XO laptops)
service: systemd:
name: cups name: cups
state: started state: started
enabled: yes enabled: yes
@ -47,8 +45,8 @@
shell: "cupsctl --remote-admin" shell: "cupsctl --remote-admin"
when: cups_enabled when: cups_enabled
- name: Disable services for CUPS (OS's other than Fedora 18) - name: Disable both CUPS services (OS's other than Fedora 18)
service: systemd:
name: "{{ item }}" name: "{{ item }}"
state: stopped state: stopped
enabled: no enabled: no
@ -58,15 +56,15 @@
when: not cups_enabled and not is_F18 when: not cups_enabled and not is_F18
- name: Disable services for CUPS (Fedora 18, for XO laptops) - name: Disable services for CUPS (Fedora 18, for XO laptops)
service: systemd:
name: cups name: cups
state: stopped state: stopped
enabled: no enabled: no
when: not cups_enabled and is_F18 when: not cups_enabled and is_F18
- name: Add 'cups' to list of services at {{ iiab_ini_file }} - name: Add 'cups' variable values to {{ iiab_ini_file }}
ini_file: ini_file:
dest: "{{ iiab_ini_file }}" path: "{{ iiab_ini_file }}"
section: cups section: cups
option: "{{ item.option }}" option: "{{ item.option }}"
value: "{{ item.value }}" value: "{{ item.value }}"
@ -77,5 +75,5 @@
value: '"CUPS (Common UNIX Printing System) is a modular printing system that allows a computer to act as a print server. A computer running CUPS is a host that can accept print jobs from client computers, process them, and send them to the appropriate printer."' value: '"CUPS (Common UNIX Printing System) is a modular printing system that allows a computer to act as a print server. A computer running CUPS is a host that can accept print jobs from client computers, process them, and send them to the appropriate printer."'
- option: installed - option: installed
value: "{{ cups_install }}" value: "{{ cups_install }}"
- option: enabled - option: cups_enabled
value: "{{ cups_enabled }}" value: "{{ cups_enabled }}"

View file

@ -40,11 +40,12 @@
enabled=false enabled=false
when: not docker_enabled when: not docker_enabled
- name: add docker to service list - name: Add 'docker' variable values to {{ iiab_ini_file }}
ini_file: dest='{{ iiab_ini_file }}' ini_file:
section=docker path: "{{ iiab_ini_file }}"
option='{{ item.option }}' section: docker
value='{{ item.value }}' option: "{{ item.option }}"
value: "{{ item.value }}"
with_items: with_items:
- option: name - option: name
value: Docker Container value: Docker Container

View file

@ -1,4 +1,4 @@
dokuwiki_url: /wiki dokuwiki_url: /wiki
dokuwiki_install: True dokuwiki_install: True
dokuwiki_enabled: False dokuwiki_enabled: False
dokuwiki_version: "dokuwiki-2018-04-22a" dokuwiki_version: "dokuwiki-2018-04-22b"

View file

@ -1,47 +1,46 @@
- name: Download DokuWiki software - name: Download {{ iiab_download_url }}/{{ dokuwiki_version }}.tgz # iiab_download_url is http://download.iiab.io/packages
get_url: get_url:
url: "{{ iiab_download_url }}/{{ dokuwiki_version }}.tgz" url: "{{ iiab_download_url }}/{{ dokuwiki_version }}.tgz"
dest: "{{ downloads_dir }}/" dest: "{{ downloads_dir }}/"
timeout: "{{ download_timeout }}" timeout: "{{ download_timeout }}"
when: internet_available when: internet_available
- name: Copy it to permanent location /library - name: Unarchive (unpack) it to /library/{{ dokuwiki_version }}
unarchive: unarchive:
src: "{{ downloads_dir }}/{{ dokuwiki_version }}.tgz" src: "{{ downloads_dir }}/{{ dokuwiki_version }}.tgz"
dest: /library dest: /library
creates: "/library/{{ dokuwiki_version }}/VERSION" creates: "/library/{{ dokuwiki_version }}/VERSION"
- name: Symlink /library/{{ dokuwiki_version }} from /library/dokuwiki - name: Symlink /library/dokuwiki to /library/{{ dokuwiki_version }}
#shell: if [ ! -d /library/dokuwiki ]; then ln -sf /library/{{ dokuwiki_version }} /library/dokuwiki; fi #shell: if [ ! -d /library/dokuwiki ]; then ln -sf /library/{{ dokuwiki_version }} /library/dokuwiki; fi
#shell: ln -sf /library/{{ dokuwiki_version }} /library/dokuwiki #shell: ln -sf /library/{{ dokuwiki_version }} /library/dokuwiki
#BOTH LINES ABOVE FAIL TO UPDATE LINK; Ansible approach below works #BOTH LINES ABOVE FAIL TO UPDATE LINK; Ansible approach below works
file: file:
path: /library/dokuwiki
src: /library/{{ dokuwiki_version }} src: /library/{{ dokuwiki_version }}
path: /library/dokuwiki
state: link state: link
force: yes force: yes
- name: Install config file for DokuWiki in Apache - name: Install /etc/{{ apache_config_dir }}/dokuwiki.conf from template, for DokuWiki's http://box/wiki
template: template:
src: dokuwiki.conf.j2 src: dokuwiki.conf.j2
dest: "/etc/{{ apache_config_dir }}/dokuwiki.conf" dest: "/etc/{{ apache_config_dir }}/dokuwiki.conf"
when: dokuwiki_enabled when: dokuwiki_enabled
- name: Enable the DokuWiki (debuntu) - name: Symlink /etc/apache2/sites-enabled/dokuwiki.conf to /etc/apache2/sites-available/dokuwiki.conf if dokuwiki_enabled (debuntu)
file: file:
src: /etc/apache2/sites-available/dokuwiki.conf src: /etc/apache2/sites-available/dokuwiki.conf
dest: /etc/apache2/sites-enabled/dokuwiki.conf path: /etc/apache2/sites-enabled/dokuwiki.conf
state: link state: link
when: dokuwiki_enabled and is_debuntu when: dokuwiki_enabled and is_debuntu
- name: Disable the DokuWiki (debuntu) - name: Remove symlink /etc/apache2/sites-enabled/dokuwiki.conf if not dokuwiki_enabled (debuntu)
file: file:
path: /etc/apache2/sites-enabled/dokuwiki.conf path: /etc/apache2/sites-enabled/dokuwiki.conf
state: absent state: absent
when: not dokuwiki_enabled and is_debuntu when: not dokuwiki_enabled and is_debuntu
- name: Set /library/{{ dokuwiki_version }} owner to {{ apache_user }} and permissions to 0755 (recursively)
- name: Change permissions on engine directory so Apache can write
file: file:
path: "/library/{{ dokuwiki_version }}" path: "/library/{{ dokuwiki_version }}"
owner: "{{ apache_user }}" owner: "{{ apache_user }}"
@ -49,7 +48,7 @@
state: directory state: directory
recurse: yes recurse: yes
- name: Restart Apache, so it picks up the new aliases - name: Restart Apache ({{ apache_service }}) to enable/disable DokuWiki's http://box/wiki
service: systemd:
name: "{{ apache_service }}" name: "{{ apache_service }}"
state: restarted state: restarted

View file

@ -2,9 +2,9 @@
include_tasks: install.yml include_tasks: install.yml
when: dokuwiki_install when: dokuwiki_install
- name: Add 'dokuwiki' to list of services at {{ iiab_ini_file }} - name: Add 'dokuwiki' variable values to {{ iiab_ini_file }}
ini_file: ini_file:
dest: "{{ iiab_ini_file }}" path: "{{ iiab_ini_file }}"
section: dokuwiki section: dokuwiki
option: "{{ item.option }}" option: "{{ item.option }}"
value: "{{ item.value }}" value: "{{ item.value }}"

View file

@ -1,9 +1,7 @@
- name: Install ejabberd packages - name: Install ejabberd package
package: package:
name: "{{ item }}" name: ejabberd
state: present state: present
with_items:
- ejabberd
tags: tags:
- download - download

View file

@ -48,3 +48,10 @@ There are a number of seemingly similar usernames and passwords in this installa
* elgg_admin_user - the Elgg (not MySQL) user that is the administrator * elgg_admin_user - the Elgg (not MySQL) user that is the administrator
* elgg_admin_password - the password for elgg_admin_user * elgg_admin_password - the password for elgg_admin_user
More Tips & Tricks
------------------
If you're online, please see "Elgg Administration: What tips & tricks exist?" at: http://FAQ.IIAB.IO
If you're offline, Internet-in-a-Box's FAQ (Frequently Asked Questions) is here: http://box/info

View file

@ -1,5 +1,5 @@
elgg_xx: elgg elgg_xx: elgg
elgg_version: "2.3.8" elgg_version: "2.3.10"
# elgg_mysql_password: defined in default_vars # elgg_mysql_password: defined in default_vars
elgg_url: /elgg elgg_url: /elgg

View file

@ -1,37 +1,42 @@
# Assume we only get here if elgg_install: True # Assume we only get here if elgg_install: True
# Assume mysql is running # Assume MySQL is running
- name: Download current version from our site - name: Download {{ iiab_download_url }}/elgg-{{ elgg_version }}.zip to {{ downloads_dir }}
shell: wget {{ iiab_download_url }}/elgg-{{ elgg_version }}.zip -c -P {{ downloads_dir }} #shell: wget {{ iiab_download_url }}/elgg-{{ elgg_version }}.zip -c -P {{ downloads_dir }}
args: #args:
creates: "{{ downloads_dir }}/elgg-{{ elgg_version }}.zip" # creates: "{{ downloads_dir }}/elgg-{{ elgg_version }}.zip"
get_url:
url: "{{ iiab_download_url }}/elgg-{{ elgg_version }}.zip"
dest: "{{ downloads_dir }}"
timeout: "{{ download_timeout }}"
when: internet_available when: internet_available
- name: Determine if software is already expanded - name: Check for existence of /opt/elgg-{{ elgg_version }}/index.php
stat: stat:
path: "/opt/elgg-{{ elgg_version }}/index.php" path: "/opt/elgg-{{ elgg_version }}/index.php"
register: elgg register: elgg
# use unzip and shell until unarchive works again - name: Unpack (unarchive) .zip to /opt, if above index.php doesn't exist
# unarchive: dest=/opt/ #shell: "/usr/bin/unzip -o {{ downloads_dir }}/elgg-{{ elgg_version }}.zip -d /opt"
# src={{ downloads_dir }}/elgg-{{ elgg_version }}.zip unarchive:
#remote_src: yes
- name: Expand it to our location unless already done #src: "{{ iiab_download_url }}/elgg-{{ elgg_version }}.zip"
shell: "/usr/bin/unzip -o {{ downloads_dir }}/elgg-{{ elgg_version }}.zip -d /opt" src: "{{ downloads_dir }}/elgg-{{ elgg_version }}.zip"
dest: /opt
owner: "{{ apache_user }}"
group: "{{ apache_user }}"
when: elgg.stat.exists is defined and not elgg.stat.exists when: elgg.stat.exists is defined and not elgg.stat.exists
- name: Create a link to the versioned elgg-* folder - name: Create softlink from /opt/elgg to /opt/elgg-{{ elgg_version }}
file: file:
src: "./elgg-{{ elgg_version }}" src: "./elgg-{{ elgg_version }}"
dest: /opt/elgg path: /opt/elgg
owner: "{{ apache_user }}" owner: "{{ apache_user }}"
group: "{{ apache_user }}" group: "{{ apache_user }}"
state: link state: link
force: true force: true
# Use template to fix up settings in elgg-config/settings.php with our variables substituted. - name: 'Install /opt/elgg/elgg-config/settings.php from template (WARNING: overwrites manual settings!)'
# Note this will overwrite any manual settings.
- name: Substitute our parameters in /opt/elgg/elgg-config/settings.php
template: template:
src: "settings.php.j2" src: "settings.php.j2"
dest: "/opt/{{ elgg_xx }}/elgg-config/settings.php" dest: "/opt/{{ elgg_xx }}/elgg-config/settings.php"
@ -39,7 +44,7 @@
group: "{{ apache_user }}" group: "{{ apache_user }}"
# The name of this file changed from 1.9 to 1.10. # The name of this file changed from 1.9 to 1.10.
- name: Copy default .htaccess to the root directory of Elgg tree - name: Copy default .htaccess into /opt/{{ elgg_xx }}, root of Elgg tree
copy: copy:
src: "/opt/{{ elgg_xx }}/vendor/elgg/elgg/install/config/htaccess.dist" src: "/opt/{{ elgg_xx }}/vendor/elgg/elgg/install/config/htaccess.dist"
dest: "/opt/{{ elgg_xx }}/.htaccess" dest: "/opt/{{ elgg_xx }}/.htaccess"
@ -48,28 +53,22 @@
group: "{{ apache_user }}" group: "{{ apache_user }}"
#regexp='^#RewriteBase' #regexp='^#RewriteBase'
- name: Modify .htaccess to have RewriteBase as our directory - name: Change .htaccess to include RewriteBase for http://box/elgg
lineinfile: lineinfile:
backup: no backup: no
dest: "/opt/{{ elgg_xx }}/.htaccess" path: "/opt/{{ elgg_xx }}/.htaccess"
state: present state: present
insertafter: '^#RewriteBase' insertafter: '^#RewriteBase'
line: "RewriteBase {{ elgg_url }}/" line: "RewriteBase {{ elgg_url }}/"
- name: Change permissions on engine directory so Apache can write - name: Set /opt/elgg/engine directory permissions to 0755 so Apache can write there
file: file:
path: /opt/elgg/engine/ path: /opt/elgg/engine/
owner: "{{ apache_user }}" owner: "{{ apache_user }}"
mode: 0755 mode: 0755
state: directory state: directory
- name: Create an upload directory that Apache can write in or Elgg - name: Change /opt/elgg-{{ elgg_version }} ownership to {{ apache_user }}:{{ apache_user }} (likely not nec, as unarchive & all do this above)
file:
path: "{{ elgg_upload_path }}"
state: directory
owner: "{{ apache_user }}"
- name: Change ownership
file: file:
path: "/opt/elgg-{{ elgg_version }}" path: "/opt/elgg-{{ elgg_version }}"
owner: "{{ apache_user }}" owner: "{{ apache_user }}"
@ -77,12 +76,18 @@
recurse: yes recurse: yes
state: directory state: directory
- name: Create a MySQL database for Elgg - can be run more than once - name: Create upload directory {{ elgg_upload_path }} that Apache (and Elgg) can write to
file:
path: "{{ elgg_upload_path }}"
state: directory
owner: "{{ apache_user }}"
- name: Create Elgg's MySQL database {{ dbname }}, to be populated below - can be run more than once
mysql_db: mysql_db:
name: "{{ dbname }}" name: "{{ dbname }}"
register: create_elgg_database register: create_elgg_database
- name: Create a user to access the Elgg database - can be run more than once - name: Create user/password to access Elgg database - can be run more than once
mysql_user: mysql_user:
name: "{{ dbuser }}" name: "{{ dbuser }}"
host: "{{ item }}" host: "{{ item }}"
@ -93,7 +98,7 @@
- ::1 - ::1
- localhost - localhost
- name: Create file to load database - name: Create /tmp/elggdb.sql from template, to load database
template: template:
src: "elggdb.sql.j2" src: "elggdb.sql.j2"
dest: "/tmp/elggdb.sql" dest: "/tmp/elggdb.sql"
@ -102,45 +107,50 @@
# tar up a mysqldump of freshly installed database and use it in the install to avoid the startup # tar up a mysqldump of freshly installed database and use it in the install to avoid the startup
# form, which worries me a lot. (/var/lib/mysql/elggdb) # form, which worries me a lot. (/var/lib/mysql/elggdb)
- name: Load Elgg database dump - name: Populate Elgg's MySQL database {{ dbname }}, from /tmp/elggdb.sql
mysql_db: mysql_db:
name: "{{ dbname }}" name: "{{ dbname }}"
state: import state: import
target: /tmp/elggdb.sql target: /tmp/elggdb.sql
when: create_elgg_database.changed when: create_elgg_database.changed
- name: Remove database dump after load - name: Remove database dump /tmp/elggdb.sql
file: file:
name: /tmp/elggdb.sql name: /tmp/elggdb.sql
state: absent state: absent
- name: Install config file for Elgg in Apache - name: Install /etc/{{ apache_config_dir }}/elgg.conf from template, for http://box/elgg
template: template:
src: elgg.conf src: elgg.conf
dest: "/etc/{{ apache_config_dir }}/elgg.conf" dest: "/etc/{{ apache_config_dir }}/elgg.conf"
- name: Enable Elgg for debuntu (will already be enabled above for redhat) - name: Create symlink elgg.conf from sites-enabled to sites-available (debuntu, not nec for redhat)
file: file:
src: /etc/apache2/sites-available/elgg.conf src: /etc/apache2/sites-available/elgg.conf
dest: /etc/apache2/sites-enabled/elgg.conf path: /etc/apache2/sites-enabled/elgg.conf
state: link state: link
when: elgg_enabled and is_debuntu when: elgg_enabled and is_debuntu
- name: Disable Elgg - remove config file for Elgg in Apache (debuntu) - name: Remove symlink /etc/apache2/sites-enabled/elgg.conf (debuntu)
file: file:
path: /etc/apache2/sites-enabled/elgg.conf path: /etc/apache2/sites-enabled/elgg.conf
state: absent state: absent
when: not elgg_enabled and is_debuntu when: not elgg_enabled and is_debuntu
- name: Disable Elgg - remove config file for Elgg in Apache (redhat) - name: Remove Apache's elgg.conf (redhat)
file: file:
dest: "/etc/{{ apache_config_dir }}/elgg.conf" dest: "/etc/{{ apache_config_dir }}/elgg.conf"
state: absent state: absent
when: not elgg_enabled and is_redhat when: not elgg_enabled and is_redhat
- name: Add 'elgg' to list of services at {{ iiab_ini_file }} - name: Restart Apache ({{ apache_service }}) to enable/disable http://box/elgg
service:
name: "{{ apache_service }}"
state: restarted
- name: Add 'elgg' variable values to {{ iiab_ini_file }}
ini_file: ini_file:
dest: "{{ iiab_ini_file }}" path: "{{ iiab_ini_file }}"
section: elgg section: elgg
option: "{{ item.option }}" option: "{{ item.option }}"
value: "{{ item.value }}" value: "{{ item.value }}"
@ -151,10 +161,5 @@
value: '"Elgg is an award-winning social networking engine, delivering the building blocks that enable businesses, schools, universities and associations to create their own fully-featured social networks and applications."' value: '"Elgg is an award-winning social networking engine, delivering the building blocks that enable businesses, schools, universities and associations to create their own fully-featured social networks and applications."'
- option: path - option: path
value: /opt/elgg value: /opt/elgg
- option: enabled - option: elgg_enabled
value: "{{ elgg_enabled }}" value: "{{ elgg_enabled }}"
- name: Restart Apache, so it picks up the new aliases
service:
name: "{{ apache_service }}"
state: restarted

View file

@ -1,4 +1,4 @@
- name: Create home directory - name: Create dir {{ doc_root }}/home
file: file:
path: "{{ doc_root }}/home" path: "{{ doc_root }}/home"
owner: "{{ apache_user }}" owner: "{{ apache_user }}"
@ -6,14 +6,14 @@
mode: 0755 mode: 0755
state: directory state: directory
- name: Install admin homepage into apache2 - name: Install /etc/{{ apache_config_dir }}/iiab-homepage.conf from template, for http://box redirect to http://box/home/
template: template:
src: iiab-homepage.conf src: iiab-homepage.conf
dest: "/etc/{{ apache_config_dir }}/iiab-homepage.conf" dest: "/etc/{{ apache_config_dir }}/iiab-homepage.conf"
- name: Enable the home page - name: Symlink /etc/apache2/sites-enabled/iiab-homepage.conf to /etc/{{ apache_config_dir }}/iiab-homepage.conf (debuntu)
file: file:
src: "/etc/{{ apache_config_dir }}/iiab-homepage.conf" src: "/etc/{{ apache_config_dir }}/iiab-homepage.conf"
dest: /etc/apache2/sites-enabled/iiab-homepage.conf path: /etc/apache2/sites-enabled/iiab-homepage.conf
state: link state: link
when: is_debuntu when: is_debuntu

View file

@ -2,5 +2,5 @@
apache_allow_sudo: True apache_allow_sudo: True
# For schools that use WordPress and/or Moodle intensively. See iiab/iiab #1147 # For schools that use WordPress and/or Moodle intensively. See iiab/iiab #1147
# WARNING: Enabling this (might) cause excess use of RAM or other resources? # WARNING: Enabling this might cause excess use of RAM/disk or other resources!
apache_high_php_limits: False apache_high_php_limits: False

View file

@ -1,9 +1,8 @@
/*! /*!
* Bootstrap v3.2.0 (http://getbootstrap.com) * Bootstrap v3.3.7 (http://getbootstrap.com)
* Copyright 2011-2014 Twitter, Inc. * Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/ */
.btn-default, .btn-default,
.btn-primary, .btn-primary,
.btn-success, .btn-success,
@ -29,6 +28,35 @@
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
} }
.btn-default.disabled,
.btn-primary.disabled,
.btn-success.disabled,
.btn-info.disabled,
.btn-warning.disabled,
.btn-danger.disabled,
.btn-default[disabled],
.btn-primary[disabled],
.btn-success[disabled],
.btn-info[disabled],
.btn-warning[disabled],
.btn-danger[disabled],
fieldset[disabled] .btn-default,
fieldset[disabled] .btn-primary,
fieldset[disabled] .btn-success,
fieldset[disabled] .btn-info,
fieldset[disabled] .btn-warning,
fieldset[disabled] .btn-danger {
-webkit-box-shadow: none;
box-shadow: none;
}
.btn-default .badge,
.btn-primary .badge,
.btn-success .badge,
.btn-info .badge,
.btn-warning .badge,
.btn-danger .badge {
text-shadow: none;
}
.btn:active, .btn:active,
.btn.active { .btn.active {
background-image: none; background-image: none;
@ -55,34 +83,66 @@
background-color: #e0e0e0; background-color: #e0e0e0;
border-color: #dbdbdb; border-color: #dbdbdb;
} }
.btn-default:disabled, .btn-default.disabled,
.btn-default[disabled] { .btn-default[disabled],
fieldset[disabled] .btn-default,
.btn-default.disabled:hover,
.btn-default[disabled]:hover,
fieldset[disabled] .btn-default:hover,
.btn-default.disabled:focus,
.btn-default[disabled]:focus,
fieldset[disabled] .btn-default:focus,
.btn-default.disabled.focus,
.btn-default[disabled].focus,
fieldset[disabled] .btn-default.focus,
.btn-default.disabled:active,
.btn-default[disabled]:active,
fieldset[disabled] .btn-default:active,
.btn-default.disabled.active,
.btn-default[disabled].active,
fieldset[disabled] .btn-default.active {
background-color: #e0e0e0; background-color: #e0e0e0;
background-image: none; background-image: none;
} }
.btn-primary { .btn-primary {
background-image: -webkit-linear-gradient(top, #428bca 0%, #2d6ca2 100%); background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
background-image: -o-linear-gradient(top, #428bca 0%, #2d6ca2 100%); background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#2d6ca2)); background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
background-image: linear-gradient(to bottom, #428bca 0%, #2d6ca2 100%); background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x; background-repeat: repeat-x;
border-color: #2b669a; border-color: #245580;
} }
.btn-primary:hover, .btn-primary:hover,
.btn-primary:focus { .btn-primary:focus {
background-color: #2d6ca2; background-color: #265a88;
background-position: 0 -15px; background-position: 0 -15px;
} }
.btn-primary:active, .btn-primary:active,
.btn-primary.active { .btn-primary.active {
background-color: #2d6ca2; background-color: #265a88;
border-color: #2b669a; border-color: #245580;
} }
.btn-primary:disabled, .btn-primary.disabled,
.btn-primary[disabled] { .btn-primary[disabled],
background-color: #2d6ca2; fieldset[disabled] .btn-primary,
.btn-primary.disabled:hover,
.btn-primary[disabled]:hover,
fieldset[disabled] .btn-primary:hover,
.btn-primary.disabled:focus,
.btn-primary[disabled]:focus,
fieldset[disabled] .btn-primary:focus,
.btn-primary.disabled.focus,
.btn-primary[disabled].focus,
fieldset[disabled] .btn-primary.focus,
.btn-primary.disabled:active,
.btn-primary[disabled]:active,
fieldset[disabled] .btn-primary:active,
.btn-primary.disabled.active,
.btn-primary[disabled].active,
fieldset[disabled] .btn-primary.active {
background-color: #265a88;
background-image: none; background-image: none;
} }
.btn-success { .btn-success {
@ -105,8 +165,24 @@
background-color: #419641; background-color: #419641;
border-color: #3e8f3e; border-color: #3e8f3e;
} }
.btn-success:disabled, .btn-success.disabled,
.btn-success[disabled] { .btn-success[disabled],
fieldset[disabled] .btn-success,
.btn-success.disabled:hover,
.btn-success[disabled]:hover,
fieldset[disabled] .btn-success:hover,
.btn-success.disabled:focus,
.btn-success[disabled]:focus,
fieldset[disabled] .btn-success:focus,
.btn-success.disabled.focus,
.btn-success[disabled].focus,
fieldset[disabled] .btn-success.focus,
.btn-success.disabled:active,
.btn-success[disabled]:active,
fieldset[disabled] .btn-success:active,
.btn-success.disabled.active,
.btn-success[disabled].active,
fieldset[disabled] .btn-success.active {
background-color: #419641; background-color: #419641;
background-image: none; background-image: none;
} }
@ -130,8 +206,24 @@
background-color: #2aabd2; background-color: #2aabd2;
border-color: #28a4c9; border-color: #28a4c9;
} }
.btn-info:disabled, .btn-info.disabled,
.btn-info[disabled] { .btn-info[disabled],
fieldset[disabled] .btn-info,
.btn-info.disabled:hover,
.btn-info[disabled]:hover,
fieldset[disabled] .btn-info:hover,
.btn-info.disabled:focus,
.btn-info[disabled]:focus,
fieldset[disabled] .btn-info:focus,
.btn-info.disabled.focus,
.btn-info[disabled].focus,
fieldset[disabled] .btn-info.focus,
.btn-info.disabled:active,
.btn-info[disabled]:active,
fieldset[disabled] .btn-info:active,
.btn-info.disabled.active,
.btn-info[disabled].active,
fieldset[disabled] .btn-info.active {
background-color: #2aabd2; background-color: #2aabd2;
background-image: none; background-image: none;
} }
@ -155,8 +247,24 @@
background-color: #eb9316; background-color: #eb9316;
border-color: #e38d13; border-color: #e38d13;
} }
.btn-warning:disabled, .btn-warning.disabled,
.btn-warning[disabled] { .btn-warning[disabled],
fieldset[disabled] .btn-warning,
.btn-warning.disabled:hover,
.btn-warning[disabled]:hover,
fieldset[disabled] .btn-warning:hover,
.btn-warning.disabled:focus,
.btn-warning[disabled]:focus,
fieldset[disabled] .btn-warning:focus,
.btn-warning.disabled.focus,
.btn-warning[disabled].focus,
fieldset[disabled] .btn-warning.focus,
.btn-warning.disabled:active,
.btn-warning[disabled]:active,
fieldset[disabled] .btn-warning:active,
.btn-warning.disabled.active,
.btn-warning[disabled].active,
fieldset[disabled] .btn-warning.active {
background-color: #eb9316; background-color: #eb9316;
background-image: none; background-image: none;
} }
@ -180,8 +288,24 @@
background-color: #c12e2a; background-color: #c12e2a;
border-color: #b92c28; border-color: #b92c28;
} }
.btn-danger:disabled, .btn-danger.disabled,
.btn-danger[disabled] { .btn-danger[disabled],
fieldset[disabled] .btn-danger,
.btn-danger.disabled:hover,
.btn-danger[disabled]:hover,
fieldset[disabled] .btn-danger:hover,
.btn-danger.disabled:focus,
.btn-danger[disabled]:focus,
fieldset[disabled] .btn-danger:focus,
.btn-danger.disabled.focus,
.btn-danger[disabled].focus,
fieldset[disabled] .btn-danger.focus,
.btn-danger.disabled:active,
.btn-danger[disabled]:active,
fieldset[disabled] .btn-danger:active,
.btn-danger.disabled.active,
.btn-danger[disabled].active,
fieldset[disabled] .btn-danger.active {
background-color: #c12e2a; background-color: #c12e2a;
background-image: none; background-image: none;
} }
@ -203,12 +327,12 @@
.dropdown-menu > .active > a, .dropdown-menu > .active > a,
.dropdown-menu > .active > a:hover, .dropdown-menu > .active > a:hover,
.dropdown-menu > .active > a:focus { .dropdown-menu > .active > a:focus {
background-color: #357ebd; background-color: #2e6da4;
background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%); background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -o-linear-gradient(top, #428bca 0%, #357ebd 100%); background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#357ebd)); background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%); background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
background-repeat: repeat-x; background-repeat: repeat-x;
} }
.navbar-default { .navbar-default {
@ -223,12 +347,13 @@
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
} }
.navbar-default .navbar-nav > .open > a,
.navbar-default .navbar-nav > .active > a { .navbar-default .navbar-nav > .active > a {
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%); background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
background-image: -o-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%); background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f3f3f3)); background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
background-image: linear-gradient(to bottom, #ebebeb 0%, #f3f3f3 100%); background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
background-repeat: repeat-x; background-repeat: repeat-x;
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
@ -245,13 +370,15 @@
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x; background-repeat: repeat-x;
border-radius: 4px;
} }
.navbar-inverse .navbar-nav > .open > a,
.navbar-inverse .navbar-nav > .active > a { .navbar-inverse .navbar-nav > .active > a {
background-image: -webkit-linear-gradient(top, #222 0%, #282828 100%); background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);
background-image: -o-linear-gradient(top, #222 0%, #282828 100%); background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#222), to(#282828)); background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
background-image: linear-gradient(to bottom, #222 0%, #282828 100%); background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
background-repeat: repeat-x; background-repeat: repeat-x;
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
@ -265,6 +392,19 @@
.navbar-fixed-bottom { .navbar-fixed-bottom {
border-radius: 0; border-radius: 0;
} }
@media (max-width: 767px) {
.navbar .navbar-nav .open .dropdown-menu > .active > a,
.navbar .navbar-nav .open .dropdown-menu > .active > a:hover,
.navbar .navbar-nav .open .dropdown-menu > .active > a:focus {
color: #fff;
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
background-repeat: repeat-x;
}
}
.alert { .alert {
text-shadow: 0 1px 0 rgba(255, 255, 255, .2); text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
@ -315,11 +455,11 @@
background-repeat: repeat-x; background-repeat: repeat-x;
} }
.progress-bar { .progress-bar {
background-image: -webkit-linear-gradient(top, #428bca 0%, #3071a9 100%); background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);
background-image: -o-linear-gradient(top, #428bca 0%, #3071a9 100%); background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#3071a9)); background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%); background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
background-repeat: repeat-x; background-repeat: repeat-x;
} }
.progress-bar-success { .progress-bar-success {
@ -367,14 +507,19 @@
.list-group-item.active, .list-group-item.active,
.list-group-item.active:hover, .list-group-item.active:hover,
.list-group-item.active:focus { .list-group-item.active:focus {
text-shadow: 0 -1px 0 #3071a9; text-shadow: 0 -1px 0 #286090;
background-image: -webkit-linear-gradient(top, #428bca 0%, #3278b3 100%); background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);
background-image: -o-linear-gradient(top, #428bca 0%, #3278b3 100%); background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#3278b3)); background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
background-image: linear-gradient(to bottom, #428bca 0%, #3278b3 100%); background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
background-repeat: repeat-x; background-repeat: repeat-x;
border-color: #3278b3; border-color: #2b669a;
}
.list-group-item.active .badge,
.list-group-item.active:hover .badge,
.list-group-item.active:focus .badge {
text-shadow: none;
} }
.panel { .panel {
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
@ -389,11 +534,11 @@
background-repeat: repeat-x; background-repeat: repeat-x;
} }
.panel-primary > .panel-heading { .panel-primary > .panel-heading {
background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%); background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -o-linear-gradient(top, #428bca 0%, #357ebd 100%); background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#357ebd)); background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%); background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
background-repeat: repeat-x; background-repeat: repeat-x;
} }
.panel-success > .panel-heading { .panel-success > .panel-heading {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,72 @@
/* open-sans-regular - latin */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src: local('Open Sans Regular'), local('OpenSans-Regular'),
url('/common/fonts/open-sans-v15-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('/common/fonts/open-sans-v15-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* open-sans-600 - latin */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 600;
src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'),
url('/common/fonts/open-sans-v15-latin-600.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('/common/fonts/open-sans-v15-latin-600.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* open-sans-700 - latin */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 700;
src: local('Open Sans Bold'), local('OpenSans-Bold'),
url('/common/fonts/open-sans-v15-latin-700.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('/common/fonts/open-sans-v15-latin-700.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* font-awesome 5 */
@font-face {
font-family: 'Font Awesome';
font-style: normal;
font-weight: 900;
src: url('/common/fonts/fa-solid-900.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('/common/fonts/fa-solid-900.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* bubblegum-sans-regular - latin */
@font-face {
font-family: 'Bubblegum Sans';
font-style: normal;
font-weight: 400;
src: local('Bubblegum Sans Regular'), local('BubblegumSans-Regular'),
url('/common/fonts/bubblegum-sans-v6-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('/common/fonts/bubblegum-sans-v6-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* finger-paint-regular - latin */
@font-face {
font-family: 'Finger Paint';
font-style: normal;
font-weight: 400;
src: local('Finger Paint Regular'), local('FingerPaint-Regular'),
url('/common/fonts/finger-paint-v7-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('/common/fonts/finger-paint-v7-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* flavors-regular - latin */
@font-face {
font-family: 'Flavors';
font-style: normal;
font-weight: 400;
src: local('Flavors'), local('Flavors-Regular'),
url('/common/fonts/flavors-v6-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('/common/fonts/flavors-v6-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* freckle-face-regular - latin */
@font-face {
font-family: 'Freckle Face';
font-style: normal;
font-weight: 400;
src: local('Freckle Face'), local('FreckleFace-Regular'),
url('/common/fonts/freckle-face-v6-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('/common/fonts/freckle-face-v6-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}

View file

@ -1,28 +0,0 @@
/* open-sans-regular - latin */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src: local('Open Sans Regular'), local('OpenSans-Regular'),
url('/common/fonts/open-sans-v15-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('/common/fonts/open-sans-v15-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* open-sans-600 - latin */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 600;
src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'),
url('/common/fonts/open-sans-v15-latin-600.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('/common/fonts/open-sans-v15-latin-600.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* open-sans-700 - latin */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 700;
src: local('Open Sans Bold'), local('OpenSans-Bold'),
url('/common/fonts/open-sans-v15-latin-700.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('/common/fonts/open-sans-v15-latin-700.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,4 +1,4 @@
- name: Copy css files to /library/www/html/common/css - name: Copy css files to {{ doc_root }}/common/css # doc_root is /library/www/html
copy: copy:
src: "{{ item }}" src: "{{ item }}"
dest: "{{ doc_root }}/common/css" dest: "{{ doc_root }}/common/css"
@ -8,7 +8,7 @@
with_fileglob: with_fileglob:
- html/css/*.css - html/css/*.css
- name: Copy js files to /library/www/html/common/js - name: Copy js files to {{ doc_root }}/common/js # doc_root is /library/www/html
copy: copy:
src: "{{ item }}" src: "{{ item }}"
dest: "{{ doc_root }}/common/js" dest: "{{ doc_root }}/common/js"
@ -18,7 +18,7 @@
with_fileglob: with_fileglob:
- html/js/*.js - html/js/*.js
- name: Copy fonts files to /library/www/html/common/fonts - name: Copy fonts files to {{ doc_root }}/common/fonts # doc_root is /library/www/html
copy: copy:
src: "{{ item }}" src: "{{ item }}"
dest: "{{ doc_root }}/common/fonts" dest: "{{ doc_root }}/common/fonts"
@ -28,7 +28,7 @@
with_fileglob: with_fileglob:
- html/fonts/* - html/fonts/*
- name: Copy html files to /library/www/html/common/html - name: Copy html files to {{ doc_root }}/common/html # doc_root is /library/www/html
copy: copy:
src: "{{ item }}" src: "{{ item }}"
dest: "{{ doc_root }}/common/html" dest: "{{ doc_root }}/common/html"
@ -38,7 +38,7 @@
with_fileglob: with_fileglob:
- html/html/* - html/html/*
- name: Copy assets files to /library/www/html/common/assets - name: Copy assets files to {{ doc_root }}/common/assets # doc_root is /library/www/html
copy: copy:
src: "{{ item }}" src: "{{ item }}"
dest: "{{ doc_root }}/common/assets" dest: "{{ doc_root }}/common/assets"
@ -49,7 +49,7 @@
- html/assets/* - html/assets/*
# copy all services, even if not permissioned elsewhere # copy all services, even if not permissioned elsewhere
- name: Copy services files to /library/www/html/common/services - name: Copy services files to {{ doc_root }}/common/services # doc_root is /library/www/html
copy: copy:
src: "{{ item }}" src: "{{ item }}"
dest: "{{ doc_root }}/common/services" dest: "{{ doc_root }}/common/services"
@ -59,10 +59,10 @@
with_fileglob: with_fileglob:
- html/services/* - html/services/*
- name: Create symlink from assets to {{ iiab_ini_file }} - name: Symlink {{ doc_root }}/common/assets/iiab.ini to {{ iiab_ini_file }} # doc_root is /library/www/html
file: file:
src: "{{ iiab_ini_file }}" src: "{{ iiab_ini_file }}"
dest: "{{ doc_root }}/common/assets/iiab.ini" path: "{{ doc_root }}/common/assets/iiab.ini"
owner: root owner: root
group: root group: root
state: link state: link

View file

@ -1,78 +1,68 @@
- name: Install httpd required packages (debian) - name: 'Install 3 packages: apache2, php{{ php_version }}, php{{ php_version }}-curl (debian)'
package: package:
name: "{{ item }}" #name: [u'apache2', u'php{{ php_version }}', u'php{{ php_version }}-curl'] # FAILS ('u' for Unicode strings)
state: present #name: ['apache2', 'php{{ php_version }}', 'php{{ php_version }}-curl'] # WORKS?
with_items: name:
- apache2 - apache2
- php{{ php_version }} - "php{{ php_version }}"
- php{{ php_version }}-curl - "php{{ php_version }}-curl"
# - php{{ php_version }}-sqlite state: present
when: is_debian
tags: tags:
- download - download
when: is_debian
- name: Debian changed SQLite name (debian-8) - name: 'Install 2 packages: apache2, php (ubuntu)'
package:
#name: [u'apache2', u'php'] # FAILS ('u' for Unicode strings)
#name: ['apache2', 'php'] # WORKS
name:
- apache2
- php
state: present
when: is_ubuntu
tags:
- download
- name: Install php{{ php_version }}-sqlite (debian-8)
package: package:
name: "php{{ php_version }}-sqlite" name: "php{{ php_version }}-sqlite"
when: is_debian and ansible_distribution_major_version == "8" when: is_debian and ansible_distribution_major_version == "8"
- name: Debian changed SQLite3 name (debian-9) # SQLite3 no longer included in another package
- name: Install php{{ php_version }}-sqlite3 (debian-9 or ubuntu-18)
package: package:
name: "php{{ php_version }}-sqlite3" name: "php{{ php_version }}-sqlite3"
when: is_debian and ansible_distribution_major_version == "9" when: (is_debian and ansible_distribution_major_version == "9") or is_ubuntu_18
- name: Install httpd required packages (ubuntu) - name: 'Install 4 packages: httpd, mod_authnz_external, php, php-curl (redhat)'
package: package:
name: "{{ item }}" #name: [u'httpd', u'php', u'php-curl', u'mod_authnz_external'] # FAILS ('u' for Unicode strings)
state: present #name: ['httpd', 'php', 'php-curl', 'mod_authnz_external'] # WORKS
with_items: name:
- apache2
- php
tags:
- download
when: is_ubuntu
- name: SQLite3 no longer included in another package (ubuntu-18)
package:
name: php{{ php_version }}-sqlite3
when: is_ubuntu_18
- name: Install httpd required packages (redhat)
package:
name: "{{ item }}"
state: present
with_items:
- httpd - httpd
- mod_authnz_external
- php - php
- php-curl - php-curl
- mod_authnz_external state: present
# - php-sqlite when: is_redhat
tags: tags:
- download - download
when: is_redhat
# MOVED DOWN ~58 LINES - name: Install Apache's 010-iiab.conf & proxy_ajp.conf into /etc/apache2/sites-available, from templates
#- name: Remove the default apache2 config file (debuntu)
# file:
# path: /etc/apache2/sites-enabled/000-default.conf
# state: absent
# when: is_debuntu
- name: Create httpd config files
template: template:
backup: yes backup: yes
src: "{{ item.src }}" src: "{{ item.src }}"
dest: "{{ item.dest }}" dest: "{{ item.dest }}"
owner: root owner: root
group: root group: root
mode: "{{ item.mode }}" mode: 0644
with_items: with_items:
- { src: '010-iiab.conf.j2', dest: '/etc/{{ apache_config_dir }}/010-iiab.conf', mode: '0755' } - { src: '010-iiab.conf.j2', dest: '/etc/{{ apache_config_dir }}/010-iiab.conf' }
- { src: 'proxy_ajp.conf.j2', dest: '/etc/{{ apache_config_dir }}/proxy_ajp.conf', mode: '0644' } - { src: 'proxy_ajp.conf.j2', dest: '/etc/{{ apache_config_dir }}/proxy_ajp.conf' }
#- { src: 'php.ini.j2', dest: '/etc/php.ini', mode: '0644' } # @jvonau suggests removing this in https://github.com/iiab/iiab/issues/1147 #- { src: 'php.ini.j2', dest: '/etc/php.ini', mode: '0644' } # @jvonau suggests removing this in https://github.com/iiab/iiab/issues/1147
# For schools that use WordPress and/or Moodle intensively. See iiab/iiab #1147 # For schools that use WordPress and/or Moodle intensively. See iiab/iiab #1147
# WARNING: Enabling this (might) cause excess use of RAM or other resources? # WARNING: Enabling this might cause excess use of RAM/disk or other resources!
- name: Enact high limits in /etc/php/{{ php_version }}/{{ apache_service }}/php.ini if using WordPress and/or Moodle intensively - name: Enact high limits in /etc/php/{{ php_version }}/{{ apache_service }}/php.ini if using WordPress and/or Moodle intensively
lineinfile: lineinfile:
path: "/etc/php/{{ php_version }}/{{ apache_service }}/php.ini" path: "/etc/php/{{ php_version }}/{{ apache_service }}/php.ini"
@ -80,14 +70,14 @@
line: "{{ item.line }}" line: "{{ item.line }}"
when: apache_high_php_limits when: apache_high_php_limits
with_items: with_items:
- { regexp: '^upload_max_filesize', line: 'upload_max_filesize = 64M ; default is 2M' } - { regexp: '^upload_max_filesize', line: 'upload_max_filesize = 500M ; default is 2M' }
- { regexp: '^post_max_size', line: 'post_max_size = 128M ; default is 8M' } - { regexp: '^post_max_size', line: 'post_max_size = 500M ; default is 8M' }
- { regexp: '^memory_limit', line: 'memory_limit = 256M ; default is 128M' } - { regexp: '^memory_limit', line: 'memory_limit = 256M ; default is 128M' }
- { regexp: '^max_execution_time', line: 'max_execution_time = 300 ; default is 30' } - { regexp: '^max_execution_time', line: 'max_execution_time = 300 ; default is 30' }
- { regexp: '^max_input_time', line: 'max_input_time = 300 ; default is 60' } - { regexp: '^max_input_time', line: 'max_input_time = 300 ; default is 60' }
# remove symlinks for mpm-event, replace with mpm-prefork # remove symlinks for mpm-event, replace with mpm-prefork
- name: Remove mpm event links (debuntu) - name: Remove both mpm_event symlinks from /etc/apache2/mods-enabled (debuntu)
file: file:
path: "/etc/apache2/mods-enabled/{{ item }}" path: "/etc/apache2/mods-enabled/{{ item }}"
state: absent state: absent
@ -96,17 +86,17 @@
- mpm_event.load - mpm_event.load
when: is_debuntu when: is_debuntu
- name: Create symlinks for mpm-prefork (debuntu) - name: Create both mpm_prefork symlinks from /etc/apache2/mods-enabled to /etc/apache2/mods-available (debuntu)
file: file:
path: "/etc/apache2/mods-enabled/{{ item }}"
src: "/etc/apache2/mods-available/{{ item }}" src: "/etc/apache2/mods-available/{{ item }}"
path: "/etc/apache2/mods-enabled/{{ item }}"
state: link state: link
with_items: with_items:
- mpm_prefork.conf - mpm_prefork.conf
- mpm_prefork.load - mpm_prefork.load
when: is_debuntu when: is_debuntu
- name: Turn on mod_proxy (debuntu) - name: 'Turn on mod_proxy using a2enmod with: proxy, proxy_html, headers, rewrite (debuntu)'
command: a2enmod {{ item }} command: a2enmod {{ item }}
with_items: with_items:
- proxy - proxy
@ -115,16 +105,14 @@
- rewrite - rewrite
when: is_debuntu when: is_debuntu
- name: Create symlinks for enabling our site (debuntu) - name: Enable our site, creating 010-iiab.conf symlink from sites-enabled to sites-available (debuntu)
file: file:
path: "/etc/apache2/sites-enabled/{{ item }}" src: "/etc/{{ apache_config_dir }}/010-iiab.conf"
src: "/etc/apache2/sites-available/{{ item }}" path: /etc/apache2/sites-enabled/010-iiab.conf
state: link state: link
with_items:
- 010-iiab.conf
when: is_debuntu when: is_debuntu
- name: Remove apache2 default config files (debuntu) - name: Remove 000-default.conf from /etc/apache2 and /etc/apache2/sites-enabled (debuntu)
file: file:
path: "{{ item }}" path: "{{ item }}"
state: absent state: absent
@ -133,7 +121,7 @@
- /etc/apache2/sites-enabled/000-default.conf - /etc/apache2/sites-enabled/000-default.conf
when: is_debuntu when: is_debuntu
- name: Create http pid dir /var/run/{{ apache_user }} - name: Create Apache's pid dir /var/run/{{ apache_user }}
file: file:
path: "/var/run/{{ apache_user }}" path: "/var/run/{{ apache_user }}"
mode: 0755 mode: 0755
@ -141,19 +129,19 @@
group: root group: root
state: directory state: directory
- name: Create admin group - name: 'Create group: admin'
group: group:
name: admin name: admin
state: present state: present
- name: Add {{ apache_user }} (from variable apache_user) to admin group - name: Add user {{ apache_user }} (from variable apache_user) to group admin
user: user:
name: "{{ apache_user }}" name: "{{ apache_user }}"
groups: admin groups: admin
state: present state: present
createhome: no createhome: no
- name: Create httpd log dir /var/log/{{ apache_service }} - name: Create Apache dir /var/log/{{ apache_service }}
file: file:
path: "/var/log/{{ apache_service }}" path: "/var/log/{{ apache_service }}"
mode: 0755 mode: 0755
@ -161,12 +149,12 @@
group: "{{ apache_user }}" group: "{{ apache_user }}"
state: directory state: directory
- name: Enable httpd - name: Enable Apache systemd service ({{ apache_service }})
service: service:
name: "{{ apache_service }}" name: "{{ apache_service }}"
enabled: yes enabled: yes
- name: Create iiab-info directory - name: Create /library/www/html/info directory for http://box/info offline docs
file: file:
path: "{{ doc_root }}/info" path: "{{ doc_root }}/info"
mode: 0755 mode: 0755
@ -174,19 +162,8 @@
group: "{{ apache_user }}" group: "{{ apache_user }}"
state: directory state: directory
- name: Remove iiab-info.conf
file:
dest: "/etc/{{ apache_config_dir }}/iiab-info.conf"
state: absent
- name: Remove iiab-info.conf symlink (debuntu)
file:
dest: /etc/apache2/sites-enabled/iiab-info.conf
state: absent
when: is_debuntu
# SEE https://github.com/iiab/iiab/issues/1143 as the old roles/osm playbook is rarely used as of late 2018 (if anybody still uses roles/osm, they can overwrite osm.conf using the original osm playbook, or in other ways) # SEE https://github.com/iiab/iiab/issues/1143 as the old roles/osm playbook is rarely used as of late 2018 (if anybody still uses roles/osm, they can overwrite osm.conf using the original osm playbook, or in other ways)
- name: Copy osm.conf for http://box/maps (all OS's) - name: Install /etc/{{ apache_config_dir }}/osm.conf for http://box/maps (all OS's)
copy: copy:
src: osm.conf src: osm.conf
dest: "/etc/{{ apache_config_dir }}" dest: "/etc/{{ apache_config_dir }}"
@ -195,10 +172,11 @@
mode: 0644 mode: 0644
backup: yes backup: yes
- name: Create link from sites-enabled to sites-available (debuntu) - name: Symlink /etc/apache2/sites-enabled/osm.conf to /etc/{{ apache_config_dir }}/osm.conf (debuntu)
file: file:
src: "/etc/{{ apache_config_dir }}/osm.conf" src: "/etc/{{ apache_config_dir }}/osm.conf"
dest: /etc/apache2/sites-enabled/osm.conf path: /etc/apache2/sites-enabled/osm.conf
#path: "/etc/{{ apache_service }}/sites-enabled/osm.conf"
state: link state: link
when: is_debuntu when: is_debuntu
@ -206,26 +184,31 @@
tags: tags:
- base - base
# Fixes search @ http://box/modules/es-wikihow - see https://github.com/iiab/iiab/issues/829 # Partially fixes search @ http://box/modules/es-wikihow (on RPi anyway) see https://github.com/iiab/iiab/issues/829
- include_tasks: php-stem.yml - include_tasks: php-stem.yml
tags: tags:
- base - base
- name: Install /usr/bin/iiab-refresh-wiki-docs (scraper script) to create http://box/info offline documentation (will be run at the end of Stage 4 = roles/4-server-options/tasks/main.yml) - name: Install /usr/bin/iiab-refresh-wiki-docs (scraper script) to create http://box/info offline documentation. (Script can be run manually and/or at the end of Stage 4 = roles/4-server-options/tasks/main.yml)
template: template:
src: refresh-wiki-docs.sh src: refresh-wiki-docs.sh
dest: /usr/bin/iiab-refresh-wiki-docs dest: /usr/bin/iiab-refresh-wiki-docs
mode: 0755 mode: 0755
- name: Give apache_user permission to poweroff - name: Give {{ apache_user }} (per variable apache_user) permission to poweroff, installing /etc/sudoers.d/020_apache_poweroff from template
template: template:
src: 020_apache_poweroff.j2 src: 020_apache_poweroff.j2
dest: /etc/sudoers.d/020_apache_poweroff dest: /etc/sudoers.d/020_apache_poweroff
mode: 0755 mode: 0755
when: apache_allow_sudo when: apache_allow_sudo
- name: Remove apache_user permission to poweroff - name: Remove {{ apache_user }} (per variable apache_user) permission to poweroff, removing /etc/sudoers.d/020_apache_poweroff
file: file:
dest: /etc/sudoers.d/020_apache_poweroff path: /etc/sudoers.d/020_apache_poweroff
state: absent state: absent
when: not apache_allow_sudo when: not apache_allow_sudo
- name: Restart Apache systemd service ({{ apache_service }})
systemd:
name: "{{ apache_service }}"
state: restarted

View file

@ -11,7 +11,7 @@
# command: cd /; wget http://download.iiab.io/packages/php-stem.x64.tar # command: cd /; wget http://download.iiab.io/packages/php-stem.x64.tar
# when: not is_rpi # when: not is_rpi
- name: Download & unpack php-stem.rpi.tar to / (rpi) - name: Unarchive http://download.iiab.io/packages/php-stem.rpi.tar to / (rpi)
unarchive: unarchive:
src: http://download.iiab.io/packages/php-stem.rpi.tar src: http://download.iiab.io/packages/php-stem.rpi.tar
dest: / dest: /
@ -21,7 +21,7 @@
remote_src: yes remote_src: yes
when: is_rpi when: is_rpi
- name: Download & unpack php-stem.x86.tar to / (debian-9 on x86_64 only) - name: Unarchive http://download.iiab.io/packages/php-stem.x64.tar to / (debian-9 on x86_64 only)
unarchive: unarchive:
src: http://download.iiab.io/packages/php-stem.x64.tar src: http://download.iiab.io/packages/php-stem.x64.tar
dest: / dest: /
@ -33,9 +33,3 @@
# Presumably fails on Debian 8 & 10? # Presumably fails on Debian 8 & 10?
# Fails on Debian i686 as of 2018-08-07: https://github.com/iiab/iiab/issues/983 # Fails on Debian i686 as of 2018-08-07: https://github.com/iiab/iiab/issues/983
# Fails on Ubuntu 18.04 as of 2018-07-28: https://github.com/iiab/iiab/issues/829 # Fails on Ubuntu 18.04 as of 2018-07-28: https://github.com/iiab/iiab/issues/829
# No need to do this twice? Happens later @ https://github.com/iiab/iiab/blob/master/roles/3-base-server/tasks/main.yml#L24-L28
#- name: Restart apache2 / httpd
# service:
# name: "{{ apache_service }}"
# state: restarted

View file

@ -177,7 +177,7 @@ DocumentRoot "{{ doc_root }}"
ErrorLog /var/log/apache2/error.log ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined CustomLog /var/log/apache2/access.log combined
ServerName {{ iiab_hostname }} ServerName {{ iiab_hostname }}
ServerAlias iiab-server.lan ServerAlias {{ iiab_hostname }}.{{ iiab_domain }}
<Directory "{{ doc_root }}"> <Directory "{{ doc_root }}">
Options Indexes FollowSymLinks Options Indexes FollowSymLinks
AllowOverride None AllowOverride None

View file

@ -79,15 +79,16 @@
insertafter='^#allowsftp' insertafter='^#allowsftp'
line=allowsftp line=allowsftp
- name: Add idmgr to service list - name: Add 'idmgr' variable values to {{ iiab_ini_file }}
ini_file: dest='{{ iiab_ini_file }}' ini_file:
section=idmgr path: "{{ iiab_ini_file }}"
option='{{ item.option }}' section: idmgr
value='{{ item.value }}' option: "{{ item.option }}"
value: "{{ item.value }}"
with_items: with_items:
- option: name - option: name
value: idmgr value: idmgr
- option: description - option: description
value: '"Idmgr is an automatic identity manager for XO clients which enables automatic backup"' value: '"IdMgr is an automatic identity manager for XO clients which enables automatic backup"'
- option: enabled - option: enabled
value: "{{ xo_services_enabled }}" value: "{{ xo_services_enabled }}"

View file

@ -1,9 +1,8 @@
- name: Install textmode remote access packages - name: "Install textmode remote access packages: screen, lynx"
package: package:
name: "{{ item }}" name:
state: present
with_items:
- screen - screen
- lynx - lynx
state: present
tags: tags:
- download - download

View file

@ -1,4 +1,4 @@
- name: Create user {{ iiab_admin_user }} for Admin Console; set password from hardcoded hash if newly creating account - name: Create user {{ iiab_admin_user }} for Admin Console; set password from iiab_admin_pwd_hash if newly creating account
user: user:
name: "{{ iiab_admin_user }}" name: "{{ iiab_admin_user }}"
password: "{{ iiab_admin_pwd_hash }}" password: "{{ iiab_admin_pwd_hash }}"

View file

@ -7,7 +7,7 @@
tags: tags:
- base - base
- name: Add 'iiab-admin' to list at {{ iiab_ini_file }} - name: Add 'iiab-admin' variable values to {{ iiab_ini_file }}
ini_file: ini_file:
dest: "{{ iiab_ini_file }}" dest: "{{ iiab_ini_file }}"
section: iiab-admin section: iiab-admin
@ -21,7 +21,7 @@
- option: iiab_admin_user - option: iiab_admin_user
value: "{{ iiab_admin_user }}" value: "{{ iiab_admin_user }}"
- name: Set up to issue warning if iiab-admin password is still default - name: Install /etc/profile.d/profile_ssh_warn.sh from template, to issue warnings if iiab-admin password is still default
template: template:
src: profile_ssh_warn.sh src: profile_ssh_warn.sh
dest: /etc/profile.d/ dest: /etc/profile.d/
@ -31,14 +31,14 @@
path: /home/pi/.config/lxsession path: /home/pi/.config/lxsession
register: lx register: lx
- name: Do the same if running on Raspbian - name: "Likewise for Raspbian, installing: /home/pi/.config/lxsession/LXDE-pi/lxde_ssh_warn.sh"
template: template:
src: lxde_ssh_warn.sh src: lxde_ssh_warn.sh
dest: /home/pi/.config/lxsession/LXDE-pi/ dest: /home/pi/.config/lxsession/LXDE-pi/
when: lx.stat.isdir is defined and lx.stat.isdir and is_rpi and is_debuntu when: lx.stat.isdir is defined and lx.stat.isdir and is_rpi and is_debuntu
- name: Put an autostart line to check for default password in LXDE (raspbian) - name: Put line in /home/pi/.config/lxsession/LXDE-pi/autostart to run the above (raspbian)
lineinfile: lineinfile:
path: /home/pi/.config/lxsession/LXDE-pi/autostart
line: "@/home/pi/.config/lxsession/LXDE-pi/lxde_ssh_warn.sh" line: "@/home/pi/.config/lxsession/LXDE-pi/lxde_ssh_warn.sh"
dest: /home/pi/.config/lxsession/LXDE-pi/autostart
when: lx.stat.isdir is defined and lx.stat.isdir and is_rpi and is_debuntu when: lx.stat.isdir is defined and lx.stat.isdir and is_rpi and is_debuntu

View file

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
function check_user_pwd() { check_user_pwd() {
# $meth (hashing method) is typically '6' which implies 5000 rounds # $meth (hashing method) is typically '6' which implies 5000 rounds
# of SHA-512 per /etc/login.defs -> /etc/pam.d/common-password # of SHA-512 per /etc/login.defs -> /etc/pam.d/common-password
meth=$(sudo grep "^$1:" /etc/shadow | cut -d: -f2 | cut -d$ -f2) meth=$(sudo grep "^$1:" /etc/shadow | cut -d: -f2 | cut -d$ -f2)

View file

@ -1,6 +1,8 @@
#!/bin/bash #!/bin/bash
function check_user_pwd() { # bash syntax "function check_user_pwd() {" was removed, as it prevented all
# lightdm/graphical logins (incl autologin) on Raspbian: #1252 -> PR #1253
check_user_pwd() {
# $meth (hashing method) is typically '6' which implies 5000 rounds # $meth (hashing method) is typically '6' which implies 5000 rounds
# of SHA-512 per /etc/login.defs -> /etc/pam.d/common-password # of SHA-512 per /etc/login.defs -> /etc/pam.d/common-password
meth=$(sudo grep "^$1:" /etc/shadow | cut -d: -f2 | cut -d$ -f2) meth=$(sudo grep "^$1:" /etc/shadow | cut -d: -f2 | cut -d$ -f2)

View file

@ -49,3 +49,10 @@ To return to using the systemd unit:
* systemctl start kalite-serve * systemctl start kalite-serve
*In late 2017, Internet-in-a-Box added a virtual environment (/usr/local/kalite/venv/) to keep KA Lite's Python package/dependency risks under control. As such the command* `/usr/bin/kalite <https://github.com/iiab/iiab/blob/master/roles/kalite/templates/kalite.sh.j2>`_ *is a wrapper to this virtualenv.* *In late 2017, Internet-in-a-Box added a virtual environment (/usr/local/kalite/venv/) to keep KA Lite's Python package/dependency risks under control. As such the command* `/usr/bin/kalite <https://github.com/iiab/iiab/blob/master/roles/kalite/templates/kalite.sh.j2>`_ *is a wrapper to this virtualenv.*
More Tips & Tricks
------------------
If you're online, please see "KA Lite Administration: What tips & tricks exist?" at: http://FAQ.IIAB.IO
If you're offline, Internet-in-a-Box's FAQ (Frequently Asked Questions) is here: http://box/info

View file

@ -50,6 +50,13 @@
# extra_args="--disable-pip-version-check" # extra_args="--disable-pip-version-check"
when: internet_available and not is_debuntu when: internet_available and not is_debuntu
# This effectively does nothing at all on Ubuntu & Raspbian, where libgeos-*
# pkgs are not installed FWIW. But it's included to safeguard us across all
# OS's, in case others OS's like Ubermix later appear. See #1382 for details.
# Removing pkgs libgeos-3.6.2 & libgeos-c1v5 fixed the situation on Ubermix!
- name: Remove libgeos-* pkgs, avoiding KA Lite Django failure on Ubermix
shell: apt -y remove "libgeos-*"
- name: Default is to have cronserve started with KA Lite - name: Default is to have cronserve started with KA Lite
set_fact: set_fact:
job_scheduler_stanza: "" job_scheduler_stanza: ""

View file

@ -12,7 +12,7 @@
kalite_db_name: "{{ kalite_root }}/database/data.sqlite" kalite_db_name: "{{ kalite_root }}/database/data.sqlite"
when: not is_F18 when: not is_F18
- name: See if KA Lite is already configured - name: Does KA Lite database {{ kalite_db_name }} exist? # See if KA Lite is already configured
stat: stat:
path: "{{ kalite_db_name }}" path: "{{ kalite_db_name }}"
register: kalite_installed register: kalite_installed
@ -36,9 +36,9 @@
- include_tasks: enable.yml - include_tasks: enable.yml
- name: Add 'kalite' to list of services at {{ iiab_ini_file }} - name: Add 'kalite' variable values to {{ iiab_ini_file }}
ini_file: ini_file:
dest: "{{ iiab_ini_file }}" path: "{{ iiab_ini_file }}"
section: kalite section: kalite
option: "{{ item.option }}" option: "{{ item.option }}"
value: "{{ item.value }}" value: "{{ item.value }}"
@ -51,7 +51,7 @@
value: "{{ kalite_root }}" value: "{{ kalite_root }}"
- option: port - option: port
value: "{{ kalite_server_port }}" value: "{{ kalite_server_port }}"
- option: enabled - option: kalite_enabled
value: "{{ kalite_enabled }}" value: "{{ kalite_enabled }}"
- option: cron_enabled - option: cron_enabled
value: "{{ kalite_cron_enabled }}" value: "{{ kalite_cron_enabled }}"

View file

@ -1,9 +1,9 @@
# Which kiwix-tools to download from http://download.iiab.io/packages/ # Which kiwix-tools to download from http://download.iiab.io/packages/
# As obtained from http://download.kiwix.org/release/kiwix-tools/ or http://download.kiwix.org/nightly/ # As obtained from http://download.kiwix.org/release/kiwix-tools/ or http://download.kiwix.org/nightly/
kiwix_version_armhf: "kiwix-tools_linux-armhf-0.6.1-1" kiwix_version_armhf: "kiwix-tools_linux-armhf-0.9.0"
kiwix_version_linux64: "kiwix-tools_linux-x86_64-0.6.1-1" kiwix_version_linux64: "kiwix-tools_linux-x86_64-0.9.0"
kiwix_version_i686: "kiwix-tools_linux-i586-0.6.1-1" kiwix_version_i686: "kiwix-tools_linux-i586-0.9.0"
# kiwix_src_file_i686: "kiwix-linux-i686.tar.bz2" # kiwix_src_file_i686: "kiwix-linux-i686.tar.bz2"
# v0.9 for i686 published May 2014 ("use it to test legacy ZIM content") # v0.9 for i686 published May 2014 ("use it to test legacy ZIM content")
# v0.10 for i686 published Oct 2016 ("experimental") REPLACED IN EARLY 2018, thx to Matthieu Gautier: # v0.10 for i686 published Oct 2016 ("experimental") REPLACED IN EARLY 2018, thx to Matthieu Gautier:

View file

@ -1,6 +1,6 @@
# 1. CREATE/VERIFY CRITICAL DIRECTORIES & FILES ARE IN PLACE # 1. CREATE/VERIFY CRITICAL DIRECTORIES & FILES ARE IN PLACE
- name: Create various directories for Kiwix ZIM files - name: Create directory {{ iiab_zim_path }} and subdirs {content, index} for Kiwix ZIM files
file: file:
path: "{{ item }}" path: "{{ item }}"
owner: root owner: root
@ -12,12 +12,12 @@
- "{{ iiab_zim_path }}/content" - "{{ iiab_zim_path }}/content"
- "{{ iiab_zim_path }}/index" - "{{ iiab_zim_path }}/index"
- name: Check for /library/zims/library.xml - name: Check for {{ kiwix_library_xml }} # /library/zims/library.xml
stat: stat:
path: "{{ kiwix_library_xml }}" path: "{{ kiwix_library_xml }}"
register: kiwix_xml register: kiwix_xml
- name: Place a stub /library/zims/library.xml if file does not exist - name: Install a stub /library/zims/library.xml if one doesn't exist
template: template:
src: "{{ item }}" src: "{{ item }}"
dest: "{{ kiwix_library_xml }}" dest: "{{ kiwix_library_xml }}"
@ -34,12 +34,12 @@
path: "{{ kiwix_path }}/bin/kiwix-serve" path: "{{ kiwix_path }}/bin/kiwix-serve"
register: kiwix_bin register: kiwix_bin
- name: Set kiwix_force_install if kiwix-serve not found - name: Set fact kiwix_force_install if kiwix-serve not found
set_fact: set_fact:
kiwix_force_install: True kiwix_force_install: True
when: not kiwix_bin.stat.exists when: not kiwix_bin.stat.exists
- name: Copy test.zim file if kiwix_force_install - name: Install {{ iiab_zim_path }}/content/test.zim if kiwix_force_install
copy: copy:
src: test.zim src: test.zim
dest: "{{ iiab_zim_path }}/content/test.zim" dest: "{{ iiab_zim_path }}/content/test.zim"
@ -49,7 +49,7 @@
force: no force: no
when: kiwix_force_install when: kiwix_force_install
- name: Create /opt/iiab/kiwix/bin directory - name: Create {{ kiwix_path }}/bin directory # /opt/iiab/kiwix/bin
file: file:
path: "{{ kiwix_path }}/bin" path: "{{ kiwix_path }}/bin"
owner: root owner: root
@ -59,7 +59,7 @@
# 2. INSTALL KIWIX-TOOLS EXECUTABLES IF kiwix_force_install # 2. INSTALL KIWIX-TOOLS EXECUTABLES IF kiwix_force_install
- name: Unarchive kiwix-tools .tar.gz to /tmp - name: Unarchive {{ kiwix_src_file }} to /tmp # e.g. kiwix-tools_linux-armhf-0.6.1-1.tar.gz
unarchive: unarchive:
src: "{{ downloads_dir }}/{{ kiwix_src_file }}" src: "{{ downloads_dir }}/{{ kiwix_src_file }}"
dest: /tmp dest: /tmp
@ -73,7 +73,7 @@
# 3. ENABLE MODS FOR APACHE PROXY IF DEBUNTU # 3. ENABLE MODS FOR APACHE PROXY IF DEBUNTU
- name: Enable the mods which permit Apache to proxy (debuntu) - name: Enable the 4 mods which permit Apache to proxy (debuntu)
apache2_module: apache2_module:
name: "{{ item }}" name: "{{ item }}"
with_items: with_items:
@ -85,7 +85,7 @@
# 4. CREATE/ENABLE/RESTART (OR DISABLE) KIWIX SERVICE & ITS CRON JOB # 4. CREATE/ENABLE/RESTART (OR DISABLE) KIWIX SERVICE & ITS CRON JOB
- name: Create 'kiwix-serve' service and related files - name: 'Install from templates: kiwix-serve.service, iiab-make-kiwix-lib, iiab-make-kiwix-lib.py, kiwix.conf'
template: template:
backup: no backup: no
src: "{{ item.src }}" src: "{{ item.src }}"
@ -101,14 +101,14 @@
# - { src: 'iiab-make-apache-config.py', dest: '/usr/bin/iiab-make-apache-config.py', mode: '0755'} # - { src: 'iiab-make-apache-config.py', dest: '/usr/bin/iiab-make-apache-config.py', mode: '0755'}
- { src: 'kiwix.conf.j2', dest: '/etc/{{ apache_config_dir }}/kiwix.conf', mode: '0644'} - { src: 'kiwix.conf.j2', dest: '/etc/{{ apache_config_dir }}/kiwix.conf', mode: '0644'}
- name: Enable Kiwix Proxy in Apache - is disabled by turning off kiwix service (debuntu) - name: Create softlink kiwix.conf from sites-enabled to sites-available - for Kiwix Proxy in Apache - is disabled by turning off service kiwix-serve (debuntu)
file: file:
src: /etc/apache2/sites-available/kiwix.conf src: /etc/apache2/sites-available/kiwix.conf
path: /etc/apache2/sites-enabled/kiwix.conf path: /etc/apache2/sites-enabled/kiwix.conf
state: link state: link
when: is_debuntu when: is_debuntu
- name: Enable 'kiwix-serve' service - name: Enable & Restart 'kiwix-serve' service
service: service:
name: kiwix-serve name: kiwix-serve
enabled: yes enabled: yes
@ -149,9 +149,9 @@
# 5. FINALIZE # 5. FINALIZE
- name: Add 'kiwix' to list of services at {{ iiab_ini_file }} - name: Add 'kiwix' variable values to {{ iiab_ini_file }}
ini_file: ini_file:
dest: "{{ iiab_ini_file }}" path: "{{ iiab_ini_file }}"
section: kiwix section: kiwix
option: "{{ item.option }}" option: "{{ item.option }}"
value: "{{ item.value }}" value: "{{ item.value }}"
@ -170,5 +170,5 @@
value: "{{ iiab_zim_path }}" value: "{{ iiab_zim_path }}"
- option: kiwix_library_xml - option: kiwix_library_xml
value: "{{ kiwix_library_xml }}" value: "{{ kiwix_library_xml }}"
- option: enabled - option: kiwix_enabled
value: "{{ kiwix_enabled }}" value: "{{ kiwix_enabled }}"

159
roles/kiwix/templates/iiab-make-kiwix-lib.py Normal file → Executable file
View file

@ -22,16 +22,18 @@ import shlex
import ConfigParser import ConfigParser
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
import argparse import argparse
import fnmatch
IIAB_PATH='/etc/iiab' IIAB_PATH='/etc/iiab'
if not IIAB_PATH in sys.path: if not IIAB_PATH in sys.path:
sys.path.append(IIAB_PATH) sys.path.append(IIAB_PATH)
from iiab_env import get_iiab_env from iiab_env import get_iiab_env
KIWIX_CAT = IIAB_PATH + '/kiwix_catalog.json'
# Config Files # Config Files
# iiab_ini_file should be in {{ iiab_env_file }} (/etc/iiab/iiab.env) ? # iiab_ini_file should be in {{ iiab_env_file }} (/etc/iiab/iiab.env) ?
iiab_ini_file = "{{ iiab_ini_file }}" # nominally /etc/iiab/iiab.ini #iiab_ini_file = "{{ iiab_ini_file }}" # nominally /etc/iiab/iiab.ini
# iiab_ini_file = "/etc/iiab/iiab.ini" # comment out after testing iiab_ini_file = "/etc/iiab/iiab.ini" # comment out after testing
IIAB_INI = get_iiab_env('IIAB_INI') # future IIAB_INI = get_iiab_env('IIAB_INI') # future
if IIAB_INI: if IIAB_INI:
@ -46,12 +48,16 @@ kiwix_manage = iiab_base_path + "/kiwix/bin/kiwix-manage"
doc_root = get_iiab_env('WWWROOT') doc_root = get_iiab_env('WWWROOT')
zim_version_idx_dir = doc_root + "/common/assets/" zim_version_idx_dir = doc_root + "/common/assets/"
zim_version_idx_file = "zim_version_idx.json" zim_version_idx_file = "zim_version_idx.json"
#zim_version_idx_file = "zim_version_idx_test.json"
menuDefs = doc_root + "/js-menu/menu-files/menu-defs/"
menuImages = doc_root + "/js-menu/menu-files/images/"
menuJsonPath = doc_root + "/home/menu.json"
old_zim_map = {"bad.zim" : "unparseable name"} old_zim_map = {"bad.zim" : "unparseable name"}
# Working variables # Working variables
# zim_files - list of zims and possible index from file system # zim_files - list of zims and possible index from file system
# path_to_array_map - list of zims in current library.xml with array index number (for delete) # path_to_id_map - list of zims in current library.xml with id (for delete)
zim_versions = {} # map of zim's generic name to version installed, e.g. wikipedia_es_all to wikipedia_es_all_2017-01 zim_versions = {} # map of zim's generic name to version installed, e.g. wikipedia_es_all to wikipedia_es_all_2017-01
def main(): def main():
@ -78,31 +84,25 @@ def main():
except OSError: except OSError:
pass pass
zims_installed = {} zims_installed = {}
path_to_array_map = {} path_to_id_map = {}
else: else:
zims_installed, path_to_array_map = read_library_xml(kiwix_library_xml) zims_installed, path_to_id_map = read_library_xml(kiwix_library_xml)
zim_files = get_zim_list(zim_path) zim_files = get_zim_list(zim_path)
# Remove zims not in file system from library.xml # Remove zims not in file system from library.xml
remove_list_str = "" remove_list_str = ""
for item in path_to_array_map: for item in path_to_id_map:
if item not in zim_files: if item not in zim_files:
remove_list_str += str(path_to_array_map[item]) + " " rem_libr_xml(path_to_id_map[item])
if remove_list_str:
rem_libr_xml(remove_list_str)
# Add zims from file system that are not in library.xml # Add zims from file system that are not in library.xml
for item in zim_files: for item in zim_files:
if item not in path_to_array_map: if item not in path_to_id_map:
add_libr_xml(kiwix_library_xml, zim_path, item, zim_files[item]) add_libr_xml(kiwix_library_xml, zim_path, item, zim_files[item])
# Write Version Map print("Writing zim_versions_idx")
if os.path.isdir(zim_version_idx_dir): write_zim_versions_idx()
with open(zim_version_idx_dir + zim_version_idx_file, 'w') as fp:
json.dump(zim_versions, fp)
else:
print zim_version_idx_dir + " not found."
sys.exit() sys.exit()
def get_zim_list(path): def get_zim_list(path):
@ -115,6 +115,7 @@ def get_zim_list(path):
for filename in flist: for filename in flist:
zimpos = filename.find(".zim") zimpos = filename.find(".zim")
if zimpos != -1: if zimpos != -1:
zim_info = {}
filename = filename[:zimpos] filename = filename[:zimpos]
zimname = "content/" + filename + ".zim" zimname = "content/" + filename + ".zim"
zimidx = "index/" + filename + ".zim.idx" zimidx = "index/" + filename + ".zim.idx"
@ -128,24 +129,25 @@ def get_zim_list(path):
wiki_name = old_zim_map[filename] wiki_name = old_zim_map[filename]
else: else:
ulpos = filename.rfind("_") ulpos = filename.rfind("_")
# but gutenberg don't - future maybe put in old_zim_map (en and fr, but instance dates may change) # but old gutenberg and some other names are not canonical
if "gutenberg_" in filename: if filename.rfind("-") < 0: # non-canonical name
ulpos = filename[:ulpos].rfind("_") ulpos = filename[:ulpos].rfind("_")
wiki_name = filename[:ulpos] wiki_name = filename[:ulpos]
zim_versions[wiki_name] = filename # if there are multiples, last should win zim_info['file_name'] = filename
zim_versions[wiki_name] = zim_info # if there are multiples, last should win
return files_processed return files_processed
def read_library_xml(lib_xml_file, kiwix_exclude_attr=[""]): # duplicated from iiab-cmdsrv def read_library_xml(lib_xml_file, kiwix_exclude_attr=[""]): # duplicated from iiab-cmdsrv
kiwix_exclude_attr.append("id") # don't include id kiwix_exclude_attr.append("id") # don't include id
kiwix_exclude_attr.append("favicon") # don't include large favicon kiwix_exclude_attr.append("favicon") # don't include large favicon
zims_installed = {} zims_installed = {}
path_to_array_map = {} path_to_id_map = {}
try: try:
tree = ET.parse(lib_xml_file) tree = ET.parse(lib_xml_file)
root = tree.getroot() root = tree.getroot()
xml_item_no = 0 xml_item_no = 0
for child in root: for child in root:
xml_item_no += 1 # hopefully this is the array number #xml_item_no += 1 # hopefully this is the array number
attributes = {} attributes = {}
if 'id' not in child.attrib: # is this necessary? implies there are records with no book id which would break index for removal if 'id' not in child.attrib: # is this necessary? implies there are records with no book id which would break index for removal
print "xml record missing Book Id" print "xml record missing Book Id"
@ -154,29 +156,32 @@ def read_library_xml(lib_xml_file, kiwix_exclude_attr=[""]): # duplicated from i
if attr not in kiwix_exclude_attr: if attr not in kiwix_exclude_attr:
attributes[attr] = child.attrib[attr] # copy if not id or in exclusion list attributes[attr] = child.attrib[attr] # copy if not id or in exclusion list
zims_installed[id] = attributes zims_installed[id] = attributes
path_to_array_map[child.attrib['path']] = xml_item_no path_to_id_map[child.attrib['path']] = id
except IOError: except IOError:
zims_installed = {} zims_installed = {}
return zims_installed, path_to_array_map return zims_installed, path_to_id_map
def rem_libr_xml(list_str): def rem_libr_xml(id):
command = kiwix_manage + " " + kiwix_library_xml + " remove " + list_str command = kiwix_manage + " " + kiwix_library_xml + " remove " + id
print command #print command
args = shlex.split(command) args = shlex.split(command)
try:
outp = subprocess.check_output(args) outp = subprocess.check_output(args)
except subprocess.CalledProcessError as e:
if e.returncode != 2: # skip bogus file open error in kiwix-manage
print outp
def add_libr_xml(kiwix_library_xml, zim_path, zimname, zimidx): def add_libr_xml(kiwix_library_xml, zim_path, zimname, zimidx):
command = kiwix_manage + " " + kiwix_library_xml + " add " + zim_path + "/" + zimname command = kiwix_manage + " " + kiwix_library_xml + " add " + zim_path + "/" + zimname
if zimidx: if zimidx:
command += " -i " + zim_path + "/" + zimidx command += " -i " + zim_path + "/" + zimidx
print command #print command
args = shlex.split(command) args = shlex.split(command)
try: try:
outp = subprocess.check_output(args) outp = subprocess.check_output(args)
except: #skip things that don't work except: #skip things that don't work
print 'skipping ' + zimname #print 'skipping ' + zimname
pass pass
def init(): def init():
@ -201,8 +206,102 @@ def parse_args():
parser.add_argument("-v", "--verbose", help="Print messages.", action="store_true") parser.add_argument("-v", "--verbose", help="Print messages.", action="store_true")
return parser.parse_args() return parser.parse_args()
# Now start the application def write_zim_versions_idx():
global zim_versions
zims_installed,path_to_id_map = read_library_xml(kiwix_library_xml)
for perma_ref in zim_versions:
zim_versions[perma_ref]['menu_item'] = find_menuitem_from_zimname(perma_ref)
articlecount,mediacount,size,tags,lang,date = \
get_substitution_data(perma_ref, zims_installed, path_to_id_map)
zim_versions[perma_ref]['article_count'] = articlecount
zim_versions[perma_ref]['media_count'] = mediacount
size = human_readable(size)
zim_versions[perma_ref]['size'] = size
zim_versions[perma_ref]['tags'] = tags
zim_versions[perma_ref]['language'] = lang
zim_versions[perma_ref]['zim_date'] = date
# Write Version Map
if os.path.isdir(zim_version_idx_dir):
with open(zim_version_idx_dir + zim_version_idx_file, 'w') as fp:
fp.write(json.dumps(zim_versions,indent=2 ))
fp.close()
else:
print zim_version_idx_dir + " not found."
def get_substitution_data(perma_ref,zims_installed, path_to_id_map):
#reconstruct the path in the id map
path = 'content/' + zim_versions[perma_ref]['file_name'] + '.zim'
id = path_to_id_map[path]
item = zims_installed[id]
if len(item) != 0 or perma_ref == 'test':
mediacount = item.get('mediaCount','')
articlecount = item.get('articleCount','')
size = item.get('size','')
tags = item.get('tags','')
lang = item.get('language','')
if len(lang) > 2:
lang = lang[:2]
date = item.get('date','')
return (articlecount,mediacount,size,tags,lang,date)
return ('0','0','0','0','0','0')
def get_menu_def_zimnames(intended_use='zim'):
menu_def_dict = {}
os.chdir(menuDefs)
for filename in os.listdir('.'):
if fnmatch.fnmatch(filename, '*.json'):
try:
with open(filename,'r') as json_file:
readstr = json_file.read()
data = json.loads(readstr)
except:
print("failed to parse %s"%filename)
print(readstr)
if data.get('intended_use','') != 'zim':
continue
zimname = data.get('zim_name','')
if zimname != '':
menu_def_dict[data['zim_name']] = menuDefs + filename
return menu_def_dict
def find_menuitem_from_zimname(zimname):
defs = get_menu_def_zimnames()
defs_filename = defs.get(zimname,'')
if defs_filename != '':
#print("reading menu-def:%s"%defs_filename)
with open(defs_filename,'r') as json_file:
readstr = json_file.read()
data = json.loads(readstr)
return data.get('menu_item_name','')
return ''
def get_kiwix_catalog_item(perma_ref):
# Read the kiwix catalog
with open(KIWIX_CAT, 'r') as kiwix_cat:
json_data = kiwix_cat.read()
download = json.loads(json_data)
zims = download['zims']
for uuid in zims.keys():
#print("%s %s"%(zims[uuid]['perma_ref'],perma_ref,))
if zims[uuid]['perma_ref'] == perma_ref:
return zims[uuid]
return {}
def human_readable(num):
# return 3 significant digits and unit specifier
num = float(num)
units = [ '','K','M','G']
for i in range(4):
if num<10.0:
return "%.2f%s"%(num,units[i])
if num<100.0:
return "%.1f%s"%(num,units[i])
if num < 1000.0:
return "%.0f%s"%(num,units[i])
num /= 1000.0
# Now start the application
if __name__ == "__main__": if __name__ == "__main__":
# Run the main routine # Run the main routine

View file

@ -8,4 +8,9 @@ RedirectMatch ^{{ kiwix_alias_url }}$ {{ kiwix_url }}
# 2018-08-31: SUCCEEDS in enabling http://box/kiwix/ & http://box/kiwix/zim & http://box/kiwix/zim/ # 2018-08-31: SUCCEEDS in enabling http://box/kiwix/ & http://box/kiwix/zim & http://box/kiwix/zim/
#ProxyPreserveHost On #ProxyPreserveHost On
ProxyPass {{ kiwix_url }} http://127.0.0.1:{{ kiwix_port}}{{ kiwix_url }} ProxyPass {{ kiwix_url }} http://127.0.0.1:{{ kiwix_port}}{{ kiwix_url }}
# CLARIF: ProxyPassReverse rewrites internal links, that come back from Apache
# proxy. Whereas e.g. calibre-web.conf (and others) use this, kiwix.conf does
# not, as kiwix itself prefixes URLs thanks to --urlRootLocation=/kiwix/ in
# kiwix's systemd file arising from roles/kiwix/templates/kiwix-serve.service.j2
#ProxyPassReverse {{ kiwix_url }} http://127.0.0.1:{{ kiwix_port}}{{ kiwix_url }} #ProxyPassReverse {{ kiwix_url }} http://127.0.0.1:{{ kiwix_port}}{{ kiwix_url }}

View file

@ -9,7 +9,7 @@ kolibri_enabled: False
kolibri_home: "{{ content_base }}/kolibri" kolibri_home: "{{ content_base }}/kolibri"
kolibri_http_port: 8009 kolibri_http_port: 8009
kolibri_url: /kolibri/ kolibri_url: /kolibri
kolibri_venv_path: /usr/local/kolibri kolibri_venv_path: /usr/local/kolibri
# 2018-07-16: IIAB recommends /usr/bin but @arky says this isn't yet possible, due to pip # 2018-07-16: IIAB recommends /usr/bin but @arky says this isn't yet possible, due to pip
kolibri_exec_path: "{{ kolibri_venv_path }}/bin/kolibri" kolibri_exec_path: "{{ kolibri_venv_path }}/bin/kolibri"

View file

@ -9,7 +9,7 @@
system: yes system: yes
create_home: no create_home: no
- name: Create /library/kolibri to store data and configuration files - name: Create {{ kolibri_home }} (for data) and {{ kolibri_venv_path }} (for program/config)
file: file:
path: "{{ item }}" path: "{{ item }}"
owner: "{{ kolibri_user }}" owner: "{{ kolibri_user }}"
@ -20,7 +20,7 @@
- "{{ kolibri_home }}" - "{{ kolibri_home }}"
- "{{ kolibri_venv_path }}" - "{{ kolibri_venv_path }}"
- name: Install kolibri using pip on all OS's - name: Install latest kolibri using pip
pip: pip:
name: kolibri name: kolibri
virtualenv: "{{ kolibri_venv_path }}" virtualenv: "{{ kolibri_venv_path }}"
@ -29,17 +29,17 @@
extra_args: --no-cache-dir extra_args: --no-cache-dir
when: internet_available when: internet_available
- name: Run kolibri migrations - name: Run Kolibri migrations
shell: export KOLIBRI_HOME="{{ kolibri_home }}" && "{{ kolibri_exec_path }}" manage migrate shell: export KOLIBRI_HOME="{{ kolibri_home }}" && "{{ kolibri_exec_path }}" manage migrate
ignore_errors: yes ignore_errors: yes
when: kolibri_provision when: kolibri_provision
- name: Set kolibri default language - name: Set Kolibri default language
shell: export KOLIBRI_HOME="{{ kolibri_home }}" && "{{ kolibri_exec_path }}" language setdefault "{{ kolibri_language }}" shell: export KOLIBRI_HOME="{{ kolibri_home }}" && "{{ kolibri_exec_path }}" language setdefault "{{ kolibri_language }}"
ignore_errors: yes ignore_errors: yes
when: kolibri_provision when: kolibri_provision
- name: Create kolibri default facility name, admin account and language - name: Create Kolibri default facility name, admin account and language
shell: > shell: >
export KOLIBRI_HOME="{{ kolibri_home }}" && export KOLIBRI_HOME="{{ kolibri_home }}" &&
"{{ kolibri_exec_path }}" manage provisiondevice --facility "{{ kolibri_facility }}" "{{ kolibri_exec_path }}" manage provisiondevice --facility "{{ kolibri_facility }}"
@ -48,7 +48,7 @@
ignore_errors: yes ignore_errors: yes
when: kolibri_provision when: kolibri_provision
- name: Change /library/kolibri directory permissions - name: chown -R {{ kolibri_user }}:{{ apache_user }} {{ kolibri_home }}
file: file:
path: "{{ kolibri_home }}" path: "{{ kolibri_home }}"
owner: "{{ kolibri_user }}" owner: "{{ kolibri_user }}"
@ -64,6 +64,7 @@
group: root group: root
with_items: with_items:
- { src: 'kolibri.service.j2', dest: '/etc/systemd/system/kolibri.service', mode: '0644' } - { src: 'kolibri.service.j2', dest: '/etc/systemd/system/kolibri.service', mode: '0644' }
- { src: 'kolibri.conf.j2', dest: '/etc/apache2/sites-available/kolibri.conf', mode: '0644' }
- name: Enable & (Re)Start kolibri service - name: Enable & (Re)Start kolibri service
systemd: systemd:
@ -73,6 +74,11 @@
daemon_reload: yes daemon_reload: yes
when: kolibri_enabled when: kolibri_enabled
# Default: http://box/kolibri
- name: Enable http://box{{ kolibri_url }} with Apache
command: a2ensite kolibri.conf
when: kolibri_enabled
- name: Disable kolibri service - name: Disable kolibri service
systemd: systemd:
name: kolibri name: kolibri
@ -80,9 +86,19 @@
state: stopped state: stopped
when: not kolibri_enabled when: not kolibri_enabled
- name: Add 'kolibri' to list of services at {{ iiab_ini_file }} - name: Disable http://box{{ kolibri_url }} with Apache
command: a2dissite kolibri.conf
when: not kolibri_enabled
# {{ apache_service }} is almost always apache2
- name: Restart Apache service ({{ apache_service }})
systemd:
name: "{{ apache_service }}"
state: restarted
- name: Add 'kolibri' variable values to {{ iiab_ini_file }}
ini_file: ini_file:
dest: "{{ iiab_ini_file }}" path: "{{ iiab_ini_file }}"
section: kolibri section: kolibri
option: "{{ item.option }}" option: "{{ item.option }}"
value: "{{ item.value }}" value: "{{ item.value }}"
@ -97,5 +113,5 @@
value: "{{ kolibri_exec_path }}" value: "{{ kolibri_exec_path }}"
- option: kolibri_port - option: kolibri_port
value: "{{ kolibri_http_port }}" value: "{{ kolibri_http_port }}"
- option: enabled - option: kolibri_enabled
value: "{{ kolibri_enabled }}" value: "{{ kolibri_enabled }}"

View file

@ -0,0 +1,3 @@
ProxyPreserveHost On
ProxyPass {{ kolibri_url }} http://localhost:{{ kolibri_http_port }}{{ kolibri_url }}
ProxyPassReverse {{ kolibri_url }} http://localhost:{{ kolibri_http_port }}{{ kolibri_url }}

Some files were not shown because too many files have changed in this diff Show more