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)
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
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.
# Also used by https://github.com/iiab/iiab-admin-console
[defaults]
squash_actions = apk, apt, dnf, homebrew, openbsd_pkg, pacman, pkgng, yum, zypper, package
#[defaults]
# 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=${OS//\"/}
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
@ -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 "(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
fi
@ -74,7 +63,7 @@ fi
# 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/
# 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
# 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 }}
iiab_base_ver: 6.7
iiab_base_ver: 7.0
iiab_revision: 0
# These entries should never be changed in this file.

View file

@ -1,5 +1,2 @@
- name: Create the directory structure for IIAB
include_tasks: fl.yml
- name: Write iiab_ini.yml for the first time
- name: Create {{ iiab_ini_file }}
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:
path: /etc/cloud/cloud.cfg
register: U18_server
- name: Edit cloud.cfg yaml
- name: 'Put "preserve_hostname: true" in /etc/cloud/cloud.cfg (ubuntu-18 server)'
lineinfile:
dest: /etc/cloud/cloud.cfg
path: /etc/cloud/cloud.cfg
regexp: '^preserve_hostname*'
line: 'preserve_hostname: true'
state: present
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 }}"
when: is_debuntu
- name: Configure /etc/sysconfig/network (redhat)
- name: Install /etc/sysconfig/network from template (redhat)
template:
src: roles/network/templates/network/sysconfig.network.j2
dest: /etc/sysconfig/network
@ -24,9 +24,9 @@
mode: 0644
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:
dest: /etc/hosts
path: /etc/hosts
regexp: '^127\.0\.0\.1'
line: '127.0.0.1 localhost.localdomain localhost box {{ iiab_hostname }}'
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)
- name: Create {{ iiab_ini_file }}
file:
dest: "{{ iiab_ini_file }}"
path: "{{ iiab_ini_file }}"
state: touch
- name: Add location section to config file
- name: Add 'location' variable values to {{ iiab_ini_file }}
ini_file:
dest: "{{ iiab_ini_file }}"
path: "{{ iiab_ini_file }}"
section: location
option: "{{ item.option }}"
value: "{{ item.value }}"
@ -18,7 +18,7 @@
- name: Add 'version' variable values to {{ iiab_ini_file }}
ini_file:
dest: "{{ iiab_ini_file }}"
path: "{{ iiab_ini_file }}"
section: version
option: "{{ item.option }}"
value: "{{ item.value }}"

View file

@ -5,14 +5,14 @@
path: "{{ iiab_env_file }}"
register: NewInstall
- name: Setting first run flag
- name: Set first_run flag
set_fact:
first_run: True
when: not NewInstall.stat.exists
# 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.
- 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
when: first_run
@ -36,30 +36,30 @@
# nobridge: True
when: ansible_local.local_facts.os == "raspbian"
- name: Set exFAT enabled for XO laptops
- name: Set exFAT_enabled if xo_model != "none"
set_fact:
exFAT_enabled: True
when: xo_model != "none"
# Discover: do we have a gateway?
# 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:
discovered_wan_iface: "{{ ansible_default_ipv4.alias }}"
iiab_wan_iface: "{{ discovered_wan_iface }}"
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
when: discovered_wan_iface != "none"
register: gw_active_test
- name: Recording gateway response
- name: If so, set gw_active
set_fact:
gw_active: True
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:
url: "{{ iiab_download_url }}/heart-beat.txt"
dest: /tmp/heart-beat.txt
@ -70,12 +70,12 @@
# poll: 2
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:
internet_available: True
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:
path: /tmp/heart-beat.txt
state: absent
@ -84,17 +84,17 @@
- name: If the TZ is not set in env, set it to UTC
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:
gui_port: 80
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:
gui_port: 443
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:
mysql_install: True
mysql_enabled: True
@ -102,19 +102,21 @@
# 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
# Late 2017: Had commented out MongoDB on a trial basis, for a more basic/lightweight Sugarizer, per https://github.com/iiab/iiab/pull/427
- name: Turn on vars for MongoDB if Sugarizer enabled
set_fact:
mongodb_install: True
mongodb_enabled: True
when: sugarizer_enabled
# MongoDB is auto-included by Sugarizer as of Feb 2019, thanks to: roles/sugarizer/meta/main.yml
#
## Late 2017: Had commented out MongoDB on a trial basis, for a more basic/lightweight Sugarizer, per https://github.com/iiab/iiab/pull/427
#- name: Turn on both vars for MongoDB if sugarizer_enabled
# set_fact:
# mongodb_install: True
# mongodb_enabled: True
# when: sugarizer_enabled
# 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:
postgresql_install: 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
# set_fact:
@ -122,12 +124,12 @@
# docker_enabled: True
# when: schooltool_enabled or schooltool_install
- name: Set python_path (redhat)
- name: "Set python_path: /lib/python2.7/site-packages/ (redhat)"
set_fact:
python_path: /lib/python2.7/site-packages/
when: is_redhat
- name: Set python_path (debuntu)
- name: "Set python_path: /usr/local/lib/python2.7/dist-packages/ (debuntu)"
set_fact:
python_path: /usr/local/lib/python2.7/dist-packages/
when: is_debuntu
@ -135,28 +137,31 @@
# 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'.
- name: Set mysql_service to mariadb by default
set_fact:
mysql_service: mariadb
# BETTER TO USE /opt/iiab/iiab/vars/<OS>.yml
#- name: "Set mysql_service: mariadb by default"
# set_fact:
# mysql_service: mariadb
- name: Set mysql_service to mysqld etc (Fedora 18)
- name: "Set mysql_service: mysqld etc (Fedora 18)"
set_fact:
mysql_service: mysqld
# BETTER TO USE /opt/iiab/iiab/vars/<OS>.yml
#mysql_service: mysqld
no_NM_reload: True
is_F18: True
when: (ansible_distribution_release == "based on Fedora 18" or ansible_distribution_version == "18") and ansible_distribution == "Fedora"
- name: Set mysql_service to mysql (debuntu)
set_fact:
mysql_service: mysql
when: is_debuntu
# BETTER TO USE /opt/iiab/iiab/vars/<OS>.yml
#- name: "Set mysql_service: mysql (debuntu)"
# set_fact:
# mysql_service: mysql
# when: is_debuntu
- name: Set FQDN
- name: "Set iiab_fqdn: {{ iiab_hostname }}.{{ iiab_domain }}"
set_fact:
iiab_fqdn: "{{ iiab_hostname }}.{{ iiab_domain }}"
FQDN_changed: False
- name: FQDN changed
- name: Set FQDN_changed when iiab_fqdn != ansible_fqdn ({{ ansible_fqdn }})
set_fact:
FQDN_changed: True
when: iiab_fqdn != ansible_fqdn
@ -206,6 +211,10 @@
value: "{{ first_run }}"
- option: local_tz
value: "{{ local_tz }}"
- option: no_NM_reload
value: "{{ no_NM_reload }}"
- option: is_F18
value: "{{ is_F18 }}"
- option: 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 ============================================
command: echo
- name: Install uuidgen program (debuntu)
- name: Install uuid-runtime package (debuntu)
package:
name: uuid-runtime
name:
- uuid-runtime
- sudo
state: present
when: is_debuntu
- name: Test for /etc/iiab/uuid file
- name: Does /etc/iiab/uuid file exist?
stat:
path: /etc/iiab/uuid
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
shell: uuidgen
register: uuid_response
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
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
register: stored_uuid
- name: Get the value into a variable
- name: Place the uuid from register into variable/fact "uuid"
set_fact:
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
include_role:
name: sshd
@ -56,21 +81,19 @@
tags: openvpn
# 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:
name: "{{ item }}"
name: chrony
state: present
with_items:
- chrony
tags:
- download
#TODO: Use regexp filter instead of hard-code ip
- name: Update chrony config file
- name: Install /etc/chrony.conf from template
template:
backup: no
dest: /etc/chrony.conf
src: chrony.conf.j2
dest: /etc/chrony.conf
backup: no
- name: Disable AppArmor -- override OS default (ubuntu)
service:
@ -95,12 +118,12 @@
- include_tasks: raspberry_pi.yml
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}'"
register: usb_NUC6
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:
url: "{{ iiab_download_url }}/iwlwifi-8000C-13.ucode"
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:
src: 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"
# 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:
dest: /boot/config.txt
path: /boot/config.txt
line: "dtoverlay=i2c-rtc,{{ rtc_id }}=on"
state: present
register: rpiconfig
when: rtc_id != "none"
register: rpiconfig # HMMM REGISTER "rpiconfig" IS *COMPLETELY UNUSED* AS OF 2018-11-02
when: rtc_id is defined and rtc_id != "none"
- name: Add a udev rule to transfer hwclock to system clock at dev creation
template:
src: 92-rtc-i2c.rules
dest: /etc/udev/rules.d/92-rtc-i2c.rules
owner: root
group: root
mode: 0644
when: rtc_id != "none"
#- 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:
# src: 92-rtc-i2c.rules
# dest: /etc/udev/rules.d/92-rtc-i2c.rules
# owner: root
# group: root
# mode: 0644
# when: rtc_id != "none"
- name: Pre-install packages
- name: Install latest ntp package
package:
name: "{{ item }}"
name: ntp
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:
path: /etc/dphys-swapfile
regexp: "^CONF_SWAPSIZE"
line: CONF_SWAPSIZE=500
dest: /etc/dphys-swapfile
when: is_debuntu
- name: Restart the swap service (debuntu)
command: /etc/init.d/dphys-swapfile restart
- name: Restart swap service "dphys-swapfile" (debuntu)
#command: /etc/init.d/dphys-swapfile restart
service: # A rare/legacy service that is NOT systemd
name: dphys-swapfile
state: restarted
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:
src: "{{ item.src }}"
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-root-resize.service', dest: '/etc/systemd/system/iiab-rpi-root-resize.service', mode: '0644'}
- name: Enable rootfs resizing service
service:
- name: Enable RPi rootfs resizing (systemd service iiab-rpi-root-resize.service)
systemd:
name: iiab-rpi-root-resize
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:
path: "{{ item }}"
owner: root
@ -6,7 +8,7 @@
mode: 0755
state: directory
with_items:
- /etc/iiab
- /etc/sysconfig/olpc-scripts/setup.d/installed/
- "{{ yum_packages_dir }}"
- "{{ pip_packages_dir }}"
- "{{ downloads_dir }}"
@ -25,10 +27,8 @@
- "{{ doc_root }}/common/images"
- "{{ doc_root }}/common/assets"
- "{{ 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:
src: "{{ doc_root }}/common/fonts"
path: "{{ doc_root }}/common/webfonts"

