0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Docker Composeとは少し違う、Canonical Workshopで作る開発環境

0
Posted at

はじめに

Canonical から Workshop というツールが公開されました。

Workshop は、プロジェクトごとに必要な開発環境を定義し、LXD ベースの sandbox として起動できる開発環境構築ツールです。

今回、自作の RISC-V 64-bit microkernel プロジェクトである Rk-C に Workshop を導入してみました。

GitHub: https://github.com/shizuku198411/Rk-C

Rk-C は Nim を中心に書いている実験的な microkernel で、QEMU virt + OpenSBI 上で動作します。

このような低レイヤ系プロジェクトでは、開発環境に必要な依存関係がかなり多くなりがちです。

例えば Rk-C では、少なくとも以下が必要になります。

  • Nim
  • QEMU RISC-V system emulation
  • OpenSBI
  • RISC-V GNU toolchain
  • clang / lld / LLVM tools
  • Python 3
  • GNU make
  • QEMU 上での smoke test
  • GitHub Actions との連携

これらをホスト環境に直接入れていくと、環境差分がかなり出やすくなります。

Workshop を使うことで、この複雑な開発環境をプロジェクト側に定義として持たせられるようになりました。

Workshopとは

Workshop は、プロジェクト用の開発環境を定義して起動するためのツールです。

ざっくり言うと、次のような情報を yaml で定義します。

  • Ubuntu の base
  • 利用する SDK
  • プロジェクトローカルのセットアップ
  • よく使うコマンド
  • tunnel や mount などの interface

そして、定義した環境を workshop launch で起動し、workshop run でコマンドを実行できます。

例えば、プロジェクト側で build や test という action を定義しておけば、開発者は次のように実行できます。

workshop run rkc-dev -- build
workshop run rkc-dev -- test

重要なのは、これらのコマンドがホスト上で直接実行されるのではなく、Workshop が用意した sandbox 環境内で実行されることです。

これにより、ホスト環境に依存しにくい、再現性のある開発環境を作りやすくなります。

基本的な使い方

まず、ホスト側には LXD と Workshop を入れます。

sudo snap install --channel=6/stable lxd
sudo snap install --classic workshop

プロジェクト内に Workshop の定義を置きます。

単一の Workshop だけなら workshop.yaml を置く形でもよいですが、複数の Workshop を使う場合は .workshop/ 以下に定義を置きます。

今回の Rk-C では次のような構成にしています。

.workshop/
  rkc-dev.yaml       # workshop #1
  rkc-actions.yaml   # workshop #2
  rkc-base/          # project local SDK #1
  act-base/          # project local SDK #2

Workshop を起動します。

workshop launch rkc-dev

状態を確認します。

workshop list

定義済みの action を実行します。

workshop run rkc-dev -- build
workshop run rkc-dev -- test
workshop run rkc-dev -- run

Rk-Cでの利用例

Rk-C では、Workshop を2つに分けています。

rkc-dev
  Nim / QEMU / OpenSBI / RISC-V toolchain を含む実開発環境

rkc-actions
  Docker / act を使った GitHub Actions workflow のローカル確認環境

このように分けた理由は、実際の OS 開発環境と、workflow の検証環境を混ぜたくなかったためです。

rkc-dev

rkc-dev は、Rk-C のビルド、実行、テスト、デバッグを行うメインの開発環境です。

定義のイメージは次のようになります。

name: rkc-dev
base: ubuntu@24.04

sdks:
  - name: nim-toolchain
    channel: latest/stable

  - name: project-rkc-base

  - name: system
    plugs:
      gdb:
        interface: tunnel
        endpoint: localhost:1234

nim-toolchain は、Nim 言語の toolchain を提供する SDK です。

また、project-rkc-base は Rk-C 用のプロジェクトローカル SDK で、QEMU、OpenSBI、LLVM tools など、Rk-C の開発に必要な環境を準備します。

よく使う操作は action として定義しています。

actions:
  build: |
    set -eux
    cd /project
    make build

  build-bins: |
    set -eux
    cd /project
    make build-bins

  test: |
    set -eux
    cd /project
    make test-apps TEST_APPS_ARGS="--boot-timeout 60 --command-recover-timeout 30 --qemu-net user --skip-network-smoke"

  run: |
    set -eux
    cd /project
    make run

  debug: |
    set -eux
    cd /project
    make qemu-debug

  clean: |
    set -eux
    cd /project
    make clean

