Compare commits

...

21 Commits

Author SHA1 Message Date
forust 726b3ee544 fix(edu): run redis as statefulset
ci / deploy-userbot-panel (push) Has been skipped
ci / lint-ruff (push) Successful in 5s
ci / lint-yaml (push) Successful in 7s
ci / build (push) Successful in 3s
ci / lint-prettier (push) Successful in 11s
ci / lint-dockerfiles (push) Successful in 4s
ci / validate (push) Successful in 5s
Keep the existing Redis PVC and data while migrating the edu-master workload from Deployment to StatefulSet.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-10 23:35:59 +02:00
forust 13309b26e0 fix: add checkmk agent entrypoint
ci / lint-dockerfiles (push) Successful in 5s
ci / validate (push) Successful in 5s
ci / deploy-userbot-panel (push) Has been skipped
ci / lint-prettier (push) Successful in 10s
ci / lint-ruff (push) Successful in 5s
ci / lint-yaml (push) Successful in 7s
ci / build (push) Successful in 2s
update traefik to v3.7.13
2026-09-10 14:52:49 +02:00
forust eddc256bed chore: remove esp32/ingress.yaml from main
ci / lint-prettier (push) Successful in 7s
ci / lint-ruff (push) Successful in 4s
ci / deploy-userbot-panel (push) Has been skipped
ci / lint-yaml (push) Successful in 7s
ci / lint-dockerfiles (push) Successful in 5s
ci / validate (push) Successful in 5s
ci / build (push) Successful in 3s
2026-09-10 12:12:54 +02:00
forust 52f821cbba Merge branch 'main' of ssh://gitssh.forust.xyz:2221/forust/homelab
ci / lint-prettier (push) Failing after 8s
ci / lint-ruff (push) Successful in 4s
ci / lint-yaml (push) Failing after 7s
ci / lint-dockerfiles (push) Successful in 5s
ci / validate (push) Successful in 5s
ci / build (push) Has been skipped
ci / deploy-userbot-panel (push) Has been skipped
2026-09-10 11:47:25 +02:00
forust 0dbc2fff13 Merge branch 'sidetree' 2026-09-10 11:47:25 +02:00
forust 91ec83bc1c Merge branch 'main' of ssh://gitssh.forust.xyz:2221/forust/homelab
ci / lint-ruff (push) Successful in 4s
ci / lint-prettier (push) Failing after 8s
ci / lint-yaml (push) Failing after 7s
ci / lint-dockerfiles (push) Successful in 5s
ci / validate (push) Successful in 6s
ci / build (push) Has been skipped
ci / deploy-userbot-panel (push) Has been skipped
2026-09-10 11:47:20 +02:00
forust 9fec1dae39 Merge branch 'sidetree' 2026-09-10 11:47:15 +02:00
forust e5626b7b2d chore: remove untracked README.md
ci / lint-prettier (push) Successful in 7s
ci / lint-ruff (push) Successful in 5s
ci / lint-yaml (push) Successful in 6s
ci / lint-dockerfiles (push) Successful in 4s
ci / validate (push) Successful in 4s
ci / build (push) Has been skipped
ci / deploy-userbot-panel (push) Has been skipped
2026-09-10 11:45:00 +02:00
forust 8fb12a2176 chore: remove untracked README.md
ci / lint-prettier (push) Successful in 7s
ci / lint-ruff (push) Successful in 4s
ci / lint-yaml (push) Successful in 6s
ci / lint-dockerfiles (push) Successful in 4s
ci / validate (push) Successful in 5s
ci / build (push) Has been skipped
ci / deploy-userbot-panel (push) Has been skipped
2026-09-10 11:44:23 +02:00
forust fe0c7067b6 Merge branch 'main' of ssh://gitssh.forust.xyz:2221/forust/homelab
ci / validate (push) Successful in 4s
ci / build (push) Has been skipped
ci / lint-prettier (push) Failing after 8s
ci / lint-ruff (push) Successful in 7s
ci / lint-yaml (push) Failing after 6s
ci / lint-dockerfiles (push) Successful in 4s
ci / deploy-userbot-panel (push) Has been skipped
2026-09-10 11:42:17 +02:00
forust d0f0843774 Merge branch 'sidetree' 2026-09-10 11:41:35 +02:00
forust 81a5b207ac Merge branch 'main' of ssh://gitssh.forust.xyz:2221/forust/homelab
ci / lint-prettier (push) Failing after 8s
ci / lint-ruff (push) Successful in 5s
ci / lint-yaml (push) Failing after 7s
ci / lint-dockerfiles (push) Successful in 4s
ci / validate (push) Successful in 5s
ci / build (push) Has been skipped
ci / deploy-userbot-panel (push) Has been skipped
2026-09-10 11:41:31 +02:00
forust e3d5970ae3 chore: remove untracked README.md
ci / lint-prettier (push) Failing after 11s
ci / lint-ruff (push) Successful in 5s
ci / lint-yaml (push) Failing after 7s
ci / lint-dockerfiles (push) Successful in 4s
ci / validate (push) Successful in 5s
ci / build (push) Has been skipped
ci / deploy-userbot-panel (push) Has been skipped
2026-09-10 11:39:20 +02:00
forust 85f05c26cb feat(edu): activate k8s management for edu-master 2026-09-10 00:55:22 +02:00
forust 68630eb773 fix(edu): read diary event times directly from DOM, drop 25 AJAX clicks
ci / lint-prettier (push) Successful in 9s
ci / lint-ruff (push) Successful in 6s
ci / lint-yaml (push) Successful in 10s
ci / lint-dockerfiles (push) Successful in 7s
ci / validate (push) Successful in 6s
ci / build (push) Has been skipped
ci / deploy-userbot-panel (push) Has been skipped
_collect_event_times re-clicked every a.event-link and waited ~3s per
event for a visible span.data, but the calendar embeds all times in
div.event-full-info[data-event-full-info-id] span.data already. The old
loop took ~109s for 25 events and collected 0 (original divs stay
sf-hidden), effectively hanging /diary. Now a single evaluate reads all
times (~3.7s), parsing HH:MM from p.date span.data.
2026-09-10 00:31:04 +02:00
forust dad9cf2104 feat(edu): parse event times in /diary and drop weekend days
ci / lint-prettier (push) Successful in 9s
ci / lint-ruff (push) Successful in 4s
ci / lint-yaml (push) Successful in 6s
ci / lint-dockerfiles (push) Successful in 5s
ci / validate (push) Successful in 6s
ci / build (push) Has been skipped
ci / deploy-userbot-panel (push) Has been skipped
- fetch each event's time via Playwright (click event-link, read span.data, close fancybox) and render as 'title (HH:MM)'
- '08:00' placeholder renders as localized 'unknown' (time_unknown key in ru/uk/en)
- diary week view shows Mon-Fri only (title ends at Friday)
- diary month view skips Sat/Sun by weekday_idx with name-based fallback
- schedule keyboard drops Sat/Sun day buttons
2026-09-10 00:05:56 +02:00
forust 60886e8be2 style(edu): ruff-format webinar-checker/checker.py
ci / lint-prettier (push) Successful in 13s
ci / lint-ruff (push) Successful in 4s
ci / lint-yaml (push) Successful in 7s
ci / lint-dockerfiles (push) Successful in 5s
ci / validate (push) Successful in 6s
ci / build (push) Has been skipped
ci / deploy-userbot-panel (push) Has been skipped
2026-09-09 23:47:04 +02:00
forust 4528321225 fix(edu): add TZ to .env.example 2026-09-09 11:46:35 +02:00
forust b246a3dea1 fix(edu): review findings for checker.py i18n — group chat language via resolve_lang/chat: keys (default uk), weekday normalization with _norm_day + logging, drop dead translation keys, html.escape, single lang lookup, distinct whitelist emoji 2026-09-09 11:44:17 +02:00
forust 4c59a2d2fe lang(edu): translate k8s manifest comments to English only
- restore-seed-job.yaml.example: translate runbook to English
- secrets.yaml.example: translate section headers to English
- webinar-checker.yaml: translate initContainer dependency-order comments to English

