FirefishからIceshrimpに移行する

Firefishが開発終了したので互換性のあるフォークに移行する必要が出てきました。
そのままマイグレーションしたい場合、2024年9月現在ではSharkeyかIceshrimpかCatodonの三択になるようです。

自分はMastodon APIとの互換性が結構残っているっぽいIceshrimpにすることにしましたが、Calckey時代からFirefishを使っているせいか[公式のマイグレーションガイド](https://iceshrimp.dev/iceshrimp/iceshrimp/src/branch/dev/docs/migrate.md)そのままだと何故か上手く行かないところがあったので自分用に移行ガイドを残すことにします。Calckey時代からUbuntuの非Docker環境で使っている人にしか参考にならないかもしれないので実質ほぼ自分用メモです。

管理しているサーバの一つはSharkeyにしましたが夜坂さんが書いてくださった[移行ガイド](https://scrapbox.io/ifyasaka/Firefish%E3%81%8B%E3%82%89Sharkey%E3%81%AB%E7%A7%BB%E8%A1%8C%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F%EF%BC%88%E9%9D%9EDocker_%2F_Ubuntu%EF%BC%89)が参考になりました。

## 事前準備
サーバー側にスナップショットなどの機能がある場合はスナップショットでサーバー全体のバックアップを取っておきましょう
それがない場合はPostgresqlとfirefish本体のバックアップを取りましょう
```
sudo -u postgres pg_dumpall > backup.sql
tar -cvpzf firefish_backup.tar.gz ~/firefish
```

nodejsのバージョンはv20推奨になっているのでv18.16.0より下だったりv21とかになっていたらv20にします。
[過去の記事](https://qiita.com/schwarzewald/items/10fca9f7cddab8c8dafe)によると自分はnでバージョン管理していたようなので以下のコマンドでv20に切り替えます
```
sudo n 20
node -v //確認
```

## Firefishのダウングレード
[Firefishの用意してくれたダウングレードガイド](https://firefish.dev/firefish/firefish/-/blob/downgrade/docs/downgrade.md)に従ってv1.0.5-rcまでダウングレードします。
ここで間違えてv20240206の方にダウングレードしてしまうと駄目になってしまうので気をつけましょう。

ダウングレードが終わったらFirefishを停止します。
（firefish.serviceの部分はバージョンによってはyouor.domain.serviceのような形式になっている場合もあるのでその場合は適宜書き換えること）

## マイグレーションパッチを当てる
上記のFirefishのダウングレードガイドの内容を行っていればFirefishを実行しているユーザーでログインしていると思いますが、していない場合は`sudo su --login calckey`もしくは`sudo su --login firefish`とかでログインしておきます。

んでもって`cd calckey/`もしくは`cd firefish/`とかでFirefishのリポジトリのルートディレクトリに移動して以下のコマンドでマイグレーションパッチを当てます
```
curl -s https://iceshrimp.dev/iceshrimp/iceshrimp/raw/branch/dev/docs/firefish-redis.patch | git apply --ignore-whitespace
cd packages/backend
pnpm run revertmigration:typeorm
```

ここで注意しなければいけないのが最後の`pnpm run revertmigration:typeorm`について「FirefishRepo1689957674000が表示されるまでコマンドを入力する必要がある」ということ。つまり一回入力しただけで終わりではありません。
一回入力した結果が以下の通りですが、この通り「Migration MoreUrls1699305365258」と違う文字列が表示されています。
>$ pnpm run revertmigration:typeorm
> （中略）
> Migration MoreUrls1699305365258 has been  reverted > successfully.
>query: COMMIT

ではどうすればいいのかというと同じコマンドをもう何回か繰り返し実行する必要があるわけです。
自分の環境ではあと三回ほど実行しました。
そして途中で以下のようなエラーが出てくると思います。

（注：まっさらの環境でインストールしたFirefishでは出てこなかったのでバージョンによってはエラーでないかもしれません）
> $ pnpm run revertmigration:typeorm
>
> backend@ revertmigration:typeorm /home/calckey/calckey/packages/backend
> typeorm migration:revert -d ormconfig.js
>
>（中略）
>query failed: ALTER TABLE "drive_file" ALTER COLUMN "userHost" TYPE character varying(128)
error: error: 値は型character varying(128)としては長すぎます
query: ROLLBACK
Error during migration revert:
QueryFailedError: 値は型character varying(128)としては長すぎます
>
> （後略）（なんかいっぱいごちゃごちゃ）
>
> ELIFECYCLE  Command failed with exit code 1.

psqlでfirefishを実行しているユーザーでデータベースに接続し、以下のコマンドを実行して問題のある行を手動で削除します。
どっちのコマンドになるかは`.config/default.yml`のpostgresqlの接続ユーザーと接続先データベースを確認してください。
ここ間違えると後でエラーになってすべて終わります。

```
// 接続ユーザーがCalckeyでデータベース名がmk1の場合
psql -U calckey -d mk1
// 接続ユーザーがfirefishでデータベース名がfirefish_dbの場合
psql -U firefish -d firefish_db

DELETE FROM "migrations" WHERE "name" = 'IncreaseHostCharLimit1692374635734';
```

削除できたら`\q`とかでデータベースシェルから出てもう一度`pnpm run revertmigration:typeorm`を実行すること。
一回か二回繰り返すと最終的にこの画面になり「**FirefishRepo1689957674000**」という文字列が出ているはずです。

>$ pnpm run revertmigration:typeorm
>
> backend@ revertmigration:typeorm /home/calckey/calckey/packages/backend
> typeorm migration:revert -d ormconfig.js
>
>（中略）
>
> Migration **FirefishRepo1689957674000** has been  reverted successfully.
> query: COMMIT

そうしたら次のコマンドを実行します。
```
pnpm run revertmigration:cargo
```
これも最終的に**m20230806_170616_fix_antenna_stream_ids**という出力結果が出てくるまで繰り返す必要があります。

>$ pnpm run revertmigration:cargo
>
> backend@ revertmigration:cargo /home/calckey/calckey/packages/backend
> ./native-utils/built/migration down
>
>Rolling back 1 applied migrations
>Rolling back migration 'm20230806_170616_fix_antenna_stream_ids'
>Migration '**m20230806_170616_fix_antenna_stream_ids**' has been rollbacked

出ていたのに気付かないでうっかりもう一回打った場合は上手く行かない可能性があるので一回終わるごとに結果を確認してこれと同じ文字列が出るかどうか確認しましょう。

## Iceshrimpへの切り替え
まずgit-lfsが入っている必要があるので入っていない場合はインストールします。
```
sudo apt install git-lfs
```
それからリポジトリのルートディレクトリに戻って以下のコマンドを実行します
```
cd ../../
git remote set-url origin https://iceshrimp.dev/iceshrimp/iceshrimp.git
git lfs install
git fetch --all
```
普通はここでIceshrimpのリポジトリが取得出来る筈ですが自分の場合は以下のエラーが出ました。
その場合は以下のコマンドを打ってからもう一回`git fetch --all`してください。
※出ない場合もあります。その場合はやらなくて大丈夫です。
>$ git fetch --all
>Fetching origin
>fatal: couldn't find remote ref refs/heads/main
>error: Could not fetch origin

```
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
```
参照：[git fetch --allしても全てのブランチをfetchできなかった時の対応](https://yoshinorin.net/articles/2017/04/06/can-not-git-fetch-all/)

それからdevブランチへの切替を行い、リポジトリから大きいファイルをダウンロードしてビルドします。

```
git checkout origin/dev
git lfs pull
yarn && yarn build && yarn migrate
```

そしたらIceshrimpのアスキーアートのロゴが出てきたあとなんか色々出てきます。SQLのquery:がいっぱい出てくるあたりで結構時間かかります。エラーとか何も無く終われば成功。

`rm -rf packages/backend/native-utils packages/megalodon`で要らないファイルを削除したら後はサービスを起動します。

## Iceshrimpの起動
`NODE_ENV=production yarn run start`で何もエラーが出なかったら大丈夫です。しばらくそのまま動いているのでCtrl+Cでいっぺん強制終了しましょう。
後は公式の[Running Iceshrimp](https://iceshrimp.dev/iceshrimp/iceshrimp/src/branch/dev/docs/install.md#running-iceshrimp)の通りにsystemdファイルを作成します。


```
sudo cp docs/examples/iceshrimp.service /etc/systemd/system/
```

上記の通り設定ファイルをコピーしたらvimとかnanoとかで編集します。
`sudo vim /etc/systemd/system/iceshrimp.service`
これもCalckeyかFirefishかでUserとWorkindDirectoryの部分が変わるので確認の上編集してください。

**calckeyの場合**
```
[Unit]
Description=Iceshrimp daemon

[Service]
Type=simple
User=calckey
ExecStart=/usr/bin/yarn start
WorkingDirectory=/home/calckey/calckey
Environment="NODE_ENV=production"
TimeoutSec=60
SyslogIdentifier=iceshrimp
Restart=always

[Install]
WantedBy=multi-user.target

```

**Firefishの場合**
```
[Unit]
Description=Iceshrimp daemon

[Service]
Type=simple
User=firefish
ExecStart=/usr/bin/yarn start
WorkingDirectory=/home/firefish/firefish
Environment="NODE_ENV=production"
TimeoutSec=60
SyslogIdentifier=iceshrimp
Restart=always

[Install]
WantedBy=multi-user.target

```

編集できたら以下のコマンドで設定ファイルを更新して自動起動を有効にします。

```
sudo systemctl daemon-reload
sudo systemctl enable --now iceshrimp

// 実行確認
sudo systemctl status iceshrimp
```

あとはFirefishの起動設定ファイルを無効にするのを忘れないようにしましょう