これにより、ローカルでの操作はかなりシンプルになります。

workshop run rkc-dev -- build
workshop run rkc-dev -- run
workshop run rkc-dev -- test

QEMU や OpenSBI、Nim のインストール手順を毎回ホストに合わせて調整する必要がなくなり、プロジェクトが想定する環境をそのまま起動できるようになりました。

rkc-actions

もう1つの Workshop として rkc-actions を用意しています。

これは GitHub Actions の workflow をローカルで確認するための環境です。

当初は Workshop の GitHub runner 連携も検討しました。

ただし、その方式は self-hosted runner を起動する形になるため、public repository で使う場合は、自分のローカル環境に外部から workflow job が流れてくる可能性があります。

今回の用途では、外部から job を受ける必要はなく、単に workflow の構文や分岐がローカルで確認できれば十分でした。

そのため、act を使う構成にしました。

rkc-actions のイメージは次のようになります。

name: rkc-actions
base: ubuntu@24.04

sdks:
  - name: docker-ce
    channel: latest/stable

  - name: project-act-base

actions:
  list: |
    set -eux
    cd /project
    act -l

  check-workflow: |
    set -eux
    cd /project
    act pull_request -j test-apps

docker-ce SDK により、Workshop 内で Docker を利用できます。

project-act-base では act をインストールしています。

これにより、次のように GitHub Actions workflow をローカルで確認できます。

workshop run rkc-actions -- list
workshop run rkc-actions -- check-workflow

ここでの目的は、QEMU を使った実テストを完全に再現することではありません。

rkc-actions では、主に以下を確認します。

  • workflow の構文
  • event の指定
  • job ID の指定
  • ACT 環境変数による分岐
  • checkout step
  • artifact upload step

一方で、実際の QEMU smoke test は rkc-dev 側で実行します。

workshop run rkc-dev -- test

この分離により、rkc-dev は純粋な開発・実行環境、rkc-actions は workflow 検証環境として扱えるようになりました。

GitHub Actionsでの利用

Workshop は GitHub Actions 上でも利用できます。

Rk-C では、GitHub Actions 本番 CI では rkc-dev を起動してテストを実行しています。

複数 Workshop を持つプロジェクトでは、canonical/launch-workshop にどの Workshop を起動するか明示する必要があります。

- name: Launch Workshop
  if: ${{ !env.ACT }}
  uses: canonical/launch-workshop@v0
  with:
    token: ${{ secrets.WORKSHOP_TOKEN }}
    workshop: rkc-dev

- name: Test on Workshop
  if: ${{ !env.ACT }}
  run: workshop run rkc-dev -- test

rkc-actions で act を使ってローカル確認する場合は、重い QEMU smoke test はスキップしています。

- name: Skip Workshop test in local act
  if: ${{ env.ACT }}
  shell: bash
  run: |
    set -eux
    echo "Skipping Workshop-based QEMU smoke test under local act."
    echo "This local act run validates the workflow wiring only."
    echo "Run the actual test with: workshop run rkc-dev -- test"

この構成により、次の3つのモードを分けられます。

ローカル実テスト:
  workshop run rkc-dev -- test

ローカルworkflow確認:
  workshop run rkc-actions -- check-workflow

本番CI:
  canonical/launch-workshop@v0 で rkc-dev を起動して test

Docker / Docker Compose と違う点

Workshop は、Docker や Docker Compose と似た用途に見える部分もあります。

どちらも「環境を定義して、ホスト環境との差分を減らす」という意味では近いです。

ただし、Workshop は Docker Compose の置き換えというより、プロジェクト用の開発環境を定義して、操作手順まで含めて扱うためのツールという印象です。

Docker Compose はサービス構成を定義する

Docker Compose は、複数のコンテナを組み合わせたアプリケーション構成を定義するのに向いています。

例えば、Web アプリケーションであれば次のような構成です。

app container
database container
redis container
worker container

このようなサービス群を起動し、ネットワークや volume をつなぐ用途では Docker Compose は非常に強力です。

一方で、Rk-C のようなプロジェクトでは、主な対象は常駐サービス群ではありません。

必要なのは、次のような「開発用 toolchain 環境」です。

Nim
QEMU
OpenSBI
RISC-V toolchain
LLVM tools
Python scripts
Makefile targets
GitHub Actions workflow checks

つまり、動かしたいのは Web サービス構成というより、ビルド・実行・テストのための開発環境です。

