colloq 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of colloq might be problematic. Click here for more details.
- colloq/__init__.py +12 -0
- colloq/__main__.py +315 -0
- colloq/_app/.colloq-dist.json +66 -0
- colloq/_app/LICENSE +21 -0
- colloq/_app/THIRD_PARTY_NOTICES.md +106 -0
- colloq/_app/cli/colloq.mjs +2517 -0
- colloq/_app/cli/launch.mjs +1572 -0
- colloq/_app/cli/package.json +5 -0
- colloq/_app/cli/public-url-lease.mjs +198 -0
- colloq/_app/kernel/Dockerfile +93 -0
- colloq/_app/kernel/environments/base-gpu.txt +21 -0
- colloq/_app/kernel/environments/base.txt +12 -0
- colloq/_app/kernel/environments/cv.txt +15 -0
- colloq/_app/kernel/environments/gpu.txt +17 -0
- colloq/_app/kernel/environments/kaggle-base.txt +20 -0
- colloq/_app/kernel/environments/pvz-geo.txt +6 -0
- colloq/_app/kernel/requirements.txt +18 -0
- colloq/_app/package.json +20 -0
- colloq/_app/scripts/backup-local.sh +165 -0
- colloq/_app/scripts/backup.sh +34 -0
- colloq/_app/scripts/cluster.sh +492 -0
- colloq/_app/scripts/dns.sh +251 -0
- colloq/_app/scripts/host.sh +1514 -0
- colloq/_app/scripts/lib.sh +62 -0
- colloq/_app/scripts/restore.sh +338 -0
- colloq/_app/scripts/runtime-backup.py +373 -0
- colloq/_app/scripts/state-lock.py +85 -0
- colloq/_app/server/assets/fonts/HSESans-Black.otf +0 -0
- colloq/_app/server/assets/fonts/HSESans-Bold.otf +0 -0
- colloq/_app/server/assets/fonts/HSESans-Regular.otf +0 -0
- colloq/_app/server/assets/fonts/JetBrainsMono-Medium.ttf +0 -0
- colloq/_app/server/assets/fonts/JetBrainsMono-OFL.txt +93 -0
- colloq/_app/server/dist/local-cleanup.js +15987 -0
- colloq/_app/server/dist/runtime-smoke.js +17026 -0
- colloq/_app/server/dist/server.js +54333 -0
- colloq/_app/server/package.json +6 -0
- colloq/_app/web/dist/assets/AdminScreen-C-cg0GlJ.css +1 -0
- colloq/_app/web/dist/assets/AdminScreen-C-cg0GlJ.css.br +0 -0
- colloq/_app/web/dist/assets/AdminScreen-C-cg0GlJ.css.gz +0 -0
- colloq/_app/web/dist/assets/AdminScreen-fu4cB6Ra.js +105 -0
- colloq/_app/web/dist/assets/AdminScreen-fu4cB6Ra.js.br +0 -0
- colloq/_app/web/dist/assets/AdminScreen-fu4cB6Ra.js.gz +0 -0
- colloq/_app/web/dist/assets/App-CMXNqOjp.css +1 -0
- colloq/_app/web/dist/assets/App-CMXNqOjp.css.br +0 -0
- colloq/_app/web/dist/assets/App-CMXNqOjp.css.gz +0 -0
- colloq/_app/web/dist/assets/App-DvCPzIRO.js +26 -0
- colloq/_app/web/dist/assets/App-DvCPzIRO.js.br +0 -0
- colloq/_app/web/dist/assets/App-DvCPzIRO.js.gz +0 -0
- colloq/_app/web/dist/assets/CellOutputs-Dl-AZL45.js +42 -0
- colloq/_app/web/dist/assets/CellOutputs-Dl-AZL45.js.br +0 -0
- colloq/_app/web/dist/assets/CellOutputs-Dl-AZL45.js.gz +0 -0
- colloq/_app/web/dist/assets/CommandPalette-DhBGho7_.js +3 -0
- colloq/_app/web/dist/assets/CommandPalette-DhBGho7_.js.br +0 -0
- colloq/_app/web/dist/assets/CommandPalette-DhBGho7_.js.gz +0 -0
- colloq/_app/web/dist/assets/CompetitionsScreen-Vu3RpHmf.js +3 -0
- colloq/_app/web/dist/assets/CompetitionsScreen-Vu3RpHmf.js.br +0 -0
- colloq/_app/web/dist/assets/CompetitionsScreen-Vu3RpHmf.js.gz +0 -0
- colloq/_app/web/dist/assets/ConsoleView-B2uyYvFh.js +1 -0
- colloq/_app/web/dist/assets/ConsoleView-B2uyYvFh.js.br +0 -0
- colloq/_app/web/dist/assets/ConsoleView-B2uyYvFh.js.gz +0 -0
- colloq/_app/web/dist/assets/ConsoleView-DLbp0Jul.css +1 -0
- colloq/_app/web/dist/assets/DependencyBundleCard-B392XMVZ.js +4 -0
- colloq/_app/web/dist/assets/DependencyBundleCard-B392XMVZ.js.br +0 -0
- colloq/_app/web/dist/assets/DependencyBundleCard-B392XMVZ.js.gz +0 -0
- colloq/_app/web/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- colloq/_app/web/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- colloq/_app/web/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- colloq/_app/web/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- colloq/_app/web/dist/assets/PultWindow-B3cc8537.css +1 -0
- colloq/_app/web/dist/assets/PultWindow-B3cc8537.css.br +0 -0
- colloq/_app/web/dist/assets/PultWindow-B3cc8537.css.gz +0 -0
- colloq/_app/web/dist/assets/PultWindow-DPOUhSqt.js +8 -0
- colloq/_app/web/dist/assets/PultWindow-DPOUhSqt.js.br +0 -0
- colloq/_app/web/dist/assets/PultWindow-DPOUhSqt.js.gz +0 -0
- colloq/_app/web/dist/assets/ReaderScreen-CV_0VAvW.js +9 -0
- colloq/_app/web/dist/assets/ReaderScreen-CV_0VAvW.js.br +0 -0
- colloq/_app/web/dist/assets/ReaderScreen-CV_0VAvW.js.gz +0 -0
- colloq/_app/web/dist/assets/SessionScreen-BrcB6CLH.js +132 -0
- colloq/_app/web/dist/assets/SessionScreen-BrcB6CLH.js.br +0 -0
- colloq/_app/web/dist/assets/SessionScreen-BrcB6CLH.js.gz +0 -0
- colloq/_app/web/dist/assets/SessionScreen-Dek9dK3C.css +1 -0
- colloq/_app/web/dist/assets/SessionScreen-Dek9dK3C.css.br +0 -0
- colloq/_app/web/dist/assets/SessionScreen-Dek9dK3C.css.gz +0 -0
- colloq/_app/web/dist/assets/actions-DLPyolgo.js +1 -0
- colloq/_app/web/dist/assets/admin-en-BHmR7Co0.js +9 -0
- colloq/_app/web/dist/assets/admin-en-BHmR7Co0.js.br +0 -0
- colloq/_app/web/dist/assets/admin-en-BHmR7Co0.js.gz +0 -0
- colloq/_app/web/dist/assets/admin-ru-Dr6Z36Zi.js +11 -0
- colloq/_app/web/dist/assets/admin-ru-Dr6Z36Zi.js.br +0 -0
- colloq/_app/web/dist/assets/admin-ru-Dr6Z36Zi.js.gz +0 -0
- colloq/_app/web/dist/assets/codemirror-6LUh0q1l.js +32 -0
- colloq/_app/web/dist/assets/codemirror-6LUh0q1l.js.br +0 -0
- colloq/_app/web/dist/assets/codemirror-6LUh0q1l.js.gz +0 -0
- colloq/_app/web/dist/assets/competitions-en-zw57uAGL.js +5 -0
- colloq/_app/web/dist/assets/competitions-en-zw57uAGL.js.br +0 -0
- colloq/_app/web/dist/assets/competitions-en-zw57uAGL.js.gz +0 -0
- colloq/_app/web/dist/assets/competitions-ru-BBQUjAx0.js +5 -0
- colloq/_app/web/dist/assets/competitions-ru-BBQUjAx0.js.br +0 -0
- colloq/_app/web/dist/assets/competitions-ru-BBQUjAx0.js.gz +0 -0
- colloq/_app/web/dist/assets/editor-theme-CVYtpZDy.js +1 -0
- colloq/_app/web/dist/assets/editor-theme-CVYtpZDy.js.br +0 -0
- colloq/_app/web/dist/assets/editor-theme-CVYtpZDy.js.gz +0 -0
- colloq/_app/web/dist/assets/index-CwbYK31L.css +1 -0
- colloq/_app/web/dist/assets/index-CwbYK31L.css.br +0 -0
- colloq/_app/web/dist/assets/index-CwbYK31L.css.gz +0 -0
- colloq/_app/web/dist/assets/index-Di16xdmz.js +2 -0
- colloq/_app/web/dist/assets/index-Di16xdmz.js.br +0 -0
- colloq/_app/web/dist/assets/index-Di16xdmz.js.gz +0 -0
- colloq/_app/web/dist/assets/katex-CS_ezkZp.css +1 -0
- colloq/_app/web/dist/assets/katex-CS_ezkZp.css.br +0 -0
- colloq/_app/web/dist/assets/katex-CS_ezkZp.css.gz +0 -0
- colloq/_app/web/dist/assets/katex-DLorvT8M.js +257 -0
- colloq/_app/web/dist/assets/katex-DLorvT8M.js.br +0 -0
- colloq/_app/web/dist/assets/katex-DLorvT8M.js.gz +0 -0
- colloq/_app/web/dist/assets/pdf-DEp6sk-T.js +55 -0
- colloq/_app/web/dist/assets/pdf-DEp6sk-T.js.br +0 -0
- colloq/_app/web/dist/assets/pdf-DEp6sk-T.js.gz +0 -0
- colloq/_app/web/dist/assets/persistence.svelte-vcuCBcT5.js +1 -0
- colloq/_app/web/dist/assets/persistence.svelte-vcuCBcT5.js.br +0 -0
- colloq/_app/web/dist/assets/persistence.svelte-vcuCBcT5.js.gz +0 -0
- colloq/_app/web/dist/assets/reader-en-UCGE3U6V.js +3 -0
- colloq/_app/web/dist/assets/reader-en-UCGE3U6V.js.br +0 -0
- colloq/_app/web/dist/assets/reader-en-UCGE3U6V.js.gz +0 -0
- colloq/_app/web/dist/assets/reader-ru-CaiNj0K8.js +3 -0
- colloq/_app/web/dist/assets/reader-ru-CaiNj0K8.js.br +0 -0
- colloq/_app/web/dist/assets/reader-ru-CaiNj0K8.js.gz +0 -0
- colloq/_app/web/dist/assets/render-CjP3RuRT.js +155 -0
- colloq/_app/web/dist/assets/render-CjP3RuRT.js.br +0 -0
- colloq/_app/web/dist/assets/render-CjP3RuRT.js.gz +0 -0
- colloq/_app/web/dist/assets/render.svelte-B4_hAJmX.js +0 -0
- colloq/_app/web/dist/assets/render.svelte-B4_hAJmX.js.br +0 -0
- colloq/_app/web/dist/assets/render.svelte-B4_hAJmX.js.gz +0 -0
- colloq/_app/web/dist/assets/room-en-Bh8L6NcO.js +3 -0
- colloq/_app/web/dist/assets/room-en-Bh8L6NcO.js.br +0 -0
- colloq/_app/web/dist/assets/room-en-Bh8L6NcO.js.gz +0 -0
- colloq/_app/web/dist/assets/room-ru-Bar2GgS0.js +3 -0
- colloq/_app/web/dist/assets/room-ru-Bar2GgS0.js.br +0 -0
- colloq/_app/web/dist/assets/room-ru-Bar2GgS0.js.gz +0 -0
- colloq/_app/web/dist/assets/seminar-link-CRaZl9Ku.js +1 -0
- colloq/_app/web/dist/assets/seminar-link-CRaZl9Ku.js.br +0 -0
- colloq/_app/web/dist/assets/seminar-link-CRaZl9Ku.js.gz +0 -0
- colloq/_app/web/dist/assets/seminar-link-DoTugxxA.css +1 -0
- colloq/_app/web/dist/assets/seminar-link-DoTugxxA.css.br +0 -0
- colloq/_app/web/dist/assets/seminar-link-DoTugxxA.css.gz +0 -0
- colloq/_app/web/dist/assets/yjs-rjB3hdnL.js +6 -0
- colloq/_app/web/dist/assets/yjs-rjB3hdnL.js.br +0 -0
- colloq/_app/web/dist/assets/yjs-rjB3hdnL.js.gz +0 -0
- colloq/_app/web/dist/fonts/JetBrainsMono-OFL.txt +93 -0
- colloq/_app/web/dist/fonts/hse-sans-400.woff2 +0 -0
- colloq/_app/web/dist/fonts/hse-sans-600.woff2 +0 -0
- colloq/_app/web/dist/fonts/hse-sans-700.woff2 +0 -0
- colloq/_app/web/dist/fonts/hse-sans-900.woff2 +0 -0
- colloq/_app/web/dist/fonts/jetbrains-mono-cyrillic-ext.woff2 +0 -0
- colloq/_app/web/dist/fonts/jetbrains-mono-cyrillic.woff2 +0 -0
- colloq/_app/web/dist/fonts/jetbrains-mono-latin-ext.woff2 +0 -0
- colloq/_app/web/dist/fonts/jetbrains-mono-latin.woff2 +0 -0
- colloq/_app/web/dist/index.html +268 -0
- colloq/_app/web/dist/og/colloq.png +0 -0
- colloq/_app/web/dist/pdf/pdf.worker.min.mjs +29 -0
- colloq/_app/web/dist/pdf/pdf.worker.min.mjs.br +0 -0
- colloq/_app/web/dist/pdf/pdf.worker.min.mjs.gz +0 -0
- colloq/_app/web/dist/plotly/plotly.min.js +3620 -0
- colloq/_app/web/dist/plotly/plotly.min.js.br +0 -0
- colloq/_app/web/dist/plotly/plotly.min.js.gz +0 -0
- colloq/_version.py +5 -0
- colloq-0.2.0.dist-info/METADATA +124 -0
- colloq-0.2.0.dist-info/RECORD +224 -0
- colloq-0.2.0.dist-info/WHEEL +4 -0
- colloq-0.2.0.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Записи DNS для colloq.ru.
|
|
4
|
+
#
|
|
5
|
+
# Скрипт приводит зону к нужному виду, а не досыпает в неё записи. Разница не
|
|
6
|
+
# косметическая: домен приехал из Рег.ру с парковочными A-записями, и если
|
|
7
|
+
# просто добавить рядом адреса GitHub Pages, посетитель будет попадать то на
|
|
8
|
+
# сайт, то на заглушку — round-robin честно раздаст и то и другое. Поэтому для
|
|
9
|
+
# каждой пары «тип + имя» лишнее удаляется, недостающее создаётся, совпадающее
|
|
10
|
+
# не трогается, и запускать это можно сколько угодно раз подряд.
|
|
11
|
+
#
|
|
12
|
+
# Главное, ради чего всё: **серое облако везде**. Оранжевое означает, что
|
|
13
|
+
# посетитель идёт на пограничные адреса Cloudflare, а они из России не
|
|
14
|
+
# открываются — лендинг на colloq.sleep3r.ru не грузился ровно до того дня,
|
|
15
|
+
# когда с него сняли проксирование. Апекс colloq.ru приехал проксированным,
|
|
16
|
+
# и это здесь исправляется.
|
|
17
|
+
#
|
|
18
|
+
# Токен берётся из .env основного репозитория; нужны Zone:Read и DNS:Edit на
|
|
19
|
+
# зону colloq.ru.
|
|
20
|
+
#
|
|
21
|
+
# Входа два:
|
|
22
|
+
#
|
|
23
|
+
# scripts/dns.sh привести всю зону к нужному виду:
|
|
24
|
+
# лендинг, www и *.colloq.ru на ретранслятор
|
|
25
|
+
# scripts/dns.sh point <имя> <адрес> одна A-запись: имя → адрес машины
|
|
26
|
+
#
|
|
27
|
+
# Второй появился не ради удобства. Его зовёт прямой режим `make host-direct`:
|
|
28
|
+
# машина с белым адресом принимает пару сама, и её имя должно смотреть на неё,
|
|
29
|
+
# а не на ретранслятор. Своей копии этой логики у host.sh нет намеренно —
|
|
30
|
+
# «удалить лишнее, создать недостающее, никогда не оставлять проксирование»
|
|
31
|
+
# написано здесь один раз и здесь же чинится.
|
|
32
|
+
set -euo pipefail
|
|
33
|
+
cd "$(dirname "$0")"
|
|
34
|
+
|
|
35
|
+
# Режим разбирается до всего остального: в режиме point ни лендинг, ни www, ни
|
|
36
|
+
# звёздочка не трогаются вовсе — иначе `make host-direct` посреди пары
|
|
37
|
+
# переписывал бы записи, о которых его не просили.
|
|
38
|
+
MODE=zone
|
|
39
|
+
if [[ "${1:-}" == point ]]; then
|
|
40
|
+
MODE=point
|
|
41
|
+
POINT_NAME=${2:?scripts/dns.sh point <name> <address>}
|
|
42
|
+
POINT_ADDR=${3:?scripts/dns.sh point <name> <address>}
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# ../.env, а не ../colloq/.env: скрипт приехал из соседнего репозитория, где
|
|
46
|
+
# основной клон лежал рядом. Здесь он лежит выше, и прежний путь не существовал
|
|
47
|
+
# ни в одном клоне — вместо «нет файла» человек читал «нужен токен с Zone:Read»
|
|
48
|
+
# и шёл проверять права токена, который всё это время лежал в .env.
|
|
49
|
+
#
|
|
50
|
+
# Читает файл общий read_env (scripts/lib.sh) — тот же, которым живут host.sh,
|
|
51
|
+
# service.sh и vast.sh.
|
|
52
|
+
#
|
|
53
|
+
# Двумя строками, а не `ENV_FILE=../.env . ./lib.sh`: присваивание перед
|
|
54
|
+
# встроенной командой bash считает временным и после возврата снимает — а
|
|
55
|
+
# read_env зовут потом, и файл настроек ему нужен уже настоящий.
|
|
56
|
+
#
|
|
57
|
+
# COLLOQ_HOME сильнее «этажом выше»: у поставленного через pip colloq этажом
|
|
58
|
+
# выше лежит только каталог приложения (доступный на чтение и сносимый
|
|
59
|
+
# обновлением), а .env с CF_TOKEN — в каталоге состояния. Без переменной всё
|
|
60
|
+
# как было: ../.env, то есть корень репозитория.
|
|
61
|
+
ENV_FILE="${COLLOQ_HOME:-..}/.env"
|
|
62
|
+
. ./lib.sh
|
|
63
|
+
|
|
64
|
+
DOMAIN=${DOMAIN:-colloq.ru}
|
|
65
|
+
# Куда смотрят семинары. Тот же адрес, что в RELAY_ADDR у инстансов, и берётся
|
|
66
|
+
# он оттуда же — из .env, а не из прибитой строки.
|
|
67
|
+
#
|
|
68
|
+
# Прибитое умолчание здесь было ловушкой: RELAY_ADDR из .env скрипт не читал
|
|
69
|
+
# вовсе, и после переезда ретранслятора любой заход «привести зону в порядок»
|
|
70
|
+
# (а это единственный способ вернуть имя после host-direct) молча возвращал
|
|
71
|
+
# `*.colloq.ru` на старый адрес — то есть уводил все семинары на мёртвую
|
|
72
|
+
# машину. Нет адреса — нет и записи: об этом сказано вслух ниже.
|
|
73
|
+
RELAY="${RELAY_ADDR:-$(read_env RELAY_ADDR)}"
|
|
74
|
+
# Чья страница на GitHub Pages — цель CNAME для www.
|
|
75
|
+
PAGES_HOST=${PAGES_HOST:-colloq-edu.github.io}
|
|
76
|
+
|
|
77
|
+
if [[ -z "${CF_TOKEN_COLLOQ:-}" ]]; then
|
|
78
|
+
# `|| true` внутри read_env: файл есть, а строки в нём нет — это «нужен
|
|
79
|
+
# токен», а не молчаливый выход по set -e без единого слова на экране.
|
|
80
|
+
CF_TOKEN_COLLOQ=$(read_env CF_TOKEN)
|
|
81
|
+
fi
|
|
82
|
+
: "${CF_TOKEN_COLLOQ:?a token with Zone:Read and DNS:Edit on ${DOMAIN} is needed}"
|
|
83
|
+
|
|
84
|
+
# Идентификатор зоны лежит в том же .env соседней строкой с токеном, а читался
|
|
85
|
+
# только из окружения. Из-за этого он не использовался никогда: зона искалась
|
|
86
|
+
# запросом, и токену без права листать зоны скрипт отвечал «зона этому токену
|
|
87
|
+
# не видна» — при том что её id был у него под рукой.
|
|
88
|
+
if [[ -z "${CF_ZONE_COLLOQ:-}" ]]; then
|
|
89
|
+
CF_ZONE_COLLOQ=$(read_env CF_ZONE)
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
API=https://api.cloudflare.com/client/v4
|
|
93
|
+
AUTH=(-H "Authorization: Bearer $CF_TOKEN_COLLOQ" -H "content-type: application/json")
|
|
94
|
+
|
|
95
|
+
RED=$'\033[31m'; OFF=$'\033[0m'
|
|
96
|
+
die() { printf '%s%s%s\n' "$RED" "$*" "$OFF" >&2; exit 1; }
|
|
97
|
+
|
|
98
|
+
# zone_id_for ИМЯ — в какой зоне живёт это имя.
|
|
99
|
+
#
|
|
100
|
+
# Спрашивать `?name=hse.colloq.ru` бесполезно: такой зоны нет, а Cloudflare
|
|
101
|
+
# отвечает на это не ошибкой, а пустым списком. Поэтому берётся список зон
|
|
102
|
+
# токена и из них самая длинная, которой запрошенное имя заканчивается:
|
|
103
|
+
# для hse.colloq.ru это colloq.ru, и то же правило работает для чужой зоны,
|
|
104
|
+
# если однажды инстанс встанет не под colloq.ru.
|
|
105
|
+
#
|
|
106
|
+
# И — без параметра status. Его допустимые значения это active, pending и
|
|
107
|
+
# подобные; «all» не из их числа, и Cloudflare на него опять же не ругается,
|
|
108
|
+
# а молча отдаёт пустой список. На этом можно потерять час, решив, что у
|
|
109
|
+
# токена нет доступа.
|
|
110
|
+
zone_id_for() {
|
|
111
|
+
local want=$1 id=""
|
|
112
|
+
# Явно названная зона сильнее поиска — но только если речь о ней же:
|
|
113
|
+
# CF_ZONE от colloq.ru для имени в чужой зоне это не подсказка, а ошибка,
|
|
114
|
+
# которая пишет запись не туда.
|
|
115
|
+
if [[ -n "${CF_ZONE_COLLOQ:-}" && ( "$want" == "$DOMAIN" || "$want" == *".$DOMAIN" ) ]]; then
|
|
116
|
+
printf '%s' "$CF_ZONE_COLLOQ"
|
|
117
|
+
return 0
|
|
118
|
+
fi
|
|
119
|
+
id=$(curl -s "${AUTH[@]}" "$API/zones?per_page=200" | WANT="$want" python3 -c '
|
|
120
|
+
import json, os, sys
|
|
121
|
+
want = os.environ["WANT"]
|
|
122
|
+
best = best_id = ""
|
|
123
|
+
try:
|
|
124
|
+
zones = json.load(sys.stdin).get("result") or []
|
|
125
|
+
except Exception:
|
|
126
|
+
zones = []
|
|
127
|
+
for z in zones:
|
|
128
|
+
name = z.get("name") or ""
|
|
129
|
+
if (want == name or want.endswith("." + name)) and len(name) > len(best):
|
|
130
|
+
best, best_id = name, z.get("id") or ""
|
|
131
|
+
print(best_id)' 2>/dev/null || true)
|
|
132
|
+
printf '%s' "$id"
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
fetch() { curl -s "${AUTH[@]}" "$API/zones/$zone/dns_records?per_page=200"; }
|
|
136
|
+
|
|
137
|
+
# reconcile ТИП ИМЯ [СОДЕРЖИМОЕ...]
|
|
138
|
+
#
|
|
139
|
+
# Приводит все записи данного типа с данным именем ровно к перечисленному
|
|
140
|
+
# списку. Пустой список означает «таких записей быть не должно» — так www
|
|
141
|
+
# избавляется от парковочной A, прежде чем стать CNAME: Cloudflare не даст
|
|
142
|
+
# держать CNAME рядом с A на одном имени.
|
|
143
|
+
reconcile() {
|
|
144
|
+
local type=$1 name=$2; shift 2
|
|
145
|
+
local want=("$@")
|
|
146
|
+
local records id content proxied keep w
|
|
147
|
+
|
|
148
|
+
records=$(fetch)
|
|
149
|
+
while read -r id content proxied; do
|
|
150
|
+
[[ -n "${id:-}" ]] || continue
|
|
151
|
+
keep=0
|
|
152
|
+
# Проксированную запись сохранять нельзя даже с верным адресом: оранжевое
|
|
153
|
+
# облако и есть то, из-за чего сайт не открывается.
|
|
154
|
+
for w in ${want[@]+"${want[@]}"}; do
|
|
155
|
+
[[ "$content" == "$w" && "$proxied" == "0" ]] && keep=1
|
|
156
|
+
done
|
|
157
|
+
if (( keep == 0 )); then
|
|
158
|
+
curl -s -X DELETE "${AUTH[@]}" "$API/zones/$zone/dns_records/$id" >/dev/null
|
|
159
|
+
printf ' removed %-5s %-16s -> %s%s\n' "$type" "$name" "$content" \
|
|
160
|
+
"$([[ $proxied == 1 ]] && echo ' (was proxied)')"
|
|
161
|
+
fi
|
|
162
|
+
done < <(printf '%s' "$records" | python3 -c "
|
|
163
|
+
import json,sys
|
|
164
|
+
for r in json.load(sys.stdin)['result']:
|
|
165
|
+
if r['type']=='$type' and r['name']=='$name':
|
|
166
|
+
print(r['id'], r['content'], int(bool(r.get('proxied'))))")
|
|
167
|
+
|
|
168
|
+
[[ ${#want[@]} -gt 0 ]] || return 0
|
|
169
|
+
|
|
170
|
+
local have
|
|
171
|
+
have=$(fetch | python3 -c "
|
|
172
|
+
import json,sys
|
|
173
|
+
print(' '.join(r['content'] for r in json.load(sys.stdin)['result']
|
|
174
|
+
if r['type']=='$type' and r['name']=='$name' and not r.get('proxied')))")
|
|
175
|
+
|
|
176
|
+
local resp
|
|
177
|
+
for w in "${want[@]}"; do
|
|
178
|
+
if [[ " $have " == *" $w "* ]]; then
|
|
179
|
+
printf ' in place %-5s %-16s -> %s\n' "$type" "$name" "$w"
|
|
180
|
+
continue
|
|
181
|
+
fi
|
|
182
|
+
resp=$(curl -s -X POST "${AUTH[@]}" "$API/zones/$zone/dns_records" \
|
|
183
|
+
--data "$(printf '{"type":"%s","name":"%s","content":"%s","ttl":300,"proxied":false}' \
|
|
184
|
+
"$type" "$name" "$w")")
|
|
185
|
+
# Ответ проверяется, а не выбрасывается. Раньше он уходил в /dev/null, и
|
|
186
|
+
# строка «создано» печаталась в том числе тогда, когда Cloudflare отказал —
|
|
187
|
+
# обычно из-за CNAME на том же имени или токена без DNS:Edit. Для зоны это
|
|
188
|
+
# означало «сайт почему-то не открылся», а для прямого режима — машину,
|
|
189
|
+
# которая ждёт сертификат на имя, никуда не указывающее.
|
|
190
|
+
if [[ "$resp" == *'"success":true'* || "$resp" == *'"success": true'* ]]; then
|
|
191
|
+
printf ' created %-5s %-16s -> %s\n' "$type" "$name" "$w"
|
|
192
|
+
else
|
|
193
|
+
printf '%s\n' "$resp" | head -c 400 >&2; printf '\n' >&2
|
|
194
|
+
die "Cloudflare did not create ${type} ${name} -> ${w}"
|
|
195
|
+
fi
|
|
196
|
+
done
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
# ------------------------------------------------------------- что делаем
|
|
200
|
+
|
|
201
|
+
# Одна запись: имя → адрес машины. Больше в зоне не трогается ничего.
|
|
202
|
+
if [[ "$MODE" == point ]]; then
|
|
203
|
+
zone=$(zone_id_for "$POINT_NAME")
|
|
204
|
+
[[ -n "$zone" ]] || die "this token cannot see the zone for ${POINT_NAME} (CF_TOKEN, CF_ZONE in .env)"
|
|
205
|
+
# Сначала снять CNAME с этого имени, потом ставить A — ровно та же причина,
|
|
206
|
+
# что у www ниже: Cloudflare не даёт держать их рядом. Случай не выдуманный:
|
|
207
|
+
# имя, которое когда-то заводил `make tunnel-setup`, держит CNAME на
|
|
208
|
+
# <id>.cfargotunnel.com, и без этой строки прямой режим на нём отказывал бы
|
|
209
|
+
# со ссылкой на конфликт записей.
|
|
210
|
+
reconcile CNAME "$POINT_NAME"
|
|
211
|
+
# Без проксирования — это здесь главное и единственное. Оранжевое облако
|
|
212
|
+
# увело бы студентов на пограничные адреса Cloudflare, а они из России не
|
|
213
|
+
# открываются: семинар стал бы недоступен ровно той аудитории, ради которой
|
|
214
|
+
# его и выставляют. Прямой режим тем и ценен, что между машиной и залом нет
|
|
215
|
+
# никого; проксирование вернуло бы посредника, да ещё и закрытого.
|
|
216
|
+
reconcile A "$POINT_NAME" "$POINT_ADDR"
|
|
217
|
+
exit 0
|
|
218
|
+
fi
|
|
219
|
+
|
|
220
|
+
# Адрес ретранслятора спрашивается до первой правки зоны, а не перед самой
|
|
221
|
+
# звёздочкой: лендинг и www приводятся в порядок раньше её, и отказ на середине
|
|
222
|
+
# оставил бы зону наполовину переписанной.
|
|
223
|
+
[[ -n "$RELAY" ]] || die "I do not know where to point *.${DOMAIN}: ../.env has no RELAY_ADDR.
|
|
224
|
+
That is the address of the relay (make relay-setup prints it). For one run it
|
|
225
|
+
can also be named like this: RELAY_ADDR=1.2.3.4 scripts/dns.sh"
|
|
226
|
+
|
|
227
|
+
zone=$(zone_id_for "$DOMAIN")
|
|
228
|
+
[[ -n "$zone" ]] || die "this token cannot see the zone ${DOMAIN}"
|
|
229
|
+
echo "zone ${DOMAIN}: $zone"
|
|
230
|
+
|
|
231
|
+
echo "landing page on GitHub Pages:"
|
|
232
|
+
reconcile A "$DOMAIN" 185.199.108.153 185.199.109.153 185.199.110.153 185.199.111.153
|
|
233
|
+
# Без AAAA посетитель на чистом IPv6 не откроет сайт вовсе.
|
|
234
|
+
reconcile AAAA "$DOMAIN" 2606:50c0:8000::153 2606:50c0:8001::153 2606:50c0:8002::153 2606:50c0:8003::153
|
|
235
|
+
# Сначала снять парковочную A с www, потом ставить CNAME — иначе Cloudflare
|
|
236
|
+
# откажет: CNAME и A на одном имени не уживаются.
|
|
237
|
+
reconcile A "www.$DOMAIN"
|
|
238
|
+
reconcile CNAME "www.$DOMAIN" "$PAGES_HOST"
|
|
239
|
+
|
|
240
|
+
echo "classes on the relay:"
|
|
241
|
+
# Одной звёздочкой, а не именем на каждый университет: поддомены раздаёт frps
|
|
242
|
+
# по общему секрету, и запись в DNS на каждого означала бы самообслуживание
|
|
243
|
+
# на ручном приводе.
|
|
244
|
+
reconcile A "*.$DOMAIN" "$RELAY"
|
|
245
|
+
|
|
246
|
+
echo
|
|
247
|
+
echo "done. Next:"
|
|
248
|
+
echo " 1. push the landing page: CNAME in the repository already points at ${DOMAIN}"
|
|
249
|
+
echo " 2. wait for the Pages certificate on ${DOMAIN}"
|
|
250
|
+
echo " 3. check from a phone WITHOUT a VPN: https://${DOMAIN}"
|
|
251
|
+
echo " 4. publish a class: make host HOST=hse.${DOMAIN}"
|