プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

Visual Studio Code あれこれ

Visual Studio Code (以下、 VSCode ) をあれこれ触っていたので、まとめておきます。

Visual Studio Code のバージョンは 1.56.0 です。

ソースコードの差分が表示されない問題

VSCode の拡張機能の Git History を入れると、コミットログがVSCode 上で快適に見れそうだと思ったので、これを試してみました。

VSCode 上で git log を見る際に便利な拡張機能 Git History | Lonely Mobiler

Git History そのものはなかなかいい感じです。ですが、ふと気づくと、 Git History そのものは動作するのですが、なぜかそれまで問題なく動いていた、エディター上で変更箇所を色付きで表示する機能が動かなくなりました(この機能は、 gutter indicators, ガターインジケータというそうです)。

これは、まずいぞ、ということで、一旦 Git Hisotry をアンインストールしたり、 VSCode 自体も再インストールしたりしたのですが、一向に解決しません。困り果ててあれこれ調べていると、

などの記事が見つかりました。これらを見ると、シンボリックリンクがあるとこのガターインジケータが正しく動作しないと書かれています。

実は開いていたフォルダは、ジャンクション経由で指定したフォルダだったので、もしやと思い、ジャンクションを経由しない方法で指定したところ、問題なく表示することができました。

にしても、なぜ今まではジャンクション経由のパスを指定して開いていたのに問題なかったのかが不思議です。とはいえ、とりあえず自分の実用上は問題ないので、これでよしとします。 似たような問題に困っている方のご参考になればと思います。

参考:VSCode のアンインストール方法

なお、 VSCode を完全にアンインストールするには、下記記事のように

VS Codeをアンインストールするには:Visual Studio Code TIPS - @IT

C:\Users\ユーザー名\AppData\Roaming\Code

C:\Users\ユーザー名\.vscode

も削除しておく必要があります。

Remote WSL 拡張機能をインストール

WSL 側に開発環境を入れて、 Visual Studio Code からリモート開発ができると知ったので、これも試してみました。

なお、余談ですが WSL は WSL 1 を使ってます。

というのも WSL 2 は Hyper-V がベースになっているっぽいので、Hyper-V が有効な状態だと、VirtualBox を使う際に支障が出てしまいます。

もちろん、 VirtualBox 側も Hyper-V が有効な状態での動作に対応しているようですが、手元の環境ではまだ検証できていないため、WSL 2 にまだ上げられず、 WSL 1 のままにしているという事情があるためです。

先々、 VirtualBox 側の動作が確認出来たら、WSL も移行したいと思います。

Visual Studio Code 側の設定

拡張機能として Remote WSL を選択し、インストールします。似たようなものとして、 Remote Development というのもあるのですが、こちらは3つのリモート機能をまとめてインストールすることができるようです。

3つのリモート機能については、下記の記事などを参考にしてください。

今回は WSL しか使わないので、 Remote WSL にしました。この辺りは、ご自分の用途に合わせてインストールするといいと思います。

WSL 側の設定

WSL のターミナルを立ち上げて、適当な作業ディレクトリに移動後、

mor@DESKTOP-H6IEJF9:~/work/test$ code .

とします。 公式の説明を読むと、 WSL 側にサーバーがインストールされ、WIndows側の VSCode と通信してリモート開発ができるようになるとのことです。

インストールが終わると、勝手に VSCode が起動します。

以後は、WSL 上の作業ディレクトリに接続して作業したければ、画面左下の緑色のアイコンをクリックすると、

f:id:junichim:20210506143855p:plain

をクリックすると、下記のように

f:id:junichim:20210506143950p:plain

コマンドパレットに選択肢が出てくるので、必要なものを選択すればOKです。なお、 New WSL Window や New WSL Windows using Distro... だと、リモートに接続した状態ですが、特にどのフォルダも開いていないので、改めてフォルダを選択して開く必要があります(この状態でメニューの『フォルダを開く』を選択すると、WSL側のフォルダを選択できるので、便利です)。

参考:code 実行時のエラーについて

実は、最初に試した際は、下記のように mv でに関するエラーが表示されました。

