VS CodeでリモートのWorkspaceを編集する

先日、[「VS Codeでrmateを通してVagrant上のファイルを直編集」](https://qiita.com/jerrywdlee/items/578b5d7e83e60c392e32)という記事を投稿しました。その記事を作成した途中、**[Remote Workspace](https://github.com/mkloubert/vscode-remote-workspace)**というプラグインを見つかりました。こちらのプラグインは**[Remote VSCode](https://github.com/rafaelmaiolla/remote-vscode)**よりもはるかに汎用性が良いので、紹介いたします。

# リモート環境の設定
*本記事ではVagrantを利用して、使い方をデモストレーションします。*
## SSHでサーバーに入ってみる
Vagrant環境を直でSSHする方法は前編の記事[VS Codeでrmateを通してVagrant上のファイルを直編集](https://qiita.com/jerrywdlee/items/578b5d7e83e60c392e32)を参考してください。

```sh
$ ssh -p 2222 vagrant@localhost
```

## 一応Demo用レポジトリを作成

```sh
[vagrant@localhost ~]$ mkdir demo_repo
[vagrant@localhost ~]$ cd demo_repo/
[vagrant@localhost demo_repo]$ git init
Initialized empty Git repository in /home/vagrant/demo_repo/.git/
[vagrant@localhost demo_repo]$ echo 'Test Repo' >> test.txt
[vagrant@localhost demo_repo]$ cat test.txt
Test Repo
```

## Remote Workspaceの設定
まずは_**VS Codeがインストールしたマシン**_に `<適当な名前>.code-workspace` というファイルを作成します。できるだけ真っさらのフォルダの中に作るのがおすすめです。

```sh
$ touch demo_repo-vagrant.code-workspace
$ code .
```

VS Codeが起動した時はこのようなメッセージが出しますが、一旦無視します。
<img width="474" alt="ようこそ_—_demo_repo.png" src="https://qiita-image-store.s3.amazonaws.com/0/87438/abce8010-4b17-7fc8-7d95-562bef01a989.png">

## `.code-workspace`ファイルの編集

```json:demo_repo-vagrant.code-workspace
{
  "folders": [
    {
      "uri": "sftp://vagrant:vagrant@localhost:2222/home/vagrant/demo_repo",
      "name": "Demo Repo"
    }
  ]
}
```
ここのURLのフォーマットはこんな感じです。
`sftp://[user:password@]host[:port][/path/to/a/folder][?param1=value1&param2=value2]`

## VS Codeでworkspaceを開く
先ほど`.code-workspace`ファイルを編集する時、右下にはこのようなボタンがあるはずです。
![demo_repo-vagrant_code-workspace_—_demo_repo.png](https://qiita-image-store.s3.amazonaws.com/0/87438/0c4d647f-c6f2-7b57-a66a-3227c1dd698c.png)
このボタンをクリックすると、VS Codeのセッションがリセットされ、リモートセッションが開かれます。

また、下記のコマンド一発でもできます。

```sh
$ code demo_repo-vagrant.code-workspace
```

順調であれば、先ほど作成した`test.txt`というファイルが見えるはずです。
<img width="491" alt="test_txt_—_demo_repo-vagrant__ワークスペース_.png" src="https://qiita-image-store.s3.amazonaws.com/0/87438/7b764fa8-aed4-f582-810c-ed2d0b25bc14.png">

## 　編集＆保存
<img width="269" alt="test_txt_—_demo_repo-vagrant__ワークスペース_.png" src="https://qiita-image-store.s3.amazonaws.com/0/87438/3e494e9e-b091-5101-54e8-a7ba202c5e25.png">
VS Codeの中のファイルを編集し、保存すれば、直ちにVagrant側に反映されます。

```sh
[vagrant@localhost demo_repo]$ cat test.txt
Test Repo
Hello World!
```

## 秘密鍵でリモートのリポジトリを編集

先ほどVagrantにアクセスする際、パスワードで入りましたが、セキュリティー上の視点では公開秘密鍵でのアクセスがより多く用いられています。

### キーペアを生成

```sh
$ ssh-keygen -f demo_repo-vagrant.key
```
生成された `demo_repo-vagrant.key.pub` を Vagrantの `~/.ssh/authorized_keys` に追記しまし、キーが使えるかどうかを確認します。

```sh
$ ssh -p 2222 vagrant@localhost -i demo_repo-vagrant.key
```

### Work Spaceの設定

```sh
$ touch demo_repo-vagrant-key.code-workspace
```

```json:demo_repo-vagrant-key.code-workspace
{
  "folders": [
    {
      "uri": "sftp://vagrant@localhost:2222/home/vagrant/demo_repo?key=/PATH/TO/demo_repo-vagrant.key",
      "name": "Demo Repo"
    }
  ]
}
```
ここの `/PATH/TO/demo_repo-vagrant.key` はキーファイルの絶対パスが必要です。ただし、`$HOME/.ssh`配下に置かれたキーはファイル名だけで読み取れます。
また、キーファイルのパスじゃなくて、キーファイルの内容をBase64化して、直書きすることも可能です。

先ほどと同じようにWork Spaceを開けます。

```sh
$ code demo_repo-vagrant.code-workspace
```

### URLのparamsをJSONファイルに記入
先ほどは `?key=/PATH/TO/KEY` で記入した部分は、別ファイルのJSONに記入することもできます。

まずは `<適当な名前>.json` を作成します。

```sh
$ touch params.json
```

```params.json
{
  "key": "/PATH/TO/demo_repo-vagrant.key"
}
```


```diff:demo_repo-vagrant-key.code-workspace
{
  "folders": [
    {
-      "uri": "sftp://vagrant@localhost:2222/home/vagrant/demo_repo?key=/PATH/TO/demo_repo-vagrant.key",
+      "uri": "sftp://vagrant@localhost:2222/home/vagrant/demo_repo?params=/PATH/TO/params.json",
      "name": "Demo Repo"
    }
  ]
}
```
ここの `/PATH/TO/params.json` も絶対パスが必要です。

同じようにWork Spaceを開けます。

```sh
$ code demo_repo-vagrant.code-workspace
```


### 落とし穴
ここに一個Bugが存在しています。
OpenSSHが作ったキーは`-----BEGIN RSA PRIVATE KEY-----`から始まる旧方式と`-----BEGIN OPENSSH PRIVATE KEY-----`から始まる新方式があります。本文が作成した際、新方式のキーを使ってテストしたところ、どうしても入りませんでした。まさかの落とし穴でした。とりあえず、旧式のキーを使えば無難です。一応[Issue](https://github.com/mkloubert/vscode-remote-workspace/issues/91)を出しました。
参考: [sshの鍵の種別と変換](https://qiita.com/tsuyoshi_cho/items/b28e5529636f06e84b5e)