remote-sshが使えないけどVSCodeでリモートサーバ上のFortranファイルを編集したい!


## ターゲット
- リモートサーバ上でVimとかEmacsでファイルをたくさん編集するのはﾁｮｯﾄﾂﾗｲ人

## 要約
(2024/11/24追記)
- 今ならVSCodeの[Remote Tunnels](https://code.visualstudio.com/docs/remote/tunnels)を使うのが良い

(2024/11/24追記ここまで、以下はRemote Tunnelsが使えない環境の場合に使うことを検討)

- sshfsでリモートサーバ上のディレクトリをマウントしてローカルPCでVSCodeを開いて編集する(これでわかる人は以下の文章は読まなくて大丈夫かも)

## VSCodeで編集する方法の分類
大まかに2種類の編集方法がある

**ホスト側がssh agent forwardingを有効にしてくれているかどうかで手順がかなり違う**

### ssh agent forwardingを有効にしてくれているとき  
VSCodeの拡張機能の[remote development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)の中にある[remote-ssh](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh)を使ってssh接続するだけで,VSCodeでリモートサーバ上のファイルが触れるようになる(正確には[ローカルでは表示だけしてリモートでVSCode serverを動かしている](https://code.visualstudio.com/docs/remote/ssh)らしい)  
この記事では解説しない
### ssh agent forwardingが無効のとき  
サーバ管理者に[/etc/sshd_configをremote sshが使えるように設定する](https://qiita.com/igrep/items/3a3ba8e9089885c3c9f6#%E3%83%8F%E3%83%9E%E3%81%A3%E3%81%9F%E3%81%A8%E3%81%93%E3%82%8D2-could-not-fetch-remote-environment)ように依頼して承認されれば[remote-ssh](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh)を使える  
それが出来ない場合は以下の手順を踏むことになる


## セットアップの概略
* gfortranをインストールして
* fortran-language-serverをインストールして
* VSCodeの拡張機能の[Modern Fortran]と[FORTRAN IntelliSense]をインストールして
* sshfsを使ってリモートサーバの任意ディレクトリ下をローカルにマウントして同期させ
* ローカルマシンでFortranファイルをVSCodeで編集
[Modern Fortran]:https://marketplace.visualstudio.com/items?itemName=krvajalm.linter-gfortran
[FORTRAN IntelliSense]:https://marketplace.visualstudio.com/items?itemName=hansec.fortran-ls
とりあえずWSL2(Ubuntu-20.04)でのセットアップを紹介する(WindowsとmacOSについては外部リンクを張る,またはコマンドの表記程度にとどめる)
WSL2の導入については[Microsoftの公式インストールガイド](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)に沿って進めればOK
### gfortranのインストール
以下の2行でOK

```sh:shell
sudo apt update
sudo apt install gfortran
```
Windowsなら[Mingw-w64をダウンロードしてインストール,pathの設定](https://i-memo.hatenablog.jp/entry/2017/01/26/windows10%E3%81%ABgfortran%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F)をする
macOSなら[homebrew](https://brew.sh/index_ja)をインストールした後

```sh:shell
sudo brew install gcc
```
で使えるようになる

### fortran-language-server
[FORTRAN IntelliSense]が使うのでインストールする
pipを使ってインストールするが[Ubuntu環境のpipは少し特殊](https://www.python.jp/install/ubuntu/pip.html)なためコマンドに注意

```sh:shell
sudo apt install python3-pip
pip3 install fortran-language-server
```
Windowsなら[python公式](https://www.python.org/downloads/)からダウンロード,インストールしてpathを設定してfortran-language-serverをインストール  
macOSなら最初からpython3が入っているはずなのでそのまま

```sh:shell
pip3 install fortran-language-server
```
でOK

### VSCodeの拡張機能のインストールと設定
VSCodeの拡張機能からFortranと検索して[Modern Fortran]と[Fortran IntelliSense]をインストールするだけ
![fortranextensions.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492996/159c1ec4-d88e-6638-cbca-0dd402d20d24.png)

```sh:shell
which fortls
which gfortran
```
でfortran-language-serverとgfortranのpathを取得して  
VSCodeのsettings.json(WSL:Ubuntu-20.04)に

``` settings.json
"fortran.gfortranExecutable": "gfortranのpath",
"fortran-ls.executablePath": "fortran-language-serverのpath",
```
を追記すればVSCodeのFortranの設定は完了

### リモートサーバ上のファイルのマウント
[sshfs](https://github.com/libfuse/sshfs)を使う
**[2022/04/03 追記]**
- これまでに紹介していた/etc/fstabで自動マウントを設定する方法は,Ubuntu起動時に自動マウントを始める方法だと紹介していたが,マウントポイントにアクセス(cdやlsするなど)すると自動マウントをし始めるような挙動になっていた  
- Ubuntuログインにマウントのための時間がかかるのと,マウントポイントの初回アクセス時にマウントのための時間がかかるのと,どちらがユーザの体験を損ねないかについては意見が分かれそうなので両方のやり方を残しておく  
- 以下の例では$HOME/sshfsをマウントポイントにする場合の設定を記述するので各環境ごとに書き換えが必要  
- 公開鍵認証(パスワードなし)を前提にしている

**[2022/04/03 追記ここまで]**

#### ~~Ubuntu起動時~~ Ubuntuログイン時にマウントする設定

```sh:shell
sudo apt install sshfs
# マウント用のディレクトリを作る
mkdir ~/sshfs
# Allow_otherを有効化して,マウント先のディレクトリをマウント後もログインユーザの権限で操作できるようにする
sudo sh -c 'echo user_allow_other >> /etc/fuse.conf'
# $HOME/sshfsをマウントポイントとしてマウントできるならマウントする
# (デフォルトでインストールされているはずだがmountpoint is not foundなどと出たらsudo apt install util-linuxでmountpointコマンドをインストール)
echo -e "if [ \"\$(ls \$HOME/sshfs)\" ]; then\n\tif ! mountpoint -q \$HOME/sshfs ; then\n\t\techo \"\$HOME/sshfs is not empty.  No mount operation is performed.\"\n\tfi\nelse\n\tmount\nfi" >> $HOME/.profile
# マウント用のコマンド
echo "alias mount='sshfs -o uid=\`id -u\` -o gid=\`id -g\` -o allow_other -o nonempty {sshログインで使うユーザ名}:{リモートサーバのマウントしたいディレクトリ} {ローカルのマウントポイント} -o IdentityFile={IdentityFilePath}'" >> $HOME/.profile
```

#### マウントポイントにアクセス(cdやlsするなど)すると自動マウントをし始める設定

WSL2(Ubuntu20.04)環境において[arch-linux.jpのsshfsの記事](https://wiki.archlinux.jp/index.php/SSHFS#.E8.87.AA.E5.8B.95.E3.83.9E.E3.82.A6.E3.83.B3.E3.83.88)によると,自動マウントはrootユーザによっておこなわれるので,fstabを編集するだけでは起動時マウントはできない
なので下記のような編集が必要になる  

- rootユーザで1度手動でsshfsを使ってマウント(/root/.ssh/known_hostsに署名を追加するため)

```sh:shell
sudo apt install sshfs
# マウント用のディレクトリを作る
mkdir ~/sshfs
# Allow_otherを有効化して,マウント先のディレクトリをマウント後もログインユーザの権限で操作できるようにする
sudo sh -c 'echo user_allow_other >> /etc/fuse.conf'
# sshfsでマウント
sudo sshfs {sshログインで使うユーザ名}@{リモートサーバのIPアドレス}:{リモートサーバのマウントしたいディレクトリ} {ローカルのマウントポイント} -o IdentityFile={IdentityFilePath}
```

ログインユーザのパスワードが求められるので入力すると

```
The authenticity of host '{リモートサーバのIPアドレス}' can't be established.
ECDSA key fingerprint is SHA256:{ハッシュ値}.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
```
と聞かれるはずなので yesで/root/.ssh/known_hostsに署名を追加する
~~起動時~~初回アクセス時に自動マウントさせるなら/etc/fstabを管理者権限で開いて

```sh:shell
sshfs#{sshログインで使うユーザ名}@{リモートサーバのIPアドレス}:{リモートサーバのマウントしたいディレクトリ} {ローカルのマウントポイント} fuse users,allow_other,delay_connect,reconnect,uid={user id},gid={group id},IdentityFile={IdentityFilePath} 0 0
```
を書き込めば~~起動時~~初回アクセス時に自動マウントされるはず(~~起動時にマウントするのでコマンドが打てるようになるまでの時間は数秒増える~~)  
user id,group idはターミナルでidコマンドを実行すると現在のログインユーザのuid,gidが表示されるのでその番号を打てばよい

ここまで終わったらUbuntuをシャットダウンさせて再起動させる
以上の工程を経ると,~~起動時~~初回アクセス時にsshfsによるリモートサーバの任意ディレクトリの自動マウントが可能になる


これでVSCodeで編集できるようになったので

```sh:shell
code ~/sshfs/{開きたいディレクトリ}
```
で開くとVSCodeでリモートサーバ上のファイル(をローカルにマウントしたもの)をいじれるようになる  
Windowsなら[このとおりにセットアップ](https://qiita.com/onomame/items/342bc9025ac209cab34b)するといい
macOSなら[これを参照](https://techracho.bpsinc.jp/hachi8833/2019_02_05/66454)するとよい

### 感想

[remote-ssh](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh)が使える環境の楽さが身に染みて分かった