View file

@ -3,20 +3,20 @@
path: /usr/libexec/iiab-startup.sh
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:
src: iiab-startup.sh
dest: /usr/libexec/
mode: 0755
when: not startup_script.stat.exists
- name: Copy iiab-startup.service to {{ systemd_location }}
- name: Install {{ systemd_location }}/iiab-startup.service from template
template:
src: iiab-startup.service
dest: "{{ systemd_location }}"
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 restart iiab-startup.service
# shell: systemctl enable iiab-startup.service

View file

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

View file

@ -3,6 +3,9 @@
- name: ...IS BEGINNING ==========================================
command: echo
- name: Create IIAB directory structure ("file layout")
include_tasks: fl.yml
- include_tasks: centos.yml
when: ansible_distribution == "CentOS"
@ -72,7 +75,7 @@
value: 1
state: present
- name: Install custom profile file
- name: Install custom /etc/profile.d/zzz_iiab.sh from template
template:
dest: /etc/profile.d/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:
name: "{{ item }}"
name:
- avahi
- 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
with_items:
- yum-utils
- createrepo
- wpa_supplicant
- linux-firmware
- syslog
- xml-common
- nss-mdns
- avahi
- avahi-tools
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:
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
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)
# 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)
- name: "Install 7 deb/apt packages: avahi-daemon, avahi-discover, exfat-fuse, exfat-utils, inetutils-syslogd, libnss-mdns, wpasupplicant (debuntu)"
package:
name: "{{ item }}"
name:
- avahi-daemon
- avahi-discover
- exfat-fuse
- exfat-utils
- inetutils-syslogd
- libnss-mdns
- wpasupplicant
state: present
with_items:
- inetutils-syslogd
- wpasupplicant
- libnss-mdns
- avahi-daemon
- avahi-discover
- exfat-fuse
- exfat-utils
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:
name: "{{ item }}"
name:
- acpid
- bridge-utils
- bzip2
- 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
- gawk
- hostapd
- htop
- i2c-tools
- logrotate
#- lynx # already installed by 1-prep's roles/iiab-admin/tasks/access.yml
- 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
- unzip
- usbmount
- usbutils
- wget
state: present
with_items:
- acpid
- mlocate
- rsync
- htop
#- 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
- usbmount
- net-tools
- openssh-server
- sudo
- logrotate
- make
- tar
- unzip
- bzip2
- i2c-tools
- bridge-utils
- netmask
- usbutils
- hostapd
- 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
- name: "Install 4 common Python packages: python-passlib, python-pip, python-setuptools, python-virtualenv"
package:
name: "{{ item }}"
name:
- python-passlib
- python-pip
- python-setuptools
- python-virtualenv
state: present
with_items:
- python-pip
- python-setuptools
- python-virtualenv
# 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
tags: base, mysql
- name: Restart httpd
service:
- name: Restart Apache systemd service ({{ apache_service }})
systemd:
name: "{{ apache_service }}"
state: restarted
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 =====================
lineinfile:
dest: "{{ iiab_env_file }}"

View file

@ -3,26 +3,34 @@
- name: ...IS BEGINNING ==================================
command: echo
- name: Installing dnsmasq
- name: Install dnsmasq
include_tasks: roles/network/tasks/dnsmasq.yml
when: dnsmasq_install
tags: base, domain, dnsmasq, network
- name: Installing named
- name: Install named / BIND
include_tasks: roles/network/tasks/named.yml
when: named_install
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
include_tasks: roles/network/tasks/dhcpd.yml
when: dhcpd_install
tags: base, dhcpd, network, domain
- name: Installing Squid
- name: Install Squid (and DansGuardian if dansguardian_install)
include_tasks: roles/network/tasks/squid.yml
when: squid_install
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
# include_role:
# name: network
@ -42,10 +50,11 @@
when: postgresql_install
tags: postgresql, pathagar, moodle
# UNMAINTAINED
- name: AUTHSERVER
include_role:
name: authserver
when: authserver_install
when: authserver_install is defined and authserver_install
tags: olpc, authserver
- name: CUPS
@ -66,13 +75,7 @@
when: usb_lib_install
tags: usb-lib
# MANDATORY SO PERHAPS THIS BELONGS IN 3-BASE-SERVER ?
- 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)
- 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)
command: /usr/bin/iiab-refresh-wiki-docs
when: not nodocs

View file

@ -27,6 +27,24 @@
when: ejabberd_install
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
include_role:
name: nextcloud
@ -39,6 +57,12 @@
# when: owncloud_install
# tags: owncloud
- name: PBX
include_role:
name: pbx
when: pbx_install
tags: pbx
- name: WORDPRESS
include_role:
name: wordpress

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,21 +1,19 @@
- name: Install AWStats package
- name: 'Install 3 packages: awstats, openssl, pwauth'
package:
name: "{{ item }}"
name:
- awstats
- pwauth
- openssl
state: present
with_items:
- awstats
- pwauth
- openssl
tags:
- download
- name: Install AWStats package (debuntu)
- name: 'Install 2 packages: apache2-utils, libapache2-mod-authnz-external (debuntu)'
package:
name: "{{ item }}"
name:
- libapache2-mod-authnz-external
- apache2-utils
state: present
with_items:
- libapache2-mod-authnz-external
- apache2-utils
when: is_debuntu
tags:
- download
@ -24,7 +22,7 @@
command: a2enmod cgi
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:
path: "{{ item }}"
mode: 0750
@ -37,7 +35,7 @@
- "{{ awstats_data_dir }}"
- "{{ apache_log_dir }}"
- name: Install the Apache config for AWStats (debuntu)
- name: Install Apache's awstats.conf from template (debuntu)
template:
src: apache.conf
dest: "/etc/{{ apache_config_dir }}/awstats.conf"
@ -46,7 +44,7 @@
mode: 0644
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:
src: apache-awstats.conf
dest: "/etc/{{ apache_config_dir }}/awstats.conf"
@ -55,35 +53,41 @@
mode: 0644
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:
src: logrotate.d.apache2
dest: /etc/logrotate.d/apache2
when: is_debuntu
- name: See if AWStats package installed a config file
- name: Check if package installed /etc/awstats/awstats.conf
stat:
path: /etc/awstats/awstats.conf
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
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:
src: /etc/apache2/sites-available/awstats.conf
path: /etc/apache2/sites-enabled/awstats.conf
state: link
when: awstats_enabled and is_debuntu
- name: Disable AWStats (debuntu)
- name: Remove symlink from sites-enabled, to disable AWStats (debuntu)
file:
path: /etc/apache2/sites-enabled/awstats.conf
state: absent
when: not awstats_enabled and is_debuntu
- name: Restart Apache service ({{ apache_service }})
systemd:
name: "{{ apache_service }}"
state: restarted
- name: Install the AWStats config
- name: Install /etc/awstats/awstats.schoolserver.conf
template:
src: awstats.schoolserver.conf.j2
dest: /etc/awstats/awstats.schoolserver.conf
@ -92,10 +96,10 @@
mode: 0644
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:
src: /etc/awstats/awstats.schoolserver.conf
dest: /etc/awstats/awstats.conf
path: /etc/awstats/awstats.conf
state: link
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
- name: Add 'awstats' to list of services at {{ iiab_ini_file }}
- name: Add 'awstats' variable values to {{ iiab_ini_file }}
ini_file:
dest: "{{ iiab_ini_file }}"
path: "{{ iiab_ini_file }}"
section: awstats
option: "{{ item.option }}"
value: "{{ item.value }}"

View file

@ -74,6 +74,8 @@ See also::
/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
------------------

View file

