diff --git a/iiab-configure b/iiab-configure new file mode 100755 index 000000000..e0e7a58ec --- /dev/null +++ b/iiab-configure @@ -0,0 +1,52 @@ +#!/bin/bash + +INVENTORY=ansible_hosts +PLAYBOOK=iiab-from-cmdline.yml +CWD=`pwd` +IIAB_STATE_FILE=/etc/iiab/iiab_state.yml +IIAB_ENV_FILE=/etc/iiab/iiab.env + +if [ ! -f $PLAYBOOK ]; then + echo -e "\nEXITING: IIAB Playbook ""$PLAYBOOK"" not found." + echo -e "\nPlease run this in /opt/iiab/iiab (top level of the git repo)." + exit 1 +fi + +if [ -f $IIAB_ENV_FILE ]; then + STAGE=0 + if grep -q STAGE= /etc/iiab/iiab.env ; then + source /etc/iiab/iiab.env + echo -e "\nExtracted STAGE=$STAGE (counter) from /etc/iiab/iiab.env" + if ! [ "$STAGE" -eq "$STAGE" ] 2> /dev/null; then + echo -e "\nEXITING: STAGE (counter) value == ""$STAGE"" is non-integer" + exit 1 + elif [ "$STAGE" -lt 0 ] || [ "$STAGE" -gt 9 ]; then + echo -e "\nEXITING: STAGE (counter) value == ""$STAGE"" is out-of-range" + exit 1 + elif [ "$STAGE" -lt 3 ]; then + echo -e "\nEXITING: STAGE (counter) value == ""$STAGE" + echo -e "\nIIAB Stage 3 not complete." + echo -e "\nPlease run: ./iiab-install" + exit 1 + fi + else + echo -e "\nEXITING: STAGE (counter) not found" + echo -e "\nIIAB not installed." + echo -e "\nPlease run: ./iiab-install" + exit 1 + fi +else + echo -e "\nEXITING: /etc/iiab/iiab.env not found" + echo -e "\nIIAB not installed." + echo -e "\nPlease run: ./iiab-install" + exit 1 +fi + +# Workaround for (web-published) images; will go away later +if grep -q sugar $IIAB_STATE_FILE && ! grep -q mongodb $IIAB_STATE_FILE; then + echo "mongodb_installed: True" >> $IIAB_STATE_FILE +fi + +export ANSIBLE_LOG_PATH="$CWD/iiab-configure.log" +ansible -m setup -i $INVENTORY localhost ${ARGS} --connection=local | grep python +ansible-playbook -i $INVENTORY $PLAYBOOK --connection=local diff --git a/iiab-from-cmdline.yml b/iiab-from-cmdline.yml new file mode 100644 index 000000000..2dd4e0689 --- /dev/null +++ b/iiab-from-cmdline.yml @@ -0,0 +1,18 @@ +--- +- hosts: all + become: yes + + vars_files: + - vars/default_vars.yml + - vars/{{ ansible_local.local_facts.os_ver }}.yml + - /etc/iiab/local_vars.yml + - /etc/iiab/iiab_state.yml + + roles: + - { role: 0-init, tags: ['0-init'] } + - { role: 4-server-options, tags: ['4-server-options'] } + - { role: 5-xo-services, tags: ['5-xo-services'] } + - { role: 6-generic-apps, tags: ['6-generic-apps'] } + - { role: 7-edu-apps, tags: ['7-edu-apps'] } + - { role: 8-mgmt-tools, tags: ['8-mgmt-tools'] } + - { role: 9-local-addons, tags: ['9-local-addons'] } diff --git a/iiab-from-console.yml b/iiab-from-console.yml index 9756638b9..2790a34cf 100644 --- a/iiab-from-console.yml +++ b/iiab-from-console.yml @@ -6,7 +6,7 @@ - vars/default_vars.yml - vars/{{ ansible_local.local_facts.os_ver }}.yml - /etc/iiab/local_vars.yml - - /etc/iiab/config_vars.yml + - /etc/iiab/iiab_state.yml roles: - { role: 0-init, tags: ['0-init'] } diff --git a/iiab-install b/iiab-install index 734caf682..9ffa92bc9 100755 --- a/iiab-install +++ b/iiab-install @@ -3,8 +3,9 @@ # Add cmdline options for passing to ansible # Todo add proper shift to gobble up --debug --reinstall -PLAYBOOK="iiab-stages.yml" -INVENTORY="ansible_hosts" +PLAYBOOK=iiab-stages.yml +INVENTORY=ansible_hosts +IIAB_STATE_FILE=/etc/iiab/iiab_state.yml ARGS="" CWD=`pwd` OS=`grep ^ID= /etc/*release|cut -d= -f2` @@ -30,7 +31,7 @@ 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.7" or a more recent version!)\n' >&2 + echo -e ' http://download.iiab.io\n' >&2 exit 1 fi @@ -46,17 +47,18 @@ cp ./scripts/local_facts.fact /etc/ansible/facts.d/local_facts.fact echo "Placed /etc/ansible/facts.d/local_facts.fact into position." if [ ! -f $PLAYBOOK ]; then - echo "EXITING: IIAB Playbook not found." - echo "Please run 'iiab-install' from /opt/iiab/iiab (top level of git repo)." + echo "EXITING: IIAB Playbook ""$PLAYBOOK"" not found." + echo "Please run './iiab-install' from /opt/iiab/iiab (top level of git repo)." exit 1 fi if [ "$1" != "--debug" ] && [ "$1" != "--reinstall" ] && [ "$1" != "" ]; then echo "Use './iiab-install' for regular installs, or to continue an install." - echo "Use './iiab-install --reinstall' to force running all Stages 0-9." - echo "Use './iiab-install --debug' to run Stage 0, followed by Stages 3-9." - echo "Use './runrole' to run a single Stage or Role." - echo "Use './iiab-network' to run Network sections." + echo "Use './iiab-install --reinstall' to force running all Stages 0-9, followed by the Network Role." + echo "Use './iiab-install --debug' to run Stage 0, followed by Stages 3-9, followed by the Network Role." + echo "Use './iiab-configure' to run Stage 0, followed by Stages 4-9." + echo "Use './runrole' to run Stage 0, followed by a single Stage or Role." + echo "Use './iiab-network' to run Stage 0, followed by the Network Role." exit 1 fi @@ -118,12 +120,8 @@ if [ -f /etc/iiab/iiab.env ]; then exit 1 fi fi -# if XSCE is present resolveconf will not be - if grep -q XSCE /etc/iiab/iiab.env ; then - STAGE=0 - rm /etc/iiab/iiab.env - echo "Removed /etc/iiab/iiab.env effectively resetting STAGE (counter)." - elif [ "$1" == "--reinstall" ]; then + + if [ "$1" == "--reinstall" ]; then STAGE=0 ARGS="$ARGS"" --extra-vars reinstall=True" sed -i 's/^STAGE=.*/STAGE=0/' /etc/iiab/iiab.env @@ -134,20 +132,57 @@ if [ -f /etc/iiab/iiab.env ]; then echo "Wrote STAGE=2 (counter) to /etc/iiab/iiab.env" elif [ "$STAGE" -eq 9 ]; then echo -e "\nEXITING: STAGE (counter) in /etc/iiab/iiab.env shows Stage 9 Is Already Done." - echo -e "Use './iiab-install --reinstall' to force running all Stages 0-9." - echo -e "Use './iiab-install --debug' to run Stage 0, followed by Stages 3-9." - echo -e "Use './runrole' to run a single Stage or Role." - echo -e "Use './iiab-network' to run Network sections.\n\n" - exit 0 # allows rerunning http://download.iiab.io/6.7/install.txt + echo -e "Use './iiab-install --reinstall' to force running all Stages 0-9, followed by the Network Role." + echo -e "Use './iiab-install --debug' to run Stage 0, followed by Stages 3-9, followed by the Network Role." + echo -e "Use './iiab-configure' to run Stage 0, followed by Stages 4-9." + echo -e "Use './runrole' to run Stage 0, followed by a single Stage or Role." + echo -e "Use './iiab-network' to run Stage 0, followed by the Network Role.\n\n" + + exit 0 # Allows rerunning http://download.iiab.io/install.txt fi fi if [ "$STAGE" -lt 2 ] && [ "$1" == "--debug" ]; then echo -e "\n'--debug' *ignored* as STAGE (counter) < 2." fi +# TEMPORARY: Catch images up to current code to benefit from pre-installed apps +# Workaround for (web-published) images; will go away later +# Assumes /etc/iiab/iiab_state.yml is not created until (prior run of) Stage 4 but +# config_vars2.yml is present with the stage counter altered by pi-gen to be 2. +if [ -f /etc/iiab/config_vars2.yml ]; then + mv /etc/iiab/config_vars2.yml $IIAB_STATE_FILE + +# Fix up prior values in state file +# mongo role improved post image creation + if grep -q sugar $IIAB_STATE_FILE && ! grep -q mongodb $IIAB_STATE_FILE; then + echo "mongodb_installed: True" >> $IIAB_STATE_FILE + fi + +# TEMPORARY: another change to account for + sed -i -e 's/pan_bluetooth/bluetooth/' $IIAB_STATE_FILE + + if [ "$STAGE" -eq 2 ]; then + echo -e "\nCompleting Stage 3 from IIAB image (starts systemd service iiab-setup-db to run the 'mysql' role)." + systemctl start iiab-setup-db + fi + + PLAYBOOK="iiab-from-console.yml" # Stage 4-9 then Network Role + ARGS="" # Removes '--extra-vars reinstall=True' if --reinstall, BUT WHY? +# The same as --reinstall except Stage 3 is not run as there are no other functional +# changes in Stage 3 to account for post image creation, once the above is run. +# reinstall=True would force kiwix to re-download and re-install in commit +# ce2ec3b0cad76449caf3299003b5d297a3164181 +## End image catch up +fi + +# Allow iiab-install to read IIAB_STATE_FILE to not repeat installs of previous +# roles that already completed within the stage. +if [ ! -f $IIAB_STATE_FILE ]; then + touch $IIAB_STATE_FILE +fi echo -e "\nTRY TO RERUN './iiab-install' IF IT FAILS DUE TO CONNECTIVITY ISSUES ETC!\n" -echo -e "Running local playbooks....Stage 0 will now run....followed by Stages $(($STAGE + 1))-9" +echo -e "Running local Ansible playbooks...\n...Stage 0 will now run\n...followed by Stages $(($STAGE + 1))-9\n...and then the Network Role.\n" export ANSIBLE_LOG_PATH="$CWD""/iiab-install.log" diff --git a/iiab-network.yml b/iiab-network.yml index 01f594449..13a490ed0 100644 --- a/iiab-network.yml +++ b/iiab-network.yml @@ -6,7 +6,7 @@ - vars/default_vars.yml - vars/{{ ansible_local.local_facts.os_ver }}.yml - /etc/iiab/local_vars.yml - - /etc/iiab/config_vars.yml + - /etc/iiab/iiab_state.yml roles: - { role: 0-init, tags: ['network'] } diff --git a/iiab-stages.yml b/iiab-stages.yml index 35db6f84f..0c1aef6f0 100644 --- a/iiab-stages.yml +++ b/iiab-stages.yml @@ -7,6 +7,7 @@ - vars/default_vars.yml - vars/{{ ansible_local.local_facts.os_ver }}.yml - /etc/iiab/local_vars.yml + - /etc/iiab/iiab_state.yml tasks: diff --git a/roles/2-common/tasks/pylib.yml b/roles/2-common/tasks/pylib.yml index 235aa7a37..47b870f95 100644 --- a/roles/2-common/tasks/pylib.yml +++ b/roles/2-common/tasks/pylib.yml @@ -7,4 +7,5 @@ mode: 0644 with_items: - { src: 'iiab_const.py.j2', dest: '{{ py3_dist_path }}/iiab/iiab_const.py' } - - { src: 'iiab_lib.py', dest: '{{ py3_dist_path }}/iiab/iiab_lib.py' } \ No newline at end of file + - { src: 'iiab_lib.py', dest: '{{ py3_dist_path }}/iiab/iiab_lib.py' } + - { src: 'iiab_env.py.j2', dest: '{{ iiab_etc_path }}/iiab_env.py' } diff --git a/roles/1-prep/templates/iiab_env.py.j2 b/roles/2-common/templates/iiab_env.py.j2 similarity index 97% rename from roles/1-prep/templates/iiab_env.py.j2 rename to roles/2-common/templates/iiab_env.py.j2 index 78c4869be..d639d4d01 100644 --- a/roles/1-prep/templates/iiab_env.py.j2 +++ b/roles/2-common/templates/iiab_env.py.j2 @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # read iiab.env from python def get_iiab_env(name): diff --git a/roles/2-common/templates/iiab_lib.py b/roles/2-common/templates/iiab_lib.py index 212437714..71b71be2f 100644 --- a/roles/2-common/templates/iiab_lib.py +++ b/roles/2-common/templates/iiab_lib.py @@ -1,27 +1,30 @@ -# iiab_lib.py -# common functions for IIAB -# Admin Console functions are in adm_lib.py - -import os, sys, syslog -import pwd, grp -import time -from datetime import date, datetime +''' +Common functions for IIAB +Admin Console functions are in adm_lib.py +''' +import os import json -import yaml -import re import subprocess import shlex -import configparser import xml.etree.ElementTree as ET -import argparse -import iiab.iiab_const as cons +import iiab.iiab_const as CONST lang_codes = {} def get_zim_list(path): + ''' + Get a list of installed zims in the passed path + + Args: + path (str): The path to search + + Returns: + files_processed (dict): A dict all zims found and any index directory (now obsolete) + zim_versions (dict): A dict that translates generic zim names to physically installed + ''' + files_processed = {} zim_versions = {} # we don't need this unless adm cons is installed, but easier to compute now - zim_list = [] content = path + "/content/" index = path + "/index/" flist = os.listdir(content) @@ -34,13 +37,13 @@ def get_zim_list(path): zimname = "content/" + filename + ".zim" zimidx = "index/" + filename + ".zim.idx" if zimname not in files_processed: - if not os.path.isdir (path + "/" + zimidx): # only declare index if exists (could be embedded) + if not os.path.isdir(path + "/" + zimidx): # only declare index if exists (could be embedded) zimidx = None files_processed[zimname] = zimidx zimname = content + filename + ".zim" zimidx = index + filename + ".zim.idx" - if filename in cons.old_zim_map: # handle old names that don't parse - perma_ref = cons.old_zim_map[filename] + if filename in CONST.old_zim_map: # handle old names that don't parse + perma_ref = CONST.old_zim_map[filename] else: ulpos = filename.rfind("_") # but old gutenberg and some other names are not canonical @@ -52,7 +55,18 @@ def get_zim_list(path): return files_processed, zim_versions def read_library_xml(lib_xml_file, kiwix_exclude_attr=[""]): # duplicated from iiab-cmdsrv - # returns dict of library.xml and map of zim id to zim file name (under /library/zims) + ''' + Read zim properties from library.xml + Returns dict of library.xml and map of zim id to zim file name (under /library/zims) + + Args: + lib_xml_file (str): Path to file to read. Can be on removable device + kiwix_exclude_attr (list): Zim properties to exclude from return + + Returns: + zims_installed (dict): A dictionary holding all installed zims and their attributes + path_to_id_map (dict): A dictionary that translates zim ids to physical names + ''' kiwix_exclude_attr.append("id") # don't include id kiwix_exclude_attr.append("favicon") # don't include large favicon @@ -61,24 +75,30 @@ def read_library_xml(lib_xml_file, kiwix_exclude_attr=[""]): # duplicated from i 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 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") - id = child.attrib['id'] + zim_id = child.attrib['id'] for attr in child.attrib: 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_id_map[child.attrib['path']] = id + zims_installed[zim_id] = attributes + path_to_id_map[child.attrib['path']] = zim_id except IOError: zims_installed = {} return zims_installed, path_to_id_map -def rem_libr_xml(id): - command = cons.kiwix_manage + " " + kiwix_library_xml + " remove " + id +def rem_libr_xml(zim_id, kiwix_library_xml): + ''' + Remove a zim from library.xml + + Args: + zim_id (uuid): Id of the zim to remove + lib_xml_file (str): Path to file to read. Can be on removable device + ''' + + command = CONST.kiwix_manage + " " + kiwix_library_xml + " remove " + zim_id #print command args = shlex.split(command) try: @@ -88,7 +108,17 @@ def rem_libr_xml(id): print(outp) def add_libr_xml(kiwix_library_xml, zim_path, zimname, zimidx): - command = cons.kiwix_manage + " " + kiwix_library_xml + " add " + cons.zim_path + "/" + zimname + ''' + Add a zim to library.xml + + Args: + kiwix_library_xml (str): Name (path) of library.xml file + zim_path (str): Path to zim file to add + zimname (str): Name of zim file to add + zimidx (str): Path to separate idx directory (obsolete) + + ''' + command = CONST.kiwix_manage + " " + kiwix_library_xml + " add " + zim_path + "/" + zimname if zimidx: command += " -i " + zim_path + "/" + zimidx #print command @@ -101,8 +131,10 @@ def add_libr_xml(kiwix_library_xml, zim_path, zimname, zimidx): pass def read_lang_codes(): + '''Populate the global lang_codes dictionary from CONST.lang_codes_path json file''' + global lang_codes - with open(cons.lang_codes_path,"r") as f: + with open(CONST.lang_codes_path, "r") as f: reads = f.read() #print("menu.json:%s"%reads) lang_codes = json.loads(reads) @@ -110,6 +142,7 @@ def read_lang_codes(): # there is a different algorithm in get_zim_list above def calc_perma_ref(uri): + '''Given a path or url return the generic zim name''' url_slash = uri.split('/') url_end = url_slash[-1] # last element file_ref = url_end.split('.zim')[0] # true for both internal and external index @@ -123,30 +156,32 @@ def calc_perma_ref(uri): return perma_ref def kiwix_lang_to_iso2(zim_lang_code): + '''Lookup the iso2 equivalent of a zim language code''' return lang_codes[zim_lang_code]['iso2'] def human_readable(num): + '''Convert a number to a human readable string''' # return 3 significant digits and unit specifier # TFM 7/15/2019 change to factor of 1024, not 1000 to match similar calcs elsewhere num = float(num) - units = [ '','K','M','G'] + 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 < 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]) + return "%.0f%s"%(num, units[i]) num /= 1024.0 # Environment Functions def get_iiab_env(name): - """ read iiab.env file for a value, return "" if does not exist. return all value for *""" + ''' read iiab.env file for a value, return "" if does not exist. return all value for *''' iiab_env = {} iiab_env_var = '' try: - fd = open(cons.iiab_env_file,"r") + fd = open("/etc/iiab/iiab.env", "r") for line in fd: line = line.lstrip() line = line.rstrip('\n') diff --git a/roles/3-base-server/tasks/main.yml b/roles/3-base-server/tasks/main.yml index 2b1672f1a..b332c0f21 100644 --- a/roles/3-base-server/tasks/main.yml +++ b/roles/3-base-server/tasks/main.yml @@ -6,7 +6,7 @@ - name: HTTPD (APACHE) include_role: name: httpd - # has no "when: XXXXX_install" flag + when: apache_install tags: base, httpd - name: MYSQL @@ -15,11 +15,14 @@ # has no "when: XXXXX_install" flag tags: base, mysql -- name: Restart Apache systemd service ({{ apache_service }}) - systemd: - name: "{{ apache_service }}" - state: restarted - when: not installing +- name: Install nginx + include_tasks: roles/nginx/tasks/install.yml + when: nginx_install + +- name: Install dnsmasq + include_tasks: roles/network/tasks/dnsmasq.yml + when: dnsmasq_install + tags: base, domain, dnsmasq, network - name: Recording STAGE 3 HAS COMPLETED ===================== lineinfile: diff --git a/roles/4-server-options/tasks/main.yml b/roles/4-server-options/tasks/main.yml index ab3f97da4..e0740cf93 100644 --- a/roles/4-server-options/tasks/main.yml +++ b/roles/4-server-options/tasks/main.yml @@ -1,12 +1,9 @@ # Server Options - name: ...IS BEGINNING ================================== - command: echo - -- name: Install dnsmasq - include_tasks: roles/network/tasks/dnsmasq.yml - when: dnsmasq_install | bool - tags: base, domain, dnsmasq, network + file: + path: "{{ iiab_state_file }}" + state: touch - name: Install named / BIND include_tasks: roles/network/tasks/named.yml @@ -26,7 +23,7 @@ - name: Install Bluetooth - only on Raspberry Pi include_role: name: bluetooth - when: is_rpi and bluetooth_install + when: (is_rpi and bluetooth_install) or bluetooth_installed is defined tags: bluetooth - name: USB-LIB @@ -60,13 +57,13 @@ - name: CUPS include_role: name: cups - when: cups_install | bool + when: cups_install or cups_installed is defined tags: cups - name: SAMBA include_role: name: samba - when: samba_install | bool + when: samba_install or samba_installed is defined tags: samba - 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) diff --git a/roles/6-generic-apps/tasks/main.yml b/roles/6-generic-apps/tasks/main.yml index d1b9b8d7f..c6edbf859 100644 --- a/roles/6-generic-apps/tasks/main.yml +++ b/roles/6-generic-apps/tasks/main.yml @@ -6,19 +6,16 @@ - name: AZURACAST include_role: name: azuracast - when: azuracast_install | bool tags: azuracast - name: DOKUWIKI include_role: name: dokuwiki - when: dokuwiki_install | bool tags: dokuwiki - name: MEDIAWIKI include_role: name: mediawiki - when: mediawiki_install | bool tags: mediawiki # UNMAINTAINED @@ -31,37 +28,31 @@ - name: ELGG include_role: name: elgg - when: elgg_install | bool tags: elgg - name: GITEA include_role: name: gitea - when: gitea_install | bool tags: gitea - name: LOKOLE include_role: name: lokole - when: lokole_install | bool tags: lokole - name: MOSQUITTO include_role: name: mosquitto - when: mosquitto_install | bool tags: mosquitto - name: NODE-RED include_role: name: nodered - when: nodered_install | bool tags: nodered - name: NEXTCLOUD include_role: name: nextcloud - when: nextcloud_install | bool tags: nextcloud #- name: OWNCLOUD @@ -79,7 +70,6 @@ - name: WORDPRESS include_role: name: wordpress - when: wordpress_install | bool tags: wordpress - name: Recording STAGE 6 HAS COMPLETED ==================== diff --git a/roles/7-edu-apps/tasks/main.yml b/roles/7-edu-apps/tasks/main.yml index 7c6d89823..49711b407 100644 --- a/roles/7-edu-apps/tasks/main.yml +++ b/roles/7-edu-apps/tasks/main.yml @@ -6,31 +6,26 @@ - name: KALITE include_role: name: kalite - when: kalite_install | bool tags: kalite - name: KOLIBRI include_role: name: kolibri - when: kolibri_install | bool tags: kolibri - name: KIWIX include_role: name: kiwix - when: kiwix_install | bool tags: kiwix - name: MOODLE include_role: name: moodle - when: moodle_install | bool tags: olpc, moodle - name: OSM-VECTOR-MAPS include_role: name: osm-vector-maps - when: osm_vector_maps_install | bool tags: osm, maps # UNMAINTAINED @@ -50,7 +45,6 @@ - name: SUGARIZER include_role: name: sugarizer - when: sugarizer_install | bool tags: sugarizer - name: Recording STAGE 7 HAS COMPLETED ======================== diff --git a/roles/8-mgmt-tools/tasks/main.yml b/roles/8-mgmt-tools/tasks/main.yml index 9536032b8..c7547d2ac 100644 --- a/roles/8-mgmt-tools/tasks/main.yml +++ b/roles/8-mgmt-tools/tasks/main.yml @@ -12,7 +12,6 @@ - name: AWSTATS include_role: name: awstats - when: awstats_install | bool tags: awstats - name: MONIT @@ -24,7 +23,6 @@ - name: MUNIN include_role: name: munin - when: munin_install | bool tags: munin - name: PHPMYADMIN diff --git a/roles/9-local-addons/tasks/main.yml b/roles/9-local-addons/tasks/main.yml index 4af8db305..4837c55e0 100644 --- a/roles/9-local-addons/tasks/main.yml +++ b/roles/9-local-addons/tasks/main.yml @@ -6,23 +6,17 @@ - name: INTERNETARCHIVE include_role: name: internetarchive - when: internetarchive_install | bool tags: internetarchive # Until porting complete (@jvonau helping transition to Python 3) -- name: 'Install Python 2.7 packages: python, python-pip' - package: - name: - - python - - python-pip # Used by Admin Console - state: present - -# Used by iiab-update-map, supplied by osm-vector-maps -- 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: 'Install Python 2.7 packages: python, python-pip' +# package: +# name: +# - python +# - python-pip # Used by Admin Console +# state: present +# To be ported soon - name: CAPTIVE PORTAL include_tasks: roles/captive-portal/tasks/main.yml when: captive_portal_install | bool @@ -31,22 +25,32 @@ - name: MINETEST include_role: name: minetest - when: minetest_install | bool tags: minetest # KEEP AT THE END as this installs dependencies from Debian's 'testing' branch! - name: CALIBRE include_role: name: calibre - when: calibre_install | bool tags: calibre - name: CALIBRE-WEB include_role: name: calibre-web - when: calibreweb_install | bool tags: calibre-web +# could split this two below to stage 10? +- name: Configure NGINX + include_role: + name: nginx + when: nginx_install + tags: base, nginx + +- name: Configure Apache systemd service ({{ apache_service }}) + include_role: + name: httpd-enable + when: apache_install + tags: base, httpd + - name: Recording STAGE 9 HAS COMPLETED ==================== lineinfile: dest: "{{ iiab_env_file }}" diff --git a/roles/awstats/tasks/enable.yml b/roles/awstats/tasks/enable.yml new file mode 100644 index 000000000..a80db27db --- /dev/null +++ b/roles/awstats/tasks/enable.yml @@ -0,0 +1,58 @@ +- name: Create symlink awstats.conf from sites-enabled to sites-available (Apache) + file: + src: /etc/apache2/sites-available/awstats.conf + path: /etc/apache2/sites-enabled/awstats.conf + state: link + when: awstats_enabled and not nginx_enabled + +- name: Remove symlink from sites-enabled, to disable AWStats (Apache) + file: + path: /etc/apache2/sites-enabled/awstats.conf + state: absent + when: not awstats_enabled or nginx_enabled + +- name: Install nginx's files from template + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: 0644 + with_items: + - { src: "awstats-nginx.conf", dest: "/etc/nginx/conf.d/" } + - { src: "cgi-bin.php", dest: "/etc/nginx/" } + when: awstats_enabled and nginx_enabled + +- name: Remove /etc/nginx/conf.d/awstats-nginx.conf + file: + path: /etc/nginx/conf.d/awstats-nginx.conf + state: absent + when: not awstats_enabled + +- name: Restart Apache service ({{ apache_service }}) + systemd: + name: "{{ apache_service }}" + state: restarted + when: awstats_enabled and not nginx_enabled + +- name: Restart nginx service + systemd: + name: nginx + state: restarted + when: awstats_enabled and nginx_enabled + +- name: Add 'awstats' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: awstats + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: AWStats + - option: description + value: '"AWStats (originally known as Advanced Web Statistics) is a package written in Perl which generates static or dynamic html summaries based upon web server logs."' + - option: installed + value: "{{ awstats_install }}" + - option: enabled + value: "{{ awstats_enabled }}" diff --git a/roles/awstats/tasks/install.yml b/roles/awstats/tasks/install.yml index ca971d973..ca62368e0 100644 --- a/roles/awstats/tasks/install.yml +++ b/roles/awstats/tasks/install.yml @@ -18,7 +18,6 @@ tags: - download -# SEE ALSO THE apache2_module SECTION IN roles/httpd/tasks/main.yml - name: Enable cgi execution (debuntu) command: a2enmod cgi when: is_debuntu | bool @@ -35,25 +34,21 @@ with_items: - "{{ awstats_data_dir }}" - "{{ apache_log_dir }}" + - /usr/lib/cgi-bin/awstats # create backward compatible path for awstats - name: Install Apache's awstats.conf from template (debuntu) template: - src: apache.conf - dest: "/etc/{{ apache_config_dir }}/awstats.conf" + src: "{{ item.src }}" + dest: "{{ item.dest }}" owner: root group: root mode: 0644 + with_items: +# - { src: "awstats-nginx.conf", dest: "/etc/nginx/conf.d/" } +# - { src: "cgi-bin.php", dest: "/etc/nginx/" } + - { src: "apache-awstats.conf", dest: "/etc/{{ apache_config_dir }}/awstats.conf" } when: awstats_enabled and is_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" - owner: root - group: root - mode: 0644 - when: awstats_enabled and not is_debuntu - - name: Ensure logrotate doesn't make logs unreadable (debuntu) template: src: logrotate.d.apache2 @@ -69,24 +64,11 @@ command: mv /etc/awstats/awstats.conf /etc/awstats/awstats.conf.dist when: awstats.stat.islnk is defined and not awstats.stat.islnk -- name: Create symlink awstats.conf from sites-enabled to sites-available (debuntu) +- name: Create symlink for awstats.pl from cgi-bin/awstats/awstats.pl to ../ so that the old apache links to awstats will work after change to nginx file: - src: /etc/apache2/sites-available/awstats.conf - path: /etc/apache2/sites-enabled/awstats.conf + src: /usr/lib/cgi-bin/awstats.pl + path: /usr/lib/cgi-bin/awstats/awstats.pl state: link - when: awstats_enabled and is_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 /etc/awstats/awstats.schoolserver.conf template: @@ -111,3 +93,10 @@ - name: On first enabling of AWStats, summarize httpd logs up to now (debuntu) shell: /usr/bin/perl /usr/lib/cgi-bin/awstats.pl -config=schoolserver -update when: awstats_enabled and is_debuntu + +- name: Add 'awstats_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^awstats_installed' + line: 'awstats_installed: True' + state: present diff --git a/roles/awstats/tasks/main.yml b/roles/awstats/tasks/main.yml index 26b53df88..b249b6a22 100644 --- a/roles/awstats/tasks/main.yml +++ b/roles/awstats/tasks/main.yml @@ -1,19 +1,7 @@ - name: Install AWStats if awstats_install include_tasks: install.yml - when: awstats_install | bool + when: awstats_install | bool and not awstats_installed is defined -- name: Add 'awstats' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" - section: awstats - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: AWStats - - option: description - value: '"AWStats (originally known as Advanced Web Statistics) is a package written in Perl which generates static or dynamic html summaries based upon web server logs."' - - option: installed - value: "{{ awstats_install }}" - - option: enabled - value: "{{ awstats_enabled }}" +- name: Enable AWStats + include_tasks: enable.yml + when: awstats_install | bool or awstats_installed is defined diff --git a/roles/awstats/templates/awstats-nginx.conf b/roles/awstats/templates/awstats-nginx.conf new file mode 100644 index 000000000..1f337c297 --- /dev/null +++ b/roles/awstats/templates/awstats-nginx.conf @@ -0,0 +1,24 @@ +location ~ ^/awstats { + rewrite ^ http://box.lan/cgi-bin/awstats.pl?config=schoolserver; +} +location ^~ /awstatsicons { + alias /usr/share/awstats/icon/; + access_log off; +} +location ^~ /awstatsclasses { + alias /usr/share/java/awstats/; + access_log off; +} + +location ~ ^/cgi-bin/.*\.(cgi|pl|py|rb) { + gzip off; + include fastcgi_params; + fastcgi_pass php; + fastcgi_index cgi-bin.php; + fastcgi_param SCRIPT_FILENAME /etc/nginx/cgi-bin.php; + fastcgi_param SCRIPT_NAME cgi-bin.php; + fastcgi_param X_SCRIPT_FILENAME /usr/lib$fastcgi_script_name; + fastcgi_param X_SCRIPT_NAME $fastcgi_script_name; + fastcgi_param REMOTE_USER $remote_user; +} + diff --git a/roles/awstats/templates/awstats.schoolserver.conf.j2 b/roles/awstats/templates/awstats.schoolserver.conf.j2 index c9f1a6620..abf4d9f41 100644 --- a/roles/awstats/templates/awstats.schoolserver.conf.j2 +++ b/roles/awstats/templates/awstats.schoolserver.conf.j2 @@ -49,7 +49,7 @@ # {% if is_debuntu %} -LogFile="/usr/share/awstats/tools/logresolvemerge.pl /var/log/{{ apache_service }}/access.log* |" +LogFile="/usr/share/awstats/tools/logresolvemerge.pl {{ apache_log_dir }}/access.log* |" {% else %} LogFile="/usr/share/awstats/tools/logresolvemerge.pl /var/log/httpd/access_log* |" {% endif %} diff --git a/roles/awstats/templates/cgi-bin.php b/roles/awstats/templates/cgi-bin.php new file mode 100644 index 000000000..a1bced748 --- /dev/null +++ b/roles/awstats/templates/cgi-bin.php @@ -0,0 +1,32 @@ + array("pipe", "r"), // stdin is a pipe that the child will read from + 1 => array("pipe", "w"), // stdout is a pipe that the child will write to + 2 => array("pipe", "w") // stderr is a file to write to +); +$newenv = $_SERVER; +$newenv["SCRIPT_FILENAME"] = $_SERVER["X_SCRIPT_FILENAME"]; +$newenv["SCRIPT_NAME"] = $_SERVER["X_SCRIPT_NAME"]; +if (is_executable($_SERVER["X_SCRIPT_FILENAME"])) { + $process = proc_open($_SERVER["X_SCRIPT_FILENAME"], $descriptorspec, $pipes, NULL, $newenv); + if (is_resource($process)) { + fclose($pipes[0]); + $head = fgets($pipes[1]); + while (strcmp($head, "\n")) { + header($head); + $head = fgets($pipes[1]); + } + fpassthru($pipes[1]); + fclose($pipes[1]); + fclose($pipes[2]); + $return_value = proc_close($process); + } else { + header("Status: 500 Internal Server Error"); + echo("Internal Server Error"); + } +} else { + header("Status: 404 Page Not Found"); + echo("Page Not Found"); +} diff --git a/roles/azuracast/tasks/enable.yml b/roles/azuracast/tasks/enable.yml new file mode 100644 index 000000000..e69de29bb diff --git a/roles/azuracast/tasks/install.yml b/roles/azuracast/tasks/install.yml index 966ce50ee..954154bcd 100644 --- a/roles/azuracast/tasks/install.yml +++ b/roles/azuracast/tasks/install.yml @@ -63,3 +63,10 @@ shell: "/bin/bash docker.sh install" args: chdir: "{{ azuracast_host_dir }}" + +- name: Add 'azuracast_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^azuracast_installed' + line: 'azuracast_installed: True' + state: present diff --git a/roles/azuracast/tasks/main.yml b/roles/azuracast/tasks/main.yml index 1ace204c8..efa0fe446 100644 --- a/roles/azuracast/tasks/main.yml +++ b/roles/azuracast/tasks/main.yml @@ -1,3 +1,8 @@ - name: Install AzuraCast if azuracast_install include_tasks: install.yml - when: azuracast_install | bool + when: azuracast_install | bool and not azuracast_installed is defined | bool + +# TODO figure out what to turn off for azuracast +#- name: Enable AzuraCast +# include_tasks: enable.yml +# when: azuracast_install | bool or azuracast_installed is defined | bool diff --git a/roles/bluetooth/tasks/enable.yml b/roles/bluetooth/tasks/enable.yml new file mode 100644 index 000000000..9696cdcb3 --- /dev/null +++ b/roles/bluetooth/tasks/enable.yml @@ -0,0 +1,73 @@ +- name: Enable & Restart 'bt-agent' service + systemd: + daemon_reload: yes + name: bluetooth + enabled: yes + state: restarted + +# enable or disable bt-agent +- name: Enable & Restart 'bt-agent' service + systemd: + daemon_reload: yes + name: bt-agent + enabled: yes + state: restarted + when: bluetooth_enabled or bluetooth_term_enabled + +- name: Disable 'bt-agent' service + systemd: + daemon_reload: yes + name: bt-agent + enabled: no + state: stopped + when: not bluetooth_enabled and not bluetooth_term_enabled + +# enable or disable bt-pan +- name: Enable & Restart 'bt-pan' service + systemd: + daemon_reload: yes + name: bt-pan + enabled: yes + state: restarted + when: bluetooth_enabled | bool + +- name: Disable 'bt-pan' service + systemd: + daemon_reload: yes + name: bt-pan + enabled: no + state: stopped + when: not bluetooth_enabled | bool + +# enable or disable bt-term +- name: Enable & Restart 'bt-term' service + systemd: + daemon_reload: yes + name: bt-term + enabled: yes + state: restarted + when: bluetooth_term_enabled | bool + +- name: Disable 'bt-term' service + systemd: + daemon_reload: yes + name: bt-term + enabled: no + state: stopped + when: not bluetooth_term_enabled | bool + +- name: Add 'bluetooth' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: bluetooth + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: Bluetooth + - option: description + value: '"Bluetooth services for pan and terminal."' + - option: bluetooth_enabled + value: "{{ bluetooth_enabled }}" + - option: bluetooth_term_enabled + value: "{{ bluetooth_term_enabled }}" diff --git a/roles/bluetooth/tasks/install.yml b/roles/bluetooth/tasks/install.yml new file mode 100644 index 000000000..e60d2cc6e --- /dev/null +++ b/roles/bluetooth/tasks/install.yml @@ -0,0 +1,63 @@ +- name: "Install bluetooth packages" + package: + name: + - bluetooth + - bluez + - bluez-tools + state: present + +- name: Create bluetooth services + template: + backup: no + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: 0644 + with_items: + - { src: 'bt-agent.service.j2', dest: '/etc/systemd/system/bt-agent.service' } + - { src: 'bt-pan.service.j2', dest: '/etc/systemd/system/bt-pan.service' } + - { src: 'bt-term.service.j2', dest: '/etc/systemd/system/bt-term.service' } + - { src: 'network.conf.j2', dest: '/etc/bluetooth/network.conf' } + +- name: Create bluetooth utility scripts + template: + backup: no + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: 0755 + with_items: + - { src: 'iiab-bt-pan-on.j2', dest: '/usr/bin/iiab-bt-pan-on' } + - { src: 'iiab-bt-pan-off.j2', dest: '/usr/bin/iiab-bt-pan-off' } + - { src: 'iiab-bt-pan-discoverable-on.j2', dest: '/usr/bin/iiab-bt-pan-discoverable-on' } + - { src: 'iiab-bt-term-on.j2', dest: '/usr/bin/iiab-bt-term-on' } + - { src: 'iiab-bt-term-off.j2', dest: '/usr/bin/iiab-bt-term-off' } + +# Bluetooth service needs /usr/lib/bluetooth/bluetoothd -C --noplugin=sap +# Copy and patch it + +- name: Copy the bluetooth service + template: + dest: /etc/systemd/system/bluetooth.service + src: /lib/systemd/system/bluetooth.service + +- name: Add -C --noplugin=sap to execStart of bluetooth service + lineinfile: + path: /etc/systemd/system/bluetooth.service + regexp: '^ExecStart=/usr/lib/bluetooth/bluetoothd' + line: 'ExecStart=/usr/lib/bluetooth/bluetoothd -C --noplugin=sap' + +- name: Set discoverable not to timeout + lineinfile: + path: /etc/bluetooth/main.conf + regexp: '^#DiscoverableTimeout' + line: 'DiscoverableTimeout = 0' + +- name: Add 'bluetooth_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^bluetooth_installed' + line: 'bluetooth_installed: True' + state: present diff --git a/roles/bluetooth/tasks/main.yml b/roles/bluetooth/tasks/main.yml index 421b9c63e..25953ddeb 100644 --- a/roles/bluetooth/tasks/main.yml +++ b/roles/bluetooth/tasks/main.yml @@ -1,4 +1,6 @@ -# This is rpi only +- include_tasks: install.yml + when: bluetooth_install and not bluetooth_installed is defined + +- include_tasks: enable.yml + when: bluetooth_install or bluetooth_installed is defined -- include_tasks: rpi_install.yml - when: is_rpi and bluetooth_install diff --git a/roles/bluetooth/tasks/rpi_install.yml b/roles/bluetooth/tasks/rpi_install.yml deleted file mode 100644 index 2fa925c53..000000000 --- a/roles/bluetooth/tasks/rpi_install.yml +++ /dev/null @@ -1,132 +0,0 @@ -# This is rpi only - -- name: "Install rpi bluetooth packages" - package: - name: - - bluetooth - - bluez - - bluez-tools - state: present - -- name: Create bluetooth services - template: - backup: no - src: "{{ item.src }}" - dest: "{{ item.dest }}" - owner: root - group: root - mode: 0644 - with_items: - - { src: 'bt-agent.service.j2', dest: '/etc/systemd/system/bt-agent.service' } - - { src: 'bt-pan.service.j2', dest: '/etc/systemd/system/bt-pan.service' } - - { src: 'bt-term.service.j2', dest: '/etc/systemd/system/bt-term.service' } - - { src: 'network.conf.j2', dest: '/etc/bluetooth/network.conf' } - -- name: Create bluetooth utility scripts - template: - backup: no - src: "{{ item.src }}" - dest: "{{ item.dest }}" - owner: root - group: root - mode: 0755 - with_items: - - { src: 'iiab-bt-pan-on.j2', dest: '/usr/bin/iiab-bt-pan-on' } - - { src: 'iiab-bt-pan-off.j2', dest: '/usr/bin/iiab-bt-pan-off' } - - { src: 'iiab-bt-pan-discoverable-on.j2', dest: '/usr/bin/iiab-bt-pan-discoverable-on' } - - { src: 'iiab-bt-term-on.j2', dest: '/usr/bin/iiab-bt-term-on' } - - { src: 'iiab-bt-term-off.j2', dest: '/usr/bin/iiab-bt-term-off' } - -# Bluetooth service needs /usr/lib/bluetooth/bluetoothd -C --noplugin=sap -# Copy and patch it - -- name: Copy the bluetooth service - template: - dest: /etc/systemd/system/bluetooth.service - src: /lib/systemd/system/bluetooth.service - -- name: Add -C --noplugin=sap to execStart of bluetooth service - lineinfile: - path: /etc/systemd/system/bluetooth.service - regexp: '^ExecStart=/usr/lib/bluetooth/bluetoothd' - line: 'ExecStart=/usr/lib/bluetooth/bluetoothd -C --noplugin=sap' - -- name: Set discoverable not to timeout - lineinfile: - path: /etc/bluetooth/main.conf - regexp: '^#DiscoverableTimeout' - line: 'DiscoverableTimeout = 0' - -- name: Enable & Restart 'bt-agent' service - systemd: - daemon_reload: yes - name: bluetooth - enabled: yes - state: restarted - -# enable or disable bt-agent -- name: Enable & Restart 'bt-agent' service - systemd: - daemon_reload: yes - name: bt-agent - enabled: yes - state: restarted - when: bluetooth_enabled or bluetooth_term_enabled - -- name: Disable 'bt-agent' service - systemd: - daemon_reload: yes - name: bt-agent - enabled: no - state: stopped - when: not bluetooth_enabled and not bluetooth_term_enabled - -# enable or disable bt-pan -- name: Enable & Restart 'bt-pan' service - systemd: - daemon_reload: yes - name: bt-pan - enabled: yes - state: restarted - when: bluetooth_enabled | bool - -- name: Disable 'bt-pan' service - systemd: - daemon_reload: yes - name: bt-pan - enabled: no - state: stopped - when: not bluetooth_enabled | bool - -# enable or disable bt-term -- name: Enable & Restart 'bt-term' service - systemd: - daemon_reload: yes - name: bt-term - enabled: yes - state: restarted - when: bluetooth_term_enabled | bool - -- name: Disable 'bt-term' service - systemd: - daemon_reload: yes - name: bt-term - enabled: no - state: stopped - when: not bluetooth_term_enabled | bool - -- name: Add 'bluetooth' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" - section: bluetooth - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: Bluetooth - - option: description - value: '"Bluetooth services for pan and terminal."' - - option: bluetooth_enabled - value: "{{ bluetooth_enabled }}" - - option: bluetooth_term_enabled - value: "{{ bluetooth_term_enabled }}" diff --git a/roles/calibre-web/tasks/enable.yml b/roles/calibre-web/tasks/enable.yml new file mode 100644 index 000000000..244c8b942 --- /dev/null +++ b/roles/calibre-web/tasks/enable.yml @@ -0,0 +1,86 @@ +- name: Enable & Restart 'calibre-web' systemd service + systemd: + name: calibre-web + daemon_reload: yes + enabled: yes + state: restarted + when: calibreweb_enabled | bool + +# Default: http://box/books +# SEE ALSO: https://github.com/janeczku/calibre-web/wiki/Setup-Reverse-Proxy +- name: Enable http://box{{ calibreweb_url1 }}, http://box{{ calibreweb_url2 }}, http://box{{ calibreweb_url3 }} with Apache + command: a2ensite calibre-web.conf + when: calibreweb_enabled | bool + +#- name: Restart Apache after enabling calibre-web httpd2 site +# command: apachectl -k graceful +# when: calibreweb_enabled | bool + +- name: Disable 'calibre-web' systemd service + systemd: + name: calibre-web + daemon_reload: yes + enabled: no + state: stopped + when: not calibreweb_enabled + +- name: Disable http://box{{ calibreweb_url1 }}, http://box{{ calibreweb_url2 }}, http://box{{ calibreweb_url3 }} with Apache + command: a2dissite calibre-web.conf + when: not calibreweb_enabled or nginx_enabled | bool + +#- name: Restart Apache after disabling calibre-web httpd2 site +# command: apachectl -k graceful +# when: not calibreweb_enabled + +- name: Install /etc/nginx/conf.d/calibre-web-nginx.conf + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + mode: "{{ item.mode }}" + owner: root + group: root + with_items: + - { src: 'calibre-web-nginx.conf.j2', dest: '/etc/nginx/conf.d/calibre-web-nginx.conf', mode: '0644' } + when: calibreweb_enabled | bool and nginx_enabled | bool + +- name: Restart nginx systemd service + systemd: + name: nginx + state: restarted + when: calibreweb_enabled | bool and nginx_enabled | bool + +- name: Restart Apache systemd service ({{ apache_service }}) + systemd: + name: "{{ apache_service }}" # httpd or apache2 + state: restarted + when: not nginx_enabled | bool + +- name: Add 'calibre-web' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: calibre-web + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: calibre-web + - option: description + value: '"calibre-web is a web app providing a clean interface for browsing, reading and downloading e-books."' + - option: calibreweb_url1 + value: "{{ calibreweb_url1 }}" + - option: calibreweb_url2 + value: "{{ calibreweb_url2 }}" + - option: calibreweb_url3 + value: "{{ calibreweb_url3 }}" + - option: calibreweb_path + value: "{{ calibreweb_venv_path }}" + - option: calibreweb_home + value: "{{ calibreweb_home }}" + - option: calibreweb_port + value: "{{ calibreweb_port }}" + - option: calibreweb_database + value: "{{ calibreweb_database }}" + - option: calibreweb_enabled + value: "{{ calibreweb_enabled }}" +# - option: calibreweb_provision +# value: "{{ calibreweb_provision }}" diff --git a/roles/calibre-web/tasks/install.yml b/roles/calibre-web/tasks/install.yml new file mode 100644 index 000000000..eadd5cb88 --- /dev/null +++ b/roles/calibre-web/tasks/install.yml @@ -0,0 +1,110 @@ +- name: Install ImageMagick (debuntu) + package: + name: + - imagemagick + state: present + when: is_debuntu | bool + +- name: Allow ImageMagick to read PDFs (debuntu) + lineinfile: + path: /etc/ImageMagick-6/policy.xml + regexp: '' + backrefs: yes + line: ' ' + state: present + when: is_debuntu | bool + +- name: Create 3 Calibre-Web folders to store data and configuration files + file: + path: "{{ item }}" + owner: "{{ calibreweb_user }}" + group: "{{ apache_user }}" + mode: 0755 + state: directory + with_items: + - "{{ calibreweb_home }}" + - "{{ calibreweb_venv_path }}" + - "{{ 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 to {{ calibreweb_venv_path }} + git: + repo: https://github.com/janeczku/calibre-web.git + dest: "{{ calibreweb_venv_path }}" + force: yes + #update: yes # not needed, as Ansible's default is to update + depth: 1 + version: "{{ calibreweb_version }}" + when: internet_available | bool + +## Ansible Pip Bug: Cannot use 'chdir' with 'env' https://github.com/ansible/ansible/issues/37912 (Patch landed) +#- name: Download calibre-web dependencies into vendor subdirectory. +# pip: +# requirements: "{{ calibreweb_path }}/requirements.txt" +# chdir: "{{ calibreweb_path }}" +# extra_args: '--target vendor' +# ignore_errors: True +## +# Implementing this with Ansible command module for now. +- name: Download Calibre-Web dependencies (using pip) into virtual environment + pip: + requirements: "{{ calibreweb_venv_path }}/requirements.txt" + virtualenv: "{{ calibreweb_venv_path }}" + virtualenv_site_packages: no + virtualenv_command: /usr/bin/virtualenv + virtualenv_python: python2.7 + when: internet_available | bool + +- name: Symlink {{ calibreweb_venv_path }}/vendor to {{ calibreweb_venv_path }}/lib/python2.7/site-packages to keep cps.py happy + file: + src: "{{ calibreweb_venv_path }}/lib/python2.7/site-packages" + dest: "{{ calibreweb_venv_path }}/vendor" + state: link + +- name: Install unit file /etc/systemd/system/calibre-web.service & /etc/apache2/sites-available/calibre-web.conf for http://box{{ calibreweb_url1 }}, http://box{{ calibreweb_url2 }}, http://box{{ calibreweb_url3 }} from templates + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: 0644 + with_items: + - { 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: + path: /library/calibre-web/metadata.db + register: metadatadb + +- name: Provision/Copy both default metadata files into /library/calibre-web IF metadata.db did not exist + copy: + src: "{{ item }}" + dest: "{{ calibreweb_home }}" + owner: "{{ calibreweb_user }}" + group: "{{ apache_user }}" + mode: 0644 + backup: yes + with_items: + - roles/calibre-web/files/metadata.db + - roles/calibre-web/files/metadata_db_prefs_backup.json + when: not metadatadb.stat.exists + #when: calibreweb_provision | bool + +- 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 }}" + owner: "{{ calibreweb_user }}" + group: "{{ apache_user }}" + mode: 0644 + backup: yes + when: not metadatadb.stat.exists + #when: calibreweb_provision | bool + +- name: Add 'calibreweb_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^calibreweb_installed' + line: 'calibreweb_installed: True' + state: present diff --git a/roles/calibre-web/tasks/main.yml b/roles/calibre-web/tasks/main.yml index 74833fe5f..6b4276c8d 100644 --- a/roles/calibre-web/tasks/main.yml +++ b/roles/calibre-web/tasks/main.yml @@ -1,173 +1,5 @@ -- name: Install ImageMagick (debuntu) - package: - name: - - imagemagick - state: present - when: is_debuntu | bool +- include_tasks: install.yml + when: calibreweb_install and not calibreweb_installed is defined -- name: Allow ImageMagick to read PDFs (debuntu) - lineinfile: - path: /etc/ImageMagick-6/policy.xml - regexp: '' - backrefs: yes - line: ' ' - state: present - when: is_debuntu | bool - -- name: Create 3 Calibre-Web folders to store data and configuration files - file: - path: "{{ item }}" - owner: "{{ calibreweb_user }}" - group: "{{ apache_user }}" - mode: 0755 - state: directory - with_items: - - "{{ calibreweb_home }}" - - "{{ calibreweb_venv_path }}" - - "{{ 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 to {{ calibreweb_venv_path }} - git: - repo: https://github.com/janeczku/calibre-web.git - dest: "{{ calibreweb_venv_path }}" - force: yes - #update: yes # not needed, as Ansible's default is to update - depth: 1 - version: "{{ calibreweb_version }}" - when: internet_available | bool - -## Ansible Pip Bug: Cannot use 'chdir' with 'env' https://github.com/ansible/ansible/issues/37912 (Patch landed) -#- name: Download calibre-web dependencies into vendor subdirectory. -# pip: -# requirements: "{{ calibreweb_path }}/requirements.txt" -# chdir: "{{ calibreweb_path }}" -# extra_args: '--target vendor' -# ignore_errors: True -## -# Implementing this with Ansible command module for now. -- name: Download Calibre-Web dependencies (using pip) into virtual environment - pip: - requirements: "{{ calibreweb_venv_path }}/requirements.txt" - virtualenv: "{{ calibreweb_venv_path }}" - virtualenv_site_packages: no - virtualenv_command: /usr/bin/virtualenv - virtualenv_python: python2.7 - - when: internet_available | bool - -- name: Symlink {{ calibreweb_venv_path }}/vendor to {{ calibreweb_venv_path }}/lib/python2.7/site-packages to keep cps.py happy - file: - src: "{{ calibreweb_venv_path }}/lib/python2.7/site-packages" - dest: "{{ calibreweb_venv_path }}/vendor" - state: link - -- name: Install unit file /etc/systemd/system/calibre-web.service & /etc/apache2/sites-available/calibre-web.conf for http://box{{ calibreweb_url1 }}, http://box{{ calibreweb_url2 }}, http://box{{ calibreweb_url3 }} from templates - template: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - owner: root - group: root - mode: 0644 - with_items: - - { 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: - path: /library/calibre-web/metadata.db - register: metadatadb - -- name: Provision/Copy both default metadata files into /library/calibre-web IF metadata.db did not exist - copy: - src: "{{ item }}" - dest: "{{ calibreweb_home }}" - owner: "{{ calibreweb_user }}" - group: "{{ apache_user }}" - mode: 0644 - backup: yes - with_items: - - roles/calibre-web/files/metadata.db - - roles/calibre-web/files/metadata_db_prefs_backup.json - when: not metadatadb.stat.exists - #when: calibreweb_provision | bool - -- 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 }}" - owner: "{{ calibreweb_user }}" - group: "{{ apache_user }}" - mode: 0644 - backup: yes - when: not metadatadb.stat.exists - #when: calibreweb_provision | bool - -- name: Enable & Restart 'calibre-web' systemd service - systemd: - name: calibre-web - daemon_reload: yes - enabled: yes - state: restarted - when: calibreweb_enabled | bool - -# Default: http://box/books -# SEE ALSO: https://github.com/janeczku/calibre-web/wiki/Setup-Reverse-Proxy -- name: Enable http://box{{ calibreweb_url1 }}, http://box{{ calibreweb_url2 }}, http://box{{ calibreweb_url3 }} with Apache - command: a2ensite calibre-web.conf - when: calibreweb_enabled | bool - -#- name: Restart Apache after enabling calibre-web httpd2 site -# command: apachectl -k graceful -# when: calibreweb_enabled | bool - -- name: Disable 'calibre-web' systemd service - systemd: - name: calibre-web - daemon_reload: yes - enabled: no - state: stopped - when: not calibreweb_enabled - -- name: Disable http://box{{ calibreweb_url1 }}, http://box{{ calibreweb_url2 }}, http://box{{ calibreweb_url3 }} with Apache - command: a2dissite calibre-web.conf - when: not calibreweb_enabled - -#- name: Restart Apache after disabling calibre-web httpd2 site -# command: apachectl -k graceful -# when: not calibreweb_enabled - -- name: Restart Apache systemd service ({{ apache_service }}) - systemd: - name: "{{ apache_service }}" # httpd or apache2 - state: restarted - -- name: Add 'calibre-web' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" - section: calibre-web - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: calibre-web - - option: description - value: '"calibre-web is a web app providing a clean interface for browsing, reading and downloading e-books."' - - option: calibreweb_url1 - value: "{{ calibreweb_url1 }}" - - option: calibreweb_url2 - value: "{{ calibreweb_url2 }}" - - option: calibreweb_url3 - value: "{{ calibreweb_url3 }}" - - option: calibreweb_path - value: "{{ calibreweb_venv_path }}" - - option: calibreweb_home - value: "{{ calibreweb_home }}" - - option: calibreweb_port - value: "{{ calibreweb_port }}" - - option: calibreweb_database - value: "{{ calibreweb_database }}" - - option: calibreweb_enabled - value: "{{ calibreweb_enabled }}" -# - option: calibreweb_provision -# value: "{{ calibreweb_provision }}" +- include_tasks: enable.yml + when: calibreweb_install or calibreweb_installed is defined diff --git a/roles/calibre-web/templates/calibre-web-nginx.conf.j2 b/roles/calibre-web/templates/calibre-web-nginx.conf.j2 new file mode 100644 index 000000000..55839acac --- /dev/null +++ b/roles/calibre-web/templates/calibre-web-nginx.conf.j2 @@ -0,0 +1,7 @@ +location /books/ { + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Script-Name /books; + proxy_pass http://127.0.0.1:8083; +} diff --git a/roles/calibre/tasks/enable.yml b/roles/calibre/tasks/enable.yml new file mode 100644 index 000000000..64e0215de --- /dev/null +++ b/roles/calibre/tasks/enable.yml @@ -0,0 +1,54 @@ +# 5. WRAP UP: ENABLE CALIBRE SERVICE, http://box/books ETC + +# http://box:8080 & http://box:8080/mobile WORK BUT OTHER URL'S LIKE http://box/calibre ARE A MESS (BOOKS RARELY DISPLAY) +# +# 2018-08-27 POSSIBLE FIX...CONSIDER THIS ProxyPass / ProxyPassReverse TECHNIQUE: +# 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 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 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 & Start service 'calibre-serve' (/usr/bin/calibre-server by Kovid Goyal) + service: + name: calibre-serve + enabled: yes + state: started + when: calibre_enabled | bool + #async: 900 + #poll: 5 + +- name: Reload Apache service ({{ apache_service }}) + systemd: + name: "{{ apache_service }}" + state: reloaded + +- name: Add 'calibre' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: calibre + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: Calibre + - option: description + value: '"Calibre is an extremely popular personal library system for e-books."' + - option: url + value: "{{ calibre_src_url }}" + - option: database + value: "{{ calibre_dbpath }}" + - option: port + value: "{{ calibre_port }}" + - option: calibre_enabled + value: "{{ calibre_enabled }}" diff --git a/roles/calibre/tasks/install.yml b/roles/calibre/tasks/install.yml new file mode 100644 index 000000000..fa500f060 --- /dev/null +++ b/roles/calibre/tasks/install.yml @@ -0,0 +1,87 @@ +# 1. INSTALL THE LATEST CALIBRE 3.X+ (calibre, calibredb, calibre-server etc) ON ALL OS'S + +- name: Does /usr/bin/calibre exist? + stat: + path: "/usr/bin/calibre" + register: calib_executable + +- name: "Install OS's latest packages: calibre, calibre-bin (IF not rpi AND /usr/bin/calibre MISSING)" + package: + name: + - calibre + - calibre-bin + state: latest + 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) + include_tasks: debs.yml + when: calibre_via_debs and (not calib_executable.stat.exists) + +- name: Install Calibre via calibre-installer.py IF calibre_via_python (AND /usr/bin/calibre WAS MISSING) + include_tasks: py-installer.yml + when: calibre_via_python and (not calib_executable.stat.exists) + +# SEE calibre_via_python's value vars/default_vars.yml, vars/ubuntu-18.yml & +# vars/raspbian-9.yml: try to AVOID Python installer on Raspbian since its +# .deb's (http://raspbian.raspberrypi.org/raspbian/pool/main/c/calibre/) +# are updated within about 10 days of Calibre's quasi-monthly releases! +# +# BUT IF ABSOLUTELY NEC: (SEE roles/calibre/tasks/debs.yml) +# - run testing branch for RPi: scripts/calibre-install-latest-rpi.sh +# - run testing branch for Ubuntu 16.04: scripts/calibre-install-latest.sh +# - run unstable branch for Debian etc: scripts/calibre-install-unstable.sh + +- name: Create calibre-serve.service and calibre.conf (IF /usr/bin/calibre WAS MISSING) + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: "{{ item.mode }}" + backup: no + #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'} + when: (not calib_executable.stat.exists) + +- name: Stop service 'calibre-serve' (/usr/bin/calibre-server by Kovid Goyal) + systemd: + name: calibre-serve + state: stopped + daemon_reload: yes + +# 3. CREATE USER DATABASE + +- name: Create /library/calibre (mandatory since Calibre 3.x) + file: + path: "{{ calibre_dbpath }}" + state: directory + #mode: 0755 + +- name: Copy template userdb to /library/calibre/users.sqlite (IF /usr/bin/calibre WAS MISSING) + copy: + src: /opt/iiab/iiab/roles/calibre/templates/users.sqlite + dest: "{{ calibre_userdb }}" + owner: root + group: root + mode: 0644 + when: (not calib_executable.stat.exists) + +# 4. CREATE CONTENT DATABASE WITH A SAMPLE BOOK (REQUIRED AS OF CALIBRE 3.x) + +- name: Does /library/calibre/metadata.db exist? + stat: + path: "{{ calibre_dbpath }}/metadata.db" + register: calibre_db + +- name: Create database (required since Calibre 3.x) with a sample book + include_tasks: create-db.yml + when: not calibre_db.stat.exists + +- name: Add 'calibre_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^calibreweb_installed' + line: 'calibre_installed: True' + state: present diff --git a/roles/calibre/tasks/main.yml b/roles/calibre/tasks/main.yml index b327558e4..6b0a77d70 100644 --- a/roles/calibre/tasks/main.yml +++ b/roles/calibre/tasks/main.yml @@ -1,151 +1,5 @@ -# 1. INSTALL THE LATEST CALIBRE 3.X+ (calibre, calibredb, calibre-server etc) ON ALL OS'S +- include_tasks: install.yml + when: calibre_install and not calibre_installed is defined -- name: Does /usr/bin/calibre exist? - stat: - path: "/usr/bin/calibre" - register: calib_executable - -- name: "Install OS's latest packages: calibre, calibre-bin (IF not rpi AND /usr/bin/calibre MISSING)" - package: - name: - - calibre - - calibre-bin - state: latest - 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) - include_tasks: debs.yml - when: calibre_via_debs and (not calib_executable.stat.exists) - -- name: Install Calibre via calibre-installer.py IF calibre_via_python (AND /usr/bin/calibre WAS MISSING) - include_tasks: py-installer.yml - when: calibre_via_python and (not calib_executable.stat.exists) - -# SEE calibre_via_python's value vars/default_vars.yml, vars/ubuntu-18.yml & -# vars/raspbian-9.yml: try to AVOID Python installer on Raspbian since its -# .deb's (http://raspbian.raspberrypi.org/raspbian/pool/main/c/calibre/) -# are updated within about 10 days of Calibre's quasi-monthly releases! -# -# BUT IF ABSOLUTELY NEC: (SEE roles/calibre/tasks/debs.yml) -# - run testing branch for RPi: scripts/calibre-install-latest-rpi.sh -# - run testing branch for Ubuntu 16.04: scripts/calibre-install-latest.sh -# - run unstable branch for Debian etc: scripts/calibre-install-unstable.sh - -- name: Create calibre-serve.service and calibre.conf (IF /usr/bin/calibre WAS MISSING) - template: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - owner: root - group: root - mode: "{{ item.mode }}" - backup: no - #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'} - when: (not calib_executable.stat.exists) - -- name: Force systemd to reread configs (IF /usr/bin/calibre WAS MISSING) - systemd: - daemon_reload: yes - when: (not calib_executable.stat.exists) - #when: calibre_config.changed - -# 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 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 - -# 3. CREATE USER DATABASE - -- name: Create /library/calibre (mandatory since Calibre 3.x) - file: - path: "{{ calibre_dbpath }}" - state: directory - #mode: 0755 - -- name: Copy template userdb to /library/calibre/users.sqlite (IF /usr/bin/calibre WAS MISSING) - copy: - src: /opt/iiab/iiab/roles/calibre/templates/users.sqlite - dest: "{{ calibre_userdb }}" - owner: root - group: root - mode: 0644 - when: (not calib_executable.stat.exists) - -# 4. CREATE CONTENT DATABASE WITH A SAMPLE BOOK (REQUIRED AS OF CALIBRE 3.x) - -- name: Does /library/calibre/metadata.db exist? - stat: - path: "{{ calibre_dbpath }}/metadata.db" - register: calibre_db - -- name: Create database (required since Calibre 3.x) with a sample book - include_tasks: create-db.yml - when: not calibre_db.stat.exists - -# 5. WRAP UP: ENABLE CALIBRE SERVICE, http://box/books ETC - -# http://box:8080 & http://box:8080/mobile WORK BUT OTHER URL'S LIKE http://box/calibre ARE A MESS (BOOKS RARELY DISPLAY) -# -# 2018-08-27 POSSIBLE FIX...CONSIDER THIS ProxyPass / ProxyPassReverse TECHNIQUE: -# 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 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 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 & Start service 'calibre-serve' (/usr/bin/calibre-server by Kovid Goyal) - service: - name: calibre-serve - enabled: yes - state: started - when: calibre_enabled | bool - #async: 900 - #poll: 5 - -- name: Reload Apache service ({{ apache_service }}) - systemd: - name: "{{ apache_service }}" - state: reloaded - -- name: Add 'calibre' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" - section: calibre - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: Calibre - - option: description - value: '"Calibre is an extremely popular personal library system for e-books."' - - option: url - value: "{{ calibre_src_url }}" - - option: database - value: "{{ calibre_dbpath }}" - - option: port - value: "{{ calibre_port }}" - - option: calibre_enabled - value: "{{ calibre_enabled }}" +- include_tasks: enable.yml + when: calibre_install or calibre_installed is defined diff --git a/roles/captive-portal/tasks/main.yml b/roles/captive-portal/tasks/main.yml index c593816dc..569afb869 100644 --- a/roles/captive-portal/tasks/main.yml +++ b/roles/captive-portal/tasks/main.yml @@ -119,6 +119,13 @@ state: absent when: not captive_portal_enabled +- name: Add 'captive_portal_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^captive_portal_installed' + line: 'captive_portal_installed: True' + state: present + - name: Restart Apache service ({{ apache_service }}) # i.e. apache2 on most distros systemd: name: "{{ apache_service }}" diff --git a/roles/cups/tasks/main.yml b/roles/cups/tasks/main.yml index 6b6ee6992..ef0dfc85d 100644 --- a/roles/cups/tasks/main.yml +++ b/roles/cups/tasks/main.yml @@ -7,6 +7,13 @@ tags: - download +- name: Add 'cups_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^cups_installed' + line: 'cups_installed: True' + state: present + - name: Install our own /etc/cups/cupsd.conf from template, to permit local LAN admin template: src: cupsd.conf diff --git a/roles/dokuwiki/tasks/enable.yml b/roles/dokuwiki/tasks/enable.yml new file mode 100644 index 000000000..379649617 --- /dev/null +++ b/roles/dokuwiki/tasks/enable.yml @@ -0,0 +1,35 @@ +- 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 + path: /etc/apache2/sites-enabled/dokuwiki.conf + state: link + when: dokuwiki_enabled and is_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: Restart Apache ({{ apache_service }}) to enable/disable DokuWiki's http://box/wiki + systemd: + name: "{{ apache_service }}" + daemon_reload: yes + state: restarted + +- name: Add 'dokuwiki' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: dokuwiki + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: DokuWiki + - option: description + value: '"DokuWiki is a simple to use and highly versatile Open Source wiki software that does not require a database."' + - option: installed + value: "{{ dokuwiki_install }}" + - option: enabled + value: "{{ dokuwiki_enabled }}" + diff --git a/roles/dokuwiki/tasks/install.yml b/roles/dokuwiki/tasks/install.yml index 9aab6692c..a23e3b494 100644 --- a/roles/dokuwiki/tasks/install.yml +++ b/roles/dokuwiki/tasks/install.yml @@ -48,7 +48,9 @@ state: directory recurse: yes -- name: Restart Apache ({{ apache_service }}) to enable/disable DokuWiki's http://box/wiki - systemd: - name: "{{ apache_service }}" - state: restarted +- name: Add 'dokuwiki_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^dokuwiki_installed' + line: 'dokuwiki_installed: True' + state: present diff --git a/roles/dokuwiki/tasks/main.yml b/roles/dokuwiki/tasks/main.yml index 15824df31..ad5ba75a7 100644 --- a/roles/dokuwiki/tasks/main.yml +++ b/roles/dokuwiki/tasks/main.yml @@ -1,19 +1,7 @@ - name: Install DokuWiki include_tasks: install.yml - when: dokuwiki_install | bool + when: dokuwiki_install | bool and not dokuwiki_installed is defined -- name: Add 'dokuwiki' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" - section: dokuwiki - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: DokuWiki - - option: description - value: '"DokuWiki is a simple to use and highly versatile Open Source wiki software that does not require a database."' - - option: installed - value: "{{ dokuwiki_install }}" - - option: enabled - value: "{{ dokuwiki_enabled }}" +- name: Enable DokuWiki + include_tasks: enable.yml + when: dokuwiki_install | bool or dokuwiki_installed is defined diff --git a/roles/elgg/tasks/enable.yml b/roles/elgg/tasks/enable.yml new file mode 100644 index 000000000..19d029530 --- /dev/null +++ b/roles/elgg/tasks/enable.yml @@ -0,0 +1,39 @@ +- name: Create symlink elgg.conf from sites-enabled to sites-available (debuntu, not nec for redhat) + file: + src: /etc/apache2/sites-available/elgg.conf + path: /etc/apache2/sites-enabled/elgg.conf + state: link + when: elgg_enabled and is_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: Remove Apache's elgg.conf (redhat) + file: + dest: "/etc/{{ apache_config_dir }}/elgg.conf" + state: absent + when: not elgg_enabled and is_redhat + +- 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: + path: "{{ iiab_ini_file }}" + section: elgg + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: Elgg + - option: description + 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: elgg_enabled + value: "{{ elgg_enabled }}" diff --git a/roles/elgg/tasks/install.yml b/roles/elgg/tasks/install.yml new file mode 100644 index 000000000..d064846f5 --- /dev/null +++ b/roles/elgg/tasks/install.yml @@ -0,0 +1,96 @@ +# Assume we only get here if elgg_install: True +# Assume MySQL is running + +- 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 | bool + +- name: Check for existence of /opt/elgg-{{ elgg_version }}/index.php + stat: + path: "/opt/elgg-{{ elgg_version }}/index.php" + register: elgg + +- 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 softlink from /opt/elgg to /opt/elgg-{{ elgg_version }} + file: + src: "./elgg-{{ elgg_version }}" + path: /opt/elgg + owner: "{{ apache_user }}" + group: "{{ apache_user }}" + state: link + force: yes + +- 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" + owner: "{{ apache_user }}" + group: "{{ apache_user }}" + +# The name of this file changed from 1.9 to 1.10. +- 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" + mode: 0644 + owner: "{{ apache_user }}" + group: "{{ apache_user }}" + +#regexp='^#RewriteBase' +- name: Change .htaccess to include RewriteBase for http://box/elgg + lineinfile: + backup: no + path: "/opt/{{ elgg_xx }}/.htaccess" + state: present + insertafter: '^#RewriteBase' + line: "RewriteBase {{ elgg_url }}/" + +- 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: 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 }}" + group: "{{ apache_user }}" + recurse: yes + state: directory + +- 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: 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: Add 'elgg_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^elgg_installed' + line: 'elgg_installed: True' + state: present + diff --git a/roles/elgg/tasks/main.yml b/roles/elgg/tasks/main.yml index 6461ebca1..8c03710ae 100644 --- a/roles/elgg/tasks/main.yml +++ b/roles/elgg/tasks/main.yml @@ -1,165 +1,11 @@ -# Assume we only get here if elgg_install: True -# Assume MySQL is running +- name: Install Elgg + include_tasks: install.yml + when: elgg_install and not elgg_installed is defined -- 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 | bool +- name: Provision DB + include_tasks: setup.yml + when: elgg_install and not installing -- name: Check for existence of /opt/elgg-{{ elgg_version }}/index.php - stat: - path: "/opt/elgg-{{ elgg_version }}/index.php" - register: elgg - -- 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 softlink from /opt/elgg to /opt/elgg-{{ elgg_version }} - file: - src: "./elgg-{{ elgg_version }}" - path: /opt/elgg - owner: "{{ apache_user }}" - group: "{{ apache_user }}" - state: link - force: yes - -- 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" - owner: "{{ apache_user }}" - group: "{{ apache_user }}" - -# The name of this file changed from 1.9 to 1.10. -- 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" - mode: 0644 - owner: "{{ apache_user }}" - group: "{{ apache_user }}" - -#regexp='^#RewriteBase' -- name: Change .htaccess to include RewriteBase for http://box/elgg - lineinfile: - backup: no - path: "/opt/{{ elgg_xx }}/.htaccess" - state: present - insertafter: '^#RewriteBase' - line: "RewriteBase {{ elgg_url }}/" - -- 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: 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 }}" - group: "{{ apache_user }}" - recurse: yes - state: directory - -- 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 user/password to access Elgg database - can be run more than once - mysql_user: - name: "{{ dbuser }}" - host: "{{ item }}" - password: "{{ dbpassword }}" - priv: "{{ dbname }}.*:ALL" - with_items: - - 127.0.0.1 - - ::1 - - localhost - -- name: Create /tmp/elggdb.sql from template, to load database - template: - src: "elggdb.sql.j2" - dest: "/tmp/elggdb.sql" - -# elggdb.sql obtained with mysqldump --skip-add-drop-table elggdb > elggdb.sql -# 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: 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 /tmp/elggdb.sql - file: - name: /tmp/elggdb.sql - state: absent - -- 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: Create symlink elgg.conf from sites-enabled to sites-available (debuntu, not nec for redhat) - file: - src: /etc/apache2/sites-available/elgg.conf - path: /etc/apache2/sites-enabled/elgg.conf - state: link - when: elgg_enabled and is_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: Remove Apache's elgg.conf (redhat) - file: - dest: "/etc/{{ apache_config_dir }}/elgg.conf" - state: absent - when: not elgg_enabled and is_redhat - -- 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: - path: "{{ iiab_ini_file }}" - section: elgg - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: Elgg - - option: description - 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: elgg_enabled - value: "{{ elgg_enabled }}" +- name: Enable Elgg + include_tasks: enable.yml + when: elgg_install or elgg_installed is defined diff --git a/roles/elgg/tasks/setup.yml b/roles/elgg/tasks/setup.yml new file mode 100644 index 000000000..66ded083f --- /dev/null +++ b/roles/elgg/tasks/setup.yml @@ -0,0 +1,36 @@ +- 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 user/password to access Elgg database - can be run more than once + mysql_user: + name: "{{ dbuser }}" + host: "{{ item }}" + password: "{{ dbpassword }}" + priv: "{{ dbname }}.*:ALL" + with_items: + - 127.0.0.1 + - ::1 + - localhost + +- name: Create /tmp/elggdb.sql from template, to load database + template: + src: "elggdb.sql.j2" + dest: "/tmp/elggdb.sql" + +# elggdb.sql obtained with mysqldump --skip-add-drop-table elggdb > elggdb.sql +# 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: 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 /tmp/elggdb.sql + file: + name: /tmp/elggdb.sql + state: absent diff --git a/roles/gitea/tasks/enable.yml b/roles/gitea/tasks/enable.yml new file mode 100644 index 000000000..5bfd1d729 --- /dev/null +++ b/roles/gitea/tasks/enable.yml @@ -0,0 +1,75 @@ +- name: Enable 'gitea' service + systemd: + daemon_reload: yes + name: gitea + enabled: yes + state: restarted + when: gitea_enabled | bool + +- name: Disable 'gitea' service + systemd: + daemon_reload: yes + name: gitea + enabled: no + state: stopped + when: not gitea_enabled + +# Configure HTTPD + +- name: Copy gitea httpd conf file + template: + src: gitea.conf.j2 + dest: "/etc/{{ apache_config_dir }}/gitea.conf" + +- name: Enable httpd conf file (apache) + file: + src: /etc/{{ apache_config_dir }}/gitea.conf + dest: /etc/apache2/sites-enabled/gitea.conf + state: link + when: gitea_enabled and is_debuntu + +- name: Remove apache httpd conf file (OS's other than debuntu) + file: + path: /etc/apache2/sites-enabled/gitea.conf + state: absent + when: not gitea_enabled or nginx_enabled + +- name: Remove nginx httpd conf file + file: + path: /etc/nginx/conf.d/gitea-nginx.conf + state: absent + when: not gitea_enabled + +- name: Enable nginx httpd conf file + template: + src: gitea-nginx.conf.j2 + dest: /etc/nginx/conf.d/gitea-nginx.conf + when: gitea_enabled and nginx_enabled + +- name: >- + Restart Apache ({{ apache_service }}) to {% if gitea_enabled %}enable{% + else %}disable{% endif %} http://box/gitea + systemd: + name: "{{ apache_service }}" + daemon_reload: yes + state: restarted + +# Add Gitea to registry + +- name: Add 'gitea' to list of services at {{ iiab_ini_file }} + ini_file: + dest: "{{ iiab_ini_file }}" + section: gitea + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: gitea + - option: description + value: '"Gitea: Git with a cup of tea"' + - option: gitea_run_directory + value: "{{ gitea_run_directory }}" + - option: gitea_url + value: "{{ gitea_url }}" + - option: gitea_enabled + value: "{{ gitea_enabled }}" diff --git a/roles/gitea/tasks/install.yml b/roles/gitea/tasks/install.yml index f67bee787..05c9b9436 100644 --- a/roles/gitea/tasks/install.yml +++ b/roles/gitea/tasks/install.yml @@ -125,64 +125,9 @@ tags: - systemd -- name: Enable 'gitea' service - systemd: - daemon_reload: yes - name: gitea - enabled: yes - state: restarted - when: gitea_enabled | bool - -- name: Disable 'gitea' service - systemd: - name: gitea - enabled: no - state: stopped - when: not gitea_enabled - -# Configure HTTPD - -- name: Copy gitea httpd conf file - template: - src: gitea.conf.j2 - dest: "/etc/{{ apache_config_dir }}/gitea.conf" - -- name: Enable httpd conf file (debuntu) - file: - src: /etc/{{ apache_config_dir }}/gitea.conf - dest: /etc/apache2/sites-enabled/gitea.conf - state: link - when: gitea_enabled and is_debuntu - -- name: Remove httpd conf file (OS's other than debuntu) - file: - path: /etc/apache2/sites-enabled/gitea.conf - state: absent - when: not gitea_enabled and is_debuntu - -- name: >- - Restart Apache ({{ apache_service }}) to {% if gitea_enabled %}enable{% - else %}disable{% endif %} http://box/gitea - service: - name: "{{ apache_service }}" - state: restarted - -# Add Gitea to registry - -- name: Add 'gitea' to list of services at {{ iiab_ini_file }} - ini_file: - dest: "{{ iiab_ini_file }}" - section: gitea - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: gitea - - option: description - value: '"Gitea: Git with a cup of tea"' - - option: gitea_run_directory - value: "{{ gitea_run_directory }}" - - option: gitea_url - value: "{{ gitea_url }}" - - option: gitea_enabled - value: "{{ gitea_enabled }}" +- name: Add 'gitea_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^gitea_installed' + line: 'gitea_installed: True' + state: present diff --git a/roles/gitea/tasks/main.yml b/roles/gitea/tasks/main.yml index 28e34380f..ee7f6aa28 100644 --- a/roles/gitea/tasks/main.yml +++ b/roles/gitea/tasks/main.yml @@ -1,3 +1,7 @@ - name: Install Gitea {{ gitea_version }} if gitea_install include_tasks: install.yml - when: gitea_install | bool + when: gitea_install | bool and not gitea_installed is defined + +- name: Enable Gitea {{ gitea_version }} if gitea_install + include_tasks: enable.yml + when: gitea_install | bool or gitea_installed is defined diff --git a/roles/gitea/templates/gitea-nginx.conf.j2 b/roles/gitea/templates/gitea-nginx.conf.j2 new file mode 100644 index 000000000..2545a3f86 --- /dev/null +++ b/roles/gitea/templates/gitea-nginx.conf.j2 @@ -0,0 +1,3 @@ +location {{ gitea_url }}/ { + proxy_pass http://127.0.0.1:{{ gitea_port }}; +} diff --git a/roles/httpd-enable/tasks/main.yml b/roles/httpd-enable/tasks/main.yml new file mode 100644 index 000000000..593affbe1 --- /dev/null +++ b/roles/httpd-enable/tasks/main.yml @@ -0,0 +1 @@ +- include_tasks: roles/httpd/tasks/enable.yml diff --git a/roles/httpd/tasks/enable.yml b/roles/httpd/tasks/enable.yml new file mode 100644 index 000000000..787fca097 --- /dev/null +++ b/roles/httpd/tasks/enable.yml @@ -0,0 +1,69 @@ +# For schools that use WordPress/Nextcloud/Moodle intensively. iiab/iiab#1147 +# 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/Nextcloud/Moodle intensively + lineinfile: + path: "/etc/php/{{ php_version }}/{{ apache_service }}/php.ini" + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + when: apache_high_php_limits | bool + with_items: + - { regexp: '^upload_max_filesize', line: 'upload_max_filesize = 500M ; default is 2M' } + - { regexp: '^post_max_size', line: 'post_max_size = 500M ; default is 8M' } + - { regexp: '^memory_limit', line: 'memory_limit = 256M ; default is 128M / Nextcloud requests 512M' } + - { regexp: '^max_execution_time', line: 'max_execution_time = 300 ; default is 30' } + - { regexp: '^max_input_time', line: 'max_input_time = 300 ; default is 60' } + +- name: Install Apache's 010-iiab.conf & proxy_ajp.conf into /etc/apache2/sites-available, from templates + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: 0644 + with_items: + - { src: 'roles/httpd/templates/010-iiab.conf.j2', dest: '/etc/{{ apache_config_dir }}/010-iiab.conf' } + - { src: 'roles/httpd/templates/proxy_ajp.conf.j2', dest: '/etc/{{ apache_config_dir }}/proxy_ajp.conf' } + +- name: Enable our site, creating 010-iiab.conf symlink from sites-enabled to sites-available (debuntu) + file: + src: "/etc/{{ apache_config_dir }}/010-iiab.conf" + path: /etc/apache2/sites-enabled/010-iiab.conf + state: link + when: is_debuntu | bool + +# 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: Install /etc/{{ apache_config_dir }}/osm.conf for http://box/maps (all OS's) + copy: + src: roles/httpd/files/osm.conf + dest: "/etc/{{ apache_config_dir }}" + owner: root + group: root + mode: 0644 + when: osm_vector_maps_install | bool + +- name: Symlink /etc/apache2/sites-enabled/osm.conf to /etc/{{ apache_config_dir }}/osm.conf (debuntu) + file: + src: "/etc/{{ apache_config_dir }}/osm.conf" + path: /etc/apache2/sites-enabled/osm.conf + state: link + when: is_debuntu | bool and osm_vector_maps_enabled | bool + +- name: Give {{ apache_user }} (per variable apache_user) permission to poweroff, installing /etc/sudoers.d/020_apache_poweroff from template + template: + src: roles/httpd/templates/020_apache_poweroff.j2 + dest: /etc/sudoers.d/020_apache_poweroff + mode: 0755 + when: apache_allow_sudo | bool + +- name: Remove {{ apache_user }} (per variable apache_user) permission to poweroff, removing /etc/sudoers.d/020_apache_poweroff + file: + 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 + enabled: yes + daemon_reload: yes diff --git a/roles/httpd/tasks/install.yml b/roles/httpd/tasks/install.yml new file mode 100644 index 000000000..c0f9300d2 --- /dev/null +++ b/roles/httpd/tasks/install.yml @@ -0,0 +1,147 @@ +- name: 'Install 3 packages: apache2, php{{ php_version }}, php{{ php_version }}-curl (debian)' + package: + #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 + when: is_debian | bool + tags: + - download + +- 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 | bool + tags: + - download + +# 2019-05-30: It's interesting that http://box.lan/admin and everything seems +# to work even without php{{ php_version }}-sqlite3 as confirmed on Ubuntu +# 16.04 (SEE PR #1697). And likely all others? @tim-moody writes "I think +# we decided that because sqlite3 and php are part of the base install the +# connector should be too." +# +# We might *try* deprecating this here as we transition beyond {raspbian-9, +# debian-9, ubuntu-18} in coming months to verify that roles/osm-vector-maps +# is the only role that needs it? +# +# Legacy Comment: SQLite3 no longer included in another package +- name: Install php{{ php_version }}-sqlite3 (raspbian-9+ or debian-9+ or ubuntu-18+) + package: + name: "php{{ php_version }}-sqlite3" + #when: is_raspbian_9 or is_debian_9 or is_ubuntu_18 + when: is_debuntu and (not is_debian_8) and (not is_ubuntu_16) + #when: (is_debian and ansible_distribution_major_version == "9") or is_ubuntu_18 + +- name: 'Install 4 packages: httpd, mod_authnz_external, php, php-curl (redhat)' + package: + #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 + when: is_redhat | bool + tags: + - download + +# remove symlinks for mpm-event, replace with mpm-prefork +- name: Remove both mpm_event symlinks from /etc/apache2/mods-enabled (debuntu) + file: + path: "/etc/apache2/mods-enabled/{{ item }}" + state: absent + with_items: + - mpm_event.conf + - mpm_event.load + when: is_debuntu | bool + +- name: Create both mpm_prefork symlinks from /etc/apache2/mods-enabled to /etc/apache2/mods-available (debuntu) + file: + 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 | bool + +#- name: 'Turn on mod_proxy using a2enmod with: proxy, proxy_html, headers, rewrite (debuntu)' +# command: a2enmod {{ item }} +# with_items: +# - proxy +# - proxy_html +# - headers +# - rewrite +# when: is_debuntu | bool + +- name: 'Enable 5 Apache modules, as with "a2enmod" command: headers, proxy, proxy_html, proxy_http, rewrite (for http://box/kiwix, http://box/kolibri, http://box/nodered, etc--if debuntu)' + apache2_module: + name: "{{ item }}" + with_items: + - headers + - proxy + - proxy_html + - proxy_http + - rewrite + when: is_debuntu | bool + +- name: Remove 000-default.conf from /etc/apache2 and /etc/apache2/sites-enabled (debuntu) + file: + path: "{{ item }}" + state: absent + with_items: + - /etc/apache2/000-default.conf # Not nec on Raspbian. Is this really still needed elsewhere? + - /etc/apache2/sites-enabled/000-default.conf + when: is_debuntu | bool + +- name: Create Apache's pid dir /var/run/{{ apache_user }} + file: + path: "/var/run/{{ apache_user }}" + mode: 0755 + owner: root + group: root + state: directory + +- name: 'Create group: admin' + group: + name: admin + state: present + +- name: Add user {{ apache_user }} (from variable apache_user) to group admin + user: + name: "{{ apache_user }}" + groups: admin + state: present + createhome: no + +- name: Create Apache dir /var/log/{{ apache_service }} + file: + path: "/var/log/{{ apache_service }}" + mode: 0755 + owner: "{{ apache_user }}" + group: "{{ apache_user }}" + state: directory + +- name: Enable Apache systemd service ({{ apache_service }}) + service: + name: "{{ apache_service }}" + enabled: yes + state: stopped + +- name: Create /library/www/html/info directory for http://box/info offline docs + file: + path: "{{ doc_root }}/info" + mode: 0755 + owner: "{{ apache_user }}" + group: "{{ apache_user }}" + state: directory diff --git a/roles/httpd/tasks/main.yml b/roles/httpd/tasks/main.yml index 669f5b6bd..1028f0096 100644 --- a/roles/httpd/tasks/main.yml +++ b/roles/httpd/tasks/main.yml @@ -1,206 +1,6 @@ -- name: 'Install 3 packages: apache2, php{{ php_version }}, php{{ php_version }}-curl (debian)' - package: - #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 - when: is_debian | bool +- include_tasks: install.yml tags: - - download - -- 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 | bool - tags: - - download - -# 2019-05-30: It's interesting that http://box.lan/admin and everything seems -# to work even without php{{ php_version }}-sqlite3 as confirmed on Ubuntu -# 16.04 (SEE PR #1697). And likely all others? @tim-moody writes "I think -# we decided that because sqlite3 and php are part of the base install the -# connector should be too." -# -# We might *try* deprecating this here as we transition beyond {raspbian-9, -# debian-9, ubuntu-18} in coming months to verify that roles/osm-vector-maps -# is the only role that needs it? -# -# Legacy Comment: SQLite3 no longer included in another package -- name: Install php{{ php_version }}-sqlite3 (raspbian-9+ or debian-9+ or ubuntu-18+) - package: - name: "php{{ php_version }}-sqlite3" - #when: is_raspbian_9 or is_debian_9 or is_ubuntu_18 - when: is_debuntu and (not is_debian_8) and (not is_ubuntu_16) - #when: (is_debian and ansible_distribution_major_version == "9") or is_ubuntu_18 - -- name: 'Install 4 packages: httpd, mod_authnz_external, php, php-curl (redhat)' - package: - #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 - when: is_redhat | bool - tags: - - download - -- 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: 0644 - with_items: - - { 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/Nextcloud/Moodle intensively. iiab/iiab#1147 -# 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/Nextcloud/Moodle intensively - lineinfile: - path: "/etc/php/{{ php_version }}/{{ apache_service }}/php.ini" - regexp: "{{ item.regexp }}" - line: "{{ item.line }}" - when: apache_high_php_limits | bool - with_items: - - { regexp: '^upload_max_filesize', line: 'upload_max_filesize = 500M ; default is 2M' } - - { regexp: '^post_max_size', line: 'post_max_size = 500M ; default is 8M' } - - { regexp: '^memory_limit', line: 'memory_limit = 256M ; default is 128M / Nextcloud requests 512M' } - - { 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 both mpm_event symlinks from /etc/apache2/mods-enabled (debuntu) - file: - path: "/etc/apache2/mods-enabled/{{ item }}" - state: absent - with_items: - - mpm_event.conf - - mpm_event.load - when: is_debuntu | bool - -- name: Create both mpm_prefork symlinks from /etc/apache2/mods-enabled to /etc/apache2/mods-available (debuntu) - file: - 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 | bool - -#- name: 'Turn on mod_proxy using a2enmod with: proxy, proxy_html, headers, rewrite (debuntu)' -# command: a2enmod {{ item }} -# with_items: -# - proxy -# - proxy_html -# - headers -# - rewrite -# when: is_debuntu | bool -# -# NOTE: activity-server/tasks/main.yml runs "a2enmod expires" -# NOTE: awstats/tasks/install.yml runs "a2enmod cgi" -# NOTE: nodered/tasks/main.yml uses apache2_module to install "proxy_wstunnel" -# 2019-10-07: proxy_http is definitely essential! (ARE THE OTHER 4 BELOW REALLY NEEDED ?) -- name: 'Enable 5 Apache modules, as with "a2enmod" command: headers, proxy, proxy_html, proxy_http, rewrite (for http://box/kiwix, http://box/kolibri, http://box/nodered, etc--if debuntu)' - apache2_module: - name: "{{ item }}" - with_items: - - headers - - proxy - - proxy_html - - proxy_http - - rewrite - when: is_debuntu | bool - -- name: Enable our site, creating 010-iiab.conf symlink from sites-enabled to sites-available (debuntu) - file: - src: "/etc/{{ apache_config_dir }}/010-iiab.conf" - path: /etc/apache2/sites-enabled/010-iiab.conf - state: link - when: is_debuntu | bool - -- name: Remove 000-default.conf from /etc/apache2 and /etc/apache2/sites-enabled (debuntu) - file: - path: "{{ item }}" - state: absent - with_items: - - /etc/apache2/000-default.conf # Not nec on Raspbian. Is this really still needed elsewhere? - - /etc/apache2/sites-enabled/000-default.conf - when: is_debuntu | bool - -- name: Create Apache's pid dir /var/run/{{ apache_user }} - file: - path: "/var/run/{{ apache_user }}" - mode: 0755 - owner: root - group: root - state: directory - -- name: 'Create group: admin' - group: - name: admin - state: present - -- name: Add user {{ apache_user }} (from variable apache_user) to group admin - user: - name: "{{ apache_user }}" - groups: admin - state: present - createhome: no - -- name: Create Apache dir /var/log/{{ apache_service }} - file: - path: "/var/log/{{ apache_service }}" - mode: 0755 - owner: "{{ apache_user }}" - group: "{{ apache_user }}" - state: directory - -- name: Enable Apache systemd service ({{ apache_service }}) - service: - name: "{{ apache_service }}" - enabled: yes - -- name: Create /library/www/html/info directory for http://box/info offline docs - file: - path: "{{ doc_root }}/info" - mode: 0755 - owner: "{{ apache_user }}" - group: "{{ apache_user }}" - state: directory - -# 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: Install /etc/{{ apache_config_dir }}/osm.conf for http://box/maps (all OS's) - copy: - src: osm.conf - dest: "/etc/{{ apache_config_dir }}" - owner: root - group: root - mode: 0644 - backup: yes - -- name: Symlink /etc/apache2/sites-enabled/osm.conf to /etc/{{ apache_config_dir }}/osm.conf (debuntu) - file: - src: "/etc/{{ apache_config_dir }}/osm.conf" - path: /etc/apache2/sites-enabled/osm.conf - #path: "/etc/{{ apache_service }}/sites-enabled/osm.conf" - state: link - when: is_debuntu | bool + - base - include_tasks: html.yml tags: @@ -216,21 +16,3 @@ src: refresh-wiki-docs.sh dest: /usr/bin/iiab-refresh-wiki-docs mode: 0755 - -- 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 | bool - -- name: Remove {{ apache_user }} (per variable apache_user) permission to poweroff, removing /etc/sudoers.d/020_apache_poweroff - file: - 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 diff --git a/roles/internetarchive/meta/main.yml b/roles/internetarchive/meta/main.yml deleted file mode 100644 index ccaac6c31..000000000 --- a/roles/internetarchive/meta/main.yml +++ /dev/null @@ -1,3 +0,0 @@ -dependencies: - - { role: nodejs, tags: ['nodejs'], when: internetarchive_install | bool } - - { role: yarn, tags: ['yarn'], when: internetarchive_install | bool } diff --git a/roles/internetarchive/tasks/enable.yml b/roles/internetarchive/tasks/enable.yml new file mode 100644 index 000000000..26788fdb6 --- /dev/null +++ b/roles/internetarchive/tasks/enable.yml @@ -0,0 +1,47 @@ +- name: Create symlink internetarchive.conf from sites-enabled to sites-available, for short URL http://box/archive (if debuntu and internetarchive_enabled) + file: + src: /etc/apache2/sites-available/internetarchive.conf + path: /etc/apache2/sites-enabled/internetarchive.conf + state: link + when: is_debuntu and internetarchive_enabled + +- name: Remove symlink /etc/apache2/sites-enabled/internetarchive.conf (if debuntu and not internetarchive_enabled) + file: + path: /etc/apache2/sites-enabled/internetarchive.conf + state: absent + when: is_debuntu and not internetarchive_enabled + + # RESTART/ENABLE SYSTEMD SERVICE +- name: Disable 'internetarchive' systemd service (if not internetarchive_enabled) + systemd: + name: internetarchive + enabled: no + when: not internetarchive_enabled + +- name: Enable & Restart 'internetarchive' systemd service (if internetarchive_enabled) + systemd: + name: internetarchive + daemon_reload: yes + enabled: yes + state: restarted + when: internetarchive_enabled | bool + +- name: Restart Apache service ({{ apache_service }}) to enable/disable http://box/archive (not just http://box:{{ internetarchive_port }}) + systemd: + name: "{{ apache_service }}" # httpd or apache2 + state: restarted + when: internetarchive_enabled | bool + +- name: Add 'internetarchive' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: internetarchive + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: Internet Archive Offline + - option: description + value: '"Dweb-mirror is intended to make the Internet Archive experience and UI available offline."' + - option: internetarchive_enabled + value: "{{ internetarchive_enabled }}" diff --git a/roles/internetarchive/tasks/install.yml b/roles/internetarchive/tasks/install.yml new file mode 100644 index 000000000..ba5cfa237 --- /dev/null +++ b/roles/internetarchive/tasks/install.yml @@ -0,0 +1,53 @@ +- name: Install NodeJS + include_role: + name: nodejs + +- name: Install Yarn + include_role: + name: yarn + +- name: Install packages needed by Internet Archive Offline + package: + name: + - libsecret-1-dev + state: present + +- name: Create directory {{ internetarchive_dir }} + file: + path: "{{ internetarchive_dir }}" + state: directory + owner: "root" + +- name: Run yarn install to get needed modules (CAN TAKE ~15 MINUTES) + shell: yarn config set child-concurrency 1 && yarn add @internetarchive/dweb-mirror + args: + chdir: "{{ internetarchive_dir }}" + creates: "{{ internetarchive_dir }}/node_modules/@internetarchive/dweb-mirror/internetarchive" + when: internet_available | bool + register: internetarchive_installing + +- name: Create directory /library/archiveorg + file: + path: "/library/archiveorg" + state: directory + owner: "root" + +# CONFIG FILES + +- name: "Install from templates: internetarchive.service (systemd), internetarchive.conf (Apache)" + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + mode: 0644 + owner: root + group: root + with_items: + - { src: 'internetarchive.service.j2', dest: '/etc/systemd/system/internetarchive.service' } + - { src: 'internetarchive.conf', dest: '/etc/apache2/sites-available/internetarchive.conf' } + +- name: Add 'internetarchive_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^internetarchive_installed' + line: 'internetarchive_installed: True' + state: present diff --git a/roles/internetarchive/tasks/main.yml b/roles/internetarchive/tasks/main.yml index c51451313..f56ec760c 100644 --- a/roles/internetarchive/tasks/main.yml +++ b/roles/internetarchive/tasks/main.yml @@ -1,115 +1,32 @@ # We need a recent version of node - - name: FAIL (STOP INSTALLING) IF nodejs_version is not set to 10.x or 12.x fail: msg: "Internet Archive install cannot proceed, as it currently requires Node.js 10.x or 12.x, and your nodejs_version is set to {{ nodejs_version }}. Please check the value of nodejs_version in /opt/iiab/iiab/vars/default_vars.yml and possibly also /etc/iiab/local_vars.yml" when: internetarchive_install and (nodejs_version != "10.x") and (nodejs_version != "12.x") -- name: Install packages needed by Internet Archive Offline - package: - name: - - libsecret-1-dev - state: present - -- name: Create directory {{ internetarchive_dir }} - file: - path: "{{ internetarchive_dir }}" - state: directory - owner: "root" - -- name: Run yarn install to get needed modules (CAN TAKE ~15 MINUTES) - shell: yarn config set child-concurrency 1 && yarn add @internetarchive/dweb-mirror - args: - chdir: "{{ internetarchive_dir }}" - creates: "{{ internetarchive_dir }}/node_modules/@internetarchive/dweb-mirror/internetarchive" - when: internet_available | bool - register: internetarchive_installing - -- name: Create directory /library/archiveorg - file: - path: "/library/archiveorg" - state: directory - owner: "root" +- name: Install Yarn and Internet Archive + include_tasks: install.yml + when: internetarchive_install and not internetarchive_installed is defined - name: Set --reinstall fact set_fact: internetarchive_upgrade: True when: reinstall is defined - -# CONFIG FILES - -- name: "Install from templates: internetarchive.service (systemd), internetarchive.conf (Apache)" - template: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - mode: 0644 - owner: root - group: root - with_items: - - { src: 'internetarchive.service.j2', dest: '/etc/systemd/system/internetarchive.service' } - - { src: 'internetarchive.conf', dest: '/etc/apache2/sites-available/internetarchive.conf' } - -- name: Create symlink internetarchive.conf from sites-enabled to sites-available, for short URL http://box/archive (if debuntu and internetarchive_enabled) - file: - src: /etc/apache2/sites-available/internetarchive.conf - path: /etc/apache2/sites-enabled/internetarchive.conf - state: link - when: is_debuntu and internetarchive_enabled - -- name: Remove symlink /etc/apache2/sites-enabled/internetarchive.conf (if debuntu and not internetarchive_enabled) - file: - path: /etc/apache2/sites-enabled/internetarchive.conf - state: absent - when: is_debuntu and not internetarchive_enabled - - # STOP SYSTEMD SERVICE - name: Stop 'internetarchive' systemd service systemd: name: internetarchive daemon_reload: yes state: stopped + when: internetarchive_enabled and internetarchive_upgrade - name: 'Update pre-existing install: yarn upgrade' shell: yarn config set child-concurrency 1 && yarn install && yarn upgrade args: chdir: "{{ internetarchive_dir }}" - when: not internetarchive_installing.changed and internetarchive_upgrade + when: internetarchive_enabled and internetarchive_upgrade - # RESTART/ENABLE SYSTEMD SERVICE -- name: Disable 'internetarchive' systemd service (if not internetarchive_enabled) - systemd: - name: internetarchive - enabled: no - when: not internetarchive_enabled - -# with "systemctl daemon-reload" in case mongodb.service changed, etc -- name: Enable & Restart 'internetarchive' systemd service (if internetarchive_enabled) - systemd: - name: internetarchive - daemon_reload: yes - enabled: yes - state: restarted - when: internetarchive_enabled | bool - -- name: Restart Apache service ({{ apache_service }}) to enable/disable http://box/archive (not just http://box:{{ internetarchive_port }}) - systemd: - name: "{{ apache_service }}" # httpd or apache2 - state: restarted - when: internetarchive_enabled | bool - - -- name: Add 'internetarchive' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" - section: internetarchive - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: Internet Archive Offline - - option: description - value: '"Dweb-mirror is intended to make the Internet Archive experience and UI available offline."' - - option: internetarchive_enabled - value: "{{ internetarchive_enabled }}" +- name: Enable Internet Archive + include_tasks: enable.yml + when: internetarchive_install or internetarchive_installed is defined diff --git a/roles/kalite/tasks/enable.yml b/roles/kalite/tasks/enable.yml index f749bf6c6..b179bd601 100644 --- a/roles/kalite/tasks/enable.yml +++ b/roles/kalite/tasks/enable.yml @@ -37,3 +37,23 @@ enabled: no state: stopped when: not kalite_cron_enabled and is_F18 + +- name: Add 'kalite' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: kalite + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: "KA Lite" + - option: description + value: '"KA Lite downloads Khan Academy videos for offline use, with exercises and accounts if students want to track their own progress."' + - option: path + value: "{{ kalite_root }}" + - option: port + value: "{{ kalite_server_port }}" + - option: kalite_enabled + value: "{{ kalite_enabled }}" + - option: cron_enabled + value: "{{ kalite_cron_enabled }}" diff --git a/roles/kalite/tasks/main.yml b/roles/kalite/tasks/main.yml index 2656d3790..a8332c117 100644 --- a/roles/kalite/tasks/main.yml +++ b/roles/kalite/tasks/main.yml @@ -15,43 +15,24 @@ - name: Does KA Lite database {{ kalite_db_name }} exist? # See if KA Lite is already configured stat: path: "{{ kalite_db_name }}" - register: kalite_installed + register: test_kalite_installed - include_tasks: install-f18.yml - when: not kalite_installed.stat.exists and is_F18 + when: not test_kalite_installed.stat.exists and is_F18 and kalite_install - include_tasks: install.yml - when: kalite_installed is defined and not kalite_installed.stat.exists and not is_F18 + when: test_kalite_installed is defined and not test_kalite_installed.stat.exists and not is_F18 and kalite_install - name: Ask systemd to reread unit files (daemon-reload) systemd: daemon_reload: yes - when: not kalite_installed.stat.exists + when: not test_kalite_installed.stat.exists - include_tasks: setup-f18.yml - when: not kalite_installed.stat.exists and is_F18 + when: not test_kalite_installed.stat.exists and is_F18 - include_tasks: setup.yml - when: not kalite_installed.stat.exists and not is_F18 + when: not test_kalite_installed.stat.exists and not is_F18 - include_tasks: enable.yml - -- name: Add 'kalite' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" - section: kalite - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: "KA Lite" - - option: description - value: '"KA Lite downloads Khan Academy videos for offline use, with exercises and accounts if students want to track their own progress."' - - option: kalite_root - value: "{{ kalite_root }}" - - option: kalite_server_port - value: "{{ kalite_server_port }}" - - option: kalite_enabled - value: "{{ kalite_enabled }}" - - option: kalite_cron_enabled - value: "{{ kalite_cron_enabled }}" + when: kalite_install or kalite_installed is defined diff --git a/roles/kalite/tasks/setup.yml b/roles/kalite/tasks/setup.yml index d0f6404e1..b9ce96a52 100644 --- a/roles/kalite/tasks/setup.yml +++ b/roles/kalite/tasks/setup.yml @@ -14,3 +14,10 @@ KALITE_HOME: "{{ kalite_root }}" # /library/ka-lite async: 1800 poll: 10 + +- name: Add 'kalite_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^kalite_installed' + line: 'kalite_installed: True' + state: present diff --git a/roles/kiwix/tasks/kiwix_enable.yml b/roles/kiwix/tasks/kiwix_enable.yml new file mode 100644 index 000000000..9e0f63f32 --- /dev/null +++ b/roles/kiwix/tasks/kiwix_enable.yml @@ -0,0 +1,90 @@ +- 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: kiwix_enabled | bool and not nginx_enabled | bool + +- name: Install nginx support + template: + backup: no + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: "{{ item.mode }}" + with_items: + - { src: 'kiwix-nginx.conf', dest: '/etc/nginx/conf.d/kiwix-nginx.conf', mode: '0644' } + when: kiwix_enabled | bool and nginx_enabled | bool + +- name: Remove symlink /etc/apache2/sites-enabled/kiwix.conf + file: + path: /etc/apache2/sites-enabled/kiwix.conf + state: absent + when: not kiwix_enabled | bool or nginx_enabled | bool + +- name: Enable & Restart 'kiwix-serve' service + systemd: + daemon_reload: yes + name: kiwix-serve + enabled: yes + state: restarted + when: kiwix_enabled | bool + +- name: Disable 'kiwix-serve' service + systemd: + name: kiwix-serve + enabled: no + state: stopped + when: not kiwix_enabled +# IN THEORY: BOTH CRON ENTRIES BELOW *SHOULD* BE DELETED "when: not kiwix_enabled" + +# In the past kiwix-serve did not stay running, so we'd been doing this hourly. +# @mgautierfr & others suggest kiwix-serve might be auto-restarted w/o cron in +# future, whenever service fails, if this really catches all cases?? +# https://github.com/iiab/iiab/issues/484#issuecomment-342151726 +- name: Make a crontab entry to restart kiwix-serve at 4AM (debuntu) + lineinfile: + # mn hr dy mo day-of-week[Sunday=0] username command-to-be-executed + line: "0 4 * * * root /bin/systemctl restart kiwix-serve.service" + dest: /etc/crontab + when: kiwix_enabled and is_debuntu + +- name: Make a crontab entry to restart kiwix-serve at 4AM (redhat) +# * * * * * user-name command to be executed + lineinfile: + # mn hr dy mo day-of-week[Sunday=0] username command-to-be-executed + line: "0 4 * * * root /usr/bin/systemctl restart kiwix-serve.service" + dest: /etc/crontab + when: kiwix_enabled and is_redhat + +- name: Restart Apache, so it picks up kiwix.conf + service: + name: "{{ apache_service }}" + state: restarted + +# 5. FINALIZE + +- name: Add 'kiwix' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: kiwix + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: Kiwix + - option: description + value: '"Part of https://github.com/kiwix/kiwix-tools/ - kiwix-serve is the most used web server for ZIM files."' + - option: kiwix_url + value: "{{ kiwix_url }}" + - option: kiwix_path + value: "{{ kiwix_path }}" + - option: kiwix_port + value: "{{ kiwix_port }}" + - option: iiab_zim_path + value: "{{ iiab_zim_path }}" + - option: kiwix_library_xml + value: "{{ kiwix_library_xml }}" + - option: kiwix_enabled + value: "{{ kiwix_enabled }}" diff --git a/roles/kiwix/tasks/kiwix_install.yml b/roles/kiwix/tasks/kiwix_install.yml index 542df81a5..1d9ae4c8b 100644 --- a/roles/kiwix/tasks/kiwix_install.yml +++ b/roles/kiwix/tasks/kiwix_install.yml @@ -1,4 +1,15 @@ # 1. CREATE/VERIFY CRITICAL DIRECTORIES & FILES ARE IN PLACE +- name: Download Kiwix software to /opt/iiab/downloads + get_url: + url: "{{ iiab_download_url }}/{{ kiwix_src_file }}" + dest: "{{ downloads_dir }}/{{ kiwix_src_file }}" + timeout: "{{ download_timeout }}" + when: internet_available | bool + +- name: Check for /opt/iiab/downloads/{{ kiwix_src_file }} + stat: + path: "{{ downloads_dir }}/{{ kiwix_src_file }}" + register: kiwix_src - name: Create directory {{ iiab_zim_path }} and subdirs {content, index} for Kiwix ZIM files file: @@ -27,16 +38,6 @@ force: no when: not kiwix_xml.stat.exists -- name: Check for /opt/iiab/kiwix/bin/kiwix-serve binary - stat: - path: "{{ kiwix_path }}/bin/kiwix-serve" - register: kiwix_bin - -- name: Set fact kiwix_force_install if kiwix-serve not found - set_fact: - kiwix_force_install: True - when: not kiwix_bin.stat.exists - - name: Install {{ iiab_zim_path }}/content/test.zim if kiwix_force_install copy: src: test.zim @@ -96,78 +97,12 @@ with_items: - { src: 'kiwix-serve.service.j2', dest: '/etc/systemd/system/kiwix-serve.service', mode: '0644'} - { src: 'iiab-make-kiwix-lib', dest: '/usr/bin/iiab-make-kiwix-lib', mode: '0755'} - - { src: 'iiab-make-kiwix-lib.py', dest: '/usr/bin/iiab-make-kiwix-lib.py', mode: '0755'} + - { src: 'iiab-make-kiwix-lib3.py', dest: '/usr/bin/iiab-make-kiwix-lib.py', mode: '0755'} - { src: 'kiwix.conf.j2', dest: '/etc/{{ apache_config_dir }}/kiwix.conf', mode: '0644'} -- 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 | bool - -- name: Enable & Restart 'kiwix-serve' service - systemd: - daemon_reload: yes - name: kiwix-serve - enabled: yes - state: restarted - when: kiwix_enabled | bool - -- name: Disable 'kiwix-serve' service - systemd: - name: kiwix-serve - enabled: no - state: stopped - when: not kiwix_enabled -# IN THEORY: BOTH CRON ENTRIES BELOW *SHOULD* BE DELETED "when: not kiwix_enabled" - -# In the past kiwix-serve did not stay running, so we'd been doing this hourly. -# @mgautierfr & others suggest kiwix-serve might be auto-restarted w/o cron in -# future, whenever service fails, if this really catches all cases?? -# https://github.com/iiab/iiab/issues/484#issuecomment-342151726 -- name: Make a crontab entry to restart kiwix-serve at 4AM (debuntu) +- name: Add 'kiwix_installed' variable values to {{ iiab_state_file }} lineinfile: - # mn hr dy mo day-of-week[Sunday=0] username command-to-be-executed - line: "0 4 * * * root /bin/systemctl restart kiwix-serve.service" - dest: /etc/crontab - when: kiwix_enabled and is_debuntu - -- name: Make a crontab entry to restart kiwix-serve at 4AM (redhat) -# * * * * * user-name command to be executed - lineinfile: - # mn hr dy mo day-of-week[Sunday=0] username command-to-be-executed - line: "0 4 * * * root /usr/bin/systemctl restart kiwix-serve.service" - dest: /etc/crontab - when: kiwix_enabled and is_redhat - -- name: Restart Apache, so it picks up kiwix.conf - service: - name: "{{ apache_service }}" - state: restarted - -# 5. FINALIZE - -- name: Add 'kiwix' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" - section: kiwix - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: Kiwix - - option: description - value: '"Part of https://github.com/kiwix/kiwix-tools/ - kiwix-serve is the most used web server for ZIM files."' - - option: kiwix_url - value: "{{ kiwix_url }}" - - option: kiwix_path - value: "{{ kiwix_path }}" - - option: kiwix_port - value: "{{ kiwix_port }}" - - option: iiab_zim_path - value: "{{ iiab_zim_path }}" - - option: kiwix_library_xml - value: "{{ kiwix_library_xml }}" - - option: kiwix_enabled - value: "{{ kiwix_enabled }}" + dest: "{{ iiab_state_file }}" + regexp: '^kiwix_installed' + line: 'kiwix_installed: True' + state: present diff --git a/roles/kiwix/tasks/main.yml b/roles/kiwix/tasks/main.yml index 2ffd410d5..a1ac24b37 100644 --- a/roles/kiwix/tasks/main.yml +++ b/roles/kiwix/tasks/main.yml @@ -23,23 +23,22 @@ msg: "WARNING: kiwix-tools SOFTWARE APPEARS UNAVAILABLE FOR YOUR {{ ansible_machine }} OS/ARCHITECTURE." when: not kiwix_src_file -- name: Download Kiwix software to /opt/iiab/downloads - get_url: - url: "{{ iiab_download_url }}/{{ kiwix_src_file }}" - dest: "{{ downloads_dir }}/{{ kiwix_src_file }}" - timeout: "{{ download_timeout }}" - when: internet_available | bool - -- name: Check for /opt/iiab/downloads/{{ kiwix_src_file }} +- name: Check for /opt/iiab/kiwix/bin/kiwix-serve binary stat: - path: "{{ downloads_dir }}/{{ kiwix_src_file }}" - register: kiwix_src + path: "{{ kiwix_path }}/bin/kiwix-serve" + register: kiwix_bin -- name: FAIL (force Ansible to exit) IF /opt/iiab/downloads/{{ kiwix_src_file }} doesn't exist - fail: - msg: "{ downloads_dir }}/{{ kiwix_src_file }} is REQUIRED in order to install Kiwix." - when: not kiwix_src.stat.exists +- name: Set fact kiwix_force_install if kiwix-serve not found + set_fact: + kiwix_force_install: True + when: not kiwix_bin.stat.exists or reinstall is defined - include_tasks: kiwix_install.yml + when: (kiwix_install | bool and not kiwix_installed is defined) or kiwix_force_install | bool + tags: + - kiwix + +- include_tasks: kiwix_enable.yml + when: kiwix_install | bool or kiwix_installed is defined tags: - kiwix diff --git a/roles/kiwix/templates/iiab-make-kiwix-lib.py b/roles/kiwix/templates/iiab-make-kiwix-lib.py index 95652ba3c..200e9324c 100755 --- a/roles/kiwix/templates/iiab-make-kiwix-lib.py +++ b/roles/kiwix/templates/iiab-make-kiwix-lib.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 """ @@ -19,7 +19,8 @@ import yaml import re import subprocess import shlex -import ConfigParser +#import ConfigParser +import configparser import xml.etree.ElementTree as ET import argparse import fnmatch @@ -153,7 +154,7 @@ def read_library_xml(lib_xml_file, kiwix_exclude_attr=[""]): # duplicated from i #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" + print ("xml record missing Book Id") id = child.attrib['id'] for attr in child.attrib: if attr not in kiwix_exclude_attr: @@ -172,7 +173,7 @@ def rem_libr_xml(id): outp = subprocess.check_output(args) except subprocess.CalledProcessError as e: if e.returncode != 2: # skip bogus file open error in kiwix-manage - print outp + print (outp) def add_libr_xml(kiwix_library_xml, zim_path, zimname, zimidx): command = kiwix_manage + " " + kiwix_library_xml + " add " + zim_path + "/" + zimname @@ -204,7 +205,8 @@ def init(): global kiwix_library_xml global kiwix_manage - config = ConfigParser.SafeConfigParser() +# config = ConfigParser.SafeConfigParser() + config = configparser.ConfigParser() config.read(iiab_ini_file) iiab_base_path = config.get('location','iiab_base') zim_path = config.get('kiwix','iiab_zim_path') @@ -242,7 +244,7 @@ def write_zim_versions_idx(): fp.write(json.dumps(zim_versions,indent=2 )) fp.close() else: - print zim_version_idx_dir + " not found." + 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 diff --git a/roles/kiwix/templates/iiab-make-kiwix-lib3.py b/roles/kiwix/templates/iiab-make-kiwix-lib3.py new file mode 100644 index 000000000..f5f73f678 --- /dev/null +++ b/roles/kiwix/templates/iiab-make-kiwix-lib3.py @@ -0,0 +1,85 @@ +#!/usr/bin/python3 + +""" + + Creates temp library.xml file for kiwix from contents of /zims/content and index + Updated to handle incremental additions and deletions + + Author: Tim Moody + Contributors: Jerry Vonau + +""" + +import os, sys, syslog +import pwd, grp +import argparse +import iiab.iiab_lib as iiab + +try: + import iiab.adm_lib as adm + adm_cons_installed = True +except: + adm_cons_installed = False + pass + +def main(): + zim_path = iiab.CONST.zim_path + zim_version_idx_dir = "" + if adm_cons_installed: + zim_version_idx_dir = adm.CONST.zim_version_idx_dir + + args = parse_args() + # args.device is either value or None + if args.device: # allow override of path + zim_path = args.device + zim_path + zim_version_idx_dir = args.device + zim_version_idx_dir + kiwix_library_xml = zim_path + "/library.xml" + + if not args.no_tmp: # don't append .tmp + kiwix_library_xml += ".tmp" + + # remove existing file if force + if args.force: + try: + os.remove(kiwix_library_xml) + except OSError: + pass + zims_installed = {} + path_to_id_map = {} + else: + zims_installed, path_to_id_map = iiab.read_library_xml(kiwix_library_xml) + + zim_files, zim_versions = iiab.get_zim_list(zim_path) + + # Remove zims not in file system from library.xml + remove_list_str = "" + for item in path_to_id_map: + if item not in zim_files: + iiab.rem_libr_xml(path_to_id_map[item], kiwix_library_xml) + + # Add zims from file system that are not in library.xml + for item in zim_files: + if item not in path_to_id_map: + iiab.add_libr_xml(kiwix_library_xml, zim_path, item, zim_files[item]) + + # Create zim_versions_idx if Admin Console installed + if adm_cons_installed: + print("Writing zim_versions_idx") + iiab.read_lang_codes() # needed by following + zim_menu_defs = adm.get_zim_menu_defs() # read all menu defs + adm.write_zim_versions_idx(zim_versions, kiwix_library_xml, zim_version_idx_dir, zim_menu_defs) + sys.exit() + +def parse_args(): + parser = argparse.ArgumentParser(description="Create library.xml for Kiwix.") + parser.add_argument("--device", help="no trailing /. change the target device from internal storage to something else like /media/usb0") + parser.add_argument("--no_tmp", help="don't append .tmp to the library.xml name", action="store_true") + parser.add_argument("-f", "--force", help="force complete rebuild of library.xml", action="store_true") + parser.add_argument("-v", "--verbose", help="Print messages.", action="store_true") + return parser.parse_args() + +# Now start the application +if __name__ == "__main__": + + # Run the main routine + main() diff --git a/roles/kiwix/templates/kiwix-nginx.conf b/roles/kiwix/templates/kiwix-nginx.conf new file mode 100644 index 000000000..c14b82f1a --- /dev/null +++ b/roles/kiwix/templates/kiwix-nginx.conf @@ -0,0 +1,3 @@ +location /kiwix { + proxy_pass http://127.0.0.1:3000; +} diff --git a/roles/kolibri/defaults/main.yml b/roles/kolibri/defaults/main.yml index 20f52bfab..e9cb42687 100644 --- a/roles/kolibri/defaults/main.yml +++ b/roles/kolibri/defaults/main.yml @@ -16,7 +16,7 @@ # https://github.com/iiab/iiab/issues/1675 # https://github.com/learningequality/kolibri/issues/5664 -kolibri_deb_url: https://learningequality.org/r/kolibri-deb-latest +kolibri_deb_url: http://ppa.launchpad.net/learningequality/kolibri/ubuntu/pool/main/k/kolibri-source/kolibri_0.12.9-0ubuntu2_all.deb # Kolibri folder to store its data and configuration files. kolibri_home: "{{ content_base }}/kolibri" # /library/kolibri diff --git a/roles/kolibri/tasks/enable.yml b/roles/kolibri/tasks/enable.yml new file mode 100644 index 000000000..b2dca9682 --- /dev/null +++ b/roles/kolibri/tasks/enable.yml @@ -0,0 +1,68 @@ +- name: Start 'kolibri' systemd service, if kolibri_enabled + systemd: + name: kolibri + state: started + enabled: yes + when: kolibri_enabled | bool + +- name: Enable http://box{{ kolibri_url }} with Apache (a2ensite) if kolibri_enabled # i.e. http://box/kolibri + command: a2ensite kolibri.conf + when: kolibri_enabled | bool and not nginx_enabled | bool + +- name: Disable & Stop 'kolibri' systemd service if not kolibri_enabled + systemd: + name: kolibri + enabled: no + state: stopped + when: not kolibri_enabled + +- name: Disable http://box{{ kolibri_url }} with Apache (a2dissite) if not kolibri_enabled + command: a2dissite kolibri.conf + when: not kolibri_enabled or nginx_enabled | bool + +- name: Supply /etc/nginx/conf.d/kolibri-nginx.conf when nginx_enabled + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + mode: "{{ item.mode }}" + owner: root + group: root + with_items: + - { src: 'kolibri-nginx.conf.j2', dest: '/etc/nginx/conf.d/kolibri-nginx.conf', mode: '0644' } + when: kolibri_enabled | bool and nginx_enabled | bool + +- name: Disable http://box{{ kolibri_url }} with Apache (a2dissite) if not kolibri_enabled + command: a2dissite kolibri.conf + when: not kolibri_enabled or nginx_enabled | bool + +- name: Restart Apache service ({{ apache_service }}) # e.g. apache2 + systemd: + name: "{{ apache_service }}" + state: restarted + when: not nginx_enabled | bool + +- name: Restart nginx service + systemd: + name: nginx + state: restarted + when: nginx_enabled | bool + +- name: Add 'kolibri' variable values to {{ iiab_ini_file }} # /etc/iiab/iiab.ini + ini_file: + path: "{{ iiab_ini_file }}" + section: kolibri + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: kolibri + - option: description + value: '"Kolibri is an open-source educational platform specially designed to provide offline access to a wide range of quality, openly licensed educational contents in low-resource contexts like rural schools, refugee camps, orphanages, and also in non-formal school programs."' + - option: kolibri_url + value: "{{ kolibri_url }}" + - option: kolibri_path + value: "{{ kolibri_exec_path }}" + - option: kolibri_port + value: "{{ kolibri_http_port }}" + - option: kolibri_enabled + value: "{{ kolibri_enabled }}" diff --git a/roles/kolibri/tasks/install.yml b/roles/kolibri/tasks/install.yml new file mode 100644 index 000000000..99dfda781 --- /dev/null +++ b/roles/kolibri/tasks/install.yml @@ -0,0 +1,120 @@ +- name: Create Linux user {{ kolibri_user }} and add it to groups {{ apache_user }}, disk + user: + name: "{{ kolibri_user }}" + groups: + - "{{ apache_user }}" + - disk + state: present + shell: /bin/false + system: yes + create_home: no + +- name: Create {{ kolibri_home }} (for Kolibri content, configuration, sqlite3 databases) + file: + path: "{{ kolibri_home }}" # /library/kolibri + owner: "{{ kolibri_user }}" # kolibri + group: "{{ apache_user }}" # www-data (on Debian/Ubuntu/Raspbian) + mode: 0755 + state: directory + +- name: Create /etc/kolibri + file: + name: /etc/kolibri + state: directory + owner: root + group: root + mode: 0755 + +- name: Save kolibri_user ({{ kolibri_user }}) to /etc/kolibri/username + copy: + content: "{{ kolibri_user }}" + dest: /etc/kolibri/username + owner: root + group: root + mode: 0644 + +- name: Save kolibri_home (KOLIBRI_HOME="{{ kolibri_home }}") to /etc/kolibri/daemon.conf + copy: + content: 'KOLIBRI_HOME="{{ kolibri_home }}"' + dest: /etc/kolibri/daemon.conf + owner: root + group: root + mode: 0644 + +- name: apt install latest Kolibri .deb from {{ kolibri_deb_url }} (populates {{ kolibri_home }}, migrates database) # i.e. /library/kolibri + apt: + deb: "{{ kolibri_deb_url }}" # https://learningequality.org/r/kolibri-deb-latest + environment: + KOLIBRI_HOME: "{{ kolibri_home }}" # these don't do a thing for now but + KOLIBRI_USER: "{{ kolibri_user }}" # both can't hurt & Might Help Later + when: internet_available | bool + +- name: 'Install from templates: kolibri.service unit file for systemd & sites-available/kolibri.conf for Apache' + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: 0644 + with_items: + - { src: 'kolibri.service.j2', dest: '/etc/systemd/system/kolibri.service' } + - { src: 'kolibri.conf.j2', dest: '/etc/apache2/sites-available/kolibri.conf' } + +- name: Enable 'kolibri' systemd service (for reboots) but ensure it's stopped for Kolibri provisioning + systemd: + name: kolibri + daemon_reload: yes + enabled: yes + state: stopped + + +# 2019-10-01: Should no longer be nec, thanks to /etc/kolibri/daemon.conf +# containing KOLIBRI_HOME="/library/kolibri" (above) +#- name: Run Kolibri migrations to begin populating {{ kolibri_home }} # i.e. /library/kolibri +# shell: export KOLIBRI_HOME="{{ kolibri_home }}" && "{{ kolibri_exec_path }}" manage migrate +# ignore_errors: yes +# become: yes +# become_user: "{{ kolibri_user }}" +# when: kolibri_provision | bool + +- name: Set Kolibri default language ({{ kolibri_language }}) + shell: export KOLIBRI_HOME="{{ kolibri_home }}" && "{{ kolibri_exec_path }}" language setdefault "{{ kolibri_language }}" + ignore_errors: yes + become: yes + become_user: "{{ kolibri_user }}" + when: kolibri_provision | bool + +- name: 'Provision Kolibri, while setting: facility name, admin acnt / password, preset type, and language' + shell: > + export KOLIBRI_HOME="{{ kolibri_home }}" && + "{{ kolibri_exec_path }}" manage provisiondevice --facility "{{ kolibri_facility }}" + --superusername "{{ kolibri_admin_user }}" --superuserpassword "{{ kolibri_admin_password }}" + --preset "{{ kolibri_preset }}" --language_id "{{ kolibri_language }}" + #--preset "{{ kolibri_preset }}" --language_id "{{ kolibri_language }}" --verbosity 0 --noinput + ignore_errors: yes + become: yes + become_user: "{{ kolibri_user }}" + when: kolibri_provision | bool + +- name: chown -R {{ kolibri_user }}:{{ apache_user }} {{ kolibri_home }} for good measure? + file: + path: "{{ kolibri_home }}" # /library/kolibri + owner: "{{ kolibri_user }}" # kolibri + group: "{{ apache_user }}" # www-data (on Debian/Ubuntu/Raspbian) + recurse: yes + when: kolibri_provision | bool + + +# 2019-10-07: Moved to roles/httpd/tasks/main.yml +# 2019-09-29: roles/kiwix/tasks/kiwix_install.yml installs 4 Apache modules +# for similar purposes (not all nec?) Only 1 (proxy_http) is needed here. +#- name: Enable Apache module proxy_http for http://box{{ kolibri_url }} # i.e. http://box/kolibri +# apache2_module: +# name: proxy_http + +- name: Add 'kolibri_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^kolibri_installed' + line: 'kolibri_installed: True' + state: present diff --git a/roles/kolibri/tasks/main.yml b/roles/kolibri/tasks/main.yml index 5c2ccd757..135287181 100644 --- a/roles/kolibri/tasks/main.yml +++ b/roles/kolibri/tasks/main.yml @@ -1,165 +1,7 @@ -- name: Create Linux user '{{ kolibri_user }}' and add it to groups '{{ apache_user }}', 'disk' - user: - name: "{{ kolibri_user }}" - groups: - - "{{ apache_user }}" - - disk - state: present - shell: /bin/false - system: yes - create_home: no +- name: Install Kolibri + include_tasks: install.yml + when: kolibri_install | bool and not kolibri_installed is defined -- name: Create {{ kolibri_home }} (for Kolibri content, configuration, sqlite3 databases) - file: - path: "{{ kolibri_home }}" # /library/kolibri - owner: "{{ kolibri_user }}" # kolibri - group: "{{ apache_user }}" # www-data (on Debian/Ubuntu/Raspbian) - mode: 0755 - state: directory - -- name: Create /etc/kolibri - file: - name: /etc/kolibri - state: directory - owner: root - group: root - mode: 0755 - -# 2019-10-14: An alternative might be to put KOLIBRI_USER="kolibri" into -# /etc/kolibri/conf.d/iiab.conf -- name: Save kolibri_user ({{ kolibri_user }}) to /etc/kolibri/username - copy: - content: "{{ kolibri_user }}" # i.e. kolibri - dest: /etc/kolibri/username - owner: root - group: root - mode: 0644 - -# 2019-10-14: An alternative mentioned by @benjaoming (Benjamin Bach) would be -# to put KOLIBRI_HOME="/library/kolibri" into /etc/kolibri/conf.d/iiab.conf -- name: Save kolibri_home (KOLIBRI_HOME="{{ kolibri_home }}") to /etc/kolibri/daemon.conf - copy: - content: 'KOLIBRI_HOME="{{ kolibri_home }}"' # i.e. /library/kolibri - dest: /etc/kolibri/daemon.conf - owner: root - group: root - mode: 0644 - -- name: apt install latest Kolibri .deb from {{ kolibri_deb_url }} (populates {{ kolibri_home }} / migrates database, based on params set in /etc/kolibri) - apt: - deb: "{{ kolibri_deb_url }}" # https://learningequality.org/r/kolibri-deb-latest - environment: - KOLIBRI_HOME: "{{ kolibri_home }}" # these don't do a thing for now but - KOLIBRI_USER: "{{ kolibri_user }}" # both can't hurt & Might Help Later - when: internet_available | bool - -- name: 'Install from templates: kolibri.service unit file for systemd & sites-available/kolibri.conf for Apache' - template: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - owner: root - group: root - mode: 0644 - with_items: - - { src: 'kolibri.service.j2', dest: '/etc/systemd/system/kolibri.service' } - - { src: 'kolibri.conf.j2', dest: '/etc/apache2/sites-available/kolibri.conf' } - -- name: Enable 'kolibri' systemd service (for reboots) but ensure it's stopped for Kolibri provisioning - systemd: - name: kolibri - daemon_reload: yes - enabled: yes - state: stopped - - -# 2019-10-01: Should no longer be nec, thanks to /etc/kolibri/daemon.conf -# containing KOLIBRI_HOME="/library/kolibri" (above) -#- name: Run Kolibri migrations to begin populating {{ kolibri_home }} # i.e. /library/kolibri -# shell: export KOLIBRI_HOME="{{ kolibri_home }}" && "{{ kolibri_exec_path }}" manage migrate -# ignore_errors: yes -# become: yes -# become_user: "{{ kolibri_user }}" -# when: kolibri_provision | bool - -- name: Set Kolibri default language ({{ kolibri_language }}) - shell: export KOLIBRI_HOME="{{ kolibri_home }}" && "{{ kolibri_exec_path }}" language setdefault "{{ kolibri_language }}" - ignore_errors: yes - become: yes - become_user: "{{ kolibri_user }}" - when: kolibri_provision | bool - -- name: 'Provision Kolibri, while setting: facility name, admin acnt / password, preset type, and language' - shell: > - export KOLIBRI_HOME="{{ kolibri_home }}" && - "{{ kolibri_exec_path }}" manage provisiondevice --facility "{{ kolibri_facility }}" - --superusername "{{ kolibri_admin_user }}" --superuserpassword "{{ kolibri_admin_password }}" - --preset "{{ kolibri_preset }}" --language_id "{{ kolibri_language }}" - #--preset "{{ kolibri_preset }}" --language_id "{{ kolibri_language }}" --verbosity 0 --noinput - ignore_errors: yes - become: yes - become_user: "{{ kolibri_user }}" - when: kolibri_provision | bool - -# 2019-10-14: This stanza should not be necessary according to @benjaoming -# (Benjamin Bach) especially as migration & provisiondevice were run above. -#- name: chown -R {{ kolibri_user }}:{{ apache_user }} {{ kolibri_home }} for good measure? -# file: -# path: "{{ kolibri_home }}" # /library/kolibri -# owner: "{{ kolibri_user }}" # kolibri -# group: "{{ apache_user }}" # www-data (on Debian/Ubuntu/Raspbian) -# recurse: yes -# when: kolibri_provision | bool - - -# 2019-10-07: Moved to roles/httpd/tasks/main.yml -# 2019-09-29: roles/kiwix/tasks/kiwix_install.yml installs 4 Apache modules -# for similar purposes (not all nec?) Only 1 (proxy_http) is needed here. -#- name: Enable Apache module proxy_http for http://box{{ kolibri_url }} # i.e. http://box/kolibri -# apache2_module: -# name: proxy_http - -- name: Start 'kolibri' systemd service, if kolibri_enabled - systemd: - name: kolibri - state: started - when: kolibri_enabled | bool - -- name: Enable http://box{{ kolibri_url }} with Apache (a2ensite) if kolibri_enabled # i.e. http://box/kolibri - command: a2ensite kolibri.conf - when: kolibri_enabled | bool - -- name: Disable & Stop 'kolibri' systemd service if not kolibri_enabled - systemd: - name: kolibri - enabled: no - state: stopped - when: not kolibri_enabled - -- name: Disable http://box{{ kolibri_url }} with Apache (a2dissite) if not kolibri_enabled - command: a2dissite kolibri.conf - when: not kolibri_enabled - -- name: Restart Apache service ({{ apache_service }}) # e.g. apache2 - systemd: - name: "{{ apache_service }}" - state: restarted - -- name: Add 'kolibri' variable values to {{ iiab_ini_file }} # /etc/iiab/iiab.ini - ini_file: - path: "{{ iiab_ini_file }}" - section: kolibri - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: kolibri - - option: description - value: '"Kolibri is an open-source educational platform specially designed to provide offline access to a wide range of quality, openly licensed educational contents in low-resource contexts like rural schools, refugee camps, orphanages, and also in non-formal school programs."' - - option: kolibri_url - value: "{{ kolibri_url }}" - - option: kolibri_exec_path - value: "{{ kolibri_exec_path }}" - - option: kolibri_http_port - value: "{{ kolibri_http_port }}" - - option: kolibri_enabled - value: "{{ kolibri_enabled }}" +- name: Enable Kolibri + include_tasks: enable.yml + when: kolibri_install | bool or kolibri_installed is defined diff --git a/roles/kolibri/templates/kolibri-nginx.conf.j2 b/roles/kolibri/templates/kolibri-nginx.conf.j2 new file mode 100644 index 000000000..163d0ee95 --- /dev/null +++ b/roles/kolibri/templates/kolibri-nginx.conf.j2 @@ -0,0 +1,8 @@ +location /kolibri/ { + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Script-Name /kolibri; + proxy_pass http://127.0.0.1:8009; +} + diff --git a/roles/lokole/tasks/enable.yml b/roles/lokole/tasks/enable.yml new file mode 100644 index 000000000..fe60530a4 --- /dev/null +++ b/roles/lokole/tasks/enable.yml @@ -0,0 +1,65 @@ +- name: Enable & Restart 'lokole' systemd service, with daemon_reload, if lokole_enabled + systemd: + daemon_reload: yes + name: lokole + enabled: yes + state: restarted + when: lokole_enabled | bool + +- name: Disable 'lokole' service, if not lokole_enabled + systemd: + daemon_reload: yes + name: lokole + enabled: no + state: stopped + when: not lokole_enabled + +- name: Install /etc/{{ apache_config_dir }}/lokole.conf from template, for http://box/lokole + template: + src: lokole.conf.j2 + dest: "/etc/{{ apache_config_dir }}/lokole.conf" + +- name: Symlink /etc/apache2/sites-enabled/lokole.conf to /etc/{{ apache_config_dir }}/lokole.conf, if lokole_enabled (debuntu) + file: + src: "/etc/{{ apache_config_dir }}/lokole.conf" + path: /etc/apache2/sites-enabled/lokole.conf + state: link + when: lokole_enabled and is_debuntu + +- name: Remove /etc/apache2/sites-enabled/lokole.conf, if not lokole_enabled (debuntu) + file: + path: /etc/apache2/sites-enabled/lokole.conf + state: absent + when: not lokole_enabled and is_debuntu + +- name: Remove /etc/{{ apache_config_dir }}/lokole.conf, if not lokole_enabled (OS's other than debuntu) + file: + path: "/etc/{{ apache_config_dir }}/lokole.conf" + state: absent + when: (not lokole_enabled) and (not is_debuntu) + +- name: Restart Apache ({{ apache_service }}) to enable/disable http://box/lokole + systemd: + daemon_reload: yes + name: "{{ apache_service }}" + state: restarted + +- name: Add 'lokole' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: lokole + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: lokole + - option: description + value: '"Lokole is an email service that works offline, for rural communities."' + - option: lokole_run_directory + value: "{{ lokole_run_directory }}" + - option: lokole_url + value: "{{ lokole_url }}" + - option: lokole_full_url + value: "{{ lokole_full_url }}" + - option: lokole_enabled + value: "{{ lokole_enabled }}" diff --git a/roles/lokole/tasks/install.yml b/roles/lokole/tasks/install.yml index 194472ac6..d531177c0 100644 --- a/roles/lokole/tasks/install.yml +++ b/roles/lokole/tasks/install.yml @@ -98,59 +98,9 @@ state: restarted when: lokole_enabled | bool -- name: Disable 'lokole' service, if not lokole_enabled - systemd: - name: lokole - enabled: no - state: stopped - when: not lokole_enabled - -- name: Install /etc/{{ apache_config_dir }}/lokole.conf from template, for http://box/lokole - template: - src: lokole.conf.j2 - dest: "/etc/{{ apache_config_dir }}/lokole.conf" - -- name: Symlink /etc/apache2/sites-enabled/lokole.conf to /etc/{{ apache_config_dir }}/lokole.conf, if lokole_enabled (debuntu) - file: - src: "/etc/{{ apache_config_dir }}/lokole.conf" - path: /etc/apache2/sites-enabled/lokole.conf - state: link - when: lokole_enabled and is_debuntu - -- name: Remove /etc/apache2/sites-enabled/lokole.conf, if not lokole_enabled (debuntu) - file: - path: /etc/apache2/sites-enabled/lokole.conf - state: absent - when: not lokole_enabled and is_debuntu - -- name: Remove /etc/{{ apache_config_dir }}/lokole.conf, if not lokole_enabled (OS's other than debuntu) - file: - path: "/etc/{{ apache_config_dir }}/lokole.conf" - state: absent - when: (not lokole_enabled) and (not is_debuntu) - -- name: Restart Apache ({{ apache_service }}) to enable/disable http://box/lokole - systemd: - daemon_reload: yes - name: "{{ apache_service }}" - state: restarted - -- name: Add 'lokole' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" - section: lokole - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: lokole - - option: description - value: '"Lokole is an email service that works offline, for rural communities."' - - option: lokole_run_directory - value: "{{ lokole_run_directory }}" - - option: lokole_url - value: "{{ lokole_url }}" - - option: lokole_full_url - value: "{{ lokole_full_url }}" - - option: lokole_enabled - value: "{{ lokole_enabled }}" +- name: Add 'lokole_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^lokole_installed' + line: 'lokole_installed: True' + state: present diff --git a/roles/lokole/tasks/main.yml b/roles/lokole/tasks/main.yml index 5f05bd4a3..159a92485 100644 --- a/roles/lokole/tasks/main.yml +++ b/roles/lokole/tasks/main.yml @@ -1,3 +1,7 @@ - name: Install Lokole {{ lokole_version }} if lokole_install include_tasks: install.yml - when: lokole_install | bool + when: lokole_install | bool and not lokole_installed is defined + +- name: Enable Lokole + include_tasks: enable.yml + when: lokole_install | bool or lokole_installed is defined diff --git a/roles/mediawiki/tasks/enable.yml b/roles/mediawiki/tasks/enable.yml new file mode 100644 index 000000000..4acbe1e12 --- /dev/null +++ b/roles/mediawiki/tasks/enable.yml @@ -0,0 +1,44 @@ +- name: Create softlink mediawiki.conf from sites-enabled to sites-available, if mediawiki_enabled (debuntu) + file: + src: /etc/apache2/sites-available/mediawiki.conf + dest: /etc/apache2/sites-enabled/mediawiki.conf + state: link + when: mediawiki_enabled and is_debuntu + +- name: Remove mediawiki.conf if not mediawiki_enabled (debuntu) + file: + path: /etc/apache2/sites-enabled/mediawiki.conf + state: absent + when: not mediawiki_enabled and is_debuntu + +- name: Restart Apache service ({{ apache_service }}) to enable/disable http://box{{ mediawiki_url }} + systemd: + name: "{{ apache_service }}" + daemon_reload: yes + state: restarted + +- name: Add 'mediawiki' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: mediawiki + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: mediawiki + - option: description + value: '"mediawiki is a blog and web site management application."' + - option: mediawiki_src + value: "{{ mediawiki_src }}" + - option: mediawiki_abs_path + value: "{{ mediawiki_abs_path }}" + - option: mediawiki_db_name + value: "{{ mediawiki_db_name }}" + - option: mediawiki_db_user + value: "{{ mediawiki_db_user }}" + - option: mediawiki_url + value: "{{ mediawiki_url }}" + - option: mediawiki_full_url + value: "{{ mediawiki_full_url }}" + - option: mediawiki_enabled + value: "{{ mediawiki_enabled }}" diff --git a/roles/mediawiki/tasks/install.yml b/roles/mediawiki/tasks/install.yml index db90e1e6c..884ab7497 100644 --- a/roles/mediawiki/tasks/install.yml +++ b/roles/mediawiki/tasks/install.yml @@ -65,46 +65,9 @@ src: mediawiki.conf.j2 dest: "/etc/{{ apache_config_dir }}/mediawiki.conf" -- name: Create softlink mediawiki.conf from sites-enabled to sites-available, if mediawiki_enabled (debuntu) - file: - src: /etc/apache2/sites-available/mediawiki.conf - dest: /etc/apache2/sites-enabled/mediawiki.conf - state: link - when: mediawiki_enabled and is_debuntu - -- name: Remove mediawiki.conf if not mediawiki_enabled (debuntu) - file: - path: /etc/apache2/sites-enabled/mediawiki.conf - state: absent - when: not mediawiki_enabled and is_debuntu - -- name: Restart Apache service ({{ apache_service }}) to enable/disable http://box{{ mediawiki_url }} - systemd: - name: "{{ apache_service }}" - state: restarted - -- name: Add 'mediawiki' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" - section: mediawiki - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: mediawiki - - option: description - value: '"mediawiki is a blog and web site management application."' - - option: mediawiki_src - value: "{{ mediawiki_src }}" - - option: mediawiki_abs_path - value: "{{ mediawiki_abs_path }}" - - option: mediawiki_db_name - value: "{{ mediawiki_db_name }}" - - option: mediawiki_db_user - value: "{{ mediawiki_db_user }}" - - option: mediawiki_url - value: "{{ mediawiki_url }}" - - option: mediawiki_full_url - value: "{{ mediawiki_full_url }}" - - option: mediawiki_enabled - value: "{{ mediawiki_enabled }}" +- name: Add 'mediawiki_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^mediawiki_installed' + line: 'mediawiki_installed: True' + state: present diff --git a/roles/mediawiki/tasks/main.yml b/roles/mediawiki/tasks/main.yml index bf0a4d795..ee96ee73b 100644 --- a/roles/mediawiki/tasks/main.yml +++ b/roles/mediawiki/tasks/main.yml @@ -1,3 +1,7 @@ - name: Install MediaWiki {{ mediawiki_version }} if mediawiki_install include_tasks: install.yml - when: mediawiki_install | bool + when: mediawiki_install | bool and not mediawiki_installed is defined + +- name: Install MediaWiki {{ mediawiki_version }} if mediawiki_install + include_tasks: enable.yml + when: mediawiki_install | bool or mediawiki_installed is defined diff --git a/roles/minetest/tasks/enable.yml b/roles/minetest/tasks/enable.yml new file mode 100644 index 000000000..170b51629 --- /dev/null +++ b/roles/minetest/tasks/enable.yml @@ -0,0 +1,36 @@ +# enable or disable +- name: Enable & Restart 'minetest-server' service + systemd: + daemon_reload: yes + name: minetest-server + enabled: yes + state: restarted + when: minetest_enabled | bool + +- name: Disable 'minetest-server' service + systemd: + daemon_reload: yes + name: minetest-server + enabled: no + state: stopped + when: not minetest_enabled + +- name: Add 'minetest' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: minetest + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: Minetest Server + - option: description + value: '"Minetest is an open source clone of the Minecraft building blocks game."' + - option: minetest_world_dir + value: "{{ minetest_world_dir }}" + - option: minetest_port + value: "{{ minetest_port }}" + - option: minetest_enabled + value: "{{ minetest_enabled }}" + - option: minetest_world_dir + value: "{{ minetest_world_dir }}" diff --git a/roles/minetest/tasks/main.yml b/roles/minetest/tasks/main.yml index 042dccde9..320079d06 100644 --- a/roles/minetest/tasks/main.yml +++ b/roles/minetest/tasks/main.yml @@ -1,109 +1,5 @@ -# Calculate local variables -- include_tasks: calc_vars.yml +- include_tasks: provision.yml + when: minetest_install and not minetest_installed is defined -- name: Check for minetest world file ({{ minetest_world_dir }}/world.mt) - stat: - path: "{{ minetest_world_dir }}/world.mt" - register: minetest_world - -- name: Create /library/games - file: - state: directory - path: "{{ item }}" - owner: root - group: root - mode: 0755 - with_items: - - /library/games - -# rpi only -- include_tasks: rpi_minetest_install.yml - when: not minetest_world.stat.exists and is_rpi - -# not rpi -- include_tasks: minetest_install.yml - when: not minetest_world.stat.exists and not is_rpi - -- git: - repo: https://github.com/Calinou/carbone-ng.git - dest: "{{ minetest_game_dir }}" - depth: 1 - when: not minetest_world.stat.exists and minetest_default_game == "carbone-ng" - -- name: Give minetest user ownership of carbone-ng - file: - state: directory - path: "{{ minetest_game_dir }}" - recurse: yes - owner: "{{ minetest_runas_user }}" - group: "{{ minetest_runas_group }}" - mode: 0755 - when: minetest_default_game == "carbone-ng" - -# Install games -#- include: minetest_install_games.yml -# with_items: -# - name: carbone-ng -# url: https://github.com/Calinou/carbone-ng - -# Install mods -- include: minetest_install_mods.yml - with_items: - - name: moreblocks - url: https://github.com/minetest-mods/moreblocks/archive/master.zip - - name: moreores - url: https://github.com/Calinou/moreores/archive/master.zip - - name: basic_materials - url: https://gitlab.com/VanessaE/basic_materials/-/archive/master/basic_materials-master.zip - - name: mesecons - url: https://github.com/minetest-mods/mesecons/archive/master.zip - - name: digilines - url: https://github.com/minetest-mods/digilines/archive/master.zip - - name: pipeworks - url: https://github.com/minetest-mods/pipeworks/archive/master.zip - - name: Minetest-WorldEdit - url: https://github.com/Uberi/Minetest-WorldEdit/archive/master.zip - when: minetest_default_game == "minetest" - -- name: Remove mod from carbone-ng that prevents our Admin name - file: - state: absent - path: "{{ minetest_game_dir }}/mods/name_restrictions" - when: minetest_default_game == "carbone-ng" - -# enable or disable -- name: Enable & Restart 'minetest-server' service - systemd: - daemon_reload: yes - name: minetest-server - enabled: yes - state: restarted - when: minetest_enabled | bool - -- name: Disable 'minetest-server' service - systemd: - daemon_reload: yes - name: minetest-server - enabled: no - state: stopped - when: not minetest_enabled - -- name: Add 'minetest' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" - section: minetest - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: Minetest Server - - option: description - value: '"Minetest is an open source clone of the Minecraft building blocks game."' - - option: minetest_world_dir - value: "{{ minetest_world_dir }}" - - option: minetest_port - value: "{{ minetest_port }}" - - option: minetest_enabled - value: "{{ minetest_enabled }}" - - option: minetest_world_dir - value: "{{ minetest_world_dir }}" +- include_tasks: enable.yml + when: minetest_install or minetest_installed is defined diff --git a/roles/minetest/tasks/provision.yml b/roles/minetest/tasks/provision.yml new file mode 100644 index 000000000..ea34c1779 --- /dev/null +++ b/roles/minetest/tasks/provision.yml @@ -0,0 +1,80 @@ +# Calculate local variables +- include_tasks: calc_vars.yml + +- name: Check for minetest world file ({{ minetest_world_dir }}/world.mt) + stat: + path: "{{ minetest_world_dir }}/world.mt" + register: minetest_world + +- name: Create /library/games + file: + state: directory + path: "{{ item }}" + owner: root + group: root + mode: 0755 + with_items: + - /library/games + +# rpi only +- include_tasks: rpi_minetest_install.yml + when: not minetest_world.stat.exists and is_rpi + +# not rpi +- include_tasks: minetest_install.yml + when: not minetest_world.stat.exists and not is_rpi + +- git: + repo: https://github.com/Calinou/carbone-ng.git + dest: "{{ minetest_game_dir }}" + depth: 1 + when: not minetest_world.stat.exists and minetest_default_game == "carbone-ng" + +- name: Give minetest user ownership of carbone-ng + file: + state: directory + path: "{{ minetest_game_dir }}" + recurse: yes + owner: "{{ minetest_runas_user }}" + group: "{{ minetest_runas_group }}" + mode: 0755 + when: minetest_default_game == "carbone-ng" + +# Install games +#- include: minetest_install_games.yml +# with_items: +# - name: carbone-ng +# url: https://github.com/Calinou/carbone-ng + +# Install mods +- include: minetest_install_mods.yml + with_items: + - name: moreblocks + url: https://github.com/minetest-mods/moreblocks/archive/master.zip + - name: moreores + url: https://github.com/Calinou/moreores/archive/master.zip + - name: basic_materials + url: https://gitlab.com/VanessaE/basic_materials/-/archive/master/basic_materials-master.zip + - name: mesecons + url: https://github.com/minetest-mods/mesecons/archive/master.zip + - name: digilines + url: https://github.com/minetest-mods/digilines/archive/master.zip + - name: pipeworks + url: https://github.com/minetest-mods/pipeworks/archive/master.zip + - name: Minetest-WorldEdit + url: https://github.com/Uberi/Minetest-WorldEdit/archive/master.zip + when: minetest_default_game == "minetest" + +- name: Remove mod from carbone-ng that prevents our Admin name + file: + state: absent + path: "{{ minetest_game_dir }}/mods/name_restrictions" + when: minetest_default_game == "carbone-ng" + +- name: Add 'minetest_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^minetest_installed' + line: 'minetest_installed: True' + state: present + diff --git a/roles/mongodb/tasks/enable.yml b/roles/mongodb/tasks/enable.yml new file mode 100644 index 000000000..f7bf994f0 --- /dev/null +++ b/roles/mongodb/tasks/enable.yml @@ -0,0 +1,38 @@ +# 3. ENABLE/DISABLE + +# 2019-07-08: mongodb_install is completely ignored. FYI mongodb_enabled: False +# works but is ineffective, as Sugarizer starts mongodb's systemd svc on its own + +- name: Enable & Restart 'mongodb' systemd service if mongodb_enabled, incl daemon-reload (in case mongodb.service changed?) + systemd: + name: mongodb + daemon_reload: yes + enabled: yes + state: restarted + when: mongodb_enabled | bool + +- name: Disable 'mongodb' service, if not mongodb_enabled + systemd: + name: mongodb + daemon_reload: yes + enabled: no + state: stopped + when: not mongodb_enabled + + +# 4. DOCUMENT IN /etc/iiab/iiab.ini + +- name: Add 'mongodb' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: mongodb + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: MongoDB + - option: description + value: '"MongoDB is an open-source document database that provides high performance, high availability, and automatic scaling."' + - option: enabled + value: "{{ mongodb_enabled }}" + diff --git a/roles/mongodb/tasks/install.yml b/roles/mongodb/tasks/install.yml index c87cf49fa..2268ac82e 100644 --- a/roles/mongodb/tasks/install.yml +++ b/roles/mongodb/tasks/install.yml @@ -128,41 +128,9 @@ - { src: 'mongodb.service.j2', dest: '/etc/systemd/system/mongodb.service', mode: '0644' } - { src: 'iiab-mongodb-repair-if-no-lock.j2', dest: '/usr/bin/iiab-mongodb-repair-if-no-lock', mode: '0755' } - -# 3. ENABLE/DISABLE - -# 2019-07-08: mongodb_install is completely ignored. FYI mongodb_enabled: False -# works but is ineffective, as Sugarizer starts mongodb's systemd svc on its own - -- name: Enable & Restart 'mongodb' systemd service if mongodb_enabled, incl daemon-reload (in case mongodb.service changed?) - systemd: - name: mongodb - daemon_reload: yes - enabled: yes - state: restarted - when: mongodb_enabled | bool - -- name: Disable 'mongodb' service, if not mongodb_enabled - systemd: - name: mongodb - daemon_reload: yes - enabled: no - state: stopped - when: not mongodb_enabled - - -# 4. DOCUMENT IN /etc/iiab/iiab.ini - -- name: Add 'mongodb' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" - section: mongodb - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: MongoDB - - option: description - value: '"MongoDB is an open-source document database that provides high performance, high availability, and automatic scaling."' - - option: enabled - value: "{{ mongodb_enabled }}" +- name: Add 'mongodb_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^mongodb_installed' + line: 'mongodb_installed: True' + state: present diff --git a/roles/mongodb/tasks/main.yml b/roles/mongodb/tasks/main.yml index c3d3f8eba..61a2aa429 100644 --- a/roles/mongodb/tasks/main.yml +++ b/roles/mongodb/tasks/main.yml @@ -3,4 +3,9 @@ - name: Install 'mongodb' if not Debian 10+ include_tasks: install.yml - when: not ((is_debian and not is_raspbian) and (not is_debian_8) and (not is_debian_9)) + when: not ((is_debian and not is_raspbian) and (not is_debian_8) and (not is_debian_9)) and not mongodb_installed is defined + +- name: Enable 'mongodb' if not Debian 10+ + include_tasks: enable.yml + when: not ((is_debian and not is_raspbian) and (not is_debian_8) and (not is_debian_9)) or mongodb_installed is defined + diff --git a/roles/moodle/tasks/enable.yml b/roles/moodle/tasks/enable.yml new file mode 100644 index 000000000..da499ed58 --- /dev/null +++ b/roles/moodle/tasks/enable.yml @@ -0,0 +1,34 @@ +- name: Create symlink 022-moodle.conf from sites-enabled to sites-available, if moodle_enabled (debuntu) + file: + src: /etc/apache2/sites-available/022-moodle.conf + dest: /etc/apache2/sites-enabled/022-moodle.conf + state: link + when: moodle_enabled and is_debuntu + +- name: Remove symlink 022-moodle.conf, if not moodle_enabled (debuntu) + file: + path: /etc/apache2/sites-enabled/022-moodle.conf + state: absent + when: not moodle_enabled and is_debuntu + +- name: Restart Apache service ({{ apache_service }}) + systemd: + name: "{{ apache_service }}" + state: restarted + daemon-reload: yes + +- name: Add 'moodle' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: moodle + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: Moodle + - option: description + value: '"Access the Moodle learning management system."' + - option: "moodle_base" + value: "{{ moodle_base }}" + - option: moodle_enabled + value: "{{ moodle_enabled }}" diff --git a/roles/moodle/tasks/install.yml b/roles/moodle/tasks/install.yml new file mode 100644 index 000000000..036867eb1 --- /dev/null +++ b/roles/moodle/tasks/install.yml @@ -0,0 +1,146 @@ +- name: "Install packages: python-psycopg2, php-pgsql (OS's other than debuntu)" + package: + name: + - python-psycopg2 + - php-pgsql + state: present + when: not is_debuntu + +- name: Install 4 php packages (debuntu) + package: + name: + - php{{ php_version }}-pgsql + - php{{ php_version }}-curl + #- php{{ php_version }}-zip + - php{{ php_version }}-gd + #- php{{ php_version }}-mbstring + # mbstring is now included in php-cli + - php{{ php_version }}-cli + state: present + when: is_debuntu | bool + +- name: "Install package: php{{ php_version }}-zip (ubuntu or debian-9+)" + package: + name: "php{{ php_version }}-zip" + when: is_ubuntu or (is_debian and not is_debian_8) + +- name: "Install package: php-pclzip (debian-8)" + package: + name: php-pclzip + when: is_debian_8 | bool + +- name: Determine if Moodle is already downloaded + stat: + path: "{{ moodle_base }}/config-dist.php" + register: moodle + +- name: Download the latest Moodle repo + git: + repo: "{{ moodle_repo_url }}" + dest: "{{ moodle_base }}" + depth: 1 + force: yes + version: "MOODLE_{{ moodle_version }}_STABLE" + #version: master # TEMPORARY DURING MAY 2018 TESTING, installed 3.5beta+ = https://download.moodle.org/releases/development/ + #ignore_errors: yes + when: internet_available and moodle.stat.exists is defined and not moodle.stat.exists + +- name: Create dir {{ moodle_base }} owned by {{ apache_user }} (for config file?) + file: + path: "{{ moodle_base }}" + owner: "{{ apache_user }}" + recurse: yes + state: directory + +- name: Create dir {{ content_base }}/dbdata/moodle owned by {{ apache_user }} with write permission 0755 + file: + path: "{{ content_base }}/dbdata/moodle" + owner: "{{ apache_user }}" + mode: 0755 + state: directory + +- name: Create dir {{ moodle_data }} owned by {{ apache_user }}:{{ apache_user }} with write permission 0770 # /library/moodle + file: + path: "{{ moodle_data }}" + owner: "{{ apache_user }}" + group: "{{ apache_user }}" + mode: 0770 + state: directory + +- name: Remove Apache's stock moodle.conf + file: + path: "/etc/{{ apache_config_dir }}/moodle.conf" + state: absent + +- name: Install Apache's 022-moodle.conf from template, if moodle_enabled + template: + src: 022-moodle.j2 + dest: "/etc/{{ apache_config_dir }}/022-moodle.conf" + owner: root + group: root + mode: 0644 + +- name: Restart postgresql-iiab + service: + name: postgresql-iiab + state: restarted + +- name: Create PostgreSQL db user Admin/changeme + postgresql_user: + name: Admin + password: changeme + encrypted: yes # Required by PostgreSQL 10+ e.g. Ubuntu 18.04's PostgreSQL 10.3+, see https://github.com/iiab/iiab/issues/759 + role_attr_flags: NOSUPERUSER,NOCREATEROLE,NOCREATEDB + state: present + become: yes + become_user: postgres + +- name: 'Create database: {{ moodle_database_name }}' + postgresql_db: + name: "{{ moodle_database_name }}" + encoding: utf8 + owner: Admin + template: template1 + state: present + become: yes + become_user: postgres + +- name: Install {{ moodle_base }}/moodle_installer from template + template: + src: moodle_installer + dest: "{{ moodle_base }}" + mode: 0755 + +- name: Enable & Restart postgresql-iiab + service: + name: postgresql-iiab + state: restarted + enabled: yes + when: moodle_enabled | bool + +- name: Restart Apache service ({{ apache_service }}) + service: + name: "{{ apache_service }}" + state: restarted + +- name: Does {{ moodle_base }}/config.php exist? + stat: + path: "{{ moodle_base }}/config.php" + register: config + +- name: Execute {{ moodle_base }}/moodle_installer + shell: "{{ moodle_base }}/moodle_installer" + when: config.stat.exists is defined and not config.stat.exists + +- name: Give read permission 0644 to {{ moodle_base }}/config.php # /opt/iiab/moodle/config.php + #command: chown -R {{ apache_user }} {{ moodle_base }} + file: + path: "{{ moodle_base }}/config.php" + mode: 0644 + +- name: Add 'moodle_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^moodle_installed' + line: 'moodle_installed: True' + state: present diff --git a/roles/moodle/tasks/main.yml b/roles/moodle/tasks/main.yml index 5495f230b..baadf93c4 100644 --- a/roles/moodle/tasks/main.yml +++ b/roles/moodle/tasks/main.yml @@ -1,169 +1,7 @@ -- name: "Install packages: python-psycopg2, php-pgsql (OS's other than debuntu)" - package: - name: - - python-psycopg2 - - php-pgsql - state: present - when: not is_debuntu +- name: "Install Moodle" + include_tasks: install.yml + when: moodle_install | bool and not moodle_installed is defined -- name: Install 4 php packages (debuntu) - package: - name: - - php{{ php_version }}-pgsql - - php{{ php_version }}-curl - #- php{{ php_version }}-zip - - php{{ php_version }}-gd - #- php{{ php_version }}-mbstring - # mbstring is now included in php-cli - - php{{ php_version }}-cli - state: present - when: is_debuntu | bool - -- name: "Install package: php{{ php_version }}-zip (ubuntu or debian-9+)" - package: - name: "php{{ php_version }}-zip" - when: is_ubuntu or (is_debian and not is_debian_8) - -- name: "Install package: php-pclzip (debian-8)" - package: - name: php-pclzip - when: is_debian_8 | bool - -- name: Determine if Moodle is already downloaded - stat: - path: "{{ moodle_base }}/config-dist.php" - register: moodle - -- name: Download the latest Moodle repo - git: - repo: "{{ moodle_repo_url }}" - dest: "{{ moodle_base }}" - depth: 1 - force: yes - version: "MOODLE_{{ moodle_version }}_STABLE" - #version: master # TEMPORARY DURING MAY 2018 TESTING, installed 3.5beta+ = https://download.moodle.org/releases/development/ - #ignore_errors: yes - when: internet_available and moodle.stat.exists is defined and not moodle.stat.exists - -- name: Create dir {{ moodle_base }} owned by {{ apache_user }} (for config file?) - file: - path: "{{ moodle_base }}" - owner: "{{ apache_user }}" - recurse: yes - state: directory - -- name: Create dir {{ content_base }}/dbdata/moodle owned by {{ apache_user }} with write permission 0755 - file: - path: "{{ content_base }}/dbdata/moodle" - owner: "{{ apache_user }}" - mode: 0755 - state: directory - -- name: Create dir {{ moodle_data }} owned by {{ apache_user }}:{{ apache_user }} with write permission 0770 # /library/moodle - file: - path: "{{ moodle_data }}" - owner: "{{ apache_user }}" - group: "{{ apache_user }}" - mode: 0770 - state: directory - -- name: Remove Apache's stock moodle.conf - file: - path: "/etc/{{ apache_config_dir }}/moodle.conf" - state: absent - -- name: Install Apache's 022-moodle.conf from template, if moodle_enabled - template: - src: 022-moodle.j2 - dest: "/etc/{{ apache_config_dir }}/022-moodle.conf" - owner: root - group: root - mode: 0644 - when: moodle_enabled | bool - -- name: Create symlink 022-moodle.conf from sites-enabled to sites-available, if moodle_enabled (debuntu) - file: - src: /etc/apache2/sites-available/022-moodle.conf - dest: /etc/apache2/sites-enabled/022-moodle.conf - state: link - when: moodle_enabled and is_debuntu - -- name: Remove symlink 022-moodle.conf, if not moodle_enabled (debuntu) - file: - path: /etc/apache2/sites-enabled/022-moodle.conf - state: absent - when: not moodle_enabled and is_debuntu - -- name: Restart postgresql-iiab - service: - name: postgresql-iiab - state: restarted - -- name: Create PostgreSQL db user Admin/changeme - postgresql_user: - name: Admin - password: changeme - encrypted: yes # Required by PostgreSQL 10+ e.g. Ubuntu 18.04's PostgreSQL 10.3+, see https://github.com/iiab/iiab/issues/759 - role_attr_flags: NOSUPERUSER,NOCREATEROLE,NOCREATEDB - state: present - become: yes - become_user: postgres - -- name: 'Create database: {{ moodle_database_name }}' - postgresql_db: - name: "{{ moodle_database_name }}" - encoding: utf8 - owner: Admin - template: template1 - state: present - become: yes - become_user: postgres - -- name: Install {{ moodle_base }}/moodle_installer from template - template: - src: moodle_installer - dest: "{{ moodle_base }}" - mode: 0755 - -- name: Enable & Restart postgresql-iiab - service: - name: postgresql-iiab - state: restarted - enabled: yes - when: moodle_enabled | bool - -- name: Restart Apache service ({{ apache_service }}) - service: - name: "{{ apache_service }}" - state: restarted - -- name: Does {{ moodle_base }}/config.php exist? - stat: - path: "{{ moodle_base }}/config.php" - register: config - -- name: Execute {{ moodle_base }}/moodle_installer - shell: "{{ moodle_base }}/moodle_installer" - when: config.stat.exists is defined and not config.stat.exists - -- name: Give read permission 0644 to {{ moodle_base }}/config.php # /opt/iiab/moodle/config.php - #command: chown -R {{ apache_user }} {{ moodle_base }} - file: - path: "{{ moodle_base }}/config.php" - mode: 0644 - -- name: Add 'moodle' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" - section: moodle - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: Moodle - - option: description - value: '"Access the Moodle learning management system."' - - option: "moodle_base" - value: "{{ moodle_base }}" - - option: moodle_enabled - value: "{{ moodle_enabled }}" +- name: Enable Moodle + include_tasks: enable.yml + when: moodle_install | bool or moodle_installed is defined diff --git a/roles/moodle/templates/moodle-nginx.conf.j2.native b/roles/moodle/templates/moodle-nginx.conf.j2.native new file mode 100644 index 000000000..bbf2fabe0 --- /dev/null +++ b/roles/moodle/templates/moodle-nginx.conf.j2.native @@ -0,0 +1,16 @@ +location ^/moodle { + alias /opt/iiab/moodle; + try_files $uri $uri/ index.php =404; +} +location ~ /moodle/(.*)\.php { + root /opt/iiab/; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Host $host; + include fastcgi_params; + fastcgi_index index.php; + fastcgi_pass php; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param SCRIPT_NAME $fastcgi_script_name; +} diff --git a/roles/mosquitto/tasks/enable.yml b/roles/mosquitto/tasks/enable.yml new file mode 100644 index 000000000..a7e1e0768 --- /dev/null +++ b/roles/mosquitto/tasks/enable.yml @@ -0,0 +1,21 @@ +- name: Enable & Start 'mosquitto' service + systemd: + daemon_reload: yes + name: mosquitto + enabled: yes + state: started + when: mosquitto_enabled | bool + +- name: Add 'mosquitto' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: mosquitto + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: Mosquitto service + - option: description + value: Mosquitto service + - option: mosquitto_enabled + value: "{{ mosquitto_enabled }}" diff --git a/roles/mosquitto/tasks/install.yml b/roles/mosquitto/tasks/install.yml new file mode 100644 index 000000000..c7edfad69 --- /dev/null +++ b/roles/mosquitto/tasks/install.yml @@ -0,0 +1,38 @@ +- name: "Install packages: mosquitto, mosquitto-clients" + package: + name: "{{ item }}" + state: present + with_items: + - mosquitto + - mosquitto-clients + tags: download + +- name: Disable & Stop 'mosquitto' service + systemd: + name: mosquitto + enabled: no + state: stopped + +- name: Create (touch) file /etc/mosquitto/passwd + file: + path: /etc/mosquitto/passwd + state: touch + mode: "u=rw,g=r,o=r" # 0644 + +- name: Populate /etc/mosquitto/passwd with actual username/password + shell: mosquitto_passwd -b /etc/mosquitto/passwd "{{ mosquitto_user }}" "{{ mosquitto_password }}" + +- name: Install /etc/mosquitto/conf.d/websockets.conf from template + template: + src: websockets.conf.j2 + dest: /etc/mosquitto/conf.d/websockets.conf + owner: root + group: root + mode: 0755 + +- name: Add 'mosquitto_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^mosquitto_installed' + line: 'mosquitto_installed: True' + state: present diff --git a/roles/mosquitto/tasks/main.yml b/roles/mosquitto/tasks/main.yml index 53ef14998..b6654ef3b 100644 --- a/roles/mosquitto/tasks/main.yml +++ b/roles/mosquitto/tasks/main.yml @@ -1,45 +1,5 @@ -- name: "Install packages: mosquitto, mosquitto-clients" - package: - name: "{{ item }}" - state: present - with_items: - - mosquitto - - mosquitto-clients - when: mosquitto_install | bool - tags: download +- include_tasks: install.yml + when: mosquitto_install | bool and not mosquitto_installed is defined -- name: Disable & Stop 'mosquitto' service - systemd: - name: mosquitto - enabled: no - state: stopped - when: mosquitto_install | bool - -- name: Create (touch) file /etc/mosquitto/passwd - file: - path: /etc/mosquitto/passwd - state: touch - mode: "u=rw,g=r,o=r" # 0644 - when: mosquitto_install | bool - -- name: Populate /etc/mosquitto/passwd with actual username/password - shell: mosquitto_passwd -b /etc/mosquitto/passwd "{{ mosquitto_user }}" "{{ mosquitto_password }}" - when: mosquitto_install | bool - -- name: Install /etc/mosquitto/conf.d/websockets.conf from template - template: - backup: yes - src: websockets.conf.j2 - dest: /etc/mosquitto/conf.d/websockets.conf - owner: root - group: root - mode: 0755 - when: mosquitto_install | bool - -- name: Enable & Start 'mosquitto' service - systemd: - daemon_reload: yes - name: mosquitto - enabled: yes - state: started - when: mosquitto_enabled | bool +- include_tasks: enable.yml + when: mosquitto_install | bool or mosquitto_installed is defined diff --git a/roles/munin/tasks/enable.yml b/roles/munin/tasks/enable.yml new file mode 100644 index 000000000..e47e59b1e --- /dev/null +++ b/roles/munin/tasks/enable.yml @@ -0,0 +1,67 @@ +- name: If MySQL is enabled, let Munin monitor it + copy: + src: "{{ item }}" + dest: /etc/munin/plugins/ + with_items: + - /usr/share/munin/plugins/mysql_ + - /usr/share/munin/plugins/mysql_bytes + - /usr/share/munin/plugins/mysql_innodb + - /usr/share/munin/plugins/mysql_isam_space_ + - /usr/share/munin/plugins/mysql_queries + - /usr/share/munin/plugins/mysql_slowqueries + - /usr/share/munin/plugins/mysql_threads + when: mysql_enabled | bool + +- name: Enable & Start munin-node systemd service + systemd: + name: munin-node + enabled: yes + state: started + when: munin_enabled | bool + +- name: Disable munin-node service if not munin_enabled + systemd: + name: munin-node + enabled: no + state: stopped + when: not munin_enabled + +- name: Create symlink munin24.conf from sites-enabled to sites-available (debuntu) + file: + src: /etc/apache2/sites-available/munin24.conf + path: /etc/apache2/sites-enabled/munin24.conf + state: link + when: munin_enabled and not nginx_enabled + +- name: Remove symlink /etc/apache2/sites-enabled/munin24.conf if not munin_enabled (debuntu) + file: + path: /etc/apache2/sites-enabled/munin24.conf + state: absent + when: not munin_enabled or nginx_enabled + +- name: Install /etc/nginx/conf.d/munin24-nginx.conf, from templates + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: 0644 + with_items: + - { src: 'munin24-nginx.conf.j2', dest: '/etc/nginx/conf.d/munin24-nginx.conf' } + when: munin_enabled | bool and nginx_enabled | bool + +- name: Add 'munin' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: munin + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: Munin + - option: description + value: '"Munin is a networked resource monitoring tool that can help analyze resource trends and \"what just happened to kill our performance?\" problems."' + - option: installed + value: "{{ munin_install }}" + - option: enabled + value: "{{ munin_enabled }}" diff --git a/roles/munin/tasks/install.yml b/roles/munin/tasks/install.yml new file mode 100644 index 000000000..cc6f0e254 --- /dev/null +++ b/roles/munin/tasks/install.yml @@ -0,0 +1,48 @@ +- name: 'Install 5 packages: munin, munin-node, munin-plugins-extra, libcgi-fast-perl, libapache2-mod-fcgid (debuntu)' + package: + name: + - munin + - munin-node + - munin-plugins-extra + - libcgi-fast-perl + - libapache2-mod-fcgid + state: present + tags: + - download + when: is_debuntu | bool + +- name: "Install 2 packages: munin, munin-node (OS's other than debuntu)" + package: + name: + - munin + - munin-node + state: present + tags: + - download + when: not is_debuntu + +- name: Install /etc/munin/munin.conf and Apache's munin24.conf, from templates + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: 0644 + with_items: + - { src: 'munin.conf.j2', dest: '/etc/munin/munin.conf' } + - { src: 'munin24.conf.j2', dest: '/etc/{{ apache_config_dir }}/munin24.conf' } + +- name: Establish username/password Admin/changeme in /etc/munin/munin-htpasswd + htpasswd: + path: /etc/munin/munin-htpasswd + name: Admin + password: changeme + create: yes + state: present + +- name: Add 'munin_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^munin_installed' + line: 'munin_installed: True' + state: present diff --git a/roles/munin/tasks/main.yml b/roles/munin/tasks/main.yml index 83c1afc7b..7a0857f42 100644 --- a/roles/munin/tasks/main.yml +++ b/roles/munin/tasks/main.yml @@ -1,98 +1,7 @@ -- name: 'Install 5 packages: munin, munin-node, munin-plugins-extra, libcgi-fast-perl, libapache2-mod-fcgid (debuntu)' - package: - name: - - munin - - munin-node - - munin-plugins-extra - - libcgi-fast-perl - - libapache2-mod-fcgid - state: present - tags: - - download - when: is_debuntu | bool +- name: Install munin + include_tasks: install.yml + when: munin_install | bool and not munin_installed is defined -- name: "Install 2 packages: munin, munin-node (OS's other than debuntu)" - package: - name: - - munin - - munin-node - state: present - tags: - - download - when: not is_debuntu - -- name: Install /etc/munin/munin.conf and Apache's munin24.conf, from templates - template: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - owner: root - group: root - mode: 0644 - with_items: - - { src: 'munin.conf.j2', dest: '/etc/munin/munin.conf' } - - { src: 'munin24.conf.j2', dest: '/etc/{{ apache_config_dir }}/munin24.conf' } - -- name: Establish username/password Admin/changeme in /etc/munin/munin-htpasswd - htpasswd: - path: /etc/munin/munin-htpasswd - name: Admin - password: changeme - create: yes - state: present - -- name: Enable & Start munin-node systemd service - service: - name: munin-node - enabled: yes - state: started - when: munin_enabled | bool - -- name: Create symlink munin24.conf from sites-enabled to sites-available (debuntu) - file: - src: /etc/apache2/sites-available/munin24.conf - path: /etc/apache2/sites-enabled/munin24.conf - state: link - when: munin_enabled and is_debuntu - -- name: Remove symlink /etc/apache2/sites-enabled/munin24.conf if not munin_enabled (debuntu) - file: - path: /etc/apache2/sites-enabled/munin24.conf - state: absent - when: not munin_enabled and is_debuntu - -- name: Disable munin-node service if not munin_enabled - service: - name: munin-node - enabled: no - state: stopped - when: not munin_enabled - -- name: If MySQL is enabled, let Munin monitor it - copy: - src: "{{ item }}" - dest: /etc/munin/plugins/ - with_items: - - /usr/share/munin/plugins/mysql_ - - /usr/share/munin/plugins/mysql_bytes - - /usr/share/munin/plugins/mysql_innodb - - /usr/share/munin/plugins/mysql_isam_space_ - - /usr/share/munin/plugins/mysql_queries - - /usr/share/munin/plugins/mysql_slowqueries - - /usr/share/munin/plugins/mysql_threads - when: mysql_enabled | bool - -- name: Add 'munin' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" - section: munin - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: Munin - - option: description - value: '"Munin is a networked resource monitoring tool that can help analyze resource trends and \"what just happened to kill our performance?\" problems."' - - option: installed - value: "{{ munin_install }}" - - option: enabled - value: "{{ munin_enabled }}" +- name: Enable munin + include_tasks: enable.yml + when: munin_install | bool or munin_installed is defined diff --git a/roles/munin/templates/munin24-nginx.conf.j2 b/roles/munin/templates/munin24-nginx.conf.j2 new file mode 100644 index 000000000..dbbcc2795 --- /dev/null +++ b/roles/munin/templates/munin24-nginx.conf.j2 @@ -0,0 +1,4 @@ +location /munin { + alias /var/cache/munin/www/ ; + try_files $uri $uri/ /index.html; +} diff --git a/roles/network/tasks/dansguardian.yml b/roles/network/tasks/dansguardian.yml index 7f76cfb5b..9b593d2a0 100644 --- a/roles/network/tasks/dansguardian.yml +++ b/roles/network/tasks/dansguardian.yml @@ -49,3 +49,10 @@ mode: 0750 state: directory when: ansible_distribution == "CentOS" + +- name: Add 'dansguardian_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^dansguardian_installed' + line: 'dansguardian_installed: True' + state: present diff --git a/roles/network/tasks/dhcpd.yml b/roles/network/tasks/dhcpd.yml index 9d04cd820..6347cd4e7 100644 --- a/roles/network/tasks/dhcpd.yml +++ b/roles/network/tasks/dhcpd.yml @@ -59,3 +59,10 @@ mode: 0644 state: file when: is_redhat | bool + +- name: Add 'dhcpd_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^dhcpd_installed' + line: 'dhcpd_installed: True' + state: present diff --git a/roles/network/tasks/enable_services.yml b/roles/network/tasks/enable_services.yml index 078c290c5..7bae3d211 100644 --- a/roles/network/tasks/enable_services.yml +++ b/roles/network/tasks/enable_services.yml @@ -2,7 +2,7 @@ service: name: dhcpd enabled: no - when: dhcpd_install and not dhcpd_enabled + when: (dhcpd_install or dhcpd_installed is defined) and not dhcpd_enabled # service is restarted with NM dispatcher.d script - name: Enable dhcpd service @@ -46,7 +46,7 @@ systemd: name: "{{ dns_service }}" enabled: no - when: named_install and not named_enabled + when: (named_install or named_installed is defined) and not named_enabled - name: Install /etc/dnsmasq.d/iiab.conf from template, when dnsmasq_enabled and isn't Appliance template: @@ -122,7 +122,7 @@ systemd: name: dansguardian enabled: no - when: dansguardian_install and not dansguardian_enabled + when: (dansguardian_install or dansguardian_installed is defined) and not dansguardian_enabled - name: Mandate 'HTTPCACHE_ON=True' in {{ iiab_env_file }}, if squid_enabled lineinfile: @@ -164,7 +164,7 @@ systemd: name: "{{ proxy }}" enabled: no - when: squid_install and not squid_enabled + when: (squid_install or squid_installed is defined) and not squid_enabled - name: Revert to 'HTTPCACHE_ON=False' if not squid_enabled lineinfile: @@ -184,7 +184,7 @@ systemd: name: wondershaper enabled: no - when: wondershaper_install and not wondershaper_enabled + when: (wondershaper_install or wondershaper_installed is defined) and not wondershaper_enabled # check-LAN should be iptables.yml remove later - name: Install clean copy of /usr/bin/iiab-gen-iptables from template diff --git a/roles/network/tasks/main.yml b/roles/network/tasks/main.yml index a97cdab28..85955936e 100644 --- a/roles/network/tasks/main.yml +++ b/roles/network/tasks/main.yml @@ -57,7 +57,7 @@ - name: Configure wondershaper include_tasks: wondershaper.yml - when: wondershaper_install | bool + when: wondershaper_install | bool or wondershaper_installed is defined tags: - network - wondershaper diff --git a/roles/network/tasks/named.yml b/roles/network/tasks/named.yml index 37343c9fa..965aa5cdf 100644 --- a/roles/network/tasks/named.yml +++ b/roles/network/tasks/named.yml @@ -100,6 +100,13 @@ state: absent when: not is_debuntu and not dns_jail_enabled +- name: Add 'named_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^named_installed' + line: 'named_installed: True' + state: present + - name: Start named systemd service systemd: name: "{{ dns_service }}" diff --git a/roles/network/tasks/restart.yml b/roles/network/tasks/restart.yml index 20d344e19..9a7c90dfc 100644 --- a/roles/network/tasks/restart.yml +++ b/roles/network/tasks/restart.yml @@ -15,13 +15,13 @@ name: "{{ proxy }}" state: stopped async: 120 - when: squid_install | bool + when: squid_install | bool or squid_installed is defined - name: Stop DansGuardian systemd: name: dansguardian state: stopped - when: dansguardian_install | bool + when: dansguardian_install | bool or dansguardian_installed is defined - name: Restart DansGuardian service (dansguardian) except Ubuntu which needs reboot to activate systemd: diff --git a/roles/network/tasks/squid.yml b/roles/network/tasks/squid.yml index 70af5b876..3378b1828 100644 --- a/roles/network/tasks/squid.yml +++ b/roles/network/tasks/squid.yml @@ -82,6 +82,13 @@ - include_tasks: roles/network/tasks/dansguardian.yml when: dansguardian_install | bool +- name: Add 'squid_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^squid_installed' + line: 'squid_installed: True' + state: present + # {{ proxy }} is normally "squid", but is "squid3" on raspbian-8 & debian-8 - name: Add '{{ proxy }}' variable values to {{ iiab_ini_file }} ini_file: diff --git a/roles/network/tasks/wondershaper.yml b/roles/network/tasks/wondershaper.yml index 6f62922af..60bcc4197 100644 --- a/roles/network/tasks/wondershaper.yml +++ b/roles/network/tasks/wondershaper.yml @@ -38,6 +38,13 @@ group: root state: link +- name: Add 'wondershaper_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^wondershaper_installed' + line: 'wondershaper_installed: True' + state: present + - name: Add 'wondershaper' variable values to {{ iiab_ini_file }} ini_file: dest: "{{ iiab_ini_file }}" diff --git a/roles/nextcloud/tasks/enable_or_disable.yml b/roles/nextcloud/tasks/enable_or_disable.yml index ff753abf9..03e477080 100644 --- a/roles/nextcloud/tasks/enable_or_disable.yml +++ b/roles/nextcloud/tasks/enable_or_disable.yml @@ -1,18 +1,8 @@ # This should go in computed_network.yml, but here for now -# 2019-09-04: THE NEXT 4 LINES ARE UNUSED (due to changes in roles/nextcloud/templates/nextcloud.conf.j2) -- name: Compute Nextcloud listen ip addr for nextcloud.conf - set_fact: - nextcloud_required_ip: "{{ ansible_default_ipv4.network }}/{{ ansible_default_ipv4.netmask }}" - when: ansible_default_ipv4.network is defined - -- name: Install Apache's nextcloud.conf from template, for http://box/nextcloud - template: - src: nextcloud.conf.j2 - dest: "/etc/{{ apache_config_dir }}/nextcloud.conf" - owner: root - group: root - mode: 0644 - when: nextcloud_enabled | bool +#- name: Compute Nextcloud listen ip addr for nextcloud.conf +# set_fact: +# nextcloud_required_ip: "{{ ansible_default_ipv4.network }}/{{ ansible_default_ipv4.netmask }}" +# when: ansible_default_ipv4.network is defined - name: Create symlink nextcloud.conf from sites-enabled to sites-available for http://box/nextcloud (debuntu) file: @@ -34,75 +24,29 @@ when: not nextcloud_enabled and is_redhat - name: Restart Apache, enabling/disabling http://box/nextcloud - service: + systemd: name: "{{ apache_service }}" + daemon-reload: yes state: restarted -# the install wizard does not succeed if already installed -- name: Determine if Nextcloud is installed - shell: > - php {{ nextcloud_prefix }}/nextcloud/occ status | - gawk '/installed:/ { print $3 }' - become: yes - become_user: "{{ apache_user }}" - register: returned - -- name: Run Nextcloud initial install wizard - shell: > - cd {{ nextcloud_prefix }}/nextcloud; - php occ maintenance:install - --database "mysql" - --database-name "{{ nextcloud_dbname }}" - --database-user "{{ nextcloud_dbuser }}" - --database-pass "{{ nextcloud_dbpassword }}" - --admin-user "{{ nextcloud_admin_user }}" - --admin-pass "{{ nextcloud_admin_password }}" - become: yes - become_user: "{{ apache_user }}" - when: nextcloud_enabled and returned.stdout == "false" - -- name: Allow access from all hosts and ips - command: php {{ nextcloud_prefix }}/nextcloud/occ config:system:set trusted_domains 1 --value=* - become: yes - become_user: "{{ apache_user }}" - when: nextcloud_enabled and returned.stdout == "false" - -# Code below was NEVER RUNNING as of 2018-10-29, as "wc | cut -d' ' -f1" ALWAYS -# returns null (rather than the intended returned_count !) This line could -# be replaced by ALTERNATIVE 1 or ALTERNATIVE 2 below IF it truly needs fixing. -# -# Or perhaps default user/password nextcloud/nextcloudmysql (from variables -# nextcloud_user/nextcloud_user_password) is just not needed in the end... -# -# NOTE: COMMENTS (FOLLOWING '#' SIGN) WITHIN A SHELL COMMAND CAUSE IT TO *FAIL* -# -#- name: Determine if Nextcloud user exists already -# shell: > -# php {{ nextcloud_prefix }}/nextcloud/occ user:list | -# grep {{ nextcloud_user }} | wc | cut -d' ' -f1 # USELESS -# #grep {{ nextcloud_user }} | wc -l # ALTERNATIVE 1 -# #grep {{ nextcloud_user }} | wc | awk '{print $1}' # ALTERNATIVE 2 -# become: yes -# become_user: "{{ apache_user }}" -# register: returned_count -# -# debug: -# var: returned_count -# -## nextcloud wants to make users rather than just mysql users and not done -#- name: Create the default user -# shell: > -# OC_PASS={{ nextcloud_user_password }}; -# php {{ nextcloud_prefix }}/nextcloud/occ user:add -# --password-from-env --display-name={{ nextcloud_user }} -# --group="users" {{ nextcloud_user }} -# become: yes -# become_user: "{{ apache_user }}" -# when: nextcloud_enabled and returned_count == "0" - -# 2019-09-04: NEXT 5 LINES APPEAR INEFFECTIVE DURING 1ST INSTALL? (possibly "overwrite.cli.url" appears later, when Nextcloud's web install completes using http://box/nextcloud ?) -- name: Try to remove overwrite.cli.url line (Rewrite URL) from /opt/nextcloud/config/config.php - lineinfile: - regexp: "overwrite.cli.url" - state: absent - path: "{{ nextcloud_prefix }}/nextcloud/config/config.php" +- name: Add 'nextcloud' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: Nextcloud + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: Nextcloud + - option: description + value: '"NextCloud is a local server-based facility for sharing files, photos, contacts, calendars, etc."' + - option: path + value: "{{ nextcloud_prefix }}/nextcloud" + #- option: nextcloud_force_install + # value: "{{ nextcloud_force_install }}" + - option: nextcloud_orig_src_file + value: "{{ nextcloud_orig_src_file }}" + - option: nextcloud_src_file + value: "{{ nextcloud_src_file }}" + - option: nextcloud_enabled + value: "{{ nextcloud_enabled }}" diff --git a/roles/nextcloud/tasks/install.yml b/roles/nextcloud/tasks/install.yml index ed2b3ac51..99f35c73e 100644 --- a/roles/nextcloud/tasks/install.yml +++ b/roles/nextcloud/tasks/install.yml @@ -174,53 +174,17 @@ mode: 0750 state: directory -- name: 'Create MySQL database with name: {{ nextcloud_dbname }}' - mysql_db: - name: "{{ nextcloud_dbname }}" - when: mysql_enabled and nextcloud_enabled +- name: Install Apache's nextcloud.conf from template, for http://box/nextcloud + template: + src: nextcloud.conf.j2 + dest: "/etc/{{ apache_config_dir }}/nextcloud.conf" + owner: root + group: root + mode: 0644 -- name: Add username/password to the MySQL database (associated with trusted IP's like localhost) - mysql_user: - name: "{{ nextcloud_dbuser }}" - host: "{{ item }}" - password: "{{ nextcloud_dbpassword }}" - priv: "{{ nextcloud_dbname }}.*:ALL,GRANT" - with_items: - - "{{ nextcloud_dbhost }}" - - 127.0.0.1 - - ::1 - - localhost - when: mysql_enabled and nextcloud_enabled - -# Appears unnec as nextcloud_enabled.yml (just below) does the same -#- name: Restart Apache -# service: -# name: "{{ apache_service }}" -# state: restarted -## when: nextcloud_enabled | bool # taken care of by nextcloud_enabled.yml below -# when: not nextcloud_enabled - -# Enables or disable Nextcloud! -- include_tasks: enable_or_disable.yml - -- name: Add 'nextcloud' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" - section: Nextcloud - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: Nextcloud - - option: description - value: '"NextCloud is a local server-based facility for sharing files, photos, contacts, calendars, etc."' - - option: path - value: "{{ nextcloud_prefix }}/nextcloud" - #- option: nextcloud_force_install - # value: "{{ nextcloud_force_install }}" - - option: nextcloud_orig_src_file - value: "{{ nextcloud_orig_src_file }}" - - option: nextcloud_src_file - value: "{{ nextcloud_src_file }}" - - option: nextcloud_enabled - value: "{{ nextcloud_enabled }}" +- name: Add 'nextcloud_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^nextcloud_installed' + line: 'nextcloud_installed: True' + state: present diff --git a/roles/nextcloud/tasks/main.yml b/roles/nextcloud/tasks/main.yml index 13bd12b01..20363d0df 100644 --- a/roles/nextcloud/tasks/main.yml +++ b/roles/nextcloud/tasks/main.yml @@ -7,10 +7,12 @@ #set_fact: # nextcloud_force_install: True include_tasks: install.yml - when: nextcloud_install and not nextcloud_page.stat.exists + when: nextcloud_install and (not nextcloud_installed is defined or not nextcloud_page.stat.exists) -# - debug: -# var: nextcloud_force_install +- name: Provision NextCloud's Mysql DB + include_tasks: setup.yml + when: nextcloud_install and not installing -# - debug: -# msg: "nextcloud_force_install: {{ nextcloud_force_install }}" +- name: Enables or disable Nextcloud! + include_tasks: enable_or_disable.yml + when: nextcloud_install or nextcloud_installed is defined diff --git a/roles/nextcloud/tasks/setup.yml b/roles/nextcloud/tasks/setup.yml new file mode 100644 index 000000000..cc178957a --- /dev/null +++ b/roles/nextcloud/tasks/setup.yml @@ -0,0 +1,84 @@ +- name: 'Create MySQL database with name: {{ nextcloud_dbname }}' + mysql_db: + name: "{{ nextcloud_dbname }}" + +- name: Add username/password to the MySQL database (associated with trusted IP's like localhost) + mysql_user: + name: "{{ nextcloud_dbuser }}" + host: "{{ item }}" + password: "{{ nextcloud_dbpassword }}" + priv: "{{ nextcloud_dbname }}.*:ALL,GRANT" + with_items: + - "{{ nextcloud_dbhost }}" + - 127.0.0.1 + - ::1 + - localhost + +# the install wizard does not succeed if already installed +- name: Determine if Nextcloud is installed + shell: > + php {{ nextcloud_prefix }}/nextcloud/occ status | + gawk '/installed:/ { print $3 }' + become: yes + become_user: "{{ apache_user }}" + register: returned + +- name: Run Nextcloud initial install wizard + shell: > + cd {{ nextcloud_prefix }}/nextcloud; + php occ maintenance:install + --database "mysql" + --database-name "{{ nextcloud_dbname }}" + --database-user "{{ nextcloud_dbuser }}" + --database-pass "{{ nextcloud_dbpassword }}" + --admin-user "{{ nextcloud_admin_user }}" + --admin-pass "{{ nextcloud_admin_password }}" + become: yes + become_user: "{{ apache_user }}" + when: nextcloud_enabled and returned.stdout == "false" + +- name: Allow access from all hosts and ips + command: php {{ nextcloud_prefix }}/nextcloud/occ config:system:set trusted_domains 1 --value=* + become: yes + become_user: "{{ apache_user }}" + when: nextcloud_enabled and returned.stdout == "false" + +# Code below was NEVER RUNNING as of 2018-10-29, as "wc | cut -d' ' -f1" ALWAYS +# returns null (rather than the intended returned_count !) This line could +# be replaced by ALTERNATIVE 1 or ALTERNATIVE 2 below IF it truly needs fixing. +# +# Or perhaps default user/password nextcloud/nextcloudmysql (from variables +# nextcloud_user/nextcloud_user_password) is just not needed in the end... +# +# NOTE: COMMENTS (FOLLOWING '#' SIGN) WITHIN A SHELL COMMAND CAUSE IT TO *FAIL* +# +#- name: Determine if Nextcloud user exists already +# shell: > +# php {{ nextcloud_prefix }}/nextcloud/occ user:list | +# grep {{ nextcloud_user }} | wc | cut -d' ' -f1 # USELESS +# #grep {{ nextcloud_user }} | wc -l # ALTERNATIVE 1 +# #grep {{ nextcloud_user }} | wc | awk '{print $1}' # ALTERNATIVE 2 +# become: yes +# become_user: "{{ apache_user }}" +# register: returned_count +# +# debug: +# var: returned_count +# +## nextcloud wants to make users rather than just mysql users and not done +#- name: Create the default user +# shell: > +# OC_PASS={{ nextcloud_user_password }}; +# php {{ nextcloud_prefix }}/nextcloud/occ user:add +# --password-from-env --display-name={{ nextcloud_user }} +# --group="users" {{ nextcloud_user }} +# become: yes +# become_user: "{{ apache_user }}" +# when: nextcloud_enabled and returned_count == "0" + +# 2019-09-04: NEXT 5 LINES APPEAR INEFFECTIVE DURING 1ST INSTALL? (possibly "overwrite.cli.url" appears later, when Nextcloud's web install completes using http://box/nextcloud ?) +- name: Try to remove overwrite.cli.url line (Rewrite URL) from /opt/nextcloud/config/config.php + lineinfile: + regexp: "overwrite.cli.url" + state: absent + path: "{{ nextcloud_prefix }}/nextcloud/config/config.php" diff --git a/roles/nginx/defaults/main.yml b/roles/nginx/defaults/main.yml new file mode 100644 index 000000000..ae625c277 --- /dev/null +++ b/roles/nginx/defaults/main.yml @@ -0,0 +1 @@ +nginx_log_dir: /var/log/nginx diff --git a/roles/nginx/files/README.md b/roles/nginx/files/README.md new file mode 100644 index 000000000..278b4f14c --- /dev/null +++ b/roles/nginx/files/README.md @@ -0,0 +1,24 @@ +### Transition to NGINX +1. Initial testing strategy is to move nginx to port 80, and proxy everything to apache on port 8090-- creating a shim. +2. Without php available via fastcgi, any function at all for php based applications validates nginx. +3. Current state (10/16/19) + 1. Principal functions migrated to nginx. + * Admin Console + * Awstats + * kalite -- goes directly to port 8009 + * usb-lib + * maps + 2. Dual support + * kiwix -- goes directly to port 3000 + * calibre-web + * kolibri + * sugarizer + 3. Still proxied to Apache + * mediawiki + * elgg + * nodered + * nextcloud + * wordpress + * moodle + 4. Not dealt with yet + * archive.org diff --git a/roles/nginx/tasks/disable.yml b/roles/nginx/tasks/disable.yml new file mode 100644 index 000000000..8ff87f1ba --- /dev/null +++ b/roles/nginx/tasks/disable.yml @@ -0,0 +1,30 @@ +#grep -r "not nginx_enabled" roles/ +#roles/calibre-web/tasks/main.yml: when: calibreweb_enabled | bool and not nginx_enabled | bool +#roles/calibre-web/tasks/main.yml: when: not nginx_enabled | bool +#roles/kolibri/tasks/main.yml: when: kolibri_enabled | bool and not nginx_enabled | bool +#roles/kolibri/tasks/main.yml: when: not nginx_enabled | bool +#roles/kiwix/tasks/kiwix_install.yml: when: kiwix_enabled | bool and not nginx_enabled | bool +#roles/kiwix/tasks/kiwix_install.yml: when: not nginx_enabled | bool +#roles/nginx/tasks/main.yml: when: not nginx_enabled | bool +#roles/nginx/tasks/main.yml: when: not nginx_enabled | bool +#roles/sugarizer/tasks/install.yml: when: sugarizer_enabled | bool and not nginx_enabled | bool +#roles/sugarizer/tasks/install.yml: when: sugarizer_enabled | bool and not nginx_enabled | bool + +- name: Enable Gitea for Apache + command: a2ensite gitea.conf + +- name: Enable Calibre-Web for Apache + command: a2ensite calibre-web.conf + +- name: Enable Kolibri for Apache + command: a2ensite kolibri.conf + +- name: Enable kiwix for Apache + command: a2ensite kiwix.conf + +- name: Enable Sugarizer for Apache + command: a2ensite sugarizer.conf + +- name: Enable AWStats for Apache + command: a2ensite awstats.conf + diff --git a/roles/nginx/tasks/install.yml b/roles/nginx/tasks/install.yml new file mode 100644 index 000000000..0e031be8d --- /dev/null +++ b/roles/nginx/tasks/install.yml @@ -0,0 +1,27 @@ +- name: Install nginx required and helper packages + package: name={{ item }} state=present + with_items: + - nginx-extras + - uwsgi + - uwsgi-plugin-python3 + - php-fpm + - libnginx-mod-http-subs-filter + +- name: Add http server user to shadow group, so it can authenticate Admin Console + user: + name: "{{ apache_user }}" + groups: shadow + +- name: Remove the nginx default config + file: + path: /etc/nginx/sites-enabled/default + state: absent + +- name: Put config files in place (2 into /etc/nginx, 1 into /etc/{{ apache_service }}) + template: + src: '{{ item.src}}' + dest: '{{ item.dest }}' + with_items: + - { src: "roles/nginx/templates/server.conf", dest: "/etc/nginx/" } + - { src: "roles/nginx/templates/nginx.conf", dest: "/etc/nginx/" } + - { src: 'roles/nginx/templates/ports.conf', dest: '/etc/{{ apache_service }}/' , mode: '0644' } diff --git a/roles/nginx/tasks/main.yml b/roles/nginx/tasks/main.yml new file mode 100644 index 000000000..795751153 --- /dev/null +++ b/roles/nginx/tasks/main.yml @@ -0,0 +1,82 @@ +- name: Put the config file in place + template: + src: '{{ item.src}}' + dest: '{{ item.dest }}' + with_items: + - { src: "server.conf",dest: "/etc/nginx/" } + - { src: "nginx.conf",dest: "/etc/nginx/" } + - { src: "usb-lib.conf",dest: "/etc/nginx/conf.d/" } + - { src: "modules.conf",dest: "/etc/nginx/conf.d/" } +# - { src: "admin-console.ini",dest: "/etc/uwsgi/apps-enabled/" } +# the above should be enough once uwsgi is started +# - { src: "uwsgi.unit",dest: "/etc/systemd/system/uwsgi.socket" } + - { src: 'ports.conf' , dest: '/etc/{{ apache_service }}/' , mode: '0644' } + when: nginx_enabled + +- name: Insure that apache2 is not running -- we may need port swap + systemd: + name: apache2 + state: stopped + +# optional services +- name: Install config for Admin Console + template: + src: admin-console-nginx.conf +# Comment one or the other to revert from nginx back to apache2, if required +# src: admin-console-apache.conf + dest: /etc/nginx/conf.d/admin-console.conf + when: admin_console_enabled and nginx_enabled + +# the below slides in nginx's proxypass config files for apache on localhost +# via the ports.conf file installed above +- name: Install proxpass to apache running on localhost port {{ apache_port }} + include_tasks: uses_apache.yml + when: nginx_enabled + +# the below task contains the same logic contained in the playbooks to enable +# 'runrole nginx' to do the right thing but with the 'src' path set to role's +# templates path ie roles//template/ + +- name: Install proxpass to other services 'dual mode' roles + include_tasks: only_nginx.yml + when: nginx_enabled + +- name: Stop and disable nginx when not nginx_enabled + systemd: + name: nginx + state: stopped + enabled: false + when: not nginx_enabled + +- name: Disable Apache port {{ apache_port }} localhost only + template: + dest: /etc/{{ apache_service }}/ports.conf + src: stock-apache-ports.conf + when: not nginx_enabled + +# should have the logic to handle both modes in the playbook +- name: Enable Apache (a2ensite) for 'dual mode' for the role when NGINX is diabled + include_tasks: disable.yml + when: not nginx_enabled + +- name: Since we stopped apache2, start it again + systemd: + name: apache2 + state: restarted + enabled: true + daemon_reload: yes + when: apache_enabled + +- name: Restart nginx to pick up the config files installed + systemd: + name: nginx + state: restarted + enabled: true + when: nginx_enabled + +#- name: Enable the uwsgi systemd service +# systemd: +# name: uwsgi +# state: restarted +# enabled: true +# when: admin_console_enabled and nginx_enabled diff --git a/roles/nginx/tasks/only_nginx.yml b/roles/nginx/tasks/only_nginx.yml new file mode 100644 index 000000000..127c357b8 --- /dev/null +++ b/roles/nginx/tasks/only_nginx.yml @@ -0,0 +1,133 @@ +- name: Remove symlink /etc/apache2/sites-enabled/awstats.conf + file: + path: /etc/apache2/sites-enabled/awstats.conf + state: absent + +- name: Install nginx support for awstats if awstats_enabled + copy: + backup: no + src: "{{ item.src }}" + dest: "{{ item.dest }}" + mode: "{{ item.mode }}" + owner: root + group: root + with_items: + - { src: 'roles/awstats/templates/awstats-nginx.conf', dest: '/etc/nginx/conf.d/kiwix-nginx.conf' , mode: '0644' } + when: awstats_enabled + +- name: Remove nginx support for AWStats + file: + path: /etc/nginx/conf.d/awstats-nginx.conf + state: absent + when: not awstats_enabled + +- name: Remove symlink /etc/apache2/sites-enabled/kiwix.conf + file: + path: /etc/apache2/sites-enabled/kiwix.conf + state: absent + +- name: Install nginx support for kiwix if kiwix_enabled + copy: + backup: no + src: "{{ item.src }}" + dest: "{{ item.dest }}" + mode: "{{ item.mode }}" + owner: root + group: root + with_items: + - { src: 'roles/kiwix/templates/kiwix-nginx.conf', dest: '/etc/nginx/conf.d/kiwix-nginx.conf' , mode: '0644' } + when: kiwix_enabled | bool + +- name: Remove nginx support for kiwix + file: + path: /etc/nginx/conf.d/kiwix-nginx.conf + state: absent + when: not kiwix_enabled | bool + +- name: Remove symlink /etc/apache2/sites-enabled/sugarizer.conf + file: + path: /etc/apache2/sites-enabled/sugarizer.conf + state: absent + +- name: "Install sugarizer-nginx.conf (nginx) if sugarizer_enabled" + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + mode: "{{ item.mode }}" + owner: root + group: root + with_items: + - { src: 'roles/sugarizer/templates/sugarizer-nginx.conf', dest: '/etc/nginx/conf.d/sugarizer-nginx.conf', mode: '0644' } + when: sugarizer_enabled | bool + +- name: Remove nginx support for sugarizer + file: + path: /etc/nginx/conf.d/sugarizer-nginx.conf + state: absent + when: not sugarizer_enabled | bool + +- name: Remove /etc/apache2/sites-enabled/kolibri.conf + file: + path: /etc/apache2/sites-enabled/kolibri.conf + state: absent + +- name: Supply /etc/nginx/conf.d/kolibri-nginx.conf when kolibri_enabled + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + mode: "{{ item.mode }}" + owner: root + group: root + with_items: + - { src: 'roles/kolibri/templates/kolibri-nginx.conf.j2', dest: '/etc/nginx/conf.d/kolibri-nginx.conf', mode: '0644' } + when: kolibri_enabled | bool + +- name: Remove nginx support for kolibri when not kolibri_enabled + file: + path: /etc/nginx/conf.d/kolibri-nginx.conf + state: absent + when: not kolibri_enabled | bool + +- name: Remove symlink /etc/apache2/sites-enabled/calibre-web.conf + file: + path: /etc/apache2/sites-enabled/calibre-web.conf + state: absent + +- name: Install /etc/nginx/conf.d/calibre-web-nginx.conf + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: "{{ item.mode }}" + with_items: + - { src: 'roles/calibre-web/templates/calibre-web-nginx.conf.j2', dest: '/etc/nginx/conf.d/calibre-web-nginx.conf', mode: '0644' } + when: calibreweb_enabled + +- name: Remove nginx support for Calibre-Web + file: + path: /etc/nginx/conf.d/calibre-web-nginx.conf + state: absent + when: not calibreweb_enabled + +- name: Remove symlink /etc/apache2/sites-enabled/gitea.conf + file: + path: /etc/apache2/sites-enabled/gitea.conf + state: absent + +- name: Install /etc/nginx/conf.d/gitea-nginx.conf + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: "{{ item.mode }}" + with_items: + - { src: 'roles/gitea/templates/gitea-nginx.conf.j2', dest: '/etc/nginx/conf.d/gitea-nginx.conf', mode: '0644' } + when: gitea_enabled + +- name: Remove nginx support for Gitea + file: + path: /etc/nginx/conf.d/gitea-nginx.conf + state: absent + when: not gitea_enabled diff --git a/roles/nginx/tasks/uses_apache.yml b/roles/nginx/tasks/uses_apache.yml new file mode 100644 index 000000000..f24afcb49 --- /dev/null +++ b/roles/nginx/tasks/uses_apache.yml @@ -0,0 +1,54 @@ +- name: Install nginx's config file from template, if moodle_enabled + template: + src: moodle-nginx.conf.j2 + dest: "/etc/nginx/conf.d/moodle-nginx.conf" + owner: root + group: root + mode: 0644 + when: moodle_enabled + +- name: Install /etc/nginx/conf.d/dokuwiki-nginx.conf from template + template: + src: dokuwiki-nginx.conf + dest: /etc/nginx/conf.d/dokuwiki-nginx.conf + when: dokuwiki_enabled + +- name: Install /etc/nginx/conf.d/elgg-nginx.conf from template + template: + src: elgg-nginx.conf + dest: "/etc/nginx/conf.d/elgg-nginx.conf" + when: elgg_enabled + +- name: Install /etc/nginx/lokole-nginx.conf from template + template: + src: lokole-nginx.conf.j2 + dest: "/etc/nginx/conf.d/lokole-nginx.conf" + when: lokole_enabled + +- name: Install MediaWiki's nginx conf.d file from template + template: + src: mediawiki-nginx.conf.j2 + dest: /etc/nginx/conf.d/mediawiki-nginx.conf + when: mediawiki_enabled + +- name: Install WordPress's nginx conf.d file from template + template: src=nextcloud-nginx.conf dest=/etc/nginx/conf.d/nextcloud-nginx.conf + when: nextcloud_enabled + +- name: Install NodeRed's nginx conf.d file from template + template: + src: nodered-nginx.conf.j2 + dest: /etc/nginx/conf.d/nodered-nginx.conf + owner: root + group: root + mode: 0666 + when: nodered_enabled + +- name: Install WordPress's nginx conf.d file from template + template: + src: wordpress-nginx.conf + dest: /etc/nginx/conf.d/ + when: wordpress_enabled + +#- name: Install proxpass to apache running on localhost + diff --git a/roles/nginx/templates/admin-console-apache.conf b/roles/nginx/templates/admin-console-apache.conf new file mode 100644 index 000000000..6e1269392 --- /dev/null +++ b/roles/nginx/templates/admin-console-apache.conf @@ -0,0 +1,9 @@ +location /admin { + proxy_pass http://127.0.0.1:{{ apache_port }}/admin; +} +location /cmd-service { + proxy_pass http://127.0.0.1:{{ apache_port }}/cmd-service; +} + + + diff --git a/roles/nginx/templates/admin-console-nginx.conf b/roles/nginx/templates/admin-console-nginx.conf new file mode 100644 index 000000000..cf610d10a --- /dev/null +++ b/roles/nginx/templates/admin-console-nginx.conf @@ -0,0 +1,29 @@ +location /admin { +# proxy_pass http://127.0.0.1:{{ apache_port }}/admin; + alias /opt/admin/console; + auth_pam "Secure zone"; + auth_pam_service_name "nginx"; + +} + +location ~ /admin/(.*)\.php$ { + alias /opt/admin/console/$1.php; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Host $host; + fastcgi_pass php; + fastcgi_index index.php; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param SCRIPT_NAME $fastcgi_script_name; + include fastcgi_params; +} + +location /cmd-service { +# proxy_pass http://127.0.0.1:{{ apache_port }}/cmd-service; + include uwsgi_params; + uwsgi_pass unix:///tmp/admin-console.sock; +} + + + diff --git a/roles/nginx/templates/admin-console.ini b/roles/nginx/templates/admin-console.ini new file mode 100644 index 000000000..520369c0e --- /dev/null +++ b/roles/nginx/templates/admin-console.ini @@ -0,0 +1,8 @@ +[uwsgi] + uid = www-data + gid = www-data + socket = /tmp/admin-console.sock + chdir = /opt/admin/console + wsgi-file = cmd-service.wsgi + master = true + plugins = python diff --git a/roles/nginx/templates/dokuwiki-nginx.conf b/roles/nginx/templates/dokuwiki-nginx.conf new file mode 100644 index 000000000..eb05289e5 --- /dev/null +++ b/roles/nginx/templates/dokuwiki-nginx.conf @@ -0,0 +1,3 @@ +location {{ dokuwiki_url }} { + proxy_pass http://127.0.0.1:{{ apache_port }}/{{ dokuwiki_url }}; +} diff --git a/roles/nginx/templates/elgg-nginx.conf b/roles/nginx/templates/elgg-nginx.conf new file mode 100644 index 000000000..8687f4853 --- /dev/null +++ b/roles/nginx/templates/elgg-nginx.conf @@ -0,0 +1,3 @@ +location /elgg { + proxy_pass http://127.0.0.1:{{ apache_port }}/elgg; +} diff --git a/roles/nginx/templates/kalite-nginx.conf b/roles/nginx/templates/kalite-nginx.conf new file mode 100644 index 000000000..33e12c106 --- /dev/null +++ b/roles/nginx/templates/kalite-nginx.conf @@ -0,0 +1,59 @@ +# NGINX configuration for KA Lite +# +# Upstream KA-Lite server uses port 7007 +# Nginx proxy for KA-Lite uses port 8008 +# +# If you want the website to be accessible at a different port, change +# PROXY_PORT = nnnn setting in /var/ka-lite/.kalite/settings.py +# and change the below accordingly. + + +upstream kalite { + server 127.0.0.1:7007; +} + +server { + + listen 8008; + + # Default value, overwritten in nginx.d + set $kalite_home {{ kalite_root }}; + include /etc/ka-lite/nginx.d/*.conf; + + location /static { + alias $kalite_home/httpsrv/static/; + } + + location /media { + alias $kalite_home/httpsrv/media/; + } + + location /content { + alias $kalite_home/content/; + } + + location /favicon.ico { + empty_gif; + } + + location / { + proxy_set_header Host $http_host; + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Real-IP $remote_addr; + proxy_pass http://kalite; + error_page 502 = @502; + } + + location @502 { + types { } + default_type "text/html"; + return 502 " +
+