mor@DESKTOP-H6IEJF9:~/work/test$ code .
Installing VS Code Server for x64 (cfa2e218100323074ac1948c885448fdf4de2a7f)
Downloading: 100%
Unpacking: 100%
mv: '/home/mor/.vscode-server/bin/cfa2e218100323074ac1948c885448fdf4de2a7f-1620269414' から '/home/mor/.vscode-server/bin/cfa2e218100323074ac1948c885448fdf4de2a7f' へ移動できません: 許可がありません
mv: '/home/mor/.vscode-server/bin/cfa2e218100323074ac1948c885448fdf4de2a7f-1620269414' から '/home/mor/.vscode-server/bin/cfa2e218100323074ac1948c885448fdf4de2a7f' へ移動できません: 許可がありません
mv: '/home/mor/.vscode-server/bin/cfa2e218100323074ac1948c885448fdf4de2a7f-1620269414' から '/home/mor/.vscode-server/bin/cfa2e218100323074ac1948c885448fdf4de2a7f' へ移動できません: 許可がありません
mv: '/home/mor/.vscode-server/bin/cfa2e218100323074ac1948c885448fdf4de2a7f-1620269414' から '/home/mor/.vscode-server/bin/cfa2e218100323074ac1948c885448fdf4de2a7f' へ移動できません: 許可がありません
Unpacked 1952 files and folders to /home/mor/.vscode-server/bin/cfa2e218100323074ac1948c885448fdf4de2a7f.
mor@DESKTOP-H6IEJF9:~/work/test$ ls

これは正しくインストール出来ているのか?と疑問に思ったので調べてみました。

すると、詳細な理由は不明ですが、似たような現象があるようです。

Install Remote WSL fail with mv - permission denied · Issue #109 · microsoft/vscode-remote-release · GitHub

上記の記事中で解決策として修正対象になっているスクリプト(今回の場合は、 C:\Users\ユーザー名.vscode\extensions\ms-vscode-remote.remote-wsl-0.56.1\scripts\wslDownload.sh)を見てみると、

   # Rename temporary folder to final folder name, retries needed due to WSL
    for _ in 1 2 3 4 5; do
        mv "$TMP_EXTRACT_FOLDER" "$VSCODE_REMOTE_BIN/$COMMIT" && break
        sleep 2
    done

    if [ ! -d "$VSCODE_REMOTE_BIN/$COMMIT" ]; then
        echo "WARNING: Unable to move $TMP_EXTRACT_FOLDER. Trying copying instead." 1>&2
        cp -r "$TMP_EXTRACT_FOLDER" "$VSCODE_REMOTE_BIN/$COMMIT"
    fi

    if [ ! -d "$VSCODE_REMOTE_BIN/$COMMIT" ]; then
        echo "ERROR: Failed create $VSCODE_REMOTE_BIN/$COMMIT. Make sure all VSCode WSL windows are closed and try again." 1>&2
        exit 11
    fi

    EXTRACTED_COUNT=$(find "$VSCODE_REMOTE_BIN/$COMMIT" | wc -l)
    if [ "$FILE_COUNT" -ne "$EXTRACTED_COUNT" ]; then
        echo "ERROR: Unpacking failed: Files expected: $FILE_COUNT, is $EXTRACTED_COUNT" 1>&2
    else
        echo "Unpacked $EXTRACTED_COUNT files and folders to $VSCODE_REMOTE_BIN/$COMMIT."
    fi

となっていました。 mv を5回試して、どこかで成功すれば『Unpacked ・・・』のメッセージが出るようです。 なので、これはこれで正しくインストールされているということのようです。

心臓に悪いですね。

ちなみに、このエラーがでたときは、 WSL というか Ubuntu のバージョンは

mor@DESKTOP-H6IEJF9:~$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.1 LTS"
mor@DESKTOP-H6IEJF9:~$

でした。

Windows 10 20H2 にアップデートしたら iSCSI ドライブのマウントが消えてしまったので修復した件

4月に入り、2020年度の仕事も一段落してきたので、次の仕事がスタートする前に手元の環境をいろいろと更新しようと思い立ちました。

で、その一環で WIndows 10 も 1909 だったので 20H2 にアップデートしました。

そうしたら、なんとまあ、iSCSI 領域を Windows 上の2か所でマウントしていたのですが、なぜか片一方だけ消えてしまいました。もっとも、 20H2 にアップデートしたタイミングで要らなくなったアプリなどもあれこれ削除していたので、Windows アップデートではなく、どれかのアンインストーラが悪さをした可能性もありますが、今となっては不明です。

一応、備忘録として、再マウントした手順を書いておきます。

再マウント

まず、 iSCSI イニシエータの設定が無事か確認します。

『スタート』->『Windows システムツール』->『コントロールパネル』->『管理ツール』->『iSCSIイニシエータ』を開くと、

f:id:junichim:20210428145629p:plain

のように問題なく接続されていました。ここは問題なさそうです。

次に、『管理ツール』に戻り、『コンピュータの管理』を開き、『ディスクの管理』を開きます。

f:id:junichim:20210428150117p:plain

ここの『ディスク1』というのが、iSCSI ドライブになります。既に、 D ドライブのドライブレターが割り当てられています。

