📦

Workspace 単位で Remote-SSH 先のサーバーに VSCode 拡張を自動インストールしたい

2024/06/28に公開

TL;DR

  • 問題: Remote-SSH 先のサーバーにVSCode 拡張を自動インストールしたいけど、ワークスペースまたはサーバー単位でやる方法がない
  • 解決策: インストールしたい VSCode 拡張のリストを bash.bashrc.profile に書いたスクリプトでインストール

はじめに

This settings has an application scope and onlyin the user settings file.

Remote-SSH 先のサーバーで利用したい VSCode 拡張を一括自動インストールしたいため、settings.jsonに設定しようとしたら、ユーザー単位の設定でしかできないと怒られてしまいました。
どうやら workspace 単位の .vscode/settings.jsonでは自動インストール機能は使えないようでした。

workspace の .vscode/settings.json に VSCode 拡張の自動インストール設定*
workspace の .vscode/settings.json に VSCode 拡張の自動インストール設定

https://code.visualstudio.com/docs/remote/ssh#_always-installed-extensions

workspace 単位では.vscode/extensions.jsonに VSCode 拡張をリストで記述し、ユーザーにインストールを推奨させることはできますが、自動インストールまではできないようです。
また、ユーザーレベルでdefaultExtensionsを設定するとどのサーバーにも自動インストールされるようになってしまうようなので(?)、サーバー毎に自動インストールしたい拡張機能を制御することは難しそうです。

https://future-architect.github.io/articles/20200828/
https://code.visualstudio.com/docs/editor/extension-marketplace#_workspace-recommended-extensions

上記の問題解決のため、サーバー単位の設定で VSCode 拡張をサーバー上の VSCode に Remote-SSH ログイン時に自動インストールする方法を紹介します。

この記事を読んで欲しい人

  • ユーザーレベルの settings.json の設定なしに、サーバー上の VSCode へ拡張機能を自動インストールしたい人
  • サーバー・コンテナ毎に、自動インストールされる VSCode 拡張を管理したい人

前提知識

本記事は下記についての基礎的な知識を前提として話を進めます。

  • Bash
  • VSCode
  • (オプション)Cloud-init
  • (オプション)Docker

VSCode 拡張の自動インストール処理

インストールしたい VSCode 拡張のリストとして VSCode が提供している .vscode/extensions.json を流用した自動インストール処理の方法を紹介します。

この方法は、VSCode の端末(Remote-SSH)からログインし、インタラクティブな shell が起動した際に、インストール処理を実施します。VSCode 以外の端末から ssh ログインした場合は何も起きません。

VSCode 拡張のリストに .vscode/extensions.json を流用

この方法は、jqコマンドを使用するので、事前にインストールをしてください。

サーバーが Debian 系の環境であれば、下記のようにインストールできます。

bash
sudo apt update
sudo apt install jq

下記ファイルを ssh 接続先のサーバーのログインユーザーのホームディレクトリに配置して下さい。

extensions.json
{
  "recommendations": [
    "mosapride.zenkaku",
    "ms-azuretools.vscode-docker",
    "oderwat.indent-rainbow",
    "shardulm94.trailing-spaces",
    "streetsidesoftware.code-spell-checker"
  ],
  "unwantedRecommendations": []
}

サーバーの.bashrcおよび.profileに下記の処理を追記して下さい。

~/.bashrc
# Remote-SSH ログイン時に vscode 拡張を自動インストール
function install_extensions() { jq -r '.recommendations[]' '/home/hoge/extensions.json' | xargs -I {} code --install-extension {} --force; }
if [[ -d '/home/hoge/init-vscode-extensions' ]] && [[ -e "$(command -v code)" ]] && [[ -f '/home/hoge/extensions.json' ]]; then
  install_extensions
  rm -rf '/home/hoge/init-vscode-extensions'
fi
[[ "${TERM_PROGRAM}" != 'vscode' ]] && rm -rf '/home/hoge/init-vscode-extensions'
~/.profile
# vscode 拡張のインストールを有効化するディレクトリを作成
mkdir -p /home/hoge/init-vscode-extensions

Cloud-init

Multipass や EC2 インスタンスの初期化で利用される Cloud-init において、拡張機能の自動インストールは write_files のブロックで下記のように記述できます。

