エンジニアじゃなくてもCircleCI Runnerをインストールできるか挑戦してみた

# はじめに
こんにちは、CircleCIカスタマーサクセスマネージャーの小島です。
最近のお客様とのミーティングの中でも、
「CircleCI Runnerがリリースされたので、ぜひご利用ください！」
と紹介させていただいております。

待て待て、紹介したはいいものそういえば私ってインストールしたことないから、
詳しいインストール方法とか聞かれても答えれないぞ。。。。と最近気づいたのであります。。
そこで、今回の記事ではエンジニアではない私が、CircleCI RunnerをインストールしてmacOSローカルマシンでビルドに挑戦してみます！

# CircleCI Runnerの紹介

さっきからRunner Runner言うてるけど、まずまず
CircleCI Runnerてなに？と思われている方へ！

CircleCI RunnerとはCircleCIが提供する、Self-hosted Runner機能のことです。
CircleCI Runnerを利用すると、CircleCIのリソースクラスとして提供されていない環境やお客様のインフラストラクチャでジョブを実行できるようになります。
![スクリーンショット 2022-04-18 9.38.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634965/81c6252a-3728-0609-ae5e-7541bf9ae44b.png)



- **ローンチ エージェント (launch-agent)** CircleCI本体と通信して必要な情報を収集したり、タスクエージェントを起動したりします。
- **タスク エージェント (task-agent)** 1つ1つのタスクの実行を行います。

すなわち、この2つのエージェントをセットアップすれば動くことになりますが、実際にはタスクエージェントはダウンロードしてきたものをそのまま動かすだけですので、ローンチエージェントの設定が主な作業になります。

永続化が必要なデータ（キャッシュデータやアーティファクトなど）はCircleCIが管理しているストレージ領域に保存されるため、Runner専用の領域を別に作成する必要はありません。

主にCircleCIのお客様では特殊な環境でビルドしたい！や、セキュリティ上クラウドではなく自社サーバーを利用してビルドしたい！などのユースケースを持つお客様が実際に利用されてます。


