diff --git a/mika/rizz/Chart.yaml b/mika/rizz/Chart.yaml
index 3c8a4291..68cc5cb7 100644
--- a/mika/rizz/Chart.yaml
+++ b/mika/rizz/Chart.yaml
@@ -2,8 +2,8 @@ apiVersion: v2
name: rizz
description: Rizz is a simple web application that tracks and posts content from RSS Feeds to Mastodon.
type: application
-version: 0.0.5
-appVersion: "0.0.1-stable-r1"
+version: 0.0.6
+appVersion: "0.0.1-stable-r2"
keywords:
- "rss"
- "monitor"
diff --git a/mika/rizz/templates/__init__.py.tpl b/mika/rizz/templates/__init__.py.tpl
new file mode 100644
index 00000000..77ea480b
--- /dev/null
+++ b/mika/rizz/templates/__init__.py.tpl
@@ -0,0 +1,8 @@
+{{/*
+Celery /base/base/__init__.py template
+*/}}
+{{- define "rizz.celery-init-py" -}}
+from .celery import app as celery_app
+
+__all__ = ("celery_app",)
+{{- end }}
diff --git a/mika/rizz/templates/_helpers.tpl b/mika/rizz/templates/_helpers.tpl
index aa05f820..52a0167f 100644
--- a/mika/rizz/templates/_helpers.tpl
+++ b/mika/rizz/templates/_helpers.tpl
@@ -60,985 +60,3 @@ Create the name of the service account to use
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
-
-{{/*
-Apache site-config.conf template
-*/}}
-{{- define "rizz.site-config-conf" -}}
-
- ServerName DOMAIN:443
- UseCanonicalName On
- ServerAdmin support@mikahomelab.com
- DocumentRoot /base
- WSGIScriptAlias / /base/base/wsgi.py
- WSGIDaemonProcess DOMAIN python-path=/base
- WSGIProcessGroup DOMAIN
-
-
-
- Require all granted
-
-
-
- Alias /static /static
-
- Require all granted
-
-
- ErrorLog /var/log/apache2/apache.error.log
- CustomLog /var/log/apache2/apache.access.log combined
-
-{{- end }}
-
-{{/*
-APScheduler /entrypoint.sh template
-*/}}
-{{- define "rizz.apscheduler-entrypoint-sh" -}}
-#!/bin/bash
-
-export APP_ROOT="base"
-
-# ================= DO NOT EDIT BEYOND THIS LINE =================
-
-python3 manage.py makemigrations
-
-python3 manage.py migrate
-
-tail -f /dev/null
-{{- end }}
-
-{{/*
-APScheduler /base/base/apps.py template
-*/}}
-{{- define "rizz.apscheduler-apps-py" -}}
-from django.apps import AppConfig
-
-class BaseConfig(AppConfig):
- name = "base"
-
- def ready(self):
- from . import signals
- from . import tasks
- tasks.start()
-{{- end }}
-
-{{/*
-APScheduler /base/base/tasks.py template
-*/}}
-{{- define "rizz.apscheduler-tasks-py" -}}
-from django.conf import settings
-from base.scheduler import post_scheduler
-from lib.rss import (
- clean_data,
- update_data,
-)
-from apscheduler.schedulers.blocking import BlockingScheduler
-
-
-SCHEDULER_TIMEZONE = getattr(settings, "SCHEDULER_TIMEZONE")
-
-
-def start():
- scheduler = BlockingScheduler(timezone=SCHEDULER_TIMEZONE)
-
- job_name = "clean_data"
- scheduler.add_job(clean_data, "cron", hour=CLEAN_DATA_HOURS, id=job_name, replace_existing=True)
-
- job_name = "update_data"
- scheduler.add_job(update_data, "cron", hour=UPDATE_DATA_HOURS, id=job_name, replace_existing=True)
-
- job_name = "post_scheduler"
- scheduler.add_job(post_scheduler, "cron", hour=POST_SCHEDULER_HOURS, id=job_name, replace_existing=True)
-
- scheduler.start()
-{{- end }}
-
-{{/*
-Celery /etc/default/celeryd template
-*/}}
-{{- define "rizz.default-celeryd" -}}
-# Names of nodes to start
-# most people will only start one node:
-#CELERYD_NODES="worker1"
-# but you can also start multiple and configure settings
-# for each in CELERYD_OPTS
-#CELERYD_NODES="worker1 worker2 worker3"
-# alternatively, you can specify the number of nodes to start:
-#CELERYD_NODES=10
-CELERYD_NODES="worker1"
-
-# Absolute or relative path to the 'celery' command:
-#CELERY_BIN="/usr/local/bin/celery"
-#CELERY_BIN="/virtualenvs/def/bin/celery"
-CELERY_BIN="/usr/local/bin/celery"
-
-# App instance to use
-# comment out this line if you don't use an app
-#CELERY_APP="proj"
-# or fully qualified:
-#CELERY_APP="proj.tasks:app"
-CELERY_APP="base"
-
-# Where to chdir at start.
-#CELERYD_CHDIR="/opt/Myproject/"
-CELERYD_CHDIR="/base/"
-
-# Extra command-line arguments to the worker
-#CELERYD_OPTS="--time-limit=300 --concurrency=8"
-# Configure node-specific settings by appending node name to arguments:
-#CELERYD_OPTS="--time-limit=300 -c 8 -c:worker2 4 -c:worker3 2 -Ofair:worker1"
-CELERYD_OPTS="--time-limit=300 --concurrency=8 --without-gossip --without-mingle --without-heartbeat -Ofair --pool=solo"
-
-# Set logging level
-#CELERYD_LOG_LEVEL="DEBUG"
-CELERYD_LOG_LEVEL="WARNING"
-
-# %n will be replaced with the first part of the nodename.
-#CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
-#CELERYD_PID_FILE="/var/run/celery/%n.pid"
-CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
-CELERYD_PID_FILE="/var/run/celery/%n.pid"
-
-# Workers should run as an unprivileged user.
-# You need to create this user manually (or you can choose
-# a user/group combination that already exists (e.g., nobody).
-#CELERYD_USER="celery"
-#CELERYD_GROUP="celery"
-CELERYD_USER="root"
-CELERYD_GROUP="root"
-
-# If enabled pid and log directories will be created if missing,
-# and owned by the userid/group configured.
-#CELERY_CREATE_DIRS=1
-CELERY_CREATE_DIRS=1
-{{- end }}
-
-{{/*
-Celery /etc/init.d/celerybeat template
-*/}}
-{{- define "rizz.initd-celerybeat" -}}
-#!/bin/sh -e
-# =========================================================
-# celerybeat - Starts the Celery periodic task scheduler.
-# =========================================================
-#
-# :Usage: /etc/init.d/celerybeat {start|stop|force-reload|restart|try-restart|status}
-# :Configuration file: /etc/default/celerybeat or /etc/default/celeryd
-#
-# See https://docs.celeryq.dev/en/latest/userguide/daemonizing.html#generic-init-scripts
-
-### BEGIN INIT INFO
-# Provides: celerybeat
-# Required-Start: $network $local_fs $remote_fs
-# Required-Stop: $network $local_fs $remote_fs
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: celery periodic task scheduler
-### END INIT INFO
-
-# Cannot use set -e/bash -e since the kill -0 command will abort
-# abnormally in the absence of a valid process ID.
-#set -e
-VERSION=10.1
-echo "celery init v${VERSION}."
-
-if [ $(id -u) -ne 0 ]; then
- echo "Error: This program can only be used by the root user."
- echo " Unprivileged users must use 'celery beat --detach'"
- exit 1
-fi
-
-origin_is_runlevel_dir () {
- set +e
- dirname $0 | grep -q "/etc/rc.\.d"
- echo $?
-}
-
-# Can be a runlevel symlink (e.g., S02celeryd)
-if [ $(origin_is_runlevel_dir) -eq 0 ]; then
- SCRIPT_FILE=$(readlink "$0")
-else
- SCRIPT_FILE="$0"
-fi
-SCRIPT_NAME="$(basename "$SCRIPT_FILE")"
-
-# /etc/init.d/celerybeat: start and stop the celery periodic task scheduler daemon.
-
-# Make sure executable configuration script is owned by root
-_config_sanity() {
- local path="$1"
- local owner=$(ls -ld "$path" | awk '{print $3}')
- local iwgrp=$(ls -ld "$path" | cut -b 6)
- local iwoth=$(ls -ld "$path" | cut -b 9)
-
- if [ "$(id -u $owner)" != "0" ]; then
- echo "Error: Config script '$path' must be owned by root!"
- echo
- echo "Resolution:"
- echo "Review the file carefully, and make sure it hasn't been "
- echo "modified with mailicious intent. When sure the "
- echo "script is safe to execute with superuser privileges "
- echo "you can change ownership of the script:"
- echo " $ sudo chown root '$path'"
- exit 1
- fi
-
- if [ "$iwoth" != "-" ]; then # S_IWOTH
- echo "Error: Config script '$path' cannot be writable by others!"
- echo
- echo "Resolution:"
- echo "Review the file carefully, and make sure it hasn't been "
- echo "modified with malicious intent. When sure the "
- echo "script is safe to execute with superuser privileges "
- echo "you can change the scripts permissions:"
- echo " $ sudo chmod 640 '$path'"
- exit 1
- fi
- if [ "$iwgrp" != "-" ]; then # S_IWGRP
- echo "Error: Config script '$path' cannot be writable by group!"
- echo
- echo "Resolution:"
- echo "Review the file carefully, and make sure it hasn't been "
- echo "modified with malicious intent. When sure the "
- echo "script is safe to execute with superuser privileges "
- echo "you can change the scripts permissions:"
- echo " $ sudo chmod 640 '$path'"
- exit 1
- fi
-}
-
-scripts=""
-
-if test -f /etc/default/celeryd; then
- scripts="/etc/default/celeryd"
- _config_sanity /etc/default/celeryd
- . /etc/default/celeryd
-fi
-
-EXTRA_CONFIG="/etc/default/${SCRIPT_NAME}"
-if test -f "$EXTRA_CONFIG"; then
- scripts="$scripts, $EXTRA_CONFIG"
- _config_sanity "$EXTRA_CONFIG"
- . "$EXTRA_CONFIG"
-fi
-
-echo "Using configuration: $scripts"
-
-CELERY_BIN=${CELERY_BIN:-"celery"}
-DEFAULT_USER="celery"
-DEFAULT_PID_FILE="/var/run/celery/beat.pid"
-DEFAULT_LOG_FILE="/var/log/celery/beat.log"
-DEFAULT_LOG_LEVEL="WARNING"
-DEFAULT_CELERYBEAT="$CELERY_BIN"
-
-CELERYBEAT=${CELERYBEAT:-$DEFAULT_CELERYBEAT}
-CELERYBEAT_LOG_LEVEL=${CELERYBEAT_LOG_LEVEL:-${CELERYBEAT_LOGLEVEL:-$DEFAULT_LOG_LEVEL}}
-
-CELERYBEAT_SU=${CELERYBEAT_SU:-"su"}
-CELERYBEAT_SU_ARGS=${CELERYBEAT_SU_ARGS:-""}
-
-# Sets --app argument for CELERY_BIN
-CELERY_APP_ARG=""
-if [ ! -z "$CELERY_APP" ]; then
- CELERY_APP_ARG="--app=$CELERY_APP"
-fi
-
-CELERYBEAT_USER=${CELERYBEAT_USER:-${CELERYD_USER:-$DEFAULT_USER}}
-
-# Set CELERY_CREATE_DIRS to always create log/pid dirs.
-CELERY_CREATE_DIRS=${CELERY_CREATE_DIRS:-0}
-CELERY_CREATE_RUNDIR=$CELERY_CREATE_DIRS
-CELERY_CREATE_LOGDIR=$CELERY_CREATE_DIRS
-if [ -z "$CELERYBEAT_PID_FILE" ]; then
- CELERYBEAT_PID_FILE="$DEFAULT_PID_FILE"
- CELERY_CREATE_RUNDIR=1
-fi
-if [ -z "$CELERYBEAT_LOG_FILE" ]; then
- CELERYBEAT_LOG_FILE="$DEFAULT_LOG_FILE"
- CELERY_CREATE_LOGDIR=1
-fi
-
-export CELERY_LOADER
-
-if [ -n "$2" ]; then
- CELERYBEAT_OPTS="$CELERYBEAT_OPTS $2"
-fi
-
-CELERYBEAT_LOG_DIR=`dirname $CELERYBEAT_LOG_FILE`
-CELERYBEAT_PID_DIR=`dirname $CELERYBEAT_PID_FILE`
-
-# Extra start-stop-daemon options, like user/group.
-
-CELERYBEAT_CHDIR=${CELERYBEAT_CHDIR:-$CELERYD_CHDIR}
-if [ -n "$CELERYBEAT_CHDIR" ]; then
- DAEMON_OPTS="$DAEMON_OPTS --workdir=$CELERYBEAT_CHDIR"
-fi
-
-
-export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
-
-check_dev_null() {
- if [ ! -c /dev/null ]; then
- echo "/dev/null is not a character device!"
- exit 75 # EX_TEMPFAIL
- fi
-}
-
-maybe_die() {
- if [ $? -ne 0 ]; then
- echo "Exiting: $*"
- exit 77 # EX_NOPERM
- fi
-}
-
-create_default_dir() {
- if [ ! -d "$1" ]; then
- echo "- Creating default directory: '$1'"
- mkdir -p "$1"
- maybe_die "Couldn't create directory $1"
- echo "- Changing permissions of '$1' to 02755"
- chmod 02755 "$1"
- maybe_die "Couldn't change permissions for $1"
- if [ -n "$CELERYBEAT_USER" ]; then
- echo "- Changing owner of '$1' to '$CELERYBEAT_USER'"
- chown "$CELERYBEAT_USER" "$1"
- maybe_die "Couldn't change owner of $1"
- fi
- if [ -n "$CELERYBEAT_GROUP" ]; then
- echo "- Changing group of '$1' to '$CELERYBEAT_GROUP'"
- chgrp "$CELERYBEAT_GROUP" "$1"
- maybe_die "Couldn't change group of $1"
- fi
- fi
-}
-
-check_paths() {
- if [ $CELERY_CREATE_LOGDIR -eq 1 ]; then
- create_default_dir "$CELERYBEAT_LOG_DIR"
- fi
- if [ $CELERY_CREATE_RUNDIR -eq 1 ]; then
- create_default_dir "$CELERYBEAT_PID_DIR"
- fi
-}
-
-
-create_paths () {
- create_default_dir "$CELERYBEAT_LOG_DIR"
- create_default_dir "$CELERYBEAT_PID_DIR"
-}
-
-is_running() {
- pid=$1
- ps $pid > /dev/null 2>&1
-}
-
-wait_pid () {
- pid=$1
- forever=1
- i=0
- while [ $forever -gt 0 ]; do
- if ! is_running $pid; then
- echo "OK"
- forever=0
- else
- kill -TERM "$pid"
- i=$((i + 1))
- if [ $i -gt 60 ]; then
- echo "ERROR"
- echo "Timed out while stopping (30s)"
- forever=0
- else
- sleep 0.5
- fi
- fi
- done
-}
-
-
-stop_beat () {
- echo -n "Stopping ${SCRIPT_NAME}... "
- if [ -f "$CELERYBEAT_PID_FILE" ]; then
- wait_pid $(cat "$CELERYBEAT_PID_FILE")
- else
- echo "NOT RUNNING"
- fi
-}
-
-_chuid () {
- ${CELERYBEAT_SU} ${CELERYBEAT_SU_ARGS} \
- "$CELERYBEAT_USER" -c "$CELERYBEAT $*"
-}
-
-start_beat () {
- echo "Starting ${SCRIPT_NAME}..."
- _chuid $CELERY_APP_ARG $DAEMON_OPTS beat --detach \
- --pidfile="$CELERYBEAT_PID_FILE" \
- --logfile="$CELERYBEAT_LOG_FILE" \
- --loglevel="$CELERYBEAT_LOG_LEVEL" \
- $CELERYBEAT_OPTS
-}
-
-
-check_status () {
- local failed=
- local pid_file=$CELERYBEAT_PID_FILE
- if [ ! -e $pid_file ]; then
- echo "${SCRIPT_NAME} is down: no pid file found"
- failed=true
- elif [ ! -r $pid_file ]; then
- echo "${SCRIPT_NAME} is in unknown state, user cannot read pid file."
- failed=true
- else
- local pid=`cat "$pid_file"`
- local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
- if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
- echo "${SCRIPT_NAME}: bad pid file ($pid_file)"
- failed=true
- else
- local failed=
- kill -0 $pid 2> /dev/null || failed=true
- if [ "$failed" ]; then
- echo "${SCRIPT_NAME} (pid $pid) is down, but pid file exists!"
- failed=true
- else
- echo "${SCRIPT_NAME} (pid $pid) is up..."
- fi
- fi
- fi
-
- [ "$failed" ] && exit 1 || exit 0
-}
-
-
-case "$1" in
- start)
- check_dev_null
- check_paths
- start_beat
- ;;
- stop)
- check_paths
- stop_beat
- ;;
- reload|force-reload)
- echo "Use start+stop"
- ;;
- status)
- check_status
- ;;
- restart)
- echo "Restarting celery periodic task scheduler"
- check_paths
- stop_beat && check_dev_null && start_beat
- ;;
- create-paths)
- check_dev_null
- create_paths
- ;;
- check-paths)
- check_dev_null
- check_paths
- ;;
- *)
- echo "Usage: /etc/init.d/${SCRIPT_NAME} {start|stop|restart|create-paths|status}"
- exit 64 # EX_USAGE
- ;;
-esac
-
-exit 0
-{{- end }}
-
-{{/*
-Celery /etc/init.d/celeryd template
-*/}}
-{{- define "rizz.initd-celeryd" -}}
-#!/bin/sh -e
-# ============================================
-# celeryd - Starts the Celery worker daemon.
-# ============================================
-#
-# :Usage: /etc/init.d/celeryd {start|stop|force-reload|restart|try-restart|status}
-# :Configuration file: /etc/default/celeryd (or /usr/local/etc/celeryd on BSD)
-#
-# See https://docs.celeryq.dev/en/latest/userguide/daemonizing.html#generic-init-scripts
-
-
-### BEGIN INIT INFO
-# Provides: celeryd
-# Required-Start: $network $local_fs $remote_fs
-# Required-Stop: $network $local_fs $remote_fs
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: celery task worker daemon
-### END INIT INFO
-#
-#
-# To implement separate init-scripts, copy this script and give it a different
-# name. That is, if your new application named "little-worker" needs an init,
-# you should use:
-#
-# cp /etc/init.d/celeryd /etc/init.d/little-worker
-#
-# You can then configure this by manipulating /etc/default/little-worker.
-#
-VERSION=10.1
-echo "celery init v${VERSION}."
-if [ $(id -u) -ne 0 ]; then
- echo "Error: This program can only be used by the root user."
- echo " Unprivileged users must use the 'celery multi' utility, "
- echo " or 'celery worker --detach'."
- exit 1
-fi
-
-origin_is_runlevel_dir () {
- set +e
- dirname $0 | grep -q "/etc/rc.\.d"
- echo $?
-}
-
-# Can be a runlevel symlink (e.g., S02celeryd)
-if [ $(origin_is_runlevel_dir) -eq 0 ]; then
- SCRIPT_FILE=$(readlink "$0")
-else
- SCRIPT_FILE="$0"
-fi
-SCRIPT_NAME="$(basename "$SCRIPT_FILE")"
-
-DEFAULT_USER="celery"
-DEFAULT_PID_FILE="/var/run/celery/%n.pid"
-DEFAULT_LOG_FILE="/var/log/celery/%n%I.log"
-DEFAULT_LOG_LEVEL="WARNING"
-DEFAULT_NODES="celery"
-DEFAULT_CELERYD="-m celery worker --detach"
-
-if [ -d "/etc/default" ]; then
- CELERY_CONFIG_DIR="/etc/default"
-else
- CELERY_CONFIG_DIR="/usr/local/etc"
-fi
-
-CELERY_DEFAULTS=${CELERY_DEFAULTS:-"$CELERY_CONFIG_DIR/${SCRIPT_NAME}"}
-
-# Make sure executable configuration script is owned by root
-_config_sanity() {
- local path="$1"
- local owner=$(ls -ld "$path" | awk '{print $3}')
- local iwgrp=$(ls -ld "$path" | cut -b 6)
- local iwoth=$(ls -ld "$path" | cut -b 9)
-
- if [ "$(id -u $owner)" != "0" ]; then
- echo "Error: Config script '$path' must be owned by root!"
- echo
- echo "Resolution:"
- echo "Review the file carefully, and make sure it hasn't been "
- echo "modified with mailicious intent. When sure the "
- echo "script is safe to execute with superuser privileges "
- echo "you can change ownership of the script:"
- echo " $ sudo chown root '$path'"
- exit 1
- fi
-
- if [ "$iwoth" != "-" ]; then # S_IWOTH
- echo "Error: Config script '$path' cannot be writable by others!"
- echo
- echo "Resolution:"
- echo "Review the file carefully, and make sure it hasn't been "
- echo "modified with malicious intent. When sure the "
- echo "script is safe to execute with superuser privileges "
- echo "you can change the scripts permissions:"
- echo " $ sudo chmod 640 '$path'"
- exit 1
- fi
- if [ "$iwgrp" != "-" ]; then # S_IWGRP
- echo "Error: Config script '$path' cannot be writable by group!"
- echo
- echo "Resolution:"
- echo "Review the file carefully, and make sure it hasn't been "
- echo "modified with malicious intent. When sure the "
- echo "script is safe to execute with superuser privileges "
- echo "you can change the scripts permissions:"
- echo " $ sudo chmod 640 '$path'"
- exit 1
- fi
-}
-
-if [ -f "$CELERY_DEFAULTS" ]; then
- _config_sanity "$CELERY_DEFAULTS"
- echo "Using config script: $CELERY_DEFAULTS"
- . "$CELERY_DEFAULTS"
-fi
-
-# Sets --app argument for CELERY_BIN
-CELERY_APP_ARG=""
-if [ ! -z "$CELERY_APP" ]; then
- CELERY_APP_ARG="--app=$CELERY_APP"
-fi
-
-# Options to su
-# can be used to enable login shell (CELERYD_SU_ARGS="-l"),
-# or even to use start-stop-daemon instead of su.
-CELERYD_SU=${CELERY_SU:-"su"}
-CELERYD_SU_ARGS=${CELERYD_SU_ARGS:-""}
-
-CELERYD_USER=${CELERYD_USER:-$DEFAULT_USER}
-
-# Set CELERY_CREATE_DIRS to always create log/pid dirs.
-CELERY_CREATE_DIRS=${CELERY_CREATE_DIRS:-0}
-CELERY_CREATE_RUNDIR=$CELERY_CREATE_DIRS
-CELERY_CREATE_LOGDIR=$CELERY_CREATE_DIRS
-if [ -z "$CELERYD_PID_FILE" ]; then
- CELERYD_PID_FILE="$DEFAULT_PID_FILE"
- CELERY_CREATE_RUNDIR=1
-fi
-if [ -z "$CELERYD_LOG_FILE" ]; then
- CELERYD_LOG_FILE="$DEFAULT_LOG_FILE"
- CELERY_CREATE_LOGDIR=1
-fi
-
-CELERYD_LOG_LEVEL=${CELERYD_LOG_LEVEL:-${CELERYD_LOGLEVEL:-$DEFAULT_LOG_LEVEL}}
-CELERY_BIN=${CELERY_BIN:-"celery"}
-CELERYD_MULTI=${CELERYD_MULTI:-"$CELERY_BIN multi"}
-CELERYD_NODES=${CELERYD_NODES:-$DEFAULT_NODES}
-
-export CELERY_LOADER
-
-if [ -n "$2" ]; then
- CELERYD_OPTS="$CELERYD_OPTS $2"
-fi
-
-CELERYD_LOG_DIR=`dirname $CELERYD_LOG_FILE`
-CELERYD_PID_DIR=`dirname $CELERYD_PID_FILE`
-
-# Extra start-stop-daemon options, like user/group.
-if [ -n "$CELERYD_CHDIR" ]; then
- DAEMON_OPTS="$DAEMON_OPTS --workdir=$CELERYD_CHDIR"
-fi
-
-
-check_dev_null() {
- if [ ! -c /dev/null ]; then
- echo "/dev/null is not a character device!"
- exit 75 # EX_TEMPFAIL
- fi
-}
-
-
-maybe_die() {
- if [ $? -ne 0 ]; then
- echo "Exiting: $* (errno $?)"
- exit 77 # EX_NOPERM
- fi
-}
-
-create_default_dir() {
- if [ ! -d "$1" ]; then
- echo "- Creating default directory: '$1'"
- mkdir -p "$1"
- maybe_die "Couldn't create directory $1"
- echo "- Changing permissions of '$1' to 02755"
- chmod 02755 "$1"
- maybe_die "Couldn't change permissions for $1"
- if [ -n "$CELERYD_USER" ]; then
- echo "- Changing owner of '$1' to '$CELERYD_USER'"
- chown "$CELERYD_USER" "$1"
- maybe_die "Couldn't change owner of $1"
- fi
- if [ -n "$CELERYD_GROUP" ]; then
- echo "- Changing group of '$1' to '$CELERYD_GROUP'"
- chgrp "$CELERYD_GROUP" "$1"
- maybe_die "Couldn't change group of $1"
- fi
- fi
-}
-
-
-check_paths() {
- if [ $CELERY_CREATE_LOGDIR -eq 1 ]; then
- create_default_dir "$CELERYD_LOG_DIR"
- fi
- if [ $CELERY_CREATE_RUNDIR -eq 1 ]; then
- create_default_dir "$CELERYD_PID_DIR"
- fi
-}
-
-create_paths() {
- create_default_dir "$CELERYD_LOG_DIR"
- create_default_dir "$CELERYD_PID_DIR"
-}
-
-export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
-
-
-_get_pidfiles () {
- # note: multi < 3.1.14 output to stderr, not stdout, hence the redirect.
- ${CELERYD_MULTI} expand "${CELERYD_PID_FILE}" ${CELERYD_NODES} 2>&1
-}
-
-
-_get_pids() {
- found_pids=0
- my_exitcode=0
-
- for pidfile in $(_get_pidfiles); do
- local pid=`cat "$pidfile"`
- local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
- if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
- echo "bad pid file ($pidfile)"
- one_failed=true
- my_exitcode=1
- else
- found_pids=1
- echo "$pid"
- fi
-
- if [ $found_pids -eq 0 ]; then
- echo "${SCRIPT_NAME}: All nodes down"
- exit $my_exitcode
- fi
- done
-}
-
-
-_chuid () {
- ${CELERYD_SU} ${CELERYD_SU_ARGS} "$CELERYD_USER" -c "$CELERYD_MULTI $*"
-}
-
-
-start_workers () {
- if [ ! -z "$CELERYD_ULIMIT" ]; then
- ulimit $CELERYD_ULIMIT
- fi
- _chuid $* start $CELERYD_NODES $DAEMON_OPTS \
- --pidfile="$CELERYD_PID_FILE" \
- --logfile="$CELERYD_LOG_FILE" \
- --loglevel="$CELERYD_LOG_LEVEL" \
- $CELERY_APP_ARG \
- $CELERYD_OPTS
-}
-
-
-dryrun () {
- (C_FAKEFORK=1 start_workers --verbose)
-}
-
-
-stop_workers () {
- _chuid stopwait $CELERYD_NODES $DAEMON_OPTS --pidfile="$CELERYD_PID_FILE"
-}
-
-
-restart_workers () {
- _chuid restart $CELERYD_NODES $DAEMON_OPTS \
- --pidfile="$CELERYD_PID_FILE" \
- --logfile="$CELERYD_LOG_FILE" \
- --loglevel="$CELERYD_LOG_LEVEL" \
- $CELERY_APP_ARG \
- $CELERYD_OPTS
-}
-
-
-kill_workers() {
- _chuid kill $CELERYD_NODES $DAEMON_OPTS --pidfile="$CELERYD_PID_FILE"
-}
-
-
-restart_workers_graceful () {
- echo "WARNING: Use with caution in production"
- echo "The workers will attempt to restart, but they may not be able to."
- local worker_pids=
- worker_pids=`_get_pids`
- [ "$one_failed" ] && exit 1
-
- for worker_pid in $worker_pids; do
- local failed=
- kill -HUP $worker_pid 2> /dev/null || failed=true
- if [ "$failed" ]; then
- echo "${SCRIPT_NAME} worker (pid $worker_pid) could not be restarted"
- one_failed=true
- else
- echo "${SCRIPT_NAME} worker (pid $worker_pid) received SIGHUP"
- fi
- done
-
- [ "$one_failed" ] && exit 1 || exit 0
-}
-
-
-check_status () {
- my_exitcode=0
- found_pids=0
-
- local one_failed=
- for pidfile in $(_get_pidfiles); do
- if [ ! -r $pidfile ]; then
- echo "${SCRIPT_NAME} down: no pidfiles found"
- one_failed=true
- break
- fi
-
- local node=`basename "$pidfile" .pid`
- local pid=`cat "$pidfile"`
- local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
- if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
- echo "bad pid file ($pidfile)"
- one_failed=true
- else
- local failed=
- kill -0 $pid 2> /dev/null || failed=true
- if [ "$failed" ]; then
- echo "${SCRIPT_NAME} (node $node) (pid $pid) is down, but pidfile exists!"
- one_failed=true
- else
- echo "${SCRIPT_NAME} (node $node) (pid $pid) is up..."
- fi
- fi
- done
-
- [ "$one_failed" ] && exit 1 || exit 0
-}
-
-
-case "$1" in
- start)
- check_dev_null
- check_paths
- start_workers
- ;;
-
- stop)
- check_dev_null
- check_paths
- stop_workers
- ;;
-
- reload|force-reload)
- echo "Use restart"
- ;;
-
- status)
- check_status
- ;;
-
- restart)
- check_dev_null
- check_paths
- restart_workers
- ;;
-
- graceful)
- check_dev_null
- restart_workers_graceful
- ;;
-
- kill)
- check_dev_null
- kill_workers
- ;;
-
- dryrun)
- check_dev_null
- dryrun
- ;;
-
- try-restart)
- check_dev_null
- check_paths
- restart_workers
- ;;
-
- create-paths)
- check_dev_null
- create_paths
- ;;
-
- check-paths)
- check_dev_null
- check_paths
- ;;
-
- *)
- echo "Usage: /etc/init.d/${SCRIPT_NAME} {start|stop|restart|graceful|kill|dryrun|create-paths}"
- exit 64 # EX_USAGE
- ;;
-esac
-
-exit 0
-{{- end }}
-
-{{/*
-Celery /base/base/celery.py template
-*/}}
-{{- define "rizz.celery-py" -}}
-from __future__ import absolute_import, unicode_literals
-import os
-from celery import Celery
-from celery.schedules import crontab
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "base.settings")
-app = Celery("base")
-app.config_from_object("django.conf:settings", namespace="CELERY")
-app.autodiscover_tasks()
-
-
-app.conf.beat_schedule = {
- # clean data
- "clean_data" : {
- "task" : "base.tasks.clean_data_task",
- "schedule" : crontab(hour=CLEAN_DATA_HOURS, minute="0"),
- },
- # update data
- "update_data" : {
- "task" : "base.tasks.update_data_task",
- "schedule" : crontab(hour=UPDATE_DATA_HOURS, minute="0"),
- },
- # check for any posts that need to be posted
- "post_scheduler" : {
- "task" : "base.tasks.post_scheduler_task",
- "schedule" : crontab(hour=POST_SCHEDULER_HOURS, minute="0"),
- },
-}
-
-
-@app.task(bind=True)
-def debug_task(self):
- print("Request: {0!r}".format(self.request))
-{{- end }}
-
-{{/*
-Celery /base/base/__init__.py template
-*/}}
-{{- define "rizz.celery-init-py" -}}
-from .celery import app as celery_app
-
-__all__ = ("celery_app",)
-{{- end }}
-
-{{/*
-Celery /base/base/tasks.py template
-*/}}
-{{- define "rizz.celery-tasks-py" -}}
-from __future__ import absolute_import, unicode_literals
-from celery import shared_task
-from base.scheduler import post_scheduler
-from lib.rss import (
- clean_data,
- update_data,
-)
-
-
-# clean data
-@shared_task
-def clean_data_task():
- clean_data()
-
-
-# update data
-@shared_task
-def update_data_task():
- update_data()
-
-
-# check for any posts that need to be posted
-@shared_task
-def post_scheduler_task():
- post_scheduler()
-{{- end }}
diff --git a/mika/rizz/templates/apps.py.tpl b/mika/rizz/templates/apps.py.tpl
new file mode 100644
index 00000000..6af98d79
--- /dev/null
+++ b/mika/rizz/templates/apps.py.tpl
@@ -0,0 +1,14 @@
+{{/*
+APScheduler /base/base/apps.py template
+*/}}
+{{- define "rizz.apscheduler-apps-py" -}}
+from django.apps import AppConfig
+
+class BaseConfig(AppConfig):
+ name = "base"
+
+ def ready(self):
+ from . import signals
+ from . import tasks
+ tasks.start()
+{{- end }}
diff --git a/mika/rizz/templates/celery.py.tpl b/mika/rizz/templates/celery.py.tpl
new file mode 100644
index 00000000..503f578f
--- /dev/null
+++ b/mika/rizz/templates/celery.py.tpl
@@ -0,0 +1,37 @@
+{{/*
+Celery /base/base/celery.py template
+*/}}
+{{- define "rizz.celery-py" -}}
+from __future__ import absolute_import, unicode_literals
+import os
+from celery import Celery
+from celery.schedules import crontab
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "base.settings")
+app = Celery("base")
+app.config_from_object("django.conf:settings", namespace="CELERY")
+app.autodiscover_tasks()
+
+
+app.conf.beat_schedule = {
+ # clean data
+ "clean_data" : {
+ "task" : "base.tasks.clean_data_task",
+ "schedule" : crontab(hour=CLEAN_DATA_HOURS, minute="0"),
+ },
+ # update data
+ "update_data" : {
+ "task" : "base.tasks.update_data_task",
+ "schedule" : crontab(hour=UPDATE_DATA_HOURS, minute="0"),
+ },
+ # check for any posts that need to be posted
+ "post_scheduler" : {
+ "task" : "base.tasks.post_scheduler_task",
+ "schedule" : crontab(hour=POST_SCHEDULER_HOURS, minute="0"),
+ },
+}
+
+
+@app.task(bind=True)
+def debug_task(self):
+ print("Request: {0!r}".format(self.request))
+{{- end }}
diff --git a/mika/rizz/templates/celerybeat.tpl b/mika/rizz/templates/celerybeat.tpl
new file mode 100644
index 00000000..e5316778
--- /dev/null
+++ b/mika/rizz/templates/celerybeat.tpl
@@ -0,0 +1,334 @@
+{{/*
+Celery /etc/init.d/celerybeat template
+*/}}
+{{- define "rizz.initd-celerybeat" -}}
+#!/bin/sh -e
+# =========================================================
+# celerybeat - Starts the Celery periodic task scheduler.
+# =========================================================
+#
+# :Usage: /etc/init.d/celerybeat {start|stop|force-reload|restart|try-restart|status}
+# :Configuration file: /etc/default/celerybeat or /etc/default/celeryd
+#
+# See https://docs.celeryq.dev/en/latest/userguide/daemonizing.html#generic-init-scripts
+
+### BEGIN INIT INFO
+# Provides: celerybeat
+# Required-Start: $network $local_fs $remote_fs
+# Required-Stop: $network $local_fs $remote_fs
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: celery periodic task scheduler
+### END INIT INFO
+
+# Cannot use set -e/bash -e since the kill -0 command will abort
+# abnormally in the absence of a valid process ID.
+#set -e
+VERSION=10.1
+echo "celery init v${VERSION}."
+
+if [ $(id -u) -ne 0 ]; then
+ echo "Error: This program can only be used by the root user."
+ echo " Unprivileged users must use 'celery beat --detach'"
+ exit 1
+fi
+
+origin_is_runlevel_dir () {
+ set +e
+ dirname $0 | grep -q "/etc/rc.\.d"
+ echo $?
+}
+
+# Can be a runlevel symlink (e.g., S02celeryd)
+if [ $(origin_is_runlevel_dir) -eq 0 ]; then
+ SCRIPT_FILE=$(readlink "$0")
+else
+ SCRIPT_FILE="$0"
+fi
+SCRIPT_NAME="$(basename "$SCRIPT_FILE")"
+
+# /etc/init.d/celerybeat: start and stop the celery periodic task scheduler daemon.
+
+# Make sure executable configuration script is owned by root
+_config_sanity() {
+ local path="$1"
+ local owner=$(ls -ld "$path" | awk '{print $3}')
+ local iwgrp=$(ls -ld "$path" | cut -b 6)
+ local iwoth=$(ls -ld "$path" | cut -b 9)
+
+ if [ "$(id -u $owner)" != "0" ]; then
+ echo "Error: Config script '$path' must be owned by root!"
+ echo
+ echo "Resolution:"
+ echo "Review the file carefully, and make sure it hasn't been "
+ echo "modified with mailicious intent. When sure the "
+ echo "script is safe to execute with superuser privileges "
+ echo "you can change ownership of the script:"
+ echo " $ sudo chown root '$path'"
+ exit 1
+ fi
+
+ if [ "$iwoth" != "-" ]; then # S_IWOTH
+ echo "Error: Config script '$path' cannot be writable by others!"
+ echo
+ echo "Resolution:"
+ echo "Review the file carefully, and make sure it hasn't been "
+ echo "modified with malicious intent. When sure the "
+ echo "script is safe to execute with superuser privileges "
+ echo "you can change the scripts permissions:"
+ echo " $ sudo chmod 640 '$path'"
+ exit 1
+ fi
+ if [ "$iwgrp" != "-" ]; then # S_IWGRP
+ echo "Error: Config script '$path' cannot be writable by group!"
+ echo
+ echo "Resolution:"
+ echo "Review the file carefully, and make sure it hasn't been "
+ echo "modified with malicious intent. When sure the "
+ echo "script is safe to execute with superuser privileges "
+ echo "you can change the scripts permissions:"
+ echo " $ sudo chmod 640 '$path'"
+ exit 1
+ fi
+}
+
+scripts=""
+
+if test -f /etc/default/celeryd; then
+ scripts="/etc/default/celeryd"
+ _config_sanity /etc/default/celeryd
+ . /etc/default/celeryd
+fi
+
+EXTRA_CONFIG="/etc/default/${SCRIPT_NAME}"
+if test -f "$EXTRA_CONFIG"; then
+ scripts="$scripts, $EXTRA_CONFIG"
+ _config_sanity "$EXTRA_CONFIG"
+ . "$EXTRA_CONFIG"
+fi
+
+echo "Using configuration: $scripts"
+
+CELERY_BIN=${CELERY_BIN:-"celery"}
+DEFAULT_USER="celery"
+DEFAULT_PID_FILE="/var/run/celery/beat.pid"
+DEFAULT_LOG_FILE="/var/log/celery/beat.log"
+DEFAULT_LOG_LEVEL="WARNING"
+DEFAULT_CELERYBEAT="$CELERY_BIN"
+
+CELERYBEAT=${CELERYBEAT:-$DEFAULT_CELERYBEAT}
+CELERYBEAT_LOG_LEVEL=${CELERYBEAT_LOG_LEVEL:-${CELERYBEAT_LOGLEVEL:-$DEFAULT_LOG_LEVEL}}
+
+CELERYBEAT_SU=${CELERYBEAT_SU:-"su"}
+CELERYBEAT_SU_ARGS=${CELERYBEAT_SU_ARGS:-""}
+
+# Sets --app argument for CELERY_BIN
+CELERY_APP_ARG=""
+if [ ! -z "$CELERY_APP" ]; then
+ CELERY_APP_ARG="--app=$CELERY_APP"
+fi
+
+CELERYBEAT_USER=${CELERYBEAT_USER:-${CELERYD_USER:-$DEFAULT_USER}}
+
+# Set CELERY_CREATE_DIRS to always create log/pid dirs.
+CELERY_CREATE_DIRS=${CELERY_CREATE_DIRS:-0}
+CELERY_CREATE_RUNDIR=$CELERY_CREATE_DIRS
+CELERY_CREATE_LOGDIR=$CELERY_CREATE_DIRS
+if [ -z "$CELERYBEAT_PID_FILE" ]; then
+ CELERYBEAT_PID_FILE="$DEFAULT_PID_FILE"
+ CELERY_CREATE_RUNDIR=1
+fi
+if [ -z "$CELERYBEAT_LOG_FILE" ]; then
+ CELERYBEAT_LOG_FILE="$DEFAULT_LOG_FILE"
+ CELERY_CREATE_LOGDIR=1
+fi
+
+export CELERY_LOADER
+
+if [ -n "$2" ]; then
+ CELERYBEAT_OPTS="$CELERYBEAT_OPTS $2"
+fi
+
+CELERYBEAT_LOG_DIR=`dirname $CELERYBEAT_LOG_FILE`
+CELERYBEAT_PID_DIR=`dirname $CELERYBEAT_PID_FILE`
+
+# Extra start-stop-daemon options, like user/group.
+
+CELERYBEAT_CHDIR=${CELERYBEAT_CHDIR:-$CELERYD_CHDIR}
+if [ -n "$CELERYBEAT_CHDIR" ]; then
+ DAEMON_OPTS="$DAEMON_OPTS --workdir=$CELERYBEAT_CHDIR"
+fi
+
+
+export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
+
+check_dev_null() {
+ if [ ! -c /dev/null ]; then
+ echo "/dev/null is not a character device!"
+ exit 75 # EX_TEMPFAIL
+ fi
+}
+
+maybe_die() {
+ if [ $? -ne 0 ]; then
+ echo "Exiting: $*"
+ exit 77 # EX_NOPERM
+ fi
+}
+
+create_default_dir() {
+ if [ ! -d "$1" ]; then
+ echo "- Creating default directory: '$1'"
+ mkdir -p "$1"
+ maybe_die "Couldn't create directory $1"
+ echo "- Changing permissions of '$1' to 02755"
+ chmod 02755 "$1"
+ maybe_die "Couldn't change permissions for $1"
+ if [ -n "$CELERYBEAT_USER" ]; then
+ echo "- Changing owner of '$1' to '$CELERYBEAT_USER'"
+ chown "$CELERYBEAT_USER" "$1"
+ maybe_die "Couldn't change owner of $1"
+ fi
+ if [ -n "$CELERYBEAT_GROUP" ]; then
+ echo "- Changing group of '$1' to '$CELERYBEAT_GROUP'"
+ chgrp "$CELERYBEAT_GROUP" "$1"
+ maybe_die "Couldn't change group of $1"
+ fi
+ fi
+}
+
+check_paths() {
+ if [ $CELERY_CREATE_LOGDIR -eq 1 ]; then
+ create_default_dir "$CELERYBEAT_LOG_DIR"
+ fi
+ if [ $CELERY_CREATE_RUNDIR -eq 1 ]; then
+ create_default_dir "$CELERYBEAT_PID_DIR"
+ fi
+}
+
+
+create_paths () {
+ create_default_dir "$CELERYBEAT_LOG_DIR"
+ create_default_dir "$CELERYBEAT_PID_DIR"
+}
+
+is_running() {
+ pid=$1
+ ps $pid > /dev/null 2>&1
+}
+
+wait_pid () {
+ pid=$1
+ forever=1
+ i=0
+ while [ $forever -gt 0 ]; do
+ if ! is_running $pid; then
+ echo "OK"
+ forever=0
+ else
+ kill -TERM "$pid"
+ i=$((i + 1))
+ if [ $i -gt 60 ]; then
+ echo "ERROR"
+ echo "Timed out while stopping (30s)"
+ forever=0
+ else
+ sleep 0.5
+ fi
+ fi
+ done
+}
+
+
+stop_beat () {
+ echo -n "Stopping ${SCRIPT_NAME}... "
+ if [ -f "$CELERYBEAT_PID_FILE" ]; then
+ wait_pid $(cat "$CELERYBEAT_PID_FILE")
+ else
+ echo "NOT RUNNING"
+ fi
+}
+
+_chuid () {
+ ${CELERYBEAT_SU} ${CELERYBEAT_SU_ARGS} \
+ "$CELERYBEAT_USER" -c "$CELERYBEAT $*"
+}
+
+start_beat () {
+ echo "Starting ${SCRIPT_NAME}..."
+ _chuid $CELERY_APP_ARG $DAEMON_OPTS beat --detach \
+ --pidfile="$CELERYBEAT_PID_FILE" \
+ --logfile="$CELERYBEAT_LOG_FILE" \
+ --loglevel="$CELERYBEAT_LOG_LEVEL" \
+ $CELERYBEAT_OPTS
+}
+
+
+check_status () {
+ local failed=
+ local pid_file=$CELERYBEAT_PID_FILE
+ if [ ! -e $pid_file ]; then
+ echo "${SCRIPT_NAME} is down: no pid file found"
+ failed=true
+ elif [ ! -r $pid_file ]; then
+ echo "${SCRIPT_NAME} is in unknown state, user cannot read pid file."
+ failed=true
+ else
+ local pid=`cat "$pid_file"`
+ local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
+ if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
+ echo "${SCRIPT_NAME}: bad pid file ($pid_file)"
+ failed=true
+ else
+ local failed=
+ kill -0 $pid 2> /dev/null || failed=true
+ if [ "$failed" ]; then
+ echo "${SCRIPT_NAME} (pid $pid) is down, but pid file exists!"
+ failed=true
+ else
+ echo "${SCRIPT_NAME} (pid $pid) is up..."
+ fi
+ fi
+ fi
+
+ [ "$failed" ] && exit 1 || exit 0
+}
+
+
+case "$1" in
+ start)
+ check_dev_null
+ check_paths
+ start_beat
+ ;;
+ stop)
+ check_paths
+ stop_beat
+ ;;
+ reload|force-reload)
+ echo "Use start+stop"
+ ;;
+ status)
+ check_status
+ ;;
+ restart)
+ echo "Restarting celery periodic task scheduler"
+ check_paths
+ stop_beat && check_dev_null && start_beat
+ ;;
+ create-paths)
+ check_dev_null
+ create_paths
+ ;;
+ check-paths)
+ check_dev_null
+ check_paths
+ ;;
+ *)
+ echo "Usage: /etc/init.d/${SCRIPT_NAME} {start|stop|restart|create-paths|status}"
+ exit 64 # EX_USAGE
+ ;;
+esac
+
+exit 0
+{{- end }}
diff --git a/mika/rizz/templates/celeryd.tpl b/mika/rizz/templates/celeryd.tpl
new file mode 100644
index 00000000..bfc81256
--- /dev/null
+++ b/mika/rizz/templates/celeryd.tpl
@@ -0,0 +1,476 @@
+{{/*
+Celery /etc/default/celeryd template
+*/}}
+{{- define "rizz.default-celeryd" -}}
+# Names of nodes to start
+# most people will only start one node:
+#CELERYD_NODES="worker1"
+# but you can also start multiple and configure settings
+# for each in CELERYD_OPTS
+#CELERYD_NODES="worker1 worker2 worker3"
+# alternatively, you can specify the number of nodes to start:
+#CELERYD_NODES=10
+CELERYD_NODES="worker1"
+
+# Absolute or relative path to the 'celery' command:
+#CELERY_BIN="/usr/local/bin/celery"
+#CELERY_BIN="/virtualenvs/def/bin/celery"
+CELERY_BIN="/usr/local/bin/celery"
+
+# App instance to use
+# comment out this line if you don't use an app
+#CELERY_APP="proj"
+# or fully qualified:
+#CELERY_APP="proj.tasks:app"
+CELERY_APP="base"
+
+# Where to chdir at start.
+#CELERYD_CHDIR="/opt/Myproject/"
+CELERYD_CHDIR="/base/"
+
+# Extra command-line arguments to the worker
+#CELERYD_OPTS="--time-limit=300 --concurrency=8"
+# Configure node-specific settings by appending node name to arguments:
+#CELERYD_OPTS="--time-limit=300 -c 8 -c:worker2 4 -c:worker3 2 -Ofair:worker1"
+CELERYD_OPTS="--time-limit=300 --concurrency=8 --without-gossip --without-mingle --without-heartbeat -Ofair --pool=solo"
+
+# Set logging level
+#CELERYD_LOG_LEVEL="DEBUG"
+CELERYD_LOG_LEVEL="WARNING"
+
+# %n will be replaced with the first part of the nodename.
+#CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
+#CELERYD_PID_FILE="/var/run/celery/%n.pid"
+CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
+CELERYD_PID_FILE="/var/run/celery/%n.pid"
+
+# Workers should run as an unprivileged user.
+# You need to create this user manually (or you can choose
+# a user/group combination that already exists (e.g., nobody).
+#CELERYD_USER="celery"
+#CELERYD_GROUP="celery"
+CELERYD_USER="root"
+CELERYD_GROUP="root"
+
+# If enabled pid and log directories will be created if missing,
+# and owned by the userid/group configured.
+#CELERY_CREATE_DIRS=1
+CELERY_CREATE_DIRS=1
+{{- end }}
+
+{{/*
+Celery /etc/init.d/celeryd template
+*/}}
+{{- define "rizz.initd-celeryd" -}}
+#!/bin/sh -e
+# ============================================
+# celeryd - Starts the Celery worker daemon.
+# ============================================
+#
+# :Usage: /etc/init.d/celeryd {start|stop|force-reload|restart|try-restart|status}
+# :Configuration file: /etc/default/celeryd (or /usr/local/etc/celeryd on BSD)
+#
+# See https://docs.celeryq.dev/en/latest/userguide/daemonizing.html#generic-init-scripts
+
+
+### BEGIN INIT INFO
+# Provides: celeryd
+# Required-Start: $network $local_fs $remote_fs
+# Required-Stop: $network $local_fs $remote_fs
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: celery task worker daemon
+### END INIT INFO
+#
+#
+# To implement separate init-scripts, copy this script and give it a different
+# name. That is, if your new application named "little-worker" needs an init,
+# you should use:
+#
+# cp /etc/init.d/celeryd /etc/init.d/little-worker
+#
+# You can then configure this by manipulating /etc/default/little-worker.
+#
+VERSION=10.1
+echo "celery init v${VERSION}."
+if [ $(id -u) -ne 0 ]; then
+ echo "Error: This program can only be used by the root user."
+ echo " Unprivileged users must use the 'celery multi' utility, "
+ echo " or 'celery worker --detach'."
+ exit 1
+fi
+
+origin_is_runlevel_dir () {
+ set +e
+ dirname $0 | grep -q "/etc/rc.\.d"
+ echo $?
+}
+
+# Can be a runlevel symlink (e.g., S02celeryd)
+if [ $(origin_is_runlevel_dir) -eq 0 ]; then
+ SCRIPT_FILE=$(readlink "$0")
+else
+ SCRIPT_FILE="$0"
+fi
+SCRIPT_NAME="$(basename "$SCRIPT_FILE")"
+
+DEFAULT_USER="celery"
+DEFAULT_PID_FILE="/var/run/celery/%n.pid"
+DEFAULT_LOG_FILE="/var/log/celery/%n%I.log"
+DEFAULT_LOG_LEVEL="WARNING"
+DEFAULT_NODES="celery"
+DEFAULT_CELERYD="-m celery worker --detach"
+
+if [ -d "/etc/default" ]; then
+ CELERY_CONFIG_DIR="/etc/default"
+else
+ CELERY_CONFIG_DIR="/usr/local/etc"
+fi
+
+CELERY_DEFAULTS=${CELERY_DEFAULTS:-"$CELERY_CONFIG_DIR/${SCRIPT_NAME}"}
+
+# Make sure executable configuration script is owned by root
+_config_sanity() {
+ local path="$1"
+ local owner=$(ls -ld "$path" | awk '{print $3}')
+ local iwgrp=$(ls -ld "$path" | cut -b 6)
+ local iwoth=$(ls -ld "$path" | cut -b 9)
+
+ if [ "$(id -u $owner)" != "0" ]; then
+ echo "Error: Config script '$path' must be owned by root!"
+ echo
+ echo "Resolution:"
+ echo "Review the file carefully, and make sure it hasn't been "
+ echo "modified with mailicious intent. When sure the "
+ echo "script is safe to execute with superuser privileges "
+ echo "you can change ownership of the script:"
+ echo " $ sudo chown root '$path'"
+ exit 1
+ fi
+
+ if [ "$iwoth" != "-" ]; then # S_IWOTH
+ echo "Error: Config script '$path' cannot be writable by others!"
+ echo
+ echo "Resolution:"
+ echo "Review the file carefully, and make sure it hasn't been "
+ echo "modified with malicious intent. When sure the "
+ echo "script is safe to execute with superuser privileges "
+ echo "you can change the scripts permissions:"
+ echo " $ sudo chmod 640 '$path'"
+ exit 1
+ fi
+ if [ "$iwgrp" != "-" ]; then # S_IWGRP
+ echo "Error: Config script '$path' cannot be writable by group!"
+ echo
+ echo "Resolution:"
+ echo "Review the file carefully, and make sure it hasn't been "
+ echo "modified with malicious intent. When sure the "
+ echo "script is safe to execute with superuser privileges "
+ echo "you can change the scripts permissions:"
+ echo " $ sudo chmod 640 '$path'"
+ exit 1
+ fi
+}
+
+if [ -f "$CELERY_DEFAULTS" ]; then
+ _config_sanity "$CELERY_DEFAULTS"
+ echo "Using config script: $CELERY_DEFAULTS"
+ . "$CELERY_DEFAULTS"
+fi
+
+# Sets --app argument for CELERY_BIN
+CELERY_APP_ARG=""
+if [ ! -z "$CELERY_APP" ]; then
+ CELERY_APP_ARG="--app=$CELERY_APP"
+fi
+
+# Options to su
+# can be used to enable login shell (CELERYD_SU_ARGS="-l"),
+# or even to use start-stop-daemon instead of su.
+CELERYD_SU=${CELERY_SU:-"su"}
+CELERYD_SU_ARGS=${CELERYD_SU_ARGS:-""}
+
+CELERYD_USER=${CELERYD_USER:-$DEFAULT_USER}
+
+# Set CELERY_CREATE_DIRS to always create log/pid dirs.
+CELERY_CREATE_DIRS=${CELERY_CREATE_DIRS:-0}
+CELERY_CREATE_RUNDIR=$CELERY_CREATE_DIRS
+CELERY_CREATE_LOGDIR=$CELERY_CREATE_DIRS
+if [ -z "$CELERYD_PID_FILE" ]; then
+ CELERYD_PID_FILE="$DEFAULT_PID_FILE"
+ CELERY_CREATE_RUNDIR=1
+fi
+if [ -z "$CELERYD_LOG_FILE" ]; then
+ CELERYD_LOG_FILE="$DEFAULT_LOG_FILE"
+ CELERY_CREATE_LOGDIR=1
+fi
+
+CELERYD_LOG_LEVEL=${CELERYD_LOG_LEVEL:-${CELERYD_LOGLEVEL:-$DEFAULT_LOG_LEVEL}}
+CELERY_BIN=${CELERY_BIN:-"celery"}
+CELERYD_MULTI=${CELERYD_MULTI:-"$CELERY_BIN multi"}
+CELERYD_NODES=${CELERYD_NODES:-$DEFAULT_NODES}
+
+export CELERY_LOADER
+
+if [ -n "$2" ]; then
+ CELERYD_OPTS="$CELERYD_OPTS $2"
+fi
+
+CELERYD_LOG_DIR=`dirname $CELERYD_LOG_FILE`
+CELERYD_PID_DIR=`dirname $CELERYD_PID_FILE`
+
+# Extra start-stop-daemon options, like user/group.
+if [ -n "$CELERYD_CHDIR" ]; then
+ DAEMON_OPTS="$DAEMON_OPTS --workdir=$CELERYD_CHDIR"
+fi
+
+
+check_dev_null() {
+ if [ ! -c /dev/null ]; then
+ echo "/dev/null is not a character device!"
+ exit 75 # EX_TEMPFAIL
+ fi
+}
+
+
+maybe_die() {
+ if [ $? -ne 0 ]; then
+ echo "Exiting: $* (errno $?)"
+ exit 77 # EX_NOPERM
+ fi
+}
+
+create_default_dir() {
+ if [ ! -d "$1" ]; then
+ echo "- Creating default directory: '$1'"
+ mkdir -p "$1"
+ maybe_die "Couldn't create directory $1"
+ echo "- Changing permissions of '$1' to 02755"
+ chmod 02755 "$1"
+ maybe_die "Couldn't change permissions for $1"
+ if [ -n "$CELERYD_USER" ]; then
+ echo "- Changing owner of '$1' to '$CELERYD_USER'"
+ chown "$CELERYD_USER" "$1"
+ maybe_die "Couldn't change owner of $1"
+ fi
+ if [ -n "$CELERYD_GROUP" ]; then
+ echo "- Changing group of '$1' to '$CELERYD_GROUP'"
+ chgrp "$CELERYD_GROUP" "$1"
+ maybe_die "Couldn't change group of $1"
+ fi
+ fi
+}
+
+
+check_paths() {
+ if [ $CELERY_CREATE_LOGDIR -eq 1 ]; then
+ create_default_dir "$CELERYD_LOG_DIR"
+ fi
+ if [ $CELERY_CREATE_RUNDIR -eq 1 ]; then
+ create_default_dir "$CELERYD_PID_DIR"
+ fi
+}
+
+create_paths() {
+ create_default_dir "$CELERYD_LOG_DIR"
+ create_default_dir "$CELERYD_PID_DIR"
+}
+
+export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
+
+
+_get_pidfiles () {
+ # note: multi < 3.1.14 output to stderr, not stdout, hence the redirect.
+ ${CELERYD_MULTI} expand "${CELERYD_PID_FILE}" ${CELERYD_NODES} 2>&1
+}
+
+
+_get_pids() {
+ found_pids=0
+ my_exitcode=0
+
+ for pidfile in $(_get_pidfiles); do
+ local pid=`cat "$pidfile"`
+ local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
+ if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
+ echo "bad pid file ($pidfile)"
+ one_failed=true
+ my_exitcode=1
+ else
+ found_pids=1
+ echo "$pid"
+ fi
+
+ if [ $found_pids -eq 0 ]; then
+ echo "${SCRIPT_NAME}: All nodes down"
+ exit $my_exitcode
+ fi
+ done
+}
+
+
+_chuid () {
+ ${CELERYD_SU} ${CELERYD_SU_ARGS} "$CELERYD_USER" -c "$CELERYD_MULTI $*"
+}
+
+
+start_workers () {
+ if [ ! -z "$CELERYD_ULIMIT" ]; then
+ ulimit $CELERYD_ULIMIT
+ fi
+ _chuid $* start $CELERYD_NODES $DAEMON_OPTS \
+ --pidfile="$CELERYD_PID_FILE" \
+ --logfile="$CELERYD_LOG_FILE" \
+ --loglevel="$CELERYD_LOG_LEVEL" \
+ $CELERY_APP_ARG \
+ $CELERYD_OPTS
+}
+
+
+dryrun () {
+ (C_FAKEFORK=1 start_workers --verbose)
+}
+
+
+stop_workers () {
+ _chuid stopwait $CELERYD_NODES $DAEMON_OPTS --pidfile="$CELERYD_PID_FILE"
+}
+
+
+restart_workers () {
+ _chuid restart $CELERYD_NODES $DAEMON_OPTS \
+ --pidfile="$CELERYD_PID_FILE" \
+ --logfile="$CELERYD_LOG_FILE" \
+ --loglevel="$CELERYD_LOG_LEVEL" \
+ $CELERY_APP_ARG \
+ $CELERYD_OPTS
+}
+
+
+kill_workers() {
+ _chuid kill $CELERYD_NODES $DAEMON_OPTS --pidfile="$CELERYD_PID_FILE"
+}
+
+
+restart_workers_graceful () {
+ echo "WARNING: Use with caution in production"
+ echo "The workers will attempt to restart, but they may not be able to."
+ local worker_pids=
+ worker_pids=`_get_pids`
+ [ "$one_failed" ] && exit 1
+
+ for worker_pid in $worker_pids; do
+ local failed=
+ kill -HUP $worker_pid 2> /dev/null || failed=true
+ if [ "$failed" ]; then
+ echo "${SCRIPT_NAME} worker (pid $worker_pid) could not be restarted"
+ one_failed=true
+ else
+ echo "${SCRIPT_NAME} worker (pid $worker_pid) received SIGHUP"
+ fi
+ done
+
+ [ "$one_failed" ] && exit 1 || exit 0
+}
+
+
+check_status () {
+ my_exitcode=0
+ found_pids=0
+
+ local one_failed=
+ for pidfile in $(_get_pidfiles); do
+ if [ ! -r $pidfile ]; then
+ echo "${SCRIPT_NAME} down: no pidfiles found"
+ one_failed=true
+ break
+ fi
+
+ local node=`basename "$pidfile" .pid`
+ local pid=`cat "$pidfile"`
+ local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
+ if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
+ echo "bad pid file ($pidfile)"
+ one_failed=true
+ else
+ local failed=
+ kill -0 $pid 2> /dev/null || failed=true
+ if [ "$failed" ]; then
+ echo "${SCRIPT_NAME} (node $node) (pid $pid) is down, but pidfile exists!"
+ one_failed=true
+ else
+ echo "${SCRIPT_NAME} (node $node) (pid $pid) is up..."
+ fi
+ fi
+ done
+
+ [ "$one_failed" ] && exit 1 || exit 0
+}
+
+
+case "$1" in
+ start)
+ check_dev_null
+ check_paths
+ start_workers
+ ;;
+
+ stop)
+ check_dev_null
+ check_paths
+ stop_workers
+ ;;
+
+ reload|force-reload)
+ echo "Use restart"
+ ;;
+
+ status)
+ check_status
+ ;;
+
+ restart)
+ check_dev_null
+ check_paths
+ restart_workers
+ ;;
+
+ graceful)
+ check_dev_null
+ restart_workers_graceful
+ ;;
+
+ kill)
+ check_dev_null
+ kill_workers
+ ;;
+
+ dryrun)
+ check_dev_null
+ dryrun
+ ;;
+
+ try-restart)
+ check_dev_null
+ check_paths
+ restart_workers
+ ;;
+
+ create-paths)
+ check_dev_null
+ create_paths
+ ;;
+
+ check-paths)
+ check_dev_null
+ check_paths
+ ;;
+
+ *)
+ echo "Usage: /etc/init.d/${SCRIPT_NAME} {start|stop|restart|graceful|kill|dryrun|create-paths}"
+ exit 64 # EX_USAGE
+ ;;
+esac
+
+exit 0
+{{- end }}
diff --git a/mika/rizz/templates/entrypoint.sh.tpl b/mika/rizz/templates/entrypoint.sh.tpl
new file mode 100644
index 00000000..5049c808
--- /dev/null
+++ b/mika/rizz/templates/entrypoint.sh.tpl
@@ -0,0 +1,16 @@
+{{/*
+APScheduler /entrypoint.sh template
+*/}}
+{{- define "rizz.apscheduler-entrypoint-sh" -}}
+#!/bin/bash
+
+export APP_ROOT="base"
+
+# ================= DO NOT EDIT BEYOND THIS LINE =================
+
+python3 manage.py makemigrations
+
+python3 manage.py migrate
+
+tail -f /dev/null
+{{- end }}
diff --git a/mika/rizz/templates/site-config.conf.tpl b/mika/rizz/templates/site-config.conf.tpl
new file mode 100644
index 00000000..ec32f96e
--- /dev/null
+++ b/mika/rizz/templates/site-config.conf.tpl
@@ -0,0 +1,28 @@
+{{/*
+Apache site-config.conf template
+*/}}
+{{- define "rizz.site-config-conf" -}}
+
+ ServerName DOMAIN:443
+ UseCanonicalName On
+ ServerAdmin support@mikahomelab.com
+ DocumentRoot /base
+ WSGIScriptAlias / /base/base/wsgi.py
+ WSGIDaemonProcess DOMAIN python-path=/base
+ WSGIProcessGroup DOMAIN
+
+
+
+ Require all granted
+
+
+
+ Alias /static /static
+
+ Require all granted
+
+
+ ErrorLog /var/log/apache2/apache.error.log
+ CustomLog /var/log/apache2/apache.access.log combined
+
+{{- end }}
diff --git a/mika/rizz/templates/tasks.py.tpl b/mika/rizz/templates/tasks.py.tpl
new file mode 100644
index 00000000..fecc711a
--- /dev/null
+++ b/mika/rizz/templates/tasks.py.tpl
@@ -0,0 +1,61 @@
+{{/*
+APScheduler /base/base/tasks.py template
+*/}}
+{{- define "rizz.apscheduler-tasks-py" -}}
+from django.conf import settings
+from base.scheduler import post_scheduler
+from lib.rss import (
+ clean_data,
+ update_data,
+)
+from apscheduler.schedulers.blocking import BlockingScheduler
+
+
+SCHEDULER_TIMEZONE = getattr(settings, "SCHEDULER_TIMEZONE")
+
+
+def start():
+ scheduler = BlockingScheduler(timezone=SCHEDULER_TIMEZONE)
+
+ job_name = "clean_data"
+ scheduler.add_job(clean_data, "cron", hour=CLEAN_DATA_HOURS, id=job_name, replace_existing=True)
+
+ job_name = "update_data"
+ scheduler.add_job(update_data, "cron", hour=UPDATE_DATA_HOURS, id=job_name, replace_existing=True)
+
+ job_name = "post_scheduler"
+ scheduler.add_job(post_scheduler, "cron", hour=POST_SCHEDULER_HOURS, id=job_name, replace_existing=True)
+
+ scheduler.start()
+{{- end }}
+
+{{/*
+Celery /base/base/tasks.py template
+*/}}
+{{- define "rizz.celery-tasks-py" -}}
+from __future__ import absolute_import, unicode_literals
+from celery import shared_task
+from base.scheduler import post_scheduler
+from lib.rss import (
+ clean_data,
+ update_data,
+)
+
+
+# clean data
+@shared_task
+def clean_data_task():
+ clean_data()
+
+
+# update data
+@shared_task
+def update_data_task():
+ update_data()
+
+
+# check for any posts that need to be posted
+@shared_task
+def post_scheduler_task():
+ post_scheduler()
+{{- end }}
diff --git a/mika/telego/Chart.yaml b/mika/telego/Chart.yaml
index 26cb61e1..0b65d2e4 100644
--- a/mika/telego/Chart.yaml
+++ b/mika/telego/Chart.yaml
@@ -2,8 +2,8 @@ apiVersion: v2
name: telego
description: Telego is an easy to use Telegram bot framework built on top of Django.
type: application
-version: 0.3.0
-appVersion: "0.1.0-stable-r1"
+version: 0.4.0
+appVersion: "0.2.0-stable-r1"
keywords:
- "Telego"
- "Telegram"
diff --git a/mika/telego/templates/__init__.py.tpl b/mika/telego/templates/__init__.py.tpl
new file mode 100644
index 00000000..072dcf4d
--- /dev/null
+++ b/mika/telego/templates/__init__.py.tpl
@@ -0,0 +1,8 @@
+{{/*
+Celery /base/base/__init__.py template
+*/}}
+{{- define "telego.celery-init-py" -}}
+from .celery import app as celery_app
+
+__all__ = ("celery_app",)
+{{- end }}
diff --git a/mika/telego/templates/_helpers.tpl b/mika/telego/templates/_helpers.tpl
index c22effda..5f664925 100644
--- a/mika/telego/templates/_helpers.tpl
+++ b/mika/telego/templates/_helpers.tpl
@@ -60,971 +60,3 @@ Create the name of the service account to use
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
-
-{{/*
-Apache site-config.conf template
-*/}}
-{{- define "telego.site-config-conf" -}}
-
- ServerName DOMAIN:443
- UseCanonicalName On
- ServerAdmin support@mikahomelab.com
- DocumentRoot /base
- WSGIScriptAlias / /base/base/wsgi.py
- WSGIDaemonProcess DOMAIN python-path=/base
- WSGIProcessGroup DOMAIN
-
-
-
- Require all granted
-
-
-
- Alias /static /static
-
- Require all granted
-
-
- ErrorLog /var/log/apache2/apache.error.log
- CustomLog /var/log/apache2/apache.access.log combined
-
-{{- end }}
-
-{{/*
-APScheduler /entrypoint.sh template
-*/}}
-{{- define "telego.apscheduler-entrypoint-sh" -}}
-#!/bin/bash
-
-export APP_ROOT="base"
-
-# ================= DO NOT EDIT BEYOND THIS LINE =================
-
-python3 manage.py makemigrations
-
-python3 manage.py migrate
-
-tail -f /dev/null
-{{- end }}
-
-{{/*
-APScheduler /base/base/apps.py template
-*/}}
-{{- define "telego.apscheduler-apps-py" -}}
-from django.apps import AppConfig
-
-class BaseConfig(AppConfig):
- name = "base"
-
- def ready(self):
- from . import signals
- from . import tasks
- tasks.start()
-{{- end }}
-
-{{/*
-APScheduler /base/base/tasks.py template
-*/}}
-{{- define "telego.apscheduler-tasks-py" -}}
-from django.conf import settings
-from base.scheduler import object_scheduler
-from lib.telegram import clean_model
-from apscheduler.schedulers.blocking import BlockingScheduler
-
-
-SCHEDULER_TIMEZONE = getattr(settings, "SCHEDULER_TIMEZONE")
-
-
-def start():
- scheduler = BlockingScheduler(timezone=SCHEDULER_TIMEZONE)
-
- job_name = "clean_model"
- scheduler.add_job(clean_model, "cron", hour=CLEAN_MODEL_HOURS, id=job_name, replace_existing=True)
-
- job_name = "object_scheduler"
- scheduler.add_job(object_scheduler, "cron", second="*/" + OBJECT_SCHEDULER_SECONDS, id=job_name, replace_existing=True)
-
- scheduler.start()
-{{- end }}
-
-{{/*
-Celery /etc/default/celeryd template
-*/}}
-{{- define "telego.default-celeryd" -}}
-# Names of nodes to start
-# most people will only start one node:
-#CELERYD_NODES="worker1"
-# but you can also start multiple and configure settings
-# for each in CELERYD_OPTS
-#CELERYD_NODES="worker1 worker2 worker3"
-# alternatively, you can specify the number of nodes to start:
-#CELERYD_NODES=10
-CELERYD_NODES="worker1"
-
-# Absolute or relative path to the 'celery' command:
-#CELERY_BIN="/usr/local/bin/celery"
-#CELERY_BIN="/virtualenvs/def/bin/celery"
-CELERY_BIN="/usr/local/bin/celery"
-
-# App instance to use
-# comment out this line if you don't use an app
-#CELERY_APP="proj"
-# or fully qualified:
-#CELERY_APP="proj.tasks:app"
-CELERY_APP="base"
-
-# Where to chdir at start.
-#CELERYD_CHDIR="/opt/Myproject/"
-CELERYD_CHDIR="/base/"
-
-# Extra command-line arguments to the worker
-#CELERYD_OPTS="--time-limit=300 --concurrency=8"
-# Configure node-specific settings by appending node name to arguments:
-#CELERYD_OPTS="--time-limit=300 -c 8 -c:worker2 4 -c:worker3 2 -Ofair:worker1"
-CELERYD_OPTS="--time-limit=300 --concurrency=8 --without-gossip --without-mingle --without-heartbeat -Ofair --pool=solo"
-
-# Set logging level
-#CELERYD_LOG_LEVEL="DEBUG"
-CELERYD_LOG_LEVEL="WARNING"
-
-# %n will be replaced with the first part of the nodename.
-#CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
-#CELERYD_PID_FILE="/var/run/celery/%n.pid"
-CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
-CELERYD_PID_FILE="/var/run/celery/%n.pid"
-
-# Workers should run as an unprivileged user.
-# You need to create this user manually (or you can choose
-# a user/group combination that already exists (e.g., nobody).
-#CELERYD_USER="celery"
-#CELERYD_GROUP="celery"
-CELERYD_USER="root"
-CELERYD_GROUP="root"
-
-# If enabled pid and log directories will be created if missing,
-# and owned by the userid/group configured.
-#CELERY_CREATE_DIRS=1
-CELERY_CREATE_DIRS=1
-{{- end }}
-
-{{/*
-Celery /etc/init.d/celerybeat template
-*/}}
-{{- define "telego.initd-celerybeat" -}}
-#!/bin/sh -e
-# =========================================================
-# celerybeat - Starts the Celery periodic task scheduler.
-# =========================================================
-#
-# :Usage: /etc/init.d/celerybeat {start|stop|force-reload|restart|try-restart|status}
-# :Configuration file: /etc/default/celerybeat or /etc/default/celeryd
-#
-# See https://docs.celeryq.dev/en/latest/userguide/daemonizing.html#generic-init-scripts
-
-### BEGIN INIT INFO
-# Provides: celerybeat
-# Required-Start: $network $local_fs $remote_fs
-# Required-Stop: $network $local_fs $remote_fs
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: celery periodic task scheduler
-### END INIT INFO
-
-# Cannot use set -e/bash -e since the kill -0 command will abort
-# abnormally in the absence of a valid process ID.
-#set -e
-VERSION=10.1
-echo "celery init v${VERSION}."
-
-if [ $(id -u) -ne 0 ]; then
- echo "Error: This program can only be used by the root user."
- echo " Unprivileged users must use 'celery beat --detach'"
- exit 1
-fi
-
-origin_is_runlevel_dir () {
- set +e
- dirname $0 | grep -q "/etc/rc.\.d"
- echo $?
-}
-
-# Can be a runlevel symlink (e.g., S02celeryd)
-if [ $(origin_is_runlevel_dir) -eq 0 ]; then
- SCRIPT_FILE=$(readlink "$0")
-else
- SCRIPT_FILE="$0"
-fi
-SCRIPT_NAME="$(basename "$SCRIPT_FILE")"
-
-# /etc/init.d/celerybeat: start and stop the celery periodic task scheduler daemon.
-
-# Make sure executable configuration script is owned by root
-_config_sanity() {
- local path="$1"
- local owner=$(ls -ld "$path" | awk '{print $3}')
- local iwgrp=$(ls -ld "$path" | cut -b 6)
- local iwoth=$(ls -ld "$path" | cut -b 9)
-
- if [ "$(id -u $owner)" != "0" ]; then
- echo "Error: Config script '$path' must be owned by root!"
- echo
- echo "Resolution:"
- echo "Review the file carefully, and make sure it hasn't been "
- echo "modified with mailicious intent. When sure the "
- echo "script is safe to execute with superuser privileges "
- echo "you can change ownership of the script:"
- echo " $ sudo chown root '$path'"
- exit 1
- fi
-
- if [ "$iwoth" != "-" ]; then # S_IWOTH
- echo "Error: Config script '$path' cannot be writable by others!"
- echo
- echo "Resolution:"
- echo "Review the file carefully, and make sure it hasn't been "
- echo "modified with malicious intent. When sure the "
- echo "script is safe to execute with superuser privileges "
- echo "you can change the scripts permissions:"
- echo " $ sudo chmod 640 '$path'"
- exit 1
- fi
- if [ "$iwgrp" != "-" ]; then # S_IWGRP
- echo "Error: Config script '$path' cannot be writable by group!"
- echo
- echo "Resolution:"
- echo "Review the file carefully, and make sure it hasn't been "
- echo "modified with malicious intent. When sure the "
- echo "script is safe to execute with superuser privileges "
- echo "you can change the scripts permissions:"
- echo " $ sudo chmod 640 '$path'"
- exit 1
- fi
-}
-
-scripts=""
-
-if test -f /etc/default/celeryd; then
- scripts="/etc/default/celeryd"
- _config_sanity /etc/default/celeryd
- . /etc/default/celeryd
-fi
-
-EXTRA_CONFIG="/etc/default/${SCRIPT_NAME}"
-if test -f "$EXTRA_CONFIG"; then
- scripts="$scripts, $EXTRA_CONFIG"
- _config_sanity "$EXTRA_CONFIG"
- . "$EXTRA_CONFIG"
-fi
-
-echo "Using configuration: $scripts"
-
-CELERY_BIN=${CELERY_BIN:-"celery"}
-DEFAULT_USER="celery"
-DEFAULT_PID_FILE="/var/run/celery/beat.pid"
-DEFAULT_LOG_FILE="/var/log/celery/beat.log"
-DEFAULT_LOG_LEVEL="WARNING"
-DEFAULT_CELERYBEAT="$CELERY_BIN"
-
-CELERYBEAT=${CELERYBEAT:-$DEFAULT_CELERYBEAT}
-CELERYBEAT_LOG_LEVEL=${CELERYBEAT_LOG_LEVEL:-${CELERYBEAT_LOGLEVEL:-$DEFAULT_LOG_LEVEL}}
-
-CELERYBEAT_SU=${CELERYBEAT_SU:-"su"}
-CELERYBEAT_SU_ARGS=${CELERYBEAT_SU_ARGS:-""}
-
-# Sets --app argument for CELERY_BIN
-CELERY_APP_ARG=""
-if [ ! -z "$CELERY_APP" ]; then
- CELERY_APP_ARG="--app=$CELERY_APP"
-fi
-
-CELERYBEAT_USER=${CELERYBEAT_USER:-${CELERYD_USER:-$DEFAULT_USER}}
-
-# Set CELERY_CREATE_DIRS to always create log/pid dirs.
-CELERY_CREATE_DIRS=${CELERY_CREATE_DIRS:-0}
-CELERY_CREATE_RUNDIR=$CELERY_CREATE_DIRS
-CELERY_CREATE_LOGDIR=$CELERY_CREATE_DIRS
-if [ -z "$CELERYBEAT_PID_FILE" ]; then
- CELERYBEAT_PID_FILE="$DEFAULT_PID_FILE"
- CELERY_CREATE_RUNDIR=1
-fi
-if [ -z "$CELERYBEAT_LOG_FILE" ]; then
- CELERYBEAT_LOG_FILE="$DEFAULT_LOG_FILE"
- CELERY_CREATE_LOGDIR=1
-fi
-
-export CELERY_LOADER
-
-if [ -n "$2" ]; then
- CELERYBEAT_OPTS="$CELERYBEAT_OPTS $2"
-fi
-
-CELERYBEAT_LOG_DIR=`dirname $CELERYBEAT_LOG_FILE`
-CELERYBEAT_PID_DIR=`dirname $CELERYBEAT_PID_FILE`
-
-# Extra start-stop-daemon options, like user/group.
-
-CELERYBEAT_CHDIR=${CELERYBEAT_CHDIR:-$CELERYD_CHDIR}
-if [ -n "$CELERYBEAT_CHDIR" ]; then
- DAEMON_OPTS="$DAEMON_OPTS --workdir=$CELERYBEAT_CHDIR"
-fi
-
-
-export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
-
-check_dev_null() {
- if [ ! -c /dev/null ]; then
- echo "/dev/null is not a character device!"
- exit 75 # EX_TEMPFAIL
- fi
-}
-
-maybe_die() {
- if [ $? -ne 0 ]; then
- echo "Exiting: $*"
- exit 77 # EX_NOPERM
- fi
-}
-
-create_default_dir() {
- if [ ! -d "$1" ]; then
- echo "- Creating default directory: '$1'"
- mkdir -p "$1"
- maybe_die "Couldn't create directory $1"
- echo "- Changing permissions of '$1' to 02755"
- chmod 02755 "$1"
- maybe_die "Couldn't change permissions for $1"
- if [ -n "$CELERYBEAT_USER" ]; then
- echo "- Changing owner of '$1' to '$CELERYBEAT_USER'"
- chown "$CELERYBEAT_USER" "$1"
- maybe_die "Couldn't change owner of $1"
- fi
- if [ -n "$CELERYBEAT_GROUP" ]; then
- echo "- Changing group of '$1' to '$CELERYBEAT_GROUP'"
- chgrp "$CELERYBEAT_GROUP" "$1"
- maybe_die "Couldn't change group of $1"
- fi
- fi
-}
-
-check_paths() {
- if [ $CELERY_CREATE_LOGDIR -eq 1 ]; then
- create_default_dir "$CELERYBEAT_LOG_DIR"
- fi
- if [ $CELERY_CREATE_RUNDIR -eq 1 ]; then
- create_default_dir "$CELERYBEAT_PID_DIR"
- fi
-}
-
-
-create_paths () {
- create_default_dir "$CELERYBEAT_LOG_DIR"
- create_default_dir "$CELERYBEAT_PID_DIR"
-}
-
-is_running() {
- pid=$1
- ps $pid > /dev/null 2>&1
-}
-
-wait_pid () {
- pid=$1
- forever=1
- i=0
- while [ $forever -gt 0 ]; do
- if ! is_running $pid; then
- echo "OK"
- forever=0
- else
- kill -TERM "$pid"
- i=$((i + 1))
- if [ $i -gt 60 ]; then
- echo "ERROR"
- echo "Timed out while stopping (30s)"
- forever=0
- else
- sleep 0.5
- fi
- fi
- done
-}
-
-
-stop_beat () {
- echo -n "Stopping ${SCRIPT_NAME}... "
- if [ -f "$CELERYBEAT_PID_FILE" ]; then
- wait_pid $(cat "$CELERYBEAT_PID_FILE")
- else
- echo "NOT RUNNING"
- fi
-}
-
-_chuid () {
- ${CELERYBEAT_SU} ${CELERYBEAT_SU_ARGS} \
- "$CELERYBEAT_USER" -c "$CELERYBEAT $*"
-}
-
-start_beat () {
- echo "Starting ${SCRIPT_NAME}..."
- _chuid $CELERY_APP_ARG $DAEMON_OPTS beat --detach \
- --pidfile="$CELERYBEAT_PID_FILE" \
- --logfile="$CELERYBEAT_LOG_FILE" \
- --loglevel="$CELERYBEAT_LOG_LEVEL" \
- $CELERYBEAT_OPTS
-}
-
-
-check_status () {
- local failed=
- local pid_file=$CELERYBEAT_PID_FILE
- if [ ! -e $pid_file ]; then
- echo "${SCRIPT_NAME} is down: no pid file found"
- failed=true
- elif [ ! -r $pid_file ]; then
- echo "${SCRIPT_NAME} is in unknown state, user cannot read pid file."
- failed=true
- else
- local pid=`cat "$pid_file"`
- local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
- if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
- echo "${SCRIPT_NAME}: bad pid file ($pid_file)"
- failed=true
- else
- local failed=
- kill -0 $pid 2> /dev/null || failed=true
- if [ "$failed" ]; then
- echo "${SCRIPT_NAME} (pid $pid) is down, but pid file exists!"
- failed=true
- else
- echo "${SCRIPT_NAME} (pid $pid) is up..."
- fi
- fi
- fi
-
- [ "$failed" ] && exit 1 || exit 0
-}
-
-
-case "$1" in
- start)
- check_dev_null
- check_paths
- start_beat
- ;;
- stop)
- check_paths
- stop_beat
- ;;
- reload|force-reload)
- echo "Use start+stop"
- ;;
- status)
- check_status
- ;;
- restart)
- echo "Restarting celery periodic task scheduler"
- check_paths
- stop_beat && check_dev_null && start_beat
- ;;
- create-paths)
- check_dev_null
- create_paths
- ;;
- check-paths)
- check_dev_null
- check_paths
- ;;
- *)
- echo "Usage: /etc/init.d/${SCRIPT_NAME} {start|stop|restart|create-paths|status}"
- exit 64 # EX_USAGE
- ;;
-esac
-
-exit 0
-{{- end }}
-
-{{/*
-Celery /etc/init.d/celeryd template
-*/}}
-{{- define "telego.initd-celeryd" -}}
-#!/bin/sh -e
-# ============================================
-# celeryd - Starts the Celery worker daemon.
-# ============================================
-#
-# :Usage: /etc/init.d/celeryd {start|stop|force-reload|restart|try-restart|status}
-# :Configuration file: /etc/default/celeryd (or /usr/local/etc/celeryd on BSD)
-#
-# See https://docs.celeryq.dev/en/latest/userguide/daemonizing.html#generic-init-scripts
-
-
-### BEGIN INIT INFO
-# Provides: celeryd
-# Required-Start: $network $local_fs $remote_fs
-# Required-Stop: $network $local_fs $remote_fs
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: celery task worker daemon
-### END INIT INFO
-#
-#
-# To implement separate init-scripts, copy this script and give it a different
-# name. That is, if your new application named "little-worker" needs an init,
-# you should use:
-#
-# cp /etc/init.d/celeryd /etc/init.d/little-worker
-#
-# You can then configure this by manipulating /etc/default/little-worker.
-#
-VERSION=10.1
-echo "celery init v${VERSION}."
-if [ $(id -u) -ne 0 ]; then
- echo "Error: This program can only be used by the root user."
- echo " Unprivileged users must use the 'celery multi' utility, "
- echo " or 'celery worker --detach'."
- exit 1
-fi
-
-origin_is_runlevel_dir () {
- set +e
- dirname $0 | grep -q "/etc/rc.\.d"
- echo $?
-}
-
-# Can be a runlevel symlink (e.g., S02celeryd)
-if [ $(origin_is_runlevel_dir) -eq 0 ]; then
- SCRIPT_FILE=$(readlink "$0")
-else
- SCRIPT_FILE="$0"
-fi
-SCRIPT_NAME="$(basename "$SCRIPT_FILE")"
-
-DEFAULT_USER="celery"
-DEFAULT_PID_FILE="/var/run/celery/%n.pid"
-DEFAULT_LOG_FILE="/var/log/celery/%n%I.log"
-DEFAULT_LOG_LEVEL="WARNING"
-DEFAULT_NODES="celery"
-DEFAULT_CELERYD="-m celery worker --detach"
-
-if [ -d "/etc/default" ]; then
- CELERY_CONFIG_DIR="/etc/default"
-else
- CELERY_CONFIG_DIR="/usr/local/etc"
-fi
-
-CELERY_DEFAULTS=${CELERY_DEFAULTS:-"$CELERY_CONFIG_DIR/${SCRIPT_NAME}"}
-
-# Make sure executable configuration script is owned by root
-_config_sanity() {
- local path="$1"
- local owner=$(ls -ld "$path" | awk '{print $3}')
- local iwgrp=$(ls -ld "$path" | cut -b 6)
- local iwoth=$(ls -ld "$path" | cut -b 9)
-
- if [ "$(id -u $owner)" != "0" ]; then
- echo "Error: Config script '$path' must be owned by root!"
- echo
- echo "Resolution:"
- echo "Review the file carefully, and make sure it hasn't been "
- echo "modified with mailicious intent. When sure the "
- echo "script is safe to execute with superuser privileges "
- echo "you can change ownership of the script:"
- echo " $ sudo chown root '$path'"
- exit 1
- fi
-
- if [ "$iwoth" != "-" ]; then # S_IWOTH
- echo "Error: Config script '$path' cannot be writable by others!"
- echo
- echo "Resolution:"
- echo "Review the file carefully, and make sure it hasn't been "
- echo "modified with malicious intent. When sure the "
- echo "script is safe to execute with superuser privileges "
- echo "you can change the scripts permissions:"
- echo " $ sudo chmod 640 '$path'"
- exit 1
- fi
- if [ "$iwgrp" != "-" ]; then # S_IWGRP
- echo "Error: Config script '$path' cannot be writable by group!"
- echo
- echo "Resolution:"
- echo "Review the file carefully, and make sure it hasn't been "
- echo "modified with malicious intent. When sure the "
- echo "script is safe to execute with superuser privileges "
- echo "you can change the scripts permissions:"
- echo " $ sudo chmod 640 '$path'"
- exit 1
- fi
-}
-
-if [ -f "$CELERY_DEFAULTS" ]; then
- _config_sanity "$CELERY_DEFAULTS"
- echo "Using config script: $CELERY_DEFAULTS"
- . "$CELERY_DEFAULTS"
-fi
-
-# Sets --app argument for CELERY_BIN
-CELERY_APP_ARG=""
-if [ ! -z "$CELERY_APP" ]; then
- CELERY_APP_ARG="--app=$CELERY_APP"
-fi
-
-# Options to su
-# can be used to enable login shell (CELERYD_SU_ARGS="-l"),
-# or even to use start-stop-daemon instead of su.
-CELERYD_SU=${CELERY_SU:-"su"}
-CELERYD_SU_ARGS=${CELERYD_SU_ARGS:-""}
-
-CELERYD_USER=${CELERYD_USER:-$DEFAULT_USER}
-
-# Set CELERY_CREATE_DIRS to always create log/pid dirs.
-CELERY_CREATE_DIRS=${CELERY_CREATE_DIRS:-0}
-CELERY_CREATE_RUNDIR=$CELERY_CREATE_DIRS
-CELERY_CREATE_LOGDIR=$CELERY_CREATE_DIRS
-if [ -z "$CELERYD_PID_FILE" ]; then
- CELERYD_PID_FILE="$DEFAULT_PID_FILE"
- CELERY_CREATE_RUNDIR=1
-fi
-if [ -z "$CELERYD_LOG_FILE" ]; then
- CELERYD_LOG_FILE="$DEFAULT_LOG_FILE"
- CELERY_CREATE_LOGDIR=1
-fi
-
-CELERYD_LOG_LEVEL=${CELERYD_LOG_LEVEL:-${CELERYD_LOGLEVEL:-$DEFAULT_LOG_LEVEL}}
-CELERY_BIN=${CELERY_BIN:-"celery"}
-CELERYD_MULTI=${CELERYD_MULTI:-"$CELERY_BIN multi"}
-CELERYD_NODES=${CELERYD_NODES:-$DEFAULT_NODES}
-
-export CELERY_LOADER
-
-if [ -n "$2" ]; then
- CELERYD_OPTS="$CELERYD_OPTS $2"
-fi
-
-CELERYD_LOG_DIR=`dirname $CELERYD_LOG_FILE`
-CELERYD_PID_DIR=`dirname $CELERYD_PID_FILE`
-
-# Extra start-stop-daemon options, like user/group.
-if [ -n "$CELERYD_CHDIR" ]; then
- DAEMON_OPTS="$DAEMON_OPTS --workdir=$CELERYD_CHDIR"
-fi
-
-
-check_dev_null() {
- if [ ! -c /dev/null ]; then
- echo "/dev/null is not a character device!"
- exit 75 # EX_TEMPFAIL
- fi
-}
-
-
-maybe_die() {
- if [ $? -ne 0 ]; then
- echo "Exiting: $* (errno $?)"
- exit 77 # EX_NOPERM
- fi
-}
-
-create_default_dir() {
- if [ ! -d "$1" ]; then
- echo "- Creating default directory: '$1'"
- mkdir -p "$1"
- maybe_die "Couldn't create directory $1"
- echo "- Changing permissions of '$1' to 02755"
- chmod 02755 "$1"
- maybe_die "Couldn't change permissions for $1"
- if [ -n "$CELERYD_USER" ]; then
- echo "- Changing owner of '$1' to '$CELERYD_USER'"
- chown "$CELERYD_USER" "$1"
- maybe_die "Couldn't change owner of $1"
- fi
- if [ -n "$CELERYD_GROUP" ]; then
- echo "- Changing group of '$1' to '$CELERYD_GROUP'"
- chgrp "$CELERYD_GROUP" "$1"
- maybe_die "Couldn't change group of $1"
- fi
- fi
-}
-
-
-check_paths() {
- if [ $CELERY_CREATE_LOGDIR -eq 1 ]; then
- create_default_dir "$CELERYD_LOG_DIR"
- fi
- if [ $CELERY_CREATE_RUNDIR -eq 1 ]; then
- create_default_dir "$CELERYD_PID_DIR"
- fi
-}
-
-create_paths() {
- create_default_dir "$CELERYD_LOG_DIR"
- create_default_dir "$CELERYD_PID_DIR"
-}
-
-export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
-
-
-_get_pidfiles () {
- # note: multi < 3.1.14 output to stderr, not stdout, hence the redirect.
- ${CELERYD_MULTI} expand "${CELERYD_PID_FILE}" ${CELERYD_NODES} 2>&1
-}
-
-
-_get_pids() {
- found_pids=0
- my_exitcode=0
-
- for pidfile in $(_get_pidfiles); do
- local pid=`cat "$pidfile"`
- local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
- if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
- echo "bad pid file ($pidfile)"
- one_failed=true
- my_exitcode=1
- else
- found_pids=1
- echo "$pid"
- fi
-
- if [ $found_pids -eq 0 ]; then
- echo "${SCRIPT_NAME}: All nodes down"
- exit $my_exitcode
- fi
- done
-}
-
-
-_chuid () {
- ${CELERYD_SU} ${CELERYD_SU_ARGS} "$CELERYD_USER" -c "$CELERYD_MULTI $*"
-}
-
-
-start_workers () {
- if [ ! -z "$CELERYD_ULIMIT" ]; then
- ulimit $CELERYD_ULIMIT
- fi
- _chuid $* start $CELERYD_NODES $DAEMON_OPTS \
- --pidfile="$CELERYD_PID_FILE" \
- --logfile="$CELERYD_LOG_FILE" \
- --loglevel="$CELERYD_LOG_LEVEL" \
- $CELERY_APP_ARG \
- $CELERYD_OPTS
-}
-
-
-dryrun () {
- (C_FAKEFORK=1 start_workers --verbose)
-}
-
-
-stop_workers () {
- _chuid stopwait $CELERYD_NODES $DAEMON_OPTS --pidfile="$CELERYD_PID_FILE"
-}
-
-
-restart_workers () {
- _chuid restart $CELERYD_NODES $DAEMON_OPTS \
- --pidfile="$CELERYD_PID_FILE" \
- --logfile="$CELERYD_LOG_FILE" \
- --loglevel="$CELERYD_LOG_LEVEL" \
- $CELERY_APP_ARG \
- $CELERYD_OPTS
-}
-
-
-kill_workers() {
- _chuid kill $CELERYD_NODES $DAEMON_OPTS --pidfile="$CELERYD_PID_FILE"
-}
-
-
-restart_workers_graceful () {
- echo "WARNING: Use with caution in production"
- echo "The workers will attempt to restart, but they may not be able to."
- local worker_pids=
- worker_pids=`_get_pids`
- [ "$one_failed" ] && exit 1
-
- for worker_pid in $worker_pids; do
- local failed=
- kill -HUP $worker_pid 2> /dev/null || failed=true
- if [ "$failed" ]; then
- echo "${SCRIPT_NAME} worker (pid $worker_pid) could not be restarted"
- one_failed=true
- else
- echo "${SCRIPT_NAME} worker (pid $worker_pid) received SIGHUP"
- fi
- done
-
- [ "$one_failed" ] && exit 1 || exit 0
-}
-
-
-check_status () {
- my_exitcode=0
- found_pids=0
-
- local one_failed=
- for pidfile in $(_get_pidfiles); do
- if [ ! -r $pidfile ]; then
- echo "${SCRIPT_NAME} down: no pidfiles found"
- one_failed=true
- break
- fi
-
- local node=`basename "$pidfile" .pid`
- local pid=`cat "$pidfile"`
- local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
- if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
- echo "bad pid file ($pidfile)"
- one_failed=true
- else
- local failed=
- kill -0 $pid 2> /dev/null || failed=true
- if [ "$failed" ]; then
- echo "${SCRIPT_NAME} (node $node) (pid $pid) is down, but pidfile exists!"
- one_failed=true
- else
- echo "${SCRIPT_NAME} (node $node) (pid $pid) is up..."
- fi
- fi
- done
-
- [ "$one_failed" ] && exit 1 || exit 0
-}
-
-
-case "$1" in
- start)
- check_dev_null
- check_paths
- start_workers
- ;;
-
- stop)
- check_dev_null
- check_paths
- stop_workers
- ;;
-
- reload|force-reload)
- echo "Use restart"
- ;;
-
- status)
- check_status
- ;;
-
- restart)
- check_dev_null
- check_paths
- restart_workers
- ;;
-
- graceful)
- check_dev_null
- restart_workers_graceful
- ;;
-
- kill)
- check_dev_null
- kill_workers
- ;;
-
- dryrun)
- check_dev_null
- dryrun
- ;;
-
- try-restart)
- check_dev_null
- check_paths
- restart_workers
- ;;
-
- create-paths)
- check_dev_null
- create_paths
- ;;
-
- check-paths)
- check_dev_null
- check_paths
- ;;
-
- *)
- echo "Usage: /etc/init.d/${SCRIPT_NAME} {start|stop|restart|graceful|kill|dryrun|create-paths}"
- exit 64 # EX_USAGE
- ;;
-esac
-
-exit 0
-{{- end }}
-
-{{/*
-Celery /base/base/celery.py template
-*/}}
-{{- define "telego.celery-py" -}}
-from __future__ import absolute_import, unicode_literals
-import re
-import os
-from celery import Celery
-from celery.schedules import crontab
-from datetime import timedelta
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "base.settings")
-app = Celery("base")
-app.config_from_object("django.conf:settings", namespace="CELERY")
-app.autodiscover_tasks()
-
-
-# make integer from object scheduler seconds string
-object_scheduler_seconds = int(re.sub(r"\D", "", OBJECT_SCHEDULER_SECONDS))
-
-
-app.conf.beat_schedule = {
- # clean model
- "clean_model" : {
- "task" : "base.tasks.clean_model_task",
- "schedule" : crontab(hour=CLEAN_MODEL_HOURS, minute="0"),
- },
- # check for any objects that need to be sent
- "object_scheduler" : {
- "task" : "base.tasks.object_scheduler_task",
- "schedule" : timedelta(seconds=object_scheduler_seconds),
- },
-}
-
-
-@app.task(bind=True)
-def debug_task(self):
- print("Request: {0!r}".format(self.request))
-{{- end }}
-
-{{/*
-Celery /base/base/__init__.py template
-*/}}
-{{- define "telego.celery-init-py" -}}
-from .celery import app as celery_app
-
-__all__ = ("celery_app",)
-{{- end }}
-
-{{/*
-Celery /base/base/tasks.py template
-*/}}
-{{- define "telego.celery-tasks-py" -}}
-from __future__ import absolute_import, unicode_literals
-from celery import shared_task
-from base.scheduler import object_scheduler
-from lib.telegram import clean_model
-
-
-# clean model
-@shared_task
-def clean_model_task():
- clean_model()
-
-
-# check for any objects that need to be sent
-@shared_task
-def object_scheduler_task():
- object_scheduler()
-{{- end }}
diff --git a/mika/telego/templates/apps.py.tpl b/mika/telego/templates/apps.py.tpl
new file mode 100644
index 00000000..526e2ed0
--- /dev/null
+++ b/mika/telego/templates/apps.py.tpl
@@ -0,0 +1,14 @@
+{{/*
+APScheduler /base/base/apps.py template
+*/}}
+{{- define "telego.apscheduler-apps-py" -}}
+from django.apps import AppConfig
+
+class BaseConfig(AppConfig):
+ name = "base"
+
+ def ready(self):
+ from . import signals
+ from . import tasks
+ tasks.start()
+{{- end }}
diff --git a/mika/telego/templates/celery.py.tpl b/mika/telego/templates/celery.py.tpl
new file mode 100644
index 00000000..c6736ca7
--- /dev/null
+++ b/mika/telego/templates/celery.py.tpl
@@ -0,0 +1,38 @@
+{{/*
+Celery /base/base/celery.py template
+*/}}
+{{- define "telego.celery-py" -}}
+from __future__ import absolute_import, unicode_literals
+import re
+import os
+from celery import Celery
+from celery.schedules import crontab
+from datetime import timedelta
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "base.settings")
+app = Celery("base")
+app.config_from_object("django.conf:settings", namespace="CELERY")
+app.autodiscover_tasks()
+
+
+# make integer from object scheduler seconds string
+object_scheduler_seconds = int(re.sub(r"\D", "", OBJECT_SCHEDULER_SECONDS))
+
+
+app.conf.beat_schedule = {
+ # clean model
+ "clean_model" : {
+ "task" : "base.tasks.clean_model_task",
+ "schedule" : crontab(hour=CLEAN_MODEL_HOURS, minute="0"),
+ },
+ # check for any objects that need to be sent
+ "object_scheduler" : {
+ "task" : "base.tasks.object_scheduler_task",
+ "schedule" : timedelta(seconds=object_scheduler_seconds),
+ },
+}
+
+
+@app.task(bind=True)
+def debug_task(self):
+ print("Request: {0!r}".format(self.request))
+{{- end }}
diff --git a/mika/telego/templates/celerybeat.tpl b/mika/telego/templates/celerybeat.tpl
new file mode 100644
index 00000000..a6ce2487
--- /dev/null
+++ b/mika/telego/templates/celerybeat.tpl
@@ -0,0 +1,334 @@
+{{/*
+Celery /etc/init.d/celerybeat template
+*/}}
+{{- define "telego.initd-celerybeat" -}}
+#!/bin/sh -e
+# =========================================================
+# celerybeat - Starts the Celery periodic task scheduler.
+# =========================================================
+#
+# :Usage: /etc/init.d/celerybeat {start|stop|force-reload|restart|try-restart|status}
+# :Configuration file: /etc/default/celerybeat or /etc/default/celeryd
+#
+# See https://docs.celeryq.dev/en/latest/userguide/daemonizing.html#generic-init-scripts
+
+### BEGIN INIT INFO
+# Provides: celerybeat
+# Required-Start: $network $local_fs $remote_fs
+# Required-Stop: $network $local_fs $remote_fs
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: celery periodic task scheduler
+### END INIT INFO
+
+# Cannot use set -e/bash -e since the kill -0 command will abort
+# abnormally in the absence of a valid process ID.
+#set -e
+VERSION=10.1
+echo "celery init v${VERSION}."
+
+if [ $(id -u) -ne 0 ]; then
+ echo "Error: This program can only be used by the root user."
+ echo " Unprivileged users must use 'celery beat --detach'"
+ exit 1
+fi
+
+origin_is_runlevel_dir () {
+ set +e
+ dirname $0 | grep -q "/etc/rc.\.d"
+ echo $?
+}
+
+# Can be a runlevel symlink (e.g., S02celeryd)
+if [ $(origin_is_runlevel_dir) -eq 0 ]; then
+ SCRIPT_FILE=$(readlink "$0")
+else
+ SCRIPT_FILE="$0"
+fi
+SCRIPT_NAME="$(basename "$SCRIPT_FILE")"
+
+# /etc/init.d/celerybeat: start and stop the celery periodic task scheduler daemon.
+
+# Make sure executable configuration script is owned by root
+_config_sanity() {
+ local path="$1"
+ local owner=$(ls -ld "$path" | awk '{print $3}')
+ local iwgrp=$(ls -ld "$path" | cut -b 6)
+ local iwoth=$(ls -ld "$path" | cut -b 9)
+
+ if [ "$(id -u $owner)" != "0" ]; then
+ echo "Error: Config script '$path' must be owned by root!"
+ echo
+ echo "Resolution:"
+ echo "Review the file carefully, and make sure it hasn't been "
+ echo "modified with mailicious intent. When sure the "
+ echo "script is safe to execute with superuser privileges "
+ echo "you can change ownership of the script:"
+ echo " $ sudo chown root '$path'"
+ exit 1
+ fi
+
+ if [ "$iwoth" != "-" ]; then # S_IWOTH
+ echo "Error: Config script '$path' cannot be writable by others!"
+ echo
+ echo "Resolution:"
+ echo "Review the file carefully, and make sure it hasn't been "
+ echo "modified with malicious intent. When sure the "
+ echo "script is safe to execute with superuser privileges "
+ echo "you can change the scripts permissions:"
+ echo " $ sudo chmod 640 '$path'"
+ exit 1
+ fi
+ if [ "$iwgrp" != "-" ]; then # S_IWGRP
+ echo "Error: Config script '$path' cannot be writable by group!"
+ echo
+ echo "Resolution:"
+ echo "Review the file carefully, and make sure it hasn't been "
+ echo "modified with malicious intent. When sure the "
+ echo "script is safe to execute with superuser privileges "
+ echo "you can change the scripts permissions:"
+ echo " $ sudo chmod 640 '$path'"
+ exit 1
+ fi
+}
+
+scripts=""
+
+if test -f /etc/default/celeryd; then
+ scripts="/etc/default/celeryd"
+ _config_sanity /etc/default/celeryd
+ . /etc/default/celeryd
+fi
+
+EXTRA_CONFIG="/etc/default/${SCRIPT_NAME}"
+if test -f "$EXTRA_CONFIG"; then
+ scripts="$scripts, $EXTRA_CONFIG"
+ _config_sanity "$EXTRA_CONFIG"
+ . "$EXTRA_CONFIG"
+fi
+
+echo "Using configuration: $scripts"
+
+CELERY_BIN=${CELERY_BIN:-"celery"}
+DEFAULT_USER="celery"
+DEFAULT_PID_FILE="/var/run/celery/beat.pid"
+DEFAULT_LOG_FILE="/var/log/celery/beat.log"
+DEFAULT_LOG_LEVEL="WARNING"
+DEFAULT_CELERYBEAT="$CELERY_BIN"
+
+CELERYBEAT=${CELERYBEAT:-$DEFAULT_CELERYBEAT}
+CELERYBEAT_LOG_LEVEL=${CELERYBEAT_LOG_LEVEL:-${CELERYBEAT_LOGLEVEL:-$DEFAULT_LOG_LEVEL}}
+
+CELERYBEAT_SU=${CELERYBEAT_SU:-"su"}
+CELERYBEAT_SU_ARGS=${CELERYBEAT_SU_ARGS:-""}
+
+# Sets --app argument for CELERY_BIN
+CELERY_APP_ARG=""
+if [ ! -z "$CELERY_APP" ]; then
+ CELERY_APP_ARG="--app=$CELERY_APP"
+fi
+
+CELERYBEAT_USER=${CELERYBEAT_USER:-${CELERYD_USER:-$DEFAULT_USER}}
+
+# Set CELERY_CREATE_DIRS to always create log/pid dirs.
+CELERY_CREATE_DIRS=${CELERY_CREATE_DIRS:-0}
+CELERY_CREATE_RUNDIR=$CELERY_CREATE_DIRS
+CELERY_CREATE_LOGDIR=$CELERY_CREATE_DIRS
+if [ -z "$CELERYBEAT_PID_FILE" ]; then
+ CELERYBEAT_PID_FILE="$DEFAULT_PID_FILE"
+ CELERY_CREATE_RUNDIR=1
+fi
+if [ -z "$CELERYBEAT_LOG_FILE" ]; then
+ CELERYBEAT_LOG_FILE="$DEFAULT_LOG_FILE"
+ CELERY_CREATE_LOGDIR=1
+fi
+
+export CELERY_LOADER
+
+if [ -n "$2" ]; then
+ CELERYBEAT_OPTS="$CELERYBEAT_OPTS $2"
+fi
+
+CELERYBEAT_LOG_DIR=`dirname $CELERYBEAT_LOG_FILE`
+CELERYBEAT_PID_DIR=`dirname $CELERYBEAT_PID_FILE`
+
+# Extra start-stop-daemon options, like user/group.
+
+CELERYBEAT_CHDIR=${CELERYBEAT_CHDIR:-$CELERYD_CHDIR}
+if [ -n "$CELERYBEAT_CHDIR" ]; then
+ DAEMON_OPTS="$DAEMON_OPTS --workdir=$CELERYBEAT_CHDIR"
+fi
+
+
+export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
+
+check_dev_null() {
+ if [ ! -c /dev/null ]; then
+ echo "/dev/null is not a character device!"
+ exit 75 # EX_TEMPFAIL
+ fi
+}
+
+maybe_die() {
+ if [ $? -ne 0 ]; then
+ echo "Exiting: $*"
+ exit 77 # EX_NOPERM
+ fi
+}
+
+create_default_dir() {
+ if [ ! -d "$1" ]; then
+ echo "- Creating default directory: '$1'"
+ mkdir -p "$1"
+ maybe_die "Couldn't create directory $1"
+ echo "- Changing permissions of '$1' to 02755"
+ chmod 02755 "$1"
+ maybe_die "Couldn't change permissions for $1"
+ if [ -n "$CELERYBEAT_USER" ]; then
+ echo "- Changing owner of '$1' to '$CELERYBEAT_USER'"
+ chown "$CELERYBEAT_USER" "$1"
+ maybe_die "Couldn't change owner of $1"
+ fi
+ if [ -n "$CELERYBEAT_GROUP" ]; then
+ echo "- Changing group of '$1' to '$CELERYBEAT_GROUP'"
+ chgrp "$CELERYBEAT_GROUP" "$1"
+ maybe_die "Couldn't change group of $1"
+ fi
+ fi
+}
+
+check_paths() {
+ if [ $CELERY_CREATE_LOGDIR -eq 1 ]; then
+ create_default_dir "$CELERYBEAT_LOG_DIR"
+ fi
+ if [ $CELERY_CREATE_RUNDIR -eq 1 ]; then
+ create_default_dir "$CELERYBEAT_PID_DIR"
+ fi
+}
+
+
+create_paths () {
+ create_default_dir "$CELERYBEAT_LOG_DIR"
+ create_default_dir "$CELERYBEAT_PID_DIR"
+}
+
+is_running() {
+ pid=$1
+ ps $pid > /dev/null 2>&1
+}
+
+wait_pid () {
+ pid=$1
+ forever=1
+ i=0
+ while [ $forever -gt 0 ]; do
+ if ! is_running $pid; then
+ echo "OK"
+ forever=0
+ else
+ kill -TERM "$pid"
+ i=$((i + 1))
+ if [ $i -gt 60 ]; then
+ echo "ERROR"
+ echo "Timed out while stopping (30s)"
+ forever=0
+ else
+ sleep 0.5
+ fi
+ fi
+ done
+}
+
+
+stop_beat () {
+ echo -n "Stopping ${SCRIPT_NAME}... "
+ if [ -f "$CELERYBEAT_PID_FILE" ]; then
+ wait_pid $(cat "$CELERYBEAT_PID_FILE")
+ else
+ echo "NOT RUNNING"
+ fi
+}
+
+_chuid () {
+ ${CELERYBEAT_SU} ${CELERYBEAT_SU_ARGS} \
+ "$CELERYBEAT_USER" -c "$CELERYBEAT $*"
+}
+
+start_beat () {
+ echo "Starting ${SCRIPT_NAME}..."
+ _chuid $CELERY_APP_ARG $DAEMON_OPTS beat --detach \
+ --pidfile="$CELERYBEAT_PID_FILE" \
+ --logfile="$CELERYBEAT_LOG_FILE" \
+ --loglevel="$CELERYBEAT_LOG_LEVEL" \
+ $CELERYBEAT_OPTS
+}
+
+
+check_status () {
+ local failed=
+ local pid_file=$CELERYBEAT_PID_FILE
+ if [ ! -e $pid_file ]; then
+ echo "${SCRIPT_NAME} is down: no pid file found"
+ failed=true
+ elif [ ! -r $pid_file ]; then
+ echo "${SCRIPT_NAME} is in unknown state, user cannot read pid file."
+ failed=true
+ else
+ local pid=`cat "$pid_file"`
+ local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
+ if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
+ echo "${SCRIPT_NAME}: bad pid file ($pid_file)"
+ failed=true
+ else
+ local failed=
+ kill -0 $pid 2> /dev/null || failed=true
+ if [ "$failed" ]; then
+ echo "${SCRIPT_NAME} (pid $pid) is down, but pid file exists!"
+ failed=true
+ else
+ echo "${SCRIPT_NAME} (pid $pid) is up..."
+ fi
+ fi
+ fi
+
+ [ "$failed" ] && exit 1 || exit 0
+}
+
+
+case "$1" in
+ start)
+ check_dev_null
+ check_paths
+ start_beat
+ ;;
+ stop)
+ check_paths
+ stop_beat
+ ;;
+ reload|force-reload)
+ echo "Use start+stop"
+ ;;
+ status)
+ check_status
+ ;;
+ restart)
+ echo "Restarting celery periodic task scheduler"
+ check_paths
+ stop_beat && check_dev_null && start_beat
+ ;;
+ create-paths)
+ check_dev_null
+ create_paths
+ ;;
+ check-paths)
+ check_dev_null
+ check_paths
+ ;;
+ *)
+ echo "Usage: /etc/init.d/${SCRIPT_NAME} {start|stop|restart|create-paths|status}"
+ exit 64 # EX_USAGE
+ ;;
+esac
+
+exit 0
+{{- end }}
diff --git a/mika/telego/templates/celeryd.tpl b/mika/telego/templates/celeryd.tpl
new file mode 100644
index 00000000..d6242277
--- /dev/null
+++ b/mika/telego/templates/celeryd.tpl
@@ -0,0 +1,476 @@
+{{/*
+Celery /etc/default/celeryd template
+*/}}
+{{- define "telego.default-celeryd" -}}
+# Names of nodes to start
+# most people will only start one node:
+#CELERYD_NODES="worker1"
+# but you can also start multiple and configure settings
+# for each in CELERYD_OPTS
+#CELERYD_NODES="worker1 worker2 worker3"
+# alternatively, you can specify the number of nodes to start:
+#CELERYD_NODES=10
+CELERYD_NODES="worker1"
+
+# Absolute or relative path to the 'celery' command:
+#CELERY_BIN="/usr/local/bin/celery"
+#CELERY_BIN="/virtualenvs/def/bin/celery"
+CELERY_BIN="/usr/local/bin/celery"
+
+# App instance to use
+# comment out this line if you don't use an app
+#CELERY_APP="proj"
+# or fully qualified:
+#CELERY_APP="proj.tasks:app"
+CELERY_APP="base"
+
+# Where to chdir at start.
+#CELERYD_CHDIR="/opt/Myproject/"
+CELERYD_CHDIR="/base/"
+
+# Extra command-line arguments to the worker
+#CELERYD_OPTS="--time-limit=300 --concurrency=8"
+# Configure node-specific settings by appending node name to arguments:
+#CELERYD_OPTS="--time-limit=300 -c 8 -c:worker2 4 -c:worker3 2 -Ofair:worker1"
+CELERYD_OPTS="--time-limit=300 --concurrency=8 --without-gossip --without-mingle --without-heartbeat -Ofair --pool=solo"
+
+# Set logging level
+#CELERYD_LOG_LEVEL="DEBUG"
+CELERYD_LOG_LEVEL="WARNING"
+
+# %n will be replaced with the first part of the nodename.
+#CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
+#CELERYD_PID_FILE="/var/run/celery/%n.pid"
+CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
+CELERYD_PID_FILE="/var/run/celery/%n.pid"
+
+# Workers should run as an unprivileged user.
+# You need to create this user manually (or you can choose
+# a user/group combination that already exists (e.g., nobody).
+#CELERYD_USER="celery"
+#CELERYD_GROUP="celery"
+CELERYD_USER="root"
+CELERYD_GROUP="root"
+
+# If enabled pid and log directories will be created if missing,
+# and owned by the userid/group configured.
+#CELERY_CREATE_DIRS=1
+CELERY_CREATE_DIRS=1
+{{- end }}
+
+{{/*
+Celery /etc/init.d/celeryd template
+*/}}
+{{- define "telego.initd-celeryd" -}}
+#!/bin/sh -e
+# ============================================
+# celeryd - Starts the Celery worker daemon.
+# ============================================
+#
+# :Usage: /etc/init.d/celeryd {start|stop|force-reload|restart|try-restart|status}
+# :Configuration file: /etc/default/celeryd (or /usr/local/etc/celeryd on BSD)
+#
+# See https://docs.celeryq.dev/en/latest/userguide/daemonizing.html#generic-init-scripts
+
+
+### BEGIN INIT INFO
+# Provides: celeryd
+# Required-Start: $network $local_fs $remote_fs
+# Required-Stop: $network $local_fs $remote_fs
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: celery task worker daemon
+### END INIT INFO
+#
+#
+# To implement separate init-scripts, copy this script and give it a different
+# name. That is, if your new application named "little-worker" needs an init,
+# you should use:
+#
+# cp /etc/init.d/celeryd /etc/init.d/little-worker
+#
+# You can then configure this by manipulating /etc/default/little-worker.
+#
+VERSION=10.1
+echo "celery init v${VERSION}."
+if [ $(id -u) -ne 0 ]; then
+ echo "Error: This program can only be used by the root user."
+ echo " Unprivileged users must use the 'celery multi' utility, "
+ echo " or 'celery worker --detach'."
+ exit 1
+fi
+
+origin_is_runlevel_dir () {
+ set +e
+ dirname $0 | grep -q "/etc/rc.\.d"
+ echo $?
+}
+
+# Can be a runlevel symlink (e.g., S02celeryd)
+if [ $(origin_is_runlevel_dir) -eq 0 ]; then
+ SCRIPT_FILE=$(readlink "$0")
+else
+ SCRIPT_FILE="$0"
+fi
+SCRIPT_NAME="$(basename "$SCRIPT_FILE")"
+
+DEFAULT_USER="celery"
+DEFAULT_PID_FILE="/var/run/celery/%n.pid"
+DEFAULT_LOG_FILE="/var/log/celery/%n%I.log"
+DEFAULT_LOG_LEVEL="WARNING"
+DEFAULT_NODES="celery"
+DEFAULT_CELERYD="-m celery worker --detach"
+
+if [ -d "/etc/default" ]; then
+ CELERY_CONFIG_DIR="/etc/default"
+else
+ CELERY_CONFIG_DIR="/usr/local/etc"
+fi
+
+CELERY_DEFAULTS=${CELERY_DEFAULTS:-"$CELERY_CONFIG_DIR/${SCRIPT_NAME}"}
+
+# Make sure executable configuration script is owned by root
+_config_sanity() {
+ local path="$1"
+ local owner=$(ls -ld "$path" | awk '{print $3}')
+ local iwgrp=$(ls -ld "$path" | cut -b 6)
+ local iwoth=$(ls -ld "$path" | cut -b 9)
+
+ if [ "$(id -u $owner)" != "0" ]; then
+ echo "Error: Config script '$path' must be owned by root!"
+ echo
+ echo "Resolution:"
+ echo "Review the file carefully, and make sure it hasn't been "
+ echo "modified with mailicious intent. When sure the "
+ echo "script is safe to execute with superuser privileges "
+ echo "you can change ownership of the script:"
+ echo " $ sudo chown root '$path'"
+ exit 1
+ fi
+
+ if [ "$iwoth" != "-" ]; then # S_IWOTH
+ echo "Error: Config script '$path' cannot be writable by others!"
+ echo
+ echo "Resolution:"
+ echo "Review the file carefully, and make sure it hasn't been "
+ echo "modified with malicious intent. When sure the "
+ echo "script is safe to execute with superuser privileges "
+ echo "you can change the scripts permissions:"
+ echo " $ sudo chmod 640 '$path'"
+ exit 1
+ fi
+ if [ "$iwgrp" != "-" ]; then # S_IWGRP
+ echo "Error: Config script '$path' cannot be writable by group!"
+ echo
+ echo "Resolution:"
+ echo "Review the file carefully, and make sure it hasn't been "
+ echo "modified with malicious intent. When sure the "
+ echo "script is safe to execute with superuser privileges "
+ echo "you can change the scripts permissions:"
+ echo " $ sudo chmod 640 '$path'"
+ exit 1
+ fi
+}
+
+if [ -f "$CELERY_DEFAULTS" ]; then
+ _config_sanity "$CELERY_DEFAULTS"
+ echo "Using config script: $CELERY_DEFAULTS"
+ . "$CELERY_DEFAULTS"
+fi
+
+# Sets --app argument for CELERY_BIN
+CELERY_APP_ARG=""
+if [ ! -z "$CELERY_APP" ]; then
+ CELERY_APP_ARG="--app=$CELERY_APP"
+fi
+
+# Options to su
+# can be used to enable login shell (CELERYD_SU_ARGS="-l"),
+# or even to use start-stop-daemon instead of su.
+CELERYD_SU=${CELERY_SU:-"su"}
+CELERYD_SU_ARGS=${CELERYD_SU_ARGS:-""}
+
+CELERYD_USER=${CELERYD_USER:-$DEFAULT_USER}
+
+# Set CELERY_CREATE_DIRS to always create log/pid dirs.
+CELERY_CREATE_DIRS=${CELERY_CREATE_DIRS:-0}
+CELERY_CREATE_RUNDIR=$CELERY_CREATE_DIRS
+CELERY_CREATE_LOGDIR=$CELERY_CREATE_DIRS
+if [ -z "$CELERYD_PID_FILE" ]; then
+ CELERYD_PID_FILE="$DEFAULT_PID_FILE"
+ CELERY_CREATE_RUNDIR=1
+fi
+if [ -z "$CELERYD_LOG_FILE" ]; then
+ CELERYD_LOG_FILE="$DEFAULT_LOG_FILE"
+ CELERY_CREATE_LOGDIR=1
+fi
+
+CELERYD_LOG_LEVEL=${CELERYD_LOG_LEVEL:-${CELERYD_LOGLEVEL:-$DEFAULT_LOG_LEVEL}}
+CELERY_BIN=${CELERY_BIN:-"celery"}
+CELERYD_MULTI=${CELERYD_MULTI:-"$CELERY_BIN multi"}
+CELERYD_NODES=${CELERYD_NODES:-$DEFAULT_NODES}
+
+export CELERY_LOADER
+
+if [ -n "$2" ]; then
+ CELERYD_OPTS="$CELERYD_OPTS $2"
+fi
+
+CELERYD_LOG_DIR=`dirname $CELERYD_LOG_FILE`
+CELERYD_PID_DIR=`dirname $CELERYD_PID_FILE`
+
+# Extra start-stop-daemon options, like user/group.
+if [ -n "$CELERYD_CHDIR" ]; then
+ DAEMON_OPTS="$DAEMON_OPTS --workdir=$CELERYD_CHDIR"
+fi
+
+
+check_dev_null() {
+ if [ ! -c /dev/null ]; then
+ echo "/dev/null is not a character device!"
+ exit 75 # EX_TEMPFAIL
+ fi
+}
+
+
+maybe_die() {
+ if [ $? -ne 0 ]; then
+ echo "Exiting: $* (errno $?)"
+ exit 77 # EX_NOPERM
+ fi
+}
+
+create_default_dir() {
+ if [ ! -d "$1" ]; then
+ echo "- Creating default directory: '$1'"
+ mkdir -p "$1"
+ maybe_die "Couldn't create directory $1"
+ echo "- Changing permissions of '$1' to 02755"
+ chmod 02755 "$1"
+ maybe_die "Couldn't change permissions for $1"
+ if [ -n "$CELERYD_USER" ]; then
+ echo "- Changing owner of '$1' to '$CELERYD_USER'"
+ chown "$CELERYD_USER" "$1"
+ maybe_die "Couldn't change owner of $1"
+ fi
+ if [ -n "$CELERYD_GROUP" ]; then
+ echo "- Changing group of '$1' to '$CELERYD_GROUP'"
+ chgrp "$CELERYD_GROUP" "$1"
+ maybe_die "Couldn't change group of $1"
+ fi
+ fi
+}
+
+
+check_paths() {
+ if [ $CELERY_CREATE_LOGDIR -eq 1 ]; then
+ create_default_dir "$CELERYD_LOG_DIR"
+ fi
+ if [ $CELERY_CREATE_RUNDIR -eq 1 ]; then
+ create_default_dir "$CELERYD_PID_DIR"
+ fi
+}
+
+create_paths() {
+ create_default_dir "$CELERYD_LOG_DIR"
+ create_default_dir "$CELERYD_PID_DIR"
+}
+
+export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
+
+
+_get_pidfiles () {
+ # note: multi < 3.1.14 output to stderr, not stdout, hence the redirect.
+ ${CELERYD_MULTI} expand "${CELERYD_PID_FILE}" ${CELERYD_NODES} 2>&1
+}
+
+
+_get_pids() {
+ found_pids=0
+ my_exitcode=0
+
+ for pidfile in $(_get_pidfiles); do
+ local pid=`cat "$pidfile"`
+ local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
+ if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
+ echo "bad pid file ($pidfile)"
+ one_failed=true
+ my_exitcode=1
+ else
+ found_pids=1
+ echo "$pid"
+ fi
+
+ if [ $found_pids -eq 0 ]; then
+ echo "${SCRIPT_NAME}: All nodes down"
+ exit $my_exitcode
+ fi
+ done
+}
+
+
+_chuid () {
+ ${CELERYD_SU} ${CELERYD_SU_ARGS} "$CELERYD_USER" -c "$CELERYD_MULTI $*"
+}
+
+
+start_workers () {
+ if [ ! -z "$CELERYD_ULIMIT" ]; then
+ ulimit $CELERYD_ULIMIT
+ fi
+ _chuid $* start $CELERYD_NODES $DAEMON_OPTS \
+ --pidfile="$CELERYD_PID_FILE" \
+ --logfile="$CELERYD_LOG_FILE" \
+ --loglevel="$CELERYD_LOG_LEVEL" \
+ $CELERY_APP_ARG \
+ $CELERYD_OPTS
+}
+
+
+dryrun () {
+ (C_FAKEFORK=1 start_workers --verbose)
+}
+
+
+stop_workers () {
+ _chuid stopwait $CELERYD_NODES $DAEMON_OPTS --pidfile="$CELERYD_PID_FILE"
+}
+
+
+restart_workers () {
+ _chuid restart $CELERYD_NODES $DAEMON_OPTS \
+ --pidfile="$CELERYD_PID_FILE" \
+ --logfile="$CELERYD_LOG_FILE" \
+ --loglevel="$CELERYD_LOG_LEVEL" \
+ $CELERY_APP_ARG \
+ $CELERYD_OPTS
+}
+
+
+kill_workers() {
+ _chuid kill $CELERYD_NODES $DAEMON_OPTS --pidfile="$CELERYD_PID_FILE"
+}
+
+
+restart_workers_graceful () {
+ echo "WARNING: Use with caution in production"
+ echo "The workers will attempt to restart, but they may not be able to."
+ local worker_pids=
+ worker_pids=`_get_pids`
+ [ "$one_failed" ] && exit 1
+
+ for worker_pid in $worker_pids; do
+ local failed=
+ kill -HUP $worker_pid 2> /dev/null || failed=true
+ if [ "$failed" ]; then
+ echo "${SCRIPT_NAME} worker (pid $worker_pid) could not be restarted"
+ one_failed=true
+ else
+ echo "${SCRIPT_NAME} worker (pid $worker_pid) received SIGHUP"
+ fi
+ done
+
+ [ "$one_failed" ] && exit 1 || exit 0
+}
+
+
+check_status () {
+ my_exitcode=0
+ found_pids=0
+
+ local one_failed=
+ for pidfile in $(_get_pidfiles); do
+ if [ ! -r $pidfile ]; then
+ echo "${SCRIPT_NAME} down: no pidfiles found"
+ one_failed=true
+ break
+ fi
+
+ local node=`basename "$pidfile" .pid`
+ local pid=`cat "$pidfile"`
+ local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
+ if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
+ echo "bad pid file ($pidfile)"
+ one_failed=true
+ else
+ local failed=
+ kill -0 $pid 2> /dev/null || failed=true
+ if [ "$failed" ]; then
+ echo "${SCRIPT_NAME} (node $node) (pid $pid) is down, but pidfile exists!"
+ one_failed=true
+ else
+ echo "${SCRIPT_NAME} (node $node) (pid $pid) is up..."
+ fi
+ fi
+ done
+
+ [ "$one_failed" ] && exit 1 || exit 0
+}
+
+
+case "$1" in
+ start)
+ check_dev_null
+ check_paths
+ start_workers
+ ;;
+
+ stop)
+ check_dev_null
+ check_paths
+ stop_workers
+ ;;
+
+ reload|force-reload)
+ echo "Use restart"
+ ;;
+
+ status)
+ check_status
+ ;;
+
+ restart)
+ check_dev_null
+ check_paths
+ restart_workers
+ ;;
+
+ graceful)
+ check_dev_null
+ restart_workers_graceful
+ ;;
+
+ kill)
+ check_dev_null
+ kill_workers
+ ;;
+
+ dryrun)
+ check_dev_null
+ dryrun
+ ;;
+
+ try-restart)
+ check_dev_null
+ check_paths
+ restart_workers
+ ;;
+
+ create-paths)
+ check_dev_null
+ create_paths
+ ;;
+
+ check-paths)
+ check_dev_null
+ check_paths
+ ;;
+
+ *)
+ echo "Usage: /etc/init.d/${SCRIPT_NAME} {start|stop|restart|graceful|kill|dryrun|create-paths}"
+ exit 64 # EX_USAGE
+ ;;
+esac
+
+exit 0
+{{- end }}
diff --git a/mika/telego/templates/entrypoint.sh.tpl b/mika/telego/templates/entrypoint.sh.tpl
new file mode 100644
index 00000000..2f464d90
--- /dev/null
+++ b/mika/telego/templates/entrypoint.sh.tpl
@@ -0,0 +1,16 @@
+{{/*
+APScheduler /entrypoint.sh template
+*/}}
+{{- define "telego.apscheduler-entrypoint-sh" -}}
+#!/bin/bash
+
+export APP_ROOT="base"
+
+# ================= DO NOT EDIT BEYOND THIS LINE =================
+
+python3 manage.py makemigrations
+
+python3 manage.py migrate
+
+tail -f /dev/null
+{{- end }}
diff --git a/mika/telego/templates/site-config.conf.tpl b/mika/telego/templates/site-config.conf.tpl
new file mode 100644
index 00000000..7a76c0d2
--- /dev/null
+++ b/mika/telego/templates/site-config.conf.tpl
@@ -0,0 +1,28 @@
+{{/*
+Apache site-config.conf template
+*/}}
+{{- define "telego.site-config-conf" -}}
+
+ ServerName DOMAIN:443
+ UseCanonicalName On
+ ServerAdmin support@mikahomelab.com
+ DocumentRoot /base
+ WSGIScriptAlias / /base/base/wsgi.py
+ WSGIDaemonProcess DOMAIN python-path=/base
+ WSGIProcessGroup DOMAIN
+
+
+
+ Require all granted
+
+
+
+ Alias /static /static
+
+ Require all granted
+
+
+ ErrorLog /var/log/apache2/apache.error.log
+ CustomLog /var/log/apache2/apache.access.log combined
+
+{{- end }}
diff --git a/mika/telego/templates/tasks.py.tpl b/mika/telego/templates/tasks.py.tpl
new file mode 100644
index 00000000..c0ff9486
--- /dev/null
+++ b/mika/telego/templates/tasks.py.tpl
@@ -0,0 +1,46 @@
+{{/*
+APScheduler /base/base/tasks.py template
+*/}}
+{{- define "telego.apscheduler-tasks-py" -}}
+from django.conf import settings
+from base.scheduler import object_scheduler
+from lib.telegram import clean_model
+from apscheduler.schedulers.blocking import BlockingScheduler
+
+
+SCHEDULER_TIMEZONE = getattr(settings, "SCHEDULER_TIMEZONE")
+
+
+def start():
+ scheduler = BlockingScheduler(timezone=SCHEDULER_TIMEZONE)
+
+ job_name = "clean_model"
+ scheduler.add_job(clean_model, "cron", hour=CLEAN_MODEL_HOURS, id=job_name, replace_existing=True)
+
+ job_name = "object_scheduler"
+ scheduler.add_job(object_scheduler, "cron", second="*/" + OBJECT_SCHEDULER_SECONDS, id=job_name, replace_existing=True)
+
+ scheduler.start()
+{{- end }}
+
+{{/*
+Celery /base/base/tasks.py template
+*/}}
+{{- define "telego.celery-tasks-py" -}}
+from __future__ import absolute_import, unicode_literals
+from celery import shared_task
+from base.scheduler import object_scheduler
+from lib.telegram import clean_model
+
+
+# clean model
+@shared_task
+def clean_model_task():
+ clean_model()
+
+
+# check for any objects that need to be sent
+@shared_task
+def object_scheduler_task():
+ object_scheduler()
+{{- end }}
diff --git a/mika/vpbot/Chart.yaml b/mika/vpbot/Chart.yaml
index a7cd3b1e..7e213d94 100644
--- a/mika/vpbot/Chart.yaml
+++ b/mika/vpbot/Chart.yaml
@@ -2,17 +2,16 @@ apiVersion: v2
name: vpbot
description: Vpbot is a Telegram bot with support for a number of useful features such as prayer time notifications, COVID-19 statistics, and more.
type: application
-version: 0.3.1
-appVersion: "1.5.6-stable"
+version: 0.4.0
+appVersion: "0.1.0-preview-r4-1"
keywords:
- - "vpbot"
- - "quarantine-bot"
- - "telegram"
- - "bot"
-home: "https://github.com/irfanhakim-as/quarantine-bot"
+ - "Vpbot"
+ - "Telegram"
+ - "Bot"
+home: "https://github.com/irfanhakim-as/vpbot"
icon: "https://irfanhakim-as.github.io/charts/logos/vpbot.png"
sources:
- - "https://github.com/irfanhakim-as/quarantine-bot"
+ - "https://github.com/irfanhakim-as/vpbot"
- "https://irfanhakim-as.github.io/charts/mika/vpbot"
maintainers:
- name: "Irfan Hakim"
diff --git a/mika/vpbot/README.md b/mika/vpbot/README.md
index 4264dd1d..9730c0f5 100644
--- a/mika/vpbot/README.md
+++ b/mika/vpbot/README.md
@@ -1,4 +1,4 @@
-# [`vpbot`](https://github.com/irfanhakim-as/quarantine-bot) 🔒
+# [`vpbot`](https://github.com/irfanhakim-as/vpbot) 🔒
## Prerequisites
@@ -69,12 +69,21 @@ Verify that your chart has been installed. Replace `$namespace` and `$release_na
helm ls --namespace $namespace | grep "$release_name"
```
-## How to upgrade
+### Add custom files
-After making any necessary changes to the `values.yaml` file, upgrade the desired chart. Replace `$release_name` and `$namespace` accordingly.
+To implement additional Telegram commands, create a custom `commands.py` file with a `Commands` class inheriting from `lib.telegram.BaseCommand`. Refer to `/base/lib/commands.py` from the container for more information.
+
+To add additional Telegram messages, create a custom `messages.py` file with both `MESSAGES` and `ICONS` dict. Refer to `/base/lib/messages.py` from the container for more information.
+
+Upgrade (or install) the chart while adding the `commands.py` and `messages.py files with the `--set-file` flag.
```sh
-helm upgrade $release_name mika/vpbot --namespace $namespace --values values.yaml --wait
+helm upgrade --install $release_name mika/vpbot \
+--namespace $namespace \
+--values values.yaml \
+--set-file vpbot.commands=commands.py \
+--set-file vpbot.messages=messages.py \
+--wait
```
## How to uninstall
@@ -110,33 +119,43 @@ Deploy [`mika/postgres-agent`](../postgres-agent/) with `postgres.mode.drop` set
| image.vpbot.pullPolicy | string | `""` | The policy that determines when Kubernetes should pull the Vpbot container image. Default: `"IfNotPresent"`. |
| image.vpbot.registry | string | `""` | The registry where the Vpbot container image is hosted. Default: `"ghcr.io"`. |
| image.vpbot.repository | string | `""` | The name of the repository that contains the Vpbot container image used. Default: `"irfanhakim-as/vpbot"`. |
-| image.vpbot.tag | string | `""` | The tag that specifies the version of the Vpbot container image used. Default: `"Chart appVersion"`. |
+| image.vpbot.tag | string | `""` | The tag that specifies the version of the Vpbot container image used. Default: `Chart appVersion`. |
| imagePullSecrets | list | `[]` | Credentials used to securely authenticate and authorise the pulling of container images from private registries. |
| replicaCount | string | `""` | The desired number of running replicas for Vpbot. Default: `"1"`. |
-| resources.redis.limits.cpu | string | `"15m"` | The maximum amount of CPU resources allowed for Redis. |
-| resources.redis.limits.memory | string | `"60Mi"` | The maximum amount of memory allowed for Redis. |
-| resources.redis.requests.cpu | string | `"5m"` | The minimum amount of CPU resources required by Redis. |
-| resources.redis.requests.memory | string | `"30Mi"` | The minimum amount of memory required by Redis. |
-| resources.vpbot.limits.cpu | string | `"50m"` | The maximum amount of CPU resources allowed for Vpbot. |
+| resources.ngrok.limits.cpu | string | `"20m"` | The maximum amount of CPU resources allowed for Ngrok. |
+| resources.ngrok.limits.memory | string | `"50Mi"` | The maximum amount of memory allowed for Ngrok. |
+| resources.ngrok.requests.cpu | string | `"10m"` | The minimum amount of CPU resources required by Ngrok. |
+| resources.ngrok.requests.memory | string | `"20Mi"` | The minimum amount of memory required by Ngrok. |
+| resources.scheduler.limits.cpu | string | `"20m"` | The maximum amount of CPU resources allowed for Scheduler. |
+| resources.scheduler.limits.memory | string | `"200Mi"` | The maximum amount of memory allowed for Scheduler. |
+| resources.scheduler.requests.cpu | string | `"10m"` | The minimum amount of CPU resources required by Scheduler. |
+| resources.scheduler.requests.memory | string | `"100Mi"` | The minimum amount of memory required by Scheduler. |
+| resources.vpbot.limits.cpu | string | `"200m"` | The maximum amount of CPU resources allowed for Vpbot. |
| resources.vpbot.limits.memory | string | `"500Mi"` | The maximum amount of memory allowed for Vpbot. |
-| resources.vpbot.requests.cpu | string | `"10m"` | The minimum amount of CPU resources required by Vpbot. |
-| resources.vpbot.requests.memory | string | `"250Mi"` | The minimum amount of memory required by Vpbot. |
-| telegram.admin_id | string | `""` | The unique Telegram chat ID of the Vpbot administrator. |
-| telegram.devel_id | string | `""` | The unique Telegram chat ID of the Vpbot developer. |
-| telegram.token | string | `""` | The Telegram bot token used by Vpbot to communicate with Telegram. |
-| telegram.webhook | string | `""` | The Telegram bot webhook path used by Vpbot to communicate with Telegram. Default: `"telegram/webhooks/"`. |
-| vpbot.celery_timezone | string | `""` | The timezone for the task scheduler used by Vpbot to schedule time-dependent operations. Default: `"Asia/Kuala_Lumpur"`. |
+| resources.vpbot.requests.cpu | string | `"50m"` | The minimum amount of CPU resources required by Vpbot. |
+| resources.vpbot.requests.memory | string | `"300Mi"` | The minimum amount of memory required by Vpbot. |
+| vpbot.api.solat.id | string | `""` | The API endpoint for acquiring Indonesian prayer times. Default: `"https://api.myquran.com/v1/sholat/jadwal/%s"`. |
+| vpbot.api.solat.my | string | `""` | The API endpoint for acquiring Malaysian prayer times. Default: `"https://mpt.i906.my/api/prayer/%s"`. |
| vpbot.cloudflared.domain | string | `""` | Registered domain name on Cloudflare used for Vpbot. |
| vpbot.cloudflared.enabled | bool | `false` | Specifies whether Vpbot should run using a Cloudflare tunnel. |
+| vpbot.commands | file | `""` | Custom Telegram `commands.py` file for Vpbot. |
| vpbot.debug | string | `""` | Specifies whether Vpbot should run in debug mode. Default: `false`. |
-| vpbot.log_size_limit | string | `""` | The log file size limit in megabytes. Default: `"4"`. |
+| vpbot.defaults.location | string | `""` | The default user location code used for personalised services. Default: `"wlp-0"`. |
+| vpbot.messages | file | `""` | Custom Telegram `messages.py` file for Vpbot. |
| vpbot.name | string | `""` | The name of the Vpbot service. Default: `"Vpbot"`. |
| vpbot.ngrok.enabled | bool | `false` | Specifies whether Vpbot should run using an Ngrok tunnel. |
| vpbot.ngrok.token | string | `""` | Ngrok authentication token. |
-| vpbot.persistence.enabled | bool | `false` | Specifies whether Vpbot should persist its storage. |
-| vpbot.persistence.logs.storage | string | `""` | The amount of persistent storage allocated for Vpbot logs. Default: `"50Mi"`. |
-| vpbot.persistence.migrations.storage | string | `""` | The amount of persistent storage allocated for Vpbot migration files. Default: `"50Mi"`. |
-| vpbot.persistence.static.storage | string | `""` | The amount of persistent storage allocated for Vpbot static files. Default: `"50Mi"`. |
-| vpbot.persistence.storageClassName | string | `""` | The storage class name used for dynamically provisioning a persistent volume for the Vpbot storage. Default: `"longhorn"`. |
+| vpbot.persistence.enabled | bool | `false` | Specifies whether Vpbot should persist its logs. |
+| vpbot.persistence.storage | string | `""` | The amount of persistent storage allocated for Vpbot logs. Default: `"10Mi"`. |
+| vpbot.persistence.storageClassName | string | `""` | The storage class name used for dynamically provisioning a persistent volume for the Vpbot logs storage. Default: `"longhorn"`. |
+| vpbot.scheduler.apscheduler | bool | `true` | Specifies whether APScheduler should be used by Vpbot as the task scheduler. |
+| vpbot.scheduler.celery | bool | `false` | Specifies whether Celery should be used by Vpbot as the task scheduler. |
+| vpbot.scheduler.schedule.clean_model | string | `""` | The hours at which the task scheduler cleans up the database. Default: `"0"`. |
+| vpbot.scheduler.schedule.object_scheduler | string | `""` | The second intervals at which the task scheduler sends scheduled messages. Default: `"2"`. |
+| vpbot.scheduler.schedule.solat_clean_db | string | `""` | The hours at which the task scheduler cleans up the solat module database. Default: `"0"`. |
+| vpbot.scheduler.schedule.solat_notification | string | `""` | The minute intervals at which the task scheduler sends prayer time notifications. Default: `"1"`. |
+| vpbot.scheduler.timezone | string | `""` | The timezone for the task scheduler used by Vpbot to schedule time-dependent operations. Default: `"Asia/Kuala_Lumpur"`. |
| vpbot.secret | string | `""` | A 50-character secret key used for secure session management and cryptographic operations within the Vpbot service. |
-| vpbot.user_pass | string | `""` | The default user password for users created by Vpbot. |
+| vpbot.telegram.api | string | `""` | API endpoint or URL for the Telegram bot. Default: `"https://api.telegram.org/bot"`. |
+| vpbot.telegram.token | string | `""` | The Telegram bot token used by Vpbot to communicate with Telegram. |
+| vpbot.telegram.webhook | string | `""` | The Telegram bot webhook path used by Vpbot to communicate with Telegram. Must contain a trailing slash. Default: `"webhook/telegram/"`. |
diff --git a/mika/vpbot/templates/__init__.py.tpl b/mika/vpbot/templates/__init__.py.tpl
new file mode 100644
index 00000000..b91d2497
--- /dev/null
+++ b/mika/vpbot/templates/__init__.py.tpl
@@ -0,0 +1,8 @@
+{{/*
+Celery /base/base/__init__.py template
+*/}}
+{{- define "vpbot.celery-init-py" -}}
+from .celery import app as celery_app
+
+__all__ = ("celery_app",)
+{{- end }}
diff --git a/mika/vpbot/templates/_helpers.tpl b/mika/vpbot/templates/_helpers.tpl
index 3ea9949c..d50224b3 100644
--- a/mika/vpbot/templates/_helpers.tpl
+++ b/mika/vpbot/templates/_helpers.tpl
@@ -60,37 +60,3 @@ Create the name of the service account to use
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
-
-{{/*
-Apache site-config.conf template
-*/}}
-{{- define "vpbot.site-config-conf" -}}
-
- ServerName DOMAIN:443
- UseCanonicalName On
- ServerAdmin support@mikahomelab.com
- DocumentRoot /quarantine-bot
- WSGIScriptAlias / /quarantine-bot/quarantine_bot/wsgi.py
- WSGIDaemonProcess DOMAIN python-path=/quarantine-bot
- WSGIProcessGroup DOMAIN
-
-
-
- Require all granted
-
-
-
- Alias /static /static
-
- Require all granted
-
-
- Alias /media /quarantine-bot/media
-
- Require all granted
-
-
- ErrorLog /quarantine-bot/logs/apache.error.log
- CustomLog /quarantine-bot/logs/apache.access.log combined
-
-{{- end }}
diff --git a/mika/vpbot/templates/apps.py.tpl b/mika/vpbot/templates/apps.py.tpl
new file mode 100644
index 00000000..8532292c
--- /dev/null
+++ b/mika/vpbot/templates/apps.py.tpl
@@ -0,0 +1,14 @@
+{{/*
+APScheduler /base/base/apps.py template
+*/}}
+{{- define "vpbot.apscheduler-apps-py" -}}
+from django.apps import AppConfig
+
+class BaseConfig(AppConfig):
+ name = "base"
+
+ def ready(self):
+ from . import signals
+ from . import tasks
+ tasks.start()
+{{- end }}
diff --git a/mika/vpbot/templates/celery.py.tpl b/mika/vpbot/templates/celery.py.tpl
new file mode 100644
index 00000000..3d548433
--- /dev/null
+++ b/mika/vpbot/templates/celery.py.tpl
@@ -0,0 +1,48 @@
+{{/*
+Celery /base/base/celery.py template
+*/}}
+{{- define "vpbot.celery-py" -}}
+from __future__ import absolute_import, unicode_literals
+import re
+import os
+from celery import Celery
+from celery.schedules import crontab
+from datetime import timedelta
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "base.settings")
+app = Celery("base")
+app.config_from_object("django.conf:settings", namespace="CELERY")
+app.autodiscover_tasks()
+
+
+# make integer from object scheduler seconds string
+object_scheduler_seconds = int(re.sub(r"\D", "", OBJECT_SCHEDULER_SECONDS))
+
+
+app.conf.beat_schedule = {
+ # clean telegram model
+ "telegram_clean_model" : {
+ "task" : "base.tasks.telegram_clean_model_task",
+ "schedule" : crontab(hour=CLEAN_MODEL_HOURS, minute="0"),
+ },
+ # check for any objects that need to be sent
+ "object_scheduler" : {
+ "task" : "base.tasks.object_scheduler_task",
+ "schedule" : timedelta(seconds=object_scheduler_seconds),
+ },
+ # clean solat db
+ "solat_clean_db" : {
+ "task" : "base.tasks.solat_clean_db_task",
+ "schedule" : crontab(hour=SOLAT_CLEAN_DB_HOURS, minute="0"),
+ },
+ # send prayer time notifications
+ "solat_notify_solat_times" : {
+ "task" : "base.tasks.solat_notify_solat_times_task",
+ "schedule" : crontab(minute="*/" + SOLAT_NOTIF_MINUTES),
+ },
+}
+
+
+@app.task(bind=True)
+def debug_task(self):
+ print("Request: {0!r}".format(self.request))
+{{- end }}
diff --git a/mika/vpbot/templates/celerybeat.tpl b/mika/vpbot/templates/celerybeat.tpl
new file mode 100644
index 00000000..0dbb0969
--- /dev/null
+++ b/mika/vpbot/templates/celerybeat.tpl
@@ -0,0 +1,334 @@
+{{/*
+Celery /etc/init.d/celerybeat template
+*/}}
+{{- define "vpbot.initd-celerybeat" -}}
+#!/bin/sh -e
+# =========================================================
+# celerybeat - Starts the Celery periodic task scheduler.
+# =========================================================
+#
+# :Usage: /etc/init.d/celerybeat {start|stop|force-reload|restart|try-restart|status}
+# :Configuration file: /etc/default/celerybeat or /etc/default/celeryd
+#
+# See https://docs.celeryq.dev/en/latest/userguide/daemonizing.html#generic-init-scripts
+
+### BEGIN INIT INFO
+# Provides: celerybeat
+# Required-Start: $network $local_fs $remote_fs
+# Required-Stop: $network $local_fs $remote_fs
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: celery periodic task scheduler
+### END INIT INFO
+
+# Cannot use set -e/bash -e since the kill -0 command will abort
+# abnormally in the absence of a valid process ID.
+#set -e
+VERSION=10.1
+echo "celery init v${VERSION}."
+
+if [ $(id -u) -ne 0 ]; then
+ echo "Error: This program can only be used by the root user."
+ echo " Unprivileged users must use 'celery beat --detach'"
+ exit 1
+fi
+
+origin_is_runlevel_dir () {
+ set +e
+ dirname $0 | grep -q "/etc/rc.\.d"
+ echo $?
+}
+
+# Can be a runlevel symlink (e.g., S02celeryd)
+if [ $(origin_is_runlevel_dir) -eq 0 ]; then
+ SCRIPT_FILE=$(readlink "$0")
+else
+ SCRIPT_FILE="$0"
+fi
+SCRIPT_NAME="$(basename "$SCRIPT_FILE")"
+
+# /etc/init.d/celerybeat: start and stop the celery periodic task scheduler daemon.
+
+# Make sure executable configuration script is owned by root
+_config_sanity() {
+ local path="$1"
+ local owner=$(ls -ld "$path" | awk '{print $3}')
+ local iwgrp=$(ls -ld "$path" | cut -b 6)
+ local iwoth=$(ls -ld "$path" | cut -b 9)
+
+ if [ "$(id -u $owner)" != "0" ]; then
+ echo "Error: Config script '$path' must be owned by root!"
+ echo
+ echo "Resolution:"
+ echo "Review the file carefully, and make sure it hasn't been "
+ echo "modified with mailicious intent. When sure the "
+ echo "script is safe to execute with superuser privileges "
+ echo "you can change ownership of the script:"
+ echo " $ sudo chown root '$path'"
+ exit 1
+ fi
+
+ if [ "$iwoth" != "-" ]; then # S_IWOTH
+ echo "Error: Config script '$path' cannot be writable by others!"
+ echo
+ echo "Resolution:"
+ echo "Review the file carefully, and make sure it hasn't been "
+ echo "modified with malicious intent. When sure the "
+ echo "script is safe to execute with superuser privileges "
+ echo "you can change the scripts permissions:"
+ echo " $ sudo chmod 640 '$path'"
+ exit 1
+ fi
+ if [ "$iwgrp" != "-" ]; then # S_IWGRP
+ echo "Error: Config script '$path' cannot be writable by group!"
+ echo
+ echo "Resolution:"
+ echo "Review the file carefully, and make sure it hasn't been "
+ echo "modified with malicious intent. When sure the "
+ echo "script is safe to execute with superuser privileges "
+ echo "you can change the scripts permissions:"
+ echo " $ sudo chmod 640 '$path'"
+ exit 1
+ fi
+}
+
+scripts=""
+
+if test -f /etc/default/celeryd; then
+ scripts="/etc/default/celeryd"
+ _config_sanity /etc/default/celeryd
+ . /etc/default/celeryd
+fi
+
+EXTRA_CONFIG="/etc/default/${SCRIPT_NAME}"
+if test -f "$EXTRA_CONFIG"; then
+ scripts="$scripts, $EXTRA_CONFIG"
+ _config_sanity "$EXTRA_CONFIG"
+ . "$EXTRA_CONFIG"
+fi
+
+echo "Using configuration: $scripts"
+
+CELERY_BIN=${CELERY_BIN:-"celery"}
+DEFAULT_USER="celery"
+DEFAULT_PID_FILE="/var/run/celery/beat.pid"
+DEFAULT_LOG_FILE="/var/log/celery/beat.log"
+DEFAULT_LOG_LEVEL="WARNING"
+DEFAULT_CELERYBEAT="$CELERY_BIN"
+
+CELERYBEAT=${CELERYBEAT:-$DEFAULT_CELERYBEAT}
+CELERYBEAT_LOG_LEVEL=${CELERYBEAT_LOG_LEVEL:-${CELERYBEAT_LOGLEVEL:-$DEFAULT_LOG_LEVEL}}
+
+CELERYBEAT_SU=${CELERYBEAT_SU:-"su"}
+CELERYBEAT_SU_ARGS=${CELERYBEAT_SU_ARGS:-""}
+
+# Sets --app argument for CELERY_BIN
+CELERY_APP_ARG=""
+if [ ! -z "$CELERY_APP" ]; then
+ CELERY_APP_ARG="--app=$CELERY_APP"
+fi
+
+CELERYBEAT_USER=${CELERYBEAT_USER:-${CELERYD_USER:-$DEFAULT_USER}}
+
+# Set CELERY_CREATE_DIRS to always create log/pid dirs.
+CELERY_CREATE_DIRS=${CELERY_CREATE_DIRS:-0}
+CELERY_CREATE_RUNDIR=$CELERY_CREATE_DIRS
+CELERY_CREATE_LOGDIR=$CELERY_CREATE_DIRS
+if [ -z "$CELERYBEAT_PID_FILE" ]; then
+ CELERYBEAT_PID_FILE="$DEFAULT_PID_FILE"
+ CELERY_CREATE_RUNDIR=1
+fi
+if [ -z "$CELERYBEAT_LOG_FILE" ]; then
+ CELERYBEAT_LOG_FILE="$DEFAULT_LOG_FILE"
+ CELERY_CREATE_LOGDIR=1
+fi
+
+export CELERY_LOADER
+
+if [ -n "$2" ]; then
+ CELERYBEAT_OPTS="$CELERYBEAT_OPTS $2"
+fi
+
+CELERYBEAT_LOG_DIR=`dirname $CELERYBEAT_LOG_FILE`
+CELERYBEAT_PID_DIR=`dirname $CELERYBEAT_PID_FILE`
+
+# Extra start-stop-daemon options, like user/group.
+
+CELERYBEAT_CHDIR=${CELERYBEAT_CHDIR:-$CELERYD_CHDIR}
+if [ -n "$CELERYBEAT_CHDIR" ]; then
+ DAEMON_OPTS="$DAEMON_OPTS --workdir=$CELERYBEAT_CHDIR"
+fi
+
+
+export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
+
+check_dev_null() {
+ if [ ! -c /dev/null ]; then
+ echo "/dev/null is not a character device!"
+ exit 75 # EX_TEMPFAIL
+ fi
+}
+
+maybe_die() {
+ if [ $? -ne 0 ]; then
+ echo "Exiting: $*"
+ exit 77 # EX_NOPERM
+ fi
+}
+
+create_default_dir() {
+ if [ ! -d "$1" ]; then
+ echo "- Creating default directory: '$1'"
+ mkdir -p "$1"
+ maybe_die "Couldn't create directory $1"
+ echo "- Changing permissions of '$1' to 02755"
+ chmod 02755 "$1"
+ maybe_die "Couldn't change permissions for $1"
+ if [ -n "$CELERYBEAT_USER" ]; then
+ echo "- Changing owner of '$1' to '$CELERYBEAT_USER'"
+ chown "$CELERYBEAT_USER" "$1"
+ maybe_die "Couldn't change owner of $1"
+ fi
+ if [ -n "$CELERYBEAT_GROUP" ]; then
+ echo "- Changing group of '$1' to '$CELERYBEAT_GROUP'"
+ chgrp "$CELERYBEAT_GROUP" "$1"
+ maybe_die "Couldn't change group of $1"
+ fi
+ fi
+}
+
+check_paths() {
+ if [ $CELERY_CREATE_LOGDIR -eq 1 ]; then
+ create_default_dir "$CELERYBEAT_LOG_DIR"
+ fi
+ if [ $CELERY_CREATE_RUNDIR -eq 1 ]; then
+ create_default_dir "$CELERYBEAT_PID_DIR"
+ fi
+}
+
+
+create_paths () {
+ create_default_dir "$CELERYBEAT_LOG_DIR"
+ create_default_dir "$CELERYBEAT_PID_DIR"
+}
+
+is_running() {
+ pid=$1
+ ps $pid > /dev/null 2>&1
+}
+
+wait_pid () {
+ pid=$1
+ forever=1
+ i=0
+ while [ $forever -gt 0 ]; do
+ if ! is_running $pid; then
+ echo "OK"
+ forever=0
+ else
+ kill -TERM "$pid"
+ i=$((i + 1))
+ if [ $i -gt 60 ]; then
+ echo "ERROR"
+ echo "Timed out while stopping (30s)"
+ forever=0
+ else
+ sleep 0.5
+ fi
+ fi
+ done
+}
+
+
+stop_beat () {
+ echo -n "Stopping ${SCRIPT_NAME}... "
+ if [ -f "$CELERYBEAT_PID_FILE" ]; then
+ wait_pid $(cat "$CELERYBEAT_PID_FILE")
+ else
+ echo "NOT RUNNING"
+ fi
+}
+
+_chuid () {
+ ${CELERYBEAT_SU} ${CELERYBEAT_SU_ARGS} \
+ "$CELERYBEAT_USER" -c "$CELERYBEAT $*"
+}
+
+start_beat () {
+ echo "Starting ${SCRIPT_NAME}..."
+ _chuid $CELERY_APP_ARG $DAEMON_OPTS beat --detach \
+ --pidfile="$CELERYBEAT_PID_FILE" \
+ --logfile="$CELERYBEAT_LOG_FILE" \
+ --loglevel="$CELERYBEAT_LOG_LEVEL" \
+ $CELERYBEAT_OPTS
+}
+
+
+check_status () {
+ local failed=
+ local pid_file=$CELERYBEAT_PID_FILE
+ if [ ! -e $pid_file ]; then
+ echo "${SCRIPT_NAME} is down: no pid file found"
+ failed=true
+ elif [ ! -r $pid_file ]; then
+ echo "${SCRIPT_NAME} is in unknown state, user cannot read pid file."
+ failed=true
+ else
+ local pid=`cat "$pid_file"`
+ local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
+ if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
+ echo "${SCRIPT_NAME}: bad pid file ($pid_file)"
+ failed=true
+ else
+ local failed=
+ kill -0 $pid 2> /dev/null || failed=true
+ if [ "$failed" ]; then
+ echo "${SCRIPT_NAME} (pid $pid) is down, but pid file exists!"
+ failed=true
+ else
+ echo "${SCRIPT_NAME} (pid $pid) is up..."
+ fi
+ fi
+ fi
+
+ [ "$failed" ] && exit 1 || exit 0
+}
+
+
+case "$1" in
+ start)
+ check_dev_null
+ check_paths
+ start_beat
+ ;;
+ stop)
+ check_paths
+ stop_beat
+ ;;
+ reload|force-reload)
+ echo "Use start+stop"
+ ;;
+ status)
+ check_status
+ ;;
+ restart)
+ echo "Restarting celery periodic task scheduler"
+ check_paths
+ stop_beat && check_dev_null && start_beat
+ ;;
+ create-paths)
+ check_dev_null
+ create_paths
+ ;;
+ check-paths)
+ check_dev_null
+ check_paths
+ ;;
+ *)
+ echo "Usage: /etc/init.d/${SCRIPT_NAME} {start|stop|restart|create-paths|status}"
+ exit 64 # EX_USAGE
+ ;;
+esac
+
+exit 0
+{{- end }}
diff --git a/mika/vpbot/templates/celeryd.tpl b/mika/vpbot/templates/celeryd.tpl
new file mode 100644
index 00000000..8d60608e
--- /dev/null
+++ b/mika/vpbot/templates/celeryd.tpl
@@ -0,0 +1,476 @@
+{{/*
+Celery /etc/default/celeryd template
+*/}}
+{{- define "vpbot.default-celeryd" -}}
+# Names of nodes to start
+# most people will only start one node:
+#CELERYD_NODES="worker1"
+# but you can also start multiple and configure settings
+# for each in CELERYD_OPTS
+#CELERYD_NODES="worker1 worker2 worker3"
+# alternatively, you can specify the number of nodes to start:
+#CELERYD_NODES=10
+CELERYD_NODES="worker1"
+
+# Absolute or relative path to the 'celery' command:
+#CELERY_BIN="/usr/local/bin/celery"
+#CELERY_BIN="/virtualenvs/def/bin/celery"
+CELERY_BIN="/usr/local/bin/celery"
+
+# App instance to use
+# comment out this line if you don't use an app
+#CELERY_APP="proj"
+# or fully qualified:
+#CELERY_APP="proj.tasks:app"
+CELERY_APP="base"
+
+# Where to chdir at start.
+#CELERYD_CHDIR="/opt/Myproject/"
+CELERYD_CHDIR="/base/"
+
+# Extra command-line arguments to the worker
+#CELERYD_OPTS="--time-limit=300 --concurrency=8"
+# Configure node-specific settings by appending node name to arguments:
+#CELERYD_OPTS="--time-limit=300 -c 8 -c:worker2 4 -c:worker3 2 -Ofair:worker1"
+CELERYD_OPTS="--time-limit=300 --concurrency=8 --without-gossip --without-mingle --without-heartbeat -Ofair --pool=solo"
+
+# Set logging level
+#CELERYD_LOG_LEVEL="DEBUG"
+CELERYD_LOG_LEVEL="WARNING"
+
+# %n will be replaced with the first part of the nodename.
+#CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
+#CELERYD_PID_FILE="/var/run/celery/%n.pid"
+CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
+CELERYD_PID_FILE="/var/run/celery/%n.pid"
+
+# Workers should run as an unprivileged user.
+# You need to create this user manually (or you can choose
+# a user/group combination that already exists (e.g., nobody).
+#CELERYD_USER="celery"
+#CELERYD_GROUP="celery"
+CELERYD_USER="root"
+CELERYD_GROUP="root"
+
+# If enabled pid and log directories will be created if missing,
+# and owned by the userid/group configured.
+#CELERY_CREATE_DIRS=1
+CELERY_CREATE_DIRS=1
+{{- end }}
+
+{{/*
+Celery /etc/init.d/celeryd template
+*/}}
+{{- define "vpbot.initd-celeryd" -}}
+#!/bin/sh -e
+# ============================================
+# celeryd - Starts the Celery worker daemon.
+# ============================================
+#
+# :Usage: /etc/init.d/celeryd {start|stop|force-reload|restart|try-restart|status}
+# :Configuration file: /etc/default/celeryd (or /usr/local/etc/celeryd on BSD)
+#
+# See https://docs.celeryq.dev/en/latest/userguide/daemonizing.html#generic-init-scripts
+
+
+### BEGIN INIT INFO
+# Provides: celeryd
+# Required-Start: $network $local_fs $remote_fs
+# Required-Stop: $network $local_fs $remote_fs
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: celery task worker daemon
+### END INIT INFO
+#
+#
+# To implement separate init-scripts, copy this script and give it a different
+# name. That is, if your new application named "little-worker" needs an init,
+# you should use:
+#
+# cp /etc/init.d/celeryd /etc/init.d/little-worker
+#
+# You can then configure this by manipulating /etc/default/little-worker.
+#
+VERSION=10.1
+echo "celery init v${VERSION}."
+if [ $(id -u) -ne 0 ]; then
+ echo "Error: This program can only be used by the root user."
+ echo " Unprivileged users must use the 'celery multi' utility, "
+ echo " or 'celery worker --detach'."
+ exit 1
+fi
+
+origin_is_runlevel_dir () {
+ set +e
+ dirname $0 | grep -q "/etc/rc.\.d"
+ echo $?
+}
+
+# Can be a runlevel symlink (e.g., S02celeryd)
+if [ $(origin_is_runlevel_dir) -eq 0 ]; then
+ SCRIPT_FILE=$(readlink "$0")
+else
+ SCRIPT_FILE="$0"
+fi
+SCRIPT_NAME="$(basename "$SCRIPT_FILE")"
+
+DEFAULT_USER="celery"
+DEFAULT_PID_FILE="/var/run/celery/%n.pid"
+DEFAULT_LOG_FILE="/var/log/celery/%n%I.log"
+DEFAULT_LOG_LEVEL="WARNING"
+DEFAULT_NODES="celery"
+DEFAULT_CELERYD="-m celery worker --detach"
+
+if [ -d "/etc/default" ]; then
+ CELERY_CONFIG_DIR="/etc/default"
+else
+ CELERY_CONFIG_DIR="/usr/local/etc"
+fi
+
+CELERY_DEFAULTS=${CELERY_DEFAULTS:-"$CELERY_CONFIG_DIR/${SCRIPT_NAME}"}
+
+# Make sure executable configuration script is owned by root
+_config_sanity() {
+ local path="$1"
+ local owner=$(ls -ld "$path" | awk '{print $3}')
+ local iwgrp=$(ls -ld "$path" | cut -b 6)
+ local iwoth=$(ls -ld "$path" | cut -b 9)
+
+ if [ "$(id -u $owner)" != "0" ]; then
+ echo "Error: Config script '$path' must be owned by root!"
+ echo
+ echo "Resolution:"
+ echo "Review the file carefully, and make sure it hasn't been "
+ echo "modified with mailicious intent. When sure the "
+ echo "script is safe to execute with superuser privileges "
+ echo "you can change ownership of the script:"
+ echo " $ sudo chown root '$path'"
+ exit 1
+ fi
+
+ if [ "$iwoth" != "-" ]; then # S_IWOTH
+ echo "Error: Config script '$path' cannot be writable by others!"
+ echo
+ echo "Resolution:"
+ echo "Review the file carefully, and make sure it hasn't been "
+ echo "modified with malicious intent. When sure the "
+ echo "script is safe to execute with superuser privileges "
+ echo "you can change the scripts permissions:"
+ echo " $ sudo chmod 640 '$path'"
+ exit 1
+ fi
+ if [ "$iwgrp" != "-" ]; then # S_IWGRP
+ echo "Error: Config script '$path' cannot be writable by group!"
+ echo
+ echo "Resolution:"
+ echo "Review the file carefully, and make sure it hasn't been "
+ echo "modified with malicious intent. When sure the "
+ echo "script is safe to execute with superuser privileges "
+ echo "you can change the scripts permissions:"
+ echo " $ sudo chmod 640 '$path'"
+ exit 1
+ fi
+}
+
+if [ -f "$CELERY_DEFAULTS" ]; then
+ _config_sanity "$CELERY_DEFAULTS"
+ echo "Using config script: $CELERY_DEFAULTS"
+ . "$CELERY_DEFAULTS"
+fi
+
+# Sets --app argument for CELERY_BIN
+CELERY_APP_ARG=""
+if [ ! -z "$CELERY_APP" ]; then
+ CELERY_APP_ARG="--app=$CELERY_APP"
+fi
+
+# Options to su
+# can be used to enable login shell (CELERYD_SU_ARGS="-l"),
+# or even to use start-stop-daemon instead of su.
+CELERYD_SU=${CELERY_SU:-"su"}
+CELERYD_SU_ARGS=${CELERYD_SU_ARGS:-""}
+
+CELERYD_USER=${CELERYD_USER:-$DEFAULT_USER}
+
+# Set CELERY_CREATE_DIRS to always create log/pid dirs.
+CELERY_CREATE_DIRS=${CELERY_CREATE_DIRS:-0}
+CELERY_CREATE_RUNDIR=$CELERY_CREATE_DIRS
+CELERY_CREATE_LOGDIR=$CELERY_CREATE_DIRS
+if [ -z "$CELERYD_PID_FILE" ]; then
+ CELERYD_PID_FILE="$DEFAULT_PID_FILE"
+ CELERY_CREATE_RUNDIR=1
+fi
+if [ -z "$CELERYD_LOG_FILE" ]; then
+ CELERYD_LOG_FILE="$DEFAULT_LOG_FILE"
+ CELERY_CREATE_LOGDIR=1
+fi
+
+CELERYD_LOG_LEVEL=${CELERYD_LOG_LEVEL:-${CELERYD_LOGLEVEL:-$DEFAULT_LOG_LEVEL}}
+CELERY_BIN=${CELERY_BIN:-"celery"}
+CELERYD_MULTI=${CELERYD_MULTI:-"$CELERY_BIN multi"}
+CELERYD_NODES=${CELERYD_NODES:-$DEFAULT_NODES}
+
+export CELERY_LOADER
+
+if [ -n "$2" ]; then
+ CELERYD_OPTS="$CELERYD_OPTS $2"
+fi
+
+CELERYD_LOG_DIR=`dirname $CELERYD_LOG_FILE`
+CELERYD_PID_DIR=`dirname $CELERYD_PID_FILE`
+
+# Extra start-stop-daemon options, like user/group.
+if [ -n "$CELERYD_CHDIR" ]; then
+ DAEMON_OPTS="$DAEMON_OPTS --workdir=$CELERYD_CHDIR"
+fi
+
+
+check_dev_null() {
+ if [ ! -c /dev/null ]; then
+ echo "/dev/null is not a character device!"
+ exit 75 # EX_TEMPFAIL
+ fi
+}
+
+
+maybe_die() {
+ if [ $? -ne 0 ]; then
+ echo "Exiting: $* (errno $?)"
+ exit 77 # EX_NOPERM
+ fi
+}
+
+create_default_dir() {
+ if [ ! -d "$1" ]; then
+ echo "- Creating default directory: '$1'"
+ mkdir -p "$1"
+ maybe_die "Couldn't create directory $1"
+ echo "- Changing permissions of '$1' to 02755"
+ chmod 02755 "$1"
+ maybe_die "Couldn't change permissions for $1"
+ if [ -n "$CELERYD_USER" ]; then
+ echo "- Changing owner of '$1' to '$CELERYD_USER'"
+ chown "$CELERYD_USER" "$1"
+ maybe_die "Couldn't change owner of $1"
+ fi
+ if [ -n "$CELERYD_GROUP" ]; then
+ echo "- Changing group of '$1' to '$CELERYD_GROUP'"
+ chgrp "$CELERYD_GROUP" "$1"
+ maybe_die "Couldn't change group of $1"
+ fi
+ fi
+}
+
+
+check_paths() {
+ if [ $CELERY_CREATE_LOGDIR -eq 1 ]; then
+ create_default_dir "$CELERYD_LOG_DIR"
+ fi
+ if [ $CELERY_CREATE_RUNDIR -eq 1 ]; then
+ create_default_dir "$CELERYD_PID_DIR"
+ fi
+}
+
+create_paths() {
+ create_default_dir "$CELERYD_LOG_DIR"
+ create_default_dir "$CELERYD_PID_DIR"
+}
+
+export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
+
+
+_get_pidfiles () {
+ # note: multi < 3.1.14 output to stderr, not stdout, hence the redirect.
+ ${CELERYD_MULTI} expand "${CELERYD_PID_FILE}" ${CELERYD_NODES} 2>&1
+}
+
+
+_get_pids() {
+ found_pids=0
+ my_exitcode=0
+
+ for pidfile in $(_get_pidfiles); do
+ local pid=`cat "$pidfile"`
+ local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
+ if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
+ echo "bad pid file ($pidfile)"
+ one_failed=true
+ my_exitcode=1
+ else
+ found_pids=1
+ echo "$pid"
+ fi
+
+ if [ $found_pids -eq 0 ]; then
+ echo "${SCRIPT_NAME}: All nodes down"
+ exit $my_exitcode
+ fi
+ done
+}
+
+
+_chuid () {
+ ${CELERYD_SU} ${CELERYD_SU_ARGS} "$CELERYD_USER" -c "$CELERYD_MULTI $*"
+}
+
+
+start_workers () {
+ if [ ! -z "$CELERYD_ULIMIT" ]; then
+ ulimit $CELERYD_ULIMIT
+ fi
+ _chuid $* start $CELERYD_NODES $DAEMON_OPTS \
+ --pidfile="$CELERYD_PID_FILE" \
+ --logfile="$CELERYD_LOG_FILE" \
+ --loglevel="$CELERYD_LOG_LEVEL" \
+ $CELERY_APP_ARG \
+ $CELERYD_OPTS
+}
+
+
+dryrun () {
+ (C_FAKEFORK=1 start_workers --verbose)
+}
+
+
+stop_workers () {
+ _chuid stopwait $CELERYD_NODES $DAEMON_OPTS --pidfile="$CELERYD_PID_FILE"
+}
+
+
+restart_workers () {
+ _chuid restart $CELERYD_NODES $DAEMON_OPTS \
+ --pidfile="$CELERYD_PID_FILE" \
+ --logfile="$CELERYD_LOG_FILE" \
+ --loglevel="$CELERYD_LOG_LEVEL" \
+ $CELERY_APP_ARG \
+ $CELERYD_OPTS
+}
+
+
+kill_workers() {
+ _chuid kill $CELERYD_NODES $DAEMON_OPTS --pidfile="$CELERYD_PID_FILE"
+}
+
+
+restart_workers_graceful () {
+ echo "WARNING: Use with caution in production"
+ echo "The workers will attempt to restart, but they may not be able to."
+ local worker_pids=
+ worker_pids=`_get_pids`
+ [ "$one_failed" ] && exit 1
+
+ for worker_pid in $worker_pids; do
+ local failed=
+ kill -HUP $worker_pid 2> /dev/null || failed=true
+ if [ "$failed" ]; then
+ echo "${SCRIPT_NAME} worker (pid $worker_pid) could not be restarted"
+ one_failed=true
+ else
+ echo "${SCRIPT_NAME} worker (pid $worker_pid) received SIGHUP"
+ fi
+ done
+
+ [ "$one_failed" ] && exit 1 || exit 0
+}
+
+
+check_status () {
+ my_exitcode=0
+ found_pids=0
+
+ local one_failed=
+ for pidfile in $(_get_pidfiles); do
+ if [ ! -r $pidfile ]; then
+ echo "${SCRIPT_NAME} down: no pidfiles found"
+ one_failed=true
+ break
+ fi
+
+ local node=`basename "$pidfile" .pid`
+ local pid=`cat "$pidfile"`
+ local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
+ if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
+ echo "bad pid file ($pidfile)"
+ one_failed=true
+ else
+ local failed=
+ kill -0 $pid 2> /dev/null || failed=true
+ if [ "$failed" ]; then
+ echo "${SCRIPT_NAME} (node $node) (pid $pid) is down, but pidfile exists!"
+ one_failed=true
+ else
+ echo "${SCRIPT_NAME} (node $node) (pid $pid) is up..."
+ fi
+ fi
+ done
+
+ [ "$one_failed" ] && exit 1 || exit 0
+}
+
+
+case "$1" in
+ start)
+ check_dev_null
+ check_paths
+ start_workers
+ ;;
+
+ stop)
+ check_dev_null
+ check_paths
+ stop_workers
+ ;;
+
+ reload|force-reload)
+ echo "Use restart"
+ ;;
+
+ status)
+ check_status
+ ;;
+
+ restart)
+ check_dev_null
+ check_paths
+ restart_workers
+ ;;
+
+ graceful)
+ check_dev_null
+ restart_workers_graceful
+ ;;
+
+ kill)
+ check_dev_null
+ kill_workers
+ ;;
+
+ dryrun)
+ check_dev_null
+ dryrun
+ ;;
+
+ try-restart)
+ check_dev_null
+ check_paths
+ restart_workers
+ ;;
+
+ create-paths)
+ check_dev_null
+ create_paths
+ ;;
+
+ check-paths)
+ check_dev_null
+ check_paths
+ ;;
+
+ *)
+ echo "Usage: /etc/init.d/${SCRIPT_NAME} {start|stop|restart|graceful|kill|dryrun|create-paths}"
+ exit 64 # EX_USAGE
+ ;;
+esac
+
+exit 0
+{{- end }}
diff --git a/mika/vpbot/templates/configmap.yaml b/mika/vpbot/templates/configmap.yaml
index a1d027dd..d527ff18 100644
--- a/mika/vpbot/templates/configmap.yaml
+++ b/mika/vpbot/templates/configmap.yaml
@@ -1,13 +1,23 @@
{{- $name := .Values.vpbot.name | default "Vpbot" | toString | quote }}
{{- $debug := .Values.vpbot.debug | default "false" | toString | quote }}
+{{- $solat_api_id := .Values.vpbot.api.solat.id | default "https://api.myquran.com/v1/sholat/jadwal/%s" | toString | quote }}
+{{- $solat_api_my := .Values.vpbot.api.solat.my | default "https://mpt.i906.my/api/prayer/%s" | toString | quote }}
+{{- $location := .Values.vpbot.defaults.location | default "wlp-0" | toString | quote }}
+{{- $api := .Values.vpbot.telegram.api | default "https://api.telegram.org/bot" | toString | quote }}
+{{- $webhook := .Values.vpbot.telegram.webhook | default "webhook/telegram/" | toString | quote }}
{{- $redis_service := printf "redis://%s-vpbot-svc" .Release.Name | quote }}
-{{- $celery_timezone := .Values.vpbot.celery_timezone | default "Asia/Kuala_Lumpur" | toString | quote }}
-{{- $webhook := .Values.telegram.webhook | default "telegram/webhooks/" | toString | quote }}
-{{- $log_size_limit := .Values.vpbot.log_size_limit | default "4" | toString | quote }}
-{{- $app_version := .Values.image.vpbot.tag | default .Chart.AppVersion | toString | quote }}
+{{- $scheduler_timezone := .Values.vpbot.scheduler.timezone | default "Asia/Kuala_Lumpur" | toString | quote }}
{{- $domain := .Values.vpbot.cloudflared.domain | default "localhost" | toString }}
+{{- $clean_model := .Values.vpbot.scheduler.schedule.clean_model | default "0" | toString | quote }}
+{{- $object_scheduler := .Values.vpbot.scheduler.schedule.object_scheduler | default "2" | toString | quote }}
+{{- $solat_clean_db := .Values.vpbot.scheduler.schedule.solat_clean_db | default "0" | toString | quote }}
+{{- $solat_notification := .Values.vpbot.scheduler.schedule.solat_notification | default "1" | toString | quote }}
+{{- $apscheduler := .Values.vpbot.scheduler.apscheduler }}
+{{- $celery := .Values.vpbot.scheduler.celery }}
{{- $cloudflared := .Values.vpbot.cloudflared.enabled }}
{{- $ngrok := .Values.vpbot.ngrok.enabled }}
+{{- $commands := .Values.vpbot.commands }}
+{{- $messages := .Values.vpbot.messages }}
apiVersion: v1
kind: ConfigMap
metadata:
@@ -17,16 +27,22 @@ metadata:
data:
APP_NAME: {{ $name }}
DEBUG: {{ $debug }}
- CELERY_BROKER: {{ $redis_service }}
- CELERY_BACKEND: {{ $redis_service }}
- CELERY_TIMEZONE: {{ $celery_timezone }}
+ PRAY_API_ID_URI: {{ $solat_api_id }}
+ PRAY_API_MY_URI: {{ $solat_api_my }}
+ DEFAULT_LOCATION_CODE: {{ $location }}
+ TELEGRAM_BOT_API_URL: {{ $api }}
+ TELEGRAM_WEBHOOK_PATH: {{ $webhook }}
NGROK: {{ $ngrok | toString | quote }}
- DJANGO_WEBHOOK_URI: {{ $webhook }}
- LOG_SIZE_LIMIT: {{ $log_size_limit }}
- APP_VERSION: {{ $app_version }}
{{- if $cloudflared }}
DOMAIN: {{ $domain | quote }}
{{- end }}
+ {{- if or $apscheduler $celery }}
+ SCHEDULER_TIMEZONE: {{ $scheduler_timezone }}
+ {{- end }}
+ {{- if $celery }}
+ CELERY_BROKER: {{ $redis_service }}
+ CELERY_BACKEND: {{ $redis_service }}
+ {{- end }}
---
apiVersion: v1
kind: ConfigMap
@@ -37,3 +53,87 @@ metadata:
data:
site-config.conf: |-
{{- include "vpbot.site-config-conf" . | replace "DOMAIN" $domain | nindent 4 }}
+{{- if $apscheduler }}
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ .Release.Name }}-vpbot-apscheduler-config
+ labels:
+ {{- include "vpbot.labels" . | nindent 4 }}
+data:
+ entrypoint.sh: |-
+ {{- include "vpbot.apscheduler-entrypoint-sh" . | nindent 4 }}
+{{- else if $celery }}
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ .Release.Name }}-vpbot-default-celery-config
+ labels:
+ {{- include "vpbot.labels" . | nindent 4 }}
+data:
+ celeryd: |-
+ {{- include "vpbot.default-celeryd" . | nindent 4 }}
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ .Release.Name }}-vpbot-initd-celery-config
+ labels:
+ {{- include "vpbot.labels" . | nindent 4 }}
+data:
+ celerybeat: |-
+ {{- include "vpbot.initd-celerybeat" . | nindent 4 }}
+ celeryd: |-
+ {{- include "vpbot.initd-celeryd" . | nindent 4 }}
+{{- end }}
+{{- if or $apscheduler $celery }}
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ .Release.Name }}-vpbot-scheduler-config
+ labels:
+ {{- include "vpbot.labels" . | nindent 4 }}
+data:
+ tasks.py: |-
+ {{- if $apscheduler }}
+ {{- include "vpbot.apscheduler-tasks-py" . | replace "CLEAN_MODEL_HOURS" $clean_model | replace "OBJECT_SCHEDULER_SECONDS" $object_scheduler | replace "SOLAT_CLEAN_DB_HOURS" $solat_clean_db | replace "SOLAT_NOTIF_MINUTES" $solat_notification | nindent 4 }}
+ {{- else if $celery }}
+ {{- include "vpbot.celery-tasks-py" . | nindent 4 }}
+ {{- end }}
+ {{- if $apscheduler }}
+ apps.py: |-
+ {{- include "vpbot.apscheduler-apps-py" . | nindent 4 }}
+ {{- else if $celery }}
+ celery.py: |-
+ {{- include "vpbot.celery-py" . | replace "CLEAN_MODEL_HOURS" $clean_model | replace "OBJECT_SCHEDULER_SECONDS" $object_scheduler | replace "SOLAT_CLEAN_DB_HOURS" $solat_clean_db | replace "SOLAT_NOTIF_MINUTES" $solat_notification | nindent 4 }}
+ init.py: |-
+ {{- include "vpbot.celery-init-py" . | nindent 4 }}
+ {{- end }}
+{{- end }}
+{{- if $commands }}
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ .Release.Name }}-vpbot-commands-cm
+ labels:
+ {{- include "vpbot.labels" . | nindent 4 }}
+data:
+ commands.py: |-
+ {{ $commands | toString | nindent 4 | trim }}
+{{- end }}
+{{- if $messages }}
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ .Release.Name }}-vpbot-messages-cm
+ labels:
+ {{- include "vpbot.labels" . | nindent 4 }}
+data:
+ messages.py: |-
+ {{ $messages | toString | nindent 4 | trim }}
+{{- end }}
diff --git a/mika/vpbot/templates/deployment.yaml b/mika/vpbot/templates/deployment.yaml
index b6c063a6..64c051fe 100644
--- a/mika/vpbot/templates/deployment.yaml
+++ b/mika/vpbot/templates/deployment.yaml
@@ -1,8 +1,8 @@
{{- $replica_count := .Values.replicaCount | default "1" | toString }}
-{{- $vpbot_registry := .Values.image.vpbot.registry | default "ghcr.io" | toString }}
-{{- $vpbot_repository := .Values.image.vpbot.repository | default "irfanhakim-as/quarantine-bot" | toString }}
-{{- $vpbot_tag := .Values.image.vpbot.tag | default .Chart.AppVersion | toString }}
-{{- $vpbot_pullPolicy := .Values.image.vpbot.pullPolicy | default "IfNotPresent" | toString | quote }}
+{{- $telego_registry := .Values.image.vpbot.registry | default "ghcr.io" | toString }}
+{{- $telego_repository := .Values.image.vpbot.repository | default "irfanhakim-as/vpbot" | toString }}
+{{- $telego_tag := .Values.image.vpbot.tag | default .Chart.AppVersion | toString }}
+{{- $telego_pullPolicy := .Values.image.vpbot.pullPolicy | default "IfNotPresent" | toString | quote }}
{{- $redis_registry := .Values.image.redis.registry | default "docker.io" | toString }}
{{- $redis_repository := .Values.image.redis.repository | default "redis" | toString }}
{{- $redis_tag := .Values.image.redis.tag | default "alpine" | toString }}
@@ -11,9 +11,13 @@
{{- $ngrok_repository := .Values.image.ngrok.repository | default "wernight/ngrok" | toString }}
{{- $ngrok_tag := .Values.image.ngrok.tag | default "latest" | toString }}
{{- $ngrok_pullPolicy := .Values.image.ngrok.pullPolicy | default "IfNotPresent" | toString | quote }}
+{{- $apscheduler := .Values.vpbot.scheduler.apscheduler }}
+{{- $celery := .Values.vpbot.scheduler.celery }}
{{- $cloudflared := .Values.vpbot.cloudflared.enabled }}
{{- $ngrok := .Values.vpbot.ngrok.enabled }}
{{- $persistence := .Values.vpbot.persistence.enabled }}
+{{- $commands := .Values.vpbot.commands }}
+{{- $messages := .Values.vpbot.messages }}
apiVersion: apps/v1
kind: Deployment
metadata:
@@ -30,6 +34,7 @@ spec:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
+ "helm.sh/hook-weight": "1"
{{- end }}
labels:
{{- include "vpbot.selectorLabels" . | nindent 8 }}
@@ -40,42 +45,102 @@ spec:
{{- end }}
containers:
- name: vpbot
- image: {{ printf "%s/%s:%s" $vpbot_registry $vpbot_repository $vpbot_tag | quote }}
- imagePullPolicy: {{ $vpbot_pullPolicy }}
+ image: {{ printf "%s/%s:%s" $telego_registry $telego_repository $telego_tag | quote }}
+ imagePullPolicy: {{ $telego_pullPolicy }}
ports:
- name: vpbot
containerPort: 80
protocol: TCP
resources:
{{- toYaml .Values.resources.vpbot | nindent 12 }}
- {{- if $cloudflared }}
- env:
- - name: ALLOWED_HOSTS
- valueFrom:
- configMapKeyRef:
- name: {{ .Release.Name }}-vpbot-cm
- key: DOMAIN
- {{- end }}
envFrom:
- configMapRef:
name: {{ .Release.Name }}-vpbot-cm
- secretRef:
name: {{ .Release.Name }}-vpbot-secret
- - secretRef:
- name: {{ .Release.Name }}-vpbot-postgres-secret
volumeMounts:
- name: {{ .Release.Name }}-vpbot-site-config
mountPath: /etc/apache2/sites-available/000-default.conf
subPath: site-config.conf
readOnly: true
+ {{- if $celery }}
+ - name: {{ .Release.Name }}-vpbot-default-celery-config
+ mountPath: /etc/default/celeryd
+ subPath: celeryd
+ - name: {{ .Release.Name }}-vpbot-initd-celery-config
+ mountPath: /etc/init.d/celerybeat
+ subPath: celerybeat
+ - name: {{ .Release.Name }}-vpbot-initd-celery-config
+ mountPath: /etc/init.d/celeryd
+ subPath: celeryd
+ - name: {{ .Release.Name }}-vpbot-scheduler-config
+ mountPath: /base/base/celery.py
+ subPath: celery.py
+ - name: {{ .Release.Name }}-vpbot-scheduler-config
+ mountPath: /base/base/tasks.py
+ subPath: tasks.py
+ - name: {{ .Release.Name }}-vpbot-scheduler-config
+ mountPath: /base/base/__init__.py
+ subPath: init.py
+ {{- end }}
+ {{- if $persistence }}
+ - name: {{ .Release.Name }}-vpbot-logs
+ mountPath: /vpbot/logs
+ {{- end }}
+ {{- if $commands }}
+ - name: {{ .Release.Name }}-vpbot-commands-cm
+ mountPath: /base/lib/commands.py
+ subPath: commands.py
+ readOnly: true
+ {{- end }}
+ {{- if $messages }}
+ - name: {{ .Release.Name }}-vpbot-messages-cm
+ mountPath: /base/lib/messages.py
+ subPath: messages.py
+ readOnly: true
+ {{- end }}
+ {{- if $apscheduler }}
+ - name: apscheduler
+ image: {{ printf "%s/%s:%s" $telego_registry $telego_repository $telego_tag | quote }}
+ imagePullPolicy: {{ $telego_pullPolicy }}
+ ports:
+ - name: vpbot
+ containerPort: 80
+ protocol: TCP
+ resources:
+ {{- toYaml .Values.resources.scheduler | nindent 12 }}
+ envFrom:
+ - configMapRef:
+ name: {{ .Release.Name }}-vpbot-cm
+ - secretRef:
+ name: {{ .Release.Name }}-vpbot-secret
+ volumeMounts:
+ - name: {{ .Release.Name }}-vpbot-apscheduler-config
+ mountPath: /entrypoint.sh
+ subPath: entrypoint.sh
+ - name: {{ .Release.Name }}-vpbot-scheduler-config
+ mountPath: /base/base/apps.py
+ subPath: apps.py
+ - name: {{ .Release.Name }}-vpbot-scheduler-config
+ mountPath: /base/base/tasks.py
+ subPath: tasks.py
{{- if $persistence }}
- - name: {{ .Release.Name }}-vpbot-static
- mountPath: /static
- name: {{ .Release.Name }}-vpbot-logs
- mountPath: /quarantine-bot/logs
- - name: {{ .Release.Name }}-vpbot-migrations
- mountPath: /quarantine-bot/quarantine_bot/migrations
+ mountPath: /var/log/apache2
+ {{- end }}
+ {{- if $commands }}
+ - name: {{ .Release.Name }}-vpbot-commands-cm
+ mountPath: /base/lib/commands.py
+ subPath: commands.py
+ readOnly: true
+ {{- end }}
+ {{- if $messages }}
+ - name: {{ .Release.Name }}-vpbot-messages-cm
+ mountPath: /base/lib/messages.py
+ subPath: messages.py
+ readOnly: true
{{- end }}
+ {{- else if $celery }}
- name: redis
image: {{ printf "%s/%s:%s" $redis_registry $redis_repository $redis_tag | quote }}
imagePullPolicy: {{ $redis_pullPolicy }}
@@ -84,7 +149,8 @@ spec:
containerPort: 6379
protocol: TCP
resources:
- {{- toYaml .Values.resources.redis | nindent 12 }}
+ {{- toYaml .Values.resources.scheduler | nindent 12 }}
+ {{- end }}
{{- if $ngrok }}
- name: ngrok
image: {{ printf "%s/%s:%s" $ngrok_registry $ngrok_repository $ngrok_tag | quote }}
@@ -99,6 +165,8 @@ spec:
- name: ngrok
containerPort: 4040
protocol: TCP
+ resources:
+ {{- toYaml .Values.resources.ngrok | nindent 12 }}
env:
- name: NGROK_AUTH
valueFrom:
@@ -110,14 +178,64 @@ spec:
- name: {{ .Release.Name }}-vpbot-site-config
configMap:
name: {{ .Release.Name }}-vpbot-site-config
+ {{- if $apscheduler }}
+ - name: {{ .Release.Name }}-vpbot-apscheduler-config
+ configMap:
+ name: {{ .Release.Name }}-vpbot-apscheduler-config
+ defaultMode: 0755
+ items:
+ - key: entrypoint.sh
+ path: entrypoint.sh
+ {{- else if $celery }}
+ - name: {{ .Release.Name }}-vpbot-default-celery-config
+ configMap:
+ name: {{ .Release.Name }}-vpbot-default-celery-config
+ defaultMode: 0640
+ items:
+ - key: celeryd
+ path: celeryd
+ - name: {{ .Release.Name }}-vpbot-initd-celery-config
+ configMap:
+ name: {{ .Release.Name }}-vpbot-initd-celery-config
+ defaultMode: 0755
+ items:
+ - key: celerybeat
+ path: celerybeat
+ - key: celeryd
+ path: celeryd
+ {{- end }}
+ {{- if or $apscheduler $celery }}
+ - name: {{ .Release.Name }}-vpbot-scheduler-config
+ configMap:
+ name: {{ .Release.Name }}-vpbot-scheduler-config
+ defaultMode: 0775
+ items:
+ - key: tasks.py
+ path: tasks.py
+ {{- if $apscheduler }}
+ - key: apps.py
+ path: apps.py
+ {{- else if $celery }}
+ - key: celery.py
+ path: celery.py
+ - key: init.py
+ path: init.py
+ {{- end }}
+ {{- end }}
{{- if $persistence }}
- - name: {{ .Release.Name }}-vpbot-static
- persistentVolumeClaim:
- claimName: {{ .Release.Name }}-vpbot-static-pvc
- name: {{ .Release.Name }}-vpbot-logs
persistentVolumeClaim:
claimName: {{ .Release.Name }}-vpbot-logs-pvc
- - name: {{ .Release.Name }}-vpbot-migrations
- persistentVolumeClaim:
- claimName: {{ .Release.Name }}-vpbot-migrations-pvc
{{- end }}
+ {{- if $commands }}
+ - name: {{ .Release.Name }}-vpbot-commands-cm
+ configMap:
+ name: {{ .Release.Name }}-vpbot-commands-cm
+ {{- end }}
+ {{- if $messages }}
+ - name: {{ .Release.Name }}-vpbot-messages-cm
+ configMap:
+ name: {{ .Release.Name }}-vpbot-messages-cm
+ {{- end }}
+ securityContext:
+ fsGroup: 33
diff --git a/mika/vpbot/templates/entrypoint.sh.tpl b/mika/vpbot/templates/entrypoint.sh.tpl
new file mode 100644
index 00000000..732410d9
--- /dev/null
+++ b/mika/vpbot/templates/entrypoint.sh.tpl
@@ -0,0 +1,16 @@
+{{/*
+APScheduler /entrypoint.sh template
+*/}}
+{{- define "vpbot.apscheduler-entrypoint-sh" -}}
+#!/bin/bash
+
+export APP_ROOT="base"
+
+# ================= DO NOT EDIT BEYOND THIS LINE =================
+
+python3 manage.py makemigrations
+
+python3 manage.py migrate
+
+tail -f /dev/null
+{{- end }}
diff --git a/mika/vpbot/templates/pvc.yaml b/mika/vpbot/templates/pvc.yaml
index ab6bb3e7..77c6eaea 100644
--- a/mika/vpbot/templates/pvc.yaml
+++ b/mika/vpbot/templates/pvc.yaml
@@ -1,6 +1,4 @@
-{{- $logs_storage := .Values.vpbot.persistence.logs.storage | default "50Mi" | toString | quote }}
-{{- $static_storage := .Values.vpbot.persistence.static.storage | default "50Mi" | toString | quote }}
-{{- $migrations_storage := .Values.vpbot.persistence.migrations.storage | default "50Mi" | toString | quote }}
+{{- $storage := .Values.vpbot.persistence.storage | default "10Mi" | toString | quote }}
{{- $storage_class_name := .Values.vpbot.persistence.storageClassName | default "longhorn" | toString | quote }}
{{- $persistence := .Values.vpbot.persistence.enabled }}
{{- if $persistence }}
@@ -15,34 +13,6 @@ spec:
- ReadWriteMany
resources:
requests:
- storage: {{ $logs_storage }}
- storageClassName: {{ $storage_class_name }}
----
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
- name: {{ .Release.Name }}-vpbot-static-pvc
- labels:
- {{- include "vpbot.labels" . | nindent 4 }}
-spec:
- accessModes:
- - ReadWriteMany
- resources:
- requests:
- storage: {{ $static_storage }}
- storageClassName: {{ $storage_class_name }}
----
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
- name: {{ .Release.Name }}-vpbot-migrations-pvc
- labels:
- {{- include "vpbot.labels" . | nindent 4 }}
-spec:
- accessModes:
- - ReadWriteMany
- resources:
- requests:
- storage: {{ $migrations_storage }}
+ storage: {{ $storage }}
storageClassName: {{ $storage_class_name }}
{{- end }}
diff --git a/mika/vpbot/templates/secret.yaml b/mika/vpbot/templates/secret.yaml
index b0e53cb2..c7c00b2a 100644
--- a/mika/vpbot/templates/secret.yaml
+++ b/mika/vpbot/templates/secret.yaml
@@ -1,8 +1,5 @@
{{- $secret := .Values.vpbot.secret | toString | b64enc }}
-{{- $telegram_token := .Values.telegram.token | toString | b64enc }}
-{{- $admin_id := .Values.telegram.admin_id | toString | b64enc }}
-{{- $devel_id := .Values.telegram.devel_id | toString | b64enc }}
-{{- $user_pass := .Values.vpbot.user_pass | toString | b64enc }}
+{{- $telegram_token := .Values.vpbot.telegram.token | toString | b64enc }}
{{- $ngrok_token := .Values.vpbot.ngrok.token | toString | b64enc }}
{{- $db_type := .Values.db.type | default "postgresql" | toString | b64enc }}
{{- $db_name := .Values.db.name | toString | b64enc }}
@@ -21,24 +18,12 @@ type: Opaque
data:
SECRET_KEY: {{ $secret }}
TELEGRAM_BOT_TOKEN: {{ $telegram_token }}
- TELEGRAM_ADMIN_ID: {{ $admin_id }}
- TELEGRAM_DEVEL_ID: {{ $devel_id }}
- DEFAULT_USER_PASS: {{ $user_pass }}
{{- if $ngrok }}
NGROK_AUTH_TOKEN: {{ $ngrok_token }}
{{- end }}
----
-apiVersion: v1
-kind: Secret
-metadata:
- name: {{ .Release.Name }}-vpbot-postgres-secret
- labels:
- {{- include "vpbot.labels" . | nindent 4 }}
-type: Opaque
-data:
- DB_HOST: {{ $db_host }}
DB_TYPE: {{ $db_type }}
- DB_PORT: {{ $db_port }}
DB_NAME: {{ $db_name }}
DB_USER: {{ $db_user }}
DB_PASS: {{ $db_password }}
+ DB_HOST: {{ $db_host }}
+ DB_PORT: {{ $db_port }}
diff --git a/mika/vpbot/templates/service.yaml b/mika/vpbot/templates/service.yaml
index 8f22471a..fc4cbeed 100644
--- a/mika/vpbot/templates/service.yaml
+++ b/mika/vpbot/templates/service.yaml
@@ -1,3 +1,5 @@
+{{- $celery := .Values.vpbot.scheduler.celery }}
+{{- $ngrok := .Values.vpbot.ngrok.enabled }}
apiVersion: v1
kind: Service
metadata:
@@ -11,9 +13,17 @@ spec:
targetPort: vpbot
protocol: TCP
name: {{ .Release.Name }}-vpbot
+ {{- if $celery }}
- port: 6379
targetPort: redis
protocol: TCP
name: {{ .Release.Name }}-redis
+ {{- end }}
+ {{- if $ngrok }}
+ - port: 4040
+ targetPort: ngrok
+ protocol: TCP
+ name: {{ .Release.Name }}-ngrok
+ {{- end }}
selector:
{{- include "vpbot.selectorLabels" . | nindent 4 }}
diff --git a/mika/vpbot/templates/site-config.conf.tpl b/mika/vpbot/templates/site-config.conf.tpl
new file mode 100644
index 00000000..9acebc53
--- /dev/null
+++ b/mika/vpbot/templates/site-config.conf.tpl
@@ -0,0 +1,28 @@
+{{/*
+Apache site-config.conf template
+*/}}
+{{- define "vpbot.site-config-conf" -}}
+
+ ServerName DOMAIN:443
+ UseCanonicalName On
+ ServerAdmin support@mikahomelab.com
+ DocumentRoot /base
+ WSGIScriptAlias / /base/base/wsgi.py
+ WSGIDaemonProcess DOMAIN python-path=/base
+ WSGIProcessGroup DOMAIN
+
+
+
+ Require all granted
+
+
+
+ Alias /static /static
+
+ Require all granted
+
+
+ ErrorLog /var/log/apache2/apache.error.log
+ CustomLog /var/log/apache2/apache.access.log combined
+
+{{- end }}
diff --git a/mika/vpbot/templates/tasks.py.tpl b/mika/vpbot/templates/tasks.py.tpl
new file mode 100644
index 00000000..7e8a6117
--- /dev/null
+++ b/mika/vpbot/templates/tasks.py.tpl
@@ -0,0 +1,70 @@
+{{/*
+APScheduler /base/base/tasks.py template
+*/}}
+{{- define "vpbot.apscheduler-tasks-py" -}}
+from apscheduler.schedulers.blocking import BlockingScheduler
+from django.conf import settings
+from base.scheduler import object_scheduler
+from lib import (
+ solat,
+ telegram,
+)
+
+
+SCHEDULER_TIMEZONE = getattr(settings, "SCHEDULER_TIMEZONE")
+
+
+def start():
+ scheduler = BlockingScheduler(timezone=SCHEDULER_TIMEZONE)
+
+ job_name = "telegram_clean_model"
+ scheduler.add_job(telegram.clean_model, "cron", hour=CLEAN_MODEL_HOURS, id=job_name, replace_existing=True)
+
+ job_name = "object_scheduler"
+ scheduler.add_job(object_scheduler, "cron", second="*/" + OBJECT_SCHEDULER_SECONDS, id=job_name, replace_existing=True)
+
+ job_name = "solat_clean_db"
+ scheduler.add_job(solat.clean_db, "cron", hour=SOLAT_CLEAN_DB_HOURS, id=job_name, replace_existing=True)
+
+ job_name = "solat_notify_solat_times"
+ scheduler.add_job(solat.notify_solat_times, "cron", minute="*/" + SOLAT_NOTIF_MINUTES, id=job_name, replace_existing=True)
+
+ scheduler.start()
+{{- end }}
+
+{{/*
+Celery /base/base/tasks.py template
+*/}}
+{{- define "vpbot.celery-tasks-py" -}}
+from __future__ import absolute_import, unicode_literals
+from celery import shared_task
+from base.scheduler import object_scheduler
+from lib import (
+ solat,
+ telegram,
+)
+
+
+# clean telegram model
+@shared_task
+def telegram_clean_model_task():
+ telegram.clean_model()
+
+
+# check for any objects that need to be sent
+@shared_task
+def object_scheduler_task():
+ object_scheduler()
+
+
+# clean solat db
+@shared_task
+def solat_clean_db_task():
+ solat.clean_db()
+
+
+# send prayer time notifications
+@shared_task
+def solat_notify_solat_times_task():
+ solat.notify_solat_times()
+{{- end }}
diff --git a/mika/vpbot/values.yaml b/mika/vpbot/values.yaml
index e225cbcf..0eb31110 100644
--- a/mika/vpbot/values.yaml
+++ b/mika/vpbot/values.yaml
@@ -14,7 +14,7 @@ image:
# Default: "ghcr.io"
registry: ""
# The name of the repository that contains the Vpbot container image used.
- # Default: "irfanhakim-as/quarantine-bot"
+ # Default: "irfanhakim-as/vpbot"
repository: ""
# The tag that specifies the version of the Vpbot container image used.
# Default: Chart appVersion
@@ -69,56 +69,100 @@ vpbot:
# Example:
# debug: true
debug: ""
- # The log file size limit in megabytes.
- # Default: "4"
- # Example:
- # log_size_limit: "3"
- log_size_limit: ""
# A 50-character secret key used for secure session management and cryptographic operations within the Vpbot service.
# Example:
# secret: "6&p4%t)-$8a14fmfh92py8j55+us51r6%e52dzy&=a3-6yd4#e"
secret: ""
- # The default user password for users created by Vpbot.
- # Example:
- # user_pass: "password"
- user_pass: ""
- # The timezone for the task scheduler used by Vpbot to schedule time-dependent operations.
- # Default: "Asia/Kuala_Lumpur"
- # Example:
- # timezone: "Asia/Kuala_Lumpur"
- celery_timezone: ""
- # Vpbot storage persistence configurations.
+ # Vpbot defaults configurations.
+ defaults:
+ # The default user location code used for personalised services.
+ # Default: "wlp-0"
+ # Example:
+ # location: "phg-0"
+ location: ""
+ # Vpbot API configurations.
+ api:
+ # Solat module API configurations.
+ solat:
+ # The API endpoint for acquiring Indonesian prayer times.
+ # Default: "https://api.myquran.com/v1/sholat/jadwal/%s"
+ # Example:
+ # id: "https://api.myquran.com/v1/sholat/jadwal/%s"
+ id: ""
+ # The API endpoint for acquiring Malaysian prayer times.
+ # Default: "https://mpt.i906.my/api/prayer/%s"
+ # Example:
+ # my: "https://mpt.i906.my/api/prayer/%s"
+ my: ""
+ # Vpbot scheduler configurations.
+ scheduler:
+ # Specifies whether APScheduler should be used by Vpbot as the task scheduler.
+ # Example:
+ # apscheduler: false
+ apscheduler: true
+ # Specifies whether Celery should be used by Vpbot as the task scheduler.
+ # Example:
+ # celery: true
+ celery: false
+ # The timezone for the task scheduler used by Vpbot to schedule time-dependent operations.
+ # Default: "Asia/Kuala_Lumpur"
+ # Example:
+ # timezone: "Asia/Kuala_Lumpur"
+ timezone: ""
+ # The schedule for the task scheduler used by Vpbot.
+ schedule:
+ # The hours at which the task scheduler cleans up the database.
+ # Default: "0"
+ # Example:
+ # clean_model: "0,6,12,18"
+ clean_model: ""
+ # The second intervals at which the task scheduler sends scheduled messages.
+ # Default: "2"
+ # Example:
+ # object_scheduler: "3"
+ object_scheduler: ""
+ # The hours at which the task scheduler cleans up the solat module database.
+ # Default: "0"
+ # Example:
+ # solat_clean_db: "0,6,12,18"
+ solat_clean_db: ""
+ # The minute intervals at which the task scheduler sends prayer time notifications.
+ # Default: "1"
+ # Example:
+ # solat_notification: "3"
+ solat_notification: ""
+ # Vpbot Telegram configurations.
+ telegram:
+ # API endpoint or URL for the Telegram bot.
+ # Default: "https://api.telegram.org/bot"
+ # Example:
+ # api: "https://api.telegram.org/bot"
+ api: ""
+ # The Telegram bot token used by Vpbot to communicate with Telegram.
+ # Example:
+ # token: "1282813559:RrqoFIuWZwNfMLrx3Jd2mdFJnxrMObgQEvz"
+ token: ""
+ # The Telegram bot webhook path used by Vpbot to communicate with Telegram. Must contain a trailing slash.
+ # Default: "webhook/telegram/"
+ # Example:
+ # webhook: "telegram/jbbhb73f6s/"
+ webhook: ""
+ # Vpbot log persistence configurations.
persistence:
- # Specifies whether Vpbot should persist its storage.
+ # Specifies whether Vpbot should persist its logs.
# Example:
# enabled: true
enabled: false
- # The storage class name used for dynamically provisioning a persistent volume for the Vpbot storage.
+ # The amount of persistent storage allocated for Vpbot logs.
+ # Default: "10Mi"
+ # Example:
+ # storage: "1Gi"
+ storage: ""
+ # The storage class name used for dynamically provisioning a persistent volume for the Vpbot logs storage.
# Default: "longhorn"
# Example:
# storageClassName: "longhorn"
storageClassName: ""
- # Vpbot logs persistence configurations.
- logs:
- # The amount of persistent storage allocated for Vpbot logs.
- # Default: "50Mi"
- # Example:
- # storage: "1Gi"
- storage: ""
- # Vpbot static files persistence configurations.
- static:
- # The amount of persistent storage allocated for Vpbot static files.
- # Default: "50Mi"
- # Example:
- # storage: "1Gi"
- storage: ""
- # Vpbot migration files persistence configurations.
- migrations:
- # The amount of persistent storage allocated for Vpbot migration files.
- # Default: "50Mi"
- # Example:
- # storage: "1Gi"
- storage: ""
# Vpbot Ngrok configurations.
ngrok:
# Specifies whether Vpbot should run using an Ngrok tunnel.
@@ -139,26 +183,10 @@ vpbot:
# Example:
# domain: "vpbot.example.com"
domain: ""
-
-# Vpbot Telegram configurations.
-telegram:
- # The Telegram bot webhook path used by Vpbot to communicate with Telegram.
- # Default: "telegram/webhooks/"
- # Example:
- # webhook: "bot/jbbhb73f6s/"
- webhook: ""
- # The Telegram bot token used by Vpbot to communicate with Telegram.
- # Example:
- # token: "1282813559:RrqoFIuWZwNfMLrx3Jd2mdFJnxrMObgQEvz"
- token: ""
- # The unique Telegram chat ID of the Vpbot administrator.
- # Example:
- # admin_id: "6649538406"
- admin_id: ""
- # The unique Telegram chat ID of the Vpbot developer.
- # Example:
- # devel_id: "4637142749"
- devel_id: ""
+ # Custom Telegram commands.py file for Vpbot.
+ commands: ""
+ # Custom Telegram messages.py file for Vpbot.
+ messages: ""
# Database configurations.
db:
@@ -198,40 +226,62 @@ resources:
# The minimum amount of CPU resources required by Vpbot.
# Example:
# cpu: "20m"
- cpu: "10m"
+ cpu: "50m"
# The minimum amount of memory required by Vpbot.
# Example:
# memory: "250Mi"
- memory: "250Mi"
+ memory: "300Mi"
# The maximum amount of resources allowed for Vpbot.
limits:
# The maximum amount of CPU resources allowed for Vpbot.
# Example:
# cpu: "50m"
- cpu: "50m"
+ cpu: "200m"
# The maximum amount of memory allowed for Vpbot.
# Example:
# memory: "450Mi"
memory: "500Mi"
- # Redis container resources.
- redis:
- # The minimum amount of resources required by Redis to run.
+ # Scheduler container resources.
+ scheduler:
+ # The minimum amount of resources required by Scheduler to run.
+ requests:
+ # The minimum amount of CPU resources required by Scheduler.
+ # Example:
+ # cpu: "5m"
+ cpu: "10m"
+ # The minimum amount of memory required by Scheduler.
+ # Example:
+ # memory: "30Mi"
+ memory: "100Mi"
+ # The maximum amount of resources allowed for Scheduler.
+ limits:
+ # The maximum amount of CPU resources allowed for Scheduler.
+ # Example:
+ # cpu: "15m"
+ cpu: "20m"
+ # The maximum amount of memory allowed for Scheduler.
+ # Example:
+ # memory: "50Mi"
+ memory: "200Mi"
+ # Ngrok container resources.
+ ngrok:
+ # The minimum amount of resources required by Ngrok to run.
requests:
- # The minimum amount of CPU resources required by Redis.
+ # The minimum amount of CPU resources required by Ngrok.
# Example:
# cpu: "5m"
- cpu: "5m"
- # The minimum amount of memory required by Redis.
+ cpu: "10m"
+ # The minimum amount of memory required by Ngrok.
# Example:
# memory: "30Mi"
- memory: "30Mi"
- # The maximum amount of resources allowed for Redis.
+ memory: "20Mi"
+ # The maximum amount of resources allowed for Ngrok.
limits:
- # The maximum amount of CPU resources allowed for Redis.
+ # The maximum amount of CPU resources allowed for Ngrok.
# Example:
# cpu: "15m"
- cpu: "15m"
- # The maximum amount of memory allowed for Redis.
+ cpu: "20m"
+ # The maximum amount of memory allowed for Ngrok.
# Example:
# memory: "50Mi"
- memory: "60Mi"
+ memory: "50Mi"