@ -5,7 +5,7 @@
calibreweb_install: False
calibreweb_enabled: False
calibreweb_port: 8083
calibreweb_port: 8083 # PORT VARIABLE HAS NO EFFECT (as of January 2019)
calibreweb_url: /books
calibreweb_venv_path: /usr/local/calibre-web
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:
path: "{{ item }}"
owner: "{{ calibreweb_user }}"
@ -11,7 +11,7 @@
- "{{ calibreweb_config }}"
## 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:
repo: https://github.com/janeczku/calibre-web.git
dest: "{{ calibreweb_venv_path }}"
@ -30,29 +30,29 @@
# ignore_errors: True
##
# 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:
requirements: "{{ calibreweb_venv_path }}/requirements.txt"
virtualenv: "{{ calibreweb_venv_path }}"
virtualenv_site_packages: no
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:
state: link
src: "{{ calibreweb_venv_path }}/lib/python2.7/site-packages"
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:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "{{ item.mode }}"
owner: "{{ calibreweb_user }}"
group: "{{ apache_user }}"
owner: root
group: root
mode: 0644
with_items:
- { src: 'calibre-web.service.j2', dest: '/etc/systemd/system/calibre-web.service', mode: '0644' }
- { src: 'calibre-web.conf.j2', dest: '/etc/apache2/sites-available/calibre-web.conf', 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' }
- name: Does /library/calibre-web/metadata.db exist?
stat:
@ -73,7 +73,7 @@
when: not metadatadb.stat.exists
#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:
src: roles/calibre-web/files/app.db
dest: "{{ calibreweb_config }}"
@ -84,7 +84,7 @@
when: not metadatadb.stat.exists
#when: calibreweb_provision
- name: Enable and restart 'calibre-web' service
- name: Enable & Restart 'calibre-web' systemd service
systemd:
name: calibre-web
daemon_reload: yes
@ -101,7 +101,7 @@
# command: apachectl -k graceful
# when: calibreweb_enabled
- name: Disable 'calibre-web' service
- name: Disable 'calibre-web' systemd service
systemd:
name: calibre-web
daemon_reload: yes
@ -117,14 +117,14 @@
# command: apachectl -k graceful
# when: not calibreweb_enabled
- name: Restart Apache
- name: Restart Apache systemd service ({{ apache_service }})
systemd:
name: "{{ apache_service }}" # httpd or apache2
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:
dest: "{{ iiab_ini_file }}"
path: "{{ iiab_ini_file }}"
section: calibre-web
option: "{{ item.option }}"
value: "{{ item.value }}"

View file

@ -11,7 +11,9 @@ RequestHeader set X-SCHEME http
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 }}/
# </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
# 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_bin_deb_pin_version: "{{ calibre_deb_pin_version }}" # for calibre-bin_3.31.0+dfsg-1+b1_armhf.deb (24M, 2018-09-07)
#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).
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.33.1+dfsg-1_armhf.deb (706K, 2018-10-23)
# 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
# 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

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
#- name: Start by installing OS's Calibre package
# package:
# name: "{{ item }}"
# state: latest
# with_items:
# - calibre
# - calibre-bin
# when: internet_available
# If you want the latest Calibre, run the appropriate script below, standalone.
# HOWEVER: it's strongly suggested you wait for apt (blessed by your OS!) to
# avoid ongoing dependency problems, as Calibre frequently demands the very
# latest/unstable dependencies.
# April/May 2018: Raspbian .deb's for the latest Calibre now appear
# (http://raspbian.raspberrypi.org/raspbian/pool/main/c/calibre/)
# within about 10 days of Calibre's quasi-monthly releases
# (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!)
# FYI Raspbian .deb's for the latest Calibre can be downloaded from either:
# http://raspbian.raspberrypi.org/raspbian/pool/main/c/calibre/
# http://archive.raspbian.org/raspbian/pool/main/c/calibre/
# ...within about 10 days after Calibre's quasi-monthly releases at:
# https://calibre-ebook.com/whats-new
#- 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
#- 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
#- 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 # WORKS for Calibre 3.28 on 2018-07-26 (PR #971). Likewise for Calibre 3.26.x
# 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: Upgrade to latest Calibre using .deb's from testing (rpi)
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.
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
# 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
- 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)
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
- name: Check if /usr/bin/calibre exists
- name: Does /usr/bin/calibre exist?
stat:
path: "/usr/bin/calibre"
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:
name: "{{ item }}"
name:
- calibre
- calibre-bin
state: latest
with_items:
- calibre
- calibre-bin
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)
@ -40,7 +39,7 @@
group: root
mode: "{{ item.mode }}"
backup: no
# register: calibre_config
#register: calibre_config
with_items:
- { src: 'calibre-serve.service.j2', dest: '/etc/systemd/system/calibre-serve.service', mode: '0644'}
- { src: 'calibre.conf', dest: '/etc/{{ apache_config_dir }}', mode: '0644'}
@ -50,24 +49,23 @@
systemd:
daemon_reload: yes
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
# stat:
# path: /etc/systemd/system/calibre-serve.service
# register: calibre_svc
- name: Stop Calibre service -- calibre-server by Kovid Goyal
# systemd:
service:
- name: Stop service 'calibre-serve' (/usr/bin/calibre-server by Kovid Goyal)
systemd:
name: calibre-serve
state: stopped
#enabled: no
# register: command_result # gist.github.com/tyrells/0a79681de339237cb04c
# failed_when: false # Never Fail during "systemctl stop calibre-serve" (even if service doesn't exist!)
# when: calibre_svc.stat.exists
#register: command_result # gist.github.com/tyrells/0a79681de339237cb04c
#failed_when: false # Never Fail during "systemctl stop calibre-serve" (even if service doesn't exist!)
#when: calibre_svc.stat.exists
# 3. CREATE USER DATABASE
@ -88,7 +86,7 @@
# 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:
path: "{{ calibre_dbpath }}/metadata.db"
register: calibre_db
@ -105,20 +103,20 @@
# 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
# 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:
src: /etc/apache2/sites-available/calibre.conf
dest: /etc/apache2/sites-enabled/calibre.conf
state: link
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:
dest: /etc/apache2/sites-enabled/calibre.conf
state: absent
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:
name: calibre-serve
enabled: yes
@ -127,14 +125,14 @@
#async: 900
#poll: 5
- name: Forcing apache to reread configs
service:
- name: Reload Apache service ({{ apache_service }})
systemd:
name: "{{ apache_service }}"
state: reloaded
- name: Add 'calibre' to list of services at {{ iiab_ini_file }}
- name: Add 'calibre' variable values to {{ iiab_ini_file }}
ini_file:
dest: "{{ iiab_ini_file }}"
path: "{{ iiab_ini_file }}"
section: calibre
option: "{{ item.option }}"
value: "{{ item.value }}"
@ -149,5 +147,5 @@
value: "{{ calibre_dbpath }}"
- option: port
value: "{{ calibre_port }}"
- option: enabled
- option: 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>
<a class="button" href="http://iiab-server.lan/home">{{ btn1 }}</a>
<a class="button" href="http://{{ FQDN }}">{{ btn1 }}</a>
</div>
</body>
</html>

View file