次に、ボリューム(D:) を選択して、『ドライブ文字とパスの変更』を選択すると、

f:id:junichim:20210428150352p:plain

f:id:junichim:20210428144710p:plain

のようになっています。

最初に書いたように、もともとは、一つの同じ iSCSI 領域を2か所にマウントしており、この画面で2つのパスが存在していました。一連のアップデート作業で、ドライブではないパスのほうのマウントが消えてしまってます。

ということで、もう一度マウントしておきます。上記画面で『追加』を選択し、『次の空のNTFSフォルダにマウントする』を選び、

f:id:junichim:20210428144651p:plain

『参照』ボタンを使い、マウント先を指定し、

f:id:junichim:20210428144631p:plain

『OK』とします。

f:id:junichim:20210428144803p:plain

もう一度、『OK』を押し、エラー等がでなければ、マウントされます。

これで、無事に一つの iSCSI 領域を2か所にマウントできました。 無事に復旧しましたが、この手のトラブルは焦りますね。

参考

『ディスクの管理』で空のNTFSフォルダにマウントしたものは、ジャンクションとしてマウントされています。

パスに割り当てたフォルダを dir コマンドでみると、

C:\Users\mor>dir
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 8824-7400 です

 C:\Users\mor のディレクトリ

2021/04/28  14:49    <DIR>          .
2021/04/28  14:49    <DIR>          ..
(中略)
2021/04/28  14:46    <JUNCTION>     home [\??\Volume{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\]
(中略)
2021/04/28  14:49    <JUNCTION>     jmtest [d:\]
(後略)

となり、ジャンクションとして扱っているのがわかります。

なお、通常、ジャンクションを作成する場合に使う mklink /j コマンドで作成した場合(上記の jmtest )は、フォルダを指定する形になっているので、直接ボリュームにジャンクションを貼っているのがちょっと違うところですね。

EC2 の自動起動と自動停止

こちらの記事で書いたように、オフラインマップサーバーをEC2上に移しましたが、このサーバーは常時稼働する必要はありません。 EC2は動かしておくと、課金もされるので、必要な時だけ、自動的に起動して、自動的に停止させたいと思います。

ネットを調べると、いろいろな方法で実現できることがわかります。今回は楽をしたかったので、 CloudWatchEvent + AWS System Manager(旧称 SSM) による処理としました。

元ネタは下記になります。

IAM ロールの作成

IAM ロールを作成する際、最初にサービスとして、 System Manager を選択します。

f:id:junichim:20210419103437p:plain f:id:junichim:20210419103521p:plain

そのうえで、ポリシーとして SSMAutomationRole をアタッチします。

f:id:junichim:20210419103608p:plain

ロール名を指定して、ロールを作成します。

f:id:junichim:20210419103737p:plain

IAMロール作成後、信頼関係を表示して、

f:id:junichim:20210419103920p:plain

『信頼関係の編集』を行い、信頼されたエンティティとして、

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ssm.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

とあるのを、

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "events.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

のように変更します。

EC2 起動用の CloudWatchEvent ルールの作成

IAM ロールが作成できれば、次は CloudWatchEvent のルールを作成します。ルールは、 Cron 式で指定します。 『ターゲット』として、『SSM Automation』を選択し、ドキュメントから『AWS-StartEC2Instance』を選択します。

f:id:junichim:20210419104354p:plain

ドキュメントを選択すると、インスタンスID入力欄が出てくるので、対象となる EC2 インスタンスのインスタンスIDを入力します。

f:id:junichim:20210419104700p:plain

最後に、ロールとして、先ほど作ったロールを設定すればOKです。

f:id:junichim:20210419104903p:plain

EC2 停止用の CloudWatchEvent ルールの作成

EC2 停止用の CloudWatchEvent ルールも起動用と同様に作成します。停止用の場合は、ドキュメントして、『AWS-StopEC2Instance』を選択するだけです。

テスト

作成したルールの Cron 式で起動する時間を適当に調整してテストします。指定した時間になると、EC2インスタンスが起動していることが確認できればOKです。停止も同様に確認しておきます。正しく動作していれば、これでOKです。

もし、EC2が期待したように起動しない場合は、ルールそのものが呼び出されたのか、ルールは呼ばれたけどEC2の起動に失敗したか、などは、CloudWatch メトリクスを見ればわかります。

f:id:junichim:20210419105347p:plain

まとめ

SSMを使えば、EC2の起動停止の制御が非常に簡単にできることがわかりました。

これ、いままで動かしっぱなしだった他の EC2 でも応用できますね。うまくすればずいぶんと、お安く運用できそうです。