KA-Lite might be busy - wait a few moments and then reload this page +

+

If KA-Lite is still busy, get help from the system administrator +

Error code: nginx 502 Bad Gateway (maybe the KA-Lite webserver is not working correctly)"; + } + +} + diff --git a/roles/nginx/templates/lokole-nginx.conf.j2 b/roles/nginx/templates/lokole-nginx.conf.j2 new file mode 100644 index 000000000..bedf791b3 --- /dev/null +++ b/roles/nginx/templates/lokole-nginx.conf.j2 @@ -0,0 +1,3 @@ +location /lokole { + proxy_pass http://127.0.0.1:{{ apache_port }}/lokole; +} diff --git a/roles/nginx/templates/mediawiki-nginx.conf.j2 b/roles/nginx/templates/mediawiki-nginx.conf.j2 new file mode 100644 index 000000000..b49220657 --- /dev/null +++ b/roles/nginx/templates/mediawiki-nginx.conf.j2 @@ -0,0 +1,11 @@ +location /mediawiki { + proxy_pass http://127.0.0.1:{{ apache_port }}/mediawiki; +} + location ~ /mediawiki/.*\.php$ { + + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Host $host; + proxy_pass http://127.0.0.1:{{ apache_port }}; + +} diff --git a/roles/nginx/templates/modules.conf b/roles/nginx/templates/modules.conf new file mode 100644 index 000000000..16d3cb641 --- /dev/null +++ b/roles/nginx/templates/modules.conf @@ -0,0 +1,10 @@ + +location /modules/ { + fancyindex on; # Enable fancy indexes. + fancyindex_exact_size off; # Output human-readable file sizes. + fancyindex_ignore index.htmlf rachel-index.php; +# autoindex on; +# autoindex_exact_size off; +# autoindex_format html; +# autoindex_localtime on; +} diff --git a/roles/nginx/templates/moodle-nginx.conf.j2 b/roles/nginx/templates/moodle-nginx.conf.j2 new file mode 100644 index 000000000..a06e6baf3 --- /dev/null +++ b/roles/nginx/templates/moodle-nginx.conf.j2 @@ -0,0 +1,13 @@ +location /moodle { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Host $host; + proxy_pass http://127.0.0.1:{{ apache_port }}; +} +location ~ ^/moodle.*\.php$ { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Host $host; + proxy_pass http://127.0.0.1:{{ apache_port }}; +} + diff --git a/roles/nginx/templates/nextcloud-nginx.conf b/roles/nginx/templates/nextcloud-nginx.conf new file mode 100644 index 000000000..114baf77b --- /dev/null +++ b/roles/nginx/templates/nextcloud-nginx.conf @@ -0,0 +1,11 @@ +location /nextcloud { + proxy_pass http://127.0.0.1:{{ apache_port }}/nextcloud; +} + +location ~ /nextcloud/.*\.php$ { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Host $host; + proxy_pass http://127.0.0.1:{{ apache_port }}; +} + diff --git a/roles/nginx/templates/nginx.conf b/roles/nginx/templates/nginx.conf new file mode 100644 index 000000000..d8c732b93 --- /dev/null +++ b/roles/nginx/templates/nginx.conf @@ -0,0 +1,80 @@ +# IIAB notes: sites-enabled is for server declarations +# cond.d is for location declarations within the main server block + +user www-data; +worker_processes auto; +pid /run/nginx.pid; +include /etc/nginx/modules-enabled/*.conf; + +events { + worker_connections 768; + # multi_accept on; +} + +http { + + ## + # Basic Settings + ## + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + # server_tokens off; + + # server_names_hash_bucket_size 64; + # server_name_in_redirect off; + + include /etc/nginx/mime.types; + default_type text/html; + + ## + # SSL Settings + ## + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE + ssl_prefer_server_ciphers on; + + ## + # Logging Settings + ## + + access_log {{ apache_log_dir }}/access.log; + error_log {{ apache_log_dir }}/error.log; + log_format scripts '$request > $document_root$fastcgi_script_name $fastcgi_path_info'; + + + ## + # Gzip Settings + ## + + gzip on; + gzip_disable "msie6"; + + # gzip_vary on; + # gzip_proxied any; + # gzip_comp_level 6; + # gzip_buffers 16 8k; + # gzip_http_version 1.1; + # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + ## + # Virtual Host Configs + ## + + + # include a server file which in turn includes conf.d/* + include /etc/nginx/server.conf; + + # include other sites + include /etc/nginx/sites-enabled/*.conf; + + + # define the upstream backend fastcgi for php + upstream php { + server unix:/run/php/php{{ php_version }}-fpm.sock; + } + +} + diff --git a/roles/nginx/templates/nodered-nginx.conf.j2 b/roles/nginx/templates/nodered-nginx.conf.j2 new file mode 100644 index 000000000..275dd98a5 --- /dev/null +++ b/roles/nginx/templates/nodered-nginx.conf.j2 @@ -0,0 +1,3 @@ +location /nodered { + proxy_pass http://127.0.0.1:{{ apache_port }}/nodered; +} diff --git a/roles/nginx/templates/ports.conf b/roles/nginx/templates/ports.conf new file mode 100644 index 000000000..5591d27be --- /dev/null +++ b/roles/nginx/templates/ports.conf @@ -0,0 +1,15 @@ +# If you just change the port or add more ports here, you will likely also +# have to change the VirtualHost statement in +# /etc/apache2/sites-enabled/000-default.conf + +Listen 127.0.0.1:{{ apache_port }} + +# +# Listen 443 +# + +# +# Listen 443 +# + +# vim: syntax=apache ts=4 sw=4 sts=4 sr noet diff --git a/roles/nginx/templates/server.conf b/roles/nginx/templates/server.conf new file mode 100644 index 000000000..0af7b08f6 --- /dev/null +++ b/roles/nginx/templates/server.conf @@ -0,0 +1,40 @@ +server { + root {{ doc_root }}; + server_name {{ iiab_hostname }}; + listen 80; + + access_log {{ apache_log_dir }}/access.log; + error_log {{ apache_log_dir }}/error.log; + access_log {{ apache_log_dir }}/scripts.log scripts; + + index index.php index.html index.htm; + rewrite ^/$ $scheme://$server_addr/home/; + + # let individual services drop location blocks in conf.d + include /etc/nginx/conf.d/*; + + location ~ .*\.php$ { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Host $host; + fastcgi_pass php; + fastcgi_index index.php; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param SCRIPT_NAME $fastcgi_script_name; + include fastcgi_params; + } + + location /cgi-bin { + root /usr/lib; + } + + # if you don't like seeing all the errors for missing favicon.ico in root + location = /favicon.ico { access_log off; log_not_found off; } + + # if you don't like seeing errors for a missing robots.txt in root + location = /robots.txt { access_log off; log_not_found off; } + + # this will prevent files like .htaccess .htpassword .secret etc from being served + location ~ /\. { deny all; } +} diff --git a/roles/nginx/templates/stock-apache-ports.conf b/roles/nginx/templates/stock-apache-ports.conf new file mode 100644 index 000000000..bd0e2c00c --- /dev/null +++ b/roles/nginx/templates/stock-apache-ports.conf @@ -0,0 +1,16 @@ +# If you just change the port or add more ports here, you will likely also +# have to change the VirtualHost statement in +# /etc/apache2/sites-enabled/000-default.conf + +Listen 80 + + + Listen 443 + + + + Listen 443 + + +# vim: syntax=apache ts=4 sw=4 sts=4 sr noet + diff --git a/roles/nginx/templates/usb-lib.conf b/roles/nginx/templates/usb-lib.conf new file mode 100644 index 000000000..8feb6703d --- /dev/null +++ b/roles/nginx/templates/usb-lib.conf @@ -0,0 +1,7 @@ +location /usb { + alias /library/www/html/local_content/; + autoindex on; +} +location /local_content/ { + autoindex on; +} diff --git a/roles/nginx/templates/uwsgi.unit b/roles/nginx/templates/uwsgi.unit new file mode 100644 index 000000000..df7fd03ed --- /dev/null +++ b/roles/nginx/templates/uwsgi.unit @@ -0,0 +1,13 @@ +[Unit] +Description=uWSGI Service + +[Service] +ExecStart=/usr/local/bin/uwsgi --ini /etc/uwsgi/admin_console_wsgi.ini +Restart=always +RestartSec=5 +KillSignal=SIGQUIT +Type=notify +NotifyAccess=all + +[Install] +WantedBy=multi-user.target diff --git a/roles/nginx/templates/wordpress-nginx.conf b/roles/nginx/templates/wordpress-nginx.conf new file mode 100644 index 000000000..345887ad9 --- /dev/null +++ b/roles/nginx/templates/wordpress-nginx.conf @@ -0,0 +1,11 @@ +location /wordpress { + proxy_pass http://127.0.0.1:{{ apache_port }}/wordpress; +} + location ~ /wordpress/.*\.php$ { + + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Host $host; + proxy_pass http://127.0.0.1:{{ apache_port }}; + +} diff --git a/roles/nodered/tasks/enable.yml b/roles/nodered/tasks/enable.yml new file mode 100644 index 000000000..d3f9783c4 --- /dev/null +++ b/roles/nodered/tasks/enable.yml @@ -0,0 +1,52 @@ +- name: Create symlink nodered.conf from sites-enabled to sites-available, for short URL http://box/nodered (if nodered_enabled) + file: + src: /etc/apache2/sites-available/nodered.conf + dest: /etc/apache2/sites-enabled/nodered.conf + owner: root + group: root + state: link + when: nodered_enabled | bool + +- name: Remove symlink /etc/apache2/sites-enabled/nodered.conf (if not nodered_enabled) + file: + path: /etc/apache2/sites-enabled/nodered.conf + state: absent + when: not nodered_enabled + +- name: Enable & (Re)start 'nodered' systemd service (if nodered_enabled) + systemd: + daemon_reload: yes + name: nodered + enabled: yes + state: restarted + when: nodered_enabled | bool + +- name: Disable & Stop 'nodered' systemd service (if not nodered_enabled) + systemd: + daemon_reload: yes + name: nodered + enabled: no + state: stopped + when: not nodered_enabled + +- name: Restart Apache service ({{ apache_service }}) to enable/disable http://box/nodered (not just http://box:{{ nodered_port }}/nodered) + systemd: + name: "{{ apache_service }}" # httpd or apache2 + state: restarted + when: nodered_install | bool + +- name: Add 'nodered' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: nodered + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: Node-RED + - option: description + value: '"Node-RED is a flow-based development tool for visual programming developed originally by IBM for wiring together hardware devices, APIs and online services as part of the Internet of Things. Node-RED provides a web browser-based flow editor, which can be used to create JavaScript functions."' + - option: nodered_install + value: "{{ nodered_install }}" + - option: nodered_enabled + value: "{{ nodered_enabled }}" diff --git a/roles/nodered/tasks/group.yml b/roles/nodered/tasks/group.yml new file mode 100644 index 000000000..ad4499023 --- /dev/null +++ b/roles/nodered/tasks/group.yml @@ -0,0 +1,26 @@ +- name: Ensure Linux group 'nodered' exists (if not rpi) + group: + name: nodered + state: present + +- name: Ensure Linux user 'nodered' exists and is added to group 'nodered' (if not rpi) + user: + name: nodered + group: nodered + +- name: Ensure directory /home/nodered/.node-red/ exists (if not rpi) + file: + path: /home/nodered/.node-red + state: directory + owner: nodered + group: nodered + mode: 0775 + +- name: Install /home/nodered/.node-red/settings.js from template, with authentication (if not rpi) + template: + backup: yes + src: settings.js.j2 + dest: /home/nodered/.node-red/settings.js + owner: nodered + group: nodered + mode: 0755 diff --git a/roles/nodered/tasks/install.yml b/roles/nodered/tasks/install.yml new file mode 100644 index 000000000..7e5365d0f --- /dev/null +++ b/roles/nodered/tasks/install.yml @@ -0,0 +1,106 @@ +# 2019-01-16: @jvonau's PR #1403 moved installation of Node.js (8.x for now) & +# npm to roles/nodejs/tasks/main.yml, triggered by roles/nodered/meta/main.yml + +# BRUTAL but ensures consistency across OS's / distros like Raspbian Desktop & +# Ubermix that often include an older version of Node-RED. Brutal, as this +# removes customizations on graphical desktop OS's e.g. Raspbian Desktop's: +# 1. Node-RED's icon (Raspberry Menu in top-left -> Programming -> Node-RED) +# 2. scripts like {node-red-start, node-red-stop, node-red-log} in /usr/bin +# 3. other changes per /usr/bin/update-nodejs-and-nodered summarized at +# https://nodered.org/docs/hardware/raspberrypi for example low-memory +# flag --max_old_space_size=256 for unit file (we're using 128 on RPi) +# That we'll reconstitute below! +- name: ASK apt/yum/dnf TO REMOVE PRE-EXISTING 'nodered' (IF PREVIOUSLY INSTALLED BY OS PKG MANAGER) + package: + name: nodered + state: absent + when: nodered_install | bool + +# 2012-02-13: the 6 RPi stanzas below recreate Raspbian Desktop's Node-RED +# environment, inspired by: +# https://nodered.org/docs/hardware/raspberrypi +# https://github.com/node-red/raspbian-deb-package/blob/master/resources/update-nodejs-and-nodered +# https://github.com/iiab/iiab/pull/1497 + +- name: "Globally 'npm install' 3 Node-RED packages: node-red, node-red-admin, node-red-dashboard" + command: npm install -g --unsafe-perm node-red node-red-admin node-red-dashboard + #command: npm install -g --unsafe-perm node-red@latest node-red-admin@latest node-red-dashboard@latest + # Above "@latest" is recommended by https://nodered.org/docs/hardware/raspberrypi (SHOULD WE CONSIDER?) + when: nodered_install and internet_available + +- name: "Globally 'npm install' 8 Node-RED learning examples for RPi: node-red-contrib-ibm-watson-iot, node-red-contrib-play-audio, node-red-node-ledborg, node-red-node-ping, node-red-node-pi-sense-hat, node-red-node-random, node-red-node-serialport, node-red-node-smooth" + command: npm install -g --unsafe-perm node-red-contrib-ibm-watson-iot node-red-contrib-play-audio node-red-node-ledborg node-red-node-ping node-red-node-pi-sense-hat node-red-node-random node-red-node-serialport node-red-node-smooth + when: nodered_install and internet_available and is_rpi + +## To protect pre-installed packages within /usr/lib/node_modules in graphical +## desktop OS's like Raspbian Desktop & Ubermix, we now only install those that +## are missing -- among the 3+8 below. WARNING: THIS COULD POTENTIALLY LEAD TO +## INCOMPATIBILITIES, IF OS'S /usr/lib/node_modules/node-red GETS OUT OF DATE! +# +## /usr/lib/node_modules/node-red is PRE-INSTALLED by Raspbian Desktop, even if +## their package (42MB, 0.19.4) is a bit out of date compared to npm's (55MB, +## 0.19.5) as of 2019-02-12. Among others in /usr/lib/node_modules, pre-placed +## by Raspbian Desktop's apt package 'nodered': +## node-red-contrib-ibm-watson-iot, node-red-contrib-play-audio, +## node-red-node-ledborg, node-red-node-ping, node-red-node-pi-sense-hat +## node-red-node-random, node-red-node-serialport, node-red-node-smooth +#- name: Globally 'npm install' pkg 'node-red' if /usr/lib/node_modules/node-red missing (most OS's except for Raspbian Desktop) +# #command: npm install -g --unsafe-perm node-red +# command: npm install -g --unsafe-perm node-red@latest +# args: +# creates: /usr/lib/node_modules/node-red +# when: nodered_install and internet_available +# +## NOT pre-installed by Raspbian Desktop as of 2019-02-12...so we install this +## on most all OS's: +#- name: Globally 'npm install' pkg 'node-red-admin' if /usr/lib/node_modules/node-red-admin missing (most OS's) +# command: npm install -g --unsafe-perm node-red-admin +# args: +# creates: /usr/lib/node_modules/node-red-admin +# when: nodered_install and internet_available +# +## NOT pre-installed by Raspbian Desktop as of 2019-02-12...so we install this +## on most all OS's: +#- name: Globally 'npm install' pkg 'node-red-dashboard' if /usr/lib/node_modules/node-red-dashboard missing (most OS's) +# command: npm install -g --unsafe-perm node-red-dashboard +# args: +# creates: /usr/lib/node_modules/node-red-dashboard +# when: nodered_install and internet_available + +- include_tasks: group.yml + when: nodered_install and not is_rpi + +- include_tasks: rpi_desk.yml + when: nodered_install and internet_available and is_rpi + +- name: Install /etc/systemd/system/nodered.service systemd unit file from template + template: + backup: yes + src: nodered.service.j2 + dest: /etc/systemd/system/nodered.service + owner: root + group: root + mode: 0666 + +- name: Install Apache's sites-available/nodered.conf from template + template: + backup: yes + src: nodered.conf.j2 + dest: /etc/apache2/sites-available/nodered.conf + owner: root + group: root + mode: 0666 + +# SEE ALSO THE apache2_module SECTION IN roles/httpd/tasks/main.yml +- name: Enable proxy_wstunnel apache2 module + apache2_module: + state: present + name: proxy_wstunnel + +- name: Add 'nodered_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^nodered_installed' + line: 'nodered_installed: True' + state: present + diff --git a/roles/nodered/tasks/main.yml b/roles/nodered/tasks/main.yml index 120021a64..3b5001416 100644 --- a/roles/nodered/tasks/main.yml +++ b/roles/nodered/tasks/main.yml @@ -1,234 +1,5 @@ -# 2019-01-16: @jvonau's PR #1403 moved installation of Node.js (8.x for now) & -# npm to roles/nodejs/tasks/main.yml, triggered by roles/nodered/meta/main.yml +- include_tasks: install.yml + when: nodered_install | bool and not nodered_installed is defined -# BRUTAL but ensures consistency across OS's / distros like Raspbian Desktop & -# Ubermix that often include an older version of Node-RED. Brutal, as this -# removes customizations on graphical desktop OS's e.g. Raspbian Desktop's: -# 1. Node-RED's icon (Raspberry Menu in top-left -> Programming -> Node-RED) -# 2. scripts like {node-red-start, node-red-stop, node-red-log} in /usr/bin -# 3. other changes per /usr/bin/update-nodejs-and-nodered summarized at -# https://nodered.org/docs/hardware/raspberrypi for example low-memory -# flag --max_old_space_size=256 for unit file (we're using 128 on RPi) -# That we'll reconstitute below! -- name: ASK apt/yum/dnf TO REMOVE PRE-EXISTING 'nodered' (IF PREVIOUSLY INSTALLED BY OS PKG MANAGER) - package: - name: nodered - state: absent - when: nodered_install | bool - -# 2012-02-13: the 6 RPi stanzas below recreate Raspbian Desktop's Node-RED -# environment, inspired by: -# https://nodered.org/docs/hardware/raspberrypi -# https://github.com/node-red/raspbian-deb-package/blob/master/resources/update-nodejs-and-nodered -# https://github.com/iiab/iiab/pull/1497 - -- name: "Globally 'npm install' 3 Node-RED packages: node-red, node-red-admin, node-red-dashboard" - command: npm install -g --unsafe-perm node-red node-red-admin node-red-dashboard - #command: npm install -g --unsafe-perm node-red@latest node-red-admin@latest node-red-dashboard@latest - # Above "@latest" is recommended by https://nodered.org/docs/hardware/raspberrypi (SHOULD WE CONSIDER?) - when: nodered_install and internet_available - -- name: "Globally 'npm install' 8 Node-RED learning examples for RPi: node-red-contrib-ibm-watson-iot, node-red-contrib-play-audio, node-red-node-ledborg, node-red-node-ping, node-red-node-pi-sense-hat, node-red-node-random, node-red-node-serialport, node-red-node-smooth" - command: npm install -g --unsafe-perm node-red-contrib-ibm-watson-iot node-red-contrib-play-audio node-red-node-ledborg node-red-node-ping node-red-node-pi-sense-hat node-red-node-random node-red-node-serialport node-red-node-smooth - when: nodered_install and internet_available and is_rpi - -# TEST UNNEC ICON/MENU FILE PLACEMENT ON RASPIAN LITE TOO ! -- name: 'Download/Install 4 useful items for RPi: Node-RED icon, start menu item, /etc/logrotate.d/nodered, tweaked "Pi cpu temperature.json"' - get_url: - url: "{{ item.url }}" - dest: "{{ item.dest }}" - with_items: - - url: https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/node-red-icon.svg - dest: /usr/share/icons/hicolor/scalable/apps/node-red-icon.svg - - url: https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/Node-RED.desktop - dest: /usr/share/applications/Node-RED.desktop - - url: https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/nodered.rotate - dest: /etc/logrotate.d/nodered - - url: 'https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/Pi%20cpu%20temperature.json' - dest: '/usr/lib/node_modules/node-red-contrib-ibm-watson-iot/examples/Pi cpu temperature.json' - when: nodered_install and internet_available and is_rpi - -#- name: Replace/Tweak "node-red-contrib-ibm-watson-iot/examples/Pi cpu temperature.json" (rpi) -# command: 'curl -sL -o /usr/lib/node_modules/node-red-contrib-ibm-watson-iot/examples/Pi\ cpu\ temperature.json https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/Pi%20cpu%20temperature.json' -# when: nodered_install and internet_available and is_rpi - -- name: 'Download/Install 4 RPi executables to /usr/bin: node-red-start, node-red-stop, node-red-restart, node-red-log' - get_url: - url: "{{ item }}" - dest: /usr/bin - mode: a+x - with_items: - - https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/node-red-start - - https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/node-red-stop - - https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/node-red-restart - - https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/node-red-log - when: nodered_install and internet_available and is_rpi - -## To protect pre-installed packages within /usr/lib/node_modules in graphical -## desktop OS's like Raspbian Desktop & Ubermix, we now only install those that -## are missing -- among the 3+8 below. WARNING: THIS COULD POTENTIALLY LEAD TO -## INCOMPATIBILITIES, IF OS'S /usr/lib/node_modules/node-red GETS OUT OF DATE! -# -## /usr/lib/node_modules/node-red is PRE-INSTALLED by Raspbian Desktop, even if -## their package (42MB, 0.19.4) is a bit out of date compared to npm's (55MB, -## 0.19.5) as of 2019-02-12. Among others in /usr/lib/node_modules, pre-placed -## by Raspbian Desktop's apt package 'nodered': -## node-red-contrib-ibm-watson-iot, node-red-contrib-play-audio, -## node-red-node-ledborg, node-red-node-ping, node-red-node-pi-sense-hat -## node-red-node-random, node-red-node-serialport, node-red-node-smooth -#- name: Globally 'npm install' pkg 'node-red' if /usr/lib/node_modules/node-red missing (most OS's except for Raspbian Desktop) -# #command: npm install -g --unsafe-perm node-red -# command: npm install -g --unsafe-perm node-red@latest -# args: -# creates: /usr/lib/node_modules/node-red -# when: nodered_install and internet_available -# -## NOT pre-installed by Raspbian Desktop as of 2019-02-12...so we install this -## on most all OS's: -#- name: Globally 'npm install' pkg 'node-red-admin' if /usr/lib/node_modules/node-red-admin missing (most OS's) -# command: npm install -g --unsafe-perm node-red-admin -# args: -# creates: /usr/lib/node_modules/node-red-admin -# when: nodered_install and internet_available -# -## NOT pre-installed by Raspbian Desktop as of 2019-02-12...so we install this -## on most all OS's: -#- name: Globally 'npm install' pkg 'node-red-dashboard' if /usr/lib/node_modules/node-red-dashboard missing (most OS's) -# command: npm install -g --unsafe-perm node-red-dashboard -# args: -# creates: /usr/lib/node_modules/node-red-dashboard -# when: nodered_install and internet_available - - -- name: Create /home/pi/.node-red/ directory (rpi) - file: - path: /home/pi/.node-red - state: directory - owner: pi - group: pi - mode: 0775 - when: nodered_install and is_rpi - -- name: Install /home/pi/.node-red/settings.js from template, with authentication (rpi) - template: - backup: yes - src: settings.js.j2 - dest: /home/pi/.node-red/settings.js - owner: pi - group: pi - mode: 0755 - when: nodered_install and is_rpi - -- name: Ensure Linux group 'nodered' exists (if not rpi) - group: - name: nodered - state: present - when: nodered_install and not is_rpi - -- name: Ensure Linux user 'nodered' exists and is added to group 'nodered' (if not rpi) - user: - name: nodered - group: nodered - when: nodered_install and not is_rpi - -- name: Ensure directory /home/nodered/.node-red/ exists (if not rpi) - file: - path: /home/nodered/.node-red - state: directory - owner: nodered - group: nodered - mode: 0775 - when: nodered_install and not is_rpi - -- name: Install /home/nodered/.node-red/settings.js from template, with authentication (if not rpi) - template: - backup: yes - src: settings.js.j2 - dest: /home/nodered/.node-red/settings.js - owner: nodered - group: nodered - mode: 0755 - when: nodered_install and not is_rpi - - -- name: Install /etc/systemd/system/nodered.service systemd unit file from template - template: - backup: yes - src: nodered.service.j2 - dest: /etc/systemd/system/nodered.service - owner: root - group: root - mode: 0666 - when: nodered_install | bool - -- name: Install Apache's sites-available/nodered.conf from template - template: - backup: yes - src: nodered.conf.j2 - dest: /etc/apache2/sites-available/nodered.conf - owner: root - group: root - mode: 0666 - when: nodered_install | bool - -- name: Create symlink nodered.conf from sites-enabled to sites-available, for short URL http://box/nodered (if nodered_enabled) - file: - src: /etc/apache2/sites-available/nodered.conf - dest: /etc/apache2/sites-enabled/nodered.conf - owner: root - group: root - state: link - when: nodered_enabled | bool - -- name: Remove symlink /etc/apache2/sites-enabled/nodered.conf (if not nodered_enabled) - file: - path: /etc/apache2/sites-enabled/nodered.conf - state: absent - when: not nodered_enabled - -# SEE ALSO THE apache2_module SECTION IN roles/httpd/tasks/main.yml -- name: Enable proxy_wstunnel apache2 module - apache2_module: - state: present - name: proxy_wstunnel - when: nodered_install | bool - -- name: Restart Apache service ({{ apache_service }}) to enable/disable http://box/nodered (not just http://box:{{ nodered_port }}/nodered) - systemd: - #daemon_reload: yes - name: "{{ apache_service }}" # httpd or apache2 - state: restarted - when: nodered_install | bool - -- name: Enable & (Re)start 'nodered' systemd service (if nodered_enabled) - systemd: - daemon_reload: yes - name: nodered - enabled: yes - state: restarted - when: nodered_enabled | bool - -- name: Disable & Stop 'nodered' systemd service (if not nodered_enabled) - systemd: - daemon_reload: yes - name: nodered - enabled: no - state: stopped - when: not nodered_enabled - - -- name: Add 'nodered' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" - section: nodered - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: Node-RED - - option: description - value: '"Node-RED is a flow-based development tool for visual programming developed originally by IBM for wiring together hardware devices, APIs and online services as part of the Internet of Things. Node-RED provides a web browser-based flow editor, which can be used to create JavaScript functions."' - - option: nodered_install - value: "{{ nodered_install }}" - - option: nodered_enabled - value: "{{ nodered_enabled }}" +- include_tasks: enable.yml + when: nodered_install | bool or nodered_installed is defined diff --git a/roles/nodered/tasks/rpi_desk.yml b/roles/nodered/tasks/rpi_desk.yml new file mode 100644 index 000000000..ed15fb587 --- /dev/null +++ b/roles/nodered/tasks/rpi_desk.yml @@ -0,0 +1,45 @@ +# TEST UNNEC ICON/MENU FILE PLACEMENT ON RASPIAN LITE TOO ! +- name: 'Download/Install 4 useful items for RPi: Node-RED icon, start menu item, /etc/logrotate.d/nodered, tweaked "Pi cpu temperature.json"' + get_url: + url: "{{ item.url }}" + dest: "{{ item.dest }}" + with_items: + - url: https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/node-red-icon.svg + dest: /usr/share/icons/hicolor/scalable/apps/node-red-icon.svg + - url: https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/Node-RED.desktop + dest: /usr/share/applications/Node-RED.desktop + - url: https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/nodered.rotate + dest: /etc/logrotate.d/nodered + - url: 'https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/Pi%20cpu%20temperature.json' + dest: '/usr/lib/node_modules/node-red-contrib-ibm-watson-iot/examples/Pi cpu temperature.json' + +#- name: Replace/Tweak "node-red-contrib-ibm-watson-iot/examples/Pi cpu temperature.json" (rpi) +# command: 'curl -sL -o /usr/lib/node_modules/node-red-contrib-ibm-watson-iot/examples/Pi\ cpu\ temperature.json https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/Pi%20cpu%20temperature.json' +# when: nodered_install and internet_available and is_rpi + +- name: 'Download/Install 4 RPi executables to /usr/bin: node-red-start, node-red-stop, node-red-restart, node-red-log' + get_url: + url: "{{ item }}" + dest: /usr/bin + mode: a+x + with_items: + - https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/node-red-start + - https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/node-red-stop + - https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/node-red-restart + - https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/node-red-log + +- name: Create /home/pi/.node-red/ directory (rpi) + file: + path: /home/pi/.node-red + state: directory + owner: pi + group: pi + mode: 0775 + +- name: Install /home/pi/.node-red/settings.js from template, with authentication (rpi) + template: + src: settings.js.j2 + dest: /home/pi/.node-red/settings.js + owner: pi + group: pi + mode: 0755 diff --git a/roles/osm-vector-maps/tasks/main.yml b/roles/osm-vector-maps/tasks/main.yml index 5b8ce54f0..c698e3644 100644 --- a/roles/osm-vector-maps/tasks/main.yml +++ b/roles/osm-vector-maps/tasks/main.yml @@ -35,19 +35,18 @@ dest: '{{ vector_map_path }}/maplist/assets/' # REMOVE this stanza once the transition to Python 3 is confirmed -- name: Install python-geojson package (OS's prior to Ubuntu 19.10) - package: - name: python-geojson - state: present - when: is_raspbian_9 or is_raspbian_10 or is_ubuntu_16 or is_ubuntu_18 or is_debian_9 or is_debian_10 +#- name: Install python-geojson package (OS's prior to Ubuntu 19.10) +# package: +# name: python-geojson +# state: present +# when: is_raspbian_9 or is_raspbian_10 or is_ubuntu_16 or is_ubuntu_18 or is_debian_9 or is_debian_10 # 2019-10-19: Above python-geojson does not exist on Ubuntu 19.10, so let's -# begin the transition to Python 3... - -- name: Install python3-geojson package (especially for new OS's like Ubuntu 19.10+) - package: - name: python3-geojson # 2019-10-19: available across most/all recent - state: present # OS's, but not yet used by osm-vector-maps code? +# begin the transition to Python 3... currently unused +#- name: Install python3-geojson package (especially for new OS's like Ubuntu 19.10+) +# package: +# name: python3-geojson # 2019-10-19: available across most/all recent +# state: present # OS's, but not yet used by osm-vector-maps code? - name: Install /usr/bin/iiab-update-map for updating of Map Pack catalog & descriptions template: @@ -70,23 +69,17 @@ src: map_functions.js dest: '{{ vector_map_path }}/maplist/assets' -- name: Install /etc/{{ apache_config_dir }}/osm-vector-maps.conf from template +- name: Install /etc/nginx/conf.d/osm-vector-maps.conf from template template: - src: osm-vector-maps.conf - dest: "/etc/{{ apache_config_dir }}/osm-vector-maps.conf" + src: osm-vector-maps-nginx.conf + dest: "/etc/nginx/conf.d/osm-vector-maps-nginx.conf" + when: osm_vector_maps_enabled | bool -- name: Create symlink osm-vector-maps.conf from sites-enabled to sites-available (debuntu, not nec for redhat) +- name: Remove config /etc/nginx/conf,d/osm-vector-maps.conf (debuntu) file: - src: /etc/apache2/sites-available/osm-vector-maps.conf - path: /etc/apache2/sites-enabled/osm-vector-maps.conf - state: link - when: osm_vector_maps_enabled and is_debuntu - -- name: Remove symlink /etc/apache2/sites-enabled/osm-vector-maps.conf (debuntu) - file: - path: /etc/apache2/sites-enabled/osm-vector-maps.conf + path: /etc/nginx/conf.d/osm-vector-maps-nginx.conf state: absent - when: not osm_vector_maps_enabled and is_debuntu + when: not osm_vector_maps_enabled | bool #- name: Does the {{ vector_map_path }}/index.html redirect already exist? # stat: diff --git a/roles/osm-vector-maps/templates/iiab-update-map b/roles/osm-vector-maps/templates/iiab-update-map index 35055e317..6ddc18a71 100755 --- a/roles/osm-vector-maps/templates/iiab-update-map +++ b/roles/osm-vector-maps/templates/iiab-update-map @@ -1,224 +1,15 @@ -#!/usr/bin/env python -# Scan the osm-vector-maps directory, update the osm-vector-maps-idx.json, add menu-defs +#!/bin/bash -from geojson import Feature, Point, FeatureCollection, Polygon -import geojson -import json -import os -import sys -import fnmatch -import re -from datetime import date +CMDSRV_SCRIPTS="/opt/admin/cmdsrv/scripts" +if [ ! -f "$CMDSRV_SCRIPTS/iiab-update-map.py" ]; then + echo "Admin Console not installed. Exiting." + exit +fi -IIAB_PATH='/etc/iiab' -if not IIAB_PATH in sys.path: - sys.path.append(IIAB_PATH) -from iiab_env import get_iiab_env +$CMDSRV_SCRIPTS/iiab-update-map.py -SCRIPT_DIR = '/opt/admin/cmdsrv/scripts' -if not SCRIPT_DIR in sys.path: - sys.path.append(SCRIPT_DIR) -if os.path.exists(os.path.join(SCRIPT_DIR,'iiab_update_menus.py')): - import iiab_update_menus as menus - console_installed = True -else: - console_installed = False - -doc_root = get_iiab_env('WWWROOT') -menuDefs = doc_root + "/js-menu/menu-files/menu-defs/" -vector_map_idx_dir = doc_root + "/common/assets" -map_doc_root = '{{ vector_map_path }}' # /library/www/osm-vector-maps -# map_catalog will be global, assumed always available -map_catalog = {} -map_menu_def_list = [] -previous_idx = {} # track new regions so we don't thrash on adding to menu - -def main(): - global map_menu_def_list - global previous_idx - - get_map_catalog() - #print(json.dumps(map_catalog,indent=2)) - - map_menu_def_list = get_menu_def_names() - print(json.dumps(map_menu_def_list,indent=2)) - - read_vector_map_idx() - - installed_maps = get_installed_regions() - print(installed_maps) - - write_vector_map_idx(installed_maps) - - # For installed regions, check that a menu def exists, and it's on home page - for fname in installed_maps: - region = extract_region_from_filename(fname) - if region == 'maplist': # it is the splash page, display only if no others - menu_ref = 'en-map_test' - item = { "perma_ref" : "en-map_test" } - if len(installed_maps) == 1: - menus.update_menu_json(menu_ref) - return - elif region not in map_catalog['regions']: - print "Skipping unknown map " + fname - continue - else: - item = map_catalog['regions'][region] - menu_ref = item['perma_ref'] - if not (menu_ref in map_menu_def_list): - print('creating menu def for %s'%item['perma_ref']) - create_menu_def(region,item['perma_ref'] + '.json') - # if autoupdate allowed and this is a new region then add to home menu - if fetch_menu_json_value('autoupdate_menu') and item['perma_ref'] not in previous_idx: - print('autoudate of menu items is enabled:%s. Adding %s'%(\ - fetch_menu_json_value('autoupdate_menu'),region,)) - menus.update_menu_json(menu_ref) - # redirect from box/maps to an installed map rather than test page - with open(map_doc_root + '/index.html','w') as fp: - outstr = """ \n\n"""%fname - fp.write(outstr) - - -def get_map_catalog(): - global map_catalog - input_json = map_doc_root + '/maplist/assets/regions.json' - with open(input_json,'r') as regions: - reg_str = regions.read() - map_catalog = json.loads(reg_str) - #print(json.dumps(map_catalog,indent=2)) - -def get_menu_def_names(intended_use='map'): - menu_def_list =[] - 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','') != intended_use: - continue - map_name = data.get('map_name','') - if map_name != '': - menu_def_list.append(map_name) - return menu_def_list - -def get_installed_regions(): - installed = [] - os.chdir(map_doc_root) - for filename in os.listdir('.'): - if fnmatch.fnmatch(filename, '??-osm-omt*'): - region = re.sub(r'^..-osm-..._(.*)',r'\1',filename) - installed.append(region) - # add the splash page if no other maps are present - if len(installed) == 0: - installed.append('maplist') - return installed - -def read_vector_map_idx(): - global previous_idx - try: # will fail first time - with open(vector_map_idx_dir + '/vector-map-idx.json','r') as idx: - str = idx.read() - previous_idx = json.loads(str) - except: - pass - -def write_vector_map_idx(installed_maps): - map_dict ={} - idx_dict = {} - for fname in installed_maps: - region = extract_region_from_filename(fname) - if map == 'maplist': continue # not a real region - map_dict = map_catalog['regions'].get(region,'') - if map_dict == '': continue - - # Create the idx file in format required bo js-menu system - item = map_dict['perma_ref'] - idx_dict[item] = {} - idx_dict[item]['file_name'] = os.path.basename(map_dict['url'][:-4]) - idx_dict[item]['menu_item'] = map_dict['perma_ref'] - idx_dict[item]['size'] = map_dict['size'] - idx_dict[item]['date'] = map_dict['date'] - idx_dict[item]['region'] = region - idx_dict[item]['language'] = map_dict['perma_ref'][:2] - - with open(vector_map_idx_dir + '/vector-map-idx.json','w') as idx: - idx.write(json.dumps(idx_dict,indent=2)) - -def create_menu_def(region,default_name,intended_use='map'): - item = map_catalog['regions'][region] - if len(item.get('language','')) > 2: - lang = item['language'][:2] - else: # default to english - lang = 'en' - filename = lang + '-' + item['perma_ref'] + '.json' - # create a stub for this zim - menuDef = {} - default_logo = 'osm.jpg' - menuDef["intended_use"] = "map" - menuDef["lang"] = lang - menuDef["logo_url"] = default_logo - menuitem = lang + '-' + item['perma_ref'] - menuDef["menu_item_name"] = default_name - - if item.get('title','ERROR') == "World": - fancyTitle = "Planet Earth" - elif item.get('title','ERROR') == "Central America": - fancyTitle = "Central America-Caribbean" - else: - fancyTitle = item.get('title','ERROR') - - if fancyTitle == "Planet Earth": - menuDef["title"] = "OpenStreetMap: " + fancyTitle - else: - menuDef["title"] = "OpenStreetMap: " + fancyTitle + " & Earth" - - menuDef["map_name"] = item['perma_ref'] - # the following is in the idx json - #menuDef["file_name"] = lang + '-osm-omt_' + region + '_' + os.path.basename(item['url'])[:-4] - menuDef["description"] = '19 levels of zoom (~1 m details) for ' + fancyTitle + ', illustrating human geography.