Co-authored-by: assistant
2026-09-09 10:46:36 +02:00
forust fcc7b0d611 ci(deploy): gate redeploy behind manual workflow_dispatch
ci / lint-prettier (push) Successful in 8s
ci / lint-ruff (push) Successful in 4s
ci / lint-yaml (push) Successful in 7s
ci / lint-dockerfiles (push) Successful in 4s
ci / validate (push) Successful in 5s
ci / build (push) Successful in 2s
ci / deploy-userbot-panel (push) Has been skipped
removes automatic redeploy on push to main; deploy now runs only on
explicit manual trigger
2026-09-06 20:55:40 +02:00
13 changed files with 545 additions and 166 deletions
-3
View File
@@ -1,9 +1,6 @@
name: deploy
on:
push:
branches:
- main
workflow_dispatch:
concurrency:
-3
View File
@@ -1,9 +1,6 @@
name: deploy
on:
push:
branches:
- main
workflow_dispatch:
concurrency:
+1
View File
@@ -41,6 +41,7 @@ traefik/dynamic/fileservers.yml
traefik/dynamic/*.local.y*ml.*
traefik/dynamic/*.external.y*ml
traefik/k8s/fileservers.y*ml
traefik/k8s/aliasHeadersStrategy.md
traefik/logs/*
+9 -2
View File
@@ -7,8 +7,12 @@ spec:
selector:
app: checkmk
ports:
- port: 5000
- name: web
port: 5000
targetPort: 5000
- name: agent-receiver
port: 8000
targetPort: 8000
---
apiVersion: apps/v1
kind: Deployment
@@ -34,7 +38,10 @@ spec:
- configMapRef:
name: checkmk-config
ports:
- containerPort: 5000
- name: web
containerPort: 5000
- name: agent-receiver
containerPort: 8000
volumeMounts:
- name: sites
mountPath: /omd/sites
+16
View File
@@ -16,6 +16,22 @@ spec:
certResolver: letsencrypt
---
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: checkmk-agent-receiver
namespace: checkmk
spec:
entryPoints:
- checkmk-agent
routes:
- match: HostSNI(`*`)
services:
- name: checkmk-service
port: 8000
tls:
passthrough: true
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: checkmk-local
+1
View File
@@ -9,5 +9,6 @@ WEBINAR_CHECK_INTERVAL=60
REDIS_HOST=redis
REDIS_PORT=6379
PLAYWRIGHT_WS=ws://playwright-service:3000/ws
TZ=Europe/Kyiv
WEBINAR_TELEGRAM_TOKEN=your_telegram_bot_token_here
WEBINAR_ADMIN_ID=123456789
View File
+2 -1
View File
@@ -1,11 +1,12 @@
apiVersion: apps/v1
kind: Deployment
kind: StatefulSet
metadata:
name: redis
namespace: edu-master
labels:
app: edu-master-redis
spec:
serviceName: redis
replicas: 1
selector:
matchLabels:
+6 -6
View File
@@ -1,17 +1,17 @@
# Разовый Job для переноса состояния redis из docker compose в k8s (maintenance window).
# Файл .example -> deploy-пайплайн его не применяет (маска *.example.yaml).
# One-time Job to migrate redis state from docker compose to k8s (maintenance window).
# The .example file is not applied by the deploy pipeline (mask *.example.yaml).
#
# Runbook:
# 1. docker compose -f <repo>/edu_master/compose.yaml stop # SIGTERM -> redis сбросит dump.rdb
# 1. docker compose -f <repo>/edu_master/compose.yaml stop # SIGTERM -> redis will flush dump.rdb
# 2. docker run --rm -v edu_master_redis-data:/data \
# -v /tmp/edu-master-backup:/backup \
# redis:alpine sh -c "cp /data/dump.rdb /backup/ && ls -la /backup"
# 3. kubectl apply -f edu_master/k8s/namespace.yaml
# 4. kubectl apply -f <только PVC из redis.yaml> # seed строго ДО старта redis-пода
# 4. kubectl apply -f <only the PVC from redis.yaml> # seed must come BEFORE redis pod starts
# 5. kubectl apply -f edu_master/k8s/restore-seed-job.yaml.example
# kubectl wait --for=condition=complete job/redis-restore-seed -n edu-master --timeout=120s
# 6. kubectl delete job redis-restore-seed -n edu-master
# 7. kubectl apply -f edu_master/k8s/ -R # остальные манифесты
# 7. kubectl apply -f edu_master/k8s/ -R # apply remaining manifests
apiVersion: batch/v1
kind: Job
metadata:
@@ -47,4 +47,4 @@ spec:
- name: backup
hostPath:
path: /tmp/edu-master-backup
type: DirectoryOrCreate
type: DirectoryOrCreate
+3 -2
View File
@@ -5,7 +5,7 @@ metadata:
namespace: edu-master
type: Opaque
stringData:
# PHPSESSID keeper
# Session keeper credentials
KEEPER_LOGIN: ""
KEEPER_PASSWORD: ""
KEEPER_INTERVAL: "10"
@@ -23,4 +23,5 @@ stringData:
WEBINAR_CHECK_INTERVAL: "60"
# Database
REDIS_HOST: "redis"
REDIS_PORT: "6379"
REDIS_PORT: "6379"
TZ: "Europe/Kyiv"
+5 -2
View File
@@ -15,9 +15,9 @@ spec:
labels:
app: edu-master-webinar-checker
spec:
# Enforces dependency order like compose depends_on:
# redis healthy -> session-keeper healthy (EXISTS EDU_PHPSESSID) -> playwright started
initContainers:
# Держит порядок зависимостей как в compose depends_on:
# redis healthy -> session-keeper healthy (EXISTS EDU_PHPSESSID) -> playwright started
- name: wait-deps
image: redis:alpine
command:
@@ -50,6 +50,9 @@ spec:
envFrom:
- secretRef:
name: edu-master-secrets
env:
- name: TZ
value: "Europe/Kyiv"
resources:
requests:
cpu: 25m
File diff suppressed because it is too large Load Diff
+25 -7
View File
@@ -3,7 +3,7 @@ hostNetwork: false
image:
registry: docker.io/library
repository: traefik
tag: v3.7.6
tag: v3.7.13
securityContext:
capabilities:
@@ -44,6 +44,7 @@ ports:
web:
port: 80
http:
aliasHeadersStrategy: delete
redirections:
entryPoint:
to: websecure
@@ -52,32 +53,54 @@ ports:
websecure:
port: 443
http:
aliasHeadersStrategy: delete
tls:
enabled: true
traefik:
port: 8080
exposedPort: 8080
protocol: TCP
expose:
default: false
http:
aliasHeadersStrategy: delete
ssh:
port: 2221
exposedPort: 2221
protocol: TCP
expose:
default: true
http:
aliasHeadersStrategy: delete
minecraft-tcp:
port: 25565
exposedPort: 25565
protocol: TCP
expose:
default: true
http:
aliasHeadersStrategy: delete
minecraft-udp:
port: 19132
exposedPort: 19132
protocol: UDP
expose:
default: true
checkmk-agent:
port: 8000
protocol: TCP
expose:
default: true
http:
aliasHeadersStrategy: delete
metrics:
port: 9100
exposedPort: 9100
protocol: TCP
expose:
default: false
http:
aliasHeadersStrategy: delete
metrics:
prometheus:
@@ -122,11 +145,6 @@ additionalArguments:
- "--providers.file.directory=/etc/traefik/dynamic"
- "--providers.file.watch=true"
- "--providers.kubernetesCRD.allowCrossNamespace=true"
- "--providers.kubernetesCRD.safeNaming=false"
- "--entryPoints.websecure.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22,192.168.1.1,192.168.1.0/24,192.168.88.0/24,192.168.88.1"
- "--entryPoints.web.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22,192.168.1.1,192.168.1.0/24,192.168.88.0/24,192.168.88.1"
log:
level: INFO
accessLog:
enabled: true
format: common