cloud-init.yml
write_files:
  # インタラクティブモードで bash を開いた際の処理を追加
  - path: /home/hoge/.bashrc
    owner: hoge:hoge
    append: true
    defer: true
    content: |
      # Remote-SSH ログイン時に vscode 拡張を自動インストール
      function install_extensions() { jq -r '.recommendations[]' '/home/hoge/extensions.json' | xargs -I {} code --install-extension {} --force; }
      if [[ -d '/home/hoge/init-vscode-extensions' ]] && [[ -e "$(command -v code)" ]] && [[ -f '/home/hoge/extensions.json' ]]; then
        install_extensions
        rm -rf '/home/hoge/init-vscode-extensions'
      fi
      [[ "${TERM_PROGRAM}" != 'vscode' ]] && rm -rf '/home/hoge/init-vscode-extensions'
  # ssh ログイン時の処理を追加
  - path: /home/hoge/.profile
    owner: hoge:hoge
    append: true
    defer: true
    content: | # vscode 拡張のインストールを有効化するディレクトリを作成
      mkdir -p /home/hoge/init-vscode-extensions
  # 自動インストールする vscode 拡張の ID 一覧
  - path: /home/hoge/extensions.json
    owner: hoge:hoge
    defer: true
    content: |
      {
        "recommendations": [
          "mosapride.zenkaku",
          "ms-azuretools.vscode-docker",
          "oderwat.indent-rainbow",
          "shardulm94.trailing-spaces",
          "streetsidesoftware.code-spell-checker"
        ],
        "unwantedRecommendations": []
      }

ユーザーは hogeとしており、必要に応じてユーザー名を書き換えて下さい。

インストール対象拡張機能のリストであるextensions.jsoncontentの内容は必要に応じて、追加・削除して下さい。

Dockerfile

すでに起動済みの Docker コンテナに VSCode をアタッチする際に、コンテナに VSCode 拡張を自動インストールしたい場合は、そのコンテナの開発用イメージの Dockerfile に先述の内容を記述しておくことで VSCode 拡張の自動インストールを実現できます。

コンテナへのアタッチによる VSCode リモート開発環境の起動
コンテナへのアタッチによる VSCode リモート開発環境の起動

Dockerfile
ARG USER_NAME=hoge
ARG VSCODE_EXTENSIONS_JSON=extensions.json
ARG WORKSPACE=/home/${USER_NAME}
ARG DOCKER_FILE_PATH=<この Docker ファイルおよび extensions.json が配置されたパス>
ARG INIT_VSCODE_EXTENSIONS=init-vscode-extensions

# vscode extensions
COPY --chown=${USER_NAME}:${USER_NAME} ${DOCKER_FILE_PATH}/${VSCODE_EXTENSIONS_JSON} ${WORKSPACE}/

# init install vscode extensions
RUN <<EOF
cat - <<EOS >>${WORKSPACE}/.bashrc

# install vscode extensions
function install_extensions() { jq -r '.recommendations[]' ${WORKSPACE}/${VSCODE_EXTENSIONS_JSON} | xargs -I {} code --install-extension {} --force; }
if [[ -d ${WORKSPACE}/${INIT_VSCODE_EXTENSIONS} ]] && [[ -e \$(which code) ]] && [[ -f ${WORKSPACE}/${VSCODE_EXTENSIONS_JSON} ]]; then
  install_extensions
  rm -rf ${WORKSPACE}/${INIT_VSCODE_EXTENSIONS}
fi
[[ \${TERM_PROGRAM} != 'vscode' ]] && rm -rf ${WORKSPACE}/${INIT_VSCODE_EXTENSIONS}
EOS
EOF
RUN echo "mkdir -p ${WORKSPACE}/${INIT_VSCODE_EXTENSIONS}" >> ${WORKSPACE}/.profile

https://code.visualstudio.com/docs/devcontainers/attach-container

おわりに

本記事では、.bashrc.profileを駆使した VSCode 拡張の自動インストール方法について紹介しました。Cloud-init や Dockerfile でどうやるか?という方法も扱いました。
もしよりスマートな方法がありましたら、ぜひコメントで共有いただけると嬉しいです。

ぬまごたつ

Discussion