10 levels of zoom (~1 km details) for satellite photos, covering the whole world.' - menuDef["extra_description"] = 'Search for cities/towns with more than 1000 people. There are about 127,654 worldwide.' - menuDef["extra_html"] = "" - #menuDef["automatically_generated"] = "true" - menuDef["change_ref"] = "generated" - menuDef["change_date"] = str(date.today()) - if not os.path.isfile(menuDefs + default_name): # logic to here can still overwrite existing menu def - print("creating %s"%menuDefs + default_name) - with open(menuDefs + default_name,'w') as menufile: - menufile.write(json.dumps(menuDef,indent=4)) - return default_name[:-5] - -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 - -def fetch_menu_json_value(key): - with open( doc_root + '/home/menu.json','r') as menudef: - data = json.loads(menudef.read()) - return data.get(key,'') - -def extract_region_from_filename(fname): - # find the index of the date - nibble = re.search(r"\d{4}-\d{2}-\d{2}",fname) - if nibble: - fname = fname[:nibble.start()-1] - return fname - else: - return("maplist") - -if __name__ == '__main__': - if console_installed: - main() +if [ $? -ne 0 ]; then + echo "Update Menus Failed." + exit 1 +fi +exit diff --git a/roles/osm-vector-maps/templates/osm-vector-maps-nginx.conf b/roles/osm-vector-maps/templates/osm-vector-maps-nginx.conf new file mode 100644 index 000000000..97cfc2535 --- /dev/null +++ b/roles/osm-vector-maps/templates/osm-vector-maps-nginx.conf @@ -0,0 +1,7 @@ +# For downloadable regional vector tilesets +location /maps { + alias /library/www/osm-vector-maps; +} +location /osm-vector-maps { + alias /library/www/osm-vector-maps; +} diff --git a/roles/samba/tasks/main.yml b/roles/samba/tasks/main.yml index f80ee9941..6e3f1c72a 100755 --- a/roles/samba/tasks/main.yml +++ b/roles/samba/tasks/main.yml @@ -30,6 +30,13 @@ src: smb.conf.j2 dest: /etc/samba/smb.conf +- name: Add 'samba_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^samba_installed' + line: 'samba_installed: True' + state: present + - name: Enable & Start Samba systemd service service: name: "{{ smb_service }}" diff --git a/roles/sugarizer/tasks/enable.yml b/roles/sugarizer/tasks/enable.yml new file mode 100644 index 000000000..95db3155f --- /dev/null +++ b/roles/sugarizer/tasks/enable.yml @@ -0,0 +1,86 @@ +- name: Create symlink sugarizer.conf from sites-enabled to sites-available, for short URLs http://box/sugar & http://box/sugarizer (if sugarizer_enabled) + file: + src: /etc/apache2/sites-available/sugarizer.conf + path: /etc/apache2/sites-enabled/sugarizer.conf + state: link + when: sugarizer_enabled | bool and not nginx_enabled | bool + +- name: Remove symlink /etc/apache2/sites-enabled/sugarizer.conf (if not sugarizer_enabled) + file: + path: /etc/apache2/sites-enabled/sugarizer.conf + state: absent + when: not sugarizer_enabled | bool or nginx_enabled | bool + +- name: "Install sugarizer-nginx.conf (nginx)" + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + mode: "{{ item.mode }}" + owner: root + group: root + with_items: + - { src: 'sugarizer-nginx.conf', dest: '/etc/nginx/conf.d/sugarizer-nginx.conf' , mode: '0644' } + when: sugarizer_enabled | bool and nginx_enabled | bool + +# 6. RESTART/STOP SYSTEMD SERVICE + +# with "systemctl daemon-reload" in case mongodb.service changed, etc +- name: Enable & Restart 'sugarizer' systemd service (if sugarizer_enabled) + systemd: + name: sugarizer + daemon_reload: yes + enabled: yes + state: restarted + when: sugarizer_enabled | bool + +- name: Disable & Stop 'sugarizer' systemd service (if not sugarizer_enabled) + systemd: + name: sugarizer + daemon_reload: yes + enabled: no + state: stopped + when: not sugarizer_enabled + +#- name: Enable services (all OS's) +# service: +# name: "{{ item.name }}" +# enabled: yes +# state: restarted +# with_items: +## - { name: mongodb } # 2018-07-14: NICE TRY, but still doesn't bring http://box:8089 to life reliably, as a reboot usually does! (Is a "systemctl daemon-reload" or some such nec?) +# - { name: sugarizer } +# when: sugarizer_enabled | bool + +#- name: Disable service (all OS's) +# service: +# name: sugarizer +# enabled: no +# state: stopped +# when: not sugarizer_enabled + +- name: Restart Apache service ({{ apache_service }}) to enable/disable http://box/sugarizer (not just http://box:{{ sugarizer_port }}) + systemd: + name: "{{ apache_service }}" # httpd or apache2 + state: restarted + when: sugarizer_enabled | bool and not nginx_enabled | bool + +- name: Restart nginx when enabled + systemd: + name: nginx + state: restarted + daemon_reload: yes + when: sugarizer_enabled and nginx_enabled + +- name: Add 'sugarizer' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: sugarizer + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: Sugarizer + - option: description + value: '"The Sugar Learning Platform began with the famous One Laptop Per Child project, written in Python. Sugarizer is the new HTML/JavaScript implementation of Sugar, usable in most all browsers."' + - option: sugarizer_enabled + value: "{{ sugarizer_enabled }}" diff --git a/roles/sugarizer/tasks/install.yml b/roles/sugarizer/tasks/install.yml index 339f4b0eb..6d41de7c4 100644 --- a/roles/sugarizer/tasks/install.yml +++ b/roles/sugarizer/tasks/install.yml @@ -138,7 +138,7 @@ # 5. CONFIG FILES -- name: "Install from templates: sugarizer.service (systemd), sugarizer.conf (Apache)" +- name: "Install from templates: sugarizer.service (systemd), sugarizer-nginx.conf (nginx)" template: src: "{{ item.src }}" dest: "{{ item.dest }}" @@ -221,72 +221,9 @@ # # Use this instead, if tabs are truly nec: # # block: "\tvar pathPrefix = '/sugarizer';\n\tapp.use(pathPrefix, require('path-prefix-proxy')(pathPrefix));" -- name: Create symlink sugarizer.conf from sites-enabled to sites-available, for short URLs http://box/sugar & http://box/sugarizer (if sugarizer_enabled) - file: - src: /etc/apache2/sites-available/sugarizer.conf - path: /etc/apache2/sites-enabled/sugarizer.conf - state: link - when: sugarizer_enabled and is_debuntu - -- name: Remove symlink /etc/apache2/sites-enabled/sugarizer.conf (if not sugarizer_enabled) - file: - path: /etc/apache2/sites-enabled/sugarizer.conf - state: absent - when: not sugarizer_enabled and is_debuntu - - -# 6. RESTART/STOP SYSTEMD SERVICE - -# with "systemctl daemon-reload" in case mongodb.service changed, etc -- name: Enable & Restart 'sugarizer' systemd service (if sugarizer_enabled) - systemd: - name: sugarizer - daemon_reload: yes - enabled: yes - state: restarted - when: sugarizer_enabled | bool - -- name: Disable & Stop 'sugarizer' systemd service (if not sugarizer_enabled) - systemd: - name: sugarizer - daemon_reload: yes - enabled: no - state: stopped - when: not sugarizer_enabled - -- name: Restart Apache service ({{ apache_service }}) to enable/disable http://box/sugarizer (not just http://box:{{ sugarizer_port }}) - systemd: - name: "{{ apache_service }}" # httpd or apache2 - state: restarted - #when: sugarizer_enabled | bool - -#- name: Enable services (all OS's) -# service: -# name: "{{ item.name }}" -# enabled: yes -# state: restarted -# with_items: -## - { name: mongodb } # 2018-07-14: NICE TRY, but still doesn't bring http://box:8089 to life reliably, as a reboot usually does! (Is a "systemctl daemon-reload" or some such nec?) -# - { name: sugarizer } -# when: sugarizer_enabled | bool - -#- name: Disable service (all OS's) -# service: -# name: sugarizer -# enabled: no -# state: stopped -# when: not sugarizer_enabled - -- name: Add 'sugarizer' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" - section: sugarizer - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: Sugarizer - - option: description - value: '"The Sugar Learning Platform began with the famous One Laptop Per Child project, written in Python. Sugarizer is the new HTML/JavaScript implementation of Sugar, usable in most all browsers."' - - option: sugarizer_enabled - value: "{{ sugarizer_enabled }}" +- name: Add 'sugarizer_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^sugarizer_installed' + line: 'sugarizer_installed: True' + state: present diff --git a/roles/sugarizer/tasks/main.yml b/roles/sugarizer/tasks/main.yml index 80ae4e837..fa9a0ddff 100644 --- a/roles/sugarizer/tasks/main.yml +++ b/roles/sugarizer/tasks/main.yml @@ -1,3 +1,7 @@ - name: Install 'sugarizer' if sugarizer_install and not Debian 10+ include_tasks: install.yml - when: sugarizer_install and not ((is_debian and not is_raspbian) and (not is_debian_8) and (not is_debian_9)) + when: not sugarizer_installed is defined and sugarizer_install | bool and not ((is_debian and not is_raspbian) and (not is_debian_8) and (not is_debian_9)) + +- name: Enable 'sugarizer' if sugarizer_enabled + include_tasks: enable.yml + when: (sugarizer_install or sugarizer_installed is defined) and not ((is_debian and not is_raspbian) and (not is_debian_8) and (not is_debian_9)) diff --git a/roles/sugarizer/templates/sugarizer-nginx.conf b/roles/sugarizer/templates/sugarizer-nginx.conf new file mode 100644 index 000000000..0085217dd --- /dev/null +++ b/roles/sugarizer/templates/sugarizer-nginx.conf @@ -0,0 +1,9 @@ +# sugarizer_port is set to 8089 in /opt/iiab/iiab/vars/default_vars.yml +# If you need to change this, edit /etc/iiab/local_vars.yml prior to installing +location /sugarizer { + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Script-Name /sugarizer; + proxy_pass http://127.0.0.1:8089; +} diff --git a/roles/wordpress/tasks/enable.yml b/roles/wordpress/tasks/enable.yml new file mode 100644 index 000000000..3796a367b --- /dev/null +++ b/roles/wordpress/tasks/enable.yml @@ -0,0 +1,43 @@ +- name: Create symlink wordpress.conf from sites-enabled to sites-available, if wordpress_enabled (debuntu) + file: + src: /etc/apache2/sites-available/wordpress.conf + path: /etc/apache2/sites-enabled/wordpress.conf + state: link + when: wordpress_enabled and is_debuntu + +- name: Remove /etc/apache2/sites-enabled/wordpress.conf if not wordpress_enabled (debuntu) + file: + path: /etc/apache2/sites-enabled/wordpress.conf + state: absent + when: not wordpress_enabled and is_debuntu + +- name: Restart Apache service ({{ apache_service }}) to enable/disable http://box{{ wp_url }} + systemd: + name: "{{ apache_service }}" + state: restarted + +- name: Add 'wordpress' variable values to {{ iiab_ini_file }} + ini_file: + path: "{{ iiab_ini_file }}" + section: wordpress + option: "{{ item.option }}" + value: "{{ item.value }}" + with_items: + - option: name + value: WordPress + - option: description + value: '"WordPress is a blog and web site management application."' + - option: wordpress_src + value: "{{ wordpress_src }}" + - option: wp_abs_path + value: "{{ wp_abs_path }}" + - option: wp_db_name + value: "{{ wp_db_name }}" + - option: wp_db_user + value: "{{ wp_db_user }}" + - option: wp_url + value: "{{ wp_url }}" + - option: wp_full_url + value: "{{ wp_full_url }}" + - option: wordpress_enabled + value: "{{ wordpress_enabled }}" diff --git a/roles/wordpress/tasks/install.yml b/roles/wordpress/tasks/install.yml index 995af2a1b..239e2ea56 100644 --- a/roles/wordpress/tasks/install.yml +++ b/roles/wordpress/tasks/install.yml @@ -87,23 +87,6 @@ path: /tmp/get-iiab-wp-salts state: absent -- name: Start MySQL systemd service - service: - state: started - name: "{{ mysql_service }}" - -- name: 'Create MySQL wordpress database: {{ wp_db_name }}' - mysql_db: - name: "{{ wp_db_name }}" - state: present - -- name: Create MySQL wordpress database user - mysql_user: - name: "{{ wp_db_user }}" - password: "{{ wp_db_user_password }}" - priv: "{{ wp_db_name }}.*:ALL,GRANT" - state: present - - name: Install {{ wp_abs_path }}/wp-config.php template: src: wp-config.php.j2 @@ -116,47 +99,11 @@ template: src: wordpress.conf.j2 dest: "/etc/{{ apache_config_dir }}/wordpress.conf" + when: apache_enabled -- name: Create symlink wordpress.conf from sites-enabled to sites-available, if wordpress_enabled (debuntu) - file: - src: /etc/apache2/sites-available/wordpress.conf - path: /etc/apache2/sites-enabled/wordpress.conf - state: link - when: wordpress_enabled and is_debuntu - -- name: Remove /etc/apache2/sites-enabled/wordpress.conf if not wordpress_enabled (debuntu) - file: - path: /etc/apache2/sites-enabled/wordpress.conf - state: absent - when: not wordpress_enabled and is_debuntu - -- name: Restart Apache service ({{ apache_service }}) to enable/disable http://box{{ wp_url }} - systemd: - name: "{{ apache_service }}" - state: restarted - -- name: Add 'wordpress' variable values to {{ iiab_ini_file }} - ini_file: - path: "{{ iiab_ini_file }}" - section: wordpress - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: - - option: name - value: WordPress - - option: description - value: '"WordPress is a blog and web site management application."' - - option: wordpress_src - value: "{{ wordpress_src }}" - - option: wp_abs_path - value: "{{ wp_abs_path }}" - - option: wp_db_name - value: "{{ wp_db_name }}" - - option: wp_db_user - value: "{{ wp_db_user }}" - - option: wp_url - value: "{{ wp_url }}" - - option: wp_full_url - value: "{{ wp_full_url }}" - - option: wordpress_enabled - value: "{{ wordpress_enabled }}" +- name: Add 'wordpress_installed' variable values to {{ iiab_state_file }} + lineinfile: + dest: "{{ iiab_state_file }}" + regexp: '^wordpress_installed' + line: 'wordpress_installed: True' + state: present diff --git a/roles/wordpress/tasks/main.yml b/roles/wordpress/tasks/main.yml index 5ff00bb3a..0e1555e01 100644 --- a/roles/wordpress/tasks/main.yml +++ b/roles/wordpress/tasks/main.yml @@ -1,5 +1,13 @@ # SEE "emergency" REINSTALL INSTRUCTIONS IN roles/wordpress/tasks/install.yml -- name: Install WordPress if wordpress_install +- name: Provision MySql DB for WordPress + include_tasks: setup.yml + when: wordpress_install | bool and not installing | bool + +- name: Install WordPress if wordpress_installed is absent include_tasks: install.yml - when: wordpress_install | bool + when: wordpress_install and not wordpress_installed is defined + +- name: Enable WordPress + include_tasks: enable.yml + when: wordpress_install or wordpress_installed is defined diff --git a/roles/wordpress/tasks/setup.yml b/roles/wordpress/tasks/setup.yml new file mode 100644 index 000000000..1f0c8a5a9 --- /dev/null +++ b/roles/wordpress/tasks/setup.yml @@ -0,0 +1,16 @@ +- name: Start MySQL systemd service + systemd: + state: started + name: "{{ mysql_service }}" + +- name: 'Create MySQL wordpress database: {{ wp_db_name }}' + mysql_db: + name: "{{ wp_db_name }}" + state: present + +- name: Create MySQL wordpress database user + mysql_user: + name: "{{ wp_db_user }}" + password: "{{ wp_db_user_password }}" + priv: "{{ wp_db_name }}.*:ALL,GRANT" + state: present diff --git a/run-one-role.yml b/run-one-role.yml index fdc678c37..38a0b97b7 100644 --- a/run-one-role.yml +++ b/run-one-role.yml @@ -6,7 +6,7 @@ - vars/default_vars.yml - "vars/{{ ansible_local.local_facts.os_ver }}.yml" - /etc/iiab/local_vars.yml - - /etc/iiab/config_vars.yml + - /etc/iiab/iiab_state.yml roles: - { role: 0-init, tags: ['0-init'] } diff --git a/runrole b/runrole index 4cd853dc6..7477c966d 100755 --- a/runrole +++ b/runrole @@ -1,38 +1,84 @@ #!/bin/bash -INVENTORY="ansible_hosts" -PLAYBOOK="run-one-role.yml" +INVENTORY=ansible_hosts +PLAYBOOK=run-one-role.yml ARGS="" +REINSTALL=0 CWD=`pwd` +IIAB_STATE_FILE=/etc/iiab/iiab_state.yml +LOCAL_VARS_FILE=/etc/iiab/local_vars.yml +if [ ! -f $PLAYBOOK ]; then + echo "Exiting: IIAB Playbook not found." + echo "Please run this in /opt/iiab/iiab (top level of the git repo)." + exit 1 +fi + +if [[ $# -eq 0 ]] ; then + echo "Usage: ./runrole " + echo "Usage: ./runrole --reinstall " + echo + echo "Optional 2nd parameter is full PATH/FILENAME for logging." + echo "If omitted, /iiab-debug.log is used." + exit 0 +fi + if [ "$1" == "--reinstall" ]; then ARGS="$ARGS --extra-vars reinstall=True" + REINSTALL=1 shift 1 fi +if ! grep -q "^""$1""_install: True" $LOCAL_VARS_FILE; then + echo "ERROR: $LOCAL_VARS_FILE must contain '""$1""_install: True'" + exit 1 +fi + +# Needed for Stages 1-3 if not installed yet +if [ ! -f $IIAB_STATE_FILE ]; then + touch $IIAB_STATE_FILE +fi + +if ! grep -q $1_install $LOCAL_VARS_FILE; then + echo " $1_install: not found in $VARS" + echo " Please review $VARS and edit as required" + exit 1 +elif grep $1_install $LOCAL_VARS_FILE | grep -q --exclude "#" False; then + echo " $1_install: set to False found in $VARS" + echo " Please review $VARS and edit as required" + exit 1 +elif grep $1_install $LOCAL_VARS_FILE | grep -q "#"; then + echo " $1_install: commented out (#) in $VARS" + echo " Please review $VARS and edit as required" + exit 1 +else + if grep $1_install $LOCAL_VARS_FILE | grep -q --exclude "#" True; then + echo " $1_install: set to True found in $VARS" + echo " continuing...." + else + echo "somthing went wrong to get here" + exit 1 + fi +fi + +if [ "$REINSTALL" == "1" ]; then + if [ ! $1 == "internetarchive" ]; then # special handling + if [ $1 == "calibre-web" ]; then # role directory & installed marker differ + sed -i -e '/^calibreweb/d' $IIAB_STATE_FILE + elif [ $1 == "captive-portal" ]; then # role directory & installed marker differ + sed -i -e '/^captive_portal/d' $IIAB_STATE_FILE + #elif [ $1 == "bluetooth" ]; then # role directory & installed marker differ + # sed -i -e '/^pan_bluetooth/d' $IIAB_STATE_FILE + else + sed -i -e "/^$1/d" $IIAB_STATE_FILE + fi + fi +fi + if [ $# -eq 2 ]; then export ANSIBLE_LOG_PATH="$2" else export ANSIBLE_LOG_PATH="$CWD/iiab-debug.log" fi -if [ ! -f $PLAYBOOK ]; then - echo "Exiting: IIAB Playbook not found." - echo "Please run this in /opt/iiab/iiab (top level of the git repo)." - exit 1 -fi - -# Is the following stanza nec? -if [ ! -f /etc/iiab/config_vars.yml ]; then - mkdir -p /etc/iiab - echo "{}" > /etc/iiab/config_vars.yml -fi - -if [[ $# -eq 0 ]] ; then - echo " usage: ./runrole " - echo " Can only take a single value." - exit 0 -fi - - ansible -m setup -i $INVENTORY localhost ${ARGS} --connection=local | grep python ansible-playbook -i $INVENTORY $PLAYBOOK ${ARGS} --connection=local -e "role_to_run=$1" diff --git a/vars/default_vars.yml b/vars/default_vars.yml index 3218ec501..b04ed6eb6 100644 --- a/vars/default_vars.yml +++ b/vars/default_vars.yml @@ -16,6 +16,7 @@ iiab_local_vars_file: "{{ iiab_etc_path }}/local_vars.yml" # Installation status files iiab_env_file: "{{ iiab_etc_path }}/iiab.env" iiab_ini_file: "{{ iiab_etc_path }}/iiab.ini" +iiab_state_file: "{{ iiab_etc_path }}/iiab_state.yml" iiab_base: /opt/iiab iiab_dir: "{{ iiab_base }}/iiab" @@ -221,6 +222,25 @@ exFAT_enabled: True # 3-BASE-SERVER +# Variables for Administrative Console +admin_console_install: True +admin_console_enabled: True + +# variables related to introduction of nginx +# apache +apache_install: True +apache_enabled: True +apache_port: "8090" +apache_interface: "127.0.0.1" +# The following variable, if True, allows Admin Console to poweroff IIAB +# see below +#allow_apache_sudo: False + +nginx_port: "80" +nginx_interface: "0.0.0.0" +nginx_install: True +nginx_enabled: True + # See also Apache vars {default_language, language_priority} @ top of this file # @@ -231,6 +251,7 @@ apache_high_php_limits: False # https://github.com/iiab/iiab/blob/master/roles/httpd/tasks/main.yml#L80-L84 # ...ARE SUITABLE FOR YOUR HARDWARE IN /etc/php//apache2/php.ini # + # Make this False to disable http://box/common/services/power_off.php button: apache_allow_sudo: True @@ -317,6 +338,7 @@ azuracast_port_range_prefix: 10 dokuwiki_install: False dokuwiki_enabled: False +dokuwiki_url: /wiki mediawiki_install: False mediawiki_enabled: False @@ -333,6 +355,8 @@ elgg_mysql_password: elgg4kids # Gitea (lightweight self-hosted "GitHub") from https://gitea.io gitea_install: False gitea_enabled: False +gitea_url: /gitea +gitea_port: 61734 # Lokole (email for rural communities) from https://ascoderu.ca lokole_install: False