Enable additional ZIM archives for kiwix #4
7 changed files with 207 additions and 38 deletions
18
CLAUDE.md
18
CLAUDE.md
|
|
@ -81,15 +81,23 @@ After creating a PR, run `open <pr-url>` to open it in the browser (Claude Code'
|
|||
|
||||
## Ansible
|
||||
|
||||
Run playbooks from the `ansible/` directory.
|
||||
|
||||
```bash
|
||||
# Install collection dependencies
|
||||
ansible-galaxy collection install -r requirements.yml
|
||||
ansible-galaxy collection install -r ansible/requirements.yml
|
||||
|
||||
# Dry-run before committing changes
|
||||
ansible-playbook playbooks/indri.yml --check --diff
|
||||
ansible-playbook ansible/playbooks/indri.yml --check --diff
|
||||
|
||||
# Apply changes
|
||||
ansible-playbook playbooks/indri.yml
|
||||
ansible-playbook ansible/playbooks/indri.yml
|
||||
```
|
||||
|
||||
## Service Health Checks
|
||||
|
||||
After making changes to services, run the service health check to verify everything is working:
|
||||
|
||||
```bash
|
||||
mise run indri-services-check
|
||||
```
|
||||
|
||||
This checks that all indri services (prometheus, grafana, kiwix, transmission, forgejo) are running and responding to health checks.
|
||||
|
|
|
|||
|
|
@ -23,40 +23,42 @@ kiwix_zim_archives:
|
|||
# - category: wikipedia
|
||||
# filename: wikipedia_en_top_maxi_2025-12.zim # 7.6G - Top 100K articles
|
||||
|
||||
## Project Gutenberg - Public domain books
|
||||
# - category: gutenberg
|
||||
# filename: gutenberg_en_all_2023-08.zim # 72G - Full collection (2023)
|
||||
# Project Gutenberg - Public domain books (72G)
|
||||
- category: gutenberg
|
||||
filename: gutenberg_en_all_2023-08.zim
|
||||
|
||||
## Newer Gutenberg (much larger, unclear why):
|
||||
# - category: gutenberg
|
||||
# filename: gutenberg_en_all_2025-11.zim # 206G - Full collection (2025)
|
||||
|
||||
## iFixit - Repair guides
|
||||
# - category: ifixit
|
||||
# filename: ifixit_en_all_2025-12.zim # 3.3G
|
||||
# iFixit - Repair guides (3.3G)
|
||||
- category: ifixit
|
||||
filename: ifixit_en_all_2025-12.zim
|
||||
|
||||
## Stack Exchange
|
||||
# - category: stack_exchange
|
||||
# filename: superuser.com_en_all_2025-12.zim # 3.7G
|
||||
# Stack Exchange
|
||||
- category: stack_exchange
|
||||
filename: superuser.com_en_all_2025-12.zim # 3.7G
|
||||
# - category: stack_exchange
|
||||
# filename: serverfault.com_en_all_2025-12.zim # 1.5G
|
||||
# - category: stack_exchange
|
||||
# filename: askubuntu.com_en_all_2025-12.zim # 2.6G
|
||||
# - category: stack_exchange
|
||||
# filename: unix.stackexchange.com_en_all_2025-12.zim # 1.2G
|
||||
# - category: stack_exchange
|
||||
# filename: math.stackexchange.com_en_all_2025-12.zim # 6.9G
|
||||
- category: stack_exchange
|
||||
filename: math.stackexchange.com_en_all_2025-12.zim # 6.9G
|
||||
# - category: stack_exchange
|
||||
# filename: stackoverflow.com_en_all_2023-11.zim # 75G - Full StackOverflow
|
||||
|
||||
## LibreTexts - Open educational resources
|
||||
# - category: libretexts
|
||||
# filename: libretexts_en_biology_2025-01.zim # 2.1G
|
||||
# - category: libretexts
|
||||
# filename: libretexts_en_chemistry_2025-01.zim # 2.0G
|
||||
# - category: libretexts
|
||||
# filename: libretexts_en_engineering_2025-01.zim # 647M
|
||||
# - category: libretexts
|
||||
# filename: libretexts_en_mathematics_2025-01.zim # 744M
|
||||
# - category: libretexts
|
||||
# filename: libretexts_en_physics_2025-01.zim # 464M
|
||||
# - category: libretexts
|
||||
# filename: libretexts_en_humanities_2025-01.zim # 3.5G
|
||||
# LibreTexts - Open educational resources
|
||||
- category: libretexts
|
||||
filename: libretexts.org_en_bio_2025-01.zim # 2.1G
|
||||
- category: libretexts
|
||||
filename: libretexts.org_en_chem_2025-01.zim # 2.0G
|
||||
- category: libretexts
|
||||
filename: libretexts.org_en_eng_2025-01.zim # 647M
|
||||
- category: libretexts
|
||||
filename: libretexts.org_en_math_2025-01.zim # 744M
|
||||
- category: libretexts
|
||||
filename: libretexts.org_en_phys_2025-01.zim # 464M
|
||||
- category: libretexts
|
||||
filename: libretexts.org_en_human_2025-01.zim # 3.5G
|
||||
|
|
|
|||
|
|
@ -158,6 +158,18 @@
|
|||
- not item.stat.exists
|
||||
notify: restart kiwix-serve
|
||||
|
||||
# --- Determine which archives are available ---
|
||||
- name: Find available ZIM archives in kiwix directory
|
||||
ansible.builtin.find:
|
||||
paths: "{{ kiwix_zim_dir }}"
|
||||
patterns: "*.zim"
|
||||
file_type: any # includes symlinks
|
||||
register: available_zim_files
|
||||
|
||||
- name: Build list of available archive filenames
|
||||
ansible.builtin.set_fact:
|
||||
kiwix_available_archives: "{{ available_zim_files.files | map(attribute='path') | map('basename') | list }}"
|
||||
|
||||
# --- LaunchAgent deployment ---
|
||||
- name: Deploy kiwix-serve LaunchAgent plist
|
||||
ansible.builtin.template:
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@
|
|||
<array>
|
||||
<string>{{ kiwix_serve_bin }}</string>
|
||||
<string>--port={{ kiwix_port }}</string>
|
||||
{% for archive in kiwix_zim_archives %}
|
||||
<string>{{ kiwix_zim_dir }}/{{ archive.filename }}</string>
|
||||
{% for filename in kiwix_available_archives %}
|
||||
<string>{{ kiwix_zim_dir }}/{{ filename }}</string>
|
||||
{% endfor %}
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
|
|
|
|||
|
|
@ -21,8 +21,19 @@
|
|||
path: ~/.config/transmission-daemon
|
||||
state: absent
|
||||
|
||||
# Note: transmission must be stopped before modifying settings.json
|
||||
# otherwise it may overwrite our changes on shutdown
|
||||
- name: Check if settings.json needs updating
|
||||
ansible.builtin.template:
|
||||
src: settings.json.j2
|
||||
dest: "{{ transmission_config_dir }}/settings.json"
|
||||
mode: '0600'
|
||||
check_mode: true
|
||||
register: settings_check
|
||||
|
||||
- name: Stop transmission before config changes
|
||||
ansible.builtin.command: brew services stop transmission-cli
|
||||
when: settings_check.changed
|
||||
register: brew_stop
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
|
@ -31,7 +42,7 @@
|
|||
ansible.builtin.template:
|
||||
src: settings.json.j2
|
||||
dest: "{{ transmission_config_dir }}/settings.json"
|
||||
mode: '0644'
|
||||
mode: '0600'
|
||||
notify: restart transmission
|
||||
|
||||
- name: Ensure transmission service is started
|
||||
|
|
|
|||
|
|
@ -1,21 +1,89 @@
|
|||
{#
|
||||
RPC is required for transmission-remote CLI to manage torrents.
|
||||
Config is secure: bound to localhost only, no auth needed.
|
||||
|
||||
rpc-password uses a static hash starting with '{' so transmission
|
||||
recognizes it as pre-hashed and won't regenerate it on restart.
|
||||
Without this, transmission writes a new hash each startup causing
|
||||
perpetual ansible diffs.
|
||||
#}
|
||||
{
|
||||
"_comment": "{{ ansible_managed }}",
|
||||
"alt-speed-down": 50,
|
||||
"alt-speed-enabled": false,
|
||||
"alt-speed-time-begin": 540,
|
||||
"alt-speed-time-day": 127,
|
||||
"alt-speed-time-enabled": false,
|
||||
"alt-speed-time-end": 1020,
|
||||
"alt-speed-up": 50,
|
||||
"announce-ip": "",
|
||||
"announce-ip-enabled": false,
|
||||
"anti-brute-force-enabled": false,
|
||||
"anti-brute-force-threshold": 100,
|
||||
"bind-address-ipv4": "0.0.0.0",
|
||||
"bind-address-ipv6": "::",
|
||||
"blocklist-enabled": false,
|
||||
"blocklist-url": "http://www.example.com/blocklist",
|
||||
"cache-size-mb": 4,
|
||||
"default-trackers": "",
|
||||
"dht-enabled": {{ transmission_dht_enabled | lower }},
|
||||
"download-dir": "{{ transmission_download_dir }}",
|
||||
"download-queue-enabled": true,
|
||||
"download-queue-size": 5,
|
||||
"encryption": {{ transmission_encryption }},
|
||||
"idle-seeding-limit": 30,
|
||||
"idle-seeding-limit-enabled": false,
|
||||
"incomplete-dir": "{{ transmission_incomplete_dir }}",
|
||||
"incomplete-dir-enabled": true,
|
||||
"dht-enabled": {{ transmission_dht_enabled | lower }},
|
||||
"lpd-enabled": true,
|
||||
"message-level": 4,
|
||||
"peer-congestion-algorithm": "",
|
||||
"peer-limit-global": 200,
|
||||
"peer-limit-per-torrent": 50,
|
||||
"peer-port": 51413,
|
||||
"peer-port-random-high": 65535,
|
||||
"peer-port-random-low": 49152,
|
||||
"peer-port-random-on-start": false,
|
||||
"peer-socket-tos": "le",
|
||||
"pex-enabled": {{ transmission_pex_enabled | lower }},
|
||||
"encryption": {{ transmission_encryption }},
|
||||
"rpc-enabled": {{ transmission_rpc_enabled | lower }},
|
||||
"rpc-port": {{ transmission_rpc_port }},
|
||||
"rpc-bind-address": "{{ transmission_rpc_bind_address }}",
|
||||
"port-forwarding-enabled": true,
|
||||
"preallocation": 1,
|
||||
"prefetch-enabled": true,
|
||||
"queue-stalled-enabled": true,
|
||||
"queue-stalled-minutes": 30,
|
||||
"ratio-limit": 2,
|
||||
"ratio-limit-enabled": false,
|
||||
"rename-partial-files": false,
|
||||
"rpc-authentication-required": {{ transmission_rpc_authentication_required | lower }},
|
||||
"rpc-whitelist-enabled": {{ transmission_rpc_whitelist_enabled | lower }},
|
||||
"rpc-bind-address": "{{ transmission_rpc_bind_address }}",
|
||||
"rpc-enabled": {{ transmission_rpc_enabled | lower }},
|
||||
"rpc-host-whitelist": "",
|
||||
"rpc-host-whitelist-enabled": true,
|
||||
"rpc-password": "{00000000000000000000000000000000000000000000000e",
|
||||
"rpc-port": {{ transmission_rpc_port }},
|
||||
"rpc-socket-mode": "0750",
|
||||
"rpc-url": "/transmission/",
|
||||
"rpc-username": "",
|
||||
"rpc-whitelist": "{{ transmission_rpc_whitelist }}",
|
||||
"rpc-whitelist-enabled": {{ transmission_rpc_whitelist_enabled | lower }},
|
||||
"scrape-paused-torrents-enabled": true,
|
||||
"script-torrent-added-enabled": false,
|
||||
"script-torrent-added-filename": "",
|
||||
"script-torrent-done-enabled": false,
|
||||
"script-torrent-done-filename": "",
|
||||
"script-torrent-done-seeding-enabled": false,
|
||||
"script-torrent-done-seeding-filename": "",
|
||||
"seed-queue-enabled": false,
|
||||
"seed-queue-size": 10,
|
||||
"speed-limit-down": {{ transmission_speed_limit_down }},
|
||||
"speed-limit-down-enabled": {{ (transmission_speed_limit_down > 0) | lower }},
|
||||
"speed-limit-up": {{ transmission_speed_limit_up }},
|
||||
"speed-limit-up-enabled": {{ (transmission_speed_limit_up > 0) | lower }},
|
||||
"start-added-torrents": true,
|
||||
"trash-original-torrent-files": false
|
||||
"tcp-enabled": true,
|
||||
"torrent-added-verify-mode": "fast",
|
||||
"trash-original-torrent-files": false,
|
||||
"umask": "022",
|
||||
"upload-slots-per-torrent": 8,
|
||||
"utp-enabled": true
|
||||
}
|
||||
|
|
|
|||
68
mise-tasks/indri-services-check
Executable file
68
mise-tasks/indri-services-check
Executable file
|
|
@ -0,0 +1,68 @@
|
|||
#!/usr/bin/env bash
|
||||
#MISE description="Check that all indri services are online and responding"
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[0;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
FAILED=0
|
||||
|
||||
check_service() {
|
||||
local name="$1"
|
||||
local check_cmd="$2"
|
||||
|
||||
printf "%-20s " "$name..."
|
||||
if eval "$check_cmd" > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}OK${NC}"
|
||||
else
|
||||
echo -e "${RED}FAILED${NC}"
|
||||
FAILED=1
|
||||
fi
|
||||
}
|
||||
|
||||
check_http() {
|
||||
local name="$1"
|
||||
local url="$2"
|
||||
|
||||
printf "%-20s " "$name..."
|
||||
if curl -sf --max-time 5 "$url" > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}OK${NC}"
|
||||
else
|
||||
echo -e "${RED}FAILED${NC}"
|
||||
FAILED=1
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Checking indri services..."
|
||||
echo "=========================="
|
||||
echo ""
|
||||
|
||||
# Check via SSH that services are running on indri
|
||||
echo "Local services (via launchctl/brew services):"
|
||||
check_service "prometheus" "ssh indri 'brew services list | grep prometheus | grep started'"
|
||||
check_service "grafana" "ssh indri 'brew services list | grep grafana | grep started'"
|
||||
check_service "transmission" "ssh indri 'brew services list | grep transmission | grep started'"
|
||||
check_service "kiwix-serve" "ssh indri 'launchctl list | grep kiwix | grep -v \"^-\"'"
|
||||
check_service "forgejo" "ssh indri 'brew services list | grep forgejo | grep started'"
|
||||
|
||||
echo ""
|
||||
echo "HTTP endpoints (via Tailscale):"
|
||||
check_http "Prometheus" "http://indri:9090/-/healthy"
|
||||
check_http "Grafana" "http://indri:3000/api/health"
|
||||
check_http "Kiwix" "http://indri:5501/"
|
||||
check_http "Forgejo" "http://indri:3001/"
|
||||
# Transmission RPC is localhost-only by design, check via SSH
|
||||
check_service "Transmission RPC" "ssh indri 'curl -sf http://127.0.0.1:9091/transmission/rpc'"
|
||||
|
||||
echo ""
|
||||
if [ $FAILED -eq 0 ]; then
|
||||
echo -e "${GREEN}All services healthy!${NC}"
|
||||
exit 0
|
||||
else
|
||||
echo -e "${RED}Some services failed health check${NC}"
|
||||
exit 1
|
||||
fi
|
||||
Loading…
Add table
Add a link
Reference in a new issue