diff --git a/docs/deployment/MIGRATION_WORKING_COPY_TO_PROTOTYPE.md b/docs/deployment/MIGRATION_WORKING_COPY_TO_PROTOTYPE.md new file mode 100644 index 0000000..ff80fd5 --- /dev/null +++ b/docs/deployment/MIGRATION_WORKING_COPY_TO_PROTOTYPE.md @@ -0,0 +1,231 @@ +# Migracja: „working copy" → „prototype" + +Runbook upgrade'u działającego deploymentu bota (Raspberry Pi) z wersji +**working copy** (kod w roocie repo, bez auth między usługami, bez integracji +Conan) na wersję **prototype** (konfiguracja przez zmienne środowiskowe, +opcjonalna autoryzacja wewnętrznych wywołań HTTP, integracja Conan Exiles). + +> **Najważniejsze:** upgrade jest **wstecznie kompatybilny**. Bez ustawiania +> żadnych nowych zmiennych bot działa tak jak dotąd — istniejące tokeny z +> `~/.netrc` i domyślne ścieżki są zachowane. Wszystkie nowe funkcje +> (autoryzacja API, most Conan, powiadomienia o graczach) są **opt-in**. + +--- + +## 0. Status / warunek wstępny + +Pełny kod prototype znajduje się obecnie na branchu **`proto-improvements`**. +Na `main` jest na razie sama restrukturyzacja (working copy w roocie). Zanim +zmigrujesz produkcję z `main`, zmerguj prototype do `main` +(`proto-improvements` → `main`) albo deployuj bezpośrednio z brancha +`proto-improvements`. Dalsza część zakłada, że prototype jest już dostępny pod +refem, który checkoutujesz w kroku 2. + +**Układ deploymentu (bez zmian):** + +| | Ścieżka | +|---|---| +| Klon repo | `/home/pi/conjurer` | +| Runtime bota | `/home/pi/Conjurer` | +| Virtualenv | `/home/pi/Conjurer/env` (używany przez `conjurer.service`) | +| Usługa systemd | `conjurer.service` → `ExecStart … /home/pi/Conjurer/bot.py` | +| Deploy | `deploy.sh` (kopiuje pliki z repo do runtime i restartuje usługę) | + +--- + +## 1. Backup i punkt powrotu + +```bash +# zapamiętaj aktualny commit (do ewentualnego rollbacku) +git -C /home/pi/conjurer rev-parse HEAD > /home/pi/conjurer_rollback_commit.txt + +# snapshot runtime (config + dane) +sudo cp -a /home/pi/Conjurer /home/pi/Conjurer.bak.$(date +%Y%m%d_%H%M%S) +``` + +Sekrety nadal pochodzą z `~/.netrc` (Discord/OpenAI/Spotify/YouTube) — upewnij +się, że ten plik istnieje i jest aktualny. Migracja go nie dotyka. + +--- + +## 2. Pobranie kodu prototype + +```bash +cd /home/pi/conjurer +git fetch --all +git checkout main && git pull # gdy prototype jest już w main +# albo, do czasu merge: git checkout proto-improvements && git pull +``` + +--- + +## 3. Instalacja nowych zależności + +Wersja prototype dodaje do `requirements_bot.txt` dwa pakiety używane przez most +Conan: **`aiomcrcon`** i **`asyncssh`**. + +```bash +source /home/pi/Conjurer/env/bin/activate +python3 -m pip install -r /home/pi/conjurer/requirements_bot.txt +deactivate +``` + +> Nawet bez tych pakietów bot się uruchomi — importy w module Conan są osłonięte +> (`try/except ImportError`), a integracja pozostaje uśpiona. Instalacja jest +> potrzebna tylko jeśli faktycznie używasz mostu Conan. + +--- + +## 4. (Opcjonalnie) Konfiguracja zmiennych środowiskowych + +Wersja prototype czyta konfigurację ze zmiennych środowiskowych z fallbackiem na +dotychczasowe wartości. **Pomiń ten krok dla zwykłego upgrade'u** — domyślne +ścieżki i `~/.netrc` wystarczą. Ustaw zmienne tylko gdy włączasz nową funkcję. + +### 4a. Plik środowiskowy dla systemd + +```bash +sudo tee /home/pi/Conjurer/conjurer.env >/dev/null <<'EOF' +# --- Autoryzacja wewnętrznych wywołań HTTP (opcjonalne) --- +# Ten sam klucz MUSI być ustawiony na bocie, musicianie i librarianie. +CONJURER_API_KEY= + +# --- Adresy usług wewnętrznych (domyślne wartości jak dotąd) --- +#CONJURER_FILE_SERVICE=http://192.168.1.15:5000 +#CONJURER_RADIO_HARBOR=http://192.168.1.15:54321 +#CONJURER_LIBRARIAN_SERVICE=http://192.168.1.192:5001 + +# --- Most Conan Exiles (opcjonalne; puste = wyłączone) --- +#CONAN_GM_ROLE_ID=0 +#CONAN_RCON_HOST= +#CONAN_RCON_PORT=25575 +#CONAN_RCON_PASSWORD= +#CONAN_CHAT_CHANNEL_ID=0 +#CONAN_EVENTS_CHANNEL_ID=0 +# Powiadomienia o wejściu gracza — ustaw id kanału, by włączyć: +#CONAN_JOIN_CHANNEL_ID=0 +#CONAN_PLAYER_POLL_SECONDS=60 +#CONAN_LOG_MODE=local +#CONAN_LOG_PATH= +EOF +sudo chmod 600 /home/pi/Conjurer/conjurer.env +``` + +### 4b. Podłączenie pliku do usługi + +Dodaj `EnvironmentFile` do sekcji `[Service]` w `conjurer.service` +(`/etc/systemd/system/conjurer.service`): + +```ini +[Service] +Type=simple +EnvironmentFile=/home/pi/Conjurer/conjurer.env +ExecStart=/home/pi/Conjurer/env/bin/python3 /home/pi/Conjurer/bot.py +Restart=on-abort +``` + +```bash +sudo systemctl daemon-reload +``` + +> `conjurer.service` w repo również warto zaktualizować o tę linię, ale `deploy.sh` +> **nie** nadpisuje jednostki systemd przy każdym deployu — wpis robisz raz, ręcznie. + +--- + +## 5. Deploy i restart + +```bash +cd /home/pi/conjurer +./deploy.sh # kopiuje m.in. bot.py oraz conanjurer_commands/_functions.py do runtime +``` + +`deploy.sh` na końcu sam wykonuje `systemctl restart conjurer.service`. Jeśli +zmieniałeś jednostkę systemd w kroku 4b, wcześniej zrób `daemon-reload`. + +--- + +## 6. Weryfikacja + +```bash +journalctl -u conjurer.service -f +``` + +Czego szukać w logu (`/home/pi/Conjurer` → plik logu również): + +- `Loading … module done` dla kolejnych rozszerzeń, w tym **`Loading conanjurer commands module done`** +- Gdy most Conan nieskonfigurowany: `Conan: log watch disabled (not configured)` + oraz `Conan: player-join notifications disabled (no channel or RCON)` — to + oczekiwane, integracja jest uśpiona +- `All systems: operational` + +Szybki test funkcjonalny: bot łączy się z Discordem, dotychczasowe komendy +działają, radio/biblioteka odpowiadają jak wcześniej. + +--- + +## 7. Zmiany zachowania, o których warto wiedzieć + +| Obszar | Working copy | Prototype | +|---|---|---| +| Konfiguracja | zahardkodowana per-platforma | env-vary z fallbackiem na stare wartości | +| Tokeny | tylko `~/.netrc` | env-var → fallback `~/.netrc` (stare działa) | +| Wewnętrzne HTTP (music/radio/librarian) | bez nagłówków | wysyła `X-Conjurer-Api-Key`, **gdy** `CONJURER_API_KEY` ustawione | +| Endpointy przychodzące bota | bez weryfikacji | `_authorize_request()` zwraca 401 przy złym kluczu (no-op gdy klucz pusty) | +| Pętla bota | wątki + `join()` | pojedyncza pętla asyncio z czystym shutdownem | +| Moduł Conan | obecny, **nieładowany** (miał SyntaxError) | naprawiony i ładowany; uśpiony bez konfiguracji | + +--- + +## 8. Włączanie funkcji opcjonalnych + +### 8a. Autoryzacja wewnętrznych wywołań HTTP +Ustaw **ten sam** `CONJURER_API_KEY` na **wszystkich** usługach: bocie, +musicianie (`conjurer_musician`) i librarianie. Po ustawieniu: +- bot dokleja nagłówek do wywołań do file-service/radia/biblioteki, +- usługi odrzucają (401) żądania bez poprawnego klucza. + +⚠️ Ustawienie klucza tylko po jednej stronie zepsuje komunikację (401). Albo +wszędzie, albo nigdzie. + +### 8b. Most Conan Exiles +Ustaw `CONAN_RCON_HOST` + `CONAN_RCON_PASSWORD` (komendy GM `say/players/kick/ +rcon/ogłoś`) oraz, dla mirrorowania czatu/zdarzeń, `CONAN_LOG_PATH` +(+ `CONAN_CHAT_CHANNEL_ID`/`CONAN_EVENTS_CHANNEL_ID`). + +### 8c. Powiadomienia o wejściu gracza +Ustaw **`CONAN_JOIN_CHANNEL_ID`** na id kanału Discord. Funkcja odpytuje RCON +`listplayers` co `CONAN_PLAYER_POLL_SECONDS` i ogłasza nowych graczy. Pozostaw +`0`, aby trzymać ją wyłączoną. + +--- + +## 9. Rollback + +```bash +cd /home/pi/conjurer +git checkout "$(cat /home/pi/conjurer_rollback_commit.txt)" +./deploy.sh +sudo systemctl restart conjurer.service +``` + +W razie potrzeby przywróć snapshot runtime z `/home/pi/Conjurer.bak.*`. Nowe +zależności (`aiomcrcon`, `asyncssh`) mogą zostać w venv — nie przeszkadzają +starszej wersji. + +--- + +## 10. Migracja usługi musician (jeśli prowadzisz radio) + +Stabilny wariant `musician_old` (zahardkodowane adresy) został zastąpiony przez +`conjurer_musician` (env-driven, domyślnie `127.0.0.1`). Jeśli bot i musician są +na **różnych** hostach, ustaw na musicianie: + +```bash +CONJURER_MAIN_BOT=http://:5000 # gdzie bot serwuje /prepped_tracks +CONJURER_API_KEY= # jeśli włączasz auth (8a) +CONJURER_MUSIC_FOLDER=/home/pi/MediaShare/mp3 +``` + +oraz na bocie `CONJURER_FILE_SERVICE=http://:5000`. Szczegóły +auth/kontraktu — patrz opis usługi `conjurer_musician`.