Workshop は action をプロジェクトの入口にできる

Workshop では、環境だけでなく、よく使う操作を actions として定義できます。

例えば Rk-C では、次のような action を定義しています。

actions:
  build: |
    set -eux
    cd /project
    make build

  test: |
    set -eux
    cd /project
    make test-apps TEST_APPS_ARGS="--boot-timeout 60 --command-recover-timeout 30 --qemu-net user --skip-network-smoke"

  run: |
    set -eux
    cd /project
    make run

これにより、利用者は内部の依存関係を意識せずに、次のようなコマンドで作業できます。

workshop run rkc-dev -- build
workshop run rkc-dev -- test
workshop run rkc-dev -- run

個人的には、この「環境定義」と「よく使う操作」が同じ場所にまとまる点がかなり気に入っています。

SDK として開発環境を分けられる

Workshop では SDK という単位で toolchain やセットアップを分けられます。

Rk-C では、Nim toolchain 用の SDK、Rk-C 固有の SDK、Docker / act 用の SDK を組み合わせています。

rkc-dev
  nim-toolchain
  project-rkc-base

rkc-actions
  docker-ce
  project-act-base

このように、複数の Workshop を作り、それぞれに必要な SDK だけを入れられます。

Docker Compose でも複数サービスを分けられますが、Workshop の場合は「開発用途ごとに toolchain 環境を分ける」感覚に近いです。

LXD ベースの Ubuntu 環境として扱える

Workshop は LXD を利用して Ubuntu ベースの sandbox を起動します。

そのため、Docker image を作るというより、Ubuntu 環境の中に project-specific な toolchain を用意する感覚に近いです。

Rk-C のように、QEMU、OpenSBI、RISC-V toolchain、system package、snap、Docker などが絡む場合、Ubuntu 環境として扱えるのはかなり便利でした。

もちろん Docker / Docker Compose でも同じような環境を作ることは可能です。

ただ、Workshop は最初から「開発環境」「SDK」「action」「project directory」という単位で設計されているため、開発者向けの入口を作りやすいと感じました。

使い分けのイメージ

個人的には、次のように使い分けると分かりやすいと思います。

Docker / Docker Compose
  アプリケーションやサービス群をコンテナとして起動するための構成管理

Workshop
  プロジェクト固有の開発環境、toolchain、よく使う操作をまとめるための環境管理

Web アプリケーションのサービス構成を立ち上げるなら Docker Compose が向いています。

一方で、OS、kernel、embedded、compiler、emulator、toolchain 系のように、開発環境そのものが複雑なプロジェクトでは Workshop がかなり合うと感じました。

Workshopを使ってよかったところ

今回 Workshop を使って特によかったのは、開発環境がプロジェクトの一部になったことです。

Rk-C のような低レイヤ系プロジェクトでは、依存関係が多く、ホスト環境によって差分が出やすいです。

特に以下のようなものが絡むと、セットアップ手順が長くなりがちです。

  • QEMU
  • OpenSBI
  • RISC-V toolchain
  • Nim
  • LLVM tools
  • smoke test scripts
  • GitHub Actions workflow

Workshop によって、これらをプロジェクトの定義としてまとめられました。

その結果、開発者が最初に触るコマンドはかなりシンプルになります。

workshop launch rkc-dev
workshop run rkc-dev -- test

また、複数 Workshop を使うことで、開発環境と workflow 検証環境を分けられた点も便利でした。

rkc-dev
  実際の開発・ビルド・QEMU実行・テスト

rkc-actions
  Docker + act による workflow wiring の確認

依存関係が多いプロジェクトほど、Workshop のメリットは大きいと感じました。

まとめ

Canonical Workshop を使うことで、Rk-C の複雑な開発環境をかなり整理できました。

特に良かった点は次の通りです。

  • プロジェクトごとに開発環境を定義できる
  • Nim / QEMU / OpenSBI / RISC-V toolchain などをまとめられる
  • ローカルと CI で近い環境を使える
  • 複数 Workshop により用途ごとに環境を分けられる
  • act と組み合わせて GitHub Actions workflow もローカル確認できる

Workshop はまだ新しいツールですが、低レイヤ開発、組み込み、エミュレータ、toolchain 系のプロジェクトとはかなり相性が良いと感じました。

Rk-C では、Workshop によって開発環境がかなり再現しやすくなり、プロジェクト全体の見通しも良くなりました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?