# インストールしてみよう
[参考ドキュメント](https://circleci.com/docs/ja/2.0/runner-installation/index.html)
必須ツール: CircleCI CLI

**CLIを使用して組織のランナーリソース用の名前空間を作成**

```
circleci namespace create <name> <vcs-type> <org-name>
```
CLIでこのコマンドを打ち、作成していいですか？にYesを選ぶと無事に作成が完了します。
myorg-namespaceという名前空間を作成してみました！
名前空間は１つの組織内(Org)で１つしか作れないので、新しい名前空間を作ろうとすると、既に存在するとエラーメッセージが出ます。

**名前空間内にランナー用のリソースクラスを作成**
```
circleci runner resource-class create <name>/<resource-class> <description> --generate-token
```
nameには先ほど作成した名前空間の名前を入れて、好きなリソースクラス名に書き換えてください。
コマンドを実行すると下記のようにリソースクラス名とDescriptionが表示されます。
auth_tokenは後ほど使用するので、どこかに保存しておいてください。
![スクリーンショット 2022-04-15 15.15.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634965/c052d801-1c94-cd15-0081-0d70fa1b9e95.png)



**ローンチ エージェント バイナリのダウンロードとチェックサムの検証**
インストール対象のプラットフォームに応じて、変数を設定します。
今回は自身のmacOS環境にインストールするための変数を設定していきます。
```
macOS x86_64 : platform=darwin/amd64
```

```
export platform=darwin/amd64
```
次に、circleci-launch-agent バージョンを設定します。 
```
export base_url="https://circleci-binary-releases.s3.amazonaws.com/circleci-launch-agent"
```

最後に、次のスクリプトを実行して、バイナリをダウンロードして検証し、インストールします。
公式ドキュメントではAdmin権限でのダウンロードを行なっているため、sudoコマンドなしでは実行できないコマンドが多々あります。
こちらのコマンドを1行ずつ打ち、sudoを足して実行してあげてください。
```
sudo curl -sSL "$base_url/$agent_version/checksums.txt" -o checksums.txt
sudo mkdir -p "$platform"
sudo curl --compressed -L "$base_url/$agent_version/$file" -o "$file"
```
```
ランナー ディレクトリのセットアップ
prefix=/System/Volumes/Data/circleci
sudo mkdir -p "$prefix/workdir"


ローンチ エージェントのダウンロード
echo "Using CircleCI Launch Agent version $agent_version"
echo "Downloading and verifying CircleCI Launch Agent Binary"
base_url="https://circleci-binary-releases.s3.amazonaws.com/circleci-launch-agent"
sudo curl -sSL "$base_url/$agent_version/checksums.txt" -o checksums.txt
file="$(grep -F "$platform" checksums.txt | cut -d ' ' -f 2 | sed 's/^.//')"
sudo mkdir -p "$platform"
echo "Downloading CircleCI Launch Agent: $file"
sudo curl --compressed -L "$base_url/$agent_version/$file" -o "$file"

ダウンロードの検証
echo "Verifying CircleCI Launch Agent download"
grep "$file" checksums.txt | sha256sum --check && chmod +x "$file"; sudo cp "$file" "$prefix/circleci-launch-agent" || echo "Invalid checksum for CircleCI Launch Agent, please try download again"
```
このスクリプトでは、ベースのインストール場所に /System/Volumes/Data/circleci を指定しています。
ダウンロードが終わると/System/Volumes/Data/に.circleciディレクトリができているのを確認できます。

# プラットフォームごとのインストール(macOSへのインストール)
**CircleCI ランナー設定ファイルを作成**

```
touch launch-agent-config.yaml
```
でyamlファイルを作成し、vimで以下の内容を入力し、編集していきます。


```
api:
  auth_token: AUTH_TOKEN
  # CircleCI Server の場合 url に CircleCI Server のホスト名を設定します。 例:
  # url: https://circleci.example.com

runner:
  name: RUNNER_NAME
  command_prefix : ["sudo", "-niHu", "USERNAME", "--"]
  working_directory: /tmp/%s
  cleanup_working_directory: true

logging:
  file: /Library/Logs/com.circleci.runner.log
```
AUTH_TOKENをリソースクラスを作成したときに保存していたトークンに変更し、RUNNER_NAMEも任意の名前に変更、
USERNAMEはmacOSマシンのユーザー名に変更、保存し、編集を終了します。

 

**CircleCI ランナー設定ファイルをインストールする**
[参考ドキュメント]（https://circleci.com/docs/ja/2.0/runner-installation-mac/index.html）
root ユーザーとして、CircleCI ランナー設定ファイルの保存ディレクトリを作成します。


```
sudo mkdir -p '/Library/Preferences/com.circleci.runner'
```
このディレクトリに、先ほど作成した launch-agent-config.yaml をコピーします。


```
sudo cp 'launch-agent-config.yaml' '/Library/Preferences/com.circleci.runner/launch-agent-config.yaml'
```

**launchd .plist をインストールする**
次の内容を /Library/LaunchDaemons/com.circleci.runner.plist にコピーし、所有者を root に、パーミッションを 644 に設定します。

 

/Library/LaunchDaemons/com.circleci.runner.plistのディレクトリに移動して、vimでcom.circleci.runner.plistを編集し、⬇️の内容をコピーして保存


```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>com.circleci.runner</string>

        <key>Program</key>
        <string>/opt/circleci/circleci-launch-agent</string>

        <key>ProgramArguments</key>
        <array>
            <string>circleci-launch-agent</string>
            <string>--config</string>
            <string>/Library/Preferences/com.circleci.runner/launch-agent-config.yaml</string>
        </array>

        <key>RunAtLoad</key>
        <true/>

        <!-- ランナーは実行状態を維持する必要があります -->
        <key>KeepAlive</key>
        <true/>

        <!-- ランナーによるリソースの使用が macOS で制限されないようにする設定です-->
        <key>ProcessType</key>
        <string>Interactive</string>

        <!-- 失敗時または更新後にランナーを再起動する頻度を増やします -->
        <key>ThrottleInterval</key>
        <integer>3</integer>

        <!-- ランナーがシャットダウンするまで 10 分間待機します (ランナー自体はタスクが完了するまで待機します) -->
        <key>ExitTimeOut</key>
        <integer>600</integer>

        <!-- ログの出力とローテーションの設定はランナー固有のものを使用します -->
        <key>StandardOutPath</key>
        <string>/dev/null</string>
        <key>StandardErrorPath</key>
        <string>/dev/null</string>
    </dict>
</plist>

```
**launchd サービスを有効にする**
これで、サービスをロードできます。

```
sudo launchctl load '/Library/LaunchDaemons/com.circleci.runner.plist'
```
configファイルでRunnerのリソースクラスを呼び出してビルドしてみよう

```YAML:config.yml
version: 2.1
jobs:
  mac-runner:
    machine: true
    resource_class:  myorg-namespace/mac-runner
    steps:
      - run: echo "Hello Runner"
workflows:
  build_and_deploy:
    jobs:
      - mac-runner
```

無事に指定したリソースクラス名を利用してビルドができました！
![スクリーンショット 2022-04-22 18.13.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634965/3a9b10cc-64d5-1aa7-900f-124b2fdf0d70.png)





# 終わりに
CircleCI Runnerのインストール以前に、コマンドラインやVimの使い方に混乱し、インストールから起動までかなり時間がかかりました。
ぶっちゃけ何度も挫折しかけました。。
ドキュメント通りにインストールを行なってもうまくRunnerが起動せず、弊社エンジニア(Tadashiさん)の方に助けていただき、ようやくビルドが成功いたしました。
今後はインストールの簡易化およびインストール時間の短縮を弊社プロダクトチームは行なっていくそうです（ボタンポチとかでできて欲しいなあ）!
一般的なエンジニアの方々なら問題なくインストールできるかと思うので、皆さんもぜひ挑戦してみてください！

参考リンク
[CircleCI Runnerのセットアップ - Qiita ](https://qiita.com/kurumai/items/6ead008e90db187a1a2a)
[CircleCI Academy](https://academy.circleci.com/)