@ -69,7 +69,7 @@
<script>
var w = window.innerWidth;
function homeclick(){
window.open("http://iiab-server.lan/home","_system");
window.open("http://{{ FQDN }}","_system");
$.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
Group=root
WorkingDirectory=/opt/iiab/captive-portal
ExecStart=/opt/iiab/captive-portal/capture-wsgi.py
ExecStart=/opt/iiab/captive-portal/capture-wsgi.py -l
StandardOutput=syslog
StandardError=syslog

View file

@ -28,7 +28,7 @@ j2_env = Environment(loader=FileSystemLoader(CAPTIVE_PORTAL_BASE),trim_blocks=Tr
# Define time outs
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
# 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/')
from iiab_env import get_iiab_env
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
# Create dummy iostream to capture stderr and stdout
@ -62,30 +55,33 @@ class StreamToLogger(object):
for line in buf.rstrip().splitlines():
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
try:
os.remove('/var/log/apache2/portal.log')
except:
pass
else:
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)
logger = logging.getLogger('/var/log/apache2/portal.log')
handler = RotatingFileHandler("/var/log/apache2/portal.log", maxBytes=100000, backupCount=2)
logger.addHandler(handler)
# divert stdout and stderr to logger
stdout_logger = logging.getLogger('STDOUT')
sl = StreamToLogger(stdout_logger, logging.ERROR)
#sys.stdout = sl
sys.stdout = sl
stderr_logger = logging.getLogger('STDERR')
sl = StreamToLogger(stderr_logger, logging.ERROR)
sys.stderr = sl
PORT={{ captive_portal_port }}
# Define globals
MAC_SUCCESS=False
ANDROID_TRIGGERED=False
logger.debug("")
@ -145,6 +141,8 @@ def timeout_info(ip):
def is_inactive(ip):
ts=tstamp(datetime.datetime.now(tzutc()))
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:
return True
if ts - int(last_ts) > INACTIVITY_TO:
@ -180,34 +178,48 @@ def set_lasttimestamp(ip):
# ################### Action routines based on OS ################3
def microsoft(environ,start_response):
#logger.debug("sending microsoft response")
en_txt={ 'message':"Click on the button to go to the IIAB home page",\
'btn1':"GO TO IIAB HOME PAGE",'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",\
'btn1':"IIAB",'doc_root':get_iiab_env("WWWROOT")}
if lang == "en":
txt = en_txt
elif lang == "es":
txt = es_txt
response_body = str(j2_env.get_template("simple.template").render(**txt))
status = '200 OK'
response_headers = [('Content-type','text/html'),
# firefox -- seems both mac and Windows use it
agent = environ.get('HTTP_USER_AGENT','default_agent')
if agent.startswith('Mozilla'):
return home(environ, start_response)
logger.debug("sending microsoft redirect")
response_body = ""
status = '302 Moved Temporarily'
response_headers = [('Location','http://box.lan/home'),
('Content-type','text/html'),
('Content-Length',str(len(response_body)))]
start_response(status, response_headers)
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)))]
start_response(status, response_headers)
return [response_body]
def android(environ, start_response):
global ANDROID_TRIGGERED
ip = environ['HTTP_X_FORWARDED_FOR'].strip()
if environ.get('HTTP_X_FORWARDED_FOR'):
ip = environ['HTTP_X_FORWARDED_FOR'].strip()
else:
ip = environ['REMOTE_ADDR'].strip()
system,system_version = platform_info(ip)
if system_version is None:
return put_302(environ, start_response)
if system_version[0:1] < '6':
logger.debug("system < 6:%s"%system_version)
location = '/android_splash'
set_204after(ip,0)
elif system_version[:1] >= '7':
location = "http://" + fully_qualified_domain_name + "/home"
else:
set_204after(ip,20)
#set_204after(ip,20)
location = '/android_https'
agent = environ['HTTP_USER_AGENT']
agent = environ.get('HTTP_USER_AGENT','default_agent')
response_body = "hello"
status = '302 Moved Temporarily'
response_headers = [('Location',location)]
@ -217,9 +229,12 @@ def android(environ, start_response):
def android_splash(environ, start_response):
en_txt={ 'message':"Click on the button to go to the IIAB home page",\
'btn1':"GO TO IIAB HOME PAGE", \
"FQDN": fully_qualified_domain_name, \
'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",\
"FQDN": fully_qualified_domain_name, \
'btn1':"IIAB",'doc_root':get_iiab_env("WWWROOT")}
txt = en_txt
if lang == "en":
txt = en_txt
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""",\
'btn2':'Click this first Go to the browser we need',\
'btn1':'Then click this to go to IIAB home page',\
"FQDN": fully_qualified_domain_name, \
'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",\
"FQDN": fully_qualified_domain_name, \
'btn1':"IIAB",'doc_root':get_iiab_env("WWWROOT")}
txt = en_txt
if lang == "en":
txt = en_txt
elif lang == "es":
@ -253,9 +271,12 @@ def mac_splash(environ,start_response):
logger.debug("in function mac_splash")
en_txt={ 'message':"Click on the button to go to the IIAB home page",\
'btn1':"GO TO IIAB HOME PAGE",'success_token': 'Success',
"FQDN": fully_qualified_domain_name, \
'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",\
"FQDN": fully_qualified_domain_name, \
'btn1':"IIAB",'doc_root':get_iiab_env("WWWROOT")}
txt = en_txt
if lang == "en":
txt = en_txt
elif lang == "es":
@ -271,6 +292,7 @@ def mac_splash(environ,start_response):
def macintosh(environ, start_response):
global ip
logger.debug("in function mcintosh")
#print >> sys.stderr , "Geo Print to stderr" + environ['HTTP_HOST']
if not is_inactive(ip):
set_lasttimestamp(ip)
return success(environ,start_response)
@ -298,7 +320,7 @@ def banner(environ, start_response):
status = '200 OK'
headers = [('Content-type', 'image/png')]
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]
def bootstrap(environ, start_response):
@ -326,7 +348,7 @@ def bootstrap_css(environ, start_response):
return [boot]
def null(environ, start_response):
status = '200 ok'
status = '404 Not Found'
headers = [('Content-type', 'text/html')]
start_response(status, headers)
return [""]
@ -347,6 +369,17 @@ def put_204(environ, start_response):
logger.debug("in function put_204: sending 204 html response")
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):
system = ''
system_version = ''
@ -366,185 +399,151 @@ def parse_agent(agent):
if match:
system = match.group(1)
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)
#
# ================== Start serving the wsgi application =================
def application (environ, start_response):
global ip
global CATCH
global LIST
global INACTIVITY_TO
global ANDROID_TRIGGERED
global ip
global CATCH
global LIST
global INACTIVITY_TO
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:
ip = environ['HTTP_X_FORWARDED_FOR'].strip()
else:
data = ['%s: %s\n' % (key, value) for key, value in sorted(environ.items()) ]
#logger.debug("need the correct ip:%s"%data)
ip = environ['REMOTE_ADDR'].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)
logger.debug(data)
#print(data)
found = False
return_204_flag = "False"
if 'HTTP_X_FORWARDED_FOR' in environ:
ip = environ['HTTP_X_FORWARDED_FOR'].strip()
else:
data = ['%s: %s\n' % (key, value) for key, value in sorted(environ.items()) ]
#logger.debug("need the correct ip:%s"%data)
ip = environ['REMOTE_ADDR'].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.get('HTTP_USER_AGENT','default_agent')
data.append("AGENT: %s\n"%agent)
logger.debug(data)
#print(data)
found = False
return_204_flag = "False"
# record the activity with this ip
ts=tstamp(datetime.datetime.now(tzutc()))
sql = "INSERT or IGNORE INTO users (current_ts,ip) VALUES (?,?)"
c.execute(sql,(ts,ip,))
sql = "UPDATE users SET current_ts = ? where ip = ?"
c.execute(sql,(ts,ip,))
if c.rowcount == 0:
logger.debug("failed UPDATE users SET current_ts = %s WHERE ip = %s"%(ts,ip,))
conn.commit()
ymd=datetime.datetime.today().strftime("%y%m%d-%H%M")
# record the activity with this ip
ts=tstamp(datetime.datetime.now(tzutc()))
sql = "INSERT or IGNORE INTO users (current_ts,ip) VALUES (?,?)"
c.execute(sql,(ts,ip,))
sql = "UPDATE users SET current_ts = ? where ip = ?"
c.execute(sql,(ts,ip,))
if c.rowcount == 0:
logger.debug("failed UPDATE users SET current_ts = %s WHERE ip = %s"%(ts,ip,))
conn.commit()
ymd=datetime.datetime.today().strftime("%y%m%d-%H%M")
system,system_version = parse_agent(agent)
if system != '':
update_user(ip, mac, system, system_version, ymd)
system,system_version = parse_agent(agent)
if system != '':
update_user(ip, mac, system, system_version, ymd)
####### Return pages based upon PATH ###############
# do more specific stuff first
if environ['PATH_INFO'] == "/iiab_banner6.png":
return banner(environ, start_response)
####### Return pages based upon PATH ###############
# do more specific stuff first
if environ['PATH_INFO'] == "/iiab_banner6.png":
return banner(environ, start_response)
if environ['PATH_INFO'] == "/bootstrap.min.js":
return bootstrap(environ, start_response)
if environ['PATH_INFO'] == "/bootstrap.min.js":
return bootstrap(environ, start_response)
if environ['PATH_INFO'] == "/bootstrap.min.css":
return bootstrap_css(environ, start_response)
if environ['PATH_INFO'] == "/bootstrap.min.css":
return bootstrap_css(environ, start_response)
if environ['PATH_INFO'] == "/jquery.min.js":
return jquery(environ, start_response)
if environ['PATH_INFO'] == "/jquery.min.js":
return jquery(environ, start_response)
if environ['PATH_INFO'] == "/favicon.ico":
return null(environ, start_response)
if environ['PATH_INFO'] == "/favicon.ico":
return null(environ, start_response)
if environ['PATH_INFO'] == "/home_selected":
# the js link to home page triggers this ajax url
# mark the sign-in conversation completed, return 204 or Success or Success
ANDROID_TRIGGERED = True
#data = ['%s: %s\n' % (key, value) for key, value in sorted(environ.items()) ]
#logger.debug("need the correct ip:%s"%data)
logger.debug("function: home_selected. Setting flag to return_204")
#print("setting flag to return_204")
set_204after(ip,PORTAL_TO)
set_lasttimestamp(ip)
status = '200 OK'
headers = [('Content-type', 'text/html')]
start_response(status, headers)
return [""]
if environ['PATH_INFO'] == "/home_selected":
# the js link to home page triggers this ajax url
# mark the sign-in conversation completed, return 204 or Success or Success
ANDROID_TRIGGERED = True
#data = ['%s: %s\n' % (key, value) for key, value in sorted(environ.items()) ]
#logger.debug("need the correct ip:%s"%data)
logger.debug("function: home_selected. Setting flag to return_204")
#print("setting flag to return_204")
set_204after(ip,PORTAL_TO)
set_lasttimestamp(ip)
status = '200 OK'
headers = [('Content-type', 'text/html')]
start_response(status, headers)
return [""]
#### parse OS platform based upon URL ##################
# mac
if environ['PATH_INFO'] == "/mac_splash":
return mac_splash(environ, start_response)
#### parse OS platform based upon URL ##################
# mac
if environ['PATH_INFO'] == "/mac_splash":
return mac_splash(environ, start_response)
if environ['PATH_INFO'] == "/step2":
return step2(environ, start_response)
if environ['PATH_INFO'] == "/step2":
return step2(environ, start_response)
if environ['HTTP_HOST'] == "captive.apple.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'] == "gsp1.apple.com" or\
environ['HTTP_HOST'] == "apple.com" or\
environ['HTTP_HOST'] == "www.apple.com":
current_ts, last_ts, send204after = timeout_info(ip)
if not send204after:
# take care of uninitialized state
set_204after(ip,0)
return macintosh(environ, start_response)
if environ['HTTP_HOST'] == "captive.apple.com" or\
environ['HTTP_HOST'] == "appleiphonecell.com" or\
environ['HTTP_HOST'] == "*.apple.com.edgekey.net" or\
environ['HTTP_HOST'] == "gsp1.apple.com" or\
environ['HTTP_HOST'] == "apple.com" or\
environ['HTTP_HOST'] == "www.apple.com":
current_ts, last_ts, send204after = timeout_info(ip)
if not send204after:
# take care of uninitialized state
set_204after(ip,0)
return macintosh(environ, start_response)
# android
if environ['PATH_INFO'] == "/android_splash":
return android_splash(environ, start_response)
if environ['PATH_INFO'] == "/android_https":
return android_https(environ, start_response)
if environ['HTTP_HOST'] == "clients3.google.com" or\
environ['HTTP_HOST'] == "mtalk.google.com" or\
environ['HTTP_HOST'] == "alt7-mtalk.google.com" or\
environ['HTTP_HOST'] == "alt6-mtalk.google.com" or\
environ['HTTP_HOST'] == "connectivitycheck.android.com" or\
environ['HTTP_HOST'] == "connectivitycheck.gstatic.com":
current_ts, last_ts, send204after = timeout_info(ip)
logger.debug("current_ts: %s laat_ts: %s send204after: %s"%(current_ts, last_ts, send204after,))
if not last_ts or (ts - int(last_ts) > INACTIVITY_TO):
return android(environ, start_response)
elif is_after204_timeout(ip):
return put_204(environ,start_response)
return null(environ,start_response) #return without doing anything
# android
if environ['PATH_INFO'] == "/android_splash":
return android_splash(environ, start_response)
if environ['PATH_INFO'] == "/android_https":
return android_https(environ, start_response)
if environ['HTTP_HOST'] == "clients3.google.com" or\
environ['HTTP_HOST'] == "mtalk.google.com" or\
environ['HTTP_HOST'] == "alt7-mtalk.google.com" or\
environ['HTTP_HOST'] == "alt6-mtalk.google.com" or\
environ['HTTP_HOST'] == "connectivitycheck.android.com" or\
environ['PATH_INFO'] == "/gen_204" or\
environ['HTTP_HOST'] == "connectivitycheck.gstatic.com":
current_ts, last_ts, send204after = timeout_info(ip)
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):
return android(environ, start_response)
elif is_after204_timeout(ip):
return put_204(environ,start_response)
return android(environ, start_response)
# 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\
environ['HTTP_HOST'] == "ipv6.msftncsi.com.edgesuite.net" or\
environ['HTTP_HOST'] == "www.msftncsi.com" or\
environ['HTTP_HOST'] == "www.msftncsi.com.edgesuite.net" or\
environ['HTTP_HOST'] == "www.msftconnecttest.com" or\
environ['HTTP_HOST'] == "teredo.ipv6.microsoft.com" or\
environ['HTTP_HOST'] == "teredo.ipv6.microsoft.com.nsatc.net":
return microsoft(environ, start_response)
# microsoft
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'] == "www.msftncsi.com" or\
environ['HTTP_HOST'] == "www.msftncsi.com.edgesuite.net" 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.nsatc.net":
return microsoft(environ, start_response)
logger.debug("executing the defaut 204 response. [%s"%data)
return put_204(environ,start_response)
logger.debug("executing the default 302 response. [%s"%data)
return put_302(environ,start_response)
# Instantiate the server
httpd = make_server (
if __name__ == "__main__":
httpd = make_server (
"", # The host name
PORT, # A port number where to wait for the request
application # The application object name, in this case a function
)
)
httpd.serve_forever()
httpd.serve_forever()
#vim: tabstop=3 expandtab shiftwidth=3 softtabstop=3 background=dark

View file

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

View file

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

View file

@ -8,6 +8,8 @@ if [ -n "$pid" ]; then
kill $pid
fi
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
systemctl start py-captive-portal
systemctl start apache2
# systemctl start captive-portal
systemctl start {{ apache_service }}

View file

@ -1,32 +1,30 @@
# administer this service by browsing to localhost:631
- name: Get the CUPS package installed
- name: Install 'cups' package
package:
name: "{{ item }}"
name: cups
state: present
with_items:
- cups
when: cups_install
tags:
- 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:
src: 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:
src: cups.conf
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:
src: /etc/apache2/sites-available/cups.conf
dest: /etc/apache2/sites-enabled/cups.conf
state: link
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:
name: "{{ item }}"
state: started
@ -36,8 +34,8 @@
- cups-browsed
when: cups_enabled and not is_F18
- name: Enable services for CUPS (Fedora 18, for XO laptops)
service:
- name: Enable & Start service 'cups' (Fedora 18, for XO laptops)
systemd:
name: cups
state: started
enabled: yes
@ -47,8 +45,8 @@
shell: "cupsctl --remote-admin"
when: cups_enabled
- name: Disable services for CUPS (OS's other than Fedora 18)
service:
- name: Disable both CUPS services (OS's other than Fedora 18)
systemd:
name: "{{ item }}"
state: stopped
enabled: no
@ -58,15 +56,15 @@
when: not cups_enabled and not is_F18
- name: Disable services for CUPS (Fedora 18, for XO laptops)
service:
systemd:
name: cups
state: stopped
enabled: no
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:
dest: "{{ iiab_ini_file }}"
path: "{{ iiab_ini_file }}"
section: cups
option: "{{ item.option }}"
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."'
- option: installed
value: "{{ cups_install }}"
- option: enabled
- option: cups_enabled
value: "{{ cups_enabled }}"

View file

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

View file

@ -1,4 +1,4 @@
dokuwiki_url: /wiki
dokuwiki_install: True
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:
url: "{{ iiab_download_url }}/{{ dokuwiki_version }}.tgz"
dest: "{{ downloads_dir }}/"
timeout: "{{ download_timeout }}"
when: internet_available
- name: Copy it to permanent location /library
- name: Unarchive (unpack) it to /library/{{ dokuwiki_version }}
unarchive:
src: "{{ downloads_dir }}/{{ dokuwiki_version }}.tgz"
dest: /library
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: ln -sf /library/{{ dokuwiki_version }} /library/dokuwiki
#BOTH LINES ABOVE FAIL TO UPDATE LINK; Ansible approach below works
file:
path: /library/dokuwiki
src: /library/{{ dokuwiki_version }}
path: /library/dokuwiki
state: link
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:
src: dokuwiki.conf.j2
dest: "/etc/{{ apache_config_dir }}/dokuwiki.conf"
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:
src: /etc/apache2/sites-available/dokuwiki.conf
dest: /etc/apache2/sites-enabled/dokuwiki.conf
path: /etc/apache2/sites-enabled/dokuwiki.conf
state: link
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:
path: /etc/apache2/sites-enabled/dokuwiki.conf
state: absent
when: not dokuwiki_enabled and is_debuntu
- name: Change permissions on engine directory so Apache can write
- name: Set /library/{{ dokuwiki_version }} owner to {{ apache_user }} and permissions to 0755 (recursively)
file:
path: "/library/{{ dokuwiki_version }}"
owner: "{{ apache_user }}"
@ -49,7 +48,7 @@
state: directory
recurse: yes
- name: Restart Apache, so it picks up the new aliases
service:
- name: Restart Apache ({{ apache_service }}) to enable/disable DokuWiki's http://box/wiki
systemd:
name: "{{ apache_service }}"
state: restarted

View file

@ -2,9 +2,9 @@
include_tasks: install.yml
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:
dest: "{{ iiab_ini_file }}"
path: "{{ iiab_ini_file }}"
section: dokuwiki
option: "{{ item.option }}"
value: "{{ item.value }}"

View file

@ -1,9 +1,7 @@
- name: Install ejabberd packages
- name: Install ejabberd package
package:
name: "{{ item }}"
name: ejabberd
state: present
with_items:
- ejabberd
tags:
- 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_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_version: "2.3.8"
elgg_version: "2.3.10"
# elgg_mysql_password: defined in default_vars
elgg_url: /elgg

View file

@ -1,37 +1,42 @@
# Assume we only get here if elgg_install: True
# Assume mysql is running
# Assume MySQL is running
- name: Download current version from our site
shell: wget {{ iiab_download_url }}/elgg-{{ elgg_version }}.zip -c -P {{ downloads_dir }}
args:
creates: "{{ downloads_dir }}/elgg-{{ elgg_version }}.zip"
- 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 }}
#args:
# 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
- name: Determine if software is already expanded
- name: Check for existence of /opt/elgg-{{ elgg_version }}/index.php
stat:
path: "/opt/elgg-{{ elgg_version }}/index.php"
register: elgg
# use unzip and shell until unarchive works again
# unarchive: dest=/opt/
# src={{ downloads_dir }}/elgg-{{ elgg_version }}.zip
- name: Expand it to our location unless already done
shell: "/usr/bin/unzip -o {{ downloads_dir }}/elgg-{{ elgg_version }}.zip -d /opt"
- name: Unpack (unarchive) .zip to /opt, if above index.php doesn't exist
#shell: "/usr/bin/unzip -o {{ downloads_dir }}/elgg-{{ elgg_version }}.zip -d /opt"
unarchive:
#remote_src: yes
#src: "{{ iiab_download_url }}/elgg-{{ elgg_version }}.zip"
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
- name: Create a link to the versioned elgg-* folder
- name: Create softlink from /opt/elgg to /opt/elgg-{{ elgg_version }}
file:
src: "./elgg-{{ elgg_version }}"
dest: /opt/elgg
path: /opt/elgg
owner: "{{ apache_user }}"
group: "{{ apache_user }}"
state: link
force: true
# Use template to fix up settings in elgg-config/settings.php with our variables substituted.
# Note this will overwrite any manual settings.
- name: Substitute our parameters in /opt/elgg/elgg-config/settings.php
- name: 'Install /opt/elgg/elgg-config/settings.php from template (WARNING: overwrites manual settings!)'
template:
src: "settings.php.j2"
dest: "/opt/{{ elgg_xx }}/elgg-config/settings.php"
@ -39,7 +44,7 @@
group: "{{ apache_user }}"
# 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:
src: "/opt/{{ elgg_xx }}/vendor/elgg/elgg/install/config/htaccess.dist"
dest: "/opt/{{ elgg_xx }}/.htaccess"
@ -48,28 +53,22 @@
group: "{{ apache_user }}"
#regexp='^#RewriteBase'
- name: Modify .htaccess to have RewriteBase as our directory
- name: Change .htaccess to include RewriteBase for http://box/elgg
lineinfile:
backup: no
dest: "/opt/{{ elgg_xx }}/.htaccess"
path: "/opt/{{ elgg_xx }}/.htaccess"
state: present
insertafter: '^#RewriteBase'
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:
path: /opt/elgg/engine/
owner: "{{ apache_user }}"
mode: 0755
state: directory
- name: Create an upload directory that Apache can write in or Elgg
file:
path: "{{ elgg_upload_path }}"
state: directory
owner: "{{ apache_user }}"
- name: Change ownership
- name: Change /opt/elgg-{{ elgg_version }} ownership to {{ apache_user }}:{{ apache_user }} (likely not nec, as unarchive & all do this above)
file:
path: "/opt/elgg-{{ elgg_version }}"
owner: "{{ apache_user }}"
@ -77,12 +76,18 @@
recurse: yes
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:
name: "{{ dbname }}"
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:
name: "{{ dbuser }}"
host: "{{ item }}"
@ -93,7 +98,7 @@
- ::1
- localhost
- name: Create file to load database
- name: Create /tmp/elggdb.sql from template, to load database
template:
src: "elggdb.sql.j2"
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
# 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:
name: "{{ dbname }}"
state: import
target: /tmp/elggdb.sql
when: create_elgg_database.changed
- name: Remove database dump after load
- name: Remove database dump /tmp/elggdb.sql
file:
name: /tmp/elggdb.sql
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:
src: 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:
src: /etc/apache2/sites-available/elgg.conf
dest: /etc/apache2/sites-enabled/elgg.conf
path: /etc/apache2/sites-enabled/elgg.conf
state: link
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:
path: /etc/apache2/sites-enabled/elgg.conf
state: absent
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:
dest: "/etc/{{ apache_config_dir }}/elgg.conf"
state: absent
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:
dest: "{{ iiab_ini_file }}"
path: "{{ iiab_ini_file }}"
section: elgg
option: "{{ item.option }}"
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."'
- option: path
value: /opt/elgg
- option: enabled
- option: 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:
path: "{{ doc_root }}/home"
owner: "{{ apache_user }}"
@ -6,14 +6,14 @@
mode: 0755
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:
src: 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:
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
when: is_debuntu

View file

@ -2,5 +2,5 @@
apache_allow_sudo: True
# 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

View file

@ -1,9 +1,8 @@
/*!
* Bootstrap v3.2.0 (http://getbootstrap.com)
* Copyright 2011-2014 Twitter, Inc.
* Bootstrap v3.3.7 (http://getbootstrap.com)
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
.btn-default,
.btn-primary,
.btn-success,
@ -29,6 +28,35 @@
-webkit-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 {
background-image: none;
@ -55,34 +83,66 @@
background-color: #e0e0e0;
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-image: none;
}
.btn-primary {
background-image: -webkit-linear-gradient(top, #428bca 0%, #2d6ca2 100%);
background-image: -o-linear-gradient(top, #428bca 0%, #2d6ca2 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#2d6ca2));
background-image: linear-gradient(to bottom, #428bca 0%, #2d6ca2 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);
background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #2b669a;
border-color: #245580;
}
.btn-primary:hover,
.btn-primary:focus {
background-color: #2d6ca2;
background-color: #265a88;
background-position: 0 -15px;
}
.btn-primary:active,
.btn-primary.active {
background-color: #2d6ca2;
border-color: #2b669a;
background-color: #265a88;
border-color: #245580;
}
.btn-primary:disabled,
.btn-primary[disabled] {
background-color: #2d6ca2;
.btn-primary.disabled,
.btn-primary[disabled],
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;
}
.btn-success {
@ -105,8 +165,24 @@
background-color: #419641;
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-image: none;
}
@ -130,8 +206,24 @@
background-color: #2aabd2;
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-image: none;
}
@ -155,8 +247,24 @@
background-color: #eb9316;
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-image: none;
}
@ -180,8 +288,24 @@
background-color: #c12e2a;
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-image: none;
}
@ -203,12 +327,12 @@
.dropdown-menu > .active > a,
.dropdown-menu > .active > a:hover,
.dropdown-menu > .active > a:focus {
background-color: #357ebd;
background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%);
background-image: -o-linear-gradient(top, #428bca 0%, #357ebd 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#357ebd));
background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);
background-color: #2e6da4;
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;
}
.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);
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 {
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%);
background-image: -o-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f3f3f3));
background-image: linear-gradient(to bottom, #ebebeb 0%, #f3f3f3 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);
background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
background-repeat: repeat-x;
-webkit-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(enabled = false);
background-repeat: repeat-x;
border-radius: 4px;
}
.navbar-inverse .navbar-nav > .open > a,
.navbar-inverse .navbar-nav > .active > a {
background-image: -webkit-linear-gradient(top, #222 0%, #282828 100%);
background-image: -o-linear-gradient(top, #222 0%, #282828 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#222), to(#282828));
background-image: linear-gradient(to bottom, #222 0%, #282828 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);
background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);
background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
background-repeat: repeat-x;
-webkit-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 {
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 {
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);
@ -315,11 +455,11 @@
background-repeat: repeat-x;
}
.progress-bar {
background-image: -webkit-linear-gradient(top, #428bca 0%, #3071a9 100%);
background-image: -o-linear-gradient(top, #428bca 0%, #3071a9 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#3071a9));
background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0);
background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar-success {
@ -367,14 +507,19 @@
.list-group-item.active,
.list-group-item.active:hover,
.list-group-item.active:focus {
text-shadow: 0 -1px 0 #3071a9;
background-image: -webkit-linear-gradient(top, #428bca 0%, #3278b3 100%);
background-image: -o-linear-gradient(top, #428bca 0%, #3278b3 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#3278b3));
background-image: linear-gradient(to bottom, #428bca 0%, #3278b3 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);
text-shadow: 0 -1px 0 #286090;
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
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 {
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
@ -389,11 +534,11 @@
background-repeat: repeat-x;
}
.panel-primary > .panel-heading {
background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%);
background-image: -o-linear-gradient(top, #428bca 0%, #357ebd 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#357ebd));
background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);
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;
}
.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:
src: "{{ item }}"
dest: "{{ doc_root }}/common/css"
@ -8,7 +8,7 @@
with_fileglob:
- 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:
src: "{{ item }}"
dest: "{{ doc_root }}/common/js"
@ -18,7 +18,7 @@
with_fileglob:
- 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:
src: "{{ item }}"
dest: "{{ doc_root }}/common/fonts"
@ -28,7 +28,7 @@
with_fileglob:
- 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:
src: "{{ item }}"
dest: "{{ doc_root }}/common/html"
@ -38,7 +38,7 @@
with_fileglob:
- 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:
src: "{{ item }}"
dest: "{{ doc_root }}/common/assets"
@ -49,7 +49,7 @@
- html/assets/*
# 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:
src: "{{ item }}"
dest: "{{ doc_root }}/common/services"
@ -59,10 +59,10 @@
with_fileglob:
- 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:
src: "{{ iiab_ini_file }}"
dest: "{{ doc_root }}/common/assets/iiab.ini"
path: "{{ doc_root }}/common/assets/iiab.ini"
owner: root
group: root
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:
name: "{{ item }}"
#name: [u'apache2', u'php{{ php_version }}', u'php{{ php_version }}-curl'] # FAILS ('u' for Unicode strings)
#name: ['apache2', 'php{{ php_version }}', 'php{{ php_version }}-curl'] # WORKS?
name:
- apache2
- "php{{ php_version }}"
- "php{{ php_version }}-curl"
state: present
with_items:
- apache2
- php{{ php_version }}
- php{{ php_version }}-curl
# - php{{ php_version }}-sqlite
when: is_debian
tags:
- 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:
name: "php{{ php_version }}-sqlite"
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:
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:
name: "{{ item }}"
#name: [u'httpd', u'php', u'php-curl', u'mod_authnz_external'] # FAILS ('u' for Unicode strings)
#name: ['httpd', 'php', 'php-curl', 'mod_authnz_external'] # WORKS
name:
- httpd
- mod_authnz_external
- php
- php-curl
state: present
with_items:
- 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
- php
- php-curl
- mod_authnz_external
# - php-sqlite
tags:
- download
when: is_redhat
tags:
- download
# MOVED DOWN ~58 LINES
#- 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
- name: Install Apache's 010-iiab.conf & proxy_ajp.conf into /etc/apache2/sites-available, from templates
template:
backup: yes
src: "{{ item.src }}"
dest: "{{ item.dest }}"
owner: root
group: root
mode: "{{ item.mode }}"
mode: 0644
with_items:
- { src: '010-iiab.conf.j2', dest: '/etc/{{ apache_config_dir }}/010-iiab.conf', mode: '0755' }
- { src: 'proxy_ajp.conf.j2', dest: '/etc/{{ apache_config_dir }}/proxy_ajp.conf', mode: '0644' }
- { 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' }
#- { 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
# 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
lineinfile:
path: "/etc/php/{{ php_version }}/{{ apache_service }}/php.ini"
@ -80,14 +70,14 @@
line: "{{ item.line }}"
when: apache_high_php_limits
with_items:
- { regexp: '^upload_max_filesize', line: 'upload_max_filesize = 64M ; default is 2M' }
- { regexp: '^post_max_size', line: 'post_max_size = 128M ; default is 8M' }
- { regexp: '^upload_max_filesize', line: 'upload_max_filesize = 500M ; default is 2M' }
- { regexp: '^post_max_size', line: 'post_max_size = 500M ; default is 8M' }
- { regexp: '^memory_limit', line: 'memory_limit = 256M ; default is 128M' }
- { regexp: '^max_execution_time', line: 'max_execution_time = 300 ; default is 30' }
- { regexp: '^max_input_time', line: 'max_input_time = 300 ; default is 60' }
# 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:
path: "/etc/apache2/mods-enabled/{{ item }}"
state: absent
@ -96,17 +86,17 @@
- mpm_event.load
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:
path: "/etc/apache2/mods-enabled/{{ item }}"
src: "/etc/apache2/mods-available/{{ item }}"
path: "/etc/apache2/mods-enabled/{{ item }}"
state: link
with_items:
- mpm_prefork.conf
- mpm_prefork.load
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 }}
with_items:
- proxy
@ -115,16 +105,14 @@
- rewrite
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:
path: "/etc/apache2/sites-enabled/{{ item }}"
src: "/etc/apache2/sites-available/{{ item }}"
src: "/etc/{{ apache_config_dir }}/010-iiab.conf"
path: /etc/apache2/sites-enabled/010-iiab.conf
state: link
with_items:
- 010-iiab.conf
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:
path: "{{ item }}"
state: absent
@ -133,7 +121,7 @@
- /etc/apache2/sites-enabled/000-default.conf
when: is_debuntu
- name: Create http pid dir /var/run/{{ apache_user }}
- name: Create Apache's pid dir /var/run/{{ apache_user }}
file:
path: "/var/run/{{ apache_user }}"
mode: 0755
@ -141,19 +129,19 @@
group: root
state: directory
- name: Create admin group
- name: 'Create group: admin'
group:
name: admin
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:
name: "{{ apache_user }}"
groups: admin
state: present
createhome: no
- name: Create httpd log dir /var/log/{{ apache_service }}
- name: Create Apache dir /var/log/{{ apache_service }}
file:
path: "/var/log/{{ apache_service }}"
mode: 0755
@ -161,12 +149,12 @@
group: "{{ apache_user }}"
state: directory
- name: Enable httpd
- name: Enable Apache systemd service ({{ apache_service }})
service:
name: "{{ apache_service }}"
enabled: yes
- name: Create iiab-info directory
- name: Create /library/www/html/info directory for http://box/info offline docs
file:
path: "{{ doc_root }}/info"
mode: 0755
@ -174,19 +162,8 @@
group: "{{ apache_user }}"
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)
- 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:
src: osm.conf
dest: "/etc/{{ apache_config_dir }}"
@ -195,10 +172,11 @@
mode: 0644
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:
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
when: is_debuntu
@ -206,26 +184,31 @@
tags:
- 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
tags:
- 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:
src: refresh-wiki-docs.sh
dest: /usr/bin/iiab-refresh-wiki-docs
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:
src: 020_apache_poweroff.j2
dest: /etc/sudoers.d/020_apache_poweroff
mode: 0755
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:
dest: /etc/sudoers.d/020_apache_poweroff
path: /etc/sudoers.d/020_apache_poweroff
state: absent
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
# 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:
src: http://download.iiab.io/packages/php-stem.rpi.tar
dest: /
@ -21,7 +21,7 @@
remote_src: yes
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:
src: http://download.iiab.io/packages/php-stem.x64.tar
dest: /
@ -33,9 +33,3 @@
# Presumably fails on Debian 8 & 10?
# 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
# 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
CustomLog /var/log/apache2/access.log combined
ServerName {{ iiab_hostname }}
ServerAlias iiab-server.lan
ServerAlias {{ iiab_hostname }}.{{ iiab_domain }}
<Directory "{{ doc_root }}">
Options Indexes FollowSymLinks
AllowOverride None

View file

@ -79,15 +79,16 @@
insertafter='^#allowsftp'
line=allowsftp
- name: Add idmgr to service list
ini_file: dest='{{ iiab_ini_file }}'
section=idmgr
option='{{ item.option }}'
value='{{ item.value }}'
- name: Add 'idmgr' variable values to {{ iiab_ini_file }}
ini_file:
path: "{{ iiab_ini_file }}"
section: idmgr
option: "{{ item.option }}"
value: "{{ item.value }}"
with_items:
- option: name
value: idmgr
- 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
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:
name: "{{ item }}"
state: present
with_items:
name:
- screen
- lynx
state: present
tags:
- 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:
name: "{{ iiab_admin_user }}"
password: "{{ iiab_admin_pwd_hash }}"

View file

@ -7,7 +7,7 @@
tags:
- base
- name: Add 'iiab-admin' to list at {{ iiab_ini_file }}
- name: Add 'iiab-admin' variable values to {{ iiab_ini_file }}
ini_file:
dest: "{{ iiab_ini_file }}"
section: iiab-admin
@ -21,7 +21,7 @@
- option: 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:
src: profile_ssh_warn.sh
dest: /etc/profile.d/
@ -31,14 +31,14 @@
path: /home/pi/.config/lxsession
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:
src: lxde_ssh_warn.sh
dest: /home/pi/.config/lxsession/LXDE-pi/
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:
path: /home/pi/.config/lxsession/LXDE-pi/autostart
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

View file

@ -1,6 +1,6 @@
#!/bin/bash
function check_user_pwd() {
check_user_pwd() {
# $meth (hashing method) is typically '6' which implies 5000 rounds
# of SHA-512 per /etc/login.defs -> /etc/pam.d/common-password
meth=$(sudo grep "^$1:" /etc/shadow | cut -d: -f2 | cut -d$ -f2)
@ -10,7 +10,7 @@ function check_user_pwd() {
}
# credit to the folks at raspberry pi foundatioon
check_hash () {
check_hash() {
if ! id -u iiab-admin > /dev/null 2>&1 ; then return 0 ; fi
if grep -q "^PasswordAuthentication\s*no" /etc/ssh/sshd_config ; then return 0 ; fi
#test -x /usr/bin/mkpasswd || return 0

View file

@ -1,6 +1,8 @@
#!/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
# of SHA-512 per /etc/login.defs -> /etc/pam.d/common-password
meth=$(sudo grep "^$1:" /etc/shadow | cut -d: -f2 | cut -d$ -f2)
@ -10,7 +12,7 @@ function check_user_pwd() {
}
# credit to the folks at raspberry pi foundatioon
check_hash () {
check_hash() {
if ! id -u iiab-admin > /dev/null 2>&1 ; then return 0 ; fi
if grep -q "^PasswordAuthentication\s*no" /etc/ssh/sshd_config ; then return 0 ; fi
#SHADOW="$(sudo -n grep -E '^iiab-admin:' /etc/shadow 2>/dev/null)"

View file

@ -49,3 +49,10 @@ To return to using the systemd unit:
* 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.*
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"
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
set_fact:
job_scheduler_stanza: ""

View file

@ -12,7 +12,7 @@
kalite_db_name: "{{ kalite_root }}/database/data.sqlite"
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:
path: "{{ kalite_db_name }}"
register: kalite_installed
@ -36,9 +36,9 @@
- 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:
dest: "{{ iiab_ini_file }}"
path: "{{ iiab_ini_file }}"
section: kalite
option: "{{ item.option }}"
value: "{{ item.value }}"
@ -51,7 +51,7 @@
value: "{{ kalite_root }}"
- option: port
value: "{{ kalite_server_port }}"
- option: enabled
- option: kalite_enabled
value: "{{ kalite_enabled }}"
- option: cron_enabled
value: "{{ kalite_cron_enabled }}"

View file

@ -1,9 +1,9 @@
# 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/
kiwix_version_armhf: "kiwix-tools_linux-armhf-0.6.1-1"
kiwix_version_linux64: "kiwix-tools_linux-x86_64-0.6.1-1"
kiwix_version_i686: "kiwix-tools_linux-i586-0.6.1-1"
kiwix_version_armhf: "kiwix-tools_linux-armhf-0.9.0"
kiwix_version_linux64: "kiwix-tools_linux-x86_64-0.9.0"
kiwix_version_i686: "kiwix-tools_linux-i586-0.9.0"
# kiwix_src_file_i686: "kiwix-linux-i686.tar.bz2"
# 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:

View file

@ -1,6 +1,6 @@
# 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:
path: "{{ item }}"
owner: root
@ -12,12 +12,12 @@
- "{{ iiab_zim_path }}/content"
- "{{ iiab_zim_path }}/index"
- name: Check for /library/zims/library.xml
- name: Check for {{ kiwix_library_xml }} # /library/zims/library.xml
stat:
path: "{{ kiwix_library_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:
src: "{{ item }}"
dest: "{{ kiwix_library_xml }}"
@ -34,12 +34,12 @@
path: "{{ kiwix_path }}/bin/kiwix-serve"
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:
kiwix_force_install: True
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:
src: test.zim
dest: "{{ iiab_zim_path }}/content/test.zim"
@ -49,7 +49,7 @@
force: no
when: kiwix_force_install
- name: Create /opt/iiab/kiwix/bin directory
- name: Create {{ kiwix_path }}/bin directory # /opt/iiab/kiwix/bin
file:
path: "{{ kiwix_path }}/bin"
owner: root
@ -59,7 +59,7 @@
# 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:
src: "{{ downloads_dir }}/{{ kiwix_src_file }}"
dest: /tmp
@ -73,7 +73,7 @@
# 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:
name: "{{ item }}"
with_items:
@ -85,7 +85,7 @@
# 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:
backup: no
src: "{{ item.src }}"
@ -101,14 +101,14 @@
# - { 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'}
- 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:
src: /etc/apache2/sites-available/kiwix.conf
path: /etc/apache2/sites-enabled/kiwix.conf
state: link
when: is_debuntu
- name: Enable 'kiwix-serve' service
- name: Enable & Restart 'kiwix-serve' service
service:
name: kiwix-serve
enabled: yes
@ -149,9 +149,9 @@
# 5. FINALIZE
- name: Add 'kiwix' to list of services at {{ iiab_ini_file }}
- name: Add 'kiwix' variable values to {{ iiab_ini_file }}
ini_file:
dest: "{{ iiab_ini_file }}"
path: "{{ iiab_ini_file }}"
section: kiwix
option: "{{ item.option }}"
value: "{{ item.value }}"
@ -170,5 +170,5 @@
value: "{{ iiab_zim_path }}"
- option: kiwix_library_xml
value: "{{ kiwix_library_xml }}"
- option: enabled
- option: kiwix_enabled
value: "{{ kiwix_enabled }}"

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

@ -22,16 +22,18 @@ import shlex
import ConfigParser
import xml.etree.ElementTree as ET
import argparse
import fnmatch
IIAB_PATH='/etc/iiab'
if not IIAB_PATH in sys.path:
sys.path.append(IIAB_PATH)
from iiab_env import get_iiab_env
KIWIX_CAT = IIAB_PATH + '/kiwix_catalog.json'
# Config Files
# 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 = "/etc/iiab/iiab.ini" # comment out after testing
#iiab_ini_file = "{{ iiab_ini_file }}" # nominally /etc/iiab/iiab.ini
iiab_ini_file = "/etc/iiab/iiab.ini" # comment out after testing
IIAB_INI = get_iiab_env('IIAB_INI') # future
if IIAB_INI:
@ -46,12 +48,16 @@ kiwix_manage = iiab_base_path + "/kiwix/bin/kiwix-manage"
doc_root = get_iiab_env('WWWROOT')
zim_version_idx_dir = doc_root + "/common/assets/"
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"}
# Working variables
# 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
def main():
@ -78,31 +84,25 @@ def main():
except OSError:
pass
zims_installed = {}
path_to_array_map = {}
path_to_id_map = {}
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)
# Remove zims not in file system from library.xml
remove_list_str = ""
for item in path_to_array_map:
if item not in zim_files:
remove_list_str += str(path_to_array_map[item]) + " "
if remove_list_str:
rem_libr_xml(remove_list_str)
for item in path_to_id_map:
if item not in zim_files:
rem_libr_xml(path_to_id_map[item])
# Add zims from file system that are not in library.xml
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])
# Write Version Map
if os.path.isdir(zim_version_idx_dir):
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."
print("Writing zim_versions_idx")
write_zim_versions_idx()
sys.exit()
def get_zim_list(path):
@ -115,6 +115,7 @@ def get_zim_list(path):
for filename in flist:
zimpos = filename.find(".zim")
if zimpos != -1:
zim_info = {}
filename = filename[:zimpos]
zimname = "content/" + filename + ".zim"
zimidx = "index/" + filename + ".zim.idx"
@ -128,24 +129,25 @@ def get_zim_list(path):
wiki_name = old_zim_map[filename]
else:
ulpos = filename.rfind("_")
# but gutenberg don't - future maybe put in old_zim_map (en and fr, but instance dates may change)
if "gutenberg_" in filename:
# but old gutenberg and some other names are not canonical
if filename.rfind("-") < 0: # non-canonical name
ulpos = filename[:ulpos].rfind("_")
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
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("favicon") # don't include large favicon
zims_installed = {}
path_to_array_map = {}
path_to_id_map = {}
try:
tree = ET.parse(lib_xml_file)
root = tree.getroot()
xml_item_no = 0
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 = {}
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"
@ -154,29 +156,32 @@ def read_library_xml(lib_xml_file, kiwix_exclude_attr=[""]): # duplicated from i
if attr not in kiwix_exclude_attr:
attributes[attr] = child.attrib[attr] # copy if not id or in exclusion list
zims_installed[id] = attributes
path_to_array_map[child.attrib['path']] = xml_item_no
path_to_id_map[child.attrib['path']] = id
except IOError:
zims_installed = {}
return zims_installed, path_to_array_map
return zims_installed, path_to_id_map
def rem_libr_xml(list_str):
command = kiwix_manage + " " + kiwix_library_xml + " remove " + list_str
print command
def rem_libr_xml(id):
command = kiwix_manage + " " + kiwix_library_xml + " remove " + id
#print command
args = shlex.split(command)
outp = subprocess.check_output(args)
try:
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):
command = kiwix_manage + " " + kiwix_library_xml + " add " + zim_path + "/" + zimname
if zimidx:
command += " -i " + zim_path + "/" + zimidx
print command
#print command
args = shlex.split(command)
try:
outp = subprocess.check_output(args)
except: #skip things that don't work
print 'skipping ' + zimname
#print 'skipping ' + zimname
pass
def init():
@ -201,8 +206,102 @@ def parse_args():
parser.add_argument("-v", "--verbose", help="Print messages.", action="store_true")
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__":
# 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/
#ProxyPreserveHost On
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 }}

View file

@ -9,7 +9,7 @@ kolibri_enabled: False
kolibri_home: "{{ content_base }}/kolibri"
kolibri_http_port: 8009
kolibri_url: /kolibri/
kolibri_url: /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
kolibri_exec_path: "{{ kolibri_venv_path }}/bin/kolibri"

View file

@ -9,7 +9,7 @@
system: yes
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:
path: "{{ item }}"
owner: "{{ kolibri_user }}"
@ -20,7 +20,7 @@
- "{{ kolibri_home }}"
- "{{ kolibri_venv_path }}"
- name: Install kolibri using pip on all OS's
- name: Install latest kolibri using pip
pip:
name: kolibri
virtualenv: "{{ kolibri_venv_path }}"
@ -29,17 +29,17 @@
extra_args: --no-cache-dir
when: internet_available
- name: Run kolibri migrations
- name: Run Kolibri migrations
shell: export KOLIBRI_HOME="{{ kolibri_home }}" && "{{ kolibri_exec_path }}" manage migrate
ignore_errors: yes
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 }}"
ignore_errors: yes
when: kolibri_provision
- name: Create kolibri default facility name, admin account and language
- name: Create Kolibri default facility name, admin account and language
shell: >
export KOLIBRI_HOME="{{ kolibri_home }}" &&
"{{ kolibri_exec_path }}" manage provisiondevice --facility "{{ kolibri_facility }}"
@ -48,7 +48,7 @@
ignore_errors: yes
when: kolibri_provision
- name: Change /library/kolibri directory permissions
- name: chown -R {{ kolibri_user }}:{{ apache_user }} {{ kolibri_home }}
file:
path: "{{ kolibri_home }}"
owner: "{{ kolibri_user }}"
@ -64,6 +64,7 @@
group: root
with_items:
- { 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
systemd:
@ -73,6 +74,11 @@
daemon_reload: yes
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
systemd:
name: kolibri
@ -80,9 +86,19 @@
state: stopped
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:
dest: "{{ iiab_ini_file }}"
path: "{{ iiab_ini_file }}"
section: kolibri
option: "{{ item.option }}"
value: "{{ item.value }}"
@ -97,5 +113,5 @@
value: "{{ kolibri_exec_path }}"
- option: kolibri_port
value: "{{ kolibri_http_port }}"
- option: enabled
- option: 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